usb接口wifi模块rtl8188cus issue

来源:互联网 发布:定制家具上楼知乎 编辑:程序博客网 时间:2024/05/21 19:40
奇怪的问题,在冷开机的时候,rtl8188cus可以正常上网,可只要一进入sleep然后再resume,
就会出现wifi出错的情况。
<4>###=> urb_write_port_complete status(-2)
<4>bSurpriseRemoved=TRUE
<4>xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel
<4>usb_write_port sync, status=-110
<4>IOL error, polling_ret:0x00
<4>rtl8192cu_hal_init in 1078ms
<4>-871x_drv - drv_open fail, bup=0
<4>rtw_resume_process, Open net dev failed 
<4>###########  rtw_resume  done with error#################

而且这个情况不论在重新关闭/打开wifi,或者任何其他操作后都会一直存在,只要sleep过一次,
哪怕sleep之前wifi并没有打开。

花了两三天的时间在realtek工程师Jeff Hung的帮助下,对比realtek的新旧版本wifi驱动,最终确认
问题不是出在wifi驱动,而是v210系统的问题。

google了很多,然后也从github下载了一些2.6.35.7的内核源码,通过对比,没有发现有什么特别的东西。
实在没招了。。 明天就是2012,难道得留到明年? 无奈之下,猜想是不是可以通过在sleep前和sleep后
打印出usb相关的寄存器来对比,看是不是寄存器出了问题。 
在drivers/usb/host/ehci-s5pv210.c中,增加打印的函数:
 struct usb_hcd *ghcd;
void dump_ehci_reg(void)
{
        int reg[] = {
        0xEC200000,0xEC200004,0xEC200008,
        0xEC200010,0xEC200014,0xEC200018,0xEC20001C,0xEC200020,0xEC200024,0xEC200028,
        0xEC200050,0xEC200054,
        0xEC200090,0xEC200094,0xEC200098,0xEC20009C,0xEC2000A0,0xEC2000A4,0xEC2000A8,0xEC2000AC,
        };
        int len = sizeof(reg)/sizeof(int);
        int i;
        printk("----------------%s len=%d------------------\n",__func__,len);
        for(i=0;i<len;i++)
                printk("0x%08x : 0x%08x\n",reg[i],readl(ghcd->regs + (reg[i]-0xEC200000)));

        printk("----------------end------------------\n");
}
EXPORT_SYMBOL(dump_ehci_reg);
static int ehci_hcd_s5pv210_drv_probe(struct platform_device *pdev)中
ghcd = hcd; //jeff

然后在drivers/input/touchscreen/raydium_ts_general.c  touch的驱动中
extern void dump_ehci_reg(void);
static void raydium_ts_early_suspend(struct early_suspend *h)
{
   printk("%s\n", __func__);
   raydium_ts_suspend(global->client, PMSG_SUSPEND);
dump_ehci_reg();
}

static void raydium_ts_late_resume(struct early_suspend *h)
{
   printk("%s\n", __func__);
   raydium_ts_resume(global->client);
dump_ehci_reg();
}
就可以在关屏,开屏的时候打印出来EHCI的寄存器值。
before sleep:
----------------dump_ehci_reg len=20------------------
0xec200000 : 0x01000010
0xec200004 : 0x00001111
0xec200008 : 0x0000a010
0xec200010 : 0x00010011
0xec200014 : 0x00004008
0xec200018 : 0x00000037
0xec20001c : 0x000023ab
0xec200020 : 0x00000000
0xec200024 : 0x3fe9e000
0xec200028 : 0x3fe9c000
0xec200050 : 0x00000001
0xec200054 : 0x00001005
0xec200090 : 0x000e0000
0xec200094 : 0x00400040
0xec200098 : 0x00000100
0xec20009c : 0x00000001
0xec2000a0 : 0x00000000
0xec2000a4 : 0x00001000
0xec2000a8 : 0x00000000
0xec2000ac : 0x00000000
----------------end------------------

after sleep:
----------------dump_ehci_reg len=20------------------
0xec200000 : 0x01000010
0xec200004 : 0x00001111
0xec200008 : 0x0000a010
0xec200010 : 0x00010011
0xec200014 : 0x00004008
0xec200018 : 0x00000037
0xec20001c : 0x00003445
0xec200020 : 0x00000000
0xec200024 : 0x3fe9e000
0xec200028 : 0x3fe9c000
0xec200050 : 0x00000001
0xec200054 : 0x00001005
0xec200090 : 0x00000000
0xec200094 : 0x00400040
0xec200098 : 0x00000100
0xec20009c : 0x00000001
0xec2000a0 : 0x00000000
0xec2000a4 : 0x00001000
0xec2000a8 : 0x00000000
0xec2000ac : 0x00000000
----------------end------------------

对比一下,有两个寄存器不同 0xec20001c   0xec200090 ,查看v210 spec,
0xec20001c为FRINDEX,是变化的,问题不大。
0xec200090为INSNREG00,在 drivers/usb/host/ehci-s5pv210.c 中的
static int ehci_hcd_s5pv210_drv_probe(struct platform_device *pdev)
函数中还有去写这个寄存器

#if defined(CONFIG_ARCH_S5PV210) || defined(CONFIG_ARCH_S5P6450)
        //jeff. writel(0x000F000e, hcd->regs + 0x90);
        writel(0x000E0000, hcd->regs + 0x90);
        writel(0x00400040, hcd->regs + 0x94);
#endif

所以将这部分也挪到 static int ehci_hcd_s5pv210_drv_resume(struct platform_device *pdev)中,编译烧写后,sleep起来也可以使用wifi了!
原创粉丝点击