aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/exec-osm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/i2o/exec-osm.c')
-rw-r--r--drivers/message/i2o/exec-osm.c74
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 */
267static 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 */
287static 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 */
301static DEVICE_ATTR(vendor_id, S_IRUGO, i2o_exec_show_vendor_id, NULL);
302static 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,
268static int i2o_exec_probe(struct device *dev) 313static 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 */
287static int i2o_exec_remove(struct device *dev) 338static 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 */
302static void i2o_exec_lct_modified(struct i2o_controller *c) 356static 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/**