Re: [PATCH v6 part1 4/8] usb: assign default peer ports for root hubs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux