fdc: fix media handling
v3 cover fdc: fix media handling
This patch series fixes handling of FDC when you don't have media inserted. Guest should see floppy drive if you start guest without media and should detect that there is no media in drive.
Pavel Hrdina (3):
fdc: floppy drive should be visible after start without media
fdc: fix media detection
fdc-test: introduced qtest no_media_on_start
hw/fdc.c | 14 ++++++++------ hw/pc.c | 2 +- tests/fdc-test.c | 29 ++++++++++++++++++++++++++--- 3 files changed, 35 insertions(+), 10 deletions(-)
Signature · 1 line
1.7.7.6
PATCH v3 1/3 fdc: floppy drive should be visible after start without media
If you start guest with floppy drive but without media inserted, guest still should see floppy drive pressent.
--- hw/pc.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
hw/pc.c +1 -1
@@ -382,7 +382,7 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,if (floppy) {fdc_get_bs (fd, floppy);for (i =0 ; i <2 ; i++) { -if (fd[i] &&bdrv_is_inserted (fd[i])) { +if (fd[i]) {bdrv_get_floppy_geometry_hint (fd[i], &nb_heads, &max_track, &last_sect,FDRIVE_DRV_NONE , &fd_type[i], &rate);
Signature · 1 line
1.7.7.6
PATCH v3 2/3 fdc: fix media detection
In reply to Pavel HrdinaWe have to set up 'media_changed' after guest start so floppy driver could detect that there is no media in drive. For this purpose we call 'fdctrl_change_cb' instead of 'fd_revalidate' in 'fdctrl_connect_drives'. 'fd_revalidate' is called inside 'fdctrl_change_cb'.
We still have to set default drive geometry in 'fd_revalidate' even if there is no media in drive. When you try to open (windows) or mount (linux) floppy the driver tries to seek on track 1. Linux guest stuck in loop then kernel crashes and windows guest prints error message.
--- hw/fdc.c | 14 ++++++++------ 1 files changed, 8 insertions(+), 6 deletions(-)
hw/fdc.c +8 -6
@@ -179,12 +179,14 @@ static void fd_revalidate(FDrive *drv)FDriveRate rate;FLOPPY_DPRINTF ("revalidate\n" ); -if (drv->bs !=NULL &&bdrv_is_inserted (drv->bs)) { +if (drv->bs !=NULL ) { ro =bdrv_is_read_only (drv->bs);bdrv_get_floppy_geometry_hint (drv->bs, &nb_heads, &max_track, &last_sect, drv->drive, &drive, &rate); -if (nb_heads !=0 && max_track !=0 && last_sect !=0 ) { -FLOPPY_DPRINTF ("User defined disk (%d %d %d)" , +if (!bdrv_is_inserted (drv->bs)) { +FLOPPY_DPRINTF ("No disk in drive\n" ); + }else if (nb_heads !=0 && max_track !=0 && last_sect !=0 ) { +FLOPPY_DPRINTF ("User defined disk (%d %d %d)\n" , nb_heads -1 , max_track, last_sect); }else { FLOPPY_DPRINTF("Floppy disk (%d h %d t %d s) %s\n", nb_heads,
@@ -201,7 +203,7 @@ static void fd_revalidate(FDrive *drv) drv->drive = drive; drv->media_rate = rate; }else { -FLOPPY_DPRINTF ("No disk in drive\n" ); +FLOPPY_DPRINTF ("No drive connected\n" ); drv->last_sect =0 ; drv->max_track =0 ; drv->flags &= ~FDISK_DBL_SIDES ;
@@ -709,7 +711,7 @@ static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t status0)FDrive *cur_drv;/* A seek clears the disk change line (if a disk is inserted) */ cur_drv =get_cur_drv (fdctrl); -if (cur_drv->max_track) { +if (cur_drv->bs !=NULL &&bdrv_is_inserted (cur_drv->bs)) { cur_drv->media_changed =0 ; } }
@@ -1878,7 +1880,7 @@ static int fdctrl_connect_drives(FDCtrl *fdctrl) }fd_init (drive); -fd_revalidate (drive); +fdctrl_change_cb (drive,0 );if (drive->bs) {bdrv_set_dev_ops (drive->bs, &fdctrl_block_ops, drive); }
Signature · 1 line
1.7.7.6
PATCH v3 3/3 fdc-test: introduced qtest no_media_on_start
In reply to Pavel HrdinaAfter guest start DSKCHG bit in DIR register should be set. If there is no media in drive, this bit should be set all the time.
--- tests/fdc-test.c | 29 ++++++++++++++++++++++++++--- 1 files changed, 26 insertions(+), 3 deletions(-)
tests/fdc-test.c +26 -3
@@ -108,6 +108,30 @@ static void send_step_pulse(void) cyl = (cyl +1 ) %4 ; } +static void test_no_media_on_start (void ) +{ +uint8_t dir; + +/* Media changed bit must be set all time after start if there is +* no media in drive. */ + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); +send_step_pulse (); +send_step_pulse (); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + +/* Insert media for other tests. */ +qmp ("{'execute':'change', 'arguments':{ 'device':'floppy0', " +"'target': '%s' }}" , test_image); +qmp ("" );/* ignore event (FIXME open -> open transition?!) */ +qmp ("" );/* ignore event */ +} +static void test_media_change (void ) {uint8_t dir;
@@ -177,12 +201,11 @@ int main(int argc, char **argv)/* Run the tests */ g_test_init (&argc, &argv,NULL ); - cmdline =g_strdup_printf ("-vnc none " -"-drive file=%s,if=floppy,cache=writeback " , - test_image); + cmdline =g_strdup_printf ("-vnc none " );qtest_start (cmdline);qtest_irq_intercept_in (global_qtest,"ioapic" ); +qtest_add_func ("/fdc/no_media_on_start" , test_no_media_on_start);qtest_add_func ("/fdc/media_change" , test_media_change); ret =g_test_run ();
Signature · 1 line
1.7.7.6
Re: [Qemu-devel] [PATCH v3 3/3] fdc-test: introduced qtest no_media_on_start
Il 23/05/2012 13:27, Pavel Hrdina ha scritto:
Quoted 29 lines
After guest start DSKCHG bit in DIR register should be set. If there is no media in drive, this bit should be set all the time.
Signed-off-by Pavel Hrdina <[email protected]>--- tests/fdc-test.c | 29 ++++++++++++++++++++++++++--- 1 files changed, 26 insertions(+), 3 deletions(-)tests/fdc-test.c +13
-0@@ -108,6 +108,30 @@ static void send_step_pulse(void) cyl = (cyl +1 ) %4 ; } +static void test_no_media_on_start (void ) +{ +uint8_t dir; + +/* Media changed bit must be set all time after start if there is +* no media in drive. */ + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); +send_step_pulse (); +send_step_pulse (); + dir =inb (FLOPPY_BASE + reg_dir);
tests/fdc-test.c static void send_step_pulse(void) · line 133
Quoted 10 lines
tests/fdc-test.c +10
-0+assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + +/* Insert media for other tests. */ +qmp ("{'execute':'change', 'arguments':{ 'device':'floppy0', " +"'target': '%s' }}" , test_image); +qmp ("" );/* ignore event (FIXME open -> open transition?!) */ +qmp ("" );/* ignore event */ +}
This makes it impossible to use the testcase with -p/-s (try tests/fdc-test --help). Please move these commands to test_media_change. Alternatively (perhaps better), leave the "-drive" option and add a matching eject command to test_no_media_on_start.
Thanks!
Paolo
Quoted 18 lines
tests/fdc-test.c +2
-3static void test_media_change (void ) {uint8_t dir;@@ -177,12 +201,11 @@ int main(int argc, char **argv)/* Run the tests */ g_test_init (&argc, &argv,NULL ); - cmdline =g_strdup_printf ("-vnc none " -"-drive file=%s,if=floppy,cache=writeback " , - test_image); + cmdline =g_strdup_printf ("-vnc none " );qtest_start (cmdline);qtest_irq_intercept_in (global_qtest,"ioapic" ); +qtest_add_func ("/fdc/no_media_on_start" , test_no_media_on_start);qtest_add_func ("/fdc/media_change" , test_media_change); ret =g_test_run ();
Re: [Qemu-devel] [PATCH v3 3/3] fdc-test: introduced qtest no_media_on_start
Am 23.05.2012 14:15, schrieb Paolo Bonzini:
Quoted 32 lines
Il 23/05/2012 13:27, Pavel Hrdina ha scritto:
Quoted 31 lines
After guest start DSKCHG bit in DIR register should be set. If there is no media in drive, this bit should be set all the time.
Signed-off-by Pavel Hrdina <[email protected]>--- tests/fdc-test.c | 29 ++++++++++++++++++++++++++--- 1 files changed, 26 insertions(+), 3 deletions(-)tests/fdc-test.c +15
-0@@ -108,6 +108,30 @@ static void send_step_pulse(void) cyl = (cyl +1 ) %4 ; } +static void test_no_media_on_start (void ) +{ +uint8_t dir; + +/* Media changed bit must be set all time after start if there is +* no media in drive. */ + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); +send_step_pulse (); +send_step_pulse (); + dir =inb (FLOPPY_BASE + reg_dir); +assert_bit_set (dir,DSKCHG ); + dir =inb (FLOPPY_BASE + reg_dir);
Quoted 8 lines
tests/fdc-test.c static void send_step_pulse(void) · line 133
Quoted 8 lines
tests/fdc-test.c +8
-0+assert_bit_set (dir,DSKCHG ); + +/* Insert media for other tests. */ +qmp ("{'execute':'change', 'arguments':{ 'device':'floppy0', " +"'target': '%s' }}" , test_image); +qmp ("" );/* ignore event (FIXME open -> open transition?!) */ +qmp ("" );/* ignore event */ +}
Can you also include a read from the CMOS to verify your fix?
Quoted 3 lines
This makes it impossible to use the testcase with -p/-s (try tests/fdc-test --help). Please move these commands to
test_media_change.
Makes sense.
Quoted 2 lines
Alternatively (perhaps better), leave the "-drive" option and add a matching eject command to
test_no_media_on_start.
Ejecting a floppy while the VM is running is different from not having it inserted at startup. Not sure, maybe system_reset after ejecting would help to run the same code paths.
Kevin