-----BEGIN PGP SIGNATURE-----

Version: GnuPG v1
 
 iQIcBAABAgAGBQJWpnoOAAoJEH3vgQaq/DkOqbgP/1E09vMe/KT50k0vgkIvX5KL
 gCLExCYwhOhE53x8QIZQp6gGWzvombqlNFhoZz6FmIU1Q+BW9khhohiecLQUlYUX
 pILkhyjFe1E1uTZ6wuDT4juhE9CGsyjIXjY0tGTyuvWqXfWJR5KAAZ9Udxo1vnfu
 +lA975W8htqenkRe/J5lB4k1ZMmKTaMYr4rIo2Bconu8sOebHXfdmY78qswY0vaG
 SP1JhauFaXJBM3lGLdlXL5cIjs7yLR5XKxOGWFtQ8rCaJxzuiCup4//Ciabckf3E
 57VGGsBPqyFFLrF3vQ7NoBVlbWf9aaxdCN5niwhmyWfTnbVdLYRvhqWNHW5gvP6G
 1VCqNGvCd8lDlM4Ad/DdlFzRk6F8ybsP64slut9Tmg4kpXfSMljbXuMd+SC1+xxC
 eGwfr4GTHmt2iGhJZUn9iguvGID0ssfP20knLXLZbZG2ans8eYO/w9ALLt4vm2HS
 WepTRBuGQD0dUTm7IIIeL2KAGaSGRWVQqgwbtvIBa3MLMzIIYyUHv54+8/AOfF2L
 hMW6tD5TKzgGdDgITtG9DqI0l/xRODCS6rND2/9aJ5MZS0yU/P0LCcYA6qV1qCY4
 jTlRI3dCxppdlCq7qCu52hQg886RIMF4VYs7HjmTf4E+WkHIgEWbAGyNMtNYodWq
 HbNTXxXChymt1CBrzTZ3
 =lTrI
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging

# gpg: Signature made Mon 25 Jan 2016 19:39:58 GMT using RSA key ID AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"

* remotes/jnsnow/tags/ide-pull-request:
  fdc: change auto fallback drive for ISA FDC to 288
  qtest/fdc: Support for 2.88MB drives
  fdc: rework pick_geometry
  fdc: add physical disk sizes
  fdc: add drive type option
  fdc: Add fallback option
  fdc: add pick_drive
  fdc: Throw an assertion on misconfigured fd_formats table
  fdc: add disk field
  fdc: add drive type qapi enum
  fdc: reduce number of pick_geometry arguments
  fdc: move pick_geometry
  ide: Correct the CHS 'cyls_max' limit to be 65535

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2016-01-26 09:16:07 +00:00
commit 1535a6d699
9 changed files with 271 additions and 117 deletions

View File

