Skip to content

Commit 428b315

Browse files
committed
Merge tag 'fixes-for-v4.5-rc6' of http://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-linus
Felipe writes: usb: fixes for v4.5-rc6 The most important fixes here are: a) yet another fix to dwc3's EP transfer resource assignment logic. This time around we will be pre-allocating transfer resources to avoid any future issues; b) two DMA fixes for the old MUSB driver. c) dwc2's data toggle fix for FS Other than these, we have a few other minor fixes elsewhere.
2 parents e5bdfd5 + 3b24351 commit 428b315

File tree

14 files changed

+108
-68
lines changed

14 files changed

+108
-68
lines changed

MAINTAINERS

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3444,7 +3444,6 @@ F: drivers/usb/dwc2/
34443444
DESIGNWARE USB3 DRD IP DRIVER
34453445
M: Felipe Balbi <[email protected]>
34463446
3447-
34483447
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
34493448
S: Maintained
34503449
F: drivers/usb/dwc3/
@@ -7354,7 +7353,7 @@ F: drivers/tty/isicom.c
73547353
F: include/linux/isicom.h
73557354

73567355
MUSB MULTIPOINT HIGH SPEED DUAL-ROLE CONTROLLER
7357-
M: Felipe Balbi <[email protected]>
7356+
M: Bin Liu <[email protected]>
73587357
73597358
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
73607359
S: Maintained
@@ -7923,11 +7922,9 @@ F: drivers/media/platform/omap3isp/
79237922
F: drivers/staging/media/omap4iss/
79247923

79257924
OMAP USB SUPPORT
7926-
M: Felipe Balbi <[email protected]>
79277925
79287926
7929-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb.git
7930-
S: Maintained
7927+
S: Orphan
79317928
F: drivers/usb/*/*omap*
79327929
F: arch/arm/*omap*/usb*
79337930

drivers/usb/dwc2/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
config USB_DWC2
22
tristate "DesignWare USB2 DRD Core Support"
3+
depends on HAS_DMA
34
depends on USB || USB_GADGET
45
help
56
Say Y here if your system has a Dual Role Hi-Speed USB

drivers/usb/dwc2/core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -619,6 +619,12 @@ void dwc2_force_dr_mode(struct dwc2_hsotg *hsotg)
619619
__func__, hsotg->dr_mode);
620620
break;
621621
}
622+
623+
/*
624+
* NOTE: This is required for some rockchip soc based
625+
* platforms.
626+
*/
627+
msleep(50);
622628
}
623629

624630
/*

drivers/usb/dwc2/hcd_ddma.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,14 +1174,11 @@ static int dwc2_process_non_isoc_desc(struct dwc2_hsotg *hsotg,
11741174
failed = dwc2_update_non_isoc_urb_state_ddma(hsotg, chan, qtd, dma_desc,
11751175
halt_status, n_bytes,
11761176
xfer_done);
1177-
if (*xfer_done && urb->status != -EINPROGRESS)
1178-
failed = 1;
1179-
1180-
if (failed) {
1177+
if (failed || (*xfer_done && urb->status != -EINPROGRESS)) {
11811178
dwc2_host_complete(hsotg, qtd, urb->status);
11821179
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd, qh);
1183-
dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x status=%08x\n",
1184-
failed, *xfer_done, urb->status);
1180+
dev_vdbg(hsotg->dev, "failed=%1x xfer_done=%1x\n",
1181+
failed, *xfer_done);
11851182
return failed;
11861183
}
11871184

@@ -1236,29 +1233,31 @@ static void dwc2_complete_non_isoc_xfer_ddma(struct dwc2_hsotg *hsotg,
12361233

12371234
list_for_each_safe(qtd_item, qtd_tmp, &qh->qtd_list) {
12381235
int i;
1236+
int qtd_desc_count;
12391237

12401238
qtd = list_entry(qtd_item, struct dwc2_qtd, qtd_list_entry);
12411239
xfer_done = 0;
1240+
qtd_desc_count = qtd->n_desc;
12421241

1243-
for (i = 0; i < qtd->n_desc; i++) {
1242+
for (i = 0; i < qtd_desc_count; i++) {
12441243
if (dwc2_process_non_isoc_desc(hsotg, chan, chnum, qtd,
12451244
desc_num, halt_status,
1246-
&xfer_done)) {
1247-
qtd = NULL;
1248-
break;
1249-
}
1245+
&xfer_done))
1246+
goto stop_scan;
1247+
12501248
desc_num++;
12511249
}
12521250
}
12531251

1252+
stop_scan:
12541253
if (qh->ep_type != USB_ENDPOINT_XFER_CONTROL) {
12551254
/*
12561255
* Resetting the data toggle for bulk and interrupt endpoints
12571256
* in case of stall. See handle_hc_stall_intr().
12581257
*/
12591258
if (halt_status == DWC2_HC_XFER_STALL)
12601259
qh->data_toggle = DWC2_HC_PID_DATA0;
1261-
else if (qtd)
1260+
else
12621261
dwc2_hcd_save_data_toggle(hsotg, chan, chnum, qtd);
12631262
}
12641263

