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_unbindandroid_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, },
+}
+