probe,disconnect,id_table,這三個咚咚中首先要登場亮相的是id_table,它是幹嘛用的呢?
我們說過,一個device只能綁定一個driver,但driver並非只能支援一種裝置,道理很簡單,比如我有兩塊隨身碟,那麼我可以一起都插入,但是我只需要載入一個模組,usb-storage,沒聽說過插入兩塊隨身碟就得載入兩次驅動程式的,除非這兩塊隨身碟本身就得使用不同的驅動程式.也正是因為一個模組可以被多個裝置共用,才會有模組計數這麼一個說法.
ok,既然一個driver可以支援多個device,那麼當發現一個device的時候,如何知道哪個driver才是她的Mr.Right呢?這就是id_table的用處,讓每一個struct usb_driver準備一張表,裡邊註明該driver支援哪些裝置,這總可以了吧.如果你這個裝置屬於這張表裡的,那麼ok,綁定吧,如果不屬於這張表裡的,那麼不好意思,您請便.哪涼快上哪去.
來自struct usb_driver中的id_table,
const struct usb_device_id *id_table;
實際上是一個指標,一個struct usb_device_id結構體的指標,當然賦了值以後就是代表一個數組名了,正如我們在定義struct usb_driver usb_storage_driver中所賦的值那樣,.id_table=storage_usb_ids,那好,我們來看一下usb_device_id這究竟是怎樣一個結構體.
struct usb_device_id來自include/linux/mod_devicetable.h,
40 /*
41 * Device table entry for "new style" table-driven USB drivers.
42 * User mode code can read these tables to choose which modules to load.
43 * Declare the table as a MODULE_DEVICE_TABLE.
44 *
45 * A probe() parameter will point to a matching entry from this table.
46 * Use the driver_info field for each match to hold information tied
47 * to that match: device quirks, etc.
48 *
49 * Terminate the driver's table with an all-zeroes entry.
50 * Use the flag values to control which fields are compared.
51 */
52
53 /**
54 * struct usb_device_id - identifies USB devices for probing and hotplugging
55 * @match_flags: Bit mask controlling of the other fields are used to match
56 * against new devices. Any field except for driver_info may be used,
57 * although some only make sense in conjunction with other fields.
58 * This is usually set by a USB_DEVICE_*() macro, which sets all
59 * other fields in this structure except for driver_info.
60 * @idVendor: USB vendor ID for a device; numbers are assigned
61 * by the USB forum to its members.
62 * @idProduct: Vendor-assigned product ID.
63 * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
64 * This is also used to identify individual product versions, for
65 * a range consisting of a single device.
66 * @bcdDevice_hi: High end of version number range. The range of product
67 * versions is inclusive.
68 * @bDeviceClass: Class of device; numbers are assigned
69 * by the USB forum. Products may choose to implement classes,
70 * or be vendor-specific. Device classes specify behavior of all
71 * the interfaces on a devices.
72 * @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
73 * @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
74 * @bInterfaceClass: Class of interface; numbers are assigned
75 * by the USB forum. Products may choose to implement classes,
76 * or be vendor-specific. Interface classes specify behavior only
77 * of a given interface; other interfaces may support other classes.
78 * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
79 * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
80 * @driver_info: Holds information used by the driver. Usually it holds
81 * a pointer to a descriptor understood by the driver, or perhaps
82 * device flags.
83 *
84 * In most cases, drivers will create a table of device IDs by using
85 * USB_DEVICE(), or similar macros designed for that purpose.
86 * They will then export it to userspace using MODULE_DEVICE_TABLE(),
87 * and provide it to the USB core through their usb_driver structure.
88 *
89 * See the usb_match_id() function for information about how matches are
90 * performed. Briefly, you will normally use one of several macros to help
91 * construct these entries. Each entry you provide will either identify
92 * one or more specific products, or will identify a class of products
93 * which have agreed to behave the same. You should put the more specific
94 * matches towards the beginning of your table, so that driver_info can
95 * record quirks of specific products.
96 */
97 struct usb_device_id {
98 /* which fields to match against? */
99 __u16 match_flags;
100
101 /* Used for product specific matches; range is inclusive */
102 __u16 idVendor;
103 __u16 idProduct;
104 __u16 bcdDevice_lo;
105 __u16 bcdDevice_hi;
106
107 /* Used for device class matches */
108 __u8 bDeviceClass;
109 __u8 bDeviceSubClass;
110 __u8 bDeviceProtocol;
111
112 /* Used for interface class matches */
113 __u8 bInterfaceClass;
114 __u8 bInterfaceSubClass;
115 __u8 bInterfaceProtocol;
116
117 /* not matched against */
118 kernel_ulong_t driver_info;
119 };
實際上這個結構體對每一個usb裝置來說,就相當於是她的身份證,記錄了她的一些基本資料,通常我們的身份證上會記錄我們的姓名,性別,出生年月,戶口地址等等,而usb裝置她也有她需要記錄的資訊,以區分她和別的usb裝置,比如Vendor-廠家,Product-產品,以及其他一些比如產品編號,產品的類別,遵循的協議,這些都會在usb的規範裡邊找到對應的冬冬.暫且先不細說.
於是我們知道,一個usb_driver會把它的這張id表去和每一個usb裝置的實際情況進行比較,如果該裝置的實際情況和這張表裡的某一個id相同,準確地說,只有這許多特徵都吻合,才能夠把一個usb device和這個usb driver進行綁定,這些特徵哪怕差一點也不行.就像我們每個人都是一道弧,都在不停尋找能讓彼此嵌成完整的圓的另一道弧,事實卻是,每個人對∏(PI)的理解不盡相同,而圓心能否重合,或許只有痛過才知道.差之毫釐,失之交臂.
那麼usb裝置的實際情況是什麼時候建立起來的?嗯,在介紹.probe指標之前有必要先談一談另一個資料結構了,她就是struct usb_device.