Commit 49f54371 authored by Anthony Liguori's avatar Anthony Liguori
Browse files

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
parents be793eb3 baa1bd89
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -209,7 +209,7 @@ obj-y = arch_init.o cpus.o monitor.o machine.o gdbstub.o balloon.o ioport.o
# need to fix this properly
obj-$(CONFIG_NO_PCI) += pci-stub.o
obj-$(CONFIG_VIRTIO) += virtio.o virtio-blk.o virtio-balloon.o virtio-net.o virtio-serial-bus.o
obj-$(CONFIG_VIRTIO_SCSI) += virtio-scsi.o
obj-$(CONFIG_VIRTIO) += virtio-scsi.o
obj-y += vhost_net.o
obj-$(CONFIG_VHOST_NET) += vhost.o
obj-$(CONFIG_REALLY_VIRTFS) += 9pfs/virtio-9p-device.o
+0 −1
Original line number Diff line number Diff line
CONFIG_PCI=y
CONFIG_VIRTIO_PCI=y
CONFIG_VIRTIO_SCSI=y
CONFIG_VIRTIO=y
CONFIG_USB_UHCI=y
CONFIG_USB_OHCI=y
+0 −1
Original line number Diff line number Diff line
CONFIG_VIRTIO=y
CONFIG_VIRTIO_SCSI=y
+18 −0
Original line number Diff line number Diff line
@@ -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);
+33 −16
Original line number Diff line number Diff line
@@ -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));
@@ -1355,6 +1348,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:
Loading