(1)
(2)
在整个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