All of lore.kernel.org
 help / color / mirror / Atom feed
From: John Snow <jsnow@redhat.com>
To: qemu-devel@nongnu.org
Cc: jsnow@redhat.com, peter.maydell@linaro.org,
	Paolo Bonzini <pbonzini@redhat.com>
Subject: [Qemu-devel] [PULL 25/30] ahci: move PIO Setup FIS before transfer, fix it for ATAPI commands
Date: Fri,  8 Jun 2018 13:47:28 -0400	[thread overview]
Message-ID: <20180608174733.4936-26-jsnow@redhat.com> (raw)
In-Reply-To: <20180608174733.4936-1-jsnow@redhat.com>

The PIO Setup FIS is written in the PIO:Entry state, which comes before
the ATA and ATAPI data transfer states.  As a result, the PIO Setup FIS
interrupt is now raised before DMA ends for ATAPI commands, and tests have
to be adjusted.

This is also hinted by the description of the command header in the AHCI
specification, where the "A" bit is described as

    When ‘1’, indicates that a PIO setup FIS shall be sent by the device
    indicating a transfer for the ATAPI command.

and also by the description of the ACMD (ATAPI command region):

    The ATAPI command must be either 12 or 16 bytes in length. The length
    transmitted by the HBA is determined by the PIO setup FIS that is sent
    by the device requesting the ATAPI command.

QEMU, which conflates the "generator" and the "receiver" of the FIS into
one device, always uses ATAPI_PACKET_SIZE, aka 12, for the length.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180606190955.20845-3-jsnow@redhat.com
Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c       | 18 ++++++------------
 tests/libqos/ahci.c | 35 +++++++++++++++++++++--------------
 tests/libqos/ahci.h |  3 +--
 3 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 571e32dd66..f25bef501d 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1259,7 +1259,6 @@ static void handle_reg_h2d_fis(AHCIState *s, int port,
             g_free(pretty_fis);
         }
         s->dev[port].done_atapi_packet = false;
-        /* XXX send PIO setup FIS */
     }
 
     ide_state->error = 0;
@@ -1353,10 +1352,12 @@ static void ahci_start_transfer(IDEDMA *dma)
     int is_atapi = opts & AHCI_CMD_ATAPI;
     int has_sglist = 0;
 
+    /* PIO FIS gets written prior to transfer */
+    ahci_write_fis_pio(ad, size);
+
     if (is_atapi && !ad->done_atapi_packet) {
         /* already prepopulated iobuffer */
         ad->done_atapi_packet = true;
-        size = 0;
         goto out;
     }
 
@@ -1376,19 +1377,12 @@ static void ahci_start_transfer(IDEDMA *dma)
         }
     }
 
-out:
-    /* declare that we processed everything */
-    s->data_ptr = s->data_end;
-
     /* Update number of transferred bytes, destroy sglist */
     dma_buf_commit(s, size);
-
+out:
+    /* declare that we processed everything */
+    s->data_ptr = s->data_end;
     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,
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 63e1f9b92d..7264e085d0 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -478,10 +478,10 @@ void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot)
     g_free(d2h);
 }
 
-void ahci_port_check_pio_sanity(AHCIQState *ahci, uint8_t port,
-                                uint8_t slot, size_t buffsize)
+void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd)
 {
     PIOSetupFIS *pio = g_malloc0(0x20);
+    uint8_t port = cmd->port;
 
     /* We cannot check the Status or E_Status registers, because
      * the status may have again changed between the PIO Setup FIS
@@ -489,15 +489,22 @@ void ahci_port_check_pio_sanity(AHCIQState *ahci, uint8_t port,
     qtest_memread(ahci->parent->qts, ahci->port[port].fb + 0x20, pio, 0x20);
     g_assert_cmphex(pio->fis_type, ==, 0x5f);
 
-    /* BUG: PIO Setup FIS as utilized by QEMU tries to fit the entire
-     * transfer size in a uint16_t field. The maximum transfer size can
-     * eclipse this; the field is meant to convey the size of data per
-     * each Data FIS, not the entire operation as a whole. For now,
-     * we will sanity check the broken case where applicable. */
-    if (buffsize <= UINT16_MAX) {
-        g_assert_cmphex(le16_to_cpu(pio->tx_count), ==, buffsize);
+    /* Data transferred by PIO will either be:
+     * (1) 12 or 16 bytes for an ATAPI command packet (QEMU always uses 12), or
+     * (2) Actual data from the drive.
+     * If we do both, (2) winds up erasing any evidence of (1).
+     */
+    if (cmd->props->atapi && (cmd->xbytes == 0 || cmd->props->dma)) {
+        g_assert(le16_to_cpu(pio->tx_count) == 12 ||
+                 le16_to_cpu(pio->tx_count) == 16);
+    } else {
+        /* The AHCI test suite here does not test any PIO command that specifies
+         * a DRQ block larger than one sector (like 0xC4), so this should always
+         * be one sector or less. */
+        size_t pio_len = ((cmd->xbytes % cmd->sector_size) ?
+                          (cmd->xbytes % cmd->sector_size) : cmd->sector_size);
+        g_assert_cmphex(le16_to_cpu(pio->tx_count), ==, pio_len);
     }
-
     g_free(pio);
 }
 
@@ -832,9 +839,9 @@ void ahci_command_enable_atapi_dma(AHCICommand *cmd)
     RegH2DFIS *fis = &(cmd->fis);
     g_assert(cmd->props->atapi);
     fis->feature_low |= 0x01;
-    cmd->interrupts &= ~AHCI_PX_IS_PSS;
+    /* PIO is still used to transfer the ATAPI command */
+    g_assert(cmd->props->pio);
     cmd->props->dma = true;
-    cmd->props->pio = false;
     /* BUG: We expect the DMA Setup interrupt for DMA commands */
     /* cmd->interrupts |= AHCI_PX_IS_DSS; */
 }
