aboutsummaryrefslogtreecommitdiff
path: root/drivers/message/i2o/driver.c
diff options
context:
space:
mode:
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>2005-06-23 22:02:11 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 00:05:28 -0700
commit61fbfa8129c1771061a0e9f47747854293081c5b (patch)
tree03fe14c41e2a49d3841ae6820a2dd43a91fddee9 /drivers/message/i2o/driver.c
parent34d6e07570ef74b965131452a862b13dfa779188 (diff)
[PATCH] I2O: bugfixes and compability enhancements
Changes: - Fixed sysfs bug where user and parent links where added to the I2O device itself - Fixed bug when calculating TID for the event handler and cleaned up the workflow of i2o_driver_dispatch() - Fixed oops when no I2O device could be found for an event delivered to Exec-OSM - Fixed initialization of spinlock in Exec-OSM - Fixed memory leak in i2o_cfg_passthru() and i2o_cfg_passthru() - Removed MTRR support - Added PCI ID of Promise SX6000 with firmware >= 1.20.x.x - Turn of caching for ioremapped memory of in_queue - Added initialization sequence for Promise controllers - Moved definition of u8 / u16 / u32 for raidutils before first use Signed-off-by: Markus Lidel <Markus.Lidel@shadowconnect.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/message/i2o/driver.c')
-rw-r--r--drivers/message/i2o/driver.c89
1 files changed, 44 insertions, 45 deletions
diff --git a/drivers/message/i2o/driver.c b/drivers/message/i2o/driver.c
index 91f4edbb2a2..c71e68f70e7 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -18,6 +18,8 @@
#include <linux/rwsem.h>
#include <linux/i2o.h>
+#define OSM_NAME "core"
+
/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
module_param_named(max_drivers, i2o_max_drivers, uint, 0);
@@ -182,62 +184,59 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
struct i2o_driver *drv;
u32 context = readl(&msg->u.s.icntxt);
- if (likely(context < i2o_max_drivers)) {
- spin_lock(&i2o_drivers_lock);
- drv = i2o_drivers[context];
- spin_unlock(&i2o_drivers_lock);
-
- if (unlikely(!drv)) {
- printk(KERN_WARNING "%s: Spurious reply to unknown "
- "driver %d\n", c->name, context);
- return -EIO;
- }
+ if (unlikely(context >= i2o_max_drivers)) {
+ printk(KERN_WARNING "%s: Spurious reply to unknown driver "
+ "%d\n", c->name, readl(&msg->u.s.icntxt));
+ return -EIO;
+ }
- if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
- struct i2o_device *dev, *tmp;
- struct i2o_event *evt;
- u16 size;
- u16 tid;
+ spin_lock(&i2o_drivers_lock);
+ drv = i2o_drivers[context];
+ spin_unlock(&i2o_drivers_lock);
- tid = readl(&msg->u.head[1]) & 0x1fff;
+ if (unlikely(!drv)) {
+ osm_warn("Spurious reply to unknown driver %d\n", context);
+ return -EIO;
+ }
- pr_debug("%s: event received from device %d\n", c->name,
- tid);
+ if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
+ struct i2o_device *dev, *tmp;
+ struct i2o_event *evt;
+ u16 size;
+ u16 tid = readl(&msg->u.head[1]) & 0xfff;
- /* cut of header from message size (in 32-bit words) */
- size = (readl(&msg->u.head[0]) >> 16) - 5;
+ osm_debug("event received from device %d\n", tid);
- evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC);
- if (!evt)
- return -ENOMEM;
- memset(evt, 0, size * 4 + sizeof(*evt));
+ /* cut of header from message size (in 32-bit words) */
+ size = (readl(&msg->u.head[0]) >> 16) - 5;
- evt->size = size;
- memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt,
- (size + 2) * 4);
+ evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
+ if (!evt)
+ return -ENOMEM;
- list_for_each_entry_safe(dev, tmp, &c->devices, list)
- if (dev->lct_data.tid == tid) {
- evt->i2o_dev = dev;
- break;
- }
+ evt->size = size;
+ evt->tcntxt = readl(&msg->u.s.tcntxt);
+ evt->event_indicator = readl(&msg->body[0]);
+ memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
- INIT_WORK(&evt->work, (void (*)(void *))drv->event,
- evt);
- queue_work(drv->event_queue, &evt->work);
- return 1;
+ list_for_each_entry_safe(dev, tmp, &c->devices, list)
+ if (dev->lct_data.tid == tid) {
+ evt->i2o_dev = dev;
+ break;
}
- if (likely(drv->reply))
- return drv->reply(c, m, msg);
- else
- pr_debug("%s: Reply to driver %s, but no reply function"
- " defined!\n", c->name, drv->name);
+ INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
+ queue_work(drv->event_queue, &evt->work);
+ return 1;
+ }
+
+ if (unlikely(!drv->reply)) {
+ pr_debug("%s: Reply to driver %s, but no reply function"
+ " defined!\n", c->name, drv->name);
return -EIO;
- } else
- printk(KERN_WARNING "%s: Spurious reply to unknown driver "
- "%d\n", c->name, readl(&msg->u.s.icntxt));
- return -EIO;
+ }
+
+ return drv->reply(c, m, msg);
}
/**