aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/driver.c
diff options
context:
space:
mode:
authorMarkus Lidel <Markus.Lidel@shadowconnect.com>2005-06-24 01:02:11 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-24 03:05:28 -0400
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 91f4edbb2a27..c71e68f70e7d 100644
--- a/drivers/message/i2o/driver.c
+++ b/drivers/message/i2o/driver.c
@@ -18,6 +18,8 @@
18#include <linux/rwsem.h> 18#include <linux/rwsem.h>
19#include <linux/i2o.h> 19#include <linux/i2o.h>
20 20
21#define OSM_NAME "core"
22
21/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ 23/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */
22unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; 24unsigned int i2o_max_drivers = I2O_MAX_DRIVERS;
23module_param_named(max_drivers, i2o_max_drivers, uint, 0); 25module_param_named(max_drivers, i2o_max_drivers, uint, 0);
@@ -182,62 +184,59 @@ int i2o_driver_dispatch(struct i2o_controller *c, u32 m,
182 struct i2o_driver *drv; 184 struct i2o_driver *drv;
183 u32 context = readl(&msg->u.s.icntxt); 185 u32 context = readl(&msg->u.s.icntxt);
184 186
185 if (likely(context < i2o_max_drivers)) { 187 if (unlikely(context >= i2o_max_drivers)) {
186 spin_lock(&i2o_drivers_lock); 188 printk(KERN_WARNING "%s: Spurious reply to unknown driver "
187 drv = i2o_drivers[context]; 189 "%d\n", c->name, readl(&msg->u.s.icntxt));
188 spin_unlock(&i2o_drivers_lock); 190 return -EIO;
189 191 }
190 if (unlikely(!drv)) {
191 printk(KERN_WARNING "%s: Spurious reply to unknown "
192 "driver %d\n", c->name, context);
193 return -EIO;
194 }
195 192
196 if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { 193 spin_lock(&i2o_drivers_lock);
197 struct i2o_device *dev, *tmp; 194 drv = i2o_drivers[context];
198 struct i2o_event *evt; 195 spin_unlock(&i2o_drivers_lock);
199 u16 size;
200 u16 tid;
201 196
202 tid = readl(&msg->u.head[1]) & 0x1fff; 197 if (unlikely(!drv)) {
198 osm_warn("Spurious reply to unknown driver %d\n", context);
199 return -EIO;
200 }
203 201
204 pr_debug("%s: event received from device %d\n", c->name, 202 if ((readl(&msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) {
205 tid); 203 struct i2o_device *dev, *tmp;
204 struct i2o_event *evt;
205 u16 size;
206 u16 tid = readl(&msg->u.head[1]) & 0xfff;
206 207
207 /* cut of header from message size (in 32-bit words) */ 208 osm_debug("event received from device %d\n", tid);
208 size = (readl(&msg->u.head[0]) >> 16) - 5;
209 209
210 evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC); 210 /* cut of header from message size (in 32-bit words) */
211 if (!evt) 211 size = (readl(&msg->u.head[0]) >> 16) - 5;
212 return -ENOMEM;
213 memset(evt, 0, size * 4 + sizeof(*evt));
214 212
215 evt->size = size; 213 evt = kmalloc(size * 4 + sizeof(*evt), GFP_ATOMIC | __GFP_ZERO);
216 memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, 214 if (!evt)
217 (size + 2) * 4); 215 return -ENOMEM;
218 216
219 list_for_each_entry_safe(dev, tmp, &c->devices, list) 217 evt->size = size;
220 if (dev->lct_data.tid == tid) { 218 evt->tcntxt = readl(&msg->u.s.tcntxt);
221 evt->i2o_dev = dev; 219 evt->event_indicator = readl(&msg->body[0]);
222 break; 220 memcpy_fromio(&evt->tcntxt, &msg->u.s.tcntxt, size * 4);
223 }
224 221
225 INIT_WORK(&evt->work, (void (*)(void *))drv->event, 222 list_for_each_entry_safe(dev, tmp, &c->devices, list)
226 evt); 223 if (dev->lct_data.tid == tid) {
227 queue_work(drv->event_queue, &evt->work); 224 evt->i2o_dev = dev;
228 return 1; 225 break;
229 } 226 }
230 227
231 if (likely(drv->reply)) 228 INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt);
232 return drv->reply(c, m, msg); 229 queue_work(drv->event_queue, &evt->work);
233 else 230 return 1;
234 pr_debug("%s: Reply to driver %s, but no reply function" 231 }
235 " defined!\n", c->name, drv->name); 232
233 if (unlikely(!drv->reply)) {
234 pr_debug("%s: Reply to driver %s, but no reply function"
235 " defined!\n", c->name, drv->name);
236 return -EIO; 236 return -EIO;
237 } else 237 }
238 printk(KERN_WARNING "%s: Spurious reply to unknown driver " 238
239 "%d\n", c->name, readl(&msg->u.s.icntxt)); 239 return drv->reply(c, m, msg);
240 return -EIO;
241} 240}
242 241
243/** 242/**