📄 1553_junk_bm-5_bu69080s1.c
字号:
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 + -