All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives
@ 2016-09-30 19:39 Kevin Wolf
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus Kevin Wolf
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Kevin Wolf @ 2016-09-30 19:39 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, jsnow, armbru, mreitz, qemu-devel

We have been complaining for a long time about how the floppy controller and
floppy drives are combined in a single qdev device and how this makes the
device awkward to work with because it behaves different from all other block
devices.

The latest reason to complain was when I noticed that using qdev device names
in QMP commands (e.g. for media change) doesn't really work when only the
controller is a qdev device, but the drives aren't.

So I decided to have a go at it, and this is the result.

It doesn't actually change any of the inner workings of the floppy controller,
but it wires things up differently on the qdev layer so that a floppy
controller now exposes a bus on which the floppy drives sit. This results in a
structure that is similar to IDE where the actual drive state is still in the
controller and the qdev device basically just contains the qdev properties -
not pretty, but quite workable.

The commit message of patch 3 explains how to use it. In short, there is a
'-device floppy' now and it does what you would expect if you ever used ide-cd.

The other problem is old command lines, especially those using things like
'-global isa-fdc,driveA=...'. In order to keep them working, we need to forward
the property to an internally created floppy drive device. This is a bit like
usb-storage, which we know is ugly, but works well enough in practice. The good
news here is that in contrast to usb-storage, the floppy controller only does
the forwarding for legacy configurations; as soon as you start using '-device
floppy', it doesn't happen any more.

So as you may have expected, this conversion doesn't result in a perfect
device, but I think it's definitely an improvement over the old state. I hope
you like it despite the warts. :-)

v2:
- Added patch 4 (qemu-iotests case for floppy config on the command line)
- Patch 2: Create a floppy device only if a BlockBackend exists instead of
  always creating two of them
- Patch 2: Initialise drive->fdctrl even if no drive is attached, it is
  accessed anyway during migration
- Patch 3: Keep 'type' qdev property and FDrive->drive in sync
- Patch 3: Removed if with condition that is always true

Kevin Wolf (4):
  fdc: Add a floppy qbus
  fdc: Add a floppy drive qdev
  fdc: Move qdev properties to FloppyDrive
  qemu-iotests: Test creating floppy drives

 hw/block/fdc.c             |  263 ++++++++--
 tests/qemu-iotests/172     |  242 +++++++++
 tests/qemu-iotests/172.out | 1205 ++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |    1 +
 vl.c                       |    1 +
 5 files changed, 1668 insertions(+), 44 deletions(-)
 create mode 100755 tests/qemu-iotests/172
 create mode 100644 tests/qemu-iotests/172.out

-- 
1.8.3.1

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus
  2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
@ 2016-09-30 19:39 ` Kevin Wolf
  2016-10-14 21:32   ` John Snow
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev Kevin Wolf
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Kevin Wolf @ 2016-09-30 19:39 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, jsnow, armbru, mreitz, qemu-devel

This adds a qbus to the floppy controller that should contain the floppy
drives eventually. At the moment it just exists and is empty.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/block/fdc.c | 40 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 5 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index b79873a..a3afb62 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -52,6 +52,33 @@
         }                                                       \
     } while (0)
 
+
+/********************************************************/
+/* qdev floppy bus                                      */
+
+#define TYPE_FLOPPY_BUS "Floppy"
+#define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
+
+typedef struct FDCtrl FDCtrl;
+
+typedef struct FloppyBus {
+    BusState bus;
+    FDCtrl *fdc;
+} FloppyBus;
+
+static const TypeInfo floppy_bus_info = {
+    .name = TYPE_FLOPPY_BUS,
+    .parent = TYPE_BUS,
+    .instance_size = sizeof(FloppyBus),
+};
+
+static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
+{
+    qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
+    bus->fdc = fdc;
+}
+
+
 /********************************************************/
 /* Floppy drive emulation                               */
 
@@ -148,8 +175,6 @@ static FDriveSize drive_size(FloppyDriveType drive)
 #define FD_SECTOR_SC           2   /* Sector size code */
 #define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
 
-typedef struct FDCtrl FDCtrl;
-
 /* Floppy disk drive emulation */
 typedef enum FDiskFlags {
     FDISK_DBL_SIDES  = 0x01,
@@ -684,6 +709,7 @@ struct FDCtrl {
     /* Power down config (also with status regB access mode */
     uint8_t pwrd;
     /* Floppy drives */
+    FloppyBus bus;
     uint8_t num_floppies;
     FDrive drives[MAX_FD];
     int reset_sensei;
@@ -2442,7 +2468,8 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
     *fdc_tc = qdev_get_gpio_in(dev, 0);
 }
 
-static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
+static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
+                                  Error **errp)
 {
     int i, j;
     static int command_tables_inited = 0;
@@ -2480,6 +2507,8 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
         k->register_channel(fdctrl->dma, fdctrl->dma_chann,
                             &fdctrl_transfer_handler, fdctrl);
     }
+
+    floppy_bus_create(fdctrl, &fdctrl->bus, dev);
     fdctrl_connect_drives(fdctrl, errp);
 }
 
@@ -2508,7 +2537,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
     }
 
     qdev_set_legacy_instance_id(dev, isa->iobase, 2);
-    fdctrl_realize_common(fdctrl, &err);
+    fdctrl_realize_common(dev, fdctrl, &err);
     if (err != NULL) {
         error_propagate(errp, err);
         return;
@@ -2559,7 +2588,7 @@ static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
     FDCtrlSysBus *sys = SYSBUS_FDC(dev);
     FDCtrl *fdctrl = &sys->state;
 
-    fdctrl_realize_common(fdctrl, errp);
+    fdctrl_realize_common(dev, fdctrl, errp);
 }
 
 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
@@ -2744,6 +2773,7 @@ static void fdc_register_types(void)
     type_register_static(&sysbus_fdc_type_info);
     type_register_static(&sysbus_fdc_info);
     type_register_static(&sun4m_fdc_info);
