]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
usb: gadget: f_fs: Re-use SS descriptors for SuperSpeedPlus
authorJack Pham <jackp@codeaurora.org>
Tue, 27 Oct 2020 23:07:31 +0000 (16:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 29 Dec 2020 12:46:49 +0000 (13:46 +0100)
commit a353397b0d5dfa3c99b372505db3378fc919c6c6 upstream.

In many cases a function that supports SuperSpeed can very well
operate in SuperSpeedPlus, if a gadget controller supports it,
as the endpoint descriptors (and companion descriptors) are
generally identical and can be re-used. This is true for two
commonly used functions: Android's ADB and MTP. So we can simply
assign the usb_function's ssp_descriptors array to point to its
ss_descriptors, if available. Similarly, we need to allow an
epfile's ioctl for FUNCTIONFS_ENDPOINT_DESC to correctly
return the corresponding SuperSpeed endpoint descriptor in case
the connected speed is SuperSpeedPlus as well.

The only exception is if a function wants to implement an
Isochronous endpoint capable of transferring more than 48KB per
service interval when operating at greater than USB 3.1 Gen1
speed, in which case it would require an additional SuperSpeedPlus
Isochronous Endpoint Companion descriptor to be returned as part
of the Configuration Descriptor. Support for that would need
to be separately added to the userspace-facing FunctionFS API
which may not be a trivial task--likely a new descriptor format
(v3?) may need to be devised to allow for separate SS and SSP
descriptors to be supplied.

Signed-off-by: Jack Pham <jackp@codeaurora.org>
Cc: stable <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20201027230731.9073-1-jackp@codeaurora.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/f_fs.c

index 2f98161d062e2f2c66da936ed612c327b6d854e4..9f1bb8ed99bc7461a9fa40b62d127d52d3d18c4e 100644 (file)
@@ -1248,6 +1248,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
 
                switch (epfile->ffs->gadget->speed) {
                case USB_SPEED_SUPER:
+               case USB_SPEED_SUPER_PLUS:
                        desc_idx = 2;
                        break;
                case USB_SPEED_HIGH:
@@ -3067,7 +3068,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
        }
 
        if (likely(super)) {
-               func->function.ss_descriptors = vla_ptr(vlabuf, d, ss_descs);
+               func->function.ss_descriptors = func->function.ssp_descriptors =
+                       vla_ptr(vlabuf, d, ss_descs);
                ss_len = ffs_do_descs(ffs->ss_descs_count,
                                vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len,
                                d_raw_descs__sz - fs_len - hs_len,
@@ -3477,6 +3479,7 @@ static void ffs_func_unbind(struct usb_configuration *c,
        func->function.fs_descriptors = NULL;
        func->function.hs_descriptors = NULL;
        func->function.ss_descriptors = NULL;
+       func->function.ssp_descriptors = NULL;
        func->interfaces_nums = NULL;
 
        ffs_event_add(ffs, FUNCTIONFS_UNBIND);