diff options
Diffstat (limited to 'usr/src/uts/common/io')
-rw-r--r-- | usr/src/uts/common/io/cpuid_drv.c | 3 | ||||
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme.c | 130 | ||||
-rw-r--r-- | usr/src/uts/common/io/nvme/nvme_reg.h | 19 |
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 */ |