* [PATCH 0/5] Feature enhancements for ses module
@ 2014-12-30 22:46 Song Liu
2014-12-30 22:46 ` [PATCH 1/5] ses: close potential registration race Song Liu
` (5 more replies)
0 siblings, 6 replies; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Song Liu
1: close potential race condition by at enclosure race condition
2,3,4: add enclosure id and device slot, so we can create symlink
in /dev/disk/by-slot:
# ls -d /dev/disk/by-slot/*
/dev/disk/by-slot/enclosure-0x5000ae41fc1310ff-slot0
5: add ability to power on/off device with power_status file in
sysfs.
Due to the complexity of SES standard, the module is not to replace implement \
all features of sg_ses (sg3_utils).
Patch 5 and existing features for device element and array device elements control \
of HDDs. It is helpful to handle some HDD related fields in the kernel, as the \
kernel can generate mapping between a device to the SES device element (or array \
device element):
/sys/block/sdc/device/enclosure_deviceXXX/
With patch 5, we can easily power off a running HDD by
echo off > /sys/block/sdc/device/enclosure_deviceXXX/power_status
This is very useful for systems like Cold Storage, where HDDs are being powered \
on/off frequently
Dan Williams (4):
ses: close potential registration race
ses: generate KOBJ_CHANGE on enclosure attach
ses: add enclosure logical id
ses: add reliable slot attribute
Song Liu (1):
ses: Add power_status to SES device slot
drivers/misc/enclosure.c | 106 +++++++++++++++++++++++++++++----
drivers/scsi/ses.c | 148 +++++++++++++++++++++++++++++++++++++++-------
include/linux/enclosure.h | 13 +++-
3 files changed, 232 insertions(+), 35 deletions(-)
--
1.8.1
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/5] ses: close potential registration race
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
@ 2014-12-30 22:46 ` Song Liu
2015-01-10 13:26 ` Hannes Reinecke
2014-12-30 22:46 ` [PATCH 2/5] ses: generate KOBJ_CHANGE on enclosure attach Song Liu
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Dan Williams, Song Liu
From: Dan Williams <dan.j.williams@intel.com>
The slot and address fields have a small window of instability when
userspace can read them before initialization. Separate
enclosure_component
allocation from registration.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Jens Axboe <axboe@fb.com>
Cc: Hannes Reinecke <hare@suse.de>
---
drivers/misc/enclosure.c | 35 +++++++++++++++++++++++++----------
drivers/scsi/ses.c | 21 ++++++++++++++-------
include/linux/enclosure.h | 5 +++--
3 files changed, 42 insertions(+), 19 deletions(-)
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index 180a544..d566f0f 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -273,23 +273,22 @@ enclosure_component_find_by_name(struct enclosure_device *edev,
static const struct attribute_group *enclosure_component_groups[];
/**
- * enclosure_component_register - add a particular component to an enclosure
+ * enclosure_component_alloc - prepare a new enclosure component
* @edev: the enclosure to add the component
* @num: the device number
* @type: the type of component being added
* @name: an optional name to appear in sysfs (leave NULL if none)
*
- * Registers the component. The name is optional for enclosures that
- * give their components a unique name. If not, leave the field NULL
- * and a name will be assigned.
+ * The name is optional for enclosures that give their components a unique
+ * name. If not, leave the field NULL and a name will be assigned.
*
* Returns a pointer to the enclosure component or an error.
*/
struct enclosure_component *
-enclosure_component_register(struct enclosure_device *edev,
- unsigned int number,
- enum enclosure_component_type type,
- const char *name)
+enclosure_component_alloc(struct enclosure_device *edev,
+ unsigned int number,
+ enum enclosure_component_type type,
+ const char *name)
{
struct enclosure_component *ecomp;
struct device *cdev;
@@ -327,14 +326,30 @@ enclosure_component_register(struct enclosure_device *edev,
cdev->release = enclosure_component_release;
cdev->groups = enclosure_component_groups;
+ return ecomp;
+}
+EXPORT_SYMBOL_GPL(enclosure_component_alloc);
+
+/**
+ * enclosure_component_register - publishes an initialized enclosure component
+ * @ecomp: component to add
+ *
+ * Returns 0 on successful registration, releases the component otherwise
+ */
+int enclosure_component_register(struct enclosure_component *ecomp)
+{
+ struct device *cdev;
+ int err;
+
+ cdev = &ecomp->cdev;
err = device_register(cdev);
if (err) {
ecomp->number = -1;
put_device(cdev);
- return ERR_PTR(err);
+ return err;
}
- return ecomp;
+ return 0;
}
EXPORT_SYMBOL_GPL(enclosure_component_register);
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index b7e79e7..7dd9cf5 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -423,16 +423,23 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
if (create)
- ecomp = enclosure_component_register(edev,
- components++,
- type_ptr[0],
- name);
+ ecomp = enclosure_component_alloc(
+ edev,
+ components++,
+ type_ptr[0],
+ name);
else
ecomp = &edev->component[components++];
- if (!IS_ERR(ecomp) && addl_desc_ptr)
- ses_process_descriptor(ecomp,
- addl_desc_ptr);
+ if (!IS_ERR(ecomp)) {
+ if (addl_desc_ptr)
+ ses_process_descriptor(
+ ecomp,
+ addl_desc_ptr);
+ if (create)
+ enclosure_component_register(
+ ecomp);
+ }
}
if (desc_ptr)
desc_ptr += len;
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 9a33c5f..a835d33 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -120,8 +120,9 @@ enclosure_register(struct device *, const char *, int,
struct enclosure_component_callbacks *);
void enclosure_unregister(struct enclosure_device *);
struct enclosure_component *
-enclosure_component_register(struct enclosure_device *, unsigned int,
- enum enclosure_component_type, const char *);
+enclosure_component_alloc(struct enclosure_device *, unsigned int,
+ enum enclosure_component_type, const char *);
+int enclosure_component_register(struct enclosure_component *);
int enclosure_add_device(struct enclosure_device *enclosure, int component,
struct device *dev);
int enclosure_remove_device(struct enclosure_device *, struct device *);
--
1.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/5] ses: generate KOBJ_CHANGE on enclosure attach
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
2014-12-30 22:46 ` [PATCH 1/5] ses: close potential registration race Song Liu
@ 2014-12-30 22:46 ` Song Liu
2014-12-30 22:46 ` [PATCH 3/5] ses: add enclosure logical id Song Liu
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Dan Williams, Song Liu
From: Dan Williams <dan.j.williams@intel.com>
In support of a /dev/disk/by-slot populated with data from the enclosure
and ses modules udev needs notification when the new interface
files/links are available. Otherwise, any udev rules specified for the
disk cannot assume that the enclosure topology has settled.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Jens Axboe <axboe@fb.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/ses.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 7dd9cf5..6662b0c 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -349,7 +349,8 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
if (scomp->addr != efd->addr)
continue;
- enclosure_add_device(edev, i, efd->dev);
+ if (enclosure_add_device(edev, i, efd->dev) == 0)
+ kobject_uevent(&efd->dev->kobj, KOBJ_CHANGE);
return 1;
}
return 0;
--
1.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/5] ses: add enclosure logical id
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
2014-12-30 22:46 ` [PATCH 1/5] ses: close potential registration race Song Liu
2014-12-30 22:46 ` [PATCH 2/5] ses: generate KOBJ_CHANGE on enclosure attach Song Liu
@ 2014-12-30 22:46 ` Song Liu
2015-01-10 13:27 ` Hannes Reinecke
2014-12-30 22:46 ` [PATCH 4/5] ses: add reliable slot attribute Song Liu
` (2 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Dan Williams, Song Liu
From: Dan Williams <dan.j.williams@intel.com>
Export the NAA logical id for the enclosure. This is optionally
available from the sas_transport_class, but it is really a property of
the enclosure.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Jens Axboe <axboe@fb.com>
Cc: Hannes Reinecke <hare@suse.de>
---
drivers/misc/enclosure.c | 13 +++++++++++++
drivers/scsi/ses.c | 9 +++++++++
include/linux/enclosure.h | 1 +
3 files changed, 23 insertions(+)
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index d566f0f..ab4de85 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -432,8 +432,21 @@ static ssize_t components_show(struct device *cdev,
}
static DEVICE_ATTR_RO(components);
+static ssize_t id_show(struct device *cdev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct enclosure_device *edev = to_enclosure_device(cdev);
+
+ if (edev->cb->show_id)
+ return edev->cb->show_id(edev, buf);
+ return -EINVAL;
+}
+static DEVICE_ATTR_RO(id);
+
static struct attribute *enclosure_class_attrs[] = {
&dev_attr_components.attr,
+ &dev_attr_id.attr,
NULL,
};
ATTRIBUTE_GROUPS(enclosure_class);
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 6662b0c..1041556 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -258,6 +258,14 @@ static int ses_set_active(struct enclosure_device *edev,
return ses_set_page2_descriptor(edev, ecomp, desc);
}
+static int ses_show_id(struct enclosure_device *edev, char *buf)
+{
+ struct ses_device *ses_dev = edev->scratch;
+ unsigned long long id = get_unaligned_be64(ses_dev->page1+8+4);
+
+ return sprintf(buf, "%#llx\n", id);
+}
+
static struct enclosure_component_callbacks ses_enclosure_callbacks = {
.get_fault = ses_get_fault,
.set_fault = ses_set_fault,
@@ -265,6 +273,7 @@ static struct enclosure_component_callbacks ses_enclosure_callbacks = {
.get_locate = ses_get_locate,
.set_locate = ses_set_locate,
.set_active = ses_set_active,
+ .show_id = ses_show_id,
};
struct ses_host_edev {
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index a835d33..807622b 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -79,6 +79,7 @@ struct enclosure_component_callbacks {
int (*set_locate)(struct enclosure_device *,
struct enclosure_component *,
enum enclosure_component_setting);
+ int (*show_id)(struct enclosure_device *, char *buf);
};
--
1.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/5] ses: add reliable slot attribute
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
` (2 preceding siblings ...)
2014-12-30 22:46 ` [PATCH 3/5] ses: add enclosure logical id Song Liu
@ 2014-12-30 22:46 ` Song Liu
2014-12-30 22:46 ` [PATCH 5/5] ses: Add power_status to SES device slot Song Liu
2015-01-05 19:26 ` [PATCH 0/5] Feature enhancements for ses module Christoph Hellwig
5 siblings, 0 replies; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Dan Williams, Song Liu
From: Dan Williams <dan.j.williams@intel.com>
The name provided by firmware is in a vendor specific format, publish
the slot number to have a reliable mechanism for identifying slots
across firmware implementations. If the enclosure does not provide a
slot number fallback to the component number which is guaranteed unique,
and usually mirrors the slot number.
Cleaned up the unused ses_component.desc in the process.
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Jens Axboe <axboe@fb.com>
Reviewed-by: Hannes Reinecke <hare@suse.de>
---
drivers/misc/enclosure.c | 20 +++++++++++++++++++-
drivers/scsi/ses.c | 17 ++++++++++++-----
include/linux/enclosure.h | 1 +
3 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index ab4de85..b7995ed 100644
--- a/drivers/misc/enclosure.c
+++ b/drivers/misc/enclosure.c
@@ -145,8 +145,10 @@ enclosure_register(struct device *dev, const char *name, int components,
if (err)
goto err;
- for (i = 0; i < components; i++)
+ for (i = 0; i < components; i++) {
edev->component[i].number = -1;
+ edev->component[i].slot = -1;
+ }
mutex_lock(&container_list_lock);
list_add_tail(&edev->node, &container_list);
@@ -589,6 +591,20 @@ static ssize_t get_component_type(struct device *cdev,
return snprintf(buf, 40, "%s\n", enclosure_type[ecomp->type]);
}
+static ssize_t get_component_slot(struct device *cdev,
+ struct device_attribute *attr, char *buf)
+{
+ struct enclosure_component *ecomp = to_enclosure_component(cdev);
+ int slot;
+
+ /* if the enclosure does not override then use 'number' as a stand-in */
+ if (ecomp->slot >= 0)
+ slot = ecomp->slot;
+ else
+ slot = ecomp->number;
+
+ return snprintf(buf, 40, "%d\n", slot);
+}
static DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, get_component_fault,
set_component_fault);
@@ -599,6 +615,7 @@ static DEVICE_ATTR(active, S_IRUGO | S_IWUSR, get_component_active,
static DEVICE_ATTR(locate, S_IRUGO | S_IWUSR, get_component_locate,
set_component_locate);
static DEVICE_ATTR(type, S_IRUGO, get_component_type, NULL);
+static DEVICE_ATTR(slot, S_IRUGO, get_component_slot, NULL);
static struct attribute *enclosure_component_attrs[] = {
&dev_attr_fault.attr,
@@ -606,6 +623,7 @@ static struct attribute *enclosure_component_attrs[] = {
&dev_attr_active.attr,
&dev_attr_locate.attr,
&dev_attr_type.attr,
+ &dev_attr_slot.attr,
NULL
};
ATTRIBUTE_GROUPS(enclosure_component);
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 1041556..433de8e 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -47,7 +47,6 @@ struct ses_device {
struct ses_component {
u64 addr;
- unsigned char *desc;
};
static int ses_probe(struct device *dev)
@@ -307,19 +306,26 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
int invalid = desc[0] & 0x80;
enum scsi_protocol proto = desc[0] & 0x0f;
u64 addr = 0;
+ int slot = -1;
struct ses_component *scomp = ecomp->scratch;
unsigned char *d;
- scomp->desc = desc;
-
if (invalid)
return;
switch (proto) {
+ case SCSI_PROTOCOL_FCP:
+ if (eip) {
+ d = desc + 4;
+ slot = d[3];
+ }
+ break;
case SCSI_PROTOCOL_SAS:
- if (eip)
+ if (eip) {
+ d = desc + 4;
+ slot = d[3];
d = desc + 8;
- else
+ } else
d = desc + 4;
/* only take the phy0 addr */
addr = (u64)d[12] << 56 |
@@ -335,6 +341,7 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
/* FIXME: Need to add more protocols than just SAS */
break;
}
+ ecomp->slot = slot;
scomp->addr = addr;
}
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 807622b..0f826c1 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -92,6 +92,7 @@ struct enclosure_component {
int fault;
int active;
int locate;
+ int slot;
enum enclosure_status status;
};
--
1.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/5] ses: Add power_status to SES device slot
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
` (3 preceding siblings ...)
2014-12-30 22:46 ` [PATCH 4/5] ses: add reliable slot attribute Song Liu
@ 2014-12-30 22:46 ` Song Liu
2015-01-10 13:28 ` Hannes Reinecke
2015-01-05 19:26 ` [PATCH 0/5] Feature enhancements for ses module Christoph Hellwig
5 siblings, 1 reply; 10+ messages in thread
From: Song Liu @ 2014-12-30 22:46 UTC (permalink / raw)
To: linux-scsi; +Cc: hch, hare, dgilbert, Song Liu
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>
---
drivers/misc/enclosure.c | 38 ++++++++++++++++++
drivers/scsi/ses.c | 98 ++++++++++++++++++++++++++++++++++++++++++-----
include/linux/enclosure.h | 6 +++
3 files changed, 133 insertions(+), 9 deletions(-)
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c
index b7995ed..3289d4d 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
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index 433de8e..dcb0d76 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -67,6 +67,20 @@ static int ses_probe(struct device *dev)
#define SES_TIMEOUT (30 * HZ)
#define SES_RETRIES 3
+static void init_device_slot_control(unsigned char *dest_desc,
+ struct enclosure_component *ecomp,
+ unsigned char *status)
+{
+ memcpy(dest_desc, status, 4);
+ dest_desc[0] = 0;
+ /* only clear byte 1 for ENCLOSURE_COMPONENT_DEVICE */
+ if (ecomp->type == ENCLOSURE_COMPONENT_DEVICE)
+ dest_desc[1] = 0;
+ dest_desc[2] &= 0xde;
+ dest_desc[3] &= 0x3c;
+}
+
+
static int ses_recv_diag(struct scsi_device *sdev, int page_code,
void *buf, int bufflen)
{
@@ -178,14 +192,22 @@ static int ses_set_fault(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- unsigned char desc[4] = {0 };
+ unsigned char desc[4];
+ unsigned char *desc_ptr;
+
+ desc_ptr = ses_get_page2_descriptor(edev, ecomp);
+
+ if (!desc_ptr)
+ return -EIO;
+
+ init_device_slot_control(desc, ecomp, desc_ptr);
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
- /* zero is disabled */
+ desc[3] &= 0xdf;
break;
case ENCLOSURE_SETTING_ENABLED:
- desc[3] = 0x20;
+ desc[3] |= 0x20;
break;
default:
/* SES doesn't do the SGPIO blink settings */
@@ -219,14 +241,22 @@ static int ses_set_locate(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- unsigned char desc[4] = {0 };
+ unsigned char desc[4];
+ unsigned char *desc_ptr;
+
+ desc_ptr = ses_get_page2_descriptor(edev, ecomp);
+
+ if (!desc_ptr)
+ return -EIO;
+
+ init_device_slot_control(desc, ecomp, desc_ptr);
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
- /* zero is disabled */
+ desc[2] &= 0xfd;
break;
case ENCLOSURE_SETTING_ENABLED:
- desc[2] = 0x02;
+ desc[2] |= 0x02;
break;
default:
/* SES doesn't do the SGPIO blink settings */
@@ -239,15 +269,23 @@ static int ses_set_active(struct enclosure_device *edev,
struct enclosure_component *ecomp,
enum enclosure_component_setting val)
{
- unsigned char desc[4] = {0 };
+ unsigned char desc[4];
+ unsigned char *desc_ptr;
+
+ desc_ptr = ses_get_page2_descriptor(edev, ecomp);
+
+ if (!desc_ptr)
+ return -EIO;
+
+ init_device_slot_control(desc, ecomp, desc_ptr);
switch (val) {
case ENCLOSURE_SETTING_DISABLED:
- /* zero is disabled */
+ desc[2] &= 0x7f;
ecomp->active = 0;
break;
case ENCLOSURE_SETTING_ENABLED:
- desc[2] = 0x80;
+ desc[2] |= 0x80;
ecomp->active = 1;
break;
default:
@@ -265,12 +303,53 @@ static int ses_show_id(struct enclosure_device *edev, char *buf)
return sprintf(buf, "%#llx\n", id);
}
+static void ses_get_power_status(struct enclosure_device *edev,
+ struct enclosure_component *ecomp)
+{
+ unsigned char *desc;
+
+ desc = ses_get_page2_descriptor(edev, ecomp);
+ if (desc)
+ ecomp->power_status = (desc[3] & 0x10) ? 0 : 1;
+}
+
+static int ses_set_power_status(struct enclosure_device *edev,
+ struct enclosure_component *ecomp,
+ int val)
+{
+ unsigned char desc[4];
+ unsigned char *desc_ptr;
+
+ desc_ptr = ses_get_page2_descriptor(edev, ecomp);
+
+ if (!desc_ptr)
+ return -EIO;
+
+ init_device_slot_control(desc, ecomp, desc_ptr);
+
+ switch (val) {
+ /* power = 1 is device_off = 0 and vice versa */
+ case 0:
+ desc[3] |= 0x10;
+ break;
+ case 1:
+ desc[3] &= 0xef;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ecomp->power_status = val;
+ return ses_set_page2_descriptor(edev, ecomp, desc);
+}
+
static struct enclosure_component_callbacks ses_enclosure_callbacks = {
.get_fault = ses_get_fault,
.set_fault = ses_set_fault,
.get_status = ses_get_status,
.get_locate = ses_get_locate,
.set_locate = ses_set_locate,
+ .get_power_status = ses_get_power_status,
+ .set_power_status = ses_set_power_status,
.set_active = ses_set_active,
.show_id = ses_show_id,
};
@@ -449,6 +528,7 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
ecomp = &edev->component[components++];
if (!IS_ERR(ecomp)) {
+ ses_get_power_status(edev, ecomp);
if (addl_desc_ptr)
ses_process_descriptor(
ecomp,
diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h
index 0f826c1..7be22da 100644
--- a/include/linux/enclosure.h
+++ b/include/linux/enclosure.h
@@ -79,6 +79,11 @@ struct enclosure_component_callbacks {
int (*set_locate)(struct enclosure_device *,
struct enclosure_component *,
enum enclosure_component_setting);
+ void (*get_power_status)(struct enclosure_device *,
+ struct enclosure_component *);
+ int (*set_power_status)(struct enclosure_device *,
+ struct enclosure_component *,
+ int);
int (*show_id)(struct enclosure_device *, char *buf);
};
@@ -94,6 +99,7 @@ struct enclosure_component {
int locate;
int slot;
enum enclosure_status status;
+ int power_status;
};
struct enclosure_device {
--
1.8.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 0/5] Feature enhancements for ses module
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
` (4 preceding siblings ...)
2014-12-30 22:46 ` [PATCH 5/5] ses: Add power_status to SES device slot Song Liu
@ 2015-01-05 19:26 ` Christoph Hellwig
5 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2015-01-05 19:26 UTC (permalink / raw)
To: Song Liu; +Cc: linux-scsi, hare, dgilbert
Thanks, applied to scsi-for-3.20.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/5] ses: close potential registration race
2014-12-30 22:46 ` [PATCH 1/5] ses: close potential registration race Song Liu
@ 2015-01-10 13:26 ` Hannes Reinecke
0 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2015-01-10 13:26 UTC (permalink / raw)
To: Song Liu, linux-scsi; +Cc: hch, dgilbert, Dan Williams
On 12/30/2014 11:46 PM, Song Liu wrote:
> From: Dan Williams <dan.j.williams@intel.com>
>
> The slot and address fields have a small window of instability when
> userspace can read them before initialization. Separate
> enclosure_component
> allocation from registration.
>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Song Liu <songliubraving@fb.com>
> Reviewed-by: Jens Axboe <axboe@fb.com>
> Cc: Hannes Reinecke <hare@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 3/5] ses: add enclosure logical id
2014-12-30 22:46 ` [PATCH 3/5] ses: add enclosure logical id Song Liu
@ 2015-01-10 13:27 ` Hannes Reinecke
0 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2015-01-10 13:27 UTC (permalink / raw)
To: Song Liu, linux-scsi; +Cc: hch, dgilbert, Dan Williams
On 12/30/2014 11:46 PM, Song Liu wrote:
> From: Dan Williams <dan.j.williams@intel.com>
>
> Export the NAA logical id for the enclosure. This is optionally
> available from the sas_transport_class, but it is really a property of
> the enclosure.
>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Song Liu <songliubraving@fb.com>
> Reviewed-by: Jens Axboe <axboe@fb.com>
> Cc: Hannes Reinecke <hare@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 5/5] ses: Add power_status to SES device slot
2014-12-30 22:46 ` [PATCH 5/5] ses: Add power_status to SES device slot Song Liu
@ 2015-01-10 13:28 ` Hannes Reinecke
0 siblings, 0 replies; 10+ messages in thread
From: Hannes Reinecke @ 2015-01-10 13:28 UTC (permalink / raw)
To: Song Liu, linux-scsi; +Cc: hch, dgilbert
On 12/30/2014 11:46 PM, Song Liu wrote:
> 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>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Cheers,
Hannes
--
Dr. Hannes Reinecke zSeries & Storage
hare@suse.de +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg)
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2015-01-10 13:28 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-12-30 22:46 [PATCH 0/5] Feature enhancements for ses module Song Liu
2014-12-30 22:46 ` [PATCH 1/5] ses: close potential registration race Song Liu
2015-01-10 13:26 ` Hannes Reinecke
2014-12-30 22:46 ` [PATCH 2/5] ses: generate KOBJ_CHANGE on enclosure attach Song Liu
2014-12-30 22:46 ` [PATCH 3/5] ses: add enclosure logical id Song Liu
2015-01-10 13:27 ` Hannes Reinecke
2014-12-30 22:46 ` [PATCH 4/5] ses: add reliable slot attribute Song Liu
2014-12-30 22:46 ` [PATCH 5/5] ses: Add power_status to SES device slot Song Liu
2015-01-10 13:28 ` Hannes Reinecke
2015-01-05 19:26 ` [PATCH 0/5] Feature enhancements for ses module Christoph Hellwig
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.