From patchwork Mon Feb 7 12:46:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 82144 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 2799DB70E3 for ; Tue, 8 Feb 2011 08:02:14 +1100 (EST) Received: from localhost ([127.0.0.1]:46498 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmRB0-0005Vm-TK for incoming@patchwork.ozlabs.org; Mon, 07 Feb 2011 08:30:47 -0500 Received: from [140.186.70.92] (port=36893 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PmQSn-0008IG-AE for qemu-devel@nongnu.org; Mon, 07 Feb 2011 07:45:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PmQSk-0001XR-Hb for qemu-devel@nongnu.org; Mon, 07 Feb 2011 07:45:03 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34628) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PmQSk-0001Vf-5o for qemu-devel@nongnu.org; Mon, 07 Feb 2011 07:45:02 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p17Cj0e1006946 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 7 Feb 2011 07:45:00 -0500 Received: from dhcp-5-188.str.redhat.com (dhcp-5-175.str.redhat.com [10.32.5.175]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p17Cin43027395; Mon, 7 Feb 2011 07:44:59 -0500 From: Kevin Wolf To: anthony@codemonkey.ws Date: Mon, 7 Feb 2011 13:46:29 +0100 Message-Id: <1297082796-1369-8-git-send-email-kwolf@redhat.com> In-Reply-To: <1297082796-1369-1-git-send-email-kwolf@redhat.com> References: <1297082796-1369-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, qemu-devel@nongnu.org Subject: [Qemu-devel] [STABLE 0.14][PATCH 07/14] ahci: send init d2h fis on fis enable X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Alexander Graf The drive sends a d2h init fis on initialization. Usually, the guest doesn't receive fises yet at that point though, so the delivery is deferred. Let's reflect that by sending the init fis on fis receive enablement. Signed-off-by: Alexander Graf Signed-off-by: Kevin Wolf (cherry picked from commit 87e62065bb5e0e544e45e6935e3ac2b053fe446e) --- hw/ide/ahci.c | 38 +++++++++++++++++++++++++++++++------- hw/ide/ahci.h | 1 + 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index 6822046..e6ac77c 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -47,6 +47,7 @@ static void check_cmd(AHCIState *s, int port); static int handle_cmd(AHCIState *s,int port,int slot); static void ahci_reset_port(AHCIState *s, int port); static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis); +static void ahci_init_d2h(AHCIDevice *ad); static uint32_t ahci_port_read(AHCIState *s, int port, int offset) { @@ -230,6 +231,16 @@ static void ahci_port_write(AHCIState *s, int port, int offset, uint32_t val) pr->cmd |= PORT_CMD_FIS_ON; } + /* XXX usually the FIS would be pending on the bus here and + issuing deferred until the OS enables FIS receival. + Instead, we only submit it once - which works in most + cases, but is a hack. */ + if ((pr->cmd & PORT_CMD_FIS_ON) && + !s->dev[port].init_d2h_sent) { + ahci_init_d2h(&s->dev[port]); + s->dev[port].init_d2h_sent = 1; + } + check_cmd(s, port); break; case PORT_TFDATA: @@ -462,12 +473,29 @@ static void ahci_check_cmd_bh(void *opaque) check_cmd(ad->hba, ad->port_no); } +static void ahci_init_d2h(AHCIDevice *ad) +{ + uint8_t init_fis[0x20]; + IDEState *ide_state = &ad->port.ifs[0]; + + memset(init_fis, 0, sizeof(init_fis)); + + init_fis[4] = 1; + init_fis[12] = 1; + + if (ide_state->drive_kind == IDE_CD) { + init_fis[5] = ide_state->lcyl; + init_fis[6] = ide_state->hcyl; + } + + ahci_write_fis_d2h(ad, init_fis); +} + static void ahci_reset_port(AHCIState *s, int port) { AHCIDevice *d = &s->dev[port]; AHCIPortRegs *pr = &d->port_regs; IDEState *ide_state = &d->port.ifs[0]; - uint8_t init_fis[0x20]; int i; DPRINTF(port, "reset port\n"); @@ -482,6 +510,7 @@ static void ahci_reset_port(AHCIState *s, int port) pr->scr_err = 0; pr->scr_act = 0; d->busy_slot = -1; + d->init_d2h_sent = 0; ide_state = &s->dev[port].port.ifs[0]; if (!ide_state->bs) { @@ -504,7 +533,6 @@ static void ahci_reset_port(AHCIState *s, int port) ncq_tfs->used = 0; } - memset(init_fis, 0, sizeof(init_fis)); s->dev[port].port_state = STATE_RUN; if (!ide_state->bs) { s->dev[port].port_regs.sig = 0; @@ -514,8 +542,6 @@ static void ahci_reset_port(AHCIState *s, int port) ide_state->lcyl = 0x14; ide_state->hcyl = 0xeb; DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl); - init_fis[5] = ide_state->lcyl; - init_fis[6] = ide_state->hcyl; ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT; } else { s->dev[port].port_regs.sig = SATA_SIGNATURE_DISK; @@ -523,9 +549,7 @@ static void ahci_reset_port(AHCIState *s, int port) } ide_state->error = 1; - init_fis[4] = 1; - init_fis[12] = 1; - ahci_write_fis_d2h(d, init_fis); + ahci_init_d2h(d); } static void debug_print_fis(uint8_t *fis, int cmd_len) diff --git a/hw/ide/ahci.h b/hw/ide/ahci.h index d65b5e3..b2786d1 100644 --- a/hw/ide/ahci.h +++ b/hw/ide/ahci.h @@ -282,6 +282,7 @@ struct AHCIDevice { int dma_status; int done_atapi_packet; int busy_slot; + int init_d2h_sent; BlockDriverCompletionFunc *dma_cb; AHCICmdHdr *cur_cmd; NCQTransferState ncq_tfs[AHCI_MAX_CMDS];