[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v6 4/6] fdc: fix interrupt handling
From: |
Kevin Wolf |
Subject: |
Re: [Qemu-devel] [PATCH v6 4/6] fdc: fix interrupt handling |
Date: |
Mon, 25 Jun 2012 14:41:57 +0200 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20120430 Thunderbird/12.0.1 |
Am 22.06.2012 12:33, schrieb Pavel Hrdina:
> If you call the SENSE INTERRUPT STATUS command while there is no interrupt
> waiting you get as result unknown command.
>
> Fixed status0 register handling for read/write/format commands.
>
> Signed-off-by: Pavel Hrdina <address@hidden>
> ---
> hw/fdc.c | 34 +++++++++++++++++++++-------------
> 1 files changed, 21 insertions(+), 13 deletions(-)
>
> diff --git a/hw/fdc.c b/hw/fdc.c
> index 0270264..e28841c 100644
> --- a/hw/fdc.c
> +++ b/hw/fdc.c
> @@ -307,6 +307,9 @@ enum {
> };
>
> enum {
> + FD_SR0_DS0 = 0x01,
> + FD_SR0_DS1 = 0x02,
> + FD_SR0_HEAD = 0x04,
> FD_SR0_EQPMT = 0x10,
> FD_SR0_SEEK = 0x20,
> FD_SR0_ABNTERM = 0x40,
> @@ -972,14 +975,15 @@ static void fdctrl_reset_fifo(FDCtrl *fdctrl)
> }
>
> /* Set FIFO status for the host to read */
> -static void fdctrl_set_fifo(FDCtrl *fdctrl, int fifo_len, int do_irq)
> +static void fdctrl_set_fifo(FDCtrl *fdctrl, int fifo_len, uint8_t status0)
> {
> fdctrl->data_dir = FD_DIR_READ;
> fdctrl->data_len = fifo_len;
> fdctrl->data_pos = 0;
> fdctrl->msr |= FD_MSR_CMDBUSY | FD_MSR_RQM | FD_MSR_DIO;
> - if (do_irq)
> - fdctrl_raise_irq(fdctrl, 0x00);
> + if (status0) {
> + fdctrl_raise_irq(fdctrl, status0);
> + }
Is status0 != 0 the real condition or is it just what we have here and
what happens to give the right result with our implementation?
> }
>
> /* Set an error: unimplemented/unknown command */
> @@ -1044,10 +1048,12 @@ static void fdctrl_stop_transfer(FDCtrl *fdctrl,
> uint8_t status0,
> FDrive *cur_drv;
>
> cur_drv = get_cur_drv(fdctrl);
> + fdctrl->status0 = status0 | FD_SR0_SEEK | (cur_drv->head << 2) |
> + GET_CUR_DRV(fdctrl);
> +
> FLOPPY_DPRINTF("transfer status: %02x %02x %02x (%02x)\n",
> - status0, status1, status2,
> - status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl));
> - fdctrl->fifo[0] = status0 | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
> + status0, status1, status2, fdctrl->status0);
> + fdctrl->fifo[0] = fdctrl->status0;
> fdctrl->fifo[1] = status1;
> fdctrl->fifo[2] = status2;
> fdctrl->fifo[3] = cur_drv->track;
> @@ -1060,7 +1066,7 @@ static void fdctrl_stop_transfer(FDCtrl *fdctrl,
> uint8_t status0,
> }
> fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO;
> fdctrl->msr &= ~FD_MSR_NONDMA;
> - fdctrl_set_fifo(fdctrl, 7, 1);
> + fdctrl_set_fifo(fdctrl, 7, fdctrl->status0);
> }
>
> /* Prepare a data transfer (either DMA or FIFO) */
> @@ -1175,7 +1181,7 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int
> direction)
> if (direction != FD_DIR_WRITE)
> fdctrl->msr |= FD_MSR_DIO;
> /* IO based transfer: calculate len */
> - fdctrl_raise_irq(fdctrl, 0x00);
> + fdctrl_raise_irq(fdctrl, FD_SR0_SEEK);
>
> return;
> }
> @@ -1604,16 +1610,18 @@ static void
> fdctrl_handle_sense_interrupt_status(FDCtrl *fdctrl, int direction)
> {
> FDrive *cur_drv = get_cur_drv(fdctrl);
>
> - if(fdctrl->reset_sensei > 0) {
> + if (fdctrl->reset_sensei > 0) {
> fdctrl->fifo[0] =
> FD_SR0_RDYCHG + FD_RESET_SENSEI_COUNT - fdctrl->reset_sensei;
> fdctrl->reset_sensei--;
> + } else if (!(fdctrl->sra & FD_SRA_INTPEND)) {
> + fdctrl->fifo[0] = FD_SR0_INVCMD;
> + fdctrl_set_fifo(fdctrl, 1, 0);
> + return;
> } else {
> - /* XXX: status0 handling is broken for read/write
> - commands, so we do this hack. It should be suppressed
> - ASAP */
> fdctrl->fifo[0] =
> - FD_SR0_SEEK | (cur_drv->head << 2) | GET_CUR_DRV(fdctrl);
> + (fdctrl->status0 & ~(FD_SR0_HEAD | FD_SR0_DS1 | FD_SR0_DS0))
> + | GET_CUR_DRV(fdctrl);
Why isn't fdctrl->status0 already right?
In any case, I think if you're masking out the head number from status0,
you need to or it back, even if from a different source.
Kevin
- [Qemu-devel] [PATCH v6 3/6] fdc: rewrite seek and DSKCHG bit handling, (continued)
- Message not available