`
dato0123
  • 浏览: 915193 次
文章分类
社区版块
存档分类
最新评论

Linux那些事儿之我是UHCI(3)-物以类聚

 
阅读更多

这年头情侣一多,黄瓜就不好卖了. –- 北大门口卖水果的小贩回忆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_driverusb这边的接口,这两概念咋扯到一块去了呢?呵呵, 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中的devstruct 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 Cstruct结构体初始化形式,一个结构体光指针就得十来个,再添加一些宏定义,编译开关,就是一个字儿--!写个模块就得定义十个八个的结构体,你要是只定义两三个啊,你都不好意思在开源社区里跟人家打招呼,你说这样的代码,一个模块得卖多少钱?我觉得怎么着也得两千美金吧,两千美金?!那是人力成本,四千美金起,你别嫌贵,还不打折,你得研究用户的购买心理,愿意掏两千美金买源程序的用户,根本不在乎再多掏两千,什么叫成功人士你知道吗?成功人士就是,买什么都买最复杂的,不买最好的,所以我们写代码的口号就是,不求最好,但求最复杂.

分享到:
评论

相关推荐

    Linux那些事儿之我是UHCI

    写一下UHCI吧,也顺便怀念一下Intel,以及Intel的那几个女同事们,好久没联系了,你们可好? UHCI是 Intel提出来的.虽然离开 Intel一年多了,但我总觉得也许有一天我还会回到 Intel.所 以关于 Intel的东西,我多少会关注...

    Linux那些事儿1-9合集

    由复旦fudan_abc写的,风趣的文笔,深入浅...linux那些事儿之我是UHCI Linux那些事儿之我是EHCI主机控制器 Linux那些事儿之我是PCI Linux那些事儿之我是SCSI硬盘 Linux那些事儿之我是Block层 linux那些事儿之我是Sysfs

    Linux那些事儿

    Linux那些事儿之我是UHCI Linux那些事儿之我是EHCI控制器 Linux那些事儿之我是PCI Linux那些事儿之我是SCSI硬盘 Linux那些事儿之我是Block层 Linux那些事儿之我是Sysfs 今天本人将9个单独的文档整理出来,做成了一...

    Linux那些事儿系列.rar

    》包括《Linux那些事儿之我是Hub》、《Linux那些事儿之我是Sysfs》《Linux那些事儿之我是UHCI》、《Linux那些事儿之我是USB core》、《Linux那些事儿之我是U盘》,令人叹为观止的一个linux系列书籍。只能说,江山代...

    linux那些事儿(EHCI Block SCSI Sysfs PCI USB U 盘 UHCI Hub)

    Linux那些事儿之我是EHCI主机控制器.pdf Linux那些事儿之我是Block层.pdf Linux那些事儿之我是SCSI硬盘.pdf Linux那些事儿之我是Sysfs.pdf Linux那些事儿之我是PCI.pdf ...Linux那些事儿之我是UHCI.pdf

    linux的那些事儿全集

    Linux那些事儿之我是Block层 Linux那些事儿之我是EHCI主机控制器 Linux那些事儿之我是Hub Linux那些事儿之我是PCI ...Linux那些事儿之我是UHCI Linux那些事儿之我是USB core Linux那些事儿之我是U盘

    linux那些事全集

    Linux那些事儿之我是UHCI Linux那些事儿之我是Sysfs Linux那些事儿之我是SCSI硬盘 Linux那些事儿之我是PCI Linux那些事儿之我是Hub Linux那些事儿之我是EHCI主机控制器 Linux那些事儿之我是Block层

    Linux那些事儿.rar

    Linux那些Linux那些事儿之我是SCSI硬盘,Linux那些事儿之我是Block层,Linux那些事儿之我是EHCI主机控制器,Linux那些事儿之我是HUB,Linux那些事儿之我是PCI,Linux那些事儿之我是Sysfs,Linux那些事儿之我是UHCI,...

    Linux那些事儿系列

    本人整理的fudan_abc的专栏中以完结的文章,在此向原作者表示感谢,给...内容包括:linux那些事儿之我是U盘,linux那些事儿之我是USB,linux那些事儿之我是HUB,linux那些事儿之我是UHCI,linux那些事儿之我是Sysfs。

    Linux那些事儿 系列之2 Block+EHCI+PCI+SCSI

    Linux那些事儿之我是Block层.pdf Linux那些事儿之我是EHCI主机控制器.pdf Linux那些事儿之我是PCI.pdf Linux那些事儿之我是SCSI硬盘.pdf 注: 之前有人已经上传了《Linux那些事儿 系列》,其已经包含了:hub,sysfs...

    Linux那些事儿之我是XXX全集.rar

    Linux那些事儿之我是XXX全集 包含USB core U盘 UHCI PCI SCSI硬盘 Block Hub EHCI 。 想学驱动的童鞋,不妨看看。该书主要是进行源代码的分析

    linux那些事儿之我是USB.zip

    里面包含Linux那些事的九个文档,Block层,ECHI主机控制,HUB,PCI,SCSI硬盘,Sysfs,UHCI,USB+core,U盘等九个文档,内容详细,而且全面都有书签,适合系统学习!

    Linux那些事系列

    Linux那些事儿之我是Hub Linux那些事儿之我是Sysfs Linux那些事儿之我是UHCI Linux那些事儿之我是USB core Linux那些事儿之我是U盘 Linux那些事之我是HUB1

    微信生活缴费商业项目标准版

    Linux那些Linux那些事儿之我是SCSI硬盘,Linux那些事儿之我是Block层,Linux那些事儿之我是EHCI主机控制器,Linux那些事儿之我是HUB,Linux那些事儿之我是PCI,Linux那些事儿之我是Sysfs,Linux那些事儿之我是UHCI,...

    usb那些事的全集

    3 Linux那些事儿之我是HUB 4 Linux那些事儿之我是PCI 5 Linux那些事儿之我是SCSI硬盘 6 Linux那些事儿之我是Sysfs 7 Linux那些事儿之我是UHCI 8 Linux那些事儿之我是USB+core 9 Linux那些事儿之我是U盘

    Linux那些事儿[完整版]自己整理

    我是U盘 说的是2.6.10的内核 我是Sysfs 说的是2.6.10的内核 戏说USB 说的是2.6.22的内核 我是Hub/UHCI/EHCI 说的是2.6.22.1的内核

    LINUX那些事儿 linux经典之作

    我是Hub/UHCI/EHCI 说的是2.6.22.1的内核 其中我是U盘属于基础性的.这一阶段会遇到一些问题.比如urb提交之后究竟怎么处理的?用户空间究竟是如何访问U盘的?DMA究竟怎么回事. 这之后可以开始看Hub.这一阶段你会明白一...

    linux那些事儿.rar

    linux那些事儿,Block层,EHCI主机控制器,Hub,PCI,SCSI硬盘,Sysfs,UHCI,USB core,U盘等文档。

    Linux那些事儿(包括Hub, Sysfs, UHCI, USB, U盘5个部分)

    一个很经典的东东,里面的很多东西都很有启发性,值得看看

Global site tag (gtag.js) - Google Analytics