NVMe: Fix DMA mapping for admin commands
authorMatthew Wilcox <matthew.r.wilcox@intel.com>
Fri, 6 Jan 2012 20:42:45 +0000 (13:42 -0700)
committerMatthew Wilcox <matthew.r.wilcox@intel.com>
Tue, 10 Jan 2012 19:54:05 +0000 (14:54 -0500)
We were always mapping as DMA_FROM_DEVICE then unmapping with
DMA_TO_DEVICE which was clearly not correct.  Follow the same pattern as
nvme_submit_io() and key off the bottom bit of the opcode to determine
whether this is a read or a write.

Signed-off-by: Matthew Wilcox <matthew.r.wilcox@intel.com>
drivers/block/nvme.c

index 1cc0187..3f8cae9 100644 (file)
@@ -1165,7 +1165,8 @@ static int nvme_user_admin_cmd(struct nvme_ns *ns,
 
        length = cmd.data_len;
        if (cmd.data_len) {
-               iod = nvme_map_user_pages(dev, 1, cmd.addr, length);
+               iod = nvme_map_user_pages(dev, cmd.opcode & 1, cmd.addr,
+                                                               length);
                if (IS_ERR(iod))
                        return PTR_ERR(iod);
                length = nvme_setup_prps(dev, &c.common, iod, length,
@@ -1178,7 +1179,8 @@ static int nvme_user_admin_cmd(struct nvme_ns *ns,
                status = nvme_submit_admin_cmd(dev, &c, NULL);
 
        if (cmd.data_len) {
-               nvme_unmap_user_pages(dev, 0, cmd.addr, cmd.data_len, iod);
+               nvme_unmap_user_pages(dev, cmd.opcode & 1, cmd.addr,
+                                                       cmd.data_len, iod);
                nvme_free_iod(dev, iod);
        }
        return status;