From 7c72fcf54af0cebad6e61aab9022b1bf62255058 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 22 Feb 2012 14:11:25 +0100 Subject: [PATCH 009/109] scsi: introduce SCSICommand RH-Author: Paolo Bonzini Message-id: <1329919979-20948-9-git-send-email-pbonzini@redhat.com> Patchwork-id: 37497 O-Subject: [RHEL 6.3 qemu-kvm PATCH v2 008/102] scsi: introduce SCSICommand Bugzilla: 782029 RH-Acked-by: Gerd Hoffmann RH-Acked-by: Laszlo Ersek RH-Acked-by: Orit Wasserman This struct is currently unnamed. Give it a name and use it explicitly to decouple (some parts of) CDB parsing from SCSIRequest. Signed-off-by: Paolo Bonzini Signed-off-by: Anthony Liguori (cherry picked from 2599aece1b222ad4f9714275b38bf1d3e9424b54) --- hw/scsi-bus.c | 95 +++++++++++++++++++++++++++++---------------------------- hw/scsi.h | 17 ++++++---- 2 files changed, 58 insertions(+), 54 deletions(-) Signed-off-by: Michal Novotny --- hw/scsi-bus.c | 95 +++++++++++++++++++++++++++++---------------------------- hw/scsi.h | 17 ++++++---- 2 files changed, 58 insertions(+), 54 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index ab7a502..6780d4d 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -218,35 +218,35 @@ static void scsi_req_dequeue(SCSIRequest *req) } } -static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) +static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { - switch (cmd[0] >> 5) { + switch (buf[0] >> 5) { case 0: - req->cmd.xfer = cmd[4]; - req->cmd.len = 6; + cmd->xfer = buf[4]; + cmd->len = 6; /* length 0 means 256 blocks */ - if (req->cmd.xfer == 0) - req->cmd.xfer = 256; + if (cmd->xfer == 0) { + cmd->xfer = 256; + } break; case 1: case 2: - req->cmd.xfer = cmd[8] | (cmd[7] << 8); - req->cmd.len = 10; + cmd->xfer = buf[8] | (buf[7] << 8); + cmd->len = 10; break; case 4: - req->cmd.xfer = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24); - req->cmd.len = 16; + cmd->xfer = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24); + cmd->len = 16; break; case 5: - req->cmd.xfer = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24); - req->cmd.len = 12; + cmd->xfer = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24); + cmd->len = 12; break; default: - trace_scsi_req_parse_bad(req->dev->id, req->lun, req->tag, cmd[0]); return -1; } - switch(cmd[0]) { + switch (buf[0]) { case TEST_UNIT_READY: case REWIND: case START_STOP: @@ -267,27 +267,27 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) case WRITE_LONG_10: case MOVE_MEDIUM: case UPDATE_BLOCK: - req->cmd.xfer = 0; + cmd->xfer = 0; break; case MODE_SENSE: break; case WRITE_SAME_10: - req->cmd.xfer = 1; + cmd->xfer = 1; break; case READ_CAPACITY_10: - req->cmd.xfer = 8; + cmd->xfer = 8; break; case READ_BLOCK_LIMITS: - req->cmd.xfer = 6; + cmd->xfer = 6; break; case READ_POSITION: - req->cmd.xfer = 20; + cmd->xfer = 20; break; case SEND_VOLUME_TAG: - req->cmd.xfer *= 40; + cmd->xfer *= 40; break; case MEDIUM_SCAN: - req->cmd.xfer *= 8; + cmd->xfer *= 8; break; case WRITE_10: case WRITE_VERIFY_10: @@ -296,7 +296,7 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) case WRITE_VERIFY_12: case WRITE_16: case WRITE_VERIFY_16: - req->cmd.xfer *= req->dev->blocksize; + cmd->xfer *= dev->blocksize; break; case READ_10: case READ_6: @@ -304,50 +304,51 @@ static int scsi_req_length(SCSIRequest *req, uint8_t *cmd) case RECOVER_BUFFERED_DATA: case READ_12: case READ_16: - req->cmd.xfer *= req->dev->blocksize; + cmd->xfer *= dev->blocksize; break; case INQUIRY: - req->cmd.xfer = cmd[4] | (cmd[3] << 8); + cmd->xfer = buf[4] | (buf[3] << 8); break; case MAINTENANCE_OUT: case MAINTENANCE_IN: - if (req->dev->type == TYPE_ROM) { + if (dev->type == TYPE_ROM) { /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */ - req->cmd.xfer = cmd[9] | (cmd[8] << 8); + cmd->xfer = buf[9] | (buf[8] << 8); } break; } return 0; } -static int scsi_req_stream_length(SCSIRequest *req, uint8_t *cmd) +static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { - switch(cmd[0]) { + switch (buf[0]) { /* stream commands */ case READ_6: case READ_REVERSE: case RECOVER_BUFFERED_DATA: case WRITE_6: - req->cmd.len = 6; - req->cmd.xfer = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16); - if (cmd[1] & 0x01) /* fixed */ - req->cmd.xfer *= req->dev->blocksize; + cmd->len = 6; + cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16); + if (buf[1] & 0x01) { /* fixed */ + cmd->xfer *= dev->blocksize; + } break; case REWIND: case START_STOP: - req->cmd.len = 6; - req->cmd.xfer = 0; + cmd->len = 6; + cmd->xfer = 0; break; /* generic commands */ default: - return scsi_req_length(req, cmd); + return scsi_req_length(cmd, dev, buf); } return 0; } -static void scsi_req_xfer_mode(SCSIRequest *req) +static void scsi_cmd_xfer_mode(SCSICommand *cmd) { - switch (req->cmd.buf[0]) { + switch (cmd->buf[0]) { case WRITE_6: case WRITE_10: case WRITE_VERIFY_10: @@ -379,21 +380,21 @@ static void scsi_req_xfer_mode(SCSIRequest *req) case SEND_VOLUME_TAG: case PERSISTENT_RESERVE_OUT: case MAINTENANCE_OUT: - req->cmd.mode = SCSI_XFER_TO_DEV; + cmd->mode = SCSI_XFER_TO_DEV; break; default: - if (req->cmd.xfer) - req->cmd.mode = SCSI_XFER_FROM_DEV; + if (cmd->xfer) + cmd->mode = SCSI_XFER_FROM_DEV; else { - req->cmd.mode = SCSI_XFER_NONE; + cmd->mode = SCSI_XFER_NONE; } break; } } -static uint64_t scsi_req_lba(SCSIRequest *req) +static uint64_t scsi_cmd_lba(SCSICommand *cmd) { - uint8_t *buf = req->cmd.buf; + uint8_t *buf = cmd->buf; uint64_t lba; switch (buf[0] >> 5) { @@ -428,16 +429,16 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf) int rc; if (req->dev->type == TYPE_TAPE) { - rc = scsi_req_stream_length(req, buf); + rc = scsi_req_stream_length(&req->cmd, req->dev, buf); } else { - rc = scsi_req_length(req, buf); + rc = scsi_req_length(&req->cmd, req->dev, buf); } if (rc != 0) return rc; assert(buf == req->cmd.buf); - scsi_req_xfer_mode(req); - req->cmd.lba = scsi_req_lba(req); + scsi_cmd_xfer_mode(&req->cmd); + req->cmd.lba = scsi_cmd_lba(&req->cmd); trace_scsi_req_parsed(req->dev->id, req->lun, req->tag, buf[0], req->cmd.mode, req->cmd.xfer); if (req->cmd.lba != -1) { diff --git a/hw/scsi.h b/hw/scsi.h index b82fbef..399671f 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -11,6 +11,7 @@ typedef struct SCSIBus SCSIBus; typedef struct SCSIBusOps SCSIBusOps; +typedef struct SCSICommand SCSICommand; typedef struct SCSIDevice SCSIDevice; typedef struct SCSIDeviceInfo SCSIDeviceInfo; typedef struct SCSIRequest SCSIRequest; @@ -30,6 +31,14 @@ typedef struct SCSISense { #define SCSI_SENSE_BUF_SIZE 96 +struct SCSICommand { + uint8_t buf[SCSI_CMD_BUF_SIZE]; + int len; + size_t xfer; + uint64_t lba; + enum SCSIXferMode mode; +}; + struct SCSIRequest { SCSIBus *bus; SCSIDevice *dev; @@ -38,13 +47,7 @@ struct SCSIRequest { uint32_t tag; uint32_t lun; uint32_t status; - struct { - uint8_t buf[SCSI_CMD_BUF_SIZE]; - int len; - size_t xfer; - uint64_t lba; - enum SCSIXferMode mode; - } cmd; + SCSICommand cmd; BlockDriverAIOCB *aiocb; uint8_t sense[SCSI_SENSE_BUF_SIZE]; uint32_t sense_len; -- 1.7.7.6