aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Stockhausen <stockhausen@collogia.de>2014-10-04 09:35:15 -0400
committerChristoph Hellwig <hch@lst.de>2014-11-12 05:15:55 -0500
commitd2fd76e6f60ce438e98512236138a3527ad6a736 (patch)
tree0e6f008a96adebdf5a32fee3d9699bc3a7943e17
parent2bec708a88ce053ffcb0dd8e373d1e46c6dc38a4 (diff)
enclosure: handle non-unique element descriptors
Some SES devices give non-unique Element Descriptors as part of the Element Descriptor diag page. Since we use these for creating sysfs entries, they need to be unique. The specification doesn't require these to be unique. Eg: $ sg_ses -p 7 /dev/sg0 FTS CORP TXS6_SAS20BPX12 0500 enclosure services device Element descriptor In diagnostic page: generation code: 0x0 element descriptor by type list Element type: Array device, subenclosure id: 0 Overall descriptor: ArrayDevicesInSubEnclsr0 Element 1 descriptor: ArrayDevice00 Element 2 descriptor: ArrayDevice01 Element 3 descriptor: ArrayDevice02 Element 4 descriptor: ArrayDevice03 Element 5 descriptor: ArrayDevice03 Element 6 descriptor: ArrayDevice03 Element 7 descriptor: ArrayDevice03 Element 8 descriptor: ArrayDevice03 Element 9 descriptor: ArrayDevice03 Element 10 descriptor: ArrayDevice03 Element 11 descriptor: ArrayDevice03 Element 12 descriptor: ArrayDevice03 Based on http://thread.gmane.org/gmane.linux.scsi/69289. This version implements James' ideas about the naming convention Signed-off-by: Markus Stockhausen <stockhausen@collogia.de> Acked-by: James Bottomley <James.Bottomley@HansenPartnership.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
-rw-r--r--drivers/misc/enclosure.c44
1 files changed, 40 insertions, 4 deletions
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 2cf2bbc0b927..180a5442fd4b 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -187,6 +187,7 @@ void enclosure_unregister(struct enclosure_device *edev)
187EXPORT_SYMBOL_GPL(enclosure_unregister); 187EXPORT_SYMBOL_GPL(enclosure_unregister);
188 188
189#define ENCLOSURE_NAME_SIZE 64 189#define ENCLOSURE_NAME_SIZE 64
190#define COMPONENT_NAME_SIZE 64
190 191
191static void enclosure_link_name(struct enclosure_component *cdev, char *name) 192static void enclosure_link_name(struct enclosure_component *cdev, char *name)
192{ 193{
@@ -246,6 +247,29 @@ static void enclosure_component_release(struct device *dev)
246 put_device(dev->parent); 247 put_device(dev->parent);
247} 248}
248 249
250static struct enclosure_component *
251enclosure_component_find_by_name(struct enclosure_device *edev,
252 const char *name)
253{
254 int i;
255 const char *cname;
256 struct enclosure_component *ecomp;
257
258 if (!edev || !name || !name[0])
259 return NULL;
260
261 for (i = 0; i < edev->components; i++) {
262 ecomp = &edev->component[i];
263 cname = dev_name(&ecomp->cdev);
264 if (ecomp->number != -1 &&
265 cname && cname[0] &&
266 !strcmp(cname, name))
267 return ecomp;
268 }
269
270 return NULL;
271}
272
249static const struct attribute_group *enclosure_component_groups[]; 273static const struct attribute_group *enclosure_component_groups[];
250 274
251/** 275/**
@@ -269,7 +293,8 @@ enclosure_component_register(struct enclosure_device *edev,
269{ 293{
270 struct enclosure_component *ecomp; 294 struct enclosure_component *ecomp;
271 struct device *cdev; 295 struct device *cdev;
272 int err; 296 int err, i;
297 char newname[COMPONENT_NAME_SIZE];
273 298
274 if (number >= edev->components) 299 if (number >= edev->components)
275 return ERR_PTR(-EINVAL); 300 return ERR_PTR(-EINVAL);
@@ -283,9 +308,20 @@ enclosure_component_register(struct enclosure_device *edev,
283 ecomp->number = number; 308 ecomp->number = number;
284 cdev = &ecomp->cdev; 309 cdev = &ecomp->cdev;
285 cdev->parent = get_device(&edev->edev); 310 cdev->parent = get_device(&edev->edev);
286 if (name && name[0]) 311
287 dev_set_name(cdev, "%s", name); 312 if (name && name[0]) {
288 else 313 /* Some hardware (e.g. enclosure in RX300 S6) has components
314 * with non unique names. Registering duplicates in sysfs
315 * will lead to warnings during bootup. So make the names
316 * unique by appending consecutive numbers -1, -2, ... */
317 i = 1;
318 snprintf(newname, COMPONENT_NAME_SIZE,
319 "%s", name);
320 while (enclosure_component_find_by_name(edev, newname))
321 snprintf(newname, COMPONENT_NAME_SIZE,
322 "%s-%i", name, i++);
323 dev_set_name(cdev, "%s", newname);
324 } else
289 dev_set_name(cdev, "%u", number); 325 dev_set_name(cdev, "%u", number);
290 326
291 cdev->release = enclosure_component_release; 327 cdev->release = enclosure_component_release;