From patchwork Mon Sep 5 15:43:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 9314281 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5131C607D3 for ; Mon, 5 Sep 2016 15:45:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 41C662878E for ; Mon, 5 Sep 2016 15:45:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3547128AAA; Mon, 5 Sep 2016 15:45:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 865DB2878E for ; Mon, 5 Sep 2016 15:45:01 +0000 (UTC) Received: from localhost ([::1]:55473 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgw4y-0003SL-ML for patchwork-qemu-devel@patchwork.kernel.org; Mon, 05 Sep 2016 11:45:00 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57043) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgw4Q-0003QD-M2 for qemu-devel@nongnu.org; Mon, 05 Sep 2016 11:44:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bgw4P-0001eT-2a for qemu-devel@nongnu.org; Mon, 05 Sep 2016 11:44:26 -0400 Received: from mx1.redhat.com ([209.132.183.28]:51564) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bgw49-0001aJ-Rb; Mon, 05 Sep 2016 11:44:10 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 69F4183F44; Mon, 5 Sep 2016 15:44:09 +0000 (UTC) Received: from noname.redhat.com (ovpn-116-62.ams2.redhat.com [10.36.116.62]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u85Fi2oW005419; Mon, 5 Sep 2016 11:44:07 -0400 From: Kevin Wolf To: qemu-block@nongnu.org Date: Mon, 5 Sep 2016 17:43:56 +0200 Message-Id: <1473090236-14793-4-git-send-email-kwolf@redhat.com> In-Reply-To: <1473090236-14793-1-git-send-email-kwolf@redhat.com> References: <1473090236-14793-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 05 Sep 2016 15:44:09 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 3/3] fdc: Move qdev properties to FloppyDrive X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: kwolf@redhat.com, qemu-devel@nongnu.org, jsnow@redhat.com, armbru@redhat.com, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- hw/block/fdc.c | 105 ++++++++++++++++++++++++++++++++++++++++++++------------- vl.c | 1 + 2 files changed, 82 insertions(+), 24 deletions(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index d1e2339..949c16a 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,25 +525,49 @@ static int floppy_drive_init(DeviceState *qdev) return -1; } - /* TODO Check whether unit is in use */ - drive = get_drv(bus->fdc, dev->unit); - drive->fdctrl = bus->fdc; - 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); + } + + 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); if (drive->blk) { blk_set_dev_ops(drive->blk, &fd_block_ops, drive); @@ -809,6 +841,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,15 +2495,36 @@ 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; DeviceState *dev; Error *local_err = NULL; for (i = 0; i < MAX_FD; i++) { + BlockBackend *blk = fdctrl->qdev_for_drives[i].blk; + if (!blk) { + continue; + } + 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); + + if (blk) { + 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); @@ -2585,7 +2642,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[] = { @@ -2710,14 +2767,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, @@ -2769,8 +2826,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 b3c80d5..f72ded6 100644 --- a/vl.c +++ b/vl.c @@ -216,6 +216,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 },