summaryrefslogtreecommitdiff
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-dbgtty.c15
-rw-r--r--drivers/usb/host/xhci-ring.c20
2 files changed, 28 insertions, 7 deletions
diff --git a/drivers/usb/host/xhci-dbgtty.c b/drivers/usb/host/xhci-dbgtty.c
index 90282e51e23e..fda5ccaba27a 100644
--- a/drivers/usb/host/xhci-dbgtty.c
+++ b/drivers/usb/host/xhci-dbgtty.c
@@ -628,8 +628,8 @@ int dbc_tty_init(void)
dbc_tty_driver = tty_alloc_driver(64, TTY_DRIVER_REAL_RAW |
TTY_DRIVER_DYNAMIC_DEV);
if (IS_ERR(dbc_tty_driver)) {
- idr_destroy(&dbc_tty_minors);
- return PTR_ERR(dbc_tty_driver);
+ ret = PTR_ERR(dbc_tty_driver);
+ goto fail;
}
dbc_tty_driver->driver_name = "dbc_serial";
@@ -649,11 +649,18 @@ int dbc_tty_init(void)
ret = tty_register_driver(dbc_tty_driver);
if (ret) {
pr_err("Can't register dbc tty driver\n");
- tty_driver_kref_put(dbc_tty_driver);
- idr_destroy(&dbc_tty_minors);
+ goto fail_put;
}
return ret;
+
+fail_put:
+ tty_driver_kref_put(dbc_tty_driver);
+fail:
+ idr_destroy(&dbc_tty_minors);
+ dbc_tty_driver = NULL;
+
+ return ret;
}
void dbc_tty_exit(void)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 2bb7569c9505..26d72b4e11ce 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2026,7 +2026,7 @@ static void handle_port_status(struct xhci_hcd *xhci, union xhci_trb *event)
vdev = xhci->devs[port->slot_id];
/* We might get interrupts after shared_hcd is removed */
- if (port->rhub == &xhci->usb3_rhub && xhci->shared_hcd == NULL) {
+ if (port->rhub == &xhci->usb3_rhub && xhci_get_usb3_hcd(xhci) == NULL) {
xhci_dbg(xhci, "ignore port event for removed USB3 hcd\n");
bogus_port_status = true;
goto cleanup;
@@ -2653,6 +2653,17 @@ static bool xhci_spurious_success_tx_event(struct xhci_hcd *xhci,
}
}
+static struct xhci_td *find_td_by_dma(struct xhci_ring *ep_ring, dma_addr_t dma)
+{
+ struct xhci_td *td;
+
+ if (dma)
+ list_for_each_entry(td, &ep_ring->td_list, td_list)
+ if (trb_in_td(td, dma))
+ return td;
+ return NULL;
+}
+
/*
* If this function returns an error condition, it means it got a Transfer
* event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
@@ -2845,8 +2856,11 @@ static int handle_tx_event(struct xhci_hcd *xhci,
xhci_dequeue_td(xhci, td, ep_ring, td->status);
}
- /* If the TRB pointer is NULL, missed TDs will be skipped on the next event */
- if (trb_comp_code == COMP_MISSED_SERVICE_ERROR && !ep_trb_dma)
+ /*
+ * We don't know how many TDs were missed when ep_trb_dma is zero (as permitted by
+ * xHCI 1.0) or bogus. Bail out leaving ep->skip set, next event will sort it out.
+ */
+ if (trb_comp_code == COMP_MISSED_SERVICE_ERROR && !find_td_by_dma(ep_ring, ep_trb_dma))
return 0;
if (list_empty(&ep_ring->td_list)) {