Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134354
  • 博文数量: 14
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 633
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-05 11:44
文章存档

2014年(14)

我的朋友

分类: LINUX

2014-06-25 10:34:36

内核源码中提供了一个USB驱动的例子是drivers/usb/usb-skeleton.c,称为USB骨架程序。

一、USB骨架程序的usb_driver结构体定义

点击(此处)折叠或打开

  1. static struct usb_driver skel_driver = {
  2.     .name =        "skeleton",//驱动名
  3.     .probe =    skel_probe,//探测方法
  4.     .disconnect =    skel_disconnect,//断开连接的方法
  5.     .suspend =    skel_suspend,//挂起方法
  6.     .resume =    skel_resume,//恢复方法
  7.     .pre_reset =    skel_pre_reset,
  8.     .post_reset =    skel_post_reset,//设备重置后调用
  9.     .id_table =    skel_table,//驱动支持的设备ID列表
  10.     .supports_autosuspend = 1,//支持挂起
  11. };
usb_driver的id_table成员指定了驱动支持的USB设备的列表,定义如下:

点击(此处)折叠或打开

  1. /* 定义这些值以匹配您的设备 */
  2. #define USB_SKEL_VENDOR_ID    0xfff0
  3. #define USB_SKEL_PRODUCT_ID    0xfff0
  4. //驱动支持的设备ID列表
  5. static const struct usb_device_id skel_table[] = {
  6.     { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
  7.     { }                    /* Terminating entry */
  8. };
  9. MODULE_DEVICE_TABLE(usb, skel_table);
二、驱动的加载和卸载方法
1、加载方法,将usb_driver结构注册到USB核心

点击(此处)折叠或打开

  1. static int __init usb_skel_init(void)
  2. {
  3.     int result;
  4.     //注册一个USB驱动
  5.     result = usb_register(&skel_driver);
  6.     if (result)
  7.         err("usb_register failed. Error number %d", result);
  8.     return result;
  9. }
2、卸载方法,将usb_driver结构注销

点击(此处)折叠或打开

  1. static void __exit usb_skel_exit(void)
  2. {
  3.     //注销一个USB驱动
  4.     usb_deregister(&skel_driver);
  5. }
三、USB的探测方法
探测方法,当USB设备插入时,USB核心检测到USB设备的属性和对应的USB驱动匹配时,会调用USB驱动的探测方法

点击(此处)折叠或打开

  1. static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
  2. {
  3.     struct usb_skel *dev;
  4.     struct usb_host_interface *iface_desc;
  5.     struct usb_endpoint_descriptor *endpoint;
  6.     size_t buffer_size;
  7.     int i;
  8.     int retval = -ENOMEM;

  9.     //分配私有数据usb_skel空间
  10.     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  11.     if (!dev) {
  12.         err("Out of memory");
  13.         goto error;
  14.     }
  15.     //初始化私有数据结构usb_skel
  16.     kref_init(&dev->kref);//初始化引用计数器
  17.     sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);//初始化信号
  18.     mutex_init(&dev->io_mutex);//初始化互斥体
  19.     spin_lock_init(&dev->err_lock);//初始化错误自旋锁
  20.     init_usb_anchor(&dev->submitted);
  21.     init_completion(&dev->bulk_in_completion);//初始化批量输入端点的地址
  22.     //通过接口得到usb设备结构
  23.     dev->udev = usb_get_dev(interface_to_usbdev(interface));
  24.     dev->interface = interface;//初始化设备的接口

  25.     //设置端点信息
  26.     //仅使用第一个bulk-in和buil-out
  27.     iface_desc = interface->cur_altsetting;//获得当前激活的设置
  28.     //扫描接口中的每一个端点
  29.     for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
  30.         endpoint = &iface_desc->endpoint[i].desc;//获得一个端点
  31.         //比较端点是否为输入端点
  32.         if (!dev->bulk_in_endpointAddr &&
  33.          usb_endpoint_is_bulk_in(endpoint)) {
  34.             //找到一个批量的输入端点
  35.             buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
  36.             dev->bulk_in_size = buffer_size;
  37.             dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
  38.             dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
  39.             if (!dev->bulk_in_buffer) {
  40.                 err("Could not allocate bulk_in_buffer");
  41.                 goto error;
  42.             }
  43.             dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
  44.             if (!dev->bulk_in_urb) {
  45.                 err("Could not allocate bulk_in_urb");
  46.                 goto error;
  47.             }
  48.         }
  49.         //比较端点是否为输出端点
  50.         if (!dev->bulk_out_endpointAddr &&
  51.          usb_endpoint_is_bulk_out(endpoint)) {
  52.             //找到一个批量的输出端点
  53.             dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
  54.         }
  55.     }
  56.     if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
  57.         err("Could not find both bulk-in and bulk-out endpoints");
  58.         goto error;
  59.     }

  60.     /*在接口设备中保存数据指针 */
  61.     usb_set_intfdata(interface, dev);//将usb_skel结构作为接口的私有数据保存

  62.     /* 注册USB设备*/
  63.     retval = usb_register_dev(interface, &skel_class);
  64.     if (retval) {
  65.         /* something prevented us from registering this driver */
  66.         err("Not able to get a minor for this device.");
  67.         usb_set_intfdata(interface, NULL);
  68.         goto error;
  69.     }

  70.     /* let the user know what node this device is now attached to */
  71.     dev_info(&interface->dev,
  72.          "USB Skeleton device now attached to USBSkel-%d",
  73.          interface->minor);
  74.     return 0;

  75. error:
  76.     if (dev)
  77.         /* this frees allocated memory */
  78.         kref_put(&dev->kref, skel_delete);
  79.     return retval;
  80. }
