summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/xhci-mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/xhci-mem.c')
-rw-r--r--drivers/usb/host/xhci-mem.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index f2c4ee7c4786..f66815fe8482 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -532,7 +532,7 @@ struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci,
return (struct xhci_ep_ctx *)
(ctx->bytes + (ep_index * CTX_SIZE(xhci->hcc_params)));
}
-
+EXPORT_SYMBOL_GPL(xhci_get_ep_ctx);
/***************** Streams structures manipulation *************************/
@@ -2129,6 +2129,15 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
if (major_revision == 0x03) {
rhub = &xhci->usb3_rhub;
+ /*
+ * Some hosts incorrectly use sub-minor version for minor
+ * version (i.e. 0x02 instead of 0x20 for bcdUSB 0x320 and 0x01
+ * for bcdUSB 0x310). Since there is no USB release with sub
+ * minor version 0x301 to 0x309, we can assume that they are
+ * incorrect and fix it here.
+ */
+ if (minor_revision > 0x00 && minor_revision < 0x10)
+ minor_revision <<= 4;
} else if (major_revision <= 0x02) {
rhub = &xhci->usb2_rhub;
} else {
@@ -2240,6 +2249,9 @@ static void xhci_create_rhub_port_array(struct xhci_hcd *xhci,
return;
rhub->ports = kcalloc_node(rhub->num_ports, sizeof(*rhub->ports),
flags, dev_to_node(dev));
+ if (!rhub->ports)
+ return;
+
for (i = 0; i < HCS_MAX_PORTS(xhci->hcs_params1); i++) {
if (xhci->hw_ports[i].rhub != rhub ||
xhci->hw_ports[i].hcd_portnum == DUPLICATE_ENTRY)