* Unable to use struct usb_endpoint_descriptor in FunctionFS
@ 2020-06-20 4:04 Sid Spry
2020-06-20 14:24 ` Alan Stern
0 siblings, 1 reply; 4+ messages in thread
From: Sid Spry @ 2020-06-20 4:04 UTC (permalink / raw)
To: linux-usb
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,
.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!
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unable to use struct usb_endpoint_descriptor in FunctionFS
2020-06-20 4:04 Unable to use struct usb_endpoint_descriptor in FunctionFS Sid Spry
@ 2020-06-20 14:24 ` Alan Stern
2020-06-21 0:58 ` Sid Spry
0 siblings, 1 reply; 4+ messages in thread
From: Alan Stern @ 2020-06-20 14:24 UTC (permalink / raw)
To: Sid Spry; +Cc: linux-usb
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
> .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!
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unable to use struct usb_endpoint_descriptor in FunctionFS
2020-06-20 14:24 ` Alan Stern
@ 2020-06-21 0:58 ` Sid Spry
2020-06-21 1:59 ` Sid Spry
0 siblings, 1 reply; 4+ messages in thread
From: Sid Spry @ 2020-06-21 0:58 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb
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!
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Unable to use struct usb_endpoint_descriptor in FunctionFS
2020-06-21 0:58 ` Sid Spry
@ 2020-06-21 1:59 ` Sid Spry
0 siblings, 0 replies; 4+ messages in thread
From: Sid Spry @ 2020-06-21 1:59 UTC (permalink / raw)
To: Alan Stern; +Cc: linux-usb
So, I solved this: all structures must be the same type. However I will
start a new thread about the issues I am experiencing. It looks like the
behavior of the endpoint isn't isochronous at all, no data is dropped.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-06-21 1:59 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-20 4:04 Unable to use struct usb_endpoint_descriptor in FunctionFS Sid Spry
2020-06-20 14:24 ` Alan Stern
2020-06-21 0:58 ` Sid Spry
2020-06-21 1:59 ` Sid Spry
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.