四、私有数据结构

点击(此处)折叠或打开

  1. struct usb_skel {
  2.     struct usb_device    *udev;            /*这个设备的usb设备 */
  3.     struct usb_interface    *interface;        /* 这个设备的接口*/
  4.     struct semaphore    limit_sem;        /*限制写的数量 */
  5.     struct usb_anchor    submitted;        /* 以防我们需要收回我们的提交*/
  6.     struct urb        *bulk_in_urb;        /* 用于读取数据的URB*/
  7.     unsigned char *bulk_in_buffer;    /*接收数据的缓冲区*/
  8.     size_t            bulk_in_size;        /* 接收缓冲区的大小 */
  9.     size_t            bulk_in_filled;        /*缓冲区的字节数*/
  10.     size_t            bulk_in_copied;        /* 已经复制到用户空间大小 */
  11.     __u8            bulk_in_endpointAddr;    //批量输入端点的地址
  12.     __u8            bulk_out_endpointAddr;    //批量输出端点的地址
  13.     int            errors;            /* the last request tanked */
  14.     int            open_count;        //打开USB设备的数量
  15.     bool            ongoing_read;        //是否在继续读数据
  16.     bool            processed_urb;        //确定是否有未处理的urb
  17.     spinlock_t        err_lock;        //错误自旋锁
  18.     struct kref        kref;//引用计数器
  19.     struct mutex        io_mutex;        //用于断开连接的同步IO
  20.     struct completion    bulk_in_completion;    /* to wait for an ongoing read */
  21. };
五、断开连接的方法
当USB设备拔出时,USB核心会调用USB驱动的断开连接方法

点击(此处)折叠或打开

  1. static void skel_disconnect(struct usb_interface *interface)
  2. {
  3.     struct usb_skel *dev;
  4.     int minor = interface->minor;//获得次设备号
  5.     //获得接口的私有数据
  6.     dev = usb_get_intfdata(interface);
  7.     usb_set_intfdata(interface, NULL);//设置接口的私有数据位空

  8.     //注销USB设备,释放设备号
  9.     usb_deregister_dev(interface, &skel_class);

  10.     //阻止更多的IO动作
  11.     mutex_lock(&dev->io_mutex);
  12.     dev->interface = NULL;
  13.     mutex_unlock(&dev->io_mutex);

  14.     usb_kill_anchored_urbs(&dev->submitted);

  15.     //释放设备号
  16.     kref_put(&dev->kref, skel_delete);

  17.     dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
  18. }
六、skel_class结构
注册USB驱动的时候需要传递一个usb_class_driver结构

点击(此处)折叠或打开

  1. static struct usb_class_driver skel_class = {
  2.     .name =        "skel%d",
  3.     .fops =        &skel_fops,//USB设备文件操作函数集合
  4.     .minor_base =    USB_SKEL_MINOR_BASE,//usb次设备号基址
  5. };
  6. static const struct file_operations skel_fops = {
  7.     .owner =    THIS_MODULE,
  8.     .read =        skel_read,//读函数
  9.     .write =    skel_write,//写函数
  10.     .open =        skel_open,//打开
  11.     .release =    skel_release,//关闭
  12.     .flush =    skel_flush,//刷新
  13.     .llseek =    noop_llseek,//重定位
  14. };
七、打开函数

点击(此处)折叠或打开

  1. static int skel_open(struct inode *inode, struct file *file)
  2. {
  3.     struct usb_skel *dev;
  4.     struct usb_interface *interface;
  5.     int subminor;
  6.     int retval = 0;

  7.     subminor = iminor(inode);//获得次设备号
  8.     //得到对应的接口
  9.     interface = usb_find_interface(&skel_driver, subminor);
  10.     if (!interface) {
  11.         err("%s - error, can't find device for minor %d",
  12.          __func__, subminor);
  13.         retval = -ENODEV;
  14.         goto exit;
  15.     }
  16.     //得到接口的私有数据
  17.     dev = usb_get_intfdata(interface);
  18.     if (!dev) {
  19.         retval = -ENODEV;
  20.         goto exit;
  21.     }

  22.     //增加引用计数
  23.     kref_get(&dev->kref);

  24.     /* lock the device to allow correctly handling errors
  25.      * in resumption */
  26.     mutex_lock(&dev->io_mutex);
  27.     //增加打开次数
  28.     if (!dev->open_count++) {
  29.         retval = usb_autopm_get_interface(interface);
  30.             if (retval) {
  31.                 dev->open_count--;
  32.                 mutex_unlock(&dev->io_mutex);
  33.                 kref_put(&dev->kref, skel_delete);
  34.                 goto exit;
  35.             }
  36.     } /* else { //uncomment this block if you want exclusive open
  37.         retval = -EBUSY;
  38.         dev->open_count--;
  39.         mutex_unlock(&dev->io_mutex);
  40.         kref_put(&dev->kref, skel_delete);
  41.         goto exit;
  42.     } */
  43.     /* prevent the device from being autosuspended */

  44.     /* save our object in the file's private structure */
  45.     file->private_data = dev;//设置文件的私有数据
  46.     mutex_unlock(&dev->io_mutex);

  47. exit:
  48.     return retval;
  49. }
八、关闭方法

点击(此处)折叠或打开

  1. static int skel_release(struct inode *inode, struct file *file)
  2. {
  3.     struct usb_skel *dev;

  4.     dev = file->private_data;//获得私有数据
  5.     if (dev == NULL)
  6.         return -ENODEV;

  7.     //减少打开次数
  8.     mutex_lock(&dev->io_mutex);
  9.     if (!--dev->open_count && dev->interface)
  10.         usb_autopm_put_interface(dev->interface);
  11.     mutex_unlock(&dev->io_mutex);

  12.     //减少引用次数
  13.     kref_put(&dev->kref, skel_delete);
  14.     return 0;
  15. }
九、写方法

