mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-28 12:25:31 +00:00
usb: assign usb3 external hub port peers
Given that root hub port peers are already established, external hub peer ports can be determined by traversing the device topology: 1/ ascend to the parent hub and find the upstream port_dev 2/ walk ->peer to find the peer port 3/ descend to the peer hub via ->child 4/ find the port with the matching port id Note that this assumes the port labeling scheme required by the specification [1]. [1]: usb3 3.1 section 10.3.3 Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
d8521afe35
commit
8b1ba80c59
@ -187,15 +187,18 @@ static void unlink_peers(struct usb_port *left, struct usb_port *right)
|
||||
left->peer = NULL;
|
||||
}
|
||||
|
||||
/* set the default peer port for root hubs */
|
||||
/*
|
||||
* Set the default peer port for root hubs, or via the upstream peer
|
||||
* relationship for all other hubs
|
||||
*/
|
||||
static void find_and_link_peer(struct usb_hub *hub, int port1)
|
||||
{
|
||||
struct usb_port *port_dev = hub->ports[port1 - 1], *peer;
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
struct usb_device *peer_hdev;
|
||||
struct usb_hub *peer_hub;
|
||||
|
||||
if (!hdev->parent) {
|
||||
struct usb_hub *peer_hub;
|
||||
struct usb_device *peer_hdev;
|
||||
struct usb_hcd *hcd = bus_to_hcd(hdev->bus);
|
||||
struct usb_hcd *peer_hcd = hcd->shared_hcd;
|
||||
|
||||
@ -203,15 +206,28 @@ static void find_and_link_peer(struct usb_hub *hub, int port1)
|
||||
return;
|
||||
|
||||
peer_hdev = peer_hcd->self.root_hub;
|
||||
} else {
|
||||
struct usb_port *upstream;
|
||||
struct usb_device *parent = hdev->parent;
|
||||
struct usb_hub *parent_hub = usb_hub_to_struct_hub(parent);
|
||||
|
||||
if (!parent_hub)
|
||||
return;
|
||||
|
||||
upstream = parent_hub->ports[hdev->portnum - 1];
|
||||
if (!upstream || !upstream->peer)
|
||||
return;
|
||||
|
||||
peer_hdev = upstream->peer->child;
|
||||
}
|
||||
|
||||
peer_hub = usb_hub_to_struct_hub(peer_hdev);
|
||||
if (!peer_hub || port1 > peer_hdev->maxchild)
|
||||
return;
|
||||
|
||||
peer = peer_hub->ports[port1 - 1];
|
||||
|
||||
if (peer)
|
||||
link_peers(port_dev, peer);
|
||||
}
|
||||
}
|
||||
|
||||
int usb_hub_create_port_device(struct usb_hub *hub, int port1)
|
||||
|
Loading…
Reference in New Issue
Block a user