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);