aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/i2o/device.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/i2o/device.c')
-rw-r--r--drivers/message/i2o/device.c272
1 files changed, 108 insertions, 164 deletions
diff --git a/drivers/message/i2o/device.c b/drivers/message/i2o/device.c
index 21f16ba3ac38..d9879965eb50 100644
--- a/drivers/message/i2o/device.c
+++ b/drivers/message/i2o/device.c
@@ -45,10 +45,10 @@ static inline int i2o_device_issue_claim(struct i2o_device *dev, u32 cmd,
45 writel(type, &msg->body[0]); 45 writel(type, &msg->body[0]);
46 46
47 return i2o_msg_post_wait(dev->iop, m, 60); 47 return i2o_msg_post_wait(dev->iop, m, 60);
48}; 48}
49 49
50/** 50/**
51 * i2o_device_claim - claim a device for use by an OSM 51 * i2o_device_claim - claim a device for use by an OSM
52 * @dev: I2O device to claim 52 * @dev: I2O device to claim
53 * @drv: I2O driver which wants to claim the device 53 * @drv: I2O driver which wants to claim the device
54 * 54 *
@@ -73,7 +73,7 @@ int i2o_device_claim(struct i2o_device *dev)
73 up(&dev->lock); 73 up(&dev->lock);
74 74
75 return rc; 75 return rc;
76}; 76}
77 77
78/** 78/**
79 * i2o_device_claim_release - release a device that the OSM is using 79 * i2o_device_claim_release - release a device that the OSM is using
@@ -119,7 +119,8 @@ int i2o_device_claim_release(struct i2o_device *dev)
119 up(&dev->lock); 119 up(&dev->lock);
120 120
121 return rc; 121 return rc;
122}; 122}
123
123 124
124/** 125/**
125 * i2o_device_release - release the memory for a I2O device 126 * i2o_device_release - release the memory for a I2O device
@@ -135,39 +136,47 @@ static void i2o_device_release(struct device *dev)
135 pr_debug("i2o: device %s released\n", dev->bus_id); 136 pr_debug("i2o: device %s released\n", dev->bus_id);
136 137
137 kfree(i2o_dev); 138 kfree(i2o_dev);
138}; 139}
140
139 141
140/** 142/**
141 * i2o_device_class_release - Remove I2O device attributes 143 * i2o_device_class_show_class_id - Displays class id of I2O device
142 * @cd: I2O class device which is added to the I2O device class 144 * @cd: class device of which the class id should be displayed
145 * @buf: buffer into which the class id should be printed
143 * 146 *
144 * Removes attributes from the I2O device again. Also search each device 147 * Returns the number of bytes which are printed into the buffer.
145 * on the controller for I2O devices which refert to this device as parent
146 * or user and remove this links also.
147 */ 148 */
148static void i2o_device_class_release(struct class_device *cd) 149static ssize_t i2o_device_show_class_id(struct device *dev,
150 struct device_attribute *attr,
151 char *buf)
149{ 152{
150 struct i2o_device *i2o_dev, *tmp; 153 struct i2o_device *i2o_dev = to_i2o_device(dev);
151 struct i2o_controller *c;
152 154
153 i2o_dev = to_i2o_device(cd->dev); 155 sprintf(buf, "0x%03x\n", i2o_dev->lct_data.class_id);
154 c = i2o_dev->iop; 156 return strlen(buf) + 1;
157}
155 158
156 sysfs_remove_link(&i2o_dev->device.kobj, "parent"); 159/**
157 sysfs_remove_link(&i2o_dev->device.kobj, "user"); 160 * i2o_device_class_show_tid - Displays TID of I2O device
161 * @cd: class device of which the TID should be displayed
162 * @buf: buffer into which the class id should be printed
163 *
164 * Returns the number of bytes which are printed into the buffer.
165 */
166static ssize_t i2o_device_show_tid(struct device *dev,
167 struct device_attribute *attr,
168 char *buf)
169{
170 struct i2o_device *i2o_dev = to_i2o_device(dev);
158 171
159 list_for_each_entry(tmp, &c->devices, list) { 172 sprintf(buf, "0x%03x\n", i2o_dev->lct_data.tid);
160 if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid) 173 return strlen(buf) + 1;
161 sysfs_remove_link(&tmp->device.kobj, "parent"); 174}
162 if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
163 sysfs_remove_link(&tmp->device.kobj, "user");
164 }
165};
166 175
167/* I2O device class */ 176struct device_attribute i2o_device_attrs[] = {
168static struct class i2o_device_class = { 177 __ATTR(class_id, S_IRUGO, i2o_device_show_class_id, NULL),
169 .name = "i2o_device", 178 __ATTR(tid, S_IRUGO, i2o_device_show_tid, NULL),
170 .release = i2o_device_class_release 179 __ATTR_NULL
171}; 180};
172 181
173/** 182/**
@@ -193,11 +202,69 @@ static struct i2o_device *i2o_device_alloc(void)
193 202
194 dev->device.bus = &i2o_bus_type; 203 dev->device.bus = &i2o_bus_type;
195 dev->device.release = &i2o_device_release; 204 dev->device.release = &i2o_device_release;
196 dev->classdev.class = &i2o_device_class;
197 dev->classdev.dev = &dev->device;
198 205
199 return dev; 206 return dev;
200}; 207}
208
209/**
210 * i2o_setup_sysfs_links - Adds attributes to the I2O device
211 * @cd: I2O class device which is added to the I2O device class
212 *
213 * This function get called when a I2O device is added to the class. It
214 * creates the attributes for each device and creates user/parent symlink
215 * if necessary.
216 *
217 * Returns 0 on success or negative error code on failure.
218 */
219static void i2o_setup_sysfs_links(struct i2o_device *i2o_dev)
220{
221 struct i2o_controller *c = i2o_dev->iop;
222 struct i2o_device *tmp;
223
224 /* create user entries for this device */
225 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
226 if (tmp && tmp != i2o_dev)
227 sysfs_create_link(&i2o_dev->device.kobj,
228 &tmp->device.kobj, "user");
229
230 /* create user entries refering to this device */
231 list_for_each_entry(tmp, &c->devices, list)
232 if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid &&
233 tmp != i2o_dev)
234 sysfs_create_link(&tmp->device.kobj,
235 &i2o_dev->device.kobj, "user");
236
237 /* create parent entries for this device */
238 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
239 if (tmp && tmp != i2o_dev)
240 sysfs_create_link(&i2o_dev->device.kobj,
241 &tmp->device.kobj, "parent");
242
243 /* create parent entries refering to this device */
244 list_for_each_entry(tmp, &c->devices, list)
245 if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid &&
246 tmp != i2o_dev)
247 sysfs_create_link(&tmp->device.kobj,
248 &i2o_dev->device.kobj, "parent");
249}
250
251static void i2o_remove_sysfs_links(struct i2o_device *i2o_dev)
252{
253 struct i2o_controller *c = i2o_dev->iop;
254 struct i2o_device *tmp;
255
256 sysfs_remove_link(&i2o_dev->device.kobj, "parent");
257 sysfs_remove_link(&i2o_dev->device.kobj, "user");
258
259 list_for_each_entry(tmp, &c->devices, list) {
260 if (tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
261 sysfs_remove_link(&tmp->device.kobj, "parent");
262 if (tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
263 sysfs_remove_link(&tmp->device.kobj, "user");
264 }
265}
266
267
201 268
202/** 269/**
203 * i2o_device_add - allocate a new I2O device and add it to the IOP 270 * i2o_device_add - allocate a new I2O device and add it to the IOP
@@ -222,28 +289,25 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
222 } 289 }
223 290
224 dev->lct_data = *entry; 291 dev->lct_data = *entry;
292 dev->iop = c;
225 293
226 snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit, 294 snprintf(dev->device.bus_id, BUS_ID_SIZE, "%d:%03x", c->unit,
227 dev->lct_data.tid); 295 dev->lct_data.tid);
228 296
229 snprintf(dev->classdev.class_id, BUS_ID_SIZE, "%d:%03x", c->unit,
230 dev->lct_data.tid);
231
232 dev->iop = c;
233 dev->device.parent = &c->device; 297 dev->device.parent = &c->device;
234 298
235 device_register(&dev->device); 299 device_register(&dev->device);
236 300
237 list_add_tail(&dev->list, &c->devices); 301 list_add_tail(&dev->list, &c->devices);
238 302
239 class_device_register(&dev->classdev); 303 i2o_setup_sysfs_links(dev);
240 304
241 i2o_driver_notify_device_add_all(dev); 305 i2o_driver_notify_device_add_all(dev);
242 306
243 pr_debug("i2o: device %s added\n", dev->device.bus_id); 307 pr_debug("i2o: device %s added\n", dev->device.bus_id);
244 308
245 return dev; 309 return dev;
246}; 310}
247 311
248/** 312/**
249 * i2o_device_remove - remove an I2O device from the I2O core 313 * i2o_device_remove - remove an I2O device from the I2O core
@@ -256,10 +320,10 @@ static struct i2o_device *i2o_device_add(struct i2o_controller *c,
256void i2o_device_remove(struct i2o_device *i2o_dev) 320void i2o_device_remove(struct i2o_device *i2o_dev)
257{ 321{
258 i2o_driver_notify_device_remove_all(i2o_dev); 322 i2o_driver_notify_device_remove_all(i2o_dev);
259 class_device_unregister(&i2o_dev->classdev); 323 i2o_remove_sysfs_links(i2o_dev);
260 list_del(&i2o_dev->list); 324 list_del(&i2o_dev->list);
261 device_unregister(&i2o_dev->device); 325 device_unregister(&i2o_dev->device);
262}; 326}
263 327
264/** 328/**
265 * i2o_device_parse_lct - Parse a previously fetched LCT and create devices 329 * i2o_device_parse_lct - Parse a previously fetched LCT and create devices
@@ -337,99 +401,8 @@ int i2o_device_parse_lct(struct i2o_controller *c)
337 up(&c->lct_lock); 401 up(&c->lct_lock);
338 402
339 return 0; 403 return 0;
340}; 404}
341
342/**
343 * i2o_device_class_show_class_id - Displays class id of I2O device
344 * @cd: class device of which the class id should be displayed
345 * @buf: buffer into which the class id should be printed
346 *
347 * Returns the number of bytes which are printed into the buffer.
348 */
349static ssize_t i2o_device_class_show_class_id(struct class_device *cd,
350 char *buf)
351{
352 struct i2o_device *dev = to_i2o_device(cd->dev);
353
354 sprintf(buf, "0x%03x\n", dev->lct_data.class_id);
355 return strlen(buf) + 1;
356};
357
358/**
359 * i2o_device_class_show_tid - Displays TID of I2O device
360 * @cd: class device of which the TID should be displayed
361 * @buf: buffer into which the class id should be printed
362 *
363 * Returns the number of bytes which are printed into the buffer.
364 */
365static ssize_t i2o_device_class_show_tid(struct class_device *cd, char *buf)
366{
367 struct i2o_device *dev = to_i2o_device(cd->dev);
368
369 sprintf(buf, "0x%03x\n", dev->lct_data.tid);
370 return strlen(buf) + 1;
371};
372
373/* I2O device class attributes */
374static CLASS_DEVICE_ATTR(class_id, S_IRUGO, i2o_device_class_show_class_id,
375 NULL);
376static CLASS_DEVICE_ATTR(tid, S_IRUGO, i2o_device_class_show_tid, NULL);
377
378/**
379 * i2o_device_class_add - Adds attributes to the I2O device
380 * @cd: I2O class device which is added to the I2O device class
381 *
382 * This function get called when a I2O device is added to the class. It
383 * creates the attributes for each device and creates user/parent symlink
384 * if necessary.
385 *
386 * Returns 0 on success or negative error code on failure.
387 */
388static int i2o_device_class_add(struct class_device *cd)
389{
390 struct i2o_device *i2o_dev, *tmp;
391 struct i2o_controller *c;
392
393 i2o_dev = to_i2o_device(cd->dev);
394 c = i2o_dev->iop;
395
396 class_device_create_file(cd, &class_device_attr_class_id);
397 class_device_create_file(cd, &class_device_attr_tid);
398
399 /* create user entries for this device */
400 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.user_tid);
401 if (tmp && (tmp != i2o_dev))
402 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
403 "user");
404
405 /* create user entries refering to this device */
406 list_for_each_entry(tmp, &c->devices, list)
407 if ((tmp->lct_data.user_tid == i2o_dev->lct_data.tid)
408 && (tmp != i2o_dev))
409 sysfs_create_link(&tmp->device.kobj,
410 &i2o_dev->device.kobj, "user");
411
412 /* create parent entries for this device */
413 tmp = i2o_iop_find_device(i2o_dev->iop, i2o_dev->lct_data.parent_tid);
414 if (tmp && (tmp != i2o_dev))
415 sysfs_create_link(&i2o_dev->device.kobj, &tmp->device.kobj,
416 "parent");
417
418 /* create parent entries refering to this device */
419 list_for_each_entry(tmp, &c->devices, list)
420 if ((tmp->lct_data.parent_tid == i2o_dev->lct_data.tid)
421 && (tmp != i2o_dev))
422 sysfs_create_link(&tmp->device.kobj,
423 &i2o_dev->device.kobj, "parent");
424
425 return 0;
426};
427 405
428/* I2O device class interface */
429static struct class_interface i2o_device_class_interface = {
430 .class = &i2o_device_class,
431 .add = i2o_device_class_add
432};
433 406
434/* 407/*
435 * Run time support routines 408 * Run time support routines
@@ -553,11 +526,11 @@ int i2o_parm_field_get(struct i2o_device *i2o_dev, int group, int field,
553} 526}
554 527
555/* 528/*
556 * if oper == I2O_PARAMS_TABLE_GET, get from all rows 529 * if oper == I2O_PARAMS_TABLE_GET, get from all rows
557 * if fieldcount == -1 return all fields 530 * if fieldcount == -1 return all fields
558 * ibuf and ibuflen are unused (use NULL, 0) 531 * ibuf and ibuflen are unused (use NULL, 0)
559 * else return specific fields 532 * else return specific fields
560 * ibuf contains fieldindexes 533 * ibuf contains fieldindexes
561 * 534 *
562 * if oper == I2O_PARAMS_LIST_GET, get from specific rows 535 * if oper == I2O_PARAMS_LIST_GET, get from specific rows
563 * if fieldcount == -1 return all fields 536 * if fieldcount == -1 return all fields
@@ -602,35 +575,6 @@ int i2o_parm_table_get(struct i2o_device *dev, int oper, int group,
602 return size; 575 return size;
603} 576}
604 577
605/**
606 * i2o_device_init - Initialize I2O devices
607 *
608 * Registers the I2O device class.
609 *
610 * Returns 0 on success or negative error code on failure.
611 */
612int i2o_device_init(void)
613{
614 int rc;
615
616 rc = class_register(&i2o_device_class);
617 if (rc)
618 return rc;
619
620 return class_interface_register(&i2o_device_class_interface);
621};
622
623/**
624 * i2o_device_exit - I2O devices exit function
625 *
626 * Unregisters the I2O device class.
627 */
628void i2o_device_exit(void)
629{
630 class_interface_register(&i2o_device_class_interface);
631 class_unregister(&i2o_device_class);
632};
633
634EXPORT_SYMBOL(i2o_device_claim); 578EXPORT_SYMBOL(i2o_device_claim);
635EXPORT_SYMBOL(i2o_device_claim_release); 579EXPORT_SYMBOL(i2o_device_claim_release);
636EXPORT_SYMBOL(i2o_parm_field_get); 580EXPORT_SYMBOL(i2o_parm_field_get);