From 7c207dd5d06efccdee7258f832d4216fe5d1d998 Mon Sep 17 00:00:00 2001 From: "Milan P. Gandhi" Date: Mon, 17 Oct 2022 14:25:34 +0530 Subject: [PATCH 3/3] scsiprint.cpp: applied patch proposed by Yannick Hemery to merge both 'supported' log pages --- smartmontools-7.1/scsicmds.h | 5 ++ smartmontools-7.1/scsiprint.cpp | 103 +++++++++++++++++--------------- 2 files changed, 59 insertions(+), 49 deletions(-) diff --git a/smartmontools-7.1/scsicmds.h b/smartmontools-7.1/scsicmds.h index 516f773..9bd8b21 100644 --- a/smartmontools-7.1/scsicmds.h +++ b/smartmontools-7.1/scsicmds.h @@ -167,6 +167,11 @@ struct scsi_readcap_resp { uint16_t l_a_lba; /* Lowest Aligned Logical Block Address */ }; +struct scsi_supp_log_pages { + uint8_t page_code; + uint8_t subpage_code; +}; + /* SCSI Peripheral types (of interest) */ #define SCSI_PT_DIRECT_ACCESS 0x0 #define SCSI_PT_SEQUENTIAL_ACCESS 0x1 diff --git a/smartmontools-7.1/scsiprint.cpp b/smartmontools-7.1/scsiprint.cpp index 81bed88..21a4929 100644 --- a/smartmontools-7.1/scsiprint.cpp +++ b/smartmontools-7.1/scsiprint.cpp @@ -39,6 +39,9 @@ uint8_t gBuf[GBUF_SIZE]; #define LOG_RESP_LONG_LEN ((62 * 256) + 252) #define LOG_RESP_TAPE_ALERT_LEN 0x144 +/* Supported log pages + Supported log pages and subpages maximum count */ +#define SCSI_SUPP_LOG_PAGES_MAX_COUNT (252 + (62 * 128) + 126) + /* Log pages supported */ static bool gSmartLPage = false; /* Informational Exceptions log page */ static bool gTempLPage = false; @@ -118,14 +121,17 @@ static void scsiGetSupportedLogPages(scsi_device * device) { bool got_subpages = false; - int k, bump, err, resp_len, num_unreported, num_unreported_spg; - int resp_len_pg0_0 = 0; - int resp_len_pg0_ff = 0; /* in SPC-4, response length of supported - * log pages _and_ log subpages */ + int k, err, resp_len, num_unreported, num_unreported_spg; + int supp_lpg_and_spg_count = 0; + const uint8_t * up; uint8_t sup_lpgs[LOG_RESP_LEN]; + struct scsi_supp_log_pages supp_lpg_and_spg[SCSI_SUPP_LOG_PAGES_MAX_COUNT]; memset(gBuf, 0, LOG_RESP_LEN); + memset(supp_lpg_and_spg, 0, sizeof(supp_lpg_and_spg)); + + /* Get supported log pages */ if ((err = scsiLogSense(device, SUPPORTED_LPAGES, 0, gBuf, LOG_RESP_LEN, 0 /* do double fetch */))) { if (scsi_debugmode > 0) @@ -140,12 +146,23 @@ scsiGetSupportedLogPages(scsi_device * device) logSenStr, scsiErrString(err)); if (err) return; - memcpy(sup_lpgs, gBuf, LOG_RESP_LEN); - } else if ((scsi_version >= SCSI_VERSION_SPC_4) && - (scsi_version <= SCSI_VERSION_HIGHEST)) { + } + + memcpy(sup_lpgs, gBuf, LOG_RESP_LEN); + resp_len = gBuf[3]; + up = gBuf + LOGPAGEHDRSIZE; + + for (k = 0; k < resp_len; k += 1) { + uint8_t page_code = 0x3f & up[k]; + supp_lpg_and_spg[supp_lpg_and_spg_count++] = {page_code, 0}; + } + + /* Get supported log pages and subpages. Most drives seems to include the + supported log pages here as well, but some drives such as the Samsung + PM1643a will only report the additional log pages with subpages here */ + if ((scsi_version >= SCSI_VERSION_SPC_4) && + (scsi_version <= SCSI_VERSION_HIGHEST)) { /* unclear what code T10 will choose for SPC-6 */ - memcpy(sup_lpgs, gBuf, LOG_RESP_LEN); - resp_len_pg0_0 = sup_lpgs[3]; if ((err = scsiLogSense(device, SUPPORTED_LPAGES, SUPP_SPAGE_L_SPAGE, gBuf, LOG_RESP_LONG_LEN, -1 /* just single not double fetch */))) { @@ -153,6 +170,7 @@ scsiGetSupportedLogPages(scsi_device * device) pout("%s for supported pages and subpages failed [%s]\n", logSenStr, scsiErrString(err)); } else { + /* Ensure we didn't get the same answer than without the subpages */ if (0 == memcmp(gBuf, sup_lpgs, LOG_RESP_LEN)) { if (scsi_debugmode > 0) pout("%s: %s ignored subpage field, bad\n", @@ -163,48 +181,34 @@ scsiGetSupportedLogPages(scsi_device * device) pout("%s supported subpages is bad SPF=%u SUBPG=%u\n", logSenRspStr, !! (0x40 & gBuf[0]), gBuf[2]); } else { - resp_len_pg0_ff = sg_get_unaligned_be16(gBuf + 2); got_subpages = true; } } - } else { - memcpy(sup_lpgs, gBuf, LOG_RESP_LEN); - resp_len_pg0_0 = sup_lpgs[3]; } if (got_subpages) { resp_len = sg_get_unaligned_be16(gBuf + 2); - if (resp_len_pg0_ff <= resp_len_pg0_0) { - /* something is rotten ....., ignore SUPP_SPAGE_L_SPAGE */ - resp_len = resp_len_pg0_0; - bump = 1; - up = sup_lpgs + LOGPAGEHDRSIZE; - got_subpages = false; - (void)got_subpages; // not yet used below, suppress warning - } else { - resp_len = resp_len_pg0_ff; - bump = 2; - up = gBuf + LOGPAGEHDRSIZE; + up = gBuf + LOGPAGEHDRSIZE; + for (k = 0; k < resp_len; k += 2) { + uint8_t page_code = 0x3f & up[k]; + uint8_t subpage_code = up[k+1]; + supp_lpg_and_spg[supp_lpg_and_spg_count++] = {page_code, subpage_code}; } - } else { - resp_len = resp_len_pg0_0; - bump = 1; - up = sup_lpgs + LOGPAGEHDRSIZE; } + num_unreported = 0; num_unreported_spg = 0; - for (num_unreported = 0, k = 0; k < resp_len; k += bump, up += bump) { - uint8_t pg_num = 0x3f & up[0]; - uint8_t sub_pg_num = (0x40 & up[0]) ? up[1] : 0; + for (k = 0; k < supp_lpg_and_spg_count; k += 1) { + struct scsi_supp_log_pages supp_lpg = supp_lpg_and_spg[k]; - switch (pg_num) + switch (supp_lpg.page_code) { case SUPPORTED_LPAGES: - if (! ((NO_SUBPAGE_L_SPAGE == sub_pg_num) || - (SUPP_SPAGE_L_SPAGE == sub_pg_num))) { + if (! ((NO_SUBPAGE_L_SPAGE == supp_lpg.subpage_code) || + (SUPP_SPAGE_L_SPAGE == supp_lpg.subpage_code))) { if (scsi_debugmode > 1) pout("%s: Strange Log page number: 0x0,0x%x\n", - __func__, sub_pg_num); + __func__, supp_lpg.subpage_code); } break; case READ_ERROR_COUNTER_LPAGE: @@ -223,13 +227,13 @@ scsiGetSupportedLogPages(scsi_device * device) gNonMediumELPage = true; break; case TEMPERATURE_LPAGE: - if (NO_SUBPAGE_L_SPAGE == sub_pg_num) + if (NO_SUBPAGE_L_SPAGE == supp_lpg.subpage_code) gTempLPage = true; - else if (ENVIRO_REP_L_SPAGE == sub_pg_num) + else if (ENVIRO_REP_L_SPAGE == supp_lpg.subpage_code) gEnviroReportingLPage = true; - else if (ENVIRO_LIMITS_L_SPAGE == sub_pg_num) + else if (ENVIRO_LIMITS_L_SPAGE == supp_lpg.subpage_code) gEnviroLimitsLPage = true; - else if (SUPP_SPAGE_L_SPAGE != sub_pg_num) { + else if (SUPP_SPAGE_L_SPAGE != supp_lpg.subpage_code) { ++num_unreported; ++num_unreported_spg; } @@ -238,11 +242,11 @@ scsiGetSupportedLogPages(scsi_device * device) reporting of ,0xff so it is not an error. */ break; case STARTSTOP_CYCLE_COUNTER_LPAGE: - if (NO_SUBPAGE_L_SPAGE == sub_pg_num) + if (NO_SUBPAGE_L_SPAGE == supp_lpg.subpage_code) gStartStopLPage = true; - else if (UTILIZATION_L_SPAGE == sub_pg_num) + else if (UTILIZATION_L_SPAGE == supp_lpg.subpage_code) gUtilizationLPage = true; - else if (SUPP_SPAGE_L_SPAGE != sub_pg_num) { + else if (SUPP_SPAGE_L_SPAGE != supp_lpg.subpage_code) { ++num_unreported; ++num_unreported_spg; } @@ -254,15 +258,15 @@ scsiGetSupportedLogPages(scsi_device * device) gSmartLPage = true; break; case BACKGROUND_RESULTS_LPAGE: - if (NO_SUBPAGE_L_SPAGE == sub_pg_num) + if (NO_SUBPAGE_L_SPAGE == supp_lpg.subpage_code) gBackgroundResultsLPage = true; - else if (PEND_DEFECTS_L_SPAGE == sub_pg_num) + else if (PEND_DEFECTS_L_SPAGE == supp_lpg.subpage_code) gPendDefectsLPage = true; - else if (BACKGROUND_OP_L_SPAGE == sub_pg_num) + else if (BACKGROUND_OP_L_SPAGE == supp_lpg.subpage_code) gBackgroundOpLPage = true; - else if (LPS_MISALIGN_L_SPAGE == sub_pg_num) + else if (LPS_MISALIGN_L_SPAGE == supp_lpg.subpage_code) gLPSMisalignLPage = true; - else if (SUPP_SPAGE_L_SPAGE != sub_pg_num) { + else if (SUPP_SPAGE_L_SPAGE != supp_lpg.subpage_code) { ++num_unreported; ++num_unreported_spg; } @@ -296,9 +300,10 @@ scsiGetSupportedLogPages(scsi_device * device) gSeagateFactoryLPage = true; break; default: - if (pg_num < 0x30) { /* don't count VS pages */ + if (supp_lpg.page_code < 0x30) { /* don't count VS pages */ ++num_unreported; - if ((sub_pg_num > 0) && (SUPP_SPAGE_L_SPAGE != sub_pg_num)) + if ((supp_lpg.subpage_code > 0) && + (SUPP_SPAGE_L_SPAGE != supp_lpg.subpage_code)) ++num_unreported_spg; } break; -- 2.35.1