diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-06-10 16:58:19 +0200 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-06-18 08:47:11 +0200 |
commit | 489c7901a6e92d65afab333d498b3790b73f7153 (patch) | |
tree | dfdaa11d98e18de5e4c7827be01e42b55f092522 /hw/scsi/virtio-scsi.c | |
parent | 57fbae6e2cbbea037196a9ad67487c3fe78217f0 (diff) |
virtio-scsi: prepare sense data handling for any_layout
Retrieve sense and copy it to guest memory, to prepare for when we will use
qemu_iovec_from_buf.
Swap response and request, since we'll use the tail of VirtIOSCSIReq
for the CDB.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'hw/scsi/virtio-scsi.c')
-rw-r--r-- | hw/scsi/virtio-scsi.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 0718626e1c..fbc7db776c 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -26,12 +26,7 @@ typedef struct VirtIOSCSIReq { VirtQueueElement elem; QEMUSGList qsgl; SCSIRequest *sreq; - union { - char *buf; - VirtIOSCSICmdReq *cmd; - VirtIOSCSICtrlTMFReq *tmf; - VirtIOSCSICtrlANReq *an; - } req; + size_t resp_size; union { char *buf; VirtIOSCSICmdResp *cmd; @@ -39,6 +34,12 @@ typedef struct VirtIOSCSIReq { VirtIOSCSICtrlANResp *an; VirtIOSCSIEvent *event; } resp; + union { + char *buf; + VirtIOSCSICmdReq *cmd; + VirtIOSCSICtrlTMFReq *tmf; + VirtIOSCSICtrlANReq *an; + } req; } VirtIOSCSIReq; static inline int virtio_scsi_get_lun(uint8_t *lun) @@ -136,6 +137,7 @@ static int virtio_scsi_parse_req(VirtIOSCSIReq *req, return -EINVAL; } req->resp.buf = req->elem.in_sg[0].iov_base; + req->resp_size = resp_size; if (req->elem.out_num > 1) { qemu_sgl_concat(req, &req->elem.out_sg[1], @@ -358,8 +360,7 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status, size_t resid) { VirtIOSCSIReq *req = r->hba_private; - VirtIOSCSI *s = req->dev; - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); + uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; if (r->io_canceled) { @@ -372,8 +373,9 @@ static void virtio_scsi_command_complete(SCSIRequest *r, uint32_t status, req->resp.cmd->resid = tswap32(resid); } else { req->resp.cmd->resid = 0; - sense_len = scsi_req_get_sense(r, req->resp.cmd->sense, - vs->sense_size); + sense_len = scsi_req_get_sense(r, sense, sizeof(sense)); + sense_len = MIN(sense_len, req->resp_size - sizeof(req->resp.cmd)); + memcpy(req->resp.cmd->sense, sense, sense_len); req->resp.cmd->sense_len = tswap32(sense_len); } virtio_scsi_complete_req(req); |