aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/enclosure.c100
1 files changed, 71 insertions, 29 deletions
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index fafb57fed761..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
@@ -166,6 +165,40 @@ void enclosure_unregister(struct enclosure_device *edev)
166} 165}
167EXPORT_SYMBOL_GPL(enclosure_unregister); 166EXPORT_SYMBOL_GPL(enclosure_unregister);
168 167
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
169static void enclosure_release(struct device *cdev) 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);
@@ -178,10 +211,15 @@ static void enclosure_component_release(struct device *dev)
178{ 211{
179 struct enclosure_component *cdev = to_enclosure_component(dev); 212 struct enclosure_component *cdev = to_enclosure_component(dev);
180 213
181 put_device(cdev->dev); 214 if (cdev->dev) {
215 enclosure_remove_links(cdev);
216 put_device(cdev->dev);
217 }
182 put_device(dev->parent); 218 put_device(dev->parent);
183} 219}
184 220
221static struct attribute_group *enclosure_groups[];
222
185/** 223/**
186 * enclosure_component_register - add a particular component to an enclosure 224 * enclosure_component_register - add a particular component to an enclosure
187 * @edev: the enclosure to add the component 225 * @edev: the enclosure to add the component
@@ -217,12 +255,14 @@ enclosure_component_register(struct enclosure_device *edev,
217 ecomp->number = number; 255 ecomp->number = number;
218 cdev = &ecomp->cdev; 256 cdev = &ecomp->cdev;
219 cdev->parent = get_device(&edev->edev); 257 cdev->parent = get_device(&edev->edev);
220 cdev->class = &enclosure_component_class;
221 if (name) 258 if (name)
222 snprintf(cdev->bus_id, BUS_ID_SIZE, "%s", name); 259 snprintf(cdev->bus_id, BUS_ID_SIZE, "%s", name);
223 else 260 else
224 snprintf(cdev->bus_id, BUS_ID_SIZE, "%u", number); 261 snprintf(cdev->bus_id, BUS_ID_SIZE, "%u", number);
225 262
263 cdev->release = enclosure_component_release;
264 cdev->groups = enclosure_groups;
265
226 err = device_register(cdev); 266 err = device_register(cdev);
227 if (err) 267 if (err)
228 ERR_PTR(err); 268 ERR_PTR(err);
@@ -255,10 +295,12 @@ int enclosure_add_device(struct enclosure_device *edev, int component,
255 295
256 cdev = &edev->component[component]; 296 cdev = &edev->component[component];
257 297
258 device_del(&cdev->cdev); 298 if (cdev->dev)
299 enclosure_remove_links(cdev);
300
259 put_device(cdev->dev); 301 put_device(cdev->dev);
260 cdev->dev = get_device(dev); 302 cdev->dev = get_device(dev);
261 return device_add(&cdev->cdev); 303 return enclosure_add_links(cdev);
262} 304}
263EXPORT_SYMBOL_GPL(enclosure_add_device); 305EXPORT_SYMBOL_GPL(enclosure_add_device);
264 306
@@ -442,24 +484,32 @@ static ssize_t get_component_type(struct device *cdev,
442} 484}
443 485
444 486
445static struct device_attribute enclosure_component_attrs[] = { 487static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
446 __ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault, 488 set_component_fault);
447 set_component_fault), 489static DEVICE_ATTR(status, S_IRUGO | S_IWUSR, get_component_status,
448 __ATTR(status, S_IRUGO | S_IWUSR, get_component_status, 490 set_component_status);
449 set_component_status), 491static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
450 __ATTR(active, S_IRUGO | S_IWUSR, get_component_active, 492 set_component_active);
451 set_component_active), 493static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
452 __ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, 494 set_component_locate);
453 set_component_locate), 495static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
454 __ATTR(type, S_IRUGO, get_component_type, NULL), 496
455 __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
456}; 504};
457 505
458static struct class enclosure_component_class = { 506static struct attribute_group enclosure_group = {
459 .name = "enclosure_component", 507 .attrs = enclosure_component_attrs,
460 .owner = THIS_MODULE, 508};
461 .dev_attrs = enclosure_component_attrs, 509
462 .dev_release = enclosure_component_release, 510static struct attribute_group *enclosure_groups[] = {
511 &enclosure_group,
512 NULL
463}; 513};
464 514
465static int __init enclosure_init(void) 515static int __init enclosure_init(void)
@@ -469,20 +519,12 @@ static int __init enclosure_init(void)
469 err = class_register(&enclosure_class); 519 err = class_register(&enclosure_class);
470 if (err) 520 if (err)
471 return err; 521 return err;
472 err = class_register(&enclosure_component_class);
473 if (err)
474 goto err_out;
475 522
476 return 0; 523 return 0;
477 err_out:
478 class_unregister(&enclosure_class);
479
480 return err;
481} 524}
482 525
483static void __exit enclosure_exit(void) 526static void __exit enclosure_exit(void)
484{ 527{
485 class_unregister(&enclosure_component_class);
486 class_unregister(&enclosure_class); 528 class_unregister(&enclosure_class);
487} 529}
488 530