Commit 8137f0c9 authored by Patrick Mochel's avatar Patrick Mochel

Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-driverfs-test
parents 322bdbf7 789e39b0
...@@ -165,9 +165,9 @@ Note that there is a struct attribute embedded in the structure. In ...@@ -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 order to relieve pain in declaring attributes, the subsystem should
also define a macro, like: 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 = { \ struct device_attribute dev_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \ .attr = {.name = __stringify(_name) , .mode = _mode }, \
.show = _show, \ .show = _show, \
.store = _store, \ .store = _store, \
}; };
...@@ -252,7 +252,7 @@ struct bus_attribute { ...@@ -252,7 +252,7 @@ struct bus_attribute {
Declaring: Declaring:
BUS_ATTR(_name,_str,_mode,_show,_store) BUS_ATTR(_name,_mode,_show,_store)
Creation/Removal: Creation/Removal:
...@@ -273,7 +273,7 @@ struct driver_attribute { ...@@ -273,7 +273,7 @@ struct driver_attribute {
Declaring: Declaring:
DRIVER_ATTR(_name,_str,_mode,_show,_store) DRIVER_ATTR(_name,_mode,_show,_store)
Creation/Removal: Creation/Removal:
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
extern struct device device_root; extern struct device device_root;
extern spinlock_t device_lock; extern spinlock_t device_lock;
extern struct device * get_device_locked(struct device *);
extern int bus_add_device(struct device * dev); extern int bus_add_device(struct device * dev);
extern void bus_remove_device(struct device * dev); extern void bus_remove_device(struct device * dev);
......
...@@ -16,6 +16,9 @@ ...@@ -16,6 +16,9 @@
static LIST_HEAD(bus_driver_list); 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_for_each_dev - walk list of devices and do something to each
* @bus: bus in question * @bus: bus in question
...@@ -26,42 +29,41 @@ static LIST_HEAD(bus_driver_list); ...@@ -26,42 +29,41 @@ static LIST_HEAD(bus_driver_list);
* counting on devices as we touch each one. * counting on devices as we touch each one.
* *
* Algorithm: * Algorithm:
* Take the bus lock and get the first node in the list. We increment * Take device_lock and get the first node in the list.
* the reference count and unlock the bus. If we have a device from a * Try and increment the reference count on it. If we can't, it's in the
* previous iteration, we decrement the reference count. * process of being removed, but that process hasn't acquired device_lock.
* After we call the callback, we get the next node in the list and loop. * It's still in the list, so we grab the next node and try that one.
* At the end, if @dev is not null, we still have it pinned, so we need * We drop the lock to call the callback.
* to let it go. * 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 bus_for_each_dev(struct bus_type * bus, void * data,
int (*callback)(struct device * dev, void * data)) int (*callback)(struct device * dev, void * data))
{ {
struct device * next;
struct device * dev = NULL;
struct list_head * node; struct list_head * node;
struct device * prev = NULL;
int error = 0; int error = 0;
get_bus(bus); get_bus(bus);
read_lock(&bus->lock); spin_lock(&device_lock);
node = bus->devices.next; list_for_each(node,&bus->devices) {
while (node != &bus->devices) { struct device * dev = get_device_locked(to_dev(node));
next = list_entry(node,struct device,bus_list); if (dev) {
get_device(next); spin_unlock(&device_lock);
read_unlock(&bus->lock); error = callback(dev,data);
if (prev)
if (dev) put_device(prev);
put_device(dev); prev = dev;
dev = next; spin_lock(&device_lock);
if ((error = callback(dev,data))) { if (error)
put_device(dev);
break; break;
} }
read_lock(&bus->lock);
node = dev->bus_list.next;
} }
read_unlock(&bus->lock); spin_unlock(&device_lock);
if (dev) if (prev)
put_device(dev); put_device(prev);
put_bus(bus); put_bus(bus);
return error; return error;
} }
...@@ -69,34 +71,30 @@ int bus_for_each_dev(struct bus_type * bus, void * data, ...@@ -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 bus_for_each_drv(struct bus_type * bus, void * data,
int (*callback)(struct device_driver * drv, void * data)) int (*callback)(struct device_driver * drv, void * data))
{ {
struct device_driver * next;
struct device_driver * drv = NULL;
struct list_head * node; struct list_head * node;
struct device_driver * prev = NULL;
int error = 0; int error = 0;
/* pin bus in memory */ /* pin bus in memory */
get_bus(bus); get_bus(bus);
read_lock(&bus->lock); spin_lock(&device_lock);
node = bus->drivers.next; list_for_each(node,&bus->drivers) {
while (node != &bus->drivers) { struct device_driver * drv = get_driver(to_drv(node));
next = list_entry(node,struct device_driver,bus_list); if (drv) {
get_driver(next); spin_unlock(&device_lock);
read_unlock(&bus->lock); error = callback(drv,data);
if (prev)
if (drv) put_driver(prev);
put_driver(drv); prev = drv;
drv = next; spin_lock(&device_lock);
if ((error = callback(drv,data))) { if (error)
put_driver(drv);
break; break;
} }
read_lock(&bus->lock);
node = drv->bus_list.next;
} }
read_unlock(&bus->lock); spin_unlock(&device_lock);
if (drv) if (prev)
put_driver(drv); put_driver(prev);
put_bus(bus); put_bus(bus);
return error; return error;
} }
...@@ -115,9 +113,9 @@ int bus_add_device(struct device * dev) ...@@ -115,9 +113,9 @@ int bus_add_device(struct device * dev)
if (dev->bus) { if (dev->bus) {
pr_debug("registering %s with bus '%s'\n",dev->bus_id,dev->bus->name); pr_debug("registering %s with bus '%s'\n",dev->bus_id,dev->bus->name);
get_bus(dev->bus); get_bus(dev->bus);
write_lock(&dev->bus->lock); spin_lock(&device_lock);
list_add_tail(&dev->bus_list,&dev->bus->devices); list_add_tail(&dev->bus_list,&dev->bus->devices);
write_unlock(&dev->bus->lock); spin_unlock(&device_lock);
device_bus_link(dev); device_bus_link(dev);
} }
return 0; return 0;
...@@ -134,9 +132,6 @@ void bus_remove_device(struct device * dev) ...@@ -134,9 +132,6 @@ void bus_remove_device(struct device * dev)
{ {
if (dev->bus) { if (dev->bus) {
device_remove_symlink(&dev->bus->device_dir,dev->bus_id); 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); put_bus(dev->bus);
} }
} }
......
...@@ -25,6 +25,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL; ...@@ -25,6 +25,8 @@ int (*platform_notify_remove)(struct device * dev) = NULL;
spinlock_t device_lock = SPIN_LOCK_UNLOCKED; 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 * found_match - do actual binding of device to driver
...@@ -53,9 +55,9 @@ static int found_match(struct device * dev, struct device_driver * drv) ...@@ -53,9 +55,9 @@ static int found_match(struct device * dev, struct device_driver * drv)
pr_debug("bound device '%s' to driver '%s'\n", pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id,drv->name); dev->bus_id,drv->name);
write_lock(&drv->lock); spin_lock(&device_lock);
list_add_tail(&dev->driver_list,&drv->devices); list_add_tail(&dev->driver_list,&drv->devices);
write_unlock(&drv->lock); spin_unlock(&device_lock);
goto Done; goto Done;
...@@ -101,14 +103,10 @@ static void device_detach(struct device * dev) ...@@ -101,14 +103,10 @@ static void device_detach(struct device * dev)
struct device_driver * drv; struct device_driver * drv;
if (dev->driver) { if (dev->driver) {
lock_device(dev); spin_lock(&device_lock);
drv = dev->driver; drv = dev->driver;
dev->driver = NULL; dev->driver = NULL;
unlock_device(dev); spin_unlock(&device_lock);
write_lock(&drv->lock);
list_del_init(&dev->driver_list);
write_unlock(&drv->lock);
/* detach from driver */ /* detach from driver */
if (drv->remove) if (drv->remove)
...@@ -136,45 +134,37 @@ int driver_attach(struct device_driver * drv) ...@@ -136,45 +134,37 @@ int driver_attach(struct device_driver * drv)
static int do_driver_detach(struct device * dev, struct device_driver * drv) static int do_driver_detach(struct device * dev, struct device_driver * drv)
{ {
lock_device(dev); spin_lock(&device_lock);
if (dev->driver == drv) { if (dev->driver == drv) {
dev->driver = NULL; dev->driver = NULL;
unlock_device(dev); spin_unlock(&device_lock);
if (drv->remove) if (drv->remove)
drv->remove(dev); drv->remove(dev);
} else } else
unlock_device(dev); spin_unlock(&device_lock);
return 0; return 0;
} }
void driver_detach(struct device_driver * drv) void driver_detach(struct device_driver * drv)
{ {
struct device * next;
struct device * dev = NULL;
struct list_head * node; 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) spin_lock(&device_lock);
put_device(dev); list_for_each(node,&drv->devices) {
dev = next; struct device * dev = get_device_locked(to_dev(node));
if ((error = do_driver_detach(dev,drv))) { if (dev) {
put_device(dev); list_del_init(node);
break; spin_unlock(&device_lock);
do_driver_detach(dev,drv);
if (prev)
put_device(prev);
prev = dev;
spin_lock(&device_lock);
} }
write_lock(&drv->lock);
node = drv->devices.next;
} }
write_unlock(&drv->lock); spin_unlock(&device_lock);
if (dev)
put_device(dev);
} }
/** /**
...@@ -191,7 +181,6 @@ void driver_detach(struct device_driver * drv) ...@@ -191,7 +181,6 @@ void driver_detach(struct device_driver * drv)
int device_register(struct device *dev) int device_register(struct device *dev)
{ {
int error; int error;
struct device *prev_dev;
if (!dev || !strlen(dev->bus_id)) if (!dev || !strlen(dev->bus_id))
return -EINVAL; return -EINVAL;
...@@ -199,24 +188,21 @@ int device_register(struct device *dev) ...@@ -199,24 +188,21 @@ int device_register(struct device *dev)
INIT_LIST_HEAD(&dev->node); INIT_LIST_HEAD(&dev->node);
INIT_LIST_HEAD(&dev->children); INIT_LIST_HEAD(&dev->children);
INIT_LIST_HEAD(&dev->g_list); INIT_LIST_HEAD(&dev->g_list);
INIT_LIST_HEAD(&dev->driver_list);
INIT_LIST_HEAD(&dev->bus_list);
spin_lock_init(&dev->lock); spin_lock_init(&dev->lock);
atomic_set(&dev->refcount,2); atomic_set(&dev->refcount,2);
spin_lock(&device_lock);
if (dev != &device_root) { if (dev != &device_root) {
if (!dev->parent) if (!dev->parent)
dev->parent = &device_root; dev->parent = &device_root;
get_device(dev->parent); get_device(dev->parent);
if (list_empty(&dev->parent->children)) spin_lock(&device_lock);
prev_dev = dev->parent; list_add_tail(&dev->g_list,&dev->parent->g_list);
else
prev_dev = list_entry(dev->parent->children.prev, struct device, node);
list_add(&dev->g_list, &prev_dev->g_list);
list_add_tail(&dev->node,&dev->parent->children); 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", pr_debug("DEV: registering device: ID = '%s', name = %s\n",
dev->bus_id, dev->name); dev->bus_id, dev->name);
...@@ -234,12 +220,37 @@ int device_register(struct device *dev) ...@@ -234,12 +220,37 @@ int device_register(struct device *dev)
platform_notify(dev); platform_notify(dev);
register_done: register_done:
put_device(dev); if (error) {
if (error && dev->parent) 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->parent);
}
put_device(dev);
return error; 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 * put_device - decrement reference count, and clean up when it hits 0
* @dev: device in question * @dev: device in question
...@@ -250,6 +261,8 @@ void put_device(struct device * dev) ...@@ -250,6 +261,8 @@ void put_device(struct device * dev)
return; return;
list_del_init(&dev->node); list_del_init(&dev->node);
list_del_init(&dev->g_list); list_del_init(&dev->g_list);
list_del_init(&dev->bus_list);
list_del_init(&dev->driver_list);
spin_unlock(&device_lock); spin_unlock(&device_lock);
pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n", pr_debug("DEV: Unregistering device. ID = '%s', name = '%s'\n",
...@@ -296,4 +309,5 @@ static int __init device_init(void) ...@@ -296,4 +309,5 @@ static int __init device_init(void)
core_initcall(device_init); core_initcall(device_init);
EXPORT_SYMBOL(device_register); EXPORT_SYMBOL(device_register);
EXPORT_SYMBOL(get_device);
EXPORT_SYMBOL(put_device); EXPORT_SYMBOL(put_device);
...@@ -10,35 +10,31 @@ ...@@ -10,35 +10,31 @@
#include <linux/errno.h> #include <linux/errno.h>
#include "base.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 list_head * node;
struct device * prev = NULL;
int error = 0; int error = 0;
get_driver(drv); get_driver(drv);
read_lock(&drv->lock); spin_lock(&device_lock);
node = drv->devices.next; list_for_each(node,&drv->devices) {
while (node != &drv->devices) { struct device * dev = get_device_locked(to_dev(node));
next = list_entry(node,struct device,driver_list); if (dev) {
get_device(next); spin_unlock(&device_lock);
read_unlock(&drv->lock); error = callback(dev,data);
if (prev)
if (dev) put_device(prev);
put_device(dev); prev = dev;
dev = next; spin_lock(&device_lock);
if ((error = callback(dev,data))) { if (error)
put_device(dev);
break; break;
} }
read_lock(&drv->lock);
node = dev->driver_list.next;
} }
read_unlock(&drv->lock); spin_unlock(&device_lock);
if (dev)
put_device(dev);
put_driver(drv); put_driver(drv);
return error; return error;
} }
...@@ -60,9 +56,9 @@ int driver_register(struct device_driver * drv) ...@@ -60,9 +56,9 @@ int driver_register(struct device_driver * drv)
atomic_set(&drv->refcount,2); atomic_set(&drv->refcount,2);
rwlock_init(&drv->lock); rwlock_init(&drv->lock);
INIT_LIST_HEAD(&drv->devices); INIT_LIST_HEAD(&drv->devices);
write_lock(&drv->bus->lock); spin_lock(&device_lock);
list_add(&drv->bus_list,&drv->bus->drivers); list_add(&drv->bus_list,&drv->bus->drivers);
write_unlock(&drv->bus->lock); spin_unlock(&device_lock);
driver_make_dir(drv); driver_make_dir(drv);
driver_attach(drv); driver_attach(drv);
put_driver(drv); put_driver(drv);
...@@ -81,10 +77,10 @@ static void __remove_driver(struct device_driver * drv) ...@@ -81,10 +77,10 @@ static void __remove_driver(struct device_driver * drv)
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); atomic_set(&drv->refcount,0);
list_del_init(&drv->bus_list); list_del_init(&drv->bus_list);
write_unlock(&drv->bus->lock); spin_unlock(&device_lock);
__remove_driver(drv); __remove_driver(drv);
} }
...@@ -94,13 +90,10 @@ void remove_driver(struct device_driver * drv) ...@@ -94,13 +90,10 @@ void remove_driver(struct device_driver * drv)
*/ */
void put_driver(struct device_driver * drv) void put_driver(struct device_driver * drv)
{ {
write_lock(&drv->bus->lock); if (!atomic_dec_and_lock(&drv->refcount,&device_lock))
if (!atomic_dec_and_test(&drv->refcount)) {
write_unlock(&drv->bus->lock);
return; return;
}
list_del_init(&drv->bus_list); list_del_init(&drv->bus_list);
write_unlock(&drv->bus->lock); spin_unlock(&device_lock);
__remove_driver(drv); __remove_driver(drv);
} }
......
...@@ -14,7 +14,7 @@ static ssize_t device_read_name(struct device * dev, char * buf, size_t count, l ...@@ -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); 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 static ssize_t
device_read_power(struct device * dev, char * page, size_t count, loff_t off) 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 ...@@ -85,7 +85,7 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
return error < 0 ? error : count; 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); device_read_power,device_write_power);
struct device_attribute * device_default_files[] = { struct device_attribute * device_default_files[] = {
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include <linux/module.h> #include <linux/module.h>
#include "base.h" #include "base.h"
#define to_dev(node) container_of(node,struct device,g_list)
/** /**
* device_suspend - suspend all devices on the device tree * device_suspend - suspend all devices on the device tree
* @state: state we're entering * @state: state we're entering
...@@ -25,30 +27,26 @@ ...@@ -25,30 +27,26 @@
*/ */
int device_suspend(u32 state, u32 level) int device_suspend(u32 state, u32 level)
{ {
struct device * dev; struct list_head * node;
struct device * prev = &device_root; struct device * prev = NULL;
int error = 0; int error = 0;
printk(KERN_EMERG "Suspending Devices\n"); printk(KERN_EMERG "Suspending Devices\n");
get_device(prev);
spin_lock(&device_lock); spin_lock(&device_lock);
dev = g_list_to_dev(prev->g_list.next); list_for_each(node,&device_root.g_list) {
while(dev != &device_root && !error) { struct device * dev = get_device_locked(dev);
get_device(dev); if (dev) {
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
if (dev->driver && dev->driver->suspend) if (dev->driver && dev->driver->suspend)
error = dev->driver->suspend(dev,state,level); error = dev->driver->suspend(dev,state,level);
if (prev)
spin_lock(&device_lock); put_device(prev);
prev = dev; prev = dev;
dev = g_list_to_dev(prev->g_list.next); spin_lock(&device_lock);
}
} }
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
return error; return error;
} }
...@@ -63,27 +61,23 @@ int device_suspend(u32 state, u32 level) ...@@ -63,27 +61,23 @@ int device_suspend(u32 state, u32 level)
*/ */
void device_resume(u32 level) void device_resume(u32 level)
{ {
struct device * dev; struct list_head * node;
struct device * prev = &device_root; struct device * prev = NULL;
get_device(prev);
spin_lock(&device_lock); spin_lock(&device_lock);
dev = g_list_to_dev(prev->g_list.prev); list_for_each_prev(node,&device_root.g_list) {
while(dev != &device_root) { struct device * dev = get_device_locked(to_dev(node));
get_device(dev); if (dev) {
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
if (dev->driver && dev->driver->resume) if (dev->driver && dev->driver->resume)
dev->driver->resume(dev,level); dev->driver->resume(dev,level);
if (prev)
spin_lock(&device_lock); put_device(prev);
prev = dev; prev = dev;
dev = g_list_to_dev(prev->g_list.prev); spin_lock(&device_lock);
}
} }
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
printk(KERN_EMERG "Devices Resumed\n"); printk(KERN_EMERG "Devices Resumed\n");
} }
...@@ -98,29 +92,25 @@ void device_resume(u32 level) ...@@ -98,29 +92,25 @@ void device_resume(u32 level)
*/ */
void device_shutdown(void) void device_shutdown(void)
{ {
struct device * dev; struct list_head * node;
struct device * prev = &device_root; struct device * prev = NULL;
printk(KERN_EMERG "Shutting down devices\n"); printk(KERN_EMERG "Shutting down devices\n");
get_device(prev);
spin_lock(&device_lock); spin_lock(&device_lock);
dev = g_list_to_dev(prev->g_list.next); list_for_each(node,&device_root.g_list) {
while(dev != &device_root) { struct device * dev = get_device_locked(to_dev(node));
get_device(dev); if (dev) {
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
if (dev->driver && dev->driver->remove) if (dev->driver && dev->driver->remove)
dev->driver->remove(dev); dev->driver->remove(dev);
if (prev)
spin_lock(&device_lock); put_device(prev);
prev = dev; prev = dev;
dev = g_list_to_dev(prev->g_list.next); spin_lock(&device_lock);
}
} }
spin_unlock(&device_lock); spin_unlock(&device_lock);
put_device(prev);
} }
EXPORT_SYMBOL(device_suspend); EXPORT_SYMBOL(device_suspend);
......
...@@ -378,7 +378,7 @@ static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_ ...@@ -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); 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) 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, ...@@ -402,7 +402,7 @@ static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count,
return (str - buf); 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) int pci_proc_attach_device(struct pci_dev *dev)
{ {
......
...@@ -305,7 +305,7 @@ static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page, ...@@ -305,7 +305,7 @@ static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page,
return 0; 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 */ /* end content handlers */
......
...@@ -1401,14 +1401,14 @@ static ssize_t sg_device_kdev_read(struct device *driverfs_dev, char *page, ...@@ -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); Sg_device * sdp=list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
return off ? 0 : sprintf(page, "%x\n",sdp->i_rdev.value); 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, static ssize_t sg_device_type_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off) size_t count, loff_t off)
{ {
return off ? 0 : sprintf (page, "CHR\n"); 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) static int sg_attach(Scsi_Device * scsidp)
{ {
......
...@@ -737,14 +737,14 @@ static ssize_t sr_device_kdev_read(struct device *driverfs_dev, ...@@ -737,14 +737,14 @@ static ssize_t sr_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)(long)driverfs_dev->driver_data; kdev.value=(int)(long)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value); 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, static ssize_t sr_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off) char *page, size_t count, loff_t off)
{ {
return off ? 0 : sprintf (page, "CHR\n"); 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() void sr_finish()
......
...@@ -3533,14 +3533,14 @@ static ssize_t st_device_kdev_read(struct device *driverfs_dev, ...@@ -3533,14 +3533,14 @@ static ssize_t st_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)(long)driverfs_dev->driver_data; kdev.value=(int)(long)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value); 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, static ssize_t st_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off) char *page, size_t count, loff_t off)
{ {
return off ? 0 : sprintf (page, "CHR\n"); 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 = static struct file_operations st_fops =
......
...@@ -836,7 +836,7 @@ show_config (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -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); 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 /* interfaces have one current setting; alternates
* can have different endpoints and class info. * can have different endpoints and class info.
...@@ -851,7 +851,7 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -851,7 +851,7 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
interface = to_usb_interface (dev); interface = to_usb_interface (dev);
return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting); 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 */ /* product driverfs file */
static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off) 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 ...@@ -870,7 +870,7 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t
buf[len+1] = 0; buf[len+1] = 0;
return len+1; 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 */ /* manufacturer driverfs file */
static ssize_t static ssize_t
...@@ -890,7 +890,7 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -890,7 +890,7 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
buf[len+1] = 0; buf[len+1] = 0;
return len+1; 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 */ /* serial number driverfs file */
static ssize_t static ssize_t
...@@ -910,7 +910,7 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -910,7 +910,7 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off)
buf[len+1] = 0; buf[len+1] = 0;
return len+1; 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. * This entrypoint gets called for each new device.
...@@ -1440,7 +1440,7 @@ int usb_new_device(struct usb_device *dev) ...@@ -1440,7 +1440,7 @@ int usb_new_device(struct usb_device *dev)
err = device_register (&dev->dev); err = device_register (&dev->dev);
if (err) if (err)
return err; return err;
device_create_file (&dev->dev, &dev_attr_config); device_create_file (&dev->dev, &dev_attr_configuration);
if (dev->descriptor.iManufacturer) if (dev->descriptor.iManufacturer)
device_create_file (&dev->dev, &dev_attr_manufacturer); device_create_file (&dev->dev, &dev_attr_manufacturer);
if (dev->descriptor.iProduct) if (dev->descriptor.iProduct)
......
...@@ -164,14 +164,14 @@ static ssize_t partition_device_kdev_read(struct device *driverfs_dev, ...@@ -164,14 +164,14 @@ static ssize_t partition_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)(long)driverfs_dev->driver_data; kdev.value=(int)(long)driverfs_dev->driver_data;
return off ? 0 : sprintf (page, "%x\n",kdev.value); 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, static ssize_t partition_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off) char *page, size_t count, loff_t off)
{ {
return off ? 0 : sprintf (page, "BLK\n"); 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) void driverfs_create_partitions(struct gendisk *hd, int minor)
{ {
......
...@@ -93,9 +93,9 @@ struct bus_attribute { ...@@ -93,9 +93,9 @@ struct bus_attribute {
ssize_t (*store)(struct bus_type *, const char * buf, size_t count, loff_t off); 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 = { \ struct bus_attribute bus_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \ .show = _show, \
.store = _store, \ .store = _store, \
}; };
...@@ -150,9 +150,9 @@ struct driver_attribute { ...@@ -150,9 +150,9 @@ struct driver_attribute {
ssize_t (*store)(struct device_driver *, const char * buf, size_t count, loff_t off); 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 = { \ struct driver_attribute driver_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \ .show = _show, \
.store = _store, \ .store = _store, \
}; };
...@@ -222,13 +222,14 @@ struct device_attribute { ...@@ -222,13 +222,14 @@ struct device_attribute {
ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off); 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 = { \ struct device_attribute dev_attr_##_name = { \
.attr = {.name = _str, .mode = _mode }, \ .attr = {.name = __stringify(_name), .mode = _mode }, \
.show = _show, \ .show = _show, \
.store = _store, \ .store = _store, \
}; };
extern int device_create_file(struct device *device, struct device_attribute * entry); extern int device_create_file(struct device *device, struct device_attribute * entry);
extern void device_remove_file(struct device * dev, struct device_attribute * attr); extern void device_remove_file(struct device * dev, struct device_attribute * attr);
...@@ -260,12 +261,7 @@ static inline void unlock_device(struct device * dev) ...@@ -260,12 +261,7 @@ static inline void unlock_device(struct device * dev)
* get_device - atomically increment the reference count for the device. * get_device - atomically increment the reference count for the device.
* *
*/ */
static inline void get_device(struct device * dev) extern struct device * get_device(struct device * dev);
{
BUG_ON(!atomic_read(&dev->refcount));
atomic_inc(&dev->refcount);
}
extern void put_device(struct device * dev); extern void put_device(struct device * dev);
/* drivers/base/sys.c */ /* drivers/base/sys.c */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment