Re: OS Descriptor version in FunctionFS

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

My apologies, I had some misunderstandings.
After rechecking using USB packet capture, I found the following details.

First. Actually, the Windoes host appears to accept only bcdVersion = 0x0100.

Normally, during the USB enumeration phase, OS descs are exchanged in the
following steps.
1. Requests only the header section of the OS desc from the host to the device.
2. Returns the header section of the OS desc from the device to the host.
3. Request the entire OS desc from the host to the device.
4. Return the entire OS desc from the device to the host.

Here I found that if bcdVersion != 0x0100 is set in the OS desc header, then
3 and 4 are skipped. If the device has not been connected to the host before,
and if the right driver cannot be determined from the bDeviceClass, etc.,
the host will fail to autoload the driver. When I tried bcdVersion != 0x0100 in
the past, I was mistaken because the host had a memory of connecting a device
with the same VID, PID and the driver autoloading was performed.


Second, even though bcdVersion = 0x0001 was set on the FunctionFS user mode
driver, bcdVersion = 0x0100 was set on the packets actually flowing. It is the
composite driver that is actually filling the data to be sent, and that driver
only reads the body of the descriptor received from FunctionFS and does not
seem to care about the headers.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/usb/gadget/composite.c#n1971

> 			os_desc_cfg = cdev->os_desc_config;
> 			w_length = min_t(u16, w_length, USB_COMP_EP0_OS_DESC_BUFSIZ);
> 			memset(buf, 0, w_length);
> 			buf[5] = 0x01; // <- here
> 			switch (ctrl->bRequestType & USB_RECIP_MASK) {
> 			case USB_RECIP_DEVICE:
> 				if (w_index != 0x4 || (w_value >> 8))

bcdVersion = 0x0100 is set here.


Now, if in fact bcdVersion = 0x0100 is correct,

> static int __ffs_do_os_desc_header(enum ffs_os_desc_type *next_type,
> 				   struct usb_os_desc_header *desc)
> {
> 	u16 bcd_version = le16_to_cpu(desc->bcdVersion);
> 	u16 w_index = le16_to_cpu(desc->wIndex);
> 
> 	if (bcd_version != 1) {
> 		pr_vdebug("unsupported os descriptors version: %d",
> 			  bcd_version);
> 		return -EINVAL;
> 	}

this would be confusing.
I think it would be better to modify the condition or perhaps even remove the
value checks.


Regards,

Yuta Hayama



[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux