From patchwork Wed Jun 13 13:43:14 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pavel Hrdina X-Patchwork-Id: 164694 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id E3E31B702B for ; Wed, 13 Jun 2012 23:44:13 +1000 (EST) Received: from localhost ([::1]:44206 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Senrn-00078t-8n for incoming@patchwork.ozlabs.org; Wed, 13 Jun 2012 09:44:11 -0400 Received: from eggs.gnu.org ([208.118.235.92]:54955) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Senr8-0005ZV-G5 for qemu-devel@nongnu.org; Wed, 13 Jun 2012 09:43:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Senr1-0004No-D0 for qemu-devel@nongnu.org; Wed, 13 Jun 2012 09:43:30 -0400 Received: from mx1.redhat.com ([209.132.183.28]:17411) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Senr1-0004NR-56 for qemu-devel@nongnu.org; Wed, 13 Jun 2012 09:43:23 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5DDhLKW003987 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 13 Jun 2012 09:43:21 -0400 Received: from antique-laptop.brq.redhat.com (dhcp-27-171.brq.redhat.com [10.34.27.171]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q5DDhFMM009415; Wed, 13 Jun 2012 09:43:20 -0400 From: Pavel Hrdina To: qemu-devel@nongnu.org Date: Wed, 13 Jun 2012 15:43:14 +0200 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: Pavel Hrdina Subject: [Qemu-devel] [PATCH v5 4/4] fdc: fix interrupt handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- hw/fdc.c | 34 +++++++++++++++++++++------------- 1 files changed, 21 insertions(+), 13 deletions(-) diff --git a/hw/fdc.c b/hw/fdc.c index d338c3f..0a5d58d 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); + } } /* Set an error: unimplemented/unknown command */ @@ -1040,10 +1044,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; @@ -1056,7 +1062,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) */ @@ -1170,7 +1176,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; } @@ -1598,16 +1604,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); } fdctrl->fifo[1] = cur_drv->track;