Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 25 Oct 2005 22:19:19 -0500
From:      "Yong Ma" <mayong@mail.com>
To:        freebsd-drivers@freebsd.org
Subject:   Cryptography Driver (Help !!!!)
Message-ID:  <20051026031920.11BC983C03@ws1-1.us4.outblaze.com>

index | next in thread | raw e-mail

Dear colleagues, 
Cry for help!!!!
The cryptography card driver (polling mode, not interrupt mode) works well 
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 
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 = NULL;
dma_addr_t dma_addr;


/*  time out vars and function */// lilin adding
volatile unsigned long  isdmatimeout=0;
volatile unsigned long  iscardtimeout=0;
struct timer_list  timer_dma,timer_card;
void dma_timeout(unsigned long ptr);
void card_timeout(unsigned long ptr);
/*                  */
		
#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=0,dataPort,addrPort;
static	int jmkmajor;

//lilin adding 
#define DMA_BUFFER_SIZE	4*1024
	
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 );

//================================
/******* 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 = 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 = HInD(0xA8);
	HOutD( 0x0A8, i1 | (1<<0) );
	HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
	i1 = 0;
	while(i1 == 0) 
	{
	
		i1 = HInD(0xA8) & (1<<4);
	}

	writel ( 0, card_clea[0]);
	return;
}



int	RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
	int i1;
	char *chp;
	chp=(char *)MI->outp;

	HOutD( 0x08c, MI->outlen+4);

	HOutD( 0x090, (1<<3) );

	i1 = HInD(0xA8);
	HOutD( 0x0A8, i1 | (1<<0) );
	HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
       
/*	init_timer(&timer_dma);//init timer struct
	timer_dma.function = dma_timeout;
	timer_dma.expires = jiffies+120*HZ;//120 seconds
	add_timer(&timer_dma); */
	i1 = 0;
	while(i1 == 0) 
	{
		if (isdmatimeout ==0)//if timeout ,del timer and return
		i1 = HInD(0xA8) & (1<<4);
/*		else
		{   
			del_timer(&timer_dma);
			card_use[card_no] = CARD_READY;
			isdmatimeout = 0;
			chp[0]=0x29;
			chp[1]=0;
			chp[2]=0;
			chp[3]=0;
			return -1;
		}*/

	}
 //   del_timer(&timer_dma);
    /*    for (i1 = 0; i1 < 16; i1++)
           printk("%x ", *((unsigned char *)dma_buffer + 4 +i1));*/
	memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );

	return 0;	

}


int	F206Function(PARAM_INFO *MI ,int card_no)
{
	unsigned long RegValue;
	unsigned long lock_flag;
	int i;
	char *chp;
	chp=(char *)MI->outp;


	spin_lock_irqsave(&sjy22_lock,lock_flag);
	if( card_use[card_no] == CARD_BUSY)
	{
		spin_unlock_irqrestore(&sjy22_lock,lock_flag);
		chp[0] = 0x2A;
		chp[1] = 0;
		chp[2] = 0;
		chp[2] = 0;
		return -EBUSY;
	}
	card_use[card_no] = CARD_BUSY;
	spin_unlock_irqrestore(&sjy22_lock,lock_flag);

	SendCmdToF206(MI, card_no);
//	init_timer(&timer_card);//init timer struct
//	timer_card.function = card_timeout;
//	timer_card.expires = jiffies+120*HZ;//120 second:s
      
//	add_timer(&timer_card);


	RegValue = 0x3;
	while( RegValue != 0)
	{
		if (iscardtimeout ==0)
		RegValue = readl ( card_clea[0] ) & 0x3;
/*		else
		{
			del_timer(&timer_card);
            iscardtimeout = 0;        
            card_use[card_no] = CARD_READY;
			chp[0]=0x29;
			chp[1]=0;
			chp[2]=0;
			chp[3]=0;
			return -1;
		}*/
	}
        printk("request RegValue = %x\n", RegValue); 
//	del_timer(&timer_card);
      
	RegValue = 0x3;
	while(RegValue != 0)
	{
		RegValue = readl(card_clea[0]) & 0x3;
	}

	RegValue = readl( card_clea[0]);
		/* It's neccessary! Two read(0x1000 0000) operation needed.*/

        printk("RegValue = %x\n", RegValue); 
	i=RcvDataFromF206( MI, card_no );
	if (i == -1)
	{
		card_use[0] = CARD_READY;
		return -1;
	}

	if(card_no==0)	card_use[0]=CARD_READY;	
	return 0;

}


