Cryptography Driver (Help !!!!)
Yong Ma
mayong at mail.com
Tue Oct 25 20:19:26 PDT 2005
Dear colleagues,=20
Cry for help!!!!
The cryptography card driver (polling mode, not interrupt mode) works well=
=20
under linux-2.4, but not working under FreeBSD-5.4. The DMA buffer just
keep intact under FreeBSD-5.4 after the Random value generation command=20
has been issued.
Every thing is compared, but it still not working.
Thanks alot
Following is the Linux and FreeBSD files:
The cryptography card driver under Linux 2.4:
/////////////////////////////////////////////////////////////
#include <linux/config.h>
#include <linux/module.h>
#include <asm/io.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/tty.h>
#include <linux/mm.h>
#include <linux/serial.h>
#include <linux/fcntl.h>
#include <linux/major.h>
#include <linux/delay.h>
#include <linux/tqueue.h>
#include <linux/version.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <linux/spinlock.h>
#include "sjy22bdrv.h"
/* lilin changed*/
u_char *dma_buffer;
struct pci_dev *pdev =3D NULL;
dma_addr_t dma_addr;
/* time out vars and function */// lilin adding
volatile unsigned long isdmatimeout=3D0;
volatile unsigned long iscardtimeout=3D0;
struct timer_list timer_dma,timer_card;
void dma_timeout(unsigned long ptr);
void card_timeout(unsigned long ptr);
/* */
=09=09
#define WORD unsigned short int
#define HInD(port) inl(card_base[card_no]+port)
#define HOutD(port,val) outl( val,card_base[card_no]+port)
#define YhOutW(port,val) outw( val,port)
#define YhOutB(port,val) outb( val,port)
WORD basePort=3D0,dataPort,addrPort;
static int jmkmajor;
//lilin adding=20
#define DMA_BUFFER_SIZE 4*1024
=09
void * card_clea[CARD_NUM];
ulong card_stat[CARD_NUM];
ulong card_use[CARD_NUM];/*added */
ulong card_base[CARD_NUM];
ulong card_addr[CARD_NUM];
ulong card_data[CARD_NUM];
int leftPort[CARD_NUM];
int rightPort[CARD_NUM];
spinlock_t sjy22_lock;
int DMAOpen( int card_no );
//=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D
/******* hhw changed 2000 12 28 ************/
/******* lilin changed 2002 5 *************/
int close_jmk(struct inode *inode , struct file *file)
{
return 0;
}
int open_jmk(struct inode *inode, struct file *file)
{
return 0;
}
void SendCmdToF206( PARAM_INFO *MI,int card_no )
{
int i1;
memcpy(dma_buffer+4, (char *)MI->inp, MI->inlen );
for (i1 =3D 0; i1 < MI->inlen + 14; i1 ++)
printk("%x ", (unsigned char )*((unsigned char *)dma_buffer + i1)=
);
printk("\n");
HOutD( 0x08c, MI->inlen+4);
//sent data
HOutD( 0x090, 0 );
i1 =3D HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
i1 =3D 0;
while(i1 =3D=3D 0)=20
{
=09
i1 =3D HInD(0xA8) & (1<<4);
}
writel ( 0, card_clea[0]);
return;
}
int RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
int i1;
char *chp;
chp=3D(char *)MI->outp;
HOutD( 0x08c, MI->outlen+4);
HOutD( 0x090, (1<<3) );
i1 =3D HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
=20=20=20=20=20=20=20
/* init_timer(&timer_dma);//init timer struct
timer_dma.function =3D dma_timeout;
timer_dma.expires =3D jiffies+120*HZ;//120 seconds
add_timer(&timer_dma); */
i1 =3D 0;
while(i1 =3D=3D 0)=20
{
if (isdmatimeout =3D=3D0)//if timeout ,del timer and return
i1 =3D HInD(0xA8) & (1<<4);
/* else
{=20=20=20
del_timer(&timer_dma);
card_use[card_no] =3D CARD_READY;
isdmatimeout =3D 0;
chp[0]=3D0x29;
chp[1]=3D0;
chp[2]=3D0;
chp[3]=3D0;
return -1;
}*/
}
// del_timer(&timer_dma);
/* for (i1 =3D 0; i1 < 16; i1++)
printk("%x ", *((unsigned char *)dma_buffer + 4 +i1));*/
memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );
return 0;=09
}
int F206Function(PARAM_INFO *MI ,int card_no)
{
unsigned long RegValue;
unsigned long lock_flag;
int i;
char *chp;
chp=3D(char *)MI->outp;
spin_lock_irqsave(&sjy22_lock,lock_flag);
if( card_use[card_no] =3D=3D CARD_BUSY)
{
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
chp[0] =3D 0x2A;
chp[1] =3D 0;
chp[2] =3D 0;
chp[2] =3D 0;
return -EBUSY;
}
card_use[card_no] =3D CARD_BUSY;
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
SendCmdToF206(MI, card_no);
// init_timer(&timer_card);//init timer struct
// timer_card.function =3D card_timeout;
// timer_card.expires =3D jiffies+120*HZ;//120 second:s
=20=20=20=20=20=20
// add_timer(&timer_card);
RegValue =3D 0x3;
while( RegValue !=3D 0)
{
if (iscardtimeout =3D=3D0)
RegValue =3D readl ( card_clea[0] ) & 0x3;
/* else
{
del_timer(&timer_card);
iscardtimeout =3D 0;=20=20=20=20=20=20=20=20
card_use[card_no] =3D CARD_READY;
chp[0]=3D0x29;
chp[1]=3D0;
chp[2]=3D0;
chp[3]=3D0;
return -1;
}*/
}
printk("request RegValue =3D %x\n", RegValue);=20
// del_timer(&timer_card);
=20=20=20=20=20=20
RegValue =3D 0x3;
while(RegValue !=3D 0)
{
RegValue =3D readl(card_clea[0]) & 0x3;
}
RegValue =3D readl( card_clea[0]);
/* It's neccessary! Two read(0x1000 0000) operation needed.*/
printk("RegValue =3D %x\n", RegValue);=20
i=3DRcvDataFromF206( MI, card_no );
if (i =3D=3D -1)
{
card_use[0] =3D CARD_READY;
return -1;
}
if(card_no=3D=3D0) card_use[0]=3DCARD_READY;=09
return 0;
}
int ioctl_jmk(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
int card_no =3D 0;
int ioadd;
unsigned long ii1;
PARAM_INFO MMI;
switch( cmd )
{
case Ioctl_F206_Reset:
ioadd =3D card_base[card_no] + 0x6c;=20=20=20=20=20=20=20=20=20=20=20=20=
=20
ii1 =3D inl( ioadd );
ii1 |=3D ( 1 << 30 );
outl( ii1, ioadd );
ii1 &=3D ~( 1 << 30 );
outl( ii1, ioadd );
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
DMAOpen( card_no );
return 0;
break;
case Ioctl_F206_Function:
copy_from_user(&MMI,(PARAM_INFO *)arg,sizeof(MMI) );
=09=09=09
F206Function( &MMI,card_no);
=09=09=09
copy_to_user((PARAM_INFO *)arg,&MMI,sizeof(MMI) );
return 0;
=09=09=09
default:
break;=09=09=09=09=09
}
return 0;
}
struct file_operations jmk_fops =3D {
ioctl: ioctl_jmk,=20=20=20=20=20=20
open: open_jmk,=09
release: close_jmk,=09
};
int init_sjy22b(void)
{
unsigned long k;
int card_no;
card_no =3D 0;
if (pci_present()) {
=09=09
u32 pio_start, pio_end, pio_flags, pio_len;=09
unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
void *map_addr;=09
=09=09=09
pdev =3D pci_find_device (0x10b5, 0x5406,pdev);
if (!pdev) return 1;
pci_write_config_word(pdev, PCI_COMMAND, 7);
pio_start =3D pci_resource_start (pdev, 1);
pio_end =3D pci_resource_end (pdev, 1);
pio_flags =3D pci_resource_flags (pdev, 1);
pio_len =3D pci_resource_len (pdev, 1);
mmio_start =3D pci_resource_start (pdev, 3);
mmio_end =3D pci_resource_end (pdev, 3);
mmio_flags =3D pci_resource_flags (pdev, 3);
mmio_len =3D pci_resource_len (pdev, 3);
if(pci_request_regions (pdev, "sjy22bdrv")){
printk("<1>%s: region resource error, aborting\n",pdev->slot_name);
return 1;
}=09
/* enable PCI bus-mastering */
// pci_set_master (pdev);
card_base[0] =3D pio_start ;
k =3D inl( card_base[0]+0x04 );
printk("Base_address[04] =3D %lxH\n",k);
k =3D inl( card_base[0]+0x0f4 );
printk("Base_address[f4] =3D %lxH\n",k);
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
outl( 0x20000000, card_base[0]+0x04 );
outl( 0x10000000, (card_base[0]+0x0f4) );
/* ioremap MMIO region */
map_addr =3D ioremap (mmio_start, mmio_len);
if (map_addr =3D=3D NULL) {
printk("%s: cannot remao mmiom,aborting\n",pdev->slot_name);
return 1;
}
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
(void *)card_clea[0] =3D map_addr;
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
// dma_buffer =3D pci_alloc_consistent(pdev,DMA_BUFFER_SIZE,&dma_addr);
dma_buffer =3D kmalloc(4096,GFP_KERNEL);
dma_addr =3D dma_buffer - 0xc0000000;=20
if(dma_buffer =3D=3D NULL) {
printk("allock dma buffer error\n");=09=09
return 1;=09
}=09
card_stat[0]=3DCARD_READY;=09
card_use[0]=3DCARD_READY;=09
card_stat[1]=3DCARD_BUSY;
card_use[1]=3DCARD_BUSY;=09
=09
k =3D inl(card_base[0] + 0x0c);=20=20=20=20=20=20=20=20=20=20=20=
=20=20
k &=3D 0xffffff00;
outl(k, card_base[0] + 0x0c);=20=20=20=20=20=20=20=20=20=20=20=20=20
DMAOpen( 0 );
spin_lock_init(&sjy22_lock);
printk("(C)Copyright Duanxuejiang, 2002, Beijing(V1.42.1).\n");
printk("Welcome to use BOCO SJY22 PCI CARD!\n");
jmkmajor=3Dregister_chrdev(0,"jmk",&jmk_fops);
printk("PCI Major=3D%d.\n",jmkmajor);
printk("SJY22 is Ok\n");
return 0;=09=09
}=09
printk("No SJY22 device!");=09
return 1;
}
int init_jmk(void)
{
int temp;
temp =3D init_sjy22b();
return temp;
}
/*-------------------------------------------------------------*/
#ifdef MODULE
int init_module(void)
{
int temp;
temp =3D init_sjy22b();
return temp;
}
void cleanup_module(void)
{
unregister_chrdev(jmkmajor,"jmk");
pci_free_consistent(pdev,DMA_BUFFER_SIZE,dma_buffer,dma_addr);
iounmap ((void *)card_addr[0]);
/* it's ok to call this even if we have no regions to free */
pci_release_regions (pdev);
printk("clean up!\n");
}
#endif
int DMAOpen( int card_no )
{
unsigned long RegValue;
=20=20=20=20=20=20=20=20
HOutD(0x004, 0x20000001 );
HOutD(0x0f4, 0x10000001 );
=09
RegValue =3D HInD(0x008);
RegValue &=3D ~(1 << 20);
RegValue |=3D (1 << 19);
HOutD(0x008, RegValue );
RegValue =3D HInD(0x0B0);
=09
HOutD(0x0B0, (RegValue & 0xffff0000));
HOutD(0x080, 0x0001c3 );
RegValue =3D HInD(0x068);
RegValue &=3D ~(1 << 18);
RegValue &=3D ~(1 << 8);
HOutD(0x068, RegValue );
//dma_buffer2 =3D virt_to_phys(dma_buffer);
RegValue =3D dma_addr;=20
HOutD(0x084, RegValue );
RegValue =3D 0x20000000;
HOutD( 0x088, RegValue );
HOutD( 0x08c, 16 );
//sent data
HOutD( 0x090, (1<<3) );
HOutD( 0x0B4, 0 );
HOutD( 0x0A8, (1<<0) );
return 0;
}
void dma_timeout(unsigned long ptr)
{
isdmatimeout=3D1;
}
void card_timeout(unsigned long ptr)
{
iscardtimeout=3D1;
}
/////////////////////////////////////////////////////////////////////
Device Driver under FreeBSD-5.4
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/*
Ma Yong, Zhouyi Zhou
Infrastructure Software Center=20
Institute of Software
Chinese Academy of Sciences
*/
//#define MIN(a,b) (((a) < (b)) ? (a) : (b))
#include <sys/param.h>=20=20
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/kernel.h>=20
#include <sys/conf.h>=20=20=20
#include <sys/uio.h>=20=20=20=20
#include <sys/malloc.h>
#include <sys/bus.h>=20=20
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include "sjy22bdrv.h"
#define WORD unsigned short int
#define DWORD unsigned long
#define BYTE unsigned char
#define HInD(port) inl(card_base[0]+port)
#define HOutD(port,val) outl( val,card_base[0]+port)
#define Debug 0
#define YhOutW(port,val) outw( val,port)
#define YhOutB(port,val) outb( val,port)
typedef struct {
volatile unsigned long lock;
volatile unsigned int babble;
const char *module;
} spinlock_t;
#define save_flags(x) __asm__ __volatile__("pushfl ; popl %0":"=3Dg=
" (x): /* no input */)
#define restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /* n=
o output */ :"g" (x):"memory", "cc")
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ; cl=
i":"=3Dg" (x): /* no input */ :"memory")
#define LOCK_SECTION_NAME \
".text.lock.sjy22bdrv"=20
#define LOCK_SECTION_START(extra) \
".subsection 1\n\t" \
extra \
".ifndef " LOCK_SECTION_NAME "\n\t" \
LOCK_SECTION_NAME ":\n\t" \
".endif\n\t"
=20
#define LOCK_SECTION_END \
".previous\n\t"
#define spin_lock_string \
"\n1:\t" \
"lock ; decb %0\n\t" \
"js 2f\n" \
LOCK_SECTION_START("") \
"2:\t" \
"cmpb $0,%0\n\t" \
"rep;nop\n\t" \
"jle 2b\n\t" \
"jmp 1b\n" \
LOCK_SECTION_END
static inline void spin_lock(spinlock_t *lock)
{
__asm__ __volatile__(
spin_lock_string
:"=3Dm" (lock->lock) : : "memory");
}
#define spin_lock_irqsave(lock, flags) do { local_irq_save(flags);=
spin_lock(lock); } while (0)
#define spin_unlock_string \
"movb $1,%0" \
:"=3Dm" (lock->lock) : : "memory"
=20
=20
static inline void spin_unlock(spinlock_t *lock)
{
__asm__ __volatile__(
spin_unlock_string
);
}
#define __restore_flags(x) __asm__ __volatile__("pushl %0 ; popfl": /*=
no output */ :"g" (x):"memory", "cc")
#define local_irq_restore(x) __restore_flags(x)
#define spin_unlock_irqrestore(lock, flags) do { spin_unlock(lock); lo=
cal_irq_restore(flags); } while (0)
spinlock_t sjy22_lock;
typedef struct=20=20=09=09=09=09
{
BYTE Code;=09=09=09=09
BYTE Unused;
WORD Length;=09=09=09=09
BYTE *Data;=09=09=09=09
} DSP_CMD_INFO, *pDSP_CMD_INFO;
typedef struct=09=09=09=09=09
{
DSP_CMD_INFO info;
BYTE Buffer[1024*16];=09=09
} DSP_CMD, *PDSP_CMD;
#define DSP_CMD_SELECT_KEY 0x62
#define DSP_CMD_SELECT_KW_GET_KS 0x3B
#define DSP_CMD_SELECT_KW_SET_KS 0x3C
#define DSP_CMD_BCA 0x63
#define DSP_CMD_HASH 0x64
#define DSP_CMD_GET_HASH 0x65
#define DSP_CMD_BCA_HASH 0x66
#define DSP_CMD_BCA_HASH_EN 0x67
#define DSP_CMD_BCA_HASH_DE 0x68
#define DSP_CMD_ENCRYPT_BLOCK 0x95
#define DSP_CMD_ENCRYPT_HASH 0x96
#define DSP_CMD_HASH_BLOCK 0x97
#define DSP_CMD_IPSEC_ENCRYPT 0x98
#define DSP_CMD_IPSEC_DECRYPT 0x99
// 纡�#define DSP_CMD_GEN_RANDOM 0x80
DSP_CMD inPara,outPara;
void SendDspCmd(DWORD , DSP_CMD *,DSP_CMD *);
WORD dspReadRandom( BYTE *);
#define SPINLOCK_MAGIC_INIT=20=20=20
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
#define spin_lock_init(x) do { *(x) =3D SPIN_LOCK_UNLOCKED; } while(0)
int DMAOpen( int );
int self_lock=3D0; /*added for pci*/
int self_lock_myself=3D0;
#define MAJOR 199
#define MAXMSGLEN 128
#define Nmypci CARD_NUM
#define DMA_BUFFER_SIZE 4*1024
bus_space_tag_t card_clea[CARD_NUM];
bus_space_tag_t card_stat[CARD_NUM];
bus_space_tag_t card_use[CARD_NUM];/*added */
bus_space_tag_t card_base[CARD_NUM];
bus_space_tag_t card_addr[CARD_NUM];
bus_space_tag_t card_data[CARD_NUM];
bus_space_tag_t card_irq[CARD_NUM];
u_char *dma_buffer;
unsigned dma_addr;
int leftPort[CARD_NUM];
int rightPort[CARD_NUM];
//int * test =3D 3;=20
struct mypci_softc=20
{
bus_space_tag_t bst;
bus_space_handle_t bsh;
device_t sc_dev;=20
u_int32_t open_mask;
u_int32_t read_mask;
struct resource *res0,*res1;
struct resource *rl_irq;
void *rl_intrhand;
int rid;
bus_dma_tag_t rl_tag;
struct cdev *dev;
};
static inline unsigned long m_sleep(unsigned long time)=20
{
int mm_i1;
int mm_i2;
if( time !=3D 1)
{
self_lock_myself=3D1;
self_lock=3D0;
}
mm_i1 =3D 0;
mm_i2 =3D 0;
while(self_lock!=3D1)
{
__asm __volatile("sti" : : : "memory");
// __asm __volatile("sti");
{
int loop_i,counter=3D0;
for(loop_i=3D0;loop_i<10;loop_i++)
{counter++;}
}
__asm __volatile("cli" : : : "memory");
// cli();
mm_i1++;
if(mm_i1>50000000){
mm_i2 =3D 1;
break;
}
}//end while
return mm_i2;
}
void SendCmdToF206( PARAM_INFO *,int );
int RcvDataFromF206( PARAM_INFO *,int );
int F206Function(PARAM_INFO * ,int );
void SendCmdToF206( PARAM_INFO *MI,int card_no )
{
int i1;
// memcpy(dma_buffer+4, (char *)MI->inp, MI->inlen );
*((unsigned char *) dma_buffer + 0) =3D 0x73;
*((unsigned char *) dma_buffer + 1) =3D 0x6a;
*((unsigned char *) dma_buffer + 2) =3D 0x79;
*((unsigned char *) dma_buffer + 3) =3D 0x32;
*((unsigned char *) dma_buffer + 4) =3D 0x80;
*((unsigned char *) dma_buffer + 5) =3D 0x0;
*((unsigned char *) dma_buffer + 6) =3D 0x1;
*((unsigned char *) dma_buffer + 7) =3D 0x0;
*((unsigned char *) dma_buffer + 8) =3D 0x3c;
*((unsigned char *) dma_buffer + 9) =3D 0xb7;
*((unsigned char *) dma_buffer + 10) =3D 0xff;
*((unsigned char *) dma_buffer + 11) =3D 0xbf;
*((unsigned char *) dma_buffer + 12) =3D 0x8;
*((unsigned char *) dma_buffer + 13) =3D 0x0;
i1 =3D readl(card_clea[0]);
HOutD( 0x08c, MI->inlen+4);
//sent data
HOutD( 0x090, 0 );
i1 =3D HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
i1 =3D 0;
while(i1 =3D=3D 0)=20
{
=09
i1 =3D HInD(0xA8) & (1<<4);
}
writel (card_clea[0],0);
return;
}
int RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
int i1;
char *chp;
chp=3D(char *)MI->outp;
HOutD( 0x08c, MI->outlen+4);
HOutD( 0x090, (1<<3) );
i1 =3D HInD(0xA8);
HOutD( 0x0A8, i1 | (1<<0) );
HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
=20=20=20=20=20=20=20
/* init_timer(&timer_dma);//init timer struct
timer_dma.function =3D dma_timeout;
timer_dma.expires =3D jiffies+120*HZ;//120 seconds
add_timer(&timer_dma);*/
i1 =3D 0;
while(i1 =3D=3D 0)=20
{
// if (isdmatimeout =3D=3D0)//if timeout ,del timer and return
i1 =3D HInD(0xA8) & (1<<4);
/* else
{=20=20=20
del_timer(&timer_dma);
card_use[card_no] =3D CARD_READY;
isdmatimeout =3D 0;
chp[0]=3D0x29;
chp[1]=3D0;
chp[2]=3D0;
chp[3]=3D0;
return -1;
}*/
}
// del_timer(&timer_dma);
printf("Zhouyi Zhou After:\n");
for (int i =3D 0; i < 16 + 10; i++)
printf("%x ", *((unsigned char *) dma_buffer + 4 +i));
memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );
return 0;=09
}
/*---------------------------------------------------------------------*/
/* =A7g=ADa碛塄F206=BC=AF=AF=FB� =
/
/ 脍: 潆=AB=A1� /
/ 鲒: 0=3D=B7k�=D2=D7 =
/
/----------------------------------------------------------------------*/
int F206Function(PARAM_INFO *MI ,int card_no)
{
unsigned long RegValue;
unsigned long lock_flag;
int i;
char *chp;
chp=3D(char *)MI->outp;
spin_lock_irqsave(&sjy22_lock,lock_flag);
if( card_use[card_no] =3D=3D CARD_BUSY)
{
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
chp[0] =3D 0x2A;
chp[1] =3D 0;
chp[2] =3D 0;
chp[2] =3D 0;
return -EBUSY;
}
card_use[card_no] =3D CARD_BUSY;
spin_unlock_irqrestore(&sjy22_lock,lock_flag);
SendCmdToF206(MI, card_no);
// init_timer(&timer_card);//init timer struct
//timer_card.function =3D card_timeout;
//timer_card.expires =3D jiffies+120*HZ;//120 second:s
=20=20=20=20=20=20
//add_timer(&timer_card);
RegValue =3D 0x3;
while( RegValue !=3D 0)
{
// if (iscardtimeout =3D=3D0)
RegValue =3D readl ( card_clea[0] ) & 0x3;
/* else
{
del_timer(&timer_card);
iscardtimeout =3D 0;=20=20=20=20=20=20=20=20
card_use[card_no] =3D CARD_READY;
chp[0]=3D0x29;
chp[1]=3D0;
chp[2]=3D0;
chp[3]=3D0;
return -1;
}*/
}
=20=20=20=20=20=20=20
// del_timer(&timer_card);
=20=20=20=20=20=20
RegValue =3D 0x3;
while(RegValue !=3D 0)
{
RegValue =3D readl(card_clea[0]) & 0x3;
}
RegValue =3D readl( card_clea[0]);
/* It's neccessary! Two read(0x1000 0000) operation needed.*/
printf("RegValue =3D %x\n", RegValue);
=20=20=20=20=20=20=20
i=3DRcvDataFromF206( MI, card_no );
if (i =3D=3D -1)
{
card_use[0] =3D CARD_READY;
return -1;
}
if(card_no=3D=3D0) card_use[0]=3DCARD_READY;=09
return 0;
}
/* Function prototypes */
static d_open_t mypci_open;
static d_close_t mypci_close;
static d_read_t mypci_read;
static d_write_t mypci_write;
static d_ioctl_t mypci_ioctl;
static struct cdevsw mypci_cdevsw =3D {
.d_version=3D D_VERSION,
.d_open =3D mypci_open,
.d_close =3D mypci_close,
.d_ioctl =3D mypci_ioctl,
.d_read =3D mypci_read,
.d_write =3D mypci_write,
.d_name =3D "mypci",
};
//static dev_t sdev;
static devclass_t mypci_devclass;
static int
mypci_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
{
return 0;
}
static int
mypci_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
{
/* int i1;
int ioadd;
int card_no =3D 0;
ioadd =3D card_base[card_no] + 0x3a;=20=20=20=20=20=20=20=20=20=20=20=20=
=20
YhOutW( ioadd, 0x0);
ioadd =3D card_base[card_no] + 0x38;=20=20=20=20=20=20=20=20=20=20=20=20=
=20
YhOutW( ioadd, 0x0);
ioadd =3D card_base[card_no] + 0x10;=20=20=20=20=20=20=20=20=20=20=20=20=
=20
i1 =3D inw( ioadd );*/
return 0;
}
char teststr[128];
static int
mypci_read(struct cdev *dev, struct uio *uio, int ioflag)
{
printf("Read\n");
int resid =3D MAXMSGLEN;
int error =3D 0;
do {
if (uio->uio_resid < resid)
resid =3D uio->uio_resid;
error =3D uiomove(teststr, resid, uio);=09
} while (resid > 0 && error =3D=3D 0);
printf("mypci reads!\n");
printf("mypci read!\n");
return (error);
}
static int
mypci_write(struct cdev *dev, struct uio *uio, int ioflag)
{
printf("write\n");
int resid =3D MAXMSGLEN;
int error =3D 0;
do {
if (uio->uio_resid < resid)
resid =3D uio->uio_resid;
error =3D uiomove(teststr, resid, uio);=09
} while (resid > 0 && error =3D=3D 0);
printf("mypci writed!\n");
return (error);
}
static int
mypci_probe(device_t dev)
{
device_printf(dev, "MyPCI Probe\nVendor ID : 0x%x\nDevice ID : 0x%x\n",
pci_get_vendor(dev), pci_get_device(dev));
if (pci_get_vendor(dev) =3D=3D 0x10b5) {
printf("We've got the Cryptgraphic Card!\n");
return (0);
}
return (ENXIO);
}
static int
mypci_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct th=
read *td)
// mypci_ioctl(struct inode *inode,struct file *file,unsigned int cmd,=
unsigned long arg )
{
int card_no =3D 0;
int ioadd;
unsigned long ii1;
//PARAM_INFO MMI;
cmd -=3D 0x20000000;
BYTE outStr[16];
switch( cmd )
{
case 2: /*Ioctl_F206_Reset:*/
ioadd =3D card_base[0] + 0x6c;=20=20=20=20=20=20=20=20=20=20=20=20=20
ii1 =3D inl( ioadd );
ii1 |=3D ( 1 << 30 );
outl( ii1, ioadd );
ii1 &=3D ~( 1 << 30 );
outl( ii1, ioadd );
HOutD(0x00, 0xfffe0000 );
HOutD(0xf0, 0xfffe0000 );
DMAOpen( card_no );
printf("mypci ioctl got called, F206 reset!\n");
break;
case 3: //Ioctl_F206_Function:
// copy_from_user((char *)&MMI,(char *)arg,sizeof(MMI) );
// F206Function( &MMI,card_no);
break;
case 4:
dspReadRandom(outStr);
=20=20=20=20=20=20=20=20
break;
default:
break;=09=09=09=09=09
}
return 0;
}
static void sjy_interrupt(void * args)
{
int i1, ioadd;
int card_no =3D 0;
unsigned long reg;
i1 =3D 0;
ioadd =3D card_base[0] + 0x68;=20=20=20=20=20=20=20=20=20=20=20=20=20
// *test =3D 5;
reg =3D inl( ioadd );
=20=20=20=20=20=20=20
if((reg & (1<<8)) =3D=3D 0)
{
=09
reg =3D inl( ioadd );
if((reg & (1<<8)) =3D=3D 0){
return;
}
}=20
printf("my pci0 interrupt got called!\n");
if(reg & 0x00e0e000)
{
=09=09
outl((reg & ~(1<<8)), card_base[0] + 0x68);
reg =3D inl( card_base[card_no] + 0x68);
if(reg & (1 << 15))
{
HOutD(0xA8,0x8);
if(self_lock_myself=3D=3D1)
{
self_lock=3D1;
self_lock_myself=3D0;
}
=09=09
}
if(reg & (1 << 21)) {
HOutD(0x068, 0x0B00);
if(self_lock_myself=3D=3D1)
{
self_lock=3D1;
self_lock_myself=3D0;
}
readl(card_clea[0]);
}
return;
}
reg =3D inl( card_base[0] + 0x30);
if( reg & ( 1<<3) )
{
outl((reg & ~(1<<8)), card_base[0] + 0x68);
}
}
int DMAOpen( int card_no )
{
unsigned long RegValue;
=20=20=20=20=20=20=20=20
HOutD(0x004, 0x20000001 );
HOutD(0x0f4, 0x10000001 );
=09
RegValue =3D HInD(0x008);
RegValue &=3D ~(1 << 20);
RegValue |=3D (1 << 19);
HOutD(0x008, RegValue );
RegValue =3D HInD(0x0B0);
=09
HOutD(0x0B0, (RegValue & 0xffff0000));
HOutD(0x080, 0x0001c3 );
RegValue =3D HInD(0x068);
RegValue &=3D ~(1 << 18);
RegValue &=3D ~(1 << 8);
HOutD(0x068, RegValue );
//dma_buffer2 =3D virt_to_phys(dma_buffer);
RegValue =3D pmap_kextract((unsigned long)dma_buffer);=20
HOutD(0x084, RegValue );
RegValue =3D 0x20000000;
HOutD( 0x088, RegValue );
HOutD( 0x08c, 16 );
//sent data
HOutD( 0x090, (1<<3) );
HOutD( 0x0B4, 0 );
HOutD( 0x0A8, (1<<0) );
return 0;
}
struct mypci_softc *sc;
int rid;
static int
mypci_attach(device_t dev)
{
unsigned long k;
int error =3D 0;
printf("Mypci device loading...");
rid=3D0x14;
struct resource *res;
unsigned map_addr;=09=09
u_long mmio_flags, mmio_len;=09
u_int32_t cmd;=20=20=20=20=20=20=20
sc =3D (struct mypci_softc *) device_get_softc(dev);
bzero(sc, sizeof (*sc));
sc->sc_dev =3D dev;=09
pci_enable_busmaster(dev);
// pci_set_powerstate(dev, 0);
cmd =3D pci_read_config(dev,PCIR_COMMAND,4);
cmd |=3D PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN|PCIM_CMD_PORTEN;
// pci_write_config(dev,PCIR_COMMAND,cmd,4);=20=20=20=20=20=20=
=20=20
sc->rid =3D rid;
res =3D bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
card_base[0]=3D rman_get_bushandle(res);
sc->res0 =3D res;
=20=20=20=20=20=20=20=20=20=20
rid =3D 28;
res =3D bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid,RF_ACTIVE=
);
sc->res1 =3D res;
mmio_flags =3D rman_get_flags(res);
map_addr =3D rman_get_bushandle(res);
mmio_len =3D bus_get_resource_count(dev, SYS_RES_MEMORY, rid);=20=
=20=20=20=20
card_clea[0] =3D (unsigned )map_addr;
//dma_buffer =3D contigmalloc(4096, M_DEVBUF, 1, 0, 0xffffffff, 4096, 0);
dma_buffer =3D malloc(4096, M_DEVBUF,M_NOWAIT|M_ZERO);
card_stat[0]=3DCARD_READY;=09
card_use[0]=3DCARD_READY;=09
card_stat[1]=3DCARD_BUSY;
card_use[1]=3DCARD_BUSY;=09
k =3D inl( card_base[0]+0x04 );
k =3D inl (card_base[0]+0x0f4);
outl(0xfffe0000, card_base[0] + 0x00);
outl(0xfffe0000, card_base[0] + 0x04);
outl( 0x20000000, card_base[0]+0x04 );
outl( 0x10000000, (card_base[0]+0x0f4) );
k =3D inl(card_base[0] + 0x0c);=20=20=20=20=20=20=20=20=20=20=20=20=
=20
k &=3D 0xffffff00;
outl(k, card_base[0] + 0x0c);=20=20=20
self_lock=3D0;
self_lock_myself=3D0;
DMAOpen( 0 );
=09
spin_lock_init(&sjy22_lock);=09
sc->dev =3D make_dev(&mypci_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "=
mypci0");
=09
=20=20=20=20=20=20=20
/////////////////////////////////////////////////////=20=20=20=20=20=20=20=
=20=20=20
printf("Attach successfully!\n");
return (0);
}
static int
mypci_detach(device_t dev)
{
bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->res1);
bus_release_resource(dev, SYS_RES_IOPORT, 0x14, sc->res0);
destroy_dev(sc->dev);
free(dma_buffer, M_DEVBUF);
free(sc, M_DEVBUF);
return (0);
}
static int
mypci_shutdown(device_t dev)
{
return 0;
}
static int
mypci_suspend(device_t dev)
{
printf("Mypci suspend!\n");
return (0);
}
static int
mypci_resume(device_t dev)
{
printf("Mypci resume!\n");
return (0);
}
static device_method_t mypci_methods[] =3D {
DEVMETHOD(device_probe, mypci_probe),
DEVMETHOD(device_attach, mypci_attach),
DEVMETHOD(device_detach, mypci_detach),
DEVMETHOD(device_shutdown, mypci_shutdown),
DEVMETHOD(device_suspend, mypci_suspend),
DEVMETHOD(device_resume, mypci_resume),
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(bus_driver_added, bus_generic_driver_added),
{ 0, 0 }
};
static driver_t mypci_driver =3D {
"mypci",
mypci_methods,
//0,
sizeof(struct mypci_softc),=20
};
void SendDspCmd(DWORD CardID, DSP_CMD *pInPara,DSP_CMD *pOutPara)
{
PARAM_INFO param;
pInPara->info.Length /=3D 2;
pInPara->info.Data =3D pInPara->Buffer;
pOutPara->info.Length /=3D2;
pOutPara->info.Data =3D pOutPara->Buffer;
=09
param.inp =3D (char *)pInPara;
param.inlen =3D sizeof(DSP_CMD_INFO) + pInPara->info.Length*2;
param.outp =3D (char *)pOutPara;
param.outlen =3D sizeof(DSP_CMD_INFO) + pOutPara->info.Length*2;
F206Function(¶m,CardID);
}
WORD dspReadRandom( BYTE *outStr)
{
// DWORD CardID =3D 0;
WORD len =3D 8;
int i;
inPara.info.Code =3D DSP_CMD_GEN_RANDOM;
inPara.info.Length =3D 2;
outPara.info.Length =3D 16;
memcpy(inPara.Buffer,&len,2);
SendDspCmd(0, &inPara,&outPara);
printf("\n");
for (i =3D 0; i < 16; i++)
printf("%x ",*((char *)outPara.Buffer + i));
printf("\n");
// memcpy(outStr,outPara.Buffer,16);
return outPara.info.Code;
}
DRIVER_MODULE(mypci, pci, mypci_driver, mypci_devclass, 0, 0);
--=20
___________________________________________________
Play 100s of games for FREE! http://games.mail.com/
More information about the freebsd-drivers
mailing list