2.6在s3c2410上usb host不工作的直接結果就是提示110錯誤: usb 1-1: device descriptor read/64, error -110
追蹤錯誤代碼,我們來看看能不能找到導致這個錯誤的線索。
include/asm-generic/errno.h #define EPROTO 71 /* Protocol error */ #define EILSEQ 84 /* Illegal byte sequence */ #define ETIMEDOUT 110 /* Connection timed out */
Documentation/usb/error-codes.txt -EPROTO (*, **) a) bitstuff error b) no response packet received within the prescribed bus turn-around time c) unknown USB error
-EILSEQ (*, **) a) CRC mismatch b) no response packet received within the prescribed bus turn-around time c) unknown USB error
-ETIMEDOUT (**) No response packet received within the prescribed bus turn-around time. This error may instead be reported as -EPROTO or -EILSEQ.
由此我們可以判斷,這個錯誤與 usb 設備的超時有關。報告這個錯誤的地方在drivers/usb/core/hub.c中的hub_port_init部分,由於usb_get_device_descriptor獲取 usb 設備信息的時候產生了超時。這樣基本可以確定三種情況,1、usb 設備及接口有問題;2、usb core有問題;3、usb driver有問題。 我們可以很容易地排除1和2的可能性,問題應該在usb driver implement部分造成的。2.6的usb driver把usb規范中對usb接口的操作集中到了core裡面,針對不同設備的implement分別歸為host、gadget、storage等。基本確定問題就在ohci-s3c2410.c裡。
跟蹤進入ohci-s3c2410.c,這裡面主要完成s3c2410 usb host設備的初始化工作,包括電源、時鐘、寄存器等。
其實很多問題在互聯網上已經被遇到和解決,我們要做的就是多參考別人的成功經驗,這樣可以節省時間,同時能夠幫助我們找到一些思路。借助google這雙強大的翅膀,我們來看看能找到什麼:
http://www.linux-usb.org/FAQ.html#ts6
Q: Why doesn’t USB work at all? I get “device not accepting address”.
A: You may have some problem with your PCI setup that’s preventing your USB host controller from getting hardware interrupts. When Linux submits a request, but never hears back from the controller, this is the diagnostic you’ll see. To see if this is the problem, look at /proc/interrupts to see if the interrupt count for your host controller driver ever goes up. If it doesn’t, this is the problem: either your BIOS isn’t telling the truth to Linux (ACPI sometimes confuses these things, or setting the expected OS to windows in your BIOS), or Linux doesn’t understand what it’s saying.
Sometimes a BIOS fix will be available for your motherboard, and in other cases a more recent kernel will have a Linux fix. You may be able to work around this by passing the noapic boot option to your kernel, or (when you’re using an add-in PCI card) moving the USB adapter to some other PCI slot. If you’re using a current kernel and BIOS, report this problem to the Linux-kernel mailing list, with details about your motherboard and BIOS.
google返回的大量結果中有個建議是設置old_scheme_first標志,讓驅動程序優先處理采用老式結構的設備: 設置old_scheme_first=y 測試結果並沒有太大幫助,不是這個原因引發的。
linux-usb-devel mail list 上Ben大哥正在不斷更新他的ohci-s3c2410 driver,但好像還沒最終完成。 http://www.mail-archive.com/linux-usb-devel%40lists.sourceforge.net/msg33670.html
跟蹤ohci-s3c2410.c,發現to_s3c2410_info返回NULL,很明顯,是platform_data沒有定義,在 include/asm/arch/usb-control.h中已經有struct s3c2410_hcd_info,那麼仿照simtec的usb-simtec.c,來構造自己的platform_data。
static struct s3c2410_hcd_info smdk2410_usbcfg = { .port[0] = { .flags = S3C_HCDFLG_USED }, };
然後在smdk2410_init中完成初始化:
s3c_device_usb.dev.platform_data = &smdk2410_usbcfg;
重新make zImage,情況有所變化: 初始化usb controller的過程中有一行debug信息: s3c2410-ohci: CTRL: TypeReq=0x2303 val=0x8 idx=0x1 len=0 ==> -115
在include/asm-generic/errno.h中查了一下這個錯誤代碼: #define EINPROGRESS 115 /* Operation now in progress */
在Documentation/usb/error-codes.txt中的解釋是: -EINPROGRESS URB still pending, no results yet (That is, if drivers see this it’s a bug.)
這時無論插入什麼USB設備,USB鼠標、U盤、USB無線網卡,都報告: usb 1-1: new full speed USB device using s3c2410-ohci and address 2 s3c2410-ohci s3c2410-ohci: urb c3c430c0 path 1 ep0in 5ec20000 cc 5 –> status -110
看上去這兩個錯誤應該存在關聯,可能前面的115錯誤導致了後面的110錯誤;在跟蹤過程中發現115錯誤是在GetPortStatus時產生的,從這個情況來看,可以暫時屏蔽0hci-s3c2410.c中GetPortStatus的實現部分,繼續觀察變化,結果還是110錯誤,因此可以排除115 造成110錯誤的假設。
最後懷疑是時鐘設置的問題,便參照2.4.18的代碼在clk_enable(clk);後面加了個udelay(11);但是錯誤還是沒有解決。
那麼需要對ohci-s3c2410.c進行詳細的排查了,2.6把系統資源進行了詳細的分類,這使得驅動程序要完成初始化相應設備寄存器的工作,查遍 ohci-s3c2410.c,竟然沒有對s3c24102410的UPLLCON進行設置的代碼,問題很可能就在這裡,user manual說UPLLCON需要48.00MHz output, 於是在s3c2410_start_hc裡增加:
__raw_writel((0x78