"./drivers/usb/usb-skeleton.c"是内核提供给usb设备驱动开发者的海量存储usb设备的模板程序, 程序不长, 通用性却很强,十分经典, 深入理解这个文件可以帮助我们更好的理解usb子系统以及usb设备驱动框架, 写出更好的usb海量存储设备驱动。
匹配前既然是一个usb设备驱动的模板,那么就少不了构造一个usb_driver对象并将其注册到内核中,
650 static struct usb_driver skel_driver = { 651 .name = "skeleton", 652 .probe = skel_probe, 653 .disconnect = skel_disconnect, 654 .suspend = skel_suspend, 655 .resume = skel_resume, 656 .pre_reset = skel_pre_reset, 657 .post_reset = skel_post_reset, 658 .id_table = skel_table, 659 .supports_autosuspend = 1, 660 }; 661 662 module_usb_driver(skel_driver);关于这个对象的域,在上一篇已经解释了,这里,我们主要关心的是skel_table,它决定了这个驱动匹配到哪个设备,从下面的定义可以看出,这个驱动是按照device进行匹配的,
30 static const struct usb_device_id skel_table[] = { 31 { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, 32 { } /* Terminating entry */ 33 }; 34 MODULE_DEVICE_TABLE(usb, skel_table); 匹配后 资源类接下来,看一下这个驱动对于资源类的定义,这可是整个驱动程序的纽带,管理着整个驱动程序各个函数与接口共用的资源, 不得不说这个注释真的是内核中少有的详细, skeleton主要是针对海量存储设备的,所以其资源对象中封装了很多缓冲区的信息VS中断设备只要一个urb即可搞定数据传输问题
49 struct usb_skel { 50 struct usb_device *udev; /* the usb device for this device */ 51 struct usb_interface *interface; /* the interface for this device */ 52 struct semaphore limit_sem; /* limiting the number of writes in progress 53 struct usb_anchor submitted; /* in case we need to retract our submission 54 struct urb *bulk_in_urb; /* the urb to read data with */ 55 unsigned char *bulk_in_buffer; /* the buffer to receive data */ 56 size_t bulk_in_size; /* the size of the receive buffer */ 57 size_t bulk_in_filled; /* number of bytes in the buffer */ 58 size_t bulk_in_copied; /* already copied to user space */ 59 __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */ 60 __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */ 61 int errors; /* the last request tanked */ 62 bool ongoing_read; /* a read is going on */ 63 spinlock_t err_lock; /* lock for errors */ 64 struct kref kref; 65 struct mutex io_mutex; /* synchronize I/O with disconnect */ 66 wait_queue_head_t bulk_in_wait; /* to wait for an ongoing read */ 67 };struct usb_skel
--50-->驱动操作的usb_device对象
--51-->驱动操作的usb_interface对象, 这两个都是设备信息, VS i2c-s3c2410.c 通过将设备信息在probe中拷贝出来以保存到驱动资源对象中, 这里也是同样的思路. struct usb_interface->dev域之于usb_skel以及其他接口函数, 相当于struct device域之于s3c24xx_i2c以及其他接口函数, 都是在各个接口函数中流动的
--54-->使用的urb对象
--55-->用于接收数据的buf指针
--56-->标识要接收数据长度的域
--57-->标识当前缓冲区有多少有效数据的域
--58-->标识当前缓冲区已经被拷贝走多少数据的域,skeleton不会清空缓冲区,而是使用各种长度表示来决定已经占用了多少,超出长度的部分,是否被清零无所谓。他们之间的关系见下图
--59-->bulk设备的输入端点
--60-->bulk设备的输出端点
--62-->设备可读标志位,0表示可读,1表示不可读
--64-->kref供内核引用计数用
usb_skeleton还参考内核中已有的to_platform_device等结构封装了一个to_skel_dev, 这种写法值得借鉴
68 #define to_skel_dev(d) container_of(d, struct usb_skel, kref) probe