int	ioctl_jmk(struct inode * inode, struct file * file,
              unsigned int cmd, unsigned long arg)

{
	int card_no = 0;
	int ioadd;
	unsigned long ii1;
	PARAM_INFO  MMI;

	switch( cmd )
	{
		case	Ioctl_F206_Reset:
			ioadd = card_base[card_no] + 0x6c;             
			ii1 = inl( ioadd );
			ii1 |= ( 1 << 30 );
			outl( ii1, ioadd );
			ii1 &= ~( 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) );
			
			F206Function( &MMI,card_no);
			
			copy_to_user((PARAM_INFO *)arg,&MMI,sizeof(MMI) );
			return 0;
			

		default:
			break;					
	}
	return 0;
}


struct file_operations jmk_fops = {
       ioctl:		ioctl_jmk,      
        open:		open_jmk,	
     release:	    close_jmk,	
};


int init_sjy22b(void)
{
	unsigned long k;
	int card_no;
	card_no = 0;
	if (pci_present()) {
		
		    u32 pio_start, pio_end, pio_flags, pio_len;	
		    unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
		    void *map_addr;	
			
          pdev = pci_find_device (0x10b5, 0x5406,pdev);
			if (!pdev) return 1;

            pci_write_config_word(pdev, PCI_COMMAND, 7);
            pio_start = pci_resource_start (pdev, 1);
            pio_end = pci_resource_end (pdev, 1);
            pio_flags = pci_resource_flags (pdev, 1);
            pio_len = pci_resource_len (pdev, 1);

			mmio_start = pci_resource_start (pdev, 3);
			mmio_end = pci_resource_end (pdev, 3);
			mmio_flags = pci_resource_flags (pdev, 3);
			mmio_len = pci_resource_len (pdev, 3);

			if(pci_request_regions (pdev, "sjy22bdrv")){
				printk("<1>%s: region resource error, aborting\n",pdev->slot_name);
				return 1;
			}	

                        /* enable PCI bus-mastering */
          //  pci_set_master (pdev);

            card_base[0] =  pio_start ;
            k = inl( card_base[0]+0x04 );
	        printk("Base_address[04] = %lxH\n",k);
	        k = inl( card_base[0]+0x0f4 );
	        printk("Base_address[f4] = %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 = ioremap (mmio_start, mmio_len);
            if (map_addr == NULL) {
							     printk("%s: cannot remao mmiom,aborting\n",pdev->slot_name);
                                return 1;
                        }
                        
		   (void *)card_clea[0] = map_addr;
                        
		   // dma_buffer = pci_alloc_consistent(pdev,DMA_BUFFER_SIZE,&dma_addr);
		   dma_buffer = kmalloc(4096,GFP_KERNEL);
                   dma_addr = dma_buffer - 0xc0000000; 
                   if(dma_buffer == NULL) {
			printk("allock dma buffer error\n");		
	                return 1;	
			}	
	        card_stat[0]=CARD_READY;	
	        card_use[0]=CARD_READY;	
	        card_stat[1]=CARD_BUSY;
	        card_use[1]=CARD_BUSY;	
	
	        k = inl(card_base[0] + 0x0c);             
	        k &= 0xffffff00;
		outl(k, card_base[0] + 0x0c);             

	         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=register_chrdev(0,"jmk",&jmk_fops);
	        printk("PCI Major=%d.\n",jmkmajor);
            	printk("SJY22 is Ok\n");
	         return 0;		
	}	
	printk("No SJY22 device!");	
	return 1;
}

int	init_jmk(void)
{
	int temp;
	temp = init_sjy22b();
	return temp;
}
/*-------------------------------------------------------------*/

#ifdef MODULE
int init_module(void)
{
	int temp;
	temp = 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;
        

	HOutD(0x004, 0x20000001 );
	HOutD(0x0f4, 0x10000001 );
	
	RegValue = HInD(0x008);
	RegValue &= ~(1 << 20);
	RegValue |= (1 << 19);
	HOutD(0x008, RegValue );

	RegValue = HInD(0x0B0);
	
	HOutD(0x0B0, (RegValue & 0xffff0000));

	HOutD(0x080, 0x0001c3 );

	RegValue = HInD(0x068);
	RegValue &= ~(1 << 18);
	RegValue &= ~(1 << 8);
	HOutD(0x068, RegValue );


    //dma_buffer2 = virt_to_phys(dma_buffer);
    RegValue = dma_addr; 

	HOutD(0x084, RegValue );
	RegValue = 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=1;
}
void card_timeout(unsigned long ptr)
{
	iscardtimeout=1;
}

/////////////////////////////////////////////////////////////////////
Device Driver under FreeBSD-5.4
/////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
/*
 Ma Yong, Zhouyi Zhou
Infrastructure Software Center 
Institute of Software
Chinese Academy of Sciences
 */

//#define MIN(a,b) (((a) < (b)) ? (a) : (b))

#include <sys/param.h>  
#include <sys/module.h>
#include <sys/systm.h>
#include <sys/errno.h>
#include <sys/kernel.h> 
#include <sys/conf.h>   
#include <sys/uio.h>    
#include <sys/malloc.h>
#include <sys/bus.h>  

#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":"=g" (x): /* no input */)
#define restore_flags(x)      __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc")
#define local_irq_save(x)       __asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x): /* no input */ :"memory")
#define LOCK_SECTION_NAME                       \
         ".text.lock.sjy22bdrv" 
#define LOCK_SECTION_START(extra)               \
         ".subsection 1\n\t"                     \
         extra                                   \
         ".ifndef " LOCK_SECTION_NAME "\n\t"     \
         LOCK_SECTION_NAME ":\n\t"               \
         ".endif\n\t"
 
#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
                 :"=m" (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" \
                 :"=m" (lock->lock) : : "memory"
 
 
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);  local_irq_restore(flags); } while (0)
spinlock_t 	sjy22_lock;

