diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:28:45 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-02-11 13:28:45 -0500 |
commit | 540a7c5061f10a07748c89b6741af90db1a07252 (patch) | |
tree | 27285b973326f894980e029cb5f726e8865e1443 /drivers/misc | |
parent | 718749d56214aa97015fe01b76b6d6dd0c171796 (diff) | |
parent | 9c4a6b1e42801343535ccab4c190019d9975cce8 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley:
"This is the usual grab bag of driver updates (hpsa, storvsc, mp2sas,
megaraid_sas, ses) plus an assortment of minor updates.
There's also an update to ufs which adds new phy drivers and finally a
new logging infrastructure for SCSI"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (114 commits)
scsi_logging: return void for dev_printk() functions
scsi: print single-character strings with seq_putc
scsi: merge consecutive seq_puts calls
scsi: replace seq_printf with seq_puts
aha152x: replace seq_printf with seq_puts
advansys: replace seq_printf with seq_puts
scsi: remove SPRINTF macro
sg: remove an unused variable
hpsa: Use local workqueues instead of system workqueues
hpsa: add in P840ar controller model name
hpsa: add in gen9 controller model names
hpsa: detect and report failures changing controller transport modes
hpsa: shorten the wait for the CISS doorbell mode change ack
hpsa: refactor duplicated scan completion code into a new routine
hpsa: move SG descriptor set-up out of hpsa_scatter_gather()
hpsa: do not use function pointers in fast path command submission
hpsa: print CDBs instead of kernel virtual addresses for uncommon errors
hpsa: do not use a void pointer for scsi_cmd field of struct CommandList
hpsa: return failed from device reset/abort handlers
hpsa: check for ctlr lockup after command allocation in main io path
...
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/enclosure.c | 108 |
1 files changed, 96 insertions, 12 deletions
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 180a5442fd4b..38552a31304a 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c | |||
@@ -145,8 +145,11 @@ enclosure_register(struct device *dev, const char *name, int components, | |||
145 | if (err) | 145 | if (err) |
146 | goto err; | 146 | goto err; |
147 | 147 | ||
148 | for (i = 0; i < components; i++) | 148 | for (i = 0; i < components; i++) { |
149 | edev->component[i].number = -1; | 149 | edev->component[i].number = -1; |
150 | edev->component[i].slot = -1; | ||
151 | edev->component[i].power_status = 1; | ||
152 | } | ||
150 | 153 | ||
151 | mutex_lock(&container_list_lock); | 154 | mutex_lock(&container_list_lock); |
152 | list_add_tail(&edev->node, &container_list); | 155 | list_add_tail(&edev->node, &container_list); |
@@ -273,27 +276,26 @@ enclosure_component_find_by_name(struct enclosure_device *edev, | |||
273 | static const struct attribute_group *enclosure_component_groups[]; | 276 | static const struct attribute_group *enclosure_component_groups[]; |
274 | 277 | ||
275 | /** | 278 | /** |
276 | * enclosure_component_register - add a particular component to an enclosure | 279 | * enclosure_component_alloc - prepare a new enclosure component |
277 | * @edev: the enclosure to add the component | 280 | * @edev: the enclosure to add the component |
278 | * @num: the device number | 281 | * @num: the device number |
279 | * @type: the type of component being added | 282 | * @type: the type of component being added |
280 | * @name: an optional name to appear in sysfs (leave NULL if none) | 283 | * @name: an optional name to appear in sysfs (leave NULL if none) |
281 | * | 284 | * |
282 | * Registers the component. The name is optional for enclosures that | 285 | * The name is optional for enclosures that give their components a unique |
283 | * give their components a unique name. If not, leave the field NULL | 286 | * name. If not, leave the field NULL and a name will be assigned. |
284 | * and a name will be assigned. | ||
285 | * | 287 | * |
286 | * Returns a pointer to the enclosure component or an error. | 288 | * Returns a pointer to the enclosure component or an error. |
287 | */ | 289 | */ |
288 | struct enclosure_component * | 290 | struct enclosure_component * |
289 | enclosure_component_register(struct enclosure_device *edev, | 291 | enclosure_component_alloc(struct enclosure_device *edev, |
290 | unsigned int number, | 292 | unsigned int number, |
291 | enum enclosure_component_type type, | 293 | enum enclosure_component_type type, |
292 | const char *name) | 294 | const char *name) |
293 | { | 295 | { |
294 | struct enclosure_component *ecomp; | 296 | struct enclosure_component *ecomp; |
295 | struct device *cdev; | 297 | struct device *cdev; |
296 | int err, i; | 298 | int i; |
297 | char newname[COMPONENT_NAME_SIZE]; | 299 | char newname[COMPONENT_NAME_SIZE]; |
298 | 300 | ||
299 | if (number >= edev->components) | 301 | if (number >= edev->components) |
@@ -327,14 +329,30 @@ enclosure_component_register(struct enclosure_device *edev, | |||
327 | cdev->release = enclosure_component_release; | 329 | cdev->release = enclosure_component_release; |
328 | cdev->groups = enclosure_component_groups; | 330 | cdev->groups = enclosure_component_groups; |
329 | 331 | ||
332 | return ecomp; | ||
333 | } | ||
334 | EXPORT_SYMBOL_GPL(enclosure_component_alloc); | ||
335 | |||
336 | /** | ||
337 | * enclosure_component_register - publishes an initialized enclosure component | ||
338 | * @ecomp: component to add | ||
339 | * | ||
340 | * Returns 0 on successful registration, releases the component otherwise | ||
341 | */ | ||
342 | int enclosure_component_register(struct enclosure_component *ecomp) | ||
343 | { | ||
344 | struct device *cdev; | ||
345 | int err; | ||
346 | |||
347 | cdev = &ecomp->cdev; | ||
330 | err = device_register(cdev); | 348 | err = device_register(cdev); |
331 | if (err) { | 349 | if (err) { |
332 | ecomp->number = -1; | 350 | ecomp->number = -1; |
333 | put_device(cdev); | 351 | put_device(cdev); |
334 | return ERR_PTR(err); | 352 | return err; |
335 | } | 353 | } |
336 | 354 | ||
337 | return ecomp; | 355 | return 0; |
338 | } | 356 | } |
339 | EXPORT_SYMBOL_GPL(enclosure_component_register); | 357 | EXPORT_SYMBOL_GPL(enclosure_component_register); |
340 | 358 | ||
@@ -417,8 +435,21 @@ static ssize_t components_show(struct device *cdev, | |||
417 | } | 435 | } |
418 | static DEVICE_ATTR_RO(components); | 436 | static DEVICE_ATTR_RO(components); |
419 | 437 | ||
438 | static ssize_t id_show(struct device *cdev, | ||
439 | struct device_attribute *attr, | ||
440 | char *buf) | ||
441 | { | ||
442 | struct enclosure_device *edev = to_enclosure_device(cdev); | ||
443 | |||
444 | if (edev->cb->show_id) | ||
445 | return edev->cb->show_id(edev, buf); | ||
446 | return -EINVAL; | ||
447 | } | ||
448 | static DEVICE_ATTR_RO(id); | ||
449 | |||
420 | static struct attribute *enclosure_class_attrs[] = { | 450 | static struct attribute *enclosure_class_attrs[] = { |
421 | &dev_attr_components.attr, | 451 | &dev_attr_components.attr, |
452 | &dev_attr_id.attr, | ||
422 | NULL, | 453 | NULL, |
423 | }; | 454 | }; |
424 | ATTRIBUTE_GROUPS(enclosure_class); | 455 | ATTRIBUTE_GROUPS(enclosure_class); |
@@ -553,6 +584,40 @@ static ssize_t set_component_locate(struct device *cdev, | |||
553 | return count; | 584 | return count; |
554 | } | 585 | } |
555 | 586 | ||
587 | static ssize_t get_component_power_status(struct device *cdev, | ||
588 | struct device_attribute *attr, | ||
589 | char *buf) | ||
590 | { | ||
591 | struct enclosure_device *edev = to_enclosure_device(cdev->parent); | ||
592 | struct enclosure_component *ecomp = to_enclosure_component(cdev); | ||
593 | |||
594 | if (edev->cb->get_power_status) | ||
595 | edev->cb->get_power_status(edev, ecomp); | ||
596 | return snprintf(buf, 40, "%s\n", ecomp->power_status ? "on" : "off"); | ||
597 | } | ||
598 | |||
599 | static ssize_t set_component_power_status(struct device *cdev, | ||
600 | struct device_attribute *attr, | ||
601 | const char *buf, size_t count) | ||
602 | { | ||
603 | struct enclosure_device *edev = to_enclosure_device(cdev->parent); | ||
604 | struct enclosure_component *ecomp = to_enclosure_component(cdev); | ||
605 | int val; | ||
606 | |||
607 | if (strncmp(buf, "on", 2) == 0 && | ||
608 | (buf[2] == '\n' || buf[2] == '\0')) | ||
609 | val = 1; | ||
610 | else if (strncmp(buf, "off", 3) == 0 && | ||
611 | (buf[3] == '\n' || buf[3] == '\0')) | ||
612 | val = 0; | ||
613 | else | ||
614 | return -EINVAL; | ||
615 | |||
616 | if (edev->cb->set_power_status) | ||
617 | edev->cb->set_power_status(edev, ecomp, val); | ||
618 | return count; | ||
619 | } | ||
620 | |||
556 | static ssize_t get_component_type(struct device *cdev, | 621 | static ssize_t get_component_type(struct device *cdev, |
557 | struct device_attribute *attr, char *buf) | 622 | struct device_attribute *attr, char *buf) |
558 | { | 623 | { |
@@ -561,6 +626,20 @@ static ssize_t get_component_type(struct device *cdev, | |||
561 | return snprintf(buf, 40, "%s\n", enclosure_type[ecomp->type]); | 626 | return snprintf(buf, 40, "%s\n", enclosure_type[ecomp->type]); |
562 | } | 627 | } |
563 | 628 | ||
629 | static ssize_t get_component_slot(struct device *cdev, | ||
630 | struct device_attribute *attr, char *buf) | ||
631 | { | ||
632 | struct enclosure_component *ecomp = to_enclosure_component(cdev); | ||
633 | int slot; | ||
634 | |||
635 | /* if the enclosure does not override then use 'number' as a stand-in */ | ||
636 | if (ecomp->slot >= 0) | ||
637 | slot = ecomp->slot; | ||
638 | else | ||
639 | slot = ecomp->number; | ||
640 | |||
641 | return snprintf(buf, 40, "%d\n", slot); | ||
642 | } | ||
564 | 643 | ||
565 | static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault, | 644 | static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault, |
566 | set_component_fault); | 645 | set_component_fault); |
@@ -570,14 +649,19 @@ static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active, | |||
570 | set_component_active); | 649 | set_component_active); |
571 | static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, | 650 | static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, |
572 | set_component_locate); | 651 | set_component_locate); |
652 | static DEVICE_ATTR(power_status, S_IRUGO | S_IWUSR, get_component_power_status, | ||
653 | set_component_power_status); | ||
573 | static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL); | 654 | static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL); |
655 | static DEVICE_ATTR(slot, S_IRUGO, get_component_slot, NULL); | ||
574 | 656 | ||
575 | static struct attribute *enclosure_component_attrs[] = { | 657 | static struct attribute *enclosure_component_attrs[] = { |
576 | &dev_attr_fault.attr, | 658 | &dev_attr_fault.attr, |
577 | &dev_attr_status.attr, | 659 | &dev_attr_status.attr, |
578 | &dev_attr_active.attr, | 660 | &dev_attr_active.attr, |
579 | &dev_attr_locate.attr, | 661 | &dev_attr_locate.attr, |
662 | &dev_attr_power_status.attr, | ||
580 | &dev_attr_type.attr, | 663 | &dev_attr_type.attr, |
664 | &dev_attr_slot.attr, | ||
581 | NULL | 665 | NULL |
582 | }; | 666 | }; |
583 | ATTRIBUTE_GROUPS(enclosure_component); | 667 | ATTRIBUTE_GROUPS(enclosure_component); |