diff options
Diffstat (limited to 'plugins/innogrit')
-rw-r--r-- | plugins/innogrit/innogrit-nvme.c | 501 | ||||
-rw-r--r-- | plugins/innogrit/innogrit-nvme.h | 3 | ||||
-rw-r--r-- | plugins/innogrit/typedef.h | 87 |
3 files changed, 248 insertions, 343 deletions
diff --git a/plugins/innogrit/innogrit-nvme.c b/plugins/innogrit/innogrit-nvme.c index cd47efa..9e7be48 100644 --- a/plugins/innogrit/innogrit-nvme.c +++ b/plugins/innogrit/innogrit-nvme.c @@ -16,176 +16,175 @@ #define CREATE_CMD #include "innogrit-nvme.h" -static int innogrit_smart_log_additional(int argc, char **argv, - struct command *command, - struct plugin *plugin) +static int nvme_vucmd(int fd, unsigned char opcode, unsigned int cdw12, + unsigned int cdw13, unsigned int cdw14, + unsigned int cdw15, char *data, int data_len) { - struct nvme_smart_log smart_log = { 0 }; - struct vsc_smart_log *pvsc_smart = (struct vsc_smart_log *)smart_log.rsvd232; - const char *desc = "Retrieve additional SMART log for the given device "; - const char *namespace = "(optional) desired namespace"; - struct nvme_dev *dev; - int err, i, iindex; - - struct config { - __u32 namespace_id; - }; + struct nvme_passthru_cmd cmd; - struct config cfg = { - .namespace_id = NVME_NSID_ALL, - }; + memset(&cmd, 0, sizeof(cmd)); + cmd.opcode = opcode; + cmd.cdw2 = IGVSC_SIG; + cmd.cdw10 = data_len / 4; + cmd.cdw12 = cdw12; + cmd.cdw13 = cdw13; + cmd.cdw14 = cdw14; + cmd.cdw15 = cdw15; + cmd.nsid = 0xffffffff; + cmd.addr = (__u64)(__u64)(uintptr_t)data; + cmd.data_len = data_len; + return nvme_submit_admin_passthru(fd, &cmd, NULL); +} - OPT_ARGS(opts) = { - OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace), - OPT_END() +int getlogpage(struct nvme_dev *dev, unsigned char ilogid, unsigned char ilsp, + char *data, int data_len, unsigned int *result) +{ + struct nvme_get_log_args args = { + .args_size = sizeof(args), + .fd = dev_fd(dev), + .lid = ilogid, + .nsid = 0xffffffff, + .lpo = 0, + .lsp = ilsp, + .lsi = 0, + .rae = true, + .uuidx = 0, + .csi = NVME_CSI_NVM, + .ot = false, + .len = data_len, + .log = (void *)data, + .timeout = NVME_DEFAULT_IOCTL_TIMEOUT, + .result = result, }; - - err = parse_and_open(&dev, argc, argv, desc, opts); - if (err) - return err; - - nvme_get_log_smart(dev_fd(dev), cfg.namespace_id, false, &smart_log); - nvme_show_smart_log(&smart_log, cfg.namespace_id, dev->name, NORMAL); - - printf("DW0[0-1] Defect Cnt : %u\n", pvsc_smart->defect_cnt); - printf("DW0[2-3] Slc Spb Cnt : %u\n", pvsc_smart->slc_spb_cnt); - printf("DW1 Slc Total Ec Cnt : %u\n", pvsc_smart->slc_total_ec_cnt); - printf("DW2 Slc Max Ec Cnt : %u\n", pvsc_smart->slc_max_ec_cnt); - printf("DW3 Slc Min Ec Cnt : %u\n", pvsc_smart->slc_min_ec_cnt); - printf("DW4 Slc Avg Ec Cnt : %u\n", pvsc_smart->slc_avg_ec_cnt); - printf("DW5 Total Ec Cnt : %u\n", pvsc_smart->total_ec_cnt); - printf("DW6 Max Ec Cnt : %u\n", pvsc_smart->max_ec_cnt); - printf("DW7 Min Ec Cnt : %u\n", pvsc_smart->min_ec_cnt); - printf("DW8 Avg Ec Cnt : %u\n", pvsc_smart->avg_ec_cnt); - printf("DW9 Mrd Rr Good Cnt : %u\n", pvsc_smart->mrd_rr_good_cnt); - printf("DW10 Ard Rr Good Cnt : %u\n", pvsc_smart->ard_rr_good_cnt); - printf("DW11 Preset Cnt : %u\n", pvsc_smart->preset_cnt); - printf("DW12 Nvme Reset Cnt : %u\n", pvsc_smart->nvme_reset_cnt); - printf("DW13 Low Pwr Cnt : %u\n", pvsc_smart->low_pwr_cnt); - printf("DW14 Wa : %u\n", pvsc_smart->wa); - printf("DW15 Ps3 Entry Cnt : %u\n", pvsc_smart->ps3_entry_cnt); - printf("DW16[0] highest_temp[0] : %u\n", pvsc_smart->highest_temp[0]); - printf("DW16[1] highest_temp[1] : %u\n", pvsc_smart->highest_temp[1]); - printf("DW16[2] highest_temp[2] : %u\n", pvsc_smart->highest_temp[2]); - printf("DW16[3] highest_temp[3] : %u\n", pvsc_smart->highest_temp[3]); - printf("DW17 weight_ec : %u\n", pvsc_smart->weight_ec); - printf("DW18 slc_cap_mb : %u\n", pvsc_smart->slc_cap_mb); - printf("DW19-20 nand_page_write_cnt : %llu\n", pvsc_smart->nand_page_write_cnt); - printf("DW21 program_error_cnt : %u\n", pvsc_smart->program_error_cnt); - printf("DW22 erase_error_cnt : %u\n", pvsc_smart->erase_error_cnt); - printf("DW23[0] flash_type : %u\n", pvsc_smart->flash_type); - printf("DW24 hs_crc_err_cnt : %u\n", pvsc_smart->hs_crc_err_cnt); - printf("DW25 ddr_ecc_err_cnt : %u\n", pvsc_smart->ddr_ecc_err_cnt); - iindex = 26; - for (i = 0; i < (sizeof(pvsc_smart->reserved3)/4); i++) { - if (pvsc_smart->reserved3[i] != 0) - printf("DW%-37d : %u\n", iindex, pvsc_smart->reserved3[i]); - iindex++; - } - - return 0; + return nvme_get_log(&args); } -static int sort_eventlog_fn(const void *a, const void *b) +int getvsctype(struct nvme_dev *dev) { - const struct eventlog_addindex *l = a; - const struct eventlog_addindex *r = b; - int rc; - - if (l->ms > r->ms) { - rc = 1; - } else if (l->ms < r->ms) { - rc = -1; - } else { - if (l->iindex < r->iindex) - rc = -1; - else - rc = 1; + unsigned char ilogid; + char data[4096]; + struct drvinfo_t *pdrvinfo = (struct drvinfo_t *)data; + + memset(data, 0, 4096); + // pdrvinfo by getlogpage + for (ilogid = 0xe1; ilogid < 0xe2; ilogid++) { + getlogpage(dev, ilogid, 0, data, 4096, NULL); + if (pdrvinfo->signature == 0x5A) + return 1; } - return rc; + //pdrvinfo by vucmd + nvme_vucmd(dev_fd(dev), 0xfe, 0x82, 0X03, 0x00, 0, (char *)data, 4096); + if (pdrvinfo->signature == 0x5A) + return 1; + + return 0; } -static void sort_eventlog(struct eventlog *data16ksrc, unsigned int icount) +int getvsc_eventlog(struct nvme_dev *dev, FILE *fp) { - struct eventlog_addindex peventlogadd[512]; - unsigned int i; + char data[4096]; + unsigned int errcnt, rxlen, start_flag; + unsigned long long end_flag; + struct evlg_flush_hdr *pevlog = (struct evlg_flush_hdr *)data; + int ret = -1; + int ivsctype = getvsctype(dev); - for (i = 0; i < icount; i++) { - memcpy(&peventlogadd[i], &data16ksrc[i], sizeof(struct eventlog)); - peventlogadd[i].iindex = i; - } + start_flag = 0; + rxlen = 0; + errcnt = 0; - qsort(peventlogadd, icount, sizeof(struct eventlog_addindex), sort_eventlog_fn); + while (1) { + memset(data, 0, 4096); + if (ivsctype == 0) { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + } else { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, 0x60, 0, + 0, 0, (char *)data, 4096); + } - for (i = 0; i < icount; i++) - memcpy(&data16ksrc[i], &peventlogadd[i], sizeof(struct eventlog)); -} + if (ret == -1) { + printf("(error)\n"); + return IG_ERROR; + } -static unsigned char setfilecontent(char *filenamea, unsigned char *buffer, - unsigned int buffersize) -{ - FILE *fp = NULL; - int rc; + if (pevlog->signature == EVLOG_SIG) { + errcnt = 0; + } else { + errcnt++; + if (errcnt > 16) { + printf("(invalid data error)\n"); + return IG_ERROR; + } + } - if (buffersize == 0) - return true; - fp = fopen(filenamea, "a+"); - rc = fwrite(buffer, 1, buffersize, fp); - fclose(fp); - if (rc != buffersize) - return false; - return true; + if (start_flag == 1) { + end_flag = *(unsigned long long *)&data[4096 - 32]; + if (end_flag == 0xffffffff00000000) + break; + fwrite(data, 1, 4096, fp); + rxlen += 4096; + printf("\rget eventlog : %d.%d MB ", rxlen / SIZE_MB, + (rxlen % SIZE_MB) * 100 / SIZE_MB); + } else if (errcnt == 0) { + printf("get eventlog by vsc command\n"); + start_flag = 1; + fwrite(data, 1, 4096, fp); + rxlen += 4096; + } + } + printf("\n"); + return IG_SUCCESS; } -static int nvme_vucmd(int fd, unsigned char opcode, unsigned int cdw12, - unsigned int cdw13, unsigned int cdw14, - unsigned int cdw15, char *data, int data_len) +int getlogpage_eventlog(struct nvme_dev *dev, FILE *fp) { - struct nvme_passthru_cmd cmd; + unsigned int i, result, total_size; + char data[4096]; + int ret = 0; - memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = opcode; - cmd.cdw2 = IGVSC_SIG; - cmd.cdw10 = data_len / 4; - cmd.cdw12 = cdw12; - cmd.cdw13 = cdw13; - cmd.cdw14 = cdw14; - cmd.cdw15 = cdw15; - cmd.nsid = 0xffffffff; - cmd.addr = (__u64)(__u64)(uintptr_t)data; - cmd.data_len = data_len; - return nvme_submit_admin_passthru(fd, &cmd, NULL); + result = 0; + ret = getlogpage(dev, 0xcb, 0x01, data, 4096, NULL); + if (ret) + return IG_UNSUPPORT; + + ret = getlogpage(dev, 0xcb, 0x02, data, 4096, &result); + if ((ret) || (result == 0)) + return IG_UNSUPPORT; + + total_size = result * 4096; + printf("total eventlog : %d.%d MB\n", total_size / SIZE_MB, + (total_size % SIZE_MB) * 100 / SIZE_MB); + for (i = 0; i <= total_size; i += 4096) { + ret = getlogpage(dev, 0xcb, 0x00, data, 4096, NULL); + printf("\rget eventlog : %d.%d MB ", i / SIZE_MB, + (i % SIZE_MB) * 100 / SIZE_MB); + if (ret) { + printf("(error)\n"); + return IG_ERROR; + } + fwrite(data, 1, 4096, fp); + } + printf("\n"); + return IG_SUCCESS; } -static int innogrit_vsc_geteventlog(int argc, char **argv, +static int innogrit_geteventlog(int argc, char **argv, struct command *command, struct plugin *plugin) { time_t timep; struct tm *logtime; - int icount, ioffset16k, iblock, ivsctype; char currentdir[128], filename[512]; - unsigned char data[4096], data16k[SIZE_16K], zerob[32]; - unsigned int *pcheckdata; - unsigned int isize, icheck_stopvalue, iend; - unsigned char bSortLog = false, bget_nextlog = true; - struct evlg_flush_hdr *pevlog = (struct evlg_flush_hdr *)data; const char *desc = "Recrieve event log for the given device "; - const char *clean_opt = "(optional) 1 for clean event log"; struct nvme_dev *dev; + FILE *fp = NULL; int ret = -1; - struct config { - __u32 clean_flg; - }; - - struct config cfg = { - .clean_flg = 0, - }; - OPT_ARGS(opts) = { - OPT_UINT("clean_flg", 'c', &cfg.clean_flg, clean_opt), OPT_END() }; @@ -193,120 +192,25 @@ static int innogrit_vsc_geteventlog(int argc, char **argv, if (ret) return ret; - if (getcwd(currentdir, 128) == NULL) return -1; - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096); - if (ret == -1) - return ret; - - if (data[0] == 0x5A) - ivsctype = 1; - else - ivsctype = 0; - time(&timep); logtime = localtime(&timep); - sprintf(filename, "%s/eventlog_%02d%02d-%02d%02d%02d.elog", currentdir, logtime->tm_mon+1, - logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec); - - iblock = 0; - ioffset16k = 0; - memset(data16k, 0, SIZE_16K); - memset(zerob, 0, 32); - - icount = 0; - while (bget_nextlog) { - if (icount % 100 == 0) { - printf("\rWait for Dump EventLog " XCLEAN_LINE); - fflush(stdout); - icount = 0; - } else if (icount % 5 == 0) { - printf("."); - fflush(stdout); - } - icount++; - - memset(data, 0, 4096); - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x60, 0x00, 0x00, 0x00, (char *)data, - 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET_EVENT_LOG, 0, 0, - (SRB_SIGNATURE >> 32), - (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); - if (ret == -1) - return ret; - - pcheckdata = (unsigned int *)&data[4096 - 32]; - icheck_stopvalue = pcheckdata[1]; - - if (icheck_stopvalue == 0xFFFFFFFF) { - isize = pcheckdata[0]; - if (isize == 0) { - /* Finish Log */ - bget_nextlog = false; - } else if (bSortLog) { - /* No Full 4K Package */ - for (iend = 0; iend < isize - 32; iend += sizeof(struct eventlog)) { - if (memcmp(&data[iend], zerob, sizeof(struct eventlog)) != 0) { - memcpy(&data16k[ioffset16k], &data[iend], sizeof(struct eventlog)); - ioffset16k += sizeof(struct eventlog); - } - } - } else { - setfilecontent(filename, data, isize); - } - } else { - /* Full 4K Package */ - if ((pevlog->signature == EVLOG_SIG) && (pevlog->log_type == 1)) - bSortLog = true; - - if (bSortLog) { - for (iend = 0; iend < SIZE_4K; iend += sizeof(struct eventlog)) { - if (memcmp(&data[iend], zerob, sizeof(struct eventlog)) != 0) { - memcpy(&data16k[ioffset16k], &data[iend], sizeof(struct eventlog)); - ioffset16k += sizeof(struct eventlog); - } - } - - iblock++; - if (iblock == 4) { - sort_eventlog((struct eventlog *)(data16k + sizeof(struct evlg_flush_hdr)), - (ioffset16k - sizeof(struct evlg_flush_hdr))/sizeof(struct eventlog)); - setfilecontent(filename, data16k, ioffset16k); - ioffset16k = 0; - iblock = 0; - memset(data16k, 0, SIZE_16K); - } - } else { - setfilecontent(filename, data, SIZE_4K); - } - - } - } + sprintf(filename, "%s/eventlog_%02d%02d-%02d%02d%02d.eraw", currentdir, + logtime->tm_mon+1, logtime->tm_mday, logtime->tm_hour, logtime->tm_min, + logtime->tm_sec); + printf("output eventlog file : %s\n", filename); - if (bSortLog) { - if (ioffset16k > 0) { - sort_eventlog((struct eventlog *)(data16k + sizeof(struct evlg_flush_hdr)), - (ioffset16k - sizeof(struct evlg_flush_hdr))/sizeof(struct eventlog)); - setfilecontent(filename, data16k, ioffset16k); - } - } - - printf("\r" XCLEAN_LINE "Dump eventLog finish to %s\n", filename); - chmod(filename, 0666); - - if (cfg.clean_flg == 1) { - printf("Clean eventlog\n"); - nvme_vucmd(dev_fd(dev), NVME_VSC_CLEAN_EVENT_LOG, 0, 0, - (SRB_SIGNATURE >> 32), - (SRB_SIGNATURE & 0xFFFFFFFF), (char *)NULL, 0); - } + fp = fopen(filename, "a+"); + getvsctype(dev); + ret = getlogpage_eventlog(dev, fp); + if (ret == IG_UNSUPPORT) + ret = getvsc_eventlog(dev, fp); + fclose(fp); dev_close(dev); + chmod(filename, 0666); return ret; } @@ -318,13 +222,14 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, struct tm *logtime; char currentdir[128], filename[512], fname[128]; unsigned int itotal, icur, ivsctype; - unsigned char data[4096]; + char data[4096]; struct cdumpinfo cdumpinfo; unsigned char busevsc = false; unsigned int ipackcount, ipackindex; char fwvera[32]; const char *desc = "Recrieve cdump data for the given device "; struct nvme_dev *dev; + FILE *fp = NULL; int ret = -1; OPT_ARGS(opts) = { @@ -335,50 +240,48 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, if (ret) return ret; + ivsctype = getvsctype(dev); + if (getcwd(currentdir, 128) == NULL) return -1; time(&timep); logtime = localtime(&timep); - ivsctype = 0; ipackindex = 0; memset(data, 0, 4096); - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x03, 0x00, 0x00, (char *)data, 4096); - if (ret == -1) - return ret; - - if (data[0] == 0x5A) { - ivsctype = 1; - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00, (char *)data, 4096); - } else { - ivsctype = 0; + if (ivsctype == 0) { ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); + (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + } else { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, 0x82, 0x00, + 0, 0, (char *)data, 4096); } - if (ret == -1) - return ret; - memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo)); - if (cdumpinfo.sig == 0x5a5b5c5d) { - busevsc = true; - ipackcount = cdumpinfo.ipackcount; - if (ipackcount == 0) { - itotal = 0; - } else { - itotal = cdumpinfo.cdumppack[ipackindex].ilenth; - memset(fwvera, 0, sizeof(fwvera)); - memcpy(fwvera, cdumpinfo.cdumppack[ipackindex].fwver, 8); - sprintf(fname, "cdump_%02d%02d-%02d%02d%02d_%d_%s.cdp", logtime->tm_mon+1, - logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec, - ipackindex, fwvera); - sprintf(filename, "%s/%s", currentdir, fname); + if (ret == 0) { + memcpy(&cdumpinfo, &data[3072], sizeof(cdumpinfo)); + if (cdumpinfo.sig == 0x5a5b5c5d) { + busevsc = true; + ipackcount = cdumpinfo.ipackcount; + if (ipackcount == 0) { + itotal = 0; + } else { + itotal = cdumpinfo.cdumppack[ipackindex].ilenth; + memset(fwvera, 0, sizeof(fwvera)); + memcpy(fwvera, cdumpinfo.cdumppack[ipackindex].fwver, 8); + sprintf(fname, "cdump_%02d%02d-%02d%02d%02d_%d_%s.cdp", + logtime->tm_mon+1, logtime->tm_mday, logtime->tm_hour, + logtime->tm_min, logtime->tm_sec, ipackindex, fwvera); + sprintf(filename, "%s/%s", currentdir, fname); + if (fp != NULL) + fclose(fp); + fp = fopen(filename, "a+"); + } } } - if (busevsc == false) { memset(data, 0, 4096); ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, @@ -389,9 +292,12 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, ipackcount = 1; memcpy(&itotal, &data[4092], 4); - sprintf(fname, "cdump_%02d%02d-%02d%02d%02d.cdp", logtime->tm_mon+1, logtime->tm_mday, - logtime->tm_hour, logtime->tm_min, logtime->tm_sec); + sprintf(fname, "cdump_%02d%02d-%02d%02d%02d.cdp", logtime->tm_mon+1, + logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec); sprintf(filename, "%s/%s", currentdir, fname); + if (fp != NULL) + fclose(fp); + fp = fopen(filename, "a+"); } if (itotal == 0) { @@ -402,17 +308,20 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, while (ipackindex < ipackcount) { memset(data, 0, 4096); strcpy((char *)data, "cdumpstart"); - setfilecontent(filename, data, strlen((char *)data)); + fwrite(data, 1, strlen((char *)data), fp); for (icur = 0; icur < itotal; icur += 4096) { memset(data, 0, 4096); if (busevsc) { - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00, - (char *)data, 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); + if (ivsctype == 0) { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + VSC_FN_GET_CDUMP, 0x00, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + } else { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, + 0x82, 0x00, 0, 0, (char *)data, 4096); + } } else { ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, @@ -421,25 +330,27 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, if (ret != 0) return ret; - setfilecontent(filename, data, 4096); - + fwrite(data, 1, 4096, fp); printf("\rWait for dump data %d%%" XCLEAN_LINE, ((icur+4096) * 100/itotal)); } memset(data, 0, 4096); strcpy((char *)data, "cdumpend"); - setfilecontent(filename, data, strlen((char *)data)); + fwrite(data, 1, strlen((char *)data), fp); printf("\r%s\n", fname); ipackindex++; if (ipackindex != ipackcount) { memset(data, 0, 4096); if (busevsc) { - if (ivsctype == 1) - ret = nvme_vucmd(dev_fd(dev), 0xFE, 0x82, 0x08, 0x00, 0x00, - (char *)data, 4096); - else - ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, VSC_FN_GET_CDUMP, 0x00, - (SRB_SIGNATURE >> 32), (SRB_SIGNATURE & 0xFFFFFFFF), - (char *)data, 4096); + if (ivsctype == 0) { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_GET, + VSC_FN_GET_CDUMP, 0x00, + (SRB_SIGNATURE >> 32), + (SRB_SIGNATURE & 0xFFFFFFFF), + (char *)data, 4096); + } else { + ret = nvme_vucmd(dev_fd(dev), NVME_VSC_TYPE1_GET, + 0x82, 0x00, 0, 0, (char *)data, 4096); + } } else { ret = nvme_get_nsid_log(dev_fd(dev), true, 0x07, @@ -455,12 +366,16 @@ static int innogrit_vsc_getcdump(int argc, char **argv, struct command *command, sprintf(fname, "cdump_%02d%02d-%02d%02d%02d_%d_%s.cdp", logtime->tm_mon+1, logtime->tm_mday, logtime->tm_hour, logtime->tm_min, logtime->tm_sec, ipackindex, fwvera); - sprintf(filename, "%s/%s", currentdir, fname); + if (fp != NULL) + fclose(fp); + fp = fopen(filename, "a+"); } } printf("\n"); dev_close(dev); + if (fp != NULL) + fclose(fp); return ret; } diff --git a/plugins/innogrit/innogrit-nvme.h b/plugins/innogrit/innogrit-nvme.h index 2de0502..885479c 100644 --- a/plugins/innogrit/innogrit-nvme.h +++ b/plugins/innogrit/innogrit-nvme.h @@ -9,8 +9,7 @@ PLUGIN(NAME("innogrit", "innogrit vendor specific extensions", NVME_VERSION), COMMAND_LIST( - ENTRY("smart-log-add", "Retrieve innogrit SMART Log, show it", innogrit_smart_log_additional) - ENTRY("get-eventlog", "get event log", innogrit_vsc_geteventlog) + ENTRY("get-eventlog", "get event log", innogrit_geteventlog) ENTRY("get-cdump", "get cdump data", innogrit_vsc_getcdump) ) ); diff --git a/plugins/innogrit/typedef.h b/plugins/innogrit/typedef.h index 7220d38..0c5e406 100644 --- a/plugins/innogrit/typedef.h +++ b/plugins/innogrit/typedef.h @@ -1,15 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#define SIZE_4K 4096 -#define SIZE_16K 16384 +#define IG_SUCCESS (0) +#define IG_UNSUPPORT (-1) +#define IG_ERROR (-2) -#define NVME_VSC_GET_EVENT_LOG 0xC2 -#define NVME_VSC_CLEAN_EVENT_LOG 0xD8 -#define NVME_VSC_GET 0xE6 -#define VSC_FN_GET_CDUMP 0x08 -#define EVLOG_SIG 0x65766C67 -#define IGVSC_SIG 0x69677673 -#define SRB_SIGNATURE 0x544952474F4E4E49ULL -#define XCLEAN_LINE "\033[K" +#define NVME_VSC_GET_EVENT_LOG 0xC2 +#define NVME_VSC_GET 0xE6 +#define NVME_VSC_TYPE1_GET 0xFE +#define VSC_FN_GET_CDUMP 0x08 +#define IGVSC_SIG 0x69677673 +#define EVLOG_SIG 0x65766C67 +#define SRB_SIGNATURE 0x544952474F4E4E49ULL + +#define XCLEAN_LINE "\033[K" +#define SIZE_MB 0x100000 struct evlg_flush_hdr { unsigned int signature; @@ -27,45 +30,33 @@ struct eventlog { unsigned int param[7]; }; -struct eventlog_addindex { - unsigned int ms; - unsigned int param[7]; - unsigned int iindex; -}; - -#pragma pack(push) -#pragma pack(1) -struct vsc_smart_log { - unsigned short defect_cnt; - unsigned short slc_spb_cnt; - unsigned int slc_total_ec_cnt; - unsigned int slc_max_ec_cnt; - unsigned int slc_min_ec_cnt; - unsigned int slc_avg_ec_cnt; - unsigned int total_ec_cnt; - unsigned int max_ec_cnt; - unsigned int min_ec_cnt; - unsigned int avg_ec_cnt; - unsigned int mrd_rr_good_cnt; - unsigned int ard_rr_good_cnt; - unsigned int preset_cnt; - unsigned int nvme_reset_cnt; - unsigned int low_pwr_cnt; - unsigned int wa; - unsigned int ps3_entry_cnt; - unsigned char highest_temp[4]; - unsigned int weight_ec; - unsigned int slc_cap_mb; - unsigned long long nand_page_write_cnt; - unsigned int program_error_cnt; - unsigned int erase_error_cnt; - unsigned char flash_type; - unsigned char reserved2[3]; - unsigned int hs_crc_err_cnt; - unsigned int ddr_ecc_err_cnt; - unsigned int reserved3[44]; +struct drvinfo_t { + unsigned char signature; + unsigned char fw_base; + unsigned short socid; + unsigned char soc_ver[4]; + unsigned char loader_version[8]; + unsigned char nand_devids[6]; + unsigned char ddr_type; + unsigned char ddr_size; + unsigned char rsvd1[8]; + unsigned char origin_fw_name[8]; + unsigned long long nand_type; + unsigned int board_type[5]; + unsigned short soc_type; + unsigned char build_mode; + unsigned char rsvd2; + unsigned int ftl_build_num; + unsigned short soc_reg; + unsigned char rsvd3[2]; + unsigned int cur_cpu_clk; + unsigned int cur_nf_clk; + unsigned char nand_geo[4]; + unsigned int fw_d2h_info_bit; + unsigned int spi_flash_id; + unsigned char rom_version[8]; + unsigned char rsvd4[404]; }; -#pragma pack(pop) struct cdump_pack { unsigned int ilenth; |