aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2007-03-15 15:50:34 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-03-15 18:29:26 -0400
commitd9a9cdfb078d755e648d53ec25b7370f84ee5729 (patch)
tree308380483fd6241b1d0ef5916b9329c1c5df00f6 /drivers/s390/cio
parent6ab27c6bf38d5ff71dafeca77b79e7c284804b75 (diff)
[PATCH] sysfs and driver core: add callback helper, used by SCSI and S390
This patch (as868) adds a helper routine for device drivers that need to set up a callback to perform some action in a different process's context. This is intended for use by attribute methods that want to unregister themselves or their parent device. Attribute method calls are mutually exclusive with unregistration, so such actions cannot be taken directly. Two attribute methods are converted to use the new helper routine: one for SCSI device deletion and one for System/390 ccwgroup devices. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: Hugh Dickins <hugh@veritas.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Oliver Neukum <oneukum@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/ccwgroup.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c
index d48e3ca4752c..5aeb68e732b0 100644
--- a/drivers/s390/cio/ccwgroup.c
+++ b/drivers/s390/cio/ccwgroup.c
@@ -71,19 +71,31 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev)
71 * Provide an 'ungroup' attribute so the user can remove group devices no 71 * Provide an 'ungroup' attribute so the user can remove group devices no
72 * longer needed or accidentially created. Saves memory :) 72 * longer needed or accidentially created. Saves memory :)
73 */ 73 */
74static void ccwgroup_ungroup_callback(struct device *dev)
75{
76 struct ccwgroup_device *gdev = to_ccwgroupdev(dev);
77
78 __ccwgroup_remove_symlinks(gdev);
79 device_unregister(dev);
80}
81
74static ssize_t 82static ssize_t
75ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) 83ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
76{ 84{
77 struct ccwgroup_device *gdev; 85 struct ccwgroup_device *gdev;
86 int rc;
78 87
79 gdev = to_ccwgroupdev(dev); 88 gdev = to_ccwgroupdev(dev);
80 89
81 if (gdev->state != CCWGROUP_OFFLINE) 90 if (gdev->state != CCWGROUP_OFFLINE)
82 return -EINVAL; 91 return -EINVAL;
83 92
84 __ccwgroup_remove_symlinks(gdev); 93 /* Note that we cannot unregister the device from one of its
85 device_unregister(dev); 94 * attribute methods, so we have to use this roundabout approach.
86 95 */
96 rc = device_schedule_callback(dev, ccwgroup_ungroup_callback);
97 if (rc)
98 count = rc;
87 return count; 99 return count;
88} 100}
89 101