免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2659 | 回复: 0
打印 上一主题 下一主题

一步一步解决 kernel 2.6 usb host driver [复制链接]

论坛徽章:
49
15-16赛季CBA联赛之福建
日期:2016-06-22 16:22:002015年亚洲杯之中国
日期:2015-01-23 16:25:12丑牛
日期:2015-01-20 09:39:23未羊
日期:2015-01-14 23:55:57巳蛇
日期:2015-01-06 18:21:36双鱼座
日期:2015-01-02 22:04:33午马
日期:2014-11-25 09:58:35辰龙
日期:2014-11-18 10:40:07寅虎
日期:2014-11-13 22:47:15申猴
日期:2014-10-22 15:29:50摩羯座
日期:2014-08-27 10:49:43辰龙
日期:2014-08-21 10:47:58
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-03-06 17:33 |只看该作者 |倒序浏览
(以下讨论基于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的usbdriver把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 preventingyour USB host controller from getting hardware interrupts. When Linuxsubmits a request, but never hears back from the controller, this isthe diagnostic you’ll see. To see if this is the problem, look at/proc/interrupts to see if the interrupt count for your host controllerdriver ever goes up. If it doesn’t, this is the problem: either yourBIOS isn’t telling the truth to Linux (ACPI sometimes confuses thesethings, or setting the expected OS to windows in your BIOS), or Linuxdoesn’t understand what it’s saying.

Sometimes a BIOS fix will be available for your motherboard, andin other cases a more recent kernel will have a Linux fix. You may beable to work around this by passing the noapic boot option to yourkernel, or (when you’re using an add-in PCI card) moving the USBadapter to some other PCI slot. If you’re using a current kernel andBIOS, report this problem to the Linux-kernel mailing list, withdetails 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中已经有structs3c2410_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进行设置的代码,问题很可能就在这里,usermanual说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);
    }
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP