USB driver调试中遇到的问题

来源:互联网 发布:python 发送qq邮件 编辑:程序博客网 时间:2024/05/16 14:39

1.当USB拔出后,USB图标不消失

The USB indication will not disappear when the usb cable plug out after plug the cable in and out  

ten more times. The indication show it is connected withUSB£¬ but actually there is not usb cable plug in¡£
 
 

In the normal case, the process of USB icon disappeared is that:

 
Disconnect interrupt:
 

1] disconnect interrput happened:

[  432.053741] musb-hdrc musb-hdrc: <== Power=e0, DevCtl=88, int_usb=0x28
[  432.060943] musb-hdrc musb-hdrc: DISCONNECT (b_peripheral) as Peripheral, devctl 88
 

2] call into the interrpt handle:

musb_stage0_irq-->
int_usb & MUSB_INTR_DISCONNECT) {
    case OTG_STATE_B_PERIPHERAL:
    case OTG_STATE_B_IDLE:
    musb_g_disconnect(musb);
    break;
}
 

3]call into usb gadget driver disconnect callback function

void musb_g_disconnect(struct musb *musb)
{
    if (musb->gadget_driver && musb->gadget_driver->disconnect) {
        spin_unlock(&musb->lock);
        musb->gadget_driver->disconnect(&musb->g);
        spin_lock(&musb->lock);
    }
}
 

4] call into the register function in adroid.c

musb->gadget_driver->disconnect(&musb->g);
void android_disconnect(struct usb_gadget *gadget)
{
composite_disconnect(gadget);
}
 

5] call into composite disconnect function

composite_disconnect(struct usb_gadget *gadget)-->
 
    composite->disconnect(cdev);
 

6] call into the registered function driver's disconnect funtion

composite->disconnect:android_usb_unbind
android_usb_unbind-->android_cleanup_functions{
  for(registered funtions}f->cleanup(f);
}
 

7] when the function called, the USB icon disappeared

android_cleanup_functions-->f->cleanup(f);
adb_function_cleanup{
misc_deregister(&adb_device);
}
 

Based on the procedure,We can get the conclusion that the disconnect interrupt is not reported to CPU when USB cable  plug out.

how to workaround?

查到了原因,根据具体的硬件情况,只有上述函数被调用即可。


2.USB worked as host,  插拔几次后就不能工作

使用sysrq查找到blocked的进程,查到原因是--

'w'    - Dumps tasks that are in uninterruptable (blocked) state.

This is done to release the usb-storage thread from waiting
for the completion of the queued urbs, which makes
khubd thread also to wait.

[ 1355.764526] SysRq : Show Blocked State
[ 1355.768341]   task                PC stack   pid father
[ 1355.773620] khubd           D c06a1fbc     0   503      2 0x00000000
[ 1355.780151] [<c06a1fbc>] (__schedule+0x3f0/0x8ec) from [<c06a26a0>] (schedule+0x58/0x70)
[ 1355.788330] [<c06a26a0>] (schedule+0x58/0x70) from [<c06a2af8>] (schedule_timeout+0x1d8/0x31c)
[ 1355.796997] [<c06a2af8>] (schedule_timeout+0x1d8/0x31c) from [<c06a1994>] (wait_for_common+0xd8/0x180)
[ 1355.806396] [<c06a1994>] (wait_for_common+0xd8/0x180) from [<c06a1b14>] (wait_for_completion+0x20/0x24)
[ 1355.815887] [<c06a1b14>] (wait_for_completion+0x20/0x24) from [<c00b9998>] (kthread_stop+0x68/0x17c)
[ 1355.825103] [<c00b9998>] (kthread_stop+0x68/0x17c) from [<c039e0e0>] (release_everything+0x30/0x8c)
[ 1355.834228] [<c039e0e0>] (release_everything+0x30/0x8c) from [<c039e168>] (usb_stor_disconnect+0x2c/0x30)
[ 1355.843902] [<c039e168>] (usb_stor_disconnect+0x2c/0x30) from [<c038e3a8>] (usb_unbind_interface+0x60/0x1e0)
[ 1355.853820] [<c038e3a8>] (usb_unbind_interface+0x60/0x1e0) from [<c031dcc0>] (__device_release_driver+0x80/0xd0)
[ 1355.864074] [<c031dcc0>] (__device_release_driver+0x80/0xd0) from [<c031ddfc>] (device_release_driver+0x2c/0x38)
[ 1355.874359] [<c031ddfc>] (device_release_driver+0x2c/0x38) from [<c031d0d8>] (bus_remove_device+0xbc/0x10c)
[ 1355.884155] [<c031d0d8>] (bus_remove_device+0xbc/0x10c) from [<c031b63c>] (device_del+0x108/0x17c)
[ 1355.893188] [<c031b63c>] (device_del+0x108/0x17c) from [<c038afe8>] (usb_disable_device+0xbc/0x200)
[ 1355.902313] [<c038afe8>] (usb_disable_device+0xbc/0x200) from [<c0384c58>] (usb_disconnect+0xb8/0x194)
[ 1355.911682] [<c0384c58>] (usb_disconnect+0xb8/0x194) from [<c0385e58>] (hub_thread+0x45c/0x14b0)
[ 1355.920562] [<c0385e58>] (hub_thread+0x45c/0x14b0) from [<c00b97e0>] (kthread+0x98/0xa0)
[ 1355.928710] [<c00b97e0>] (kthread+0x98/0xa0) from [<c0064834>] (kernel_thread_exit+0x0/0x8)
[ 1356.014373] usb-storage     D c06a1fbc     0  2379      2 0x00000000
[ 1356.020843] [<c06a1fbc>] (__schedule+0x3f0/0x8ec) from [<c06a26a0>] (schedule+0x58/0x70)
[ 1356.029022] [<c06a26a0>] (schedule+0x58/0x70) from [<c06a2af8>] (schedule_timeout+0x1d8/0x31c)
[ 1356.037719] [<c06a2af8>] (schedule_timeout+0x1d8/0x31c) from [<c06a1994>] (wait_for_common+0xd8/0x180)
[ 1356.047088] [<c06a1994>] (wait_for_common+0xd8/0x180) from [<c06a1b14>] (wait_for_completion+0x20/0x24)
[ 1356.056549] [<c06a1b14>] (wait_for_completion+0x20/0x24) from [<c038b5dc>] (usb_sg_wait+0x108/0x194)
[ 1356.065795] [<c038b5dc>] (usb_sg_wait+0x108/0x194) from [<c039d6dc>] (usb_stor_bulk_transfer_sglist+0x9c/0xf4)
[ 1356.075866] [<c039d6dc>] (usb_stor_bulk_transfer_sglist+0x9c/0xf4) from [<c039d76c>] (usb_stor_bulk_srb+0x38/0x50)
[ 1356.086303] [<c039d76c>] (usb_stor_bulk_srb+0x38/0x50) from [<c039d92c>] (usb_stor_Bulk_transport+0x114/0x2d0)
[ 1356.096374] [<c039d92c>] (usb_stor_Bulk_transport+0x114/0x2d0) from [<c039d190>] (usb_stor_invoke_transport+0x34/0x3f4)
[ 1356.107238] [<c039d190>] (usb_stor_invoke_transport+0x34/0x3f4) from [<c039cc0c>] (usb_stor_transparent_scsi_command+0x18/0x1c)
[ 1356.118804] [<c039cc0c>] (usb_stor_transparent_scsi_command+0x18/0x1c) from [<c039f144>] (usb_stor_control_thread+0x190/0x28c)
[ 1356.130279] [<c039f144>] (usb_stor_control_thread+0x190/0x28c) from [<c00b97e0>] (kthread+0x98/0xa0)
[ 1356.139465] [<c00b97e0>] (kthread+0x98/0xa0) from [<c0064834>] (kernel_thread_exit+0x0/0x8)


