Bug 183505 - [usb] Arduino Leonardo exposes three interface descriptors but no modem is attached to the first one (bInterfaceSubClass=2)
Summary: [usb] Arduino Leonardo exposes three interface descriptors but no modem is at...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-usb (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-30 22:40 UTC by Adrian Chadd
Modified: 2017-04-19 20:49 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Adrian Chadd freebsd_committer freebsd_triage 2013-10-30 22:40:00 UTC
When plugging in the Arduino Leonardo, it doesn't stay connected as a modem.

It connects, shows a modem device, then disconnects and reappears as a device with three interfaces.

Unfortunately the only one which shows up is uhid.

How-To-Repeat: 
Plug in an Arduino Leonardo.

It comes up as a modem very briefly:

umodem0: <Arduino LLC Arduino Leonardo, class 2/0, rev 1.10/0.01, addr 3> on usbus4
umodem0: data interface 1, has CM over data, has break

. then it disconnects (I guess it loads in something) and comes back as multiple interfaces:

ugen4.3: <Arduino LLC> at usbus4 (disconnected)
umodem0: at uhub2, port 2, addr 3 (disconnected)
ugen4.3: <Arduino LLC> at usbus4
uhid2: <Arduino LLC Arduino Leonardo, class 2/0, rev 2.00/1.00, addr 3> on usbus4

I dumped the descriptor:

# usbconfig -d ugen4.3 dump_all_config_desc



ugen4.3: <Arduino Leonardo Arduino LLC> at usbus4, cfg=0 md=HOST spd=FULL (12Mbps) pwr=ON (500mA)


 Configuration index 0

    bLength = 0x0009
    bDescriptorType = 0x0002
    wTotalLength = 0x0064
    bNumInterfaces = 0x0003
    bConfigurationValue = 0x0001
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x0080
    bMaxPower = 0x00fa

    Additional Descriptor

    bLength = 0x08
    bDescriptorType = 0x0b
    bDescriptorSubType = 0x00
     RAW dump:
     0x00 | 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, 0x01, 0x00


    Interface 0
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0000
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0001
      bInterfaceClass = 0x0002
      bInterfaceSubClass = 0x0002
      bInterfaceProtocol = 0x0000
      iInterface = 0x0000  <no string>

      Additional Descriptor

      bLength = 0x05
      bDescriptorType = 0x24
      bDescriptorSubType = 0x00
       RAW dump:
       0x00 | 0x05, 0x24, 0x00, 0x10, 0x01


      Additional Descriptor

      bLength = 0x05
      bDescriptorType = 0x24
      bDescriptorSubType = 0x01
       RAW dump:
       0x00 | 0x05, 0x24, 0x01, 0x01, 0x01


      Additional Descriptor

      bLength = 0x04
      bDescriptorType = 0x24
      bDescriptorSubType = 0x02
       RAW dump:
       0x00 | 0x04, 0x24, 0x02, 0x06


      Additional Descriptor

      bLength = 0x05
      bDescriptorType = 0x24
      bDescriptorSubType = 0x06
       RAW dump:
       0x00 | 0x05, 0x24, 0x06, 0x00, 0x01


     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0010
        bInterval = 0x0040
        bRefresh = 0x0000
        bSynchAddress = 0x0000


    Interface 1
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0001
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0002
      bInterfaceClass = 0x000a
      bInterfaceSubClass = 0x0000
      bInterfaceProtocol = 0x0000
      iInterface = 0x0000  <no string>

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0002  <OUT>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0040
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000

     Endpoint 1
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0083  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0040
        bInterval = 0x0000
        bRefresh = 0x0000
        bSynchAddress = 0x0000


    Interface 2
      bLength = 0x0009
      bDescriptorType = 0x0004
      bInterfaceNumber = 0x0002
      bAlternateSetting = 0x0000
      bNumEndpoints = 0x0001
      bInterfaceClass = 0x0003
      bInterfaceSubClass = 0x0000
      bInterfaceProtocol = 0x0000
      iInterface = 0x0000  <no string>

      Additional Descriptor

      bLength = 0x09
      bDescriptorType = 0x21
      bDescriptorSubType = 0x01
       RAW dump:
       0x00 | 0x09, 0x21, 0x01, 0x01, 0x00, 0x01, 0x22, 0x65,
       0x08 | 0x00

     Endpoint 0
        bLength = 0x0007
        bDescriptorType = 0x0005
        bEndpointAddress = 0x0084  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0040
        bInterval = 0x0001
        bRefresh = 0x0000
        bSynchAddress = 0x0000



root@lucy-11i386:/home/adrian #
Comment 1 mwm 2013-10-30 22:49:09 UTC
This is a duplicate of http://www.freebsd.org/cgi/query-pr.cgi?pr=usb/179505
.

We really need to get a leonardo into the hands of someone who knows the
USB stack. I've been buried (new job shortly after I reported this). Any
chance you can help here?
Comment 2 Adrian Chadd freebsd_committer freebsd_triage 2013-10-30 22:50:55 UTC
no; yours focuses on the weird USB protocol stuff going on. Mine sees
the devices, I don't see any stalls like you are now; it's just not
gluing umodem into the relevant interface.



-a


On 30 October 2013 15:49, Mike Meyer <mwm@mired.org> wrote:
> This is a duplicate of
> http://www.freebsd.org/cgi/query-pr.cgi?pr=usb/179505.
>
> We really need to get a leonardo into the hands of someone who knows the USB
> stack. I've been buried (new job shortly after I reported this). Any chance
> you can help here?
Comment 3 Adrian Chadd freebsd_committer freebsd_triage 2013-10-31 00:58:23 UTC
Here's a patch that fixes it:


===

adrian@lucy-11i386:~/work/freebsd/head/src % svn diff sys/dev/usb
Index: sys/dev/usb/serial/umodem.c
===================================================================
--- sys/dev/usb/serial/umodem.c (revision 257371)
+++ sys/dev/usb/serial/umodem.c (working copy)
@@ -128,6 +128,9 @@
        {USB_IFACE_CLASS(UICLASS_CDC),
                USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
                USB_IFACE_PROTOCOL(UIPROTO_CDC_AT)},
+       {USB_IFACE_CLASS(UICLASS_CDC),
+               USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
+               USB_IFACE_PROTOCOL(UIPROTO_CDC_NONE)},
        /* Huawei Modem class match */
        {USB_IFACE_CLASS(UICLASS_CDC),
                USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
Index: sys/dev/usb/usb.h
===================================================================
--- sys/dev/usb/usb.h   (revision 257371)
+++ sys/dev/usb/usb.h   (working copy)
@@ -441,6 +441,7 @@
 #define        UISUBCLASS_ETHERNET_EMULATION_MODEL 12
 #define        UISUBCLASS_NETWORK_CONTROL_MODEL 13

+#define        UIPROTO_CDC_AT                  0
 #define        UIPROTO_CDC_AT                  1

 #define        UICLASS_HID             0x03

===

Reading the spec,
Comment 4 Adrian Chadd freebsd_committer freebsd_triage 2013-10-31 00:59:49 UTC
Gah, browser stupidity.

Here's the real one:

adrian@lucy-11i386:~/work/freebsd/head/src % svn diff sys/dev/usb
Index: sys/dev/usb/serial/umodem.c
===================================================================
--- sys/dev/usb/serial/umodem.c (revision 257371)
+++ sys/dev/usb/serial/umodem.c (working copy)
@@ -128,6 +128,9 @@
        {USB_IFACE_CLASS(UICLASS_CDC),
                USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
                USB_IFACE_PROTOCOL(UIPROTO_CDC_AT)},
+       {USB_IFACE_CLASS(UICLASS_CDC),
+               USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
+               USB_IFACE_PROTOCOL(UIPROTO_CDC_NONE)},
        /* Huawei Modem class match */
        {USB_IFACE_CLASS(UICLASS_CDC),
                USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
Index: sys/dev/usb/usb.h
===================================================================
--- sys/dev/usb/usb.h   (revision 257371)
+++ sys/dev/usb/usb.h   (working copy)
@@ -441,6 +441,7 @@
 #define        UISUBCLASS_ETHERNET_EMULATION_MODEL 12
 #define        UISUBCLASS_NETWORK_CONTROL_MODEL 13

+#define        UIPROTO_CDC_NONE                0
 #define        UIPROTO_CDC_AT                  1

 #define        UICLASS_HID             0x03

The USB 1.1 specification states that CDC=0 is just "no command
structure over the line", versus CDC=1 which says "AT commands".

This is enough to make the Leonardo work fine.

Thanks to everyone else who fixed the USB protocol mis-behvaiour!



-adrian
Comment 5 mwm 2013-10-31 05:56:40 UTC
I'll confirm that patch the issues I with the Leonardo in 179505. Also with
the Due, which I never reported as the behavior was identical to the
Leonardo. I've added a comment to that effect to 179505 as well.

Thanks!
Comment 6 HPS 2013-10-31 07:01:59 UTC
On 10/30/13 23:34, adrian chadd wrote:
>     bInterfaceProtocol = 0x0000

Hi,

The umodem driver currently only supports:

#define UIPROTO_CDC_AT                  1


You need to add more entries to:

static const STRUCT_USB_HOST_ID umodem_devs[] = {

--HPS
Comment 7 dfilter service freebsd_committer freebsd_triage 2013-10-31 13:54:59 UTC
Author: adrian
Date: Thu Oct 31 13:54:51 2013
New Revision: 257446
URL: http://svnweb.freebsd.org/changeset/base/257446

Log:
  Allow the Arduino Leonardo to work by supporting CDC=0 devices.
  
  CDC=0 simply means "no command codes", CDC=1 means "AT command codes."
  There's no driver change required!  It's purely to tell the application
  layer whether to speak AT commands or not.  Things are all still serial.
  
  PR:		usb/183505
  Reviewed by:	hps
  MFC after:	1 week

Modified:
  head/sys/dev/usb/serial/umodem.c
  head/sys/dev/usb/usb.h

Modified: head/sys/dev/usb/serial/umodem.c
==============================================================================
--- head/sys/dev/usb/serial/umodem.c	Thu Oct 31 13:47:39 2013	(r257445)
+++ head/sys/dev/usb/serial/umodem.c	Thu Oct 31 13:54:51 2013	(r257446)
@@ -128,6 +128,9 @@ static const STRUCT_USB_HOST_ID umodem_d
 	{USB_IFACE_CLASS(UICLASS_CDC),
 		USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
 		USB_IFACE_PROTOCOL(UIPROTO_CDC_AT)},
+	{USB_IFACE_CLASS(UICLASS_CDC),
+		USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),
+		USB_IFACE_PROTOCOL(UIPROTO_CDC_NONE)},
 	/* Huawei Modem class match */
 	{USB_IFACE_CLASS(UICLASS_CDC),
 		USB_IFACE_SUBCLASS(UISUBCLASS_ABSTRACT_CONTROL_MODEL),

Modified: head/sys/dev/usb/usb.h
==============================================================================
--- head/sys/dev/usb/usb.h	Thu Oct 31 13:47:39 2013	(r257445)
+++ head/sys/dev/usb/usb.h	Thu Oct 31 13:54:51 2013	(r257446)
@@ -441,6 +441,7 @@ typedef struct usb_interface_assoc_descr
 #define	UISUBCLASS_ETHERNET_EMULATION_MODEL 12
 #define	UISUBCLASS_NETWORK_CONTROL_MODEL 13
 
+#define	UIPROTO_CDC_NONE		0
 #define	UIPROTO_CDC_AT			1
 
 #define	UICLASS_HID		0x03
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 8 Boris Samorodov freebsd_committer freebsd_triage 2017-04-19 20:49:57 UTC
The problem seems to be fixed by the submitter. Beat me if not.