好了,usb_alloc_dev,多么熟悉啊,在讲hub驱动时这就是那个八大函数的第一个.这里做的就是为Root Hub申请了一个struct usb_device结构体,并且初始化,将返回值赋给指针rhdev.回顾这个函数我们可以知道,Root Hub的parent指针指向了Controller本身.
1585行,确定rhdev的speed,UHCI和OHCI都是源于曾经的USB1.1,而EHCI才是来自USB2.0.只有USB2.0才定义了高速的设备,以前的设备只有两种速度,低速和全速.也只有EHCI的驱动才定义了一个flag,HCD_USB2.所以咱们这里记录的rhdev->speed就是USB_SPEED_FULL.不过我需要再次提醒一下,hcd->driver在咱们的故事里就是那个hc_driver,即uhci_driver,有且只有这一个driver.
1593行,device_init_wakeup.也是咱们在hub驱动中见过的.第二个参数是1就意味着我们把Root Hub的Wakeup能力打开了.正如注释里说的那样,你要是看不惯,你可以在自己的driver里面把它关掉.
1598行,如果hc_driver中有reset函数,就调用它,咱们的uhci_driver里面显然是有的.回去看它的定义,知道它就是uhci_init.所以这时候就要调用这个函数了,显然它的名字告诉我们它的作用是做一些初始化.它来自drivers/usb/host/uhci-hcd.c:
483 static int uhci_init(struct usb_hcd *hcd)
484 {
485 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
486 unsigned io_size = (unsigned) hcd->rsrc_len;
487 int port;
488
489 uhci->io_addr = (unsigned long) hcd->rsrc_start;
490
491 /* The UHCI spec says devices must have 2 ports, and goes on to say
492 * they may have more but gives no way to determine how many there
493 * are. However according to the UHCI spec, Bit 7 of the port
494 * status and control register is always set to 1. So we try to
495 * use this to our advantage. Another common failure mode when
496 * a nonexistent register is addressed is to return all ones, so
497 * we test for that also.
498 */
499 for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) {
500 unsigned int portstatus;
501
502 portstatus = inw(uhci->io_addr + USBPORTSC1 + (port * 2));
503 if (!(portstatus & 0x0080) || portstatus == 0xffff)
504 break;
505 }
506 if (debug)
507 dev_info(uhci_dev(uhci), "detected %d ports/n", port);
508
509 /* Anything greater than 7 is weird so we'll ignore it. */
510 if (port > UHCI_RH_MAXCHILD) {
511 dev_info(uhci_dev(uhci), "port count misdetected? "
512 "forcing to 2 ports/n");
513 port = 2;
514 }
515 uhci->rh_numports = port;
516
517 /* Kick BIOS off this hardware and reset if the controller
518 * isn't already safely quiescent.
519 */
520 check_and_reset_hc(uhci);
521 return 0;
522 }
可恶!又出来一个新的结构体.struct uhci_hcd,很显然,这是uhci特有的.
371 struct uhci_hcd {
372
373 /* debugfs */
374 struct dentry *dentry;
375
376 /* Grabbed from PCI */
377 unsigned long io_addr;
378
379 struct dma_pool *qh_pool;
380 struct dma_pool *td_pool;
381
382 struct uhci_td *term_td; /* Terminating TD, see UHCI bug */
383 struct uhci_qh *skelqh[UHCI_NUM_SKELQH]; /* Skeleton QHs */
384 struct uhci_qh *next_qh; /* Next QH to scan */
385
386 spinlock_t lock;
387
388 dma_addr_t frame_dma_handle; /* Hardware frame list */
389 __le32 *frame;
390 void **frame_cpu; /* CPU's frame list */
391
392 enum uhci_rh_state rh_state;
393 unsigned long auto_stop_time; /* When to AUTO_STOP */
394
395 unsigned int frame_number; /* As of last check */
396 unsigned int is_stopped;
397 #define UHCI_IS_STOPPED 9999 /* Larger than a frame # */
398 unsigned int last_iso_frame; /* Frame of last scan */
399 unsigned int cur_iso_frame; /* Frame for current scan */
400
401 unsigned int scan_in_progress:1; /* Schedule scan is running */
402 unsigned int need_rescan:1; /* Redo the schedule scan */
403 unsigned int dead:1; /* Controller has died */
404 unsigned int working_RD:1; /* Suspended root hub doesn't
405 need to be polled */
406 unsigned int is_initialized:1; /* Data structure is usable */
407 unsigned int fsbr_is_on:1; /* FSBR is turned on */
408 unsigned int fsbr_is_wanted:1; /* Does any URB want FSBR? */
409 unsigned int fsbr_expiring:1; /* FSBR is timing out */
410
411 struct timer_list fsbr_timer; /* For turning off FBSR */
412
413 /* Support for port suspend/resume/reset */
414 unsigned long port_c_suspend; /* Bit-arrays of ports */
415 unsigned long resuming_ports;
416 unsigned long ports_timeout; /* Time to stop signalling */
417
418 struct list_head idle_qh_list; /* Where the idle QHs live */
419
420 int rh_numports; /* Number of root-hub ports */
421
422 wait_queue_head_t waitqh; /* endpoint_disable waiters */
423 int num_waiting; /* Number of waiters */
424
425 int total_load; /* Sum of array values */
426 short load[MAX_PHASE]; /* Periodic allocations */
427 };
写代码的人永远都不会体会到我们读代码人的痛苦,我真的觉得如果这些变态的数据结构再多出现几个的话我就不想看了.我的忍耐是有底线的,我甚至怀疑今年那部号称十足的悲剧的电影<<十分爱>>中女主角之所以说出那句经典的“那些男人只知道女人的底裤在哪里,永远都不知道女人的底线在哪里,总是想挑战女人的极限.”是不是因为当时她也在看Linux内核代码?