summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io')
-rw-r--r--usr/src/uts/common/io/cpuid_drv.c3
-rw-r--r--usr/src/uts/common/io/nvme/nvme.c130
-rw-r--r--usr/src/uts/common/io/nvme/nvme_reg.h19
3 files changed, 109 insertions, 43 deletions
diff --git a/usr/src/uts/common/io/cpuid_drv.c b/usr/src/uts/common/io/cpuid_drv.c
index ef3a21793f..5711258f9e 100644
--- a/usr/src/uts/common/io/cpuid_drv.c
+++ b/usr/src/uts/common/io/cpuid_drv.c
@@ -169,14 +169,17 @@ cpuid_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cr, int *rval)
if (strcmp(areq, architecture) == 0) {
STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap);
STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap_2);
+ STRUCT_FSET(h, cgh_hwcap[2], auxv_hwcap_3);
#if defined(_SYSCALL32_IMPL)
} else if (strcmp(areq, architecture_32) == 0) {
STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap32);
STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap32_2);
+ STRUCT_FSET(h, cgh_hwcap[2], auxv_hwcap32_3);
#endif
} else {
STRUCT_FSET(h, cgh_hwcap[0], 0);
STRUCT_FSET(h, cgh_hwcap[1], 0);
+ STRUCT_FSET(h, cgh_hwcap[2], 0);
}
if (ddi_copyout(STRUCT_BUF(h),
(void *)arg, STRUCT_SIZE(h), mode))
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c
index 9710dd5728..d76fa48d1b 100644
--- a/usr/src/uts/common/io/nvme/nvme.c
+++ b/usr/src/uts/common/io/nvme/nvme.c
@@ -353,7 +353,7 @@
* 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(sizeof (nvme_identify_ctrl_t) == NVME_IDENTIFY_BUFSIZE);
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_oncs) == 520);
@@ -362,17 +362,22 @@ 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(sizeof (nvme_identify_nsid_t) == NVME_IDENTIFY_BUFSIZE);
CTASSERT(offsetof(nvme_identify_nsid_t, id_fpi) == 32);
CTASSERT(offsetof(nvme_identify_nsid_t, id_anagrpid) == 92);
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(sizeof (nvme_identify_nsid_list_t) == NVME_IDENTIFY_BUFSIZE);
+CTASSERT(sizeof (nvme_identify_ctrl_list_t) == NVME_IDENTIFY_BUFSIZE);
+
+CTASSERT(sizeof (nvme_identify_primary_caps_t) == NVME_IDENTIFY_BUFSIZE);
CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vqfrt) == 32);
CTASSERT(offsetof(nvme_identify_primary_caps_t, nipc_vifrt) == 64);
+CTASSERT(sizeof (nvme_nschange_list_t) == 4096);
+
/* NVMe spec version supported */
static const int nvme_version_major = 1;
@@ -436,7 +441,7 @@ static int nvme_format_nvm(nvme_t *, boolean_t, uint32_t, uint8_t, boolean_t,
uint8_t, boolean_t, uint8_t);
static int nvme_get_logpage(nvme_t *, boolean_t, void **, size_t *, uint8_t,
...);
-static int nvme_identify(nvme_t *, boolean_t, uint32_t, void **);
+static int nvme_identify(nvme_t *, boolean_t, uint32_t, uint8_t, void **);
static int nvme_set_features(nvme_t *, boolean_t, uint32_t, uint8_t, uint32_t,
uint32_t *);
static int nvme_get_features(nvme_t *, boolean_t, uint32_t, uint8_t, uint32_t *,
@@ -2266,7 +2271,8 @@ fail:
}
static int
-nvme_identify(nvme_t *nvme, boolean_t user, uint32_t nsid, void **buf)
+nvme_identify(nvme_t *nvme, boolean_t user, uint32_t nsid, uint8_t cns,
+ void **buf)
{
nvme_cmd_t *cmd = nvme_alloc_cmd(nvme, KM_SLEEP);
int ret;
@@ -2278,7 +2284,7 @@ nvme_identify(nvme_t *nvme, boolean_t user, uint32_t nsid, void **buf)
cmd->nc_callback = nvme_wakeup_cmd;
cmd->nc_sqe.sqe_opc = NVME_OPC_IDENTIFY;
cmd->nc_sqe.sqe_nsid = nsid;
- cmd->nc_sqe.sqe_cdw10 = nsid ? NVME_IDENTIFY_NSID : NVME_IDENTIFY_CTRL;
+ cmd->nc_sqe.sqe_cdw10 = cns;
if (nvme_zalloc_dma(nvme, NVME_IDENTIFY_BUFSIZE, DDI_DMA_READ,
&nvme->n_prp_dma_attr, &cmd->nc_dma) != DDI_SUCCESS) {
@@ -2974,7 +2980,8 @@ nvme_init_ns(nvme_t *nvme, int nsid)
ASSERT(MUTEX_HELD(&nvme->n_mgmt_mutex));
- if (nvme_identify(nvme, B_FALSE, nsid, (void **)&idns) != 0) {
+ if (nvme_identify(nvme, B_FALSE, nsid, NVME_IDENTIFY_NSID,
+ (void **)&idns) != 0) {
dev_err(nvme->n_dip, CE_WARN,
"!failed to identify namespace %d", nsid);
return (DDI_FAILURE);
@@ -3332,7 +3339,8 @@ nvme_init(nvme_t *nvme)
/*
* Identify Controller
*/
- if (nvme_identify(nvme, B_FALSE, 0, (void **)&nvme->n_idctl) != 0) {
+ if (nvme_identify(nvme, B_FALSE, 0, NVME_IDENTIFY_CTRL,
+ (void **)&nvme->n_idctl) != 0) {
dev_err(nvme->n_dip, CE_WARN,
"!failed to identify controller");
goto fail;
@@ -4799,7 +4807,94 @@ nvme_ioctl_identify(nvme_t *nvme, int nsid, nvme_ioctl_t *nioc, int mode,
if (nioc->n_len < NVME_IDENTIFY_BUFSIZE)
return (EINVAL);
- if ((rv = nvme_identify(nvme, B_TRUE, nsid, (void **)&idctl)) != 0)
+ switch (nioc->n_arg) {
+ case NVME_IDENTIFY_NSID:
+ /*
+ * If we support namespace management, set the nsid to -1 to
+ * retrieve the common namespace capabilities. Otherwise
+ * have a best guess by returning identify data for namespace 1.
+ */
+ if (nsid == 0)
+ nsid = nvme->n_idctl->id_oacs.oa_nsmgmt == 1 ? -1 : 1;
+ break;
+
+ case NVME_IDENTIFY_CTRL:
+ /*
+ * Let NVME_IDENTIFY_CTRL work the same on devctl and attachment
+ * point nodes.
+ */
+ nsid = 0;
+ break;
+
+ case NVME_IDENTIFY_NSID_LIST:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 1))
+ return (ENOTSUP);
+
+ /*
+ * For now, always try to get the list of active NSIDs starting
+ * at the first namespace. This will have to be revisited should
+ * the need arise to support more than 1024 namespaces.
+ */
+ nsid = 0;
+ break;
+
+ case NVME_IDENTIFY_NSID_DESC:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 3))
+ return (ENOTSUP);
+ break;
+
+ case NVME_IDENTIFY_NSID_ALLOC:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2) ||
+ (nvme->n_idctl->id_oacs.oa_nsmgmt == 0))
+ return (ENOTSUP);
+
+ /*
+ * To make this work on a devctl node, make this return the
+ * identify data for namespace 1. We assume that any NVMe
+ * device supports at least one namespace, which has ID 1.
+ */
+ if (nsid == 0)
+ nsid = 1;
+ break;
+
+ case NVME_IDENTIFY_NSID_ALLOC_LIST:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2) ||
+ (nvme->n_idctl->id_oacs.oa_nsmgmt == 0))
+ return (ENOTSUP);
+
+ /*
+ * For now, always try to get the list of allocated NSIDs
+ * starting at the first namespace. This will have to be
+ * revisited should the need arise to support more than 1024
+ * namespaces.
+ */
+ nsid = 0;
+ break;
+
+ case NVME_IDENTIFY_NSID_CTRL_LIST:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2) ||
+ (nvme->n_idctl->id_oacs.oa_nsmgmt == 0))
+ return (ENOTSUP);
+
+ if (nsid == 0)
+ return (EINVAL);
+ break;
+
+ case NVME_IDENTIFY_CTRL_LIST:
+ if (!NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2) ||
+ (nvme->n_idctl->id_oacs.oa_nsmgmt == 0))
+ return (ENOTSUP);
+
+ if (nsid != 0)
+ return (EINVAL);
+ break;
+
+ default:
+ return (EINVAL);
+ }
+
+ if ((rv = nvme_identify(nvme, B_TRUE, nsid, nioc->n_arg & 0xff,
+ (void **)&idctl)) != 0)
return (rv);
if (ddi_copyout(idctl, (void *)nioc->n_buf, NVME_IDENTIFY_BUFSIZE, mode)
@@ -5728,7 +5823,7 @@ nvme_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
int (*nvme_ioctl[])(nvme_t *, int, nvme_ioctl_t *, int, cred_t *) = {
NULL,
nvme_ioctl_identify,
- nvme_ioctl_identify,
+ NULL,
nvme_ioctl_capabilities,
nvme_ioctl_get_logpage,
nvme_ioctl_get_features,
@@ -5777,21 +5872,6 @@ nvme_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *cred_p,
if (nvme->n_dead && cmd != NVME_IOC_DETACH)
return (EIO);
-
- if (cmd == NVME_IOC_IDENTIFY_CTRL) {
- /*
- * This makes NVME_IOC_IDENTIFY_CTRL work the same on devctl and
- * attachment point nodes.
- */
- nsid = 0;
- } else if (cmd == NVME_IOC_IDENTIFY_NSID && nsid == 0) {
- /*
- * This makes NVME_IOC_IDENTIFY_NSID work on a devctl node, it
- * will always return identify data for namespace 1.
- */
- nsid = 1;
- }
-
if (IS_NVME_IOC(cmd) && nvme_ioctl[NVME_IOC_CMD(cmd)] != NULL)
rv = nvme_ioctl[NVME_IOC_CMD(cmd)](nvme, nsid, &nioc, mode,
cred_p);
diff --git a/usr/src/uts/common/io/nvme/nvme_reg.h b/usr/src/uts/common/io/nvme/nvme_reg.h
index 9c981cf33a..8fb3252aa6 100644
--- a/usr/src/uts/common/io/nvme/nvme_reg.h
+++ b/usr/src/uts/common/io/nvme/nvme_reg.h
@@ -10,9 +10,8 @@
*/
/*
- * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
* Copyright 2020 Joyent, Inc.
- * Copyright 2019 Western Digital Corporation
+ * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
* Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
*/
@@ -396,21 +395,6 @@ typedef union {
} nvme_create_sq_dw11_t;
/*
- * NVMe Identify
- */
-
-/* NVMe Identify parameters (cdw10) */
-#define NVME_IDENTIFY_NSID 0x0 /* Identify Namespace */
-#define NVME_IDENTIFY_CTRL 0x1 /* Identify Controller */
-#define NVME_IDENTIFY_LIST 0x2 /* Identify List Namespaces */
-
-#define NVME_IDENTIFY_NSID_ALLOC_LIST 0x10 /* List Allocated NSID */
-#define NVME_IDENTIFY_NSID_ALLOC 0x11 /* Identify Allocated NSID */
-#define NVME_IDENTIFY_NSID_CTRL_LIST 0x12 /* List Controllers on NSID */
-#define NVME_IDENTIFY_CTRL_LIST 0x13 /* Controller List */
-#define NVME_IDENTIFY_PRIMARY_CAPS 0x14 /* Primary Controller Caps */
-
-/*
* NVMe Abort Command
*/
typedef union {
@@ -421,7 +405,6 @@ typedef union {
uint32_t r;
} nvme_abort_cmd_t;
-
/*
* NVMe Get Log Page
*/