Author Topic: Composite Mass Storage & HID: enumeration problems  (Read 26087 times)

knbl

  • Member
  • ***
  • Posts: 4
Composite Mass Storage & HID: enumeration problems
« on: April 23, 2012, 12:01:10 pm »
Hi,

I have a composite device of Mass Storage and HID and have enumeration problems, especially on Windows hosts.

When testing the Mass Storage and HID function stand alone everything seems to work fine.
But when combining then, I see two strange things happening:
- Windows sometimes does multiple times configuration selection. Have seen this happening up to 10 or more times.
- Windows sometimes does not read the HID report descriptor at all. In that case the HID interface is not working correctly. I have only seen this happening after having multiple times the configuration selection.

Here is some info about my practical setup:
- Linux gadget having both the standard f_mass_storage and f_ffs
- User space application implementing the HID specific parts

I have an automated enumeration test that does enumeration until the HID report descriptor is read out and then restarts the test.
Below are the descriptors as read by usblyzer.

Thanks for your help.

Br,
Koen

Code: [Select]
USB Composite Device

Connection Status Device connected
Current Configuration 1
Speed High
Device Address 5
Number Of Open Pipes 4
Device Descriptor ***
Offset Field Size Value Description
0 bLength 1 12h
1 bDescriptorType 1 01h Device
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 idVendor 2 0600h ***
10 idProduct 2 0070h
12 bcdDevice 2 0000h 0.00
14 iManufacturer 1 03h "***"
15 iProduct 1 04h "***"
16 iSerialNumber 1 05h "0000000000"
17 bNumConfigurations 1 01h
Device Qualifier Descriptor
Offset Field Size Value Description
0 bLength 1 0Ah
1 bDescriptorType 1 06h Device Qualifier
2 bcdUSB 2 0200h USB Spec 2.0
4 bDeviceClass 1 00h Class info in Ifc Descriptors
5 bDeviceSubClass 1 00h
6 bDeviceProtocol 1 00h
7 bMaxPacketSize0 1 40h 64 bytes
8 bNumConfigurations 1 01h
9 bReserved 1 00h
Configuration Descriptor 1 Bus Powered, 500 mA
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 02h Configuration
2 wTotalLength 2 0040h
4 bNumInterfaces 1 02h
5 bConfigurationValue 1 01h
6 iConfiguration 1 00h
7 bmAttributes 1 80h Bus Powered
4..0: Reserved ...00000
5: Remote Wakeup ..0..... No
6: Self Powered .0...... No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0) 1.......
8 bMaxPower 1 FAh 500 mA
Interface Descriptor 0/0 Mass Storage, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 08h Mass Storage
6 bInterfaceSubClass 1 06h SCSI Transparent Command Set
7 bInterfaceProtocol 1 50h Bulk-Only Transport
8 iInterface 1 02h "Mass Storage"
Endpoint Descriptor 81 1 In, Bulk, 512 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 02h Bulk
1..0: Transfer Type ......10 Bulk
7..2: Reserved 000000..
4 wMaxPacketSize 2 0200h 512 bytes
6 bInterval 1 00h
Endpoint Descriptor 01 1 Out, Bulk, 512 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 01h 1 Out
3 bmAttributes 1 02h Bulk
1..0: Transfer Type ......10 Bulk
7..2: Reserved 000000..
4 wMaxPacketSize 2 0200h 512 bytes
6 bInterval 1 01h
Interface Descriptor 1/0 HID, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 01h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 01h "***"
HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0101h 1.01
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0024h 36 bytes
Endpoint Descriptor 82 2 In, Interrupt, 125 us
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 82h 2 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0400h 1024 bytes
6 bInterval 1 01h 125 us
Endpoint Descriptor 02 2 Out, Interrupt, 125 us
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 02h 2 Out
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0400h 1024 bytes
6 bInterval 1 01h 125 us
Other Speed Configuration Descriptor 1 Bus Powered, 500 mA
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 07h Other Speed Configuration
2 wTotalLength 2 0040h
4 bNumInterfaces 1 02h
5 bConfigurationValue 1 01h
6 iConfiguration 1 00h
7 bmAttributes 1 80h Bus Powered
4..0: Reserved ...00000
5: Remote Wakeup ..0..... No
6: Self Powered .0...... No, Bus Powered
7: Reserved (set to one)
(bus-powered for 1.0) 1.......
8 bMaxPower 1 FAh 500 mA
Interface Descriptor 0/0 Mass Storage, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 00h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 08h Mass Storage
6 bInterfaceSubClass 1 06h SCSI Transparent Command Set
7 bInterfaceProtocol 1 50h Bulk-Only Transport
8 iInterface 1 02h "Mass Storage"
Endpoint Descriptor 81 1 In, Bulk, 64 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 81h 1 In
3 bmAttributes 1 02h Bulk
1..0: Transfer Type ......10 Bulk
7..2: Reserved 000000..
4 wMaxPacketSize 2 0040h 64 bytes
6 bInterval 1 00h
Endpoint Descriptor 01 1 Out, Bulk, 64 bytes
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 01h 1 Out
3 bmAttributes 1 02h Bulk
1..0: Transfer Type ......10 Bulk
7..2: Reserved 000000..
4 wMaxPacketSize 2 0040h 64 bytes
6 bInterval 1 00h
Interface Descriptor 1/0 HID, 2 Endpoints
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 04h Interface
2 bInterfaceNumber 1 01h
3 bAlternateSetting 1 00h
4 bNumEndpoints 1 02h
5 bInterfaceClass 1 03h HID
6 bInterfaceSubClass 1 00h
7 bInterfaceProtocol 1 00h
8 iInterface 1 01h "***"
HID Descriptor
Offset Field Size Value Description
0 bLength 1 09h
1 bDescriptorType 1 21h HID
2 bcdHID 2 0101h 1.01
4 bCountryCode 1 00h
5 bNumDescriptors 1 01h
6 bDescriptorType 1 22h Report
7 wDescriptorLength 2 0024h 36 bytes
Endpoint Descriptor 82 2 In, Interrupt
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 82h 2 In
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0008h 8 bytes
6 bInterval 1 80h
Endpoint Descriptor 02 2 Out, Interrupt
Offset Field Size Value Description
0 bLength 1 07h
1 bDescriptorType 1 05h Endpoint
2 bEndpointAddress 1 02h 2 Out
3 bmAttributes 1 03h Interrupt
1..0: Transfer Type ......11 Interrupt
7..2: Reserved 000000..
4 wMaxPacketSize 2 0008h 8 bytes
6 bInterval 1 80h
Interface 1 HID Report Descriptor Vendor-Defined 1
Item Tag (Value) Raw Data
Usage Page (Vendor-Defined 1) 06 00 FF
Usage (Vendor-Defined 1) 09 01
Collection (Application) A1 01
    Usage (Vendor-Defined 1) 09 01
    Logical Minimum (0) 15 00
    Logical Maximum (255) 26 FF 00
    Report Count (1024) 96 00 04
    Report Size (8) 75 08
    Input (Data,Var,Abs,NWrp,Lin,Pref,NNul,Bit) 81 02
    Usage (Vendor-Defined 1) 09 01
    Logical Minimum (0) 15 00
    Logical Maximum (255) 26 FF 00
    Report Count (4096) 96 00 10
    Report Size (8) 75 08
    Output (Data,Var,Abs,NWrp,Lin,Pref,NNul,NVol,Bit) 91 02
