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

📄 usbdev.c

📁 周立功magic2410实验箱源码 第6章Linux高级实验(part1) 6.1 Linux内核编译实验 6.2 Linux根文件系统实验 6.3 CAT1025读/写实验. 6.4 ZL
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************Copyright (c)****************************************************                               Guangzhou ZHIYUAN electronics Co.,LTD.**                                     **                                 http://www.zyinside.com****--------------File Info-------------------------------------------------------------------------------** File Name: 				usbdev.c** Last modified Date: 		2006.01.09** Last Version:			V1.0		** Description: 			usbdev.c, S3C2410 USB 设备驱动程序**                          usbdev.c, S3C2410 USB Device Driver**------------------------------------------------------------------------------------------------------** Created By: 				MingYuan Zheng 郑明远** Created date: 			2006.01.09** Version: 				V1.0** Descriptions:			The original version 初始版本****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** Version:** Description:**********************************************************************************************************/

#ifndef __KERNEL__
    #define __KERNEL__
#endif
#ifndef MODULE
    #define MODULE
#endif

#include "config.h"

static ssize_t usbdev_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos);
static ssize_t usbdev_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);

static int usbdev_open(struct inode *inode, struct file *filp);
static int usbdev_release(struct inode *inode, struct file *filp); 
static int usbdev_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long param);

void ep1_int_handler(void);
void ep2_int_handler(void);
void ep3_int_handler(void);
void ep4_int_handler(void);


/********************************************************************************************************
              define announce
********************************************************************************************************/
MODULE_PARM(major, "i");

MODULE_LICENSE("Proprietary");
MODULE_DESCRIPTION("GuangZhou ZhiYuan Electronics Co.,LTD.\nhttp://www.zyinside.com");
MODULE_SUPPORTED_DEVICE("linux2.4.18 S3C2410 usbdev");
MODULE_AUTHOR("MingYuan Zheng");

#define  MAJOR_NR   major

/*********************************************************************************************************
**                  "全局和静态变量在这里定义"         
**        global variables and static variables define here
********************************************************************************************************/

/* device using count */
unsigned int   usage = 0;										  /* 设备使用计数器 */
static int major = USBDEV_MAJOR_NR;

/* endpoint numbers except control endpoint */
#define NUMS_REC_ENDPOINTS      2								  /* 除控制端点外端点数 */	
#define NUMS_SEND_ENDPOINTS     2

/* endpoint used semaphore  */
struct semaphore    rec_sem[NUMS_REC_ENDPOINTS];                  /* 端点占用信号量(用于互斥) */
struct semaphore    send_sem[NUMS_SEND_ENDPOINTS]; 

/* endpoint interrupt semaphore */
struct semaphore    rec_irq_sem[NUMS_REC_ENDPOINTS];              /* 端点中断信号量(用于数据收发) */   
struct semaphore    send_irq_sem[NUMS_SEND_ENDPOINTS];           

/* endpoint size */												  /* 端点FIFO大小 */	
static int rec_fifo_size[NUMS_REC_ENDPOINTS] = {EP2_PACKET_SIZE, EP4_PACKET_SIZE};
static int send_fifo_size[NUMS_SEND_ENDPOINTS] = {EP1_PACKET_SIZE, EP3_PACKET_SIZE};

/* endpoint waiting queue */
wait_queue_head_t rec_queue[NUMS_REC_ENDPOINTS];				  /* 端点等待队列 */ 
wait_queue_head_t send_queue[NUMS_SEND_ENDPOINTS];

/* endpoint timeout */
static int rec_timeout[NUMS_REC_ENDPOINTS];						  /* 端点收发超时时间 */
static int send_timeout[NUMS_SEND_ENDPOINTS];

/* endpoint have finished receiving and trasmitting once */
static int b_send[NUMS_SEND_ENDPOINTS];							  /* 端点是(1)否(0)完成一次数据收发 */
static int b_rec[NUMS_REC_ENDPOINTS];


/********************************************************************************************************/
static struct file_operations usbdev_fops =        /* driver info  */
{
    owner:              THIS_MODULE,
    write:              usbdev_write,
    read:               usbdev_read,    
    open:               usbdev_open,
    release:            usbdev_release,
    ioctl:              usbdev_ioctl,
};


/*********************************************************************************************************
** Function name : usbdev_release
** Descriptions  : release device
** Input		 : inode:  information of device
**					filp:  pointer of file
** Output		 :     0:  OK
**				   other:  not OK
** Created by	 :  MingYuan Zheng 郑明远    
** Created Date  :  2006-01-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static int  usbdev_release(struct inode *inode, struct file *filp) 
{
    int i;
    
    MOD_DEC_USE_COUNT;
    usage--;   
    /* re-initialize global variable */   
    for (i = 0; i < NUMS_REC_ENDPOINTS; i++)		
    {
		rec_timeout[i] = 0;							/* timeout time be setted to 0  	 超时时间置为0 */
        send_timeout[i] = 0;
                        
        b_send[i] = 0;								/* transmitted flash be setted to 0  已发送标志置为0 */
        b_rec[i] = 0;								/* received flash be setted to 0     已接收标志置为0 */
    }
   
    return(0); 
} 


/*********************************************************************************************************
** Function name : usbdev_write
** Descriptions  : write device(transmit data to USB host by endpoint)
** Input		 :   filp: pointer of file
**					  buf: buf to write data
**					count:  size for write
**					f_pos:  *f_pos = write point
** Output		 : write size    
** Created by	 : MingYuan Zheng 郑明远
** Created Date  : 2006-01-12
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static ssize_t usbdev_write(struct file *filp, const char *buf, size_t count,
                            loff_t *f_pos)
{
    unsigned int num,len;
    unsigned int sendcnt = 0,i;
    unsigned int epsize;                        			/* endpoint buffer size */
    unsigned char sendbuf[64];
    unsigned int  flag, bfinish = 0;
    int ret;
               
    num = (unsigned int)filp->private_data;
    if ((num > NUMS_SEND_ENDPOINTS) || (num < 1))
    {
        return -ENODEV; 
    }

    if (down_interruptible(&send_sem[num - 1])) 			/* occupy the endpoint */
    {
        return -ERESTARTSYS;
    }
    
    epsize = send_fifo_size[num - 1];						/* get FIFO size */
    
    while(1)
    {
        /****************************************************
         	write the data to the FIFO of USB device 
        ****************************************************/
        local_irq_save(flag); 
        len = count - sendcnt;
        if (len >= epsize)
        {
            copy_from_user(sendbuf, (unsigned char *)(buf + sendcnt), epsize);
            len = USB_WriteEndpoint(num * 2 - 1, epsize, sendbuf);				/* write FIFO */
        }
        else
        {
            copy_from_user(sendbuf, (unsigned char *)(buf + sendcnt), len);
            len = USB_WriteEndpoint(num * 2 - 1, len, sendbuf);					/* write FIFO */
        }
                                
        sendcnt = sendcnt + len;
        if (sendcnt >= count)
        {													 /* all data have been write into FIFO */
            b_send[num - 1] = 0;
            local_irq_restore(flag);
            bfinish = 1;
        }
        b_send[num - 1] = 0;
        local_irq_restore(flag);
 
 		/*****************************************************
 		    wait the data be received by USB Host(PC) 
 		*****************************************************/
        if (send_timeout[num - 1] != 0)
        {
            local_irq_save(flag); 
            if (b_send[num - 1] == 0)
            {
                local_irq_restore(flag);
                ret = interruptible_sleep_on_timeout(&send_queue[num - 1], send_timeout[num - 1] * HZ/1000);
                if (ret <= 0)
                {
                	printk("S3C2410 USB device ep%d send data timeout!\n", num);
                    up(&send_sem[num - 1]); 
                    return sendcnt;     
                }          
            }
            else
                b_send[num - 1] = 0;
        }
        else
        {             
            if (down_interruptible(&send_irq_sem[num - 1]))
            {   /* can not wait the send_irq_sem*/
                up(&send_sem[num - 1]);
                return -ERESTARTSYS;
            }
        }     
    
    	/******************************************************
    	  all data has been received by USB host(such as PC)
    	******************************************************/
        if (bfinish == 1)
        {
        	up(&send_sem[num - 1]);
           	return sendcnt;
        }//end of if (bfinish == 1)  
          
    }//end of while(1)
    
}


/*********************************************************************************************************
** Function name : usbdev_read
** Descriptions  :  read device (receive data from USB host by endpoint)
** Input		 :   filp:   pointer of file
**				      buf:    buf for save data
**					count:  size for read
**					f_pos:  *f_pos = read point
** Output		 : read size    
** Created by	 : MingYuan Zheng
** Created Date  : 2005-5-17
**-------------------------------------------------------------------------------------------------------
** Modified by:
** Modified Date: 
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        static ssize_t usbdev_read(struct file *filp, char *buf, size_t count,
                           loff_t *f_pos)
{
	unsigned int flag, num, len;
    unsigned int epsize, reccnt = 0, i;
    unsigned char recbuf[64], endpstatus;
    int ret;
               
    num = (unsigned int)filp->private_data;
    if ((num > NUMS_REC_ENDPOINTS) ||(num < 1))
    {
        return -ENODEV; 
    }

    if (down_interruptible(&rec_sem[num - 1]))				/* occupy the endpoint */       
    {
        return -ERESTARTSYS;
    }
    
    epsize = rec_fifo_size[num - 1];						/* get FIFO size */

    while(1)
    {
        /*******************************************************
         	wait for the data(send from USB host(such as PC))
        *******************************************************/    	
        if (rec_timeout[num - 1] != 0)
        {
            local_irq_save(flag);

⌨️ 快捷键说明

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