xref: /openbmc/qemu/hw/block/fdc.c (revision 4c4465ff)
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/acpi/aml-build.h"
36 #include "hw/irq.h"
37 #include "hw/isa/isa.h"
38 #include "hw/qdev-properties.h"
39 #include "hw/qdev-properties-system.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 #include "qom/object.h"
51 
52 /********************************************************/
53 /* debug Floppy devices */
54 
55 #define DEBUG_FLOPPY 0
56 
57 #define FLOPPY_DPRINTF(fmt, ...)                                \
58     do {                                                        \
59         if (DEBUG_FLOPPY) {                                     \
60             fprintf(stderr, "FLOPPY: " fmt , ## __VA_ARGS__);   \
61         }                                                       \
62     } while (0)
63 
64 
65 /********************************************************/
66 /* qdev floppy bus                                      */
67 
68 #define TYPE_FLOPPY_BUS "floppy-bus"
69 OBJECT_DECLARE_SIMPLE_TYPE(FloppyBus, FLOPPY_BUS)
70 
71 typedef struct FDCtrl FDCtrl;
72 typedef struct FDrive FDrive;
73 static FDrive *get_drv(FDCtrl *fdctrl, int unit);
74 
75 struct FloppyBus {
76     BusState bus;
77     FDCtrl *fdc;
78 };
79 
80 static const TypeInfo floppy_bus_info = {
81     .name = TYPE_FLOPPY_BUS,
82     .parent = TYPE_BUS,
83     .instance_size = sizeof(FloppyBus),
84 };
85 
86 static void floppy_bus_create(FDCtrl *fdc, FloppyBus *bus, DeviceState *dev)
87 {
88     qbus_create_inplace(bus, sizeof(FloppyBus), TYPE_FLOPPY_BUS, dev, NULL);
89     bus->fdc = fdc;
90 }
91 
92 
93 /********************************************************/
94 /* Floppy drive emulation                               */
95 
96 typedef enum FDriveRate {
97     FDRIVE_RATE_500K = 0x00,  /* 500 Kbps */
98     FDRIVE_RATE_300K = 0x01,  /* 300 Kbps */
99     FDRIVE_RATE_250K = 0x02,  /* 250 Kbps */
100     FDRIVE_RATE_1M   = 0x03,  /*   1 Mbps */
101 } FDriveRate;
102 
103 typedef enum FDriveSize {
104     FDRIVE_SIZE_UNKNOWN,
105     FDRIVE_SIZE_350,
106     FDRIVE_SIZE_525,
107 } FDriveSize;
108 
109 typedef struct FDFormat {
110     FloppyDriveType drive;
111     uint8_t last_sect;
112     uint8_t max_track;
113     uint8_t max_head;
114     FDriveRate rate;
115 } FDFormat;
116 
117 /* In many cases, the total sector size of a format is enough to uniquely
118  * identify it. However, there are some total sector collisions between
119  * formats of different physical size, and these are noted below by
120  * highlighting the total sector size for entries with collisions. */
121 static const FDFormat fd_formats[] = {
122     /* First entry is default format */
123     /* 1.44 MB 3"1/2 floppy disks */
124     { FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */
125     { FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */
126     { FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
127     { FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
128     { FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
129     { FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, },
130     { FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, },
131     { FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, },
132     /* 2.88 MB 3"1/2 floppy disks */
133     { FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, },
134     { FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, },
135     { FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, },
136     { FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
137     { FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
138     /* 720 kB 3"1/2 floppy disks */
139     { FLOPPY_DRIVE_TYPE_144,  9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */
140     { FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
141     { FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
142     { FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
143     { FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, },
144     { FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
145     /* 1.2 MB 5"1/4 floppy disks */
146     { FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
147     { FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */
148     { FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
149     { FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
150     { FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */
151     /* 720 kB 5"1/4 floppy disks */
152     { FLOPPY_DRIVE_TYPE_120,  9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */
153     { FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
154     /* 360 kB 5"1/4 floppy disks */
155     { FLOPPY_DRIVE_TYPE_120,  9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */
156     { FLOPPY_DRIVE_TYPE_120,  9, 40, 0, FDRIVE_RATE_300K, },
157     { FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
158     { FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
159     /* 320 kB 5"1/4 floppy disks */
160     { FLOPPY_DRIVE_TYPE_120,  8, 40, 1, FDRIVE_RATE_250K, },
161     { FLOPPY_DRIVE_TYPE_120,  8, 40, 0, FDRIVE_RATE_250K, },
162     /* 360 kB must match 5"1/4 better than 3"1/2... */
163     { FLOPPY_DRIVE_TYPE_144,  9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */
164     /* end */
165     { FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
166 };
167 
168 static FDriveSize drive_size(FloppyDriveType drive)
169 {
170     switch (drive) {
171     case FLOPPY_DRIVE_TYPE_120:
172         return FDRIVE_SIZE_525;
173     case FLOPPY_DRIVE_TYPE_144:
174     case FLOPPY_DRIVE_TYPE_288:
175         return FDRIVE_SIZE_350;
176     default:
177         return FDRIVE_SIZE_UNKNOWN;
178     }
179 }
180 
181 #define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
182 #define SET_CUR_DRV(fdctrl, drive) ((fdctrl)->cur_drv = (drive))
183 
184 /* Will always be a fixed parameter for us */
185 #define FD_SECTOR_LEN          512
186 #define FD_SECTOR_SC           2   /* Sector size code */
187 #define FD_RESET_SENSEI_COUNT  4   /* Number of sense interrupts on RESET */
188 
189 /* Floppy disk drive emulation */
190 typedef enum FDiskFlags {
191     FDISK_DBL_SIDES  = 0x01,
192 } FDiskFlags;
193 
194 struct FDrive {
195     FDCtrl *fdctrl;
196     BlockBackend *blk;
197     BlockConf *conf;
198     /* Drive status */
199     FloppyDriveType drive;    /* CMOS drive type        */
200     uint8_t perpendicular;    /* 2.88 MB access mode    */
201     /* Position */
202     uint8_t head;
203     uint8_t track;
204     uint8_t sect;
205     /* Media */
206     FloppyDriveType disk;     /* Current disk type      */
207     FDiskFlags flags;
208     uint8_t last_sect;        /* Nb sector per track    */
209     uint8_t max_track;        /* Nb of tracks           */
210     uint16_t bps;             /* Bytes per sector       */
211     uint8_t ro;               /* Is read-only           */
212     uint8_t media_changed;    /* Is media changed       */
213     uint8_t media_rate;       /* Data rate of medium    */
214 
215     bool media_validated;     /* Have we validated the media? */
216 };
217 
218 
219 static FloppyDriveType get_fallback_drive_type(FDrive *drv);
220 
221 /* Hack: FD_SEEK is expected to work on empty drives. However, QEMU
222  * currently goes through some pains to keep seeks within the bounds
223  * established by last_sect and max_track. Correcting this is difficult,
224  * as refactoring FDC code tends to expose nasty bugs in the Linux kernel.
225  *
226  * For now: allow empty drives to have large bounds so we can seek around,
227  * with the understanding that when a diskette is inserted, the bounds will
228  * properly tighten to match the geometry of that inserted medium.
229  */
230 static void fd_empty_seek_hack(FDrive *drv)
231 {
232     drv->last_sect = 0xFF;
233     drv->max_track = 0xFF;
234 }
235 
236 static void fd_init(FDrive *drv)
237 {
238     /* Drive */
239     drv->perpendicular = 0;
240     /* Disk */
241     drv->disk = FLOPPY_DRIVE_TYPE_NONE;
242     drv->last_sect = 0;
243     drv->max_track = 0;
244     drv->ro = true;
245     drv->media_changed = 1;
246 }
247 
248 #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
249 
250 static int fd_sector_calc(uint8_t head, uint8_t track, uint8_t sect,
251                           uint8_t last_sect, uint8_t num_sides)
252 {
253     return (((track * num_sides) + head) * last_sect) + sect - 1;
254 }
255 
256 /* Returns current position, in sectors, for given drive */
257 static int fd_sector(FDrive *drv)
258 {
259     return fd_sector_calc(drv->head, drv->track, drv->sect, drv->last_sect,
260                           NUM_SIDES(drv));
261 }
262 
263 /* Returns current position, in bytes, for given drive */
264 static int fd_offset(FDrive *drv)
265 {
266     g_assert(fd_sector(drv) < INT_MAX >> BDRV_SECTOR_BITS);
267     return fd_sector(drv) << BDRV_SECTOR_BITS;
268 }
269 
270 /* Seek to a new position:
271  * returns 0 if already on right track
272  * returns 1 if track changed
273  * returns 2 if track is invalid
274  * returns 3 if sector is invalid
275  * returns 4 if seek is disabled
276  */
277 static int fd_seek(FDrive *drv, uint8_t head, uint8_t track, uint8_t sect,
278                    int enable_seek)
279 {
280     uint32_t sector;
281     int ret;
282 
283     if (track > drv->max_track ||
284         (head != 0 && (drv->flags & FDISK_DBL_SIDES) == 0)) {
285         FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
286                        head, track, sect, 1,
287                        (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
288                        drv->max_track, drv->last_sect);
289         return 2;
290     }
291     if (sect > drv->last_sect) {
292         FLOPPY_DPRINTF("try to read %d %02x %02x (max=%d %d %02x %02x)\n",
293                        head, track, sect, 1,
294                        (drv->flags & FDISK_DBL_SIDES) == 0 ? 0 : 1,
295                        drv->max_track, drv->last_sect);
296         return 3;
297     }
298     sector = fd_sector_calc(head, track, sect, drv->last_sect, NUM_SIDES(drv));
299     ret = 0;
300     if (sector != fd_sector(drv)) {
301 #if 0
302         if (!enable_seek) {
303             FLOPPY_DPRINTF("error: no implicit seek %d %02x %02x"
304                            " (max=%d %02x %02x)\n",
305                            head, track, sect, 1, drv->max_track,
306                            drv->last_sect);
307             return 4;
308         }
309 #endif
310         drv->head = head;
311         if (drv->track != track) {
312             if (drv->blk != NULL && blk_is_inserted(drv->blk)) {
313                 drv->media_changed = 0;
314             }
315             ret = 1;
316         }
317         drv->track = track;
318         drv->sect = sect;
319     }
320 
321     if (drv->blk == NULL || !blk_is_inserted(drv->blk)) {
322         ret = 2;
323     }
324 
325     return ret;
326 }
327 
328 /* Set drive back to track 0 */
329 static void fd_recalibrate(FDrive *drv)
330 {
331     FLOPPY_DPRINTF("recalibrate\n");
332     fd_seek(drv, 0, 0, 1, 1);
333 }
334 
335 /**
336  * Determine geometry based on inserted diskette.
337  * Will not operate on an empty drive.
338  *
339  * @return: 0 on success, -1 if the drive is empty.
340  */
341 static int pick_geometry(FDrive *drv)
342 {
343     BlockBackend *blk = drv->blk;
344     const FDFormat *parse;
345     uint64_t nb_sectors, size;
346     int i;
347     int match, size_match, type_match;
348     bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
349 
350     /* We can only pick a geometry if we have a diskette. */
351     if (!drv->blk || !blk_is_inserted(drv->blk) ||
352         drv->drive == FLOPPY_DRIVE_TYPE_NONE)
353     {
354         return -1;
355     }
356 
357     /* We need to determine the likely geometry of the inserted medium.
358      * In order of preference, we look for:
359      * (1) The same drive type and number of sectors,
360      * (2) The same diskette size and number of sectors,
361      * (3) The same drive type.
362      *
363      * In all cases, matches that occur higher in the drive table will take
364      * precedence over matches that occur later in the table.
365      */
366     blk_get_geometry(blk, &nb_sectors);
367     match = size_match = type_match = -1;
368     for (i = 0; ; i++) {
369         parse = &fd_formats[i];
370         if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
371             break;
372         }
373         size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
374         if (nb_sectors == size) {
375             if (magic || parse->drive == drv->drive) {
376                 /* (1) perfect match -- nb_sectors and drive type */
377                 goto out;
378             } else if (drive_size(parse->drive) == drive_size(drv->drive)) {
379                 /* (2) size match -- nb_sectors and physical medium size */
380                 match = (match == -1) ? i : match;
381             } else {
382                 /* This is suspicious -- Did the user misconfigure? */
383                 size_match = (size_match == -1) ? i : size_match;
384             }
385         } else if (type_match == -1) {
386             if ((parse->drive == drv->drive) ||
387                 (magic && (parse->drive == get_fallback_drive_type(drv)))) {
388                 /* (3) type match -- nb_sectors mismatch, but matches the type
389                  *     specified explicitly by the user, or matches the fallback
390                  *     default type when using the drive autodetect mechanism */
391                 type_match = i;
392             }
393         }
394     }
395 
396     /* No exact match found */
397     if (match == -1) {
398         if (size_match != -1) {
399             parse = &fd_formats[size_match];
400             FLOPPY_DPRINTF("User requested floppy drive type '%s', "
401                            "but inserted medium appears to be a "
402                            "%"PRId64" sector '%s' type\n",
403                            FloppyDriveType_str(drv->drive),
404                            nb_sectors,
405                            FloppyDriveType_str(parse->drive));
406         }
407         assert(type_match != -1 && "misconfigured fd_format");
408         match = type_match;
409     }
410     parse = &(fd_formats[match]);
411 
412  out:
413     if (parse->max_head == 0) {
414         drv->flags &= ~FDISK_DBL_SIDES;
415     } else {
416         drv->flags |= FDISK_DBL_SIDES;
417     }
418     drv->max_track = parse->max_track;
419     drv->last_sect = parse->last_sect;
420     drv->disk = parse->drive;
421     drv->media_rate = parse->rate;
422     return 0;
423 }
424 
425 static void pick_drive_type(FDrive *drv)
426 {
427     if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
428         return;
429     }
430 
431     if (pick_geometry(drv) == 0) {
432         drv->drive = drv->disk;
433     } else {
434         drv->drive = get_fallback_drive_type(drv);
435     }
436 
437     g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
438 }
439 
440 /* Revalidate a disk drive after a disk change */
441 static void fd_revalidate(FDrive *drv)
442 {
443     int rc;
444 
445     FLOPPY_DPRINTF("revalidate\n");
446     if (drv->blk != NULL) {
447         drv->ro = blk_is_read_only(drv->blk);
448         if (!blk_is_inserted(drv->blk)) {
449             FLOPPY_DPRINTF("No disk in drive\n");
450             drv->disk = FLOPPY_DRIVE_TYPE_NONE;
451             fd_empty_seek_hack(drv);
452         } else if (!drv->media_validated) {
453             rc = pick_geometry(drv);
454             if (rc) {
455                 FLOPPY_DPRINTF("Could not validate floppy drive media");
456             } else {
457                 drv->media_validated = true;
458                 FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
459                                (drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
460                                drv->max_track, drv->last_sect,
461                                drv->ro ? "ro" : "rw");
462             }
463         }
464     } else {
465         FLOPPY_DPRINTF("No drive connected\n");
466         drv->last_sect = 0;
467         drv->max_track = 0;
468         drv->flags &= ~FDISK_DBL_SIDES;
469         drv->drive = FLOPPY_DRIVE_TYPE_NONE;
470         drv->disk = FLOPPY_DRIVE_TYPE_NONE;
471     }
472 }
473 
474 static void fd_change_cb(void *opaque, bool load, Error **errp)
475 {
476     FDrive *drive = opaque;
477 
478     if (!load) {
479         blk_set_perm(drive->blk, 0, BLK_PERM_ALL, &error_abort);
480     } else {
481         if (!blkconf_apply_backend_options(drive->conf,
482                                            blk_is_read_only(drive->blk), false,
483                                            errp)) {
484             return;
485         }
486     }
487 
488     drive->media_changed = 1;
489     drive->media_validated = false;
490     fd_revalidate(drive);
491 }
492 
493 static const BlockDevOps fd_block_ops = {
494     .change_media_cb = fd_change_cb,
495 };
496 
497 
498 #define TYPE_FLOPPY_DRIVE "floppy"
499 OBJECT_DECLARE_SIMPLE_TYPE(FloppyDrive, FLOPPY_DRIVE)
500 
501 struct FloppyDrive {
502     DeviceState     qdev;
503     uint32_t        unit;
504     BlockConf       conf;
505     FloppyDriveType type;
506 };
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 OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlSysBus, SYSBUS_FDC)
891 
892 struct FDCtrlSysBus {
893     /*< private >*/
894     SysBusDevice parent_obj;
895     /*< public >*/
896 
897     struct FDCtrl state;
898 };
899 
900 OBJECT_DECLARE_SIMPLE_TYPE(FDCtrlISABus, ISA_FDC)
901 
902 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 };
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 
2503 static void fdctrl_init_drives(FloppyBus *bus, DriveInfo **fds)
2504 {
2505     DeviceState *dev;
2506     int i;
2507 
2508     for (i = 0; i < MAX_FD; i++) {
2509         if (fds[i]) {
2510             dev = qdev_new("floppy");
2511             qdev_prop_set_uint32(dev, "unit", i);
2512             qdev_prop_set_enum(dev, "drive-type", FLOPPY_DRIVE_TYPE_AUTO);
2513             qdev_prop_set_drive_err(dev, "drive", blk_by_legacy_dinfo(fds[i]),
2514                                     &error_fatal);
2515             qdev_realize_and_unref(dev, &bus->bus, &error_fatal);
2516         }
2517     }
2518 }
2519 
2520 void isa_fdc_init_drives(ISADevice *fdc, DriveInfo **fds)
2521 {
2522     fdctrl_init_drives(&ISA_FDC(fdc)->state.bus, fds);
2523 }
2524 
2525 static void fdctrl_connect_drives(FDCtrl *fdctrl, DeviceState *fdc_dev,
2526                                   Error **errp)
2527 {
2528     unsigned int i;
2529     FDrive *drive;
2530     DeviceState *dev;
2531     BlockBackend *blk;
2532     bool ok;
2533     const char *fdc_name, *drive_suffix;
2534 
2535     for (i = 0; i < MAX_FD; i++) {
2536         drive = &fdctrl->drives[i];
2537         drive->fdctrl = fdctrl;
2538 
2539         /* If the drive is not present, we skip creating the qdev device, but
2540          * still have to initialise the controller. */
2541         blk = fdctrl->qdev_for_drives[i].blk;
2542         if (!blk) {
2543             fd_init(drive);
2544             fd_revalidate(drive);
2545             continue;
2546         }
2547 
2548         fdc_name = object_get_typename(OBJECT(fdc_dev));
2549         drive_suffix = !strcmp(fdc_name, "SUNW,fdtwo") ? "" : i ? "B" : "A";
2550         warn_report("warning: property %s.drive%s is deprecated",
2551                     fdc_name, drive_suffix);
2552         error_printf("Use -device floppy,unit=%d,drive=... instead.\n", i);
2553 
2554         dev = qdev_new("floppy");
2555         qdev_prop_set_uint32(dev, "unit", i);
2556         qdev_prop_set_enum(dev, "drive-type", fdctrl->qdev_for_drives[i].type);
2557 
2558         /*
2559          * Hack alert: we move the backend from the floppy controller
2560          * device to the floppy device.  We first need to detach the
2561          * controller, or else floppy_create()'s qdev_prop_set_drive()
2562          * will die when it attaches floppy device.  We also need to
2563          * take another reference so that blk_detach_dev() doesn't
2564          * free blk while we still need it.
2565          *
2566          * The hack is probably a bad idea.
2567          */
2568         blk_ref(blk);
2569         blk_detach_dev(blk, fdc_dev);
2570         fdctrl->qdev_for_drives[i].blk = NULL;
2571         ok = qdev_prop_set_drive_err(dev, "drive", blk, errp);
2572         blk_unref(blk);
2573         if (!ok) {
2574             return;
2575         }
2576 
2577         if (!qdev_realize_and_unref(dev, &fdctrl->bus.bus, errp)) {
2578             return;
2579         }
2580     }
2581 }
2582 
2583 void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
2584                         hwaddr mmio_base, DriveInfo **fds)
2585 {
2586     FDCtrl *fdctrl;
2587     DeviceState *dev;
2588     SysBusDevice *sbd;
2589     FDCtrlSysBus *sys;
2590 
2591     dev = qdev_new("sysbus-fdc");
2592     sys = SYSBUS_FDC(dev);
2593     fdctrl = &sys->state;
2594     fdctrl->dma_chann = dma_chann; /* FIXME */
2595     sbd = SYS_BUS_DEVICE(dev);
2596     sysbus_realize_and_unref(sbd, &error_fatal);
2597     sysbus_connect_irq(sbd, 0, irq);
2598     sysbus_mmio_map(sbd, 0, mmio_base);
2599 
2600     fdctrl_init_drives(&sys->state.bus, fds);
2601 }
2602 
2603 void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
2604                        DriveInfo **fds, qemu_irq *fdc_tc)
2605 {
2606     DeviceState *dev;
2607     FDCtrlSysBus *sys;
2608 
2609     dev = qdev_new("SUNW,fdtwo");
2610     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
2611     sys = SYSBUS_FDC(dev);
2612     sysbus_connect_irq(SYS_BUS_DEVICE(sys), 0, irq);
2613     sysbus_mmio_map(SYS_BUS_DEVICE(sys), 0, io_base);
2614     *fdc_tc = qdev_get_gpio_in(dev, 0);
2615 
2616     fdctrl_init_drives(&sys->state.bus, fds);
2617 }
2618 
2619 static void fdctrl_realize_common(DeviceState *dev, FDCtrl *fdctrl,
2620                                   Error **errp)
2621 {
2622     int i, j;
2623     static int command_tables_inited = 0;
2624 
2625     if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
2626         error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
2627         return;
2628     }
2629 
2630     /* Fill 'command_to_handler' lookup table */
2631     if (!command_tables_inited) {
2632         command_tables_inited = 1;
2633         for (i = ARRAY_SIZE(handlers) - 1; i >= 0; i--) {
2634             for (j = 0; j < sizeof(command_to_handler); j++) {
2635                 if ((j & handlers[i].mask) == handlers[i].value) {
2636                     command_to_handler[j] = i;
2637                 }
2638             }
2639         }
2640     }
2641 
2642     FLOPPY_DPRINTF("init controller\n");
2643     fdctrl->fifo = qemu_memalign(512, FD_SECTOR_LEN);
2644     memset(fdctrl->fifo, 0, FD_SECTOR_LEN);
2645     fdctrl->fifo_size = 512;
2646     fdctrl->result_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
2647                                              fdctrl_result_timer, fdctrl);
2648 
2649     fdctrl->version = 0x90; /* Intel 82078 controller */
2650     fdctrl->config = FD_CONFIG_EIS | FD_CONFIG_EFIFO; /* Implicit seek, polling & FIFO enabled */
2651     fdctrl->num_floppies = MAX_FD;
2652 
2653     if (fdctrl->dma_chann != -1) {
2654         IsaDmaClass *k;
2655         assert(fdctrl->dma);
2656         k = ISADMA_GET_CLASS(fdctrl->dma);
2657         k->register_channel(fdctrl->dma, fdctrl->dma_chann,
2658                             &fdctrl_transfer_handler, fdctrl);
2659     }
2660 
2661     floppy_bus_create(fdctrl, &fdctrl->bus, dev);
2662     fdctrl_connect_drives(fdctrl, dev, errp);
2663 }
2664 
2665 static const MemoryRegionPortio fdc_portio_list[] = {
2666     { 1, 5, 1, .read = fdctrl_read, .write = fdctrl_write },
2667     { 7, 1, 1, .read = fdctrl_read, .write = fdctrl_write },
2668     PORTIO_END_OF_LIST(),
2669 };
2670 
2671 static void isabus_fdc_realize(DeviceState *dev, Error **errp)
2672 {
2673     ISADevice *isadev = ISA_DEVICE(dev);
2674     FDCtrlISABus *isa = ISA_FDC(dev);
2675     FDCtrl *fdctrl = &isa->state;
2676     Error *err = NULL;
2677 
2678     isa_register_portio_list(isadev, &fdctrl->portio_list,
2679                              isa->iobase, fdc_portio_list, fdctrl,
2680                              "fdc");
2681 
2682     isa_init_irq(isadev, &fdctrl->irq, isa->irq);
2683     fdctrl->dma_chann = isa->dma;
2684     if (fdctrl->dma_chann != -1) {
2685         fdctrl->dma = isa_get_dma(isa_bus_from_device(isadev), isa->dma);
2686         if (!fdctrl->dma) {
2687             error_setg(errp, "ISA controller does not support DMA");
2688             return;
2689         }
2690     }
2691 
2692     qdev_set_legacy_instance_id(dev, isa->iobase, 2);
2693     fdctrl_realize_common(dev, fdctrl, &err);
2694     if (err != NULL) {
2695         error_propagate(errp, err);
2696         return;
2697     }
2698 }
2699 
2700 static void sysbus_fdc_initfn(Object *obj)
2701 {
2702     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2703     FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2704     FDCtrl *fdctrl = &sys->state;
2705 
2706     fdctrl->dma_chann = -1;
2707 
2708     memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_ops, fdctrl,
2709                           "fdc", 0x08);
2710     sysbus_init_mmio(sbd, &fdctrl->iomem);
2711 }
2712 
2713 static void sun4m_fdc_initfn(Object *obj)
2714 {
2715     SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
2716     FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2717     FDCtrl *fdctrl = &sys->state;
2718 
2719     fdctrl->dma_chann = -1;
2720 
2721     memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops,
2722                           fdctrl, "fdctrl", 0x08);
2723     sysbus_init_mmio(sbd, &fdctrl->iomem);
2724 }
2725 
2726 static void sysbus_fdc_common_initfn(Object *obj)
2727 {
2728     DeviceState *dev = DEVICE(obj);
2729     SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
2730     FDCtrlSysBus *sys = SYSBUS_FDC(obj);
2731     FDCtrl *fdctrl = &sys->state;
2732 
2733     qdev_set_legacy_instance_id(dev, 0 /* io */, 2); /* FIXME */
2734 
2735     sysbus_init_irq(sbd, &fdctrl->irq);
2736     qdev_init_gpio_in(dev, fdctrl_handle_tc, 1);
2737 }
2738 
2739 static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
2740 {
2741     FDCtrlSysBus *sys = SYSBUS_FDC(dev);
2742     FDCtrl *fdctrl = &sys->state;
2743 
2744     fdctrl_realize_common(dev, fdctrl, errp);
2745 }
2746 
2747 FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
2748 {
2749     FDCtrlISABus *isa = ISA_FDC(fdc);
2750 
2751     return isa->state.drives[i].drive;
2752 }
2753 
2754 static void isa_fdc_get_drive_max_chs(FloppyDriveType type, uint8_t *maxc,
2755                                       uint8_t *maxh, uint8_t *maxs)
2756 {
2757     const FDFormat *fdf;
2758 
2759     *maxc = *maxh = *maxs = 0;
2760     for (fdf = fd_formats; fdf->drive != FLOPPY_DRIVE_TYPE_NONE; fdf++) {
2761         if (fdf->drive != type) {
2762             continue;
2763         }
2764         if (*maxc < fdf->max_track) {
2765             *maxc = fdf->max_track;
2766         }
2767         if (*maxh < fdf->max_head) {
2768             *maxh = fdf->max_head;
2769         }
2770         if (*maxs < fdf->last_sect) {
2771             *maxs = fdf->last_sect;
2772         }
2773     }
2774     (*maxc)--;
2775 }
2776 
2777 static Aml *build_fdinfo_aml(int idx, FloppyDriveType type)
2778 {
2779     Aml *dev, *fdi;
2780     uint8_t maxc, maxh, maxs;
2781 
2782     isa_fdc_get_drive_max_chs(type, &maxc, &maxh, &maxs);
2783 
2784     dev = aml_device("FLP%c", 'A' + idx);
2785 
2786     aml_append(dev, aml_name_decl("_ADR", aml_int(idx)));
2787 
2788     fdi = aml_package(16);
2789     aml_append(fdi, aml_int(idx));  /* Drive Number */
2790     aml_append(fdi,
2791         aml_int(cmos_get_fd_drive_type(type)));  /* Device Type */
2792     /*
2793      * the values below are the limits of the drive, and are thus independent
2794      * of the inserted media
2795      */
2796     aml_append(fdi, aml_int(maxc));  /* Maximum Cylinder Number */
2797     aml_append(fdi, aml_int(maxs));  /* Maximum Sector Number */
2798     aml_append(fdi, aml_int(maxh));  /* Maximum Head Number */
2799     /*
2800      * SeaBIOS returns the below values for int 0x13 func 0x08 regardless of
2801      * the drive type, so shall we
2802      */
2803     aml_append(fdi, aml_int(0xAF));  /* disk_specify_1 */
2804     aml_append(fdi, aml_int(0x02));  /* disk_specify_2 */
2805     aml_append(fdi, aml_int(0x25));  /* disk_motor_wait */
2806     aml_append(fdi, aml_int(0x02));  /* disk_sector_siz */
2807     aml_append(fdi, aml_int(0x12));  /* disk_eot */
2808     aml_append(fdi, aml_int(0x1B));  /* disk_rw_gap */
2809     aml_append(fdi, aml_int(0xFF));  /* disk_dtl */
2810     aml_append(fdi, aml_int(0x6C));  /* disk_formt_gap */
2811     aml_append(fdi, aml_int(0xF6));  /* disk_fill */
2812     aml_append(fdi, aml_int(0x0F));  /* disk_head_sttl */
2813     aml_append(fdi, aml_int(0x08));  /* disk_motor_strt */
2814 
2815     aml_append(dev, aml_name_decl("_FDI", fdi));
2816     return dev;
2817 }
2818 
2819 int cmos_get_fd_drive_type(FloppyDriveType fd0)
2820 {
2821     int val;
2822 
2823     switch (fd0) {
2824     case FLOPPY_DRIVE_TYPE_144:
2825         /* 1.44 Mb 3"5 drive */
2826         val = 4;
2827         break;
2828     case FLOPPY_DRIVE_TYPE_288:
2829         /* 2.88 Mb 3"5 drive */
2830         val = 5;
2831         break;
2832     case FLOPPY_DRIVE_TYPE_120:
2833         /* 1.2 Mb 5"5 drive */
2834         val = 2;
2835         break;
2836     case FLOPPY_DRIVE_TYPE_NONE:
2837     default:
2838         val = 0;
2839         break;
2840     }
2841     return val;
2842 }
2843 
2844 static void fdc_isa_build_aml(ISADevice *isadev, Aml *scope)
2845 {
2846     Aml *dev;
2847     Aml *crs;
2848     int i;
2849 
2850 #define ACPI_FDE_MAX_FD 4
2851     uint32_t fde_buf[5] = {
2852         0, 0, 0, 0,     /* presence of floppy drives #0 - #3 */
2853         cpu_to_le32(2)  /* tape presence (2 == never present) */
2854     };
2855 
2856     crs = aml_resource_template();
2857     aml_append(crs, aml_io(AML_DECODE16, 0x03F2, 0x03F2, 0x00, 0x04));
2858     aml_append(crs, aml_io(AML_DECODE16, 0x03F7, 0x03F7, 0x00, 0x01));
2859     aml_append(crs, aml_irq_no_flags(6));
2860     aml_append(crs,
2861         aml_dma(AML_COMPATIBILITY, AML_NOTBUSMASTER, AML_TRANSFER8, 2));
2862 
2863     dev = aml_device("FDC0");
2864     aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0700")));
2865     aml_append(dev, aml_name_decl("_CRS", crs));
2866 
2867     for (i = 0; i < MIN(MAX_FD, ACPI_FDE_MAX_FD); i++) {
2868         FloppyDriveType type = isa_fdc_get_drive_type(isadev, i);
2869 
2870         if (type < FLOPPY_DRIVE_TYPE_NONE) {
2871             fde_buf[i] = cpu_to_le32(1);  /* drive present */
2872             aml_append(dev, build_fdinfo_aml(i, type));
2873         }
2874     }
2875     aml_append(dev, aml_name_decl("_FDE",
2876                aml_buffer(sizeof(fde_buf), (uint8_t *)fde_buf)));
2877 
2878     aml_append(scope, dev);
2879 }
2880 
2881 static const VMStateDescription vmstate_isa_fdc ={
2882     .name = "fdc",
2883     .version_id = 2,
2884     .minimum_version_id = 2,
2885     .fields = (VMStateField[]) {
2886         VMSTATE_STRUCT(state, FDCtrlISABus, 0, vmstate_fdc, FDCtrl),
2887         VMSTATE_END_OF_LIST()
2888     }
2889 };
2890 
2891 static Property isa_fdc_properties[] = {
2892     DEFINE_PROP_UINT32("iobase", FDCtrlISABus, iobase, 0x3f0),
2893     DEFINE_PROP_UINT32("irq", FDCtrlISABus, irq, 6),
2894     DEFINE_PROP_UINT32("dma", FDCtrlISABus, dma, 2),
2895     DEFINE_PROP_DRIVE("driveA", FDCtrlISABus, state.qdev_for_drives[0].blk),
2896     DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.qdev_for_drives[1].blk),
2897     DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
2898                     0, true),
2899     DEFINE_PROP_SIGNED("fdtypeA", FDCtrlISABus, state.qdev_for_drives[0].type,
2900                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2901                         FloppyDriveType),
2902     DEFINE_PROP_SIGNED("fdtypeB", FDCtrlISABus, state.qdev_for_drives[1].type,
2903                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2904                         FloppyDriveType),
2905     DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2906                         FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
2907                         FloppyDriveType),
2908     DEFINE_PROP_END_OF_LIST(),
2909 };
2910 
2911 static void isabus_fdc_class_init(ObjectClass *klass, void *data)
2912 {
2913     DeviceClass *dc = DEVICE_CLASS(klass);
2914     ISADeviceClass *isa = ISA_DEVICE_CLASS(klass);
2915 
2916     dc->realize = isabus_fdc_realize;
2917     dc->fw_name = "fdc";
2918     dc->reset = fdctrl_external_reset_isa;
2919     dc->vmsd = &vmstate_isa_fdc;
2920     isa->build_aml = fdc_isa_build_aml;
2921     device_class_set_props(dc, isa_fdc_properties);
2922     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2923 }
2924 
2925 static void isabus_fdc_instance_init(Object *obj)
2926 {
2927     FDCtrlISABus *isa = ISA_FDC(obj);
2928 
2929     device_add_bootindex_property(obj, &isa->bootindexA,
2930                                   "bootindexA", "/floppy@0",
2931                                   DEVICE(obj));
2932     device_add_bootindex_property(obj, &isa->bootindexB,
2933                                   "bootindexB", "/floppy@1",
2934                                   DEVICE(obj));
2935 }
2936 
2937 static const TypeInfo isa_fdc_info = {
2938     .name          = TYPE_ISA_FDC,
2939     .parent        = TYPE_ISA_DEVICE,
2940     .instance_size = sizeof(FDCtrlISABus),
2941     .class_init    = isabus_fdc_class_init,
2942     .instance_init = isabus_fdc_instance_init,
2943 };
2944 
2945 static const VMStateDescription vmstate_sysbus_fdc ={
2946     .name = "fdc",
2947     .version_id = 2,
2948     .minimum_version_id = 2,
2949     .fields = (VMStateField[]) {
2950         VMSTATE_STRUCT(state, FDCtrlSysBus, 0, vmstate_fdc, FDCtrl),
2951         VMSTATE_END_OF_LIST()
2952     }
2953 };
2954 
2955 static Property sysbus_fdc_properties[] = {
2956     DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2957     DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.qdev_for_drives[1].blk),
2958     DEFINE_PROP_SIGNED("fdtypeA", FDCtrlSysBus, state.qdev_for_drives[0].type,
2959                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2960                         FloppyDriveType),
2961     DEFINE_PROP_SIGNED("fdtypeB", FDCtrlSysBus, state.qdev_for_drives[1].type,
2962                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2963                         FloppyDriveType),
2964     DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2965                         FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2966                         FloppyDriveType),
2967     DEFINE_PROP_END_OF_LIST(),
2968 };
2969 
2970 static void sysbus_fdc_class_init(ObjectClass *klass, void *data)
2971 {
2972     DeviceClass *dc = DEVICE_CLASS(klass);
2973 
2974     device_class_set_props(dc, sysbus_fdc_properties);
2975     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
2976 }
2977 
2978 static const TypeInfo sysbus_fdc_info = {
2979     .name          = "sysbus-fdc",
2980     .parent        = TYPE_SYSBUS_FDC,
2981     .instance_init = sysbus_fdc_initfn,
2982     .class_init    = sysbus_fdc_class_init,
2983 };
2984 
2985 static Property sun4m_fdc_properties[] = {
2986     DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.qdev_for_drives[0].blk),
2987     DEFINE_PROP_SIGNED("fdtype", FDCtrlSysBus, state.qdev_for_drives[0].type,
2988                         FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
2989                         FloppyDriveType),
2990     DEFINE_PROP_SIGNED("fallback", FDCtrlISABus, state.fallback,
2991                         FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
2992                         FloppyDriveType),
2993     DEFINE_PROP_END_OF_LIST(),
2994 };
2995 
2996 static void sun4m_fdc_class_init(ObjectClass *klass, void *data)
2997 {
2998     DeviceClass *dc = DEVICE_CLASS(klass);
2999 
3000     device_class_set_props(dc, sun4m_fdc_properties);
3001     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
3002 }
3003 
3004 static const TypeInfo sun4m_fdc_info = {
3005     .name          = "SUNW,fdtwo",
3006     .parent        = TYPE_SYSBUS_FDC,
3007     .instance_init = sun4m_fdc_initfn,
3008     .class_init    = sun4m_fdc_class_init,
3009 };
3010 
3011 static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data)
3012 {
3013     DeviceClass *dc = DEVICE_CLASS(klass);
3014 
3015     dc->realize = sysbus_fdc_common_realize;
3016     dc->reset = fdctrl_external_reset_sysbus;
3017     dc->vmsd = &vmstate_sysbus_fdc;
3018 }
3019 
3020 static const TypeInfo sysbus_fdc_type_info = {
3021     .name          = TYPE_SYSBUS_FDC,
3022     .parent        = TYPE_SYS_BUS_DEVICE,
3023     .instance_size = sizeof(FDCtrlSysBus),
3024     .instance_init = sysbus_fdc_common_initfn,
3025     .abstract      = true,
3026     .class_init    = sysbus_fdc_common_class_init,
3027 };
3028 
3029 static void fdc_register_types(void)
3030 {
3031     type_register_static(&isa_fdc_info);
3032     type_register_static(&sysbus_fdc_type_info);
3033     type_register_static(&sysbus_fdc_info);
3034     type_register_static(&sun4m_fdc_info);
3035     type_register_static(&floppy_bus_info);
3036     type_register_static(&floppy_drive_info);
3037 }
3038 
3039 type_init(fdc_register_types)
3040