git: ad9cc86bf60c - main - linux: Translate Linux NVME ioctls to the lower layers.

From: Warner Losh <imp_at_FreeBSD.org>
Date: Fri, 14 Jun 2024 22:40:11 UTC
The branch main has been updated by imp:

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

commit ad9cc86bf60cee2b35e804b348840a096f66561d
Author:     Chuck Tuffli <chuck@FreeBSD.org>
AuthorDate: 2024-06-14 22:40:20 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-06-14 22:40:20 +0000

    linux: Translate Linux NVME ioctls to the lower layers.
    
    The lower layers implement a ABI compatible Linux ioctl for a few of the
    Linux IOCTLs. Translate them and pass them down. Since they are ABI
    compatible, just use the nvme ioctl name.
    
    Co-Authored-by: Warner Losh <imp@bsdimp.com>
    Reviewed by:    chuck
    Differential Revision:  https://reviews.freebsd.org/D45416
---
 sys/compat/linux/linux_ioctl.c | 35 +++++++++++++++++++++++++++++++++++
 sys/compat/linux/linux_ioctl.h | 14 ++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c
index 41c43f1ef8e6..aa2c9ce7f273 100644
--- a/sys/compat/linux/linux_ioctl.c
+++ b/sys/compat/linux/linux_ioctl.c
@@ -83,6 +83,8 @@
 
 #include <cam/scsi/scsi_sg.h>
 
+#include <dev/nvme/nvme_linux.h>
+
 #define	DEFINE_LINUX_IOCTL_SET(shortname, SHORTNAME)		\
 static linux_ioctl_function_t linux_ioctl_ ## shortname;	\
 static struct linux_ioctl_handler shortname ## _handler = {	\
@@ -108,6 +110,9 @@ DEFINE_LINUX_IOCTL_SET(v4l2, VIDEO2);
 DEFINE_LINUX_IOCTL_SET(fbsd_usb, FBSD_LUSB);
 DEFINE_LINUX_IOCTL_SET(evdev, EVDEV);
 DEFINE_LINUX_IOCTL_SET(kcov, KCOV);
+#ifndef COMPAT_LINUX32
+DEFINE_LINUX_IOCTL_SET(nvme, NVME);
+#endif
 
 #undef DEFINE_LINUX_IOCTL_SET
 
@@ -3531,6 +3536,36 @@ linux_ioctl_kcov(struct thread *td, struct linux_ioctl_args *args)
 	return (error);
 }
 
+#ifndef COMPAT_LINUX32
+static int
+linux_ioctl_nvme(struct thread *td, struct linux_ioctl_args *args)
+{
+
+	/*
+	 * The NVMe drivers for namespace and controller implement these
+	 * commands using their native format. All the others are not
+	 * implemented yet.
+	 */
+	switch (args->cmd & 0xffff) {
+	case LINUX_NVME_IOCTL_ID:
+		args->cmd = NVME_IOCTL_ID;
+		break;
+	case LINUX_NVME_IOCTL_RESET:
+		args->cmd = NVME_IOCTL_RESET;
+		break;
+	case LINUX_NVME_IOCTL_ADMIN_CMD:
+		args->cmd = NVME_IOCTL_ADMIN_CMD;
+		break;
+	case LINUX_NVME_IOCTL_IO_CMD:
+		args->cmd = NVME_IOCTL_IO_CMD;
+		break;
+	default:
+		return (ENODEV);
+	}
+	return (sys_ioctl(td, (struct ioctl_args *)args));
+}
+#endif
+
 /*
  * main ioctl syscall function
  */
diff --git a/sys/compat/linux/linux_ioctl.h b/sys/compat/linux/linux_ioctl.h
index 8a56e35d10c6..4ef6d4f40830 100644
--- a/sys/compat/linux/linux_ioctl.h
+++ b/sys/compat/linux/linux_ioctl.h
@@ -781,6 +781,20 @@
 #define	LINUX_KCOV_DISABLE		0x6365
 #define	LINUX_KCOV_REMOTE_ENABLE	0x6366
 
+/*
+ * NVMe IOCTLs defined by Linux
+ */
+#define LINUX_NVME_IOCTL_ID		0x4e40
+#define LINUX_NVME_IOCTL_ADMIN_CMD	0x4e41
+#define LINUX_NVME_IOCTL_SUBMIT_IO	0x4e42
+#define LINUX_NVME_IOCTL_IO_CMD		0x4e43
+#define LINUX_NVME_IOCTL_RESET		0x4e44
+#define LINUX_NVME_IOCTL_SUBSYS_RESET	0x4e45
+#define LINUX_NVME_IOCTL_RESCAN		0x4e46
+
+#define LINUX_IOCTL_NVME_MIN	LINUX_NVME_IOCTL_ID
+#define LINUX_IOCTL_NVME_MAX	LINUX_NVME_IOCTL_RESCAN
+
 /*
  * Pluggable ioctl handlers
  */