diff options
Diffstat (limited to 'drivers/message/i2o/exec-osm.c')
-rw-r--r-- | drivers/message/i2o/exec-osm.c | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 5581344fbba6..0160221c802a 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c | |||
@@ -206,6 +206,7 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
206 | u32 context) | 206 | u32 context) |
207 | { | 207 | { |
208 | struct i2o_exec_wait *wait, *tmp; | 208 | struct i2o_exec_wait *wait, *tmp; |
209 | unsigned long flags; | ||
209 | static spinlock_t lock = SPIN_LOCK_UNLOCKED; | 210 | static spinlock_t lock = SPIN_LOCK_UNLOCKED; |
210 | int rc = 1; | 211 | int rc = 1; |
211 | 212 | ||
@@ -216,11 +217,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
216 | * already expired. Not much we can do about that except log it for | 217 | * already expired. Not much we can do about that except log it for |
217 | * debug purposes, increase timeout, and recompile. | 218 | * debug purposes, increase timeout, and recompile. |
218 | */ | 219 | */ |
219 | spin_lock(&lock); | 220 | spin_lock_irqsave(&lock, flags); |
220 | list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { | 221 | list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { |
221 | if (wait->tcntxt == context) { | 222 | if (wait->tcntxt == context) { |
222 | list_del(&wait->list); | 223 | list_del(&wait->list); |
223 | 224 | ||
225 | spin_unlock_irqrestore(&lock, flags); | ||
226 | |||
224 | wait->m = m; | 227 | wait->m = m; |
225 | wait->msg = msg; | 228 | wait->msg = msg; |
226 | wait->complete = 1; | 229 | wait->complete = 1; |
@@ -242,13 +245,11 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
242 | rc = -1; | 245 | rc = -1; |
243 | } | 246 | } |
244 | 247 | ||
245 | spin_unlock(&lock); | ||
246 | |||
247 | return rc; | 248 | return rc; |
248 | } | 249 | } |
249 | } | 250 | } |
250 | 251 | ||
251 | spin_unlock(&lock); | 252 | spin_unlock_irqrestore(&lock, flags); |
252 | 253 | ||
253 | osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, | 254 | osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, |
254 | context); | 255 | context); |
@@ -257,6 +258,50 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
257 | }; | 258 | }; |
258 | 259 | ||
259 | /** | 260 | /** |
261 | * i2o_exec_show_vendor_id - Displays Vendor ID of controller | ||
262 | * @d: device of which the Vendor ID should be displayed | ||
263 | * @buf: buffer into which the Vendor ID should be printed | ||
264 | * | ||
265 | * Returns number of bytes printed into buffer. | ||
266 | */ | ||
267 | static ssize_t i2o_exec_show_vendor_id(struct device *d, char *buf) | ||
268 | { | ||
269 | struct i2o_device *dev = to_i2o_device(d); | ||
270 | u16 id; | ||
271 | |||
272 | if (i2o_parm_field_get(dev, 0x0000, 0, &id, 2)) { | ||
273 | sprintf(buf, "0x%04x", id); | ||
274 | return strlen(buf) + 1; | ||
275 | } | ||
276 | |||
277 | return 0; | ||
278 | }; | ||
279 | |||
280 | /** | ||
281 | * i2o_exec_show_product_id - Displays Product ID of controller | ||
282 | * @d: device of which the Product ID should be displayed | ||
283 | * @buf: buffer into which the Product ID should be printed | ||
284 | * | ||
285 | * Returns number of bytes printed into buffer. | ||
286 | */ | ||
287 | static ssize_t i2o_exec_show_product_id(struct device *d, char *buf) | ||
288 | { | ||
289 | struct i2o_device *dev = to_i2o_device(d); | ||
290 | u16 id; | ||
291 | |||
292 | if (i2o_parm_field_get(dev, 0x0000, 1, &id, 2)) { | ||
293 | sprintf(buf, "0x%04x", id); | ||
294 | return strlen(buf) + 1; | ||
295 | } | ||
296 | |||
297 | return 0; | ||
298 | }; | ||
299 | |||
300 | /* Exec-OSM device attributes */ | ||
301 | static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL); | ||
302 | static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); | ||
303 | |||
304 | /** | ||
260 | * i2o_exec_probe - Called if a new I2O device (executive class) appears | 305 | * i2o_exec_probe - Called if a new I2O device (executive class) appears |
261 | * @dev: I2O device which should be probed | 306 | * @dev: I2O device which should be probed |
262 | * | 307 | * |
@@ -268,10 +313,16 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, | |||
268 | static int i2o_exec_probe(struct device *dev) | 313 | static int i2o_exec_probe(struct device *dev) |
269 | { | 314 | { |
270 | struct i2o_device *i2o_dev = to_i2o_device(dev); | 315 | struct i2o_device *i2o_dev = to_i2o_device(dev); |
316 | struct i2o_controller *c = i2o_dev->iop; | ||
271 | 317 | ||
272 | i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); | 318 | i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); |
273 | 319 | ||
274 | i2o_dev->iop->exec = i2o_dev; | 320 | c->exec = i2o_dev; |
321 | |||
322 | i2o_exec_lct_notify(c, c->lct->change_ind + 1); | ||
323 | |||
324 | device_create_file(dev, &dev_attr_vendor_id); | ||
325 | device_create_file(dev, &dev_attr_product_id); | ||
275 | 326 | ||
276 | return 0; | 327 | return 0; |
277 | }; | 328 | }; |
@@ -286,6 +337,9 @@ static int i2o_exec_probe(struct device *dev) | |||
286 | */ | 337 | */ |
287 | static int i2o_exec_remove(struct device *dev) | 338 | static int i2o_exec_remove(struct device *dev) |
288 | { | 339 | { |
340 | device_remove_file(dev, &dev_attr_product_id); | ||
341 | device_remove_file(dev, &dev_attr_vendor_id); | ||
342 | |||
289 | i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); | 343 | i2o_event_register(to_i2o_device(dev), &i2o_exec_driver, 0, 0); |
290 | 344 | ||
291 | return 0; | 345 | return 0; |
@@ -297,12 +351,16 @@ static int i2o_exec_remove(struct device *dev) | |||
297 | * | 351 | * |
298 | * This function handles asynchronus LCT NOTIFY replies. It parses the | 352 | * This function handles asynchronus LCT NOTIFY replies. It parses the |
299 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY | 353 | * new LCT and if the buffer for the LCT was to small sends a LCT NOTIFY |
300 | * again. | 354 | * again, otherwise send LCT NOTIFY to get informed on next LCT change. |
301 | */ | 355 | */ |
302 | static void i2o_exec_lct_modified(struct i2o_controller *c) | 356 | static void i2o_exec_lct_modified(struct i2o_controller *c) |
303 | { | 357 | { |
304 | if (i2o_device_parse_lct(c) == -EAGAIN) | 358 | u32 change_ind = 0; |
305 | i2o_exec_lct_notify(c, 0); | 359 | |
360 | if (i2o_device_parse_lct(c) != -EAGAIN) | ||
361 | change_ind = c->lct->change_ind + 1; | ||
362 | |||
363 | i2o_exec_lct_notify(c, change_ind); | ||
306 | }; | 364 | }; |
307 | 365 | ||
308 | /** | 366 | /** |