@samitouri / QOSamiQemu / commits / 31f13e71af

tests/qtest/ahci: cover raw (2352-byte) ATAPI CD reads

Add /ahci/cdrom/{pio,dma}/raw: read several sectors with READ CD in raw mode (atapi_raw), so the ATAPI 2352-byte unpack path is exercised through the AHCI delivery, which IDE coverage does not reach. Each sector's 2048-byte payload is verified at its in-sector offset. The PIO case uses a byte-count limit of one raw sector per DRQ burst: libqos asserts a one-sector PIO transfer, and the multi-sector unpack loop is already covered by the IDE raw test. Signed-off-by: Denis V. Lunev <den@openvz.org>

Denis V. Lunev committed Jun 19, 2026 at 02:29 UTC 31f13e71afd1cfb55b02c6977c829f0813ab439c
1 file changed +68
tests/qtest/ahci-test.c
+68
@@ -1565,6 +1565,31 @@ static int ahci_cb_cmp_buff(AHCIQState *ahci, AHCICommand *cmd,
1565 return 0;
1566 }
1567
1568 +static int ahci_cb_cmp_raw(AHCIQState *ahci, AHCICommand *cmd,
1569 + const AHCIOpts *opts)
1570 +{
1571 + unsigned char *tx = opts->opaque;
1572 + unsigned char *rx;
1573 + unsigned i, nsectors;
1574 +
1575 + if (!opts->size) {
1576 + return 0;
1577 + }
1578 +
1579 + nsectors = opts->size / ATAPI_RAW_SECTOR_SIZE;
1580 + rx = g_malloc0(opts->size);
1581 + qtest_bufread(ahci->parent->qts, opts->buffer, rx, opts->size);
1582 + /* Each raw sector carries its 2048-byte payload past a 16-byte header. */
1583 + for (i = 0; i < nsectors; i++) {
1584 + g_assert_cmphex(memcmp(rx + i * ATAPI_RAW_SECTOR_SIZE + 16,
1585 + tx + i * ATAPI_SECTOR_SIZE,
1586 + ATAPI_SECTOR_SIZE), ==, 0);
1587 + }
1588 + g_free(rx);
1589 +
1590 + return 0;
1591 +}
1592 +
1593 static void ahci_test_cdrom(int nsectors, bool dma, uint8_t cmd,
1594 bool override_bcl, uint16_t bcl)
1595 {
@@ -1625,6 +1650,47 @@ static void test_cdrom_pio_multi(void)
1650 ahci_test_cdrom_read10(3, false);
1651 }
1652
1653 +static void ahci_test_cdrom_raw(int nsectors, bool dma)
1654 +{
1655 + AHCIQState *ahci;
1656 + unsigned char *tx;
1657 + char *iso;
1658 + int fd;
1659 + AHCIOpts opts = {
1660 + .size = (uint64_t)ATAPI_RAW_SECTOR_SIZE * nsectors,
1661 + .atapi = true,
1662 + .atapi_dma = dma,
1663 + .atapi_raw = true,
1664 + .set_bcl = true,
1665 + .bcl = ATAPI_RAW_SECTOR_SIZE, /* one raw sector per DRQ burst */
1666 + .post_cb = ahci_cb_cmp_raw,
1667 + };
1668 + uint64_t iso_size = (uint64_t)ATAPI_SECTOR_SIZE * (nsectors + 1);
1669 +
1670 + fd = prepare_iso(iso_size, &tx, &iso);
1671 + opts.opaque = tx;
1672 +
1673 + ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw "
1674 + "-M q35 "
1675 + "-device ide-cd,drive=drive0 ", iso);
1676 +
1677 + ahci_exec(ahci, ahci_port_select(ahci), CMD_ATAPI_READ_CD, &opts);
1678 +
1679 + g_free(tx);
1680 + ahci_shutdown(ahci);
1681 + remove_iso(fd, iso);
1682 +}
1683 +
1684 +static void test_cdrom_dma_raw(void)
1685 +{
1686 + ahci_test_cdrom_raw(3, true);
1687 +}
1688 +
1689 +static void test_cdrom_pio_raw(void)
1690 +{
1691 + ahci_test_cdrom_raw(3, false);
1692 +}
1693 +
1694 /*
1695 * Regression test: a buffered ATAPI read completing after a command
1696 * engine restart must not dereference the cleared cur_cmd. Cover both
@@ -2100,8 +2166,10 @@ int main(int argc, char **argv)
2166
2167 qtest_add_func("/ahci/cdrom/dma/single", test_cdrom_dma);
2168 qtest_add_func("/ahci/cdrom/dma/multi", test_cdrom_dma_multi);
2169 + qtest_add_func("/ahci/cdrom/dma/raw", test_cdrom_dma_raw);
2170 qtest_add_func("/ahci/cdrom/pio/single", test_cdrom_pio);
2171 qtest_add_func("/ahci/cdrom/pio/multi", test_cdrom_pio_multi);
2172 + qtest_add_func("/ahci/cdrom/pio/raw", test_cdrom_pio_raw);
2173
2174 qtest_add_func("/ahci/cdrom/pio/bcl", test_atapi_bcl);
2175 qtest_add_func("/ahci/cdrom/eject", test_atapi_tray);