typedef  struct  				
{
	BYTE    Code;				
	BYTE	Unused;
	WORD  	Length;				
	BYTE  	*Data;				
}	DSP_CMD_INFO, *pDSP_CMD_INFO;

typedef  struct					
{
	DSP_CMD_INFO info;
   	BYTE  	Buffer[1024*16];		
}	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

//	&#32417;&#58392;&#65533;#define DSP_CMD_GEN_RANDOM		0x80

DSP_CMD inPara,outPara;

void SendDspCmd(DWORD , DSP_CMD *,DSP_CMD *);
WORD dspReadRandom( BYTE *);
#define SPINLOCK_MAGIC_INIT   
#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 SPINLOCK_MAGIC_INIT }
#define spin_lock_init(x)       do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)

int	DMAOpen( int  );
int self_lock=0;	/*added for pci*/
int self_lock_myself=0;
#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 = 3; 
struct mypci_softc 
{
	bus_space_tag_t	bst;
	bus_space_handle_t bsh;
	device_t                sc_dev; 
	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) 
{
	int mm_i1;
	int mm_i2;
	if( time != 1)
	{
	self_lock_myself=1;
	self_lock=0;
	}

	mm_i1 = 0;
	mm_i2 = 0;
	while(self_lock!=1)
	{
           __asm __volatile("sti" : : : "memory");
	  //		__asm __volatile("sti");
		{
			int loop_i,counter=0;
			for(loop_i=0;loop_i<10;loop_i++)
			{counter++;}
		}
               __asm __volatile("cli" : : : "memory");
	       //	cli();
		mm_i1++;
		if(mm_i1>50000000){
			mm_i2 = 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) = 0x73;
	*((unsigned  char *) dma_buffer + 1) = 0x6a;
	*((unsigned  char *) dma_buffer + 2) = 0x79;
       	*((unsigned  char *) dma_buffer + 3) = 0x32;
	*((unsigned  char *) dma_buffer + 4) = 0x80;
        *((unsigned  char *) dma_buffer + 5) = 0x0;
        *((unsigned  char *) dma_buffer + 6) = 0x1;
        *((unsigned  char *) dma_buffer + 7) = 0x0;
        *((unsigned  char *) dma_buffer + 8) = 0x3c;
        *((unsigned  char *) dma_buffer + 9) = 0xb7;
        *((unsigned  char *) dma_buffer + 10) = 0xff;
        *((unsigned  char *) dma_buffer + 11) = 0xbf;
        *((unsigned  char *) dma_buffer + 12) = 0x8;
        *((unsigned  char *) dma_buffer + 13) = 0x0;


	i1 = readl(card_clea[0]);
	HOutD( 0x08c, MI->inlen+4);

	//sent data
	HOutD( 0x090, 0 );

	i1 = HInD(0xA8);
	HOutD( 0x0A8, i1 | (1<<0) );
	HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
	i1 = 0;
	while(i1 == 0) 
	{
	
		i1 = HInD(0xA8) & (1<<4);
	}

	writel (card_clea[0],0);
	return;
}



int	RcvDataFromF206( PARAM_INFO *MI,int card_no)
{
	int i1;
	char *chp;
	chp=(char *)MI->outp;

	HOutD( 0x08c, MI->outlen+4);

	HOutD( 0x090, (1<<3) );

	i1 = HInD(0xA8);
	HOutD( 0x0A8, i1 | (1<<0) );
	HOutD( 0x0A8, i1 | ((1<<0)|(1<<1)) );
       
	/*	init_timer(&timer_dma);//init timer struct
	timer_dma.function = dma_timeout;
	timer_dma.expires = jiffies+120*HZ;//120 seconds
	add_timer(&timer_dma);*/
	i1 = 0;
	while(i1 == 0) 
	{
	  //		if (isdmatimeout ==0)//if timeout ,del timer and return
		i1 = HInD(0xA8) & (1<<4);
		/*	else
		{   
			del_timer(&timer_dma);
			card_use[card_no] = CARD_READY;
			isdmatimeout = 0;
			chp[0]=0x29;
			chp[1]=0;
			chp[2]=0;
			chp[3]=0;
			return -1;
			}*/

	}
	//    del_timer(&timer_dma);
        printf("Zhouyi Zhou After:\n");
        for (int i = 0; i < 16 + 10; i++)
          printf("%x ", *((unsigned char *) dma_buffer + 4 +i));
	memcpy((char *)MI->outp, dma_buffer+4 ,MI->outlen );

	return 0;	

}

/*---------------------------------------------------------------------*/
/*              §g­a&#30875;&#22596;F206¼¯¯û&#65533;                         /
/       &#33037;:   &#28486;«¡&#57931;&#65533;				        /
/       &#40082;:   0=·k&#57599;&#65533;Ò×&#58170;		                        /
/----------------------------------------------------------------------*/
int	F206Function(PARAM_INFO *MI ,int card_no)
{
	unsigned long RegValue;
	unsigned long lock_flag;
	int i;
	char *chp;
	chp=(char *)MI->outp;


	spin_lock_irqsave(&sjy22_lock,lock_flag);
	if( card_use[card_no] == CARD_BUSY)
	{
		spin_unlock_irqrestore(&sjy22_lock,lock_flag);
		chp[0] = 0x2A;
		chp[1] = 0;
		chp[2] = 0;
		chp[2] = 0;
		return -EBUSY;
	}
	card_use[card_no] = CARD_BUSY;
	spin_unlock_irqrestore(&sjy22_lock,lock_flag);

	SendCmdToF206(MI, card_no);
	//	init_timer(&timer_card);//init timer struct
	//timer_card.function = card_timeout;
	//timer_card.expires = jiffies+120*HZ;//120 second:s
      
	//add_timer(&timer_card);


	RegValue = 0x3;
	while( RegValue != 0)
	{
	  //	if (iscardtimeout ==0)
		RegValue = readl ( card_clea[0] ) & 0x3;
		/*		else
		{
			del_timer(&timer_card);
            iscardtimeout = 0;        
            card_use[card_no] = CARD_READY;
			chp[0]=0x29;
			chp[1]=0;
			chp[2]=0;
			chp[3]=0;
			return -1;
			}*/
	}
       
	//	del_timer(&timer_card);
      
	RegValue = 0x3;
	while(RegValue != 0)
	{
		RegValue = readl(card_clea[0]) & 0x3;
	}

	RegValue = readl( card_clea[0]);
		/* It's neccessary! Two read(0x1000 0000) operation needed.*/
        printf("RegValue = %x\n", RegValue);
       
	i=RcvDataFromF206( MI, card_no );
	if (i == -1)
	{
		card_use[0] = CARD_READY;
		return -1;
	}

	if(card_no==0)	card_use[0]=CARD_READY;	
	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 = {
    .d_version=  D_VERSION,
    .d_open =   mypci_open,
    .d_close =  mypci_close,
    .d_ioctl =  mypci_ioctl,
    .d_read =   mypci_read,
    .d_write =  mypci_write,
    .d_name =   "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 = 0;
		ioadd = card_base[card_no] + 0x3a;             
		YhOutW( ioadd, 0x0);
		ioadd = card_base[card_no] + 0x38;             
		YhOutW( ioadd, 0x0);
		ioadd = card_base[card_no] + 0x10;             
		i1 = inw( ioadd );*/
    return 0;
}

char teststr[128];
static int
mypci_read(struct cdev *dev, struct uio *uio, int ioflag)
{
  	printf("Read\n");
	int resid = MAXMSGLEN;
	int error = 0;
	do {
		if (uio->uio_resid < resid)
			resid = uio->uio_resid;
		error = uiomove(teststr, resid, uio);	
	} while (resid > 0 && error == 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 = MAXMSGLEN;
	int error = 0;
	do {
		if (uio->uio_resid < resid)
			resid = uio->uio_resid;
		error = uiomove(teststr, resid, uio);	
	} while (resid > 0 && error == 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) == 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 thread *td)
     //	mypci_ioctl(struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg )

{
	int card_no = 0;
	int ioadd;
	unsigned long ii1;
	//PARAM_INFO  MMI;
        cmd -= 0x20000000;
        BYTE outStr[16];
	switch( cmd )
	{
	case	2: /*Ioctl_F206_Reset:*/
			ioadd = card_base[0] + 0x6c;             
			ii1 = inl( ioadd );
			ii1 |= ( 1 << 30 );
			outl( ii1, ioadd );
			ii1 &= ~( 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);
        
          break;
	default:
			break;					
	}
	return 0;
}





static void sjy_interrupt(void * args)
{
	int i1, ioadd;
	int card_no = 0;
	unsigned long reg;

	i1 = 0;
	ioadd = card_base[0] + 0x68;             
	//        *test = 5;
	reg = inl( ioadd );
       
	if((reg & (1<<8)) == 0)
	{
	
		reg = inl( ioadd );
		if((reg & (1<<8)) == 0){
			return;
		}
	} 
        printf("my pci0 interrupt got called!\n");
	if(reg & 0x00e0e000)
	{
		
		outl((reg & ~(1<<8)), card_base[0] + 0x68);
		reg = inl( card_base[card_no] + 0x68);
		if(reg & (1 << 15))
		{
			HOutD(0xA8,0x8);
			if(self_lock_myself==1)

			{
				self_lock=1;
				self_lock_myself=0;
			}
		
		}
		if(reg & (1 << 21)) {
				HOutD(0x068, 0x0B00);
				if(self_lock_myself==1)
				{
					self_lock=1;
					self_lock_myself=0;
				}
				readl(card_clea[0]);
		}
		return;
	}
	reg = 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;
        

	HOutD(0x004, 0x20000001 );
	HOutD(0x0f4, 0x10000001 );
	
	RegValue = HInD(0x008);
	RegValue &= ~(1 << 20);
	RegValue |= (1 << 19);
	HOutD(0x008, RegValue );

	RegValue = HInD(0x0B0);
	
	HOutD(0x0B0, (RegValue & 0xffff0000));

	HOutD(0x080, 0x0001c3 );

	RegValue = HInD(0x068);
	RegValue &= ~(1 << 18);
	RegValue &= ~(1 << 8);
	HOutD(0x068, RegValue );


    //dma_buffer2 = virt_to_phys(dma_buffer);
	RegValue =  pmap_kextract((unsigned long)dma_buffer); 
        HOutD(0x084, RegValue );
	RegValue = 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 = 0;
        printf("Mypci device loading...");
        rid=0x14;
        struct resource *res;

       	unsigned map_addr;		
        u_long   mmio_flags, mmio_len;	
        u_int32_t cmd;       
	sc = (struct mypci_softc *) device_get_softc(dev);
        bzero(sc, sizeof (*sc));
        sc->sc_dev = dev;	


	  pci_enable_busmaster(dev);
        //  pci_set_powerstate(dev, 0);
          cmd = pci_read_config(dev,PCIR_COMMAND,4);
          cmd |= PCIM_CMD_MEMEN|PCIM_CMD_BUSMASTEREN|PCIM_CMD_PORTEN;
	  //          pci_write_config(dev,PCIR_COMMAND,cmd,4);        
	  sc->rid = rid;

	  res = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &rid, RF_ACTIVE);
       	  card_base[0]=  rman_get_bushandle(res);
          sc->res0 = res;
          
          rid = 28;
          res = bus_alloc_resource_any(dev,SYS_RES_MEMORY, &rid,RF_ACTIVE);
          sc->res1 = res;
          mmio_flags = rman_get_flags(res);
          map_addr = rman_get_bushandle(res);
          mmio_len = bus_get_resource_count(dev, SYS_RES_MEMORY, rid);     
          card_clea[0] = (unsigned )map_addr;
	  //dma_buffer = contigmalloc(4096, M_DEVBUF, 1, 0, 0xffffffff, 4096, 0);
	  dma_buffer = malloc(4096, M_DEVBUF,M_NOWAIT|M_ZERO);

	card_stat[0]=CARD_READY;	
        card_use[0]=CARD_READY;	
	card_stat[1]=CARD_BUSY;
	card_use[1]=CARD_BUSY;	
	k = inl( card_base[0]+0x04 );
	k = 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 = inl(card_base[0] + 0x0c);             
	k &= 0xffffff00;
	outl(k, card_base[0] + 0x0c);   
        self_lock=0;
        self_lock_myself=0;
        DMAOpen( 0 );

	
	spin_lock_init(&sjy22_lock);	
        sc->dev = make_dev(&mypci_cdevsw, 0, UID_ROOT, GID_WHEEL, 0644, "mypci0");
	
       

	/////////////////////////////////////////////////////          
	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[] = {
    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 = {
     "mypci",
     mypci_methods,
     //0,
     sizeof(struct mypci_softc), 
};

void SendDspCmd(DWORD CardID, DSP_CMD *pInPara,DSP_CMD *pOutPara)
{
	PARAM_INFO param;

	pInPara->info.Length /= 2;
	pInPara->info.Data = pInPara->Buffer;
	pOutPara->info.Length /=2;
	pOutPara->info.Data = pOutPara->Buffer;
	
	param.inp = (char *)pInPara;
	param.inlen = sizeof(DSP_CMD_INFO) + pInPara->info.Length*2;
	param.outp = (char *)pOutPara;
	param.outlen = sizeof(DSP_CMD_INFO) + pOutPara->info.Length*2;

	F206Function(&param,CardID);
}


WORD dspReadRandom( BYTE *outStr)
{
  //	DWORD CardID = 0;
	WORD len = 8;
        int i;
	inPara.info.Code = DSP_CMD_GEN_RANDOM;
	inPara.info.Length = 2;
	outPara.info.Length = 16;
	memcpy(inPara.Buffer,&len,2);

	SendDspCmd(0, &inPara,&outPara);


        printf("\n");
        for (i = 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);



-- 
___________________________________________________
Play 100s of games for FREE! http://games.mail.com/



home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051026031920.11BC983C03>