Windows 8.1 USB driver stack not USB 2 compliant

A bold statement, but …
The USB Specification Revision 2.0 para 9.5 states “… If the descriptor returns with a value in its length field that is greater than defined by this specification, the extra bytes are ignored by the host. but the next descriptor is located using the length returned rather than the length expected.”

Devices based on the Cypress CY7C67300 occasionally have to ‘pad’ the descriptors due to a BIOS issue in the device (See CYC67300 data sheet, errata 9).

Guess what, I have such a device and the (only) interface descriptor has been padded to return a length of 0x0A (c.f. 0x09 in the specification).

All versions of Windows that I have tried up to and including 7 (I haven’t tried 8) allow this device to enumerate and appear in device manager, fully working; on Windows 8.1 the device fails to start “Error code 10”. The same set of (my) drivers has been used in all cases.

So, I can …
order a complete recall of all devices in the field that will be used on 8.1 based machines to reflash the firmware, expensive and painful.
find a registry ‘tweak’ that relaxes MS’s Win 8.1 descriptor length checking, possible but unlikely
get MS to issue a patch ASAP, equally unlikely but surely the right way to go.

Any thoughts anyone?

xxxxx@sheard.force9.co.uk wrote:

A bold statement, but …
The USB Specification Revision 2.0 para 9.5 states “… If the descriptor returns with a value in its length field that is greater than defined by this specification, the extra bytes are ignored by the host. but the next descriptor is located using the length returned rather than the length expected.”

Devices based on the Cypress CY7C67300 occasionally have to ‘pad’ the descriptors due to a BIOS issue in the device (See CYC67300 data sheet, errata 9).

Guess what, I have such a device and the (only) interface descriptor has been padded to return a length of 0x0A (c.f. 0x09 in the specification).

All versions of Windows that I have tried up to and including 7 (I haven’t tried 8) allow this device to enumerate and appear in device manager, fully working; on Windows 8.1 the device fails to start “Error code 10”. The same set of (my) drivers has been used in all cases.

So, you had the bad luck to create a configuration descriptor that was
an exact multiple of 64 bytes? How did that happen, if you only had one
interface descriptor, and it has no endpoints? That shouldn’t be 64 bytes.

Is the driver for this device a custom driver that you wrote? Are you
able to duplicate this in house? Is your driver being loaded?

Code 10 usually means some driver in the stack failed during the PnP
“start” process, which means your PrepareHardware and your D0Entry
callbacks. Have you traced through the startup process to determine
exactly the error is being returned?

If the failure truly is coming from a standard Windows component, then
this definitely is a Windows bug, and a serious one at that. The spec,
as you point out, is quite clear.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Tim,

Thanks for response.

OK, the (relevant parts of the) descriptors (i.e. ignoring strings), as extracted by TDD are:

Information for device Hidden USB device (VID=0xXXXX PID=0xXXXX):

*** ERROR: Descriptor has errors! ***

Connection Information:

Connection status: Device connected
Device actual bus speed: Full
Device is hub: No
Device adress: 0x0003 (TDD’s spelling mistake :slight_smile:
Current configuration value: 0x00
Number of open pipes: 0

Device Descriptor:

0x12 bLength
0x01 bDescriptorType
0x0110 bcdUSB
0xFF bDeviceClass (Vendor specific)
0xFF bDeviceSubClass
0xFF bDeviceProtocol
0x08 bMaxPacketSize0 (8 Bytes)
0xXXXX idVendor
0xXXXX idProduct
0x0000 bcdDevice
0x01 iManufacturer “Hidden”
0x02 iProduct “Hidden”
0x03 iSerialNumber “Hidden”
0x01 bNumConfigurations
Hex dump:
0x12 0x01 0x10 0x01 0xFF 0xFF 0xFF 0x08 0xXX 0xXX
0xXX 0xXX 0x00 0x00 0x01 0x02 0x03 0x01

Configuration Descriptor:

0x09 bLength
0x02 bDescriptorType
0x0021 wTotalLength
0x01 bNumInterfaces
0x01 bConfigurationValue
0x00 iConfiguration
0xC0 bmAttributes (Self-powered Device)
0x00 bMaxPower (0 mA)
Hex dump:
0x09 0x02 0x21 0x00 0x01 0x01 0x00 0xC0 0x00

Interface Descriptor:

0x0A bLength
0x04 bDescriptorType
*** ERROR: Invalid descriptor length 0x0A
Hex dump:
0x0A 0x04 0x00 0x00 0x02 0xFF 0xFF 0xFF 0x00 0xCC

Endpoint Descriptor:

0x07 bLength
0x05 bDescriptorType
0x01 bEndpointAddress (OUT Endpoint)
0x02 bmAttributes (Transfer: Bulk / Synch: None / Usage: Data)
0x0040 wMaxPacketSize (64 Bytes)
0x00 bInterval
Hex dump:
0x07 0x05 0x01 0x02 0x40 0x00 0x00

Endpoint Descriptor:

0x07 bLength
0x05 bDescriptorType
0x82 bEndpointAddress (IN Endpoint)
0x03 bmAttributes (Transfer: Interrupt / Synch: None / Usage: Data)
0x0040 wMaxPacketSize (64 Bytes)
0x01 bInterval
Hex dump:
0x07 0x05 0x82 0x03 0x40 0x00 0x01

The Interface descriptor *should* be, if the Cypress chip’s BIOS wasn’t errata’d:
Interface Descriptor:

0x09 bLength
0x04 bDescriptorType
0x00 bInterfaceNumber
0x00 bAlternateSetting
0x02 bNumEndPoints
0xFF bInterfaceClass (Vendor specific)
0xFF bInterfaceSubClass
0xFF bInterfaceProtocol
0x00 iInterface
Hex dump:
0x09 0x04 0x00 0x00 0x02 0xFF 0xFF 0xFF 0x00

i.e. from 1 config, 1 interface and 2 endpoints a total descriptor length of 9 + 9 + 7 + 7 = 32 which is, as I’m sure you can calculate, an exact multiple of bMaxPacketSize0.

So I can’t use the correct length; I *may* be able to create a dummy (unused) endpoint descriptor on the end (and increase bNumEndPoints) to give me 39 bytes, but I haven’t tried this yet.

I will capture some startup debugging info this evening and post again.

OK, startup info, blank lines added around error:

Microsoft (R) Windows Debugger Version 6.12.0002.633 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Waiting for pipe \.\pipe\debug
Waiting to reconnect…
Connected to Windows 7 9600 x64 target at (Thu Dec 11 18:23:59.292 2014 (UTC + 0:00)), ptr64 TRUE
Kernel Debugger connection established.
WARNING: Path element is empty
Symbol search path is: srv*c:\MyServerSymbols*http://msdl.microsoft.com/download/symbols;;C:\Projects\AESSoftware\USB\VSVCPBus\VSVCPBus\sys\objchk_win7_amd64\amd64;C:\Projects\AESSoftware\USB\VSVCPBus\VSVCPort\sys\objchk_win7_amd64\amd64
Executable search path is:
Windows 7 Kernel Version 9600 MP (1 procs) Free x64
Built by: 9600.17415.amd64fre.winblue_r4.141028-1500
Machine Name:
Kernel base = 0xfffff80070a86000 PsLoadedModuleList = 0xfffff80070d5f250
System Uptime: 0 days 0:00:00.037
IOINIT: Built-in driver \Driver\hwpolicy failed to initialize with status - 0xC000025E
KDTARGET: Refreshing KD connection
VSVCPBus DriverEntry: VCP Bus Driver, Built Dec 8 2014 20:58:21
VSVCPBus DriverEntry: RegistryPath: \REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\VSVCPBus
VSVCPBus VSVCPBus_EvtDeviceAdd: Debug level: 6
VSVCPBus VSVCPBus_EvtDeviceAdd: Debug mask: 4294967295
VSVCPBus VSVCPBus_EvtDeviceAdd: pVSVCPBusContext:0xFFFFE000883E86E0
VSVCPBus GetDeviceEventLoggingNames: –>
VSVCPBus GetDeviceEventLoggingNames: Device Name: Hidden Hidden
VSVCPBus GetDeviceEventLoggingNames: Hardware ID: USB\VID_XXXX&PID_XXXX&REV_0000
VSVCPBus GetDeviceEventLoggingNames: Device Location: Port_#0002.Hub_#0001
VSVCPBus GetDeviceEventLoggingNames: <–
VSVCPBus VSVCPBus_EnumerateVSVCPorts: –>
VSVCPBus VSVCPBus_EnumerateVSVCPorts: Command base: 0
VSVCPBus VSVCPBus_EnumerateVSVCPorts: Command mask: 0x0F
VSVCPBus VSVCPBus_EnumerateVSVCPorts: Num device ports: 1
VSVCPBus CreateDevicePort: –>
VSVCPBus CreateDevicePort: Port number 1
VSVCPBus CreateDevicePort: <–, status 0x00000000
VSVCPBus VSVCPBus_EnumerateVSVCPorts: <–, status 0x00000000
VSVCPBus VSVCPBus_EvtDeviceAdd: Create VSDeviceNotify Interface
VSVCPBus VSVCPBus_EvtDeviceAdd: <–, status 0x00000000
VSVCPBus VSVCPBus_EvtDevicePrepareHardware: –>

VSVCPBus VSVCPBus_EvtDevicePrepareHardware: WdfUsbTargetDeviceCreate failed with status:0xC000000D

VSVCPBus VSVCPBus_EvtDriverContextCleanup: –>
VSVCPBus VSVCPBus_EvtDriverContextCleanup: <–

How come you’re able to give the conf descriptor length 9, but cannot use 9 for the interface descriptor?

Nothing to do with individual lengths, the problem with the Cypress chip is that the sum of descriptor lengths retrieved in one go can’t be an exact multiple of bMaxPacketSize0; i.e. 9 + 9 + 7 + 7 = 32 (as stated previously).

xxxxx@sheard.force9.co.uk wrote:

Nothing to do with individual lengths, the problem with the Cypress chip is that the sum of descriptor lengths retrieved in one go can’t be an exact multiple of bMaxPacketSize0; i.e. 9 + 9 + 7 + 7 = 32 (as stated previously).

Have you tried setting bcdUSB to 0x0200 and bMaxPacketSize0 to 64? That
would avoid the problem.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Indeed, but I’m not sure that the device actually supports it (the data sheet is a bit lacking in detail).

Also, this still involves a reflashing of devices which I would really like to avoid.

Anyone from MS care to chip in?

Did you capture a usb ETW log trace and see if it reports something actionable?

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@sheard.force9.co.uk
Sent: Thursday, December 11, 2014 1:01 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Windows 8.1 USB driver stack not USB 2 compliant

Indeed, but I’m not sure that the device actually supports it (the data sheet is a bit lacking in detail).

Also, this still involves a reflashing of devices which I would really like to avoid.

Anyone from MS care to chip in?


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

CancelMappedTransfer only makes sense for system DMA.

Doron,
Not yet - this weekend’s task!

Correct. Did someone mention CancelMappedTransfer?

-p

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@broadcom.com
Sent: Thursday, December 11, 2014 1:32 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] Windows 8.1 USB driver stack not USB 2 compliant

