Re: Unable to use struct usb_endpoint_descriptor in FunctionFS

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

 



On Sat, Jun 20, 2020, at 9:24 AM, Alan Stern wrote:
> On Fri, Jun 19, 2020 at 11:04:31PM -0500, Sid Spry wrote:
> > Hello, I've figured out how to get my userspace driver code to enumerate for
> > the host and send/receive from the device with bulk endpoints as demonstrated
> > in ffs-test.c. I have successfully added another bulk endpoint, but issues
> > arise when I try to add an isochronous endpoint.
> > 
> > I've tracked the problem, I think, to the mere presence of the struct
> > usb_endpoint_descriptor. Is anyone able to elucidate what I might be missing?
> > 
> > The rejected set of descriptors follows. Note I set the usb_endpoint_descriptor
> > struct to be a bulk endpoint; I expect the extra fields would be ignored.
> > 
> > I can provide the full code if helpful. Superspeed descriptors commented out
> > as I'm less familiar with USB3 and I found that the fs/hs/ss descriptor sets had
> > to be equivalent.
> > 
> > ```
> > static const struct {
> > 	struct usb_functionfs_descs_head_v2 header;
> > 	__le32 fs_count;
> > 	__le32 hs_count;
> > 	//__le32 ss_count;
> > 	struct {
> > 		struct usb_interface_descriptor intf;
> > 		struct usb_endpoint_descriptor_no_audio sink;
> > 		struct usb_endpoint_descriptor_no_audio source;
> > 		struct usb_endpoint_descriptor iso_sink;
> > 	} __attribute__((packed)) fs_descs, hs_descs;
> > 	/*struct {
> > 		struct usb_interface_descriptor intf;
> > 		struct usb_endpoint_descriptor_no_audio sink;
> > 		struct usb_ss_ep_comp_descriptor sink_comp;
> > 		struct usb_endpoint_descriptor_no_audio source;
> > 		struct usb_ss_ep_comp_descriptor source_comp;
> > 	} ss_descs;*/
> > } __attribute__((packed)) descriptors = {
> > 	.header = {
> > 		.magic  = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
> > 		.length = cpu_to_le32(sizeof descriptors),
> > 		.flags  = cpu_to_le32(FUNCTIONFS_HAS_FS_DESC |
> > 				     FUNCTIONFS_HAS_HS_DESC), // |
> > 				     //FUNCTIONFS_HAS_SS_DESC),
> > 	},
> > 	.fs_count = cpu_to_le32(4),
> > 	.hs_count = cpu_to_le32(4),
> > 	//.ss_count = cpu_to_le32(5),
> > 	.fs_descs = {
> > 		.intf = {
> > 			.bLength = sizeof descriptors.fs_descs.intf,
> > 			.bDescriptorType = USB_DT_INTERFACE,
> > 			.bNumEndpoints = 2,
> 
> This should be 3, not 2.
> 
> Alan Stern
> 

Thanks for catching this. However, that change does not solve the problem. It
seems fs_count and hs_count supercede that number. I never used USB FS but if
I had I probably would have noticed the dropped endpoint.

With the fix you provided I still get "Invalid argument" when attempting to
write the descriptors to ep0. If I change the struct to the _no_audio version
then it works with no other changes.


I appreciate the help, this is something I've been doing on/off for about ~6mo
from the Linux side. Wasted about 2 years with proprietary MCU stuff.

> > 			.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
> > 			.iInterface = 1,
> > 		},
> > 		.sink = {
> > 			.bLength = sizeof descriptors.fs_descs.sink,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 1 | USB_DIR_IN,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			/* .wMaxPacketSize = autoconfiguration (kernel) */
> > 		},
> > 		.source = {
> > 			.bLength = sizeof descriptors.fs_descs.source,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 2 | USB_DIR_OUT,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			/* .wMaxPacketSize = autoconfiguration (kernel) */
> > 		},
> > 		.iso_sink = {
> > 			.bLength = sizeof descriptors.fs_descs.iso_sink,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 3 | USB_DIR_OUT,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 		},
> > 	},
> > 	.hs_descs = {
> > 		.intf = {
> > 			.bLength = sizeof descriptors.fs_descs.intf,
> > 			.bDescriptorType = USB_DT_INTERFACE,
> > 			.bNumEndpoints = 3,
> > 			.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
> > 			.iInterface = 1,
> > 		},
> > 		.sink = {
> > 			.bLength = sizeof descriptors.hs_descs.sink,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 1 | USB_DIR_IN,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			.wMaxPacketSize = cpu_to_le16(512),
> > 		},
> > 		.source = {
> > 			.bLength = sizeof descriptors.hs_descs.iso_sink,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 2 | USB_DIR_OUT,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			.wMaxPacketSize = cpu_to_le16(512),
> > 			.bInterval = 1,
> > 		},
> > 		.iso_sink = {
> > 			.bLength = sizeof descriptors.hs_descs.source,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 3 | USB_DIR_OUT,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			.wMaxPacketSize = cpu_to_le16(512),
> > 			.bInterval = 1,
> > 		},
> > 
> > 	},
> > 	/*.ss_descs = {
> > 		.intf = {
> > 			.bLength = sizeof descriptors.fs_descs.intf,
> > 			.bDescriptorType = USB_DT_INTERFACE,
> > 			.bNumEndpoints = 2,
> > 			.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
> > 			.iInterface = 1,
> > 		},
> > 		.sink = {
> > 			.bLength = sizeof descriptors.hs_descs.sink,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 1 | USB_DIR_IN,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			.wMaxPacketSize = cpu_to_le16(1024),
> > 		},
> > 		.sink_comp = {
> > 			.bLength = USB_DT_SS_EP_COMP_SIZE,
> > 			.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
> > 			.bMaxBurst = 0,
> > 			.bmAttributes = 0,
> > 			.wBytesPerInterval = 0,
> > 		},
> > 		.source = {
> > 			.bLength = sizeof descriptors.hs_descs.source,
> > 			.bDescriptorType = USB_DT_ENDPOINT,
> > 			.bEndpointAddress = 2 | USB_DIR_OUT,
> > 			.bmAttributes = USB_ENDPOINT_XFER_BULK,
> > 			.wMaxPacketSize = cpu_to_le16(1024),
> > 			.bInterval = 1,
> > 		},
> > 		.source_comp = {
> > 			.bLength = USB_DT_SS_EP_COMP_SIZE,
> > 			.bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
> > 			.bMaxBurst = 0,
> > 			.bmAttributes = 0,
> > 			.wBytesPerInterval = 0,
> > 		},
> > 	},*/
> > };
> > ```
> > 
> > Cheers!
>



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

  Powered by Linux