aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/cam/scsi/scsi_ses.h44
-rw-r--r--usr.sbin/sesutil/sesutil.c3
2 files changed, 46 insertions, 1 deletions
diff --git a/sys/cam/scsi/scsi_ses.h b/sys/cam/scsi/scsi_ses.h
index 86cc88ad27f1..8a1c7118f99a 100644
--- a/sys/cam/scsi/scsi_ses.h
+++ b/sys/cam/scsi/scsi_ses.h
@@ -2058,6 +2058,50 @@ union ses_status_element {
uint8_t bytes[4];
};
+/*
+ * Convert element status into control as much as possible.
+ * Some bits have different meaning in status and control,
+ * while others have the same and should be preserved.
+ */
+static inline void
+ses_status_to_ctrl(uint8_t type, uint8_t *bytes)
+{
+ /* Updated to SES4r5. */
+ static const uint8_t mask[][4] = {
+ { 0x60, 0x00, 0x00, 0x00 }, /* UNSPECIFIED */
+ { 0x60, 0x00, 0x4e, 0x3c }, /* DEVICE */
+ { 0x60, 0xc0, 0x00, 0x60 }, /* POWER */
+ { 0x60, 0xc0, 0x00, 0x60 }, /* COOLING/FAN */
+ { 0x60, 0xc0, 0x00, 0x80 }, /* THERM */
+ { 0x60, 0xc0, 0x00, 0x01 }, /* DOORLOCK */
+ { 0x60, 0xc0, 0x00, 0x5f }, /* ALARM */
+ { 0x60, 0xf0, 0x01, 0x00 }, /* ESSC */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* SCC */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* NVRAM */
+ { 0x60, 0x00, 0x00, 0x00 }, /* INV_OP_REASON */
+ { 0x60, 0x00, 0x00, 0xe0 }, /* UPS */
+ { 0x60, 0xc0, 0xff, 0xff }, /* DISPLAY */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* KEYPAD */
+ { 0x60, 0x80, 0x00, 0xff }, /* ENCLOSURE */
+ { 0x60, 0xc0, 0x00, 0x10 }, /* SCSIXVR */
+ { 0x60, 0x80, 0xff, 0xff }, /* LANGUAGE */
+ { 0x60, 0xc0, 0x00, 0x01 }, /* COMPORT */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* VOM */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* AMMETER */
+ { 0x60, 0xc0, 0x00, 0x01 }, /* SCSI_TGT */
+ { 0x60, 0xc0, 0x00, 0x01 }, /* SCSI_INI*/
+ { 0x60, 0xc0, 0x00, 0x00 }, /* SUBENC */
+ { 0x60, 0xff, 0x4e, 0x3c }, /* ARRAY_DEV */
+ { 0x60, 0xc0, 0x00, 0x00 }, /* SAS_EXP */
+ { 0x60, 0x80, 0x00, 0x40 }, /* SAS_CONN */
+ };
+
+ if (type >= sizeof(mask) / sizeof(mask[0]))
+ type = 0;
+ for (int i = 0; i < 4; i++)
+ bytes[i] &= mask[type][i];
+}
+
/*===================== SCSI SES Status Diagnostic Page =====================*/
struct ses_status_page {
struct ses_page_hdr hdr;
diff --git a/usr.sbin/sesutil/sesutil.c b/usr.sbin/sesutil/sesutil.c
index 9e6098e1da35..d78a9172e454 100644
--- a/usr.sbin/sesutil/sesutil.c
+++ b/usr.sbin/sesutil/sesutil.c
@@ -138,10 +138,11 @@ do_led(int fd, unsigned int idx, elm_type_t type, bool onoff, bool setfault)
close(fd);
xo_err(EXIT_FAILURE, "ENCIOC_GETELMSTAT");
}
- slot = (struct ses_ctrl_dev_slot *) &o.cstat[0];
+ ses_status_to_ctrl(type, &o.cstat[0]);
switch (type) {
case ELMTYP_DEVICE:
case ELMTYP_ARRAY_DEV:
+ slot = (struct ses_ctrl_dev_slot *) &o.cstat[0];
ses_ctrl_common_set_select(&slot->common, 1);
if (setfault)
ses_ctrl_dev_slot_set_rqst_fault(slot, state);