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>
Denis V. Lunev committed
Aug 18, 2026 at 01:05 UTC
dd90d3cd73b9b2b0f27a9e51bfe542b3a510545b
1 file changed
+69
tests/qtest/ide-test.c
+69
@@ -104,6 +104,7 @@ enum {
104
CMD_FLUSH_CACHE = 0xe7,
105
CMD_IDENTIFY = 0xec,
106
CMD_PACKET = 0xa0,
107
+ CMD_IDENTIFY_PACKET = 0xa1,
108
CMD_READ_NATIVE = 0xf8, /* READ NATIVE MAX ADDRESS */
109
110
CMDF_ABORT = 0x100,
@@ -1571,6 +1572,72 @@ static void test_migrate_chs_rejected(void)
1572
unlink(path);
1573
}
1574
1575
+/*
1576
+ * A device advertising UDMA5 has to claim a standard that defines it, and a
1577
+ * parallel attachment has to report the cable word (ACS-3 7.12.7.47).
1578
+ */
1579
+static void test_identify_udma(bool packet)
1580
+{
1581
+ QTestState *qts;
1582
+ QPCIDevice *dev;
1583
+ QPCIBar bmdma_bar, ide_bar;
1584
+ uint16_t buf[256];
1585
+ int i;
1586
+
1587
+ if (packet) {
1588
+ qts = ide_test_start("-device ide-cd,bus=ide.0");
1589
+ } else {
1590
+ qts = ide_test_start(
1591
+ "-blockdev driver=file,node-name=hda,filename=%s "
1592
+ "-device ide-hd,drive=hda,bus=ide.0,unit=0 ",
1593
+ tmp_path[0]);
1594
+ }
1595
+ dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
1596
+
1597
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
1598
+ qpci_io_writeb(dev, ide_bar, reg_command,
1599
+ packet ? CMD_IDENTIFY_PACKET : CMD_IDENTIFY);
1600
+ for (i = 0; i < 256; i++) {
1601
+ buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
1602
+ }
1603
+
1604
+ /* UDMA5 supported and selected */
1605
+ assert_bit_set(buf[88], 1 << 5);
1606
+ assert_bit_set(buf[88], 1 << 13);
1607
+
1608
+ /* UDMA5 arrived in ATA/ATAPI-6, so word 80 has to reach bit 6 */
1609
+ assert_bit_set(buf[80], 1 << 6);
1610
+ if (packet) {
1611
+ /* Bits 3:1 are obsolete in IDENTIFY PACKET DEVICE data */
1612
+ assert_bit_clear(buf[80], 0x0e);
1613
+ }
1614
+
1615
+ /* Word 93: reserved bit clear, fixed bit set, 80-conductor cable */
1616
+ assert_bit_clear(buf[93], 1 << 15);
1617
+ assert_bit_set(buf[93], 1 << 14);
1618
+ assert_bit_set(buf[93], 1 << 13);
1619
+ assert_bit_set(buf[93], 1 << 0);
1620
+ /* Device 0 clears the device 1 result */
1621
+ assert_bit_clear(buf[93], 0x1f00);
1622
+ if (packet) {
1623
+ /* the disk path has yet to gain this */
1624
+ assert_bit_set(buf[93], 1 << 3);
1625
+ }
1626
+
1627
+ free_pci_device(dev);
1628
+ ide_test_quit(qts);
1629
+}
1630
+
1631
+static void test_identify_udma_ata(void)
1632
+{
1633
+ test_identify_udma(false);
1634
+}
1635
+
1636
+static void test_identify_udma_atapi(void)
1637
+{
1638
+ test_identify_udma(true);
1639
+}
1640
+
1641
/* A PIO transfer window reaching past the io_buffer has to be refused */
1642
static void test_migrate_pio_state_rejected(void)
1643
{
@@ -1843,6 +1910,8 @@ int main(int argc, char **argv)
1910
qtest_add_func("/ide/migration/chs_rejected", test_migrate_chs_rejected);
1911
qtest_add_func("/ide/migration/pio_state_rejected",
1912
test_migrate_pio_state_rejected);
1913
+ qtest_add_func("/ide/identify/udma", test_identify_udma_ata);
1914
+ qtest_add_func("/ide/identify/udma_atapi", test_identify_udma_atapi);
1915
1916
qtest_add_func("/ide/identify", test_identify);
1917