aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/nvme-scsi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-13 17:22:26 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-13 17:22:26 -0500
commit9ea18f8cab5f1c36cdd0f09717e35ceb48c36a87 (patch)
tree0c8da7ac47cb59fe39f177ab0407f554aff77194 /drivers/block/nvme-scsi.c
parentcaf292ae5bb9d57198ce001d8b762f7abae3a94d (diff)
parent849c6e7746e4f6317ace6aa7d2fcdcd844e99ddb (diff)
Merge branch 'for-3.19/drivers' of git://git.kernel.dk/linux-block
Pull block layer driver updates from Jens Axboe: - NVMe updates: - The blk-mq conversion from Matias (and others) - A stack of NVMe bug fixes from the nvme tree, mostly from Keith. - Various bug fixes from me, fixing issues in both the blk-mq conversion and generic bugs. - Abort and CPU online fix from Sam. - Hot add/remove fix from Indraneel. - A couple of drbd fixes from the drbd team (Andreas, Lars, Philipp) - With the generic IO stat accounting from 3.19/core, converting md, bcache, and rsxx to use those. From Gu Zheng. - Boundary check for queue/irq mode for null_blk from Matias. Fixes cases where invalid values could be given, causing the device to hang. - The xen blkfront pull request, with two bug fixes from Vitaly. * 'for-3.19/drivers' of git://git.kernel.dk/linux-block: (56 commits) NVMe: fix race condition in nvme_submit_sync_cmd() NVMe: fix retry/error logic in nvme_queue_rq() NVMe: Fix FS mount issue (hot-remove followed by hot-add) NVMe: fix error return checking from blk_mq_alloc_request() NVMe: fix freeing of wrong request in abort path xen/blkfront: remove redundant flush_op xen/blkfront: improve protection against issuing unsupported REQ_FUA NVMe: Fix command setup on IO retry null_blk: boundary check queue_mode and irqmode block/rsxx: use generic io stats accounting functions to simplify io stat accounting md: use generic io stats accounting functions to simplify io stat accounting drbd: use generic io stats accounting functions to simplify io stat accounting md/bcache: use generic io stats accounting functions to simplify io stat accounting NVMe: Update module version major number NVMe: fail pci initialization if the device doesn't have any BARs NVMe: add ->exit_hctx() hook NVMe: make setup work for devices that don't do INTx NVMe: enable IO stats by default NVMe: nvme_submit_async_admin_req() must use atomic rq allocation NVMe: replace blk_put_request() with blk_mq_free_request() ...
Diffstat (limited to 'drivers/block/nvme-scsi.c')
-rw-r--r--drivers/block/nvme-scsi.c162
1 files changed, 12 insertions, 150 deletions
diff --git a/drivers/block/nvme-scsi.c b/drivers/block/nvme-scsi.c
index 0b4b2775600e..5e78568026c3 100644
--- a/drivers/block/nvme-scsi.c
+++ b/drivers/block/nvme-scsi.c
@@ -2105,7 +2105,7 @@ static int nvme_trans_do_nvme_io(struct nvme_ns *ns, struct sg_io_hdr *hdr,
2105 2105
2106 nvme_offset += unit_num_blocks; 2106 nvme_offset += unit_num_blocks;
2107 2107
2108 nvme_sc = nvme_submit_io_cmd(dev, &c, NULL); 2108 nvme_sc = nvme_submit_io_cmd(dev, ns, &c, NULL);
2109 if (nvme_sc != NVME_SC_SUCCESS) { 2109 if (nvme_sc != NVME_SC_SUCCESS) {
2110 nvme_unmap_user_pages(dev, 2110 nvme_unmap_user_pages(dev,
2111 (is_write) ? DMA_TO_DEVICE : DMA_FROM_DEVICE, 2111 (is_write) ? DMA_TO_DEVICE : DMA_FROM_DEVICE,
@@ -2658,7 +2658,7 @@ static int nvme_trans_start_stop(struct nvme_ns *ns, struct sg_io_hdr *hdr,
2658 c.common.opcode = nvme_cmd_flush; 2658 c.common.opcode = nvme_cmd_flush;
2659 c.common.nsid = cpu_to_le32(ns->ns_id); 2659 c.common.nsid = cpu_to_le32(ns->ns_id);
2660 2660
2661 nvme_sc = nvme_submit_io_cmd(ns->dev, &c, NULL); 2661 nvme_sc = nvme_submit_io_cmd(ns->dev, ns, &c, NULL);
2662 res = nvme_trans_status_code(hdr, nvme_sc); 2662 res = nvme_trans_status_code(hdr, nvme_sc);
2663 if (res) 2663 if (res)
2664 goto out; 2664 goto out;
@@ -2686,7 +2686,7 @@ static int nvme_trans_synchronize_cache(struct nvme_ns *ns,
2686 c.common.opcode = nvme_cmd_flush; 2686 c.common.opcode = nvme_cmd_flush;
2687 c.common.nsid = cpu_to_le32(ns->ns_id); 2687 c.common.nsid = cpu_to_le32(ns->ns_id);
2688 2688
2689 nvme_sc = nvme_submit_io_cmd(ns->dev, &c, NULL); 2689 nvme_sc = nvme_submit_io_cmd(ns->dev, ns, &c, NULL);
2690 2690
2691 res = nvme_trans_status_code(hdr, nvme_sc); 2691 res = nvme_trans_status_code(hdr, nvme_sc);
2692 if (res) 2692 if (res)
@@ -2894,7 +2894,7 @@ static int nvme_trans_unmap(struct nvme_ns *ns, struct sg_io_hdr *hdr,
2894 c.dsm.nr = cpu_to_le32(ndesc - 1); 2894 c.dsm.nr = cpu_to_le32(ndesc - 1);
2895 c.dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD); 2895 c.dsm.attributes = cpu_to_le32(NVME_DSMGMT_AD);
2896 2896
2897 nvme_sc = nvme_submit_io_cmd(dev, &c, NULL); 2897 nvme_sc = nvme_submit_io_cmd(dev, ns, &c, NULL);
2898 res = nvme_trans_status_code(hdr, nvme_sc); 2898 res = nvme_trans_status_code(hdr, nvme_sc);
2899 2899
2900 dma_free_coherent(&dev->pci_dev->dev, ndesc * sizeof(*range), 2900 dma_free_coherent(&dev->pci_dev->dev, ndesc * sizeof(*range),
@@ -2915,6 +2915,14 @@ static int nvme_scsi_translate(struct nvme_ns *ns, struct sg_io_hdr *hdr)
2915 if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len)) 2915 if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len))
2916 return -EFAULT; 2916 return -EFAULT;
2917 2917
2918 /*
2919 * Prime the hdr with good status for scsi commands that don't require
2920 * an nvme command for translation.
2921 */
2922 retcode = nvme_trans_status_code(hdr, NVME_SC_SUCCESS);
2923 if (retcode)
2924 return retcode;
2925
2918 opcode = cmd[0]; 2926 opcode = cmd[0];
2919 2927
2920 switch (opcode) { 2928 switch (opcode) {
@@ -3016,152 +3024,6 @@ int nvme_sg_io(struct nvme_ns *ns, struct sg_io_hdr __user *u_hdr)
3016 return retcode; 3024 return retcode;
3017} 3025}
3018 3026
3019#ifdef CONFIG_COMPAT
3020typedef struct sg_io_hdr32 {
3021 compat_int_t interface_id; /* [i] 'S' for SCSI generic (required) */
3022 compat_int_t dxfer_direction; /* [i] data transfer direction */
3023 unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
3024 unsigned char mx_sb_len; /* [i] max length to write to sbp */
3025 unsigned short iovec_count; /* [i] 0 implies no scatter gather */
3026 compat_uint_t dxfer_len; /* [i] byte count of data transfer */
3027 compat_uint_t dxferp; /* [i], [*io] points to data transfer memory
3028 or scatter gather list */
3029 compat_uptr_t cmdp; /* [i], [*i] points to command to perform */
3030 compat_uptr_t sbp; /* [i], [*o] points to sense_buffer memory */
3031 compat_uint_t timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
3032 compat_uint_t flags; /* [i] 0 -> default, see SG_FLAG... */
3033 compat_int_t pack_id; /* [i->o] unused internally (normally) */
3034 compat_uptr_t usr_ptr; /* [i->o] unused internally */
3035 unsigned char status; /* [o] scsi status */
3036 unsigned char masked_status; /* [o] shifted, masked scsi status */
3037 unsigned char msg_status; /* [o] messaging level data (optional) */
3038 unsigned char sb_len_wr; /* [o] byte count actually written to sbp */
3039 unsigned short host_status; /* [o] errors from host adapter */
3040 unsigned short driver_status; /* [o] errors from software driver */
3041 compat_int_t resid; /* [o] dxfer_len - actual_transferred */
3042 compat_uint_t duration; /* [o] time taken by cmd (unit: millisec) */
3043 compat_uint_t info; /* [o] auxiliary information */
3044} sg_io_hdr32_t; /* 64 bytes long (on sparc32) */
3045
3046typedef struct sg_iovec32 {
3047 compat_uint_t iov_base;
3048 compat_uint_t iov_len;
3049} sg_iovec32_t;
3050
3051static int sg_build_iovec(sg_io_hdr_t __user *sgio, void __user *dxferp, u16 iovec_count)
3052{
3053 sg_iovec_t __user *iov = (sg_iovec_t __user *) (sgio + 1);
3054 sg_iovec32_t __user *iov32 = dxferp;
3055 int i;
3056
3057 for (i = 0; i < iovec_count; i++) {
3058 u32 base, len;
3059
3060 if (get_user(base, &iov32[i].iov_base) ||
3061 get_user(len, &iov32[i].iov_len) ||
3062 put_user(compat_ptr(base), &iov[i].iov_base) ||
3063 put_user(len, &iov[i].iov_len))
3064 return -EFAULT;
3065 }
3066
3067 if (put_user(iov, &sgio->dxferp))
3068 return -EFAULT;
3069 return 0;
3070}
3071
3072int nvme_sg_io32(struct nvme_ns *ns, unsigned long arg)
3073{
3074 sg_io_hdr32_t __user *sgio32 = (sg_io_hdr32_t __user *)arg;
3075 sg_io_hdr_t __user *sgio;
3076 u16 iovec_count;
3077 u32 data;
3078 void __user *dxferp;
3079 int err;
3080 int interface_id;
3081
3082 if (get_user(interface_id, &sgio32->interface_id))
3083 return -EFAULT;
3084 if (interface_id != 'S')
3085 return -EINVAL;
3086
3087 if (get_user(iovec_count, &sgio32->iovec_count))
3088 return -EFAULT;
3089
3090 {
3091 void __user *top = compat_alloc_user_space(0);
3092 void __user *new = compat_alloc_user_space(sizeof(sg_io_hdr_t) +
3093 (iovec_count * sizeof(sg_iovec_t)));
3094 if (new > top)
3095 return -EINVAL;
3096
3097 sgio = new;
3098 }
3099
3100 /* Ok, now construct. */
3101 if (copy_in_user(&sgio->interface_id, &sgio32->interface_id,
3102 (2 * sizeof(int)) +
3103 (2 * sizeof(unsigned char)) +
3104 (1 * sizeof(unsigned short)) +
3105 (1 * sizeof(unsigned int))))
3106 return -EFAULT;
3107
3108 if (get_user(data, &sgio32->dxferp))
3109 return -EFAULT;
3110 dxferp = compat_ptr(data);
3111 if (iovec_count) {
3112 if (sg_build_iovec(sgio, dxferp, iovec_count))
3113 return -EFAULT;
3114 } else {
3115 if (put_user(dxferp, &sgio->dxferp))
3116 return -EFAULT;
3117 }
3118
3119 {
3120 unsigned char __user *cmdp;
3121 unsigned char __user *sbp;
3122
3123 if (get_user(data, &sgio32->cmdp))
3124 return -EFAULT;
3125 cmdp = compat_ptr(data);
3126
3127 if (get_user(data, &sgio32->sbp))
3128 return -EFAULT;
3129 sbp = compat_ptr(data);
3130
3131 if (put_user(cmdp, &sgio->cmdp) ||
3132 put_user(sbp, &sgio->sbp))
3133 return -EFAULT;
3134 }
3135
3136 if (copy_in_user(&sgio->timeout, &sgio32->timeout,
3137 3 * sizeof(int)))
3138 return -EFAULT;
3139
3140 if (get_user(data, &sgio32->usr_ptr))
3141 return -EFAULT;
3142 if (put_user(compat_ptr(data), &sgio->usr_ptr))
3143 return -EFAULT;
3144
3145 err = nvme_sg_io(ns, sgio);
3146 if (err >= 0) {
3147 void __user *datap;
3148
3149 if (copy_in_user(&sgio32->pack_id, &sgio->pack_id,
3150 sizeof(int)) ||
3151 get_user(datap, &sgio->usr_ptr) ||
3152 put_user((u32)(unsigned long)datap,
3153 &sgio32->usr_ptr) ||
3154 copy_in_user(&sgio32->status, &sgio->status,
3155 (4 * sizeof(unsigned char)) +
3156 (2 * sizeof(unsigned short)) +
3157 (3 * sizeof(int))))
3158 err = -EFAULT;
3159 }
3160
3161 return err;
3162}
3163#endif
3164
3165int nvme_sg_get_version_num(int __user *ip) 3027int nvme_sg_get_version_num(int __user *ip)
3166{ 3028{
3167 return put_user(sg_version_num, ip); 3029 return put_user(sg_version_num, ip);