[PULL 15/17] hw/block/fdc: select the drive named by the READ ID command
Kevin Wolf <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu.block,gmane.comp.emulators.qemu |
|---|---|
| Message-ID | <[email protected]> |
From: Christian Quante <[email protected]> Every other command handler begins by latching the drive from the command byte: SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); fdctrl_handle_readid() does not, so it works on whichever drive happened to be selected last. A guest that issues READ ID for a drive other than the one currently selected gets an answer about the wrong one. It has gone unnoticed because a driver normally writes the DOR to spin up the motor first, and that write selects the drive as a side effect. The controller does not require it, though, and the command carries the drive number for a reason. Reported-by: Kevin Wolf <[email protected]> Signed-off-by: Christian Quante <[email protected]> Message-ID: <[email protected]> Reviewed-by: Kevin Wolf <[email protected]> Signed-off-by: Kevin Wolf <[email protected]> --- hw/block/fdc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 2c1681b7d0a..9b2409cfa4c 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -1936,7 +1936,10 @@ static void fdctrl_handle_save(FDCtrl *fdctrl, int direction) static void fdctrl_handle_readid(FDCtrl *fdctrl, int direction) { - FDrive *cur_drv = get_cur_drv(fdctrl); + FDrive *cur_drv; + + SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK); + cur_drv = get_cur_drv(fdctrl); cur_drv->head = (fdctrl->fifo[1] >> 2) & 1; timer_mod(fdctrl->result_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + -- 2.55.0