+    type_register_static(&floppy_bus_info);
 }
 
 type_init(fdc_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev
  2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus Kevin Wolf
@ 2016-09-30 19:39 ` Kevin Wolf
  2016-10-14 22:09   ` John Snow
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive Kevin Wolf
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 10+ messages in thread
From: Kevin Wolf @ 2016-09-30 19:39 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, jsnow, armbru, mreitz, qemu-devel

Floppy controllers automatically create two floppy drive devices in qdev
now. (They always created two drives, but managed them only internally.)

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/block/fdc.c | 151 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 120 insertions(+), 31 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index a3afb62..5aa8e52 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -60,6 +60,8 @@
 #define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
 
 typedef struct FDCtrl FDCtrl;
+typedef struct FDrive FDrive;
+static FDrive *get_drv(FDCtrl *fdctrl, int unit);
 
 typedef struct FloppyBus {
     BusState bus;
@@ -180,7 +182,7 @@ typedef enum FDiskFlags {
     FDISK_DBL_SIDES  = 0x01,
 } FDiskFlags;
 
-typedef struct FDrive {
+struct FDrive {
     FDCtrl *fdctrl;
     BlockBackend *blk;
     /* Drive status */
@@ -201,7 +203,7 @@ typedef struct FDrive {
     uint8_t media_rate;       /* Data rate of medium    */
 
     bool media_validated;     /* Have we validated the media? */
-} FDrive;
+};
 
 
 static FloppyDriveType get_fallback_drive_type(FDrive *drv);
@@ -466,6 +468,100 @@ static void fd_revalidate(FDrive *drv)
     }
 }
 
+static void fd_change_cb(void *opaque, bool load)
+{
+    FDrive *drive = opaque;
+
+    drive->media_changed = 1;
+    drive->media_validated = false;
+    fd_revalidate(drive);
+}
+
+static const BlockDevOps fd_block_ops = {
+    .change_media_cb = fd_change_cb,
+};
+
+
+#define TYPE_FLOPPY_DRIVE "floppy"
+#define FLOPPY_DRIVE(obj) \
+     OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
+
+typedef struct FloppyDrive {
+    DeviceState qdev;
+    uint32_t    unit;
+} FloppyDrive;
+
+static Property floppy_drive_properties[] = {
+    DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static int floppy_drive_init(DeviceState *qdev)
+{
+    FloppyDrive *dev = FLOPPY_DRIVE(qdev);
+    FloppyBus *bus = DO_UPCAST(FloppyBus, bus, dev->qdev.parent_bus);
+    FDrive *drive;
+
+    if (dev->unit == -1) {
+        for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
+            drive = get_drv(bus->fdc, dev->unit);
+            if (!drive->blk) {
+                break;
+            }
+        }
+    }
+
+    if (dev->unit >= MAX_FD) {
+        error_report("Can't create floppy unit %d, bus supports only %d units",
+                     dev->unit, MAX_FD);
+        return -1;
+    }
+
+    /* TODO Check whether unit is in use */
+
+    drive = get_drv(bus->fdc, dev->unit);
+
+    if (drive->blk) {
+        if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
+            error_report("fdc doesn't support drive option werror");
+            return -1;
+        }
+        if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+            error_report("fdc doesn't support drive option rerror");
+            return -1;
+        }
+    } else {
+        /* Anonymous BlockBackend for an empty drive */
+        drive->blk = blk_new();
+    }
+
+    fd_init(drive);
+    if (drive->blk) {
+        blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
+        pick_drive_type(drive);
+    }
+    fd_revalidate(drive);
+
+    return 0;
+}
+
+static void floppy_drive_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *k = DEVICE_CLASS(klass);
+    k->init = floppy_drive_init;
+    set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
+    k->bus_type = TYPE_FLOPPY_BUS;
+    k->props = floppy_drive_properties;
+    k->desc = "virtual floppy drive";
+}
+
+static const TypeInfo floppy_drive_info = {
+    .name = TYPE_FLOPPY_DRIVE,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(FloppyDrive),
+    .class_init = floppy_drive_class_init,
+};
+
 /********************************************************/
 /* Intel 82078 floppy disk controller emulation          */
 
@@ -1185,9 +1281,9 @@ static inline FDrive *drv3(FDCtrl *fdctrl)
 }
 #endif
 
-static FDrive *get_cur_drv(FDCtrl *fdctrl)
+static FDrive *get_drv(FDCtrl *fdctrl, int unit)
 {
-    switch (fdctrl->cur_drv) {
+    switch (unit) {
         case 0: return drv0(fdctrl);
         case 1: return drv1(fdctrl);
 #if MAX_FD == 4
@@ -1198,6 +1294,11 @@ static FDrive *get_cur_drv(FDCtrl *fdctrl)
     }
 }
 
+static FDrive *get_cur_drv(FDCtrl *fdctrl)
+{
+    return get_drv(fdctrl, fdctrl->cur_drv);
+}
+
 /* Status A register : 0x00 (read-only) */
 static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
 {
@@ -2357,46 +2458,33 @@ static void fdctrl_result_timer(void *opaque)
     }
 }
 
-static void fdctrl_change_cb(void *opaque, bool load)
-{
-    FDrive *drive = opaque;
-
-    drive->media_changed = 1;
-    drive->media_validated = false;
-    fd_revalidate(drive);
-}
-
-static const BlockDevOps fdctrl_block_ops = {
-    .change_media_cb = fdctrl_change_cb,
-};
-
 /* Init functions */
 static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
 {
     unsigned int i;
     FDrive *drive;
+    DeviceState *dev;
+    Error *local_err = NULL;
 
     for (i = 0; i < MAX_FD; i++) {
         drive = &fdctrl->drives[i];
         drive->fdctrl = fdctrl;
 
-        if (drive->blk) {
-            if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
-                error_setg(errp, "fdc doesn't support drive option werror");
-                return;
-            }
-            if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
-                error_setg(errp, "fdc doesn't support drive option rerror");
-                return;
-            }
+        /* If the drive is not present, we skip creating the qdev device, but
+         * still have to initialise the controller. */
+        if (!fdctrl->drives[i].blk) {
+            fd_init(drive);
+            fd_revalidate(drive);
+            continue;
         }
 
-        fd_init(drive);
-        if (drive->blk) {
-            blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive);
-            pick_drive_type(drive);
+        dev = qdev_create(&fdctrl->bus.bus, "floppy");
+        qdev_prop_set_uint32(dev, "unit", i);
+        object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
         }
-        fd_revalidate(drive);
     }
 }
 
@@ -2774,6 +2862,7 @@ static void fdc_register_types(void)
     type_register_static(&sysbus_fdc_info);
     type_register_static(&sun4m_fdc_info);
     type_register_static(&floppy_bus_info);
+    type_register_static(&floppy_drive_info);
 }
 
 type_init(fdc_register_types)
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive
  2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus Kevin Wolf
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev Kevin Wolf
@ 2016-09-30 19:39 ` Kevin Wolf
  2016-10-14 22:32   ` John Snow
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 4/4] qemu-iotests: Test creating floppy drives Kevin Wolf
  2016-10-14 11:11 ` [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
  4 siblings, 1 reply; 10+ messages in thread
From: Kevin Wolf @ 2016-09-30 19:39 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, jsnow, armbru, mreitz, qemu-devel

This makes the FloppyDrive qdev object actually useful: Now that it has
all properties that don't belong to the controller, you can actually
use '-device floppy' and get a working result.

Command line semantics is consistent with CD-ROM drives: By default you
get a single empty floppy drive. You can override it with -drive and
using the same index, but if you use -drive to add a floppy to a
different index, you get both of them. However, as soon as you use any
'-device floppy', even to a different slot, the default drive is
disabled.

Using '-device floppy' without specifying the unit will choose the first
free slot on the controller.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/block/fdc.c | 112 ++++++++++++++++++++++++++++++++++++++++++---------------
 vl.c           |   1 +
 2 files changed, 85 insertions(+), 28 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 5aa8e52..00c0ec6 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -35,6 +35,7 @@
 #include "qemu/timer.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
+#include "hw/block/block.h"
 #include "sysemu/block-backend.h"
 #include "sysemu/blockdev.h"
 #include "sysemu/sysemu.h"
@@ -487,12 +488,18 @@ static const BlockDevOps fd_block_ops = {
      OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
 
 typedef struct FloppyDrive {
-    DeviceState qdev;
-    uint32_t    unit;
+    DeviceState     qdev;
+    uint32_t        unit;
+    BlockConf       conf;
+    FloppyDriveType type;
 } FloppyDrive;
 
 static Property floppy_drive_properties[] = {
     DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
+    DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
+    DEFINE_PROP_DEFAULT("drive-type", FloppyDrive, type,
+                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
+                        FloppyDriveType),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -501,6 +508,7 @@ static int floppy_drive_init(DeviceState *qdev)
     FloppyDrive *dev = FLOPPY_DRIVE(qdev);
     FloppyBus *bus = DO_UPCAST(FloppyBus, bus, dev->qdev.parent_bus);
     FDrive *drive;
+    int ret;
 
     if (dev->unit == -1) {
         for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
@@ -517,29 +525,57 @@ static int floppy_drive_init(DeviceState *qdev)
         return -1;
     }
 
-    /* TODO Check whether unit is in use */
-
     drive = get_drv(bus->fdc, dev->unit);
-
     if (drive->blk) {
-        if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
-            error_report("fdc doesn't support drive option werror");
-            return -1;
-        }
-        if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
-            error_report("fdc doesn't support drive option rerror");
-            return -1;
-        }
-    } else {
+        error_report("Floppy unit %d is in use", dev->unit);
+        return -1;
+    }
+
+    if (!dev->conf.blk) {
         /* Anonymous BlockBackend for an empty drive */
-        drive->blk = blk_new();
+        dev->conf.blk = blk_new();
+        ret = blk_attach_dev(dev->conf.blk, dev);
+        assert(ret == 0);
     }
 
-    fd_init(drive);
-    if (drive->blk) {
-        blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
-        pick_drive_type(drive);
+    blkconf_blocksizes(&dev->conf);
+    if (dev->conf.logical_block_size != 512 ||
+        dev->conf.physical_block_size != 512)
+    {
+        error_report("Physical and logical block size must be 512 for floppy");
+        return -1;
+    }
+
+    /* rerror/werror aren't supported by fdc and therefore not even registered
+     * with qdev. So set the defaults manually before they are used in
+     * blkconf_apply_backend_options(). */
+    dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
+    dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
+    blkconf_apply_backend_options(&dev->conf);
+
+    /* 'enospc' is the default for -drive, 'report' is what blk_new() gives us
+     * for empty drives. */
+    if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC &&
+        blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) {
+        error_report("fdc doesn't support drive option werror");
+        return -1;
     }
+    if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
+        error_report("fdc doesn't support drive option rerror");
+        return -1;
+    }
+
+    drive->blk = dev->conf.blk;
+    drive->fdctrl = bus->fdc;
+
+    fd_init(drive);
+    blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
+
+    /* Keep 'type' qdev property and FDrive->drive in sync */
+    drive->drive = dev->type;
+    pick_drive_type(drive);
+    dev->type = drive->drive;
+
     fd_revalidate(drive);
 
     return 0;
@@ -808,6 +844,10 @@ struct FDCtrl {
     FloppyBus bus;
     uint8_t num_floppies;
     FDrive drives[MAX_FD];
+    struct {
+        BlockBackend *blk;
+        FloppyDriveType type;
+    } qdev_for_drives[MAX_FD];
     int reset_sensei;
     uint32_t check_media_rate;
     FloppyDriveType fallback; /* type=auto failure fallback */
@@ -2459,11 +2499,13 @@ static void fdctrl_result_timer(void *opaque)
 }
 
 /* Init functions */
-static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
+static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp,
+                                  DeviceState *fdc_dev)
 {
     unsigned int i;
     FDrive *drive;
     DeviceState *dev;
+    BlockBackend *blk;
     Error *local_err = NULL;
 
     for (i = 0; i < MAX_FD; i++) {
@@ -2472,7 +2514,8 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
 
         /* If the drive is not present, we skip creating the qdev device, but
          * still have to initialise the controller. */
-        if (!fdctrl->drives[i].blk) {
+        blk = fdctrl->qdev_for_drives[i].blk;
+        if (!blk) {
             fd_init(drive);
             fd_revalidate(drive);
             continue;
@@ -2480,6 +2523,19 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
 
         dev = qdev_create(&fdctrl->bus.bus, "floppy");
         qdev_prop_set_uint32(dev, "unit", i);
+        qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
+
+        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);
+        blk_unref(blk);
+
+        if (local_err) {
+            error_propagate(errp, local_err);
+            return;
+        }
+
         object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
         if (local_err) {
             error_propagate(errp, local_err);
@@ -2597,7 +2653,7 @@ static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
     }
 
     floppy_bus_create(fdctrl, &fdctrl->bus, dev);
-    fdctrl_connect_drives(fdctrl, errp);
+    fdctrl_connect_drives(fdctrl, errp, dev);
 }
 
 static const MemoryRegionPortio fdc_portio_list[] = {
@@ -2723,14 +2779,14 @@ static Property isa_fdc_properties[] = {
     DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
     DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
     DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
-    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].blk),
-    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
+    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.qdev_for_drives[0].blk),
+    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
     DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
                     0, true),
-    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.drives[0].drive,
+    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                         FloppyDriveType),
-    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.drives[1].drive,
+    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                         FloppyDriveType),
     DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
@@ -2782,8 +2838,8 @@ static const VMStateDescription vmstate_sysbus_fdc ={
 };
 
 static Property sysbus_fdc_properties[] = {
-    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
-    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
+    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
+    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
     DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                         FloppyDriveType),
diff --git a/vl.c b/vl.c
index ab0349b..7486f33 100644
--- a/vl.c
+++ b/vl.c
@@ -218,6 +218,7 @@ static struct {
     { .driver = "isa-serial",           .flag = &default_serial    },
     { .driver = "isa-parallel",         .flag = &default_parallel  },
     { .driver = "isa-fdc",              .flag = &default_floppy    },
+    { .driver = "floppy",               .flag = &default_floppy    },
     { .driver = "ide-cd",               .flag = &default_cdrom     },
     { .driver = "ide-hd",               .flag = &default_cdrom     },
     { .driver = "ide-drive",            .flag = &default_cdrom     },
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [Qemu-devel] [PATCH v2 4/4] qemu-iotests: Test creating floppy drives
  2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
                   ` (2 preceding siblings ...)
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive Kevin Wolf
@ 2016-09-30 19:39 ` Kevin Wolf
  2016-10-14 11:11 ` [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Wolf @ 2016-09-30 19:39 UTC (permalink / raw)
  To: qemu-block; +Cc: kwolf, jsnow, armbru, mreitz, qemu-devel

This tests the different supported methods to create floppy drives and
how they interact.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 tests/qemu-iotests/172     |  242 +++++++++
 tests/qemu-iotests/172.out | 1205 ++++++++++++++++++++++++++++++++++++++++++++
 tests/qemu-iotests/group   |    1 +
 3 files changed, 1448 insertions(+)
 create mode 100755 tests/qemu-iotests/172
 create mode 100644 tests/qemu-iotests/172.out

diff --git a/tests/qemu-iotests/172 b/tests/qemu-iotests/172
new file mode 100755
index 0000000..8bb6443
--- /dev/null
+++ b/tests/qemu-iotests/172
@@ -0,0 +1,242 @@
+#!/bin/bash
+#
+# Test floppy configuration
+#
+# Copyright (C) 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=kwolf@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1	# failure is the default!
+
+_cleanup()
+{
+	_cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt qcow2
+_supported_proto file
+_supported_os Linux
+
+if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
+    _notrun "Requires a PC machine"
+fi
+
+function do_run_qemu()
+{
+    (
+        if ! test -t 0; then
+            while read cmd; do
+                echo $cmd
+            done
+        fi
+        echo quit
+    ) | $QEMU -nographic -monitor stdio -serial none "$@"
+    echo
+}
+
+function check_floppy_qtree()
+{
+    echo
+    echo Testing: "$@" | _filter_testdir
+
+    # QEMU_OPTIONS contains -nodefaults, we don't want that here because the
+    # defaults are part of what should be checked here
+    echo "info qtree" |
+    QEMU_OPTIONS="" do_run_qemu "$@" | _filter_win32 |
+    grep -zo '[[:cntrl:]]\( *\)dev: isa-fdc.*\([[:cntrl:]]\1 .*\)*[[:cntrl:]] *dev:'
+}
+
+function check_cache_mode()
+{
+    echo "info block none0" |
+    QEMU_OPTIONS="" do_run_qemu -drive if=none,file="$TEST_IMG" "$@" |
+    _filter_win32 | grep "Cache mode"
+}
+
+
+size=720k
+
+_make_test_img $size
+
+# Default drive semantics:
+#
+# By default you get a single empty floppy drive. You can override it with
+# -drive and using the same index, but if you use -drive to add a floppy to a
+# different index, you get both of them. However, as soon as you use any
+# '-device floppy', even to a different slot, the default drive is disabled.
+
+echo
+echo
+echo === Default ===
+
+check_floppy_qtree
+
+echo
+echo
+echo === Using -fda/-fdb options ===
+
+check_floppy_qtree -fda "$TEST_IMG"
+check_floppy_qtree -fdb "$TEST_IMG"
+check_floppy_qtree -fda "$TEST_IMG" -fdb "$TEST_IMG"
+
+
+echo
+echo
+echo === Using -drive options ===
+
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG"
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG",index=1
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive if=floppy,file="$TEST_IMG",index=1
+
+echo
+echo
+echo === Using -drive if=none and -global ===
+
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -global isa-fdc.driveA=none0
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -global isa-fdc.driveB=none0
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveA=none0 -global isa-fdc.driveB=none1
+
+echo
+echo
+echo === Using -drive if=none and -device ===
+
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=1
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -device floppy,drive=none0 -device floppy,drive=none1,unit=1
+
+echo
+echo
+echo === Mixing -fdX and -global ===
+
+# Working
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global isa-fdc.driveB=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global isa-fdc.driveA=none0
+
+# Conflicting (-fdX wins)
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global isa-fdc.driveA=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -global isa-fdc.driveB=none0
+
+echo
+echo
+echo === Mixing -fdX and -device ===
+
+# Working
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=1
+
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=0
+
+# Conflicting
+check_floppy_qtree -fda "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=0
+check_floppy_qtree -fdb "$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=1
+
+echo
+echo
+echo === Mixing -drive and -device ===
+
+# Working
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=1
+
+# Conflicting
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,unit=0
+
+echo
+echo
+echo === Mixing -global and -device ===
+
+# Working
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveA=none0 -device floppy,drive=none1
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveA=none0 -device floppy,drive=none1,unit=1
+
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveB=none0 -device floppy,drive=none1
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveB=none0 -device floppy,drive=none1,unit=0
+
+# Conflicting
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveA=none0 -device floppy,drive=none1,unit=0
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveB=none0 -device floppy,drive=none1,unit=1
+
+echo
+echo
+echo === Too many floppy drives ===
+
+# Working
+check_floppy_qtree -drive if=floppy,file="$TEST_IMG" \
+                   -drive if=none,file="$TEST_IMG" \
+                   -drive if=none,file="$TEST_IMG" \
+                   -global isa-fdc.driveB=none0 \
+                   -device floppy,drive=none1
+
+echo
+echo
+echo === Creating an empty drive with anonymous BB ===
+
+check_floppy_qtree -device floppy
+check_floppy_qtree -device floppy,drive-type=120
+check_floppy_qtree -device floppy,drive-type=144
+check_floppy_qtree -device floppy,drive-type=288
+
+echo
+echo
+echo === Try passing different drive size with image ===
+
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,drive-type=120
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,drive-type=288
+
+echo
+echo
+echo === Try passing different block sizes ===
+
+# Explicitly setting the default is okay
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,logical_block_size=512
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,physical_block_size=512
+
+# Changing it is not
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,logical_block_size=4096
+check_floppy_qtree -drive if=none,file="$TEST_IMG" -device floppy,drive=none0,physical_block_size=1024
+
+echo
+echo
+echo === Writethrough caching ===
+
+check_cache_mode -device floppy,drive=none0
+check_cache_mode -device floppy,drive=none0,write-cache=on
+check_cache_mode -device floppy,drive=none0,write-cache=off
+
+# success, all done
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/172.out b/tests/qemu-iotests/172.out
new file mode 100644
index 0000000..b26fb2d
--- /dev/null
+++ b/tests/qemu-iotests/172.out
@@ -0,0 +1,1205 @@
+QA output created by 172
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=737280
+
+
+=== Default ===
+
+Testing:
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+
+=== Using -fda/-fdb options ===
+
+Testing: -fda TEST_DIR/t.qcow2
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fdb TEST_DIR/t.qcow2
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+Testing: -fda TEST_DIR/t.qcow2 -fdb TEST_DIR/t.qcow2
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+
+=== Using -drive options ===
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=floppy,file=TEST_DIR/t.qcow2,index=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+
+=== Using -drive if=none and -global ===
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0 -global isa-fdc.driveB=none1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+
+=== Using -drive if=none and -device ===
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0 -device floppy,drive=none1,unit=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+
+=== Mixing -fdX and -global ===
+
+Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+
+=== Mixing -fdX and -device ===
+
+Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "floppy1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -fda TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=0
+qemu: -device floppy,drive=none0,unit=0: Floppy unit 0 is in use
+qemu: -device floppy,drive=none0,unit=0: Device initialization failed.
+
+Testing: -fdb TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
+qemu: -device floppy,drive=none0,unit=1: Floppy unit 1 is in use
+qemu: -device floppy,drive=none0,unit=1: Device initialization failed.
+
+
+=== Mixing -drive and -device ===
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "floppy0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,unit=0
+qemu: -device floppy,drive=none0,unit=0: Floppy unit 0 is in use
+qemu: -device floppy,drive=none0,unit=0: Device initialization failed.
+
+
+=== Mixing -global and -device ===
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0 -device floppy,drive=none1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0 -device floppy,drive=none1,unit=1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0 -device floppy,drive=none1
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0 -device floppy,drive=none1,unit=0
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none1"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+              dev: floppy, id ""
+                unit = 1 (0x1)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveA=none0 -device floppy,drive=none1,unit=0
+qemu: -device floppy,drive=none1,unit=0: Floppy unit 0 is in use
+qemu: -device floppy,drive=none1,unit=0: Device initialization failed.
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0 -device floppy,drive=none1,unit=1
+qemu: -device floppy,drive=none1,unit=1: Floppy unit 1 is in use
+qemu: -device floppy,drive=none1,unit=1: Device initialization failed.
+
+
+=== Too many floppy drives ===
+
+Testing: -drive if=floppy,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -drive if=none,file=TEST_DIR/t.qcow2 -global isa-fdc.driveB=none0 -device floppy,drive=none1
+qemu: -device floppy,drive=none1: Can't create floppy unit 2, bus supports only 2 units
+qemu: -device floppy,drive=none1: Device initialization failed.
+
+
+=== Creating an empty drive with anonymous BB ===
+
+Testing: -device floppy
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = ""
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+Testing: -device floppy,drive-type=120
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = ""
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "120"
+          dev:
+
+Testing: -device floppy,drive-type=144
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = ""
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -device floppy,drive-type=288
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = ""
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+
+=== Try passing different drive size with image ===
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-type=120
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "120"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,drive-type=288
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "288"
+          dev:
+
+
+=== Try passing different block sizes ===
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical_block_size=512
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physical_block_size=512
+
+          dev: isa-fdc, id ""
+            iobase = 1008 (0x3f0)
+            irq = 6 (0x6)
+            dma = 2 (0x2)
+            driveA = ""
+            driveB = ""
+            check_media_rate = true
+            fdtypeA = "auto"
+            fdtypeB = "auto"
+            fallback = "288"
+            isa irq 6
+            bus: floppy.0
+              type Floppy
+              dev: floppy, id ""
+                unit = 0 (0x0)
+                drive = "none0"
+                logical_block_size = 512 (0x200)
+                physical_block_size = 512 (0x200)
+                min_io_size = 0 (0x0)
+                opt_io_size = 0 (0x0)
+                discard_granularity = 4294967295 (0xffffffff)
+                write-cache = "auto"
+                drive-type = "144"
+          dev:
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,logical_block_size=4096
+qemu: -device floppy,drive=none0,logical_block_size=4096: Physical and logical block size must be 512 for floppy
+qemu: -device floppy,drive=none0,logical_block_size=4096: Device initialization failed.
+
+Testing: -drive if=none,file=TEST_DIR/t.qcow2 -device floppy,drive=none0,physical_block_size=1024
+qemu: -device floppy,drive=none0,physical_block_size=1024: Physical and logical block size must be 512 for floppy
+qemu: -device floppy,drive=none0,physical_block_size=1024: Device initialization failed.
+
+
+=== Writethrough caching ===
+    Cache mode:       writeback
+    Cache mode:       writeback
+    Cache mode:       writethrough
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 7eb1770..dbc9ba9 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -162,3 +162,4 @@
 160 rw auto quick
 162 auto quick
 170 rw auto quick
+172 auto
-- 
1.8.3.1

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives
  2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
                   ` (3 preceding siblings ...)
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 4/4] qemu-iotests: Test creating floppy drives Kevin Wolf
@ 2016-10-14 11:11 ` Kevin Wolf
  4 siblings, 0 replies; 10+ messages in thread
From: Kevin Wolf @ 2016-10-14 11:11 UTC (permalink / raw)
  To: qemu-block; +Cc: jsnow, armbru, mreitz, qemu-devel

Am 30.09.2016 um 21:39 hat Kevin Wolf geschrieben:
> We have been complaining for a long time about how the floppy controller and
> floppy drives are combined in a single qdev device and how this makes the
> device awkward to work with because it behaves different from all other block
> devices.
> 
> The latest reason to complain was when I noticed that using qdev device names
> in QMP commands (e.g. for media change) doesn't really work when only the
> controller is a qdev device, but the drives aren't.
> 
> So I decided to have a go at it, and this is the result.
> 
> It doesn't actually change any of the inner workings of the floppy controller,
> but it wires things up differently on the qdev layer so that a floppy
> controller now exposes a bus on which the floppy drives sit. This results in a
> structure that is similar to IDE where the actual drive state is still in the
> controller and the qdev device basically just contains the qdev properties -
> not pretty, but quite workable.
> 
> The commit message of patch 3 explains how to use it. In short, there is a
> '-device floppy' now and it does what you would expect if you ever used ide-cd.
> 
> The other problem is old command lines, especially those using things like
> '-global isa-fdc,driveA=...'. In order to keep them working, we need to forward
> the property to an internally created floppy drive device. This is a bit like
> usb-storage, which we know is ugly, but works well enough in practice. The good
> news here is that in contrast to usb-storage, the floppy controller only does
> the forwarding for legacy configurations; as soon as you start using '-device
> floppy', it doesn't happen any more.
> 
> So as you may have expected, this conversion doesn't result in a perfect
> device, but I think it's definitely an improvement over the old state. I hope
> you like it despite the warts. :-)
> 
> v2:
> - Added patch 4 (qemu-iotests case for floppy config on the command line)
> - Patch 2: Create a floppy device only if a BlockBackend exists instead of
>   always creating two of them
> - Patch 2: Initialise drive->fdctrl even if no drive is attached, it is
>   accessed anyway during migration
> - Patch 3: Keep 'type' qdev property and FDrive->drive in sync
> - Patch 3: Removed if with condition that is always true

ping (freeze coming closer...)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus Kevin Wolf
@ 2016-10-14 21:32   ` John Snow
  0 siblings, 0 replies; 10+ messages in thread
From: John Snow @ 2016-10-14 21:32 UTC (permalink / raw)
  To: Kevin Wolf, qemu-block; +Cc: qemu-devel, armbru, mreitz



On 09/30/2016 03:39 PM, Kevin Wolf wrote:
> This adds a qbus to the floppy controller that should contain the floppy
> drives eventually. At the moment it just exists and is empty.
>

Not unlike myself.

> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  hw/block/fdc.c | 40 +++++++++++++++++++++++++++++++++++-----
>  1 file changed, 35 insertions(+), 5 deletions(-)
>
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index b79873a..a3afb62 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -52,6 +52,33 @@
>          }                                                       \
>      } while (0)
>
> +
> +/********************************************************/
> +/* qdev floppy bus                                      */
> +
> +#define TYPE_FLOPPY_BUS "Floppy"
> +#define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
> +
> +typedef struct FDCtrl FDCtrl;
> +
> +typedef struct FloppyBus {
> +    BusState bus;
> +    FDCtrl *fdc;
> +} FloppyBus;
> +
> +static const TypeInfo floppy_bus_info = {
> +    .name = TYPE_FLOPPY_BUS,
> +    .parent = TYPE_BUS,
> +    .instance_size = sizeof(FloppyBus),
> +};
> +
> +static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
> +{
> +    qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
> +    bus->fdc = fdc;
> +}
> +
> +
>  /********************************************************/
>  /* Floppy drive emulation                               */
>
> @@ -148,8 +175,6 @@ static FDriveSize drive_size(FloppyDriveType drive)
>  #define FD_SECTOR_SC           2   /* Sector size code */
>  #define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
>
> -typedef struct FDCtrl FDCtrl;
> -
>  /* Floppy disk drive emulation */
>  typedef enum FDiskFlags {
>      FDISK_DBL_SIDES  = 0x01,
> @@ -684,6 +709,7 @@ struct FDCtrl {
>      /* Power down config (also with status regB access mode */
>      uint8_t pwrd;
>      /* Floppy drives */
> +    FloppyBus bus;
>      uint8_t num_floppies;
>      FDrive drives[MAX_FD];
>      int reset_sensei;
> @@ -2442,7 +2468,8 @@ void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
>      *fdc_tc = qdev_get_gpio_in(dev, 0);
>  }
>
> -static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
> +static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
> +                                  Error **errp)
>  {
>      int i, j;
>      static int command_tables_inited = 0;
> @@ -2480,6 +2507,8 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
>          k->register_channel(fdctrl->dma, fdctrl->dma_chann,
>                              &fdctrl_transfer_handler, fdctrl);
>      }
> +
> +    floppy_bus_create(fdctrl, &fdctrl->bus, dev);
>      fdctrl_connect_drives(fdctrl, errp);
>  }
>
> @@ -2508,7 +2537,7 @@ static void isabus_fdc_realize(DeviceState *dev, Error **errp)
>      }
>
>      qdev_set_legacy_instance_id(dev, isa->iobase, 2);
> -    fdctrl_realize_common(fdctrl, &err);
> +    fdctrl_realize_common(dev, fdctrl, &err);
>      if (err != NULL) {
>          error_propagate(errp, err);
>          return;
> @@ -2559,7 +2588,7 @@ static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
>      FDCtrlSysBus *sys = SYSBUS_FDC(dev);
>      FDCtrl *fdctrl = &sys->state;
>
> -    fdctrl_realize_common(fdctrl, errp);
> +    fdctrl_realize_common(dev, fdctrl, errp);
>  }
>
>  FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
> @@ -2744,6 +2773,7 @@ static void fdc_register_types(void)
>      type_register_static(&sysbus_fdc_type_info);
>      type_register_static(&sysbus_fdc_info);
>      type_register_static(&sun4m_fdc_info);
> +    type_register_static(&floppy_bus_info);
>  }
>
>  type_init(fdc_register_types)
>

Reviewed-by: John Snow <jsnow@redhat.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev Kevin Wolf
@ 2016-10-14 22:09   ` John Snow
  0 siblings, 0 replies; 10+ messages in thread
From: John Snow @ 2016-10-14 22:09 UTC (permalink / raw)
  To: Kevin Wolf, qemu-block; +Cc: qemu-devel, armbru, mreitz



On 09/30/2016 03:39 PM, Kevin Wolf wrote:
> Floppy controllers automatically create two floppy drive devices in qdev
> now. (They always created two drives, but managed them only internally.)
>

Is this commit message out-of-phase now?

> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  hw/block/fdc.c | 151 +++++++++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 120 insertions(+), 31 deletions(-)
>
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index a3afb62..5aa8e52 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -60,6 +60,8 @@
>  #define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
>
>  typedef struct FDCtrl FDCtrl;
> +typedef struct FDrive FDrive;
> +static FDrive *get_drv(FDCtrl *fdctrl, int unit);
>
>  typedef struct FloppyBus {
>      BusState bus;
> @@ -180,7 +182,7 @@ typedef enum FDiskFlags {
>      FDISK_DBL_SIDES  = 0x01,
>  } FDiskFlags;
>
> -typedef struct FDrive {
> +struct FDrive {
>      FDCtrl *fdctrl;
>      BlockBackend *blk;
>      /* Drive status */
> @@ -201,7 +203,7 @@ typedef struct FDrive {
>      uint8_t media_rate;       /* Data rate of medium    */
>
>      bool media_validated;     /* Have we validated the media? */
> -} FDrive;
> +};
>
>
>  static FloppyDriveType get_fallback_drive_type(FDrive *drv);
> @@ -466,6 +468,100 @@ static void fd_revalidate(FDrive *drv)
>      }
>  }
>
> +static void fd_change_cb(void *opaque, bool load)
> +{
> +    FDrive *drive = opaque;
> +
> +    drive->media_changed = 1;
> +    drive->media_validated = false;
> +    fd_revalidate(drive);
> +}
> +
> +static const BlockDevOps fd_block_ops = {
> +    .change_media_cb = fd_change_cb,
> +};
> +
> +
> +#define TYPE_FLOPPY_DRIVE "floppy"
> +#define FLOPPY_DRIVE(obj) \
> +     OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
> +
> +typedef struct FloppyDrive {
> +    DeviceState qdev;
> +    uint32_t    unit;
> +} FloppyDrive;
> +
> +static Property floppy_drive_properties[] = {
> +    DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
> +    DEFINE_PROP_END_OF_LIST(),
> +};
> +
> +static int floppy_drive_init(DeviceState *qdev)
> +{
> +    FloppyDrive *dev = FLOPPY_DRIVE(qdev);
> +    FloppyBus *bus = DO_UPCAST(FloppyBus, bus, dev->qdev.parent_bus);
> +    FDrive *drive;
> +
> +    if (dev->unit == -1) {
> +        for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
> +            drive = get_drv(bus->fdc, dev->unit);
> +            if (!drive->blk) {
> +                break;
> +            }
> +        }
> +    }
> +
> +    if (dev->unit >= MAX_FD) {
> +        error_report("Can't create floppy unit %d, bus supports only %d units",
> +                     dev->unit, MAX_FD);
> +        return -1;
> +    }
> +
> +    /* TODO Check whether unit is in use */
> +

Dear whoever cares about FDC: Save me from the merciless void ...!

(I see you remove this in the next patch, but don't make my heart jump 
like that!)

> +    drive = get_drv(bus->fdc, dev->unit);
> +
> +    if (drive->blk) {
> +        if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
> +            error_report("fdc doesn't support drive option werror");
> +            return -1;
> +        }
> +        if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
> +            error_report("fdc doesn't support drive option rerror");
> +            return -1;
> +        }
> +    } else {
> +        /* Anonymous BlockBackend for an empty drive */
> +        drive->blk = blk_new();
> +    }
> +
> +    fd_init(drive);
> +    if (drive->blk) {
> +        blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
> +        pick_drive_type(drive);
> +    }
> +    fd_revalidate(drive);
> +
> +    return 0;
> +}
> +
> +static void floppy_drive_class_init(ObjectClass *klass, void *data)
> +{
> +    DeviceClass *k = DEVICE_CLASS(klass);
> +    k->init = floppy_drive_init;
> +    set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
> +    k->bus_type = TYPE_FLOPPY_BUS;
> +    k->props = floppy_drive_properties;
> +    k->desc = "virtual floppy drive";
> +}
> +
> +static const TypeInfo floppy_drive_info = {
> +    .name = TYPE_FLOPPY_DRIVE,
> +    .parent = TYPE_DEVICE,
> +    .instance_size = sizeof(FloppyDrive),
> +    .class_init = floppy_drive_class_init,
> +};
> +
>  /********************************************************/
>  /* Intel 82078 floppy disk controller emulation          */
>
> @@ -1185,9 +1281,9 @@ static inline FDrive *drv3(FDCtrl *fdctrl)
>  }
>  #endif
>
> -static FDrive *get_cur_drv(FDCtrl *fdctrl)
> +static FDrive *get_drv(FDCtrl *fdctrl, int unit)
>  {
> -    switch (fdctrl->cur_drv) {
> +    switch (unit) {
>          case 0: return drv0(fdctrl);
>          case 1: return drv1(fdctrl);
>  #if MAX_FD == 4
> @@ -1198,6 +1294,11 @@ static FDrive *get_cur_drv(FDCtrl *fdctrl)
>      }
>  }
>
> +static FDrive *get_cur_drv(FDCtrl *fdctrl)
> +{
> +    return get_drv(fdctrl, fdctrl->cur_drv);
> +}
> +
>  /* Status A register : 0x00 (read-only) */
>  static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
>  {
> @@ -2357,46 +2458,33 @@ static void fdctrl_result_timer(void *opaque)
>      }
>  }
>
> -static void fdctrl_change_cb(void *opaque, bool load)
> -{
> -    FDrive *drive = opaque;
> -
> -    drive->media_changed = 1;
> -    drive->media_validated = false;
> -    fd_revalidate(drive);
> -}
> -
> -static const BlockDevOps fdctrl_block_ops = {
> -    .change_media_cb = fdctrl_change_cb,
> -};
> -
>  /* Init functions */
>  static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
>  {
>      unsigned int i;
>      FDrive *drive;
> +    DeviceState *dev;
> +    Error *local_err = NULL;
>
>      for (i = 0; i < MAX_FD; i++) {
>          drive = &fdctrl->drives[i];
>          drive->fdctrl = fdctrl;
>
> -        if (drive->blk) {
> -            if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
> -                error_setg(errp, "fdc doesn't support drive option werror");
> -                return;
> -            }
> -            if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
> -                error_setg(errp, "fdc doesn't support drive option rerror");
> -                return;
> -            }
> +        /* If the drive is not present, we skip creating the qdev device, but
> +         * still have to initialise the controller. */
> +        if (!fdctrl->drives[i].blk) {
> +            fd_init(drive);
> +            fd_revalidate(drive);
> +            continue;
>          }
>
> -        fd_init(drive);
> -        if (drive->blk) {
> -            blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive);
> -            pick_drive_type(drive);
> +        dev = qdev_create(&fdctrl->bus.bus, "floppy");
> +        qdev_prop_set_uint32(dev, "unit", i);
> +        object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            return;
>          }
> -        fd_revalidate(drive);
>      }
>  }
>
> @@ -2774,6 +2862,7 @@ static void fdc_register_types(void)
>      type_register_static(&sysbus_fdc_info);
>      type_register_static(&sun4m_fdc_info);
>      type_register_static(&floppy_bus_info);
> +    type_register_static(&floppy_drive_info);
>  }
>
>  type_init(fdc_register_types)
>

