diff options
Diffstat (limited to 'drivers/message/i2o/driver.c')
| -rw-r--r-- | drivers/message/i2o/driver.c | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c index 0079a4be0af..1b18a0d1d05 100644 --- a/drivers/message/i2o/driver.c +++ b/drivers/message/i2o/driver.c @@ -17,6 +17,9 @@ #include <linux/module.h> #include <linux/rwsem.h> #include <linux/i2o.h> +#include <linux/workqueue.h> +#include <linux/string.h> +#include <linux/slab.h> #include "core.h" #define OSM_NAME "i2o" @@ -31,9 +34,7 @@ static spinlock_t i2o_drivers_lock; static struct i2o_driver **i2o_drivers; /** - * i2o_bus_match - Tell if a I2O device class id match the class ids of - * the I2O driver (OSM) - * + * i2o_bus_match - Tell if I2O device class id matches the class ids of the I2O driver (OSM) * @dev: device which should be verified * @drv: the driver to match against * @@ -58,12 +59,10 @@ static int i2o_bus_match(struct device *dev, struct device_driver *drv) }; /* I2O bus type */ -extern struct device_attribute i2o_device_attrs[]; - struct bus_type i2o_bus_type = { .name = "i2o", .match = i2o_bus_match, - .dev_attrs = i2o_device_attrs, + .dev_groups = i2o_device_groups, }; /** @@ -85,7 +84,8 @@ int i2o_driver_register(struct i2o_driver *drv) osm_debug("Register driver %s\n", drv->name); if (drv->event) { - drv->event_queue = create_workqueue(drv->name); + drv->event_queue = alloc_workqueue("%s", WQ_MEM_RECLAIM, 1, + drv->name); if (!drv->event_queue) { osm_err("Could not initialize event queue for driver " "%s\n", drv->name); @@ -105,7 +105,8 @@ int i2o_driver_register(struct i2o_driver *drv) osm_err("too many drivers registered, increase " "max_drivers\n"); spin_unlock_irqrestore(&i2o_drivers_lock, flags); - return -EFAULT; + rc = -EFAULT; + goto out; } drv->context = i; @@ -125,7 +126,14 @@ int i2o_driver_register(struct i2o_driver *drv) rc = driver_register(&drv->driver); if (rc) + goto out; + + return 0; +out: + if (drv->event_queue) { destroy_workqueue(drv->event_queue); + drv->event_queue = NULL; + } return rc; }; @@ -170,7 +178,6 @@ void i2o_driver_unregister(struct i2o_driver *drv) * i2o_driver_dispatch - dispatch an I2O reply message * @c: I2O controller of the message * @m: I2O message number - * @msg: I2O message to be delivered * * The reply is delivered to the driver from which the original message * was. This function is only called from interrupt context. @@ -216,14 +223,14 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) /* cut of header from message size (in 32-bit words) */ size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5; - evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO); + evt = kzalloc(size * 4 + sizeof(*evt), GFP_ATOMIC); if (!evt) return -ENOMEM; evt->size = size; evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt); evt->event_indicator = le32_to_cpu(msg->body[0]); - memcpy(&evt->tcntxt, &msg->u.s.tcntxt, size * 4); + memcpy(&evt->data, &msg->body[1], size * 4); list_for_each_entry_safe(dev, tmp, &c->devices, list) if (dev->lct_data.tid == tid) { @@ -231,7 +238,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) break; } - INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt); + INIT_WORK(&evt->work, drv->event); queue_work(drv->event_queue, &evt->work); return 1; } @@ -247,7 +254,7 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m) /** * i2o_driver_notify_controller_add_all - Send notify of added controller - * to all I2O drivers + * @c: newly added controller * * Send notifications to all registered drivers that a new controller was * added. @@ -257,7 +264,7 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -266,8 +273,8 @@ void i2o_driver_notify_controller_add_all(struct i2o_controller *c) } /** - * i2o_driver_notify_controller_remove_all - Send notify of removed - * controller to all I2O drivers + * i2o_driver_notify_controller_remove_all - Send notify of removed controller + * @c: controller that is being removed * * Send notifications to all registered drivers that a controller was * removed. @@ -277,7 +284,7 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -286,8 +293,8 @@ void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) } /** - * i2o_driver_notify_device_add_all - Send notify of added device to all - * I2O drivers + * i2o_driver_notify_device_add_all - Send notify of added device + * @i2o_dev: newly added I2O device * * Send notifications to all registered drivers that a device was added. */ @@ -296,7 +303,7 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -305,8 +312,8 @@ void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) } /** - * i2o_driver_notify_device_remove_all - Send notify of removed device to - * all I2O drivers + * i2o_driver_notify_device_remove_all - Send notify of removed device + * @i2o_dev: device that is being removed * * Send notifications to all registered drivers that a device was removed. */ @@ -315,7 +322,7 @@ void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev) int i; struct i2o_driver *drv; - for (i = 0; i < I2O_MAX_DRIVERS; i++) { + for (i = 0; i < i2o_max_drivers; i++) { drv = i2o_drivers[i]; if (drv) @@ -336,22 +343,18 @@ int __init i2o_driver_init(void) spin_lock_init(&i2o_drivers_lock); - if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) || - ((i2o_max_drivers ^ (i2o_max_drivers - 1)) != - (2 * i2o_max_drivers - 1))) { - osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and " - "a power of 2\n", i2o_max_drivers); + if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64)) { + osm_warn("max_drivers set to %d, but must be >=2 and <= 64\n", + i2o_max_drivers); i2o_max_drivers = I2O_MAX_DRIVERS; } osm_info("max drivers = %d\n", i2o_max_drivers); i2o_drivers = - kmalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL); + kcalloc(i2o_max_drivers, sizeof(*i2o_drivers), GFP_KERNEL); if (!i2o_drivers) return -ENOMEM; - memset(i2o_drivers, 0, i2o_max_drivers * sizeof(*i2o_drivers)); - rc = bus_register(&i2o_bus_type); if (rc < 0) @@ -363,9 +366,9 @@ int __init i2o_driver_init(void) /** * i2o_driver_exit - clean up I2O drivers (OSMs) * - * Unregisters the I2O bus and free driver array. + * Unregisters the I2O bus and frees driver array. */ -void __exit i2o_driver_exit(void) +void i2o_driver_exit(void) { bus_unregister(&i2o_bus_type); kfree(i2o_drivers); |
