Commit fff4687b authored by John Snow's avatar John Snow
Browse files

fdc: add drive type option



This patch adds a new explicit Floppy Drive Type option. The existing
behavior in QEMU is to automatically guess a drive type based on the
media inserted, or if a diskette is not present, arbitrarily assign one.

This behavior can be described as "auto." This patch adds the option
to pick an explicit behavior: 120, 144, 288 or none. The new "auto"
option is intended to mimic current behavior, while the other types
pick one explicitly.

Set the type given by the CLI during fd_init. If the type remains the
default (auto), we'll attempt to scan an inserted diskette if present
to determine a type. If auto is selected but no diskette is present,
we fall back to a predetermined default (currently 1.44MB to match
legacy QEMU behavior.)

Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarJohn Snow <jsnow@redhat.com>
Message-id: 1453495865-9649-9-git-send-email-jsnow@redhat.com
parent a73275dd
Loading
Loading
Loading
Loading
+23 −3
Original line number Diff line number Diff line
@@ -160,7 +160,6 @@ static FloppyDriveType get_fallback_drive_type(FDrive *drv);
static void fd_init(FDrive *drv)
{
    /* Drive */
    drv->drive = FLOPPY_DRIVE_TYPE_NONE;
    drv->perpendicular = 0;
    /* Disk */
    drv->disk = FLOPPY_DRIVE_TYPE_NONE;
@@ -264,7 +263,7 @@ static int pick_geometry(FDrive *drv)
    int i, first_match, match;

    /* We can only pick a geometry if we have a diskette. */
    if (!drv->media_inserted) {
    if (!drv->media_inserted || drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
        return -1;
    }

@@ -277,7 +276,7 @@ static int pick_geometry(FDrive *drv)
            break;
        }
        if (drv->drive == parse->drive ||
            drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
            drv->drive == FLOPPY_DRIVE_TYPE_AUTO) {
            size = (parse->max_head + 1) * parse->max_track *
                parse->last_sect;
            if (nb_sectors == size) {
@@ -314,11 +313,17 @@ static int pick_geometry(FDrive *drv)

static void pick_drive_type(FDrive *drv)
{
    if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
        return;
    }

    if (pick_geometry(drv) == 0) {
        drv->drive = drv->disk;
    } else {
        drv->drive = get_fallback_drive_type(drv);
    }

    g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
}

/* Revalidate a disk drive after a disk change */
@@ -2475,6 +2480,12 @@ static Property isa_fdc_properties[] = {
    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.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,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.drives[1].drive,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
@@ -2526,6 +2537,12 @@ 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_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlSysBus, state.drives[1].drive,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
@@ -2549,6 +2566,9 @@ static const TypeInfo sysbus_fdc_info = {

static Property sun4m_fdc_properties[] = {
    DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].blk),
    DEFINE_PROP_DEFAULT("fdtype", FDCtrlSysBus, state.drives[0].drive,
                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
                        FloppyDriveType),
    DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
                        FloppyDriveType),