天天看點

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

好了,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        

    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        

    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        

    520         check_and_reset_hc(uhci);

    521         return 0;

    522 }

可惡!又出來一個新的結構體.struct uhci_hcd,很顯然,這是uhci特有的.

    371 struct uhci_hcd {

    372

    373        

    374         struct dentry *dentry;

    375

    376        

    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;       

    383         struct uhci_qh *skelqh[UHCI_NUM_SKELQH];       

    384         struct uhci_qh *next_qh;       

    385

    386         spinlock_t lock;

    387

    388         dma_addr_t frame_dma_handle;   

    389         __le32 *frame;

    390         void **frame_cpu;               

    391

    392         enum uhci_rh_state rh_state;

    393         unsigned long auto_stop_time;          

    394

    395         unsigned int frame_number;             

    396         unsigned int is_stopped;

    397 #define UHCI_IS_STOPPED         9999           

    398         unsigned int last_iso_frame;           

    399         unsigned int cur_iso_frame;            

    400

    401         unsigned int scan_in_progress:1;       

    402         unsigned int need_rescan:1;            

    403         unsigned int dead:1;                    

    404         unsigned int working_RD:1;             

    406         unsigned int is_initialized:1;         

    407         unsigned int fsbr_is_on:1;             

    408         unsigned int fsbr_is_wanted:1;         

    409         unsigned int fsbr_expiring:1;          

    410

    411         struct timer_list fsbr_timer;          

    412

    413        

    414         unsigned long port_c_suspend;          

    415         unsigned long resuming_ports;

    416         unsigned long ports_timeout;           

    417

    418         struct list_head idle_qh_list;         

    419

    420         int rh_numports;                       

    421

    422         wait_queue_head_t waitqh;              

    423         int num_waiting;                       

    424

    425         int total_load;                        

    426         short load[MAX_PHASE];                 

    427 };

寫代碼的人永遠都不會體會到我們讀代碼人的痛苦,我真的覺得如果這些變态的資料結構再多出現幾個的話我就不想看了.我的忍耐是有底線的,我甚至懷疑今年那部号稱十足的悲劇的電影<<十分愛>>中女主角之是以說出那句經典的“那些男人隻知道女人的底褲在哪裡,永遠都不知道女人的底線在哪裡,總是想挑戰女人的極限.”是不是因為當時她也在看Linux核心代碼?

繼續閱讀