End Collection C0
This report was generated by USBlyzer

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Composite Mass Storage & HID: enumeration problems
« Reply #1 on: April 23, 2012, 01:05:10 pm »
I doubt this is the problem, but bcdHID should be 0110 for HID 1.1; I've never seen a HID 1.01 spec, and support for interrupt OUT endpoints wasn't added until HID 1.1.

Be sure the device is sending the complete descriptor set when requested.

A hardware analyzer will show what is happening on the bus.

If your automated test is repeatedly re-enumerating the device with simulated detach/reattach, leave the device detached for at least a few seconds.

Jan


knbl

  • Member
  • ***
  • Posts: 4
Re: Composite Mass Storage & HID: enumeration problems
« Reply #2 on: April 24, 2012, 06:18:17 am »
Hi Jan,

Thanks for the quick reply.
I have corrected the HID spec version and now leave the device 5 seconds detached from the bus before entering the next test loop.

Still the same result: report descriptor not enumerated after a some time.

Have previously captured the problem with a LeCroy Voyager M3i but don't see the problem.
Now using usblyzer software analyser as the output it gives is more easy to understand.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Composite Mass Storage & HID: enumeration problems
« Reply #3 on: April 24, 2012, 08:54:23 am »
Does the device always ACK the Set_Configuration requests?

Any traffic between the multiple Set_Configuration requests?

Jan


knbl

  • Member
  • ***
  • Posts: 4
Re: Composite Mass Storage & HID: enumeration problems
« Reply #4 on: May 03, 2012, 06:41:43 am »
As far as i have seen the device always ACK's the set configuration requests. I will check again to make sure.

I do see much mass storage (SCSI) traffic even before Windows is reading the report descriptor. So I see windows reading all descriptors (except for the report descriptor); Then it start using the mass storage devices (see a lock of scsi traffic). The mass storage devices is read only and not very large (20 MB) and it seem Windows (7) is caching this completely. This is the traffic visible in the usb sniffer. Only already having captured a lot of mass storage transfers I do see the host reading the hid report descriptor.
Could this have any influence on correct enumeration?

First usb interface of the usb device is mass_storage, second is HID. I could try to change the order of these interfaces to see if that would help. This is however not very easily done with the setup (functionfs) is have here. I would only test this if there is a change that this would make any difference of course.

Tx,
Koen

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Composite Mass Storage & HID: enumeration problems
« Reply #5 on: May 03, 2012, 11:42:58 am »
This is worth a try -

Attach the device.

From Windows Device Manager, right-click the device and select uninstall.

Physically remove and reattach the device.

Jan

knbl

  • Member
  • ***
  • Posts: 4
Re: Composite Mass Storage & HID: enumeration problems
« Reply #6 on: May 08, 2012, 07:57:34 am »
I have changed the hid and mass storage interfaces on the devices (this was easier then i though before).
After that i needed to remove all registry entries for my VID/PID. Windows seems to remember this and before cleaning the registry entries for my VID/PID enumeration did not work at all anymore.

Now enumeration seem to go just fine every time. Seems like my issue is resolved. However, still strange that the order of interfaces makes any difference for Windows.

Thanks for the support.

Br,
Koen

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
Re: Composite Mass Storage & HID: enumeration problems
« Reply #7 on: May 08, 2012, 10:12:43 am »
Good to hear you got it working. The order of interfaces shouldn't matter.

Jan

coolsunny2012

  • Member
  • ***
  • Posts: 19
Re: Composite Mass Storage & HID: enumeration problems
« Reply #8 on: June 22, 2012, 04:22:41 pm »
Hi Koen,

I've a HID device and would like to configure my device as Composite Mass storage + HID.
As of now, I am able to configure the device as HID and wondering if you can give some pointers for how to configure my device as composite device.

I am using linux kernel 2.6.35 on iMX processor.

Tsuneo

  • Frequent Contributor
  • ****
  • Posts: 145
Re: Composite Mass Storage & HID: enumeration problems
« Reply #9 on: June 23, 2012, 09:21:04 am »
coolsunny2012,

Quote
I am using linux kernel 2.6.35 on iMX processor.

Maybe, continued from
http://www.janaxelson.com/forum/index.php?topic=879.0

On the Linux gadget (device) drivers directory, there isn't any example for MSC (Mass-Storage Class) + HID composite device. But you may modify existing composite example into your target one. It isn't so hard.

For example, acm_ms.c (CDC-ACM + MSC) gives you a good starting point.
Linux/drivers/usb/gadget/acm_ms.c
The major changes are as follows,

Code: [Select]
http://lxr.free-electrons.com/source/drivers/usb/gadget/acm_ms.c#L125

 36 /*
 37  * Kbuild is not very cooperative with respect to linking separately
 38  * compiled library objects into one module.  So for now we won't use
 39  * separate compilation ... ensuring init/exit sections work to shrink
 40  * the runtime footprint, and giving us at least some parts of what
 41  * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
 42  */
 43
 44 #include "composite.c"
 45 #include "usbstring.c"
 46 #include "config.c"
 47 #include "epautoconf.c"
 48 #include "u_serial.c"
 49 #include "f_acm.c"         // <-------- replace to "f_hid.c"
 50 #include "f_mass_storage.c"

Code: [Select]
http://lxr.free-electrons.com/source/drivers/usb/gadget/acm_ms.c#L125

125 /*
126  * We _always_ have both ACM and mass storage functions.
127  */
128 static int __init acm_ms_do_config(struct usb_configuration *c)
129 {
130         int     status;
131
132         if (gadget_is_otg(c->cdev->gadget)) {
133                 c->descriptors = otg_desc;
134                 c->bmAttributes |= USB_CONFIG_ATT_WAKEUP;
135         }
136
137
138         status = acm_bind_config(c, 0);      // <----- replace to hidg_bind_config()
139         if (status < 0)
140                 return status;
141
142         status = fsg_bind_config(c->cdev, c, &fsg_common);
143         if (status < 0)
144                 return status;
145
146         return 0;
147 }

You may also refer to /drivers/usb/gadget/hid.c, HID + HID composite device, to know how to set up HID  function driver for composite device.

Tsuneo
« Last Edit: June 29, 2015, 10:18:46 am by Jan Axelson »

coolsunny2012

  • Member
  • ***
  • Posts: 19
Re: Composite Mass Storage & HID: enumeration problems
« Reply #10 on: June 25, 2012, 04:38:32 pm »
Thanks Tsuneo for your suggestions. I started digging into the code and probably will open a new thread as a follow up.

Below is the reference code i am working on (minor changes compared to "http://lxr.free-electrons.com/source/drivers/usb/gadget/")  .
https://github.com/lgeek/linux-2.6.35.3-imx53/blob/master/drivers/usb/gadget



« Last Edit: June 25, 2012, 04:49:22 pm by coolsunny2012 »