Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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