Commit ebec7c7322 for qemu.org
commit ebec7c73229831c6574c70fec3cc28c778566277
Author: Denis V. Lunev <den@openvz.org>
Date: Fri Jun 19 02:25:22 2026 +0200
tests/qtest/ide-test: parametrize the ATAPI CD-ROM read test
cdrom_pio_impl() and test_cdrom_dma() duplicate the same image setup
and data-integrity check around two different transfer mechanisms.
Fold them into a single cdrom_read_impl(nblocks, flags) helper, with a
CDROM_PIO/CDROM_DMA flag selecting the transfer, so further read
coverage can be added once for both paths.
No functional change: /ide/cdrom/pio, pio_large and dma run exactly
as before.
Signed-off-by: Denis V. Lunev <den@openvz.org>
diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c
index 721e78170b..c97bc17b67 100644
--- a/tests/qtest/ide-test.c
+++ b/tests/qtest/ide-test.c
@@ -1034,8 +1034,12 @@ static void ide_wait_intr(QTestState *qts, int irq)
g_assert_not_reached();
}
-static void cdrom_pio_impl(int nblocks)
+#define CDROM_PIO 0
+#define CDROM_DMA (1 << 0)
+
+static void cdrom_read_impl(int nblocks, unsigned flags)
{
+ bool dma = flags & CDROM_DMA;
QTestState *qts;
QPCIDevice *dev;
QPCIBar bmdma_bar, ide_bar;
@@ -1063,57 +1067,75 @@ static void cdrom_pio_impl(int nblocks)
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
qtest_irq_intercept_in(qts, "ioapic");
- /* PACKET command on device 0 */
- qpci_io_writeb(dev, ide_bar, reg_device, 0);
- qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
- qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
- qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
- /* HP0: Check_Status_A State */
- nsleep(qts, 400);
- data = ide_wait_clear(qts, BSY);
- /* HP1: Send_Packet State */
- assert_bit_set(data, DRQ | DRDY);
- assert_bit_clear(data, ERR | DF | BSY);
-
- /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
- send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
-
- /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
- * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
- * We allow an odd limit only when the remaining transfer size is
- * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
- * request n blocks, so our request size is always even.
- * For this reason, we assume there is never a hanging byte to fetch. */
- g_assert(!(rxsize & 1));
- limit = BYTE_COUNT_LIMIT & ~1;
- for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
- size_t offset = i * (limit / 2);
- size_t rem = (rxsize / 2) - offset;
-
- /* HP3: INTRQ_Wait */
- ide_wait_intr(qts, IDE_PRIMARY_IRQ);
+ if (dma) {
+ uintptr_t guest_buf = guest_alloc(&guest_malloc, rxsize);
+ PrdtEntry prdt[1];
+
+ prdt[0].addr = cpu_to_le32(guest_buf);
+ prdt[0].size = cpu_to_le32(rxsize | PRDT_EOT);
+
+ send_dma_request_dev(qts, dev, bmdma_bar, ide_bar, CMD_PACKET, 0,
+ nblocks, prdt, ARRAY_SIZE(prdt),
+ send_scsi_cdb_read10);
- /* HP2: Check_Status_B (and clear IRQ) */
+ qtest_memread(qts, guest_buf, rx, rxsize);
+ } else {
+ /* PACKET command on device 0 */
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
+ qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
+ qpci_io_writeb(dev, ide_bar, reg_lba_high,
+ (BYTE_COUNT_LIMIT >> 8 & 0xFF));
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
+ /* HP0: Check_Status_A State */
+ nsleep(qts, 400);
data = ide_wait_clear(qts, BSY);
+ /* HP1: Send_Packet State */
assert_bit_set(data, DRQ | DRDY);
assert_bit_clear(data, ERR | DF | BSY);
- /* HP4: Transfer_Data */
- for (j = 0; j < MIN((limit / 2), rem); j++) {
- rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
- reg_data));
+ /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
+ send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
+
+ /*
+ * Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
+ * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
+ * We allow an odd limit only when the remaining transfer size is
+ * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
+ * request n blocks, so our request size is always even.
+ * For this reason, we assume there is never a hanging byte to fetch.
+ */
+ g_assert(!(rxsize & 1));
+ limit = BYTE_COUNT_LIMIT & ~1;
+ for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
+ size_t offset = i * (limit / 2);
+ size_t rem = (rxsize / 2) - offset;
+
+ /* HP3: INTRQ_Wait */
+ ide_wait_intr(qts, IDE_PRIMARY_IRQ);
+
+ /* HP2: Check_Status_B (and clear IRQ) */
+ data = ide_wait_clear(qts, BSY);
+ assert_bit_set(data, DRQ | DRDY);
+ assert_bit_clear(data, ERR | DF | BSY);
+
+ /* HP4: Transfer_Data */
+ for (j = 0; j < MIN((limit / 2), rem); j++) {
+ rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
+ reg_data));
+ }
}
- }
- /* Check for final completion IRQ */
- ide_wait_intr(qts, IDE_PRIMARY_IRQ);
+ /* Check for final completion IRQ */
+ ide_wait_intr(qts, IDE_PRIMARY_IRQ);
- /* Sanity check final state */
- data = ide_wait_clear(qts, DRQ);
- assert_bit_set(data, DRDY);
- assert_bit_clear(data, DRQ | ERR | DF | BSY);
+ /* Sanity check final state */
+ data = ide_wait_clear(qts, DRQ);
+ assert_bit_set(data, DRDY);
+ assert_bit_clear(data, DRQ | ERR | DF | BSY);
+ }
g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
+
g_free(pattern);
g_free(rx);
test_bmdma_teardown(qts);
@@ -1122,51 +1144,18 @@ static void cdrom_pio_impl(int nblocks)
static void test_cdrom_pio(void)
{
- cdrom_pio_impl(1);
+ cdrom_read_impl(1, CDROM_PIO);
}
static void test_cdrom_pio_large(void)
{
/* Test a few loops of the PIO DRQ mechanism. */
- cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
+ cdrom_read_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE, CDROM_PIO);
}
-
static void test_cdrom_dma(void)
{
- QTestState *qts;
- static const size_t len = ATAPI_BLOCK_SIZE;
- size_t ret;
- char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16);
- char *rx = g_malloc0(len);
- uintptr_t guest_buf;
- PrdtEntry prdt[1];
- FILE *fh;
-
- qts = ide_test_start(
- "-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
- "-device ide-cd,drive=sr0,bus=ide.0", tmp_path[0]);
- qtest_irq_intercept_in(qts, "ioapic");
-
- guest_buf = guest_alloc(&guest_malloc, len);
- prdt[0].addr = cpu_to_le32(guest_buf);
- prdt[0].size = cpu_to_le32(len | PRDT_EOT);
-
- generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE);
- fh = fopen(tmp_path[0], "wb+");
- ret = fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh);
- g_assert_cmpint(ret, ==, 16);
- fclose(fh);
-
- send_dma_request(qts, CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
-
- /* Read back data from guest memory into local qtest memory */
- qtest_memread(qts, guest_buf, rx, len);
- g_assert_cmpint(memcmp(pattern, rx, len), ==, 0);
-
- g_free(pattern);
- g_free(rx);
- test_bmdma_teardown(qts);
+ cdrom_read_impl(1, CDROM_DMA);
}
int main(int argc, char **argv)