aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
authorKeith Busch <keith.busch@intel.com>2014-09-12 18:07:20 -0400
committerJens Axboe <axboe@fb.com>2014-11-04 15:17:09 -0500
commit7963e521811ed19396d47793cc77d87c643ab891 (patch)
tree5587991bb23e2694f627e7ff73b784eda2dd1cc8 /drivers/block
parent1b9dbf7fe02d85f70e8efc1c12c070206c0d5c5f (diff)
NVMe: Passthrough IOCTL for IO commands
The NVME_IOCTL_SUBMIT_IO only works for IO commands with block data transfers and isn't usable for other NVMe commands like flush, data set management, or any sort of vendor unique command. The NVME_IOCTL_ADMIN_CMD, however, can easily be modified to accept arbitrary IO commands in addition to arbitrary admin commands without breaking backward compatibility. This patch just adds a new IOCTL to distinguish if the driver should submit the command on an IO or Admin queue. Signed-off-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/nvme-core.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 93ee55ee3775..70be3a151eb7 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1732,10 +1732,10 @@ static int nvme_submit_io(struct nvme_ns *ns, struct nvme_user_io __user *uio)
1732 return status; 1732 return status;
1733} 1733}
1734 1734
1735static int nvme_user_admin_cmd(struct nvme_dev *dev, 1735static int nvme_user_cmd(struct nvme_dev *dev,
1736 struct nvme_admin_cmd __user *ucmd) 1736 struct nvme_passthru_cmd __user *ucmd, bool ioq)
1737{ 1737{
1738 struct nvme_admin_cmd cmd; 1738 struct nvme_passthru_cmd cmd;
1739 struct nvme_command c; 1739 struct nvme_command c;
1740 int status, length; 1740 int status, length;
1741 struct nvme_iod *uninitialized_var(iod); 1741 struct nvme_iod *uninitialized_var(iod);
@@ -1774,6 +1774,9 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev,
1774 ADMIN_TIMEOUT; 1774 ADMIN_TIMEOUT;
1775 if (length != cmd.data_len) 1775 if (length != cmd.data_len)
1776 status = -ENOMEM; 1776 status = -ENOMEM;
1777 else if (ioq)
1778 status = nvme_submit_sync_cmd(dev, this_cpu_read(*dev->io_queue), &c,
1779 &cmd.result, timeout);
1777 else 1780 else
1778 status = nvme_submit_sync_cmd(dev, 0, &c, &cmd.result, timeout); 1781 status = nvme_submit_sync_cmd(dev, 0, &c, &cmd.result, timeout);
1779 1782
@@ -1799,7 +1802,9 @@ static int nvme_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
1799 force_successful_syscall_return(); 1802 force_successful_syscall_return();
1800 return ns->ns_id; 1803 return ns->ns_id;
1801 case NVME_IOCTL_ADMIN_CMD: 1804 case NVME_IOCTL_ADMIN_CMD:
1802 return nvme_user_admin_cmd(ns->dev, (void __user *)arg); 1805 return nvme_user_cmd(ns->dev, (void __user *)arg, false);
1806 case NVME_IOCTL_IO_CMD:
1807 return nvme_user_cmd(ns->dev, (void __user *)arg, true);
1803 case NVME_IOCTL_SUBMIT_IO: 1808 case NVME_IOCTL_SUBMIT_IO:
1804 return nvme_submit_io(ns, (void __user *)arg); 1809 return nvme_submit_io(ns, (void __user *)arg);
1805 case SG_GET_VERSION_NUM: 1810 case SG_GET_VERSION_NUM:
@@ -2743,7 +2748,9 @@ static long nvme_dev_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
2743 struct nvme_dev *dev = f->private_data; 2748 struct nvme_dev *dev = f->private_data;
2744 switch (cmd) { 2749 switch (cmd) {
2745 case NVME_IOCTL_ADMIN_CMD: 2750 case NVME_IOCTL_ADMIN_CMD:
2746 return nvme_user_admin_cmd(dev, (void __user *)arg); 2751 return nvme_user_cmd(dev, (void __user *)arg, false);
2752 case NVME_IOCTL_IO_CMD:
2753 return nvme_user_cmd(dev, (void __user *)arg, true);
2747 default: 2754 default:
2748 return -ENOTTY; 2755 return -ENOTTY;
2749 } 2756 }