[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-block] [Qemu-devel] [PATCH v3 06/11] fdc: do not call revalida
From: |
John Snow |
Subject: |
Re: [Qemu-block] [Qemu-devel] [PATCH v3 06/11] fdc: do not call revalidate on eject |
Date: |
Fri, 18 Dec 2015 15:13:29 -0500 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 |
On 12/18/2015 11:11 AM, Markus Armbruster wrote:
> John Snow <address@hidden> writes:
>
>> Currently, fd_revalidate is called in two different places, with two
>> different expectations of behavior:
>>
>> (1) On initialization, as a routine to help pick the drive type and
>> initial geometries as a side-effect of the pick_geometry routine
>>
>> (2) On insert/eject, which either sets the geometries to a default value
>> or chooses new geometries based on the inserted diskette.
>>
>> Break this nonsense apart by creating a new function dedicated towards
>> picking the drive type on initialization.
>>
>> This has a few results:
>>
>> (1) fd_revalidate does not get called on boot anymore for drives with no
>> diskette.
>>
>> (2) pick_geometry will actually get called twice if we have a diskette
>> inserted, but this is harmless. (Once for the drive type, and once
>> as part of the media callback.)
>>
>> Signed-off-by: John Snow <address@hidden>
>> ---
>> hw/block/fdc.c | 36 +++++++++++++++++++++++++++++-------
>> 1 file changed, 29 insertions(+), 7 deletions(-)
>>
>> diff --git a/hw/block/fdc.c b/hw/block/fdc.c
>> index b587de8..e752758 100644
>> --- a/hw/block/fdc.c
>> +++ b/hw/block/fdc.c
>> @@ -167,6 +167,7 @@ static void fd_init(FDrive *drv)
>> drv->disk = FLOPPY_DRIVE_TYPE_NONE;
>> drv->last_sect = 0;
>> drv->max_track = 0;
>> + drv->ro = true;
>> }
>>
>> #define NUM_SIDES(drv) ((drv)->flags & FDISK_DBL_SIDES ? 2 : 1)
>> @@ -249,13 +250,21 @@ static void fd_recalibrate(FDrive *drv)
>> fd_seek(drv, 0, 0, 1, 1);
>> }
>>
>> -static void pick_geometry(FDrive *drv)
>> +/**
>> + * Determine geometry based on inserted diskette.
>> + */
>> +static bool pick_geometry(FDrive *drv)
>
> Meaning of return value?
>
1: "Modified diskette geometry values."
Will amend with documentation.
>> {
>> BlockBackend *blk = drv->blk;
>> const FDFormat *parse;
>> uint64_t nb_sectors, size;
>> int i, first_match, match;
>>
>> + /* We can only pick a geometry if we have a diskette. */
>> + if (!drv->media_inserted) {
>> + return false;
>> + }
>> +
>> blk_get_geometry(blk, &nb_sectors);
>> match = -1;
>> first_match = -1;
>> @@ -293,8 +302,7 @@ static void pick_geometry(FDrive *drv)
>> }
>> drv->max_track = parse->max_track;
>> drv->last_sect = parse->last_sect;
>> - drv->drive = parse->drive;
>> - drv->disk = drv->media_inserted ? parse->drive : FLOPPY_DRIVE_TYPE_NONE;
>> + drv->disk = parse->drive;
>> drv->media_rate = parse->rate;
>>
>> if (drv->media_inserted) {
>> @@ -303,6 +311,14 @@ static void pick_geometry(FDrive *drv)
>> drv->max_track, drv->last_sect,
>> drv->ro ? "ro" : "rw");
>> }
>> + return true;
>> +}
>> +
>> +static void pick_drive_type(FDrive *drv)
>> +{
>> + if (pick_geometry(drv)) {
>> + drv->drive = drv->disk;
>> + }
>> }
>>
>> /* Revalidate a disk drive after a disk change */
>> @@ -311,15 +327,18 @@ static void fd_revalidate(FDrive *drv)
>> FLOPPY_DPRINTF("revalidate\n");
>> if (drv->blk != NULL) {
>> drv->ro = blk_is_read_only(drv->blk);
>> - pick_geometry(drv);
>> if (!drv->media_inserted) {
>> FLOPPY_DPRINTF("No disk in drive\n");
>> + drv->disk = FLOPPY_DRIVE_TYPE_NONE;
>
> The left hand side is the "current disk type" (@disk's comment says so).
>
> The right hand side is "no drive connected" drive type (the enum's
> comment says so).
>
> Thus, we set the current disk type to the "no drive connected" drive
> type. Sounds nuts, doesn't it? :)
>
> Perhaps drv->disk isn't a disk type, but really into what an auto drive
> type should be morphed. Correct?
>
... yyyyes, it certainly informs us, if our type is auto, what we should
be setting the drive type to.
I'm definitely cheating, since there really should be two separate
enumerations, honestly:
DriveType: {120, 144, 288, auto, none}
DiskType: {120, 144, 288, none}
Though I concede the disk field isn't strictly needed, I was just
desperate to not have the one field mean two things simultaneously.
>> + } else {
>> + pick_geometry(drv);
>> }
>> } else {
>> FLOPPY_DPRINTF("No drive connected\n");
>> drv->last_sect = 0;
>> drv->max_track = 0;
>> drv->flags &= ~FDISK_DBL_SIDES;
>> + drv->disk = FLOPPY_DRIVE_TYPE_NONE;
>> }
>> }
>>
>> @@ -2196,9 +2215,11 @@ static void fdctrl_change_cb(void *opaque, bool load)
>> FDrive *drive = opaque;
>>
>> drive->media_inserted = load && drive->blk &&
>> blk_is_inserted(drive->blk);
>> -
>> drive->media_changed = 1;
>> - fd_revalidate(drive);
>> +
>> + if (load) {
>> + fd_revalidate(drive);
>> + }
>
> Hmm. Looks like drv->last_sect, ->max_track and ->flags now remain
> after an eject. If yes, why is that a good idea?
>
It probably isn't. Overlooked. I can allow the call to propagate as far
as the revalidate function, since it won't call pick_geometry for empty
drives anymore anyway.
>> }
>>
>> static bool fdctrl_is_tray_open(void *opaque)
>> @@ -2234,13 +2255,14 @@ 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);
>> } else {
>> drive->drive = FLOPPY_DRIVE_TYPE_NONE;
>> }
>> + fdctrl_change_cb(drive, drive->media_inserted);
>> }
>> }
- Re: [Qemu-block] [Qemu-devel] [PATCH v3 03/11] fdc: add disk field, (continued)
- [Qemu-block] [PATCH v3 01/11] fdc: move pick_geometry, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 04/11] fdc: add default drive type option, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 06/11] fdc: do not call revalidate on eject, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 08/11] fdc: add physical disk sizes, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 05/11] fdc: Add fallback option, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 07/11] fdc: implement new drive type property, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 09/11] fdc: rework pick_geometry, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 10/11] qtest/fdc: Support for 2.88MB drives, John Snow, 2015/12/16
- [Qemu-block] [PATCH v3 11/11] fdc: change auto fallback drive for ISA FDC to 288, John Snow, 2015/12/16