From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38916) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X4DV4-0003JP-1F for qemu-devel@nongnu.org; Mon, 07 Jul 2014 14:18:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X4DUt-0004GY-Dz for qemu-devel@nongnu.org; Mon, 07 Jul 2014 14:18:49 -0400 Received: from mx1.redhat.com ([209.132.183.28]:49195) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X4DUt-0004GC-3t for qemu-devel@nongnu.org; Mon, 07 Jul 2014 14:18:39 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s67IIb0W025152 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 7 Jul 2014 14:18:38 -0400 From: John Snow Date: Mon, 7 Jul 2014 14:17:58 -0400 Message-Id: <1404757089-4836-18-git-send-email-jsnow@redhat.com> In-Reply-To: <1404757089-4836-1-git-send-email-jsnow@redhat.com> References: <1404757089-4836-1-git-send-email-jsnow@redhat.com> Subject: [Qemu-devel] [PATCH 17/28] ahci: construct PIO Setup FIS for PIO commands List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: pbonzini@redhat.com, John Snow , stefanha@redhat.com, mst@redhat.com From: Paolo Bonzini PIO commands should put a PIO Setup FIS in the receive area when data transfer ends. Currently QEMU does not do this and only places the D2H FIS at the end of the operation. Signed-off-by: Paolo Bonzini Signed-off-by: John Snow --- hw/ide/ahci.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c index b40ec06..1299920 100644 --- a/hw/ide/ahci.c +++ b/hw/ide/ahci.c @@ -587,6 +587,56 @@ static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_SDB_FIS); } +static void ahci_write_fis_pio(AHCIDevice *ad, uint16_t len) +{ + AHCIPortRegs *pr = &ad->port_regs; + uint8_t *pio_fis, *cmd_fis; + uint64_t tbl_addr; + dma_addr_t cmd_len = 0x80; + + if (!ad->res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { + return; + } + + /* map cmd_fis */ + tbl_addr = le64_to_cpu(ad->cur_cmd->tbl_addr); + cmd_fis = dma_memory_map(ad->hba->as, tbl_addr, &cmd_len, + DMA_DIRECTION_TO_DEVICE); + + pio_fis = &ad->res_fis[RES_FIS_PSFIS]; + + pio_fis[0] = 0x5f; + pio_fis[1] = (ad->hba->control_regs.irqstatus ? (1 << 6) : 0); + pio_fis[2] = ad->port.ifs[0].status; + pio_fis[3] = ad->port.ifs[0].error; + + pio_fis[4] = cmd_fis[4]; + pio_fis[5] = cmd_fis[5]; + pio_fis[6] = cmd_fis[6]; + pio_fis[7] = cmd_fis[7]; + pio_fis[8] = cmd_fis[8]; + pio_fis[9] = cmd_fis[9]; + pio_fis[10] = cmd_fis[10]; + pio_fis[11] = cmd_fis[11]; + pio_fis[12] = cmd_fis[12]; + pio_fis[13] = cmd_fis[13]; + pio_fis[14] = 0; + pio_fis[15] = ad->port.ifs[0].status; + pio_fis[16] = len & 255; + pio_fis[17] = len >> 8; + pio_fis[18] = 0; + pio_fis[19] = 0; + + if (pio_fis[2] & ERR_STAT) { + ahci_trigger_irq(ad->hba, ad, PORT_IRQ_TF_ERR); + } + + ahci_trigger_irq(ad->hba, ad, PORT_IRQ_PIOS_FIS); + + dma_memory_unmap(ad->hba->as, cmd_fis, cmd_len, + DMA_DIRECTION_TO_DEVICE, cmd_len); +} + static void ahci_write_fis_d2h(AHCIDevice *ad, uint8_t *cmd_fis) { AHCIPortRegs *pr = &ad->port_regs; @@ -1031,6 +1081,11 @@ out: } s->end_transfer_func(s); + + if (!(s->status & DRQ_STAT)) { + /* done with PIO send/receive */ + ahci_write_fis_pio(ad, le32_to_cpu(ad->cur_cmd->status)); + } } static void ahci_start_dma(IDEDMA *dma, IDEState *s, -- 1.9.3