@@ -210,10 +210,8 @@ void *qemu_blockalign(BlockDriverState *bs, size_t size);
int is_windows_drive(const char *filename);
#endif
-struct DriveInfo;
-
typedef struct BlockConf {
- struct DriveInfo *dinfo;
+ BlockDriverState *bs;
uint16_t physical_block_size;
uint16_t logical_block_size;
uint16_t min_io_size;
@@ -232,7 +230,7 @@ static inline unsigned int get_physical_block_exp(BlockConf *conf)
}
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
- DEFINE_PROP_DRIVE("drive", _state, _conf.dinfo), \
+ DEFINE_PROP_DRIVE("drive", _state, _conf.bs), \
DEFINE_PROP_UINT16("logical_block_size", _state, \
_conf.logical_block_size, 512), \
DEFINE_PROP_UINT16("physical_block_size", _state, \
@@ -80,7 +80,6 @@ typedef enum FDiskFlags {
} FDiskFlags;
typedef struct FDrive {
- DriveInfo *dinfo;
BlockDriverState *bs;
/* Drive status */
FDriveType drive;
@@ -100,7 +99,6 @@ typedef struct FDrive {
static void fd_init(FDrive *drv)
{
/* Drive */
- drv->bs = drv->dinfo ? drv->dinfo->bdrv : NULL;
drv->drive = FDRIVE_DRV_NONE;
drv->perpendicular = 0;
/* Disk */
@@ -1862,10 +1860,10 @@ FDCtrl *fdctrl_init_isa(DriveInfo **fds)
dev = isa_create("isa-fdc");
if (fds[0]) {
- qdev_prop_set_drive(&dev->qdev, "driveA", fds[0]);
+ qdev_prop_set_drive(&dev->qdev, "driveA", fds[0]->bdrv);
}
if (fds[1]) {
- qdev_prop_set_drive(&dev->qdev, "driveB", fds[1]);
+ qdev_prop_set_drive(&dev->qdev, "driveB", fds[1]->bdrv);
}
if (qdev_init(&dev->qdev) < 0)
return NULL;
@@ -1884,10 +1882,10 @@ FDCtrl *fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
fdctrl = &sys->state;
fdctrl->dma_chann = dma_chann; /* FIXME */
if (fds[0]) {
- qdev_prop_set_drive(dev, "driveA", fds[0]);
+ qdev_prop_set_drive(dev, "driveA", fds[0]->bdrv);
}
if (fds[1]) {
- qdev_prop_set_drive(dev, "driveB", fds[1]);
+ qdev_prop_set_drive(dev, "driveB", fds[1]->bdrv);
}
qdev_init_nofail(dev);
sysbus_connect_irq(&sys->busdev, 0, irq);
@@ -1905,7 +1903,7 @@ FDCtrl *sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
dev = qdev_create(NULL, "SUNW,fdtwo");
if (fds[0]) {
- qdev_prop_set_drive(dev, "drive", fds[0]);
+ qdev_prop_set_drive(dev, "drive", fds[0]->bdrv);
}
qdev_init_nofail(dev);
sys = DO_UPCAST(FDCtrlSysBus, busdev.qdev, dev);
@@ -2030,8 +2028,8 @@ static ISADeviceInfo isa_fdc_info = {
.qdev.vmsd = &vmstate_isa_fdc,
.qdev.reset = fdctrl_external_reset_isa,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].dinfo),
- DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].dinfo),
+ DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].bs),
+ DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].bs),
DEFINE_PROP_END_OF_LIST(),
},
};
@@ -2053,8 +2051,8 @@ static SysBusDeviceInfo sysbus_fdc_info = {
.qdev.vmsd = &vmstate_sysbus_fdc,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].dinfo),
- DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].dinfo),
+ DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].bs),
+ DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].bs),
DEFINE_PROP_END_OF_LIST(),
},
};
@@ -2066,7 +2064,7 @@ static SysBusDeviceInfo sun4m_fdc_info = {
.qdev.vmsd = &vmstate_sysbus_fdc,
.qdev.reset = fdctrl_external_reset_sysbus,
.qdev.props = (Property[]) {
- DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].dinfo),
+ DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].bs),
DEFINE_PROP_END_OF_LIST(),
},
};
@@ -2594,15 +2594,15 @@ void ide_bus_reset(IDEBus *bus)
ide_clear_hob(bus);
}
-void ide_init_drive(IDEState *s, DriveInfo *dinfo,
+void ide_init_drive(IDEState *s, BlockDriverState *bs,
const char *version, const char *serial)
{
int cylinders, heads, secs;
uint64_t nb_sectors;
- s->bs = dinfo->bdrv;
- bdrv_get_geometry(s->bs, &nb_sectors);
- bdrv_guess_geometry(s->bs, &cylinders, &heads, &secs);
+ s->bs = bs;
+ bdrv_get_geometry(bs, &nb_sectors);
+ bdrv_guess_geometry(bs, &cylinders, &heads, &secs);
s->cylinders = cylinders;
s->heads = heads;
s->sectors = secs;
@@ -2613,9 +2613,9 @@ void ide_init_drive(IDEState *s, DriveInfo *dinfo,
s->smart_autosave = 1;
s->smart_errors = 0;
s->smart_selftest_count = 0;
- if (bdrv_get_type_hint(s->bs) == BDRV_TYPE_CDROM) {
+ if (bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM) {
s->is_cdrom = 1;
- bdrv_set_change_cb(s->bs, cdrom_change_cb, s);
+ bdrv_set_change_cb(bs, cdrom_change_cb, s);
}
if (serial && *serial) {
strncpy(s->drive_serial_str, serial, sizeof(s->drive_serial_str));
@@ -2668,7 +2668,7 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
dinfo = i == 0 ? hd0 : hd1;
ide_init1(bus, i);
if (dinfo) {
- ide_init_drive(&bus->ifs[i], dinfo, NULL, dinfo->serial);
+ ide_init_drive(&bus->ifs[i], dinfo->bdrv, NULL, dinfo->serial);
} else {
ide_reset(&bus->ifs[i]);
}
@@ -555,7 +555,7 @@ uint32_t ide_data_readw(void *opaque, uint32_t addr);
void ide_data_writel(void *opaque, uint32_t addr, uint32_t val);
uint32_t ide_data_readl(void *opaque, uint32_t addr);
-void ide_init_drive(IDEState *s, DriveInfo *dinfo,
+void ide_init_drive(IDEState *s, BlockDriverState *bs,
const char *version, const char *serial);
void ide_init2(IDEBus *bus, qemu_irq irq);
void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0,
@@ -39,7 +39,7 @@ static int ide_qdev_init(DeviceState *qdev, DeviceInfo *base)
IDEDeviceInfo *info = DO_UPCAST(IDEDeviceInfo, qdev, base);
IDEBus *bus = DO_UPCAST(IDEBus, qbus, qdev->parent_bus);
- if (!dev->conf.dinfo) {
+ if (!dev->conf.bs) {
fprintf(stderr, "%s: no drive specified\n", qdev->info->name);
goto err;
}
@@ -83,7 +83,7 @@ IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive)
dev = qdev_create(&bus->qbus, "ide-drive");
qdev_prop_set_uint32(dev, "unit", unit);
- qdev_prop_set_drive(dev, "drive", drive);
+ qdev_prop_set_drive(dev, "drive", drive->bdrv);
if (qdev_init(dev) < 0)
return NULL;
return DO_UPCAST(IDEDevice, qdev, dev);
@@ -104,10 +104,10 @@ static int ide_drive_initfn(IDEDevice *dev)
serial = dev->serial;
if (!serial) {
/* try to fall back to value set with legacy -drive serial=... */
- serial = dev->conf.dinfo->serial;
+ serial = drive_get_serial(dev->conf.bs);
}
- ide_init_drive(s, dev->conf.dinfo, dev->version, serial);
+ ide_init_drive(s, dev->conf.bs, dev->version, serial);
if (!dev->version) {
dev->version = qemu_strdup(s->version);
@@ -89,7 +89,7 @@ static int scsi_hot_add(Monitor *mon, DeviceState *adapter,
* specified).
*/
dinfo->unit = qemu_opt_get_number(dinfo->opts, "unit", -1);
- scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo, dinfo->unit);
+ scsidev = scsi_bus_legacy_add_drive(scsibus, dinfo->bdrv, dinfo->unit);
dinfo->unit = scsidev->id;
if (printinfo)
@@ -211,7 +211,7 @@ static PCIDevice *qemu_pci_hot_add_storage(Monitor *mon,
return NULL;
}
dev = pci_create(bus, devfn, "virtio-blk-pci");
- qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
+ qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv);
if (qdev_init(&dev->qdev) < 0)
dev = NULL;
break;
@@ -285,26 +285,41 @@ PropertyInfo qdev_prop_string = {
static int parse_drive(DeviceState *dev, Property *prop, const char *str)
{
- DriveInfo **ptr = qdev_get_prop_ptr(dev, prop);
+ BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+ BlockDriverState *bs;
- *ptr = drive_get_by_id(str);
- if (*ptr == NULL)
+ bs = bdrv_find(str);
+ if (bs == NULL)
return -ENOENT;
+ if (blockdev_attach(bs, dev) < 0)
+ return -EEXIST;
+ *ptr = bs;
return 0;
}
+static void free_drive(DeviceState *dev, Property *prop)
+{
+ BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+
+ if (*ptr) {
+ blockdev_detach(*ptr, dev);
+ }
+}
+
static int print_drive(DeviceState *dev, Property *prop, char *dest, size_t len)
{
- DriveInfo **ptr = qdev_get_prop_ptr(dev, prop);
- return snprintf(dest, len, "%s", (*ptr) ? (*ptr)->id : "<null>");
+ BlockDriverState **ptr = qdev_get_prop_ptr(dev, prop);
+ return snprintf(dest, len, "%s",
+ *ptr ? bdrv_get_device_name(*ptr) : "<null>");
}
PropertyInfo qdev_prop_drive = {
.name = "drive",
.type = PROP_TYPE_DRIVE,
- .size = sizeof(DriveInfo*),
+ .size = sizeof(BlockDriverState *),
.parse = parse_drive,
.print = print_drive,
+ .free = free_drive,
};
/* --- character device --- */
@@ -627,9 +642,19 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, char *value)
qdev_prop_set(dev, name, &value, PROP_TYPE_STRING);
}
-void qdev_prop_set_drive(DeviceState *dev, const char *name, DriveInfo *value)
+void qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value)
{
+ int res;
+
qdev_prop_set(dev, name, &value, PROP_TYPE_DRIVE);
+ res = blockdev_attach(value, dev);
+ if (res < 0) {
+ error_report("Can't attach drive %s to %s.%s: %s",
+ bdrv_get_device_name(value),
+ dev->id ? dev->id : dev->info->name,
+ name, strerror(res));
+ exit(1);
+ }
}
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value)
@@ -253,8 +253,8 @@ extern PropertyInfo qdev_prop_pci_devfn;
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, VLANClientState*)
#define DEFINE_PROP_VLAN(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, VLANState*)
-#define DEFINE_PROP_DRIVE(_n, _s, _f) \
- DEFINE_PROP(_n, _s, _f, qdev_prop_drive, DriveInfo*)
+#define DEFINE_PROP_DRIVE(_n, _s, _f) \
+ DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
@@ -275,7 +275,7 @@ void qdev_prop_set_string(DeviceState *dev, const char *name, char *value);
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
void qdev_prop_set_netdev(DeviceState *dev, const char *name, VLANClientState *value);
void qdev_prop_set_vlan(DeviceState *dev, const char *name, VLANState *value);
-void qdev_prop_set_drive(DeviceState *dev, const char *name, DriveInfo *value);
+void qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value);
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
@@ -262,7 +262,7 @@ static void s390_init(ram_addr_t ram_size,
}
dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");
- qdev_prop_set_drive(dev, "drive", dinfo);
+ qdev_prop_set_drive(dev, "drive", dinfo->bdrv);
qdev_init_nofail(dev);
}
}
@@ -84,15 +84,15 @@ void scsi_qdev_register(SCSIDeviceInfo *info)
/* handle legacy '-drive if=scsi,...' cmd line args */
/* FIXME callers should check for failure, but don't */
-SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit)
+SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int unit)
{
const char *driver;
DeviceState *dev;
- driver = bdrv_is_sg(dinfo->bdrv) ? "scsi-generic" : "scsi-disk";
+ driver = bdrv_is_sg(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);
+ qdev_prop_set_drive(dev, "drive", bdrv);
if (qdev_init(dev) < 0)
return NULL;
return DO_UPCAST(SCSIDevice, qdev, dev);
@@ -108,7 +108,7 @@ void scsi_bus_legacy_handle_cmdline(SCSIBus *bus)
if (dinfo == NULL) {
continue;
}
- scsi_bus_legacy_add_drive(bus, dinfo, unit);
+ scsi_bus_legacy_add_drive(bus, dinfo->bdrv, unit);
}
}
@@ -1043,26 +1043,26 @@ static void scsi_destroy(SCSIDevice *dev)
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
scsi_disk_purge_requests(s);
- drive_uninit(s->qdev.conf.dinfo);
}
static int scsi_disk_initfn(SCSIDevice *dev)
{
SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
+ const char *serial;
- if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
+ if (!s->qdev.conf.bs) {
error_report("scsi-disk: drive property not set");
return -1;
}
- s->bs = s->qdev.conf.dinfo->bdrv;
+ s->bs = s->qdev.conf.bs;
if (!s->serial) {
- if (*dev->conf.dinfo->serial) {
- /* try to fall back to value set with legacy -drive serial=... */
- s->serial = qemu_strdup(dev->conf.dinfo->serial);
- } else {
- s->serial = qemu_strdup("0");
+ /* try to fall back to value set with legacy -drive serial=... */
+ serial = drive_get_serial(s->bs);
+ if (!*serial) {
+ serial = "0";
}
+ s->serial = qemu_strdup(serial);
}
if (!s->version) {
@@ -453,7 +453,6 @@ static void scsi_destroy(SCSIDevice *d)
r = DO_UPCAST(SCSIGenericReq, req, QTAILQ_FIRST(&s->qdev.requests));
scsi_remove_request(r);
}
- drive_uninit(s->qdev.conf.dinfo);
}
static int scsi_generic_initfn(SCSIDevice *dev)
@@ -462,11 +461,11 @@ static int scsi_generic_initfn(SCSIDevice *dev)
int sg_version;
struct sg_scsi_id scsiid;
- if (!s->qdev.conf.dinfo || !s->qdev.conf.dinfo->bdrv) {
+ if (!s->qdev.conf.bs) {
error_report("scsi-generic: drive property not set");
return -1;
}
- s->bs = s->qdev.conf.dinfo->bdrv;
+ s->bs = s->qdev.conf.bs;
/* check we are really using a /dev/sg* file */
if (!bdrv_is_sg(s->bs)) {
@@ -97,7 +97,7 @@ static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
}
-SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, DriveInfo *dinfo, int unit);
+SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv, int unit);
void scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
void scsi_dev_clear_sense(SCSIDevice *dev);
@@ -523,20 +523,20 @@ static int usb_msd_initfn(USBDevice *dev)
{
MSDState *s = DO_UPCAST(MSDState, dev, dev);
- if (!s->conf.dinfo || !s->conf.dinfo->bdrv) {
+ if (!s->conf.bs) {
error_report("usb-msd: drive property not set");
return -1;
}
s->dev.speed = USB_SPEED_FULL;
scsi_bus_new(&s->bus, &s->dev.qdev, 0, 1, usb_msd_command_complete);
- s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->conf.dinfo, 0);
+ s->scsi_dev = scsi_bus_legacy_add_drive(&s->bus, s->conf.bs, 0);
s->bus.qbus.allow_hotplug = 0;
usb_msd_handle_reset(dev);
- if (bdrv_key_required(s->conf.dinfo->bdrv)) {
+ if (bdrv_key_required(s->conf.bs)) {
if (cur_mon) {
- monitor_read_bdrv_key_start(cur_mon, s->conf.dinfo->bdrv,
+ monitor_read_bdrv_key_start(cur_mon, s->conf.bs,
usb_msd_password_cb, s);
s->dev.auto_attach = 0;
} else {
@@ -595,7 +595,7 @@ static USBDevice *usb_msd_init(const char *filename)
if (!dev) {
return NULL;
}
- qdev_prop_set_drive(&dev->qdev, "drive", dinfo);
+ qdev_prop_set_drive(&dev->qdev, "drive", dinfo->bdrv);
if (qdev_init(&dev->qdev) < 0)
return NULL;
@@ -500,7 +500,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf)
s->vdev.get_config = virtio_blk_update_config;
s->vdev.get_features = virtio_blk_get_features;
s->vdev.reset = virtio_blk_reset;
- s->bs = conf->dinfo->bdrv;
+ s->bs = conf->bs;
s->conf = conf;
s->rq = NULL;
s->sector_mask = (s->conf->logical_block_size / BDRV_SECTOR_SIZE) - 1;
@@ -547,7 +547,7 @@ static int virtio_blk_init_pci(PCIDevice *pci_dev)
proxy->class_code != PCI_CLASS_STORAGE_OTHER)
proxy->class_code = PCI_CLASS_STORAGE_SCSI;
- if (!proxy->block.dinfo) {
+ if (!proxy->block.bs) {
error_report("virtio-blk-pci: drive property not set");
return -1;
}
@@ -567,14 +567,6 @@ static int virtio_exit_pci(PCIDevice *pci_dev)
return msix_uninit(pci_dev);
}
-static int virtio_blk_exit_pci(PCIDevice *pci_dev)
-{
- VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
-
- drive_uninit(proxy->block.dinfo);
- return virtio_exit_pci(pci_dev);
-}
-
static int virtio_serial_init_pci(PCIDevice *pci_dev)
{
VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
@@ -663,7 +655,7 @@ static PCIDeviceInfo virtio_info[] = {
.qdev.name = "virtio-blk-pci",
.qdev.size = sizeof(VirtIOPCIProxy),
.init = virtio_blk_init_pci,
- .exit = virtio_blk_exit_pci,
+ .exit = virtio_exit_pci,
.qdev.props = (Property[]) {
DEFINE_PROP_HEX32("class", VirtIOPCIProxy, class_code, 0),
DEFINE_BLOCK_PROPERTIES(VirtIOPCIProxy, block),
Make the property point to BlockDriverState, cutting out the DriveInfo middleman. Signed-off-by: Markus Armbruster <armbru@redhat.com> --- block_int.h | 6 ++---- hw/fdc.c | 22 ++++++++++------------ hw/ide/core.c | 14 +++++++------- hw/ide/internal.h | 2 +- hw/ide/qdev.c | 8 ++++---- hw/pci-hotplug.c | 4 ++-- hw/qdev-properties.c | 39 ++++++++++++++++++++++++++++++++------- hw/qdev.h | 6 +++--- hw/s390-virtio.c | 2 +- hw/scsi-bus.c | 8 ++++---- hw/scsi-disk.c | 16 ++++++++-------- hw/scsi-generic.c | 5 ++--- hw/scsi.h | 2 +- hw/usb-msd.c | 10 +++++----- hw/virtio-blk.c | 2 +- hw/virtio-pci.c | 12 ++---------- 16 files changed, 85 insertions(+), 73 deletions(-)