Merge tag 'ras_for_3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/bp/bp into...
[cascardo/linux.git] / drivers / vhost / scsi.c
index a17f118..d695b16 100644 (file)
@@ -168,6 +168,7 @@ enum {
        VHOST_SCSI_VQ_IO = 2,
 };
 
+/* Note: can't set VIRTIO_F_VERSION_1 yet, since that implies ANY_LAYOUT. */
 enum {
        VHOST_SCSI_FEATURES = VHOST_FEATURES | (1ULL << VIRTIO_SCSI_F_HOTPLUG) |
                                               (1ULL << VIRTIO_SCSI_F_T10_PI)
@@ -577,8 +578,8 @@ tcm_vhost_allocate_evt(struct vhost_scsi *vs,
                return NULL;
        }
 
-       evt->event.event = event;
-       evt->event.reason = reason;
+       evt->event.event = cpu_to_vhost32(vq, event);
+       evt->event.reason = cpu_to_vhost32(vq, reason);
        vs->vs_events_nr++;
 
        return evt;
@@ -636,7 +637,7 @@ again:
        }
 
        if (vs->vs_events_missed) {
-               event->event |= VIRTIO_SCSI_T_EVENTS_MISSED;
+               event->event |= cpu_to_vhost32(vq, VIRTIO_SCSI_T_EVENTS_MISSED);
                vs->vs_events_missed = false;
        }
 
@@ -695,12 +696,13 @@ static void vhost_scsi_complete_cmd_work(struct vhost_work *work)
                        cmd, se_cmd->residual_count, se_cmd->scsi_status);
 
                memset(&v_rsp, 0, sizeof(v_rsp));
-               v_rsp.resid = se_cmd->residual_count;
+               v_rsp.resid = cpu_to_vhost32(cmd->tvc_vq, se_cmd->residual_count);
                /* TODO is status_qualifier field needed? */
                v_rsp.status = se_cmd->scsi_status;
-               v_rsp.sense_len = se_cmd->scsi_sense_length;
+               v_rsp.sense_len = cpu_to_vhost32(cmd->tvc_vq,
+                                                se_cmd->scsi_sense_length);
                memcpy(v_rsp.sense, cmd->tvc_sense_buf,
-                      v_rsp.sense_len);
+                      se_cmd->scsi_sense_length);
                ret = copy_to_user(cmd->tvc_resp, &v_rsp, sizeof(v_rsp));
                if (likely(ret == 0)) {
                        struct vhost_scsi_virtqueue *q;
@@ -909,6 +911,23 @@ vhost_scsi_map_iov_to_prot(struct tcm_vhost_cmd *cmd,
        return 0;
 }
 
+static int vhost_scsi_to_tcm_attr(int attr)
+{
+       switch (attr) {
+       case VIRTIO_SCSI_S_SIMPLE:
+               return TCM_SIMPLE_TAG;
+       case VIRTIO_SCSI_S_ORDERED:
+               return TCM_ORDERED_TAG;
+       case VIRTIO_SCSI_S_HEAD:
+               return TCM_HEAD_TAG;
+       case VIRTIO_SCSI_S_ACA:
+               return TCM_ACA_TAG;
+       default:
+               break;
+       }
+       return TCM_SIMPLE_TAG;
+}
+
 static void tcm_vhost_submission_work(struct work_struct *work)
 {
        struct tcm_vhost_cmd *cmd =
@@ -934,9 +953,10 @@ static void tcm_vhost_submission_work(struct work_struct *work)
        rc = target_submit_cmd_map_sgls(se_cmd, tv_nexus->tvn_se_sess,
                        cmd->tvc_cdb, &cmd->tvc_sense_buf[0],
                        cmd->tvc_lun, cmd->tvc_exp_data_len,
-                       cmd->tvc_task_attr, cmd->tvc_data_direction,
-                       TARGET_SCF_ACK_KREF, sg_ptr, cmd->tvc_sgl_count,
-                       NULL, 0, sg_prot_ptr, cmd->tvc_prot_sgl_count);
+                       vhost_scsi_to_tcm_attr(cmd->tvc_task_attr),
+                       cmd->tvc_data_direction, TARGET_SCF_ACK_KREF,
+                       sg_ptr, cmd->tvc_sgl_count, NULL, 0, sg_prot_ptr,
+                       cmd->tvc_prot_sgl_count);
        if (rc < 0) {
                transport_send_check_condition_and_sense(se_cmd,
                                TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0);
@@ -1095,14 +1115,14 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                                                ", but wrong data_direction\n");
                                        goto err_cmd;
                                }
-                               prot_bytes = v_req_pi.pi_bytesout;
+                               prot_bytes = vhost32_to_cpu(vq, v_req_pi.pi_bytesout);
                        } else if (v_req_pi.pi_bytesin) {
                                if (data_direction != DMA_FROM_DEVICE) {
                                        vq_err(vq, "Received non zero di_pi_niov"
                                                ", but wrong data_direction\n");
                                        goto err_cmd;
                                }
-                               prot_bytes = v_req_pi.pi_bytesin;
+                               prot_bytes = vhost32_to_cpu(vq, v_req_pi.pi_bytesin);
                        }
                        if (prot_bytes) {
                                int tmp = 0;
@@ -1117,12 +1137,12 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                                data_first += prot_niov;
                                data_niov = data_num - prot_niov;
                        }
-                       tag = v_req_pi.tag;
+                       tag = vhost64_to_cpu(vq, v_req_pi.tag);
                        task_attr = v_req_pi.task_attr;
                        cdb = &v_req_pi.cdb[0];
                        lun = ((v_req_pi.lun[2] << 8) | v_req_pi.lun[3]) & 0x3FFF;
                } else {
-                       tag = v_req.tag;
+                       tag = vhost64_to_cpu(vq, v_req.tag);
                        task_attr = v_req.task_attr;
                        cdb = &v_req.cdb[0];
                        lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF;