diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-19 13:36:37 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-03-19 13:36:37 -0500 |
commit | 49f54371f22e3e95124e8115050cea29fadde606 (patch) | |
tree | dff7144c8c1527b078b0c6735f52f403aa5281cb /hw | |
parent | be793eb3b9d04ce524cebcffb96e9770d68e57d9 (diff) | |
parent | baa1bd8992c22095fa5a483f4b6415eb15180665 (diff) |
Merge remote-tracking branch 'bonzini/scsi-next' into staging
* bonzini/scsi-next:
scsi: add get_dev_path
virtio-scsi: call unregister_savevm properly
scsi: copy serial number into VPD page 0x83
scsi-cd: check ready condition before processing several commands
get rid of CONFIG_VIRTIO_SCSI
Diffstat (limited to 'hw')
-rw-r--r-- | hw/scsi-bus.c | 18 | ||||
-rw-r--r-- | hw/scsi-disk.c | 49 | ||||
-rw-r--r-- | hw/virtio-scsi.c | 2 |
3 files changed, 53 insertions, 16 deletions
diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 2cb5a18da2..8e76c5d32c 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -7,6 +7,7 @@ #include "trace.h" #include "dma.h" +static char *scsibus_get_dev_path(DeviceState *dev); static char *scsibus_get_fw_dev_path(DeviceState *dev); static int scsi_req_parse(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf); static void scsi_req_dequeue(SCSIRequest *req); @@ -14,6 +15,7 @@ static void scsi_req_dequeue(SCSIRequest *req); static struct BusInfo scsi_bus_info = { .name = "SCSI", .size = sizeof(SCSIBus), + .get_dev_path = scsibus_get_dev_path, .get_fw_dev_path = scsibus_get_fw_dev_path, .props = (Property[]) { DEFINE_PROP_UINT32("channel", SCSIDevice, channel, 0), @@ -1423,6 +1425,22 @@ void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense) sdev->unit_attention = sense; } +static char *scsibus_get_dev_path(DeviceState *dev) +{ + SCSIDevice *d = DO_UPCAST(SCSIDevice, qdev, dev); + DeviceState *hba = dev->parent_bus->parent; + char *id = NULL; + + if (hba && hba->parent_bus && hba->parent_bus->info->get_dev_path) { + id = hba->parent_bus->info->get_dev_path(hba); + } + if (id) { + return g_strdup_printf("%s/%d:%d:%d", id, d->channel, d->id, d->lun); + } else { + return g_strdup_printf("%d:%d:%d", d->channel, d->id, d->lun); + } +} + static char *scsibus_get_fw_dev_path(DeviceState *dev) { SCSIDevice *d = SCSI_DEVICE(dev); diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index add399e97b..9949786e52 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -471,8 +471,9 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) case 0x83: /* Device identification page, mandatory */ { - int max_len = 255 - 8; - int id_len = strlen(bdrv_get_device_name(s->qdev.conf.bs)); + const char *str = s->serial ?: bdrv_get_device_name(s->qdev.conf.bs); + int max_len = s->serial ? 20 : 255 - 8; + int id_len = strlen(str); if (id_len > max_len) { id_len = max_len; @@ -486,7 +487,7 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req, uint8_t *outbuf) outbuf[buflen++] = 0; // reserved outbuf[buflen++] = id_len; // length of data following - memcpy(outbuf+buflen, bdrv_get_device_name(s->qdev.conf.bs), id_len); + memcpy(outbuf+buflen, str, id_len); buflen += id_len; break; } @@ -1152,9 +1153,7 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) outbuf = r->iov.iov_base; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: - if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { - goto not_ready; - } + assert(!s->tray_open && bdrv_is_inserted(s->qdev.conf.bs)); break; case INQUIRY: buflen = scsi_disk_emulate_inquiry(req, outbuf); @@ -1209,7 +1208,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) memset(outbuf, 0, 8); bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); if (!nb_sectors) { - goto not_ready; + scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); + return -1; } if ((req->cmd.buf[8] & 1) == 0 && req->cmd.lba) { goto illegal_request; @@ -1269,7 +1269,8 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) memset(outbuf, 0, req->cmd.xfer); bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); if (!nb_sectors) { - goto not_ready; + scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); + return -1; } if ((req->cmd.buf[14] & 1) == 0 && req->cmd.lba) { goto illegal_request; @@ -1314,14 +1315,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r) buflen = MIN(buflen, req->cmd.xfer); return buflen; -not_ready: - if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { - scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); - } else { - scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); - } - return -1; - illegal_request: if (r->req.status == -1) { scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); @@ -1356,6 +1349,30 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) #endif switch (command) { + case INQUIRY: + case MODE_SENSE: + case MODE_SENSE_10: + case RESERVE: + case RESERVE_10: + case RELEASE: + case RELEASE_10: + case START_STOP: + case ALLOW_MEDIUM_REMOVAL: + case GET_CONFIGURATION: + case GET_EVENT_STATUS_NOTIFICATION: + case MECHANISM_STATUS: + case REQUEST_SENSE: + break; + + default: + if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { + scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); + return 0; + } + break; + } + + switch (command) { case TEST_UNIT_READY: case INQUIRY: case MODE_SENSE: diff --git a/hw/virtio-scsi.c b/hw/virtio-scsi.c index e607edc915..45d54faeb5 100644 --- a/hw/virtio-scsi.c +++ b/hw/virtio-scsi.c @@ -613,5 +613,7 @@ VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf) void virtio_scsi_exit(VirtIODevice *vdev) { + VirtIOSCSI *s = (VirtIOSCSI *)vdev; + unregister_savevm(s->qdev, "virtio-scsi", s); virtio_cleanup(vdev); } |