scsi-bus: Convert DeviceClass init to realize

Replace "init/destroy" with "realize/unrealize" in SCSIDeviceClass,
which has errp as a parameter. So all the implementations now use
error_setg instead of error_report for reporting error.

Also in scsi_bus_legacy_handle_cmdline, report the error when
initializing the if=scsi devices, before returning it, because in the
callee, error_report is changed to error_setg. And the callers don't
have the right locations (e.g. "-drive if=scsi").

Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Fam Zheng 2014-08-12 10:12:55 +08:00 committed by Paolo Bonzini
parent 5ff5efb46c
commit a818a4b69d
6 changed files with 95 additions and 97 deletions

View File

@ -19,6 +19,7 @@
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
#include "hw/scsi/scsi.h" #include "hw/scsi/scsi.h"
#include "sysemu/dma.h" #include "sysemu/dma.h"
#include "qemu/error-report.h"
//#define DEBUG_LSI //#define DEBUG_LSI
//#define DEBUG_LSI_REG //#define DEBUG_LSI_REG

View File

@ -36,20 +36,19 @@ static const TypeInfo scsi_bus_info = {
}; };
static int next_scsi_bus; static int next_scsi_bus;
static int scsi_device_init(SCSIDevice *s) static void scsi_device_realize(SCSIDevice *s, Error **errp)
{ {
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
if (sc->init) { if (sc->realize) {
return sc->init(s); sc->realize(s, errp);
} }
return 0;
} }
static void scsi_device_destroy(SCSIDevice *s) static void scsi_device_unrealize(SCSIDevice *s, Error **errp)
{ {
SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s);
if (sc->destroy) { if (sc->unrealize) {
sc->destroy(s); sc->unrealize(s, errp);
} }
} }
@ -143,24 +142,24 @@ static void scsi_dma_restart_cb(void *opaque, int running, RunState state)
} }
} }
static int scsi_qdev_init(DeviceState *qdev) static void scsi_qdev_realize(DeviceState *qdev, Error **errp)
{ {
SCSIDevice *dev = SCSI_DEVICE(qdev); SCSIDevice *dev = SCSI_DEVICE(qdev);
SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus); SCSIBus *bus = DO_UPCAST(SCSIBus, qbus, dev->qdev.parent_bus);
SCSIDevice *d; SCSIDevice *d;
int rc = -1; Error *local_err = NULL;
if (dev->channel > bus->info->max_channel) { if (dev->channel > bus->info->max_channel) {
error_report("bad scsi channel id: %d", dev->channel); error_setg(errp, "bad scsi channel id: %d", dev->channel);
goto err; return;
} }
if (dev->id != -1 && dev->id > bus->info->max_target) { if (dev->id != -1 && dev->id > bus->info->max_target) {
error_report("bad scsi device id: %d", dev->id); error_setg(errp, "bad scsi device id: %d", dev->id);
goto err; return;
} }
if (dev->lun != -1 && dev->lun > bus->info->max_lun) { if (dev->lun != -1 && dev->lun > bus->info->max_lun) {
error_report("bad scsi device lun: %d", dev->lun); error_setg(errp, "bad scsi device lun: %d", dev->lun);
goto err; return;
} }
if (dev->id == -1) { if (dev->id == -1) {
@ -172,8 +171,8 @@ static int scsi_qdev_init(DeviceState *qdev)
d = scsi_device_find(bus, dev->channel, ++id, dev->lun); d = scsi_device_find(bus, dev->channel, ++id, dev->lun);
} while (d && d->lun == dev->lun && id < bus->info->max_target); } while (d && d->lun == dev->lun && id < bus->info->max_target);
if (d && d->lun == dev->lun) { if (d && d->lun == dev->lun) {
error_report("no free target"); error_setg(errp, "no free target");
goto err; return;
} }
dev->id = id; dev->id = id;
} else if (dev->lun == -1) { } else if (dev->lun == -1) {
@ -182,43 +181,41 @@ static int scsi_qdev_init(DeviceState *qdev)
d = scsi_device_find(bus, dev->channel, dev->id, ++lun); d = scsi_device_find(bus, dev->channel, dev->id, ++lun);
} while (d && d->lun == lun && lun < bus->info->max_lun); } while (d && d->lun == lun && lun < bus->info->max_lun);
if (d && d->lun == lun) { if (d && d->lun == lun) {
error_report("no free lun"); error_setg(errp, "no free lun");
goto err; return;
} }
dev->lun = lun; dev->lun = lun;
} else { } else {
d = scsi_device_find(bus, dev->channel, dev->id, dev->lun); d = scsi_device_find(bus, dev->channel, dev->id, dev->lun);
assert(d); assert(d);
if (d->lun == dev->lun && dev != d) { if (d->lun == dev->lun && dev != d) {
error_report("lun already used by '%s'", d->qdev.id); error_setg(errp, "lun already used by '%s'", d->qdev.id);
goto err; return;
} }
} }
QTAILQ_INIT(&dev->requests); QTAILQ_INIT(&dev->requests);
rc = scsi_device_init(dev); scsi_device_realize(dev, &local_err);
if (rc == 0) { if (local_err) {
dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb, error_propagate(errp, local_err);
dev); return;
} }
dev->vmsentry = qemu_add_vm_change_state_handler(scsi_dma_restart_cb,
dev);
if (bus->info->hotplug) { if (bus->info->hotplug) {
bus->info->hotplug(bus, dev); bus->info->hotplug(bus, dev);
} }
err:
return rc;
} }
static int scsi_qdev_exit(DeviceState *qdev) static void scsi_qdev_unrealize(DeviceState *qdev, Error **errp)
{ {
SCSIDevice *dev = SCSI_DEVICE(qdev); SCSIDevice *dev = SCSI_DEVICE(qdev);
if (dev->vmsentry) { if (dev->vmsentry) {
qemu_del_vm_change_state_handler(dev->vmsentry); qemu_del_vm_change_state_handler(dev->vmsentry);
} }
scsi_device_destroy(dev); scsi_device_unrealize(dev, errp);
return 0;
} }
/* handle legacy '-drive if=scsi,...' cmd line args */ /* handle legacy '-drive if=scsi,...' cmd line args */
@ -273,6 +270,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus, Error **errp)
scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL, scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit, false, -1, NULL,
&err); &err);
if (err != NULL) { if (err != NULL) {
error_report("%s", error_get_pretty(err));
error_propagate(errp, err); error_propagate(errp, err);
break; break;
} }
@ -1992,11 +1990,11 @@ static void scsi_device_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *k = DEVICE_CLASS(klass); DeviceClass *k = DEVICE_CLASS(klass);
set_bit(DEVICE_CATEGORY_STORAGE, k->categories); set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
k->bus_type = TYPE_SCSI_BUS; k->bus_type = TYPE_SCSI_BUS;
k->init = scsi_qdev_init; k->realize = scsi_qdev_realize;
k->unplug = scsi_qdev_unplug; k->unplug = scsi_qdev_unplug;
k->exit = scsi_qdev_exit; k->unrealize = scsi_qdev_unrealize;
k->props = scsi_props; k->props = scsi_props;
} }
static const TypeInfo scsi_device_type_info = { static const TypeInfo scsi_device_type_info = {

View File

@ -2151,7 +2151,7 @@ static void scsi_disk_reset(DeviceState *dev)
s->tray_open = 0; s->tray_open = 0;
} }
static void scsi_destroy(SCSIDevice *dev) static void scsi_unrealize(SCSIDevice *dev, Error **errp)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
@ -2234,29 +2234,28 @@ static void scsi_disk_unit_attention_reported(SCSIDevice *dev)
} }
} }
static int scsi_initfn(SCSIDevice *dev) static void scsi_realize(SCSIDevice *dev, Error **errp)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
Error *err = NULL; Error *err = NULL;
if (!s->qdev.conf.bs) { if (!s->qdev.conf.bs) {
error_report("drive property not set"); error_setg(errp, "drive property not set");
return -1; return;
} }
if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) && if (!(s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
!bdrv_is_inserted(s->qdev.conf.bs)) { !bdrv_is_inserted(s->qdev.conf.bs)) {
error_report("Device needs media, but drive is empty"); error_setg(errp, "Device needs media, but drive is empty");
return -1; return;
} }
blkconf_serial(&s->qdev.conf, &s->serial); blkconf_serial(&s->qdev.conf, &s->serial);
if (dev->type == TYPE_DISK) { if (dev->type == TYPE_DISK) {
blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err); blkconf_geometry(&dev->conf, NULL, 65535, 255, 255, &err);
if (err) { if (err) {
error_report("%s", error_get_pretty(err)); error_propagate(errp, err);
error_free(err); return;
return -1;
} }
} }
@ -2273,8 +2272,8 @@ static int scsi_initfn(SCSIDevice *dev)
} }
if (bdrv_is_sg(s->qdev.conf.bs)) { if (bdrv_is_sg(s->qdev.conf.bs)) {
error_report("unwanted /dev/sg*"); error_setg(errp, "unwanted /dev/sg*");
return -1; return;
} }
if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) && if ((s->features & (1 << SCSI_DISK_F_REMOVABLE)) &&
@ -2287,10 +2286,9 @@ static int scsi_initfn(SCSIDevice *dev)
bdrv_iostatus_enable(s->qdev.conf.bs); bdrv_iostatus_enable(s->qdev.conf.bs);
add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL); add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, NULL);
return 0;
} }
static int scsi_hd_initfn(SCSIDevice *dev) static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
s->qdev.blocksize = s->qdev.conf.logical_block_size; s->qdev.blocksize = s->qdev.conf.logical_block_size;
@ -2298,10 +2296,10 @@ static int scsi_hd_initfn(SCSIDevice *dev)
if (!s->product) { if (!s->product) {
s->product = g_strdup("QEMU HARDDISK"); s->product = g_strdup("QEMU HARDDISK");
} }
return scsi_initfn(&s->qdev); scsi_realize(&s->qdev, errp);
} }
static int scsi_cd_initfn(SCSIDevice *dev) static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
s->qdev.blocksize = 2048; s->qdev.blocksize = 2048;
@ -2310,22 +2308,26 @@ static int scsi_cd_initfn(SCSIDevice *dev)
if (!s->product) { if (!s->product) {
s->product = g_strdup("QEMU CD-ROM"); s->product = g_strdup("QEMU CD-ROM");
} }
return scsi_initfn(&s->qdev); scsi_realize(&s->qdev, errp);
} }
static int scsi_disk_initfn(SCSIDevice *dev) static void scsi_disk_realize(SCSIDevice *dev, Error **errp)
{ {
DriveInfo *dinfo; DriveInfo *dinfo;
Error *local_err = NULL;
if (!dev->conf.bs) { if (!dev->conf.bs) {
return scsi_initfn(dev); /* ... and die there */ scsi_realize(dev, &local_err);
assert(local_err);
error_propagate(errp, local_err);
return;
} }
dinfo = drive_get_by_blockdev(dev->conf.bs); dinfo = drive_get_by_blockdev(dev->conf.bs);
if (dinfo->media_cd) { if (dinfo->media_cd) {
return scsi_cd_initfn(dev); scsi_cd_realize(dev, errp);
} else { } else {
return scsi_hd_initfn(dev); scsi_hd_realize(dev, errp);
} }
} }
@ -2457,35 +2459,35 @@ static int get_device_type(SCSIDiskState *s)
return 0; return 0;
} }
static int scsi_block_initfn(SCSIDevice *dev) static void scsi_block_realize(SCSIDevice *dev, Error **errp)
{ {
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
int sg_version; int sg_version;
int rc; int rc;
if (!s->qdev.conf.bs) { if (!s->qdev.conf.bs) {
error_report("drive property not set"); error_setg(errp, "drive property not set");
return -1; return;
} }
/* check we are using a driver managing SG_IO (version 3 and after) */ /* check we are using a driver managing SG_IO (version 3 and after) */
rc = bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version); rc = bdrv_ioctl(s->qdev.conf.bs, SG_GET_VERSION_NUM, &sg_version);
if (rc < 0) { if (rc < 0) {
error_report("cannot get SG_IO version number: %s. " error_setg(errp, "cannot get SG_IO version number: %s. "
"Is this a SCSI device?", "Is this a SCSI device?",
strerror(-rc)); strerror(-rc));
return -1; return;
} }
if (sg_version < 30000) { if (sg_version < 30000) {
error_report("scsi generic interface too old"); error_setg(errp, "scsi generic interface too old");
return -1; return;
} }
/* get device type from INQUIRY data */ /* get device type from INQUIRY data */
rc = get_device_type(s); rc = get_device_type(s);
if (rc < 0) { if (rc < 0) {
error_report("INQUIRY failed"); error_setg(errp, "INQUIRY failed");
return -1; return;
} }
/* Make a guess for the block size, we'll fix it when the guest sends. /* Make a guess for the block size, we'll fix it when the guest sends.
@ -2503,7 +2505,7 @@ static int scsi_block_initfn(SCSIDevice *dev)
*/ */
s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS); s->features |= (1 << SCSI_DISK_F_NO_REMOVABLE_DEVOPS);
return scsi_initfn(&s->qdev); scsi_realize(&s->qdev, errp);
} }
static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf) static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf)
@ -2626,8 +2628,8 @@ static void scsi_hd_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->init = scsi_hd_initfn; sc->realize = scsi_hd_realize;
sc->destroy = scsi_destroy; sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request; sc->alloc_req = scsi_new_request;
sc->unit_attention_reported = scsi_disk_unit_attention_reported; sc->unit_attention_reported = scsi_disk_unit_attention_reported;
dc->fw_name = "disk"; dc->fw_name = "disk";
@ -2657,8 +2659,8 @@ static void scsi_cd_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->init = scsi_cd_initfn; sc->realize = scsi_cd_realize;
sc->destroy = scsi_destroy; sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request; sc->alloc_req = scsi_new_request;
sc->unit_attention_reported = scsi_disk_unit_attention_reported; sc->unit_attention_reported = scsi_disk_unit_attention_reported;
dc->fw_name = "disk"; dc->fw_name = "disk";
@ -2687,8 +2689,8 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->init = scsi_block_initfn; sc->realize = scsi_block_realize;
sc->destroy = scsi_destroy; sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_block_new_request; sc->alloc_req = scsi_block_new_request;
sc->parse_cdb = scsi_block_parse_cdb; sc->parse_cdb = scsi_block_parse_cdb;
dc->fw_name = "disk"; dc->fw_name = "disk";
@ -2725,8 +2727,8 @@ static void scsi_disk_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->init = scsi_disk_initfn; sc->realize = scsi_disk_realize;
sc->destroy = scsi_destroy; sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request; sc->alloc_req = scsi_new_request;
sc->unit_attention_reported = scsi_disk_unit_attention_reported; sc->unit_attention_reported = scsi_disk_unit_attention_reported;
dc->fw_name = "disk"; dc->fw_name = "disk";