点击(此处)折叠或打开

  1. static ssize_t skel_write(struct file *file, const char *user_buffer,
  2.              size_t count, loff_t *ppos)
  3. {
  4.     struct usb_skel *dev;
  5.     int retval = 0;
  6.     struct urb *urb = NULL;
  7.     char *buf = NULL;
  8.     size_t writesize = min(count, (size_t)MAX_TRANSFER);//计算写入大小

  9.     dev = file->private_data;//获得私有数据

  10.     /* verify that we actually have some data to write */
  11.     if (count == 0)//写入大小为0时退出
  12.         goto exit;

  13.     /*
  14.      * limit the number of URBs in flight to stop a user from using up all
  15.      * RAM
  16.      */
  17.      //判断文件类型是否为阻塞的
  18.     if (!(file->f_flags & O_NONBLOCK)) {
  19.         //获得信号量
  20.         if (down_interruptible(&dev->limit_sem)) {
  21.             retval = -ERESTARTSYS;
  22.             goto exit;
  23.         }
  24.     } else {
  25.         //尝试获得信号量
  26.         if (down_trylock(&dev->limit_sem)) {
  27.             retval = -EAGAIN;
  28.             goto exit;
  29.         }
  30.     }

  31.     spin_lock_irq(&dev->err_lock);
  32.     retval = dev->errors;
  33.     if (retval < 0) {
  34.         /* any error is reported once */
  35.         dev->errors = 0;
  36.         /* to preserve notifications about reset */
  37.         retval = (retval == -EPIPE) ? retval : -EIO;
  38.     }
  39.     spin_unlock_irq(&dev->err_lock);
  40.     if (retval < 0)
  41.         goto error;

  42.     /* 创建一个urb,一个缓冲区,并将数据复制到urb */
  43.     urb = usb_alloc_urb(0, GFP_KERNEL);
  44.     if (!urb) {
  45.         retval = -ENOMEM;
  46.         goto error;
  47.     }
  48.     //分配一个缓冲区
  49.     buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
  50.                  &urb->transfer_dma);
  51.     if (!buf) {
  52.         retval = -ENOMEM;
  53.         goto error;
  54.     }
  55.     //从用户控件复制数据到缓冲区
  56.     if (copy_from_user(buf, user_buffer, writesize)) {
  57.         retval = -EFAULT;
  58.         goto error;
  59.     }

  60.     /* this lock makes sure we don't submit URBs to gone devices */
  61.     mutex_lock(&dev->io_mutex);
  62.     if (!dev->interface) {        /* disconnect() was called */
  63.         mutex_unlock(&dev->io_mutex);
  64.         retval = -ENODEV;
  65.         goto error;
  66.     }

  67.     //批量urb初始化
  68.     usb_fill_bulk_urb(urb, dev->udev,
  69.              usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
  70.              buf, writesize, skel_write_bulk_callback, dev);
  71.     urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  72.     usb_anchor_urb(urb, &dev->submitted);

  73.     //提交urb到核心
  74.     retval = usb_submit_urb(urb, GFP_KERNEL);
  75.     mutex_unlock(&dev->io_mutex);
  76.     if (retval) {
  77.         err("%s - failed submitting write urb, error %d", __func__,
  78.          retval);
  79.         goto error_unanchor;
  80.     }

  81.     //释放urb
  82.     usb_free_urb(urb);

  83.     return writesize;

  84. error_unanchor:
  85.     usb_unanchor_urb(urb);
  86. error:
  87.     if (urb) {
  88.         usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
  89.         usb_free_urb(urb);
  90.     }
  91.     up(&dev->limit_sem);

  92. exit:
  93.     return retval;
  94. }

  95. //写完成回调函数,当URB传输完成后调用
  96. static void skel_write_bulk_callback(struct urb *urb)
  97. {
  98.     struct usb_skel *dev;

  99.     dev = urb->context;

  100.     //判断urb状态
  101.     if (urb->status) {
  102.         if (!(urb->status == -ENOENT ||
  103.          urb->status == -ECONNRESET ||
  104.          urb->status == -ESHUTDOWN))
  105.             err("%s - nonzero write bulk status received: %d",
  106.              __func__, urb->status);

  107.         spin_lock(&dev->err_lock);
  108.         dev->errors = urb->status;
  109.         spin_unlock(&dev->err_lock);
  110.     }

  111.     /*释放我们的分配缓冲区*/
  112.     usb_free_coherent(urb->dev, urb->transfer_buffer_length,
  113.              urb->transfer_buffer, urb->transfer_dma);
  114.     up(&dev->limit_sem);
  115. }
十、读方法

