Skip to content

Commit dc241f0

Browse files
jbrun3twuliangfeng
authored andcommitted
UPSTREAML: usb: gadget: f_uac2: reset wMaxPacketSize
With commit 913e4a9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") wMaxPacketSize is computed dynamically but the value is never reset. Because of this, the actual maximum packet size can only decrease each time the audio gadget is instantiated. Reset the endpoint maximum packet size and mark wMaxPacketSize as dynamic to solve the problem. Change-Id: Idccb5e19358f1cab9d08325f39969cf216a98b8e Fixes: 913e4a9 ("usb: gadget: f_uac2: finalize wMaxPacketSize according to bandwidth") Signed-off-by: Jerome Brunet <jbrunet@baylibre.com> Cc: stable <stable@vger.kernel.org> Link: https://lore.kernel.org/r/20201221173531.215169-2-jbrunet@baylibre.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: William Wu <william.wu@rock-chips.com> (cherry picked from commit 9389044f27081d6ec77730c36d5bf9a1288bcda2)
1 parent e9bffaa commit dc241f0

File tree

1 file changed

+56
-15
lines changed

1 file changed

+56
-15
lines changed

drivers/usb/gadget/function/f_uac2.c

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = {
336336

337337
.bEndpointAddress = USB_DIR_OUT,
338338
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE,
339-
.wMaxPacketSize = cpu_to_le16(1023),
339+
/* .wMaxPacketSize = DYNAMIC */
340340
.bInterval = 1,
341341
};
342342

@@ -345,7 +345,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = {
345345
.bDescriptorType = USB_DT_ENDPOINT,
346346

347347
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE,
348-
.wMaxPacketSize = cpu_to_le16(1024),
348+
/* .wMaxPacketSize = DYNAMIC */
349349
.bInterval = 4,
350350
};
351351

@@ -413,7 +413,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = {
413413

414414
.bEndpointAddress = USB_DIR_IN,
415415
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_SYNC,
416-
.wMaxPacketSize = cpu_to_le16(1023),
416+
/* .wMaxPacketSize = DYNAMIC */
417417
.bInterval = 1,
418418
};
419419

@@ -422,7 +422,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = {
422422
.bDescriptorType = USB_DT_ENDPOINT,
423423

424424
.bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_SYNC,
425-
.wMaxPacketSize = cpu_to_le16(1024),
425+
/* .wMaxPacketSize = DYNAMIC */
426426
.bInterval = 4,
427427
};
428428

@@ -530,14 +530,30 @@ struct cntrl_ranges_lay3 {
530530
struct cntrl_range_lay3 r[UAC_MAX_RATES];
531531
} __packed;
532532

533-
static void set_ep_max_packet_size(const struct f_uac_opts *uac2_opts,
533+
static int set_ep_max_packet_size(const struct f_uac_opts *uac2_opts,
534534
struct usb_endpoint_descriptor *ep_desc,
535-
unsigned int factor, bool is_playback)
535+
enum usb_device_speed speed, bool is_playback)
536536
{
537537
int chmask, srate = 0, ssize;
538-
u16 max_packet_size;
538+
u16 max_size_bw, max_size_ep;
539+
unsigned int factor;
539540
int i;
540541

542+
switch (speed) {
543+
case USB_SPEED_FULL:
544+
max_size_ep = 1023;
545+
factor = 1000;
546+
break;
547+
548+
case USB_SPEED_HIGH:
549+
max_size_ep = 1024;
550+
factor = 8000;
551+
break;
552+
553+
default:
554+
return -EINVAL;
555+
}
556+
541557
if (is_playback) {
542558
chmask = uac2_opts->p_chmask;
543559
for (i = 0; i < UAC_MAX_RATES; i++) {
@@ -558,10 +574,12 @@ static void set_ep_max_packet_size(const struct f_uac_opts *uac2_opts,
558574
ssize = uac2_opts->c_ssize;
559575
}
560576

561-
max_packet_size = num_channels(chmask) * ssize *
562-
DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
563-
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
564-
le16_to_cpu(ep_desc->wMaxPacketSize)));
577+
max_size_bw = num_channels(chmask) * ssize *
578+
((srate / (factor / (1 << (ep_desc->bInterval - 1)))) + 1);
579+
ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
580+
max_size_ep));
581+
582+
return 0;
565583
}
566584

567585
/* Use macro to overcome line length limitation */
@@ -794,10 +812,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
794812
}
795813

796814
/* Calculate wMaxPacketSize according to audio bandwidth */
797-
set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
798-
set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
799-
set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
800-
set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
815+
ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL,
816+
true);
817+
if (ret < 0) {
818+
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
819+
return ret;
820+
}
821+
822+
ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL,
823+
false);
824+
if (ret < 0) {
825+
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
826+
return ret;
827+
}
828+
829+
ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH,
830+
true);
831+
if (ret < 0) {
832+
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
833+
return ret;
834+
}
835+
836+
ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH,
837+
false);
838+
if (ret < 0) {
839+
dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
840+
return ret;
841+
}
801842

802843
if (EPOUT_EN(uac2_opts)) {
803844
agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);

0 commit comments

Comments
 (0)