diff options
author | James Bottomley <James.Bottomley@steeleye.com> | 2005-08-14 18:09:01 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-08-14 18:21:27 -0400 |
commit | d0a7e574007fd547d72ec693bfa35778623d0738 (patch) | |
tree | 3457bdf4e8eaf870971aab03c99c31534ba85658 /drivers/base/attribute_container.c | |
parent | 10c1b88987d618f4f89c10e11e574c76de73b5e7 (diff) |
[SCSI] correct transport class abstraction to work outside SCSI
I recently tried to construct a totally generic transport class and
found there were certain features missing from the current abstract
transport class. Most notable is that you have to hang the data on the
class_device but most of the API is framed in terms of the generic
device, not the class_device.
These changes are two fold
- Provide the class_device to all of the setup and configure APIs
- Provide and extra API to take the device and the attribute class and
return the corresponding class_device
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/base/attribute_container.c')
-rw-r--r-- | drivers/base/attribute_container.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/base/attribute_container.c b/drivers/base/attribute_container.c index ec615d854be9..62c093db11e6 100644 --- a/drivers/base/attribute_container.c +++ b/drivers/base/attribute_container.c | |||
@@ -58,6 +58,7 @@ attribute_container_register(struct attribute_container *cont) | |||
58 | { | 58 | { |
59 | INIT_LIST_HEAD(&cont->node); | 59 | INIT_LIST_HEAD(&cont->node); |
60 | INIT_LIST_HEAD(&cont->containers); | 60 | INIT_LIST_HEAD(&cont->containers); |
61 | spin_lock_init(&cont->containers_lock); | ||
61 | 62 | ||
62 | down(&attribute_container_mutex); | 63 | down(&attribute_container_mutex); |
63 | list_add_tail(&cont->node, &attribute_container_list); | 64 | list_add_tail(&cont->node, &attribute_container_list); |
@@ -77,11 +78,13 @@ attribute_container_unregister(struct attribute_container *cont) | |||
77 | { | 78 | { |
78 | int retval = -EBUSY; | 79 | int retval = -EBUSY; |
79 | down(&attribute_container_mutex); | 80 | down(&attribute_container_mutex); |
81 | spin_lock(&cont->containers_lock); | ||
80 | if (!list_empty(&cont->containers)) | 82 | if (!list_empty(&cont->containers)) |
81 | goto out; | 83 | goto out; |
82 | retval = 0; | 84 | retval = 0; |
83 | list_del(&cont->node); | 85 | list_del(&cont->node); |
84 | out: | 86 | out: |
87 | spin_unlock(&cont->containers_lock); | ||
85 | up(&attribute_container_mutex); | 88 | up(&attribute_container_mutex); |
86 | return retval; | 89 | return retval; |
87 | 90 | ||
@@ -151,7 +154,9 @@ attribute_container_add_device(struct device *dev, | |||
151 | fn(cont, dev, &ic->classdev); | 154 | fn(cont, dev, &ic->classdev); |
152 | else | 155 | else |
153 | attribute_container_add_class_device(&ic->classdev); | 156 | attribute_container_add_class_device(&ic->classdev); |
157 | spin_lock(&cont->containers_lock); | ||
154 | list_add_tail(&ic->node, &cont->containers); | 158 | list_add_tail(&ic->node, &cont->containers); |
159 | spin_unlock(&cont->containers_lock); | ||
155 | } | 160 | } |
156 | up(&attribute_container_mutex); | 161 | up(&attribute_container_mutex); |
157 | } | 162 | } |
@@ -189,6 +194,7 @@ attribute_container_remove_device(struct device *dev, | |||
189 | 194 | ||
190 | if (!cont->match(cont, dev)) | 195 | if (!cont->match(cont, dev)) |
191 | continue; | 196 | continue; |
197 | spin_lock(&cont->containers_lock); | ||
192 | list_for_each_entry_safe(ic, tmp, &cont->containers, node) { | 198 | list_for_each_entry_safe(ic, tmp, &cont->containers, node) { |
193 | if (dev != ic->classdev.dev) | 199 | if (dev != ic->classdev.dev) |
194 | continue; | 200 | continue; |
@@ -200,6 +206,7 @@ attribute_container_remove_device(struct device *dev, | |||
200 | class_device_unregister(&ic->classdev); | 206 | class_device_unregister(&ic->classdev); |
201 | } | 207 | } |
202 | } | 208 | } |
209 | spin_unlock(&cont->containers_lock); | ||
203 | } | 210 | } |
204 | up(&attribute_container_mutex); | 211 | up(&attribute_container_mutex); |
205 | } | 212 | } |
@@ -230,10 +237,12 @@ attribute_container_device_trigger(struct device *dev, | |||
230 | if (!cont->match(cont, dev)) | 237 | if (!cont->match(cont, dev)) |
231 | continue; | 238 | continue; |
232 | 239 | ||
240 | spin_lock(&cont->containers_lock); | ||
233 | list_for_each_entry_safe(ic, tmp, &cont->containers, node) { | 241 | list_for_each_entry_safe(ic, tmp, &cont->containers, node) { |
234 | if (dev == ic->classdev.dev) | 242 | if (dev == ic->classdev.dev) |
235 | fn(cont, dev, &ic->classdev); | 243 | fn(cont, dev, &ic->classdev); |
236 | } | 244 | } |
245 | spin_unlock(&cont->containers_lock); | ||
237 | } | 246 | } |
238 | up(&attribute_container_mutex); | 247 | up(&attribute_container_mutex); |
239 | } | 248 | } |
@@ -368,6 +377,35 @@ attribute_container_class_device_del(struct class_device *classdev) | |||
368 | } | 377 | } |
369 | EXPORT_SYMBOL_GPL(attribute_container_class_device_del); | 378 | EXPORT_SYMBOL_GPL(attribute_container_class_device_del); |
370 | 379 | ||
380 | /** | ||
381 | * attribute_container_find_class_device - find the corresponding class_device | ||
382 | * | ||
383 | * @cont: the container | ||
384 | * @dev: the generic device | ||
385 | * | ||
386 | * Looks up the device in the container's list of class devices and returns | ||
387 | * the corresponding class_device. | ||
388 | */ | ||
389 | struct class_device * | ||
390 | attribute_container_find_class_device(struct attribute_container *cont, | ||
391 | struct device *dev) | ||
392 | { | ||
393 | struct class_device *cdev = NULL; | ||
394 | struct internal_container *ic; | ||
395 | |||
396 | spin_lock(&cont->containers_lock); | ||
397 | list_for_each_entry(ic, &cont->containers, node) { | ||
398 | if (ic->classdev.dev == dev) { | ||
399 | cdev = &ic->classdev; | ||
400 | break; | ||
401 | } | ||
402 | } | ||
403 | spin_unlock(&cont->containers_lock); | ||
404 | |||
405 | return cdev; | ||
406 | } | ||
407 | EXPORT_SYMBOL_GPL(attribute_container_find_class_device); | ||
408 | |||
371 | int __init | 409 | int __init |
372 | attribute_container_init(void) | 410 | attribute_container_init(void) |
373 | { | 411 | { |