at v2.6.16 378 lines 9.7 kB view raw
1/* 2 * Functions to handle I2O drivers (OSMs) and I2O bus type for sysfs 3 * 4 * Copyright (C) 2004 Markus Lidel <Markus.Lidel@shadowconnect.com> 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License as published by the 8 * Free Software Foundation; either version 2 of the License, or (at your 9 * option) any later version. 10 * 11 * Fixes/additions: 12 * Markus Lidel <Markus.Lidel@shadowconnect.com> 13 * initial version. 14 */ 15 16#include <linux/device.h> 17#include <linux/module.h> 18#include <linux/rwsem.h> 19#include <linux/i2o.h> 20#include <linux/workqueue.h> 21#include <linux/string.h> 22#include <linux/slab.h> 23#include "core.h" 24 25#define OSM_NAME "i2o" 26 27/* max_drivers - Maximum I2O drivers (OSMs) which could be registered */ 28static unsigned int i2o_max_drivers = I2O_MAX_DRIVERS; 29module_param_named(max_drivers, i2o_max_drivers, uint, 0); 30MODULE_PARM_DESC(max_drivers, "maximum number of OSM's to support"); 31 32/* I2O drivers lock and array */ 33static spinlock_t i2o_drivers_lock; 34static struct i2o_driver **i2o_drivers; 35 36/** 37 * i2o_bus_match - Tell if a I2O device class id match the class ids of 38 * the I2O driver (OSM) 39 * 40 * @dev: device which should be verified 41 * @drv: the driver to match against 42 * 43 * Used by the bus to check if the driver wants to handle the device. 44 * 45 * Returns 1 if the class ids of the driver match the class id of the 46 * device, otherwise 0. 47 */ 48static int i2o_bus_match(struct device *dev, struct device_driver *drv) 49{ 50 struct i2o_device *i2o_dev = to_i2o_device(dev); 51 struct i2o_driver *i2o_drv = to_i2o_driver(drv); 52 struct i2o_class_id *ids = i2o_drv->classes; 53 54 if (ids) 55 while (ids->class_id != I2O_CLASS_END) { 56 if (ids->class_id == i2o_dev->lct_data.class_id) 57 return 1; 58 ids++; 59 } 60 return 0; 61}; 62 63/* I2O bus type */ 64struct bus_type i2o_bus_type = { 65 .name = "i2o", 66 .match = i2o_bus_match, 67 .dev_attrs = i2o_device_attrs 68}; 69 70/** 71 * i2o_driver_register - Register a I2O driver (OSM) in the I2O core 72 * @drv: I2O driver which should be registered 73 * 74 * Registers the OSM drv in the I2O core and creates an event queues if 75 * necessary. 76 * 77 * Returns 0 on success or negative error code on failure. 78 */ 79int i2o_driver_register(struct i2o_driver *drv) 80{ 81 struct i2o_controller *c; 82 int i; 83 int rc = 0; 84 unsigned long flags; 85 86 osm_debug("Register driver %s\n", drv->name); 87 88 if (drv->event) { 89 drv->event_queue = create_workqueue(drv->name); 90 if (!drv->event_queue) { 91 osm_err("Could not initialize event queue for driver " 92 "%s\n", drv->name); 93 return -EFAULT; 94 } 95 osm_debug("Event queue initialized for driver %s\n", drv->name); 96 } else 97 drv->event_queue = NULL; 98 99 drv->driver.name = drv->name; 100 drv->driver.bus = &i2o_bus_type; 101 102 spin_lock_irqsave(&i2o_drivers_lock, flags); 103 104 for (i = 0; i2o_drivers[i]; i++) 105 if (i >= i2o_max_drivers) { 106 osm_err("too many drivers registered, increase " 107 "max_drivers\n"); 108 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 109 return -EFAULT; 110 } 111 112 drv->context = i; 113 i2o_drivers[i] = drv; 114 115 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 116 117 osm_debug("driver %s gets context id %d\n", drv->name, drv->context); 118 119 list_for_each_entry(c, &i2o_controllers, list) { 120 struct i2o_device *i2o_dev; 121 122 i2o_driver_notify_controller_add(drv, c); 123 list_for_each_entry(i2o_dev, &c->devices, list) 124 i2o_driver_notify_device_add(drv, i2o_dev); 125 } 126 127 rc = driver_register(&drv->driver); 128 if (rc) 129 destroy_workqueue(drv->event_queue); 130 131 return rc; 132}; 133 134/** 135 * i2o_driver_unregister - Unregister a I2O driver (OSM) from the I2O core 136 * @drv: I2O driver which should be unregistered 137 * 138 * Unregisters the OSM drv from the I2O core and cleanup event queues if 139 * necessary. 140 */ 141void i2o_driver_unregister(struct i2o_driver *drv) 142{ 143 struct i2o_controller *c; 144 unsigned long flags; 145 146 osm_debug("unregister driver %s\n", drv->name); 147 148 driver_unregister(&drv->driver); 149 150 list_for_each_entry(c, &i2o_controllers, list) { 151 struct i2o_device *i2o_dev; 152 153 list_for_each_entry(i2o_dev, &c->devices, list) 154 i2o_driver_notify_device_remove(drv, i2o_dev); 155 156 i2o_driver_notify_controller_remove(drv, c); 157 } 158 159 spin_lock_irqsave(&i2o_drivers_lock, flags); 160 i2o_drivers[drv->context] = NULL; 161 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 162 163 if (drv->event_queue) { 164 destroy_workqueue(drv->event_queue); 165 drv->event_queue = NULL; 166 osm_debug("event queue removed for %s\n", drv->name); 167 } 168}; 169 170/** 171 * i2o_driver_dispatch - dispatch an I2O reply message 172 * @c: I2O controller of the message 173 * @m: I2O message number 174 * @msg: I2O message to be delivered 175 * 176 * The reply is delivered to the driver from which the original message 177 * was. This function is only called from interrupt context. 178 * 179 * Returns 0 on success and the message should not be flushed. Returns > 0 180 * on success and if the message should be flushed afterwords. Returns 181 * negative error code on failure (the message will be flushed too). 182 */ 183int i2o_driver_dispatch(struct i2o_controller *c, u32 m) 184{ 185 struct i2o_driver *drv; 186 struct i2o_message *msg = i2o_msg_out_to_virt(c, m); 187 u32 context = le32_to_cpu(msg->u.s.icntxt); 188 unsigned long flags; 189 190 if (unlikely(context >= i2o_max_drivers)) { 191 osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, 192 context); 193 return -EIO; 194 } 195 196 spin_lock_irqsave(&i2o_drivers_lock, flags); 197 drv = i2o_drivers[context]; 198 spin_unlock_irqrestore(&i2o_drivers_lock, flags); 199 200 if (unlikely(!drv)) { 201 osm_warn("%s: Spurious reply to unknown driver %d\n", c->name, 202 context); 203 return -EIO; 204 } 205 206 if ((le32_to_cpu(msg->u.head[1]) >> 24) == I2O_CMD_UTIL_EVT_REGISTER) { 207 struct i2o_device *dev, *tmp; 208 struct i2o_event *evt; 209 u16 size; 210 u16 tid = le32_to_cpu(msg->u.head[1]) & 0xfff; 211 212 osm_debug("event received from device %d\n", tid); 213 214 if (!drv->event) 215 return -EIO; 216 217 /* cut of header from message size (in 32-bit words) */ 218 size = (le32_to_cpu(msg->u.head[0]) >> 16) - 5; 219 220 evt = kzalloc(size * 4 + sizeof(*evt), GFP_ATOMIC); 221 if (!evt) 222 return -ENOMEM; 223 224 evt->size = size; 225 evt->tcntxt = le32_to_cpu(msg->u.s.tcntxt); 226 evt->event_indicator = le32_to_cpu(msg->body[0]); 227 memcpy(&evt->data, &msg->body[1], size * 4); 228 229 list_for_each_entry_safe(dev, tmp, &c->devices, list) 230 if (dev->lct_data.tid == tid) { 231 evt->i2o_dev = dev; 232 break; 233 } 234 235 INIT_WORK(&evt->work, (void (*)(void *))drv->event, evt); 236 queue_work(drv->event_queue, &evt->work); 237 return 1; 238 } 239 240 if (unlikely(!drv->reply)) { 241 osm_debug("%s: Reply to driver %s, but no reply function" 242 " defined!\n", c->name, drv->name); 243 return -EIO; 244 } 245 246 return drv->reply(c, m, msg); 247} 248 249/** 250 * i2o_driver_notify_controller_add_all - Send notify of added controller 251 * to all I2O drivers 252 * 253 * Send notifications to all registered drivers that a new controller was 254 * added. 255 */ 256void i2o_driver_notify_controller_add_all(struct i2o_controller *c) 257{ 258 int i; 259 struct i2o_driver *drv; 260 261 for (i = 0; i < I2O_MAX_DRIVERS; i++) { 262 drv = i2o_drivers[i]; 263 264 if (drv) 265 i2o_driver_notify_controller_add(drv, c); 266 } 267} 268 269/** 270 * i2o_driver_notify_controller_remove_all - Send notify of removed 271 * controller to all I2O drivers 272 * 273 * Send notifications to all registered drivers that a controller was 274 * removed. 275 */ 276void i2o_driver_notify_controller_remove_all(struct i2o_controller *c) 277{ 278 int i; 279 struct i2o_driver *drv; 280 281 for (i = 0; i < I2O_MAX_DRIVERS; i++) { 282 drv = i2o_drivers[i]; 283 284 if (drv) 285 i2o_driver_notify_controller_remove(drv, c); 286 } 287} 288 289/** 290 * i2o_driver_notify_device_add_all - Send notify of added device to all 291 * I2O drivers 292 * 293 * Send notifications to all registered drivers that a device was added. 294 */ 295void i2o_driver_notify_device_add_all(struct i2o_device *i2o_dev) 296{ 297 int i; 298 struct i2o_driver *drv; 299 300 for (i = 0; i < I2O_MAX_DRIVERS; i++) { 301 drv = i2o_drivers[i]; 302 303 if (drv) 304 i2o_driver_notify_device_add(drv, i2o_dev); 305 } 306} 307 308/** 309 * i2o_driver_notify_device_remove_all - Send notify of removed device to 310 * all I2O drivers 311 * 312 * Send notifications to all registered drivers that a device was removed. 313 */ 314void i2o_driver_notify_device_remove_all(struct i2o_device *i2o_dev) 315{ 316 int i; 317 struct i2o_driver *drv; 318 319 for (i = 0; i < I2O_MAX_DRIVERS; i++) { 320 drv = i2o_drivers[i]; 321 322 if (drv) 323 i2o_driver_notify_device_remove(drv, i2o_dev); 324 } 325} 326 327/** 328 * i2o_driver_init - initialize I2O drivers (OSMs) 329 * 330 * Registers the I2O bus and allocate memory for the array of OSMs. 331 * 332 * Returns 0 on success or negative error code on failure. 333 */ 334int __init i2o_driver_init(void) 335{ 336 int rc = 0; 337 338 spin_lock_init(&i2o_drivers_lock); 339 340 if ((i2o_max_drivers < 2) || (i2o_max_drivers > 64) || 341 ((i2o_max_drivers ^ (i2o_max_drivers - 1)) != 342 (2 * i2o_max_drivers - 1))) { 343 osm_warn("max_drivers set to %d, but must be >=2 and <= 64 and " 344 "a power of 2\n", i2o_max_drivers); 345 i2o_max_drivers = I2O_MAX_DRIVERS; 346 } 347 osm_info("max drivers = %d\n", i2o_max_drivers); 348 349 i2o_drivers = 350 kzalloc(i2o_max_drivers * sizeof(*i2o_drivers), GFP_KERNEL); 351 if (!i2o_drivers) 352 return -ENOMEM; 353 354 rc = bus_register(&i2o_bus_type); 355 356 if (rc < 0) 357 kfree(i2o_drivers); 358 359 return rc; 360}; 361 362/** 363 * i2o_driver_exit - clean up I2O drivers (OSMs) 364 * 365 * Unregisters the I2O bus and free driver array. 366 */ 367void __exit i2o_driver_exit(void) 368{ 369 bus_unregister(&i2o_bus_type); 370 kfree(i2o_drivers); 371}; 372 373EXPORT_SYMBOL(i2o_driver_register); 374EXPORT_SYMBOL(i2o_driver_unregister); 375EXPORT_SYMBOL(i2o_driver_notify_controller_add_all); 376EXPORT_SYMBOL(i2o_driver_notify_controller_remove_all); 377EXPORT_SYMBOL(i2o_driver_notify_device_add_all); 378EXPORT_SYMBOL(i2o_driver_notify_device_remove_all);