aboutsummaryrefslogtreecommitdiff
path: root/drivers/usb/core
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pretzel.yyz.us>2005-06-22 13:07:28 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-06-22 13:07:28 -0400
commitff40c6d3d1437ecdf295b8e39adcb06c3d6021ef (patch)
tree3666d029b4bd4df2909dbefd9c7a09e6042b7d32 /drivers/usb/core
parent8bf62ecee58360749c5f0e68bc97d5e02a6816b1 (diff)
parent2a5a68b840cbab31baab2d9b2e1e6de3b289ae1e (diff)
Merge upstream kernel changes into 'C/H/S support' branch of libata.
Diffstat (limited to 'drivers/usb/core')
-rw-r--r--drivers/usb/core/devices.c2
-rw-r--r--drivers/usb/core/file.c13
-rw-r--r--drivers/usb/core/hcd.c61
-rw-r--r--drivers/usb/core/sysfs.c56
-rw-r--r--drivers/usb/core/usb.c53
5 files changed, 111 insertions, 74 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index ef0b35731ff..83e815d3cd5 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -239,7 +239,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end,
int setno)
{
const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc;
- char *driver_name = "";
+ const char *driver_name = "";
if (start > end)
return start;
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 38ed2220c9f..65ca131cc44 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -68,7 +68,7 @@ static struct file_operations usb_fops = {
.open = usb_open,
};
-static struct class_simple *usb_class;
+static struct class *usb_class;
int usb_major_init(void)
{
@@ -80,9 +80,10 @@ int usb_major_init(void)
goto out;
}
- usb_class = class_simple_create(THIS_MODULE, "usb");
+ usb_class = class_create(THIS_MODULE, "usb");
if (IS_ERR(usb_class)) {
- err("class_simple_create failed for usb devices");
+ error = PTR_ERR(usb_class);
+ err("class_create failed for usb devices");
unregister_chrdev(USB_MAJOR, "usb");
goto out;
}
@@ -95,7 +96,7 @@ out:
void usb_major_cleanup(void)
{
- class_simple_destroy(usb_class);
+ class_destroy(usb_class);
devfs_remove("usb");
unregister_chrdev(USB_MAJOR, "usb");
}
@@ -171,7 +172,7 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
- intf->class_dev = class_simple_device_add(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
+ intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp);
if (IS_ERR(intf->class_dev)) {
spin_lock (&minor_lock);
usb_minors[intf->minor] = NULL;
@@ -220,7 +221,7 @@ void usb_deregister_dev(struct usb_interface *intf,
snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base);
devfs_remove (name);
- class_simple_device_remove(MKDEV(USB_MAJOR, intf->minor));
+ class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor));
intf->class_dev = NULL;
intf->minor = -1;
}
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 266e9e06a9f..d041782e0c8 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -651,50 +651,45 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb)
/*-------------------------------------------------------------------------*/
/* exported only within usbcore */
-struct usb_bus *usb_bus_get (struct usb_bus *bus)
+struct usb_bus *usb_bus_get(struct usb_bus *bus)
{
- struct class_device *tmp;
+ if (bus)
+ kref_get(&bus->kref);
+ return bus;
+}
- if (!bus)
- return NULL;
+static void usb_host_release(struct kref *kref)
+{
+ struct usb_bus *bus = container_of(kref, struct usb_bus, kref);
- tmp = class_device_get(&bus->class_dev);
- if (tmp)
- return to_usb_bus(tmp);
- else
- return NULL;
+ if (bus->release)
+ bus->release(bus);
}
/* exported only within usbcore */
-void usb_bus_put (struct usb_bus *bus)
+void usb_bus_put(struct usb_bus *bus)
{
if (bus)
- class_device_put(&bus->class_dev);
+ kref_put(&bus->kref, usb_host_release);
}
/*-------------------------------------------------------------------------*/
-static void usb_host_release(struct class_device *class_dev)
-{
- struct usb_bus *bus = to_usb_bus(class_dev);
-
- if (bus->release)
- bus->release(bus);
-}
-
-static struct class usb_host_class = {
- .name = "usb_host",
- .release = &usb_host_release,
-};
+static struct class *usb_host_class;
int usb_host_init(void)
{
- return class_register(&usb_host_class);
+ int retval = 0;
+
+ usb_host_class = class_create(THIS_MODULE, "usb_host");
+ if (IS_ERR(usb_host_class))
+ retval = PTR_ERR(usb_host_class);
+ return retval;
}
void usb_host_cleanup(void)
{
- class_unregister(&usb_host_class);
+ class_destroy(usb_host_class);
}
/**
@@ -719,8 +714,7 @@ static void usb_bus_init (struct usb_bus *bus)
INIT_LIST_HEAD (&bus->bus_list);
- class_device_initialize(&bus->class_dev);
- bus->class_dev.class = &usb_host_class;
+ kref_init(&bus->kref);
}
/**
@@ -761,7 +755,6 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op)
static int usb_register_bus(struct usb_bus *bus)
{
int busnum;
- int retval;
down (&usb_bus_list_lock);
busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1);
@@ -774,15 +767,15 @@ static int usb_register_bus(struct usb_bus *bus)
return -E2BIG;
}
- snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
- bus->class_dev.dev = bus->controller;
- retval = class_device_add(&bus->class_dev);
- if (retval) {
+ bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum);
+ if (IS_ERR(bus->class_dev)) {
clear_bit(busnum, busmap.busmap);
up(&usb_bus_list_lock);
- return retval;
+ return PTR_ERR(bus->class_dev);
}
+ class_set_devdata(bus->class_dev, bus);
+
/* Add it to the local list of buses */
list_add (&bus->bus_list, &usb_bus_list);
up (&usb_bus_list_lock);
@@ -820,7 +813,7 @@ static void usb_deregister_bus (struct usb_bus *bus)
clear_bit (bus->busnum, busmap.busmap);
- class_device_del(&bus->class_dev);
+ class_device_unregister(bus->class_dev);
}
/**
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index ec9b3bde8ae..740cb4c668d 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -24,7 +24,7 @@
/* Active configuration fields */
#define usb_actconfig_show(field, multiplier, format_string) \
-static ssize_t show_##field (struct device *dev, char *buf) \
+static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
struct usb_host_config *actconfig; \
@@ -46,7 +46,7 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n")
usb_actconfig_attr (bmAttributes, 1, "%2x\n")
usb_actconfig_attr (bMaxPower, 2, "%3dmA\n")
-static ssize_t show_configuration_string(struct device *dev, char *buf)
+static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
struct usb_host_config *actconfig;
@@ -69,7 +69,7 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL);
usb_actconfig_show(bConfigurationValue, 1, "%u\n");
static ssize_t
-set_bConfigurationValue (struct device *dev, const char *buf, size_t count)
+set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
struct usb_device *udev = udev = to_usb_device (dev);
int config, value;
@@ -87,7 +87,7 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR,
/* String fields */
#define usb_string_attr(name) \
-static ssize_t show_##name(struct device *dev, char *buf) \
+static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
int len; \
@@ -107,7 +107,7 @@ usb_string_attr(manufacturer);
usb_string_attr(serial);
static ssize_t
-show_speed (struct device *dev, char *buf)
+show_speed (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
char *speed;
@@ -133,7 +133,7 @@ show_speed (struct device *dev, char *buf)
static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
static ssize_t
-show_devnum (struct device *dev, char *buf)
+show_devnum (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
@@ -143,7 +143,7 @@ show_devnum (struct device *dev, char *buf)
static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
static ssize_t
-show_version (struct device *dev, char *buf)
+show_version (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
u16 bcdUSB;
@@ -155,7 +155,7 @@ show_version (struct device *dev, char *buf)
static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
static ssize_t
-show_maxchild (struct device *dev, char *buf)
+show_maxchild (struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
@@ -167,7 +167,7 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
/* Descriptor fields */
#define usb_descriptor_attr_le16(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
\
@@ -183,7 +183,7 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n")
#define usb_descriptor_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_device *udev; \
\
@@ -254,7 +254,7 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev)
/* Interface fields */
#define usb_intf_attr(field, format_string) \
static ssize_t \
-show_##field (struct device *dev, char *buf) \
+show_##field (struct device *dev, struct device_attribute *attr, char *buf) \
{ \
struct usb_interface *intf = to_usb_interface (dev); \
\
@@ -269,7 +269,7 @@ usb_intf_attr (bInterfaceClass, "%02x\n")
usb_intf_attr (bInterfaceSubClass, "%02x\n")
usb_intf_attr (bInterfaceProtocol, "%02x\n")
-static ssize_t show_interface_string(struct device *dev, char *buf)
+static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_interface *intf;
struct usb_device *udev;
@@ -286,6 +286,37 @@ static ssize_t show_interface_string(struct device *dev, char *buf)
}
static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL);
+static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *intf;
+ struct usb_device *udev;
+ int len;
+
+ intf = to_usb_interface(dev);
+ udev = interface_to_usbdev(intf);
+
+ len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic",
+ le16_to_cpu(udev->descriptor.idVendor),
+ le16_to_cpu(udev->descriptor.idProduct),
+ le16_to_cpu(udev->descriptor.bcdDevice),
+ udev->descriptor.bDeviceClass,
+ udev->descriptor.bDeviceSubClass,
+ udev->descriptor.bDeviceProtocol);
+ buf += len;
+
+ if (udev->descriptor.bDeviceClass == 0) {
+ struct usb_host_interface *alt = intf->cur_altsetting;
+
+ return len + sprintf(buf, "%02Xisc%02Xip%02X\n",
+ alt->desc.bInterfaceClass,
+ alt->desc.bInterfaceSubClass,
+ alt->desc.bInterfaceProtocol);
+ } else {
+ return len + sprintf(buf, "*isc*ip*\n");
+ }
+}
+static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+
static struct attribute *intf_attrs[] = {
&dev_attr_bInterfaceNumber.attr,
&dev_attr_bAlternateSetting.attr,
@@ -293,6 +324,7 @@ static struct attribute *intf_attrs[] = {
&dev_attr_bInterfaceClass.attr,
&dev_attr_bInterfaceSubClass.attr,
&dev_attr_bInterfaceProtocol.attr,
+ &dev_attr_modalias.attr,
NULL,
};
static struct attribute_group intf_attr_grp = {
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 25cf7e9eccf..a3c42203213 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -293,7 +293,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
/* if interface was already added, bind now; else let
* the future device_add() bind it, bypassing probe()
*/
- if (!list_empty (&dev->bus_list))
+ if (klist_node_attached(&dev->knode_bus))
device_bind_driver(dev);
return 0;
@@ -322,9 +322,15 @@ void usb_driver_release_interface(struct usb_driver *driver,
if (!dev->driver || dev->driver != &driver->driver)
return;
- /* don't disconnect from disconnect(), or before dev_add() */
- if (!list_empty (&dev->driver_list) && !list_empty (&dev->bus_list))
+ /* don't release from within disconnect() */
+ if (iface->condition != USB_INTERFACE_BOUND)
+ return;
+
+ /* release only after device_add() */
+ if (klist_node_attached(&dev->knode_bus)) {
+ iface->condition = USB_INTERFACE_UNBINDING;
device_release_driver(dev);
+ }
dev->driver = NULL;
usb_set_intfdata(iface, NULL);
@@ -462,6 +468,25 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
return NULL;
}
+
+static int __find_interface(struct device * dev, void * data)
+{
+ struct usb_interface ** ret = (struct usb_interface **)data;
+ struct usb_interface * intf = *ret;
+ int *minor = (int *)data;
+
+ /* can't look at usb devices, only interfaces */
+ if (dev->driver == &usb_generic_driver)
+ return 0;
+
+ intf = to_usb_interface(dev);
+ if (intf->minor != -1 && intf->minor == *minor) {
+ *ret = intf;
+ return 1;
+ }
+ return 0;
+}
+
/**
* usb_find_interface - find usb_interface pointer for driver and device
* @drv: the driver whose current configuration is considered
@@ -473,26 +498,12 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id)
*/
struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor)
{
- struct list_head *entry;
- struct device *dev;
- struct usb_interface *intf;
+ struct usb_interface *intf = (struct usb_interface *)(long)minor;
+ int ret;
- list_for_each(entry, &drv->driver.devices) {
- dev = container_of(entry, struct device, driver_list);
-
- /* can't look at usb devices, only interfaces */
- if (dev->driver == &usb_generic_driver)
- continue;
-
- intf = to_usb_interface(dev);
- if (intf->minor == -1)
- continue;
- if (intf->minor == minor)
- return intf;
- }
+ ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface);
- /* no device found that matches */
- return NULL;
+ return ret ? intf : NULL;
}
static int usb_device_match (struct device *dev, struct device_driver *drv)