这年头情侣一多,黄瓜就不好卖了. –- 北大门口卖水果的小贩回忆2005
开源社区的家伙大概都是光棍,因为他们展现给我们的不是情侣多,而是变态的数据结构多.尤其我们这一节里要经历的变态数据结构更是多,基本上这些变态的数据结构都聚集到了这一节,所谓物以类聚吧.这么一堆变态的数据结构,要是写博客的是谭浩强,估计你看了就崩溃了,也亏了是我在写.平心而论,经历了毕业这两年来的种种挫折之后,尤其是两次求职的那冷暖自知的种种辛酸之后,有些东西我也算是看得比较透了,写代码的这群混蛋们就是唯恐天下不乱,每写一个模块就给我们引进一堆复杂的数据结构,仿佛他们的理念就是,男人,就是要对别人狠一点.没办法,哥们儿也是因为没钱,迫于生计才学Linux,有钱了我才不会来看这无聊的代码呢,如果我要中500万,除了爹妈不换,剩下全换!
usb_create_hcd的第一个参数struct hc_driver,这个结构体掀开了我们对usb host controller driver的认识,它来自drivers/usb/core/hcd.h:
149 struct hc_driver {
150 const char *description; /* "ehci-hcd" etc */
151 const char *product_desc; /* product/vendor string */
152 size_t hcd_priv_size; /* size of private data */
153
154 /* irq handler */
155 irqreturn_t (*irq) (struct usb_hcd *hcd);
156
157 int flags;
158 #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */
159 #define HCD_USB11 0x0010 /* USB 1.1 */
160 #define HCD_USB2 0x0020 /* USB 2.0 */
161
162 /* called to init HCD and root hub */
163 int (*reset) (struct usb_hcd *hcd);
164 int (*start) (struct usb_hcd *hcd);
165
166 /* NOTE: these suspend/resume calls relate to the HC as
167 * a whole, not just the root hub; they're for PCI bus glue.
168 */
169 /* called after suspending the hub, before entering D3 etc */
170 int (*suspend) (struct usb_hcd *hcd, pm_message_t message);
171
172 /* called after entering D0 (etc), before resuming the hub */
173 int (*resume) (struct usb_hcd *hcd);
174
175 /* cleanly make HCD stop writing memory and doing I/O */
176 void (*stop) (struct usb_hcd *hcd);
177
178 /* shutdown HCD */
179 void (*shutdown) (struct usb_hcd *hcd);
180
181 /* return current frame number */
182 int (*get_frame_number) (struct usb_hcd *hcd);
183
184 /* manage i/o requests, device state */
185 int (*urb_enqueue) (struct usb_hcd *hcd,
186 struct usb_host_endpoint *ep,
187 struct urb *urb,
188 gfp_t mem_flags);
189 int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb);
190
191 /* hw synch, freeing endpoint resources that urb_dequeue can't */
192 void (*endpoint_disable)(struct usb_hcd *hcd,
193 struct usb_host_endpoint *ep);
194
195 /* root hub support */
196 int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
197 int (*hub_control) (struct usb_hcd *hcd,
198 u16 typeReq, u16 wValue, u16 wIndex,
199 char *buf, u16 wLength);
200 int (*bus_suspend)(struct usb_hcd *);
201 int (*bus_resume)(struct usb_hcd *);
202 int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
203 void (*hub_irq_enable)(struct usb_hcd *);
204 /* Needed only if port-change IRQs are level-triggered */
205 };
说句良心话,你说这么长的一个结构体你要我怎么看?现在制药的都知道要制良心药,你们这些写代码的就不能写良心代码?算了,先不看这个结构体的细节了,反正吧,每个hcd都得对应这么一个结构体变量.比如咱们的uhci,在drivers/usb/host/uhci-hcd中就有这么一段:
862 static const char hcd_name[] = "uhci_hcd";
863
864 static const struct hc_driver uhci_driver = {
865 .description = hcd_name,
866 .product_desc = "UHCI Host Controller",
867 .hcd_priv_size = sizeof(struct uhci_hcd),
868
869 /* Generic hardware linkage */
870 .irq = uhci_irq,
871 .flags = HCD_USB11,
872
873 /* Basic lifecycle operations */
874 .reset = uhci_init,
875 .start = uhci_start,
876 #ifdef CONFIG_PM
877 .suspend = uhci_suspend,
878 .resume = uhci_resume,
879 .bus_suspend = uhci_rh_suspend,
880 .bus_resume = uhci_rh_resume,
881 #endif
882 .stop = uhci_stop,
883
884 .urb_enqueue = uhci_urb_enqueue,
885 .urb_dequeue = uhci_urb_dequeue,
886
887 .endpoint_disable = uhci_hcd_endpoint_disable,
888 .get_frame_number = uhci_hcd_get_frame_number,
889
890 .hub_status_data = uhci_hub_status_data,
891 .hub_control = uhci_hub_control,
892 };
其实就是一堆乱七八糟的指针,也没什么了不起.不过我得提醒你了,在咱们整个故事中也就只有一个struct hc_driver变量,就是这一个uhci_driver,以后凡是提到hc_driver,指的就是uhci_driver.不过你说这个probe函数咋知道的?probe函数是pci那边的接口,而hc_driver是usb这边的接口,这两概念咋扯到一块去了呢?呵呵, usb_hcd_pci_probe函数67行,看见没有,driver在这里被赋值了,而等号右边那个id->driver_data又是什么?继续回去看,在uhci_pci_ids这张表里写得很清楚,driver_data就是被赋值为&uhci_driver,所以说一切都是有因才有果的,不会无缘无故的出现一个变量.说到因果,就好比你问我”没房没老婆”是什么关系,我就只能告诉你三十岁以前是并列关系,三十岁以后是因果关系.
继续看,1496行,一个变态的数据结构还不够,还得来一个更变态的.struct usb_hcd,这意思很明确,有一个hcd就得有这么一个结构体,也是来自drivers/usb/core/hcd.h:
47 /*-------------------------------------------------------------------------*/
48
49 /*
50 * USB Host Controller Driver (usb_hcd) framework
51 *
52 * Since "struct usb_bus" is so thin, you can't share much code in it.
53 * This framework is a layer over that, and should be more sharable.
54 */
55
56 /*-------------------------------------------------------------------------*/
57
58 struct usb_hcd {
59
60 /*
61 * housekeeping
62 */
63 struct usb_bus self; /* hcd is-a bus */
64 struct kref kref; /* reference counter */
65
66 const char *product_desc; /* product/vendor string */
67 char irq_descr[24]; /* driver + bus # */
68
69 struct timer_list rh_timer; /* drives root-hub polling */
70 struct urb *status_urb; /* the current status urb */
71 #ifdef CONFIG_PM
72 struct work_struct wakeup_work; /* for remote wakeup */
73 #endif
74
75 /*
76 * hardware info/state
77 */
78 const struct hc_driver *driver; /* hw-specific hooks */
79
80 /* Flags that need to be manipulated atomically */
81 unsigned long flags;
82 #define HCD_FLAG_HW_ACCESSIBLE 0x00000001
83 #define HCD_FLAG_SAW_IRQ 0x00000002
84
85 unsigned rh_registered:1;/* is root hub registered? */
86
87 /* The next flag is a stopgap, to be removed when all the HCDs
88 * support the new root-hub polling mechanism. */
89 unsigned uses_new_polling:1;
90 unsigned poll_rh:1; /* poll for rh status? */
91 unsigned poll_pending:1; /* status has changed? */
92 unsigned wireless:1; /* Wireless USB HCD */
93
94 int irq; /* irq allocated */
95 void __iomem *regs; /* device memory/io */
96 u64 rsrc_start; /* memory/io resource start */
97 u64 rsrc_len; /* memory/io resource length */
98 unsigned power_budget; /* in mA, 0 = no limit */
99
100 #define HCD_BUFFER_POOLS 4
101 struct dma_pool *pool [HCD_BUFFER_POOLS];
102
103 int state;
104 # define __ACTIVE 0x01
105 # define __SUSPEND 0x04
106 # define __TRANSIENT 0x80
107
108 # define HC_STATE_HALT 0
109 # define HC_STATE_RUNNING (__ACTIVE)
110 # define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
111 # define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
112 # define HC_STATE_SUSPENDED (__SUSPEND)
113
114 #define HC_IS_RUNNING(state) ((state) & __ACTIVE)
115 #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
116
117 /* more shared queuing code would be good; it should support
118 * smarter scheduling, handle transaction translators, etc;
119 * input size of periodic table to an interrupt scheduler.
120 * (ohci 32, uhci 1024, ehci 256/512/1024).
121 */
122
123 /* The HC driver's private data is stored at the end of
124 * this structure.
125 */
126 unsigned long hcd_priv[0]
127 __attribute__ ((aligned (sizeof(unsigned long))));
128 };
所以usb_create_hcd这个函数就是为struct usb_hcd申请内存空间,并且初始化.我们来看它具体如何初始化的.
1498行是申请内存,并且初值为0.
接下来你得注意了,usb_create_hcd中的dev可是struct device结构体指针,而刚才的usb_hcd_pci_probe中的dev是struct pci_dev结构体指针,struct pci_dev虽然我们没说,但也该知道,表示的就是一个pci设备,它有一个成员struct device dev,所以实际上我们看到我们在调用usb_create_hcd的时候第二个参数是&dev->dev.而这里1503行这个dev_set_drvdata就是一简单的内联函数,来自include/linux/device.h:
491 static inline void
492 dev_set_drvdata (struct device *dev, void *data)
493 {
494 dev->driver_data = data;
495 }
struct device这个结构体中有一个成员void *driver_data,所以在我们这里,其效果就是令dev->driver_data等于咱们这里申请好的hcd.
而1504行就是初始化一个引用计数,struct usb_hcd也不是白贴出来了,至少我们可以看到它有一个成员struct kref kref,这玩艺说白了就是一个引用计数的变量.
1506行,我不知道该说什么了,反正我也贴出来了,你也看到了,struct usb_hcd中有一个成员struct usb_bus self,我们说了一个主机控制器就意味着一条总线,所以这里又出来另一个结构体,struct usb_bus,
273 /*
274 * Allocated per bus (tree of devices) we have:
275 */
276 struct usb_bus {
277 struct device *controller; /* host/master side hardware */
278 int busnum; /* Bus number (in order of reg) */
279 char *bus_name; /* stable id (PCI slot_name etc) */
280 u8 uses_dma; /* Does the host controller use DMA? */
281 u8 otg_port; /* 0, or number of OTG/HNP port */
282 unsigned is_b_host:1; /* true during some HNP roleswitches */
283 unsigned b_hnp_enable:1; /* OTG: did A-Host enable HNP? */
284
285 int devnum_next; /* Next open device number in
286 * round-robin allocation */
287
288 struct usb_devmap devmap; /* device address allocation map */
289 struct usb_device *root_hub; /* Root hub */
290 struct list_head bus_list; /* list of busses */
291
292 int bandwidth_allocated; /* on this bus: how much of the time
293 * reserved for periodic (intr/iso)
294 * requests is used, on average?
295 * Units: microseconds/frame.
296 * Limits: Full/low speed reserve 90%,
297 * while high speed reserves 80%.
298 */
299 int bandwidth_int_reqs; /* number of Interrupt requests */
300 int bandwidth_isoc_reqs; /* number of Isoc. requests */
301
302 #ifdef CONFIG_USB_DEVICEFS
303 struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */
304 #endif
305 struct class_device *class_dev; /* class device for this bus */
306
307 #if defined(CONFIG_USB_MON)
308 struct mon_bus *mon_bus; /* non-null when associated */
309 int monitored; /* non-zero when monitored */
310 #endif
311 };
有时候我真的很困惑,难道定义的结构体越多说明写代码的人腕儿越大?真的,我算是看明白了,这些人的思路是,一定得选最变态的数据结构,行数至少也得30行,什么int型呀,char型呀,unsinged型呀,能给它用的全给它用上,结构体前边有说明,里边有嵌套的结构体,结构体内写一堆注释,跨行,特长的那种,一套地道的gcc语法,倍儿有面子,再用上ANSI C的struct结构体初始化形式,一个结构体光指针就得十来个,再添加一些宏定义,编译开关,就是一个字儿--帅!写个模块就得定义十个八个的结构体,你要是只定义两三个啊,你都不好意思在开源社区里跟人家打招呼,你说这样的代码,一个模块得卖多少钱?我觉得怎么着也得两千美金吧,两千美金?!那是人力成本,四千美金起,你别嫌贵,还不打折,你得研究用户的购买心理,愿意掏两千美金买源程序的用户,根本不在乎再多掏两千,什么叫成功人士你知道吗?成功人士就是,买什么都买最复杂的,不买最好的,所以我们写代码的口号就是,不求最好,但求最复杂.