From 7e52d75e2cce0eb12bbc284b0c67ab97c535f3e7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 4 Jun 2026 09:05:07 +0100 Subject: [PATCH 1/3] SES: Correctly interpret element index field when EIIOE=1 --- src/lib/ses.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib/ses.c b/src/lib/ses.c index 25901394..38fc8629 100644 --- a/src/lib/ses.c +++ b/src/lib/ses.c @@ -100,7 +100,7 @@ static void print_page10(struct ses_pages *sp) printf("\tDescriptor len (x-1): %d\n", ai[1] + 1); eip = ai[0] & 0x10; if (eip) - printf("\tElement Index: %d\n", ai[3]); + printf("\tElement Index: %d EIIOE: %d\n", ai[3], (ai[2] & 0x3)); len = ai[1] + 2; if ((ai[0] & 0xf) == SCSI_PROTOCOL_SAS) { if (eip) @@ -519,6 +519,13 @@ int ses_get_slots(struct ses_pages *sp, struct ses_slot **out_slots, int *out_sl ((uint64_t)addr_p[19]); slots[j].index = ap[0] & 0x10 ? ap[3] : j; + + // If EIIOE=1, ELEMENT INDEX includes overall elements, otherwise not. + // As (Array) Device Slot elements are always first in the list, there + // will be exactly one overall element that needs to be ignored. + if ((ap[0] & 0x10) && ((ap[2] & 0x3) == 0x01)) + slots[j].index--; + get_led_status(sp, slots[j].index, &slots[j].ibpi_status); } From 2ff6b3ae86044596ac8fe80eadd40316ab2b852a Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 4 Jun 2026 09:14:30 +0100 Subject: [PATCH 2/3] Spaces to tabs --- src/lib/ses.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/lib/ses.c b/src/lib/ses.c index 38fc8629..307ab821 100644 --- a/src/lib/ses.c +++ b/src/lib/ses.c @@ -520,11 +520,11 @@ int ses_get_slots(struct ses_pages *sp, struct ses_slot **out_slots, int *out_sl slots[j].index = ap[0] & 0x10 ? ap[3] : j; - // If EIIOE=1, ELEMENT INDEX includes overall elements, otherwise not. - // As (Array) Device Slot elements are always first in the list, there - // will be exactly one overall element that needs to be ignored. - if ((ap[0] & 0x10) && ((ap[2] & 0x3) == 0x01)) - slots[j].index--; + // If EIIOE=1, ELEMENT INDEX includes overall elements, otherwise not. + // As (Array) Device Slot elements are always first in the list, there + // will be exactly one overall element that needs to be ignored. + if ((ap[0] & 0x10) && ((ap[2] & 0x3) == 0x01)) + slots[j].index--; get_led_status(sp, slots[j].index, &slots[j].ibpi_status); } From ec9da8481dd241d0ef2ec44dd58961cc418404b7 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Thu, 4 Jun 2026 13:10:08 +0100 Subject: [PATCH 3/3] SES: Report additional LED states --- src/lib/ses.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/lib/ses.c b/src/lib/ses.c index 307ab821..cec0b76d 100644 --- a/src/lib/ses.c +++ b/src/lib/ses.c @@ -461,6 +461,7 @@ static void get_led_status(struct ses_pages *sp, int idx, enum led_ibpi_pattern { struct ses_slot_ctrl_elem *descriptors = (void *)(sp->page2.buf + 8); struct ses_slot_ctrl_elem *desc_element = NULL; + element_type ele_type = sp->page1_types[0].element_type; descriptors++; desc_element = &descriptors[idx]; @@ -472,6 +473,43 @@ static void get_led_status(struct ses_pages *sp, int idx, enum led_ibpi_pattern *led_status = LED_IBPI_PATTERN_LOCATE; else if (desc_element->b3 & 0x60) *led_status = LED_IBPI_PATTERN_FAILED_DRIVE; + else if (desc_element->common_control & 0x40) + *led_status = LED_IBPI_PATTERN_PFA; + + // Byte 1 is only valid for Array Device Slot elements + if ((*led_status == LED_IBPI_PATTERN_NORMAL) && (ele_type == SES_ARRAY_DEVICE_SLOT)) + { + if (desc_element->array_slot_control & 0x04) + *led_status = LED_IBPI_PATTERN_FAILED_ARRAY; + else if (desc_element->array_slot_control & 0x02) + *led_status = LED_IBPI_PATTERN_REBUILD; + else if (desc_element->array_slot_control & 0x20) + *led_status = LED_IBPI_PATTERN_HOTSPARE; + else if (desc_element->array_slot_control & 0x08) + *led_status = LED_IBPI_PATTERN_DEGRADED; + else if (desc_element->array_slot_control & 0x10) + *led_status = LED_SES_REQ_CONS_CHECK; + else if (desc_element->array_slot_control & 0x01) + *led_status = LED_SES_REQ_ABORT; + else if (desc_element->array_slot_control & 0x40) + *led_status = LED_SES_REQ_RSVD_DEV; + } + + if (*led_status == LED_IBPI_PATTERN_NORMAL) + { + if (desc_element->b2 & 0x40) + *led_status = LED_SES_REQ_DNR; + else if (desc_element->b2 & 0x08) + *led_status = LED_SES_REQ_INS; + else if (desc_element->b2 & 0x04) + *led_status = LED_SES_REQ_RM; + else if (desc_element->b3 & 0x10) + *led_status = LED_SES_REQ_DEV_OFF; + else if (desc_element->b3 & 0x08) + *led_status = LED_SES_REQ_EN_BA; + else if (desc_element->b3 & 0x04) + *led_status = LED_SES_REQ_EN_BB; + } } int ses_get_slots(struct ses_pages *sp, struct ses_slot **out_slots, int *out_slots_count)