aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/enclosure.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/enclosure.c')
-rw-r--r--drivers/misc/enclosure.c202
1 files changed, 127 insertions, 75 deletions
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 6fcb0e96adf4..0736cff9d97a 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -31,7 +31,6 @@
31static LIST_HEAD(container_list); 31static LIST_HEAD(container_list);
32static DEFINE_MUTEX(container_list_lock); 32static DEFINE_MUTEX(container_list_lock);
33static struct class enclosure_class; 33static struct class enclosure_class;
34static struct class enclosure_component_class;
35 34
36/** 35/**
37 * enclosure_find - find an enclosure given a device 36 * enclosure_find - find an enclosure given a device
@@ -40,16 +39,16 @@ static struct class enclosure_component_class;
40 * Looks through the list of registered enclosures to see 39 * Looks through the list of registered enclosures to see
41 * if it can find a match for a device. Returns NULL if no 40 * if it can find a match for a device. Returns NULL if no
42 * enclosure is found. Obtains a reference to the enclosure class 41 * enclosure is found. Obtains a reference to the enclosure class
43 * device which must be released with class_device_put(). 42 * device which must be released with device_put().
44 */ 43 */
45struct enclosure_device *enclosure_find(struct device *dev) 44struct enclosure_device *enclosure_find(struct device *dev)
46{ 45{
47 struct enclosure_device *edev = NULL; 46 struct enclosure_device *edev;
48 47
49 mutex_lock(&container_list_lock); 48 mutex_lock(&container_list_lock);
50 list_for_each_entry(edev, &container_list, node) { 49 list_for_each_entry(edev, &container_list, node) {
51 if (edev->cdev.dev == dev) { 50 if (edev->edev.parent == dev) {
52 class_device_get(&edev->cdev); 51 get_device(&edev->edev);
53 mutex_unlock(&container_list_lock); 52 mutex_unlock(&container_list_lock);
54 return edev; 53 return edev;
55 } 54 }
@@ -117,11 +116,11 @@ enclosure_register(struct device *dev, const char *name, int components,
117 116
118 edev->components = components; 117 edev->components = components;
119 118
120 edev->cdev.class = &enclosure_class; 119 edev->edev.class = &enclosure_class;
121 edev->cdev.dev = get_device(dev); 120 edev->edev.parent = get_device(dev);
122 edev->cb = cb; 121 edev->cb = cb;
123 snprintf(edev->cdev.class_id, BUS_ID_SIZE, "%s", name); 122 snprintf(edev->edev.bus_id, BUS_ID_SIZE, "%s", name);
124 err = class_device_register(&edev->cdev); 123 err = device_register(&edev->edev);
125 if (err) 124 if (err)
126 goto err; 125 goto err;
127 126
@@ -135,7 +134,7 @@ enclosure_register(struct device *dev, const char *name, int components,
135 return edev; 134 return edev;
136 135
137 err: 136 err:
138 put_device(edev->cdev.dev); 137 put_device(edev->edev.parent);
139 kfree(edev); 138 kfree(edev);
140 return ERR_PTR(err); 139 return ERR_PTR(err);
141} 140}
@@ -158,29 +157,69 @@ void enclosure_unregister(struct enclosure_device *edev)
158 157
159 for (i = 0; i < edev->components; i++) 158 for (i = 0; i < edev->components; i++)
160 if (edev->component[i].number != -1) 159 if (edev->component[i].number != -1)
161 class_device_unregister(&edev->component[i].cdev); 160 device_unregister(&edev->component[i].cdev);
162 161
163 /* prevent any callbacks into service user */ 162 /* prevent any callbacks into service user */
164 edev->cb = &enclosure_null_callbacks; 163 edev->cb = &enclosure_null_callbacks;
165 class_device_unregister(&edev->cdev); 164 device_unregister(&edev->edev);
166} 165}
167EXPORT_SYMBOL_GPL(enclosure_unregister); 166EXPORT_SYMBOL_GPL(enclosure_unregister);
168 167
169static void enclosure_release(struct class_device *cdev) 168#define ENCLOSURE_NAME_SIZE 64
169
170static void enclosure_link_name(struct enclosure_component *cdev, char *name)
171{
172 strcpy(name, "enclosure_device:");
173 strcat(name, cdev->cdev.bus_id);
174}
175
176static void enclosure_remove_links(struct enclosure_component *cdev)
177{
178 char name[ENCLOSURE_NAME_SIZE];
179
180 enclosure_link_name(cdev, name);
181 sysfs_remove_link(&cdev->dev->kobj, name);
182 sysfs_remove_link(&cdev->cdev.kobj, "device");
183}
184
185static int enclosure_add_links(struct enclosure_component *cdev)
186{
187 int error;
188 char name[ENCLOSURE_NAME_SIZE];
189
190 error = sysfs_create_link(&cdev->cdev.kobj, &cdev->dev->kobj, "device");
191 if (error)
192 return error;
193
194 enclosure_link_name(cdev, name);
195 error = sysfs_create_link(&cdev->dev->kobj, &cdev->cdev.kobj, name);
196 if (error)
197 sysfs_remove_link(&cdev->cdev.kobj, "device");
198
199 return error;
200}
201
202static void enclosure_release(struct device *cdev)
170{ 203{
171 struct enclosure_device *edev = to_enclosure_device(cdev); 204 struct enclosure_device *edev = to_enclosure_device(cdev);
172 205
173 put_device(cdev->dev); 206 put_device(cdev->parent);
174 kfree(edev); 207 kfree(edev);
175} 208}
176 209
177static void enclosure_component_release(struct class_device *cdev) 210static void enclosure_component_release(struct device *dev)
178{ 211{
179 if (cdev->dev) 212 struct enclosure_component *cdev = to_enclosure_component(dev);
213
214 if (cdev->dev) {
215 enclosure_remove_links(cdev);
180 put_device(cdev->dev); 216 put_device(cdev->dev);
181 class_device_put(cdev->parent); 217 }
218 put_device(dev->parent);
182} 219}
183 220
221static struct attribute_group *enclosure_groups[];
222
184/** 223/**
185 * enclosure_component_register - add a particular component to an enclosure 224 * enclosure_component_register - add a particular component to an enclosure
186 * @edev: the enclosure to add the component 225 * @edev: the enclosure to add the component
@@ -201,7 +240,7 @@ enclosure_component_register(struct enclosure_device *edev,
201 const char *name) 240 const char *name)
202{ 241{
203 struct enclosure_component *ecomp; 242 struct enclosure_component *ecomp;
204 struct class_device *cdev; 243 struct device *cdev;
205 int err; 244 int err;
206 245
207 if (number >= edev->components) 246 if (number >= edev->components)
@@ -215,14 +254,16 @@ enclosure_component_register(struct enclosure_device *edev,
215 ecomp->type = type; 254 ecomp->type = type;
216 ecomp->number = number; 255 ecomp->number = number;
217 cdev = &ecomp->cdev; 256 cdev = &ecomp->cdev;
218 cdev->parent = class_device_get(&edev->cdev); 257 cdev->parent = get_device(&edev->edev);
219 cdev->class = &enclosure_component_class;
220 if (name) 258 if (name)
221 snprintf(cdev->class_id, BUS_ID_SIZE, "%s", name); 259 snprintf(cdev->bus_id, BUS_ID_SIZE, "%s", name);
222 else 260 else
223 snprintf(cdev->class_id, BUS_ID_SIZE, "%u", number); 261 snprintf(cdev->bus_id, BUS_ID_SIZE, "%u", number);
224 262
225 err = class_device_register(cdev); 263 cdev->release = enclosure_component_release;
264 cdev->groups = enclosure_groups;
265
266 err = device_register(cdev);
226 if (err) 267 if (err)
227 ERR_PTR(err); 268 ERR_PTR(err);
228 269
@@ -247,18 +288,19 @@ EXPORT_SYMBOL_GPL(enclosure_component_register);
247int enclosure_add_device(struct enclosure_device *edev, int component, 288int enclosure_add_device(struct enclosure_device *edev, int component,
248 struct device *dev) 289 struct device *dev)
249{ 290{
250 struct class_device *cdev; 291 struct enclosure_component *cdev;
251 292
252 if (!edev || component >= edev->components) 293 if (!edev || component >= edev->components)
253 return -EINVAL; 294 return -EINVAL;
254 295
255 cdev = &edev->component[component].cdev; 296 cdev = &edev->component[component];
256 297
257 class_device_del(cdev);
258 if (cdev->dev) 298 if (cdev->dev)
259 put_device(cdev->dev); 299 enclosure_remove_links(cdev);
300
301 put_device(cdev->dev);
260 cdev->dev = get_device(dev); 302 cdev->dev = get_device(dev);
261 return class_device_add(cdev); 303 return enclosure_add_links(cdev);
262} 304}
263EXPORT_SYMBOL_GPL(enclosure_add_device); 305EXPORT_SYMBOL_GPL(enclosure_add_device);
264 306
@@ -272,18 +314,17 @@ EXPORT_SYMBOL_GPL(enclosure_add_device);
272 */ 314 */
273int enclosure_remove_device(struct enclosure_device *edev, int component) 315int enclosure_remove_device(struct enclosure_device *edev, int component)
274{ 316{
275 struct class_device *cdev; 317 struct enclosure_component *cdev;
276 318
277 if (!edev || component >= edev->components) 319 if (!edev || component >= edev->components)
278 return -EINVAL; 320 return -EINVAL;
279 321
280 cdev = &edev->component[component].cdev; 322 cdev = &edev->component[component];
281 323
282 class_device_del(cdev); 324 device_del(&cdev->cdev);
283 if (cdev->dev) 325 put_device(cdev->dev);
284 put_device(cdev->dev);
285 cdev->dev = NULL; 326 cdev->dev = NULL;
286 return class_device_add(cdev); 327 return device_add(&cdev->cdev);
287} 328}
288EXPORT_SYMBOL_GPL(enclosure_remove_device); 329EXPORT_SYMBOL_GPL(enclosure_remove_device);
289 330
@@ -291,14 +332,16 @@ EXPORT_SYMBOL_GPL(enclosure_remove_device);
291 * sysfs pieces below 332 * sysfs pieces below
292 */ 333 */
293 334
294static ssize_t enclosure_show_components(struct class_device *cdev, char *buf) 335static ssize_t enclosure_show_components(struct device *cdev,
336 struct device_attribute *attr,
337 char *buf)
295{ 338{
296 struct enclosure_device *edev = to_enclosure_device(cdev); 339 struct enclosure_device *edev = to_enclosure_device(cdev);
297 340
298 return snprintf(buf, 40, "%d\n", edev->components); 341 return snprintf(buf, 40, "%d\n", edev->components);
299} 342}
300 343
301static struct class_device_attribute enclosure_attrs[] = { 344static struct device_attribute enclosure_attrs[] = {
302 __ATTR(components, S_IRUGO, enclosure_show_components, NULL), 345 __ATTR(components, S_IRUGO, enclosure_show_components, NULL),
303 __ATTR_NULL 346 __ATTR_NULL
304}; 347};
@@ -306,8 +349,8 @@ static struct class_device_attribute enclosure_attrs[] = {
306static struct class enclosure_class = { 349static struct class enclosure_class = {
307 .name = "enclosure", 350 .name = "enclosure",
308 .owner = THIS_MODULE, 351 .owner = THIS_MODULE,
309 .release = enclosure_release, 352 .dev_release = enclosure_release,
310 .class_dev_attrs = enclosure_attrs, 353 .dev_attrs = enclosure_attrs,
311}; 354};
312 355
313static const char *const enclosure_status [] = { 356static const char *const enclosure_status [] = {
@@ -326,7 +369,8 @@ static const char *const enclosure_type [] = {
326 [ENCLOSURE_COMPONENT_ARRAY_DEVICE] = "array device", 369 [ENCLOSURE_COMPONENT_ARRAY_DEVICE] = "array device",
327}; 370};
328 371
329static ssize_t get_component_fault(struct class_device *cdev, char *buf) 372static ssize_t get_component_fault(struct device *cdev,
373 struct device_attribute *attr, char *buf)
330{ 374{
331 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 375 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
332 struct enclosure_component *ecomp = to_enclosure_component(cdev); 376 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -336,8 +380,9 @@ static ssize_t get_component_fault(struct class_device *cdev, char *buf)
336 return snprintf(buf, 40, "%d\n", ecomp->fault); 380 return snprintf(buf, 40, "%d\n", ecomp->fault);
337} 381}
338 382
339static ssize_t set_component_fault(struct class_device *cdev, const char *buf, 383static ssize_t set_component_fault(struct device *cdev,
340 size_t count) 384 struct device_attribute *attr,
385 const char *buf, size_t count)
341{ 386{
342 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 387 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
343 struct enclosure_component *ecomp = to_enclosure_component(cdev); 388 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -348,7 +393,8 @@ static ssize_t set_component_fault(struct class_device *cdev, const char *buf,
348 return count; 393 return count;
349} 394}
350 395
351static ssize_t get_component_status(struct class_device *cdev, char *buf) 396static ssize_t get_component_status(struct device *cdev,
397 struct device_attribute *attr,char *buf)
352{ 398{
353 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 399 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
354 struct enclosure_component *ecomp = to_enclosure_component(cdev); 400 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -358,8 +404,9 @@ static ssize_t get_component_status(struct class_device *cdev, char *buf)
358 return snprintf(buf, 40, "%s\n", enclosure_status[ecomp->status]); 404 return snprintf(buf, 40, "%s\n", enclosure_status[ecomp->status]);
359} 405}
360 406
361static ssize_t set_component_status(struct class_device *cdev, const char *buf, 407static ssize_t set_component_status(struct device *cdev,
362 size_t count) 408 struct device_attribute *attr,
409 const char *buf, size_t count)
363{ 410{
364 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 411 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
365 struct enclosure_component *ecomp = to_enclosure_component(cdev); 412 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -380,7 +427,8 @@ static ssize_t set_component_status(struct class_device *cdev, const char *buf,
380 return -EINVAL; 427 return -EINVAL;
381} 428}
382 429
383static ssize_t get_component_active(struct class_device *cdev, char *buf) 430static ssize_t get_component_active(struct device *cdev,
431 struct device_attribute *attr, char *buf)
384{ 432{
385 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 433 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
386 struct enclosure_component *ecomp = to_enclosure_component(cdev); 434 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -390,8 +438,9 @@ static ssize_t get_component_active(struct class_device *cdev, char *buf)
390 return snprintf(buf, 40, "%d\n", ecomp->active); 438 return snprintf(buf, 40, "%d\n", ecomp->active);
391} 439}
392 440
393static ssize_t set_component_active(struct class_device *cdev, const char *buf, 441static ssize_t set_component_active(struct device *cdev,
394 size_t count) 442 struct device_attribute *attr,
443 const char *buf, size_t count)
395{ 444{
396 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 445 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
397 struct enclosure_component *ecomp = to_enclosure_component(cdev); 446 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -402,7 +451,8 @@ static ssize_t set_component_active(struct class_device *cdev, const char *buf,
402 return count; 451 return count;
403} 452}
404 453
405static ssize_t get_component_locate(struct class_device *cdev, char *buf) 454static ssize_t get_component_locate(struct device *cdev,
455 struct device_attribute *attr, char *buf)
406{ 456{
407 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 457 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
408 struct enclosure_component *ecomp = to_enclosure_component(cdev); 458 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -412,8 +462,9 @@ static ssize_t get_component_locate(struct class_device *cdev, char *buf)
412 return snprintf(buf, 40, "%d\n", ecomp->locate); 462 return snprintf(buf, 40, "%d\n", ecomp->locate);
413} 463}
414 464
415static ssize_t set_component_locate(struct class_device *cdev, const char *buf, 465static ssize_t set_component_locate(struct device *cdev,
416 size_t count) 466 struct device_attribute *attr,
467 const char *buf, size_t count)
417{ 468{
418 struct enclosure_device *edev = to_enclosure_device(cdev->parent); 469 struct enclosure_device *edev = to_enclosure_device(cdev->parent);
419 struct enclosure_component *ecomp = to_enclosure_component(cdev); 470 struct enclosure_component *ecomp = to_enclosure_component(cdev);
@@ -424,7 +475,8 @@ static ssize_t set_component_locate(struct class_device *cdev, const char *buf,
424 return count; 475 return count;
425} 476}
426 477
427static ssize_t get_component_type(struct class_device *cdev, char *buf) 478static ssize_t get_component_type(struct device *cdev,
479 struct device_attribute *attr, char *buf)
428{ 480{
429 struct enclosure_component *ecomp = to_enclosure_component(cdev); 481 struct enclosure_component *ecomp = to_enclosure_component(cdev);
430 482
@@ -432,24 +484,32 @@ static ssize_t get_component_type(struct class_device *cdev, char *buf)
432} 484}
433 485
434 486
435static struct class_device_attribute enclosure_component_attrs[] = { 487static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
436 __ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault, 488 set_component_fault);
437 set_component_fault), 489static DEVICE_ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
438 __ATTR(status, S_IRUGO | S_IWUSR, get_component_status, 490 set_component_status);
439 set_component_status), 491static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
440 __ATTR(active, S_IRUGO | S_IWUSR, get_component_active, 492 set_component_active);
441 set_component_active), 493static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
442 __ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, 494 set_component_locate);
443 set_component_locate), 495static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
444 __ATTR(type, S_IRUGO, get_component_type, NULL), 496
445 __ATTR_NULL 497static struct attribute *enclosure_component_attrs[] = {
498 &dev_attr_fault.attr,
499 &dev_attr_status.attr,
500 &dev_attr_active.attr,
501 &dev_attr_locate.attr,
502 &dev_attr_type.attr,
503 NULL
446}; 504};
447 505
448static struct class enclosure_component_class = { 506static struct attribute_group enclosure_group = {
449 .name = "enclosure_component", 507 .attrs = enclosure_component_attrs,
450 .owner = THIS_MODULE, 508};
451 .class_dev_attrs = enclosure_component_attrs, 509
452 .release = enclosure_component_release, 510static struct attribute_group *enclosure_groups[] = {
511 &enclosure_group,
512 NULL
453}; 513};
454 514
455static int __init enclosure_init(void) 515static int __init enclosure_init(void)
@@ -459,20 +519,12 @@ static int __init enclosure_init(void)
459 err = class_register(&enclosure_class); 519 err = class_register(&enclosure_class);
460 if (err) 520 if (err)
461 return err; 521 return err;
462 err = class_register(&enclosure_component_class);
463 if (err)
464 goto err_out;
465 522
466 return 0; 523 return 0;
467 err_out:
468 class_unregister(&enclosure_class);
469
470 return err;
471} 524}
472 525
473static void __exit enclosure_exit(void) 526static void __exit enclosure_exit(void)
474{ 527{
475 class_unregister(&enclosure_component_class);
476 class_unregister(&enclosure_class); 528 class_unregister(&enclosure_class);
477} 529}
478 530