Commit 5308a91b authored by Sarah Sharp's avatar Sarah Sharp

xhci: Index with a port array instead of PORTSC addresses.

In the upcoming patches, the roothub emulation code will need to return
port status and port change buffers based on whether they are called with
the xHCI USB 2.0 or USB 3.0 roothub.  To facilitate that, make the roothub
code index into an array of port addresses with wIndex, rather than
calculating the address using the offset and the address of the PORTSC
registers.  Later we can set the port array to be the array of USB 3.0
port addresses, or the USB 2.0 port addresses, depending on the roothub
passed in.

Create a temporary (statically sized) port array and fill it in with both
USB 3.0 and USB 2.0 port addresses.  This is inefficient to do for every
roothub call, but this is needed for git bisect compatibility.  The
temporary port array will be deleted in a subsequent patch.
Signed-off-by: default avatarSarah Sharp <sarah.a.sharp@linux.intel.com>
parent ff9d78b3
This diff is collapsed.
......@@ -1161,9 +1161,11 @@ static void handle_port_status(struct xhci_hcd *xhci,
struct usb_hcd *hcd = xhci_to_hcd(xhci);
u32 port_id;
u32 temp, temp1;
u32 __iomem *addr;
int max_ports;
int slot_id;
unsigned int faked_port_index;
u32 __iomem *port_array[15 + USB_MAXCHILDREN];
int i;
/* Port status change events always have a successful completion code */
if (GET_COMP_CODE(event->generic.field[2]) != COMP_SUCCESS) {
......@@ -1179,8 +1181,16 @@ static void handle_port_status(struct xhci_hcd *xhci,
goto cleanup;
}
addr = &xhci->op_regs->port_status_base + NUM_PORT_REGS * (port_id - 1);
temp = xhci_readl(xhci, addr);
for (i = 0; i < max_ports; i++) {
if (i < xhci->num_usb3_ports)
port_array[i] = xhci->usb3_ports[i];
else
port_array[i] =
xhci->usb2_ports[i - xhci->num_usb3_ports];
}
faked_port_index = port_id;
temp = xhci_readl(xhci, port_array[faked_port_index]);
if (hcd->state == HC_STATE_SUSPENDED) {
xhci_dbg(xhci, "resume root hub\n");
usb_hcd_resume_root_hub(hcd);
......@@ -1200,7 +1210,7 @@ static void handle_port_status(struct xhci_hcd *xhci,
temp = xhci_port_state_to_neutral(temp);
temp &= ~PORT_PLS_MASK;
temp |= PORT_LINK_STROBE | XDEV_U0;
xhci_writel(xhci, temp, addr);
xhci_writel(xhci, temp, port_array[faked_port_index]);
slot_id = xhci_find_slot_id_by_port(xhci, port_id);
if (!slot_id) {
xhci_dbg(xhci, "slot_id is zero\n");
......@@ -1209,10 +1219,10 @@ static void handle_port_status(struct xhci_hcd *xhci,
xhci_ring_device(xhci, slot_id);
xhci_dbg(xhci, "resume SS port %d finished\n", port_id);
/* Clear PORT_PLC */
temp = xhci_readl(xhci, addr);
temp = xhci_readl(xhci, port_array[faked_port_index]);
temp = xhci_port_state_to_neutral(temp);
temp |= PORT_PLC;
xhci_writel(xhci, temp, addr);
xhci_writel(xhci, temp, port_array[faked_port_index]);
} else {
xhci_dbg(xhci, "resume HS port %d\n", port_id);
xhci->resume_done[port_id - 1] = jiffies +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment