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

[PATCH] I2O: remove on-demand allocation of Scsi_Host's in

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

- New notification system for i2o_driver's which get now a notification if a
  I2O controller is added or removed.

- SCSI-OSM now uses notifications to create the Scsi_Host to the
  corresponding I2O controller.

- Use __scsi_add_device to preset hostdata.
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ff8da0ac
...@@ -72,6 +72,7 @@ struct bus_type i2o_bus_type = { ...@@ -72,6 +72,7 @@ struct bus_type i2o_bus_type = {
*/ */
int i2o_driver_register(struct i2o_driver *drv) int i2o_driver_register(struct i2o_driver *drv)
{ {
struct i2o_controller *c;
int i; int i;
int rc = 0; int rc = 0;
unsigned long flags; unsigned long flags;
...@@ -109,6 +110,9 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -109,6 +110,9 @@ 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)
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_ADD, c);
rc = driver_register(&drv->driver); rc = driver_register(&drv->driver);
if (rc) if (rc)
destroy_workqueue(drv->event_queue); destroy_workqueue(drv->event_queue);
...@@ -125,12 +129,16 @@ int i2o_driver_register(struct i2o_driver *drv) ...@@ -125,12 +129,16 @@ int i2o_driver_register(struct i2o_driver *drv)
*/ */
void i2o_driver_unregister(struct i2o_driver *drv) void i2o_driver_unregister(struct i2o_driver *drv)
{ {
struct i2o_controller *c;
unsigned long flags; unsigned long flags;
pr_debug("unregister driver %s\n", drv->name); pr_debug("unregister driver %s\n", drv->name);
driver_unregister(&drv->driver); driver_unregister(&drv->driver);
list_for_each_entry(c, &i2o_controllers, list)
i2o_driver_notify(drv, I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE, 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;
spin_unlock_irqrestore(&i2o_drivers_lock, flags); spin_unlock_irqrestore(&i2o_drivers_lock, flags);
...@@ -219,6 +227,23 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m, ...@@ -219,6 +227,23 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
return -EIO; return -EIO;
} }
/**
* i2o_driver_notify_all - Send notification to all I2O drivers
*
* Send notifications to all registered drivers.
*/
void i2o_driver_notify_all(enum i2o_driver_notify evt, void *data) {
int i;
struct i2o_driver *drv;
for(i = 0; i < I2O_MAX_DRIVERS; i ++) {
drv = i2o_drivers[i];
if(drv)
i2o_driver_notify(drv, evt, data);
}
}
/** /**
* i2o_driver_init - initialize I2O drivers (OSMs) * i2o_driver_init - initialize I2O drivers (OSMs)
* *
...@@ -267,3 +292,4 @@ void __exit i2o_driver_exit(void) ...@@ -267,3 +292,4 @@ 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);
...@@ -67,13 +67,12 @@ ...@@ -67,13 +67,12 @@
#define VERSION_STRING "Version 0.1.2" #define VERSION_STRING "Version 0.1.2"
static struct i2o_driver i2o_scsi_driver;
static int i2o_scsi_max_id = 16; static int i2o_scsi_max_id = 16;
static int i2o_scsi_max_lun = 8; static int i2o_scsi_max_lun = 8;
static LIST_HEAD(i2o_scsi_hosts);
struct i2o_scsi_host { struct i2o_scsi_host {
struct list_head list; /* node in in i2o_scsi_hosts */
struct Scsi_Host *scsi_host; /* pointer to the SCSI host */ struct Scsi_Host *scsi_host; /* pointer to the SCSI host */
struct i2o_controller *iop; /* pointer to the I2O controller */ struct i2o_controller *iop; /* pointer to the I2O controller */
struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */ struct i2o_device *channel[0]; /* channel->i2o_dev mapping table */
...@@ -81,19 +80,6 @@ struct i2o_scsi_host { ...@@ -81,19 +80,6 @@ struct i2o_scsi_host {
static struct scsi_host_template i2o_scsi_host_template; static struct scsi_host_template i2o_scsi_host_template;
/*
* This is only needed, because we can only set the hostdata after the device is
* added to the scsi core. So we need this little workaround.
*/
static DECLARE_MUTEX(i2o_scsi_probe_lock);
static struct i2o_device *i2o_scsi_probe_dev = NULL;
static int i2o_scsi_slave_alloc(struct scsi_device *sdp)
{
sdp->hostdata = i2o_scsi_probe_dev;
return 0;
};
#define I2O_SCSI_CAN_QUEUE 4 #define I2O_SCSI_CAN_QUEUE 4
/* SCSI OSM class handling definition */ /* SCSI OSM class handling definition */
...@@ -169,37 +155,11 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c) ...@@ -169,37 +155,11 @@ static struct i2o_scsi_host *i2o_scsi_host_alloc(struct i2o_controller *c)
* is returned, otherwise the I2O controller is added to the SCSI * is returned, otherwise the I2O controller is added to the SCSI
* core. * core.
* *
* Returns pointer to the I2O SCSI host on success or negative error code * Returns pointer to the I2O SCSI host on success or NULL on failure.
* on failure.
*/ */
static struct i2o_scsi_host *i2o_scsi_get_host(struct i2o_controller *c) static struct i2o_scsi_host *i2o_scsi_get_host(struct i2o_controller *c)
{ {
struct i2o_scsi_host *i2o_shost; return c->driver_data[i2o_scsi_driver.context];
int rc;
/* skip if already registered as I2O SCSI host */
list_for_each_entry(i2o_shost, &i2o_scsi_hosts, list)
if (i2o_shost->iop == c)
return i2o_shost;
i2o_shost = i2o_scsi_host_alloc(c);
if (IS_ERR(i2o_shost)) {
printk(KERN_ERR "scsi-osm: Could not initialize SCSI host\n");
return 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 ERR_PTR(rc);
}
list_add(&i2o_shost->list, &i2o_scsi_hosts);
pr_debug("new I2O SCSI host added\n");
return i2o_shost;
}; };
/** /**
...@@ -252,8 +212,8 @@ static int i2o_scsi_probe(struct device *dev) ...@@ -252,8 +212,8 @@ static int i2o_scsi_probe(struct device *dev)
int i; int i;
i2o_shost = i2o_scsi_get_host(c); i2o_shost = i2o_scsi_get_host(c);
if (IS_ERR(i2o_shost)) if (!i2o_shost)
return PTR_ERR(i2o_shost); return -EFAULT;
scsi_host = i2o_shost->scsi_host; scsi_host = i2o_shost->scsi_host;
...@@ -292,11 +252,8 @@ static int i2o_scsi_probe(struct device *dev) ...@@ -292,11 +252,8 @@ static int i2o_scsi_probe(struct device *dev)
return -EFAULT; return -EFAULT;
} }
down_interruptible(&i2o_scsi_probe_lock); scsi_dev =
i2o_scsi_probe_dev = i2o_dev; __scsi_add_device(i2o_shost->scsi_host, channel, id, lun, i2o_dev);
scsi_dev = scsi_add_device(i2o_shost->scsi_host, channel, id, lun);
i2o_scsi_probe_dev = NULL;
up(&i2o_scsi_probe_lock);
if (!scsi_dev) { if (!scsi_dev) {
printk(KERN_WARNING "scsi-osm: can not add SCSI device " printk(KERN_WARNING "scsi-osm: can not add SCSI device "
...@@ -536,13 +493,67 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m, ...@@ -536,13 +493,67 @@ static int i2o_scsi_reply(struct i2o_controller *c, u32 m,
cmd->request_bufflen, cmd->sc_data_direction); cmd->request_bufflen, cmd->sc_data_direction);
return 1; return 1;
} };
/**
* i2o_scsi_notify - Retrieve notifications of controller added or removed
* @notify: the notification event which occurs
* @data: pointer to additional data
*
* If a I2O controller is added, we catch the notification to add a
* corresponding Scsi_Host. On removal also remove the Scsi_Host.
*/
void i2o_scsi_notify(enum i2o_driver_notify notify, void *data)
{
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;
}
c->driver_data[i2o_scsi_driver.context] = i2o_shost;
pr_debug("new I2O SCSI host added\n");
break;
case I2O_DRIVER_NOTIFY_CONTROLLER_REMOVE:
i2o_shost = i2o_scsi_get_host(c);
if (!i2o_shost)
return;
c->driver_data[i2o_scsi_driver.context] = NULL;
scsi_remove_host(i2o_shost->scsi_host);
scsi_host_put(i2o_shost->scsi_host);
pr_debug("I2O SCSI host removed\n");
break;
default:
break;
}
};
/* SCSI OSM driver struct */ /* SCSI OSM driver struct */
static struct i2o_driver i2o_scsi_driver = { 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,
.driver = { .driver = {
.probe = i2o_scsi_probe, .probe = i2o_scsi_probe,
.remove = i2o_scsi_remove, .remove = i2o_scsi_remove,
...@@ -736,54 +747,47 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt, ...@@ -736,54 +747,47 @@ static int i2o_scsi_queuecommand(struct scsi_cmnd *SCpnt,
return 0; return 0;
}; };
#if 0
FIXME
/** /**
* i2o_scsi_abort - abort a running command * i2o_scsi_abort - abort a running command
* @SCpnt: command to abort * @SCpnt: command to abort
* *
* Ask the I2O controller to abort a command. This is an asynchrnous * Ask the I2O controller to abort a command. This is an asynchrnous
* process and our callback handler will see the command complete * process and our callback handler will see the command complete with an
* with an aborted message if it succeeds. * aborted message if it succeeds.
* *
* Locks: no locks are held or needed * Returns 0 if the command is successfully aborted or negative error code
* on failure.
*/ */
int i2o_scsi_abort(struct scsi_cmnd *SCpnt) int i2o_scsi_abort(struct scsi_cmnd *SCpnt)
{ {
struct i2o_device *i2o_dev;
struct i2o_controller *c; struct i2o_controller *c;
struct Scsi_Host *host; struct i2o_message *msg;
struct i2o_scsi_host *hostdata; u32 m;
u32 msg[5];
int tid; int tid;
int status = FAILED; int status = FAILED;
printk(KERN_WARNING "i2o_scsi: Aborting command block.\n"); printk(KERN_WARNING "i2o_scsi: Aborting command block.\n");
host = SCpnt->device->host; i2o_dev = SCpnt->device->hostdata;
hostdata = (struct i2o_scsi_host *)host->hostdata; c = i2o_dev->iop;
tid = hostdata->task[SCpnt->device->id][SCpnt->device->lun]; tid = i2o_dev->lct_data.tid;
if (tid == -1) {
printk(KERN_ERR "i2o_scsi: Impossible command to abort!\n"); m = i2o_msg_get_wait(c, &msg, I2O_TIMEOUT_MESSAGE_GET);
return status; if (m == I2O_QUEUE_EMPTY)
} return SCSI_MLQUEUE_HOST_BUSY;
c = hostdata->controller;
spin_unlock_irq(host->host_lock); writel(FIVE_WORD_MSG_SIZE | SGL_OFFSET_0, &msg->u.head[0]);
writel(I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid,
&msg->u.head[1]);
writel(i2o_cntxt_list_get_ptr(c, SCpnt), &msg->body[0]);
msg[0] = FIVE_WORD_MSG_SIZE; if (i2o_msg_post_wait(c, m, I2O_TIMEOUT_SCSI_SCB_ABORT))
msg[1] = I2O_CMD_SCSI_ABORT << 24 | HOST_TID << 12 | tid;
msg[2] = scsi_context;
msg[3] = 0;
msg[4] = i2o_context_list_remove(SCpnt, c);
if (i2o_post_wait(c, msg, sizeof(msg), 240))
status = SUCCESS; status = SUCCESS;
spin_lock_irq(host->host_lock);
return status; return status;
} }
#endif
/** /**
* i2o_scsi_bios_param - Invent disk geometry * i2o_scsi_bios_param - Invent disk geometry
* @sdev: scsi device * @sdev: scsi device
...@@ -817,15 +821,12 @@ static struct scsi_host_template i2o_scsi_host_template = { ...@@ -817,15 +821,12 @@ static struct scsi_host_template i2o_scsi_host_template = {
.name = "I2O SCSI Peripheral OSM", .name = "I2O SCSI Peripheral OSM",
.info = i2o_scsi_info, .info = i2o_scsi_info,
.queuecommand = i2o_scsi_queuecommand, .queuecommand = i2o_scsi_queuecommand,
/* .eh_abort_handler = i2o_scsi_abort,
.eh_abort_handler = i2o_scsi_abort,
*/
.bios_param = i2o_scsi_bios_param, .bios_param = i2o_scsi_bios_param,
.can_queue = I2O_SCSI_CAN_QUEUE, .can_queue = I2O_SCSI_CAN_QUEUE,
.sg_tablesize = 8, .sg_tablesize = 8,
.cmd_per_lun = 6, .cmd_per_lun = 6,
.use_clustering = ENABLE_CLUSTERING, .use_clustering = ENABLE_CLUSTERING,
.slave_alloc = i2o_scsi_slave_alloc,
}; };
/* /*
...@@ -867,14 +868,6 @@ static int __init i2o_scsi_init(void) ...@@ -867,14 +868,6 @@ static int __init i2o_scsi_init(void)
*/ */
static void __exit i2o_scsi_exit(void) static void __exit i2o_scsi_exit(void)
{ {
struct i2o_scsi_host *i2o_shost, *tmp;
/* Remove I2O SCSI hosts */
list_for_each_entry_safe(i2o_shost, tmp, &i2o_scsi_hosts, list) {
scsi_remove_host(i2o_shost->scsi_host);
scsi_host_put(i2o_shost->scsi_host);
}
/* Unregister I2O SCSI OSM from I2O core */ /* Unregister I2O SCSI OSM from I2O core */
i2o_driver_unregister(&i2o_scsi_driver); i2o_driver_unregister(&i2o_scsi_driver);
}; };
......
...@@ -108,8 +108,8 @@ u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message **msg, ...@@ -108,8 +108,8 @@ u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message **msg,
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
/** /**
* i2o_cntxt_list_add - Append a pointer to context list and return a id * i2o_cntxt_list_add - Append a pointer to context list and return a id
* @ptr: pointer to add to the context list
* @c: controller to which the context list belong * @c: controller to which the context list belong
* @ptr: pointer to add to the context list
* *
* Because the context field in I2O is only 32-bit large, on 64-bit the * Because the context field in I2O is only 32-bit large, on 64-bit the
* pointer is to large to fit in the context field. The i2o_cntxt_list * pointer is to large to fit in the context field. The i2o_cntxt_list
...@@ -117,7 +117,7 @@ u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message **msg, ...@@ -117,7 +117,7 @@ u32 i2o_msg_get_wait(struct i2o_controller *c, struct i2o_message **msg,
* *
* Returns context id > 0 on success or 0 on failure. * Returns context id > 0 on success or 0 on failure.
*/ */
u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr) u32 i2o_cntxt_list_add(struct i2o_controller *c, void *ptr)
{ {
struct i2o_context_list_element *entry; struct i2o_context_list_element *entry;
unsigned long flags; unsigned long flags;
...@@ -154,15 +154,15 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr) ...@@ -154,15 +154,15 @@ u32 i2o_cntxt_list_add(struct i2o_controller * c, void *ptr)
/** /**
* i2o_cntxt_list_remove - Remove a pointer from the context list * i2o_cntxt_list_remove - Remove a pointer from the context list
* @ptr: pointer which should be removed from the context list
* @c: controller to which the context list belong * @c: controller to which the context list belong
* @ptr: pointer which should be removed from the context list
* *
* Removes a previously added pointer from the context list and returns * Removes a previously added pointer from the context list and returns
* the matching context id. * the matching context id.
* *
* Returns context id on succes or 0 on failure. * Returns context id on succes or 0 on failure.
*/ */
u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr) u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr)
{ {
struct i2o_context_list_element *entry; struct i2o_context_list_element *entry;
u32 context = 0; u32 context = 0;
...@@ -189,9 +189,11 @@ u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr) ...@@ -189,9 +189,11 @@ u32 i2o_cntxt_list_remove(struct i2o_controller * c, void *ptr)
/** /**
* i2o_cntxt_list_get - Get a pointer from the context list and remove it * i2o_cntxt_list_get - Get a pointer from the context list and remove it
* @context: context id to which the pointer belong
* @c: controller to which the context list belong * @c: controller to which the context list belong
* returns pointer to the matching context id * @context: context id to which the pointer belong
*
* Returns pointer to the matching context id on success or NULL on
* failure.
*/ */
void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context) void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
{ {
...@@ -216,6 +218,37 @@ void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context) ...@@ -216,6 +218,37 @@ void *i2o_cntxt_list_get(struct i2o_controller *c, u32 context)
return ptr; return ptr;
}; };
/**
* i2o_cntxt_list_get_ptr - Get a context id from the context list
* @c: controller to which the context list belong
* @ptr: pointer to which the context id should be fetched
*
* Returns context id which matches to the pointer on succes or 0 on
* failure.
*/
u32 i2o_cntxt_list_get_ptr(struct i2o_controller * c, void *ptr)
{
struct i2o_context_list_element *entry;
u32 context = 0;
unsigned long flags;
spin_lock_irqsave(&c->context_list_lock, flags);
list_for_each_entry(entry, &c->context_list, list)
if (entry->ptr == ptr) {
context = entry->context;
break;
}
spin_unlock_irqrestore(&c->context_list_lock, flags);
if (!context)
printk(KERN_WARNING "i2o: Could not find nonexistent ptr "
"%p\n", ptr);
pr_debug("get context id from context list %p -> %d\n", ptr, context);
return context;
};
#endif #endif
/** /**
...@@ -782,6 +815,8 @@ void i2o_iop_remove(struct i2o_controller *c) ...@@ -782,6 +815,8 @@ 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);
list_del(&c->list); list_del(&c->list);
list_for_each_entry_safe(dev, tmp, &c->devices, list) list_for_each_entry_safe(dev, tmp, &c->devices, list)
...@@ -1098,6 +1133,8 @@ int i2o_iop_add(struct i2o_controller *c) ...@@ -1098,6 +1133,8 @@ 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);
printk(KERN_INFO "%s: Controller added\n", c->name); printk(KERN_INFO "%s: Controller added\n", c->name);
return 0; return 0;
...@@ -1209,6 +1246,7 @@ MODULE_LICENSE("GPL"); ...@@ -1209,6 +1246,7 @@ MODULE_LICENSE("GPL");
EXPORT_SYMBOL(i2o_cntxt_list_add); EXPORT_SYMBOL(i2o_cntxt_list_add);
EXPORT_SYMBOL(i2o_cntxt_list_get); EXPORT_SYMBOL(i2o_cntxt_list_get);
EXPORT_SYMBOL(i2o_cntxt_list_remove); EXPORT_SYMBOL(i2o_cntxt_list_remove);
EXPORT_SYMBOL(i2o_cntxt_list_get_ptr);
#endif #endif
EXPORT_SYMBOL(i2o_msg_get_wait); EXPORT_SYMBOL(i2o_msg_get_wait);
EXPORT_SYMBOL(i2o_msg_nop); EXPORT_SYMBOL(i2o_msg_nop);
......
...@@ -34,6 +34,10 @@ ...@@ -34,6 +34,10 @@
/* 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
...@@ -113,6 +117,9 @@ struct i2o_driver { ...@@ -113,6 +117,9 @@ struct i2o_driver {
struct device_driver driver; struct device_driver driver;
/* notification of changes */
void (*notify)(enum i2o_driver_notify, void *);
struct semaphore lock; struct semaphore lock;
}; };
...@@ -201,6 +208,8 @@ struct i2o_controller ...@@ -201,6 +208,8 @@ struct i2o_controller
#endif #endif
spinlock_t lock; /* lock for controller spinlock_t lock; /* lock for controller
configuration */ configuration */
void *driver_data[I2O_MAX_DRIVERS]; /* storage for drivers */
}; };
/* /*
...@@ -275,6 +284,7 @@ extern struct i2o_controller *i2o_find_iop(int); ...@@ -275,6 +284,7 @@ extern struct i2o_controller *i2o_find_iop(int);
extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *); extern u32 i2o_cntxt_list_add(struct i2o_controller *, void *);
extern void *i2o_cntxt_list_get(struct i2o_controller *, u32); extern void *i2o_cntxt_list_get(struct i2o_controller *, u32);
extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *); extern u32 i2o_cntxt_list_remove(struct i2o_controller *, void *);
extern u32 i2o_cntxt_list_get_ptr(struct i2o_controller *, void *);
static inline u32 i2o_ptr_low(void *ptr) static inline u32 i2o_ptr_low(void *ptr)
{ {
...@@ -301,6 +311,11 @@ static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr) ...@@ -301,6 +311,11 @@ static inline u32 i2o_cntxt_list_remove(struct i2o_controller *c, void *ptr)
return (u32)ptr; return (u32)ptr;
}; };
static inline u32 i2o_cntxt_list_get_ptr(struct i2o_controller *c, void *ptr)
{
return (u32)ptr;
};
static inline u32 i2o_ptr_low(void *ptr) static inline u32 i2o_ptr_low(void *ptr)
{ {
return (u32)ptr; return (u32)ptr;
...@@ -316,6 +331,19 @@ static inline u32 i2o_ptr_high(void *ptr) ...@@ -316,6 +331,19 @@ static inline u32 i2o_ptr_high(void *ptr)
extern int i2o_driver_register(struct i2o_driver *); 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
*
* Send notifications to a single registered driver.
*/
static inline void i2o_driver_notify(struct i2o_driver *drv,
enum i2o_driver_notify notify, void *data) {
if(drv->notify)
drv->notify(notify, data);
}
extern void i2o_driver_notify_all(enum i2o_driver_notify, void *);
/* I2O device functions */ /* I2O device functions */
extern int i2o_device_claim(struct i2o_device *); extern int i2o_device_claim(struct i2o_device *);
extern int i2o_device_claim_release(struct i2o_device *); extern int i2o_device_claim_release(struct i2o_device *);
...@@ -890,6 +918,7 @@ extern void i2o_debug_state(struct i2o_controller *c); ...@@ -890,6 +918,7 @@ extern void i2o_debug_state(struct i2o_controller *c);
#define I2O_TIMEOUT_RESET 30 #define I2O_TIMEOUT_RESET 30
#define I2O_TIMEOUT_STATUS_GET 5 #define I2O_TIMEOUT_STATUS_GET 5
#define I2O_TIMEOUT_LCT_GET 20 #define I2O_TIMEOUT_LCT_GET 20
#define I2O_TIMEOUT_SCSI_SCB_ABORT 240
/* retries */ /* retries */
#define I2O_HRT_GET_TRIES 3 #define I2O_HRT_GET_TRIES 3
......
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