git://git.onelab.eu
/
linux-2.6.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Fedora kernel-2.6.17-1.2142_FC4 patched with stable patch-2.6.17.4-vs2.0.2-rc26.diff
[linux-2.6.git]
/
drivers
/
usb
/
core
/
devices.c
diff --git
a/drivers/usb/core/devices.c
b/drivers/usb/core/devices.c
index
aa6f7ba
..
c0f3734
100644
(file)
--- a/
drivers/usb/core/devices.c
+++ b/
drivers/usb/core/devices.c
@@
-57,8
+57,10
@@
#include <linux/usb.h>
#include <linux/smp_lock.h>
#include <linux/usbdevice_fs.h>
#include <linux/usb.h>
#include <linux/smp_lock.h>
#include <linux/usbdevice_fs.h>
+#include <linux/mutex.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
+#include "usb.h"
#include "hcd.h"
#define MAX_TOPO_LEVEL 6
#include "hcd.h"
#define MAX_TOPO_LEVEL 6
@@
-66,45
+68,45
@@
/* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
#define ALLOW_SERIAL_NUMBER
/* Define ALLOW_SERIAL_NUMBER if you want to see the serial number of devices */
#define ALLOW_SERIAL_NUMBER
-static char *format_topo =
+static c
onst c
har *format_topo =
/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
/* T: Bus=dd Lev=dd Prnt=dd Port=dd Cnt=dd Dev#=ddd Spd=ddd MxCh=dd */
"\nT: Bus=%2.2d Lev=%2.2d Prnt=%2.2d Port=%2.2d Cnt=%2.2d Dev#=%3d Spd=%3s MxCh=%2d\n";
-static char *format_string_manufacturer =
+static c
onst c
har *format_string_manufacturer =
/* S: Manufacturer=xxxx */
"S: Manufacturer=%.100s\n";
/* S: Manufacturer=xxxx */
"S: Manufacturer=%.100s\n";
-static char *format_string_product =
+static c
onst c
har *format_string_product =
/* S: Product=xxxx */
"S: Product=%.100s\n";
#ifdef ALLOW_SERIAL_NUMBER
/* S: Product=xxxx */
"S: Product=%.100s\n";
#ifdef ALLOW_SERIAL_NUMBER
-static char *format_string_serialnumber =
+static c
onst c
har *format_string_serialnumber =
/* S: SerialNumber=xxxx */
"S: SerialNumber=%.100s\n";
#endif
/* S: SerialNumber=xxxx */
"S: SerialNumber=%.100s\n";
#endif
-static char *format_bandwidth =
+static c
onst c
har *format_bandwidth =
/* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
"B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
/* B: Alloc=ddd/ddd us (xx%), #Int=ddd, #Iso=ddd */
"B: Alloc=%3d/%3d us (%2d%%), #Int=%3d, #Iso=%3d\n";
-static char *format_device1 =
+static c
onst c
har *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";
/* 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 char *format_device2 =
+static c
onst c
har *format_device2 =
/* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */
"P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
/* P: Vendor=xxxx ProdID=xxxx Rev=xx.xx */
"P: Vendor=%04x ProdID=%04x Rev=%2x.%02x\n";
-static char *format_config =
+static c
onst c
har *format_config =
/* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
"C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
/* C: #Ifs=dd Cfg#=dd Atr=xx MPwr=dddmA */
"C:%c #Ifs=%2d Cfg#=%2d Atr=%02x MxPwr=%3dmA\n";
-static char *format_iface =
+static c
onst c
har *format_iface =
/* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
"I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
/* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/
"I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n";
-static char *format_endpt =
+static c
onst c
har *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";
/* 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";
@@
-149,7
+151,7
@@
static const struct class_info clas_info[] =
/*****************************************************************/
/*****************************************************************/
-void usb
dev
fs_conn_disc_event(void)
+void usbfs_conn_disc_event(void)
{
conndiscevcnt++;
wake_up(&deviceconndiscwq);
{
conndiscevcnt++;
wake_up(&deviceconndiscwq);
@@
-180,7
+182,7
@@
static char *usb_dump_endpoint_descriptor (
in = (desc->bEndpointAddress & USB_DIR_IN);
dir = in ? 'I' : 'O';
if (speed == USB_SPEED_HIGH) {
in = (desc->bEndpointAddress & USB_DIR_IN);
dir = in ? 'I' : 'O';
if (speed == USB_SPEED_HIGH) {
- switch (
desc->wMaxPacketSize
& (0x03 << 11)) {
+ switch (
le16_to_cpu(desc->wMaxPacketSize)
& (0x03 << 11)) {
case 1 << 11: bandwidth = 2; break;
case 2 << 11: bandwidth = 3; break;
}
case 1 << 11: bandwidth = 2; break;
case 2 << 11: bandwidth = 3; break;
}
@@
-227,18
+229,26
@@
static char *usb_dump_endpoint_descriptor (
start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
desc->bmAttributes, type,
start += sprintf(start, format_endpt, desc->bEndpointAddress, dir,
desc->bmAttributes, type,
- (
desc->wMaxPacketSize
& 0x07ff) * bandwidth,
+ (
le16_to_cpu(desc->wMaxPacketSize)
& 0x07ff) * bandwidth,
interval, unit);
return start;
}
interval, unit);
return start;
}
-static char *usb_dump_interface_descriptor(char *start, char *end, const struct usb_interface *iface, int setno)
+static char *usb_dump_interface_descriptor(char *start, char *end,
+ const struct usb_interface_cache *intfc,
+ const struct usb_interface *iface,
+ int setno)
{
{
- struct usb_interface_descriptor *desc = &iface->altsetting[setno].desc;
+ const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc;
+ const char *driver_name = "";
if (start > end)
return start;
down_read(&usb_bus_type.subsys.rwsem);
if (start > end)
return start;
down_read(&usb_bus_type.subsys.rwsem);
+ if (iface)
+ driver_name = (iface->dev.driver
+ ? iface->dev.driver->name
+ : "(none)");
start += sprintf(start, format_iface,
desc->bInterfaceNumber,
desc->bAlternateSetting,
start += sprintf(start, format_iface,
desc->bInterfaceNumber,
desc->bAlternateSetting,
@@
-247,9
+257,7
@@
static char *usb_dump_interface_descriptor(char *start, char *end, const struct
class_decode(desc->bInterfaceClass),
desc->bInterfaceSubClass,
desc->bInterfaceProtocol,
class_decode(desc->bInterfaceClass),
desc->bInterfaceSubClass,
desc->bInterfaceProtocol,
- iface->dev.driver
- ? iface->dev.driver->name
- : "(none)");
+ driver_name);
up_read(&usb_bus_type.subsys.rwsem);
return start;
}
up_read(&usb_bus_type.subsys.rwsem);
return start;
}
@@
-258,13
+266,14
@@
static char *usb_dump_interface(
int speed,
char *start,
char *end,
int speed,
char *start,
char *end,
+ const struct usb_interface_cache *intfc,
const struct usb_interface *iface,
int setno
) {
const struct usb_interface *iface,
int setno
) {
-
struct usb_host_interface *desc = &iface
->altsetting[setno];
+
const struct usb_host_interface *desc = &intfc
->altsetting[setno];
int i;
int i;
- start = usb_dump_interface_descriptor(start, end, iface, setno);
+ start = usb_dump_interface_descriptor(start, end, i
ntfc, i
face, setno);
for (i = 0; i < desc->desc.bNumEndpoints; i++) {
if (start > end)
return start;
for (i = 0; i < desc->desc.bNumEndpoints; i++) {
if (start > end)
return start;
@@
-276,9
+285,8
@@
static char *usb_dump_interface(
/* TBD:
* 0. TBDs
/* TBD:
* 0. TBDs
- * 1. marking active
config and iface
s (code lists all, but should mark
+ * 1. marking active
interface altsetting
s (code lists all, but should mark
* which ones are active, if any)
* which ones are active, if any)
- * 2. add <halted> status to each endpoint line
*/
static char *usb_dump_config_descriptor(char *start, char *end, const struct usb_config_descriptor *desc, int active)
*/
static char *usb_dump_config_descriptor(char *start, char *end, const struct usb_config_descriptor *desc, int active)
@@
-303,6
+311,7
@@
static char *usb_dump_config (
)
{
int i, j;
)
{
int i, j;
+ struct usb_interface_cache *intfc;
struct usb_interface *interface;
if (start > end)
struct usb_interface *interface;
if (start > end)
@@
-311,14
+320,13
@@
static char *usb_dump_config (
return start + sprintf(start, "(null Cfg. desc.)\n");
start = usb_dump_config_descriptor(start, end, &config->desc, active);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
return start + sprintf(start, "(null Cfg. desc.)\n");
start = usb_dump_config_descriptor(start, end, &config->desc, active);
for (i = 0; i < config->desc.bNumInterfaces; i++) {
+ intfc = config->intf_cache[i];
interface = config->interface[i];
interface = config->interface[i];
- if (!interface)
- break;
- for (j = 0; j < interface->num_altsetting; j++) {
+ for (j = 0; j < intfc->num_altsetting; j++) {
if (start > end)
return start;
start = usb_dump_interface(speed,
if (start > end)
return start;
start = usb_dump_interface(speed,
-
start, end
, interface, j);
+
start, end, intfc
, interface, j);
}
}
return start;
}
}
return start;
@@
-329,10
+337,13
@@
static char *usb_dump_config (
*/
static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
{
*/
static char *usb_dump_device_descriptor(char *start, char *end, const struct usb_device_descriptor *desc)
{
+ u16 bcdUSB = le16_to_cpu(desc->bcdUSB);
+ u16 bcdDevice = le16_to_cpu(desc->bcdDevice);
+
if (start > end)
return start;
start += sprintf (start, format_device1,
if (start > end)
return start;
start += sprintf (start, format_device1,
-
desc->bcdUSB >> 8, desc->
bcdUSB & 0xff,
+
bcdUSB >> 8,
bcdUSB & 0xff,
desc->bDeviceClass,
class_decode (desc->bDeviceClass),
desc->bDeviceSubClass,
desc->bDeviceClass,
class_decode (desc->bDeviceClass),
desc->bDeviceSubClass,
@@
-342,8
+353,9
@@
static char *usb_dump_device_descriptor(char *start, char *end, const struct usb
if (start > end)
return start;
start += sprintf(start, format_device2,
if (start > end)
return start;
start += sprintf(start, format_device2,
- desc->idVendor, desc->idProduct,
- desc->bcdDevice >> 8, desc->bcdDevice & 0xff);
+ le16_to_cpu(desc->idVendor),
+ le16_to_cpu(desc->idProduct),
+ bcdDevice >> 8, bcdDevice & 0xff);
return start;
}
return start;
}
@@
-352,33
+364,21
@@
static char *usb_dump_device_descriptor(char *start, char *end, const struct usb
*/
static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev)
{
*/
static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev)
{
- char *buf;
-
if (start > end)
return start;
if (start > end)
return start;
- buf = kmalloc(128, GFP_KERNEL);
- if (!buf)
- return start;
- if (dev->descriptor.iManufacturer) {
- if (usb_string(dev, dev->descriptor.iManufacturer, buf, 128) > 0)
- start += sprintf(start, format_string_manufacturer, buf);
- }
+ if (dev->manufacturer)
+ start += sprintf(start, format_string_manufacturer, dev->manufacturer);
if (start > end)
goto out;
if (start > end)
goto out;
- if (dev->descriptor.iProduct) {
- if (usb_string(dev, dev->descriptor.iProduct, buf, 128) > 0)
- start += sprintf(start, format_string_product, buf);
- }
+ if (dev->product)
+ start += sprintf(start, format_string_product, dev->product);
if (start > end)
goto out;
#ifdef ALLOW_SERIAL_NUMBER
if (start > end)
goto out;
#ifdef ALLOW_SERIAL_NUMBER
- if (dev->descriptor.iSerialNumber) {
- if (usb_string(dev, dev->descriptor.iSerialNumber, buf, 128) > 0)
- start += sprintf(start, format_string_serialnumber, buf);
- }
+ if (dev->serial)
+ start += sprintf(start, format_string_serialnumber, dev->serial);
#endif
out:
#endif
out:
- kfree(buf);
return start;
}
return start;
}
@@
-395,7
+395,7
@@
static char *usb_dump_desc(char *start, char *end, struct usb_device *dev)
return start;
start = usb_dump_device_strings (start, end, dev);
return start;
start = usb_dump_device_strings (start, end, dev);
-
+
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
if (start > end)
return start;
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
if (start > end)
return start;
@@
-445,6
+445,7
@@
static char *usb_dump_string(char *start, char *end, const struct usb_device *de
* nbytes - the maximum number of bytes to write
* skip_bytes - the number of bytes to skip before writing anything
* file_offset - the offset into the devices file on completion
* nbytes - the maximum number of bytes to write
* skip_bytes - the number of bytes to skip before writing anything
* file_offset - the offset into the devices file on completion
+ * The caller must own the device lock.
*/
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
*/
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *skip_bytes, loff_t *file_offset,
struct usb_device *usbdev, struct usb_bus *bus, int level, int index, int count)
@@
-461,7
+462,7
@@
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
return 0;
if (level > MAX_TOPO_LEVEL)
return 0;
if (level > MAX_TOPO_LEVEL)
- return
total_written
;
+ return
0
;
/* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
return -ENOMEM;
/* allocate 2^1 pages = 8K (on i386); should be more than enough for one device */
if (!(pages_start = (char*) __get_free_pages(GFP_KERNEL,1)))
return -ENOMEM;
@@
-528,10
+529,7
@@
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
length = *nbytes;
if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) {
free_pages((unsigned long)pages_start, 1);
length = *nbytes;
if (copy_to_user(*buffer, pages_start + *skip_bytes, length)) {
free_pages((unsigned long)pages_start, 1);
-
- if (total_written == 0)
- return -EFAULT;
- return total_written;
+ return -EFAULT;
}
*nbytes -= length;
*file_offset += length;
}
*nbytes -= length;
*file_offset += length;
@@
-545,9
+543,13
@@
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
/* Now look at all of this device's children. */
for (chix = 0; chix < usbdev->maxchild; chix++) {
/* Now look at all of this device's children. */
for (chix = 0; chix < usbdev->maxchild; chix++) {
- if (usbdev->children[chix]) {
- ret = usb_device_dump(buffer, nbytes, skip_bytes, file_offset, usbdev->children[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);
bus, level + 1, chix, ++cnt);
+ usb_unlock_device(childdev);
if (ret == -EFAULT)
return total_written;
total_written += ret;
if (ret == -EFAULT)
return total_written;
total_written += ret;
@@
-558,7
+560,6
@@
static ssize_t usb_device_dump(char __user **buffer, size_t *nbytes, loff_t *ski
static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
- struct list_head *buslist;
struct usb_bus *bus;
ssize_t ret, total_written = 0;
loff_t skip_bytes = *ppos;
struct usb_bus *bus;
ssize_t ret, total_written = 0;
loff_t skip_bytes = *ppos;
@@
-570,20
+571,22
@@
static ssize_t usb_device_read(struct file *file, char __user *buf, size_t nbyte
if (!access_ok(VERIFY_WRITE, buf, nbytes))
return -EFAULT;
if (!access_ok(VERIFY_WRITE, buf, nbytes))
return -EFAULT;
- /* enumerate busses */
- down (&usb_bus_list_lock);
- for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) {
- /* print devices for this bus */
- bus = list_entry(buslist, struct usb_bus, bus_list);
+ mutex_lock(&usb_bus_list_lock);
+ /* print devices for all busses */
+ list_for_each_entry(bus, &usb_bus_list, bus_list) {
/* recurse through all children of the root hub */
/* recurse through all children of the root hub */
+ if (!bus->root_hub)
+ continue;
+ usb_lock_device(bus->root_hub);
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
ret = usb_device_dump(&buf, &nbytes, &skip_bytes, ppos, bus->root_hub, bus, 0, 0, 0);
+ usb_unlock_device(bus->root_hub);
if (ret < 0) {
if (ret < 0) {
-
up
(&usb_bus_list_lock);
+
mutex_unlock
(&usb_bus_list_lock);
return ret;
}
total_written += ret;
}
return ret;
}
total_written += ret;
}
-
up
(&usb_bus_list_lock);
+
mutex_unlock
(&usb_bus_list_lock);
return total_written;
}
return total_written;
}
@@
-604,6
+607,7
@@
static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
/* we may have dropped BKL - need to check for having lost the race */
if (file->private_data) {
kfree(st);
/* we may have dropped BKL - need to check for having lost the race */
if (file->private_data) {
kfree(st);
+ st = file->private_data;
goto lost_race;
}
goto lost_race;
}
@@
-634,11
+638,8
@@
static int usb_device_open(struct inode *inode, struct file *file)
static int usb_device_release(struct inode *inode, struct file *file)
{
static int usb_device_release(struct inode *inode, struct file *file)
{
- if (file->private_data) {
- kfree(file->private_data);
- file->private_data = NULL;
- }
-
+ kfree(file->private_data);
+ file->private_data = NULL;
return 0;
}
return 0;
}
@@
-666,7
+667,7
@@
static loff_t usb_device_lseek(struct file * file, loff_t offset, int orig)
return ret;
}
return ret;
}
-struct file_operations usb
dev
fs_devices_fops = {
+struct file_operations usbfs_devices_fops = {
.llseek = usb_device_lseek,
.read = usb_device_read,
.poll = usb_device_poll,
.llseek = usb_device_lseek,
.read = usb_device_read,
.poll = usb_device_poll,