点击(此处)折叠或打开

  1. static ssize_t skel_read(struct file *file, char *buffer, size_t count,
  2.              loff_t *ppos)
  3. {
  4.     struct usb_skel *dev;
  5.     int rv;
  6.     bool ongoing_io;

  7.     dev = file->private_data;//获得私有数据

  8.     //判断读取的数量为0,或用于读取的URB未分配
  9.     if (!dev->bulk_in_urb || !count)
  10.         return 0;

  11.     //互斥体
  12.     rv = mutex_lock_interruptible(&dev->io_mutex);
  13.     if (rv < 0)
  14.         return rv;
  15.     //判断接口是否为空
  16.     if (!dev->interface) {        /* disconnect() was called */
  17.         rv = -ENODEV;
  18.         goto exit;
  19.     }

  20.     /* if IO is under way, we must not touch things */
  21. retry:
  22.     spin_lock_irq(&dev->err_lock);
  23.     ongoing_io = dev->ongoing_read;
  24.     spin_unlock_irq(&dev->err_lock);
  25.     //判断是否在进行IO操作
  26.     if (ongoing_io) {
  27.         /* 非阻塞IO不等待*/
  28.         if (file->f_flags & O_NONBLOCK) {
  29.             rv = -EAGAIN;
  30.             goto exit;
  31.         }
  32.         //如果是阻塞的,阻塞IO
  33.         rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
  34.         if (rv < 0)
  35.             goto exit;
  36.         /*
  37.          * by waiting we also semiprocessed the urb
  38.          * we must finish now
  39.          */
  40.         dev->bulk_in_copied = 0;
  41.         dev->processed_urb = 1;
  42.     }
  43.     //判断是否有未完成的urb
  44.     if (!dev->processed_urb) {
  45.         /*
  46.          * the URB hasn't been processed
  47.          * do it now
  48.          */
  49.         wait_for_completion(&dev->bulk_in_completion);
  50.         dev->bulk_in_copied = 0;
  51.         dev->processed_urb = 1;
  52.     }

  53.     /* errors must be reported */
  54.     rv = dev->errors;
  55.     if (rv < 0) {
  56.         /* any error is reported once */
  57.         dev->errors = 0;
  58.         /* to preserve notifications about reset */
  59.         rv = (rv == -EPIPE) ? rv : -EIO;
  60.         /* no data to deliver */
  61.         dev->bulk_in_filled = 0;
  62.         /* report it */
  63.         goto exit;
  64.     }

  65.     /*
  66.      * if the buffer is filled we may satisfy the read
  67.      * else we need to start IO
  68.      */
  69.     //判断缓冲区的字节数
  70.     if (dev->bulk_in_filled) {
  71.         //得到需要读取数据的大小
  72.         size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
  73.         size_t chunk = min(available, count);

  74.         if (!available) {
  75.             /*
  76.              * all data has been used
  77.              * actual IO needs to be done
  78.              */
  79.             rv = skel_do_read_io(dev, count);
  80.             if (rv < 0)
  81.                 goto exit;
  82.             else
  83.                 goto retry;
  84.         }
  85.         /*
  86.          * data is available
  87.          * chunk tells us how much shall be copied
  88.          */

  89.         if (copy_to_user(buffer,
  90.                  dev->bulk_in_buffer + dev->bulk_in_copied,
  91.                  chunk))
  92.             rv = -EFAULT;
  93.         else
  94.             rv = chunk;

  95.         dev->bulk_in_copied += chunk;

  96.         /*
  97.          * if we are asked for more than we have,
  98.          * we start IO but don't wait
  99.          */
  100.         if (available < count)
  101.             skel_do_read_io(dev, count - chunk);
  102.     } else {
  103.         /* no data in the buffer */
  104.         rv = skel_do_read_io(dev, count);
  105.         if (rv < 0)
  106.             goto exit;
  107.         else if (!(file->f_flags & O_NONBLOCK))
  108.             goto retry;
  109.         rv = -EAGAIN;
  110.     }
  111. exit:
  112.     mutex_unlock(&dev->io_mutex);
  113.     return rv;
  114. }
  115. //读IO方法
  116. static int skel_do_read_io(struct usb_skel *dev, size_t count)
  117. {
  118.     int rv;

  119.     //批量urb初始化
  120.     usb_fill_bulk_urb(dev->bulk_in_urb,
  121.             dev->udev,
  122.             usb_rcvbulkpipe(dev->udev,
  123.                 dev->bulk_in_endpointAddr),
  124.             dev->bulk_in_buffer,
  125.             min(dev->bulk_in_size, count),
  126.             skel_read_bulk_callback,
  127.             dev);
  128.     //设置IO操作标志
  129.     spin_lock_irq(&dev->err_lock);
  130.     dev->ongoing_read = 1;
  131.     spin_unlock_irq(&dev->err_lock);

  132.     //提交urb到核心
  133.     rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
  134.     if (rv < 0) {
  135.         err("%s - failed submitting read urb, error %d",
  136.             __func__, rv);
  137.         dev->bulk_in_filled = 0;
  138.         rv = (rv == -ENOMEM) ? rv : -EIO;
  139.         spin_lock_irq(&dev->err_lock);
  140.         dev->ongoing_read = 0;
  141.         spin_unlock_irq(&dev->err_lock);
  142.     }

  143.     return rv;
  144. }
  145. //读完成回调方法
  146. static void skel_read_bulk_callback(struct urb *urb)
  147. {
  148.     struct usb_skel *dev;

  149.     dev = urb->context;

  150.     spin_lock(&dev->err_lock);
  151.     //判断URB
  152.     if (urb->status) {
  153.         if (!(urb->status == -ENOENT ||
  154.          urb->status == -ECONNRESET ||
  155.          urb->status == -ESHUTDOWN))
  156.             err("%s - nonzero write bulk status received: %d",
  157.              __func__, urb->status);

  158.         dev->errors = urb->status;
  159.     } else {
  160.         dev->bulk_in_filled = urb->actual_length;
  161.     }
  162.     dev->ongoing_read = 0;
  163.     spin_unlock(&dev->err_lock);

  164.     complete(&dev->bulk_in_completion);
  165. }
