usb: gadget: f_fs: Re-use SS descriptors for SuperSpeedPlus

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>
This commit is contained in:
Jack Pham 2020-10-27 16:07:31 -07:00 committed by Greg Kroah-Hartman
parent 457a902ba1
commit a353397b0d
1 changed files with 4 additions and 1 deletions

View File

@ -1330,6 +1330,7 @@ static long ffs_epfile_ioctl(struct file *file, unsigned code,
switch (epfile->ffs->gadget->speed) { switch (epfile->ffs->gadget->speed) {
case USB_SPEED_SUPER: case USB_SPEED_SUPER:
case USB_SPEED_SUPER_PLUS:
desc_idx = 2; desc_idx = 2;
break; break;
case USB_SPEED_HIGH: case USB_SPEED_HIGH:
@ -3176,7 +3177,8 @@ static int _ffs_func_bind(struct usb_configuration *c,
} }
if (likely(super)) { 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, ss_len = ffs_do_descs(ffs->ss_descs_count,
vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len, vla_ptr(vlabuf, d, raw_descs) + fs_len + hs_len,
d_raw_descs__sz - fs_len - hs_len, d_raw_descs__sz - fs_len - hs_len,
@ -3586,6 +3588,7 @@ static void ffs_func_unbind(struct usb_configuration *c,
func->function.fs_descriptors = NULL; func->function.fs_descriptors = NULL;
func->function.hs_descriptors = NULL; func->function.hs_descriptors = NULL;
func->function.ss_descriptors = NULL; func->function.ss_descriptors = NULL;
func->function.ssp_descriptors = NULL;
func->interfaces_nums = NULL; func->interfaces_nums = NULL;
ffs_event_add(ffs, FUNCTIONFS_UNBIND); ffs_event_add(ffs, FUNCTIONFS_UNBIND);