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

📄 usbdev.c

📁 周立功magic2410实验箱源码 第6章Linux高级实验(part1) 6.1 Linux内核编译实验 6.2 Linux根文件系统实验 6.3 CAT1025读/写实验. 6.4 ZL
💻 C
📖 第 1 页 / 共 3 页
字号:
            if (b_rec[num - 1] == 0)
            {
                local_irq_restore(flag);
                ret = interruptible_sleep_on_timeout(&rec_queue[num - 1], rec_timeout[num - 1] * HZ/1000);            
                if (ret <= 0)
                {
                	printk("S3C2410 USB device ep%d receive data timeout!\n", num);
                    up(&rec_sem[num - 1]); 
                    return reccnt;     
                }
            }
            
            b_rec[num - 1] = 0;
        }
        else
        {
            if (down_interruptible(&rec_irq_sem[num - 1]))
            {   /* can not wait the irq_sem*/
                up(&rec_sem[num - 1]);
                return -ERESTARTSYS;
            }
        }
        
        /******************************************************
         	read data from FIFO 
        *******************************************************/    
        local_irq_save(flag);
        endpstatus = USB_ReadOUTEpStatus(num * 2);
        if ((endpstatus & 0x01) == 0)  
        {													/* FIFO is empty */
        	local_irq_restore(flag);												
            up(&rec_sem[num - 1]);
            return -ERESTARTSYS;            
        }
                      
        len = count - reccnt;
        if (len >= epsize)
        {
       		len = USB_ReadEndpoint(num * 2, epsize, recbuf);/* read FIFO */ 
        	copy_to_user(buf + reccnt, recbuf, len);
        }
        else
        {
            len = USB_ReadEndpoint(num * 2, len, recbuf);	/* read FIFO */ 
            copy_to_user(buf + reccnt, recbuf, len);
        }
                        
        reccnt = reccnt + len;
        if (reccnt >= count)
        {													/* all data has been received */
            local_irq_restore(flag); 
            up(&rec_sem[num - 1]);
            return reccnt;
        }
         
        b_rec[num - 1] = 0;
        local_irq_restore(flag);   
             
    }//end of while(1)
    
}


/*********************************************************************************************************
** Function name: usbdev_ioctl
** Descriptions : IO control function(be used to set receiveing and transmitting timeout value)
** Input		: inode : information of device
**       		  filp  : pointer of file
**       		  cmd   : command
**       		  arg   : additive parameter
** Output		:     0 : OK
**        		  other : not OK
** Created by   : MingYuan Zheng
** Created Date : 2006-01-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static int usbdev_ioctl(struct inode *inode, struct file *filp, 
                            unsigned int cmd, unsigned long arg)
{
    unsigned int num;
    
    if (_IOC_TYPE(cmd) != USBDEV_IOC_MAGIC)
    {	
    	/* no such command */													
        return -ENOTTY;
    }
    
    if (_IOC_NR(cmd) >= USBDEV_MAXNR)
    {
    	/* no such minor */														
        return -ENOTTY;
    }
    
    num = (unsigned int)filp->private_data;    
    if (num > NUMS_REC_ENDPOINTS)                           /* 超出最大端点数 */
    {	
    	/* above the max endpoint number */
        return -ENODEV; 
    }
    
    switch(cmd)
    {
    	/* set the receiving timeout */
        case USBDEV_SET_READ_TIMEOUT:						/* 设置接收超时时间 */
              rec_timeout[num - 1] = arg;      
        break;
        
        /* set the transmitting timeout */		
        case USBDEV_SET_WRITE_TIMEOUT:						/* 设置发送超时时间 */
              send_timeout[num - 1] = arg;					
        break; 

        default:
        	 printk(KERN_ERR DEVICE_NAME "No such command!"); 
             return -ENOTTY;
        break;
    }

    return 0;
}


/*********************************************************************************************************
** Function name : usb_irq_handle
** Descriptions  : S3C2410 USB device controller Interrupt Service Program
** Input		 : Linux Interrupt Service input parameter
** Output 		 : NULL
** Created by	 : MingYuan Zheng
** Created Date	 : 2006-01-12
**-------------	------------------------------------------------------------------------------------------
** Modified by   :
** Modified Date : 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void usb_irq_handle(int irq, void *dev_id, struct pt_regs *regs)
{
	INT8U usb_ints, ep_ints;
    INT32U flag;

    usb_ints = UD_USBINT;
    ep_ints = UD_INT;                            /* 读USB中断寄存器   read USB interrupt register */
        
    if (usb_ints & RESET_INT)
    	USB_BusReset();                          /* USB 总线复位处理  process USB bus reset */                           

    if (usb_ints & SUSPEND_INT)
        USB_Suspend();                           /* USB 设备挂起处理  process USB device suspend */
                
    if (usb_ints & RESUME_INT)
    {
        UD_USBINT = RESUME_INT;                  /* USB 设备恢复处理  process USB device resume */
    }
         
    if (ep_ints & EP0_INT)  
        ep0_int_handler();                       /* 物理端点0 (Control) 中断处理 EP0(Control) interrupt handler */

    if (ep_ints & EP1_INT)
        ep1_int_handler();                       /* 物理端点1 (IN)  中断处理     EP1(IN)  interrupt handler */

    if (ep_ints & EP2_INT)
        ep2_int_handler();                       /* 物理端点2 (OUT) 中断处理     EP2(OUT) interrupt handler */
        
    if (ep_ints & EP3_INT)
        ep3_int_handler();                       /* 物理端点3 (IN)  中断处理     EP3(IN)  interrupt handler */
               
    if (ep_ints & EP4_INT)
        ep4_int_handler();                       /* 物理端点4 (OUT) 中断处理     EP4(OUT) interrupt handler */
        
    if (bEPPflags.bits.setup_packet)
    {                                            /* 收到 SETUP 包    receive SETUP packet*/
    	bEPPflags.bits.setup_packet = 0;
    	control_handler();                       /* 控制传输处理     process control transmission */
    } // if SETUP packet

   
    /* clear the interrupt of mcu */ 
    SRCPND = INT_USBD;                           /* 清除相关中断标志 clear the interrupt flag */          
    INTPND = INT_USBD;  
}


