⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 1553_junk_bm-5_bu69080s1.c

📁 BU-65550M2-605 PCMCIA card (1553) 的驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	
	DEBUG(1, "%s: bu69080s1_fops_open(): Number of Channels: %02x\n",
				MODULE_NAME,m_aCards[bCardNum].bNumChnls);
	
    /*jmf Add initialise for wait_queue */
    init_waitqueue_head(&m_apWaitQue[bSystemNum]);

    /* Increment module usage count. */
	MOD_INC_USE_COUNT;
	
	/* Reset BC Auto Flip Stack */
	m_aCards[bCardNum].Channel[bChanNum].bAutoFlipStk = 0;

	/* define device as open */
	m_aCards[bCardNum].Channel[bChanNum].bOpen = 1;
	return STATUS_ACE53_SUCCESS;
}





/*******************************************************************
 * Function: bu69080s1_fops_release                                *
 *                                                                 *
 * Description: Handles closing of a single channel (device)       *
 *                                                                 *
 * Parameters:   inode - used to get the Minor Number		           *
 *               flip  - Not Used				                           *
 *******************************************************************/
int bu69080s1_fops_release(struct inode *inode, struct file *filp)
{
	/* Obtain index into enumerated card list from inode. */
	__u8	bSystemNum = MINOR(inode->i_rdev);    /* Enumerated device */
	__u8	bCardNum   = (__u8)bSystemNum / 2;   /* Card number in system (0 - 3) */
	__u8	bChanNum   = bSystemNum % 2;	   /* Channel number on card (0, 1) */
	

	DEBUG(1, "%s: bu69080s1_fops_release(): Sys#:%02d/Card#:%02d/Chan#:%02d\n",
	      MODULE_NAME, bSystemNum,bCardNum,bChanNum);

	
	/* Check that minor number corresponds to a card installed in the system. */
	if ( bSystemNum >= m_bNumberOfCards )
	{
	    printk("%s: bu69080s1_fops_release(): STATUS_ACE53_DEVICE_NOT_EXIST\n", MODULE_NAME);
	    return STATUS_ACE53_DEVICE_NOT_EXIST;
	}

	/* Return error if an attempt was made to close an unopened card. */
	if (m_aCards[bCardNum].Channel[bChanNum].bOpen == 0)
	{
	    printk("%s: bu69080s1_fops_release(): STATUS_ACE53_CARD_NOT_OPEN\n", MODULE_NAME);
	    return STATUS_ACE53_CARD_NOT_OPEN;
	}
	/* Unmap the channels REGISTER memory from user space (if not already done) */
	if( m_aCards[bCardNum].Channel[bChanNum].dwRegWndUsrAddr)
	{
		m_aCards[bCardNum].Channel[bChanNum].dwRegWndUsrAddr = (__u32)NULL;
	}

	/* Unmap the channels ACEMEM memory from user space (if not already done) */
	if( m_aCards[bCardNum].Channel[bChanNum].dwMemWndUsrAddr)
	{
		m_aCards[bCardNum].Channel[bChanNum].dwMemWndUsrAddr = (__u32)NULL;
	}

	/* Define device as closed */
	m_aCards[bCardNum].Channel[bChanNum].bOpen = 0;
	
	/* If both channels are closed, unmap REGISTER memory from kernel space */
	if ((!m_aCards[bCardNum].Channel[0].bOpen) && (!m_aCards[bCardNum].Channel[1].bOpen))
	{

		/* Unmap the channel REGISTER memory from kernel space (if not already done) */
		if( m_aCards[bCardNum].dwRegWndKrnAddr )
		{
			iounmap( (void*)m_aCards[bCardNum].dwRegWndKrnAddr );
			m_aCards[bCardNum].dwRegWndKrnAddr = (__u32)NULL;
		}
	}

	/* Clear mmap window count. */
	m_aCards[bCardNum].Channel[bChanNum].bMmapWinNum = 0;
	
#if 0
	/* Flag interrupts as disabled. */
	m_aCards[bCardNum].Channel[bChanNum].bIsrEnabled = 0;
#else

//------- begin of insert (A.Lebedev) -----------------------------------------
{
  __u32  dwFlags    = 0x00000000;             // temp variables for save_flags
  __u8  *bpChanNum  = &m_Dev_id[bSystemNum];  // pointer to interrupted device

  save_flags(dwFlags);
  cli();
  if (m_aCards[bCardNum].Channel[bChanNum].bIsrEnabled) {
    free_irq(m_aCards[bCardNum].wIrq, bpChanNum);
    wake_up_interruptible(&m_apWaitQue[bSystemNum]);
  }
  m_aCards[bCardNum].Channel[bChanNum].bIsrEnabled = 0;
  restore_flags(dwFlags);     // sti() is not recommended by LinuxDD book
}
//------- end of insert (A.Lebedev) -------------------------------------------

#endif

	/* Decrement module usage count. */
	MOD_DEC_USE_COUNT;
	
	return STATUS_ACE53_SUCCESS;
}




