aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Bottomley <James.Bottomley@steeleye.com>2005-08-14 18:09:01 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-08-14 18:21:27 -0400
commitd0a7e574007fd547d72ec693bfa35778623d0738 (patch)
tree3457bdf4e8eaf870971aab03c99c31534ba85658 /drivers
parent10c1b88987d618f4f89c10e11e574c76de73b5e7 (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')
-rw-r--r--drivers/base/attribute_container.c38
-rw-r--r--drivers/base/transport_class.c17
-rw-r--r--drivers/scsi/scsi_transport_fc.c6
-rw-r--r--drivers/scsi/scsi_transport_spi.c11
4 files changed, 61 insertions, 11 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}
369EXPORT_SYMBOL_GPL(attribute_container_class_device_del); 378EXPORT_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 */
389struct class_device *
390attribute_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}
407EXPORT_SYMBOL_GPL(attribute_container_find_class_device);
408
371int __init 409int __init
372attribute_container_init(void) 410attribute_container_init(void)
373{ 411{
diff --git a/drivers/base/transport_class.c b/drivers/base/transport_class.c
index 6c2b447a3336..4fb4c5de8470 100644
--- a/drivers/base/transport_class.c
+++ b/drivers/base/transport_class.c
@@ -64,7 +64,9 @@ void transport_class_unregister(struct transport_class *tclass)
64} 64}
65EXPORT_SYMBOL_GPL(transport_class_unregister); 65EXPORT_SYMBOL_GPL(transport_class_unregister);
66 66
67static int anon_transport_dummy_function(struct device *dev) 67static int anon_transport_dummy_function(struct transport_container *tc,
68 struct device *dev,
69 struct class_device *cdev)
68{ 70{
69 /* do nothing */ 71 /* do nothing */
70 return 0; 72 return 0;
@@ -115,9 +117,10 @@ static int transport_setup_classdev(struct attribute_container *cont,
115 struct class_device *classdev) 117 struct class_device *classdev)
116{ 118{
117 struct transport_class *tclass = class_to_transport_class(cont->class); 119 struct transport_class *tclass = class_to_transport_class(cont->class);
120 struct transport_container *tcont = attribute_container_to_transport_container(cont);
118 121
119 if (tclass->setup) 122 if (tclass->setup)
120 tclass->setup(dev); 123 tclass->setup(tcont, dev, classdev);
121 124
122 return 0; 125 return 0;
123} 126}
@@ -178,12 +181,14 @@ void transport_add_device(struct device *dev)
178EXPORT_SYMBOL_GPL(transport_add_device); 181EXPORT_SYMBOL_GPL(transport_add_device);
179 182
180static int transport_configure(struct attribute_container *cont, 183static int transport_configure(struct attribute_container *cont,
181 struct device *dev) 184 struct device *dev,
185 struct class_device *cdev)
182{ 186{
183 struct transport_class *tclass = class_to_transport_class(cont->class); 187 struct transport_class *tclass = class_to_transport_class(cont->class);
188 struct transport_container *tcont = attribute_container_to_transport_container(cont);
184 189
185 if (tclass->configure) 190 if (tclass->configure)
186 tclass->configure(dev); 191 tclass->configure(tcont, dev, cdev);
187 192
188 return 0; 193 return 0;
189} 194}
@@ -202,7 +207,7 @@ static int transport_configure(struct attribute_container *cont,
202 */ 207 */
203void transport_configure_device(struct device *dev) 208void transport_configure_device(struct device *dev)
204{ 209{
205 attribute_container_trigger(dev, transport_configure); 210 attribute_container_device_trigger(dev, transport_configure);
206} 211}
207EXPORT_SYMBOL_GPL(transport_configure_device); 212EXPORT_SYMBOL_GPL(transport_configure_device);
208 213
@@ -215,7 +220,7 @@ static int transport_remove_classdev(struct attribute_container *cont,
215 struct transport_class *tclass = class_to_transport_class(cont->class); 220 struct transport_class *tclass = class_to_transport_class(cont->class);
216 221
217 if (tclass->remove) 222 if (tclass->remove)
218 tclass->remove(dev); 223 tclass->remove(tcont, dev, classdev);
219 224
220 if (tclass->remove != anon_transport_dummy_function) { 225 if (tclass->remove != anon_transport_dummy_function) {
221 if (tcont->statistics) 226 if (tcont->statistics)
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 35d1c1e8e345..96243c7fe110 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -252,7 +252,8 @@ struct fc_internal {
252 252
253#define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t) 253#define to_fc_internal(tmpl) container_of(tmpl, struct fc_internal, t)
254 254
255static int fc_target_setup(struct device *dev) 255static int fc_target_setup(struct transport_container *tc, struct device *dev,
256 struct class_device *cdev)
256{ 257{
257 struct scsi_target *starget = to_scsi_target(dev); 258 struct scsi_target *starget = to_scsi_target(dev);
258 struct fc_rport *rport = starget_to_rport(starget); 259 struct fc_rport *rport = starget_to_rport(starget);
@@ -281,7 +282,8 @@ static DECLARE_TRANSPORT_CLASS(fc_transport_class,
281 NULL, 282 NULL,
282 NULL); 283 NULL);
283 284
284static int fc_host_setup(struct device *dev) 285static int fc_host_setup(struct transport_container *tc, struct device *dev,
286 struct class_device *cdev)
285{ 287{
286 struct Scsi_Host *shost = dev_to_shost(dev); 288 struct Scsi_Host *shost = dev_to_shost(dev);
287 289
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 02134fce2174..89f6b7feb9c2 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -162,7 +162,8 @@ static inline enum spi_signal_type spi_signal_to_value(const char *name)
162 return SPI_SIGNAL_UNKNOWN; 162 return SPI_SIGNAL_UNKNOWN;
163} 163}
164 164
165static int spi_host_setup(struct device *dev) 165static int spi_host_setup(struct transport_container *tc, struct device *dev,
166 struct class_device *cdev)
166{ 167{
167 struct Scsi_Host *shost = dev_to_shost(dev); 168 struct Scsi_Host *shost = dev_to_shost(dev);
168 169
@@ -196,7 +197,9 @@ static int spi_host_match(struct attribute_container *cont,
196 return &i->t.host_attrs.ac == cont; 197 return &i->t.host_attrs.ac == cont;
197} 198}
198 199
199static int spi_device_configure(struct device *dev) 200static int spi_device_configure(struct transport_container *tc,
201 struct device *dev,
202 struct class_device *cdev)
200{ 203{
201 struct scsi_device *sdev = to_scsi_device(dev); 204 struct scsi_device *sdev = to_scsi_device(dev);
202 struct scsi_target *starget = sdev->sdev_target; 205 struct scsi_target *starget = sdev->sdev_target;
@@ -214,7 +217,9 @@ static int spi_device_configure(struct device *dev)
214 return 0; 217 return 0;
215} 218}
216 219
217static int spi_setup_transport_attrs(struct device *dev) 220static int spi_setup_transport_attrs(struct transport_container *tc,
221 struct device *dev,
222 struct class_device *cdev)
218{ 223{
219 struct scsi_target *starget = to_scsi_target(dev); 224 struct scsi_target *starget = to_scsi_target(dev);
220 225