[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v3 3/4] fdc: rewrite seek and DSKCHG bit handlin
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH v3 3/4] fdc: rewrite seek and DSKCHG bit handling |
Date: |
Tue, 12 Jun 2012 15:03:59 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120605 Thunderbird/13.0 |
Il 12/06/2012 13:19, Pavel Hrdina ha scritto:
> This bit is cleared on every successful seek to a different track (cylinder).
> The seek is also called on revalidate or on read/write/format commands which
> also clear the DSKCHG bit.
>
> Signed-off-by: Pavel Hrdina <address@hidden>
> ---
> hw/fdc.c | 66 ++++++++++++++++++++++++++++++-------------------------------
> 1 files changed, 32 insertions(+), 34 deletions(-)
>
> diff --git a/hw/fdc.c b/hw/fdc.c
> index 096aefc..b658504 100644
> --- a/hw/fdc.c
> +++ b/hw/fdc.c
> @@ -153,8 +153,11 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t
> track, uint8_t sect,
> }
> #endif
> drv->head = head;
> - if (drv->track != track)
> + if (drv->track != track) {
> ret = 1;
> + if (drv->bs != NULL && bdrv_is_inserted(drv->bs))
> + drv->media_changed = 0;
Coding style...
Otherwise looks good.
Paolo
> + }
> drv->track = track;
> drv->sect = sect;
> }
> @@ -169,9 +172,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t
> track, uint8_t sect,
> static void fd_recalibrate(FDrive *drv)
> {
> FLOPPY_DPRINTF("recalibrate\n");
> - drv->head = 0;
> - drv->track = 0;
> - drv->sect = 1;
> + fd_seek(drv, 0, 0, 1, 1);
> }
>
> /* Revalidate a disk drive after a disk change */
> @@ -710,14 +711,6 @@ static void fdctrl_raise_irq(FDCtrl *fdctrl, uint8_t
> status0)
> qemu_set_irq(fdctrl->irq, 1);
> fdctrl->sra |= FD_SRA_INTPEND;
> }
> - if (status0 & FD_SR0_SEEK) {
> - FDrive *cur_drv;
> - /* A seek clears the disk change line (if a disk is inserted) */
> - cur_drv = get_cur_drv(fdctrl);
> - if (cur_drv->bs != NULL && bdrv_is_inserted(cur_drv->bs)) {
> - cur_drv->media_changed = 0;
> - }
> - }
>
> fdctrl->reset_sensei = 0;
> fdctrl->status0 = status0;
> @@ -1003,30 +996,39 @@ static int fdctrl_seek_to_next_sect(FDCtrl *fdctrl,
> FDrive *cur_drv)
> fd_sector(cur_drv));
> /* XXX: cur_drv->sect >= cur_drv->last_sect should be an
> error in fact */
> - if (cur_drv->sect >= cur_drv->last_sect ||
> - cur_drv->sect == fdctrl->eot) {
> - cur_drv->sect = 1;
> + uint8_t new_head = cur_drv->head;
> + uint8_t new_track = cur_drv->track;
> + uint8_t new_sect = cur_drv->sect;
> +
> + int ret = 1;
> +
> + if (new_sect >= cur_drv->last_sect ||
> + new_sect == fdctrl->eot) {
> + new_sect = 1;
> if (FD_MULTI_TRACK(fdctrl->data_state)) {
> - if (cur_drv->head == 0 &&
> + if (new_head == 0 &&
> (cur_drv->flags & FDISK_DBL_SIDES) != 0) {
> - cur_drv->head = 1;
> + new_head = 1;
> } else {
> - cur_drv->head = 0;
> - cur_drv->track++;
> + new_head = 0;
> + new_track++;
> if ((cur_drv->flags & FDISK_DBL_SIDES) == 0)
> - return 0;
> + ret = 0;
> }
> } else {
> - cur_drv->track++;
> - return 0;
> + new_track++;
> + ret = 0;
> }
> - FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
> + if (ret == 1) {
> + FLOPPY_DPRINTF("seek to next track (%d %02x %02x => %d)\n",
> cur_drv->head, cur_drv->track,
> cur_drv->sect, fd_sector(cur_drv));
> + }
> } else {
> - cur_drv->sect++;
> + new_sect++;
> }
> - return 1;
> + fd_seek(cur_drv, new_head, new_track, new_sect, 1);
> + return ret;
> }
>
> /* Callback for transfer end (stop or abort) */
> @@ -1622,11 +1624,7 @@ static void fdctrl_handle_seek(FDCtrl *fdctrl, int
> direction)
> /* The seek command just sends step pulses to the drive and doesn't care
> if
> * there is a medium inserted of if it's banging the head against the
> drive.
> */
> - if (fdctrl->fifo[2] > cur_drv->max_track) {
> - cur_drv->track = cur_drv->max_track;
> - } else {
> - cur_drv->track = fdctrl->fifo[2];
> - }
> + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
> /* Raise Interrupt */
> fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
> }
> @@ -1691,9 +1689,9 @@ static void fdctrl_handle_relative_seek_out(FDCtrl
> *fdctrl, int direction)
> SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
> cur_drv = get_cur_drv(fdctrl);
> if (fdctrl->fifo[2] + cur_drv->track >= cur_drv->max_track) {
> - cur_drv->track = cur_drv->max_track - 1;
> + fd_seek(cur_drv, cur_drv->head, cur_drv->max_track - 1,
> cur_drv->sect, 1);
> } else {
> - cur_drv->track += fdctrl->fifo[2];
> + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
> }
> fdctrl_reset_fifo(fdctrl);
> /* Raise Interrupt */
> @@ -1707,9 +1705,9 @@ static void fdctrl_handle_relative_seek_in(FDCtrl
> *fdctrl, int direction)
> SET_CUR_DRV(fdctrl, fdctrl->fifo[1] & FD_DOR_SELMASK);
> cur_drv = get_cur_drv(fdctrl);
> if (fdctrl->fifo[2] > cur_drv->track) {
> - cur_drv->track = 0;
> + fd_seek(cur_drv, cur_drv->head, 0, cur_drv->sect, 1);
> } else {
> - cur_drv->track -= fdctrl->fifo[2];
> + fd_seek(cur_drv, cur_drv->head, fdctrl->fifo[2], cur_drv->sect, 1);
> }
> fdctrl_reset_fifo(fdctrl);
> /* Raise Interrupt */
>