Add super speed descriptors to the USB fastboot gadget. The
necessary bits and pieces are taken from Linux-6.3-rc2.

Signed-off-by: Sascha Hauer <[email protected]>
---
 drivers/usb/gadget/function/f_mass_storage.c | 40 ++++++++++++-------
 drivers/usb/gadget/function/storage_common.c | 42 ++++++++++++++++++++
 drivers/usb/gadget/function/storage_common.h |  6 +++
 3 files changed, 74 insertions(+), 14 deletions(-)

diff --git a/drivers/usb/gadget/function/f_mass_storage.c 
b/drivers/usb/gadget/function/f_mass_storage.c
index 4e9777994e..2c934c621a 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -2194,15 +2194,18 @@ reset:
        fsg = common->fsg;
 
        /* Enable the endpoints */
-       fsg->bulk_in->desc = fsg_ep_desc(common->gadget,
-                                        &fsg_fs_bulk_in_desc, 
&fsg_hs_bulk_in_desc);
+       rc = config_ep_by_speed(common->gadget, &(fsg->function), fsg->bulk_in);
+       if (rc)
+               goto reset;
        rc = enable_endpoint(common, fsg->bulk_in);
        if (rc)
                goto reset;
        fsg->bulk_in_enabled = 1;
 
-       fsg->bulk_out->desc = fsg_ep_desc(common->gadget,
-                                         &fsg_fs_bulk_out_desc, 
&fsg_hs_bulk_out_desc);
+       rc = config_ep_by_speed(common->gadget, &(fsg->function),
+                               fsg->bulk_out);
+       if (rc)
+               goto reset;
        rc = enable_endpoint(common, fsg->bulk_out);
        if (rc)
                goto reset;
@@ -2615,7 +2618,7 @@ static int fsg_bind(struct usb_configuration *c, struct 
usb_function *f)
        struct usb_gadget       *gadget = c->cdev->gadget;
        int                     ret;
        struct usb_ep           *ep;
-       struct usb_descriptor_header **hs_function = NULL;
+       unsigned                max_burst;
        struct fsg_common       *common = fsg->common;
 
        if (!ums_files) {
@@ -2656,17 +2659,26 @@ static int fsg_bind(struct usb_configuration *c, struct 
usb_function *f)
        ep->driver_data = common;       /* claim the endpoint */
        fsg->bulk_out = ep;
 
-       if (gadget_is_dualspeed(gadget)) {
-               /* Assume endpoint addresses are the same for both speeds */
-               fsg_hs_bulk_in_desc.bEndpointAddress =
-                       fsg_fs_bulk_in_desc.bEndpointAddress;
-               fsg_hs_bulk_out_desc.bEndpointAddress =
-                       fsg_fs_bulk_out_desc.bEndpointAddress;
-               hs_function = fsg_hs_function;
-       }
+       /* Assume endpoint addresses are the same for both speeds */
+       fsg_hs_bulk_in_desc.bEndpointAddress =
+               fsg_fs_bulk_in_desc.bEndpointAddress;
+       fsg_hs_bulk_out_desc.bEndpointAddress =
+               fsg_fs_bulk_out_desc.bEndpointAddress;
+
+       /* Calculate bMaxBurst, we know packet size is 1024 */
+       max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
+
+       fsg_ss_bulk_in_desc.bEndpointAddress =
+               fsg_fs_bulk_in_desc.bEndpointAddress;
+       fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
+
+       fsg_ss_bulk_out_desc.bEndpointAddress =
+               fsg_fs_bulk_out_desc.bEndpointAddress;
+       fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
 
        /* Copy descriptors */
-       return usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function, 
NULL, NULL);
+       return usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
+                                     fsg_ss_function, fsg_ss_function);
 
 autoconf_fail:
        ERROR(fsg, "unable to autoconfigure all endpoints\n");
diff --git a/drivers/usb/gadget/function/storage_common.c 
b/drivers/usb/gadget/function/storage_common.c
index 69fcd06565..60e0994235 100644
--- a/drivers/usb/gadget/function/storage_common.c
+++ b/drivers/usb/gadget/function/storage_common.c
@@ -104,6 +104,48 @@ struct usb_descriptor_header *fsg_hs_function[] = {
        NULL,
 };
 
+struct usb_endpoint_descriptor fsg_ss_bulk_in_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+};
+
+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+
+       /*.bMaxBurst =          DYNAMIC, */
+};
+
+struct usb_endpoint_descriptor fsg_ss_bulk_out_desc = {
+       .bLength =              USB_DT_ENDPOINT_SIZE,
+       .bDescriptorType =      USB_DT_ENDPOINT,
+
+       /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */
+       .bmAttributes =         USB_ENDPOINT_XFER_BULK,
+       .wMaxPacketSize =       cpu_to_le16(1024),
+};
+
+struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc = {
+       .bLength =              sizeof(fsg_ss_bulk_in_comp_desc),
+       .bDescriptorType =      USB_DT_SS_ENDPOINT_COMP,
+
+       /*.bMaxBurst =          DYNAMIC, */
+};
+
+struct usb_descriptor_header *fsg_ss_function[] = {
+       (struct usb_descriptor_header *) &fsg_intf_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_in_comp_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_out_desc,
+       (struct usb_descriptor_header *) &fsg_ss_bulk_out_comp_desc,
+       NULL,
+};
+EXPORT_SYMBOL_GPL(fsg_ss_function);
+
 /* Maxpacket and other transfer characteristics vary by speed. */
 struct usb_endpoint_descriptor *
 fsg_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
diff --git a/drivers/usb/gadget/function/storage_common.h 
b/drivers/usb/gadget/function/storage_common.h
index 3b98c82ee3..29afe77685 100644
--- a/drivers/usb/gadget/function/storage_common.h
+++ b/drivers/usb/gadget/function/storage_common.h
@@ -232,6 +232,12 @@ extern struct usb_endpoint_descriptor fsg_hs_bulk_in_desc;
 extern struct usb_endpoint_descriptor fsg_hs_bulk_out_desc;
 extern struct usb_descriptor_header *fsg_hs_function[];
 
+extern struct usb_endpoint_descriptor fsg_ss_bulk_in_desc;
+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_in_comp_desc;
+extern struct usb_endpoint_descriptor fsg_ss_bulk_out_desc;
+extern struct usb_ss_ep_comp_descriptor fsg_ss_bulk_out_comp_desc;
+extern struct usb_descriptor_header *fsg_ss_function[];
+
 int fsg_lun_open(struct fsg_lun *curlun, unsigned int num_sectors,
                 const char *filename);
 void fsg_lun_close(struct fsg_lun *curlun);
-- 
2.30.2


Reply via email to