Hello Felipe,

I am not an expert on Linux Kernel but I have a problem with the USB
gadget and the origin seems to be there.

I am working with Kernel 4.13.0 on Stamp 9G20 from Taskit GmbH (CPU:
Atmel AT91SAM9G20 Embedded Processor featuring an ARM926EJ-STM ARM®
Thumb® Core).

The problem is, the disconnection of the USB gadget cable is not
acquainted by the Kernel. There is nothing in dmesg.

When I connect the cable, there is a reaction visible in dmesg:

[ 1711.406250] g_ether gadget: full-speed config #1: CDC Ethernet (ECM)
[ 1711.414062] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready

Kernel modules loaded:

Module                  Size  Used by
usb_f_ecm               9123  1
g_ether                 4488  0
usb_f_rndis            20935  2 g_ether
u_ether                10799  3 usb_f_ecm,g_ether,usb_f_rndis
libcomposite           44168  3 usb_f_ecm,g_ether,usb_f_rndis

After disconnecting the cable, usb0 is still shown as connected:

4: usb0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast
state UP group default qlen 1000
    link/ether 8e:8e:76:28:44:ab brd ff:ff:ff:ff:ff:ff
    inet 169.254.169.4/16 brd 169.254.255.255 scope link usb0
       valid_lft forever preferred_lft forever
    inet6 fe80::8c8e:76ff:fe28:44ab/64 scope link
       valid_lft forever preferred_lft forever


We used to work with an older Kernel (3.2) and we had a patch for this
problem. We expected it to be solved in 4.13 but it isn't.

diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 8efe0fa..423fc6a 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1395,6 +1395,7 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
     u32            rescans = 5;
     int            disable_clock = 0;
     unsigned long        flags;
+    struct usb_ctrlrequest    req;
 
     spin_lock_irqsave(&udc->lock, flags);
 
@@ -1443,7 +1444,18 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc)
             at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP);
             /* VDBG("bus suspend\n"); */
             if (udc->suspended)
-                continue;
+                continue;   
+
+            /* tell the driver the disconnect */
+            if (udc->driver) {
+                spin_unlock(&udc->lock);
+                memset(&req, 0, sizeof(req));
+                req.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD |
USB_RECIP_DEVICE;    
+                req.bRequest = USB_REQ_SET_CONFIGURATION;    
+                status = udc->driver->setup(&udc->gadget, &req);
+                spin_lock(&udc->lock);
+            }
+
             udc->suspended = 1;
 
             /*

Please let me know if I can supply more information or if I should
address another maintainer.


Thanks

Ana

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to