mirror of https://github.com/xemu-project/xemu.git
scsi-disk: Remove duplicate cdb parsing
We parse the CDB twice, which is completely unnecessary. Signed-off-by: Hannes Reinecke <hare@suse.de> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
a6d96eb78b
commit
2dd791b630
|
@ -1004,9 +1004,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
uint8_t *buf, int lun)
|
uint8_t *buf, int lun)
|
||||||
{
|
{
|
||||||
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
|
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);
|
||||||
uint64_t lba;
|
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
int cmdlen;
|
|
||||||
int is_write;
|
int is_write;
|
||||||
uint8_t command;
|
uint8_t command;
|
||||||
uint8_t *outbuf;
|
uint8_t *outbuf;
|
||||||
|
@ -1025,55 +1023,21 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
outbuf = (uint8_t *)r->iov.iov_base;
|
outbuf = (uint8_t *)r->iov.iov_base;
|
||||||
is_write = 0;
|
is_write = 0;
|
||||||
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
|
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]);
|
||||||
switch (command >> 5) {
|
|
||||||
case 0:
|
if (scsi_req_parse(&r->req, buf) != 0) {
|
||||||
lba = (uint64_t) buf[3] | ((uint64_t) buf[2] << 8) |
|
|
||||||
(((uint64_t) buf[1] & 0x1f) << 16);
|
|
||||||
len = buf[4];
|
|
||||||
cmdlen = 6;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
|
|
||||||
((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
|
|
||||||
len = buf[8] | (buf[7] << 8);
|
|
||||||
cmdlen = 10;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
lba = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) |
|
|
||||||
((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24) |
|
|
||||||
((uint64_t) buf[5] << 32) | ((uint64_t) buf[4] << 40) |
|
|
||||||
((uint64_t) buf[3] << 48) | ((uint64_t) buf[2] << 56);
|
|
||||||
len = buf[13] | (buf[12] << 8) | (buf[11] << 16) | (buf[10] << 24);
|
|
||||||
cmdlen = 16;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
lba = (uint64_t) buf[5] | ((uint64_t) buf[4] << 8) |
|
|
||||||
((uint64_t) buf[3] << 16) | ((uint64_t) buf[2] << 24);
|
|
||||||
len = buf[9] | (buf[8] << 8) | (buf[7] << 16) | (buf[6] << 24);
|
|
||||||
cmdlen = 12;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BADF("Unsupported command length, command %x\n", command);
|
BADF("Unsupported command length, command %x\n", command);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_SCSI
|
#ifdef DEBUG_SCSI
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 1; i < cmdlen; i++) {
|
for (i = 1; i < r->req.cmd.len; i++) {
|
||||||
printf(" 0x%02x", buf[i]);
|
printf(" 0x%02x", buf[i]);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (scsi_req_parse(&r->req, buf) != 0) {
|
|
||||||
BADF("Unsupported command length, command %x\n", command);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
assert(r->req.cmd.len == cmdlen);
|
|
||||||
assert(r->req.cmd.lba == lba);
|
|
||||||
|
|
||||||
if (lun || buf[1] >> 5) {
|
if (lun || buf[1] >> 5) {
|
||||||
/* Only LUN 0 supported. */
|
/* Only LUN 0 supported. */
|
||||||
DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
|
DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5);
|
||||||
|
@ -1111,10 +1075,11 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
case READ_10:
|
case READ_10:
|
||||||
case READ_12:
|
case READ_12:
|
||||||
case READ_16:
|
case READ_16:
|
||||||
DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len);
|
len = r->req.cmd.xfer / d->blocksize;
|
||||||
if (lba > s->max_lba)
|
DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len);
|
||||||
|
if (r->req.cmd.lba > s->max_lba)
|
||||||
goto illegal_lba;
|
goto illegal_lba;
|
||||||
r->sector = lba * s->cluster_size;
|
r->sector = r->req.cmd.lba * s->cluster_size;
|
||||||
r->sector_count = len * s->cluster_size;
|
r->sector_count = len * s->cluster_size;
|
||||||
break;
|
break;
|
||||||
case WRITE_6:
|
case WRITE_6:
|
||||||
|
@ -1124,42 +1089,45 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
|
||||||
case WRITE_VERIFY:
|
case WRITE_VERIFY:
|
||||||
case WRITE_VERIFY_12:
|
case WRITE_VERIFY_12:
|
||||||
case WRITE_VERIFY_16:
|
case WRITE_VERIFY_16:
|
||||||
|
len = r->req.cmd.xfer / d->blocksize;
|
||||||
DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
|
DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
|
||||||
(command & 0xe) == 0xe ? "And Verify " : "", lba, len);
|
(command & 0xe) == 0xe ? "And Verify " : "",
|
||||||
if (lba > s->max_lba)
|
r->req.cmd.lba, len);
|
||||||
|
if (r->req.cmd.lba > s->max_lba)
|
||||||
goto illegal_lba;
|
goto illegal_lba;
|
||||||
r->sector = lba * s->cluster_size;
|
r->sector = r->req.cmd.lba * s->cluster_size;
|
||||||
r->sector_count = len * s->cluster_size;
|
r->sector_count = len * s->cluster_size;
|
||||||
is_write = 1;
|
is_write = 1;
|
||||||
break;
|
break;
|
||||||
case MODE_SELECT:
|
case MODE_SELECT:
|
||||||
DPRINTF("Mode Select(6) (len %d)\n", len);
|
DPRINTF("Mode Select(6) (len %lu)\n", (long)r->req.cmd.xfer);
|
||||||
/* We don't support mode parameter changes.
|
/* We don't support mode parameter changes.
|
||||||
Allow the mode parameter header + block descriptors only. */
|
Allow the mode parameter header + block descriptors only. */
|
||||||
if (len > 12) {
|
if (r->req.cmd.xfer > 12) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MODE_SELECT_10:
|
case MODE_SELECT_10:
|
||||||
DPRINTF("Mode Select(10) (len %d)\n", len);
|
DPRINTF("Mode Select(10) (len %lu)\n", (long)r->req.cmd.xfer);
|
||||||
/* We don't support mode parameter changes.
|
/* We don't support mode parameter changes.
|
||||||
Allow the mode parameter header + block descriptors only. */
|
Allow the mode parameter header + block descriptors only. */
|
||||||
if (len > 16) {
|
if (r->req.cmd.xfer > 16) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SEEK_6:
|
case SEEK_6:
|
||||||
case SEEK_10:
|
case SEEK_10:
|
||||||
DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, lba);
|
DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10,
|
||||||
if (lba > s->max_lba) {
|
r->req.cmd.lba);
|
||||||
|
if (r->req.cmd.lba > s->max_lba) {
|
||||||
goto illegal_lba;
|
goto illegal_lba;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
|
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
|
||||||
fail:
|
fail:
|
||||||
scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
|
scsi_command_complete(r, CHECK_CONDITION, ILLEGAL_REQUEST);
|
||||||
return 0;
|
return 0;
|
||||||
illegal_lba:
|
illegal_lba:
|
||||||
scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
|
scsi_command_complete(r, CHECK_CONDITION, HARDWARE_ERROR);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue