Invalid FunctionFS USB Superspeed Descriptors

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

 



Hello again, I realize this is partially spec help, my apologies. I'm not aware of a better
place to potentially ask for guidance.

Interesting to note is that Windows fails to enumerate but Linux falls back to USB2.
On Windows, enumeration fails early enough I get no useful message.

The code is in Rust. If that is problematic I can rewrite it, but it is very close to C. The
USB HS descriptors work just fine. I suspect I have made a mistake in the companion
descriptors. It is hard to find good isochronous examples.

Thanks in advance.

-------

#[derive(Debug)]
#[repr(C, packed)]
pub struct usb_functionfs_ep_descs {
    intf: usb_interface_descriptor,
    sink: usb_endpoint_descriptor,
    source: usb_endpoint_descriptor,
    intf_alt1: usb_interface_descriptor,
    isoc_sink: usb_endpoint_descriptor,
    isoc_source: usb_endpoint_descriptor,
}

// Per example this is not packed.
#[derive(Debug)]
pub struct usb_functionfs_ss_ep_descs {
    intf: usb_interface_descriptor,
    sink: usb_endpoint_descriptor,
    sink_comp: usb_ss_ep_comp_descriptor,
    source: usb_endpoint_descriptor,
    source_comp: usb_ss_ep_comp_descriptor,
    intf_alt1: usb_interface_descriptor,
    isoc_sink: usb_endpoint_descriptor,
    isoc_sink_comp: usb_ss_ep_comp_descriptor,
    isoc_source: usb_endpoint_descriptor,
    isoc_source_comp: usb_ss_ep_comp_descriptor,
}

#[derive(Debug)]
#[repr(C, packed)]
pub struct usb_functionfs_descriptors {
    header: usb_functionfs_descs_head_v2,
    fs_count: u32,
    hs_count: u32,
    ss_count: u32,
    fs_descs: usb_functionfs_ep_descs,
    hs_descs: usb_functionfs_ep_descs,
    ss_descs: usb_functionfs_ss_ep_descs,
}

pub const fn descriptors() -> usb_functionfs_descriptors {
    usb_functionfs_descriptors {
        header: usb_functionfs_descs_head_v2 {
            magic: FUNCTIONFS_DESCRIPTORS_MAGIC_V2.to_le(),
            flags: (functionfs_flags_FUNCTIONFS_HAS_FS_DESC |
                    functionfs_flags_FUNCTIONFS_HAS_HS_DESC |
                    functionfs_flags_FUNCTIONFS_HAS_SS_DESC).to_le(),
            length: (mem::size_of::<usb_functionfs_descriptors>() as u32).to_le(),
        },
        fs_count: 6u32.to_le(),
        hs_count: 6u32.to_le(),
        ss_count: 10u32.to_le(),
        fs_descs: usb_functionfs_ep_descs {
            intf: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 0,
                bAlternateSetting: 0,
                bNumEndpoints: 2,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 1,
            },
            sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 1 | USB_DIR_IN as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 0,
                bInterval: 0,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 2 | USB_DIR_OUT as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 0,
                bInterval: 0,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            intf_alt1: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 1,
                bAlternateSetting: 1,
                bNumEndpoints: 2,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 2,
            },
            isoc_sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 3 | USB_DIR_IN as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            isoc_source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 4 | USB_DIR_OUT as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
        },
        hs_descs: usb_functionfs_ep_descs {
            intf: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 0,
                bAlternateSetting: 0,
                bNumEndpoints: 4,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 1,
            },
            sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 1 | USB_DIR_IN as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 512u16.to_le(),
                bInterval: 0,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 2 | USB_DIR_OUT as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 512u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            intf_alt1: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 1,
                bAlternateSetting: 1,
                bNumEndpoints: 2,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 2,
            },
            isoc_sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 3 | USB_DIR_IN as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            isoc_source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 4 | USB_DIR_OUT as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
        },
        ss_descs: usb_functionfs_ss_ep_descs {
            intf: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 0,
                bAlternateSetting: 0,
                bNumEndpoints: 4,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 1,
            },
            sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 1 | USB_DIR_IN as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 1024u16.to_le(),
                bInterval: 0,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            sink_comp: usb_ss_ep_comp_descriptor {
                bLength: USB_DT_SS_EP_COMP_SIZE as u8,
                bDescriptorType: USB_DT_SS_ENDPOINT_COMP as u8,
                bMaxBurst: 0,
                bmAttributes: 0,
                wBytesPerInterval: 0,
            },
            source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 2 | USB_DIR_OUT as u8,
                bmAttributes: USB_ENDPOINT_XFER_BULK as u8,
                wMaxPacketSize: 1024u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            source_comp: usb_ss_ep_comp_descriptor {
                bLength: USB_DT_SS_EP_COMP_SIZE as u8,
                bDescriptorType: USB_DT_SS_ENDPOINT_COMP as u8,
                bMaxBurst: 0,
                bmAttributes: 0,
                wBytesPerInterval: 0,
            },
            intf_alt1: usb_interface_descriptor {
                bLength: mem::size_of::<usb_interface_descriptor>() as u8,
                bDescriptorType: USB_DT_INTERFACE as u8,
                bInterfaceNumber: 1,
                bAlternateSetting: 1,
                bNumEndpoints: 2,
                bInterfaceClass: USB_CLASS_VENDOR_SPEC as u8,
                bInterfaceSubClass: 0,
                bInterfaceProtocol: 0,
                iInterface: 2,
            },
            isoc_sink: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 3 | USB_DIR_IN as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            isoc_sink_comp: usb_ss_ep_comp_descriptor {
                bLength: USB_DT_SS_EP_COMP_SIZE as u8,
                bDescriptorType: USB_DT_SS_ENDPOINT_COMP as u8,
                bMaxBurst: 0,
                bmAttributes: 0,
                wBytesPerInterval: 0,
            },
            isoc_source: usb_endpoint_descriptor {
                bLength: mem::size_of::<usb_endpoint_descriptor>() as u8,
                bDescriptorType: USB_DT_ENDPOINT as u8,
                bEndpointAddress: 4 | USB_DIR_OUT as u8,
                bmAttributes: (USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC | USB_ENDPOINT_USAGE_DATA) as u8,
                wMaxPacketSize: 256u16.to_le(),
                bInterval: 1,
                bRefresh: 0,
                bSynchAddress: 0,
            },
            isoc_source_comp: usb_ss_ep_comp_descriptor {
                bLength: USB_DT_SS_EP_COMP_SIZE as u8,
                bDescriptorType: USB_DT_SS_ENDPOINT_COMP as u8,
                bMaxBurst: 0,
                bmAttributes: 0,
                wBytesPerInterval: 0,
            },
        },
    }
}



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

  Powered by Linux