diff options
| -rw-r--r-- | Documentation/filesystems/driverfs.txt | 8 | ||||
| -rw-r--r-- | drivers/base/base.h | 2 | ||||
| -rw-r--r-- | drivers/base/bus.c | 97 | ||||
| -rw-r--r-- | drivers/base/core.c | 112 | ||||
| -rw-r--r-- | drivers/base/driver.c | 53 | ||||
| -rw-r--r-- | drivers/base/interface.c | 4 | ||||
| -rw-r--r-- | drivers/base/power.c | 92 | ||||
| -rw-r--r-- | drivers/pci/proc.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/scsi_scan.c | 2 | ||||
| -rw-r--r-- | drivers/scsi/sg.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/sr.c | 4 | ||||
| -rw-r--r-- | drivers/scsi/st.c | 4 | ||||
| -rw-r--r-- | drivers/usb/core/usb.c | 12 | ||||
| -rw-r--r-- | fs/partitions/check.c | 4 | ||||
| -rw-r--r-- | include/linux/device.h | 20 |
15 files changed, 199 insertions, 223 deletions
diff --git a/Documentation/filesystems/driverfs.txt b/Documentation/filesystems/driverfs.txt index 8ae574fab1c9..15dedc22a8ba 100644 --- a/Documentation/filesystems/driverfs.txt +++ b/Documentation/filesystems/driverfs.txt @@ -165,9 +165,9 @@ Note that there is a struct attribute embedded in the structure. In order to relieve pain in declaring attributes, the subsystem should also define a macro, like: -#define DEVICE_ATTR(_name,_str,_mode,_show,_store) \ +#define DEVICE_ATTR(_name,_mode,_show,_store) \ struct device_attribute dev_attr_##_name = { \ - .attr = {.name = _str, .mode = _mode }, \ + .attr = {.name = __stringify(_name) , .mode = _mode }, \ .show = _show, \ .store = _store, \ }; @@ -252,7 +252,7 @@ struct bus_attribute { Declaring: -BUS_ATTR(_name,_str,_mode,_show,_store) +BUS_ATTR(_name,_mode,_show,_store) Creation/Removal: @@ -273,7 +273,7 @@ struct driver_attribute { Declaring: -DRIVER_ATTR(_name,_str,_mode,_show,_store) +DRIVER_ATTR(_name,_mode,_show,_store) Creation/Removal: diff --git a/drivers/base/base.h b/drivers/base/base.h index c2a1f9b1e9af..2ba238eba033 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -9,6 +9,8 @@ extern struct device device_root; extern spinlock_t device_lock; +extern struct device * get_device_locked(struct device *); + extern int bus_add_device(struct device * dev); extern void bus_remove_device(struct device * dev); diff --git a/drivers/base/bus.c b/drivers/base/bus.c index e85af605a07f..7daffbfd9913 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -16,6 +16,9 @@ static LIST_HEAD(bus_driver_list); +#define to_dev(node) container_of(node,struct device,bus_list) +#define to_drv(node) container_of(node,struct device_driver,bus_list) + /** * bus_for_each_dev - walk list of devices and do something to each * @bus: bus in question @@ -26,42 +29,41 @@ static LIST_HEAD(bus_driver_list); * counting on devices as we touch each one. * * Algorithm: - * Take the bus lock and get the first node in the list. We increment - * the reference count and unlock the bus. If we have a device from a - * previous iteration, we decrement the reference count. - * After we call the callback, we get the next node in the list and loop. - * At the end, if @dev is not null, we still have it pinned, so we need - * to let it go. + * Take device_lock and get the first node in the list. + * Try and increment the reference count on it. If we can't, it's in the + * process of being removed, but that process hasn't acquired device_lock. + * It's still in the list, so we grab the next node and try that one. + * We drop the lock to call the callback. + * We can't decrement the reference count yet, because we need the next + * node in the list. So, we set @prev to point to the current device. + * On the next go-round, we decrement the reference count on @prev, so if + * it's being removed, it won't affect us. */ int bus_for_each_dev(struct bus_type * bus, void * data, int (*callback)(struct device * dev, void * data)) { - struct device * next; - struct device * dev = NULL; struct list_head * node; + struct device * prev = NULL; int error = 0; get_bus(bus); - read_lock(&bus->lock); - node = bus->devices.next; - while (node != &bus->devices) { - next = list_entry(node,struct device,bus_list); - get_device(next); - read_unlock(&bus->lock); - - if (dev) - put_device(dev); - dev = next; - if ((error = callback(dev,data))) { - put_device(dev); - break; + spin_lock(&device_lock); + list_for_each(node,&bus->devices) { + struct device * dev = get_device_locked(to_dev(node)); + if (dev) { + spin_unlock(&device_lock); + error = callback(dev,data); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); + if (error) + break; } - read_lock(&bus->lock); - node = dev->bus_list.next; } - read_unlock(&bus->lock); - if (dev) - put_device(dev); + spin_unlock(&device_lock); + if (prev) + put_device(prev); put_bus(bus); return error; } @@ -69,34 +71,30 @@ int bus_for_each_dev(struct bus_type * bus, void * data, int bus_for_each_drv(struct bus_type * bus, void * data, int (*callback)(struct device_driver * drv, void * data)) { - struct device_driver * next; - struct device_driver * drv = NULL; struct list_head * node; + struct device_driver * prev = NULL; int error = 0; /* pin bus in memory */ get_bus(bus); - read_lock(&bus->lock); - node = bus->drivers.next; - while (node != &bus->drivers) { - next = list_entry(node,struct device_driver,bus_list); - get_driver(next); - read_unlock(&bus->lock); - - if (drv) - put_driver(drv); - drv = next; - if ((error = callback(drv,data))) { - put_driver(drv); - break; + spin_lock(&device_lock); + list_for_each(node,&bus->drivers) { + struct device_driver * drv = get_driver(to_drv(node)); + if (drv) { + spin_unlock(&device_lock); + error = callback(drv,data); + if (prev) + put_driver(prev); + prev = drv; + spin_lock(&device_lock); + if (error) + break; } - read_lock(&bus->lock); - node = drv->bus_list.next; } - read_unlock(&bus->lock); - if (drv) - put_driver(drv); + spin_unlock(&device_lock); + if (prev) + put_driver(prev); put_bus(bus); return error; } @@ -115,9 +113,9 @@ int bus_add_device(struct device * dev) if (dev->bus) { pr_debug("registering %s with bus '%s'\n",dev->bus_id,dev->bus->name); get_bus(dev->bus); - write_lock(&dev->bus->lock); + spin_lock(&device_lock); list_add_tail(&dev->bus_list,&dev->bus->devices); - write_unlock(&dev->bus->lock); + spin_unlock(&device_lock); device_bus_link(dev); } return 0; @@ -134,9 +132,6 @@ void bus_remove_device(struct device * dev) { if (dev->bus) { device_remove_symlink(&dev->bus->device_dir,dev->bus_id); - write_lock(&dev->bus->lock); - list_del_init(&dev->bus_list); - write_unlock(&dev->bus->lock); put_bus(dev->bus); } } diff --git a/drivers/base/core.c b/drivers/base/core.c index 9d04145d5ac2..246a00a1cc18 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -25,6 +25,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL; spinlock_t device_lock = SPIN_LOCK_UNLOCKED; +#define to_dev(node) container_of(node,struct device,driver_list) + /** * found_match - do actual binding of device to driver @@ -53,9 +55,9 @@ static int found_match(struct device * dev, struct device_driver * drv) pr_debug("bound device '%s' to driver '%s'\n", dev->bus_id,drv->name); - write_lock(&drv->lock); + spin_lock(&device_lock); list_add_tail(&dev->driver_list,&drv->devices); - write_unlock(&drv->lock); + spin_unlock(&device_lock); goto Done; @@ -101,19 +103,14 @@ static void device_detach(struct device * dev) struct device_driver * drv; if (dev->driver) { - lock_device(dev); + spin_lock(&device_lock); drv = dev->driver; dev->driver = NULL; - unlock_device(dev); - - write_lock(&drv->lock); - list_del_init(&dev->driver_list); - write_unlock(&drv->lock); + spin_unlock(&device_lock); /* detach from driver */ - if (drv->remove) + if (drv && drv->remove) drv->remove(dev); - put_driver(drv); } } @@ -134,47 +131,26 @@ int driver_attach(struct device_driver * drv) return bus_for_each_dev(drv->bus,drv,do_driver_attach); } -static int do_driver_detach(struct device * dev, struct device_driver * drv) -{ - lock_device(dev); - if (dev->driver == drv) { - dev->driver = NULL; - unlock_device(dev); - if (drv->remove) - drv->remove(dev); - } else - unlock_device(dev); - return 0; -} - void driver_detach(struct device_driver * drv) { - struct device * next; - struct device * dev = NULL; struct list_head * node; - int error = 0; + struct device * prev = NULL; - write_lock(&drv->lock); - node = drv->devices.next; - while (node != &drv->devices) { - next = list_entry(node,struct device,driver_list); - get_device(next); - list_del_init(&next->driver_list); - write_unlock(&drv->lock); - - if (dev) - put_device(dev); - dev = next; - if ((error = do_driver_detach(dev,drv))) { - put_device(dev); - break; + spin_lock(&device_lock); + list_for_each(node,&drv->devices) { + struct device * dev = get_device_locked(to_dev(node)); + if (dev) { + if (prev) + list_del_init(&prev->driver_list); + spin_unlock(&device_lock); + device_detach(dev); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); } - write_lock(&drv->lock); - node = drv->devices.next; } - write_unlock(&drv->lock); - if (dev) - put_device(dev); + spin_unlock(&device_lock); } /** @@ -191,7 +167,6 @@ void driver_detach(struct device_driver * drv) int device_register(struct device *dev) { int error; - struct device *prev_dev; if (!dev || !strlen(dev->bus_id)) return -EINVAL; @@ -199,24 +174,21 @@ int device_register(struct device *dev) INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->children); INIT_LIST_HEAD(&dev->g_list); + INIT_LIST_HEAD(&dev->driver_list); + INIT_LIST_HEAD(&dev->bus_list); spin_lock_init(&dev->lock); atomic_set(&dev->refcount,2); - spin_lock(&device_lock); if (dev != &device_root) { if (!dev->parent) dev->parent = &device_root; get_device(dev->parent); - if (list_empty(&dev->parent->children)) - prev_dev = dev->parent; - else - prev_dev = list_entry(dev->parent->children.prev, struct device, node); - list_add(&dev->g_list, &prev_dev->g_list); - + spin_lock(&device_lock); + list_add_tail(&dev->g_list,&dev->parent->g_list); list_add_tail(&dev->node,&dev->parent->children); + spin_unlock(&device_lock); } - spin_unlock(&device_lock); pr_debug("DEV: registering device: ID = '%s', name = %s\n", dev->bus_id, dev->name); @@ -234,12 +206,37 @@ int device_register(struct device *dev) platform_notify(dev); register_done: + if (error) { + spin_lock(&device_lock); + list_del_init(&dev->g_list); + list_del_init(&dev->node); + spin_unlock(&device_lock); + if (dev->parent) + put_device(dev->parent); + } put_device(dev); - if (error && dev->parent) - put_device(dev->parent); return error; } +struct device * get_device_locked(struct device * dev) +{ + struct device * ret = dev; + if (dev && atomic_read(&dev->refcount) > 0) + atomic_inc(&dev->refcount); + else + ret = NULL; + return ret; +} + +struct device * get_device(struct device * dev) +{ + struct device * ret; + spin_lock(&device_lock); + ret = get_device_locked(dev); + spin_unlock(&device_lock); + return ret; +} + /** * put_device - decrement reference count, and clean up when it hits 0 * @dev: device in question @@ -250,6 +247,8 @@ void put_device(struct device * dev) return; list_del_init(&dev->node); list_del_init(&dev->g_list); + list_del_init(&dev->bus_list); + list_del_init(&dev->driver_list); spin_unlock(&device_lock); pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n", @@ -296,4 +295,5 @@ static int __init device_init(void) core_initcall(device_init); EXPORT_SYMBOL(device_register); +EXPORT_SYMBOL(get_device); EXPORT_SYMBOL(put_device); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 2b4aa02a0683..221e525736bd 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -10,35 +10,31 @@ #include <linux/errno.h> #include "base.h" +#define to_dev(node) container_of(node,struct device,driver_list) -int driver_for_each_dev(struct device_driver * drv, void * data, int (*callback)(struct device *, void * )) +int driver_for_each_dev(struct device_driver * drv, void * data, + int (*callback)(struct device *, void * )) { - struct device * next; - struct device * dev = NULL; struct list_head * node; + struct device * prev = NULL; int error = 0; get_driver(drv); - read_lock(&drv->lock); - node = drv->devices.next; - while (node != &drv->devices) { - next = list_entry(node,struct device,driver_list); - get_device(next); - read_unlock(&drv->lock); - - if (dev) - put_device(dev); - dev = next; - if ((error = callback(dev,data))) { - put_device(dev); - break; + spin_lock(&device_lock); + list_for_each(node,&drv->devices) { + struct device * dev = get_device_locked(to_dev(node)); + if (dev) { + spin_unlock(&device_lock); + error = callback(dev,data); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); + if (error) + break; } - read_lock(&drv->lock); - node = dev->driver_list.next; } - read_unlock(&drv->lock); - if (dev) - put_device(dev); + spin_unlock(&device_lock); put_driver(drv); return error; } @@ -60,9 +56,9 @@ int driver_register(struct device_driver * drv) atomic_set(&drv->refcount,2); rwlock_init(&drv->lock); INIT_LIST_HEAD(&drv->devices); - write_lock(&drv->bus->lock); + spin_lock(&device_lock); list_add(&drv->bus_list,&drv->bus->drivers); - write_unlock(&drv->bus->lock); + spin_unlock(&device_lock); driver_make_dir(drv); driver_attach(drv); put_driver(drv); @@ -81,10 +77,10 @@ static void __remove_driver(struct device_driver * drv) void remove_driver(struct device_driver * drv) { - write_lock(&drv->bus->lock); + spin_lock(&device_lock); atomic_set(&drv->refcount,0); list_del_init(&drv->bus_list); - write_unlock(&drv->bus->lock); + spin_unlock(&device_lock); __remove_driver(drv); } @@ -94,13 +90,10 @@ void remove_driver(struct device_driver * drv) */ void put_driver(struct device_driver * drv) { - write_lock(&drv->bus->lock); - if (!atomic_dec_and_test(&drv->refcount)) { - write_unlock(&drv->bus->lock); + if (!atomic_dec_and_lock(&drv->refcount,&device_lock)) return; - } list_del_init(&drv->bus_list); - write_unlock(&drv->bus->lock); + spin_unlock(&device_lock); __remove_driver(drv); } diff --git a/drivers/base/interface.c b/drivers/base/interface.c index 7c1f2fb94de2..a585b729c5c4 100644 --- a/drivers/base/interface.c +++ b/drivers/base/interface.c @@ -14,7 +14,7 @@ static ssize_t device_read_name(struct device * dev, char * buf, size_t count, l return off ? 0 : sprintf(buf,"%s\n",dev->name); } -static DEVICE_ATTR(name,"name",S_IRUGO,device_read_name,NULL); +static DEVICE_ATTR(name,S_IRUGO,device_read_name,NULL); static ssize_t device_read_power(struct device * dev, char * page, size_t count, loff_t off) @@ -85,7 +85,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o return error < 0 ? error : count; } -static DEVICE_ATTR(power,"power",S_IWUSR | S_IRUGO, +static DEVICE_ATTR(power,S_IWUSR | S_IRUGO, device_read_power,device_write_power); struct device_attribute * device_default_files[] = { diff --git a/drivers/base/power.c b/drivers/base/power.c index f916cb838b30..cc48f96cf353 100644 --- a/drivers/base/power.c +++ b/drivers/base/power.c @@ -14,6 +14,8 @@ #include <linux/module.h> #include "base.h" +#define to_dev(node) container_of(node,struct device,g_list) + /** * device_suspend - suspend all devices on the device tree * @state: state we're entering @@ -25,30 +27,26 @@ */ int device_suspend(u32 state, u32 level) { - struct device * dev; - struct device * prev = &device_root; + struct list_head * node; + struct device * prev = NULL; int error = 0; printk(KERN_EMERG "Suspending Devices\n"); - get_device(prev); - spin_lock(&device_lock); - dev = g_list_to_dev(prev->g_list.next); - while(dev != &device_root && !error) { - get_device(dev); - spin_unlock(&device_lock); - put_device(prev); - - if (dev->driver && dev->driver->suspend) - error = dev->driver->suspend(dev,state,level); - - spin_lock(&device_lock); - prev = dev; - dev = g_list_to_dev(prev->g_list.next); + list_for_each(node,&device_root.g_list) { + struct device * dev = get_device_locked(dev); + if (dev) { + spin_unlock(&device_lock); + if (dev->driver && dev->driver->suspend) + error = dev->driver->suspend(dev,state,level); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); + } } spin_unlock(&device_lock); - put_device(prev); return error; } @@ -63,27 +61,23 @@ int device_suspend(u32 state, u32 level) */ void device_resume(u32 level) { - struct device * dev; - struct device * prev = &device_root; - - get_device(prev); + struct list_head * node; + struct device * prev = NULL; spin_lock(&device_lock); - dev = g_list_to_dev(prev->g_list.prev); - while(dev != &device_root) { - get_device(dev); - spin_unlock(&device_lock); - put_device(prev); - - if (dev->driver && dev->driver->resume) - dev->driver->resume(dev,level); - - spin_lock(&device_lock); - prev = dev; - dev = g_list_to_dev(prev->g_list.prev); + list_for_each_prev(node,&device_root.g_list) { + struct device * dev = get_device_locked(to_dev(node)); + if (dev) { + spin_unlock(&device_lock); + if (dev->driver && dev->driver->resume) + dev->driver->resume(dev,level); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); + } } spin_unlock(&device_lock); - put_device(prev); printk(KERN_EMERG "Devices Resumed\n"); } @@ -98,29 +92,25 @@ void device_resume(u32 level) */ void device_shutdown(void) { - struct device * dev; - struct device * prev = &device_root; + struct list_head * node; + struct device * prev = NULL; printk(KERN_EMERG "Shutting down devices\n"); - get_device(prev); - spin_lock(&device_lock); - dev = g_list_to_dev(prev->g_list.next); - while(dev != &device_root) { - get_device(dev); - spin_unlock(&device_lock); - put_device(prev); - - if (dev->driver && dev->driver->remove) - dev->driver->remove(dev); - - spin_lock(&device_lock); - prev = dev; - dev = g_list_to_dev(prev->g_list.next); + list_for_each(node,&device_root.g_list) { + struct device * dev = get_device_locked(to_dev(node)); + if (dev) { + spin_unlock(&device_lock); + if (dev->driver && dev->driver->remove) + dev->driver->remove(dev); + if (prev) + put_device(prev); + prev = dev; + spin_lock(&device_lock); + } } spin_unlock(&device_lock); - put_device(prev); } EXPORT_SYMBOL(device_suspend); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 7dd1a28b3435..67c7e1feb732 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -378,7 +378,7 @@ static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_ return off ? 0 : sprintf(buf,"%u\n",pci_dev->irq); } -static DEVICE_ATTR(irq,"irq",S_IRUGO,pci_show_irq,NULL); +static DEVICE_ATTR(irq,S_IRUGO,pci_show_irq,NULL); static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count, loff_t off) { @@ -402,7 +402,7 @@ static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count, return (str - buf); } -static DEVICE_ATTR(resource,"resource",S_IRUGO,pci_show_resources,NULL); +static DEVICE_ATTR(resource,S_IRUGO,pci_show_resources,NULL); int pci_proc_attach_device(struct pci_dev *dev) { diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index bd6d234c886e..6f8f019111b1 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -305,7 +305,7 @@ static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page, return 0; } -static DEVICE_ATTR(type,"type",S_IRUGO,scsi_device_type_read,NULL); +static DEVICE_ATTR(type,S_IRUGO,scsi_device_type_read,NULL); /* end content handlers */ diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index e53ea226c1f6..5c9b42f9da21 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -1401,14 +1401,14 @@ static ssize_t sg_device_kdev_read(struct device *driverfs_dev, char *page, Sg_device * sdp=list_entry(driverfs_dev, Sg_device, sg_driverfs_dev); return off ? 0 : sprintf(page, "%x\n",sdp->i_rdev.value); } -static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sg_device_kdev_read,NULL); +static DEVICE_ATTR(kdev,S_IRUGO,sg_device_kdev_read,NULL); static ssize_t sg_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) { return off ? 0 : sprintf (page, "CHR\n"); } -static DEVICE_ATTR(type,"type",S_IRUGO,sg_device_type_read,NULL); +static DEVICE_ATTR(type,S_IRUGO,sg_device_type_read,NULL); static int sg_attach(Scsi_Device * scsidp) { diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 1d527d6f9096..6be5cdac0797 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -737,14 +737,14 @@ static ssize_t sr_device_kdev_read(struct device *driverfs_dev, kdev.value=(int)(long)driverfs_dev->driver_data; return off ? 0 : sprintf(page, "%x\n",kdev.value); } -static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sr_device_kdev_read,NULL); +static DEVICE_ATTR(kdev,S_IRUGO,sr_device_kdev_read,NULL); static ssize_t sr_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) { return off ? 0 : sprintf (page, "CHR\n"); } -static DEVICE_ATTR(type,"type",S_IRUGO,sr_device_type_read,NULL); +static DEVICE_ATTR(type,S_IRUGO,sr_device_type_read,NULL); void sr_finish() diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index b84bcc5378b2..eff9e16feee4 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -3533,14 +3533,14 @@ static ssize_t st_device_kdev_read(struct device *driverfs_dev, kdev.value=(int)(long)driverfs_dev->driver_data; return off ? 0 : sprintf(page, "%x\n",kdev.value); } -static DEVICE_ATTR(kdev,"kdev",S_IRUGO,st_device_kdev_read,NULL); +static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL); static ssize_t st_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) { return off ? 0 : sprintf (page, "CHR\n"); } -static DEVICE_ATTR(type,"type",S_IRUGO,st_device_type_read,NULL); +static DEVICE_ATTR(type,S_IRUGO,st_device_type_read,NULL); static struct file_operations st_fops = diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 32e30d296316..22aaddd711d9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -836,7 +836,7 @@ show_config (struct device *dev, char *buf, size_t count, loff_t off) return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue); } -static DEVICE_ATTR(config,"configuration",S_IRUGO,show_config,NULL); +static DEVICE_ATTR(configuration,S_IRUGO,show_config,NULL); /* interfaces have one current setting; alternates * can have different endpoints and class info. @@ -851,7 +851,7 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off) interface = to_usb_interface (dev); return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting); } -static DEVICE_ATTR(altsetting,"altsetting",S_IRUGO,show_altsetting,NULL); +static DEVICE_ATTR(altsetting,S_IRUGO,show_altsetting,NULL); /* product driverfs file */ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off) @@ -870,7 +870,7 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t buf[len+1] = 0; return len+1; } -static DEVICE_ATTR(product,"product",S_IRUGO,show_product,NULL); +static DEVICE_ATTR(product,S_IRUGO,show_product,NULL); /* manufacturer driverfs file */ static ssize_t @@ -890,7 +890,7 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off) buf[len+1] = 0; return len+1; } -static DEVICE_ATTR(manufacturer,"manufacturer",S_IRUGO,show_manufacturer,NULL); +static DEVICE_ATTR(manufacturer,S_IRUGO,show_manufacturer,NULL); /* serial number driverfs file */ static ssize_t @@ -910,7 +910,7 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off) buf[len+1] = 0; return len+1; } -static DEVICE_ATTR(serial,"serial",S_IRUGO,show_serial,NULL); +static DEVICE_ATTR(serial,S_IRUGO,show_serial,NULL); /* * This entrypoint gets called for each new device. @@ -1440,7 +1440,7 @@ int usb_new_device(struct usb_device *dev) err = device_register (&dev->dev); if (err) return err; - device_create_file (&dev->dev, &dev_attr_config); + device_create_file (&dev->dev, &dev_attr_configuration); if (dev->descriptor.iManufacturer) device_create_file (&dev->dev, &dev_attr_manufacturer); if (dev->descriptor.iProduct) diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 4cab6f920e2b..2ad9f95cb157 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -164,14 +164,14 @@ static ssize_t partition_device_kdev_read(struct device *driverfs_dev, kdev.value=(int)(long)driverfs_dev->driver_data; return off ? 0 : sprintf (page, "%x\n",kdev.value); } -static DEVICE_ATTR(kdev,"kdev",S_IRUGO,partition_device_kdev_read,NULL); +static DEVICE_ATTR(kdev,S_IRUGO,partition_device_kdev_read,NULL); static ssize_t partition_device_type_read(struct device *driverfs_dev, char *page, size_t count, loff_t off) { return off ? 0 : sprintf (page, "BLK\n"); } -static DEVICE_ATTR(type,"type",S_IRUGO,partition_device_type_read,NULL); +static DEVICE_ATTR(type,S_IRUGO,partition_device_type_read,NULL); void driverfs_create_partitions(struct gendisk *hd, int minor) { diff --git a/include/linux/device.h b/include/linux/device.h index 9706d94ff7b6..c33eae266026 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -93,9 +93,9 @@ struct bus_attribute { ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off); }; -#define BUS_ATTR(_name,_str,_mode,_show,_store) \ +#define BUS_ATTR(_name,_mode,_show,_store) \ struct bus_attribute bus_attr_##_name = { \ - .attr = {.name = _str, .mode = _mode }, \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; @@ -150,9 +150,9 @@ struct driver_attribute { ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off); }; -#define DRIVER_ATTR(_name,_str,_mode,_show,_store) \ +#define DRIVER_ATTR(_name,_mode,_show,_store) \ struct driver_attribute driver_attr_##_name = { \ - .attr = {.name = _str, .mode = _mode }, \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; @@ -222,13 +222,14 @@ struct device_attribute { ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); }; -#define DEVICE_ATTR(_name,_str,_mode,_show,_store) \ +#define DEVICE_ATTR(_name,_mode,_show,_store) \ struct device_attribute dev_attr_##_name = { \ - .attr = {.name = _str, .mode = _mode }, \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ .show = _show, \ .store = _store, \ }; + extern int device_create_file(struct device *device, struct device_attribute * entry); extern void device_remove_file(struct device * dev, struct device_attribute * attr); @@ -260,12 +261,7 @@ static inline void unlock_device(struct device * dev) * get_device - atomically increment the reference count for the device. * */ -static inline void get_device(struct device * dev) -{ - BUG_ON(!atomic_read(&dev->refcount)); - atomic_inc(&dev->refcount); -} - +extern struct device * get_device(struct device * dev); extern void put_device(struct device * dev); /* drivers/base/sys.c */ |
