aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 13:28:45 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-02-11 13:28:45 -0500
commit540a7c5061f10a07748c89b6741af90db1a07252 (patch)
tree27285b973326f894980e029cb5f726e8865e1443 /drivers/misc
parent718749d56214aa97015fe01b76b6d6dd0c171796 (diff)
parent9c4a6b1e42801343535ccab4c190019d9975cce8 (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.c108
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,
273static const struct attribute_group *enclosure_component_groups[]; 276static 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 */
288struct enclosure_component * 290struct enclosure_component *
289enclosure_component_register(struct enclosure_device *edev, 291enclosure_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}
334EXPORT_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 */
342int 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}
339EXPORT_SYMBOL_GPL(enclosure_component_register); 357EXPORT_SYMBOL_GPL(enclosure_component_register);
340 358
@@ -417,8 +435,21 @@ static ssize_t components_show(struct device *cdev,
417} 435}
418static DEVICE_ATTR_RO(components); 436static DEVICE_ATTR_RO(components);
419 437
438static 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}
448static DEVICE_ATTR_RO(id);
449
420static struct attribute *enclosure_class_attrs[] = { 450static 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};
424ATTRIBUTE_GROUPS(enclosure_class); 455ATTRIBUTE_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
587static 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
599static 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
556static ssize_t get_component_type(struct device *cdev, 621static 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
629static 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
565static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault, 644static 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);
571static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, 650static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
572 set_component_locate); 651 set_component_locate);
652static DEVICE_ATTR(power_status, S_IRUGO | S_IWUSR, get_component_power_status,
653 set_component_power_status);
573static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL); 654static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
655static DEVICE_ATTR(slot, S_IRUGO, get_component_slot, NULL);
574 656
575static struct attribute *enclosure_component_attrs[] = { 657static 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};
583ATTRIBUTE_GROUPS(enclosure_component); 667ATTRIBUTE_GROUPS(enclosure_component);