/* Helper function for command completion with sense. */
static void scsi_check_condition(SCSIDiskReq *r, SCSISense sense)
{
- DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n",
- r->req.tag, status, sense.key, sense.asc, sense.ascq);
+ DPRINTF("Command complete tag=0x%x sense=%d/%d/%d\n",
+ r->req.tag, sense.key, sense.asc, sense.ascq);
scsi_req_build_sense(&r->req, sense);
scsi_req_complete(&r->req, CHECK_CONDITION);
}
memset(outbuf, 0, buflen);
- if (req->lun) {
- outbuf[0] = 0x7f; /* LUN not supported */
- return buflen;
- }
-
outbuf[0] = s->qdev.type & 0x1f;
if (s->qdev.type == TYPE_ROM) {
outbuf[1] = 0x80;
if (!bdrv_is_inserted(s->bs))
goto not_ready;
break;
- case REQUEST_SENSE:
- if (req->cmd.xfer < 4)
- goto illegal_request;
- buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,
- (req->cmd.buf[1] & 1) == 0);
- break;
case INQUIRY:
buflen = scsi_disk_emulate_inquiry(req, outbuf);
if (buflen < 0)
}
DPRINTF("Unsupported Service Action In\n");
goto illegal_request;
- case REPORT_LUNS:
- if (req->cmd.xfer < 16)
- goto illegal_request;
- memset(outbuf, 0, 16);
- outbuf[3] = 8;
- buflen = 16;
- break;
case VERIFY_10:
break;
default:
outbuf = (uint8_t *)r->iov.iov_base;
DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]);
- if (scsi_req_parse(&r->req, buf) != 0) {
- BADF("Unsupported command length, command %x\n", command);
- scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
- return 0;
- }
#ifdef DEBUG_SCSI
{
int i;
}
#endif
- if (req->lun) {
- /* Only LUN 0 supported. */
- DPRINTF("Unimplemented LUN %d\n", req->lun);
- if (command != REQUEST_SENSE && command != INQUIRY) {
- scsi_check_condition(r, SENSE_CODE(LUN_NOT_SUPPORTED));
- return 0;
- }
- }
switch (command) {
case TEST_UNIT_READY:
- case REQUEST_SENSE:
case INQUIRY:
case MODE_SENSE:
case MODE_SENSE_10:
case READ_TOC:
case GET_CONFIGURATION:
case SERVICE_ACTION_IN:
- case REPORT_LUNS:
case VERIFY_10:
rc = scsi_disk_emulate_command(r, outbuf);
if (rc < 0) {
}
break;
+ case REQUEST_SENSE:
+ abort();
default:
DPRINTF("Unknown SCSI command (%2.2x)\n", buf[0]);
scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev.qdev, dev);
uint64_t nb_sectors;
- scsi_device_purge_requests(&s->qdev);
+ scsi_device_purge_requests(&s->qdev, SENSE_CODE(RESET));
bdrv_get_geometry(s->bs, &nb_sectors);
nb_sectors /= s->cluster_size;
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
- scsi_device_purge_requests(&s->qdev);
+ scsi_device_purge_requests(&s->qdev, SENSE_CODE(NO_SENSE));
blockdev_mark_auto_del(s->qdev.conf.bs);
}
/* try to fall back to value set with legacy -drive serial=... */
dinfo = drive_get_by_blockdev(s->bs);
if (*dinfo->serial) {
- s->serial = qemu_strdup(dinfo->serial);
+ s->serial = g_strdup(dinfo->serial);
}
}
if (!s->version) {
- s->version = qemu_strdup(QEMU_VERSION);
+ s->version = g_strdup(QEMU_VERSION);
}
if (bdrv_is_sg(s->bs)) {
static SCSIReqOps scsi_disk_reqops = {
.size = sizeof(SCSIDiskReq),
+ .free_req = scsi_free_request,
+ .send_command = scsi_send_command,
+ .read_data = scsi_read_data,
+ .write_data = scsi_write_data,
+ .cancel_io = scsi_cancel_io,
+ .get_buf = scsi_get_buf,
};
static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag,
.init = scsi_hd_initfn,
.destroy = scsi_destroy,
.alloc_req = scsi_new_request,
- .free_req = scsi_free_request,
- .send_command = scsi_send_command,
- .read_data = scsi_read_data,
- .write_data = scsi_write_data,
- .cancel_io = scsi_cancel_io,
- .get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
DEFINE_SCSI_DISK_PROPERTIES(),
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),
.init = scsi_cd_initfn,
.destroy = scsi_destroy,
.alloc_req = scsi_new_request,
- .free_req = scsi_free_request,
- .send_command = scsi_send_command,
- .read_data = scsi_read_data,
- .write_data = scsi_write_data,
- .cancel_io = scsi_cancel_io,
- .get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
DEFINE_SCSI_DISK_PROPERTIES(),
DEFINE_PROP_END_OF_LIST(),
.init = scsi_disk_initfn,
.destroy = scsi_destroy,
.alloc_req = scsi_new_request,
- .free_req = scsi_free_request,
- .send_command = scsi_send_command,
- .read_data = scsi_read_data,
- .write_data = scsi_write_data,
- .cancel_io = scsi_cancel_io,
- .get_buf = scsi_get_buf,
.qdev.props = (Property[]) {
DEFINE_SCSI_DISK_PROPERTIES(),
DEFINE_PROP_BIT("removable", SCSIDiskState, removable, 0, false),