Linux那些事儿 之 戏说USB(26)设备的生命线(九)
生活随笔
收集整理的這篇文章主要介紹了
Linux那些事儿 之 戏说USB(26)设备的生命线(九)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
聊完了struct usb_hcd和struct usb_bus,算是已經(jīng)向HCD片兒區(qū)的老大們拜過山頭了,接下來就該看看usb_submit_urb()最后的那個(gè)遺留問題usb_hcd_submit_urb()了,要有心理準(zhǔn)備,也是個(gè)一百多行的狠角色。現(xiàn)在內(nèi)核里有個(gè)很不好的現(xiàn)象,設(shè)計(jì)結(jié)構(gòu)比復(fù)雜,寫函數(shù)比長。如果你缺少動(dòng)力往下看,就去看一遍福布斯美國富翁排行榜,如果上面沒有你的名字,你就繼續(xù)往下看,這是勉勵(lì)俺的,也拿來與你共勉。
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里的,目標(biāo)也很明確,就是將提交過來的urb指派給合適的主機(jī)控制器驅(qū)動(dòng)程序。core目錄下面以hcd打頭的幾個(gè)文件嚴(yán)格來說不能算是HCD,只能算HCDI,即主機(jī)控制器驅(qū)動(dòng)的接口層,用來銜接具體的主機(jī)控制器驅(qū)動(dòng)和usb core的。
4行,bus_to_hcd在哪里提到過一下,是用來獲得struct usb_bus結(jié)構(gòu)體對應(yīng)的struct usb_hcd結(jié)構(gòu)體,urb要去的那個(gè)設(shè)備所在的總線是在設(shè)備生命線的開頭兒就初始化好了的,忘了可以再驀然回首一下。bus_to_hcd還有個(gè)兄弟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有關(guān)的,如果你編譯內(nèi)核的時(shí)候沒有配置上CONFIG_USB_MON,它就啥也不是,一個(gè)空函數(shù),一具空殼。
23行,判斷這個(gè)urb是不是流向root hub的,如果是,它就走向了root hub的生命線。不過,畢竟你更關(guān)注的是你的usb設(shè)備,應(yīng)該很少有機(jī)會(huì)和欲望直接和root hub交流些什么。
26行,如果這個(gè)主機(jī)控制器支持DMA
28行,終于可以將urb扔給具體的主機(jī)控制器驅(qū)動(dòng)程序了,urb可以歡快的盡情呼喊,UHCI,OHCI,EHCI,我來了!
下面的路就讓urb去走吧,咱們說到這里也該回頭了,經(jīng)過了這么多事,遇到了這么多人,我始終都不能忘懷自己是從設(shè)置設(shè)備地址,發(fā)送SET_ADDRESS請求給主機(jī)控制器開始,這么一路走過來的,到現(xiàn)在,設(shè)備已經(jīng)可以進(jìn)入Address狀態(tài),這樁心愿已了,該繼續(xù)看設(shè)備的那條生命線了。
總結(jié)
以上是生活随笔為你收集整理的Linux那些事儿 之 戏说USB(26)设备的生命线(九)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux那些事儿 之 戏说USB(25
- 下一篇: Linux那些事儿 之 戏说USB(27