Re: [PATCH 1/5] USB: Add parsing of SuperSpeed endpoint companion descriptor.

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

 



On Thu, Apr 08, 2010 at 01:02:14PM -0400, Alan Stern wrote:
> On Wed, 7 Apr 2010, Sarah Sharp wrote:
> 
> > > > I really struggled with the descriptor parsing code to get it right, so
> > > > I really don't ever want to touch that code again.  Maybe someone else
> > > > wants to take a shot at it?
> > > 
> > > I can change it to do this.  Parts of xhci-hcd would have to be changed 
> > > too.
> > 
> > Ok, sure, just CC me on the patches and I'll see if I need to rebase the
> > streams patches.
> 
> Does this look okay to you?  I don't have any way to test it.

Yes and no.  Everything seems to behave properly with all the USB
devices I have; the I can read and write to the USB 3.0 hard drives,
etc.  (The one thing I don't have is a USB 3.0 device that has
descriptors between the SuperSpeed Endpoint Companion Descriptor and the
next Endpoint Descriptor, like a UAS device would have).

However, some devices are missing from the lsusb output, which is very
strange.  Specifically, the roothub is always missing, and any hubs
directly connected to it disappear after a device has been plugged into
them.  Hubs further up the tree do not disappear from the lsusb output.
I think this might be related to the fact that the roothub doesn't have
a SuperSpeed Endpoint Companion Descriptor.

Here's the output of lsusb during various experiments:

The xHCI root hub is missing from the initial output:

sarah@xanatos:~$ sudo lsusb
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

But I can see other devices when I plug a SuperSpeed hard drive and a HS
hub into the two roothub ports:

Bus 009 Device 003: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

When I plug in a mouse into the HS hub, it disappears too:

Bus 009 Device 004: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

If I plug a mouse and flash drive into the first hub, and then attach a
second HS hub to the first one:

sarah@xanatos:~/git/logs/2010-04$ sudo lsusb
Bus 009 Device 006: ID 050d:0413 Belkin Components 
Bus 009 Device 005: ID 125f:c82a A-DATA Technology Co., Ltd. 
Bus 009 Device 004: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

The second hub (the Belkin device) is still visible.  If I plug in a
flash drive into that, it stays visible:

sarah@xanatos:~/git/logs/2010-04$ sudo lsusb
Bus 009 Device 007: ID 05dc:a620 Lexar Media, Inc. 
Bus 009 Device 006: ID 050d:0413 Belkin Components 
Bus 009 Device 005: ID 125f:c82a A-DATA Technology Co., Ltd. 
Bus 009 Device 004: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Remove the mouse, flash drives, and 2nd hub.  Unplug and replug in the
HS hub connected to the roothub, and it reappears:

sarah@xanatos:~/git/logs/2010-04$ sudo lsusb
Bus 009 Device 003: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc.
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Plug in the mouse, it disappears:
sarah@xanatos:~/git/logs/2010-04$ sudo lsusb
Bus 009 Device 004: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

Unplug the mouse+the hub and then plug in the mouse+hub again, and the hub is there:
sarah@xanatos:~/git/logs/2010-04$ sudo lsusb
Bus 009 Device 004: ID 15ca:00c3 Textech International Ltd. Mini Optical Mouse
Bus 009 Device 003: ID 05e3:0608 Genesys Logic, Inc. USB-2.0 4-Port HUB
Bus 009 Device 002: ID 174c:55aa ASMedia Technology Inc. 
Bus 008 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 007 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 006 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 003: ID 0a5c:2145 Broadcom Corp. 
Bus 003 Device 002: ID 08ff:2810 AuthenTec, Inc. 
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

I'm not sure what to make of this, since the patch looks correct to me.
Reverting the patch creates normal lsusb output, so I know the patch
must be the cause of the issue.

Sarah Sharp

> Index: usb-2.6/include/linux/usb.h
> ===================================================================
> --- usb-2.6.orig/include/linux/usb.h
> +++ usb-2.6/include/linux/usb.h
> @@ -45,19 +45,6 @@ struct wusb_dev;
>  
>  struct ep_device;
>  
> -/* For SS devices */
> -/**
> - * struct usb_host_ss_ep_comp - Valid for SuperSpeed devices only
> - * @desc: endpoint companion descriptor, wMaxPacketSize in native byteorder
> - * @extra: descriptors following this endpoint companion descriptor
> - * @extralen: how many bytes of "extra" are valid
> - */
> -struct usb_host_ss_ep_comp {
> -	struct usb_ss_ep_comp_descriptor	desc;
> -	unsigned char				*extra;   /* Extra descriptors */
> -	int					extralen;
> -};
> -
>  /**
>   * struct usb_host_endpoint - host-side endpoint descriptor and queue
>   * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder
> @@ -65,7 +52,7 @@ struct usb_host_ss_ep_comp {
>   * @hcpriv: for use by HCD; typically holds hardware dma queue head (QH)
>   *	with one or more transfer descriptors (TDs) per urb
>   * @ep_dev: ep_device for sysfs info
> - * @ss_ep_comp: companion descriptor information for this endpoint
> + * @ss_ep_comp: SuperSpeed companion descriptor for this endpoint
>   * @extra: descriptors following this endpoint in the configuration
>   * @extralen: how many bytes of "extra" are valid
>   * @enabled: URBs may be submitted to this endpoint
> @@ -78,7 +65,7 @@ struct usb_host_endpoint {
>  	struct list_head		urb_list;
>  	void				*hcpriv;
>  	struct ep_device 		*ep_dev;	/* For sysfs info */
> -	struct usb_host_ss_ep_comp	*ss_ep_comp;	/* For SS devices */
> +	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
>  
>  	unsigned char *extra;   /* Extra descriptors */
>  	int extralen;
> Index: usb-2.6/drivers/usb/host/xhci-mem.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/host/xhci-mem.c
> +++ usb-2.6/drivers/usb/host/xhci-mem.c
> @@ -657,12 +657,9 @@ int xhci_endpoint_init(struct xhci_hcd *
>  		max_packet = ep->desc.wMaxPacketSize;
>  		ep_ctx->ep_info2 |= MAX_PACKET(max_packet);
>  		/* dig out max burst from ep companion desc */
> -		if (!ep->ss_ep_comp) {
> -			xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n");
> -			max_packet = 0;
> -		} else {
> -			max_packet = ep->ss_ep_comp->desc.bMaxBurst;
> -		}
> +		max_packet = ep->ss_ep_comp.bMaxBurst;
> +		if (!max_packet)
> +			xhci_warn(xhci, "WARN no SS endpoint bMaxBurst\n");
>  		ep_ctx->ep_info2 |= MAX_BURST(max_packet);
>  		break;
>  	case USB_SPEED_HIGH:
> Index: usb-2.6/drivers/usb/core/config.c
> ===================================================================
> --- usb-2.6.orig/drivers/usb/core/config.c
> +++ usb-2.6/drivers/usb/core/config.c
> @@ -19,32 +19,6 @@ static inline const char *plural(int n)
>  	return (n == 1 ? "" : "s");
>  }
>  
> -/* FIXME: this is a kludge */
> -static int find_next_descriptor_more(unsigned char *buffer, int size,
> -    int dt1, int dt2, int dt3, int *num_skipped)
> -{
> -	struct usb_descriptor_header *h;
> -	int n = 0;
> -	unsigned char *buffer0 = buffer;
> -
> -	/* Find the next descriptor of type dt1 or dt2 or dt3 */
> -	while (size > 0) {
> -		h = (struct usb_descriptor_header *) buffer;
> -		if (h->bDescriptorType == dt1 || h->bDescriptorType == dt2 ||
> -				h->bDescriptorType == dt3)
> -			break;
> -		buffer += h->bLength;
> -		size -= h->bLength;
> -		++n;
> -	}
> -
> -	/* Store the number of descriptors skipped and return the
> -	 * number of bytes skipped */
> -	if (num_skipped)
> -		*num_skipped = n;
> -	return buffer - buffer0;
> -}
> -
>  static int find_next_descriptor(unsigned char *buffer, int size,
>      int dt1, int dt2, int *num_skipped)
>  {
> @@ -69,47 +43,41 @@ static int find_next_descriptor(unsigned
>  	return buffer - buffer0;
>  }
>  
> -static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
> +static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
>  		int inum, int asnum, struct usb_host_endpoint *ep,
> -		int num_ep, unsigned char *buffer, int size)
> +		unsigned char *buffer, int size)
>  {
> -	unsigned char *buffer_start = buffer;
> -	struct usb_ss_ep_comp_descriptor	*desc;
> -	int retval;
> -	int num_skipped;
> +	struct usb_ss_ep_comp_descriptor *desc;
>  	int max_tx;
> -	int i;
>  
> +	/* The SuperSpeed endpoint companion descriptor is supposed to
> +	 * be the first thing immediately following the endpoint descriptor.
> +	 */
>  	desc = (struct usb_ss_ep_comp_descriptor *) buffer;
> -	if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) {
> +	if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP ||
> +			size < USB_DT_SS_EP_COMP_SIZE) {
>  		dev_warn(ddev, "No SuperSpeed endpoint companion for config %d "
>  				" interface %d altsetting %d ep %d: "
>  				"using minimum values\n",
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		/*
> -		 * The next descriptor is for an Endpoint or Interface,
> -		 * no extra descriptors to copy into the companion structure,
> -		 * and we didn't eat up any of the buffer.
> +
> +		/* Fill in some default values.
> +		 * Leave bmAttributes as zero, which will mean no streams for
> +		 * bulk, and isoc won't support multiple bursts of packets.
> +		 * With bursts of only one packet, and a Mult of 1, the max
> +		 * amount of data moved per endpoint service interval is one
> +		 * packet.
>  		 */
> -		return 0;
> +		ep->ss_ep_comp.bLength = USB_DT_SS_EP_COMP_SIZE;
> +		ep->ss_ep_comp.bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
> +		if (usb_endpoint_xfer_isoc(&ep->desc) ||
> +				usb_endpoint_xfer_int(&ep->desc))
> +			ep->ss_ep_comp.wBytesPerInterval =
> +					ep->desc.wMaxPacketSize;
> +		return;
>  	}
> -	memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE);
> -	desc = &ep->ss_ep_comp->desc;
> -	buffer += desc->bLength;
> -	size -= desc->bLength;
>  
> -	/* Eat up the other descriptors we don't care about */
> -	ep->ss_ep_comp->extra = buffer;
> -	i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT,
> -			USB_DT_INTERFACE, &num_skipped);
> -	ep->ss_ep_comp->extralen = i;
> -	buffer += i;
> -	size -= i;
> -	retval = buffer - buffer_start;
> -	if (num_skipped > 0)
> -		dev_dbg(ddev, "skipped %d descriptor%s after %s\n",
> -				num_skipped, plural(num_skipped),
> -				"SuperSpeed endpoint companion");
> +	memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE);
>  
>  	/* Check the various values */
>  	if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) {
> @@ -117,15 +85,16 @@ static int usb_parse_ss_endpoint_compani
>  				"config %d interface %d altsetting %d ep %d: "
>  				"setting to zero\n", desc->bMaxBurst,
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		desc->bMaxBurst = 0;
> +		ep->ss_ep_comp.bMaxBurst = 0;
>  	}
> -	if (desc->bMaxBurst > 15) {
> +	else if (desc->bMaxBurst > 15) {
>  		dev_warn(ddev, "Endpoint with bMaxBurst = %d in "
>  				"config %d interface %d altsetting %d ep %d: "
>  				"setting to 15\n", desc->bMaxBurst,
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		desc->bMaxBurst = 15;
> +		ep->ss_ep_comp.bMaxBurst = 15;
>  	}
> +
>  	if ((usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_int(&ep->desc))
>  			&& desc->bmAttributes != 0) {
>  		dev_warn(ddev, "%s endpoint with bmAttributes = %d in "
> @@ -134,30 +103,30 @@ static int usb_parse_ss_endpoint_compani
>  				usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk",
>  				desc->bmAttributes,
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		desc->bmAttributes = 0;
> +		ep->ss_ep_comp.bmAttributes = 0;
>  	}
> -	if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) {
> +	else if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) {
>  		dev_warn(ddev, "Bulk endpoint with more than 65536 streams in "
>  				"config %d interface %d altsetting %d ep %d: "
>  				"setting to max\n",
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		desc->bmAttributes = 16;
> +		ep->ss_ep_comp.bmAttributes = 16;
>  	}
> -	if (usb_endpoint_xfer_isoc(&ep->desc) && desc->bmAttributes > 2) {
> +	else if (usb_endpoint_xfer_isoc(&ep->desc) && desc->bmAttributes > 2) {
>  		dev_warn(ddev, "Isoc endpoint has Mult of %d in "
>  				"config %d interface %d altsetting %d ep %d: "
>  				"setting to 3\n", desc->bmAttributes + 1,
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress);
> -		desc->bmAttributes = 2;
> +		ep->ss_ep_comp.bmAttributes = 2;
>  	}
> -	if (usb_endpoint_xfer_isoc(&ep->desc)) {
> +
> +	if (usb_endpoint_xfer_isoc(&ep->desc))
>  		max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) *
>  			(desc->bmAttributes + 1);
> -	} else if (usb_endpoint_xfer_int(&ep->desc)) {
> +	else if (usb_endpoint_xfer_int(&ep->desc))
>  		max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1);
> -	} else {
> -		goto valid;
> -	}
> +	else
> +		max_tx = 999999;
>  	if (desc->wBytesPerInterval > max_tx) {
>  		dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in "
>  				"config %d interface %d altsetting %d ep %d: "
> @@ -166,10 +135,8 @@ static int usb_parse_ss_endpoint_compani
>  				desc->wBytesPerInterval,
>  				cfgno, inum, asnum, ep->desc.bEndpointAddress,
>  				max_tx);
> -		desc->wBytesPerInterval = max_tx;
> +		ep->ss_ep_comp.wBytesPerInterval = max_tx;
>  	}
> -valid:
> -	return retval;
>  }
>  
>  static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
> @@ -291,61 +258,19 @@ static int usb_parse_endpoint(struct dev
>  				cfgno, inum, asnum, d->bEndpointAddress,
>  				maxp);
>  	}
> -	/* Allocate room for and parse any SS endpoint companion descriptors */
> -	if (to_usb_device(ddev)->speed == USB_SPEED_SUPER) {
> -		endpoint->extra = buffer;
> -		i = find_next_descriptor_more(buffer, size, USB_DT_SS_ENDPOINT_COMP,
> -				USB_DT_ENDPOINT, USB_DT_INTERFACE, &n);
> -		endpoint->extralen = i;
> -		buffer += i;
> -		size -= i;
> -
> -		/* Allocate space for the SS endpoint companion descriptor */
> -		endpoint->ss_ep_comp = kzalloc(sizeof(struct usb_host_ss_ep_comp),
> -				GFP_KERNEL);
> -		if (!endpoint->ss_ep_comp)
> -			return -ENOMEM;
>  
> -		/* Fill in some default values (may be overwritten later) */
> -		endpoint->ss_ep_comp->desc.bLength = USB_DT_SS_EP_COMP_SIZE;
> -		endpoint->ss_ep_comp->desc.bDescriptorType = USB_DT_SS_ENDPOINT_COMP;
> -		endpoint->ss_ep_comp->desc.bMaxBurst = 0;
> -		/*
> -		 * Leave bmAttributes as zero, which will mean no streams for
> -		 * bulk, and isoc won't support multiple bursts of packets.
> -		 * With bursts of only one packet, and a Mult of 1, the max
> -		 * amount of data moved per endpoint service interval is one
> -		 * packet.
> -		 */
> -		if (usb_endpoint_xfer_isoc(&endpoint->desc) ||
> -				usb_endpoint_xfer_int(&endpoint->desc))
> -			endpoint->ss_ep_comp->desc.wBytesPerInterval =
> -				endpoint->desc.wMaxPacketSize;
> -
> -		if (size > 0) {
> -			retval = usb_parse_ss_endpoint_companion(ddev, cfgno,
> -					inum, asnum, endpoint, num_ep, buffer,
> -					size);
> -			if (retval >= 0) {
> -				buffer += retval;
> -				retval = buffer - buffer0;
> -			}
> -		} else {
> -			dev_warn(ddev, "config %d interface %d altsetting %d "
> -				"endpoint 0x%X has no "
> -				"SuperSpeed companion descriptor\n",
> -				cfgno, inum, asnum, d->bEndpointAddress);
> -			retval = buffer - buffer0;
> -		}
> -	} else {
> -		/* Skip over any Class Specific or Vendor Specific descriptors;
> -		 * find the next endpoint or interface descriptor */
> -		endpoint->extra = buffer;
> -		i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT,
> -				USB_DT_INTERFACE, &n);
> -		endpoint->extralen = i;
> -		retval = buffer - buffer0 + i;
> -	}
> +	/* Parse a possible SuperSpeed endpoint companion descriptor */
> +	if (to_usb_device(ddev)->speed == USB_SPEED_SUPER)
> +		usb_parse_ss_endpoint_companion(ddev, cfgno,
> +				inum, asnum, endpoint, buffer, size);
> +
> +	/* Skip over any Class Specific or Vendor Specific descriptors;
> +	 * find the next endpoint or interface descriptor */
> +	endpoint->extra = buffer;
> +	i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT,
> +			USB_DT_INTERFACE, &n);
> +	endpoint->extralen = i;
> +	retval = buffer - buffer0 + i;
>  	if (n > 0)
>  		dev_dbg(ddev, "skipped %d descriptor%s after %s\n",
>  		    n, plural(n), "endpoint");
> 
--
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