现在的位置: 首页 > 综合 > 正文

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

2013年09月11日 ⁄ 综合 ⁄ 共 5009字 ⁄ 字号 评论关闭

好了,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内核代码?

抱歉!评论已关闭.