diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2011-10-30 10:16:52 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2011-10-30 10:16:43 -0400 |
commit | dbdf1afcaaabe83dea15a3cb9b9013e73ae3b1ad (patch) | |
tree | 5d54789554dedcacdb9f20a2bd42b48771682156 /drivers/s390/cio | |
parent | d4e81b35b882d96f059afdb0f98e5b6025973b09 (diff) |
[S390] ccwgroup: move attributes to attribute group
Put sysfs attributes of ccwgroup devices in an attribute group to
ensure that these attributes are actually present when userspace
is notified via uevents.
Cc: stable@kernel.org
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r-- | drivers/s390/cio/ccwgroup.c | 42 |
1 files changed, 22 insertions, 20 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 5c567414c4bb..cda9bd6e48e8 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c | |||
@@ -87,6 +87,12 @@ static void __ccwgroup_remove_cdev_refs(struct ccwgroup_device *gdev) | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | static ssize_t ccwgroup_online_store(struct device *dev, | ||
91 | struct device_attribute *attr, | ||
92 | const char *buf, size_t count); | ||
93 | static ssize_t ccwgroup_online_show(struct device *dev, | ||
94 | struct device_attribute *attr, | ||
95 | char *buf); | ||
90 | /* | 96 | /* |
91 | * Provide an 'ungroup' attribute so the user can remove group devices no | 97 | * Provide an 'ungroup' attribute so the user can remove group devices no |
92 | * longer needed or accidentially created. Saves memory :) | 98 | * longer needed or accidentially created. Saves memory :) |
@@ -134,6 +140,20 @@ out: | |||
134 | } | 140 | } |
135 | 141 | ||
136 | static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store); | 142 | static DEVICE_ATTR(ungroup, 0200, NULL, ccwgroup_ungroup_store); |
143 | static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); | ||
144 | |||
145 | static struct attribute *ccwgroup_attrs[] = { | ||
146 | &dev_attr_online.attr, | ||
147 | &dev_attr_ungroup.attr, | ||
148 | NULL, | ||
149 | }; | ||
150 | static struct attribute_group ccwgroup_attr_group = { | ||
151 | .attrs = ccwgroup_attrs, | ||
152 | }; | ||
153 | static const struct attribute_group *ccwgroup_attr_groups[] = { | ||
154 | &ccwgroup_attr_group, | ||
155 | NULL, | ||
156 | }; | ||
137 | 157 | ||
138 | static void | 158 | static void |
139 | ccwgroup_release (struct device *dev) | 159 | ccwgroup_release (struct device *dev) |
@@ -293,25 +313,17 @@ int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | |||
293 | } | 313 | } |
294 | 314 | ||
295 | dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); | 315 | dev_set_name(&gdev->dev, "%s", dev_name(&gdev->cdev[0]->dev)); |
296 | 316 | gdev->dev.groups = ccwgroup_attr_groups; | |
297 | rc = device_add(&gdev->dev); | 317 | rc = device_add(&gdev->dev); |
298 | if (rc) | 318 | if (rc) |
299 | goto error; | 319 | goto error; |
300 | get_device(&gdev->dev); | 320 | get_device(&gdev->dev); |
301 | rc = device_create_file(&gdev->dev, &dev_attr_ungroup); | ||
302 | |||
303 | if (rc) { | ||
304 | device_unregister(&gdev->dev); | ||
305 | goto error; | ||
306 | } | ||
307 | |||
308 | rc = __ccwgroup_create_symlinks(gdev); | 321 | rc = __ccwgroup_create_symlinks(gdev); |
309 | if (!rc) { | 322 | if (!rc) { |
310 | mutex_unlock(&gdev->reg_mutex); | 323 | mutex_unlock(&gdev->reg_mutex); |
311 | put_device(&gdev->dev); | 324 | put_device(&gdev->dev); |
312 | return 0; | 325 | return 0; |
313 | } | 326 | } |
314 | device_remove_file(&gdev->dev, &dev_attr_ungroup); | ||
315 | device_unregister(&gdev->dev); | 327 | device_unregister(&gdev->dev); |
316 | error: | 328 | error: |
317 | for (i = 0; i < num_devices; i++) | 329 | for (i = 0; i < num_devices; i++) |
@@ -423,7 +435,7 @@ ccwgroup_online_store (struct device *dev, struct device_attribute *attr, const | |||
423 | int ret; | 435 | int ret; |
424 | 436 | ||
425 | if (!dev->driver) | 437 | if (!dev->driver) |
426 | return -ENODEV; | 438 | return -EINVAL; |
427 | 439 | ||
428 | gdev = to_ccwgroupdev(dev); | 440 | gdev = to_ccwgroupdev(dev); |
429 | gdrv = to_ccwgroupdrv(dev->driver); | 441 | gdrv = to_ccwgroupdrv(dev->driver); |
@@ -456,8 +468,6 @@ ccwgroup_online_show (struct device *dev, struct device_attribute *attr, char *b | |||
456 | return sprintf(buf, online ? "1\n" : "0\n"); | 468 | return sprintf(buf, online ? "1\n" : "0\n"); |
457 | } | 469 | } |
458 | 470 | ||
459 | static DEVICE_ATTR(online, 0644, ccwgroup_online_show, ccwgroup_online_store); | ||
460 | |||
461 | static int | 471 | static int |
462 | ccwgroup_probe (struct device *dev) | 472 | ccwgroup_probe (struct device *dev) |
463 | { | 473 | { |
@@ -469,12 +479,7 @@ ccwgroup_probe (struct device *dev) | |||
469 | gdev = to_ccwgroupdev(dev); | 479 | gdev = to_ccwgroupdev(dev); |
470 | gdrv = to_ccwgroupdrv(dev->driver); | 480 | gdrv = to_ccwgroupdrv(dev->driver); |
471 | 481 | ||
472 | if ((ret = device_create_file(dev, &dev_attr_online))) | ||
473 | return ret; | ||
474 | |||
475 | ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV; | 482 | ret = gdrv->probe ? gdrv->probe(gdev) : -ENODEV; |
476 | if (ret) | ||
477 | device_remove_file(dev, &dev_attr_online); | ||
478 | 483 | ||
479 | return ret; | 484 | return ret; |
480 | } | 485 | } |
@@ -485,9 +490,6 @@ ccwgroup_remove (struct device *dev) | |||
485 | struct ccwgroup_device *gdev; | 490 | struct ccwgroup_device *gdev; |
486 | struct ccwgroup_driver *gdrv; | 491 | struct ccwgroup_driver *gdrv; |
487 | 492 | ||
488 | device_remove_file(dev, &dev_attr_online); | ||
489 | device_remove_file(dev, &dev_attr_ungroup); | ||
490 | |||
491 | if (!dev->driver) | 493 | if (!dev->driver) |
492 | return 0; | 494 | return 0; |
493 | 495 | ||