aboutsummaryrefslogtreecommitdiff
path: root/hw/block/fdc.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/block/fdc.c')
-rw-r--r--hw/block/fdc.c82
1 files changed, 45 insertions, 37 deletions
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index be0674e4aa..f4493d6afa 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2497,6 +2497,29 @@ static void fdctrl_result_timer(void *opaque)
}
/* Init functions */
+
+static void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
+{
+ DeviceState *dev;
+ int i;
+
+ for (i = 0; i < MAX_FD; i++) {
+ if (fds[i]) {
+ dev = qdev_new("floppy");
+ qdev_prop_set_uint32(dev, "unit", i);
+ qdev_prop_set_enum(dev, "drive-type", FLOPPY_DRIVE_TYPE_AUTO);
+ qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(fds[i]),
+ &error_fatal);
+ qdev_realize_and_unref(dev, &bus->bus, &error_fatal);
+ }
+ }
+}
+
+void isa_fdc_init_drives(ISADevice *fdc, DriveInfo **fds)
+{
+ fdctrl_init_drives(&ISA_FDC(fdc)->state.bus, fds);
+}
+
static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
Error **errp)
{
@@ -2505,6 +2528,7 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
DeviceState *dev;
BlockBackend *blk;
Error *local_err = NULL;
+ const char *fdc_name, *drive_suffix;
for (i = 0; i < MAX_FD; i++) {
drive = &fdctrl->drives[i];
@@ -2519,14 +2543,30 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
continue;
}
+ fdc_name = object_get_typename(OBJECT(fdc_dev));
+ drive_suffix = !strcmp(fdc_name, "SUNW,fdtwo") ? "" : i ? "B" : "A";
+ warn_report("warning: property %s.drive%s is deprecated",
+ fdc_name, drive_suffix);
+ error_printf("Use -device floppy,unit=%d,drive=... instead.\n", i);
+
dev = qdev_new("floppy");
qdev_prop_set_uint32(dev, "unit", i);
qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
+ /*
+ * Hack alert: we move the backend from the floppy controller
+ * device to the floppy device. We first need to detach the
+ * controller, or else floppy_create()'s qdev_prop_set_drive()
+ * will die when it attaches floppy device. We also need to
+ * take another reference so that blk_detach_dev() doesn't
+ * free blk while we still need it.
+ *
+ * The hack is probably a bad idea.
+ */
blk_ref(blk);
blk_detach_dev(blk, fdc_dev);
fdctrl->qdev_for_drives[i].blk = NULL;
- qdev_prop_set_drive(dev, "drive", blk, &local_err);
+ qdev_prop_set_drive_err(dev, "drive", blk, &local_err);
blk_unref(blk);
if (local_err) {
@@ -2542,30 +2582,6 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
}
}
-ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
-{
- DeviceState *dev;
- ISADevice *isadev;
-
- isadev = isa_try_new(TYPE_ISA_FDC);
- if (!isadev) {
- return NULL;
- }
- dev = DEVICE(isadev);
-
- if (fds[0]) {
- qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fds[0]),
- &error_fatal);
- }
- if (fds[1]) {
- qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fds[1]),
- &error_fatal);
- }
- isa_realize_and_unref(isadev, bus, &error_fatal);
-
- return isadev;
-}
-
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
hwaddr mmio_base, DriveInfo **fds)
{
@@ -2578,18 +2594,12 @@ void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
sys = SYSBUS_FDC(dev);
fdctrl = &sys->state;
fdctrl->dma_chann = dma_chann; /* FIXME */
- if (fds[0]) {
- qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fds[0]),
- &error_fatal);
- }
- if (fds[1]) {
- qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fds[1]),
- &error_fatal);
- }
sbd = SYS_BUS_DEVICE(dev);
sysbus_realize_and_unref(sbd, &error_fatal);
sysbus_connect_irq(sbd, 0, irq);
sysbus_mmio_map(sbd, 0, mmio_base);
+
+ fdctrl_init_drives(&sys->state.bus, fds);
}
void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
@@ -2599,15 +2609,13 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
FDCtrlSysBus *sys;
dev = qdev_new("SUNW,fdtwo");
- if (fds[0]) {
- qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(fds[0]),
- &error_fatal);
- }
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sys = SYSBUS_FDC(dev);
sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
*fdc_tc = qdev_get_gpio_in(dev, 0);
+
+ fdctrl_init_drives(&sys->state.bus, fds);
}
static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,