天天看點

《Linux那些事兒之我是USB》我是U盤(10)我是誰的他?

probe,disconnect,id_table,這三個元素中首先要登場亮相的是id_table,它是幹什麼用的呢?

我們說過,一個裝置隻能綁定一個驅動,但驅動并非隻能支援一種裝置。道理很簡單,比如我有兩塊U盤,那麼我可以一起都插入,但是我隻需要加載一個子產品,usb-storage。沒聽說過插入兩塊U盤就得加載兩次驅動程式的,除非這兩塊U盤本身就得使用不同的驅動程式。也正是因為一個子產品可以被多個裝置共用,才會有“子產品計數”這個說法。

既然一個驅動可以支援多個裝置,那麼當發現一個裝置時,如何知道哪個才是它的驅動呢?這就是id_table的用處,讓每一個struct usb_driver準備一張表,裡面注明該驅動支援哪些裝置,這總可以了吧。如果這個裝置屬于這張表裡的,那麼綁定,如果不屬于這張表裡的,那麼不好意思,您請便。

id_table來自struct usb_driver中:

const struct usb_device_id *id_table;

它實際上是一個指針,一個structusb_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:

98 struct usb_device_id {

99

100 __u16match_flags;

101

102

103 __u16idVendor;

104 __u16idProduct;

105 __u16bcdDevice_lo;

106 __u16bcdDevice_hi;

107

108

109 __u8bDeviceClass;

110 __u8bDeviceSubClass;

111 __u8bDeviceProtocol;

112

113

114 __u8bInterfaceClass;

115 __u8bInterfaceSubClass;

116 __u8bInterfaceProtocol;

117

118

119 kernel_ulong_t driver_info;

120 };

實際上這個結構體對每一個USB裝置來說,就相當于是它的身份證,記錄了它的一些基本資訊。通常我們的身份證上會記錄我們的姓名,性别,出生年月,戶口位址等,而USB裝置也有它需要記錄的資訊,以區分它和别的USB裝置。比如Vendor-廠家,Product-産品,以及其他一些比如産品編号、産品的類别、遵循的協定,這些都會在USB的規範裡邊找到對應的成員。

于是我們知道,一個usb_driver會把它的id表和每一個USB裝置的實際情況進行比較,如果該裝置的實際情況和這張表裡的某一個id相同,準确地說,隻有這許多特征都吻合,才能夠把一個USB裝置和這個USB驅動進行綁定,這些特征哪怕差一點也不行。

那麼USB裝置的實際情況是什麼時候建立起來的?在介紹.probe指針之前有必要先談一談另一個資料結構了,它就是struct usb_device。