《Linux那些事儿之我是USB》我是U盘(17)冬天来了,春天还会远吗(一)--总结

(1)
在整个usb-storage模块的代码中,其最重要的工作在usb_stor_control_thread()的函数中。这个函数的调用是从usb_stor_acquire_resources()函数进入的。
int usb_stor_probe2(struct us_data *us)
{
result = usb_stor_acquire_resources(us);----> th = kthread_run(usb_stor_control_thread, us, "usb-storage"); 
}
然而在此之前,有四个函数:get_device_info,get_transport,get_protocol,get_pipes。这四个函数就是让驱动去认识设备的。驱动需要知道设备的名字,驱动需要知道设备是哪一种类型.
int usb_stor_probe1(struct us_data **pus,struct usb_interface *intf,const struct usb_device_id *id, struct us_unusual_dev *unusual_dev){
     
      result = associate_dev(us, intf);
       result = get_device_info(us, id, unusual_dev); //Get the unusual_devs entries and the descriptors 获得设备信息
}
/* Get the unusual_devs entries and the string descriptors */                                                   
static int get_device_info(struct us_data *us, const struct usb_device_id *id,struct us_unusual_dev *unusual_dev)     
{
struct usb_interface_descriptor *idesc = &us->pusb_intf->cur_altsetting->desc;  //整个故事就是针对一个接口的,一个接口就对应一个接口描述符
}
struct us_unusual_dev {
    const char* vendorName;
    const char* productName;
    __u8  useProtocol;
    __u8  useTransport;
    int (*initFunction)(struct us_data *);
};
struct usb_device_id usb_storage_usb_ids[] = {                                                                  
#   include "unusual_devs.h"                                                                                    
    { }     /* Terminating entry */                                                                             
};                                                                                                              
MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids);
//每一个USB_DEVICE_VER或者USB_INTERFACE_INFO就是构造一个struct usb_device_id的结构体变量,为其中的四个元素赋了值:match_flags、bInterfaceClass、bInterfaceSubClass和bInterfaceProtocol
#define USB_DEVICE_INFO(cl, sc, pr) \
    .match_flags = USB_DEVICE_ID_MATCH_DEV_INFO, \
    .bDeviceClass = (cl), \
    .bDeviceSubClass = (sc), \
    .bDeviceProtocol = (pr)
#define USB_INTERFACE_INFO(cl, sc, pr) \
    .match_flags = USB_DEVICE_ID_MATCH_INT_INFO, \
    .bInterfaceClass = (cl), \
    .bInterfaceSubClass = (sc), \
    .bInterfaceProtocol = (pr)
struct usb_device_id {
    /* which fields to match against? */
    __u16       match_flags;
    /* Used for product specific matches; range is inclusive */ 
    __u16       idVendor;
    __u16       idProduct;
    __u16       bcdDevice_lo;
    __u16       bcdDevice_hi;
    /* Used for device class matches */
    __u8        bDeviceClass;
    __u8        bDeviceSubClass;
    __u8        bDeviceProtocol;
    /* Used for interface class matches */
    __u8        bInterfaceClass;
    __u8        bInterfaceSubClass;
    __u8        bInterfaceProtocol;
    /* Used for vendor-specific interface matches */
    __u8        bInterfaceNumber;
    /* not matched against */
    kernel_ulong_t  driver_info
        __attribute__((aligned(sizeof(kernel_ulong_t))));
};

(2)
USB规范或者说USB协议,把USB设备分成了很多类,然而每个类又分成子类。USB协议也是,首先每个接口属于一个Class,(为什么是把接口分类,而不把设备分类?在USB设备驱动中,因为每个设备驱动对应的是一种接口,而不是一种设备),然后Class下面分了SubClass,接着SubClass下面又按各种设备所遵循的不同的通信协议继续细分。
USB协议中为每一种Class、每一种SubClass和每一种Protocol定义一个数值,比如Mass Storage的Class就是0x08,USB_CLASS_MASS_STORAGE这个宏在include/linux/usb/ch9.h中定义,其值正是8。
#define USB_CLASS_MASS_STORAGE      8

USUAL_DEV(USB_SC_RBC, USB_PR_CB)

把这个宏展开,就是说定义了这么一个usb_device_id结构体变量,
match_flags=USB_DEVICE_ID_MATCH_INT_INFO
bInterfaceClass=USB_CLASS_MASS_STORAGE
bInterfaceSubClass=US_SC_RBC
bInterfaceProtocol=US_PR_CB
match_flag是给USB Core去用的,USB Core负责给设备寻找适合它的驱动,负责给驱动寻找适合它的设备,它所比较的就是struct usb_device_id的变量,而struct usb_device_id结构体中有许多成员,告诉USB Core,你只要比较bInterfaceClass,bInterfaceSubClass和bInterfaceProtocol即可。include/linux/mod_devicetable.h中针对struct usb_device_id中的每一个要比较的项定义了一个宏:

#define USB_DEVICE_ID_MATCH_VENDOR      0x0001                                                        
#define USB_DEVICE_ID_MATCH_PRODUCT     0x0002                                                        
#define USB_DEVICE_ID_MATCH_DEV_LO      0x0004                                                        
#define USB_DEVICE_ID_MATCH_DEV_HI      0x0008                                                        
#define USB_DEVICE_ID_MATCH_DEV_CLASS       0x0010                                                    
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS    0x0020                                                    
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL    0x0040                                                    
#define USB_DEVICE_ID_MATCH_INT_CLASS       0x0080                                                    
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS    0x0100                                                    
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL    0x0200                                                    
#define USB_DEVICE_ID_MATCH_INT_NUMBER      0x0400
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux技术芯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值