Commit d51b5cb4 authored by Andrew Morton's avatar Andrew Morton Committed by James Bottomley

[PATCH] I2O: removes multiplexer notification and use

From: Markus Lidel <Markus.Lidel@shadowconnect.com>

- remove the multiplexer notification and replace it with a type-safe
  function for each event (controller add/remove, device add/remove).
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 6cdbe80e
...@@ -239,6 +239,8 @@ struct i2o_device *i2o_device_add(struct i2o_controller *c, ...@@ -239,6 +239,8 @@ struct i2o_device *i2o_device_add(struct i2o_controller *c,
class_device_register(&dev->classdev); class_device_register(&dev->classdev);
i2o_driver_notify_device_add_all(dev);
pr_debug("I2O device %s added\n", dev->device.bus_id); pr_debug("I2O device %s added\n", dev->device.bus_id);
return dev; return dev;
...@@ -254,6 +256,7 @@ struct i2o_device *i2o_device_add(struct i2o_controller *c, ...@@ -254,6 +256,7 @@ struct i2o_device *i2o_device_add(struct i2o_controller *c,
*/ */
void i2o_device_remove(struct i2o_device *i2o_dev) void i2o_device_remove(struct i2o_device *i2o_dev)
{ {
i2o_driver_notify_device_remove_all(i2o_dev);
class_device_unregister(&i2o_dev->classdev); class_device_unregister(&i2o_dev->classdev);
list_del(&i2o_dev->list); list_del(&i2o_dev->list);
device_unregister(&i2o_dev->device); device_unregister(&i2o_dev->device);
......
...@@ -110,8 +110,14 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -110,8 +110,14 @@ int i2o_driver_register(struct i2o_driver *drv)
pr_debug("driver %s gets context id %d\n", drv->name, drv->context); pr_debug("driver %s gets context id %d\n", drv->name, drv->context);
list_for_each_entry(c, &i2o_controllers, list) list_for_each_entry(c, &i2o_controllers, list) {
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_ADD, c); struct i2o_device *i2o_dev;
i2o_driver_notify_controller_add(drv, c);
list_for_each_entry(i2o_dev, &c->devices, list)
i2o_driver_notify_device_add(drv, i2o_dev);
}
rc = driver_register(&drv->driver); rc = driver_register(&drv->driver);
if (rc) if (rc)
...@@ -136,8 +142,14 @@ void i2o_driver_unregister(struct i2o_driver *drv) ...@@ -136,8 +142,14 @@ void i2o_driver_unregister(struct i2o_driver *drv)
driver_unregister(&drv->driver); driver_unregister(&drv->driver);
list_for_each_entry(c, &i2o_controllers, list) list_for_each_entry(c, &i2o_controllers, list) {
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE, c); struct i2o_device *i2o_dev;
list_for_each_entry(i2o_dev, &c->devices, list)
i2o_driver_notify_device_remove(drv, i2o_dev);
i2o_driver_notify_controller_remove(drv, c);
}
spin_lock_irqsave(&i2o_drivers_lock, flags); spin_lock_irqsave(&i2o_drivers_lock, flags);
i2o_drivers[drv->context] = NULL; i2o_drivers[drv->context] = NULL;
...@@ -228,11 +240,68 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m, ...@@ -228,11 +240,68 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
} }
/** /**
* i2o_driver_notify_all - Send notification to all I2O drivers * i2o_driver_notify_controller_add_all - Send notify of added controller
* to all I2O drivers
*
* Send notifications to all registered drivers that a new controller was
* added.
*/
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 ++) {
drv = i2o_drivers[i];
if(drv)
i2o_driver_notify_controller_add(drv, c);
}
}
/**
* i2o_driver_notify_controller_remove_all - Send notify of removed
* controller to all I2O drivers
*
* Send notifications to all registered drivers that a controller was
* removed.
*/
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 ++) {
drv = i2o_drivers[i];
if(drv)
i2o_driver_notify_controller_remove(drv, c);
}
}
/**
* i2o_driver_notify_device_add_all - Send notify of added device to all
* I2O drivers
*
* Send notifications to all registered drivers that a device was added.
*/
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 ++) {
drv = i2o_drivers[i];
if(drv)
i2o_driver_notify_device_add(drv, i2o_dev);
}
}
/**
* i2o_driver_notify_device_remove_all - Send notify of removed device to
* all I2O drivers
* *
* Send notifications to all registered drivers. * Send notifications to all registered drivers that a device was removed.
*/ */
void i2o_driver_notify_all(enum i2o_driver_notify evt, void *data) { void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev) {
int i; int i;
struct i2o_driver *drv; struct i2o_driver *drv;
...@@ -240,7 +309,7 @@ void i2o_driver_notify_all(enum i2o_driver_notify evt, void *data) { ...@@ -240,7 +309,7 @@ void i2o_driver_notify_all(enum i2o_driver_notify evt, void *data) {
drv = i2o_drivers[i]; drv = i2o_drivers[i];
if(drv) if(drv)
i2o_driver_notify(drv, evt, data); i2o_driver_notify_device_remove(drv, i2o_dev);
} }
} }
...@@ -292,4 +361,7 @@ void __exit i2o_driver_exit(void) ...@@ -292,4 +361,7 @@ void __exit i2o_driver_exit(void)
EXPORT_SYMBOL(i2o_driver_register); EXPORT_SYMBOL(i2o_driver_register);
EXPORT_SYMBOL(i2o_driver_unregister); EXPORT_SYMBOL(i2o_driver_unregister);
EXPORT_SYMBOL(i2o_driver_notify_all); EXPORT_SYMBOL(i2o_driver_notify_controller_add_all);
EXPORT_SYMBOL(i2o_driver_notify_controller_remove_all);
EXPORT_SYMBOL(i2o_driver_notify_device_add_all);
EXPORT_SYMBOL(i2o_driver_notify_device_remove_all);
...@@ -496,56 +496,58 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, ...@@ -496,56 +496,58 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
}; };
/** /**
* i2o_scsi_notify - Retrieve notifications of controller added or removed * i2o_scsi_notify_controller_add - Retrieve notifications of added
* @notify: the notification event which occurs * controllers
* @data: pointer to additional data * @c: the controller which was added
* *
* If a I2O controller is added, we catch the notification to add a * If a I2O controller is added, we catch the notification to add a
* corresponding Scsi_Host. On removal also remove the Scsi_Host. * corresponding Scsi_Host.
*/ */
void i2o_scsi_notify(enum i2o_driver_notify notify, void *data) void i2o_scsi_notify_controller_add(struct i2o_controller *c)
{ {
struct i2o_controller *c = data;
struct i2o_scsi_host *i2o_shost; struct i2o_scsi_host *i2o_shost;
int rc; int rc;
switch (notify) { i2o_shost = i2o_scsi_host_alloc(c);
case I2O_DRIVER_NOTIFY_CONTROLLER_ADD: if (IS_ERR(i2o_shost)) {
i2o_shost = i2o_scsi_host_alloc(c); printk(KERN_ERR "scsi-osm: Could not initialize"
if (IS_ERR(i2o_shost)) { " SCSI host\n");
printk(KERN_ERR "scsi-osm: Could not initialize" return;
" SCSI host\n"); }
return;
}
rc = scsi_add_host(i2o_shost->scsi_host, &c->device);
if (rc) {
printk(KERN_ERR "scsi-osm: Could not add SCSI "
"host\n");
scsi_host_put(i2o_shost->scsi_host);
return;
}
c->driver_data[i2o_scsi_driver.context] = i2o_shost; rc = scsi_add_host(i2o_shost->scsi_host, &c->device);
if (rc) {
printk(KERN_ERR "scsi-osm: Could not add SCSI "
"host\n");
scsi_host_put(i2o_shost->scsi_host);
return;
}
pr_debug("new I2O SCSI host added\n"); c->driver_data[i2o_scsi_driver.context] = i2o_shost;
break;
case I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE: pr_debug("new I2O SCSI host added\n");
i2o_shost = i2o_scsi_get_host(c); };
if (!i2o_shost)
return;
c->driver_data[i2o_scsi_driver.context] = NULL; /**
* i2o_scsi_notify_controller_remove - Retrieve notifications of removed
* controllers
* @c: the controller which was removed
*
* If a I2O controller is removed, we catch the notification to remove the
* corresponding Scsi_Host.
*/
void i2o_scsi_notify_controller_remove(struct i2o_controller *c)
{
struct i2o_scsi_host *i2o_shost;
i2o_shost = i2o_scsi_get_host(c);
if (!i2o_shost)
return;
scsi_remove_host(i2o_shost->scsi_host); c->driver_data[i2o_scsi_driver.context] = NULL;
scsi_host_put(i2o_shost->scsi_host);
pr_debug("I2O SCSI host removed\n");
break;
default: scsi_remove_host(i2o_shost->scsi_host);
break; scsi_host_put(i2o_shost->scsi_host);
} pr_debug("I2O SCSI host removed\n");
}; };
/* SCSI OSM driver struct */ /* SCSI OSM driver struct */
...@@ -553,7 +555,8 @@ static struct i2o_driver i2o_scsi_driver = { ...@@ -553,7 +555,8 @@ static struct i2o_driver i2o_scsi_driver = {
.name = "scsi-osm", .name = "scsi-osm",
.reply = i2o_scsi_reply, .reply = i2o_scsi_reply,
.classes = i2o_scsi_class_id, .classes = i2o_scsi_class_id,
.notify = i2o_scsi_notify, .notify_controller_add = i2o_scsi_notify_controller_add,
.notify_controller_remove = i2o_scsi_notify_controller_remove,
.driver = { .driver = {
.probe = i2o_scsi_probe, .probe = i2o_scsi_probe,
.remove = i2o_scsi_remove, .remove = i2o_scsi_remove,
......
...@@ -815,7 +815,7 @@ void i2o_iop_remove(struct i2o_controller *c) ...@@ -815,7 +815,7 @@ void i2o_iop_remove(struct i2o_controller *c)
pr_debug("Deleting controller %s\n", c->name); pr_debug("Deleting controller %s\n", c->name);
i2o_driver_notify_all(I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE, c); i2o_driver_notify_controller_remove_all(c);
list_del(&c->list); list_del(&c->list);
...@@ -1133,7 +1133,7 @@ int i2o_iop_add(struct i2o_controller *c) ...@@ -1133,7 +1133,7 @@ int i2o_iop_add(struct i2o_controller *c)
list_add(&c->list, &i2o_controllers); list_add(&c->list, &i2o_controllers);
i2o_driver_notify_all(I2O_DRIVER_NOTIFY_CONTROLLER_ADD, c); i2o_driver_notify_controller_add_all(c);
printk(KERN_INFO "%s: Controller added\n", c->name); printk(KERN_INFO "%s: Controller added\n", c->name);
......
...@@ -33,11 +33,6 @@ ...@@ -33,11 +33,6 @@
/* message queue empty */ /* message queue empty */
#define I2O_QUEUE_EMPTY 0xffffffff #define I2O_QUEUE_EMPTY 0xffffffff
enum i2o_driver_notify {
I2O_DRIVER_NOTIFY_CONTROLLER_ADD = 0,
I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE = 1,
};
/* /*
* Message structures * Message structures
*/ */
...@@ -115,7 +110,10 @@ struct i2o_driver { ...@@ -115,7 +110,10 @@ struct i2o_driver {
struct device_driver driver; struct device_driver driver;
/* notification of changes */ /* notification of changes */
void (*notify) (enum i2o_driver_notify, void *); void (*notify_controller_add) (struct i2o_controller *);
void (*notify_controller_remove) (struct i2o_controller *);
void (*notify_device_add) (struct i2o_device *);
void (*notify_device_remove) (struct i2o_device *);
struct semaphore lock; struct semaphore lock;
}; };
...@@ -325,18 +323,61 @@ extern int i2o_driver_register(struct i2o_driver *); ...@@ -325,18 +323,61 @@ extern int i2o_driver_register(struct i2o_driver *);
extern void i2o_driver_unregister(struct i2o_driver *); extern void i2o_driver_unregister(struct i2o_driver *);
/** /**
* i2o_driver_notify - Send notification to a single I2O drivers * i2o_driver_notify_controller_add - Send notification of added controller
* to a single I2O driver
* *
* Send notifications to a single registered driver. * Send notification of added controller to a single registered driver.
*/ */
static inline void i2o_driver_notify(struct i2o_driver *drv, static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv,
enum i2o_driver_notify notify, void *data) struct i2o_controller *c)
{ {
if (drv->notify) if (drv->notify_controller_add)
drv->notify(notify, data); drv->notify_controller_add(c);
} };
/**
* i2o_driver_notify_controller_remove - Send notification of removed
* controller to a single I2O driver
*
* Send notification of removed controller to a single registered driver.
*/
static inline void i2o_driver_notify_controller_remove(struct i2o_driver *drv,
struct i2o_controller *c)
{
if (drv->notify_controller_remove)
drv->notify_controller_remove(c);
};
/**
* i2o_driver_notify_device_add - Send notification of added device to a
* single I2O driver
*
* Send notification of added device to a single registered driver.
*/
static inline void i2o_driver_notify_device_add(struct i2o_driver *drv,
struct i2o_device *i2o_dev)
{
if (drv->notify_device_add)
drv->notify_device_add(i2o_dev);
};
/**
* i2o_driver_notify_device_remove - Send notification of removed device
* to a single I2O driver
*
* Send notification of removed device to a single registered driver.
*/
static inline void i2o_driver_notify_device_remove(struct i2o_driver *drv,
struct i2o_device *i2o_dev)
{
if (drv->notify_device_remove)
drv->notify_device_remove(i2o_dev);
};
extern void i2o_driver_notify_all(enum i2o_driver_notify, void *); extern void i2o_driver_notify_controller_add_all(struct i2o_controller *);
extern void i2o_driver_notify_controller_remove_all(struct i2o_controller *);
extern void i2o_driver_notify_device_add_all(struct i2o_device *);
extern void i2o_driver_notify_device_remove_all(struct i2o_device *);
/* I2O device functions */ /* I2O device functions */
extern int i2o_device_claim(struct i2o_device *); extern int i2o_device_claim(struct i2o_device *);
......
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