git: bbed4b4b1a26 - stable/13 - sesutil: Avoid setting reserved bits.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 27 Jan 2022 02:05:39 UTC
The branch stable/13 has been updated by mav:
URL: https://cgit.FreeBSD.org/src/commit/?id=bbed4b4b1a26f59da0e09cda70f9632e6171bb6e
commit bbed4b4b1a26f59da0e09cda70f9632e6171bb6e
Author: Alexander Motin <mav@FreeBSD.org>
AuthorDate: 2022-01-13 18:45:28 +0000
Commit: Alexander Motin <mav@FreeBSD.org>
CommitDate: 2022-01-27 00:52:19 +0000
sesutil: Avoid setting reserved bits.
Weird side of SES specification is that some bits have different
meaning or semantics in status and control pages. This patch fixes
non-zero writes into reserved fields, that caused errors on some
enclosures when trying to control locate/fault LEDs, keeping other
bits unchanged.
MFC after: 2 weeks
Sposonred by: iXsystems, Inc.
(cherry picked from commit 2e19fae49fd4ab2360971463cee99a62198973b1)
---
sys/cam/scsi/scsi_ses.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
usr.sbin/sesutil/sesutil.c | 3 ++-
2 files changed, 46 insertions(+), 1 deletion(-)
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 b365988e27d4..3164116a8fdc 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);