Re: [RFC v2] xHCI/USB: Make xHCI driver have a BOS descriptor.

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

 



On Wed, 5 Oct 2011, Sarah Sharp wrote:

> To add USB 3.0 link power management (LPM), we need to know what the U1
> and U2 exit latencies are for the xHCI host controller.  External USB 3.0
> hubs report these values through the SuperSpeed Capabilities descriptor in
> the BOS descriptor.  Make the USB 3.0 roothub for the xHCI host behave
> like an external hub and return the BOS descriptors.
> 
> The U1 and U2 exit latencies will vary across each host controller, so we
> need to dynamically fill those values in by reading the exit latencies out
> of the xHC registers.  Make the roothub code in the USB core handle
> hub_control() returning the length of the data copied.
> 
> Signed-off-by: Sarah Sharp <sarah.a.sharp@xxxxxxxxxxxxxxx>
> ---
> 
> Like so?

Yes, with just a few alterations...

> diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
> index 73cbbd8..8b66a4f 100644
> --- a/drivers/usb/core/hcd.c
> +++ b/drivers/usb/core/hcd.c
> @@ -442,7 +442,7 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb)
>  	struct usb_ctrlrequest *cmd;
>   	u16		typeReq, wValue, wIndex, wLength;
>  	u8		*ubuf = urb->transfer_buffer;
> -	u8		tbuf [sizeof (struct usb_hub_descriptor)]
> +	u8		tbuf [USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE]

Get rid of the space before the '['.  Dave Brownell used to like having
a space before his opening brackets and parens, but it's not the
standard kernel style.

Also, it would be a good idea to add a comment about the array size.  
The array needs to be big enough to hold the BOS descriptor + the SS
Device Capability descriptor, as well as big enough to hold a
usb_hub_descriptor.  As it happens, both come out to 15 bytes.  But if
things change in the future, people will need to know what's going on.

> --- a/drivers/usb/host/xhci-hub.c
> +++ b/drivers/usb/host/xhci-hub.c
> @@ -28,6 +28,25 @@
>  #define	PORT_RWC_BITS	(PORT_CSC | PORT_PEC | PORT_WRC | PORT_OCC | \
>  			 PORT_RC | PORT_PLC | PORT_PE)
>  
> +/* usb 1.1 root hub device descriptor */
> +static u8 usb_bos_descriptor [] = {
> +	USB_DT_BOS_SIZE,		/*  __u8 bLength */
> +	USB_DT_BOS,			/*  __u8 bDescriptorType */
> +	0x0F, 0x00,			/*  __le16 wTotalLength, 15 bytes */
> +	0x1,				/*  __u8 bNumDeviceCaps */
> +	/* First device capability */
> +	USB_DT_USB_SS_CAP_SIZE,		/*  __u8 bLength, 10 bytes */
> +	0x10,				/* Device Capability; value = 16 */

This should be USB_DT_DEVICE_CAPABILITY.

> +	USB_SS_CAP_TYPE,		/* bDevCapabilityType, SUPERSPEED_USB */
> +	0x00,				/* bmAttributes, LTM off by default */
> +	USB_5GBPS_OPERATION, 0x00,	/* wSpeedsSupported, 5Gbps only */
> +	0x03,				/* bFunctionalitySupport,
> +					   USB 3.0 speed only */
> +	0x00,				/* bU1DevExitLat, set later. */
> +	0x00, 0x00			/* __le16 bU2DevExitLat, set later. */
> +};
> +
> +
>  static void xhci_common_hub_descriptor(struct xhci_hcd *xhci,
>  		struct usb_hub_descriptor *desc, int ports)
>  {
> @@ -455,6 +474,20 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
>  		xhci_hub_descriptor(hcd, xhci,
>  				(struct usb_hub_descriptor *) buf);
>  		break;
> +	case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
> +		if ((wValue & 0xff00) != (USB_DT_BOS << 8))
> +			goto error;
> +
> +		if (hcd->speed != HCD_USB3)
> +			goto error;
> +
> +		memcpy(buf, &usb_bos_descriptor, sizeof(usb_bos_descriptor));
> +		temp = xhci_readl(xhci, &xhci->cap_regs->hcs_params3);
> +		buf[12] = HCS_U1_LATENCY(temp);
> +		put_unaligned_le16(HCS_U2_LATENCY(temp), &buf[13]);
> +
> +		spin_unlock_irqrestore(&xhci->lock, flags);
> +		return sizeof(usb_bos_descriptor);

This should return USB_DT_BOS_SIZE + USB_DT_USB_SS_CAP_SIZE.

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