Example #1
0
/* FIXME callers should check for failure, but don't */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
{
    const char *driver;
    DeviceState *dev;

    driver = bdrv_is_sg(dinfo->bdrv) ? "scsi-generic" : "scsi-disk";
    dev = qdev_create(&bus->qbus, driver);
    qdev_prop_set_uint32(dev, "scsi-id", unit);
    qdev_prop_set_drive(dev, "drive", dinfo);
    if (qdev_init(dev) < 0)
        return NULL;
    return DO_UPCAST(SCSIDevice, qdev, dev);
}
Example #2
0
/* handle legacy '-drive if=scsi,...' cmd line args */
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
                                      int unit, bool removable)
{
    const char *driver;
    DeviceState *dev;

    driver = bdrv_is_sg(bdrv) ? "scsi-generic" : "scsi-disk";
    dev = qdev_create(&bus->qbus, driver);
    qdev_prop_set_uint32(dev, "scsi-id", unit);
    if (qdev_prop_exists(dev, "removable")) {
        qdev_prop_set_bit(dev, "removable", removable);
    }
    if (qdev_prop_set_drive(dev, "drive", bdrv) < 0) {
        qdev_free(dev);
        return NULL;
    }
    if (qdev_init(dev) < 0)
        return NULL;
    return DO_UPCAST(SCSIDevice, qdev, dev);
}
Example #3
0
static int scsi_generic_initfn(SCSIDevice *s)
{
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->conf.bs) {
        error_report("drive property not set");
        return -1;
    }

    /* check we are really using a /dev/sg* file */
    if (!bdrv_is_sg(s->conf.bs)) {
        error_report("not /dev/sg*");
        return -1;
    }

    if (bdrv_get_on_error(s->conf.bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
        error_report("Device doesn't support drive option werror");
        return -1;
    }
    if (bdrv_get_on_error(s->conf.bs, 1) != BLOCK_ERR_REPORT) {
        error_report("Device doesn't support drive option rerror");
        return -1;
    }

    /* check we are using a driver managing SG_IO (version 3 and after */
    if (bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
        sg_version < 30000) {
        error_report("scsi generic interface too old");
        return -1;
    }

    /* get LUN of the /dev/sg? */
    if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
        error_report("SG_GET_SCSI_ID ioctl failed");
        return -1;
    }

    /* define device state */
    s->type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->type);
    if (s->type == TYPE_DISK || s->type == TYPE_ROM) {
        add_boot_device_path(s->conf.bootindex, &s->qdev, NULL);
    }

    switch (s->type) {
    case TYPE_TAPE:
        s->blocksize = get_stream_blocksize(s->conf.bs);
        if (s->blocksize == -1) {
            s->blocksize = 0;
        }
        break;

        /* Make a guess for block devices, we'll fix it when the guest sends.
         * READ CAPACITY.  If they don't, they likely would assume these sizes
         * anyway. (TODO: they could also send MODE SENSE).
         */
    case TYPE_ROM:
    case TYPE_WORM:
        s->blocksize = 2048;
        break;
    default:
        s->blocksize = 512;
        break;
    }

    DPRINTF("block size %d\n", s->blocksize);
    return 0;
}
Example #4
0
static int scsi_generic_initfn(SCSIDevice *dev)
{
    SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, dev);
    int sg_version;
    struct sg_scsi_id scsiid;

    if (!s->qdev.conf.bs) {
        error_report("scsi-generic: drive property not set");
        return -1;
    }
    s->bs = s->qdev.conf.bs;

    /* check we are really using a /dev/sg* file */
    if (!bdrv_is_sg(s->bs)) {
        error_report("scsi-generic: not /dev/sg*");
        return -1;
    }

    if (bdrv_get_on_error(s->bs, 0) != BLOCK_ERR_STOP_ENOSPC) {
        error_report("Device doesn't support drive option werror");
        return -1;
    }
    if (bdrv_get_on_error(s->bs, 1) != BLOCK_ERR_REPORT) {
        error_report("Device doesn't support drive option rerror");
        return -1;
    }

    /* check we are using a driver managing SG_IO (version 3 and after */
    if (bdrv_ioctl(s->bs, SG_GET_VERSION_NUM, &sg_version) < 0 ||
        sg_version < 30000) {
        error_report("scsi-generic: scsi generic interface too old");
        return -1;
    }

    /* get LUN of the /dev/sg? */
    if (bdrv_ioctl(s->bs, SG_GET_SCSI_ID, &scsiid)) {
        error_report("scsi-generic: SG_GET_SCSI_ID ioctl failed");
        return -1;
    }

    /* define device state */
    s->lun = scsiid.lun;
    DPRINTF("LUN %d\n", s->lun);
    s->qdev.type = scsiid.scsi_type;
    DPRINTF("device type %d\n", s->qdev.type);
    if (s->qdev.type == TYPE_TAPE) {
        s->qdev.blocksize = get_stream_blocksize(s->bs);
        if (s->qdev.blocksize == -1)
            s->qdev.blocksize = 0;
    } else {
        s->qdev.blocksize = get_blocksize(s->bs);
        /* removable media returns 0 if not present */
        if (s->qdev.blocksize <= 0) {
            if (s->qdev.type == TYPE_ROM || s->qdev.type  == TYPE_WORM)
                s->qdev.blocksize = 2048;
            else
                s->qdev.blocksize = 512;
        }
    }
    DPRINTF("block size %d\n", s->qdev.blocksize);
    s->driver_status = 0;
    memset(s->sensebuf, 0, sizeof(s->sensebuf));
    bdrv_set_removable(s->bs, 0);
    return 0;
}