diff --git a/examples/nvme/identify/identify.c b/examples/nvme/identify/identify.c index 74d2e3681..4435c90c6 100644 --- a/examples/nvme/identify/identify.c +++ b/examples/nvme/identify/identify.c @@ -25,6 +25,8 @@ #define MAX_OCSSD_PU 128 #define MAX_ZONE_DESC_ENTRIES 8 +#define FDP_LOG_PAGE_SIZE 4096 + static int outstanding_commands; struct feature { @@ -46,6 +48,21 @@ static struct spdk_nvme_ana_group_descriptor *g_copied_ana_desc; static size_t g_ana_log_page_size; +static uint8_t g_fdp_cfg_log_page_buf[FDP_LOG_PAGE_SIZE]; + +static uint8_t g_fdp_ruhu_log_page_buf[FDP_LOG_PAGE_SIZE]; + +static uint8_t g_fdp_events_log_page_buf[FDP_LOG_PAGE_SIZE]; + +static struct spdk_nvme_fdp_stats_log_page g_fdp_stats_log_page; + +static struct spdk_nvme_fdp_cfg_log_page *g_fdp_cfg_log_page = (void *)g_fdp_cfg_log_page_buf; + +static struct spdk_nvme_fdp_ruhu_log_page *g_fdp_ruhu_log_page = (void *)g_fdp_ruhu_log_page_buf; + +static struct spdk_nvme_fdp_events_log_page *g_fdp_events_log_page = (void *) + g_fdp_events_log_page_buf; + static struct spdk_nvme_cmds_and_effect_log_page cmd_effects_log_page; static struct spdk_nvme_intel_smart_information_page intel_smart_page; @@ -496,6 +513,114 @@ get_log_pages(struct spdk_nvme_ctrlr *ctrlr) } } +static int +get_fdp_cfg_log_page(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); + const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); + + outstanding_commands = 0; + + if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS)) { + /* Fetch the FDP configurations log page for only 4096 bytes */ + if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS, 0, + g_fdp_cfg_log_page, FDP_LOG_PAGE_SIZE, 0, 0, (nsdata->endgid << 16), + 0, get_log_page_completion, NULL) == 0) { + outstanding_commands++; + } else { + printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP config) failed\n"); + return -1; + } + } + + while (outstanding_commands) { + spdk_nvme_ctrlr_process_admin_completions(ctrlr); + } + + return 0; +} + +static int +get_fdp_ruhu_log_page(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); + const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); + + outstanding_commands = 0; + + if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE)) { + /* Fetch the reclaim unit handle usage log page for only 4096 bytes */ + if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE, 0, + g_fdp_ruhu_log_page, FDP_LOG_PAGE_SIZE, 0, 0, (nsdata->endgid << 16), + 0, get_log_page_completion, NULL) == 0) { + outstanding_commands++; + } else { + printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(RUH usage) failed\n"); + return -1; + } + } + + while (outstanding_commands) { + spdk_nvme_ctrlr_process_admin_completions(ctrlr); + } + + return 0; +} + +static int +get_fdp_stats_log_page(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); + const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); + + outstanding_commands = 0; + + if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_LOG_FDP_STATISTICS)) { + if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_STATISTICS, 0, + &g_fdp_stats_log_page, 64, 0, 0, (nsdata->endgid << 16), 0, + get_log_page_completion, NULL) == 0) { + outstanding_commands++; + } else { + printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP stats) failed\n"); + return -1; + } + } + + while (outstanding_commands) { + spdk_nvme_ctrlr_process_admin_completions(ctrlr); + } + + return 0; +} + +static int +get_fdp_events_log_page(struct spdk_nvme_ns *ns) +{ + struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns); + const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns); + + outstanding_commands = 0; + + if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_LOG_FDP_EVENTS)) { + /* Only fetch FDP host events here */ + if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_EVENTS, 0, + g_fdp_events_log_page, FDP_LOG_PAGE_SIZE, 0, + (SPDK_NVME_FDP_REPORT_HOST_EVENTS << 8), (nsdata->endgid << 16), + 0, get_log_page_completion, NULL) == 0) { + outstanding_commands++; + } else { + printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP events) failed\n"); + return -1; + } + } + + while (outstanding_commands) { + spdk_nvme_ctrlr_process_admin_completions(ctrlr); + } + + return 0; +} + static int get_ocssd_chunk_info_log_page(struct spdk_nvme_ns *ns) { @@ -636,6 +761,182 @@ print_uline(char marker, int line_len) putchar('\n'); } +static void +print_fdp_cfg_log_page(void) +{ + uint32_t i, j; + struct spdk_nvme_fdp_cfg_descriptor *cfg_desc; + void *log = g_fdp_cfg_log_page->cfg_desc; + + printf("FDP configurations log page\n"); + printf("===========================\n"); + if (g_hex_dump) { + hex_dump(g_fdp_cfg_log_page, FDP_LOG_PAGE_SIZE); + printf("\n"); + } + + printf("Number of FDP configurations: %u\n", g_fdp_cfg_log_page->ncfg + 1); + printf("Version: %u\n", g_fdp_cfg_log_page->version); + printf("Size: %u\n", g_fdp_cfg_log_page->size); + + for (i = 0; i <= g_fdp_cfg_log_page->ncfg; i++) { + cfg_desc = log; + printf("FDP Configuration Descriptor: %u\n", i); + printf(" Descriptor Size: %u\n", cfg_desc->ds); + printf(" Reclaim Group Identifier format: %u\n", cfg_desc->fdpa.bits.rgif); + printf(" FDP Volatile Write Cache: %s\n", + cfg_desc->fdpa.bits.fdpvwc ? "Present" : "Not Present"); + printf(" FDP Configuration: %s\n", + cfg_desc->fdpa.bits.fdpcv ? "Valid" : "Invalid"); + printf(" Vendor Specific Size: %u\n", cfg_desc->vss); + printf(" Number of Reclaim Groups: %u\n", cfg_desc->nrg); + printf(" Number of Recalim Unit Handles: %u\n", cfg_desc->nruh); + printf(" Max Placement Identifiers: %u\n", cfg_desc->maxpids + 1); + printf(" Number of Namespaces Suppprted: %u\n", cfg_desc->nns); + printf(" Reclaim unit Nominal Size: %" PRIx64 " bytes\n", cfg_desc->runs); + printf(" Estimated Reclaim Unit Time Limit: "); + if (cfg_desc->erutl) { + printf("%u seconds\n", cfg_desc->erutl); + } else { + printf("Not Reported\n"); + } + for (j = 0; j < cfg_desc->nruh; j++) { + printf(" RUH Desc #%03d: RUH Type: %s\n", j, + cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" : + cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED ? "Persistently Isolated" : + "Reserved"); + } + log += cfg_desc->ds; + } + + printf("\n"); + +} + +static void +print_fdp_ruhu_log_page(void) +{ + uint32_t i; + struct spdk_nvme_fdp_ruhu_descriptor *ruhu_desc; + + printf("FDP reclaim unit handle usage log page\n"); + printf("======================================\n"); + if (g_hex_dump) { + hex_dump(g_fdp_ruhu_log_page, FDP_LOG_PAGE_SIZE); + printf("\n"); + } + + printf("Number of Reclaim Unit Handles: %u\n", g_fdp_ruhu_log_page->nruh); + + for (i = 0; i < g_fdp_ruhu_log_page->nruh; i++) { + ruhu_desc = &g_fdp_ruhu_log_page->ruhu_desc[i]; + + printf(" RUH Usage Desc #%03d: RUH Attributes: %s\n", i, + ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_UNUSED ? "Unused" : + ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_HOST_SPECIFIED ? "Host Specified" : + ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED ? "Controller Specified" : + "Reserved"); + } + + printf("\n"); +} + +static void +print_fdp_stats_log_page(void) +{ + printf("FDP statistics log page\n"); + printf("=======================\n"); + if (g_hex_dump) { + hex_dump(&g_fdp_stats_log_page, 64); + printf("\n"); + } + + printf("Host bytes with metadata written: "); + print_uint128_dec(g_fdp_stats_log_page.hbmw); + printf("\n"); + printf("Media bytes with metadata written: "); + print_uint128_dec(g_fdp_stats_log_page.mbmw); + printf("\n"); + printf("Media bytes erased: "); + print_uint128_dec(g_fdp_stats_log_page.mbe); + printf("\n\n"); +} + +static void +print_fdp_events_log_page(void) +{ + uint32_t i; + struct spdk_nvme_fdp_event *event; + struct spdk_nvme_fdp_event_media_reallocated *media_reallocated; + + printf("FDP events log page\n"); + printf("===================\n"); + if (g_hex_dump) { + hex_dump(g_fdp_events_log_page, FDP_LOG_PAGE_SIZE); + printf("\n"); + } + + printf("Number of FDP events: %u\n", g_fdp_events_log_page->nevents); + + for (i = 0; i < g_fdp_events_log_page->nevents; i++) { + event = &g_fdp_events_log_page->event[i]; + + printf("FDP Event #%u:\n", i); + printf(" Event Type: %s\n", + event->etype == SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY ? "RU Not Written to Capacity" : + event->etype == SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED ? "RU Time Limit Exceeded" : + event->etype == SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH ? "Ctrlr Reset Modified RUH's" : + event->etype == SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID ? "Invalid Placement Identifier" : + event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED ? "Media Reallocated" : + event->etype == SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH ? "Implicitly modified RUH" : + "Reserved"); + printf(" Placement Identifier: %s\n", + event->fdpef.bits.piv ? "Valid" : "Invalid"); + printf(" NSID: %s\n", + event->fdpef.bits.nsidv ? "Valid" : "Invalid"); + printf(" Location: %s\n", + event->fdpef.bits.lv ? "Valid" : "Invalid"); + if (event->fdpef.bits.piv) { + printf(" Placement Identifier: %u\n", event->pid); + } else { + printf(" Placement Identifier: Reserved\n"); + } + printf(" Event Timestamp: %" PRIx64 "\n", event->timestamp); + if (event->fdpef.bits.nsidv) { + printf(" Namespace Identifier: %u\n", event->nsid); + } else { + printf(" Namespace Identifier: Ignore\n"); + } + + if (event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED) { + media_reallocated = (struct spdk_nvme_fdp_event_media_reallocated *)&event->event_type_specific; + + printf(" LBA: %s\n", + media_reallocated->sef.bits.lbav ? "Valid" : "Invalid"); + printf(" Number of LBA's Moved: %u\n", media_reallocated->nlbam); + if (media_reallocated->sef.bits.lbav) { + printf(" Logical Block Address: %u\n", event->nsid); + } else { + printf(" Logical Block Address: Ignore\n"); + } + } + + if (event->fdpef.bits.lv) { + printf(" Reclaim Group Identifier: %u\n", event->rgid); + } else { + printf(" Reclaim Group Identifier: Ignore\n"); + } + if (event->fdpef.bits.lv) { + printf(" Reclaim Unit Handle Identifier: %u\n", event->ruhid); + } else { + printf(" Reclaim Unit Handle Identifier: Ignore\n"); + } + } + + printf("\n"); + +} + static void print_ocssd_chunk_info(struct spdk_ocssd_chunk_information_entry *chk_info, int chk_num) { @@ -1146,6 +1447,19 @@ print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns) printf(" Enabled: %s\n", fdp_res.bits.fdpe ? "Yes" : "No"); printf(" FDP configuration index: %u\n\n", fdp_res.bits.fdpci); + + if (fdp_res.bits.fdpe && !get_fdp_cfg_log_page(ns)) { + print_fdp_cfg_log_page(); + } + if (fdp_res.bits.fdpe && !get_fdp_ruhu_log_page(ns)) { + print_fdp_ruhu_log_page(); + } + if (fdp_res.bits.fdpe && !get_fdp_stats_log_page(ns)) { + print_fdp_stats_log_page(); + } + if (fdp_res.bits.fdpe && !get_fdp_events_log_page(ns)) { + print_fdp_events_log_page(); + } } } diff --git a/include/spdk/nvme_spec.h b/include/spdk/nvme_spec.h index f2d138eef..2d6f0561f 100644 --- a/include/spdk/nvme_spec.h +++ b/include/spdk/nvme_spec.h @@ -3205,7 +3205,21 @@ enum spdk_nvme_log_page { /** Rotational media information (optional) */ SPDK_NVME_LOG_ROTATIONAL_MEDIA_INFORMATION = 0x16, - /* 0x17-0x6f - reserved */ + /* 0x17-0x1f - reserved */ + + /** FDP configurations (optional) */ + SPDK_NVME_LOG_FDP_CONFIGURATIONS = 0x20, + + /** Reclaim unit handle usage (optional) */ + SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE = 0x21, + + /** FDP statistics (optional) */ + SPDK_NVME_LOG_FDP_STATISTICS = 0x22, + + /** FDP events (optional) */ + SPDK_NVME_LOG_FDP_EVENTS = 0x23, + + /* 0x24-0x6f - reserved */ /** Discovery(refer to the NVMe over Fabrics specification) */ SPDK_NVME_LOG_DISCOVERY = 0x70, @@ -3549,6 +3563,222 @@ struct spdk_nvme_ana_group_descriptor { }; SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_ana_group_descriptor) == 32, "Incorrect size"); +/* Reclaim unit handle type */ +enum spdk_nvme_fdp_ruh_type { + /* 0x0 Reserved */ + + /* Reclaim unit handle type initially isolated */ + SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED = 0x1, + /* Reclaim unit handle type persistently isolated */ + SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED = 0x2, + + /* 0x3 - 0xBF Reserved */ + + /* 0xC0 - 0xFF Vendor specific */ +}; + +/* Reclaim unit handle descriptor */ +struct spdk_nvme_fdp_ruh_descriptor { + /* Reclaim unit handle type */ + uint8_t ruht; + uint8_t reserved[3]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruh_descriptor) == 4, "Incorrect size"); + +/* FDP configuration descriptor */ +struct spdk_nvme_fdp_cfg_descriptor { + /* Descriptor size */ + uint16_t ds; + + /* FDP attributes */ + union { + uint8_t raw; + struct { + /* Reclaim group identifier format */ + uint8_t rgif : 4; + /* FDP volatile write cache */ + uint8_t fdpvwc : 1; + uint8_t rsvd1 : 2; + /* FDP configuration valid */ + uint8_t fdpcv : 1; + } bits; + } fdpa; + + /* Vendor specific size */ + uint8_t vss; + /* Number of reclaim groups */ + uint32_t nrg; + /* Number of reclaim unit handles */ + uint16_t nruh; + /* Max placement identifiers */ + uint16_t maxpids; + /* Number of namespaces supported */ + uint32_t nns; + /* Reclaim unit nominal size */ + uint64_t runs; + /* Estimated reclaim unit time limit */ + uint32_t erutl; + uint8_t rsvd28[36]; + struct spdk_nvme_fdp_ruh_descriptor ruh_desc[]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_descriptor) == 64, "Incorrect size"); + +/* FDP configurations log page (\ref SPDK_NVME_LOG_FDP_CONFIGURATIONS) */ +struct spdk_nvme_fdp_cfg_log_page { + /* Number of FDP configurations */ + uint16_t ncfg; + /* Version of log page */ + uint8_t version; + uint8_t reserved1; + /* Size of this log page in bytes */ + uint32_t size; + uint8_t reserved2[8]; + struct spdk_nvme_fdp_cfg_descriptor cfg_desc[]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_cfg_log_page) == 16, "Incorrect size"); + +/* Reclaim unit handle attributes */ +enum spdk_nvme_fdp_ruh_attributes { + /* Not used by a namespace */ + SPDK_NVME_FDP_RUHA_UNUSED = 0x0, + /* Use a specific reclaim unit handle */ + SPDK_NVME_FDP_RUHA_HOST_SPECIFIED = 0x1, + /* Use the only default reclaim unit handle */ + SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED = 0x2, + + /* 0x3 - 0xFF Reserved */ +}; + +/* Reclaim unit handle usage descriptor */ +struct spdk_nvme_fdp_ruhu_descriptor { + /* Reclaim unit handle attributes */ + uint8_t ruha; + uint8_t reserved[7]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_descriptor) == 8, "Incorrect size"); + +/* Reclaim unit handle usage log page (\ref SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE) */ +struct spdk_nvme_fdp_ruhu_log_page { + /* Number of Reclaim Unit Handles */ + uint16_t nruh; + uint8_t reserved[6]; + struct spdk_nvme_fdp_ruhu_descriptor ruhu_desc[]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_ruhu_log_page) == 8, "Incorrect size"); + +/* FDP statistics log page (\ref SPDK_NVME_LOG_FDP_STATISTICS) */ +struct spdk_nvme_fdp_stats_log_page { + /* Host bytes with metadata written */ + uint64_t hbmw[2]; + /* Media bytes with metadata written */ + uint64_t mbmw[2]; + /* Media bytes erased */ + uint64_t mbe[2]; + uint8_t rsvd48[16]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_stats_log_page) == 64, "Incorrect size"); + +/* FDP report event types (cdw10 log specific parameter) */ +enum spdk_nvme_fdp_report_event_type { + /* Report FDP controller events */ + SPDK_NVME_FDP_REPORT_CTRL_EVENTS = 0x0, + /* Report FDP host events */ + SPDK_NVME_FDP_REPORT_HOST_EVENTS = 0x1, +}; + +/* FDP event type */ +enum spdk_nvme_fdp_event_type { + /* FDP host events */ + /* Reclaim unit not fully written to capacity */ + SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY = 0x0, + /* Reclaim unit time limit exceeded */ + SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED = 0x1, + /* Controller reset modified reclaim unit handles */ + SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH = 0x2, + /* Invalid placement identifier */ + SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID = 0x3, + + /* 0x4 - 0x6F Reserved */ + + /* 0x70 - 0x7F Vendor specific */ + + /* FDP controller events */ + /* Media reallocated */ + SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED = 0x80, + /* Implicitly modified reclaim unit handle */ + SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH = 0x81, + + /* 0x82 - 0xEF Reserved */ + + /* 0xF0 - 0xFF Vendor specific */ +}; + +/* Media reallocated */ +struct __attribute__((packed)) spdk_nvme_fdp_event_media_reallocated { + /* Specific event flags */ + union { + uint8_t raw; + struct { + /* LBA valid */ + uint8_t lbav : 1; + uint8_t reserved : 7; + } bits; + } sef; + + uint8_t reserved1; + /* Number of LBAs moved */ + uint16_t nlbam; + /* Logical block address */ + uint64_t lba; + uint8_t reserved2[4]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event_media_reallocated) == 16, "Incorrect size"); + +/* FDP event */ +struct __attribute__((packed)) spdk_nvme_fdp_event { + /* Event type */ + uint8_t etype; + + /* FDP event flags */ + union { + uint8_t raw; + struct { + /* Placement identifier valid */ + uint8_t piv : 1; + /* NSID valid */ + uint8_t nsidv : 1; + /* Location valid */ + uint8_t lv : 1; + uint8_t reserved : 5; + } bits; + } fdpef; + + /* Placement identifier */ + uint16_t pid; + /* Event timestamp */ + uint64_t timestamp; + /* Namespace identifier */ + uint32_t nsid; + /* Event type specific */ + uint64_t event_type_specific[2]; + /* Reclaim group identifier */ + uint16_t rgid; + /* Reclaim unit handle identifier */ + uint16_t ruhid; + uint8_t reserved[4]; + uint8_t vs[24]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_event) == 64, "Incorrect size"); + +/* FDP events log page (\ref SPDK_NVME_LOG_FDP_EVENTS) */ +struct spdk_nvme_fdp_events_log_page { + /* Number of FDP events */ + uint32_t nevents; + uint8_t reserved[60]; + struct spdk_nvme_fdp_event event[]; +}; +SPDK_STATIC_ASSERT(sizeof(struct spdk_nvme_fdp_events_log_page) == 64, "Incorrect size"); + /** * Namespace attachment Type Encoding */ diff --git a/lib/nvme/nvme_ctrlr.c b/lib/nvme/nvme_ctrlr.c index 9a4837a2d..ca4cdfe9f 100644 --- a/lib/nvme/nvme_ctrlr.c +++ b/lib/nvme/nvme_ctrlr.c @@ -878,6 +878,13 @@ nvme_ctrlr_set_supported_log_pages(struct spdk_nvme_ctrlr *ctrlr) } } + if (ctrlr->cdata.ctratt.fdps) { + ctrlr->log_page_supported[SPDK_NVME_LOG_FDP_CONFIGURATIONS] = true; + ctrlr->log_page_supported[SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE] = true; + ctrlr->log_page_supported[SPDK_NVME_LOG_FDP_STATISTICS] = true; + ctrlr->log_page_supported[SPDK_NVME_LOG_FDP_EVENTS] = true; + } + if (ctrlr->cdata.vid == SPDK_PCI_VID_INTEL && ctrlr->trid.trtype == SPDK_NVME_TRANSPORT_PCIE && !(ctrlr->quirks & NVME_INTEL_QUIRK_NO_LOG_PAGES)) {