Reviewed-by: John Snow <jsnow@redhat.com>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive
  2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive Kevin Wolf
@ 2016-10-14 22:32   ` John Snow
  2016-10-17  8:53     ` Kevin Wolf
  0 siblings, 1 reply; 10+ messages in thread
From: John Snow @ 2016-10-14 22:32 UTC (permalink / raw)
  To: Kevin Wolf, qemu-block; +Cc: qemu-devel, armbru, mreitz



On 09/30/2016 03:39 PM, Kevin Wolf wrote:
> This makes the FloppyDrive qdev object actually useful: Now that it has
> all properties that don't belong to the controller, you can actually
> use '-device floppy' and get a working result.
>
> Command line semantics is consistent with CD-ROM drives: By default you
> get a single empty floppy drive. You can override it with -drive and
> using the same index, but if you use -drive to add a floppy to a
> different index, you get both of them. However, as soon as you use any
> '-device floppy', even to a different slot, the default drive is
> disabled.
>
> Using '-device floppy' without specifying the unit will choose the first
> free slot on the controller.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>  hw/block/fdc.c | 112 ++++++++++++++++++++++++++++++++++++++++++---------------
>  vl.c           |   1 +
>  2 files changed, 85 insertions(+), 28 deletions(-)
>
> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> index 5aa8e52..00c0ec6 100644
> --- a/hw/block/fdc.c
> +++ b/hw/block/fdc.c
> @@ -35,6 +35,7 @@
>  #include "qemu/timer.h"
>  #include "hw/isa/isa.h"
>  #include "hw/sysbus.h"
> +#include "hw/block/block.h"
>  #include "sysemu/block-backend.h"
>  #include "sysemu/blockdev.h"
>  #include "sysemu/sysemu.h"
> @@ -487,12 +488,18 @@ static const BlockDevOps fd_block_ops = {
>       OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
>
>  typedef struct FloppyDrive {
> -    DeviceState qdev;
> -    uint32_t    unit;
> +    DeviceState     qdev;
> +    uint32_t        unit;
> +    BlockConf       conf;
> +    FloppyDriveType type;
>  } FloppyDrive;
>
>  static Property floppy_drive_properties[] = {
>      DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
> +    DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
> +    DEFINE_PROP_DEFAULT("drive-type", FloppyDrive, type,
> +                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> +                        FloppyDriveType),
>      DEFINE_PROP_END_OF_LIST(),
>  };
>
> @@ -501,6 +508,7 @@ static int floppy_drive_init(DeviceState *qdev)
>      FloppyDrive *dev = FLOPPY_DRIVE(qdev);
>      FloppyBus *bus = DO_UPCAST(FloppyBus, bus, dev->qdev.parent_bus);
>      FDrive *drive;
> +    int ret;
>
>      if (dev->unit == -1) {
>          for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
> @@ -517,29 +525,57 @@ static int floppy_drive_init(DeviceState *qdev)
>          return -1;
>      }
>
> -    /* TODO Check whether unit is in use */
> -
>      drive = get_drv(bus->fdc, dev->unit);
> -
>      if (drive->blk) {
> -        if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
> -            error_report("fdc doesn't support drive option werror");
> -            return -1;
> -        }
> -        if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
> -            error_report("fdc doesn't support drive option rerror");
> -            return -1;
> -        }
> -    } else {
> +        error_report("Floppy unit %d is in use", dev->unit);
> +        return -1;
> +    }
> +
> +    if (!dev->conf.blk) {
>          /* Anonymous BlockBackend for an empty drive */
> -        drive->blk = blk_new();
> +        dev->conf.blk = blk_new();
> +        ret = blk_attach_dev(dev->conf.blk, dev);

Missing a 'q' here:                           ^

> +        assert(ret == 0);
>      }
>
> -    fd_init(drive);
> -    if (drive->blk) {
> -        blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
> -        pick_drive_type(drive);
> +    blkconf_blocksizes(&dev->conf);
> +    if (dev->conf.logical_block_size != 512 ||
> +        dev->conf.physical_block_size != 512)
> +    {
> +        error_report("Physical and logical block size must be 512 for floppy");
> +        return -1;
> +    }
> +
> +    /* rerror/werror aren't supported by fdc and therefore not even registered
> +     * with qdev. So set the defaults manually before they are used in
> +     * blkconf_apply_backend_options(). */
> +    dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
> +    dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
> +    blkconf_apply_backend_options(&dev->conf);
> +
> +    /* 'enospc' is the default for -drive, 'report' is what blk_new() gives us
> +     * for empty drives. */
> +    if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC &&
> +        blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) {
> +        error_report("fdc doesn't support drive option werror");
> +        return -1;
>      }
> +    if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
> +        error_report("fdc doesn't support drive option rerror");
> +        return -1;
> +    }
> +
> +    drive->blk = dev->conf.blk;
> +    drive->fdctrl = bus->fdc;
> +
> +    fd_init(drive);
> +    blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
> +
> +    /* Keep 'type' qdev property and FDrive->drive in sync */
> +    drive->drive = dev->type;
> +    pick_drive_type(drive);
> +    dev->type = drive->drive;
> +
>      fd_revalidate(drive);
>
>      return 0;
> @@ -808,6 +844,10 @@ struct FDCtrl {
>      FloppyBus bus;
>      uint8_t num_floppies;
>      FDrive drives[MAX_FD];
> +    struct {
> +        BlockBackend *blk;
> +        FloppyDriveType type;
> +    } qdev_for_drives[MAX_FD];
>      int reset_sensei;
>      uint32_t check_media_rate;
>      FloppyDriveType fallback; /* type=auto failure fallback */
> @@ -2459,11 +2499,13 @@ static void fdctrl_result_timer(void *opaque)
>  }
>
>  /* Init functions */
> -static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
> +static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp,
> +                                  DeviceState *fdc_dev)
>  {
>      unsigned int i;
>      FDrive *drive;
>      DeviceState *dev;
> +    BlockBackend *blk;
>      Error *local_err = NULL;
>
>      for (i = 0; i < MAX_FD; i++) {
> @@ -2472,7 +2514,8 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
>
>          /* If the drive is not present, we skip creating the qdev device, but
>           * still have to initialise the controller. */
> -        if (!fdctrl->drives[i].blk) {
> +        blk = fdctrl->qdev_for_drives[i].blk;
> +        if (!blk) {
>              fd_init(drive);
>              fd_revalidate(drive);
>              continue;
> @@ -2480,6 +2523,19 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
>
>          dev = qdev_create(&fdctrl->bus.bus, "floppy");
>          qdev_prop_set_uint32(dev, "unit", i);
> +        qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
> +
> +        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);
> +        blk_unref(blk);
> +
> +        if (local_err) {
> +            error_propagate(errp, local_err);
> +            return;
> +        }
> +
>          object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
>          if (local_err) {
>              error_propagate(errp, local_err);
> @@ -2597,7 +2653,7 @@ static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
>      }
>
>      floppy_bus_create(fdctrl, &fdctrl->bus, dev);
> -    fdctrl_connect_drives(fdctrl, errp);
> +    fdctrl_connect_drives(fdctrl, errp, dev);
>  }
>
>  static const MemoryRegionPortio fdc_portio_list[] = {
> @@ -2723,14 +2779,14 @@ static Property isa_fdc_properties[] = {
>      DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
>      DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
>      DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
> -    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.drives[0].blk),
> -    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
> +    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.qdev_for_drives[0].blk),
> +    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
>      DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
>                      0, true),
> -    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.drives[0].drive,
> +    DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
>                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
>                          FloppyDriveType),
> -    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.drives[1].drive,
> +    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
>                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
>                          FloppyDriveType),
>      DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
> @@ -2782,8 +2838,8 @@ static const VMStateDescription vmstate_sysbus_fdc ={
>  };
>
>  static Property sysbus_fdc_properties[] = {
> -    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
> -    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
> +    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
> +    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
>      DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
>                          FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
>                          FloppyDriveType),