/*******************************************************************
 * Function: bu69080s1_isr                                         *
 *                                                                 *
 * Description: Handles catching the interrupt from the device     *
 *                                                                 *
 * Parameters:   irq    - the irq level of this device             *
 *               dev_id - device identifier			                   *
 *               regs   - ???? 		                                 *
 *******************************************************************/
void bu69080s1_isr(unsigned int irq, void* dev_id, struct pt_regs *regs)
{
#if 0
	__u8	*bpChanNum    = dev_id;			     /* Pointer to interrupted device */
	__u8	bSystemNum    = (__u8)(*bpChanNum);            /* Enumerated System Number */
	__u8	bCardNum      = (__u8)(bSystemNum) / 2;        /* Card number in system (0 - 3) */
	__u8	bChanNum      = (__u8)(bSystemNum) % 2;        /* Channel number on card (0, 1) */
	__u8   bIntFlag      = 0x11;                          /* This device's INT flag */
	__u8   bCurArea      = 0x00;                          /* Current Stack Area (A/B) */
	__u8   bBCEof        = 0x00;                          /* BC End-of-Frame Interrupt */
	__u8   bIntAutoClr   = 0x00;			     /* Ace Interrupt auto-clear status */
	__u16  wConfigReg    = 0x1111;                        /* 65549 0800 Configuration Space */
	__u16  wIntStatReg   = 0x0000;                        /* Ace Interrupt Status Register */
	__u16  wCfgReg1      = 0x0000;			     /* Ace Configuration Register #1 */
	__u16  wCfgReg2      = 0x0000;			     /* Ace Configuration Register #2 */
	__u16  wIntMaskReg   = 0x0000;                        /* Ace Interrupt Mask Register */
	__u32  dwChanOffset  = 0x00000000;                    /* Holds the channel's Reg base addr */

	/* Get 0800 Config Space */
	wConfigReg = readw((void*)(m_aCards[bCardNum].dwRegWndKrnAddr + 0x0800));

	/* Get Interrupt watch flag */
	bIntFlag = ((wConfigReg >> bChanNum) & 0x1);

	printk("%s: bu69080s1_isr(): Sys#:%02d/Card#:%02d/Chan#:%02d/ConfigReg:%04X\n",
		MODULE_NAME, bSystemNum,bCardNum,bChanNum,wConfigReg);

	/* Check if we issued the interrupt */
	if (bIntFlag == 1)
	{
#if 0
	    printk("%s: bu69080s1_isr(): ISR call not by us, returning to OS\n", MODULE_NAME);
	    return; /* Not us, return to OS */
#else
	    printk("%s: bu69080s1_isr(): ISR call not by us, pressing on\n", MODULE_NAME);
#endif
	}

	/* Get Channel Offset */
	dwChanOffset = (__u32)(m_aCards[bCardNum].dwRegWndKrnAddr + (bChanNum*0x0080)); /* reg space = 0x80 */
	
	/* Get CONFIG_REG_2 */
	wCfgReg2 = readw((void*)(dwChanOffset + 0x0004));

	/* Get interrupt auto-clear status */
	bIntAutoClr = ((wCfgReg2 >> 4) & 0x1);

	/* Get INTERRUPT_STATUS_REG */
	wIntStatReg = readw((void*)(dwChanOffset + 0x000C));

	/* Check for BC EOF Interrupt */
	bBCEof = ((wIntStatReg >> 3) & 0x1);

	/* Get INTERRUPT_MASK_REG */
	wIntMaskReg = readw((void*)(dwChanOffset + 0x0000));

	/* Get CONFIG_REG_1 */
	wCfgReg1 = readw((void*)(dwChanOffset + 0x0002));

	/* Get Current BC Stack Area */
	bCurArea = ((wCfgReg1 >> 13) & 0x1);

	/* Save Interrupt Status Register */
	m_aCards[bCardNum].Channel[bChanNum].wIntStatus = (U16)(wIntStatReg);


	DEBUG(1, "%s: bu69080s1_isr(): INTERRUPT OCCURED [CFGREG=%04x] - [STATREG=%04x] - [IMR=%04x]\n", 
	MODULE_NAME, (unsigned int)wConfigReg,(unsigned int)wIntStatReg,(unsigned int)wIntMaskReg);

	/* Make sure Interrupt Status Reg is valid */
	if (m_aCards[bCardNum].Channel[bChanNum].wIntStatus)
	{
		/* Check Int Auto-Clear */
		if(!bIntAutoClr)
		{
			/* Clear Interrupt */
			writew(0x0004,(void*)(dwChanOffset + 0x0006));	
		}

		/* Flip BC Stacks if EOF Int and its enabled */
		if ((m_aCards[bCardNum].Channel[bChanNum].bAutoFlipStk) && (bBCEof))
		{
			if (bCurArea)  /* A */
			{
				writew(wCfgReg1&0xDFFF,(void*)(dwChanOffset + 0x0002));	
			}
			else  /* B */
			{
				writew(wCfgReg1|0x2000,(void*)(dwChanOffset + 0x0002));	
			}
		}
		
		/* Wake up the blocked driver level ISR thread */
		if(m_aCards[bCardNum].Channel[bChanNum].bIsrEnabled)
		{
		    DEBUG(1, "%s: bu69080s1_isr(): Waking up via Interrupt [CFGREG=%04x] - [STATREG=%04x] - [IMR=%04x]\n", MODULE_NAME,(unsigned int)wConfigReg,(unsigned int)wIntStatReg,(unsigned int)wIntMaskReg);
		    wake_up_interruptible(&m_apWaitQue[bSystemNum]);
		}
	}
#else

//------- begin of insert (A.Lebedev) -----------------------------------------

  __u8 *bpChanNum   = dev_id;                  // Pointer to interrupted device
  __u8  bSystemNum  = (__u8)(*bpChanNum);      // Enumerated System Number
  __u8  bCardNum    = (__u8)(bSystemNum) / 2;  // Card number in system (0 - 3)
  __u8  bChanNum    = (__u8)(bSystemNum) % 2;  // Channel number on card (0, 1)
  __u16 wIntStatReg;                           // Ace Interrupt Status Register
  __u32 dwChanOffset;                          // Channel's Reg base addr

  dwChanOffset = (__u32)(m_aCards[bCardNum].dwRegWndKrnAddr
               + (bChanNum*0x0080));           // (reg space = 0x80)

  wIntStatReg  = readw((void*)(dwChanOffset + 0x000C));
  m_aCards[bCardNum].Channel[bChanNum].wIntStatus = (U16)(wIntStatReg);

  if (m_aCards[bCardNum].Channel[bChanNum].bIsrEnabled) {
    wake_up_interruptible(&m_apWaitQue[bSystemNum]);
  }

//------- end of insert (A.Lebedev) -------------------------------------------

#endif
}











/*******************************************************************
 * Function: bu69080s1_fops_ioctl                                  *
 *                                                                 *
 * Description: Handles all ioctl calls to device driver           *
 *                                                                 *
 * Parameters:   inode    - used to get Minor number		           *
 *               flip     - Not Used				                       *
 *               wCmd     - ioctl command requested		             *
 *               dwParam  - ioctl return data variable             *
 *******************************************************************/
int bu69080s1_fops_ioctl( struct inode *inode, struct file *flip, unsigned int wCmd, unsigned long dwParam )
{
	int 	nResult     = STATUS_ACE53_SUCCESS;   /* return value */	
	__u8	bSystemNum  = MINOR(inode->i_rdev);   /* Enumerated device number */
	__u8	bCardNum    = (__u8)bSystemNum / 2;   /* Card number in system (0 - 3) */
	__u8	bChanNum    = bSystemNum % 2;	   /* Channel number on card (0, 1) */
	__u8	*bpChanNum  = &m_Dev_id[bSystemNum];    /* pointer to interrupted device */
	__u32	dwFlags     = 0x00000000;	          /* temp variables for cli() */
	//U32BIT  address;
	//char* ptr;
	//char* cParam;
	//int n;
	//int i;
	
	DEBUG(1, "%s: bu69080s1_fops_ioctl(): Sys#:%02d/Card#:%02d/Chan#:%02d\n", MODULE_NAME, bSystemNum,bCardNum,bChanNum);
	/* Check that minor number is in the system */
	if ( bSystemNum >= m_bNumberOfCards)
	{
		printk("%s: bu69080s1_fops_ioctl(): STATUS_ACE53_DEVICE_NOT_EXIST \n", MODULE_NAME);
		return STATUS_ACE53_DEVICE_NOT_EXIST;
	}
	
	/* Return error if an attempt was made to 'ioctl' an unopened card. */
	if (m_aCards[bCardNum].Channel[bChanNum].bOpen == 0)
	{
		printk("%s: bu69080s1_fops_ioctl(): STATUS_ACE53_CARD_NOT_OPEN\n", MODULE_NAME);
		return STATUS_ACE53_CARD_NOT_OPEN;
	}
	
	/* Process the command. */
	switch(wCmd)
	{
		/* Get Driver Version */
         	case	IOCTL_ACE53_GET_VERSION:
			*(__u32 *)dwParam = ACE53_VERSION;
			break;

		/* BC Auto Flip Stack */
		case	IOCTL_ACE53_BC_AUTO_FLIPSTK:
			m_aCards[bCardNum].Channel[bChanNum].bAutoFlipStk = *(__u32 *)dwParam;
			break;
			
		/* Get specific card's information */
		case	IOCTL_ACE53_GET_CARD_INFO:
		        ((pACE53_CARD)dwParam)->plink              = m_aCards[bCardNum].plink;
			((pACE53_CARD)dwParam)->bPciBusNum         = m_aCards[bCardNum].bPciBusNum;
			((pACE53_CARD)dwParam)->bPciDevNum         = m_aCards[bCardNum].bPciDevNum;
			((pACE53_CARD)dwParam)->bPciFcnNum         = m_aCards[bCardNum].bPciFcnNum;
			((pACE53_CARD)dwParam)->wDeviceID          = m_aCards[bCardNum].wDeviceID;
			((pACE53_CARD)dwParam)->wCardID            = m_aCards[bCardNum].wCardID;
			((pACE53_CARD)dwParam)->cDevFileCardRef    = m_aCards[bCardNum].cDevFileCardRef;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -