Print this page
MFV: illumos-gate@48d370f1e98a10b1bdf160dd83a49e0f49f6c1b7
9809 nvme driver should attach to all NVMe 1.x devices
9810 Update parts of NVMe headers for newer specs
9811 nvmeadm(1M) should have ctf
Reviewed by: Hans Rosenfeld <hans.rosenfeld@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Reviewed by: Andy Fiddaman <omnios@citrus-it.co.uk>
Approved by: Dan McDonald <danmcd@joyent.com>
Author: Robert Mustacchi <rm@joyent.com>
NEX-18067 Catch up with illumos 8806 8805
8806 xattr_dir_inactive() releases used vnode with kernel panic
Reviewed by: Marcel Telka <marcel@telka.sk>
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Approved by: Dan McDonald <danmcd@joyent.com>
8805 xattr_dir_lookup() can leak a vnode hold
Reviewed by: Marcel Telka <marcel@telka.sk>
Reviewed by: Gordon Ross <gordon.w.ross@gmail.com>
Approved by: Dan McDonald <danmcd@joyent.com>
NEX-17991 emulated NVMe controller on ESXi 6.7 fails to attach
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-16749 some NVMe controllers get upset about NS ID of 0 when checking "Error Recovery" feature
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-16880 update NVME code
8804 nvme: add alias for pciclass,010802
Reviewed by: Peter Tribble <peter.tribble@gmail.com>
Reviewed by: Michal Nowak <mnowak@startmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
8979 nvmeadm(1m): ctl/[ns] -> ctl[/ns]
Reviewed by: Yuri Pankov <yuripv@gmx.com>
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: Rob Johnston <rob.johnston@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Dan McDonald <danmcd@joyent.com>
8945 nvme panics when async events are not supported
Reviewed by: Hans Rosenfeld <rosenfeld@grumpf.hope-2000.org>
Reviewed by: Yuri Pankov <yuripv@yuripv.net>
Reviewed by: Michal Nowak <mnowak@startmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-16549 nvme: "programming error: invalid NS/format" doing 'nvmeadm list' on a controller without namespaces
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-15208 nvme: Software Progress Marker feature is optional
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Cynthia Eastham <cynthia.eastham@nexenta.com>
NEX-8020 illumos nvme changes
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-7539 nvme fails to get error log page from Samsung PM1725
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-7538 nvme shouldn't ignore namespaces that support extended data LBAs
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7373 nvme queue DMA attribute count_max is 0-based
Reviewed by: Gordon Ross <gordon.ross@nexenta.com
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-7369 bump nvme admin command timeout to 1s
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6740 nvme checksum errors with blocksize < 4096
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7349 nvme ignores interrupt enabling failure
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-7336 nvme initial interrupt issues
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-7322 nvme fix from Tegile needs a fix
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
NEX-7321 nvme version number check is broken again
Reviewed by: Steve Peng <steve.peng@nexenta.com>
Reviewed by: Rob Gittins <rob.gittins@nexenta.com>
NEX-7291 several small nvme fixes from Tegile
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-7290 nvme: id_nlbaf field is 0-based
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-7236 nvme shouldn't use ddi_intr_enable/disable to block interrupts
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com>
NEX-5192 Samsung SSD SM951-NVMe shows checksum errors
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-5792 support NVMe namespace EUI64
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6132 nvmeadm(1M) get-feature command could use some cleanup
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-6130 basic NVMe 1.1 support
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-5791 support NVMe volatile write cache
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-4431 want NVMe management utility
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-4849 nvme version number check is broken
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-4850 off-by-one in nvme_get_logpage()
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Robert Mustacchi <rm@joyent.com>
NEX-4427 blkdev should provide the device_error kstat for iostat -E
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
NEX-4424 kstat module needs cleanup
Reviewed by: Richard Elling <Richard.Elling@RichardElling.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
NEX-4420 format(1M) should be able to use device inquiry properties
Reviewed by: Dan McDonald <danmcd@omniti.com>
NEX-4419 blkdev and blkdev drivers should provide inquiry properties
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-2182 need driver for Intel NVM Express (nvme)
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
NEX-2182 need driver for Intel NVM Express (nvme) (preview)
Reviewed by: Dan Fields <dan.fields@nexenta.com>

*** 8,21 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright 2016 Tegile Systems, Inc. All rights reserved. * Copyright (c) 2016 The MathWorks, Inc. All rights reserved. ! * Copyright 2017 Joyent, Inc. */ /* * blkdev driver for NVMe compliant storage devices * --- 8,21 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2018 Nexenta Systems, Inc. * Copyright 2016 Tegile Systems, Inc. All rights reserved. * Copyright (c) 2016 The MathWorks, Inc. All rights reserved. ! * Copyright 2018 Joyent, Inc. */ /* * blkdev driver for NVMe compliant storage devices *
*** 81,92 **** * Namespace Support: * * NVMe devices can have multiple namespaces, each being a independent data * store. The driver supports multiple namespaces and creates a blkdev interface * for each namespace found. Namespaces can have various attributes to support ! * thin provisioning and protection information. This driver does not support ! * any of this and ignores namespaces that have these attributes. * * As of NVMe 1.1 namespaces can have an 64bit Extended Unique Identifier * (EUI64). This driver uses the EUI64 if present to generate the devid and * passes it to blkdev to use it in the device node names. As this is currently * untested namespaces with EUI64 are ignored by default. --- 81,92 ---- * Namespace Support: * * NVMe devices can have multiple namespaces, each being a independent data * store. The driver supports multiple namespaces and creates a blkdev interface * for each namespace found. Namespaces can have various attributes to support ! * protection information. This driver does not support any of this and ignores ! * namespaces that have these attributes. * * As of NVMe 1.1 namespaces can have an 64bit Extended Unique Identifier * (EUI64). This driver uses the EUI64 if present to generate the devid and * passes it to blkdev to use it in the device node names. As this is currently * untested namespaces with EUI64 are ignored by default.
*** 194,204 **** * Driver Configuration: * * The following driver properties can be changed to control some aspects of the * drivers operation: * - strict-version: can be set to 0 to allow devices conforming to newer ! * versions or namespaces with EUI64 to be used * - ignore-unknown-vendor-status: can be set to 1 to not handle any vendor * specific command status as a fatal error leading device faulting * - admin-queue-len: the maximum length of the admin queue (16-4096) * - io-queue-len: the maximum length of the I/O queues (16-65536) * - async-event-limit: the maximum number of asynchronous event requests to be --- 194,204 ---- * Driver Configuration: * * The following driver properties can be changed to control some aspects of the * drivers operation: * - strict-version: can be set to 0 to allow devices conforming to newer ! * major versions to be used * - ignore-unknown-vendor-status: can be set to 1 to not handle any vendor * specific command status as a fatal error leading device faulting * - admin-queue-len: the maximum length of the admin queue (16-4096) * - io-queue-len: the maximum length of the I/O queues (16-65536) * - async-event-limit: the maximum number of asynchronous event requests to be
*** 256,269 **** #endif #include "nvme_reg.h" #include "nvme_var.h" /* NVMe spec version supported */ static const int nvme_version_major = 1; - static const int nvme_version_minor = 2; /* tunable for admin command timeout in seconds, default is 1s */ int nvme_admin_cmd_timeout = 1; /* tunable for FORMAT NVM command timeout in seconds, default is 600s */ --- 256,290 ---- #endif #include "nvme_reg.h" #include "nvme_var.h" + /* + * Assertions to make sure that we've properly captured various aspects of the + * packed structures and haven't broken them during updates. + */ + CTASSERT(sizeof (nvme_identify_ctrl_t) == 0x1000); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_oacs) == 256); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_sqes) == 512); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_subnqn) == 768); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_nvmof) == 1792); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_psd) == 2048); + CTASSERT(offsetof(nvme_identify_ctrl_t, id_vs) == 3072); + CTASSERT(sizeof (nvme_identify_nsid_t) == 0x1000); + CTASSERT(offsetof(nvme_identify_nsid_t, id_fpi) == 32); + CTASSERT(offsetof(nvme_identify_nsid_t, id_nguid) == 104); + CTASSERT(offsetof(nvme_identify_nsid_t, id_lbaf) == 128); + CTASSERT(offsetof(nvme_identify_nsid_t, id_vs) == 384); + + CTASSERT(sizeof (nvme_identify_primary_caps_t) == 0x1000); + CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vqfrt) == 32); + CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vifrt) == 64); + + /* NVMe spec version supported */ static const int nvme_version_major = 1; /* tunable for admin command timeout in seconds, default is 1s */ int nvme_admin_cmd_timeout = 1; /* tunable for FORMAT NVM command timeout in seconds, default is 600s */
*** 1082,1092 **** case NVME_CQE_SC_GEN_INV_NS: /* Invalid Namespace or Format */ if (!cmd->nc_dontpanic) dev_err(cmd->nc_nvme->n_dip, CE_PANIC, ! "programming error: " "invalid NS/format in cmd %p", (void *)cmd); return (EINVAL); case NVME_CQE_SC_GEN_NVM_LBA_RANGE: /* LBA Out Of Range */ --- 1103,1113 ---- case NVME_CQE_SC_GEN_INV_NS: /* Invalid Namespace or Format */ if (!cmd->nc_dontpanic) dev_err(cmd->nc_nvme->n_dip, CE_PANIC, ! "programming error: invalid NS/format in cmd %p", (void *)cmd); return (EINVAL); case NVME_CQE_SC_GEN_NVM_LBA_RANGE: /* LBA Out Of Range */
*** 1853,1896 **** cmd->nc_callback = nvme_wakeup_cmd; cmd->nc_sqe.sqe_opc = NVME_OPC_GET_FEATURES; cmd->nc_sqe.sqe_cdw10 = feature; cmd->nc_sqe.sqe_cdw11 = *res; switch (feature) { case NVME_FEAT_ARBITRATION: case NVME_FEAT_POWER_MGMT: case NVME_FEAT_TEMPERATURE: - case NVME_FEAT_ERROR: case NVME_FEAT_NQUEUES: case NVME_FEAT_INTR_COAL: case NVME_FEAT_INTR_VECT: case NVME_FEAT_WRITE_ATOM: case NVME_FEAT_ASYNC_EVENT: - case NVME_FEAT_PROGRESS: break; case NVME_FEAT_WRITE_CACHE: if (!nvme->n_write_cache_present) goto fail; break; case NVME_FEAT_LBA_RANGE: if (!nvme->n_lba_range_supported) goto fail; - /* - * The LBA Range Type feature is optional. There doesn't seem - * be a method of detecting whether it is supported other than - * using it. This will cause a "invalid field in command" error, - * which is normally considered a programming error and causes - * panic in nvme_check_generic_cmd_status(). - */ cmd->nc_dontpanic = B_TRUE; cmd->nc_sqe.sqe_nsid = nsid; ASSERT(bufsize != NULL); *bufsize = NVME_LBA_RANGE_BUFSIZE; - break; case NVME_FEAT_AUTO_PST: if (!nvme->n_auto_pst_supported) goto fail; --- 1874,1926 ---- cmd->nc_callback = nvme_wakeup_cmd; cmd->nc_sqe.sqe_opc = NVME_OPC_GET_FEATURES; cmd->nc_sqe.sqe_cdw10 = feature; cmd->nc_sqe.sqe_cdw11 = *res; + /* + * For some of the optional features there doesn't seem to be a method + * of detecting whether it is supported other than using it. This will + * cause "Invalid Field in Command" error, which is normally considered + * a programming error. Set the nc_dontpanic flag to override the panic + * in nvme_check_generic_cmd_status(). + */ switch (feature) { case NVME_FEAT_ARBITRATION: case NVME_FEAT_POWER_MGMT: case NVME_FEAT_TEMPERATURE: case NVME_FEAT_NQUEUES: case NVME_FEAT_INTR_COAL: case NVME_FEAT_INTR_VECT: case NVME_FEAT_WRITE_ATOM: case NVME_FEAT_ASYNC_EVENT: break; + case NVME_FEAT_ERROR: + /* + * Per-namespace Deallocated or Unwritten Logical Block + * Error Enable (DULBE) feature was added after initial NVMe + * specification, but we currently only check this feature with + * NS ID of 0 (the controller itself), and some controllers get + * upset, reporting the error. For the moment, override the + * panic by setting the nc_dontpanic flag. + */ + cmd->nc_dontpanic = B_TRUE; + break; + case NVME_FEAT_WRITE_CACHE: if (!nvme->n_write_cache_present) goto fail; break; case NVME_FEAT_LBA_RANGE: if (!nvme->n_lba_range_supported) goto fail; cmd->nc_dontpanic = B_TRUE; cmd->nc_sqe.sqe_nsid = nsid; ASSERT(bufsize != NULL); *bufsize = NVME_LBA_RANGE_BUFSIZE; break; case NVME_FEAT_AUTO_PST: if (!nvme->n_auto_pst_supported) goto fail;
*** 1897,1906 **** --- 1927,1943 ---- ASSERT(bufsize != NULL); *bufsize = NVME_AUTO_PST_BUFSIZE; break; + case NVME_FEAT_PROGRESS: + if (!nvme->n_progress_supported) + goto fail; + + cmd->nc_dontpanic = B_TRUE; + break; + default: goto fail; } if (bufsize != NULL && *bufsize != 0) {
*** 1931,1949 **** } nvme_admin_cmd(cmd, nvme_admin_cmd_timeout); if ((ret = nvme_check_cmd_status(cmd)) != 0) { ! if (feature == NVME_FEAT_LBA_RANGE && ! cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC && ! cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD) nvme->n_lba_range_supported = B_FALSE; ! else dev_err(nvme->n_dip, CE_WARN, "!GET FEATURES %d failed with sct = %x, sc = %x", feature, cmd->nc_cqe.cqe_sf.sf_sct, cmd->nc_cqe.cqe_sf.sf_sc); goto fail; } if (bufsize != NULL && *bufsize != 0) { ASSERT(buf != NULL); --- 1968,2005 ---- } nvme_admin_cmd(cmd, nvme_admin_cmd_timeout); if ((ret = nvme_check_cmd_status(cmd)) != 0) { ! boolean_t known = B_TRUE; ! ! /* Check if this is unsupported optional feature */ ! if (cmd->nc_cqe.cqe_sf.sf_sct == NVME_CQE_SCT_GENERIC && ! cmd->nc_cqe.cqe_sf.sf_sc == NVME_CQE_SC_GEN_INV_FLD) { ! switch (feature) { ! case NVME_FEAT_LBA_RANGE: nvme->n_lba_range_supported = B_FALSE; ! break; ! case NVME_FEAT_PROGRESS: ! nvme->n_progress_supported = B_FALSE; ! break; ! default: ! known = B_FALSE; ! break; ! } ! } else { ! known = B_FALSE; ! } ! ! /* Report the error otherwise */ ! if (!known) { dev_err(nvme->n_dip, CE_WARN, "!GET FEATURES %d failed with sct = %x, sc = %x", feature, cmd->nc_cqe.cqe_sf.sf_sct, cmd->nc_cqe.cqe_sf.sf_sc); + } + goto fail; } if (bufsize != NULL && *bufsize != 0) { ASSERT(buf != NULL);
*** 2197,2216 **** if (ns->ns_best_block_size < nvme->n_min_block_size) ns->ns_best_block_size = nvme->n_min_block_size; /* * We currently don't support namespaces that use either: - * - thin provisioning * - protection information * - illegal block size (< 512) */ ! if (idns->id_nsfeat.f_thin || ! idns->id_dps.dp_pinfo) { dev_err(nvme->n_dip, CE_WARN, ! "!ignoring namespace %d, unsupported features: " ! "thin = %d, pinfo = %d", nsid, ! idns->id_nsfeat.f_thin, idns->id_dps.dp_pinfo); ns->ns_ignore = B_TRUE; } else if (ns->ns_block_size < 512) { dev_err(nvme->n_dip, CE_WARN, "!ignoring namespace %d, unsupported block size %"PRIu64, nsid, (uint64_t)ns->ns_block_size); --- 2253,2269 ---- if (ns->ns_best_block_size < nvme->n_min_block_size) ns->ns_best_block_size = nvme->n_min_block_size; /* * We currently don't support namespaces that use either: * - protection information * - illegal block size (< 512) */ ! if (idns->id_dps.dp_pinfo) { dev_err(nvme->n_dip, CE_WARN, ! "!ignoring namespace %d, unsupported feature: " ! "pinfo = %d", nsid, idns->id_dps.dp_pinfo); ns->ns_ignore = B_TRUE; } else if (ns->ns_block_size < 512) { dev_err(nvme->n_dip, CE_WARN, "!ignoring namespace %d, unsupported block size %"PRIu64, nsid, (uint64_t)ns->ns_block_size);
*** 2242,2255 **** nvme->n_version.v_major = vs.b.vs_mjr; nvme->n_version.v_minor = vs.b.vs_mnr; dev_err(nvme->n_dip, CE_CONT, "?NVMe spec version %d.%d", nvme->n_version.v_major, nvme->n_version.v_minor); ! if (NVME_VERSION_HIGHER(&nvme->n_version, ! nvme_version_major, nvme_version_minor)) { ! dev_err(nvme->n_dip, CE_WARN, "!no support for version > %d.%d", ! nvme_version_major, nvme_version_minor); if (nvme->n_strict_version) goto fail; } /* retrieve controller configuration */ --- 2295,2307 ---- nvme->n_version.v_major = vs.b.vs_mjr; nvme->n_version.v_minor = vs.b.vs_mnr; dev_err(nvme->n_dip, CE_CONT, "?NVMe spec version %d.%d", nvme->n_version.v_major, nvme->n_version.v_minor); ! if (nvme->n_version.v_major > nvme_version_major) { ! dev_err(nvme->n_dip, CE_WARN, "!no support for version > %d.x", ! nvme_version_major); if (nvme->n_strict_version) goto fail; } /* retrieve controller configuration */
*** 2519,2531 **** --- 2571,2596 ---- if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 1)) nvme->n_auto_pst_supported = nvme->n_idctl->id_apsta.ap_sup == 0 ? B_FALSE : B_TRUE; /* + * Assume Software Progress Marker feature is supported. If it isn't + * this will be set to B_FALSE by nvme_get_features(). + */ + nvme->n_progress_supported = B_TRUE; + + /* * Identify Namespaces */ nvme->n_namespace_count = nvme->n_idctl->id_nn; + + if (nvme->n_namespace_count == 0) { + dev_err(nvme->n_dip, CE_WARN, + "!controllers without namespaces are not supported"); + goto fail; + } + if (nvme->n_namespace_count > NVME_MINOR_MAX) { dev_err(nvme->n_dip, CE_WARN, "!too many namespaces: %d, limiting to %d\n", nvme->n_namespace_count, NVME_MINOR_MAX); nvme->n_namespace_count = NVME_MINOR_MAX;