View File

@ -386,49 +386,49 @@ static void scsi_generic_reset(DeviceState *dev)
scsi_device_purge_requests(s, SENSE_CODE(RESET)); scsi_device_purge_requests(s, SENSE_CODE(RESET));
} }
static void scsi_destroy(SCSIDevice *s) static void scsi_unrealize(SCSIDevice *s, Error **errp)
{ {
scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE)); scsi_device_purge_requests(s, SENSE_CODE(NO_SENSE));
blockdev_mark_auto_del(s->conf.bs); blockdev_mark_auto_del(s->conf.bs);
} }
static int scsi_generic_initfn(SCSIDevice *s) static void scsi_generic_realize(SCSIDevice *s, Error **errp)
{ {
int rc; int rc;
int sg_version; int sg_version;
struct sg_scsi_id scsiid; struct sg_scsi_id scsiid;
if (!s->conf.bs) { if (!s->conf.bs) {
error_report("drive property not set"); error_setg(errp, "drive property not set");
return -1; return;
} }
if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) { if (bdrv_get_on_error(s->conf.bs, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
error_report("Device doesn't support drive option werror"); error_setg(errp, "Device doesn't support drive option werror");
return -1; return;
} }
if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) { if (bdrv_get_on_error(s->conf.bs, 1) != BLOCKDEV_ON_ERROR_REPORT) {
error_report("Device doesn't support drive option rerror"); error_setg(errp, "Device doesn't support drive option rerror");
return -1; return;
} }
/* check we are using a driver managing SG_IO (version 3 and after */ /* check we are using a driver managing SG_IO (version 3 and after */
rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version); rc = bdrv_ioctl(s->conf.bs, SG_GET_VERSION_NUM, &sg_version);
if (rc < 0) { if (rc < 0) {
error_report("cannot get SG_IO version number: %s. " error_setg(errp, "cannot get SG_IO version number: %s. "
"Is this a SCSI device?", "Is this a SCSI device?",
strerror(-rc)); strerror(-rc));
return -1; return;
} }
if (sg_version < 30000) { if (sg_version < 30000) {
error_report("scsi generic interface too old"); error_setg(errp, "scsi generic interface too old");
return -1; return;
} }
/* get LUN of the /dev/sg? */ /* get LUN of the /dev/sg? */
if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) { if (bdrv_ioctl(s->conf.bs, SG_GET_SCSI_ID, &scsiid)) {
error_report("SG_GET_SCSI_ID ioctl failed"); error_setg(errp, "SG_GET_SCSI_ID ioctl failed");
return -1; return;
} }
/* define device state */ /* define device state */
@ -460,7 +460,6 @@ static int scsi_generic_initfn(SCSIDevice *s)
} }
DPRINTF("block size %d\n", s->blocksize); DPRINTF("block size %d\n", s->blocksize);
return 0;
} }
const SCSIReqOps scsi_generic_req_ops = { const SCSIReqOps scsi_generic_req_ops = {
@ -501,8 +500,8 @@ static void scsi_generic_class_initfn(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass);
SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass);
sc->init = scsi_generic_initfn; sc->realize = scsi_generic_realize;
sc->destroy = scsi_destroy; sc->unrealize = scsi_unrealize;
sc->alloc_req = scsi_new_request; sc->alloc_req = scsi_new_request;
sc->parse_cdb = scsi_generic_parse_cdb; sc->parse_cdb = scsi_generic_parse_cdb;
dc->fw_name = "disk"; dc->fw_name = "disk";

View File

@ -74,8 +74,8 @@ struct SCSIRequest {
typedef struct SCSIDeviceClass { typedef struct SCSIDeviceClass {
DeviceClass parent_class; DeviceClass parent_class;
int (*init)(SCSIDevice *dev); void (*realize)(SCSIDevice *dev, Error **errp);
void (*destroy)(SCSIDevice *s); void (*unrealize)(SCSIDevice *dev, Error **errp);
int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf, int (*parse_cdb)(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf,
void *hba_private); void *hba_private);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun, SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,

View File

@ -149,13 +149,11 @@ QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty (qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
QEMU X.Y.Z monitor - type 'help' for more information QEMU X.Y.Z monitor - type 'help' for more information
(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty (qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized