提交 ebef0bbb 编写于 作者: B Bernhard Kohl 提交者: Kevin Wolf

scsi-disk: add some optional scsi commands

I use a legacy OS which depends on some optional SCSI commands.
In fact this implementation does nothing special, but provides minimum
support for the following commands:

REZERO UNIT
WRITE AND VERIFY(10)
WRITE AND VERIFY(12)
WRITE AND VERIFY(16)
MODE SELECT(6)
MODE SELECT(10)
SEEK(6)
SEEK(10)
Signed-off-by: NBernhard Kohl <bernhard.kohl@nsn.com>
Signed-off-by: NKevin Wolf <kwolf@redhat.com>
上级 79d1d331
...@@ -892,6 +892,12 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) ...@@ -892,6 +892,12 @@ static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf)
break; break;
case VERIFY: case VERIFY:
break; break;
case REZERO_UNIT:
DPRINTF("Rezero Unit\n");
if (!bdrv_is_inserted(s->bs)) {
goto not_ready;
}
break;
default: default:
goto illegal_request; goto illegal_request;
} }
...@@ -1011,6 +1017,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, ...@@ -1011,6 +1017,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
case SERVICE_ACTION_IN: case SERVICE_ACTION_IN:
case REPORT_LUNS: case REPORT_LUNS:
case VERIFY: case VERIFY:
case REZERO_UNIT:
rc = scsi_disk_emulate_command(&r->req, outbuf); rc = scsi_disk_emulate_command(&r->req, outbuf);
if (rc > 0) { if (rc > 0) {
r->iov.iov_len = rc; r->iov.iov_len = rc;
...@@ -1034,13 +1041,40 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, ...@@ -1034,13 +1041,40 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
case WRITE_10: case WRITE_10:
case WRITE_12: case WRITE_12:
case WRITE_16: case WRITE_16:
DPRINTF("Write (sector %" PRId64 ", count %d)\n", lba, len); case WRITE_VERIFY:
case WRITE_VERIFY_12:
case WRITE_VERIFY_16:
DPRINTF("Write %s(sector %" PRId64 ", count %d)\n",
(command & 0xe) == 0xe ? "And Verify " : "", lba, len);
if (lba > s->max_lba) if (lba > s->max_lba)
goto illegal_lba; goto illegal_lba;
r->sector = lba * s->cluster_size; r->sector = 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:
DPRINTF("Mode Select(6) (len %d)\n", len);
/* We don't support mode parameter changes.
Allow the mode parameter header + block descriptors only. */
if (len > 12) {
goto fail;
}
break;
case MODE_SELECT_10:
DPRINTF("Mode Select(10) (len %d)\n", len);
/* We don't support mode parameter changes.
Allow the mode parameter header + block descriptors only. */
if (len > 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) {
goto illegal_lba;
}
break;
default: default:
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]); DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
fail: fail:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册