Blame plugins/memblaze/memblaze-nvme.c

Packit Service b7b338
#include <fcntl.h>
Packit Service b7b338
#include <errno.h>
Packit Service b7b338
#include <stdio.h>
Packit Service b7b338
#include <stdlib.h>
Packit Service b7b338
#include <unistd.h>
Packit Service b7b338
Packit Service b7b338
#include "linux/nvme_ioctl.h"
Packit Service b7b338
Packit Service b7b338
#include "nvme.h"
Packit Service b7b338
#include "nvme-print.h"
Packit Service b7b338
#include "nvme-ioctl.h"
Packit Service b7b338
#include "plugin.h"
Packit Service b7b338
Packit Service b7b338
#include "argconfig.h"
Packit Service b7b338
#include "suffix.h"
Packit Service b7b338
Packit Service b7b338
#define CREATE_CMD
Packit Service b7b338
#include "memblaze-nvme.h"
Packit Service b7b338
#include "memblaze-utils.h"
Packit Service b7b338
Packit Service b7b338
enum {
Packit Service b7b338
    MB_FEAT_POWER_MGMT = 0xc6,
Packit Service b7b338
};
Packit Service b7b338
Packit Service b7b338
/*
Packit Service b7b338
 * Return -1 if @fw1 < @fw2
Packit Service b7b338
 * Return 0 if @fw1 == @fw2
Packit Service b7b338
 * Return 1 if @fw1 > @fw2
Packit Service b7b338
 */
Packit Service b7b338
static int compare_fw_version(const char *fw1, const char *fw2)
Packit Service b7b338
{
Packit Service b7b338
    while (*fw1 != '\0') {
Packit Service b7b338
        if (*fw2 == '\0' || *fw1 > *fw2)
Packit Service b7b338
            return 1;
Packit Service b7b338
        if (*fw1 < *fw2)
Packit Service b7b338
            return -1;
Packit Service b7b338
        fw1++;
Packit Service b7b338
        fw2++;
Packit Service b7b338
    }
Packit Service b7b338
Packit Service b7b338
    if (*fw2 != '\0')
Packit Service b7b338
        return -1;
Packit Service b7b338
Packit Service b7b338
    return 0;
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
/**********************************************************
Packit Service b7b338
 * input: firmware version string
Packit Service b7b338
 * output:
Packit Service b7b338
 *     1: new intel format
Packit Service b7b338
 *     0: old memblaze format
Packit Service b7b338
 * *******************************************************/
Packit Service b7b338
#define MEMBLAZE_FORMAT         (0)
Packit Service b7b338
#define INTEL_FORMAT            (1)
Packit Service b7b338
Packit Service b7b338
// 2.83 = raisin
Packit Service b7b338
#define IS_RAISIN(str)          (!strcmp(str, "2.83"))
Packit Service b7b338
// 2.13 = papaya
Packit Service b7b338
#define IS_PAPAYA(str)          (!strcmp(str, "2.13"))
Packit Service b7b338
#define STR_VER_SIZE            5
Packit Service b7b338
Packit Service b7b338
int getlogpage_format_type(char *fw_ver)
Packit Service b7b338
{
Packit Service b7b338
    char fw_ver_local[STR_VER_SIZE];
Packit Service b7b338
    strncpy(fw_ver_local, fw_ver, STR_VER_SIZE);
Packit Service b7b338
    *(fw_ver_local + STR_VER_SIZE - 1) = '\0';
Packit Service b7b338
    if ( IS_RAISIN(fw_ver_local) )
Packit Service b7b338
    {
Packit Service b7b338
        return INTEL_FORMAT;
Packit Service b7b338
    }
Packit Service b7b338
    else
Packit Service b7b338
    {
Packit Service b7b338
        return MEMBLAZE_FORMAT;
Packit Service b7b338
    }
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static __u32 item_id_2_u32(struct nvme_memblaze_smart_log_item *item)
Packit Service b7b338
{
Packit Service b7b338
    __le32  __id = 0;
Packit Service b7b338
    memcpy(&__id, item->id, 3);
Packit Service b7b338
    return le32_to_cpu(__id);
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static __u64 raw_2_u64(const __u8 *buf, size_t len)
Packit Service b7b338
{
Packit Service b7b338
    __le64  val = 0;
Packit Service b7b338
    memcpy(&val, buf, len);
Packit Service b7b338
    return le64_to_cpu(val);
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
#define STRN2_01    "Additional Smart Log for NVME device"
Packit Service b7b338
#define STRN2_02    "namespace-id"
Packit Service b7b338
#define STRN1_01    "key"
Packit Service b7b338
#define STRN1_02    "normalized"
Packit Service b7b338
#define STRN1_03    "raw"
Packit Service b7b338
#define STR00_01    "program_fail_count"
Packit Service b7b338
#define STR01_01    "erase_fail_count"
Packit Service b7b338
#define STR02_01    "wear_leveling"
Packit Service b7b338
#define STR02_03    "min: "
Packit Service b7b338
#define STR02_04    ", max: "
Packit Service b7b338
#define STR02_05    ", avg: "
Packit Service b7b338
#define STR03_01    "end_to_end_error_detection_count"
Packit Service b7b338
#define STR04_01    "crc_error_count"
Packit Service b7b338
#define STR05_01    "timed_workload_media_wear"
Packit Service b7b338
#define STR06_01    "timed_workload_host_reads"
Packit Service b7b338
#define STR07_01    "timed_workload_timer"
Packit Service b7b338
#define STR07_02    " min"
Packit Service b7b338
#define STR08_01    "thermal_throttle_status"
Packit Service b7b338
#define STR08_02    ", cnt: "
Packit Service b7b338
#define STR09_01    "retry_buffer_overflow_count"
Packit Service b7b338
#define STR10_01    "pll_lock_loss_count"
Packit Service b7b338
#define STR11_01    "nand_bytes_written"
Packit Service b7b338
#define STR11_03    "sectors: "
Packit Service b7b338
#define STR12_01    "host_bytes_written"
Packit Service b7b338
#define STR12_03    "sectors: "
Packit Service b7b338
#define STR13_01    "system_area_life_left"
Packit Service b7b338
#define STR14_01    "total_read"
Packit Service b7b338
#define STR15_01    "tempt_since_born"
Packit Service b7b338
#define STR15_03    "max: "
Packit Service b7b338
#define STR15_04    ", min: "
Packit Service b7b338
#define STR15_05    ", curr: "
Packit Service b7b338
#define STR16_01    "power_consumption"
Packit Service b7b338
#define STR16_03    "max: "
Packit Service b7b338
#define STR16_04    ", min: "
Packit Service b7b338
#define STR16_05    ", curr: "
Packit Service b7b338
#define STR17_01    "tempt_since_bootup"
Packit Service b7b338
#define STR17_03    "max: "
Packit Service b7b338
#define STR17_04    ", min: "
Packit Service b7b338
#define STR17_05    ", curr: "
Packit Service b7b338
#define STR18_01    "power_loss_protection"
Packit Service b7b338
#define STR19_01    "read_fail"
Packit Service b7b338
#define STR20_01    "thermal_throttle_time"
Packit Service b7b338
#define STR21_01    "flash_media_error"
Packit Service b7b338
Packit Service b7b338
static void get_memblaze_new_smart_info(struct nvme_p4_smart_log *smart, int index, u8 *nm_val, u8 *raw_val)
Packit Service b7b338
{
Packit Service b7b338
    memcpy(nm_val, smart->itemArr[index].nmVal, NM_SIZE);
Packit Service b7b338
    memcpy(raw_val, smart->itemArr[index].rawVal, RAW_SIZE);
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static void show_memblaze_smart_log_new(struct nvme_memblaze_smart_log *s,
Packit Service b7b338
    unsigned int nsid, const char *devname)
Packit Service b7b338
{
Packit Service b7b338
    struct nvme_p4_smart_log *smart = (struct nvme_p4_smart_log *)s;
Packit Service b7b338
    u8 *nm = malloc(NM_SIZE * sizeof(u8));
Packit Service b7b338
    u8 *raw = malloc(RAW_SIZE * sizeof(u8));
Packit Service b7b338
Packit Service b7b338
    /* Table Title */
Packit Service b7b338
    printf("%s:%s %s:%x\n", STRN2_01, devname, STRN2_02, nsid);
Packit Service b7b338
    /* Clumn Name*/
Packit Service b7b338
    printf("%-34s%-11s%s\n", STRN1_01, STRN1_02, STRN1_03);
Packit Service b7b338
    /* 00 RAISIN_SI_VD_PROGRAM_FAIL */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PROGRAM_FAIL, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR00_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 01 RAISIN_SI_VD_ERASE_FAIL */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_ERASE_FAIL, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR01_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 02 RAISIN_SI_VD_WEARLEVELING_COUNT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_WEARLEVELING_COUNT, nm, raw);
Packit Service b7b338
    printf("%-31s : %3d%%       %s%u%s%u%s%u\n", STR02_01, *nm,
Packit Service b7b338
        STR02_03, *raw, STR02_04, *(raw+2), STR02_05, *(raw+4));
Packit Service b7b338
    /* 03 RAISIN_SI_VD_E2E_DECTECTION_COUNT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_E2E_DECTECTION_COUNT, nm, raw);
Packit Service b7b338
    printf("%-31s: %3d%%       %"PRIu64"\n", STR03_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 04 RAISIN_SI_VD_PCIE_CRC_ERR_COUNT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PCIE_CRC_ERR_COUNT, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR04_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 05 RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_MEDIA_WEAR, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %.3f%%\n", STR05_01, *nm, ((float)int48_to_long(raw))/1000);
Packit Service b7b338
    /* 06 RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_HOST_READ, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"%%\n", STR06_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 07 RAISIN_SI_VD_TIMED_WORKLOAD_TIMER */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TIMED_WORKLOAD_TIMER, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"%s\n", STR07_01, *nm, int48_to_long(raw), STR07_02);
Packit Service b7b338
    /* 08 RAISIN_SI_VD_THERMAL_THROTTLE_STATUS */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_STATUS, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"%%%s%"PRIu64"\n", STR08_01, *nm,
Packit Service b7b338
        int48_to_long(raw), STR08_02, int48_to_long(raw+1));
Packit Service b7b338
    /* 09 RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_RETRY_BUFF_OVERFLOW_COUNT, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR09_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 10 RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_PLL_LOCK_LOSS_COUNT, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR10_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 11 RAISIN_SI_VD_TOTAL_WRITE */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_WRITE, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %s%"PRIu64"\n", STR11_01, *nm, STR11_03, int48_to_long(raw));
Packit Service b7b338
    /* 12 RAISIN_SI_VD_HOST_WRITE */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_HOST_WRITE, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %s%"PRIu64"\n", STR12_01, *nm, STR12_03, int48_to_long(raw));
Packit Service b7b338
    /* 13 RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_SYSTEM_AREA_LIFE_LEFT, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR13_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 14 RAISIN_SI_VD_TOTAL_READ */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TOTAL_READ, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR14_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 15 RAISIN_SI_VD_TEMPT_SINCE_BORN */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BORN, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %s%u%s%u%s%u\n", STR15_01,  *nm,
Packit Service b7b338
        STR15_03, *raw, STR15_04, *(raw+2), STR15_05, *(raw+4));
Packit Service b7b338
    /* 16 RAISIN_SI_VD_POWER_CONSUMPTION */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_CONSUMPTION, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %s%u%s%u%s%u\n", STR16_01,  *nm,
Packit Service b7b338
        STR16_03, *raw, STR16_04, *(raw+2), STR16_05, *(raw+4));
Packit Service b7b338
    /* 17 RAISIN_SI_VD_TEMPT_SINCE_BOOTUP */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_TEMPT_SINCE_BOOTUP, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %s%u%s%u%s%u\n", STR17_01,  *nm, STR17_03, *raw,
Packit Service b7b338
        STR17_04, *(raw+2), STR17_05, *(raw+4));
Packit Service b7b338
    /* 18 RAISIN_SI_VD_POWER_LOSS_PROTECTION */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_POWER_LOSS_PROTECTION, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR18_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 19 RAISIN_SI_VD_READ_FAIL */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_READ_FAIL, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR19_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 20 RAISIN_SI_VD_THERMAL_THROTTLE_TIME */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_THERMAL_THROTTLE_TIME, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR20_01, *nm, int48_to_long(raw));
Packit Service b7b338
    /* 21 RAISIN_SI_VD_FLASH_MEDIA_ERROR */
Packit Service b7b338
    get_memblaze_new_smart_info(smart, RAISIN_SI_VD_FLASH_MEDIA_ERROR, nm, raw);
Packit Service b7b338
    printf("%-32s: %3d%%       %"PRIu64"\n", STR21_01, *nm, int48_to_long(raw));
Packit Service b7b338
Packit Service b7b338
    free(nm);
Packit Service b7b338
    free(raw);
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static void show_memblaze_smart_log_old(struct nvme_memblaze_smart_log *smart,
Packit Service b7b338
    unsigned int nsid, const char *devname, const char *fw_ver)
Packit Service b7b338
{
Packit Service b7b338
    char fw_ver_local[STR_VER_SIZE];
Packit Service b7b338
    struct nvme_memblaze_smart_log_item *item;
Packit Service b7b338
Packit Service b7b338
    strncpy(fw_ver_local, fw_ver, STR_VER_SIZE);
Packit Service b7b338
    *(fw_ver_local + STR_VER_SIZE - 1) = '\0';
Packit Service b7b338
Packit Service b7b338
    printf("Additional Smart Log for NVME device:%s namespace-id:%x\n", devname, nsid);
Packit Service b7b338
Packit Service b7b338
    printf("Total write in GB since last factory reset			: %"PRIu64"\n",
Packit Service b7b338
        int48_to_long(smart->items[TOTAL_WRITE].rawval));
Packit Service b7b338
    printf("Total read in GB since last factory reset			: %"PRIu64"\n",
Packit Service b7b338
        int48_to_long(smart->items[TOTAL_READ].rawval));
Packit Service b7b338
Packit Service b7b338
    printf("Thermal throttling status[1:HTP in progress]			: %u\n",
Packit Service b7b338
        smart->items[THERMAL_THROTTLE].thermal_throttle.on);
Packit Service b7b338
    printf("Total thermal throttling minutes since power on			: %u\n",
Packit Service b7b338
        smart->items[THERMAL_THROTTLE].thermal_throttle.count);
Packit Service b7b338
Packit Service b7b338
    printf("Maximum temperature in Kelvin since last factory reset		: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.max));
Packit Service b7b338
    printf("Minimum temperature in Kelvin since last factory reset		: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.min));
Packit Service b7b338
    if (compare_fw_version(fw_ver, "0.09.0300") != 0) {
Packit Service b7b338
        printf("Maximum temperature in Kelvin since power on			: %u\n",
Packit Service b7b338
            le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.max));
Packit Service b7b338
        printf("Minimum temperature in Kelvin since power on			: %u\n",
Packit Service b7b338
            le16_to_cpu(smart->items[TEMPT_SINCE_BOOTUP].temperature_p.min));
Packit Service b7b338
    }
Packit Service b7b338
    printf("Current temperature in Kelvin					: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[TEMPT_SINCE_RESET].temperature.curr));
Packit Service b7b338
Packit Service b7b338
    printf("Maximum power in watt since power on				: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[POWER_CONSUMPTION].power.max));
Packit Service b7b338
    printf("Minimum power in watt since power on				: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[POWER_CONSUMPTION].power.min));
Packit Service b7b338
    printf("Current power in watt						: %u\n",
Packit Service b7b338
        le16_to_cpu(smart->items[POWER_CONSUMPTION].power.curr));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[POWER_LOSS_PROTECTION];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xEC)
Packit Service b7b338
        printf("Power loss protection normalized value				: %u\n",
Packit Service b7b338
            item->power_loss_protection.curr);
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[WEARLEVELING_COUNT];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xAD) {
Packit Service b7b338
        printf("Percentage of wearleveling count left				: %u\n",
Packit Service b7b338
            le16_to_cpu(item->nmval));
Packit Service b7b338
        printf("Wearleveling count min erase cycle				: %u\n",
Packit Service b7b338
            le16_to_cpu(item->wearleveling_count.min));
Packit Service b7b338
        printf("Wearleveling count max erase cycle				: %u\n",
Packit Service b7b338
            le16_to_cpu(item->wearleveling_count.max));
Packit Service b7b338
        printf("Wearleveling count avg erase cycle				: %u\n",
Packit Service b7b338
            le16_to_cpu(item->wearleveling_count.avg));
Packit Service b7b338
    }
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[HOST_WRITE];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xF5)
Packit Service b7b338
        printf("Total host write in GiB since device born 			: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[THERMAL_THROTTLE_CNT];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xEB)
Packit Service b7b338
        printf("Thermal throttling count since device born 			: %u\n",
Packit Service b7b338
            item->thermal_throttle_cnt.cnt);
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[CORRECT_PCIE_PORT0];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xED)
Packit Service b7b338
        printf("PCIE Correctable Error Count of Port0    			: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[CORRECT_PCIE_PORT1];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xEE)
Packit Service b7b338
        printf("PCIE Correctable Error Count of Port1 	        		: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[REBUILD_FAIL];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xEF)
Packit Service b7b338
        printf("End-to-End Error Detection Count 	        		: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[ERASE_FAIL];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xF0)
Packit Service b7b338
        printf("Erase Fail Count 		                        	: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[PROGRAM_FAIL];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xF1)
Packit Service b7b338
        printf("Program Fail Count 		                        	: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
    item = &smart->items[READ_FAIL];
Packit Service b7b338
    if (item_id_2_u32(item) == 0xF2)
Packit Service b7b338
        printf("Read Fail Count	                                 		: %llu\n",
Packit Service b7b338
            (unsigned long long)raw_2_u64(item->rawval, sizeof(item->rawval)));
Packit Service b7b338
Packit Service b7b338
     if ( IS_PAPAYA(fw_ver_local) ) {
Packit Service b7b338
        struct nvme_p4_smart_log *s = (struct nvme_p4_smart_log *)smart;
Packit Service b7b338
        u8 *nm = malloc(NM_SIZE * sizeof(u8));
Packit Service b7b338
        u8 *raw = malloc(RAW_SIZE * sizeof(u8));
Packit Service b7b338
Packit Service b7b338
        /* 00 RAISIN_SI_VD_PROGRAM_FAIL */
Packit Service b7b338
        get_memblaze_new_smart_info(s, PROGRAM_FAIL, nm, raw);
Packit Service b7b338
        printf("%-32s                                : %3d%%       %"PRIu64"\n",
Packit Service b7b338
			STR00_01, *nm, int48_to_long(raw));
Packit Service b7b338
        /* 01 RAISIN_SI_VD_ERASE_FAIL */
Packit Service b7b338
        get_memblaze_new_smart_info(s, ERASE_FAIL, nm, raw);
Packit Service b7b338
        printf("%-32s                                : %3d%%       %"PRIu64"\n",
Packit Service b7b338
			STR01_01, *nm, int48_to_long(raw));
Packit Service b7b338
        /* 02 RAISIN_SI_VD_WEARLEVELING_COUNT */
Packit Service b7b338
        get_memblaze_new_smart_info(s, WEARLEVELING_COUNT, nm, raw);
Packit Service b7b338
        printf("%-31s                                 : %3d%%       %s%u%s%u%s%u\n",
Packit Service b7b338
			STR02_01, *nm, STR02_03, *raw, STR02_04, *(raw+2), STR02_05, *(raw+4));
Packit Service b7b338
        /* 11 RAISIN_SI_VD_TOTAL_WRITE */
Packit Service b7b338
        get_memblaze_new_smart_info(s, TOTAL_WRITE, nm, raw);
Packit Service b7b338
        printf("%-32s                                : %3d%%       %"PRIu64"\n",
Packit Service b7b338
			STR11_01, *nm, 32*int48_to_long(raw));
Packit Service b7b338
        /* 12 RAISIN_SI_VD_HOST_WRITE */
Packit Service b7b338
        get_memblaze_new_smart_info(s, HOST_WRITE, nm, raw);
Packit Service b7b338
        printf("%-32s                                : %3d%%       %"PRIu64"\n",
Packit Service b7b338
			STR12_01, *nm, 32*int48_to_long(raw));
Packit Service b7b338
Packit Service b7b338
        free(nm);
Packit Service b7b338
        free(raw);
Packit Service b7b338
    }
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int show_memblaze_smart_log(int fd, __u32 nsid, const char *devname,
Packit Service b7b338
    struct nvme_memblaze_smart_log *smart)
Packit Service b7b338
{
Packit Service b7b338
    struct nvme_id_ctrl ctrl;
Packit Service b7b338
    char fw_ver[10];
Packit Service b7b338
    int err = 0;
Packit Service b7b338
Packit Service b7b338
    err = nvme_identify_ctrl(fd, &ctrl);
Packit Service b7b338
    if (err)
Packit Service b7b338
        return err;
Packit Service b7b338
Packit Service b7b338
    snprintf(fw_ver, sizeof(fw_ver), "%c.%c%c.%c%c%c%c",
Packit Service b7b338
        ctrl.fr[0], ctrl.fr[1], ctrl.fr[2], ctrl.fr[3],
Packit Service b7b338
        ctrl.fr[4], ctrl.fr[5], ctrl.fr[6]);
Packit Service b7b338
Packit Service b7b338
    if (getlogpage_format_type(fw_ver)) // Intel Format & new format
Packit Service b7b338
    {
Packit Service b7b338
        show_memblaze_smart_log_new(smart, nsid, devname);
Packit Service b7b338
    }
Packit Service b7b338
    else  // Memblaze Format & old format
Packit Service b7b338
    {
Packit Service b7b338
        show_memblaze_smart_log_old(smart, nsid, devname, fw_ver);
Packit Service b7b338
    }
Packit Service b7b338
	return err;
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int get_additional_smart_log(int argc, char **argv, struct command *cmd, struct plugin *plugin)
Packit Service b7b338
{
Packit Service b7b338
	struct nvme_memblaze_smart_log smart_log;
Packit Service b7b338
	int err, fd;
Packit Service b7b338
	char *desc = "Get Memblaze vendor specific additional smart log (optionally, "\
Packit Service b7b338
		      "for the specified namespace), and show it.";
Packit Service b7b338
	const char *namespace = "(optional) desired namespace";
Packit Service b7b338
	const char *raw = "dump output in binary format";
Packit Service b7b338
	struct config {
Packit Service b7b338
		__u32 namespace_id;
Packit Service b7b338
		int   raw_binary;
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	struct config cfg = {
Packit Service b7b338
		.namespace_id = NVME_NSID_ALL,
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	OPT_ARGS(opts) = {
Packit Service b7b338
		OPT_UINT("namespace-id", 'n', &cfg.namespace_id,  namespace),
Packit Service b7b338
		OPT_FLAG("raw-binary",   'b', &cfg.raw_binary,    raw),
Packit Service b7b338
		OPT_END()
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	fd = parse_and_open(argc, argv, desc, opts);
Packit Service b7b338
	if (fd < 0)
Packit Service b7b338
		return fd;
Packit Service b7b338
Packit Service b7b338
	err = nvme_get_log(fd, cfg.namespace_id, 0xca, false,
Packit Service b7b338
			   sizeof(smart_log), &smart_log);
Packit Service b7b338
	if (!err) {
Packit Service b7b338
		if (!cfg.raw_binary)
Packit Service b7b338
			err = show_memblaze_smart_log(fd, cfg.namespace_id, devicename, &smart_log);
Packit Service b7b338
		else
Packit Service b7b338
			d_raw((unsigned char *)&smart_log, sizeof(smart_log));
Packit Service b7b338
	}
Packit Service b7b338
	if (err > 0)
Packit Service b7b338
		fprintf(stderr, "NVMe Status:%s(%x)\n", nvme_status_to_string(err), err);
Packit Service b7b338
Packit Service b7b338
	return err;
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static char *mb_feature_to_string(int feature)
Packit Service b7b338
{
Packit Service b7b338
	switch (feature) {
Packit Service b7b338
	case MB_FEAT_POWER_MGMT: return "Memblaze power management";
Packit Service b7b338
	default:	return "Unknown";
Packit Service b7b338
	}
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int get_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
Packit Service b7b338
{
Packit Service b7b338
	const char *desc = "Read operating parameters of the "\
Packit Service b7b338
		"specified controller. Operating parameters are grouped "\
Packit Service b7b338
		"and identified by Feature Identifiers; each Feature "\
Packit Service b7b338
		"Identifier contains one or more attributes that may affect "\
Packit Service b7b338
		"behaviour of the feature. Each Feature has three possible "\
Packit Service b7b338
		"settings: default, saveable, and current. If a Feature is "\
Packit Service b7b338
		"saveable, it may be modified by set-feature. Default values "\
Packit Service b7b338
		"are vendor-specific and not changeable. Use set-feature to "\
Packit Service b7b338
		"change saveable Features.\n\n"\
Packit Service b7b338
		"Available additional feature id:\n"\
Packit Service b7b338
		"0xc6:	Memblaze power management\n"\
Packit Service b7b338
		"	(value 0 - 25w, 1 - 20w, 2 - 15w)";
Packit Service b7b338
	const char *raw = "show feature in binary format";
Packit Service b7b338
	const char *namespace_id = "identifier of desired namespace";
Packit Service b7b338
	const char *feature_id = "hexadecimal feature name";
Packit Service b7b338
	const char *sel = "[0-3]: curr./default/saved/supp.";
Packit Service b7b338
	const char *data_len = "buffer len (if) data is returned";
Packit Service b7b338
	const char *cdw11 = "dword 11 for interrupt vector config";
Packit Service b7b338
	const char *human_readable = "show infos in readable format";
Packit Service b7b338
	int err, fd;
Packit Service b7b338
	__u32 result;
Packit Service b7b338
	void *buf = NULL;
Packit Service b7b338
Packit Service b7b338
	struct config {
Packit Service b7b338
		__u32 namespace_id;
Packit Service b7b338
		__u32 feature_id;
Packit Service b7b338
		__u8  sel;
Packit Service b7b338
		__u32 cdw11;
Packit Service b7b338
		__u32 data_len;
Packit Service b7b338
		int  raw_binary;
Packit Service b7b338
		int  human_readable;
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	struct config cfg = {
Packit Service b7b338
		.namespace_id = 1,
Packit Service b7b338
		.feature_id   = 0,
Packit Service b7b338
		.sel          = 0,
Packit Service b7b338
		.cdw11        = 0,
Packit Service b7b338
		.data_len     = 0,
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	OPT_ARGS(opts) = {
Packit Service b7b338
		OPT_UINT("namespace-id",   'n', &cfg.namespace_id,   namespace_id),
Packit Service b7b338
		OPT_UINT("feature-id",     'f', &cfg.feature_id,     feature_id),
Packit Service b7b338
		OPT_BYTE("sel",            's', &cfg.sel,            sel),
Packit Service b7b338
		OPT_UINT("data-len",       'l', &cfg.data_len,       data_len),
Packit Service b7b338
		OPT_UINT("cdw11",          'c', &cfg.cdw11,          cdw11),
Packit Service b7b338
		OPT_FLAG("human-readable", 'H', &cfg.human_readable, human_readable),
Packit Service b7b338
		OPT_FLAG("raw-binary",     'b', &cfg.raw_binary,     raw),
Packit Service b7b338
		OPT_END()
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	fd = parse_and_open(argc, argv, desc, opts);
Packit Service b7b338
	if (fd < 0)
Packit Service b7b338
		return fd;
Packit Service b7b338
Packit Service b7b338
	if (cfg.sel > 7) {
Packit Service b7b338
		fprintf(stderr, "invalid 'select' param:%d\n", cfg.sel);
Packit Service b7b338
		return EINVAL;
Packit Service b7b338
	}
Packit Service b7b338
	if (!cfg.feature_id) {
Packit Service b7b338
		fprintf(stderr, "feature-id required param\n");
Packit Service b7b338
		return EINVAL;
Packit Service b7b338
	}
Packit Service b7b338
	if (cfg.data_len) {
Packit Service b7b338
		if (posix_memalign(&buf, getpagesize(), cfg.data_len))
Packit Service b7b338
			exit(ENOMEM);
Packit Service b7b338
		memset(buf, 0, cfg.data_len);
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	err = nvme_get_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.sel, cfg.cdw11,
Packit Service b7b338
			cfg.data_len, buf, &result);
Packit Service b7b338
	if (!err) {
Packit Service b7b338
		printf("get-feature:0x%02x (%s), %s value: %#08x\n", cfg.feature_id,
Packit Service b7b338
				mb_feature_to_string(cfg.feature_id),
Packit Service b7b338
				nvme_select_to_string(cfg.sel), result);
Packit Service b7b338
		if (cfg.human_readable)
Packit Service b7b338
			nvme_feature_show_fields(cfg.feature_id, result, buf);
Packit Service b7b338
		else {
Packit Service b7b338
			if (buf) {
Packit Service b7b338
				if (!cfg.raw_binary)
Packit Service b7b338
					d(buf, cfg.data_len, 16, 1);
Packit Service b7b338
				else
Packit Service b7b338
					d_raw(buf, cfg.data_len);
Packit Service b7b338
			}
Packit Service b7b338
		}
Packit Service b7b338
	} else if (err > 0)
Packit Service b7b338
		fprintf(stderr, "NVMe Status:%s(%x)\n",
Packit Service b7b338
				nvme_status_to_string(err), err);
Packit Service b7b338
	if (buf)
Packit Service b7b338
		free(buf);
Packit Service b7b338
	return err;
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int set_additional_feature(int argc, char **argv, struct command *cmd, struct plugin *plugin)
Packit Service b7b338
{
Packit Service b7b338
	const char *desc = "Modify the saveable or changeable "\
Packit Service b7b338
		"current operating parameters of the controller. Operating "\
Packit Service b7b338
		"parameters are grouped and identified by Feature "\
Packit Service b7b338
		"Identifiers. Feature settings can be applied to the entire "\
Packit Service b7b338
		"controller and all associated namespaces, or to only a few "\
Packit Service b7b338
		"namespace(s) associated with the controller. Default values "\
Packit Service b7b338
		"for each Feature are vendor-specific and may not be modified."\
Packit Service b7b338
		"Use get-feature to determine which Features are supported by "\
Packit Service b7b338
		"the controller and are saveable/changeable.\n\n"\
Packit Service b7b338
		"Available additional feature id:\n"\
Packit Service b7b338
		"0xc6:	Memblaze power management\n"\
Packit Service b7b338
		"	(value 0 - 25w, 1 - 20w, 2 - 15w)";
Packit Service b7b338
	const char *namespace_id = "desired namespace";
Packit Service b7b338
	const char *feature_id = "hex feature name (required)";
Packit Service b7b338
	const char *data_len = "buffer length if data required";
Packit Service b7b338
	const char *data = "optional file for feature data (default stdin)";
Packit Service b7b338
	const char *value = "new value of feature (required)";
Packit Service b7b338
	const char *save = "specifies that the controller shall save the attribute";
Packit Service b7b338
	int err, fd;
Packit Service b7b338
	__u32 result;
Packit Service b7b338
	void *buf = NULL;
Packit Service b7b338
	int ffd = STDIN_FILENO;
Packit Service b7b338
Packit Service b7b338
	struct config {
Packit Service b7b338
		char *file;
Packit Service b7b338
		__u32 namespace_id;
Packit Service b7b338
		__u32 feature_id;
Packit Service b7b338
		__u32 value;
Packit Service b7b338
		__u32 data_len;
Packit Service b7b338
		int   save;
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	struct config cfg = {
Packit Service b7b338
		.file         = "",
Packit Service b7b338
		.namespace_id = 0,
Packit Service b7b338
		.feature_id   = 0,
Packit Service b7b338
		.value        = 0,
Packit Service b7b338
		.data_len     = 0,
Packit Service b7b338
		.save         = 0,
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	OPT_ARGS(opts) = {
Packit Service b7b338
		OPT_UINT("namespace-id", 'n', &cfg.namespace_id, namespace_id),
Packit Service b7b338
		OPT_UINT("feature-id",   'f', &cfg.feature_id,   feature_id),
Packit Service b7b338
		OPT_UINT("value",        'v', &cfg.value,        value),
Packit Service b7b338
		OPT_UINT("data-len",     'l', &cfg.data_len,     data_len),
Packit Service b7b338
		OPT_FILE("data",         'd', &cfg.file,         data),
Packit Service b7b338
		OPT_FLAG("save",         's', &cfg.save,         save),
Packit Service b7b338
		OPT_END()
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	fd = parse_and_open(argc, argv, desc, opts);
Packit Service b7b338
	if (fd < 0)
Packit Service b7b338
		return fd;
Packit Service b7b338
Packit Service b7b338
	if (!cfg.feature_id) {
Packit Service b7b338
		fprintf(stderr, "feature-id required param\n");
Packit Service b7b338
		return EINVAL;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	if (cfg.data_len) {
Packit Service b7b338
		if (posix_memalign(&buf, getpagesize(), cfg.data_len))
Packit Service b7b338
			exit(ENOMEM);
Packit Service b7b338
		memset(buf, 0, cfg.data_len);
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	if (buf) {
Packit Service b7b338
		if (strlen(cfg.file)) {
Packit Service b7b338
			ffd = open(cfg.file, O_RDONLY);
Packit Service b7b338
			if (ffd <= 0) {
Packit Service b7b338
				fprintf(stderr, "no firmware file provided\n");
Packit Service b7b338
				err = EINVAL;
Packit Service b7b338
				goto free;
Packit Service b7b338
			}
Packit Service b7b338
		}
Packit Service b7b338
		if (read(ffd, (void *)buf, cfg.data_len) < 0) {
Packit Service b7b338
			fprintf(stderr, "failed to read data buffer from input file\n");
Packit Service b7b338
			err = EINVAL;
Packit Service b7b338
			goto free;
Packit Service b7b338
		}
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	err = nvme_set_feature(fd, cfg.namespace_id, cfg.feature_id, cfg.value,
Packit Service b7b338
				0, cfg.save, cfg.data_len, buf, &result);
Packit Service b7b338
	if (err < 0) {
Packit Service b7b338
		perror("set-feature");
Packit Service b7b338
		goto free;
Packit Service b7b338
	}
Packit Service b7b338
	if (!err) {
Packit Service b7b338
		printf("set-feature:%02x (%s), value:%#08x\n", cfg.feature_id,
Packit Service b7b338
			mb_feature_to_string(cfg.feature_id), cfg.value);
Packit Service b7b338
		if (buf)
Packit Service b7b338
			d(buf, cfg.data_len, 16, 1);
Packit Service b7b338
	} else if (err > 0)
Packit Service b7b338
		fprintf(stderr, "NVMe Status:%s(%x)\n",
Packit Service b7b338
				nvme_status_to_string(err), err);
Packit Service b7b338
Packit Service b7b338
free:
Packit Service b7b338
	if (buf)
Packit Service b7b338
		free(buf);
Packit Service b7b338
	return err;
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int memblaze_fw_commit(int fd, int select)
Packit Service b7b338
{
Packit Service b7b338
	struct nvme_admin_cmd cmd = {
Packit Service b7b338
		.opcode		= nvme_admin_activate_fw,
Packit Service b7b338
		.cdw10		= 8,
Packit Service b7b338
		.cdw12      = select,
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	return nvme_submit_admin_passthru(fd, &cmd);
Packit Service b7b338
}
Packit Service b7b338
Packit Service b7b338
static int memblaze_selective_download(int argc, char **argv, struct command *cmd, struct plugin *plugin)
Packit Service b7b338
{
Packit Service b7b338
	const char *desc =
Packit Service b7b338
		"This performs a selective firmware download, which allows the user to "
Packit Service b7b338
		"select which firmware binary to update for 9200 devices. This requires a power cycle once the "
Packit Service b7b338
		"update completes. The options available are: \n\n"
Packit Service b7b338
		"OOB - This updates the OOB and main firmware\n"
Packit Service b7b338
		"EEP - This updates the eeprom and main firmware\n"
Packit Service b7b338
		"ALL - This updates the eeprom, OOB, and main firmware";
Packit Service b7b338
	const char *fw = "firmware file (required)";
Packit Service b7b338
	const char *select = "FW Select (e.g., --select=OOB, EEP, ALL)";
Packit Service b7b338
	int xfer = 4096;
Packit Service b7b338
	void *fw_buf;
Packit Service b7b338
	int fd, selectNo,fw_fd,fw_size,err,offset = 0;
Packit Service b7b338
	struct stat sb;
Packit Service b7b338
	int i;
Packit Service b7b338
Packit Service b7b338
	struct config {
Packit Service b7b338
		char  *fw;
Packit Service b7b338
		char  *select;
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	struct config cfg = {
Packit Service b7b338
		.fw     = "",
Packit Service b7b338
		.select = "\0",
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	OPT_ARGS(opts) = {
Packit Service b7b338
		OPT_STRING("fw", 'f', "FILE", &cfg.fw, fw),
Packit Service b7b338
		OPT_STRING("select", 's', "flag", &cfg.select, select),
Packit Service b7b338
		OPT_END()
Packit Service b7b338
	};
Packit Service b7b338
Packit Service b7b338
	fd = parse_and_open(argc, argv, desc, opts);
Packit Service b7b338
	if (fd < 0)
Packit Service b7b338
		return fd;
Packit Service b7b338
Packit Service b7b338
	if (strlen(cfg.select) != 3) {
Packit Service b7b338
		fprintf(stderr, "Invalid select flag\n");
Packit Service b7b338
		err = EINVAL;
Packit Service b7b338
		goto out;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	for (i = 0; i < 3; i++) {
Packit Service b7b338
		cfg.select[i] = toupper(cfg.select[i]);
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	if (strncmp(cfg.select,"OOB", 3) == 0) {
Packit Service b7b338
		selectNo = 18;
Packit Service b7b338
	} else if (strncmp(cfg.select,"EEP", 3) == 0) {
Packit Service b7b338
		selectNo = 10;
Packit Service b7b338
	} else if (strncmp(cfg.select,"ALL", 3) == 0) {
Packit Service b7b338
		selectNo = 26;
Packit Service b7b338
	} else {
Packit Service b7b338
		fprintf(stderr, "Invalid select flag\n");
Packit Service b7b338
		err = EINVAL;
Packit Service b7b338
		goto out;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	fw_fd = open(cfg.fw, O_RDONLY);
Packit Service b7b338
	if (fw_fd < 0) {
Packit Service b7b338
		fprintf(stderr, "no firmware file provided\n");
Packit Service b7b338
		err = EINVAL;
Packit Service b7b338
		goto out;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	err = fstat(fw_fd, &sb);
Packit Service b7b338
	if (err < 0) {
Packit Service b7b338
		perror("fstat");
Packit Service b7b338
		err = errno;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	fw_size = sb.st_size;
Packit Service b7b338
	if (fw_size & 0x3) {
Packit Service b7b338
		fprintf(stderr, "Invalid size:%d for f/w image\n", fw_size);
Packit Service b7b338
		err = EINVAL;
Packit Service b7b338
		goto out;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	if (posix_memalign(&fw_buf, getpagesize(), fw_size)) {
Packit Service b7b338
		fprintf(stderr, "No memory for f/w size:%d\n", fw_size);
Packit Service b7b338
		err = ENOMEM;
Packit Service b7b338
		goto out;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	if (read(fw_fd, fw_buf, fw_size) != ((ssize_t)(fw_size)))
Packit Service b7b338
		return EIO;
Packit Service b7b338
Packit Service b7b338
	while (fw_size > 0) {
Packit Service b7b338
		xfer = min(xfer, fw_size);
Packit Service b7b338
Packit Service b7b338
		err = nvme_fw_download(fd, offset, xfer, fw_buf);
Packit Service b7b338
		if (err < 0) {
Packit Service b7b338
			perror("fw-download");
Packit Service b7b338
			goto out;
Packit Service b7b338
		} else if (err != 0) {
Packit Service b7b338
			fprintf(stderr, "NVME Admin command error:%s(%x)\n",
Packit Service b7b338
					nvme_status_to_string(err), err);
Packit Service b7b338
			goto out;
Packit Service b7b338
		}
Packit Service b7b338
		fw_buf     += xfer;
Packit Service b7b338
		fw_size    -= xfer;
Packit Service b7b338
		offset += xfer;
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
	err = memblaze_fw_commit(fd,selectNo);
Packit Service b7b338
Packit Service b7b338
	if(err == 0x10B || err == 0x20B) {
Packit Service b7b338
		err = 0;
Packit Service b7b338
		fprintf(stderr, "Update successful! Please power cycle for changes to take effect\n");
Packit Service b7b338
	}
Packit Service b7b338
Packit Service b7b338
out:
Packit Service b7b338
	return err;
Packit Service b7b338
}
Packit Service b7b338