Loading hw/scsi-disk.c +21 −53 Original line number Diff line number Diff line Loading @@ -1004,9 +1004,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, uint8_t *buf, int lun) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); uint64_t lba; uint32_t len; int cmdlen; int is_write; uint8_t command; uint8_t *outbuf; Loading @@ -1025,55 +1023,21 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, outbuf = (uint8_t *)r->iov.iov_base; is_write = 0; DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); switch (command >> 5) { case 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: if (scsi_req_parse(&r->req, buf) != 0) { BADF("Unsupported command length, command %x\n", command); goto fail; } #ifdef DEBUG_SCSI { int i; for (i = 1; i < cmdlen; i++) { for (i = 1; i < r->req.cmd.len; i++) { printf(" 0x%02x", buf[i]); } printf("\n"); } #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) { /* Only LUN 0 supported. */ DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); Loading Loading @@ -1111,10 +1075,11 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case READ_10: case READ_12: case READ_16: DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len); if (lba > s->max_lba) len = r->req.cmd.xfer / d->blocksize; DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len); if (r->req.cmd.lba > s->max_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; break; case WRITE_6: Loading @@ -1124,34 +1089,37 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY_16: len = r->req.cmd.xfer / d->blocksize; DPRINTF("Write %s(sector %" PRId64 ", count %d)\n", (command & 0xe) == 0xe ? "And Verify " : "", lba, len); if (lba > s->max_lba) (command & 0xe) == 0xe ? "And Verify " : "", r->req.cmd.lba, len); if (r->req.cmd.lba > s->max_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; is_write = 1; break; 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. Allow the mode parameter header + block descriptors only. */ if (len > 12) { if (r->req.cmd.xfer > 12) { goto fail; } break; 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. Allow the mode parameter header + block descriptors only. */ if (len > 16) { if (r->req.cmd.xfer > 16) { goto fail; } break; case SEEK_6: case SEEK_10: DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, lba); if (lba > s->max_lba) { DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, r->req.cmd.lba); if (r->req.cmd.lba > s->max_lba) { goto illegal_lba; } break; Loading Loading
hw/scsi-disk.c +21 −53 Original line number Diff line number Diff line Loading @@ -1004,9 +1004,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, uint8_t *buf, int lun) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); uint64_t lba; uint32_t len; int cmdlen; int is_write; uint8_t command; uint8_t *outbuf; Loading @@ -1025,55 +1023,21 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, outbuf = (uint8_t *)r->iov.iov_base; is_write = 0; DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", lun, tag, buf[0]); switch (command >> 5) { case 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: if (scsi_req_parse(&r->req, buf) != 0) { BADF("Unsupported command length, command %x\n", command); goto fail; } #ifdef DEBUG_SCSI { int i; for (i = 1; i < cmdlen; i++) { for (i = 1; i < r->req.cmd.len; i++) { printf(" 0x%02x", buf[i]); } printf("\n"); } #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) { /* Only LUN 0 supported. */ DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); Loading Loading @@ -1111,10 +1075,11 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case READ_10: case READ_12: case READ_16: DPRINTF("Read (sector %" PRId64 ", count %d)\n", lba, len); if (lba > s->max_lba) len = r->req.cmd.xfer / d->blocksize; DPRINTF("Read (sector %" PRId64 ", count %d)\n", r->req.cmd.lba, len); if (r->req.cmd.lba > s->max_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; break; case WRITE_6: Loading @@ -1124,34 +1089,37 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, case WRITE_VERIFY: case WRITE_VERIFY_12: case WRITE_VERIFY_16: len = r->req.cmd.xfer / d->blocksize; DPRINTF("Write %s(sector %" PRId64 ", count %d)\n", (command & 0xe) == 0xe ? "And Verify " : "", lba, len); if (lba > s->max_lba) (command & 0xe) == 0xe ? "And Verify " : "", r->req.cmd.lba, len); if (r->req.cmd.lba > s->max_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; is_write = 1; break; 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. Allow the mode parameter header + block descriptors only. */ if (len > 12) { if (r->req.cmd.xfer > 12) { goto fail; } break; 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. Allow the mode parameter header + block descriptors only. */ if (len > 16) { if (r->req.cmd.xfer > 16) { goto fail; } break; case SEEK_6: case SEEK_10: DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, lba); if (lba > s->max_lba) { DPRINTF("Seek(%d) (sector %" PRId64 ")\n", command == SEEK_6 ? 6 : 10, r->req.cmd.lba); if (r->req.cmd.lba > s->max_lba) { goto illegal_lba; } break; Loading