diff options
Diffstat (limited to 'drivers/usb/core/devices.c')
| -rw-r--r-- | drivers/usb/core/devices.c | 79 | 
1 files changed, 42 insertions, 37 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ddb4dc98092..2a3bbdf7eb9 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c @@ -54,7 +54,6 @@  #include <linux/gfp.h>  #include <linux/poll.h>  #include <linux/usb.h> -#include <linux/smp_lock.h>  #include <linux/usbdevice_fs.h>  #include <linux/usb/hcd.h>  #include <linux/mutex.h> @@ -65,49 +64,49 @@  /* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */  #define ALLOW_SERIAL_NUMBER -static const char *format_topo = +static const char format_topo[] =  /* T:  Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=dddd MxCh=dd */  "\nT:  Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%-4s MxCh=%2d\n"; -static const char *format_string_manufacturer = +static const char format_string_manufacturer[] =  /* S:  Manufacturer=xxxx */    "S:  Manufacturer=%.100s\n"; -static const char *format_string_product = +static const char format_string_product[] =  /* S:  Product=xxxx */    "S:  Product=%.100s\n";  #ifdef ALLOW_SERIAL_NUMBER -static const char *format_string_serialnumber = +static const char format_string_serialnumber[] =  /* S:  SerialNumber=xxxx */    "S:  SerialNumber=%.100s\n";  #endif -static const char *format_bandwidth = +static const char format_bandwidth[] =  /* B:  Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */    "B:  Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n"; -static const char *format_device1 = +static const char format_device1[] =  /* D:  Ver=xx.xx Cls=xx(sssss) Sub=xx Prot=xx MxPS=dd #Cfgs=dd */    "D:  Ver=%2x.%02x Cls=%02x(%-5s) Sub=%02x Prot=%02x MxPS=%2d #Cfgs=%3d\n"; -static const char *format_device2 = +static const char format_device2[] =  /* P:  Vendor=xxxx ProdID=xxxx Rev=xx.xx */    "P:  Vendor=%04x ProdID=%04x Rev=%2x.%02x\n"; -static const char *format_config = +static const char format_config[] =  /* C:  #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */    "C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n"; -static const char *format_iad = +static const char format_iad[] =  /* A:  FirstIf#=dd IfCount=dd Cls=xx(sssss) Sub=xx Prot=xx */    "A:  FirstIf#=%2d IfCount=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x\n"; -static const char *format_iface = +static const char format_iface[] =  /* I:  If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/    "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; -static const char *format_endpt = +static const char format_endpt[] =  /* E:  Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */    "E:  Ad=%02x(%c) Atr=%02x(%-4s) MxPS=%4d Ivl=%d%cs\n"; @@ -191,7 +190,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	dir = usb_endpoint_dir_in(desc) ? 'I' : 'O';  	if (speed == USB_SPEED_HIGH) { -		switch (le16_to_cpu(desc->wMaxPacketSize) & (0x03 << 11)) { +		switch (usb_endpoint_maxp(desc) & (0x03 << 11)) {  		case 1 << 11:  			bandwidth = 2; break;  		case 2 << 11: @@ -222,7 +221,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  		break;  	case USB_ENDPOINT_XFER_INT:  		type = "Int."; -		if (speed == USB_SPEED_HIGH) +		if (speed == USB_SPEED_HIGH || speed == USB_SPEED_SUPER)  			interval = 1 << (desc->bInterval - 1);  		else  			interval = desc->bInterval; @@ -230,7 +229,8 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	default:	/* "can't happen" */  		return start;  	} -	interval *= (speed == USB_SPEED_HIGH) ? 125 : 1000; +	interval *= (speed == USB_SPEED_HIGH || +		     speed == USB_SPEED_SUPER) ? 125 : 1000;  	if (interval % 1000)  		unit = 'u';  	else { @@ -240,7 +240,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end,  	start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,  			 desc->bmAttributes, type, -			 (le16_to_cpu(desc->wMaxPacketSize) & 0x07ff) * +			 (usb_endpoint_maxp(desc) & 0x07ff) *  			 bandwidth,  			 interval, unit);  	return start; @@ -316,17 +316,23 @@ static char *usb_dump_iad_descriptor(char *start, char *end,   */  static char *usb_dump_config_descriptor(char *start, char *end,  				const struct usb_config_descriptor *desc, -				int active) +				int active, int speed)  { +	int mul; +  	if (start > end)  		return start; +	if (speed == USB_SPEED_SUPER) +		mul = 8; +	else +		mul = 2;  	start += sprintf(start, format_config,  			 /* mark active/actual/current cfg. */  			 active ? '*' : ' ',  			 desc->bNumInterfaces,  			 desc->bConfigurationValue,  			 desc->bmAttributes, -			 desc->bMaxPower * 2); +			 desc->bMaxPower * mul);  	return start;  } @@ -342,7 +348,8 @@ static char *usb_dump_config(int speed, char *start, char *end,  	if (!config)  		/* getting these some in 2.3.7; none in 2.3.6 */  		return start + sprintf(start, "(null Cfg. desc.)\n"); -	start = usb_dump_config_descriptor(start, end, &config->desc, active); +	start = usb_dump_config_descriptor(start, end, &config->desc, active, +			speed);  	for (i = 0; i < USB_MAXIADS; i++) {  		if (config->intf_assoc[i] == NULL)  			break; @@ -496,6 +503,7 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	char *pages_start, *data_end, *speed;  	unsigned int length;  	ssize_t total_written = 0; +	struct usb_device *childdev = NULL;  	/* don't bother with anything else if we're not writing any data */  	if (*nbytes <= 0) @@ -543,8 +551,9 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	if (level == 0) {  		int	max; -		/* high speed reserves 80%, full/low reserves 90% */ -		if (usbdev->speed == USB_SPEED_HIGH) +		/* super/high speed reserves 80%, full/low reserves 90% */ +		if (usbdev->speed == USB_SPEED_HIGH || +		    usbdev->speed == USB_SPEED_SUPER)  			max = 800;  		else  			max = FRAME_TIME_MAX_USECS_ALLOC; @@ -588,19 +597,15 @@ static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes,  	free_pages((unsigned long)pages_start, 1);  	/* Now look at all of this device's children. */ -	for (chix = 0; chix < usbdev->maxchild; chix++) { -		struct usb_device *childdev = usbdev->children[chix]; - -		if (childdev) { -			usb_lock_device(childdev); -			ret = usb_device_dump(buffer, nbytes, skip_bytes, -					      file_offset, childdev, bus, -					      level + 1, chix, ++cnt); -			usb_unlock_device(childdev); -			if (ret == -EFAULT) -				return total_written; -			total_written += ret; -		} +	usb_hub_for_each_child(usbdev, chix, childdev) { +		usb_lock_device(childdev); +		ret = usb_device_dump(buffer, nbytes, skip_bytes, +				      file_offset, childdev, bus, +				      level + 1, chix - 1, ++cnt); +		usb_unlock_device(childdev); +		if (ret == -EFAULT) +			return total_written; +		total_written += ret;  	}  	return total_written;  } @@ -623,7 +628,7 @@ static ssize_t usb_device_read(struct file *file, char __user *buf,  	/* print devices for all busses */  	list_for_each_entry(bus, &usb_bus_list, bus_list) {  		/* recurse through all children of the root hub */ -		if (!bus->root_hub) +		if (!bus_to_hcd(bus)->rh_registered)  			continue;  		usb_lock_device(bus->root_hub);  		ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, @@ -660,7 +665,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)  {  	loff_t ret; -	mutex_lock(&file->f_dentry->d_inode->i_mutex); +	mutex_lock(&file_inode(file)->i_mutex);  	switch (orig) {  	case 0: @@ -676,7 +681,7 @@ static loff_t usb_device_lseek(struct file *file, loff_t offset, int orig)  		ret = -EINVAL;  	} -	mutex_unlock(&file->f_dentry->d_inode->i_mutex); +	mutex_unlock(&file_inode(file)->i_mutex);  	return ret;  }  | 