CancelMappedTransfer only makes sense for system DMA.


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer

I feel like I’m tuning a radio dial through separate stations… Weren’t we in a different thread?

Peter
OSR
@OSRDrivers

We were, and I didn’t see CancelMappedTransfer mentioned there either.

-p

Sent from my Windows Phone


From: xxxxx@osr.commailto:xxxxx
Sent: ?12/?12/?2014 7:11 AM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Windows 8.1 USB driver stack not USB 2 compliant



I feel like I’m tuning a radio dial through separate stations… Weren’t we in a different thread?

Peter
OSR
@OSRDrivers


NTDEV is sponsored by OSR

Visit the list at: http://www.osronline.com/showlists.cfm?list=ntdev

OSR is HIRING!! See http://www.osr.com/careers

For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars

To unsubscribe, visit the List Server section of OSR Online at http://www.osronline.com/page.cfm?name=ListServer</mailto:xxxxx></mailto:xxxxx>

Sorry, that’s the danger of having two threads open in the browser at the same time.

Used NetMon etc to log differences between a ‘real’ device and a simulated device - simulated meaning in this case a different development board running firmware that is close enough to the real firmware for USB enumeration/startup etc…

The one that *fails* never gets issued the control transfer ‘Set configuration’.
The one that succeeds, is issued a set configuration followed by 4 Endpoint Opens (that’s the main difference in the firmware - number of endpoints; other difference is therefore length of descriptors and also bMaxPacket0 is 64 c.f. 8)

I don’t seem to be able to post attachments to the forum so I can’t send the logs.

xxxxx@sheard.force9.co.uk wrote:

Used NetMon etc to log differences between a ‘real’ device and a simulated device - simulated meaning in this case a different development board running firmware that is close enough to the real firmware for USB enumeration/startup etc…

The one that *fails* never gets issued the control transfer ‘Set configuration’.
The one that succeeds, is issued a set configuration followed by 4 Endpoint Opens (that’s the main difference in the firmware - number of endpoints; other difference is therefore length of descriptors and also bMaxPacket0 is 64 c.f. 8)

That description alone is pretty revealing, in my opinion.

I don’t seem to be able to post attachments to the forum so I can’t send the logs.

If this catches the interest of someone in the USB team, I imagine they
will ask you privately for the logs. If it doesn’t, you may have to
open a product support incident. Assuming it is a Microsoft problem,
they will refund the initial fee.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Can you send ETW logs to me at vivekg(@)Microsoft.com

Here is another low-speed device which Win8.1 fails to detect,
because of error reading device descriptor.

http://vusb.wikidot.com/project:driver-less-usb-relays-hid-interface

It works happily on Win7 sp1, XP and Linux on same machine.

Regards,
– pa

On Tue, Dec 23, 2014 at 10:38 AM, Pavel A. wrote:
> Here is another low-speed device which Win8.1 fails to detect,
> because of error reading device descriptor.
>
> http://vusb.wikidot.com/project:driver-less-usb-relays-hid-interface
>
> It works happily on Win7 sp1, XP and Linux on same machine.

You are lucky that it works under any machines. It is based on
the V-USB “firmware only USB driver for AVR”.

Read this one:
http://www.obdev.at/products/vusb/index.html

“Features
Fully USB 1.1 compliant low-speed device, except handling of
communication errors and electrical specifications.”

It might have its usage when USB MCUs are a bit expensive
for hobbyists. Now there are many USB MCUs available. No
need to resort to this kind of non-compliant implementations.


Xiaofan