^ Does sysbus' type property not need updating ...?

> diff --git a/vl.c b/vl.c
> index ab0349b..7486f33 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -218,6 +218,7 @@ static struct {
>      { .driver = "isa-serial",           .flag = &default_serial    },
>      { .driver = "isa-parallel",         .flag = &default_parallel  },
>      { .driver = "isa-fdc",              .flag = &default_floppy    },
> +    { .driver = "floppy",               .flag = &default_floppy    },
>      { .driver = "ide-cd",               .flag = &default_cdrom     },
>      { .driver = "ide-hd",               .flag = &default_cdrom     },
>      { .driver = "ide-drive",            .flag = &default_cdrom     },
>

wew... Floppy drives, man. Fun.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive
  2016-10-14 22:32   ` John Snow
@ 2016-10-17  8:53     ` Kevin Wolf
  0 siblings, 0 replies; 10+ messages in thread
From: Kevin Wolf @ 2016-10-17  8:53 UTC (permalink / raw)
  To: John Snow; +Cc: qemu-block, qemu-devel, armbru, mreitz

Am 15.10.2016 um 00:32 hat John Snow geschrieben:
> On 09/30/2016 03:39 PM, Kevin Wolf wrote:
> >This makes the FloppyDrive qdev object actually useful: Now that it has
> >all properties that don't belong to the controller, you can actually
> >use '-device floppy' and get a working result.
> >
> >Command line semantics is consistent with CD-ROM drives: By default you
> >get a single empty floppy drive. You can override it with -drive and
> >using the same index, but if you use -drive to add a floppy to a
> >different index, you get both of them. However, as soon as you use any
> >'-device floppy', even to a different slot, the default drive is
> >disabled.
> >
> >Using '-device floppy' without specifying the unit will choose the first
> >free slot on the controller.
> >
> >Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> >---
> > hw/block/fdc.c | 112 ++++++++++++++++++++++++++++++++++++++++++---------------
> > vl.c           |   1 +
> > 2 files changed, 85 insertions(+), 28 deletions(-)
> >
> >diff --git a/hw/block/fdc.c b/hw/block/fdc.c
> >index 5aa8e52..00c0ec6 100644
> >--- a/hw/block/fdc.c
> >+++ b/hw/block/fdc.c
> >@@ -35,6 +35,7 @@
> > #include "qemu/timer.h"
> > #include "hw/isa/isa.h"
> > #include "hw/sysbus.h"
> >+#include "hw/block/block.h"
> > #include "sysemu/block-backend.h"
> > #include "sysemu/blockdev.h"
> > #include "sysemu/sysemu.h"
> >@@ -487,12 +488,18 @@ static const BlockDevOps fd_block_ops = {
> >      OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
> >
> > typedef struct FloppyDrive {
> >-    DeviceState qdev;
> >-    uint32_t    unit;
> >+    DeviceState     qdev;
> >+    uint32_t        unit;
> >+    BlockConf       conf;
> >+    FloppyDriveType type;
> > } FloppyDrive;
> >
> > static Property floppy_drive_properties[] = {
> >     DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
> >+    DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
> >+    DEFINE_PROP_DEFAULT("drive-type", FloppyDrive, type,
> >+                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> >+                        FloppyDriveType),
> >     DEFINE_PROP_END_OF_LIST(),
> > };
> >
> >@@ -501,6 +508,7 @@ static int floppy_drive_init(DeviceState *qdev)
> >     FloppyDrive *dev = FLOPPY_DRIVE(qdev);
> >     FloppyBus *bus = DO_UPCAST(FloppyBus, bus, dev->qdev.parent_bus);
> >     FDrive *drive;
> >+    int ret;
> >
> >     if (dev->unit == -1) {
> >         for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
> >@@ -517,29 +525,57 @@ static int floppy_drive_init(DeviceState *qdev)
> >         return -1;
> >     }
> >
> >-    /* TODO Check whether unit is in use */
> >-
> >     drive = get_drv(bus->fdc, dev->unit);
> >-
> >     if (drive->blk) {
> >-        if (blk_get_on_error(drive->blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC) {
> >-            error_report("fdc doesn't support drive option werror");
> >-            return -1;
> >-        }
> >-        if (blk_get_on_error(drive->blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
> >-            error_report("fdc doesn't support drive option rerror");
> >-            return -1;
> >-        }
> >-    } else {
> >+        error_report("Floppy unit %d is in use", dev->unit);
> >+        return -1;
> >+    }
> >+
> >+    if (!dev->conf.blk) {
> >         /* Anonymous BlockBackend for an empty drive */
> >-        drive->blk = blk_new();
> >+        dev->conf.blk = blk_new();
> >+        ret = blk_attach_dev(dev->conf.blk, dev);
> 
> Missing a 'q' here:                           ^

Yes. It has the same value, but after my last pull request we need a
DeviceState* here indeed rather than a void*.

> >@@ -2782,8 +2838,8 @@ static const VMStateDescription vmstate_sysbus_fdc ={
> > };
> >
> > static Property sysbus_fdc_properties[] = {
> >-    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
> >-    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
> >+    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
> >+    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
> >     DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
> >                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
> >                         FloppyDriveType),
> 
> ^ Does sysbus' type property not need updating ...?

Doing half of the properties here felt like a good transitional step
from fully converting the PC device to completely ignoring Sun.

Well, I guess, I should fix that...

Kevin

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2016-10-17  8:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-30 19:39 [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf
2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 1/4] fdc: Add a floppy qbus Kevin Wolf
2016-10-14 21:32   ` John Snow
2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 2/4] fdc: Add a floppy drive qdev Kevin Wolf
2016-10-14 22:09   ` John Snow
2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 3/4] fdc: Move qdev properties to FloppyDrive Kevin Wolf
2016-10-14 22:32   ` John Snow
2016-10-17  8:53     ` Kevin Wolf
2016-09-30 19:39 ` [Qemu-devel] [PATCH v2 4/4] qemu-iotests: Test creating floppy drives Kevin Wolf
2016-10-14 11:11 ` [Qemu-devel] [PATCH v2 0/4] fdc: Use separate qdev device for drives Kevin Wolf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.