qemu/hw/block/fdc.c
<<
>>
Prefs
   1/*
   2 * QEMU Floppy disk emulator (Intel 82078)
   3 *
   4 * Copyright (c) 2003, 2007 Jocelyn Mayer
   5 * Copyright (c) 2008 Hervé Poussineau
   6 *
   7 * Permission is hereby granted, free of charge, to any person obtaining a copy
   8 * of this software and associated documentation files (the "Software"), to deal
   9 * in the Software without restriction, including without limitation the rights
  10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11 * copies of the Software, and to permit persons to whom the Software is
  12 * furnished to do so, subject to the following conditions:
  13 *
  14 * The above copyright notice and this permission notice shall be included in
  15 * all copies or substantial portions of the Software.
  16 *
  17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23 * THE SOFTWARE.
  24 */
  25/*
  26 * The controller is used in Sun4m systems in a slightly different
  27 * way. There are changes in DOR register and DMA is not available.
  28 */
  29
  30#include "qemu/osdep.h"
  31#include "hw/hw.h"
  32#include "hw/block/fdc.h"
  33#include "qapi/error.h"
  34#include "qemu/error-report.h"
  35#include "qemu/timer.h"
  36#include "hw/isa/isa.h"
  37#include "hw/sysbus.h"
  38#include "hw/block/block.h"
  39#include "sysemu/block-backend.h"
  40#include "sysemu/blockdev.h"
  41#include "sysemu/sysemu.h"
  42#include "qemu/log.h"
  43#include "qemu/module.h"
  44#include "trace.h"
  45
  46/********************************************************/
  47/* debug Floppy devices */
  48
  49#define DEBUG_FLOPPY 0
  50
  51#define FLOPPY_DPRINTF(fmt, ...)                                \
  52    do {                                                        \
  53        if (DEBUG_FLOPPY) {                                     \
  54            fprintf(stderr, "FLOPPY: " fmt , ## __VA_ARGS__);   \
  55        }                                                       \
  56    } while (0)
  57
  58
  59/********************************************************/
  60/* qdev floppy bus                                      */
  61
  62#define TYPE_FLOPPY_BUS "floppy-bus"
  63#define FLOPPY_BUS(obj) OBJECT_CHECK(FloppyBus, (obj), TYPE_FLOPPY_BUS)
  64
  65typedef struct FDCtrl FDCtrl;
  66typedef struct FDrive FDrive;
  67static FDrive *get_drv(FDCtrl *fdctrl, int unit);
  68
  69typedef struct FloppyBus {
  70    BusState bus;
  71    FDCtrl *fdc;
  72} FloppyBus;
  73
  74static const TypeInfo floppy_bus_info = {
  75    .name = TYPE_FLOPPY_BUS,
  76    .parent = TYPE_BUS,
  77    .instance_size = sizeof(FloppyBus),
  78};
  79
  80static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
  81{
  82    qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
  83    bus->fdc = fdc;
  84}
  85
  86
  87/********************************************************/
  88/* Floppy drive emulation                               */
  89
  90typedef enum FDriveRate {
  91    FDRIVE_RATE_500K = 0x00,  /* 500 Kbps */
  92    FDRIVE_RATE_300K = 0x01,  /* 300 Kbps */
  93    FDRIVE_RATE_250K = 0x02,  /* 250 Kbps */
  94    FDRIVE_RATE_1M   = 0x03,  /*   1 Mbps */
  95} FDriveRate;
  96
  97typedef enum FDriveSize {
  98    FDRIVE_SIZE_UNKNOWN,
  99    FDRIVE_SIZE_350,
 100    FDRIVE_SIZE_525,
 101} FDriveSize;
 102
 103typedef struct FDFormat {
 104    FloppyDriveType drive;
 105    uint8_t last_sect;
 106    uint8_t max_track;
 107    uint8_t max_head;
 108    FDriveRate rate;
 109} FDFormat;
 110
 111/* In many cases, the total sector size of a format is enough to uniquely
 112 * identify it. However, there are some total sector collisions between
 113 * formats of different physical size, and these are noted below by
 114 * highlighting the total sector size for entries with collisions. */
 115static const FDFormat fd_formats[] = {
 116    /* First entry is default format */
 117    /* 1.44 MB 3"1/2 floppy disks */
 118    { FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */
 119    { FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */
 120    { FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
 121    { FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
 122    { FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
 123    { FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, },
 124    { FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, },
 125    { FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, },
 126    /* 2.88 MB 3"1/2 floppy disks */
 127    { FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, },
 128    { FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, },
 129    { FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, },
 130    { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
 131    { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
 132    /* 720 kB 3"1/2 floppy disks */
 133    { FLOPPY_DRIVE_TYPE_144,  9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */
 134    { FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
 135    { FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
 136    { FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
 137    { FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, },
 138    { FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
 139    /* 1.2 MB 5"1/4 floppy disks */
 140    { FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
 141    { FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */
 142    { FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
 143    { FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
 144    { FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */
 145    /* 720 kB 5"1/4 floppy disks */
 146    { FLOPPY_DRIVE_TYPE_120,  9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */
 147    { FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
 148    /* 360 kB 5"1/4 floppy disks */
 149    { FLOPPY_DRIVE_TYPE_120,  9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */
 150    { FLOPPY_DRIVE_TYPE_120,  9, 40, 0, FDRIVE_RATE_300K, },
 151    { FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
 152    { FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
 153    /* 320 kB 5"1/4 floppy disks */
 154    { FLOPPY_DRIVE_TYPE_120,  8, 40, 1, FDRIVE_RATE_250K, },
 155    { FLOPPY_DRIVE_TYPE_120,  8, 40, 0, FDRIVE_RATE_250K, },
 156    /* 360 kB must match 5"1/4 better than 3"1/2... */
 157    { FLOPPY_DRIVE_TYPE_144,  9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */
 158    /* end */
 159    { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
 160};
 161
 162static FDriveSize drive_size(FloppyDriveType drive)
 163{
 164    switch (drive) {
 165    case FLOPPY_DRIVE_TYPE_120:
 166        return FDRIVE_SIZE_525;
 167    case FLOPPY_DRIVE_TYPE_144:
 168    case FLOPPY_DRIVE_TYPE_288:
 169        return FDRIVE_SIZE_350;
 170    default:
 171        return FDRIVE_SIZE_UNKNOWN;
 172    }
 173}
 174
 175#define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
 176#define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
 177
 178/* Will always be a fixed parameter for us */
 179#define FD_SECTOR_LEN          512
 180#define FD_SECTOR_SC           2   /* Sector size code */
 181#define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
 182
 183/* Floppy disk drive emulation */
 184typedef enum FDiskFlags {
 185    FDISK_DBL_SIDES  = 0x01,
 186} FDiskFlags;
 187
 188struct FDrive {
 189    FDCtrl *fdctrl;
 190    BlockBackend *blk;
 191    BlockConf *conf;
 192    /* Drive status */
 193    FloppyDriveType drive;    /* CMOS drive type        */
 194    uint8_t perpendicular;    /* 2.88 MB access mode    */
 195    /* Position */
 196    uint8_t head;
 197    uint8_t track;
 198    uint8_t sect;
 199    /* Media */
 200    FloppyDriveType disk;     /* Current disk type      */
 201    FDiskFlags flags;
 202    uint8_t last_sect;        /* Nb sector per track    */
 203    uint8_t max_track;        /* Nb of tracks           */
 204    uint16_t bps;             /* Bytes per sector       */
 205    uint8_t ro;               /* Is read-only           */
 206    uint8_t media_changed;    /* Is media changed       */
 207    uint8_t media_rate;       /* Data rate of medium    */
 208
 209    bool media_validated;     /* Have we validated the media? */
 210};
 211
 212
 213static FloppyDriveType get_fallback_drive_type(FDrive *drv);
 214
 215/* Hack: FD_SEEK is expected to work on empty drives. However, QEMU
 216 * currently goes through some pains to keep seeks within the bounds
 217 * established by last_sect and max_track. Correcting this is difficult,
 218 * as refactoring FDC code tends to expose nasty bugs in the Linux kernel.
 219 *
 220 * For now: allow empty drives to have large bounds so we can seek around,
 221 * with the understanding that when a diskette is inserted, the bounds will
 222 * properly tighten to match the geometry of that inserted medium.
 223 */
 224static void fd_empty_seek_hack(FDrive *drv)
 225{
 226    drv->last_sect = 0xFF;
 227    drv->max_track = 0xFF;
 228}
 229
 230static void fd_init(FDrive *drv)
 231{
 232    /* Drive */
 233    drv->perpendicular = 0;
 234    /* Disk */
 235    drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 236    drv->last_sect = 0;
 237    drv->max_track = 0;
 238    drv->ro = true;
 239    drv->media_changed = 1;
 240}
 241
 242#define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
 243
 244static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
 245                          uint8_t last_sect, uint8_t num_sides)
 246{
 247    return (((track * num_sides) + head) * last_sect) + sect - 1;
 248}
 249
 250/* Returns current position, in sectors, for given drive */
 251static int fd_sector(FDrive *drv)
 252{
 253    return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect,
 254                          NUM_SIDES(drv));
 255}
 256
 257/* Returns current position, in bytes, for given drive */
 258static int fd_offset(FDrive *drv)
 259{
 260    g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS);
 261    return fd_sector(drv) << BDRV_SECTOR_BITS;
 262}
 263
 264/* Seek to a new position:
 265 * returns 0 if already on right track
 266 * returns 1 if track changed
 267 * returns 2 if track is invalid
 268 * returns 3 if sector is invalid
 269 * returns 4 if seek is disabled
 270 */
 271static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
 272                   int enable_seek)
 273{
 274    uint32_t sector;
 275    int ret;
 276
 277    if (track > drv->max_track ||
 278        (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
 279        FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
 280                       head, track, sect, 1,
 281                       (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
 282                       drv->max_track, drv->last_sect);
 283        return 2;
 284    }
 285    if (sect > drv->last_sect) {
 286        FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
 287                       head, track, sect, 1,
 288                       (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
 289                       drv->max_track, drv->last_sect);
 290        return 3;
 291    }
 292    sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
 293    ret = 0;
 294    if (sector != fd_sector(drv)) {
 295#if 0
 296        if (!enable_seek) {
 297            FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x"
 298                           " (max=%d %02x %02x)\n",
 299                           head, track, sect, 1, drv->max_track,
 300                           drv->last_sect);
 301            return 4;
 302        }
 303#endif
 304        drv->head = head;
 305        if (drv->track != track) {
 306            if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
 307                drv->media_changed = 0;
 308            }
 309            ret = 1;
 310        }
 311        drv->track = track;
 312        drv->sect = sect;
 313    }
 314
 315    if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
 316        ret = 2;
 317    }
 318
 319    return ret;
 320}
 321
 322/* Set drive back to track 0 */
 323static void fd_recalibrate(FDrive *drv)
 324{
 325    FLOPPY_DPRINTF("recalibrate\n");
 326    fd_seek(drv, 0, 0, 1, 1);
 327}
 328
 329/**
 330 * Determine geometry based on inserted diskette.
 331 * Will not operate on an empty drive.
 332 *
 333 * @return: 0 on success, -1 if the drive is empty.
 334 */
 335static int pick_geometry(FDrive *drv)
 336{
 337    BlockBackend *blk = drv->blk;
 338    const FDFormat *parse;
 339    uint64_t nb_sectors, size;
 340    int i;
 341    int match, size_match, type_match;
 342    bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
 343
 344    /* We can only pick a geometry if we have a diskette. */
 345    if (!drv->blk || !blk_is_inserted(drv->blk) ||
 346        drv->drive == FLOPPY_DRIVE_TYPE_NONE)
 347    {
 348        return -1;
 349    }
 350
 351    /* We need to determine the likely geometry of the inserted medium.
 352     * In order of preference, we look for:
 353     * (1) The same drive type and number of sectors,
 354     * (2) The same diskette size and number of sectors,
 355     * (3) The same drive type.
 356     *
 357     * In all cases, matches that occur higher in the drive table will take
 358     * precedence over matches that occur later in the table.
 359     */
 360    blk_get_geometry(blk, &nb_sectors);
 361    match = size_match = type_match = -1;
 362    for (i = 0; ; i++) {
 363        parse = &fd_formats[i];
 364        if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
 365            break;
 366        }
 367        size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
 368        if (nb_sectors == size) {
 369            if (magic || parse->drive == drv->drive) {
 370                /* (1) perfect match -- nb_sectors and drive type */
 371                goto out;
 372            } else if (drive_size(parse->drive) == drive_size(drv->drive)) {
 373                /* (2) size match -- nb_sectors and physical medium size */
 374                match = (match == -1) ? i : match;
 375            } else {
 376                /* This is suspicious -- Did the user misconfigure? */
 377                size_match = (size_match == -1) ? i : size_match;
 378            }
 379        } else if (type_match == -1) {
 380            if ((parse->drive == drv->drive) ||
 381                (magic && (parse->drive == get_fallback_drive_type(drv)))) {
 382                /* (3) type match -- nb_sectors mismatch, but matches the type
 383                 *     specified explicitly by the user, or matches the fallback
 384                 *     default type when using the drive autodetect mechanism */
 385                type_match = i;
 386            }
 387        }
 388    }
 389
 390    /* No exact match found */
 391    if (match == -1) {
 392        if (size_match != -1) {
 393            parse = &fd_formats[size_match];
 394            FLOPPY_DPRINTF("User requested floppy drive type '%s', "
 395                           "but inserted medium appears to be a "
 396                           "%"PRId64" sector '%s' type\n",
 397                           FloppyDriveType_str(drv->drive),
 398                           nb_sectors,
 399                           FloppyDriveType_str(parse->drive));
 400        }
 401        assert(type_match != -1 && "misconfigured fd_format");
 402        match = type_match;
 403    }
 404    parse = &(fd_formats[match]);
 405
 406 out:
 407    if (parse->max_head == 0) {
 408        drv->flags &= ~FDISK_DBL_SIDES;
 409    } else {
 410        drv->flags |= FDISK_DBL_SIDES;
 411    }
 412    drv->max_track = parse->max_track;
 413    drv->last_sect = parse->last_sect;
 414    drv->disk = parse->drive;
 415    drv->media_rate = parse->rate;
 416    return 0;
 417}
 418
 419static void pick_drive_type(FDrive *drv)
 420{
 421    if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
 422        return;
 423    }
 424
 425    if (pick_geometry(drv) == 0) {
 426        drv->drive = drv->disk;
 427    } else {
 428        drv->drive = get_fallback_drive_type(drv);
 429    }
 430
 431    g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
 432}
 433
 434/* Revalidate a disk drive after a disk change */
 435static void fd_revalidate(FDrive *drv)
 436{
 437    int rc;
 438
 439    FLOPPY_DPRINTF("revalidate\n");
 440    if (drv->blk != NULL) {
 441        drv->ro = blk_is_read_only(drv->blk);
 442        if (!blk_is_inserted(drv->blk)) {
 443            FLOPPY_DPRINTF("No disk in drive\n");
 444            drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 445            fd_empty_seek_hack(drv);
 446        } else if (!drv->media_validated) {
 447            rc = pick_geometry(drv);
 448            if (rc) {
 449                FLOPPY_DPRINTF("Could not validate floppy drive media");
 450            } else {
 451                drv->media_validated = true;
 452                FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
 453                               (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
 454                               drv->max_track, drv->last_sect,
 455                               drv->ro ? "ro" : "rw");
 456            }
 457        }
 458    } else {
 459        FLOPPY_DPRINTF("No drive connected\n");
 460        drv->last_sect = 0;
 461        drv->max_track = 0;
 462        drv->flags &= ~FDISK_DBL_SIDES;
 463        drv->drive = FLOPPY_DRIVE_TYPE_NONE;
 464        drv->disk = FLOPPY_DRIVE_TYPE_NONE;
 465    }
 466}
 467
 468static void fd_change_cb(void *opaque, bool load, Error **errp)
 469{
 470    FDrive *drive = opaque;
 471
 472    if (!load) {
 473        blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
 474    } else {
 475        if (!blkconf_apply_backend_options(drive->conf,
 476                                           blk_is_read_only(drive->blk), false,
 477                                           errp)) {
 478            return;
 479        }
 480    }
 481
 482    drive->media_changed = 1;
 483    drive->media_validated = false;
 484    fd_revalidate(drive);
 485}
 486
 487static const BlockDevOps fd_block_ops = {
 488    .change_media_cb = fd_change_cb,
 489};
 490
 491
 492#define TYPE_FLOPPY_DRIVE "floppy"
 493#define FLOPPY_DRIVE(obj) \
 494     OBJECT_CHECK(FloppyDrive, (obj), TYPE_FLOPPY_DRIVE)
 495
 496typedef struct FloppyDrive {
 497    DeviceState     qdev;
 498    uint32_t        unit;
 499    BlockConf       conf;
 500    FloppyDriveType type;
 501} FloppyDrive;
 502
 503static Property floppy_drive_properties[] = {
 504    DEFINE_PROP_UINT32("unit", FloppyDrive, unit, -1),
 505    DEFINE_BLOCK_PROPERTIES(FloppyDrive, conf),
 506    DEFINE_PROP_SIGNED("drive-type", FloppyDrive, type,
 507                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
 508                        FloppyDriveType),
 509    DEFINE_PROP_END_OF_LIST(),
 510};
 511
 512static void floppy_drive_realize(DeviceState *qdev, Error **errp)
 513{
 514    FloppyDrive *dev = FLOPPY_DRIVE(qdev);
 515    FloppyBus *bus = FLOPPY_BUS(qdev->parent_bus);
 516    FDrive *drive;
 517    bool read_only;
 518    int ret;
 519
 520    if (dev->unit == -1) {
 521        for (dev->unit = 0; dev->unit < MAX_FD; dev->unit++) {
 522            drive = get_drv(bus->fdc, dev->unit);
 523            if (!drive->blk) {
 524                break;
 525            }
 526        }
 527    }
 528
 529    if (dev->unit >= MAX_FD) {
 530        error_setg(errp, "Can't create floppy unit %d, bus supports "
 531                   "only %d units", dev->unit, MAX_FD);
 532        return;
 533    }
 534
 535    drive = get_drv(bus->fdc, dev->unit);
 536    if (drive->blk) {
 537        error_setg(errp, "Floppy unit %d is in use", dev->unit);
 538        return;
 539    }
 540
 541    if (!dev->conf.blk) {
 542        /* Anonymous BlockBackend for an empty drive */
 543        dev->conf.blk = blk_new(qemu_get_aio_context(), 0, BLK_PERM_ALL);
 544        ret = blk_attach_dev(dev->conf.blk, qdev);
 545        assert(ret == 0);
 546
 547        /* Don't take write permissions on an empty drive to allow attaching a
 548         * read-only node later */
 549        read_only = true;
 550    } else {
 551        read_only = !blk_bs(dev->conf.blk) || blk_is_read_only(dev->conf.blk);
 552    }
 553
 554    blkconf_blocksizes(&dev->conf);
 555    if (dev->conf.logical_block_size != 512 ||
 556        dev->conf.physical_block_size != 512)
 557    {
 558        error_setg(errp, "Physical and logical block size must "
 559                   "be 512 for floppy");
 560        return;
 561    }
 562
 563    /* rerror/werror aren't supported by fdc and therefore not even registered
 564     * with qdev. So set the defaults manually before they are used in
 565     * blkconf_apply_backend_options(). */
 566    dev->conf.rerror = BLOCKDEV_ON_ERROR_AUTO;
 567    dev->conf.werror = BLOCKDEV_ON_ERROR_AUTO;
 568
 569    if (!blkconf_apply_backend_options(&dev->conf, read_only, false, errp)) {
 570        return;
 571    }
 572
 573    /* 'enospc' is the default for -drive, 'report' is what blk_new() gives us
 574     * for empty drives. */
 575    if (blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_ENOSPC &&
 576        blk_get_on_error(dev->conf.blk, 0) != BLOCKDEV_ON_ERROR_REPORT) {
 577        error_setg(errp, "fdc doesn't support drive option werror");
 578        return;
 579    }
 580    if (blk_get_on_error(dev->conf.blk, 1) != BLOCKDEV_ON_ERROR_REPORT) {
 581        error_setg(errp, "fdc doesn't support drive option rerror");
 582        return;
 583    }
 584
 585    drive->conf = &dev->conf;
 586    drive->blk = dev->conf.blk;
 587    drive->fdctrl = bus->fdc;
 588
 589    fd_init(drive);
 590    blk_set_dev_ops(drive->blk, &fd_block_ops, drive);
 591
 592    /* Keep 'type' qdev property and FDrive->drive in sync */
 593    drive->drive = dev->type;
 594    pick_drive_type(drive);
 595    dev->type = drive->drive;
 596
 597    fd_revalidate(drive);
 598}
 599
 600static void floppy_drive_class_init(ObjectClass *klass, void *data)
 601{
 602    DeviceClass *k = DEVICE_CLASS(klass);
 603    k->realize = floppy_drive_realize;
 604    set_bit(DEVICE_CATEGORY_STORAGE, k->categories);
 605    k->bus_type = TYPE_FLOPPY_BUS;
 606    k->props = floppy_drive_properties;
 607    k->desc = "virtual floppy drive";
 608}
 609
 610static const TypeInfo floppy_drive_info = {
 611    .name = TYPE_FLOPPY_DRIVE,
 612    .parent = TYPE_DEVICE,
 613    .instance_size = sizeof(FloppyDrive),
 614    .class_init = floppy_drive_class_init,
 615};
 616
 617/********************************************************/
 618/* Intel 82078 floppy disk controller emulation          */
 619
 620static void fdctrl_reset(FDCtrl *fdctrl, int do_irq);
 621static void fdctrl_to_command_phase(FDCtrl *fdctrl);
 622static int fdctrl_transfer_handler (void *opaque, int nchan,
 623                                    int dma_pos, int dma_len);
 624static void fdctrl_raise_irq(FDCtrl *fdctrl);
 625static FDrive *get_cur_drv(FDCtrl *fdctrl);
 626
 627static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl);
 628static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl);
 629static uint32_t fdctrl_read_dor(FDCtrl *fdctrl);
 630static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value);
 631static uint32_t fdctrl_read_tape(FDCtrl *fdctrl);
 632static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value);
 633static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl);
 634static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value);
 635static uint32_t fdctrl_read_data(FDCtrl *fdctrl);
 636static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value);
 637static uint32_t fdctrl_read_dir(FDCtrl *fdctrl);
 638static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value);
 639
 640enum {
 641    FD_DIR_WRITE   = 0,
 642    FD_DIR_READ    = 1,
 643    FD_DIR_SCANE   = 2,
 644    FD_DIR_SCANL   = 3,
 645    FD_DIR_SCANH   = 4,
 646    FD_DIR_VERIFY  = 5,
 647};
 648
 649enum {
 650    FD_STATE_MULTI  = 0x01,     /* multi track flag */
 651    FD_STATE_FORMAT = 0x02,     /* format flag */
 652};
 653
 654enum {
 655    FD_REG_SRA = 0x00,
 656    FD_REG_SRB = 0x01,
 657    FD_REG_DOR = 0x02,
 658    FD_REG_TDR = 0x03,
 659    FD_REG_MSR = 0x04,
 660    FD_REG_DSR = 0x04,
 661    FD_REG_FIFO = 0x05,
 662    FD_REG_DIR = 0x07,
 663    FD_REG_CCR = 0x07,
 664};
 665
 666enum {
 667    FD_CMD_READ_TRACK = 0x02,
 668    FD_CMD_SPECIFY = 0x03,
 669    FD_CMD_SENSE_DRIVE_STATUS = 0x04,
 670    FD_CMD_WRITE = 0x05,
 671    FD_CMD_READ = 0x06,
 672    FD_CMD_RECALIBRATE = 0x07,
 673    FD_CMD_SENSE_INTERRUPT_STATUS = 0x08,
 674    FD_CMD_WRITE_DELETED = 0x09,
 675    FD_CMD_READ_ID = 0x0a,
 676    FD_CMD_READ_DELETED = 0x0c,
 677    FD_CMD_FORMAT_TRACK = 0x0d,
 678    FD_CMD_DUMPREG = 0x0e,
 679    FD_CMD_SEEK = 0x0f,
 680    FD_CMD_VERSION = 0x10,
 681    FD_CMD_SCAN_EQUAL = 0x11,
 682    FD_CMD_PERPENDICULAR_MODE = 0x12,
 683    FD_CMD_CONFIGURE = 0x13,
 684    FD_CMD_LOCK = 0x14,
 685    FD_CMD_VERIFY = 0x16,
 686    FD_CMD_POWERDOWN_MODE = 0x17,
 687    FD_CMD_PART_ID = 0x18,
 688    FD_CMD_SCAN_LOW_OR_EQUAL = 0x19,
 689    FD_CMD_SCAN_HIGH_OR_EQUAL = 0x1d,
 690    FD_CMD_SAVE = 0x2e,
 691    FD_CMD_OPTION = 0x33,
 692    FD_CMD_RESTORE = 0x4e,
 693    FD_CMD_DRIVE_SPECIFICATION_COMMAND = 0x8e,
 694    FD_CMD_RELATIVE_SEEK_OUT = 0x8f,
 695    FD_CMD_FORMAT_AND_WRITE = 0xcd,
 696    FD_CMD_RELATIVE_SEEK_IN = 0xcf,
 697};
 698
 699enum {
 700    FD_CONFIG_PRETRK = 0xff, /* Pre-compensation set to track 0 */
 701    FD_CONFIG_FIFOTHR = 0x0f, /* FIFO threshold set to 1 byte */
 702    FD_CONFIG_POLL  = 0x10, /* Poll enabled */
 703    FD_CONFIG_EFIFO = 0x20, /* FIFO disabled */
 704    FD_CONFIG_EIS   = 0x40, /* No implied seeks */
 705};
 706
 707enum {
 708    FD_SR0_DS0      = 0x01,
 709    FD_SR0_DS1      = 0x02,
 710    FD_SR0_HEAD     = 0x04,
 711    FD_SR0_EQPMT    = 0x10,
 712    FD_SR0_SEEK     = 0x20,
 713    FD_SR0_ABNTERM  = 0x40,
 714    FD_SR0_INVCMD   = 0x80,
 715    FD_SR0_RDYCHG   = 0xc0,
 716};
 717
 718enum {
 719    FD_SR1_MA       = 0x01, /* Missing address mark */
 720    FD_SR1_NW       = 0x02, /* Not writable */
 721    FD_SR1_EC       = 0x80, /* End of cylinder */
 722};
 723
 724enum {
 725    FD_SR2_SNS      = 0x04, /* Scan not satisfied */
 726    FD_SR2_SEH      = 0x08, /* Scan equal hit */
 727};
 728
 729enum {
 730    FD_SRA_DIR      = 0x01,
 731    FD_SRA_nWP      = 0x02,
 732    FD_SRA_nINDX    = 0x04,
 733    FD_SRA_HDSEL    = 0x08,
 734    FD_SRA_nTRK0    = 0x10,
 735    FD_SRA_STEP     = 0x20,
 736    FD_SRA_nDRV2    = 0x40,
 737    FD_SRA_INTPEND  = 0x80,
 738};
 739
 740enum {
 741    FD_SRB_MTR0     = 0x01,
 742    FD_SRB_MTR1     = 0x02,
 743    FD_SRB_WGATE    = 0x04,
 744    FD_SRB_RDATA    = 0x08,
 745    FD_SRB_WDATA    = 0x10,
 746    FD_SRB_DR0      = 0x20,
 747};
 748
 749enum {
 750#if MAX_FD == 4
 751    FD_DOR_SELMASK  = 0x03,
 752#else
 753    FD_DOR_SELMASK  = 0x01,
 754#endif
 755    FD_DOR_nRESET   = 0x04,
 756    FD_DOR_DMAEN    = 0x08,
 757    FD_DOR_MOTEN0   = 0x10,
 758    FD_DOR_MOTEN1   = 0x20,
 759    FD_DOR_MOTEN2   = 0x40,
 760    FD_DOR_MOTEN3   = 0x80,
 761};
 762
 763enum {
 764#if MAX_FD == 4
 765    FD_TDR_BOOTSEL  = 0x0c,
 766#else
 767    FD_TDR_BOOTSEL  = 0x04,
 768#endif
 769};
 770
 771enum {
 772    FD_DSR_DRATEMASK= 0x03,
 773    FD_DSR_PWRDOWN  = 0x40,
 774    FD_DSR_SWRESET  = 0x80,
 775};
 776
 777enum {
 778    FD_MSR_DRV0BUSY = 0x01,
 779    FD_MSR_DRV1BUSY = 0x02,
 780    FD_MSR_DRV2BUSY = 0x04,
 781    FD_MSR_DRV3BUSY = 0x08,
 782    FD_MSR_CMDBUSY  = 0x10,
 783    FD_MSR_NONDMA   = 0x20,
 784    FD_MSR_DIO      = 0x40,
 785    FD_MSR_RQM      = 0x80,
 786};
 787
 788enum {
 789    FD_DIR_DSKCHG   = 0x80,
 790};
 791
 792/*
 793 * See chapter 5.0 "Controller phases" of the spec:
 794 *
 795 * Command phase:
 796 * The host writes a command and its parameters into the FIFO. The command
 797 * phase is completed when all parameters for the command have been supplied,
 798 * and execution phase is entered.
 799 *
 800 * Execution phase:
 801 * Data transfers, either DMA or non-DMA. For non-DMA transfers, the FIFO
 802 * contains the payload now, otherwise it's unused. When all bytes of the
 803 * required data have been transferred, the state is switched to either result
 804 * phase (if the command produces status bytes) or directly back into the
 805 * command phase for the next command.
 806 *
 807 * Result phase:
 808 * The host reads out the FIFO, which contains one or more result bytes now.
 809 */
 810enum {
 811    /* Only for migration: reconstruct phase from registers like qemu 2.3 */
 812    FD_PHASE_RECONSTRUCT    = 0,
 813
 814    FD_PHASE_COMMAND        = 1,
 815    FD_PHASE_EXECUTION      = 2,
 816    FD_PHASE_RESULT         = 3,
 817};
 818
 819#define FD_MULTI_TRACK(state) ((state) & FD_STATE_MULTI)
 820#define FD_FORMAT_CMD(state) ((state) & FD_STATE_FORMAT)
 821
 822struct FDCtrl {
 823    MemoryRegion iomem;
 824    qemu_irq irq;
 825    /* Controller state */
 826    QEMUTimer *result_timer;
 827    int dma_chann;
 828    uint8_t phase;
 829    IsaDma *dma;
 830    /* Controller's identification */
 831    uint8_t version;
 832    /* HW */
 833    uint8_t sra;
 834    uint8_t srb;
 835    uint8_t dor;
 836    uint8_t dor_vmstate; /* only used as temp during vmstate */
 837    uint8_t tdr;
 838    uint8_t dsr;
 839    uint8_t msr;
 840    uint8_t cur_drv;
 841    uint8_t status0;
 842    uint8_t status1;
 843    uint8_t status2;
 844    /* Command FIFO */
 845    uint8_t *fifo;
 846    int32_t fifo_size;
 847    uint32_t data_pos;
 848    uint32_t data_len;
 849    uint8_t data_state;
 850    uint8_t data_dir;
 851    uint8_t eot; /* last wanted sector */
 852    /* States kept only to be returned back */
 853    /* precompensation */
 854    uint8_t precomp_trk;
 855    uint8_t config;
 856    uint8_t lock;
 857    /* Power down config (also with status regB access mode */
 858    uint8_t pwrd;
 859    /* Floppy drives */
 860    FloppyBus bus;
 861    uint8_t num_floppies;
 862    FDrive drives[MAX_FD];
 863    struct {
 864        BlockBackend *blk;
 865        FloppyDriveType type;
 866    } qdev_for_drives[MAX_FD];
 867    int reset_sensei;
 868    uint32_t check_media_rate;
 869    FloppyDriveType fallback; /* type=auto failure fallback */
 870    /* Timers state */
 871    uint8_t timer0;
 872    uint8_t timer1;
 873    PortioList portio_list;
 874};
 875
 876static FloppyDriveType get_fallback_drive_type(FDrive *drv)
 877{
 878    return drv->fdctrl->fallback;
 879}
 880
 881#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
 882#define SYSBUS_FDC(obj) OBJECT_CHECK(FDCtrlSysBus, (obj), TYPE_SYSBUS_FDC)
 883
 884typedef struct FDCtrlSysBus {
 885    /*< private >*/
 886    SysBusDevice parent_obj;
 887    /*< public >*/
 888
 889    struct FDCtrl state;
 890} FDCtrlSysBus;
 891
 892#define ISA_FDC(obj) OBJECT_CHECK(FDCtrlISABus, (obj), TYPE_ISA_FDC)
 893
 894typedef struct FDCtrlISABus {
 895    ISADevice parent_obj;
 896
 897    uint32_t iobase;
 898    uint32_t irq;
 899    uint32_t dma;
 900    struct FDCtrl state;
 901    int32_t bootindexA;
 902    int32_t bootindexB;
 903} FDCtrlISABus;
 904
 905static uint32_t fdctrl_read (void *opaque, uint32_t reg)
 906{
 907    FDCtrl *fdctrl = opaque;
 908    uint32_t retval;
 909
 910    reg &= 7;
 911    switch (reg) {
 912    case FD_REG_SRA:
 913        retval = fdctrl_read_statusA(fdctrl);
 914        break;
 915    case FD_REG_SRB:
 916        retval = fdctrl_read_statusB(fdctrl);
 917        break;
 918    case FD_REG_DOR:
 919        retval = fdctrl_read_dor(fdctrl);
 920        break;
 921    case FD_REG_TDR:
 922        retval = fdctrl_read_tape(fdctrl);
 923        break;
 924    case FD_REG_MSR:
 925        retval = fdctrl_read_main_status(fdctrl);
 926        break;
 927    case FD_REG_FIFO:
 928        retval = fdctrl_read_data(fdctrl);
 929        break;
 930    case FD_REG_DIR:
 931        retval = fdctrl_read_dir(fdctrl);
 932        break;
 933    default:
 934        retval = (uint32_t)(-1);
 935        break;
 936    }
 937    trace_fdc_ioport_read(reg, retval);
 938
 939    return retval;
 940}
 941
 942static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
 943{
 944    FDCtrl *fdctrl = opaque;
 945
 946    reg &= 7;
 947    trace_fdc_ioport_write(reg, value);
 948    switch (reg) {
 949    case FD_REG_DOR:
 950        fdctrl_write_dor(fdctrl, value);
 951        break;
 952    case FD_REG_TDR:
 953        fdctrl_write_tape(fdctrl, value);
 954        break;
 955    case FD_REG_DSR:
 956        fdctrl_write_rate(fdctrl, value);
 957        break;
 958    case FD_REG_FIFO:
 959        fdctrl_write_data(fdctrl, value);
 960        break;
 961    case FD_REG_CCR:
 962        fdctrl_write_ccr(fdctrl, value);
 963        break;
 964    default:
 965        break;
 966    }
 967}
 968
 969static uint64_t fdctrl_read_mem (void *opaque, hwaddr reg,
 970                                 unsigned ize)
 971{
 972    return fdctrl_read(opaque, (uint32_t)reg);
 973}
 974
 975static void fdctrl_write_mem (void *opaque, hwaddr reg,
 976                              uint64_t value, unsigned size)
 977{
 978    fdctrl_write(opaque, (uint32_t)reg, value);
 979}
 980
 981static const MemoryRegionOps fdctrl_mem_ops = {
 982    .read = fdctrl_read_mem,
 983    .write = fdctrl_write_mem,
 984    .endianness = DEVICE_NATIVE_ENDIAN,
 985};
 986
 987static const MemoryRegionOps fdctrl_mem_strict_ops = {
 988    .read = fdctrl_read_mem,
 989    .write = fdctrl_write_mem,
 990    .endianness = DEVICE_NATIVE_ENDIAN,
 991    .valid = {
 992        .min_access_size = 1,
 993        .max_access_size = 1,
 994    },
 995};
 996
 997static bool fdrive_media_changed_needed(void *opaque)
 998{
 999    FDrive *drive = opaque;
1000
1001    return (drive->blk != NULL && drive->media_changed != 1);
1002}
1003
1004static const VMStateDescription vmstate_fdrive_media_changed = {
1005    .name = "fdrive/media_changed",
1006    .version_id = 1,
1007    .minimum_version_id = 1,
1008    .needed = fdrive_media_changed_needed,
1009    .fields = (VMStateField[]) {
1010        VMSTATE_UINT8(media_changed, FDrive),
1011        VMSTATE_END_OF_LIST()
1012    }
1013};
1014
1015static bool fdrive_media_rate_needed(void *opaque)
1016{
1017    FDrive *drive = opaque;
1018
1019    return drive->fdctrl->check_media_rate;
1020}
1021
1022static const VMStateDescription vmstate_fdrive_media_rate = {
1023    .name = "fdrive/media_rate",
1024    .version_id = 1,
1025    .minimum_version_id = 1,
1026    .needed = fdrive_media_rate_needed,
1027    .fields = (VMStateField[]) {
1028        VMSTATE_UINT8(media_rate, FDrive),
1029        VMSTATE_END_OF_LIST()
1030    }
1031};
1032
1033static bool fdrive_perpendicular_needed(void *opaque)
1034{
1035    FDrive *drive = opaque;
1036
1037    return drive->perpendicular != 0;
1038}
1039
1040static const VMStateDescription vmstate_fdrive_perpendicular = {
1041    .name = "fdrive/perpendicular",
1042    .version_id = 1,
1043    .minimum_version_id = 1,
1044    .needed = fdrive_perpendicular_needed,
1045    .fields = (VMStateField[]) {
1046        VMSTATE_UINT8(perpendicular, FDrive),
1047        VMSTATE_END_OF_LIST()
1048    }
1049};
1050
1051static int fdrive_post_load(void *opaque, int version_id)
1052{
1053    fd_revalidate(opaque);
1054    return 0;
1055}
1056
1057static const VMStateDescription vmstate_fdrive = {
1058    .name = "fdrive",
1059    .version_id = 1,
1060    .minimum_version_id = 1,
1061    .post_load = fdrive_post_load,
1062    .fields = (VMStateField[]) {
1063        VMSTATE_UINT8(head, FDrive),
1064        VMSTATE_UINT8(track, FDrive),
1065        VMSTATE_UINT8(sect, FDrive),
1066        VMSTATE_END_OF_LIST()
1067    },
1068    .subsections = (const VMStateDescription*[]) {
1069        &vmstate_fdrive_media_changed,
1070        &vmstate_fdrive_media_rate,
1071        &vmstate_fdrive_perpendicular,
1072        NULL
1073    }
1074};
1075
1076/*
1077 * Reconstructs the phase from register values according to the logic that was
1078 * implemented in qemu 2.3. This is the default value that is used if the phase
1079 * subsection is not present on migration.
1080 *
1081 * Don't change this function to reflect newer qemu versions, it is part of
1082 * the migration ABI.
1083 */
1084static int reconstruct_phase(FDCtrl *fdctrl)
1085{
1086    if (fdctrl->msr & FD_MSR_NONDMA) {
1087        return FD_PHASE_EXECUTION;
1088    } else if ((fdctrl->msr & FD_MSR_RQM) == 0) {
1089        /* qemu 2.3 disabled RQM only during DMA transfers */
1090        return FD_PHASE_EXECUTION;
1091    } else if (fdctrl->msr & FD_MSR_DIO) {
1092        return FD_PHASE_RESULT;
1093    } else {
1094        return FD_PHASE_COMMAND;
1095    }
1096}
1097
1098static int fdc_pre_save(void *opaque)
1099{
1100    FDCtrl *s = opaque;
1101
1102    s->dor_vmstate = s->dor | GET_CUR_DRV(s);
1103
1104    return 0;
1105}
1106
1107static int fdc_pre_load(void *opaque)
1108{
1109    FDCtrl *s = opaque;
1110    s->phase = FD_PHASE_RECONSTRUCT;
1111    return 0;
1112}
1113
1114static int fdc_post_load(void *opaque, int version_id)
1115{
1116    FDCtrl *s = opaque;
1117
1118    SET_CUR_DRV(s, s->dor_vmstate & FD_DOR_SELMASK);
1119    s->dor = s->dor_vmstate & ~FD_DOR_SELMASK;
1120
1121    if (s->phase == FD_PHASE_RECONSTRUCT) {
1122        s->phase = reconstruct_phase(s);
1123    }
1124
1125    return 0;
1126}
1127
1128static bool fdc_reset_sensei_needed(void *opaque)
1129{
1130    FDCtrl *s = opaque;
1131
1132    return s->reset_sensei != 0;
1133}
1134
1135static const VMStateDescription vmstate_fdc_reset_sensei = {
1136    .name = "fdc/reset_sensei",
1137    .version_id = 1,
1138    .minimum_version_id = 1,
1139    .needed = fdc_reset_sensei_needed,
1140    .fields = (VMStateField[]) {
1141        VMSTATE_INT32(reset_sensei, FDCtrl),
1142        VMSTATE_END_OF_LIST()
1143    }
1144};
1145
1146static bool fdc_result_timer_needed(void *opaque)
1147{
1148    FDCtrl *s = opaque;
1149
1150    return timer_pending(s->result_timer);
1151}
1152
1153static const VMStateDescription vmstate_fdc_result_timer = {
1154    .name = "fdc/result_timer",
1155    .version_id = 1,
1156    .minimum_version_id = 1,
1157    .needed = fdc_result_timer_needed,
1158    .fields = (VMStateField[]) {
1159        VMSTATE_TIMER_PTR(result_timer, FDCtrl),
1160        VMSTATE_END_OF_LIST()
1161    }
1162};
1163
1164static bool fdc_phase_needed(void *opaque)
1165{
1166    FDCtrl *fdctrl = opaque;
1167
1168    return reconstruct_phase(fdctrl) != fdctrl->phase;
1169}
1170
1171static const VMStateDescription vmstate_fdc_phase = {
1172    .name = "fdc/phase",
1173    .version_id = 1,
1174    .minimum_version_id = 1,
1175    .needed = fdc_phase_needed,
1176    .fields = (VMStateField[]) {
1177        VMSTATE_UINT8(phase, FDCtrl),
1178        VMSTATE_END_OF_LIST()
1179    }
1180};
1181
1182static const VMStateDescription vmstate_fdc = {
1183    .name = "fdc",
1184    .version_id = 2,
1185    .minimum_version_id = 2,
1186    .pre_save = fdc_pre_save,
1187    .pre_load = fdc_pre_load,
1188    .post_load = fdc_post_load,
1189    .fields = (VMStateField[]) {
1190        /* Controller State */
1191        VMSTATE_UINT8(sra, FDCtrl),
1192        VMSTATE_UINT8(srb, FDCtrl),
1193        VMSTATE_UINT8(dor_vmstate, FDCtrl),
1194        VMSTATE_UINT8(tdr, FDCtrl),
1195        VMSTATE_UINT8(dsr, FDCtrl),
1196        VMSTATE_UINT8(msr, FDCtrl),
1197        VMSTATE_UINT8(status0, FDCtrl),
1198        VMSTATE_UINT8(status1, FDCtrl),
1199        VMSTATE_UINT8(status2, FDCtrl),
1200        /* Command FIFO */
1201        VMSTATE_VARRAY_INT32(fifo, FDCtrl, fifo_size, 0, vmstate_info_uint8,
1202                             uint8_t),
1203        VMSTATE_UINT32(data_pos, FDCtrl),
1204        VMSTATE_UINT32(data_len, FDCtrl),
1205        VMSTATE_UINT8(data_state, FDCtrl),
1206        VMSTATE_UINT8(data_dir, FDCtrl),
1207        VMSTATE_UINT8(eot, FDCtrl),
1208        /* States kept only to be returned back */
1209        VMSTATE_UINT8(timer0, FDCtrl),
1210        VMSTATE_UINT8(timer1, FDCtrl),
1211        VMSTATE_UINT8(precomp_trk, FDCtrl),
1212        VMSTATE_UINT8(config, FDCtrl),
1213        VMSTATE_UINT8(lock, FDCtrl),
1214        VMSTATE_UINT8(pwrd, FDCtrl),
1215        VMSTATE_UINT8_EQUAL(num_floppies, FDCtrl, NULL),
1216        VMSTATE_STRUCT_ARRAY(drives, FDCtrl, MAX_FD, 1,
1217                             vmstate_fdrive, FDrive),
1218        VMSTATE_END_OF_LIST()
1219    },
1220    .subsections = (const VMStateDescription*[]) {
1221        &vmstate_fdc_reset_sensei,
1222        &vmstate_fdc_result_timer,
1223        &vmstate_fdc_phase,
1224        NULL
1225    }
1226};
1227
1228static void fdctrl_external_reset_sysbus(DeviceState *d)
1229{
1230    FDCtrlSysBus *sys = SYSBUS_FDC(d);
1231    FDCtrl *s = &sys->state;
1232
1233    fdctrl_reset(s, 0);
1234}
1235
1236static void fdctrl_external_reset_isa(DeviceState *d)
1237{
1238    FDCtrlISABus *isa = ISA_FDC(d);
1239    FDCtrl *s = &isa->state;
1240
1241    fdctrl_reset(s, 0);
1242}
1243
1244static void fdctrl_handle_tc(void *opaque, int irq, int level)
1245{
1246    //FDCtrl *s = opaque;
1247
1248    if (level) {
1249        // XXX
1250        FLOPPY_DPRINTF("TC pulsed\n");
1251    }
1252}
1253
1254/* Change IRQ state */
1255static void fdctrl_reset_irq(FDCtrl *fdctrl)
1256{
1257    fdctrl->status0 = 0;
1258    if (!(fdctrl->sra & FD_SRA_INTPEND))
1259        return;
1260    FLOPPY_DPRINTF("Reset interrupt\n");
1261    qemu_set_irq(fdctrl->irq, 0);
1262    fdctrl->sra &= ~FD_SRA_INTPEND;
1263}
1264
1265static void fdctrl_raise_irq(FDCtrl *fdctrl)
1266{
1267    if (!(fdctrl->sra & FD_SRA_INTPEND)) {
1268        qemu_set_irq(fdctrl->irq, 1);
1269        fdctrl->sra |= FD_SRA_INTPEND;
1270    }
1271
1272    fdctrl->reset_sensei = 0;
1273    FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", fdctrl->status0);
1274}
1275
1276/* Reset controller */
1277static void fdctrl_reset(FDCtrl *fdctrl, int do_irq)
1278{
1279    int i;
1280
1281    FLOPPY_DPRINTF("reset controller\n");
1282    fdctrl_reset_irq(fdctrl);
1283    /* Initialise controller */
1284    fdctrl->sra = 0;
1285    fdctrl->srb = 0xc0;
1286    if (!fdctrl->drives[1].blk) {
1287        fdctrl->sra |= FD_SRA_nDRV2;
1288    }
1289    fdctrl->cur_drv = 0;
1290    fdctrl->dor = FD_DOR_nRESET;
1291    fdctrl->dor |= (fdctrl->dma_chann != -1) ? FD_DOR_DMAEN : 0;
1292    fdctrl->msr = FD_MSR_RQM;
1293    fdctrl->reset_sensei = 0;
1294    timer_del(fdctrl->result_timer);
1295    /* FIFO state */
1296    fdctrl->data_pos = 0;
1297    fdctrl->data_len = 0;
1298    fdctrl->data_state = 0;
1299    fdctrl->data_dir = FD_DIR_WRITE;
1300    for (i = 0; i < MAX_FD; i++)
1301        fd_recalibrate(&fdctrl->drives[i]);
1302    fdctrl_to_command_phase(fdctrl);
1303    if (do_irq) {
1304        fdctrl->status0 |= FD_SR0_RDYCHG;
1305        fdctrl_raise_irq(fdctrl);
1306        fdctrl->reset_sensei = FD_RESET_SENSEI_COUNT;
1307    }
1308}
1309
1310static inline FDrive *drv0(FDCtrl *fdctrl)
1311{
1312    return &fdctrl->drives[(fdctrl->tdr & FD_TDR_BOOTSEL) >> 2];
1313}
1314
1315static inline FDrive *drv1(FDCtrl *fdctrl)
1316{
1317    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (1 << 2))
1318        return &fdctrl->drives[1];
1319    else
1320        return &fdctrl->drives[0];
1321}
1322
1323#if MAX_FD == 4
1324static inline FDrive *drv2(FDCtrl *fdctrl)
1325{
1326    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (2 << 2))
1327        return &fdctrl->drives[2];
1328    else
1329        return &fdctrl->drives[1];
1330}
1331
1332static inline FDrive *drv3(FDCtrl *fdctrl)
1333{
1334    if ((fdctrl->tdr & FD_TDR_BOOTSEL) < (3 << 2))
1335        return &fdctrl->drives[3];
1336    else
1337        return &fdctrl->drives[2];
1338}
1339#endif
1340
1341static FDrive *get_drv(FDCtrl *fdctrl, int unit)
1342{
1343    switch (unit) {
1344        case 0: return drv0(fdctrl);
1345        case 1: return drv1(fdctrl);
1346#if MAX_FD == 4
1347        case 2: return drv2(fdctrl);
1348        case 3: return drv3(fdctrl);
1349#endif
1350        default: return NULL;
1351    }
1352}
1353
1354static FDrive *get_cur_drv(FDCtrl *fdctrl)
1355{
1356    return get_drv(fdctrl, fdctrl->cur_drv);
1357}
1358
1359/* Status A register : 0x00 (read-only) */
1360static uint32_t fdctrl_read_statusA(FDCtrl *fdctrl)
1361{
1362    uint32_t retval = fdctrl->sra;
1363
1364    FLOPPY_DPRINTF("status register A: 0x%02x\n", retval);
1365
1366    return retval;
1367}
1368
1369/* Status B register : 0x01 (read-only) */
1370static uint32_t fdctrl_read_statusB(FDCtrl *fdctrl)
1371{
1372    uint32_t retval = fdctrl->srb;
1373
1374    FLOPPY_DPRINTF("status register B: 0x%02x\n", retval);
1375
1376    return retval;
1377}
1378
1379/* Digital output register : 0x02 */
1380static uint32_t fdctrl_read_dor(FDCtrl *fdctrl)
1381{
1382    uint32_t retval = fdctrl->dor;
1383
1384    /* Selected drive */
1385    retval |= fdctrl->cur_drv;
1386    FLOPPY_DPRINTF("digital output register: 0x%02x\n", retval);
1387
1388    return retval;
1389}
1390
1391static void fdctrl_write_dor(FDCtrl *fdctrl, uint32_t value)
1392{
1393    FLOPPY_DPRINTF("digital output register set to 0x%02x\n", value);
1394
1395    /* Motors */
1396    if (value & FD_DOR_MOTEN0)
1397        fdctrl->srb |= FD_SRB_MTR0;
1398    else
1399        fdctrl->srb &= ~FD_SRB_MTR0;
1400    if (value & FD_DOR_MOTEN1)
1401        fdctrl->srb |= FD_SRB_MTR1;
1402    else
1403        fdctrl->srb &= ~FD_SRB_MTR1;
1404
1405    /* Drive */
1406    if (value & 1)
1407        fdctrl->srb |= FD_SRB_DR0;
1408    else
1409        fdctrl->srb &= ~FD_SRB_DR0;
1410
1411    /* Reset */
1412    if (!(value & FD_DOR_nRESET)) {
1413        if (fdctrl->dor & FD_DOR_nRESET) {
1414            FLOPPY_DPRINTF("controller enter RESET state\n");
1415        }
1416    } else {
1417        if (!(fdctrl->dor & FD_DOR_nRESET)) {
1418            FLOPPY_DPRINTF("controller out of RESET state\n");
1419            fdctrl_reset(fdctrl, 1);
1420            fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1421        }
1422    }
1423    /* Selected drive */
1424    fdctrl->cur_drv = value & FD_DOR_SELMASK;
1425
1426    fdctrl->dor = value;
1427}
1428
1429/* Tape drive register : 0x03 */
1430static uint32_t fdctrl_read_tape(FDCtrl *fdctrl)
1431{
1432    uint32_t retval = fdctrl->tdr;
1433
1434    FLOPPY_DPRINTF("tape drive register: 0x%02x\n", retval);
1435
1436    return retval;
1437}
1438
1439static void fdctrl_write_tape(FDCtrl *fdctrl, uint32_t value)
1440{
1441    /* Reset mode */
1442    if (!(fdctrl->dor & FD_DOR_nRESET)) {
1443        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1444        return;
1445    }
1446    FLOPPY_DPRINTF("tape drive register set to 0x%02x\n", value);
1447    /* Disk boot selection indicator */
1448    fdctrl->tdr = value & FD_TDR_BOOTSEL;
1449    /* Tape indicators: never allow */
1450}
1451
1452/* Main status register : 0x04 (read) */
1453static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl)
1454{
1455    uint32_t retval = fdctrl->msr;
1456
1457    fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1458    fdctrl->dor |= FD_DOR_nRESET;
1459
1460    FLOPPY_DPRINTF("main status register: 0x%02x\n", retval);
1461
1462    return retval;
1463}
1464
1465/* Data select rate register : 0x04 (write) */
1466static void fdctrl_write_rate(FDCtrl *fdctrl, uint32_t value)
1467{
1468    /* Reset mode */
1469    if (!(fdctrl->dor & FD_DOR_nRESET)) {
1470        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1471        return;
1472    }
1473    FLOPPY_DPRINTF("select rate register set to 0x%02x\n", value);
1474    /* Reset: autoclear */
1475    if (value & FD_DSR_SWRESET) {
1476        fdctrl->dor &= ~FD_DOR_nRESET;
1477        fdctrl_reset(fdctrl, 1);
1478        fdctrl->dor |= FD_DOR_nRESET;
1479    }
1480    if (value & FD_DSR_PWRDOWN) {
1481        fdctrl_reset(fdctrl, 1);
1482    }
1483    fdctrl->dsr = value;
1484}
1485
1486/* Configuration control register: 0x07 (write) */
1487static void fdctrl_write_ccr(FDCtrl *fdctrl, uint32_t value)
1488{
1489    /* Reset mode */
1490    if (!(fdctrl->dor & FD_DOR_nRESET)) {
1491        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
1492        return;
1493    }
1494    FLOPPY_DPRINTF("configuration control register set to 0x%02x\n", value);
1495
1496    /* Only the rate selection bits used in AT mode, and we
1497     * store those in the DSR.
1498     */
1499    fdctrl->dsr = (fdctrl->dsr & ~FD_DSR_DRATEMASK) |
1500                  (value & FD_DSR_DRATEMASK);
1501}
1502
1503static int fdctrl_media_changed(FDrive *drv)
1504{
1505    return drv->media_changed;
1506}
1507
1508/* Digital input register : 0x07 (read-only) */
1509static uint32_t fdctrl_read_dir(FDCtrl *fdctrl)
1510{
1511    uint32_t retval = 0;
1512
1513    if (fdctrl_media_changed(get_cur_drv(fdctrl))) {
1514        retval |= FD_DIR_DSKCHG;
1515    }
1516    if (retval != 0) {
1517        FLOPPY_DPRINTF("Floppy digital input register: 0x%02x\n", retval);
1518    }
1519
1520    return retval;
1521}
1522
1523/* Clear the FIFO and update the state for receiving the next command */
1524static void fdctrl_to_command_phase(FDCtrl *fdctrl)
1525{
1526    fdctrl->phase = FD_PHASE_COMMAND;
1527    fdctrl->data_dir = FD_DIR_WRITE;
1528    fdctrl->data_pos = 0;
1529    fdctrl->data_len = 1; /* Accept command byte, adjust for params later */
1530    fdctrl->msr &= ~(FD_MSR_CMDBUSY | FD_MSR_DIO);
1531    fdctrl->msr |= FD_MSR_RQM;
1532}
1533
1534/* Update the state to allow the guest to read out the command status.
1535 * @fifo_len is the number of result bytes to be read out. */
1536static void fdctrl_to_result_phase(FDCtrl *fdctrl, int fifo_len)
1537{
1538    fdctrl->phase = FD_PHASE_RESULT;
1539    fdctrl->data_dir = FD_DIR_READ;
1540    fdctrl->data_len = fifo_len;
1541    fdctrl->data_pos = 0;
1542    fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
1543}
1544
1545/* Set an error: unimplemented/unknown command */
1546static void fdctrl_unimplemented(FDCtrl *fdctrl, int direction)
1547{
1548    qemu_log_mask(LOG_UNIMP, "fdc: unimplemented command 0x%02x\n",
1549                  fdctrl->fifo[0]);
1550    fdctrl->fifo[0] = FD_SR0_INVCMD;
1551    fdctrl_to_result_phase(fdctrl, 1);
1552}
1553
1554/* Seek to next sector
1555 * returns 0 when end of track reached (for DBL_SIDES on head 1)
1556 * otherwise returns 1
1557 */
1558static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl, FDrive *cur_drv)
1559{
1560    FLOPPY_DPRINTF("seek to next sector (%d %02x %02x => %d)\n",
1561                   cur_drv->head, cur_drv->track, cur_drv->sect,
1562                   fd_sector(cur_drv));
1563    /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
1564       error in fact */
1565    uint8_t new_head = cur_drv->head;
1566    uint8_t new_track = cur_drv->track;
1567    uint8_t new_sect = cur_drv->sect;
1568
1569    int ret = 1;
1570
1571    if (new_sect >= cur_drv->last_sect ||
1572        new_sect == fdctrl->eot) {
1573        new_sect = 1;
1574        if (FD_MULTI_TRACK(fdctrl->data_state)) {
1575            if (new_head == 0 &&
1576                (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
1577                new_head = 1;
1578            } else {
1579                new_head = 0;
1580                new_track++;
1581                fdctrl->status0 |= FD_SR0_SEEK;
1582                if ((cur_drv->flags & FDISK_DBL_SIDES) == 0) {
1583                    ret = 0;
1584                }
1585            }
1586        } else {
1587            fdctrl->status0 |= FD_SR0_SEEK;
1588            new_track++;
1589            ret = 0;
1590        }
1591        if (ret == 1) {
1592            FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
1593                    new_head, new_track, new_sect, fd_sector(cur_drv));
1594        }
1595    } else {
1596        new_sect++;
1597    }
1598    fd_seek(cur_drv, new_head, new_track, new_sect, 1);
1599    return ret;
1600}
1601
1602/* Callback for transfer end (stop or abort) */
1603static void fdctrl_stop_transfer(FDCtrl *fdctrl, uint8_t status0,
1604                                 uint8_t status1, uint8_t status2)
1605{
1606    FDrive *cur_drv;
1607    cur_drv = get_cur_drv(fdctrl);
1608
1609    fdctrl->status0 &= ~(FD_SR0_DS0 | FD_SR0_DS1 | FD_SR0_HEAD);
1610    fdctrl->status0 |= GET_CUR_DRV(fdctrl);
1611    if (cur_drv->head) {
1612        fdctrl->status0 |= FD_SR0_HEAD;
1613    }
1614    fdctrl->status0 |= status0;
1615
1616    FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
1617                   status0, status1, status2, fdctrl->status0);
1618    fdctrl->fifo[0] = fdctrl->status0;
1619    fdctrl->fifo[1] = status1;
1620    fdctrl->fifo[2] = status2;
1621    fdctrl->fifo[3] = cur_drv->track;
1622    fdctrl->fifo[4] = cur_drv->head;
1623    fdctrl->fifo[5] = cur_drv->sect;
1624    fdctrl->fifo[6] = FD_SECTOR_SC;
1625    fdctrl->data_dir = FD_DIR_READ;
1626    if (fdctrl->dma_chann != -1 && !(fdctrl->msr & FD_MSR_NONDMA)) {
1627        IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
1628        k->release_DREQ(fdctrl->dma, fdctrl->dma_chann);
1629    }
1630    fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
1631    fdctrl->msr &= ~FD_MSR_NONDMA;
1632
1633    fdctrl_to_result_phase(fdctrl, 7);
1634    fdctrl_raise_irq(fdctrl);
1635}
1636
1637/* Prepare a data transfer (either DMA or FIFO) */
1638static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
1639{
1640    FDrive *cur_drv;
1641    uint8_t kh, kt, ks;
1642
1643    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
1644    cur_drv = get_cur_drv(fdctrl);
1645    kt = fdctrl->fifo[2];
1646    kh = fdctrl->fifo[3];
1647    ks = fdctrl->fifo[4];
1648    FLOPPY_DPRINTF("Start transfer at %d %d %02x %02x (%d)\n",
1649                   GET_CUR_DRV(fdctrl), kh, kt, ks,
1650                   fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
1651                                  NUM_SIDES(cur_drv)));
1652    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
1653    case 2:
1654        /* sect too big */
1655        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1656        fdctrl->fifo[3] = kt;
1657        fdctrl->fifo[4] = kh;
1658        fdctrl->fifo[5] = ks;
1659        return;
1660    case 3:
1661        /* track too big */
1662        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
1663        fdctrl->fifo[3] = kt;
1664        fdctrl->fifo[4] = kh;
1665        fdctrl->fifo[5] = ks;
1666        return;
1667    case 4:
1668        /* No seek enabled */
1669        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1670        fdctrl->fifo[3] = kt;
1671        fdctrl->fifo[4] = kh;
1672        fdctrl->fifo[5] = ks;
1673        return;
1674    case 1:
1675        fdctrl->status0 |= FD_SR0_SEEK;
1676        break;
1677    default:
1678        break;
1679    }
1680
1681    /* Check the data rate. If the programmed data rate does not match
1682     * the currently inserted medium, the operation has to fail. */
1683    if (fdctrl->check_media_rate &&
1684        (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
1685        FLOPPY_DPRINTF("data rate mismatch (fdc=%d, media=%d)\n",
1686                       fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
1687        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
1688        fdctrl->fifo[3] = kt;
1689        fdctrl->fifo[4] = kh;
1690        fdctrl->fifo[5] = ks;
1691        return;
1692    }
1693
1694    /* Set the FIFO state */
1695    fdctrl->data_dir = direction;
1696    fdctrl->data_pos = 0;
1697    assert(fdctrl->msr & FD_MSR_CMDBUSY);
1698    if (fdctrl->fifo[0] & 0x80)
1699        fdctrl->data_state |= FD_STATE_MULTI;
1700    else
1701        fdctrl->data_state &= ~FD_STATE_MULTI;
1702    if (fdctrl->fifo[5] == 0) {
1703        fdctrl->data_len = fdctrl->fifo[8];
1704    } else {
1705        int tmp;
1706        fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
1707        tmp = (fdctrl->fifo[6] - ks + 1);
1708        if (fdctrl->fifo[0] & 0x80)
1709            tmp += fdctrl->fifo[6];
1710        fdctrl->data_len *= tmp;
1711    }
1712    fdctrl->eot = fdctrl->fifo[6];
1713    if (fdctrl->dor & FD_DOR_DMAEN) {
1714        IsaDmaTransferMode dma_mode;
1715        IsaDmaClass *k = ISADMA_GET_CLASS(fdctrl->dma);
1716        bool dma_mode_ok;
1717        /* DMA transfer are enabled. Check if DMA channel is well programmed */
1718        dma_mode = k->get_transfer_mode(fdctrl->dma, fdctrl->dma_chann);
1719        FLOPPY_DPRINTF("dma_mode=%d direction=%d (%d - %d)\n",
1720                       dma_mode, direction,
1721                       (128 << fdctrl->fifo[5]) *
1722                       (cur_drv->last_sect - ks + 1), fdctrl->data_len);
1723        switch (direction) {
1724        case FD_DIR_SCANE:
1725        case FD_DIR_SCANL:
1726        case FD_DIR_SCANH:
1727            dma_mode_ok = (dma_mode == ISADMA_TRANSFER_VERIFY);
1728            break;
1729        case FD_DIR_WRITE:
1730            dma_mode_ok = (dma_mode == ISADMA_TRANSFER_WRITE);
1731            break;
1732        case FD_DIR_READ:
1733            dma_mode_ok = (dma_mode == ISADMA_TRANSFER_READ);
1734            break;
1735        case FD_DIR_VERIFY:
1736            dma_mode_ok = true;
1737            break;
1738        default:
1739            dma_mode_ok = false;
1740            break;
1741        }
1742        if (dma_mode_ok) {
1743            /* No access is allowed until DMA transfer has completed */
1744            fdctrl->msr &= ~FD_MSR_RQM;
1745            if (direction != FD_DIR_VERIFY) {
1746                /* Now, we just have to wait for the DMA controller to
1747                 * recall us...
1748                 */
1749                k->hold_DREQ(fdctrl->dma, fdctrl->dma_chann);
1750                k->schedule(fdctrl->dma);
1751            } else {
1752                /* Start transfer */
1753                fdctrl_transfer_handler(fdctrl, fdctrl->dma_chann, 0,
1754                                        fdctrl->data_len);
1755            }
1756            return;
1757        } else {
1758            FLOPPY_DPRINTF("bad dma_mode=%d direction=%d\n", dma_mode,
1759                           direction);
1760        }
1761    }
1762    FLOPPY_DPRINTF("start non-DMA transfer\n");
1763    fdctrl->msr |= FD_MSR_NONDMA | FD_MSR_RQM;
1764    if (direction != FD_DIR_WRITE)
1765        fdctrl->msr |= FD_MSR_DIO;
1766    /* IO based transfer: calculate len */
1767    fdctrl_raise_irq(fdctrl);
1768}
1769
1770/* Prepare a transfer of deleted data */
1771static void fdctrl_start_transfer_del(FDCtrl *fdctrl, int direction)
1772{
1773    qemu_log_mask(LOG_UNIMP, "fdctrl_start_transfer_del() unimplemented\n");
1774
1775    /* We don't handle deleted data,
1776     * so we don't return *ANYTHING*
1777     */
1778    fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1779}
1780
1781/* handlers for DMA transfers */
1782static int fdctrl_transfer_handler (void *opaque, int nchan,
1783                                    int dma_pos, int dma_len)
1784{
1785    FDCtrl *fdctrl;
1786    FDrive *cur_drv;
1787    int len, start_pos, rel_pos;
1788    uint8_t status0 = 0x00, status1 = 0x00, status2 = 0x00;
1789    IsaDmaClass *k;
1790
1791    fdctrl = opaque;
1792    if (fdctrl->msr & FD_MSR_RQM) {
1793        FLOPPY_DPRINTF("Not in DMA transfer mode !\n");
1794        return 0;
1795    }
1796    k = ISADMA_GET_CLASS(fdctrl->dma);
1797    cur_drv = get_cur_drv(fdctrl);
1798    if (fdctrl->data_dir == FD_DIR_SCANE || fdctrl->data_dir == FD_DIR_SCANL ||
1799        fdctrl->data_dir == FD_DIR_SCANH)
1800        status2 = FD_SR2_SNS;
1801    if (dma_len > fdctrl->data_len)
1802        dma_len = fdctrl->data_len;
1803    if (cur_drv->blk == NULL) {
1804        if (fdctrl->data_dir == FD_DIR_WRITE)
1805            fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1806        else
1807            fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1808        len = 0;
1809        goto transfer_error;
1810    }
1811    rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
1812    for (start_pos = fdctrl->data_pos; fdctrl->data_pos < dma_len;) {
1813        len = dma_len - fdctrl->data_pos;
1814        if (len + rel_pos > FD_SECTOR_LEN)
1815            len = FD_SECTOR_LEN - rel_pos;
1816        FLOPPY_DPRINTF("copy %d bytes (%d %d %d) %d pos %d %02x "
1817                       "(%d-0x%08x 0x%08x)\n", len, dma_len, fdctrl->data_pos,
1818                       fdctrl->data_len, GET_CUR_DRV(fdctrl), cur_drv->head,
1819                       cur_drv->track, cur_drv->sect, fd_sector(cur_drv),
1820                       fd_sector(cur_drv) * FD_SECTOR_LEN);
1821        if (fdctrl->data_dir != FD_DIR_WRITE ||
1822            len < FD_SECTOR_LEN || rel_pos != 0) {
1823            /* READ & SCAN commands and realign to a sector for WRITE */
1824            if (blk_pread(cur_drv->blk, fd_offset(cur_drv),
1825                          fdctrl->fifo, BDRV_SECTOR_SIZE) < 0) {
1826                FLOPPY_DPRINTF("Floppy: error getting sector %d\n",
1827                               fd_sector(cur_drv));
1828                /* Sure, image size is too small... */
1829                memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
1830            }
1831        }
1832        switch (fdctrl->data_dir) {
1833        case FD_DIR_READ:
1834            /* READ commands */
1835            k->write_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
1836                            fdctrl->data_pos, len);
1837            break;
1838        case FD_DIR_WRITE:
1839            /* WRITE commands */
1840            if (cur_drv->ro) {
1841                /* Handle readonly medium early, no need to do DMA, touch the
1842                 * LED or attempt any writes. A real floppy doesn't attempt
1843                 * to write to readonly media either. */
1844                fdctrl_stop_transfer(fdctrl,
1845                                     FD_SR0_ABNTERM | FD_SR0_SEEK, FD_SR1_NW,
1846                                     0x00);
1847                goto transfer_error;
1848            }
1849
1850            k->read_memory(fdctrl->dma, nchan, fdctrl->fifo + rel_pos,
1851                           fdctrl->data_pos, len);
1852            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv),
1853                           fdctrl->fifo, BDRV_SECTOR_SIZE, 0) < 0) {
1854                FLOPPY_DPRINTF("error writing sector %d\n",
1855                               fd_sector(cur_drv));
1856                fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
1857                goto transfer_error;
1858            }
1859            break;
1860        case FD_DIR_VERIFY:
1861            /* VERIFY commands */
1862            break;
1863        default:
1864            /* SCAN commands */
1865            {
1866                uint8_t tmpbuf[FD_SECTOR_LEN];
1867                int ret;
1868                k->read_memory(fdctrl->dma, nchan, tmpbuf, fdctrl->data_pos,
1869                               len);
1870                ret = memcmp(tmpbuf, fdctrl->fifo + rel_pos, len);
1871                if (ret == 0) {
1872                    status2 = FD_SR2_SEH;
1873                    goto end_transfer;
1874                }
1875                if ((ret < 0 && fdctrl->data_dir == FD_DIR_SCANL) ||
1876                    (ret > 0 && fdctrl->data_dir == FD_DIR_SCANH)) {
1877                    status2 = 0x00;
1878                    goto end_transfer;
1879                }
1880            }
1881            break;
1882        }
1883        fdctrl->data_pos += len;
1884        rel_pos = fdctrl->data_pos % FD_SECTOR_LEN;
1885        if (rel_pos == 0) {
1886            /* Seek to next sector */
1887            if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv))
1888                break;
1889        }
1890    }
1891 end_transfer:
1892    len = fdctrl->data_pos - start_pos;
1893    FLOPPY_DPRINTF("end transfer %d %d %d\n",
1894                   fdctrl->data_pos, len, fdctrl->data_len);
1895    if (fdctrl->data_dir == FD_DIR_SCANE ||
1896        fdctrl->data_dir == FD_DIR_SCANL ||
1897        fdctrl->data_dir == FD_DIR_SCANH)
1898        status2 = FD_SR2_SEH;
1899    fdctrl->data_len -= len;
1900    fdctrl_stop_transfer(fdctrl, status0, status1, status2);
1901 transfer_error:
1902
1903    return len;
1904}
1905
1906/* Data register : 0x05 */
1907static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
1908{
1909    FDrive *cur_drv;
1910    uint32_t retval = 0;
1911    uint32_t pos;
1912
1913    cur_drv = get_cur_drv(fdctrl);
1914    fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1915    if (!(fdctrl->msr & FD_MSR_RQM) || !(fdctrl->msr & FD_MSR_DIO)) {
1916        FLOPPY_DPRINTF("error: controller not ready for reading\n");
1917        return 0;
1918    }
1919
1920    /* If data_len spans multiple sectors, the current position in the FIFO
1921     * wraps around while fdctrl->data_pos is the real position in the whole
1922     * request. */
1923    pos = fdctrl->data_pos;
1924    pos %= FD_SECTOR_LEN;
1925
1926    switch (fdctrl->phase) {
1927    case FD_PHASE_EXECUTION:
1928        assert(fdctrl->msr & FD_MSR_NONDMA);
1929        if (pos == 0) {
1930            if (fdctrl->data_pos != 0)
1931                if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
1932                    FLOPPY_DPRINTF("error seeking to next sector %d\n",
1933                                   fd_sector(cur_drv));
1934                    return 0;
1935                }
1936            if (blk_pread(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
1937                          BDRV_SECTOR_SIZE)
1938                < 0) {
1939                FLOPPY_DPRINTF("error getting sector %d\n",
1940                               fd_sector(cur_drv));
1941                /* Sure, image size is too small... */
1942                memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
1943            }
1944        }
1945
1946        if (++fdctrl->data_pos == fdctrl->data_len) {
1947            fdctrl->msr &= ~FD_MSR_RQM;
1948            fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
1949        }
1950        break;
1951
1952    case FD_PHASE_RESULT:
1953        assert(!(fdctrl->msr & FD_MSR_NONDMA));
1954        if (++fdctrl->data_pos == fdctrl->data_len) {
1955            fdctrl->msr &= ~FD_MSR_RQM;
1956            fdctrl_to_command_phase(fdctrl);
1957            fdctrl_reset_irq(fdctrl);
1958        }
1959        break;
1960
1961    case FD_PHASE_COMMAND:
1962    default:
1963        abort();
1964    }
1965
1966    retval = fdctrl->fifo[pos];
1967    FLOPPY_DPRINTF("data register: 0x%02x\n", retval);
1968
1969    return retval;
1970}
1971
1972static void fdctrl_format_sector(FDCtrl *fdctrl)
1973{
1974    FDrive *cur_drv;
1975    uint8_t kh, kt, ks;
1976
1977    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
1978    cur_drv = get_cur_drv(fdctrl);
1979    kt = fdctrl->fifo[6];
1980    kh = fdctrl->fifo[7];
1981    ks = fdctrl->fifo[8];
1982    FLOPPY_DPRINTF("format sector at %d %d %02x %02x (%d)\n",
1983                   GET_CUR_DRV(fdctrl), kh, kt, ks,
1984                   fd_sector_calc(kh, kt, ks, cur_drv->last_sect,
1985                                  NUM_SIDES(cur_drv)));
1986    switch (fd_seek(cur_drv, kh, kt, ks, fdctrl->config & FD_CONFIG_EIS)) {
1987    case 2:
1988        /* sect too big */
1989        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
1990        fdctrl->fifo[3] = kt;
1991        fdctrl->fifo[4] = kh;
1992        fdctrl->fifo[5] = ks;
1993        return;
1994    case 3:
1995        /* track too big */
1996        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_EC, 0x00);
1997        fdctrl->fifo[3] = kt;
1998        fdctrl->fifo[4] = kh;
1999        fdctrl->fifo[5] = ks;
2000        return;
2001    case 4:
2002        /* No seek enabled */
2003        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, 0x00, 0x00);
2004        fdctrl->fifo[3] = kt;
2005        fdctrl->fifo[4] = kh;
2006        fdctrl->fifo[5] = ks;
2007        return;
2008    case 1:
2009        fdctrl->status0 |= FD_SR0_SEEK;
2010        break;
2011    default:
2012        break;
2013    }
2014    memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
2015    if (cur_drv->blk == NULL ||
2016        blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
2017                   BDRV_SECTOR_SIZE, 0) < 0) {
2018        FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
2019        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
2020    } else {
2021        if (cur_drv->sect == cur_drv->last_sect) {
2022            fdctrl->data_state &= ~FD_STATE_FORMAT;
2023            /* Last sector done */
2024            fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2025        } else {
2026            /* More to do */
2027            fdctrl->data_pos = 0;
2028            fdctrl->data_len = 4;
2029        }
2030    }
2031}
2032
2033static void fdctrl_handle_lock(FDCtrl *fdctrl, int direction)
2034{
2035    fdctrl->lock = (fdctrl->fifo[0] & 0x80) ? 1 : 0;
2036    fdctrl->fifo[0] = fdctrl->lock << 4;
2037    fdctrl_to_result_phase(fdctrl, 1);
2038}
2039
2040static void fdctrl_handle_dumpreg(FDCtrl *fdctrl, int direction)
2041{
2042    FDrive *cur_drv = get_cur_drv(fdctrl);
2043
2044    /* Drives position */
2045    fdctrl->fifo[0] = drv0(fdctrl)->track;
2046    fdctrl->fifo[1] = drv1(fdctrl)->track;
2047#if MAX_FD == 4
2048    fdctrl->fifo[2] = drv2(fdctrl)->track;
2049    fdctrl->fifo[3] = drv3(fdctrl)->track;
2050#else
2051    fdctrl->fifo[2] = 0;
2052    fdctrl->fifo[3] = 0;
2053#endif
2054    /* timers */
2055    fdctrl->fifo[4] = fdctrl->timer0;
2056    fdctrl->fifo[5] = (fdctrl->timer1 << 1) | (fdctrl->dor & FD_DOR_DMAEN ? 1 : 0);
2057    fdctrl->fifo[6] = cur_drv->last_sect;
2058    fdctrl->fifo[7] = (fdctrl->lock << 7) |
2059        (cur_drv->perpendicular << 2);
2060    fdctrl->fifo[8] = fdctrl->config;
2061    fdctrl->fifo[9] = fdctrl->precomp_trk;
2062    fdctrl_to_result_phase(fdctrl, 10);
2063}
2064
2065static void fdctrl_handle_version(FDCtrl *fdctrl, int direction)
2066{
2067    /* Controller's version */
2068    fdctrl->fifo[0] = fdctrl->version;
2069    fdctrl_to_result_phase(fdctrl, 1);
2070}
2071
2072static void fdctrl_handle_partid(FDCtrl *fdctrl, int direction)
2073{
2074    fdctrl->fifo[0] = 0x41; /* Stepping 1 */
2075    fdctrl_to_result_phase(fdctrl, 1);
2076}
2077
2078static void fdctrl_handle_restore(FDCtrl *fdctrl, int direction)
2079{
2080    FDrive *cur_drv = get_cur_drv(fdctrl);
2081
2082    /* Drives position */
2083    drv0(fdctrl)->track = fdctrl->fifo[3];
2084    drv1(fdctrl)->track = fdctrl->fifo[4];
2085#if MAX_FD == 4
2086    drv2(fdctrl)->track = fdctrl->fifo[5];
2087    drv3(fdctrl)->track = fdctrl->fifo[6];
2088#endif
2089    /* timers */
2090    fdctrl->timer0 = fdctrl->fifo[7];
2091    fdctrl->timer1 = fdctrl->fifo[8];
2092    cur_drv->last_sect = fdctrl->fifo[9];
2093    fdctrl->lock = fdctrl->fifo[10] >> 7;
2094    cur_drv->perpendicular = (fdctrl->fifo[10] >> 2) & 0xF;
2095    fdctrl->config = fdctrl->fifo[11];
2096    fdctrl->precomp_trk = fdctrl->fifo[12];
2097    fdctrl->pwrd = fdctrl->fifo[13];
2098    fdctrl_to_command_phase(fdctrl);
2099}
2100
2101static void fdctrl_handle_save(FDCtrl *fdctrl, int direction)
2102{
2103    FDrive *cur_drv = get_cur_drv(fdctrl);
2104
2105    fdctrl->fifo[0] = 0;
2106    fdctrl->fifo[1] = 0;
2107    /* Drives position */
2108    fdctrl->fifo[2] = drv0(fdctrl)->track;
2109    fdctrl->fifo[3] = drv1(fdctrl)->track;
2110#if MAX_FD == 4
2111    fdctrl->fifo[4] = drv2(fdctrl)->track;
2112    fdctrl->fifo[5] = drv3(fdctrl)->track;
2113#else
2114    fdctrl->fifo[4] = 0;
2115    fdctrl->fifo[5] = 0;
2116#endif
2117    /* timers */
2118    fdctrl->fifo[6] = fdctrl->timer0;
2119    fdctrl->fifo[7] = fdctrl->timer1;
2120    fdctrl->fifo[8] = cur_drv->last_sect;
2121    fdctrl->fifo[9] = (fdctrl->lock << 7) |
2122        (cur_drv->perpendicular << 2);
2123    fdctrl->fifo[10] = fdctrl->config;
2124    fdctrl->fifo[11] = fdctrl->precomp_trk;
2125    fdctrl->fifo[12] = fdctrl->pwrd;
2126    fdctrl->fifo[13] = 0;
2127    fdctrl->fifo[14] = 0;
2128    fdctrl_to_result_phase(fdctrl, 15);
2129}
2130
2131static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction)
2132{
2133    FDrive *cur_drv = get_cur_drv(fdctrl);
2134
2135    cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
2136    timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
2137             (NANOSECONDS_PER_SECOND / 50));
2138}
2139
2140static void fdctrl_handle_format_track(FDCtrl *fdctrl, int direction)
2141{
2142    FDrive *cur_drv;
2143
2144    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2145    cur_drv = get_cur_drv(fdctrl);
2146    fdctrl->data_state |= FD_STATE_FORMAT;
2147    if (fdctrl->fifo[0] & 0x80)
2148        fdctrl->data_state |= FD_STATE_MULTI;
2149    else
2150        fdctrl->data_state &= ~FD_STATE_MULTI;
2151    cur_drv->bps =
2152        fdctrl->fifo[2] > 7 ? 16384 : 128 << fdctrl->fifo[2];
2153#if 0
2154    cur_drv->last_sect =
2155        cur_drv->flags & FDISK_DBL_SIDES ? fdctrl->fifo[3] :
2156        fdctrl->fifo[3] / 2;
2157#else
2158    cur_drv->last_sect = fdctrl->fifo[3];
2159#endif
2160    /* TODO: implement format using DMA expected by the Bochs BIOS
2161     * and Linux fdformat (read 3 bytes per sector via DMA and fill
2162     * the sector with the specified fill byte
2163     */
2164    fdctrl->data_state &= ~FD_STATE_FORMAT;
2165    fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2166}
2167
2168static void fdctrl_handle_specify(FDCtrl *fdctrl, int direction)
2169{
2170    fdctrl->timer0 = (fdctrl->fifo[1] >> 4) & 0xF;
2171    fdctrl->timer1 = fdctrl->fifo[2] >> 1;
2172    if (fdctrl->fifo[2] & 1)
2173        fdctrl->dor &= ~FD_DOR_DMAEN;
2174    else
2175        fdctrl->dor |= FD_DOR_DMAEN;
2176    /* No result back */
2177    fdctrl_to_command_phase(fdctrl);
2178}
2179
2180static void fdctrl_handle_sense_drive_status(FDCtrl *fdctrl, int direction)
2181{
2182    FDrive *cur_drv;
2183
2184    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2185    cur_drv = get_cur_drv(fdctrl);
2186    cur_drv->head = (fdctrl->fifo[1] >> 2) & 1;
2187    /* 1 Byte status back */
2188    fdctrl->fifo[0] = (cur_drv->ro << 6) |
2189        (cur_drv->track == 0 ? 0x10 : 0x00) |
2190        (cur_drv->head << 2) |
2191        GET_CUR_DRV(fdctrl) |
2192        0x28;
2193    fdctrl_to_result_phase(fdctrl, 1);
2194}
2195
2196static void fdctrl_handle_recalibrate(FDCtrl *fdctrl, int direction)
2197{
2198    FDrive *cur_drv;
2199
2200    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2201    cur_drv = get_cur_drv(fdctrl);
2202    fd_recalibrate(cur_drv);
2203    fdctrl_to_command_phase(fdctrl);
2204    /* Raise Interrupt */
2205    fdctrl->status0 |= FD_SR0_SEEK;
2206    fdctrl_raise_irq(fdctrl);
2207}
2208
2209static void fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
2210{
2211    FDrive *cur_drv = get_cur_drv(fdctrl);
2212
2213    if (fdctrl->reset_sensei > 0) {
2214        fdctrl->fifo[0] =
2215            FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
2216        fdctrl->reset_sensei--;
2217    } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
2218        fdctrl->fifo[0] = FD_SR0_INVCMD;
2219        fdctrl_to_result_phase(fdctrl, 1);
2220        return;
2221    } else {
2222        fdctrl->fifo[0] =
2223                (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
2224                | GET_CUR_DRV(fdctrl);
2225    }
2226
2227    fdctrl->fifo[1] = cur_drv->track;
2228    fdctrl_to_result_phase(fdctrl, 2);
2229    fdctrl_reset_irq(fdctrl);
2230    fdctrl->status0 = FD_SR0_RDYCHG;
2231}
2232
2233static void fdctrl_handle_seek(FDCtrl *fdctrl, int direction)
2234{
2235    FDrive *cur_drv;
2236
2237    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2238    cur_drv = get_cur_drv(fdctrl);
2239    fdctrl_to_command_phase(fdctrl);
2240    /* The seek command just sends step pulses to the drive and doesn't care if
2241     * there is a medium inserted of if it's banging the head against the drive.
2242     */
2243    fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
2244    /* Raise Interrupt */
2245    fdctrl->status0 |= FD_SR0_SEEK;
2246    fdctrl_raise_irq(fdctrl);
2247}
2248
2249static void fdctrl_handle_perpendicular_mode(FDCtrl *fdctrl, int direction)
2250{
2251    FDrive *cur_drv = get_cur_drv(fdctrl);
2252
2253    if (fdctrl->fifo[1] & 0x80)
2254        cur_drv->perpendicular = fdctrl->fifo[1] & 0x7;
2255    /* No result back */
2256    fdctrl_to_command_phase(fdctrl);
2257}
2258
2259static void fdctrl_handle_configure(FDCtrl *fdctrl, int direction)
2260{
2261    fdctrl->config = fdctrl->fifo[2];
2262    fdctrl->precomp_trk =  fdctrl->fifo[3];
2263    /* No result back */
2264    fdctrl_to_command_phase(fdctrl);
2265}
2266
2267static void fdctrl_handle_powerdown_mode(FDCtrl *fdctrl, int direction)
2268{
2269    fdctrl->pwrd = fdctrl->fifo[1];
2270    fdctrl->fifo[0] = fdctrl->fifo[1];
2271    fdctrl_to_result_phase(fdctrl, 1);
2272}
2273
2274static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
2275{
2276    /* No result back */
2277    fdctrl_to_command_phase(fdctrl);
2278}
2279
2280static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
2281{
2282    FDrive *cur_drv = get_cur_drv(fdctrl);
2283    uint32_t pos;
2284
2285    pos = fdctrl->data_pos - 1;
2286    pos %= FD_SECTOR_LEN;
2287    if (fdctrl->fifo[pos] & 0x80) {
2288        /* Command parameters done */
2289        if (fdctrl->fifo[pos] & 0x40) {
2290            fdctrl->fifo[0] = fdctrl->fifo[1];
2291            fdctrl->fifo[2] = 0;
2292            fdctrl->fifo[3] = 0;
2293            fdctrl_to_result_phase(fdctrl, 4);
2294        } else {
2295            fdctrl_to_command_phase(fdctrl);
2296        }
2297    } else if (fdctrl->data_len > 7) {
2298        /* ERROR */
2299        fdctrl->fifo[0] = 0x80 |
2300            (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
2301        fdctrl_to_result_phase(fdctrl, 1);
2302    }
2303}
2304
2305static void fdctrl_handle_relative_seek_in(FDCtrl *fdctrl, int direction)
2306{
2307    FDrive *cur_drv;
2308
2309    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2310    cur_drv = get_cur_drv(fdctrl);
2311    if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
2312        fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
2313                cur_drv->sect, 1);
2314    } else {
2315        fd_seek(cur_drv, cur_drv->head,
2316                cur_drv->track + fdctrl->fifo[2], cur_drv->sect, 1);
2317    }
2318    fdctrl_to_command_phase(fdctrl);
2319    /* Raise Interrupt */
2320    fdctrl->status0 |= FD_SR0_SEEK;
2321    fdctrl_raise_irq(fdctrl);
2322}
2323
2324static void fdctrl_handle_relative_seek_out(FDCtrl *fdctrl, int direction)
2325{
2326    FDrive *cur_drv;
2327
2328    SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
2329    cur_drv = get_cur_drv(fdctrl);
2330    if (fdctrl->fifo[2] > cur_drv->track) {
2331        fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
2332    } else {
2333        fd_seek(cur_drv, cur_drv->head,
2334                cur_drv->track - fdctrl->fifo[2], cur_drv->sect, 1);
2335    }
2336    fdctrl_to_command_phase(fdctrl);
2337    /* Raise Interrupt */
2338    fdctrl->status0 |= FD_SR0_SEEK;
2339    fdctrl_raise_irq(fdctrl);
2340}
2341
2342/*
2343 * Handlers for the execution phase of each command
2344 */
2345typedef struct FDCtrlCommand {
2346    uint8_t value;
2347    uint8_t mask;
2348    const char* name;
2349    int parameters;
2350    void (*handler)(FDCtrl *fdctrl, int direction);
2351    int direction;
2352} FDCtrlCommand;
2353
2354static const FDCtrlCommand handlers[] = {
2355    { FD_CMD_READ, 0x1f, "READ", 8, fdctrl_start_transfer, FD_DIR_READ },
2356    { FD_CMD_WRITE, 0x3f, "WRITE", 8, fdctrl_start_transfer, FD_DIR_WRITE },
2357    { FD_CMD_SEEK, 0xff, "SEEK", 2, fdctrl_handle_seek },
2358    { FD_CMD_SENSE_INTERRUPT_STATUS, 0xff, "SENSE INTERRUPT STATUS", 0, fdctrl_handle_sense_interrupt_status },
2359    { FD_CMD_RECALIBRATE, 0xff, "RECALIBRATE", 1, fdctrl_handle_recalibrate },
2360    { FD_CMD_FORMAT_TRACK, 0xbf, "FORMAT TRACK", 5, fdctrl_handle_format_track },
2361    { FD_CMD_READ_TRACK, 0xbf, "READ TRACK", 8, fdctrl_start_transfer, FD_DIR_READ },
2362    { FD_CMD_RESTORE, 0xff, "RESTORE", 17, fdctrl_handle_restore }, /* part of READ DELETED DATA */
2363    { FD_CMD_SAVE, 0xff, "SAVE", 0, fdctrl_handle_save }, /* part of READ DELETED DATA */
2364    { FD_CMD_READ_DELETED, 0x1f, "READ DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_READ },
2365    { FD_CMD_SCAN_EQUAL, 0x1f, "SCAN EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANE },
2366    { FD_CMD_VERIFY, 0x1f, "VERIFY", 8, fdctrl_start_transfer, FD_DIR_VERIFY },
2367    { FD_CMD_SCAN_LOW_OR_EQUAL, 0x1f, "SCAN LOW OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANL },
2368    { FD_CMD_SCAN_HIGH_OR_EQUAL, 0x1f, "SCAN HIGH OR EQUAL", 8, fdctrl_start_transfer, FD_DIR_SCANH },
2369    { FD_CMD_WRITE_DELETED, 0x3f, "WRITE DELETED DATA", 8, fdctrl_start_transfer_del, FD_DIR_WRITE },
2370    { FD_CMD_READ_ID, 0xbf, "READ ID", 1, fdctrl_handle_readid },
2371    { FD_CMD_SPECIFY, 0xff, "SPECIFY", 2, fdctrl_handle_specify },
2372    { FD_CMD_SENSE_DRIVE_STATUS, 0xff, "SENSE DRIVE STATUS", 1, fdctrl_handle_sense_drive_status },
2373    { FD_CMD_PERPENDICULAR_MODE, 0xff, "PERPENDICULAR MODE", 1, fdctrl_handle_perpendicular_mode },
2374    { FD_CMD_CONFIGURE, 0xff, "CONFIGURE", 3, fdctrl_handle_configure },
2375    { FD_CMD_POWERDOWN_MODE, 0xff, "POWERDOWN MODE", 2, fdctrl_handle_powerdown_mode },
2376    { FD_CMD_OPTION, 0xff, "OPTION", 1, fdctrl_handle_option },
2377    { FD_CMD_DRIVE_SPECIFICATION_COMMAND, 0xff, "DRIVE SPECIFICATION COMMAND", 5, fdctrl_handle_drive_specification_command },
2378    { FD_CMD_RELATIVE_SEEK_OUT, 0xff, "RELATIVE SEEK OUT", 2, fdctrl_handle_relative_seek_out },
2379    { FD_CMD_FORMAT_AND_WRITE, 0xff, "FORMAT AND WRITE", 10, fdctrl_unimplemented },
2380    { FD_CMD_RELATIVE_SEEK_IN, 0xff, "RELATIVE SEEK IN", 2, fdctrl_handle_relative_seek_in },
2381    { FD_CMD_LOCK, 0x7f, "LOCK", 0, fdctrl_handle_lock },
2382    { FD_CMD_DUMPREG, 0xff, "DUMPREG", 0, fdctrl_handle_dumpreg },
2383    { FD_CMD_VERSION, 0xff, "VERSION", 0, fdctrl_handle_version },
2384    { FD_CMD_PART_ID, 0xff, "PART ID", 0, fdctrl_handle_partid },
2385    { FD_CMD_WRITE, 0x1f, "WRITE (BeOS)", 8, fdctrl_start_transfer, FD_DIR_WRITE }, /* not in specification ; BeOS 4.5 bug */
2386    { 0, 0, "unknown", 0, fdctrl_unimplemented }, /* default handler */
2387};
2388/* Associate command to an index in the 'handlers' array */
2389static uint8_t command_to_handler[256];
2390
2391static const FDCtrlCommand *get_command(uint8_t cmd)
2392{
2393    int idx;
2394
2395    idx = command_to_handler[cmd];
2396    FLOPPY_DPRINTF("%s command\n", handlers[idx].name);
2397    return &handlers[idx];
2398}
2399
2400static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
2401{
2402    FDrive *cur_drv;
2403    const FDCtrlCommand *cmd;
2404    uint32_t pos;
2405
2406    /* Reset mode */
2407    if (!(fdctrl->dor & FD_DOR_nRESET)) {
2408        FLOPPY_DPRINTF("Floppy controller in RESET state !\n");
2409        return;
2410    }
2411    if (!(fdctrl->msr & FD_MSR_RQM) || (fdctrl->msr & FD_MSR_DIO)) {
2412        FLOPPY_DPRINTF("error: controller not ready for writing\n");
2413        return;
2414    }
2415    fdctrl->dsr &= ~FD_DSR_PWRDOWN;
2416
2417    FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
2418
2419    /* If data_len spans multiple sectors, the current position in the FIFO
2420     * wraps around while fdctrl->data_pos is the real position in the whole
2421     * request. */
2422    pos = fdctrl->data_pos++;
2423    pos %= FD_SECTOR_LEN;
2424    fdctrl->fifo[pos] = value;
2425
2426    if (fdctrl->data_pos == fdctrl->data_len) {
2427        fdctrl->msr &= ~FD_MSR_RQM;
2428    }
2429
2430    switch (fdctrl->phase) {
2431    case FD_PHASE_EXECUTION:
2432        /* For DMA requests, RQM should be cleared during execution phase, so
2433         * we would have errored out above. */
2434        assert(fdctrl->msr & FD_MSR_NONDMA);
2435
2436        /* FIFO data write */
2437        if (pos == FD_SECTOR_LEN - 1 ||
2438            fdctrl->data_pos == fdctrl->data_len) {
2439            cur_drv = get_cur_drv(fdctrl);
2440            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
2441                           BDRV_SECTOR_SIZE, 0) < 0) {
2442                FLOPPY_DPRINTF("error writing sector %d\n",
2443                               fd_sector(cur_drv));
2444                break;
2445            }
2446            if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
2447                FLOPPY_DPRINTF("error seeking to next sector %d\n",
2448                               fd_sector(cur_drv));
2449                break;
2450            }
2451        }
2452
2453        /* Switch to result phase when done with the transfer */
2454        if (fdctrl->data_pos == fdctrl->data_len) {
2455            fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2456        }
2457        break;
2458
2459    case FD_PHASE_COMMAND:
2460        assert(!(fdctrl->msr & FD_MSR_NONDMA));
2461        assert(fdctrl->data_pos < FD_SECTOR_LEN);
2462
2463        if (pos == 0) {
2464            /* The first byte specifies the command. Now we start reading
2465             * as many parameters as this command requires. */
2466            cmd = get_command(value);
2467            fdctrl->data_len = cmd->parameters + 1;
2468            if (cmd->parameters) {
2469                fdctrl->msr |= FD_MSR_RQM;
2470            }
2471            fdctrl->msr |= FD_MSR_CMDBUSY;
2472        }
2473
2474        if (fdctrl->data_pos == fdctrl->data_len) {
2475            /* We have all parameters now, execute the command */
2476            fdctrl->phase = FD_PHASE_EXECUTION;
2477
2478            if (fdctrl->data_state & FD_STATE_FORMAT) {
2479                fdctrl_format_sector(fdctrl);
2480                break;
2481            }
2482
2483            cmd = get_command(fdctrl->fifo[0]);
2484            FLOPPY_DPRINTF("Calling handler for '%s'\n", cmd->name);
2485            cmd->handler(fdctrl, cmd->direction);
2486        }
2487        break;
2488
2489    case FD_PHASE_RESULT:
2490    default:
2491        abort();
2492    }
2493}
2494
2495static void fdctrl_result_timer(void *opaque)
2496{
2497    FDCtrl *fdctrl = opaque;
2498    FDrive *cur_drv = get_cur_drv(fdctrl);
2499
2500    /* Pretend we are spinning.
2501     * This is needed for Coherent, which uses READ ID to check for
2502     * sector interleaving.
2503     */
2504    if (cur_drv->last_sect != 0) {
2505        cur_drv->sect = (cur_drv->sect % cur_drv->last_sect) + 1;
2506    }
2507    /* READ_ID can't automatically succeed! */
2508    if (fdctrl->check_media_rate &&
2509        (fdctrl->dsr & FD_DSR_DRATEMASK) != cur_drv->media_rate) {
2510        FLOPPY_DPRINTF("read id rate mismatch (fdc=%d, media=%d)\n",
2511                       fdctrl->dsr & FD_DSR_DRATEMASK, cur_drv->media_rate);
2512        fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
2513    } else {
2514        fdctrl_stop_transfer(fdctrl, 0x00, 0x00, 0x00);
2515    }
2516}
2517
2518/* Init functions */
2519static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
2520                                  Error **errp)
2521{
2522    unsigned int i;
2523    FDrive *drive;
2524    DeviceState *dev;
2525    BlockBackend *blk;
2526    Error *local_err = NULL;
2527
2528    for (i = 0; i < MAX_FD; i++) {
2529        drive = &fdctrl->drives[i];
2530        drive->fdctrl = fdctrl;
2531
2532        /* If the drive is not present, we skip creating the qdev device, but
2533         * still have to initialise the controller. */
2534        blk = fdctrl->qdev_for_drives[i].blk;
2535        if (!blk) {
2536            fd_init(drive);
2537            fd_revalidate(drive);
2538            continue;
2539        }
2540
2541        dev = qdev_create(&fdctrl->bus.bus, "floppy");
2542        qdev_prop_set_uint32(dev, "unit", i);
2543        qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
2544
2545        blk_ref(blk);
2546        blk_detach_dev(blk, fdc_dev);
2547        fdctrl->qdev_for_drives[i].blk = NULL;
2548        qdev_prop_set_drive(dev, "drive", blk, &local_err);
2549        blk_unref(blk);
2550
2551        if (local_err) {
2552            error_propagate(errp, local_err);
2553            return;
2554        }
2555
2556        object_property_set_bool(OBJECT(dev), true, "realized", &local_err);
2557        if (local_err) {
2558            error_propagate(errp, local_err);
2559            return;
2560        }
2561    }
2562}
2563
2564ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds)
2565{
2566    DeviceState *dev;
2567    ISADevice *isadev;
2568
2569    isadev = isa_try_create(bus, TYPE_ISA_FDC);
2570    if (!isadev) {
2571        return NULL;
2572    }
2573    dev = DEVICE(isadev);
2574
2575    if (fds[0]) {
2576        qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fds[0]),
2577                            &error_fatal);
2578    }
2579    if (fds[1]) {
2580        qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fds[1]),
2581                            &error_fatal);
2582    }
2583    qdev_init_nofail(dev);
2584
2585    return isadev;
2586}
2587
2588void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
2589                        hwaddr mmio_base, DriveInfo **fds)
2590{
2591    FDCtrl *fdctrl;
2592    DeviceState *dev;
2593    SysBusDevice *sbd;
2594    FDCtrlSysBus *sys;
2595
2596    dev = qdev_create(NULL, "sysbus-fdc");
2597    sys = SYSBUS_FDC(dev);
2598    fdctrl = &sys->state;
2599    fdctrl->dma_chann = dma_chann; /* FIXME */
2600    if (fds[0]) {
2601        qdev_prop_set_drive(dev, "driveA", blk_by_legacy_dinfo(fds[0]),
2602                            &error_fatal);
2603    }
2604    if (fds[1]) {
2605        qdev_prop_set_drive(dev, "driveB", blk_by_legacy_dinfo(fds[1]),
2606                            &error_fatal);
2607    }
2608    qdev_init_nofail(dev);
2609    sbd = SYS_BUS_DEVICE(dev);
2610    sysbus_connect_irq(sbd, 0, irq);
2611    sysbus_mmio_map(sbd, 0, mmio_base);
2612}
2613
2614void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
2615                       DriveInfo **fds, qemu_irq *fdc_tc)
2616{
2617    DeviceState *dev;
2618    FDCtrlSysBus *sys;
2619
2620    dev = qdev_create(NULL, "SUNW,fdtwo");
2621    if (fds[0]) {
2622        qdev_prop_set_drive(dev, "drive", blk_by_legacy_dinfo(fds[0]),
2623                            &error_fatal);
2624    }
2625    qdev_init_nofail(dev);
2626    sys = SYSBUS_FDC(dev);
2627    sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
2628    sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
2629    *fdc_tc = qdev_get_gpio_in(dev, 0);
2630}
2631
2632static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
2633                                  Error **errp)
2634{
2635    int i, j;
2636    static int command_tables_inited = 0;
2637
2638    if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
2639        error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
2640    }
2641
2642    /* Fill 'command_to_handler' lookup table */
2643    if (!command_tables_inited) {
2644        command_tables_inited = 1;
2645        for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
2646            for (j = 0; j < sizeof(command_to_handler); j++) {
2647                if ((j & handlers[i].mask) == handlers[i].value) {
2648                    command_to_handler[j] = i;
2649                }
2650            }
2651        }
2652    }
2653
2654    FLOPPY_DPRINTF("init controller\n");
2655    fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
2656    memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
2657    fdctrl->fifo_size = 512;
2658    fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
2659                                             fdctrl_result_timer, fdctrl);
2660
2661    fdctrl->version = 0x90; /* Intel 82078 controller */
2662    fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
2663    fdctrl->num_floppies = MAX_FD;
2664
2665    if (fdctrl->dma_chann != -1) {
2666        IsaDmaClass *k;
2667        assert(fdctrl->dma);
2668        k = ISADMA_GET_CLASS(fdctrl->dma);
2669        k->register_channel(fdctrl->dma, fdctrl->dma_chann,
2670                            &fdctrl_transfer_handler, fdctrl);
2671    }
2672
2673    floppy_bus_create(fdctrl, &fdctrl->bus, dev);
2674    fdctrl_connect_drives(fdctrl, dev, errp);
2675}
2676
2677static const MemoryRegionPortio fdc_portio_list[] = {
2678    { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
2679    { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
2680    PORTIO_END_OF_LIST(),
2681};
2682
2683static void isabus_fdc_realize(DeviceState *dev, Error **errp)
2684{
2685    ISADevice *isadev = ISA_DEVICE(dev);
2686    FDCtrlISABus *isa = ISA_FDC(dev);
2687    FDCtrl *fdctrl = &isa->state;
2688    Error *err = NULL;
2689
2690    isa_register_portio_list(isadev, &fdctrl->portio_list,
2691                             isa->iobase, fdc_portio_list, fdctrl,
2692                             "fdc");
2693
2694    isa_init_irq(isadev, &fdctrl->irq, isa->irq);
2695    fdctrl->dma_chann = isa->dma;
2696    if (fdctrl->dma_chann != -1) {
2697        fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma);
2698        if (!fdctrl->dma) {
2699            error_setg(errp, "ISA controller does not support DMA");
2700            return;
2701        }
2702    }
2703
2704    qdev_set_legacy_instance_id(dev, isa->iobase, 2);
2705    fdctrl_realize_common(dev, fdctrl, &err);
2706    if (err != NULL) {
2707        error_propagate(errp, err);
2708        return;
2709    }
2710}
2711
2712static void sysbus_fdc_initfn(Object *obj)
2713{
2714    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2715    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2716    FDCtrl *fdctrl = &sys->state;
2717
2718    fdctrl->dma_chann = -1;
2719
2720    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl,
2721                          "fdc", 0x08);
2722    sysbus_init_mmio(sbd, &fdctrl->iomem);
2723}
2724
2725static void sun4m_fdc_initfn(Object *obj)
2726{
2727    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2728    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2729    FDCtrl *fdctrl = &sys->state;
2730
2731    fdctrl->dma_chann = -1;
2732
2733    memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
2734                          fdctrl, "fdctrl", 0x08);
2735    sysbus_init_mmio(sbd, &fdctrl->iomem);
2736}
2737
2738static void sysbus_fdc_common_initfn(Object *obj)
2739{
2740    DeviceState *dev = DEVICE(obj);
2741    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
2742    FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2743    FDCtrl *fdctrl = &sys->state;
2744
2745    qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
2746
2747    sysbus_init_irq(sbd, &fdctrl->irq);
2748    qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
2749}
2750
2751static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
2752{
2753    FDCtrlSysBus *sys = SYSBUS_FDC(dev);
2754    FDCtrl *fdctrl = &sys->state;
2755
2756    fdctrl_realize_common(dev, fdctrl, errp);
2757}
2758
2759FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
2760{
2761    FDCtrlISABus *isa = ISA_FDC(fdc);
2762
2763    return isa->state.drives[i].drive;
2764}
2765
2766void isa_fdc_get_drive_max_chs(FloppyDriveType type,
2767                               uint8_t *maxc, uint8_t *maxh, uint8_t *maxs)
2768{
2769    const FDFormat *fdf;
2770
2771    *maxc = *maxh = *maxs = 0;
2772    for (fdf = fd_formats; fdf->drive != FLOPPY_DRIVE_TYPE_NONE; fdf++) {
2773        if (fdf->drive != type) {
2774            continue;
2775        }
2776        if (*maxc < fdf->max_track) {
2777            *maxc = fdf->max_track;
2778        }
2779        if (*maxh < fdf->max_head) {
2780            *maxh = fdf->max_head;
2781        }
2782        if (*maxs < fdf->last_sect) {
2783            *maxs = fdf->last_sect;
2784        }
2785    }
2786    (*maxc)--;
2787}
2788
2789static const VMStateDescription vmstate_isa_fdc ={
2790    .name = "fdc",
2791    .version_id = 2,
2792    .minimum_version_id = 2,
2793    .fields = (VMStateField[]) {
2794        VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
2795        VMSTATE_END_OF_LIST()
2796    }
2797};
2798
2799static Property isa_fdc_properties[] = {
2800    DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
2801    DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
2802    DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
2803    DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.qdev_for_drives[0].blk),
2804    DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
2805    DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
2806                    0, true),
2807    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
2808                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2809                        FloppyDriveType),
2810    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
2811                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2812                        FloppyDriveType),
2813    DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2814                        FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
2815                        FloppyDriveType),
2816    DEFINE_PROP_END_OF_LIST(),
2817};
2818
2819static void isabus_fdc_class_init(ObjectClass *klass, void *data)
2820{
2821    DeviceClass *dc = DEVICE_CLASS(klass);
2822
2823    dc->realize = isabus_fdc_realize;
2824    dc->fw_name = "fdc";
2825    dc->reset = fdctrl_external_reset_isa;
2826    dc->vmsd = &vmstate_isa_fdc;
2827    dc->props = isa_fdc_properties;
2828    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2829}
2830
2831static void isabus_fdc_instance_init(Object *obj)
2832{
2833    FDCtrlISABus *isa = ISA_FDC(obj);
2834
2835    device_add_bootindex_property(obj, &isa->bootindexA,
2836                                  "bootindexA", "/floppy@0",
2837                                  DEVICE(obj), NULL);
2838    device_add_bootindex_property(obj, &isa->bootindexB,
2839                                  "bootindexB", "/floppy@1",
2840                                  DEVICE(obj), NULL);
2841}
2842
2843static const TypeInfo isa_fdc_info = {
2844    .name          = TYPE_ISA_FDC,
2845    .parent        = TYPE_ISA_DEVICE,
2846    .instance_size = sizeof(FDCtrlISABus),
2847    .class_init    = isabus_fdc_class_init,
2848    .instance_init = isabus_fdc_instance_init,
2849};
2850
2851static const VMStateDescription vmstate_sysbus_fdc ={
2852    .name = "fdc",
2853    .version_id = 2,
2854    .minimum_version_id = 2,
2855    .fields = (VMStateField[]) {
2856        VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
2857        VMSTATE_END_OF_LIST()
2858    }
2859};
2860
2861static Property sysbus_fdc_properties[] = {
2862    DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2863    DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
2864    DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
2865                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2866                        FloppyDriveType),
2867    DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
2868                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2869                        FloppyDriveType),
2870    DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2871                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2872                        FloppyDriveType),
2873    DEFINE_PROP_END_OF_LIST(),
2874};
2875
2876static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
2877{
2878    DeviceClass *dc = DEVICE_CLASS(klass);
2879
2880    dc->props = sysbus_fdc_properties;
2881    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2882}
2883
2884static const TypeInfo sysbus_fdc_info = {
2885    .name          = "sysbus-fdc",
2886    .parent        = TYPE_SYSBUS_FDC,
2887    .instance_init = sysbus_fdc_initfn,
2888    .class_init    = sysbus_fdc_class_init,
2889};
2890
2891static Property sun4m_fdc_properties[] = {
2892    DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2893    DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
2894                        FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2895                        FloppyDriveType),
2896    DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2897                        FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2898                        FloppyDriveType),
2899    DEFINE_PROP_END_OF_LIST(),
2900};
2901
2902static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
2903{
2904    DeviceClass *dc = DEVICE_CLASS(klass);
2905
2906    dc->props = sun4m_fdc_properties;
2907    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2908}
2909
2910static const TypeInfo sun4m_fdc_info = {
2911    .name          = "SUNW,fdtwo",
2912    .parent        = TYPE_SYSBUS_FDC,
2913    .instance_init = sun4m_fdc_initfn,
2914    .class_init    = sun4m_fdc_class_init,
2915};
2916
2917static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
2918{
2919    DeviceClass *dc = DEVICE_CLASS(klass);
2920
2921    dc->realize = sysbus_fdc_common_realize;
2922    dc->reset = fdctrl_external_reset_sysbus;
2923    dc->vmsd = &vmstate_sysbus_fdc;
2924}
2925
2926static const TypeInfo sysbus_fdc_type_info = {
2927    .name          = TYPE_SYSBUS_FDC,
2928    .parent        = TYPE_SYS_BUS_DEVICE,
2929    .instance_size = sizeof(FDCtrlSysBus),
2930    .instance_init = sysbus_fdc_common_initfn,
2931    .abstract      = true,
2932    .class_init    = sysbus_fdc_common_class_init,
2933};
2934
2935static void fdc_register_types(void)
2936{
2937    type_register_static(&isa_fdc_info);
2938    type_register_static(&sysbus_fdc_type_info);
2939    type_register_static(&sysbus_fdc_info);
2940    type_register_static(&sun4m_fdc_info);
2941    type_register_static(&floppy_bus_info);
2942    type_register_static(&floppy_drive_info);
2943}
2944
2945type_init(fdc_register_types)
2946