Greg Kroah-HartmanMerge 7.2-rc7 into usb-nextacbecf63 months agoHistory
1163 lines · 34.1 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0/* * Released under the GPLv2 only. */ #include <linux/usb.h>#include <linux/usb/ch9.h>#include <linux/usb/hcd.h>#include <linux/usb/quirks.h>#include <linux/module.h>#include <linux/slab.h>#include <linux/string_choices.h>#include <linux/device.h>#include <asm/byteorder.h>#include "usb.h"  #define USB_MAXALTSETTING		128	/* Hard limit */ #define USB_MAXCONFIG			8	/* Arbitrary limit */ static int find_next_descriptor(unsigned char *buffer, int size,    int dt1, int dt2, int *num_skipped){	struct usb_descriptor_header *h;	int n = 0;	unsigned char *buffer0 = buffer; 	/* Find the next descriptor of type dt1 or dt2 */	while (size > 0) {		h = (struct usb_descriptor_header *) buffer;		if (h->bDescriptorType == dt1 || h->bDescriptorType == dt2)			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 void usb_parse_ssp_isoc_endpoint_companion(struct device *ddev,		int cfgno, int inum, int asnum, struct usb_host_endpoint *ep,		unsigned char *buffer, int size){	struct usb_ssp_isoc_ep_comp_descriptor *desc; 	/*	 * The SuperSpeedPlus Isoc endpoint companion descriptor immediately	 * follows the SuperSpeed Endpoint Companion descriptor	 */	desc = (struct usb_ssp_isoc_ep_comp_descriptor *) buffer;	if (size < USB_DT_SSP_ISOC_EP_COMP_SIZE ||	    desc->bDescriptorType != USB_DT_SSP_ISOC_ENDPOINT_COMP) {		dev_notice(ddev, "Invalid SuperSpeedPlus isoc endpoint companion for config %d interface %d altsetting %d ep 0x%X.\n",			 cfgno, inum, asnum, ep->desc.bEndpointAddress);		return;	}	memcpy(&ep->ssp_isoc_ep_comp, desc, USB_DT_SSP_ISOC_EP_COMP_SIZE);} static void usb_parse_eusb2_isoc_endpoint_companion(struct device *ddev,		int cfgno, int inum, int asnum, struct usb_host_endpoint *ep,		unsigned char *buffer, int size){	struct usb_eusb2_isoc_ep_comp_descriptor *desc;	struct usb_descriptor_header *h; 	/*	 * eUSB2 isochronous endpoint companion descriptor for this endpoint	 * shall be declared before the next endpoint or interface descriptor	 */	while (size >= USB_DT_EUSB2_ISOC_EP_COMP_SIZE) {		h = (struct usb_descriptor_header *)buffer; 		if (h->bDescriptorType == USB_DT_EUSB2_ISOC_ENDPOINT_COMP) {			desc = (struct usb_eusb2_isoc_ep_comp_descriptor *)buffer;			ep->eusb2_isoc_ep_comp = *desc;			return;		}		if (h->bDescriptorType == USB_DT_ENDPOINT ||		    h->bDescriptorType == USB_DT_INTERFACE)			break; 		buffer += h->bLength;		size -= h->bLength;	} 	dev_notice(ddev, "No eUSB2 isoc ep 0x%X companion for config %d interface %d altsetting %d\n",		   ep->desc.bEndpointAddress, cfgno, inum, asnum);} static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,		int inum, int asnum, struct usb_host_endpoint *ep,		unsigned char *buffer, int size){	struct usb_ss_ep_comp_descriptor *desc;	int max_tx; 	/* 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 (size < USB_DT_SS_EP_COMP_SIZE) {		dev_notice(ddev,			   "invalid SuperSpeed endpoint companion descriptor "			   "of length %d, skipping\n", size);		return;	} 	if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) {		dev_notice(ddev, "No SuperSpeed endpoint companion for config %d interface %d altsetting %d ep 0x%X: using minimum values\n",				cfgno, inum, asnum, ep->desc.bEndpointAddress); 		/* 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.		 */		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;	}	buffer += desc->bLength;	size -= desc->bLength;	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) {		dev_notice(ddev, "Control endpoint with bMaxBurst = %d in config %d interface %d altsetting %d ep 0x%X: setting to zero\n",				desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress);		ep->ss_ep_comp.bMaxBurst = 0;	} else if (desc->bMaxBurst > 15) {		dev_notice(ddev, "Endpoint with bMaxBurst = %d in config %d interface %d altsetting %d ep 0x%X: setting to 15\n",				desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress);		ep->ss_ep_comp.bMaxBurst = 15;	} 	if ((usb_endpoint_xfer_control(&ep->desc) ||			usb_endpoint_xfer_int(&ep->desc)) &&				desc->bmAttributes != 0) {		dev_notice(ddev, "%s endpoint with bmAttributes = %d in config %d interface %d altsetting %d ep 0x%X: setting to zero\n",				usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Interrupt",				desc->bmAttributes,				cfgno, inum, asnum, ep->desc.bEndpointAddress);		ep->ss_ep_comp.bmAttributes = 0;	} else if (usb_endpoint_xfer_bulk(&ep->desc) &&			desc->bmAttributes > 16) {		dev_notice(ddev, "Bulk endpoint with more than 65536 streams in config %d interface %d altsetting %d ep 0x%X: setting to max\n",				cfgno, inum, asnum, ep->desc.bEndpointAddress);		ep->ss_ep_comp.bmAttributes = 16;	} else if (usb_endpoint_xfer_isoc(&ep->desc) &&		   !USB_SS_SSP_ISOC_COMP(desc->bmAttributes) &&		   USB_SS_MULT(desc->bmAttributes) > 3) {		dev_notice(ddev, "Isoc endpoint has Mult of %d in config %d interface %d altsetting %d ep 0x%X: setting to 3\n",				USB_SS_MULT(desc->bmAttributes),				cfgno, inum, asnum, ep->desc.bEndpointAddress);		ep->ss_ep_comp.bmAttributes = 2;	} 	if (usb_endpoint_xfer_isoc(&ep->desc))		max_tx = (desc->bMaxBurst + 1) *			(USB_SS_MULT(desc->bmAttributes)) *			usb_endpoint_maxp(&ep->desc);	else if (usb_endpoint_xfer_int(&ep->desc))		max_tx = usb_endpoint_maxp(&ep->desc) *			(desc->bMaxBurst + 1);	else		max_tx = 999999;	/*	 * wBytesPerInterval > max_tx is bogus, but USB3 spec doesn't forbid the opposite.	 * Experience shows that wBytesPerInterval < wMaxPacketSize on common interrupt IN	 * endpoints is usually bogus too, and recent HCs enforce interrupt BW limits.	 */	if (le16_to_cpu(desc->wBytesPerInterval) > max_tx ||	    (le16_to_cpu(desc->wBytesPerInterval) < usb_endpoint_maxp(&ep->desc) &&	     usb_endpoint_is_int_in(&ep->desc))) {		dev_notice(ddev, "%s endpoint with wBytesPerInterval of %d in config %d interface %d altsetting %d ep 0x%X: setting to %d\n",				usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",				le16_to_cpu(desc->wBytesPerInterval),				cfgno, inum, asnum, ep->desc.bEndpointAddress,				max_tx);		ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);	}	/* Parse a possible SuperSpeedPlus isoc ep companion descriptor */	if (usb_endpoint_xfer_isoc(&ep->desc) &&	    USB_SS_SSP_ISOC_COMP(desc->bmAttributes))		usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,							ep, buffer, size);} static const unsigned short low_speed_maxpacket_maxes[4] = {	[USB_ENDPOINT_XFER_CONTROL] = 8,	[USB_ENDPOINT_XFER_ISOC] = 0,	[USB_ENDPOINT_XFER_BULK] = 0,	[USB_ENDPOINT_XFER_INT] = 8,};static const unsigned short full_speed_maxpacket_maxes[4] = {	[USB_ENDPOINT_XFER_CONTROL] = 64,	[USB_ENDPOINT_XFER_ISOC] = 1023,	[USB_ENDPOINT_XFER_BULK] = 64,	[USB_ENDPOINT_XFER_INT] = 64,};static const unsigned short high_speed_maxpacket_maxes[4] = {	[USB_ENDPOINT_XFER_CONTROL] = 64,	[USB_ENDPOINT_XFER_ISOC] = 1024, 	/* Bulk should be 512, but some devices use 1024: we will warn below */	[USB_ENDPOINT_XFER_BULK] = 1024,	[USB_ENDPOINT_XFER_INT] = 1024,};static const unsigned short super_speed_maxpacket_maxes[4] = {	[USB_ENDPOINT_XFER_CONTROL] = 512,	[USB_ENDPOINT_XFER_ISOC] = 1024,	[USB_ENDPOINT_XFER_BULK] = 1024,	[USB_ENDPOINT_XFER_INT] = 1024,}; static bool endpoint_is_duplicate(struct usb_endpoint_descriptor *e1,		struct usb_endpoint_descriptor *e2){	if (e1->bEndpointAddress == e2->bEndpointAddress)		return true; 	if (usb_endpoint_xfer_control(e1) || usb_endpoint_xfer_control(e2)) {		if (usb_endpoint_num(e1) == usb_endpoint_num(e2))			return true;	} 	return false;} /* * Check for duplicate endpoint addresses in other interfaces and in the * altsetting currently being parsed. */static bool config_endpoint_is_duplicate(struct usb_host_config *config,		int inum, int asnum, struct usb_endpoint_descriptor *d){	struct usb_endpoint_descriptor *epd;	struct usb_interface_cache *intfc;	struct usb_host_interface *alt;	int i, j, k; 	for (i = 0; i < config->desc.bNumInterfaces; ++i) {		intfc = config->intf_cache[i]; 		for (j = 0; j < intfc->num_altsetting; ++j) {			alt = &intfc->altsetting[j]; 			if (alt->desc.bInterfaceNumber == inum &&					alt->desc.bAlternateSetting != asnum)				continue; 			for (k = 0; k < alt->desc.bNumEndpoints; ++k) {				epd = &alt->endpoint[k].desc; 				if (endpoint_is_duplicate(epd, d))					return true;			}		}	} 	return false;} static int usb_parse_endpoint(struct device *ddev, int cfgno,		struct usb_host_config *config, int inum, int asnum,		struct usb_host_interface *ifp, int num_ep,		unsigned char *buffer, int size){	struct usb_device *udev = to_usb_device(ddev);	unsigned char *buffer0 = buffer;	struct usb_endpoint_descriptor *d;	struct usb_host_endpoint *endpoint;	int n, i, j, retval;	unsigned int maxp;	const unsigned short *maxpacket_maxes;	u16 bcdUSB; 	d = (struct usb_endpoint_descriptor *) buffer;	bcdUSB = le16_to_cpu(udev->descriptor.bcdUSB);	buffer += d->bLength;	size -= d->bLength; 	if (d->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE)		n = USB_DT_ENDPOINT_AUDIO_SIZE;	else if (d->bLength >= USB_DT_ENDPOINT_SIZE)		n = USB_DT_ENDPOINT_SIZE;	else {		dev_notice(ddev, "config %d interface %d altsetting %d has an "		    "invalid endpoint descriptor of length %d, skipping\n",		    cfgno, inum, asnum, d->bLength);		goto skip_to_next_endpoint_or_interface_descriptor;	} 	i = usb_endpoint_num(d);	if (i == 0) {		dev_notice(ddev, "config %d interface %d altsetting %d has an "		    "invalid descriptor for endpoint zero, skipping\n",		    cfgno, inum, asnum);		goto skip_to_next_endpoint_or_interface_descriptor;	} 	/* Only store as many endpoints as we have room for */	if (ifp->desc.bNumEndpoints >= num_ep)		goto skip_to_next_endpoint_or_interface_descriptor; 	/* Save a copy of the descriptor and use it instead of the original */	endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints];	memcpy(&endpoint->desc, d, n);	d = &endpoint->desc; 	/* Clear the reserved bits in bEndpointAddress */	i = d->bEndpointAddress &			(USB_ENDPOINT_DIR_MASK | USB_ENDPOINT_NUMBER_MASK);	if (i != d->bEndpointAddress) {		dev_notice(ddev, "config %d interface %d altsetting %d has an endpoint descriptor with address 0x%X, changing to 0x%X\n",		    cfgno, inum, asnum, d->bEndpointAddress, i);		endpoint->desc.bEndpointAddress = i;	} 	/* Check for duplicate endpoint addresses */	if (config_endpoint_is_duplicate(config, inum, asnum, d)) {		dev_notice(ddev, "config %d interface %d altsetting %d has a duplicate endpoint with address 0x%X, skipping\n",				cfgno, inum, asnum, d->bEndpointAddress);		goto skip_to_next_endpoint_or_interface_descriptor;	} 	/* Ignore some endpoints */	if (udev->quirks & USB_QUIRK_ENDPOINT_IGNORE) {		if (usb_endpoint_is_ignored(udev, ifp, d)) {			dev_notice(ddev, "config %d interface %d altsetting %d has an ignored endpoint with address 0x%X, skipping\n",					cfgno, inum, asnum,					d->bEndpointAddress);			goto skip_to_next_endpoint_or_interface_descriptor;		}	} 	/* Accept this endpoint */	++ifp->desc.bNumEndpoints;	INIT_LIST_HEAD(&endpoint->urb_list); 	/*	 * Fix up bInterval values outside the legal range.	 * Use 10 or 8 ms if no proper value can be guessed.	 */	i = 0;		/* i = min, j = max, n = default */	j = 255;	if (usb_endpoint_xfer_int(d)) {		i = 1;		switch (udev->speed) {		case USB_SPEED_SUPER_PLUS:		case USB_SPEED_SUPER:		case USB_SPEED_HIGH:			/*			 * Many device manufacturers are using full-speed			 * bInterval values in high-speed interrupt endpoint			 * descriptors. Try to fix those and fall back to an			 * 8-ms default value otherwise.			 */			n = fls(d->bInterval*8);			if (n == 0)				n = 7;	/* 8 ms = 2^(7-1) uframes */			j = 16; 			/*			 * Adjust bInterval for quirked devices.			 */			/*			 * This quirk fixes bIntervals reported in ms.			 */			if (udev->quirks & USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {				n = clamp(fls(d->bInterval) + 3, i, j);				i = j = n;			}			/*			 * This quirk fixes bIntervals reported in			 * linear microframes.			 */			if (udev->quirks & USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) {				n = clamp(fls(d->bInterval), i, j);				i = j = n;			}			break;		default:		/* USB_SPEED_FULL or _LOW */			/*			 * For low-speed, 10 ms is the official minimum.			 * But some "overclocked" devices might want faster			 * polling so we'll allow it.			 */			n = 10;			break;		}	} else if (usb_endpoint_xfer_isoc(d)) {		i = 1;		j = 16;		switch (udev->speed) {		case USB_SPEED_HIGH:			n = 7;		/* 8 ms = 2^(7-1) uframes */			break;		default:		/* USB_SPEED_FULL */			n = 4;		/* 8 ms = 2^(4-1) frames */			break;		}	}	if (d->bInterval < i || d->bInterval > j) {		dev_notice(ddev, "config %d interface %d altsetting %d "		    "endpoint 0x%X has an invalid bInterval %d, "		    "changing to %d\n",		    cfgno, inum, asnum,		    d->bEndpointAddress, d->bInterval, n);		endpoint->desc.bInterval = n;	} 	/* Some buggy low-speed devices have Bulk endpoints, which is	 * explicitly forbidden by the USB spec.  In an attempt to make	 * them usable, we will try treating them as Interrupt endpoints.	 */	if (udev->speed == USB_SPEED_LOW && usb_endpoint_xfer_bulk(d)) {		dev_notice(ddev, "config %d interface %d altsetting %d "		    "endpoint 0x%X is Bulk; changing to Interrupt\n",		    cfgno, inum, asnum, d->bEndpointAddress);		endpoint->desc.bmAttributes = USB_ENDPOINT_XFER_INT;		endpoint->desc.bInterval = 1;		if (usb_endpoint_maxp(&endpoint->desc) > 8)			endpoint->desc.wMaxPacketSize = cpu_to_le16(8);	} 	/*	 * Validate the wMaxPacketSize field.	 * eUSB2 devices (see USB 2.0 Double Isochronous IN ECN 9.6.6 Endpoint)	 * and devices with isochronous endpoints in altsetting 0 (see USB 2.0	 * end of section 5.6.3) have wMaxPacketSize = 0.	 * So don't warn about those.	 */	maxp = le16_to_cpu(endpoint->desc.wMaxPacketSize); 	if (maxp == 0 && bcdUSB != 0x0220 &&	    !(usb_endpoint_xfer_isoc(d) && asnum == 0))		dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n",		    cfgno, inum, asnum, d->bEndpointAddress); 	/* Find the highest legal maxpacket size for this endpoint */	i = 0;		/* additional transactions per microframe */	switch (udev->speed) {	case USB_SPEED_LOW:		maxpacket_maxes = low_speed_maxpacket_maxes;		break;	case USB_SPEED_FULL:		maxpacket_maxes = full_speed_maxpacket_maxes;		break;	case USB_SPEED_HIGH:		/* Multiple-transactions bits are allowed only for HS periodic endpoints */		if (usb_endpoint_xfer_int(d) || usb_endpoint_xfer_isoc(d)) {			i = maxp & USB_EP_MAXP_MULT_MASK;			maxp &= ~i;		}		fallthrough;	default:		maxpacket_maxes = high_speed_maxpacket_maxes;		break;	case USB_SPEED_SUPER:	case USB_SPEED_SUPER_PLUS:		maxpacket_maxes = super_speed_maxpacket_maxes;		break;	}	j = maxpacket_maxes[usb_endpoint_type(&endpoint->desc)]; 	if (maxp > j) {		dev_notice(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid maxpacket %d, setting to %d\n",		    cfgno, inum, asnum, d->bEndpointAddress, maxp, j);		maxp = j;		endpoint->desc.wMaxPacketSize = cpu_to_le16(i | maxp);	} 	/*	 * Some buggy high speed devices have bulk endpoints using	 * maxpacket sizes other than 512.  High speed HCDs may not	 * be able to handle that particular bug, so let's warn...	 */	if (udev->speed == USB_SPEED_HIGH && usb_endpoint_xfer_bulk(d)) {		if (maxp != 512)			dev_notice(ddev, "config %d interface %d altsetting %d "				"bulk endpoint 0x%X has invalid maxpacket %d\n",				cfgno, inum, asnum, d->bEndpointAddress,				maxp);	} 

Lines 1–500 of 1163.