Chinaunix首页 | 论坛 | 博客
  • 博客访问: 67535
  • 博文数量: 26
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 12
  • 用 户 组: 普通用户
  • 注册时间: 2014-10-15 21:22
文章分类
文章存档

2014年(26)

我的朋友

分类: LINUX

2014-10-23 20:49:12

进行ch341相关的usb设备读写.
在插入usb设备驱动模块usb-skeleton.ko之后,可通过/dev/skel0文件读写usb设备. 
先写十几个byte的字符, 然后再读设备. 读写/dev/skel0文件的代码如下:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <errno.h>
  6. #include <termios.h>


  7. int main(int argc, char* argv[])
  8. {
  9.     int fd; /* File descriptor for the port */
  10.     int i;
  11.     int iRet;
  12.     char *ptr = "1234567890abcdef";
  13.     size_t count = 16;
  14.     char buf[1024];

  15.     if(argc >= 2) {
  16.         ptr = argv[1];
  17.         count = strlen(argv[1]);
  18.     }
  19.     printf("[%s-%d]tracing: \n", __FILE__, __LINE__);
  20.     fd = open("/dev/skel0", O_RDWR);
  21.     if (fd < 0) { /** error **/
  22.         perror("open");
  23.         printf("[%s-%d] open error!!!\n", __FILE__, __LINE__);
  24.         iRet = fd;
  25.         goto err1;
  26.     }
  27.     //iRet = write(fd, "1234567890abcdef", 16);
  28.     iRet = write(fd, ptr, count);
  29.     if (iRet < 0) {
  30.         printf("[%s-%d] write error!!!\n", __FILE__, __LINE__);
  31.     }

  32.     iRet = read(fd, buf, count);
  33.     if (iRet < 0) {
  34.         printf("[%s-%d] read error!!!\n", __FILE__, __LINE__);
  35.     } else {
  36.         for(i = 0; i < iRet; i++) {
  37.             printf("[0x%02x - %c]", buf[i], buf[i]);
  38.         }
  39.         printf("\n");
  40.     }

  41.     close(fd);
  42. err1:
  43.     return iRet;
  44. }
1.编译, 运行此代码, 发现ch341接到com串口的一端收到乱码, 并且程序卡住了, ch341接到com串口的一端发出数据后, 没打印输出, 程序仍卡住. "ctrl+c"也不能退出.
2.从现象可猜测, 数据写的过程已完成, 程序很可能卡在读数据上. 对usb-skeleton.c文件中的skel_read()函数中及其调用的函数中所有可能卡住的地方加"printk("[%s-%d]tracing !\n", __func__, __LINE__);"打印执行路径的语句. 发现代码卡在"wait_for_completion(&dev->bulk_in_completion);"
3.分析其执行条件if (!dev->processed_urb) {...}. 查看代码, 没有发现其它地方对其清零. 也没有初始化清零的动作. 从代码注释看初始化更应该是置1. 猜测是dev->processed_urb初始设置错误. 在skel_probe()函数中加入初始置1的代码"dev->processed_urb = 1;". 重新编译/插入模块/运行代码. 程序运行后停下, ch341接到com串口的一端发出数据后, 有打印输出, 然后程序退出. 至此, 收发操作都有. 然而收到后打印的数据并非ch341对端发出的数据.
4.考虑到ch341芯片是专门用于usb转串口的, 而RS-232串口有特定的通信波特率/校验位/数据位/停止位, 而本实验中并没有进行相应设置. 传输乱码可能的原因是其中一项设置不一致造成的. 抱着试一试的想法, 将ch341接串口一端的串口调试助手的通信波特率由115200到300挨个试, 发现波特率为19200时, ch341接口两端都收到对方发来的数据, 并且数据收发正确. 暂没发现其它问题.

修改后的usb-skeletion.c内容如下:

点击(此处)折叠或打开

  1. /*
  2.  * USB Skeleton driver - 2.2
  3.  *
  4.  * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
  5.  *
  6.  *    This program is free software; you can redistribute it and/or
  7.  *    modify it under the terms of the GNU General Public License as
  8.  *    published by the Free Software Foundation, version 2.
  9.  *
  10.  * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
  11.  * but has been rewritten to be easier to read and use.
  12.  *
  13.  */

  14. #include <linux/kernel.h>
  15. #include <linux/errno.h>
  16. #include <linux/init.h>
  17. #include <linux/slab.h>
  18. #include <linux/module.h>
  19. #include <linux/kref.h>
  20. #include <linux/uaccess.h>
  21. #include <linux/usb.h>
  22. #include <linux/mutex.h>


  23. /* Define these values to match your devices */
  24. #define USB_SKEL_VENDOR_ID    0x1A86
  25. #define USB_SKEL_PRODUCT_ID    0x7523

  26. /* table of devices that work with this driver */
  27. static const struct usb_device_id skel_table[] = {
  28.     { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
  29.     { }                    /* Terminating entry */
  30. };
  31. MODULE_DEVICE_TABLE(usb, skel_table);


  32. /* Get a minor range for your devices from the usb maintainer */
  33. #define USB_SKEL_MINOR_BASE    192

  34. /* our private defines. if this grows any larger, use your own .h file */
  35. #define MAX_TRANSFER        (PAGE_SIZE - 512)
  36. /* MAX_TRANSFER is chosen so that the VM is not stressed by
  37.    allocations > PAGE_SIZE and the number of packets in a page
  38.    is an integer 512 is the largest possible packet on EHCI */
  39. #define WRITES_IN_FLIGHT    8
  40. /* arbitrarily chosen */

  41. /* Structure to hold all of our device specific stuff */
  42. struct usb_skel {
  43.     struct usb_device    *udev;            /* the usb device for this device */
  44.     struct usb_interface    *interface;        /* the interface for this device */
  45.     struct semaphore    limit_sem;        /* limiting the number of writes in progress */
  46.     struct usb_anchor    submitted;        /* in case we need to retract our submissions */
  47.     struct urb        *bulk_in_urb;        /* the urb to read data with */
  48.     unsigned char *bulk_in_buffer;    /* the buffer to receive data */
  49.     size_t            bulk_in_size;        /* the size of the receive buffer */
  50.     size_t            bulk_in_filled;        /* number of bytes in the buffer */
  51.     size_t            bulk_in_copied;        /* already copied to user space */
  52.     __u8            bulk_in_endpointAddr;    /* the address of the bulk in endpoint */
  53.     __u8            bulk_out_endpointAddr;    /* the address of the bulk out endpoint */
  54.     int            errors;            /* the last request tanked */
  55.     int            open_count;        /* count the number of openers */
  56.     bool            ongoing_read;        /* a read is going on */
  57.     bool            processed_urb;        /* indicates we haven't processed the urb */
  58.     spinlock_t        err_lock;        /* lock for errors */
  59.     struct kref        kref;
  60.     struct mutex        io_mutex;        /* synchronize I/O with disconnect */
  61.     struct completion    bulk_in_completion;    /* to wait for an ongoing read */
  62. };
  63. #define to_skel_dev(d) container_of(d, struct usb_skel, kref)

  64. static struct usb_driver skel_driver;
  65. static void skel_draw_down(struct usb_skel *dev);

  66. static void skel_delete(struct kref *kref)
  67. {
  68.     struct usb_skel *dev = to_skel_dev(kref);

  69.     usb_free_urb(dev->bulk_in_urb);
  70.     usb_put_dev(dev->udev);
  71.     kfree(dev->bulk_in_buffer);
  72.     kfree(dev);
  73. }

  74. static int skel_open(struct inode *inode, struct file *file)
  75. {
  76.     struct usb_skel *dev;
  77.     struct usb_interface *interface;
  78.     int subminor;
  79.     int retval = 0;

  80.     subminor = iminor(inode);

  81.     interface = usb_find_interface(&skel_driver, subminor);
  82.     if (!interface) {
  83.         err("%s - error, can't find device for minor %d",
  84.          __func__, subminor);
  85.         retval = -ENODEV;
  86.         goto exit;
  87.     }

  88.     dev = usb_get_intfdata(interface);
  89.     if (!dev) {
  90.         retval = -ENODEV;
  91.         goto exit;
  92.     }

  93.     /* increment our usage count for the device */
  94.     kref_get(&dev->kref);

  95.     /* lock the device to allow correctly handling errors
  96.      * in resumption */
  97.     mutex_lock(&dev->io_mutex);

  98.     if (!dev->open_count++) {
  99.         retval = usb_autopm_get_interface(interface);
  100.             if (retval) {
  101.                 dev->open_count--;
  102.                 mutex_unlock(&dev->io_mutex);
  103.                 kref_put(&dev->kref, skel_delete);
  104.                 goto exit;
  105.             }
  106.     } /* else { //uncomment this block if you want exclusive open
  107.         retval = -EBUSY;
  108.         dev->open_count--;
  109.         mutex_unlock(&dev->io_mutex);
  110.         kref_put(&dev->kref, skel_delete);
  111.         goto exit;
  112.     } */
  113.     /* prevent the device from being autosuspended */

  114.     /* save our object in the file's private structure */
  115.     file->private_data = dev;
  116.     mutex_unlock(&dev->io_mutex);

  117. exit:
  118.     return retval;
  119. }

  120. static int skel_release(struct inode *inode, struct file *file)
  121. {
  122.     struct usb_skel *dev;

  123.     dev = file->private_data;
  124.     if (dev == NULL)
  125.         return -ENODEV;

  126.     /* allow the device to be autosuspended */
  127.     mutex_lock(&dev->io_mutex);
  128.     if (!--dev->open_count && dev->interface)
  129.         usb_autopm_put_interface(dev->interface);
  130.     mutex_unlock(&dev->io_mutex);

  131.     /* decrement the count on our device */
  132.     kref_put(&dev->kref, skel_delete);
  133.     return 0;
  134. }

  135. static int skel_flush(struct file *file, fl_owner_t id)
  136. {
  137.     struct usb_skel *dev;
  138.     int res;

  139.     dev = file->private_data;
  140.     if (dev == NULL)
  141.         return -ENODEV;

  142.     /* wait for io to stop */
  143.     mutex_lock(&dev->io_mutex);
  144.     skel_draw_down(dev);

  145.     /* read out errors, leave subsequent opens a clean slate */
  146.     spin_lock_irq(&dev->err_lock);
  147.     res = dev->errors ? (dev->errors == -EPIPE ? -EPIPE : -EIO) : 0;
  148.     dev->errors = 0;
  149.     spin_unlock_irq(&dev->err_lock);

  150.     mutex_unlock(&dev->io_mutex);

  151.     return res;
  152. }

  153. static void skel_read_bulk_callback(struct urb *urb)
  154. {
  155.     struct usb_skel *dev;

  156.     dev = urb->context;

  157.     spin_lock(&dev->err_lock);
  158.     /* sync/async unlink faults aren't errors */
  159.     if (urb->status) {
  160.         if (!(urb->status == -ENOENT ||
  161.          urb->status == -ECONNRESET ||
  162.          urb->status == -ESHUTDOWN))
  163.             err("%s - nonzero write bulk status received: %d",
  164.              __func__, urb->status);

  165.         dev->errors = urb->status;
  166.     } else {
  167.         dev->bulk_in_filled = urb->actual_length;
  168.     }
  169.     dev->ongoing_read = 0;
  170.     spin_unlock(&dev->err_lock);

  171.     complete(&dev->bulk_in_completion);
  172. }

  173. static int skel_do_read_io(struct usb_skel *dev, size_t count)
  174. {
  175.     int rv;

  176.     /* prepare a read */
  177.     usb_fill_bulk_urb(dev->bulk_in_urb,
  178.             dev->udev,
  179.             usb_rcvbulkpipe(dev->udev,
  180.                 dev->bulk_in_endpointAddr),
  181.             dev->bulk_in_buffer,
  182.             min(dev->bulk_in_size, count),
  183.             skel_read_bulk_callback,
  184.             dev);
  185.     /* tell everybody to leave the URB alone */
  186.     spin_lock_irq(&dev->err_lock);
  187.     dev->ongoing_read = 1;
  188.     spin_unlock_irq(&dev->err_lock);

  189.     /* do it */
  190.     rv = usb_submit_urb(dev->bulk_in_urb, GFP_KERNEL);
  191.     if (rv < 0) {
  192.         err("%s - failed submitting read urb, error %d",
  193.             __func__, rv);
  194.         dev->bulk_in_filled = 0;
  195.         rv = (rv == -ENOMEM) ? rv : -EIO;
  196.         spin_lock_irq(&dev->err_lock);
  197.         dev->ongoing_read = 0;
  198.         spin_unlock_irq(&dev->err_lock);
  199.     }

  200.     return rv;
  201. }

  202. static ssize_t skel_read(struct file *file, char *buffer, size_t count,
  203.              loff_t *ppos)
  204. {
  205.     struct usb_skel *dev;
  206.     int rv;
  207.     bool ongoing_io;

  208.     dev = file->private_data;

  209.     /* if we cannot read at all, return EOF */
  210.     if (!dev->bulk_in_urb || !count)
  211.         return 0;

  212.     /* no concurrent readers */
  213.     rv = mutex_lock_interruptible(&dev->io_mutex);
  214.     if (rv < 0)
  215.         return rv;

  216.     if (!dev->interface) {        /* disconnect() was called */
  217.         rv = -ENODEV;
  218.         goto exit;
  219.     }

  220.     /* if IO is under way, we must not touch things */
  221. retry:
  222.     spin_lock_irq(&dev->err_lock);
  223.     ongoing_io = dev->ongoing_read;
  224.     spin_unlock_irq(&dev->err_lock);

  225.     if (ongoing_io) {
  226.         /* nonblocking IO shall not wait */
  227.         if (file->f_flags & O_NONBLOCK) {
  228.             rv = -EAGAIN;
  229.             goto exit;
  230.         }
  231.         /*
  232.          * IO may take forever
  233.          * hence wait in an interruptible state
  234.          */
  235.         rv = wait_for_completion_interruptible(&dev->bulk_in_completion);
  236.         if (rv < 0)
  237.             goto exit;
  238.         /*
  239.          * by waiting we also semiprocessed the urb
  240.          * we must finish now
  241.          */
  242.         dev->bulk_in_copied = 0;
  243.         dev->processed_urb = 1;
  244.     }

  245.     if (!dev->processed_urb) {
  246.         /*
  247.          * the URB hasn't been processed
  248.          * do it now
  249.          */
  250.         wait_for_completion(&dev->bulk_in_completion);
  251.         dev->bulk_in_copied = 0;
  252.         dev->processed_urb = 1;
  253.     }

  254.     /* errors must be reported */
  255.     rv = dev->errors;
  256.     if (rv < 0) {
  257.         /* any error is reported once */
  258.         dev->errors = 0;
  259.         /* to preserve notifications about reset */
  260.         rv = (rv == -EPIPE) ? rv : -EIO;
  261.         /* no data to deliver */
  262.         dev->bulk_in_filled = 0;
  263.         /* report it */
  264.         goto exit;
  265.     }

  266.     /*
  267.      * if the buffer is filled we may satisfy the read
  268.      * else we need to start IO
  269.      */

  270.     if (dev->bulk_in_filled) {
  271.         /* we had read data */
  272.         size_t available = dev->bulk_in_filled - dev->bulk_in_copied;
  273.         size_t chunk = min(available, count);

  274.         if (!available) {
  275.             /*
  276.              * all data has been used
  277.              * actual IO needs to be done
  278.              */
  279.             rv = skel_do_read_io(dev, count);
  280.             if (rv < 0)
  281.                 goto exit;
  282.             else
  283.                 goto retry;
  284.         }
  285.         /*
  286.          * data is available
  287.          * chunk tells us how much shall be copied
  288.          */

  289.         if (copy_to_user(buffer,
  290.                  dev->bulk_in_buffer + dev->bulk_in_copied,
  291.                  chunk))
  292.             rv = -EFAULT;
  293.         else
  294.             rv = chunk;

  295.         dev->bulk_in_copied += chunk;

  296.         /*
  297.          * if we are asked for more than we have,
  298.          * we start IO but don't wait
  299.          */
  300.         if (available < count)
  301.             skel_do_read_io(dev, count - chunk);
  302.     } else {
  303.         /* no data in the buffer */
  304.         rv = skel_do_read_io(dev, count);
  305.         if (rv < 0)
  306.             goto exit;
  307.         else if (!(file->f_flags & O_NONBLOCK))
  308.             goto retry;
  309.         rv = -EAGAIN;
  310.     }
  311. exit:
  312.     mutex_unlock(&dev->io_mutex);
  313.     return rv;
  314. }

  315. static void skel_write_bulk_callback(struct urb *urb)
  316. {
  317.     struct usb_skel *dev;

  318.     dev = urb->context;

  319.     /* sync/async unlink faults aren't errors */
  320.     if (urb->status) {
  321.         if (!(urb->status == -ENOENT ||
  322.          urb->status == -ECONNRESET ||
  323.          urb->status == -ESHUTDOWN))
  324.             err("%s - nonzero write bulk status received: %d",
  325.              __func__, urb->status);

  326.         spin_lock(&dev->err_lock);
  327.         dev->errors = urb->status;
  328.         spin_unlock(&dev->err_lock);
  329.     }

  330.     /* free up our allocated buffer */
  331.     usb_free_coherent(urb->dev, urb->transfer_buffer_length,
  332.              urb->transfer_buffer, urb->transfer_dma);
  333.     up(&dev->limit_sem);
  334. }

  335. static ssize_t skel_write(struct file *file, const char *user_buffer,
  336.              size_t count, loff_t *ppos)
  337. {
  338.     struct usb_skel *dev;
  339.     int retval = 0;
  340.     struct urb *urb = NULL;
  341.     char *buf = NULL;
  342.     size_t writesize = min(count, (size_t)MAX_TRANSFER);

  343.     dev = file->private_data;

  344.     /* verify that we actually have some data to write */
  345.     if (count == 0)
  346.         goto exit;

  347.     /*
  348.      * limit the number of URBs in flight to stop a user from using up all
  349.      * RAM
  350.      */
  351.     if (!(file->f_flags & O_NONBLOCK)) {
  352.         if (down_interruptible(&dev->limit_sem)) {
  353.             retval = -ERESTARTSYS;
  354.             goto exit;
  355.         }
  356.     } else {
  357.         if (down_trylock(&dev->limit_sem)) {
  358.             retval = -EAGAIN;
  359.             goto exit;
  360.         }
  361.     }

  362.     spin_lock_irq(&dev->err_lock);
  363.     retval = dev->errors;
  364.     if (retval < 0) {
  365.         /* any error is reported once */
  366.         dev->errors = 0;
  367.         /* to preserve notifications about reset */
  368.         retval = (retval == -EPIPE) ? retval : -EIO;
  369.     }
  370.     spin_unlock_irq(&dev->err_lock);
  371.     if (retval < 0)
  372.         goto error;

  373.     /* create a urb, and a buffer for it, and copy the data to the urb */
  374.     urb = usb_alloc_urb(0, GFP_KERNEL);
  375.     if (!urb) {
  376.         retval = -ENOMEM;
  377.         goto error;
  378.     }

  379.     buf = usb_alloc_coherent(dev->udev, writesize, GFP_KERNEL,
  380.                  &urb->transfer_dma);
  381.     if (!buf) {
  382.         retval = -ENOMEM;
  383.         goto error;
  384.     }

  385.     if (copy_from_user(buf, user_buffer, writesize)) {
  386.         retval = -EFAULT;
  387.         goto error;
  388.     }

  389.     /* this lock makes sure we don't submit URBs to gone devices */
  390.     mutex_lock(&dev->io_mutex);
  391.     if (!dev->interface) {        /* disconnect() was called */
  392.         mutex_unlock(&dev->io_mutex);
  393.         retval = -ENODEV;
  394.         goto error;
  395.     }

  396.     /* initialize the urb properly */
  397.     usb_fill_bulk_urb(urb, dev->udev,
  398.              usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
  399.              buf, writesize, skel_write_bulk_callback, dev);
  400.     urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
  401.     usb_anchor_urb(urb, &dev->submitted);

  402.     /* send the data out the bulk port */
  403.     retval = usb_submit_urb(urb, GFP_KERNEL);
  404.     mutex_unlock(&dev->io_mutex);
  405.     if (retval) {
  406.         err("%s - failed submitting write urb, error %d", __func__,
  407.          retval);
  408.         goto error_unanchor;
  409.     }

  410.     /*
  411.      * release our reference to this urb, the USB core will eventually free
  412.      * it entirely
  413.      */
  414.     usb_free_urb(urb);


  415.     return writesize;

  416. error_unanchor:
  417.     usb_unanchor_urb(urb);
  418. error:
  419.     if (urb) {
  420.         usb_free_coherent(dev->udev, writesize, buf, urb->transfer_dma);
  421.         usb_free_urb(urb);
  422.     }
  423.     up(&dev->limit_sem);

  424. exit:
  425.     return retval;
  426. }

  427. static const struct file_operations skel_fops = {
  428.     .owner =    THIS_MODULE,
  429.     .read =        skel_read,
  430.     .write =    skel_write,
  431.     .open =        skel_open,
  432.     .release =    skel_release,
  433.     .flush =    skel_flush,
  434.     .llseek =    noop_llseek,
  435. };

  436. /*
  437.  * usb class driver info in order to get a minor number from the usb core,
  438.  * and to have the device registered with the driver core
  439.  */
  440. static struct usb_class_driver skel_class = {
  441.     .name =        "skel%d",
  442.     .fops =        &skel_fops,
  443.     .minor_base =    USB_SKEL_MINOR_BASE,
  444. };

  445. static int skel_probe(struct usb_interface *interface,
  446.          const struct usb_device_id *id)
  447. {
  448.     struct usb_skel *dev;
  449.     struct usb_host_interface *iface_desc;
  450.     struct usb_endpoint_descriptor *endpoint;
  451.     size_t buffer_size;
  452.     int i;
  453.     int retval = -ENOMEM;

  454.     /* allocate memory for our device state and initialize it */
  455.     dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  456.     if (!dev) {
  457.         err("Out of memory");
  458.         goto error;
  459.     }
  460.     kref_init(&dev->kref);
  461.     sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
  462.     mutex_init(&dev->io_mutex);
  463.     spin_lock_init(&dev->err_lock);
  464.     init_usb_anchor(&dev->submitted);
  465.     init_completion(&dev->bulk_in_completion);

  466.     dev->udev = usb_get_dev(interface_to_usbdev(interface));
  467.     dev->interface = interface;

  468.     dev->processed_urb = 1; //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  469.     /* set up the endpoint information */
  470.     /* use only the first bulk-in and bulk-out endpoints */
  471.     iface_desc = interface->cur_altsetting;
  472.     for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
  473.         endpoint = &iface_desc->endpoint[i].desc;

  474.         if (!dev->bulk_in_endpointAddr &&
  475.          usb_endpoint_is_bulk_in(endpoint)) {
  476.             /* we found a bulk in endpoint */
  477.             buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
  478.             dev->bulk_in_size = buffer_size;
  479.             dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
  480.             dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
  481.             if (!dev->bulk_in_buffer) {
  482.                 err("Could not allocate bulk_in_buffer");
  483.                 goto error;
  484.             }
  485.             dev->bulk_in_urb = usb_alloc_urb(0, GFP_KERNEL);
  486.             if (!dev->bulk_in_urb) {
  487.                 err("Could not allocate bulk_in_urb");
  488.                 goto error;
  489.             }
  490.         }

  491.         if (!dev->bulk_out_endpointAddr &&
  492.          usb_endpoint_is_bulk_out(endpoint)) {
  493.             /* we found a bulk out endpoint */
  494.             dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
  495.         }
  496.     }
  497.     if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) {
  498.         err("Could not find both bulk-in and bulk-out endpoints");
  499.         goto error;
  500.     }

  501.     /* save our data pointer in this interface device */
  502.     usb_set_intfdata(interface, dev);

  503.     /* we can register the device now, as it is ready */
  504.     retval = usb_register_dev(interface, &skel_class);
  505.     if (retval) {
  506.         /* something prevented us from registering this driver */
  507.         err("Not able to get a minor for this device.");
  508.         usb_set_intfdata(interface, NULL);
  509.         goto error;
  510.     }

  511.     /* let the user know what node this device is now attached to */
  512.     dev_info(&interface->dev,
  513.          "USB Skeleton device now attached to USBSkel-%d",
  514.          interface->minor);
  515.     return 0;

  516. error:
  517.     if (dev)
  518.         /* this frees allocated memory */
  519.         kref_put(&dev->kref, skel_delete);
  520.     return retval;
  521. }

  522. static void skel_disconnect(struct usb_interface *interface)
  523. {
  524.     struct usb_skel *dev;
  525.     int minor = interface->minor;

  526.     dev = usb_get_intfdata(interface);
  527.     usb_set_intfdata(interface, NULL);

  528.     /* give back our minor */
  529.     usb_deregister_dev(interface, &skel_class);

  530.     /* prevent more I/O from starting */
  531.     mutex_lock(&dev->io_mutex);
  532.     dev->interface = NULL;
  533.     mutex_unlock(&dev->io_mutex);

  534.     usb_kill_anchored_urbs(&dev->submitted);

  535.     /* decrement our usage count */
  536.     kref_put(&dev->kref, skel_delete);

  537.     dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor);
  538. }

  539. static void skel_draw_down(struct usb_skel *dev)
  540. {
  541.     int time;

  542.     time = usb_wait_anchor_empty_timeout(&dev->submitted, 1000);
  543.     if (!time)
  544.         usb_kill_anchored_urbs(&dev->submitted);
  545.     usb_kill_urb(dev->bulk_in_urb);
  546. }

  547. static int skel_suspend(struct usb_interface *intf, pm_message_t message)
  548. {
  549.     struct usb_skel *dev = usb_get_intfdata(intf);

  550.     if (!dev)
  551.         return 0;
  552.     skel_draw_down(dev);
  553.     return 0;
  554. }

  555. static int skel_resume(struct usb_interface *intf)
  556. {
  557.     return 0;
  558. }

  559. static int skel_pre_reset(struct usb_interface *intf)
  560. {
  561.     struct usb_skel *dev = usb_get_intfdata(intf);

  562.     mutex_lock(&dev->io_mutex);
  563.     skel_draw_down(dev);

  564.     return 0;
  565. }

  566. static int skel_post_reset(struct usb_interface *intf)
  567. {
  568.     struct usb_skel *dev = usb_get_intfdata(intf);

  569.     /* we are sure no URBs are active - no locking needed */
  570.     dev->errors = -EPIPE;
  571.     mutex_unlock(&dev->io_mutex);

  572.     return 0;
  573. }

  574. static struct usb_driver skel_driver = {
  575.     .name =        "skeleton",
  576.     .probe =    skel_probe,
  577.     .disconnect =    skel_disconnect,
  578.     .suspend =    skel_suspend,
  579.     .resume =    skel_resume,
  580.     .pre_reset =    skel_pre_reset,
  581.     .post_reset =    skel_post_reset,
  582.     .id_table =    skel_table,
  583.     .supports_autosuspend = 1,
  584. };

  585. static int __init usb_skel_init(void)
  586. {
  587.     int result;

  588.     /* register this driver with the USB subsystem */
  589.     result = usb_register(&skel_driver);
  590.     if (result)
  591.         err("usb_register failed. Error number %d", result);

  592.     return result;
  593. }

  594. static void __exit usb_skel_exit(void)
  595. {
  596.     /* deregister this driver with the USB subsystem */
  597.     usb_deregister(&skel_driver);
  598. }

  599. module_init(usb_skel_init);
  600. module_exit(usb_skel_exit);

  601. MODULE_LICENSE("GPL");


阅读(1371) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~