Commit dd90d3cd73 for qemu.org
commit dd90d3cd73b9b2b0f27a9e51bfe542b3a510545b
Author: Denis V. Lunev <den@openvz.org>
Date: Tue Aug 18 01:05:36 2026 +0200
tests/qtest/ide-test: cover the UDMA5 identify words
/ide/identify/udma and /ide/identify/udma_atapi check that a device
advertising UDMA mode 5 claims a standard that defines it and reports the
hardware reset result, on the disk and on the CD-ROM. The ATAPI case also
checks that the words obsolete in IDENTIFY PACKET DEVICE data stay
clear, and that the reset result reports a passed diagnostic, which
only the packet path does so far.
Cc: John Snow <jsnow@redhat.com>
Cc: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
index a3109da908..92e3d9b343 100644
--- a/tests/qtest/ide-test.c
+++ b/tests/qtest/ide-test.c
@@ -104,6 +104,7 @@ enum {
CMD_FLUSH_CACHE = 0xe7,
CMD_IDENTIFY = 0xec,
CMD_PACKET = 0xa0,
+ CMD_IDENTIFY_PACKET = 0xa1,
CMD_READ_NATIVE = 0xf8, /* READ NATIVE MAX ADDRESS */
CMDF_ABORT = 0x100,
@@ -1571,6 +1572,72 @@ static void test_migrate_chs_rejected(void)
unlink(path);
}
+/*
+ * A device advertising UDMA5 has to claim a standard that defines it, and a
+ * parallel attachment has to report the cable word (ACS-3 7.12.7.47).
+ */
+static void test_identify_udma(bool packet)
+{
+ QTestState *qts;
+ QPCIDevice *dev;
+ QPCIBar bmdma_bar, ide_bar;
+ uint16_t buf[256];
+ int i;
+
+ if (packet) {
+ qts = ide_test_start("-device ide-cd,bus=ide.0");
+ } else {
+ qts = ide_test_start(
+ "-blockdev driver=file,node-name=hda,filename=%s "
+ "-device ide-hd,drive=hda,bus=ide.0,unit=0 ",
+ tmp_path[0]);
+ }
+ dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
+
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_command,
+ packet ? CMD_IDENTIFY_PACKET : CMD_IDENTIFY);
+ for (i = 0; i < 256; i++) {
+ buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
+ }
+
+ /* UDMA5 supported and selected */
+ assert_bit_set(buf[88], 1 << 5);
+ assert_bit_set(buf[88], 1 << 13);
+
+ /* UDMA5 arrived in ATA/ATAPI-6, so word 80 has to reach bit 6 */
+ assert_bit_set(buf[80], 1 << 6);
+ if (packet) {
+ /* Bits 3:1 are obsolete in IDENTIFY PACKET DEVICE data */
+ assert_bit_clear(buf[80], 0x0e);
+ }
+
+ /* Word 93: reserved bit clear, fixed bit set, 80-conductor cable */
+ assert_bit_clear(buf[93], 1 << 15);
+ assert_bit_set(buf[93], 1 << 14);
+ assert_bit_set(buf[93], 1 << 13);
+ assert_bit_set(buf[93], 1 << 0);
+ /* Device 0 clears the device 1 result */
+ assert_bit_clear(buf[93], 0x1f00);
+ if (packet) {
+ /* the disk path has yet to gain this */
+ assert_bit_set(buf[93], 1 << 3);
+ }
+
+ free_pci_device(dev);
+ ide_test_quit(qts);
+}
+
+static void test_identify_udma_ata(void)
+{
+ test_identify_udma(false);
+}
+
+static void test_identify_udma_atapi(void)
+{
+ test_identify_udma(true);
+}
+
/* A PIO transfer window reaching past the io_buffer has to be refused */
static void test_migrate_pio_state_rejected(void)
{
@@ -1843,6 +1910,8 @@ int main(int argc, char **argv)
qtest_add_func("/ide/migration/chs_rejected", test_migrate_chs_rejected);
qtest_add_func("/ide/migration/pio_state_rejected",
test_migrate_pio_state_rejected);
+ qtest_add_func("/ide/identify/udma", test_identify_udma_ata);
+ qtest_add_func("/ide/identify/udma_atapi", test_identify_udma_atapi);
qtest_add_func("/ide/identify", test_identify);