@@ -846,7 +853,7 @@ AHCICommand *ahci_command_create(uint8_t command_name)
 
     g_assert(props);
     cmd = g_new0(AHCICommand, 1);
-    g_assert(!(props->dma && props->pio));
+    g_assert(!(props->dma && props->pio) || props->atapi);
     g_assert(!(props->lba28 && props->lba48));
     g_assert(!(props->read && props->write));
     g_assert(!props->size || props->data);
@@ -1218,7 +1225,7 @@ void ahci_command_verify(AHCIQState *ahci, AHCICommand *cmd)
         ahci_port_check_d2h_sanity(ahci, port, slot);
     }
     if (cmd->props->pio) {
-        ahci_port_check_pio_sanity(ahci, port, slot, cmd->xbytes);
+        ahci_port_check_pio_sanity(ahci, cmd);
     }
 }
 
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index 715ca1e226..13f6d87b75 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -596,8 +596,7 @@ void ahci_port_check_interrupts(AHCIQState *ahci, uint8_t port,
                                 uint32_t intr_mask);
 void ahci_port_check_nonbusy(AHCIQState *ahci, uint8_t port, uint8_t slot);
 void ahci_port_check_d2h_sanity(AHCIQState *ahci, uint8_t port, uint8_t slot);
-void ahci_port_check_pio_sanity(AHCIQState *ahci, uint8_t port,
-                                uint8_t slot, size_t buffsize);
+void ahci_port_check_pio_sanity(AHCIQState *ahci, AHCICommand *cmd);
 void ahci_port_check_cmd_sanity(AHCIQState *ahci, AHCICommand *cmd);
 
 /* Misc */
-- 
2.14.3

  parent reply	other threads:[~2018-06-08 17:47 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-08 17:47 [Qemu-devel] [PULL 00/30] Ide patches John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 01/30] ahci: trim signatures on raise/lower John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 02/30] ahci: fix PxCI register race John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 03/30] ahci: don't schedule unnecessary BH John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 04/30] ahci: add port register enumeration John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 05/30] ahci: modify ahci_port_read to use register numbers John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 06/30] ahci: make port read traces more descriptive John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 07/30] ahci: fix spacing damage on ahci_port_write John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 08/30] ahci: combine identical clauses in port write John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 09/30] ahci: modify ahci_port_write to use register numbers John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 10/30] ahci: make port write traces more descriptive John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 11/30] ahci: delete old port register address definitions John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 12/30] ahci: add host register enumeration John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 13/30] ahci: fix host register max address John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 14/30] ahci: modify ahci_mem_read_32 to work on register numbers John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 15/30] ahci: make mem_read_32 traces more descriptive John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 16/30] ahci: fix spacing damage on ahci_mem_write John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 17/30] ahci: adjust ahci_mem_write to work on registers John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 18/30] ahci: delete old host register address definitions John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 19/30] ahci: make ahci_mem_write traces more descriptive John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 20/30] tests/boot-sector: Add magic bytes to s390x boot code header John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 21/30] tests/cdrom-test: Test booting from CD-ROM ISO image file John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 22/30] tests/cdrom-test: Test that -cdrom parameter is working John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 23/30] MAINTAINERS: Add the cdrom-test to John's section John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 24/30] libqos/ahci: track sector size John Snow
2018-06-08 17:47 ` John Snow [this message]
2018-06-08 17:47 ` [Qemu-devel] [PULL 26/30] ide: push end_transfer_func out of start_transfer callback, rename callback John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 27/30] ide: call ide_cmd_done from ide_transfer_stop John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 28/30] ide: make ide_transfer_stop idempotent John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 29/30] atapi: call ide_set_irq before ide_transfer_start John Snow
2018-06-08 17:47 ` [Qemu-devel] [PULL 30/30] ide: introduce ide_transfer_start_norecurse John Snow
2018-06-11 11:46 ` [Qemu-devel] [PULL 00/30] Ide patches Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180608174733.4936-26-jsnow@redhat.com \
    --to=jsnow@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.