git: bef5da8ebf74 - main - ctl: Add helper routines to populate NVMe namespace data IDs for a LUN

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 03 May 2024 00:16:01 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=bef5da8ebf740d05e893f5fb92912c3ee4295e85

commit bef5da8ebf740d05e893f5fb92912c3ee4295e85
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-05-02 23:32:41 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-05-02 23:38:19 +0000

    ctl: Add helper routines to populate NVMe namespace data IDs for a LUN
    
    These will be used by the backends to populate the unique ID fields
    like EUI64 in the NVMe namespace data (CNS == 0) and namespace
    identification descriptor list (CNS == 3).
    
    Reviewed by:    imp
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D44721
---
 sys/cam/ctl/ctl.c         | 85 +++++++++++++++++++++++++++++++++++++++++++++++
 sys/cam/ctl/ctl_backend.h | 11 ++++++
 2 files changed, 96 insertions(+)

diff --git a/sys/cam/ctl/ctl.c b/sys/cam/ctl/ctl.c
index 039670c17529..fde873f4f7e5 100644
--- a/sys/cam/ctl/ctl.c
+++ b/sys/cam/ctl/ctl.c
@@ -4956,6 +4956,91 @@ ctl_lun_capacity_changed(struct ctl_be_lun *be_lun)
 	}
 }
 
+void
+ctl_lun_nsdata_ids(struct ctl_be_lun *be_lun,
+    struct nvme_namespace_data *nsdata)
+{
+	struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
+	struct scsi_vpd_id_descriptor *idd;
+
+	if (lun->lun_devid == NULL)
+		return;
+
+	idd = scsi_get_devid_desc((struct scsi_vpd_id_descriptor *)
+	    lun->lun_devid->data, lun->lun_devid->len, scsi_devid_is_lun_naa);
+	if (idd != NULL) {
+		if (idd->length == 16) {
+			memcpy(nsdata->nguid, idd->identifier, 16);
+			return;
+		}
+		if (idd->length == 8) {
+			memcpy(nsdata->eui64, idd->identifier, 8);
+			return;
+		}
+	}
+
+	idd = scsi_get_devid_desc((struct scsi_vpd_id_descriptor *)
+	    lun->lun_devid->data, lun->lun_devid->len, scsi_devid_is_lun_eui64);
+	if (idd != NULL) {
+		if (idd->length == 8) {
+			memcpy(nsdata->eui64, idd->identifier, 8);
+			return;
+		}
+	}
+}
+
+void
+ctl_lun_nvme_ids(struct ctl_be_lun *be_lun, void *data)
+{
+	struct ctl_lun *lun = (struct ctl_lun *)be_lun->ctl_lun;
+	struct scsi_vpd_id_descriptor *naa, *eui64, *uuid;
+	char *p;
+
+	memset(data, 0, 4096);
+
+	if (lun->lun_devid == NULL)
+		return;
+
+	naa = scsi_get_devid_desc((struct scsi_vpd_id_descriptor *)
+	    lun->lun_devid->data, lun->lun_devid->len, scsi_devid_is_lun_naa);
+	eui64 = scsi_get_devid_desc((struct scsi_vpd_id_descriptor *)
+	    lun->lun_devid->data, lun->lun_devid->len, scsi_devid_is_lun_eui64);
+	uuid = scsi_get_devid_desc((struct scsi_vpd_id_descriptor *)
+	    lun->lun_devid->data, lun->lun_devid->len, scsi_devid_is_lun_uuid);
+
+	p = data;
+
+	/* EUI64 */
+	if ((naa != NULL && naa->length == 8) || eui64 != NULL) {
+		*p++ = 1;
+		*p++ = 8;
+		p += 2;
+		if (naa != NULL && naa->length == 8)
+			memcpy(p, naa->identifier, 8);
+		else
+			memcpy(p, eui64->identifier, 8);
+		p += 8;
+	}
+
+	/* NGUID */
+	if (naa != NULL && naa->length == 16) {
+		*p++ = 1;
+		*p++ = 16;
+		p += 2;
+		memcpy(p, naa->identifier, 16);
+		p += 16;
+	}
+
+	/* UUID */
+	if (uuid != NULL) {
+		*p++ = 1;
+		*p++ = uuid->length;
+		p += 2;
+		memcpy(p, uuid->identifier, uuid->length);
+		p += uuid->length;
+	}
+}
+
 /*
  * Backend "memory move is complete" callback for requests that never
  * make it down to say RAIDCore's configuration code.
diff --git a/sys/cam/ctl/ctl_backend.h b/sys/cam/ctl/ctl_backend.h
index 6ebf104fb0d2..f3d65c34f2ac 100644
--- a/sys/cam/ctl/ctl_backend.h
+++ b/sys/cam/ctl/ctl_backend.h
@@ -242,6 +242,17 @@ int ctl_lun_secondary(struct ctl_be_lun *be_lun);
  */
 void ctl_lun_capacity_changed(struct ctl_be_lun *be_lun);
 
+/*
+ * Populate unique ID fields in NVMe namespace data for a LUN.
+ */
+void ctl_lun_nsdata_ids(struct ctl_be_lun *be_lun,
+    struct nvme_namespace_data *nsdata);
+
+/*
+ * Populate the NVMe namespace identification descriptor list for a LUN.
+ */
+void ctl_lun_nvme_ids(struct ctl_be_lun *be_lun, void *data);
+
 #endif /* _KERNEL */
 #endif /* _CTL_BACKEND_H_ */