summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2022-04-27 20:31:39 +0200
committerHans Rosenfeld <rosenfeld@grumpf.hope-2000.org>2022-08-24 10:01:48 +0200
commitb8f43eb65c2ac2ff69cf1a69aabc90c27cdb859e (patch)
treea97cccc0762ae99978817dbc9d84cee8c65609cb /usr/src
parentabb88ab1b9516b1ca12094db7f2cfb5d91e0a135 (diff)
downloadillumos-joyent-b8f43eb65c2ac2ff69cf1a69aabc90c27cdb859e.tar.gz
14686 nvme should use namespace GUID for devid if available
Reviewed by: Andrew Giles <agiles@tintri.com> Reviewed by: Guy Morrogh <gmorrogh@tintri.com> Reviewed by: Robert Mustacchi <rm+illumos@fingolfin.org> Reviewed by: Toomas Soome <tsoome@me.com> Approved by: Dan McDonald <danmcd@mnx.io>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/io/nvme/nvme.c32
-rw-r--r--usr/src/uts/common/io/nvme/nvme_var.h3
-rw-r--r--usr/src/uts/common/os/sunddi.c7
-rw-r--r--usr/src/uts/common/sys/ddi_impldefs.h15
-rw-r--r--usr/src/uts/common/sys/dditypes.h16
5 files changed, 55 insertions, 18 deletions
diff --git a/usr/src/uts/common/io/nvme/nvme.c b/usr/src/uts/common/io/nvme/nvme.c
index 6ce0b3dcf9..9710dd5728 100644
--- a/usr/src/uts/common/io/nvme/nvme.c
+++ b/usr/src/uts/common/io/nvme/nvme.c
@@ -93,9 +93,10 @@
* 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.
+ * (EUI64), and NVMe 1.2 introduced an additional 128bit Namespace Globally
+ * Unique Identifier (NGUID). This driver uses either the NGUID or the EUI64
+ * if present to generate the devid, and passes the EUI64 to blkdev to use it
+ * in the device node names.
*
* We currently support only (2 << NVME_MINOR_INST_SHIFT) - 2 namespaces in a
* single controller. This is an artificial limit imposed by the driver to be
@@ -136,9 +137,9 @@
* Blkdev also supports querying device/media information and generating a
* devid. The driver reports the best block size as determined by the namespace
* format back to blkdev as physical block size to support partition and block
- * alignment. The devid is either based on the namespace EUI64, if present, or
- * composed using the device vendor ID, model number, serial number, and the
- * namespace ID.
+ * alignment. The devid is either based on the namespace GUID or EUI64, if
+ * present, or composed using the device vendor ID, model number, serial number,
+ * and the namespace ID.
*
*
* Error Handling:
@@ -2996,11 +2997,17 @@ nvme_init_ns(nvme_t *nvme, int nsid)
ns->ns_best_block_size = ns->ns_block_size;
/*
- * Get the EUI64 if present. Use it for devid and device node names.
+ * Get the EUI64 if present.
*/
if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 1))
bcopy(idns->id_eui64, ns->ns_eui64, sizeof (ns->ns_eui64));
+ /*
+ * Get the NGUID if present.
+ */
+ if (NVME_VERSION_ATLEAST(&nvme->n_version, 1, 2))
+ bcopy(idns->id_nguid, ns->ns_nguid, sizeof (ns->ns_nguid));
+
/*LINTED: E_BAD_PTR_CAST_ALIGN*/
if (*(uint64_t *)ns->ns_eui64 != 0) {
uint8_t *eui64 = ns->ns_eui64;
@@ -4647,12 +4654,15 @@ nvme_bd_devid(void *arg, dev_info_t *devinfo, ddi_devid_t *devid)
return (EIO);
}
- /*LINTED: E_BAD_PTR_CAST_ALIGN*/
- if (*(uint64_t *)ns->ns_eui64 != 0) {
- return (ddi_devid_init(devinfo, DEVID_SCSI3_WWN,
+ if (*(uint64_t *)ns->ns_nguid != 0 ||
+ *(uint64_t *)(ns->ns_nguid + 8) != 0) {
+ return (ddi_devid_init(devinfo, DEVID_NVME_NGUID,
+ sizeof (ns->ns_nguid), ns->ns_nguid, devid));
+ } else if (*(uint64_t *)ns->ns_eui64 != 0) {
+ return (ddi_devid_init(devinfo, DEVID_NVME_EUI64,
sizeof (ns->ns_eui64), ns->ns_eui64, devid));
} else {
- return (ddi_devid_init(devinfo, DEVID_ENCAP,
+ return (ddi_devid_init(devinfo, DEVID_NVME_NSID,
strlen(ns->ns_devid), ns->ns_devid, devid));
}
}
diff --git a/usr/src/uts/common/io/nvme/nvme_var.h b/usr/src/uts/common/io/nvme/nvme_var.h
index 10cc529fd9..dde0af58fb 100644
--- a/usr/src/uts/common/io/nvme/nvme_var.h
+++ b/usr/src/uts/common/io/nvme/nvme_var.h
@@ -278,6 +278,7 @@ struct nvme {
struct nvme_namespace {
nvme_t *ns_nvme;
uint8_t ns_eui64[8];
+ uint8_t ns_nguid[16];
char ns_name[17];
bd_handle_t ns_bd_hdl;
@@ -298,7 +299,7 @@ struct nvme_namespace {
nvme_minor_state_t ns_minor;
/*
- * If a namespace has no EUI64, we create a devid in
+ * If a namespace has neither NGUID nor EUI64, we create a devid in
* nvme_prepare_devid().
*/
char *ns_devid;
diff --git a/usr/src/uts/common/os/sunddi.c b/usr/src/uts/common/os/sunddi.c
index 27158e8810..30cc5744c2 100644
--- a/usr/src/uts/common/os/sunddi.c
+++ b/usr/src/uts/common/os/sunddi.c
@@ -22,6 +22,7 @@
/*
* Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2022 Garrett D'Amore
+ * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
*/
#include <sys/note.h>
@@ -7793,6 +7794,12 @@ ddi_devid_init(
/*FALLTHRU*/
case DEVID_ATA_SERIAL:
/*FALLTHRU*/
+ case DEVID_NVME_NSID:
+ /*FALLTHRU*/
+ case DEVID_NVME_EUI64:
+ /*FALLTHRU*/
+ case DEVID_NVME_NGUID:
+ /*FALLTHRU*/
case DEVID_ENCAP:
if (nbytes == 0)
return (DDI_FAILURE);
diff --git a/usr/src/uts/common/sys/ddi_impldefs.h b/usr/src/uts/common/sys/ddi_impldefs.h
index bf3e29397f..2570fe8772 100644
--- a/usr/src/uts/common/sys/ddi_impldefs.h
+++ b/usr/src/uts/common/sys/ddi_impldefs.h
@@ -23,6 +23,7 @@
* Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
* Copyright 2016 Joyent, Inc.
* Copyright (c) 2016 by Delphix. All rights reserved.
+ * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
*/
#ifndef _SYS_DDI_IMPLDEFS_H
@@ -1119,6 +1120,12 @@ typedef struct impl_devid {
* 'E' | // DEVID_ENCAP <ascii_id>
* 'a' | // DEVID_ATA_SERIAL <hex_id>
* 'A' | // DEVID_ATA_SERIAL <ascii_id>
+ * 'd' | // DEVID_NVME_NSID <hex_id>
+ * 'D' | // DEVID_NVME_NSID <ascii_id>
+ * 'i' | // DEVID_NVME_EUI64 <hex_id>
+ * 'I' | // DEVID_NVME_EUI64 <ascii_id>
+ * 'g' | // DEVID_NVME_NGUID <hex_id>
+ * 'G' | // DEVID_NVME_NGUID <ascii_id>
* 'u' | // unknown <hex_id>
* 'U' // unknown <ascii_id>
* // NOTE:lower case -> <hex_id>
@@ -1179,6 +1186,9 @@ typedef struct impl_devid {
((b) == DEVID_FAB) ? 'f' : \
((b) == DEVID_ENCAP) ? 'e' : \
((b) == DEVID_ATA_SERIAL) ? 'a' : \
+ ((b) == DEVID_NVME_NSID) ? 'd' : \
+ ((b) == DEVID_NVME_EUI64) ? 'i' : \
+ ((b) == DEVID_NVME_NGUID) ? 'g' : \
'u') /* unknown */
/* convert type field from ascii to binary */
@@ -1191,6 +1201,9 @@ typedef struct impl_devid {
(((c) == 'f') || ((c) == 'F')) ? DEVID_FAB : \
(((c) == 'e') || ((c) == 'E')) ? DEVID_ENCAP : \
(((c) == 'a') || ((c) == 'A')) ? DEVID_ATA_SERIAL : \
+ (((c) == 'd') || ((c) == 'D')) ? DEVID_NVME_NSID : \
+ (((c) == 'i') || ((c) == 'I')) ? DEVID_NVME_EUI64 : \
+ (((c) == 'g') || ((c) == 'G')) ? DEVID_NVME_NGUID : \
DEVID_MAXTYPE +1) /* unknown */
/* determine if the type should be forced to hex encoding (non-ascii) */
@@ -1198,6 +1211,8 @@ typedef struct impl_devid {
((b) == DEVID_SCSI3_WWN) || \
((b) == DEVID_SCSI3_VPD_EUI) || \
((b) == DEVID_SCSI3_VPD_NAA) || \
+ ((b) == DEVID_NVME_EUI64) || \
+ ((b) == DEVID_NVME_NGUID) || \
((b) == DEVID_FAB))
/* determine if the type is from a scsi3 vpd */
diff --git a/usr/src/uts/common/sys/dditypes.h b/usr/src/uts/common/sys/dditypes.h
index 733b35772e..b11052e39b 100644
--- a/usr/src/uts/common/sys/dditypes.h
+++ b/usr/src/uts/common/sys/dditypes.h
@@ -22,6 +22,7 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2022 Tintri by DDN, Inc. All rights reserved.
*/
#ifndef _SYS_DDITYPES_H
@@ -83,7 +84,7 @@ typedef struct __ddi_dma_seg *ddi_dma_seg_t;
typedef struct {
union {
uint64_t _dmac_ll; /* 64 bit DMA address */
- uint32_t _dmac_la[2]; /* 2 x 32 bit address */
+ uint32_t _dmac_la[2]; /* 2 x 32 bit address */
} _dmu;
size_t dmac_size; /* DMA cookie size */
uint_t dmac_type; /* bus specific type bits */
@@ -163,7 +164,10 @@ typedef struct __ddi_devid *ddi_devid_t;
#define DEVID_SCSI3_VPD_T10 6
#define DEVID_SCSI3_VPD_EUI 7
#define DEVID_SCSI3_VPD_NAA 8
-#define DEVID_MAXTYPE 8
+#define DEVID_NVME_NSID 9
+#define DEVID_NVME_EUI64 10
+#define DEVID_NVME_NGUID 11
+#define DEVID_MAXTYPE 11
/*
* Device id scsi encode versions (version of encode interface, not devid)
@@ -232,8 +236,8 @@ typedef struct ddi_device_acc_attr {
uchar_t devacc_attr_access; /* access error protection */
} ddi_device_acc_attr_t;
-#define DDI_DEVICE_ATTR_V0 0x0001
-#define DDI_DEVICE_ATTR_V1 0x0002
+#define DDI_DEVICE_ATTR_V0 0x0001
+#define DDI_DEVICE_ATTR_V1 0x0002
/*
* endian-ness flags
@@ -262,14 +266,14 @@ typedef struct ddi_device_acc_attr {
/*
* Data Access Handle
*/
-#define VERS_ACCHDL 0x0001
+#define VERS_ACCHDL 0x0001
typedef struct __ddi_acc_handle *ddi_acc_handle_t;
typedef struct ddi_acc_hdl {
int ah_vers; /* version number */
void *ah_bus_private; /* bus private pointer */
- void *ah_platform_private; /* platform private pointer */
+ void *ah_platform_private; /* platform private pointer */
dev_info_t *ah_dip; /* requesting device */
uint_t ah_rnumber; /* register number */