Commit 5e16adf555 for qemu.org

commit 5e16adf5550e50e7d792d7a328f4bc0b17a53673
Author: Denis V. Lunev <den@openvz.org>
Date:   Fri Aug 14 15:35:23 2026 +0200

    tests/qtest/libqos/ahci: allow a count and an expected error

    A command that transfers no data can still take an argument in the count
    register of the register FIS, and a test may well expect such a command
    to be aborted. AHCICommand is private to the library, so add two
    setters: ahci_command_set_count() writes the count of a non-data
    command, and ahci_command_expect_error() records the error register bits
    the command is expected to complete with, which is what
    ahci_atapi_test_ready() does inline for a sense key today.

    INITIALIZE DEVICE PARAMETERS is the first user of both, so describe it
    in the command properties table as well.

    Cc: John Snow <jsnow@redhat.com>
    Cc: Peter Maydell <peter.maydell@linaro.org>
    Cc: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
    Signed-off-by: Denis V. Lunev <den@openvz.org>

diff --git a/tests/qtest/libqos/ahci.c b/tests/qtest/libqos/ahci.c
index e3019a1eca..50b63239c2 100644
--- a/tests/qtest/libqos/ahci.c
+++ b/tests/qtest/libqos/ahci.c
@@ -74,6 +74,7 @@ AHCICommandProp ahci_command_properties[] = {
     { .cmd = CMD_READ_MAX,       .lba28 = true },
     { .cmd = CMD_READ_MAX_EXT,   .lba48 = true },
     { .cmd = CMD_FLUSH_CACHE,    .data = false },
+    { .cmd = CMD_INIT_DP,        .data = false },
     { .cmd = CMD_PACKET,         .data = true,  .size = 16,
                                  .atapi = true, .pio = true },
     { .cmd = CMD_PACKET_ID,      .data = true,  .pio = true,
@@ -1180,6 +1181,19 @@ void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size)
     ahci_command_set_sizes(cmd, cmd->xbytes, prd_size);
 }

+/* For a no-data command, whose count carries an argument of its own */
+void ahci_command_set_count(AHCICommand *cmd, uint16_t count)
+{
+    g_assert(!cmd->props->data);
+    cmd->fis.count = count;
+}
+
+void ahci_command_expect_error(AHCICommand *cmd, uint8_t err)
+{
+    cmd->interrupts |= AHCI_PX_IS_TFES;
+    cmd->errors |= err;
+}
+
 void ahci_command_adjust(AHCICommand *cmd, uint64_t offset, uint64_t buffer,
                          uint64_t xbytes, unsigned prd_size)
 {
diff --git a/tests/qtest/libqos/ahci.h b/tests/qtest/libqos/ahci.h
index 2a48a7523d..6d861c79ee 100644
--- a/tests/qtest/libqos/ahci.h
+++ b/tests/qtest/libqos/ahci.h
@@ -278,6 +278,7 @@ enum {
     CMD_READ_MAX       = 0xF8,
     CMD_READ_MAX_EXT   = 0x27,
     CMD_FLUSH_CACHE    = 0xE7,
+    CMD_INIT_DP        = 0x91, /* INITIALIZE DEVICE PARAMETERS */
     CMD_IDENTIFY       = 0xEC,
     CMD_PACKET         = 0xA0,
     CMD_PACKET_ID      = 0xA1,
@@ -324,6 +325,9 @@ enum {
 #define ATA_DEVICE_DRIVE 0x10
 #define ATA_DEVICE_HEAD  0x0F

+/* ATA error register bits */
+#define ATA_ERR_ABRT     0x04
+
 /*** Structures ***/

 typedef struct AHCIPortQState {
@@ -638,6 +642,8 @@ void ahci_command_set_size(AHCICommand *cmd, uint64_t xbytes);
 void ahci_command_set_prd_size(AHCICommand *cmd, unsigned prd_size);
 void ahci_command_set_sizes(AHCICommand *cmd, uint64_t xbytes,
                             unsigned prd_size);
+void ahci_command_set_count(AHCICommand *cmd, uint16_t count);
+void ahci_command_expect_error(AHCICommand *cmd, uint8_t err);
 void ahci_command_set_acmd(AHCICommand *cmd, void *acmd);
 void ahci_command_enable_atapi_dma(AHCICommand *cmd);
 void ahci_command_adjust(AHCICommand *cmd, uint64_t lba_sect, uint64_t gbuffer,