qemu-devel
[Top][All Lists]
Advanced

[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 */
> 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]