十一、USB驱动的模板
通过对USB骨架驱动的分析,可总结出USB模板

点击(此处)折叠或打开

  1. //驱动支持的设备ID列表
  2. static const struct usb_device_id xxx_table[] = {
  3.     { USB_DEVICE(USB_XXX_VENDOR_ID, USB_XXX_PRODUCT_ID) },
  4.     { }                    /* Terminating entry */
  5. };
  6. MODULE_DEVICE_TABLE(usb, xxx_table);

  7. //打开方法
  8. static int xxx_open(struct inode *inode, struct file *file)
  9. {
  10.     。。。
  11.     //增加引用计数
  12.     kref_get(&dev->kref);

  13.     file->private_data = dev;//设置文件的私有数据
  14.     。。。
  15. }
  16. //关闭方法
  17. static int xxx_release(struct inode *inode, struct file *file)
  18. {
  19.     dev = file->private_data;//获得私有数据
  20.     if (dev == NULL)
  21.         return -ENODEV;

  22.     //减少引用次数
  23.     kref_put(&dev->kref, xxx_delete);
  24.     。。。
  25. }

  26. //读完成回调方法
  27. static void xxx_read_bulk_callback(struct urb *urb)
  28. {
  29.     。。。
  30.     //判断URB
  31.     if (urb->status) {
  32.         。。。
  33.     }
  34.     complete(&dev->bulk_in_completion);
  35. }

  36. //读方法
  37. static ssize_t skel_read(struct file *file, char *buffer, size_t count,
  38.              loff_t *ppos)
  39. {
  40.     。。。
  41.         //批量urb初始化
  42.     usb_fill_bulk_urb(dev->bulk_in_urb,
  43.             dev->udev,
  44.             usb_rcvbulkpipe(dev->udev,
  45.                 dev->bulk_in_endpointAddr),
  46.             dev->bulk_in_buffer,
  47.             min(dev->bulk_in_size, count),
  48.             xxx_read_bulk_callback,
  49.             dev);
  50.     //提交urb到核心
  51.     rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
  52.     
  53.     copy_to_user(buffer,dev->bulk_in_buffer + dev->bulk_in_copied,chunk);
  54.     。。。
  55. }

  56. //写完成回调函数,当URB传输完成后调用
  57. static void xxx_write_bulk_callback(struct urb *urb)
  58. {
  59.     。。。

  60.     /*释放我们的分配缓冲区*/
  61.     usb_free_coherent(urb->dev, urb->transfer_buffer_length,
  62.              urb->transfer_buffer, urb->transfer_dma);
  63.     。。。
  64. }
  65. //写方法
  66. static ssize_t xxx_write(struct file *file, const char *user_buffer,
  67.              size_t count, loff_t *ppos)
  68. {
  69.     。。。
  70.     /* 创建一个urb */
  71.     urb = usb_alloc_urb(0, GFP_KERNEL);
  72.     if (!urb) {
  73.         retval = -ENOMEM;
  74.         goto error;
  75.     }
  76.     //分配一个缓冲区
  77.     buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
  78.                  &urb->transfer_dma);
  79.     if (!buf) {
  80.         retval = -ENOMEM;
  81.         goto error;
  82.     }
  83.     //从用户控件复制数据到缓冲区
  84.     if (copy_from_user(buf, user_buffer, writesize)) {
  85.         retval = -EFAULT;
  86.         goto error;
  87.     }

  88.     //批量urb初始化
  89.     usb_fill_bulk_urb(urb, dev->udev,
  90.              usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
  91.              buf, writesize,xxx_write_bulk_callback, dev);
  92.     urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  93.     usb_anchor_urb(urb, &dev->submitted);

  94.     //提交urb到核心
  95.     retval = usb_submit_urb(urb, GFP_KERNEL);
  96.     mutex_unlock(&dev->io_mutex);
  97.     if (retval) {
  98.         err("%s - failed submitting write urb, error %d", __func__,
  99.          retval);
  100.         goto error_unanchor;
  101.     }

  102.     //释放urb
  103.     usb_free_urb(urb);

  104.     。。。
  105. }

  106. static const struct file_operations xxx_fops = {
  107.     .owner =    THIS_MODULE,
  108.     .read =        xxx_read,//读函数
  109.     .write =    xxx_write,//写函数
  110.     .open =        xxx_open,//打开
  111.     .release =    xxx_release,//关闭
  112.     。。。
  113. };

  114. static struct usb_class_driver xxx_class = {
  115.     .name =        "xxx%d",
  116.     .fops =        &xxx_fops,//USB设备文件操作函数集合
  117.     .minor_base =    USB_XXX_MINOR_BASE,//usb次设备号基址
  118. };

  119. //探测方法,当USB设备插入时,USB核心检测到USB设备的属性和对应的USB驱动匹配时,会调用USB驱动的探测方法
  120. static int skel_probe(struct usb_interface *interface, const struct usb_device_id *id)
  121. {
  122.     。。。
  123.     
  124.     /* 注册USB设备*/
  125.     retval = usb_register_dev(interface, &xxx_class);
  126.     if (retval) {
  127.         /* something prevented us from registering this driver */
  128.         err("Not able to get a minor for this device.");
  129.         usb_set_intfdata(interface, NULL);
  130.         goto error;
  131.     }
  132.     。。。
  133. }

  134. //驱动结构体
  135. static struct usb_driver xxx_driver = {
  136.     .name =        "xxx",//驱动名
  137.     .probe =    xxx_probe,//探测方法
  138.     .disconnect =    xxx_disconnect,//断开连接的方法
  139.     .suspend =    xxx_suspend,//挂起方法
  140.     .resume =    xxx_resume,//恢复方法
  141.     .id_table =    xxx_table,//驱动支持的设备ID列表
  142.     。。。
  143. };

  144. //驱动加载函数
  145. static int __init usb_xxx_init(void)
  146. {
  147.     int result;

  148.     //注册一个USB驱动
  149.     result = usb_register(&xxx_driver);
  150.     if (result)
  151.         err("usb_register failed. Error number %d", result);

  152.     return result;
  153. }

  154. //驱动卸载函数
  155. static void __exit usb_xxx_exit(void)
  156. {
  157.     //注销一个USB驱动
  158.     usb_deregister(&xxx_driver);
  159. }

  160. module_init(usb_xxx_init);
  161. module_exit(usb_xxx_exit);













阅读(2467) | 评论(0) | 转发(0) |
1

上一篇:linux GPIO驱动

下一篇:input输入设备驱动

给主人留下些什么吧!~~