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,
class_device_register(&dev->classdev);
i2o_driver_notify_device_add_all(dev);
pr_debug("I2O device %s added\n", dev->device.bus_id);
return dev;
......@@ -254,6 +256,7 @@ struct i2o_device *i2o_device_add(struct i2o_controller *c,
*/
void i2o_device_remove(struct i2o_device *i2o_dev)
{
i2o_driver_notify_device_remove_all(i2o_dev);
class_device_unregister(&i2o_dev->classdev);
list_del(&i2o_dev->list);
device_unregister(&i2o_dev->device);
......
......@@ -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);
list_for_each_entry(c, &i2o_controllers, list)
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_ADD, c);
list_for_each_entry(c, &i2o_controllers, list) {
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);
if (rc)
......@@ -136,8 +142,14 @@ void i2o_driver_unregister(struct i2o_driver *drv)
driver_unregister(&drv->driver);
list_for_each_entry(c, &i2o_controllers, list)
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE, c);
list_for_each_entry(c, &i2o_controllers, list) {
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);
i2o_drivers[drv->context] = NULL;
......@@ -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;
struct i2o_driver *drv;
......@@ -240,7 +309,7 @@ void i2o_driver_notify_all(enum i2o_driver_notify evt, void *data) {
drv = i2o_drivers[i];
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)
EXPORT_SYMBOL(i2o_driver_register);
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,
};
/**
* i2o_scsi_notify - Retrieve notifications of controller added or removed
* @notify: the notification event which occurs
* @data: pointer to additional data
* i2o_scsi_notify_controller_add - Retrieve notifications of added
* controllers
* @c: the controller which was added
*
* 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;
int rc;
switch (notify) {
case I2O_DRIVER_NOTIFY_CONTROLLER_ADD:
i2o_shost = i2o_scsi_host_alloc(c);
if (IS_ERR(i2o_shost)) {
printk(KERN_ERR "scsi-osm: Could not initialize"
" 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;
}
i2o_shost = i2o_scsi_host_alloc(c);
if (IS_ERR(i2o_shost)) {
printk(KERN_ERR "scsi-osm: Could not initialize"
" SCSI host\n");
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");
break;
c->driver_data[i2o_scsi_driver.context] = i2o_shost;
case I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE:
i2o_shost = i2o_scsi_get_host(c);
if (!i2o_shost)
return;
pr_debug("new I2O SCSI host added\n");
};
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);
scsi_host_put(i2o_shost->scsi_host);
pr_debug("I2O SCSI host removed\n");
break;
c->driver_data[i2o_scsi_driver.context] = NULL;
default:
break;
}
scsi_remove_host(i2o_shost->scsi_host);
scsi_host_put(i2o_shost->scsi_host);
pr_debug("I2O SCSI host removed\n");
};
/* SCSI OSM driver struct */
......@@ -553,7 +555,8 @@ static struct i2o_driver i2o_scsi_driver = {
.name = "scsi-osm",
.reply = i2o_scsi_reply,
.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 = {
.probe = i2o_scsi_probe,
.remove = i2o_scsi_remove,
......
......@@ -815,7 +815,7 @@ void i2o_iop_remove(struct i2o_controller *c)
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);
......@@ -1133,7 +1133,7 @@ int i2o_iop_add(struct i2o_controller *c)
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);
......
......@@ -33,11 +33,6 @@
/* message queue empty */
#define I2O_QUEUE_EMPTY 0xffffffff
enum i2o_driver_notify {
I2O_DRIVER_NOTIFY_CONTROLLER_ADD = 0,
I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE = 1,
};
/*
* Message structures
*/
......@@ -115,7 +110,10 @@ struct i2o_driver {
struct device_driver driver;
/* 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;
};
......@@ -325,18 +323,61 @@ extern int i2o_driver_register(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,
enum i2o_driver_notify notify, void *data)
static inline void i2o_driver_notify_controller_add(struct i2o_driver *drv,
struct i2o_controller *c)
{
if (drv->notify)
drv->notify(notify, data);
}
if (drv->notify_controller_add)
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 */
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