diff options
-rw-r--r-- | drivers/usb/host/xhci-hub.c | 71 | ||||
-rw-r--r-- | drivers/usb/host/xhci-mem.c | 5 | ||||
-rw-r--r-- | drivers/usb/host/xhci-pci.c | 10 | ||||
-rw-r--r-- | drivers/usb/host/xhci-ring.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/xhci.h | 4 |
5 files changed, 26 insertions, 75 deletions
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c index 37128a777a58..61f083de6e19 100644 --- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -448,40 +448,6 @@ u32 xhci_port_state_to_neutral(u32 state) } EXPORT_SYMBOL_GPL(xhci_port_state_to_neutral); -/** - * xhci_find_slot_id_by_port() - Find slot id of a usb device on a roothub port - * @hcd: pointer to hcd of the roothub - * @xhci: pointer to xhci structure - * @port: one-based port number of the port in this roothub. - * - * Return: Slot id of the usb device connected to the root port, 0 if not found - */ - -int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, - u16 port) -{ - int slot_id; - int i; - enum usb_device_speed speed; - - /* 'hcd_portnum' is zero-based, thus convert one-based 'port' to zero-based */ - port -= 1; - slot_id = 0; - for (i = 0; i < MAX_HC_SLOTS; i++) { - if (!xhci->devs[i] || !xhci->devs[i]->udev) - continue; - speed = xhci->devs[i]->udev->speed; - if (((speed >= USB_SPEED_SUPER) == (hcd->speed >= HCD_USB3)) - && xhci->devs[i]->rhub_port->hcd_portnum == port) { - slot_id = i; - break; - } - } - - return slot_id; -} -EXPORT_SYMBOL_GPL(xhci_find_slot_id_by_port); - /* * Stop device * It issues stop endpoint command for EP 0 to 30. And wait the last command @@ -932,7 +898,6 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, struct xhci_bus_state *bus_state; struct xhci_hcd *xhci; struct usb_hcd *hcd; - int slot_id; u32 wIndex; hcd = port->rhub->hcd; @@ -988,13 +953,11 @@ static int xhci_handle_usb2_port_link_resume(struct xhci_port *port, spin_lock_irqsave(&xhci->lock, *flags); if (time_left) { - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - wIndex + 1); - if (!slot_id) { + if (!port->slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); return -ENODEV; } - xhci_ring_device(xhci, slot_id); + xhci_ring_device(xhci, port->slot_id); } else { int port_status = readl(port->addr); @@ -1204,7 +1167,6 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, unsigned long flags; u32 temp, status; int retval = 0; - int slot_id; struct xhci_bus_state *bus_state; u16 link_state = 0; u16 wake_mask = 0; @@ -1334,15 +1296,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, goto error; } - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - portnum1); - if (!slot_id) { + if (!port->slot_id) { xhci_warn(xhci, "slot_id is zero\n"); goto error; } /* unlock to execute stop endpoint commands */ spin_unlock_irqrestore(&xhci->lock, flags); - xhci_stop_device(xhci, slot_id, 1); + xhci_stop_device(xhci, port->slot_id, 1); spin_lock_irqsave(&xhci->lock, flags); xhci_set_link_state(xhci, port, XDEV_U3); @@ -1465,14 +1425,12 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, if (link_state == USB_SS_PORT_LS_U3) { int retries = 16; - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - portnum1); - if (slot_id) { + if (port->slot_id) { /* unlock to execute stop endpoint * commands */ spin_unlock_irqrestore(&xhci->lock, flags); - xhci_stop_device(xhci, slot_id, 1); + xhci_stop_device(xhci, port->slot_id, 1); spin_lock_irqsave(&xhci->lock, flags); } xhci_set_link_state(xhci, port, USB_SS_PORT_LS_U3); @@ -1586,13 +1544,11 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, } bus_state->port_c_suspend |= 1 << wIndex; - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - portnum1); - if (!slot_id) { + if (!port->slot_id) { xhci_dbg(xhci, "slot_id is zero\n"); goto error; } - xhci_ring_device(xhci, slot_id); + xhci_ring_device(xhci, port->slot_id); break; case USB_PORT_FEAT_C_SUSPEND: bus_state->port_c_suspend &= ~(1 << wIndex); @@ -1823,10 +1779,7 @@ retry: if (!portsc_buf[port_index]) continue; if (test_bit(port_index, &bus_state->bus_suspended)) { - int slot_id; - - slot_id = xhci_find_slot_id_by_port(hcd, xhci, - port_index + 1); + int slot_id = ports[port_index]->slot_id; if (slot_id) { spin_unlock_irqrestore(&xhci->lock, flags); xhci_stop_device(xhci, slot_id, 1); @@ -1879,7 +1832,6 @@ int xhci_bus_resume(struct usb_hcd *hcd) struct xhci_bus_state *bus_state; unsigned long flags; int max_ports, port_index; - int slot_id; int sret; u32 next_state; u32 temp, portsc; @@ -1972,9 +1924,8 @@ int xhci_bus_resume(struct usb_hcd *hcd) continue; } xhci_test_and_clear_bit(xhci, ports[port_index], PORT_PLC); - slot_id = xhci_find_slot_id_by_port(hcd, xhci, port_index + 1); - if (slot_id) - xhci_ring_device(xhci, slot_id); + if (ports[port_index]->slot_id) + xhci_ring_device(xhci, ports[port_index]->slot_id); } (void) readl(&xhci->op_regs->command); diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 9fa68fa17ac7..c4b3e425bd19 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c @@ -907,6 +907,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id) if (dev->udev && dev->udev->slot_id) dev->udev->slot_id = 0; + if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) + dev->rhub_port->slot_id = 0; kfree(xhci->devs[slot_id]); xhci->devs[slot_id] = NULL; } @@ -1124,6 +1126,9 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud dev->rhub_port = xhci_find_rhub_port(xhci, udev); if (!dev->rhub_port) return -EINVAL; + /* Slot ID is set to the device directly below the root hub */ + if (!udev->parent->parent) + dev->rhub_port->slot_id = udev->slot_id; slot_ctx->dev_info2 |= cpu_to_le32(ROOT_HUB_PORT(dev->rhub_port->hw_portnum + 1)); xhci_dbg(xhci, "Slot ID %d: HW portnum %d, hcd portnum %d\n", udev->slot_id, dev->rhub_port->hw_portnum, dev->rhub_port->hcd_portnum); diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index b534ca9752be..1843f3d5b1e6 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c @@ -820,7 +820,6 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup) struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_port *port; struct usb_device *udev; - unsigned int slot_id; u32 portsc; int i; @@ -843,15 +842,14 @@ static int xhci_pci_poweroff_late(struct usb_hcd *hcd, bool do_wakeup) if ((portsc & PORT_PLS_MASK) != XDEV_U3) continue; - slot_id = xhci_find_slot_id_by_port(port->rhub->hcd, xhci, - port->hcd_portnum + 1); - if (!slot_id || !xhci->devs[slot_id]) { + if (!port->slot_id || !xhci->devs[port->slot_id]) { xhci_err(xhci, "No dev for slot_id %d for port %d-%d in U3\n", - slot_id, port->rhub->hcd->self.busnum, port->hcd_portnum + 1); + port->slot_id, port->rhub->hcd->self.busnum, + port->hcd_portnum + 1); continue; } - udev = xhci->devs[slot_id]->udev; + udev = xhci->devs[port->slot_id]->udev; /* if wakeup is enabled then don't disable the port */ if (udev->do_remote_wakeup && do_wakeup) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index d4a28ac4967f..95ed26114ee8 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1870,7 +1870,6 @@ static void handle_port_status(struct xhci_hcd *xhci, u32 port_id; u32 portsc, cmd_reg; int max_ports; - int slot_id; unsigned int hcd_portnum; struct xhci_bus_state *bus_state; bool bogus_port_status = false; @@ -1922,9 +1921,8 @@ static void handle_port_status(struct xhci_hcd *xhci, if (hcd->speed >= HCD_USB3 && (portsc & PORT_PLS_MASK) == XDEV_INACTIVE) { - slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1); - if (slot_id && xhci->devs[slot_id]) - xhci->devs[slot_id]->flags |= VDEV_PORT_ERROR; + if (port->slot_id && xhci->devs[port->slot_id]) + xhci->devs[port->slot_id]->flags |= VDEV_PORT_ERROR; } if ((portsc & PORT_PLC) && (portsc & PORT_PLS_MASK) == XDEV_RESUME) { @@ -1982,9 +1980,8 @@ static void handle_port_status(struct xhci_hcd *xhci, * so the roothub behavior is consistent with external * USB 3.0 hub behavior. */ - slot_id = xhci_find_slot_id_by_port(hcd, xhci, hcd_portnum + 1); - if (slot_id && xhci->devs[slot_id]) - xhci_ring_device(xhci, slot_id); + if (port->slot_id && xhci->devs[port->slot_id]) + xhci_ring_device(xhci, port->slot_id); if (bus_state->port_remote_wakeup & (1 << hcd_portnum)) { xhci_test_and_clear_bit(xhci, port, PORT_PLC); usb_wakeup_notification(hcd->self.root_hub, diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 634ab517a776..6f4bf98a6282 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1462,6 +1462,8 @@ struct xhci_port { unsigned int lpm_incapable:1; unsigned long resume_timestamp; bool rexit_active; + /* Slot ID is the index of the device directly connected to the port */ + int slot_id; struct completion rexit_done; struct completion u3exit_done; }; @@ -1944,8 +1946,6 @@ unsigned long xhci_get_resuming_ports(struct usb_hcd *hcd); #endif /* CONFIG_PM */ u32 xhci_port_state_to_neutral(u32 state); -int xhci_find_slot_id_by_port(struct usb_hcd *hcd, struct xhci_hcd *xhci, - u16 port); void xhci_ring_device(struct xhci_hcd *xhci, int slot_id); /* xHCI contexts */ |