aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/dwc2/hcd_queue.c
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2019-05-31 16:04:12 -0400
committerFelipe Balbi <felipe.balbi@linux.intel.com>2019-06-06 06:51:41 -0400
commitbabd183915e91a64e976b9e8ab682bb56624df76 (patch)
treeab678ec74fbcb6ec20ddd1fee34208c71c743a21 /drivers/usb/dwc2/hcd_queue.c
parentf2c7c76c5d0a443053e94adb9f0918fa2fb85c3a (diff)
usb: dwc2: host: Fix wMaxPacketSize handling (fix webcam regression)
In commit abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") the API to usb_endpoint_maxp() changed. It used to just return wMaxPacketSize but after that commit it returned wMaxPacketSize with the high bits (the multiplier) masked off. If you wanted to get the multiplier it was now up to your code to call the new usb_endpoint_maxp_mult() which was introduced in commit 541b6fe63023 ("usb: add helper to extract bits 12:11 of wMaxPacketSize"). Prior to the API change most host drivers were updated, but no update was made to dwc2. Presumably it was assumed that dwc2 was too simplistic to use the multiplier and thus just didn't support a certain class of USB devices. However, it turns out that dwc2 did use the multiplier and many devices using it were working quite nicely. That means that many USB devices have been broken since the API change. One such device is a Logitech HD Pro Webcam C920. Specifically, though dwc2 didn't directly call usb_endpoint_maxp(), it did call usb_maxpacket() which in turn called usb_endpoint_maxp(). Let's update dwc2 to work properly with the new API. Fixes: abb621844f6a ("usb: ch9: make usb_endpoint_maxp() return only packet size") Cc: stable@vger.kernel.org Acked-by: Minas Harutyunyan <hminas@synopsys.com> Reviewed-by: Matthias Kaehlcke <mka@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Diffstat (limited to 'drivers/usb/dwc2/hcd_queue.c')
-rw-r--r--drivers/usb/dwc2/hcd_queue.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/usb/dwc2/hcd_queue.c b/drivers/usb/dwc2/hcd_queue.c
index ea3aa640c15c..68bbac64b753 100644
--- a/drivers/usb/dwc2/hcd_queue.c
+++ b/drivers/usb/dwc2/hcd_queue.c
@@ -708,7 +708,7 @@ static void dwc2_hs_pmap_unschedule(struct dwc2_hsotg *hsotg,
708static int dwc2_uframe_schedule_split(struct dwc2_hsotg *hsotg, 708static int dwc2_uframe_schedule_split(struct dwc2_hsotg *hsotg,
709 struct dwc2_qh *qh) 709 struct dwc2_qh *qh)
710{ 710{
711 int bytecount = dwc2_hb_mult(qh->maxp) * dwc2_max_packet(qh->maxp); 711 int bytecount = qh->maxp_mult * qh->maxp;
712 int ls_search_slice; 712 int ls_search_slice;
713 int err = 0; 713 int err = 0;
714 int host_interval_in_sched; 714 int host_interval_in_sched;
@@ -1332,7 +1332,7 @@ static int dwc2_check_max_xfer_size(struct dwc2_hsotg *hsotg,
1332 u32 max_channel_xfer_size; 1332 u32 max_channel_xfer_size;
1333 int status = 0; 1333 int status = 0;
1334 1334
1335 max_xfer_size = dwc2_max_packet(qh->maxp) * dwc2_hb_mult(qh->maxp); 1335 max_xfer_size = qh->maxp * qh->maxp_mult;
1336 max_channel_xfer_size = hsotg->params.max_transfer_size; 1336 max_channel_xfer_size = hsotg->params.max_transfer_size;
1337 1337
1338 if (max_xfer_size > max_channel_xfer_size) { 1338 if (max_xfer_size > max_channel_xfer_size) {
@@ -1517,8 +1517,9 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
1517 u32 prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT; 1517 u32 prtspd = (hprt & HPRT0_SPD_MASK) >> HPRT0_SPD_SHIFT;
1518 bool do_split = (prtspd == HPRT0_SPD_HIGH_SPEED && 1518 bool do_split = (prtspd == HPRT0_SPD_HIGH_SPEED &&
1519 dev_speed != USB_SPEED_HIGH); 1519 dev_speed != USB_SPEED_HIGH);
1520 int maxp = dwc2_hcd_get_mps(&urb->pipe_info); 1520 int maxp = dwc2_hcd_get_maxp(&urb->pipe_info);
1521 int bytecount = dwc2_hb_mult(maxp) * dwc2_max_packet(maxp); 1521 int maxp_mult = dwc2_hcd_get_maxp_mult(&urb->pipe_info);
1522 int bytecount = maxp_mult * maxp;
1522 char *speed, *type; 1523 char *speed, *type;
1523 1524
1524 /* Initialize QH */ 1525 /* Initialize QH */
@@ -1531,6 +1532,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
1531 1532
1532 qh->data_toggle = DWC2_HC_PID_DATA0; 1533 qh->data_toggle = DWC2_HC_PID_DATA0;
1533 qh->maxp = maxp; 1534 qh->maxp = maxp;
1535 qh->maxp_mult = maxp_mult;
1534 INIT_LIST_HEAD(&qh->qtd_list); 1536 INIT_LIST_HEAD(&qh->qtd_list);
1535 INIT_LIST_HEAD(&qh->qh_list_entry); 1537 INIT_LIST_HEAD(&qh->qh_list_entry);
1536 1538