Linux那些事儿之我是UHCI(7)主机控制器的初始化(一)

好了,usb_alloc_dev,多么熟悉啊,在讲hub驱动时这就是那个八大函数的第一个.这里做的就是为Root Hub申请了一个struct usb_device结构体,并且初始化,将返回值赋给指针rhdev.回顾这个函数我们可以知道,Root Hubparent指针指向了Controller本身.

1585,确定rhdevspeed,UHCIOHCI都是源于曾经的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 HubWakeup能力打开了.正如注释里说的那样,你要是看不惯,你可以在自己的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内核代码?

你可能感兴趣的:(linux)