Bug 203289 - BeagleBone Black invalid USB target descriptors
Summary: BeagleBone Black invalid USB target descriptors
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-usb (Nobody)
URL:
Keywords:
Depends on:
Blocks: 203349
  Show dependency treegraph
 
Reported: 2015-09-23 18:15 UTC by Ed Maste
Modified: 2018-06-01 09:18 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ed Maste freebsd_committer freebsd_triage 2015-09-23 18:15:56 UTC
BeagleBone Black image has a number of issues with the USB target, found while using http://www.usblyzer.com/ to get the BBB serial console working with Windows.

# usbconfig -d ugen1.5 dump_device_desc
ugen1.5: <SERIALNET The FreeBSD Project> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (50mA)

  bLength = 0x0012 
  bDescriptorType = 0x0001 
  bcdUSB = 0x0200 
  bDeviceClass = 0x0002  <Communication device>
  bDeviceSubClass = 0x0000 
  bDeviceProtocol = 0x0000 
  bMaxPacketSize0 = 0x0040 
  idVendor = 0x0001 
  idProduct = 0x0001 
  bcdDevice = 0x0100 
  iManufacturer = 0x0007  <The FreeBSD Project>
  iProduct = 0x0008  <SERIALNET>
  iSerialNumber = 0x0009  <January 2015>
  bNumConfigurations = 0x0001 

The image presents a composite device and it seems that this typically requires either bDeviceClass to be zero, or bDeviceClass, bDeviceSubClass and bDeviceProtocol are 0xEF, 0x02, and 0x01 respectively.

usblyzer also reports (for the Device Qualifier Descriptor):
bMaxPacketSize0 00h Should be 64 bytes for high-speed devices
bNumConfigurations 00h Should be greater than zero

Note that Device Descriptor bMaxPacketSize is 64 and bNumConfigurations is 1
Comment 1 Ed Maste freebsd_committer freebsd_triage 2015-09-23 18:17:16 UTC
For reference here is the Device Descriptor for the stock Linux BBB image:

ugen1.5: <BeagleBoneBlack Circuitco> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)

  bLength = 0x0012 
  bDescriptorType = 0x0001 
  bcdUSB = 0x0200 
  bDeviceClass = 0x00ef  <Miscellaneous device>
  bDeviceSubClass = 0x0002 
  bDeviceProtocol = 0x0001 
  bMaxPacketSize0 = 0x0040 
  idVendor = 0x1d6b 
  idProduct = 0x0104 
  bcdDevice = 0x0308 
  iManufacturer = 0x0002  <Circuitco>
  iProduct = 0x0003  <BeagleBoneBlack>
  iSerialNumber = 0x0004  <5A-1513BBBK3026>
  bNumConfigurations = 0x0001 

and dump_all_config_desc:

ugen1.5: <BeagleBoneBlack Circuitco> at usbus1, cfg=0 md=HOST spd=HIGH (480Mbps) pwr=ON (2mA)


 Configuration index 0

    bLength = 0x0009 
    bDescriptorType = 0x0002 
    wTotalLength = 0x00a4 
    bNumInterfaces = 0x0005 
    bConfigurationValue = 0x0001 
    iConfiguration = 0x0005  <Multifunction with RNDIS>
    bmAttributes = 0x00c0 
    bMaxPower = 0x0001 

    Additional Descriptor

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


    Interface 0
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0001 
      bInterfaceClass = 0x0002  <Communication device>
      bInterfaceSubClass = 0x0002 
      bInterfaceProtocol = 0x00ff 
      iInterface = 0x0007  <RNDIS Communications Control>

      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, 0x00, 0x01


      Additional Descriptor

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


      Additional Descriptor

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


     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0082  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0008 
        bInterval = 0x0009 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 


    Interface 1
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0001 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x000a  <CDC-data>
      bInterfaceSubClass = 0x0000 
      bInterfaceProtocol = 0x0000 
      iInterface = 0x0008  <RNDIS Ethernet Data>

     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200 
        bInterval = 0x0000 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 

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

      Additional Descriptor

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



    Interface 2
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0002 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0001 
      bInterfaceClass = 0x0002  <Communication device>
      bInterfaceSubClass = 0x0002 
      bInterfaceProtocol = 0x0001 
      iInterface = 0x000a  <CDC Abstract Control Model (ACM)>

      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, 0x00, 0x03


      Additional Descriptor

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


      Additional Descriptor

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


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


    Interface 3
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0003 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x000a  <CDC-data>
      bInterfaceSubClass = 0x0000 
      bInterfaceProtocol = 0x0000 
      iInterface = 0x000b  <CDC ACM Data>

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

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


    Interface 4
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0004 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0002 
      bInterfaceClass = 0x0008  <Mass storage>
      bInterfaceSubClass = 0x0006 
      bInterfaceProtocol = 0x0050 
      iInterface = 0x0001  <Mass Storage>

     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0085  <IN>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200 
        bInterval = 0x0000 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 

     Endpoint 1
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0003  <OUT>
        bmAttributes = 0x0002  <BULK>
        wMaxPacketSize = 0x0200 
        bInterval = 0x0001 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000
