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