diff options
Diffstat (limited to 'sys/dev/nvme')
| -rw-r--r-- | sys/dev/nvme/nvme_ctrlr.c | 24 | ||||
| -rw-r--r-- | sys/dev/nvme/nvme_ns.c | 5 | ||||
| -rw-r--r-- | sys/dev/nvme/nvme_private.h | 1 |
3 files changed, 30 insertions, 0 deletions
diff --git a/sys/dev/nvme/nvme_ctrlr.c b/sys/dev/nvme/nvme_ctrlr.c index 3a1894bf754d..f212759a5500 100644 --- a/sys/dev/nvme/nvme_ctrlr.c +++ b/sys/dev/nvme/nvme_ctrlr.c @@ -33,6 +33,7 @@ #include <sys/buf.h> #include <sys/bus.h> #include <sys/conf.h> +#include <sys/disk.h> #include <sys/ioccom.h> #include <sys/proc.h> #include <sys/smp.h> @@ -1254,6 +1255,24 @@ nvme_ctrlr_poll(struct nvme_controller *ctrlr) } /* + * Copy the NVME device's serial number to the provided buffer, which must be + * at least DISK_IDENT_SIZE bytes large. + */ +void +nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn) +{ + _Static_assert(NVME_SERIAL_NUMBER_LENGTH < DISK_IDENT_SIZE, + "NVME serial number too big for disk ident"); + + memmove(sn, ctrlr->cdata.sn, NVME_SERIAL_NUMBER_LENGTH); + sn[NVME_SERIAL_NUMBER_LENGTH] = '\0'; + for (int i = 0; sn[i] != '\0'; i++) { + if (sn[i] < 0x20 || sn[i] >= 0x80) + sn[i] = ' '; + } +} + +/* * Poll the single-vector interrupt case: num_io_queues will be 1 and * there's only a single vector. While we're polling, we mask further * interrupts in the controller. @@ -1495,6 +1514,11 @@ nvme_ctrlr_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, case NVME_GET_CONTROLLER_DATA: memcpy(arg, &ctrlr->cdata, sizeof(ctrlr->cdata)); break; + case DIOCGIDENT: { + uint8_t *sn = arg; + nvme_ctrlr_get_ident(ctrlr, sn); + break; + } /* Linux Compatible (see nvme_linux.h) */ case NVME_IOCTL_ID: td->td_retval[0] = 0xfffffffful; diff --git a/sys/dev/nvme/nvme_ns.c b/sys/dev/nvme/nvme_ns.c index e84d2066930e..a759181a8c16 100644 --- a/sys/dev/nvme/nvme_ns.c +++ b/sys/dev/nvme/nvme_ns.c @@ -88,6 +88,11 @@ nvme_ns_ioctl(struct cdev *cdev, u_long cmd, caddr_t arg, int flag, gnsid->nsid = ns->id; break; } + case DIOCGIDENT: { + uint8_t *sn = arg; + nvme_ctrlr_get_ident(ctrlr, sn); + break; + } case DIOCGMEDIASIZE: *(off_t *)arg = (off_t)nvme_ns_get_size(ns); break; diff --git a/sys/dev/nvme/nvme_private.h b/sys/dev/nvme/nvme_private.h index 52e9fcbbebcd..04a47d799350 100644 --- a/sys/dev/nvme/nvme_private.h +++ b/sys/dev/nvme/nvme_private.h @@ -563,6 +563,7 @@ void nvme_notify_new_controller(struct nvme_controller *ctrlr); void nvme_notify_ns(struct nvme_controller *ctrlr, int nsid); void nvme_ctrlr_shared_handler(void *arg); +void nvme_ctrlr_get_ident(const struct nvme_controller *ctrlr, uint8_t *sn); void nvme_ctrlr_poll(struct nvme_controller *ctrlr); int nvme_ctrlr_suspend(struct nvme_controller *ctrlr); |