@ -60,104 +60,82 @@ typedef enum FDriveRate {
FDRIVE_RATE_1M = 0x03, /* 1 Mbps */
} FDriveRate;
typedef enum FDriveSize {
FDRIVE_SIZE_UNKNOWN,
FDRIVE_SIZE_350,
FDRIVE_SIZE_525,
} FDriveSize;
typedef struct FDFormat {
FDriveType drive;
FloppyDriveType drive;
uint8_t last_sect;
uint8_t max_track;
uint8_t max_head;
FDriveRate rate;
} FDFormat;
/* In many cases, the total sector size of a format is enough to uniquely
* identify it. However, there are some total sector collisions between
* formats of different physical size, and these are noted below by
* highlighting the total sector size for entries with collisions. */
static const FDFormat fd_formats[] = {
/* First entry is default format */
/* 1.44 MB 3"1/2 floppy disks */
{ FDRIVE_DRV_144, 18, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 20, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 21, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 21, 82, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 21, 83, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 22, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 23, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_144, 24, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 18, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 2880 */
{ FLOPPY_DRIVE_TYPE_144, 20, 80, 1, FDRIVE_RATE_500K, }, /* 3.5" 3200 */
{ FLOPPY_DRIVE_TYPE_144, 21, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 21, 82, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 21, 83, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 22, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 23, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_144, 24, 80, 1, FDRIVE_RATE_500K, },
/* 2.88 MB 3"1/2 floppy disks */
{ FDRIVE_DRV_288, 36, 80, 1, FDRIVE_RATE_1M, },
{ FDRIVE_DRV_288, 39, 80, 1, FDRIVE_RATE_1M, },
{ FDRIVE_DRV_288, 40, 80, 1, FDRIVE_RATE_1M, },
{ FDRIVE_DRV_288, 44, 80, 1, FDRIVE_RATE_1M, },
{ FDRIVE_DRV_288, 48, 80, 1, FDRIVE_RATE_1M, },
{ FLOPPY_DRIVE_TYPE_288, 36, 80, 1, FDRIVE_RATE_1M, },
{ FLOPPY_DRIVE_TYPE_288, 39, 80, 1, FDRIVE_RATE_1M, },
{ FLOPPY_DRIVE_TYPE_288, 40, 80, 1, FDRIVE_RATE_1M, },
{ FLOPPY_DRIVE_TYPE_288, 44, 80, 1, FDRIVE_RATE_1M, },
{ FLOPPY_DRIVE_TYPE_288, 48, 80, 1, FDRIVE_RATE_1M, },
/* 720 kB 3"1/2 floppy disks */
{ FDRIVE_DRV_144, 9, 80, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_144, 10, 80, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_144, 10, 82, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_144, 10, 83, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_144, 13, 80, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_144, 14, 80, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 9, 80, 1, FDRIVE_RATE_250K, }, /* 3.5" 1440 */
{ FLOPPY_DRIVE_TYPE_144, 10, 80, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 10, 82, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 10, 83, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 13, 80, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 14, 80, 1, FDRIVE_RATE_250K, },
/* 1.2 MB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 15, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_120, 18, 80, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_120, 18, 82, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_120, 18, 83, 1, FDRIVE_RATE_500K, },
{ FDRIVE_DRV_120, 20, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_120, 15, 80, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_120, 18, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 2880 */
{ FLOPPY_DRIVE_TYPE_120, 18, 82, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_120, 18, 83, 1, FDRIVE_RATE_500K, },
{ FLOPPY_DRIVE_TYPE_120, 20, 80, 1, FDRIVE_RATE_500K, }, /* 5.25" 3200 */
/* 720 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 9, 80, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_120, 11, 80, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_120, 9, 80, 1, FDRIVE_RATE_250K, }, /* 5.25" 1440 */
{ FLOPPY_DRIVE_TYPE_120, 11, 80, 1, FDRIVE_RATE_250K, },
/* 360 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 9, 40, 1, FDRIVE_RATE_300K, },
{ FDRIVE_DRV_120, 9, 40, 0, FDRIVE_RATE_300K, },
{ FDRIVE_DRV_120, 10, 41, 1, FDRIVE_RATE_300K, },
{ FDRIVE_DRV_120, 10, 42, 1, FDRIVE_RATE_300K, },
{ FLOPPY_DRIVE_TYPE_120, 9, 40, 1, FDRIVE_RATE_300K, }, /* 5.25" 720 */
{ FLOPPY_DRIVE_TYPE_120, 9, 40, 0, FDRIVE_RATE_300K, },
{ FLOPPY_DRIVE_TYPE_120, 10, 41, 1, FDRIVE_RATE_300K, },
{ FLOPPY_DRIVE_TYPE_120, 10, 42, 1, FDRIVE_RATE_300K, },
/* 320 kB 5"1/4 floppy disks */
{ FDRIVE_DRV_120, 8, 40, 1, FDRIVE_RATE_250K, },
{ FDRIVE_DRV_120, 8, 40, 0, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_120, 8, 40, 1, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_120, 8, 40, 0, FDRIVE_RATE_250K, },
/* 360 kB must match 5"1/4 better than 3"1/2... */
{ FDRIVE_DRV_144, 9, 80, 0, FDRIVE_RATE_250K, },
{ FLOPPY_DRIVE_TYPE_144, 9, 80, 0, FDRIVE_RATE_250K, }, /* 3.5" 720 */
/* end */
{ FDRIVE_DRV_NONE, -1, -1, 0, 0, },
{ FLOPPY_DRIVE_TYPE_NONE, -1, -1, 0, 0, },
};
static void pick_geometry(BlockBackend *blk, int *nb_heads,
int *max_track, int *last_sect,
FDriveType drive_in, FDriveType *drive,
FDriveRate *rate)
static FDriveSize drive_size(FloppyDriveType drive)
{
const FDFormat *parse;
uint64_t nb_sectors, size;
int i, first_match, match;
blk_get_geometry(blk, &nb_sectors);
match = -1;
first_match = -1;
for (i = 0; ; i++) {
parse = &fd_formats[i];
if (parse->drive == FDRIVE_DRV_NONE) {
break;
}
if (drive_in == parse->drive ||
drive_in == FDRIVE_DRV_NONE) {
size = (parse->max_head + 1) * parse->max_track *
parse->last_sect;
if (nb_sectors == size) {
match = i;
break;
}
if (first_match == -1) {
first_match = i;
}
}
switch (drive) {
case FLOPPY_DRIVE_TYPE_120:
return FDRIVE_SIZE_525;
case FLOPPY_DRIVE_TYPE_144:
case FLOPPY_DRIVE_TYPE_288:
return FDRIVE_SIZE_350;
default:
return FDRIVE_SIZE_UNKNOWN;
}
if (match == -1) {
if (first_match == -1) {
match = 1;
} else {
match = first_match;
}
parse = &fd_formats[match];
}
*nb_heads = parse->max_head + 1;
*max_track = parse->max_track;
*last_sect = parse->last_sect;
*drive = parse->drive;
*rate = parse->rate;
}
#define GET_CUR_DRV(fdctrl) ((fdctrl)->cur_drv)
@ -179,13 +157,14 @@ typedef struct FDrive {
FDCtrl *fdctrl;
BlockBackend *blk;
/* Drive status */
FDriveType drive;
FloppyDriveType drive; /* CMOS drive type */
uint8_t perpendicular; /* 2.88 MB access mode */
/* Position */
uint8_t head;
uint8_t track;
uint8_t sect;
/* Media */
FloppyDriveType disk; /* Current disk type */
FDiskFlags flags;
uint8_t last_sect; /* Nb sector per track */
uint8_t max_track; /* Nb of tracks */
@ -195,16 +174,22 @@ typedef struct FDrive {
uint8_t media_rate; /* Data rate of medium */
bool media_inserted; /* Is there a medium in the tray */
bool media_validated; /* Have we validated the media? */
} FDrive;
static FloppyDriveType get_fallback_drive_type(FDrive *drv);
static void fd_init(FDrive *drv)
{
/* Drive */
drv->drive = FDRIVE_DRV_NONE;
drv->perpendicular = 0;
/* Disk */
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
drv->last_sect = 0;
drv->max_track = 0;
drv->ro = true;
drv->media_changed = 1;
}
#define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
@ -287,39 +272,146 @@ static void fd_recalibrate(FDrive *drv)
fd_seek(drv, 0, 0, 1, 1);
}
/**
* Determine geometry based on inserted diskette.
* Will not operate on an empty drive.
*
* @return: 0 on success, -1 if the drive is empty.
*/
static int pick_geometry(FDrive *drv)
{
BlockBackend *blk = drv->blk;
const FDFormat *parse;
uint64_t nb_sectors, size;
int i;
int match, size_match, type_match;
bool magic = drv->drive == FLOPPY_DRIVE_TYPE_AUTO;
/* We can only pick a geometry if we have a diskette. */
if (!drv->media_inserted || drv->drive == FLOPPY_DRIVE_TYPE_NONE) {
return -1;
}
/* We need to determine the likely geometry of the inserted medium.
* In order of preference, we look for:
* (1) The same drive type and number of sectors,
* (2) The same diskette size and number of sectors,
* (3) The same drive type.
*
* In all cases, matches that occur higher in the drive table will take
* precedence over matches that occur later in the table.
*/
blk_get_geometry(blk, &nb_sectors);
match = size_match = type_match = -1;
for (i = 0; ; i++) {
parse = &fd_formats[i];
if (parse->drive == FLOPPY_DRIVE_TYPE_NONE) {
break;
}
size = (parse->max_head + 1) * parse->max_track * parse->last_sect;
if (nb_sectors == size) {
if (magic || parse->drive == drv->drive) {
/* (1) perfect match -- nb_sectors and drive type */
goto out;
} else if (drive_size(parse->drive) == drive_size(drv->drive)) {
/* (2) size match -- nb_sectors and physical medium size */
match = (match == -1) ? i : match;
} else {
/* This is suspicious -- Did the user misconfigure? */
size_match = (size_match == -1) ? i : size_match;
}
} else if (type_match == -1) {
if ((parse->drive == drv->drive) ||
(magic && (parse->drive == get_fallback_drive_type(drv)))) {
/* (3) type match -- nb_sectors mismatch, but matches the type
* specified explicitly by the user, or matches the fallback
* default type when using the drive autodetect mechanism */
type_match = i;
}
}
}
/* No exact match found */
if (match == -1) {
if (size_match != -1) {
parse = &fd_formats[size_match];
FLOPPY_DPRINTF("User requested floppy drive type '%s', "
"but inserted medium appears to be a "
"%d sector '%s' type\n",
FloppyDriveType_lookup[drv->drive],
nb_sectors,
FloppyDriveType_lookup[parse->drive]);
}
match = type_match;
}
/* No match of any kind found -- fd_format is misconfigured, abort. */
if (match == -1) {
error_setg(&error_abort, "No candidate geometries present in table "
" for floppy drive type '%s'",
FloppyDriveType_lookup[drv->drive]);
}
parse = &(fd_formats[match]);
out:
if (parse->max_head == 0) {
drv->flags &= ~FDISK_DBL_SIDES;
} else {
drv->flags |= FDISK_DBL_SIDES;
}
drv->max_track = parse->max_track;
drv->last_sect = parse->last_sect;
drv->disk = parse->drive;
drv->media_rate = parse->rate;
return 0;
}
static void pick_drive_type(FDrive *drv)
{
if (drv->drive != FLOPPY_DRIVE_TYPE_AUTO) {
return;
}
if (pick_geometry(drv) == 0) {
drv->drive = drv->disk;
} else {
drv->drive = get_fallback_drive_type(drv);
}
g_assert(drv->drive != FLOPPY_DRIVE_TYPE_AUTO);
}
/* Revalidate a disk drive after a disk change */
static void fd_revalidate(FDrive *drv)
{
int nb_heads, max_track, last_sect, ro;
FDriveType drive;
FDriveRate rate;
int rc;
FLOPPY_DPRINTF("revalidate\n");
if (drv->blk != NULL) {
ro = blk_is_read_only(drv->blk);
pick_geometry(drv->blk, &nb_heads, &max_track,
&last_sect, drv->drive, &drive, &rate);
drv->ro = blk_is_read_only(drv->blk);
if (!drv->media_inserted) {
FLOPPY_DPRINTF("No disk in drive\n");
} else {
FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
max_track, last_sect, ro ? "ro" : "rw");
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
} else if (!drv->media_validated) {
rc = pick_geometry(drv);
if (rc) {
FLOPPY_DPRINTF("Could not validate floppy drive media");
} else {
drv->media_validated = true;
FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n",
(drv->flags & FDISK_DBL_SIDES) ? 2 : 1,
drv->max_track, drv->last_sect,
drv->ro ? "ro" : "rw");
}
}
if (nb_heads == 1) {
drv->flags &= ~FDISK_DBL_SIDES;
} else {
drv->flags |= FDISK_DBL_SIDES;
}
drv->max_track = max_track;
drv->last_sect = last_sect;
drv->ro = ro;
drv->drive = drive;
drv->media_rate = rate;
} else {
FLOPPY_DPRINTF("No drive connected\n");
drv->last_sect = 0;
drv->max_track = 0;
drv->flags &= ~FDISK_DBL_SIDES;
drv->drive = FLOPPY_DRIVE_TYPE_NONE;
drv->disk = FLOPPY_DRIVE_TYPE_NONE;
}
}
@ -569,11 +661,17 @@ struct FDCtrl {
FDrive drives[MAX_FD];
int reset_sensei;
uint32_t check_media_rate;
FloppyDriveType fallback; /* type=auto failure fallback */
/* Timers state */
uint8_t timer0;
uint8_t timer1;
};
static FloppyDriveType get_fallback_drive_type(FDrive *drv)
{
return drv->fdctrl->fallback;
}
#define TYPE_SYSBUS_FDC "base-sysbus-fdc"
#define SYSBUS_FDC(obj) OBJECT_CHECK(FDCtrlSysBus, (obj), TYPE_SYSBUS_FDC)
@ -2190,6 +2288,7 @@ static void fdctrl_change_cb(void *opaque, bool load)
drive->media_inserted = load && drive->blk && blk_is_inserted(drive->blk);
drive->media_changed = 1;
drive->media_validated = false;
fd_revalidate(drive);
}
@ -2226,11 +2325,12 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error **errp)
}
fd_init(drive);
fdctrl_change_cb(drive, 0);
if (drive->blk) {
blk_set_dev_ops(drive->blk, &fdctrl_block_ops, drive);
drive->media_inserted = blk_is_inserted(drive->blk);
pick_drive_type(drive);
}
fd_revalidate(drive);
}
}
@ -2307,6 +2407,10 @@ static void fdctrl_realize_common(FDCtrl *fdctrl, Error **errp)
int i, j;
static int command_tables_inited = 0;
if (fdctrl->fallback == FLOPPY_DRIVE_TYPE_AUTO) {
error_setg(errp, "Cannot choose a fallback FDrive type of 'auto'");
}
/* Fill 'command_to_handler' lookup table */
if (!command_tables_inited) {
command_tables_inited = 1;
@ -2407,7 +2511,7 @@ static void sysbus_fdc_common_realize(DeviceState *dev, Error **errp)
fdctrl_realize_common(fdctrl, errp);
}
FDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i)
{
FDCtrlISABus *isa = ISA_FDC(fdc);
@ -2432,6 +2536,15 @@ static Property isa_fdc_properties[] = {
DEFINE_PROP_DRIVE("driveB", FDCtrlISABus, state.drives[1].blk),
DEFINE_PROP_BIT("check_media_rate", FDCtrlISABus, state.check_media_rate,
0, true),
DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlISABus, state.drives[0].drive,
FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlISABus, state.drives[1].drive,
FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
FLOPPY_DRIVE_TYPE_288, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_END_OF_LIST(),
};
@ -2480,6 +2593,15 @@ static const VMStateDescription vmstate_sysbus_fdc ={
static Property sysbus_fdc_properties[] = {
DEFINE_PROP_DRIVE("driveA", FDCtrlSysBus, state.drives[0].blk),
DEFINE_PROP_DRIVE("driveB", FDCtrlSysBus, state.drives[1].blk),
DEFINE_PROP_DEFAULT("fdtypeA", FDCtrlSysBus, state.drives[0].drive,
FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_DEFAULT("fdtypeB", FDCtrlSysBus, state.drives[1].drive,
FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_END_OF_LIST(),
};
@ -2500,6 +2622,12 @@ static const TypeInfo sysbus_fdc_info = {
static Property sun4m_fdc_properties[] = {
DEFINE_PROP_DRIVE("drive", FDCtrlSysBus, state.drives[0].blk),
DEFINE_PROP_DEFAULT("fdtype", FDCtrlSysBus, state.drives[0].drive,
FLOPPY_DRIVE_TYPE_AUTO, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_DEFAULT("fallback", FDCtrlISABus, state.fallback,
FLOPPY_DRIVE_TYPE_144, qdev_prop_fdc_drive_type,
FloppyDriveType),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -541,6 +541,17 @@ PropertyInfo qdev_prop_bios_chs_trans = {
.set = set_enum,
};
/* --- FDC default drive types */
PropertyInfo qdev_prop_fdc_drive_type = {
.name = "FdcDriveType",
.description = "FDC drive type, "
"144/288/120/none/auto",
.enum_table = FloppyDriveType_lookup,
.get = get_enum,
.set = set_enum
};
/* --- pci address --- */
/*

View File

@ -199,24 +199,24 @@ static void pic_irq_request(void *opaque, int irq, int level)
#define REG_EQUIPMENT_BYTE 0x14
static int cmos_get_fd_drive_type(FDriveType fd0)
static int cmos_get_fd_drive_type(FloppyDriveType fd0)
{
int val;
switch (fd0) {
case FDRIVE_DRV_144:
case FLOPPY_DRIVE_TYPE_144:
/* 1.44 Mb 3"5 drive */
val = 4;
break;
case FDRIVE_DRV_288:
case FLOPPY_DRIVE_TYPE_288:
/* 2.88 Mb 3"5 drive */
val = 5;
break;
case FDRIVE_DRV_120:
case FLOPPY_DRIVE_TYPE_120:
/* 1.2 Mb 5"5 drive */
val = 2;
break;
case FDRIVE_DRV_NONE:
case FLOPPY_DRIVE_TYPE_NONE:
default:
val = 0;
break;
@ -287,7 +287,8 @@ static void pc_boot_set(void *opaque, const char *boot_device, Error **errp)
static void pc_cmos_init_floppy(ISADevice *rtc_state, ISADevice *floppy)
{
int val, nb, i;
FDriveType fd_type[2] = { FDRIVE_DRV_NONE, FDRIVE_DRV_NONE };
FloppyDriveType fd_type[2] = { FLOPPY_DRIVE_TYPE_NONE,
FLOPPY_DRIVE_TYPE_NONE };
/* floppy type */
if (floppy) {
@ -301,10 +302,10 @@ static void pc_cmos_init_floppy(ISADevice *rtc_state, ISADevice *floppy)
val = rtc_get_memory(rtc_state, REG_EQUIPMENT_BYTE);
nb = 0;
if (fd_type[0] < FDRIVE_DRV_NONE) {
if (fd_type[0] != FLOPPY_DRIVE_TYPE_NONE) {
nb++;
}
if (fd_type[1] < FDRIVE_DRV_NONE) {
if (fd_type[1] != FLOPPY_DRIVE_TYPE_NONE) {
nb++;
}
switch (nb) {

View File

@ -172,7 +172,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
blkconf_serial(&dev->conf, &dev->serial);
if (kind != IDE_CD) {
blkconf_geometry(&dev->conf, &dev->chs_trans, 65536, 16, 255, &err);
blkconf_geometry(&dev->conf, &dev->chs_trans, 65535, 16, 255, &err);
if (err) {
error_report_err(err);
return -1;

View File

@ -6,13 +6,6 @@
/* fdc.c */
#define MAX_FD 2
typedef enum FDriveType {
FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
FDRIVE_DRV_NONE = 0x03, /* No drive connected */
} FDriveType;
#define TYPE_ISA_FDC "isa-fdc"
ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds);
@ -21,6 +14,6 @@ void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
FDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
FloppyDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
#endif

View File

@ -3,6 +3,10 @@
#define HW_COMPAT_2_5 \
{\
.driver = "isa-fdc",\
.property = "fallback",\
.value = "144",\
},{\
.driver = "pvscsi",\
.property = "x-old-pci-configuration",\
.value = "on",\

View File

@ -20,6 +20,7 @@ extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
extern PropertyInfo qdev_prop_losttickpolicy;
extern PropertyInfo qdev_prop_bios_chs_trans;
extern PropertyInfo qdev_prop_fdc_drive_type;
extern PropertyInfo qdev_prop_drive;
extern PropertyInfo qdev_prop_netdev;
extern PropertyInfo qdev_prop_vlan;

View File

@ -39,6 +39,22 @@
{ 'enum': 'BiosAtaTranslation',
'data': ['auto', 'none', 'lba', 'large', 'rechs']}
##
# @FloppyDriveType
#
# Type of Floppy drive to be emulated by the Floppy Disk Controller.
#
# @144: 1.44MB 3.5" drive
# @288: 2.88MB 3.5" drive
# @120: 1.2MB 5.25" drive
# @none: No drive connected
# @auto: Automatically determined by inserted media at boot
#
# Since: 2.6
##
{ 'enum': 'FloppyDriveType',
'data': ['144', '288', '120', 'none', 'auto']}
##
# @BlockdevSnapshotInternal
#

View File

@ -267,7 +267,7 @@ static void test_cmos(void)
uint8_t cmos;
cmos = cmos_read(CMOS_FLOPPY);
g_assert(cmos == 0x40);
g_assert(cmos == 0x40 || cmos == 0x50);
}
static void test_no_media_on_start(void)