当拔出后,把URB释放掉

+void musb_handle_disconnect(struct musb *musb)
+{
+    int epnum, i;
+    struct urb        *urb;
+    struct musb_hw_ep       *hw_ep;
+    struct musb_qh        *qh;
+    struct usb_hcd *hcd = musb_to_hcd(musb);
+
+    for (epnum = 0; epnum < musb->config->num_eps;
+            epnum++) {
+        hw_ep = musb->endpoints + epnum;
+        for (i = 0; i < 2; i++) {
+            if (hw_ep->in_qh == hw_ep->out_qh)
+                i++;
+            qh = (i == 0) ? hw_ep->in_qh : hw_ep->out_qh;
+            
+            if (qh && qh->hep) {
+                qh->is_ready = 0;
+                while ((urb = next_urb(qh))) {
+                    usb_hcd_unlink_urb_from_ep(hcd, urb);
+
+                    spin_unlock(&musb->lock);
+                    usb_hcd_giveback_urb(hcd, urb, 0);
+                    spin_lock(&musb->lock);
+                }
+                
+                qh->hep->hcpriv = NULL;
+                list_del(&qh->ring);
+                kfree(qh);
+                hw_ep->in_qh = hw_ep->out_qh = NULL;
+            }
+        }
+    }


copy big file failed.

这个问题是mass storage对应的端点没有配置成 double buffer模式

Occurrence: 50%, large file or folders(>30MB) easily reproduce.
 
Both SD card and phone memory could reproduce this issue.
 
 
Now the USB configue in system.prop is thatpersist.sys.usb.config=mass_storage,acm,ecm,adb.
And the corresponding item in file of init.rc is that on property:sys.usb.config=mass_storage,acm,ecm,adb.
 
we need to take care of changing the double buffering for Mass storage EP to achieve good performance.  
Now, I have enabled double buffering on endpoint 1 at the current configure. So endpoint 1 has mass_storage and with double buffering enabled.
With this configuration on ubuntu/windows PC copy of large file happens successfully.
 
In file of arch/arm/mach-ux500/usb.c, we can see the note of "Enable Double buffer for Mass Storage Class".
 
To enable double buffering will need to modify the file arch/arm/mach-ux500/usb.c to
static struct musb_fifo_cfg ux500_mode_cfg[] = {
{ .hw_ep_num =  1, .style = FIFO_TX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num =  1, .style = FIFO_RX,   .maxpacket = 512, .mode = BUF_DOUBLE, },
{ .hw_ep_num =  2, .style = FIFO_TX,   .maxpacket = 512, },
{ .hw_ep_num =  2, .style = FIFO_RX,   .maxpacket = 512, },
{ .hw_ep_num =  3, .style = FIFO_TX,   .maxpacket = 512, },
{ .hw_ep_num =  3, .style = FIFO_RX,   .maxpacket = 512, },
{ .hw_ep_num =  4, .style = FIFO_TX,   .maxpacket = 512, },
{ .hw_ep_num =  4, .style = FIFO_RX,   .maxpacket = 512, },
{ .hw_ep_num =  5, .style = FIFO_TX,   .maxpacket = 512, },
{ .hw_ep_num =  5, .style = FIFO_RX,   .maxpacket = 512, },
{ .hw_ep_num =  6, .style = FIFO_TX,   .maxpacket = 32, },
{ .hw_ep_num =  6, .style = FIFO_RX,   .maxpacket = 32, },
+}
+


0 0
原创粉丝点击