diff options
Diffstat (limited to 'drivers/usb/core/config.c')
| -rw-r--r-- | drivers/usb/core/config.c | 18 | 
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index 3362af165ef5..880d52c0949d 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c @@ -291,6 +291,20 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,  	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", @@ -308,10 +322,8 @@ static int usb_parse_endpoint(struct device *ddev, int cfgno,  		}  	} -	endpoint = &ifp->endpoint[ifp->desc.bNumEndpoints]; +	/* Accept this endpoint */  	++ifp->desc.bNumEndpoints; - -	memcpy(&endpoint->desc, d, n);  	INIT_LIST_HEAD(&endpoint->urb_list);  	/*  | 
