On Wed, 5 Mar 2014, Dan Williams wrote: > Please have a look at the following. I'm sure Greg will be happy that > we are killing these bugs before they become fodder for -stable. Thanks Wow, do you really think all these changes will ever go into -stable? I'm doubtful; they're rather large. > for the review! The other change I made was to convert > find_default_peer to find_and_link_peer per your other comments about > centralizing peering on patch 6. Good idea, since it now finds all peers and not just the default ones. > 8<--------- > Subject: usb: assign default peer ports for root hubs > > From: Dan Williams <dan.j.williams@xxxxxxxxx> > > Assume that the peer of a superspeed port is the port with the same id > on the shared_hcd root hub. This identification scheme is required of > external hubs by the USB3 spec [1]. However, for root hubs, tier mismatch > may be in effect [2]. Tier mismatch can only be enumerated via platform > firmware. For now, simply perform the nominal association. > > A new lock 'usb_port_peer_mutex' is introduced to synchronize port > device add/remove with peer lookups. It protects peering against > changes to hcd->shared_hcd, hcd->self.root_hub, hdev->maxchild, and > port_dev->child pointers. > > [1]: usb 3.1 section 10.3.3 > [2]: xhci 1.1 appendix D > > Cc: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> > [alan: usb_port_peer_mutex locking scheme] > Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx> > diff --git a/drivers/usb/core/port.c b/drivers/usb/core/port.c > index 531a591a7b1e..0d36610af156 100644 > --- a/drivers/usb/core/port.c > +++ b/drivers/usb/core/port.c > @@ -151,9 +151,66 @@ static struct device_driver usb_port_driver = { > .owner = THIS_MODULE, > }; > > +static void link_peers(struct usb_port *left, struct usb_port *right) > +{ > + if (left->peer == right && right->peer == left) > + return; > + > + if (left->peer || right->peer) { > + struct usb_port *lpeer = left->peer; > + struct usb_port *rpeer = right->peer; > + > + WARN(1, "failed to peer %s and %s (%s -> %p) (%s -> %p)\n", > + dev_name(&left->dev), dev_name(&right->dev), > + dev_name(&left->dev), lpeer, > + dev_name(&right->dev), rpeer); > + return; > + } > + > + left->peer = right; > + right->peer = left; > +} > + > +static void unlink_peers(struct usb_port *left, struct usb_port *right) > +{ > + WARN(right->peer != left || left->peer != right, > + "%s and %s are not peers?\n", > + dev_name(&left->dev), dev_name(&right->dev)); At some point, maybe we'll have enough confidence in the locking to remove all these checks. :-) Acked-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> Alan Stern -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html