drivers/usb/dwc2/hcd_intr.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,11 +525,19 @@ void dwc2_hcd_save_data_toggle(struct dwc2_hsotg *hsotg,
525525
u32 pid = (hctsiz & TSIZ_SC_MC_PID_MASK) >> TSIZ_SC_MC_PID_SHIFT;
526526

527527
if (chan->ep_type != USB_ENDPOINT_XFER_CONTROL) {
528+
if (WARN(!chan || !chan->qh,
529+
"chan->qh must be specified for non-control eps\n"))
530+
return;
531+
528532
if (pid == TSIZ_SC_MC_PID_DATA0)
529533
chan->qh->data_toggle = DWC2_HC_PID_DATA0;
530534
else
531535
chan->qh->data_toggle = DWC2_HC_PID_DATA1;
532536
} else {
537+
if (WARN(!qtd,
538+
"qtd must be specified for control eps\n"))
539+
return;
540+
533541
if (pid == TSIZ_SC_MC_PID_DATA0)
534542
qtd->data_toggle = DWC2_HC_PID_DATA0;
535543
else

drivers/usb/dwc3/core.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -856,7 +856,6 @@ struct dwc3 {
856856
unsigned pullups_connected:1;
857857
unsigned resize_fifos:1;
858858
unsigned setup_packet_pending:1;
859-
unsigned start_config_issued:1;
860859
unsigned three_stage_setup:1;
861860
unsigned usb3_lpm_capable:1;
862861

drivers/usb/dwc3/ep0.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,6 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
555555
int ret;
556556
u32 reg;
557557

558-
dwc->start_config_issued = false;
559558
cfg = le16_to_cpu(ctrl->wValue);
560559

561560
switch (state) {
@@ -737,10 +736,6 @@ static int dwc3_ep0_std_request(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
737736
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_ISOCH_DELAY");
738737
ret = dwc3_ep0_set_isoch_delay(dwc, ctrl);
739738
break;
740-
case USB_REQ_SET_INTERFACE:
741-
dwc3_trace(trace_dwc3_ep0, "USB_REQ_SET_INTERFACE");
742-
dwc->start_config_issued = false;
743-
/* Fall through */
744739
default:
745740
dwc3_trace(trace_dwc3_ep0, "Forwarding to gadget driver");
746741
ret = dwc3_ep0_delegate_req(dwc, ctrl);

drivers/usb/dwc3/gadget.c

Lines changed: 52 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -385,24 +385,66 @@ static void dwc3_free_trb_pool(struct dwc3_ep *dep)
385385
dep->trb_pool_dma = 0;
386386
}
387387

388+
static int dwc3_gadget_set_xfer_resource(struct dwc3 *dwc, struct dwc3_ep *dep);
389+
390+
/**
391+
* dwc3_gadget_start_config - Configure EP resources
392+
* @dwc: pointer to our controller context structure
393+
* @dep: endpoint that is being enabled
394+
*
395+
* The assignment of transfer resources cannot perfectly follow the
396+
* data book due to the fact that the controller driver does not have
397+
* all knowledge of the configuration in advance. It is given this
398+
* information piecemeal by the composite gadget framework after every
399+
* SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook
400+
* programming model in this scenario can cause errors. For two
401+
* reasons:
402+
*
403+
* 1) The databook says to do DEPSTARTCFG for every SET_CONFIGURATION
404+
* and SET_INTERFACE (8.1.5). This is incorrect in the scenario of
405+
* multiple interfaces.
406+
*
407+
* 2) The databook does not mention doing more DEPXFERCFG for new
408+
* endpoint on alt setting (8.1.6).
409+
*
410+
* The following simplified method is used instead:
411+
*
412+
* All hardware endpoints can be assigned a transfer resource and this
413+
* setting will stay persistent until either a core reset or
414+
* hibernation. So whenever we do a DEPSTARTCFG(0) we can go ahead and
415+
* do DEPXFERCFG for every hardware endpoint as well. We are
416+
* guaranteed that there are as many transfer resources as endpoints.
417+
*
418+
* This function is called for each endpoint when it is being enabled
419+
* but is triggered only when called for EP0-out, which always happens
420+
* first, and which should only happen in one of the above conditions.
421+
*/
388422
static int dwc3_gadget_start_config(struct dwc3 *dwc, struct dwc3_ep *dep)
389423
{
390424
struct dwc3_gadget_ep_cmd_params params;
391425
u32 cmd;
426+
int i;
427+
int ret;
428+
429+
if (dep->number)
430+
return 0;
392431

393432
memset(&params, 0x00, sizeof(params));
433+
cmd = DWC3_DEPCMD_DEPSTARTCFG;
394434

395-
if (dep->number != 1) {
396-
cmd = DWC3_DEPCMD_DEPSTARTCFG;
397-
/* XferRscIdx == 0 for ep0 and 2 for the remaining */
398-
if (dep->number > 1) {
399-
if (dwc->start_config_issued)
400-
return 0;
401-
dwc->start_config_issued = true;
402-
cmd |= DWC3_DEPCMD_PARAM(2);
403-
}
435+
ret = dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
436+
if (ret)
437+
return ret;
404438

405-
return dwc3_send_gadget_ep_cmd(dwc, 0, cmd, &params);
439+
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) {
440+
struct dwc3_ep *dep = dwc->eps[i];
441+
442+
if (!dep)
443+
continue;
444+
445+
ret = dwc3_gadget_set_xfer_resource(dwc, dep);
446+
if (ret)
447+
return ret;
406448
}
407449

408450
return 0;
@@ -516,10 +558,6 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
516558
struct dwc3_trb *trb_st_hw;
517559
struct dwc3_trb *trb_link;
518560

519-
ret = dwc3_gadget_set_xfer_resource(dwc, dep);
520-
if (ret)
521-
return ret;
522-
523561
dep->endpoint.desc = desc;
524562
dep->comp_desc = comp_desc;
525563
dep->type = usb_endpoint_type(desc);
@@ -1636,8 +1674,6 @@ static int dwc3_gadget_start(struct usb_gadget *g,
16361674
}
16371675
dwc3_writel(dwc->regs, DWC3_DCFG, reg);
16381676

1639-
dwc->start_config_issued = false;
1640-
16411677
/* Start with SuperSpeed Default */
16421678
dwc3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(512);
16431679

@@ -2237,7 +2273,6 @@ static void dwc3_gadget_disconnect_interrupt(struct dwc3 *dwc)
22372273
dwc3_writel(dwc->regs, DWC3_DCTL, reg);
22382274

22392275
dwc3_disconnect_gadget(dwc);
2240-
dwc->start_config_issued = false;
22412276

22422277
dwc->gadget.speed = USB_SPEED_UNKNOWN;
22432278
dwc->setup_packet_pending = false;
@@ -2288,7 +2323,6 @@ static void dwc3_gadget_reset_interrupt(struct dwc3 *dwc)
22882323

22892324
dwc3_stop_active_transfers(dwc);
22902325
dwc3_clear_stall_all_ep(dwc);
2291-
dwc->start_config_issued = false;
22922326

22932327
/* Reset device address to zero */
22942328
reg = dwc3_readl(dwc->regs, DWC3_DCFG);

drivers/usb/gadget/legacy/inode.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,8 @@ struct dev_data {
130130
setup_can_stall : 1,
131131
setup_out_ready : 1,
132132
setup_out_error : 1,
133-
setup_abort : 1;
133+
setup_abort : 1,
134+
gadget_registered : 1;
134135
unsigned setup_wLength;
135136

136137
/* the rest is basically write-once */
@@ -1179,7 +1180,8 @@ dev_release (struct inode *inode, struct file *fd)
11791180

11801181
/* closing ep0 === shutdown all */
11811182

1182-
usb_gadget_unregister_driver (&gadgetfs_driver);
1183+
if (dev->gadget_registered)
1184+
usb_gadget_unregister_driver (&gadgetfs_driver);
11831185

11841186
/* at this point "good" hardware has disconnected the
11851187
* device from USB; the host won't see it any more.
@@ -1847,6 +1849,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
18471849
* kick in after the ep0 descriptor is closed.
18481850
*/
18491851
value = len;
1852+
dev->gadget_registered = true;
18501853
}
18511854
return value;
18521855

drivers/usb/gadget/udc/fsl_qe_udc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2340,7 +2340,7 @@ static struct qe_udc *qe_udc_config(struct platform_device *ofdev)
23402340
{
23412341
struct qe_udc *udc;
23422342
struct device_node *np = ofdev->dev.of_node;
2343-
unsigned int tmp_addr = 0;
2343+
unsigned long tmp_addr = 0;
23442344
struct usb_device_para __iomem *usbpram;
23452345
unsigned int i;
23462346
u64 size;

0 commit comments

Comments
 (0)