Linux那些事儿 之 戏说USB(26)设备的生命线(九)
生活随笔
收集整理的這篇文章主要介紹了
Linux那些事儿 之 戏说USB(26)设备的生命线(九)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
聊完了struct usb_hcd和struct usb_bus,算是已經向HCD片兒區的老大們拜過山頭了,接下來就該看看usb_submit_urb()最后的那個遺留問題usb_hcd_submit_urb()了,要有心理準備,也是個一百多行的狠角色。現在內核里有個很不好的現象,設計結構比復雜,寫函數比長。如果你缺少動力往下看,就去看一遍福布斯美國富翁排行榜,如果上面沒有你的名字,你就繼續往下看,這是勉勵俺的,也拿來與你共勉。
drivers/usb/core/hcd.c
int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags)
{int status;struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus);/* increment urb's reference count as part of giving it to the HCD* (which will control it). HCD guarantees that it either returns* an error or calls giveback(), but not both.*/usb_get_urb(urb);atomic_inc(&urb->use_count);atomic_inc(&urb->dev->urbnum);usbmon_urb_submit(&hcd->self, urb);/* NOTE requirements on root-hub callers (usbfs and the hub* driver, for now): URBs' urb->transfer_buffer must be* valid and usb_buffer_{sync,unmap}() not be needed, since* they could clobber root hub response data. Also, control* URBs must be submitted in process context with interrupts* enabled.*/if (is_root_hub(urb->dev)) {status = rh_urb_enqueue(hcd, urb);} else {status = map_urb_for_dma(hcd, urb, mem_flags);if (likely(status == 0)) {status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);if (unlikely(status))unmap_urb_for_dma(hcd, urb);}}if (unlikely(status)) {usbmon_urb_submit_error(&hcd->self, urb, status);urb->hcpriv = NULL;INIT_LIST_HEAD(&urb->urb_list);atomic_dec(&urb->use_count);atomic_dec(&urb->dev->urbnum);if (atomic_read(&urb->reject))wake_up(&usb_kill_urb_queue);usb_put_urb(urb);}return status;
}usb_hcd_submit_urb是hcd.c里的,目標也很明確,就是將提交過來的urb指派給合適的主機控制器驅動程序。core目錄下面以hcd打頭的幾個文件嚴格來說不能算是HCD,只能算HCDI,即主機控制器驅動的接口層,用來銜接具體的主機控制器驅動和usb core的。
4行,bus_to_hcd在哪里提到過一下,是用來獲得struct usb_bus結構體對應的struct usb_hcd結構體,urb要去的那個設備所在的總線是在設備生命線的開頭兒就初始化好了的,忘了可以再驀然回首一下。bus_to_hcd還有個兄弟hcd_to_bus,都在include/linux/usb/hcd.h里定義
static inline struct usb_bus *hcd_to_bus(struct usb_hcd *hcd)
{return &hcd->self;
}static inline struct usb_hcd *bus_to_hcd(struct usb_bus *bus)
{return container_of(bus, struct usb_hcd, self);
}13行,usbmon_urb_submit就是與前面Greg孕育出來的usb Monitor有關的,如果你編譯內核的時候沒有配置上CONFIG_USB_MON,它就啥也不是,一個空函數,一具空殼。
23行,判斷這個urb是不是流向root hub的,如果是,它就走向了root hub的生命線。不過,畢竟你更關注的是你的usb設備,應該很少有機會和欲望直接和root hub交流些什么。
26行,如果這個主機控制器支持DMA
28行,終于可以將urb扔給具體的主機控制器驅動程序了,urb可以歡快的盡情呼喊,UHCI,OHCI,EHCI,我來了!
下面的路就讓urb去走吧,咱們說到這里也該回頭了,經過了這么多事,遇到了這么多人,我始終都不能忘懷自己是從設置設備地址,發送SET_ADDRESS請求給主機控制器開始,這么一路走過來的,到現在,設備已經可以進入Address狀態,這樁心愿已了,該繼續看設備的那條生命線了。
總結
以上是生活随笔為你收集整理的Linux那些事儿 之 戏说USB(26)设备的生命线(九)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux那些事儿 之 戏说USB(25
- 下一篇: Linux那些事儿 之 戏说USB(27