Commit d6960ecdde for qemu.org
commit d6960ecdded35b2d4ef8b23763d19038b2d190b6
Author: Denis V. Lunev <den@openvz.org>
Date: Fri Aug 14 15:35:23 2026 +0200
tests/qtest/ahci: cover the sector count of INITIALIZE DEVICE PARAMETERS
The sector count register of a legacy port is eight bits wide, so
ide-test can only reach the lower end of the range the command has to
refuse. A register FIS carries a 16 bit count, which leaves AHCI as the
only way to ask for a translation of 256 sectors per logical track or
more.
Ask for 0, 256 and 65535 sectors and expect each to be aborted, then ask
for 32 and expect it to be accepted, so that the check cannot pass by
refusing everything.
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/ahci-test.c b/tests/qtest/ahci-test.c
index 71d23fe56a..30d7005626 100644
--- a/tests/qtest/ahci-test.c
+++ b/tests/qtest/ahci-test.c
@@ -905,6 +905,30 @@ static void ahci_test_flush(AHCIQState *ahci)
ahci_test_nondata(ahci, CMD_FLUSH_CACHE);
}
+static void ahci_test_specify(AHCIQState *ahci, uint16_t sectors,
+ bool supported)
+{
+ AHCICommand *cmd;
+ uint8_t port;
+
+ port = ahci_port_select(ahci);
+ ahci_port_clear(ahci, port);
+
+ cmd = ahci_command_create(CMD_INIT_DP);
+ ahci_command_set_count(cmd, sectors);
+ if (!supported) {
+ ahci_command_expect_error(cmd, ATA_ERR_ABRT);
+ }
+ ahci_command_commit(ahci, cmd, port);
+ ahci_command_issue(ahci, cmd);
+ if (!supported) {
+ ASSERT_BIT_SET(ahci_px_rreg(ahci, port, AHCI_PX_TFD),
+ AHCI_PX_TFD_STS_ERR);
+ }
+ ahci_command_verify(ahci, cmd);
+ ahci_command_free(cmd);
+}
+
static void ahci_test_max(AHCIQState *ahci)
{
RegD2HFIS *d2h = g_malloc0(0x20);
@@ -1012,6 +1036,21 @@ static void test_identify(void)
ahci_shutdown(ahci);
}
+static void test_specify(void)
+{
+ AHCIQState *ahci;
+
+ ahci = ahci_boot_and_enable(NULL);
+
+ /* A register FIS carries 16 bits of count, the legacy ports only eight */
+ ahci_test_specify(ahci, 0, false);
+ ahci_test_specify(ahci, 256, false);
+ ahci_test_specify(ahci, 0xffff, false);
+ ahci_test_specify(ahci, 32, true);
+
+ ahci_shutdown(ahci);
+}
+
/**
* Fragmented DMA test: Perform a standard 4K DMA read/write
* test, but make sure the physical regions are fragmented to
@@ -2220,6 +2259,7 @@ int main(int argc, char **argv)
qtest_add_func("/ahci/migrate/dma/halted", test_migrate_halted_dma);
qtest_add_func("/ahci/max", test_max);
+ qtest_add_func("/ahci/specify", test_specify);
qtest_add_func("/ahci/reset/simple", test_reset);
qtest_add_func("/ahci/reset/pending_callback", test_reset_pending_callback);