From 52c7755ba19ee2ae97fe5bfea7627bb27d5d7602 Mon Sep 17 00:00:00 2001 From: Mathias Nyman Date: Mon, 21 May 2018 16:39:57 +0300 Subject: [PATCH] xhci: xhci-ring: use port structures for port event handler use port structures in the port event handler. Getting the right hcd and hcd portnumber from the hardware port number is a lot easier with port structures, and allows us to remove a lot of the previous code, including the find_faked_portnum_from_hw_index() function Signed-off-by: Mathias Nyman Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/xhci-ring.c | 79 +++++--------------------------------------- 1 file changed, 8 insertions(+), 71 deletions(-) diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 91a1a82..4d2d0e8 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1497,44 +1497,6 @@ static void handle_vendor_event(struct xhci_hcd *xhci, handle_cmd_completion(xhci, &event->event_cmd); } -/* @port_id: the one-based port ID from the hardware (indexed from array of all - * port registers -- USB 3.0 and USB 2.0). - * - * Returns a zero-based port number, which is suitable for indexing into each of - * the split roothubs' port arrays and bus state arrays. - * Add one to it in order to call xhci_find_slot_id_by_port. - */ -static unsigned int find_faked_portnum_from_hw_portnum(struct usb_hcd *hcd, - struct xhci_hcd *xhci, u32 port_id) -{ - unsigned int i; - unsigned int num_similar_speed_ports = 0; - - /* port_id from the hardware is 1-based, but port_array[], usb3_ports[], - * and usb2_ports are 0-based indexes. Count the number of similar - * speed ports, up to 1 port before this port. - */ - for (i = 0; i < (port_id - 1); i++) { - u8 port_speed = xhci->port_array[i]; - - /* - * Skip ports that don't have known speeds, or have duplicate - * Extended Capabilities port speed entries. - */ - if (port_speed == 0 || port_speed == DUPLICATE_ENTRY) - continue; - - /* - * USB 3.0 ports are always under a USB 3.0 hub. USB 2.0 and - * 1.1 ports are under the USB 2.0 hub. If the port speed - * matches the device speed, it's a similar speed port. - */ - if ((port_speed == 0x03) == (hcd->speed >= HCD_USB3)) - num_similar_speed_ports++; - } - return num_similar_speed_ports; -} - static void handle_device_notification(struct xhci_hcd *xhci, union xhci_trb *event) { @@ -1564,10 +1526,10 @@ static void handle_port_status(struct xhci_hcd *xhci, int max_ports; int slot_id; unsigned int faked_port_index; - u8 major_revision; struct xhci_bus_state *bus_state; __le32 __iomem **port_array; bool bogus_port_status = false; + struct xhci_port *port; /* Port status change events always have a successful completion code */ if (GET_COMP_CODE(le32_to_cpu(event->generic.field[2])) != COMP_SUCCESS) @@ -1584,47 +1546,22 @@ static void handle_port_status(struct xhci_hcd *xhci, return; } - /* Figure out which usb_hcd this port is attached to: - * is it a USB 3.0 port or a USB 2.0/1.1 port? - */ - major_revision = xhci->port_array[port_id - 1]; - - /* Find the right roothub. */ - hcd = xhci_to_hcd(xhci); - if ((major_revision == 0x03) != (hcd->speed >= HCD_USB3)) - hcd = xhci->shared_hcd; - - if (major_revision == 0) { - xhci_warn(xhci, "Event for port %u not in " - "Extended Capabilities, ignoring.\n", - port_id); - bogus_port_status = true; - goto cleanup; - } - if (major_revision == DUPLICATE_ENTRY) { - xhci_warn(xhci, "Event for port %u duplicated in" - "Extended Capabilities, ignoring.\n", - port_id); + port = &xhci->hw_ports[port_id - 1]; + if (!port || !port->rhub || port->hcd_portnum == DUPLICATE_ENTRY) { + xhci_warn(xhci, "Event for invalid port %u\n", port_id); bogus_port_status = true; goto cleanup; } - /* - * Hardware port IDs reported by a Port Status Change Event include USB - * 3.0 and USB 2.0 ports. We want to check if the port has reported a - * resume event, but we first need to translate the hardware port ID - * into the index into the ports on the correct split roothub, and the - * correct bus_state structure. - */ + hcd = port->rhub->hcd; bus_state = &xhci->bus_state[hcd_index(hcd)]; if (hcd->speed >= HCD_USB3) port_array = xhci->usb3_ports; else port_array = xhci->usb2_ports; - /* Find the faked port hub number */ - faked_port_index = find_faked_portnum_from_hw_portnum(hcd, xhci, - port_id); - portsc = readl(port_array[faked_port_index]); + + faked_port_index = port->hcd_portnum; + portsc = readl(port->addr); trace_xhci_handle_port_status(faked_port_index, portsc); -- 2.7.4