Comment 2 Hans Petter Selasky freebsd_committer freebsd_triage 2015-09-23 18:52:27 UTC
Hi,

You can change the descriptors values in sys/dev/usb/template/usb_template_serialnet.c .

Are you able to make a patch?

Regarding the device qualifier descriptor, I'll have a look. It is currently not used for enumeration, only when trying to switch the device to another USB speed.

--HPS
Comment 3 Hans Petter Selasky freebsd_committer freebsd_triage 2015-09-23 18:58:59 UTC
More specifically this structure:

const struct usb_temp_device_desc usb_template_serialnet = {
        .getStringDesc = &serialnet_get_string_desc,
        .ppConfigDesc = serialnet_configs,
        .idVendor = USB_TEMPLATE_VENDOR,
        .idProduct = 0x0001,
        .bcdDevice = 0x0100,
        .bDeviceClass = UDCLASS_COMM,
        .bDeviceSubClass = 0,
        .bDeviceProtocol = 0,
        .iManufacturer = STRING_VENDOR_INDEX,
        .iProduct = STRING_PRODUCT_INDEX,
        .iSerialNumber = STRING_SERIAL_INDEX,
};

--HPS
Comment 4 Ed Maste freebsd_committer freebsd_triage 2015-09-23 20:04:03 UTC
Hi HPS, thanks for the reply. I put this in to keep track of this issue while investigating it; I'll have a look at updating the descriptor values in the template when I get set up for BBB builds in a bit.

I was able to get a functional USB serial port in Windows with the BBB image despite the device qualifier descriptor issue, it's just that the USB tool complained.

As an aside, we'll need to do something different to support the network interface with Windows hosts. This page makes it sound like Windows has support for the CDC Ethernet Networking Control Model:
https://msdn.microsoft.com/en-us/library/windows/hardware/ff537037%28v=vs.85%29.aspx
but I wasn't able to actually find any evidence of that (looking for Class_02 and SubClass_06).

It looks like the options are:

* 3rd party CDC Ethernet class drivers for Windows
http://www.thesycon.de/eng/usb_network.shtml
These are proprietary and Windows 10 is "coming soon"

* Implement CDC MBIM target in FreeBSD
Likely fairly straightforward. MBIM does not Ethernet encapsulate
frames, I think it's just IP.

* Implement RNDIS target in FreeBSD
The host side (if_urndis.c) is pretty small - we could probably implement it without much trouble.
Comment 5 commit-hook freebsd_committer freebsd_triage 2018-06-01 09:17:57 UTC
A commit references this bug:

Author: trasz
Date: Fri Jun  1 09:17:20 UTC 2018
New revision: 334476
URL: https://svnweb.freebsd.org/changeset/base/334476

Log:
  Set bDeviceClass properly for composite device (template 8).  There should
  be no functional change.

  PR:		203289
  Reviewed by:	hselasky@
  MFC after:	2 weeks
  Sponsored by:	The FreeBSD Foundation

Changes:
  head/sys/dev/usb/template/usb_template_serialnet.c