@samitouri / QOSamiQemu / commits / 0720913323

tests/qtest/ide-test: cover the IDENTIFY DEVICE geometry words

INITIALIZE DEVICE PARAMETERS has to leave the geometry the drive came with in words 3 and 6 and describe the translation it selected in words 54 to 58, and the data is cached, so which of the two a guest is told depends on when it first asked. Cover both orders, as each alone leaves half of it untested: one test has the data built while the default is in effect and then replaces the translation, which the cached copy has to follow, the other replaces it before the first IDENTIFY DEVICE, where the words describing the default have to keep doing so. Factor the reading of the data out of test_specify_zero_sectors() for the three of them to share. 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>

Denis V. Lunev committed Aug 14, 2026 at 18:19 UTC 07209133238f0d660ff33e33c32ce7dd95127adb
1 file changed +84 -5
tests/qtest/ide-test.c
+84 -5
@@ -1196,6 +1196,18 @@ static void cdrom_read_impl(int nblocks, unsigned flags)
1196 free_pci_device(dev);
1197 }
1198
1199 +static void ide_identify_words(QPCIDevice *dev, QPCIBar ide_bar,
1200 + uint16_t buf[256])
1201 +{
1202 + int i;
1203 +
1204 + qpci_io_writeb(dev, ide_bar, reg_device, 0);
1205 + qpci_io_writeb(dev, ide_bar, reg_command, CMD_IDENTIFY);
1206 + for (i = 0; i < 256; i++) {
1207 + buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
1208 + }
1209 +}
1210 +
1211 /* Zero sectors per track has to abort (ATA-5 8.16.6), not divide by zero */
1212 static void test_specify_zero_sectors(void)
1213 {
@@ -1221,11 +1233,7 @@ static void test_specify_zero_sectors(void)
1233 assert_bit_set(qpci_io_readb(dev, ide_bar, reg_error), ABRT);
1234
1235 /* The refused request has to leave the default translation in effect */
1224 - qpci_io_writeb(dev, ide_bar, reg_device, 0);
1225 - qpci_io_writeb(dev, ide_bar, reg_command, CMD_IDENTIFY);
1226 - for (i = 0; i < 256; i++) {
1227 - buf[i] = qpci_io_readw(dev, ide_bar, reg_data);
1228 - }
1236 + ide_identify_words(dev, ide_bar, buf);
1237 g_assert_cmpint(buf[55], ==, 16);
1238 g_assert_cmpint(buf[56], ==, 63);
1239
@@ -1563,6 +1571,74 @@ static void test_migrate_chs_rejected(void)
1571 unlink(path);
1572 }
1573
1574 +/* Words 54 to 58 follow the translation even when the data was cached first */
1575 +static void test_specify_identify(void)
1576 +{
1577 + QTestState *qts;
1578 + QPCIDevice *dev;
1579 + QPCIBar bmdma_bar, ide_bar;
1580 + uint16_t buf[256];
1581 + unsigned int cyls;
1582 +
1583 + qts = ide_test_start(
1584 + "-blockdev driver=file,node-name=hda,filename=%s "
1585 + "-device ide-hd,drive=hda,bus=ide.0,unit=0 ",
1586 + tmp_path[0]);
1587 + dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
1588 +
1589 + /* Have the data built while the default translation is still in effect */
1590 + ide_identify_words(dev, ide_bar, buf);
1591 + cyls = buf[1];
1592 + g_assert_cmpint(buf[3], ==, 16);
1593 + g_assert_cmpint(buf[6], ==, 63);
1594 + g_assert_cmpint(buf[53] & 1, ==, 1);
1595 + g_assert_cmpint(buf[55], ==, 16);
1596 + g_assert_cmpint(buf[56], ==, 63);
1597 + g_assert_cmpint(buf[57] | (buf[58] << 16), ==, cyls * 16 * 63);
1598 +
1599 + ide_set_translation(dev, ide_bar, 8, 32);
1600 +
1601 + ide_identify_words(dev, ide_bar, buf);
1602 + g_assert_cmpint(buf[1], ==, cyls);
1603 + g_assert_cmpint(buf[3], ==, 16);
1604 + g_assert_cmpint(buf[4], ==, 512 * 63);
1605 + g_assert_cmpint(buf[6], ==, 63);
1606 + g_assert_cmpint(buf[55], ==, 8);
1607 + g_assert_cmpint(buf[56], ==, 32);
1608 + g_assert_cmpint(buf[57] | (buf[58] << 16), ==, cyls * 8 * 32);
1609 +
1610 + free_pci_device(dev);
1611 + ide_test_quit(qts);
1612 +}
1613 +
1614 +/* Words 3 and 6 keep the drive's own geometry even if built after a change */
1615 +static void test_specify_identify_default(void)
1616 +{
1617 + QTestState *qts;
1618 + QPCIDevice *dev;
1619 + QPCIBar bmdma_bar, ide_bar;
1620 + uint16_t buf[256];
1621 +
1622 + qts = ide_test_start(
1623 + "-blockdev driver=file,node-name=hda,filename=%s "
1624 + "-device ide-hd,drive=hda,bus=ide.0,unit=0 ",
1625 + tmp_path[0]);
1626 + dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
1627 +
1628 + /* No IDENTIFY DEVICE before this one, so nothing was cached yet */
1629 + ide_set_translation(dev, ide_bar, 8, 32);
1630 + ide_identify_words(dev, ide_bar, buf);
1631 + g_assert_cmpint(buf[3], ==, 16);
1632 + g_assert_cmpint(buf[4], ==, 512 * 63);
1633 + g_assert_cmpint(buf[6], ==, 63);
1634 + g_assert_cmpint(buf[55], ==, 8);
1635 + g_assert_cmpint(buf[56], ==, 32);
1636 + g_assert_cmpint(buf[57] | (buf[58] << 16), ==, buf[1] * 8 * 32);
1637 +
1638 + free_pci_device(dev);
1639 + ide_test_quit(qts);
1640 +}
1641 +
1642 static void test_cdrom_pio(void)
1643 {
1644 cdrom_read_impl(1, CDROM_PIO);
@@ -1635,6 +1711,9 @@ int main(int argc, char **argv)
1711
1712 qtest_add_func("/ide/read_native", test_specify);
1713 qtest_add_func("/ide/specify/zero_sectors", test_specify_zero_sectors);
1714 + qtest_add_func("/ide/specify/identify", test_specify_identify);
1715 + qtest_add_func("/ide/specify/identify_default",
1716 + test_specify_identify_default);
1717 qtest_add_func("/ide/migration/chs_translation",
1718 test_migrate_chs_translation);
1719 qtest_add_func("/ide/migration/chs_snapshot", test_migrate_chs_snapshot);