diff options
author | Song Liu <songliubraving@fb.com> | 2014-12-30 14:46:18 -0800 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-01-09 15:44:19 +0100 |
commit | 08024885a2a3ed432716e9d50046a620a5b2df05 (patch) | |
tree | 52e0042dac2c8651641987da49163908c3305e74 /drivers/misc/enclosure.c | |
parent | 921ce7f5786052749a22a75780f5ce1a456bcdc6 (diff) |
ses: Add power_status to SES device slot
Add power_status to SES device slot, so we can power on/off the
HDDs behind the enclosure.
Check firmware status in ses_set_* before sending control pages to
firmware.
Signed-off-by: Song Liu <songliubraving@fb.com>
Acked-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Jens Axboe <axboe@fb.com>
Cc: Hannes Reinecke <hare@suse.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'drivers/misc/enclosure.c')
-rw-r--r-- | drivers/misc/enclosure.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index b62314d627ae..38552a31304a 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c @@ -148,6 +148,7 @@ enclosure_register(struct device *dev, const char *name, int components, for (i = 0; i < components; i++) { edev->component[i].number = -1; edev->component[i].slot = -1; + edev->component[i].power_status = 1; } mutex_lock(&container_list_lock); @@ -583,6 +584,40 @@ static ssize_t set_component_locate(struct device *cdev, return count; } +static ssize_t get_component_power_status(struct device *cdev, + struct device_attribute *attr, + char *buf) +{ + struct enclosure_device *edev = to_enclosure_device(cdev->parent); + struct enclosure_component *ecomp = to_enclosure_component(cdev); + + if (edev->cb->get_power_status) + edev->cb->get_power_status(edev, ecomp); + return snprintf(buf, 40, "%s\n", ecomp->power_status ? "on" : "off"); +} + +static ssize_t set_component_power_status(struct device *cdev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct enclosure_device *edev = to_enclosure_device(cdev->parent); + struct enclosure_component *ecomp = to_enclosure_component(cdev); + int val; + + if (strncmp(buf, "on", 2) == 0 && + (buf[2] == '\n' || buf[2] == '\0')) + val = 1; + else if (strncmp(buf, "off", 3) == 0 && + (buf[3] == '\n' || buf[3] == '\0')) + val = 0; + else + return -EINVAL; + + if (edev->cb->set_power_status) + edev->cb->set_power_status(edev, ecomp, val); + return count; +} + static ssize_t get_component_type(struct device *cdev, struct device_attribute *attr, char *buf) { @@ -614,6 +649,8 @@ static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active, set_component_active); static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate, set_component_locate); +static DEVICE_ATTR(power_status, S_IRUGO | S_IWUSR, get_component_power_status, + set_component_power_status); static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL); static DEVICE_ATTR(slot, S_IRUGO, get_component_slot, NULL); @@ -622,6 +659,7 @@ static struct attribute *enclosure_component_attrs[] = { &dev_attr_status.attr, &dev_attr_active.attr, &dev_attr_locate.attr, + &dev_attr_power_status.attr, &dev_attr_type.attr, &dev_attr_slot.attr, NULL |