From: "Denis V. Lunev" <den@openvz.org>
To: qemu-devel@nongnu.org
Cc: qemu-block@nongnu.org, "John Snow" <jsnow@redhat.com>,
"Denis V. Lunev" <den@openvz.org>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@oss.qualcomm.com>
Subject: [PULL v2 1/7] tests/qtest/ide-test: parametrize the ATAPI CD-ROM read test
Date: Tue, 4 Aug 2026 19:00:08 +0200 [thread overview]
Message-ID: <20260804170015.3128363-2-den@openvz.org> (raw)
In-Reply-To: <20260804170015.3128363-1-den@openvz.org>
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>
CC: Stefan Hajnoczi <stefanha@redhat.com>
CC: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
---
tests/qtest/ide-test.c | 145 +++++++++++++++++++----------------------
1 file changed, 67 insertions(+), 78 deletions(-)
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)
--
2.53.0
next prev parent reply other threads:[~2026-08-04 17:02 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-04 17:00 [PULL v2 0/7] IDE patches Denis V. Lunev
2026-08-04 17:00 ` Denis V. Lunev [this message]
2026-08-04 17:00 ` [PULL v2 2/7] tests/qtest/ide-test: add a multi-sector ATAPI DMA read test Denis V. Lunev
2026-08-04 17:00 ` [PULL v2 3/7] tests/qtest/ide-test: cover raw (2352-byte) ATAPI CD reads Denis V. Lunev
2026-08-04 17:00 ` [PULL v2 4/7] tests/qtest/libqos/ahci: support raw (2352-byte) READ CD Denis V. Lunev
2026-08-04 17:00 ` [PULL v2 5/7] tests/qtest/ahci: cover raw (2352-byte) ATAPI CD reads Denis V. Lunev
2026-08-04 17:00 ` [PULL v2 6/7] hw/ide/atapi: read the whole elementary transfer asynchronously Denis V. Lunev
2026-08-04 17:00 ` [PULL v2 7/7] tests/qtest/ahci: regression test for ATAPI read vs. drain Denis V. Lunev
2026-08-05 0:55 ` [PULL v2 0/7] IDE patches Stefan Hajnoczi
2026-08-12 12:48 ` Denis V. Lunev
2026-08-12 14:32 ` Stefan Hajnoczi
2026-08-12 14:34 ` Denis V. Lunev
2026-08-12 16:19 ` Richard Henderson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260804170015.3128363-2-den@openvz.org \
--to=den@openvz.org \
--cc=jsnow@redhat.com \
--cc=philmd@oss.qualcomm.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.