[转]一步一步解决 kernel 2.6 usb host drive

src: http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=556915&page=0&view=collapsed&sb=5&o=0&fpart=1&vc=1

(以下讨论基于kernel 2.6.11,ARM9 s3c2410,arm-linux-gcc 3.4.1 )
=================================================

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无线网卡,都报告:
<6>usb 1-1: new full speed USB device using s3c2410-ohci and address 2
<7>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<<12)|(0x02<<4)|(0x03), S3C2410_UPLLCON);

OK!usb host可以工作了,但是在第一次上电还会出现110错误,reset后才可以正常,2410上的这个UPLLCON问题由来已久,2.4内核也经常出现,原因是UPLLCON的值没有设置成功,那么就需要对设置的值进行检查,直到成功为止。

把上面的代码修改为:
unsigned long upllvalue = (0x78<<12)|(0x02<<4)|(0x03);

while (upllvalue != __raw_readl(S3C2410_UPLLCON))
{
__raw_writel(upllvalue, S3C2410_UPLLCON);
mdelay(1);
}

src:
http://www.linuxforum.net/forum/showflat.php?Cat=&Board=embedded&Number=556915&page=0&view=collapsed&sb=5&o=0&fpart=1&v
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内核是操作系统中最核心的部分,负责管理和控制硬件资源以及处理程序的运行。USB串口是一种常见的接口换技术,通过连接USB接口和串口设备,实现数据的传输和通信。 在操作系统中,内核需要提供对USB串口设备的支持。首先,内核需要识别和识别连接的USB设备,并将其与相应的串口设备进行关联。其次,内核需要加载相应的驱动程序,以便能够正确地与USB串口设备进行通信。这些驱动程序通常包括USB和串口驱动,它们负责处理设备的初始化、数据传输和错误处理等功能。 一旦内核成功加载并与USB串口设备建立连接,用户空间的程序就可以通过串口接口与外部设备进行通信。用户程序可以使用串口编程接口来发送和接收数据,内核负责将这些数据传递给USB设备,然后将其换为串口数据并发送到相应的设备。类似地,内核还可以将外部设备发送的串口数据换为USB数据,并传递给用户程序进行处理。 USB串口技术在各种应用场景中被广泛使用,例如调试和控制嵌入式设备、连接计算机与传统串口设备等。内核在支持USB串口时,需要考虑设备的兼容性、稳定性和安全性等因素,以确保数据的可靠传输和设备的正常运作。 总的来说,内核对于USB串口的支持是实现这种接口换的关键。它负责管理和控制设备的连接和数据传输,确保用户能够方便地使用USB串口设备进行数据通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值