/*********************************************************************************************************
** Function name : ep1_int_handler
** Descriptions  : the interrupt hanlder of the physical endpoint 1(IN). 物理端点1 (IN) 中断处理(发送)
** Input		 : NULL
** Output 		 : NULL
** Created by	 : MingYuan Zheng
** Created Date	 : 2006-01-12
**-------------	------------------------------------------------------------------------------------------
** Modified by   :
** Modified Date : 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep1_int_handler(void)
{
    USB_SelectClrIntEndpoint(1);                  /* 选择端点并清除中断  select endpoint/clear interrupt */

    if (send_timeout[0] != 0)
    {
        wake_up_interruptible(&send_queue[0]);    /* 唤醒发送等待队列    wake up the sending waiting queue */
        b_send[0] = 1;
    }
    else
    {
        up(&send_irq_sem[0]);					  /* 唤醒发送等待信号量  wake up the sending waiting semaphore */
    }      
}


/*********************************************************************************************************
** Function name : ep2_int_handler
** Descriptions  : the interrupt hanlder of the physical endpoint 2(OUT). 物理端点2 (OUT) 中断处理
** Input		 : NULL
** Output 		 : NULL
** Created by	 : MingYuan Zheng
** Created Date	 : 2006-01-12
**-------------	------------------------------------------------------------------------------------------
** Modified by   :
** Modified Date : 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep2_int_handler(void)
{
    INT8U len;

    USB_SelectClrIntEndpoint(2);                   /* 选择端点并清除中断  select endpoint/clear interrupt */
    
    if (rec_timeout[0] != 0)
    {
        wake_up_interruptible(&rec_queue[0]);	   /* 唤醒接收等待队列    wake up the receiving waiting queue */
        b_rec[0] = 1;   
    }
    else
    {
        up(&rec_irq_sem[0]);					   /* 唤醒接收等待信号量  wake up the receiving waiting semaphore */
    }
}


/*********************************************************************************************************
** Function name : ep3_int_handler
** Descriptions  : the interrupt hanlder of the physical endpoint 3(IN). 物理端点3 (IN) 中断处理
** Input		 : NULL
** Output 		 : NULL
** Created by	 : MingYuan Zheng
** Created Date	 : 2006-01-12
**-------------	------------------------------------------------------------------------------------------
** Modified by   :
** Modified Date : 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep3_int_handler(void)
{
    USB_SelectClrIntEndpoint(3);                    /* 选择端点并清除中断  select endpoint/clear interrupt */

    if (send_timeout[1] != 0)
    {
        wake_up_interruptible(&send_queue[1]);  	/* 唤醒发送等待队列    wake up the sending waiting queue */
        b_send[1] = 1;
    }
    else
    {
        up(&send_irq_sem[1]);						/* 唤醒发送等待信号量  wake up the sending waiting semaphore */
    } 
}


/*********************************************************************************************************
** Function name : ep4_int_handler
** Descriptions  : the interrupt hanlder of the physical endpoint 4(OUT). 物理端点4 (OUT) 中断处理
** Input		 : NULL
** Output 		 : NULL
** Created by	 : MingYuan Zheng
** Created Date	 : 2006-01-12
**-------------	------------------------------------------------------------------------------------------
** Modified by   :
** Modified Date : 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
void ep4_int_handler(void)
{
    INT8U len;
        
    USB_SelectClrIntEndpoint(4);                     /* 选择端点并清除中断  select endpoint/clear interrupt */

    if (rec_timeout[1] != 0)
    {
        wake_up_interruptible(&rec_queue[1]);   	 /* 唤醒接收等待队列    wake up the receiving waiting queue */
    }
    else
    {
        up(&rec_irq_sem[1]);						 /* 唤醒接收等待信号量  wake up the receiving waiting semaphore */
    }        

⌨️ 快捷键说明

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