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, stefanha@redhat.com, mst@redhat.com
Subject: [Qemu-devel] [RFC 09/10] ahci: factor out FIS decomposition
Date: Sat, 13 Sep 2014 00:34:14 -0400	[thread overview]
Message-ID: <1410582855-21870-10-git-send-email-jsnow@redhat.com> (raw)
In-Reply-To: <1410582855-21870-1-git-send-email-jsnow@redhat.com>

Signed-off-by: John Snow <jsnow@redhat.com>
---
 hw/ide/ahci.c | 169 ++++++++++++++++++++++++++++++----------------------------
 1 file changed, 86 insertions(+), 83 deletions(-)

diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index e4eae0c..5bc5a92 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -936,10 +936,94 @@ static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,
     }
 }
 
+static void handle_reg_h2d_fis(AHCIState *s, int port,
+                               int slot, uint8_t *cmd_fis)
+{
+    IDEState *ide_state = &s->dev[port].port.ifs[0];
+    AHCICmdHdr *cmd = s->dev[port].cur_cmd;
+    uint32_t opts = le32_to_cpu(cmd->opts);
+
+    if (cmd_fis[1] & 0x0F) {
+        DPRINTF(port, "Port Multiplier not supported."
+                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
+                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
+        return;
+    }
+
+    if (cmd_fis[1] & 0x70) {
+        DPRINTF(port, "Reserved flags set in H2D Register FIS."
+                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
+                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
+        return;
+    }
+
+    if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
+        switch (s->dev[port].port_state) {
+        case STATE_RUN:
+            if (cmd_fis[15] & ATA_SRST) {
+                s->dev[port].port_state = STATE_RESET;
+            }
+            break;
+        case STATE_RESET:
+            if (!(cmd_fis[15] & ATA_SRST)) {
+                ahci_reset_port(s, port);
+            }
+            break;
+        }
+        return;
+    }
+
+    /* Check for NCQ command */
+    if (is_ncq(cmd_fis[2])) {
+        process_ncq_command(s, port, cmd_fis, slot);
+        return;
+    }
+
+    /* Decompose the FIS:
+     * AHCI does not interpret FIS packets, it only forwards them.
+     * SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
+     * Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
+     *
+     * ATA4 describes sector number for LBA28/CHS commands.
+     * ATA6 describes sector number for LBA48 commands.
+     * ATA8 deprecates CHS fully, describing only LBA28/48.
+     *
+     * We dutifully convert the FIS into IDE registers, and allow the
+     * core layer to interpret them as needed. */
+    ide_state->feature = cmd_fis[3];
+    ide_state->sector = cmd_fis[4];      /* LBA 7:0 */
+    ide_state->lcyl = cmd_fis[5];        /* LBA 15:8  */
+    ide_state->hcyl = cmd_fis[6];        /* LBA 23:16 */
+    ide_state->select = cmd_fis[7];      /* LBA 27:24 (LBA28) */
+    ide_state->hob_sector = cmd_fis[8];  /* LBA 31:24 */
+    ide_state->hob_lcyl = cmd_fis[9];    /* LBA 39:32 */
+    ide_state->hob_hcyl = cmd_fis[10];   /* LBA 47:40 */
+    ide_state->hob_feature = cmd_fis[11];
+    ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
+    /* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
+    /* 15: Only valid when UPDATE_COMMAND not set. */
+
+    /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
+     * table to ide_state->io_buffer */
+    if (opts & AHCI_CMD_ATAPI) {
+        memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
+        debug_print_fis(ide_state->io_buffer, 0x10);
+        s->dev[port].done_atapi_packet = false;
+        /* XXX send PIO setup FIS */
+    }
+
+    ide_state->error = 0;
+
+    /* Reset transferred byte counter */
+    cmd->status = 0;
+
+    /* We're ready to process the command in FIS byte 2. */
+    ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
+}
+
 static int handle_cmd(AHCIState *s, int port, int slot)
 {
     IDEState *ide_state;
-    uint32_t opts;
     uint64_t tbl_addr;
     AHCICmdHdr *cmd;
     uint8_t *cmd_fis;
@@ -966,7 +1050,6 @@ static int handle_cmd(AHCIState *s, int port, int slot)
         return -1;
     }
 
-    opts = le32_to_cpu(cmd->opts);
     tbl_addr = le64_to_cpu(cmd->tbl_addr);
     cmd_len = 0x80;
     cmd_fis = dma_memory_map(s->as, tbl_addr, &cmd_len,
@@ -984,95 +1067,15 @@ static int handle_cmd(AHCIState *s, int port, int slot)
 
     switch (cmd_fis[0]) {
         case SATA_FIS_TYPE_REGISTER_H2D:
+            handle_reg_h2d_fis(s, port, slot, cmd_fis);
             break;
         default:
             DPRINTF(port, "unknown command cmd_fis[0]=%02x cmd_fis[1]=%02x "
                           "cmd_fis[2]=%02x\n", cmd_fis[0], cmd_fis[1],
                           cmd_fis[2]);
-            goto out;
             break;
     }
 
-    if (cmd_fis[1] & 0x0F) {
-        DPRINTF(port, "Port Multiplier not supported."
-                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
-                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
-        goto out;
-    }
-
-    if (cmd_fis[1] & 0x70) {
-        DPRINTF(port, "Reserved flags set in H2D Register FIS."
-                " cmd_fis[0]=%02x cmd_fis[1]=%02x cmd_fis[2]=%02x\n",
-                cmd_fis[0], cmd_fis[1], cmd_fis[2]);
-        goto out;
-    }
-
-    if (!(cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER)) {
-        switch (s->dev[port].port_state) {
-        case STATE_RUN:
-            if (cmd_fis[15] & ATA_SRST) {
-                s->dev[port].port_state = STATE_RESET;
-            }
-            break;
-        case STATE_RESET:
-            if (!(cmd_fis[15] & ATA_SRST)) {
-                ahci_reset_port(s, port);
-            }
-            break;
-        }
-    }
-
-    else if (cmd_fis[1] & SATA_FIS_REG_H2D_UPDATE_COMMAND_REGISTER) {
-
-        /* Check for NCQ command */
-        if (is_ncq(cmd_fis[2])) {
-            process_ncq_command(s, port, cmd_fis, slot);
-            goto out;
-        }
-
-        /* Decompose the FIS:
-         * AHCI does not interpret FIS packets, it only forwards them.
-         * SATA 1.0 describes how to decode LBA28 and CHS FIS packets.
-         * Later specifications, e.g, SATA 3.2, describe LBA48 FIS packets.
-         *
-         * ATA4 describes sector number for LBA28/CHS commands.
-         * ATA6 describes sector number for LBA48 commands.
-         * ATA8 deprecates CHS fully, describing only LBA28/48.
-         *
-         * We dutifully convert the FIS into IDE registers, and allow the
-         * core layer to interpret them as needed. */
-        ide_state->feature = cmd_fis[3];
-        ide_state->sector = cmd_fis[4];     /* LBA 7:0 */
-        ide_state->lcyl = cmd_fis[5];       /* LBA 15:8  */
-        ide_state->hcyl = cmd_fis[6];       /* LBA 23:16 */
-        ide_state->select = cmd_fis[7];     /* LBA 27:24 (LBA28) */
-        ide_state->hob_sector = cmd_fis[8]; /* LBA 31:24 */
-        ide_state->hob_lcyl = cmd_fis[9];   /* LBA 39:32 */
-        ide_state->hob_hcyl = cmd_fis[10];  /* LBA 47:40 */
-        ide_state->hob_feature = cmd_fis[11];
-        ide_state->nsector = (int64_t)((cmd_fis[13] << 8) | cmd_fis[12]);
-        /* 14, 16, 17, 18, 19: Reserved (SATA 1.0) */
-        /* 15: Only valid when UPDATE_COMMAND not set. */
-
-        /* Copy the ACMD field (ATAPI packet, if any) from the AHCI command
-         * table to ide_state->io_buffer
-         */
-        if (opts & AHCI_CMD_ATAPI) {
-            memcpy(ide_state->io_buffer, &cmd_fis[AHCI_COMMAND_TABLE_ACMD], 0x10);
-            debug_print_fis(ide_state->io_buffer, 0x10);
-            s->dev[port].done_atapi_packet = false;
-            /* XXX send PIO setup FIS */
-        }
-
-        ide_state->error = 0;
-
-        /* Reset transferred byte counter */
-        cmd->status = 0;
-
-        /* We're ready to process the command in FIS byte 2. */
-        ide_exec_cmd(&s->dev[port].port, cmd_fis[2]);
-    }
-
 out:
     dma_memory_unmap(s->as, cmd_fis, cmd_len, DMA_DIRECTION_FROM_DEVICE,
                      cmd_len);
-- 
1.9.3

  parent reply	other threads:[~2014-09-13  4:34 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-13  4:34 [Qemu-devel] [RFC 00/10] AHCI Device improvements John Snow
2014-09-13  4:34 ` [Qemu-devel] [RFC 01/10] ide: add is_write() macro for semantic consistency John Snow
2014-09-13 12:54   ` Paolo Bonzini
2014-09-13 17:01     ` John Snow
2014-09-13  4:34 ` [Qemu-devel] [RFC 02/10] AHCI: Update byte count after DMA completion John Snow
2014-09-13 13:21   ` Paolo Bonzini
2014-09-15 20:07     ` John Snow
2014-09-16  7:54       ` Paolo Bonzini
2014-09-13  4:34 ` [Qemu-devel] [RFC 03/10] AHCI: Add PRD interrupt John Snow
2014-09-13 13:26   ` Paolo Bonzini
2014-09-13 19:50     ` Paolo Bonzini
2014-09-15 16:31       ` John Snow
2014-09-16  7:44         ` Paolo Bonzini
2014-09-15 16:13     ` John Snow
2014-09-13  4:34 ` [Qemu-devel] [RFC 04/10] ide: Correct handling of malformed/short PRDTs John Snow
2014-09-13 13:23   ` Paolo Bonzini
2014-09-13  4:34 ` [Qemu-devel] [RFC 05/10] AHCI: Rename NCQFIS structure fields John Snow
2014-09-13  4:34 ` [Qemu-devel] [RFC 06/10] AHCI: Fix FIS decomposition John Snow
2014-09-13  4:34 ` [Qemu-devel] [RFC 07/10] ide/ahci: Reorder error cases in handle_cmd John Snow
2014-09-13 13:27   ` Paolo Bonzini
2014-09-13  4:34 ` [Qemu-devel] [RFC 08/10] ahci: Check cmd_fis[1] more explicitly John Snow
2014-09-13 13:26   ` Paolo Bonzini
2014-09-13  4:34 ` John Snow [this message]
2014-09-13 13:27   ` [Qemu-devel] [RFC 09/10] ahci: factor out FIS decomposition Paolo Bonzini
2014-09-13  4:34 ` [Qemu-devel] [RFC 10/10] AHCI: Fix SDB FIS Construction John Snow

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=1410582855-21870-10-git-send-email-jsnow@redhat.com \
    --to=jsnow@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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.