Commit 2e1280e8 authored by Max Reitz's avatar Max Reitz Committed by Kevin Wolf
Browse files

hw/block/fdc: Implement tray status



The tray of an FDD is open iff there is no medium inserted (there are
only two states for an FDD: "medium inserted" or "no medium inserted").

Signed-off-by: default avatarMax Reitz <mreitz@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarKevin Wolf <kwolf@redhat.com>
Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
parent b4d02820
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ typedef struct FDrive {
    uint8_t ro;               /* Is read-only           */
    uint8_t media_changed;    /* Is media changed       */
    uint8_t media_rate;       /* Data rate of medium    */

    bool media_inserted;      /* Is there a medium in the tray */
} FDrive;

static void fd_init(FDrive *drv)
@@ -261,7 +263,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
#endif
        drv->head = head;
        if (drv->track != track) {
            if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
            if (drv->media_inserted) {
                drv->media_changed = 0;
            }
            ret = 1;
@@ -270,7 +272,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
        drv->sect = sect;
    }

    if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
    if (!drv->media_inserted) {
        ret = 2;
    }

@@ -296,7 +298,7 @@ static void fd_revalidate(FDrive *drv)
        ro = blk_is_read_only(drv->blk);
        pick_geometry(drv->blk, &nb_heads, &max_track,
                      &last_sect, drv->drive, &drive, &rate);
        if (!blk_is_inserted(drv->blk)) {
        if (!drv->media_inserted) {
            FLOPPY_DPRINTF("No disk in drive\n");
        } else {
            FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
@@ -692,7 +694,7 @@ static bool fdrive_media_changed_needed(void *opaque)
{
    FDrive *drive = opaque;

    return (drive->blk != NULL && drive->media_changed != 1);
    return (drive->media_inserted && drive->media_changed != 1);
}

static const VMStateDescription vmstate_fdrive_media_changed = {
@@ -2184,12 +2186,21 @@ static void fdctrl_change_cb(void *opaque, bool load)
{
    FDrive *drive = opaque;

    drive->media_inserted = load && drive->blk && blk_is_inserted(drive->blk);

    drive->media_changed = 1;
    fd_revalidate(drive);
}

static bool fdctrl_is_tray_open(void *opaque)
{
    FDrive *drive = opaque;
    return !drive->media_inserted;
}

static const BlockDevOps fdctrl_block_ops = {
    .change_media_cb = fdctrl_change_cb,
    .is_tray_open = fdctrl_is_tray_open,
};

/* Init functions */
@@ -2217,6 +2228,7 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
        fdctrl_change_cb(drive, 0);
        if (drive->blk) {
            blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive);
            drive->media_inserted = blk_is_inserted(drive->blk);
        }
    }
}
+1 −3
Original line number Diff line number Diff line
@@ -304,9 +304,7 @@ static void test_media_insert(void)
    qmp_discard_response("{'execute':'change', 'arguments':{"
                         " 'device':'floppy0', 'target': %s, 'arg': 'raw' }}",
                         test_image);
    qmp_discard_response(""); /* ignore event
                                 (FIXME open -> open transition?!) */
    qmp_discard_response(""); /* ignore event */
    qmp_discard_response(""); /* ignore event (open -> close) */

    dir = inb(FLOPPY_BASE + reg_dir);
    assert_bit_set(dir, DSKCHG);