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>
Denis V. Lunev committed
Jun 19, 2026 at 02:25 UTC
ebec7c73229831c6574c70fec3cc28c778566277
1 file changed
+67
-78
tests/qtest/ide-test.c
+67
-78
@@ -1034,8 +1034,12 @@ static void ide_wait_intr(QTestState *qts, int irq)
1034
g_assert_not_reached();
1035
}
1036
1037
-static void cdrom_pio_impl(int nblocks)
1037
+#define CDROM_PIO 0
1038
+#define CDROM_DMA (1 << 0)
1039
+
1040
+static void cdrom_read_impl(int nblocks, unsigned flags)
1041
{
1042
+ bool dma = flags & CDROM_DMA;
1043
QTestState *qts;
1044
QPCIDevice *dev;
1045
QPCIBar bmdma_bar, ide_bar;
@@ -1063,57 +1067,75 @@ static void cdrom_pio_impl(int nblocks)
1067
dev = get_pci_device(qts, &bmdma_bar, &ide_bar);
1068
qtest_irq_intercept_in(qts, "ioapic");
1069
1066
- /* PACKET command on device 0 */
1067
- qpci_io_writeb(dev, ide_bar, reg_device, 0);
1068
- qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
1069
- qpci_io_writeb(dev, ide_bar, reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
1070
- qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
1071
- /* HP0: Check_Status_A State */
1072
- nsleep(qts, 400);
1073
- data = ide_wait_clear(qts, BSY);
1074
- /* HP1: Send_Packet State */
1075
- assert_bit_set(data, DRQ | DRDY);
1076
- assert_bit_clear(data, ERR | DF | BSY);
1077
-
1078
- /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
1079
- send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
1080
-
1081
- /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
1082
- * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
1083
- * We allow an odd limit only when the remaining transfer size is
1084
- * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
1085
- * request n blocks, so our request size is always even.
1086
- * For this reason, we assume there is never a hanging byte to fetch. */
1087
- g_assert(!(rxsize & 1));
1088
- limit = BYTE_COUNT_LIMIT & ~1;
1089
- for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
1090
- size_t offset = i * (limit / 2);
1091
- size_t rem = (rxsize / 2) - offset;
1092
-
1093
- /* HP3: INTRQ_Wait */
1094
- ide_wait_intr(qts, IDE_PRIMARY_IRQ);
1070
+ if (dma) {
1071
+ uintptr_t guest_buf = guest_alloc(&guest_malloc, rxsize);
1072
+ PrdtEntry prdt[1];
1073
+
1074
+ prdt[0].addr = cpu_to_le32(guest_buf);
1075
+ prdt[0].size = cpu_to_le32(rxsize | PRDT_EOT);
1076
+
1077
+ send_dma_request_dev(qts, dev, bmdma_bar, ide_bar, CMD_PACKET, 0,
1078
+ nblocks, prdt, ARRAY_SIZE(prdt),
1079
+ send_scsi_cdb_read10);
1080
1096
- /* HP2: Check_Status_B (and clear IRQ) */
1081
+ qtest_memread(qts, guest_buf, rx, rxsize);
1082
+ } else {
1083
+ /* PACKET command on device 0 */
1084
+ qpci_io_writeb(dev, ide_bar, reg_device, 0);
1085
+ qpci_io_writeb(dev, ide_bar, reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
1086
+ qpci_io_writeb(dev, ide_bar, reg_lba_high,
1087
+ (BYTE_COUNT_LIMIT >> 8 & 0xFF));
1088
+ qpci_io_writeb(dev, ide_bar, reg_command, CMD_PACKET);
1089
+ /* HP0: Check_Status_A State */
1090
+ nsleep(qts, 400);
1091
data = ide_wait_clear(qts, BSY);
1092
+ /* HP1: Send_Packet State */
1093
assert_bit_set(data, DRQ | DRDY);
1094
assert_bit_clear(data, ERR | DF | BSY);
1095
1101
- /* HP4: Transfer_Data */
1102
- for (j = 0; j < MIN((limit / 2), rem); j++) {
1103
- rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
1104
- reg_data));
1096
+ /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
1097
+ send_scsi_cdb_read10(dev, ide_bar, 0, nblocks);
1098
+
1099
+ /*
1100
+ * Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
1101
+ * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
1102
+ * We allow an odd limit only when the remaining transfer size is
1103
+ * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
1104
+ * request n blocks, so our request size is always even.
1105
+ * For this reason, we assume there is never a hanging byte to fetch.
1106
+ */
1107
+ g_assert(!(rxsize & 1));
1108
+ limit = BYTE_COUNT_LIMIT & ~1;
1109
+ for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
1110
+ size_t offset = i * (limit / 2);
1111
+ size_t rem = (rxsize / 2) - offset;
1112
+
1113
+ /* HP3: INTRQ_Wait */
1114
+ ide_wait_intr(qts, IDE_PRIMARY_IRQ);
1115
+
1116
+ /* HP2: Check_Status_B (and clear IRQ) */
1117
+ data = ide_wait_clear(qts, BSY);
1118
+ assert_bit_set(data, DRQ | DRDY);
1119
+ assert_bit_clear(data, ERR | DF | BSY);
1120
+
1121
+ /* HP4: Transfer_Data */
1122
+ for (j = 0; j < MIN((limit / 2), rem); j++) {
1123
+ rx[offset + j] = cpu_to_le16(qpci_io_readw(dev, ide_bar,
1124
+ reg_data));
1125
+ }
1126
}
1106
- }
1127
1108
- /* Check for final completion IRQ */
1109
- ide_wait_intr(qts, IDE_PRIMARY_IRQ);
1128
+ /* Check for final completion IRQ */
1129
+ ide_wait_intr(qts, IDE_PRIMARY_IRQ);
1130
1111
- /* Sanity check final state */
1112
- data = ide_wait_clear(qts, DRQ);
1113
- assert_bit_set(data, DRDY);
1114
- assert_bit_clear(data, DRQ | ERR | DF | BSY);
1131
+ /* Sanity check final state */
1132
+ data = ide_wait_clear(qts, DRQ);
1133
+ assert_bit_set(data, DRDY);
1134
+ assert_bit_clear(data, DRQ | ERR | DF | BSY);
1135
+ }
1136
1137
g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
1138
+
1139
g_free(pattern);
1140
g_free(rx);
1141
test_bmdma_teardown(qts);
@@ -1122,51 +1144,18 @@ static void cdrom_pio_impl(int nblocks)
1144
1145
static void test_cdrom_pio(void)
1146
{
1125
- cdrom_pio_impl(1);
1147
+ cdrom_read_impl(1, CDROM_PIO);
1148
}
1149
1150
static void test_cdrom_pio_large(void)
1151
{
1152
/* Test a few loops of the PIO DRQ mechanism. */
1131
- cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
1153
+ cdrom_read_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE, CDROM_PIO);
1154
}
1155
1134
-
1156
static void test_cdrom_dma(void)
1157
{
1137
- QTestState *qts;
1138
- static const size_t len = ATAPI_BLOCK_SIZE;
1139
- size_t ret;
1140
- char *pattern = g_malloc(ATAPI_BLOCK_SIZE * 16);
1141
- char *rx = g_malloc0(len);
1142
- uintptr_t guest_buf;
1143
- PrdtEntry prdt[1];
1144
- FILE *fh;
1145
-
1146
- qts = ide_test_start(
1147
- "-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
1148
- "-device ide-cd,drive=sr0,bus=ide.0", tmp_path[0]);
1149
- qtest_irq_intercept_in(qts, "ioapic");
1150
-
1151
- guest_buf = guest_alloc(&guest_malloc, len);
1152
- prdt[0].addr = cpu_to_le32(guest_buf);
1153
- prdt[0].size = cpu_to_le32(len | PRDT_EOT);
1154
-
1155
- generate_pattern(pattern, ATAPI_BLOCK_SIZE * 16, ATAPI_BLOCK_SIZE);
1156
- fh = fopen(tmp_path[0], "wb+");
1157
- ret = fwrite(pattern, ATAPI_BLOCK_SIZE, 16, fh);
1158
- g_assert_cmpint(ret, ==, 16);
1159
- fclose(fh);
1160
-
1161
- send_dma_request(qts, CMD_PACKET, 0, 1, prdt, 1, send_scsi_cdb_read10);
1162
-
1163
- /* Read back data from guest memory into local qtest memory */
1164
- qtest_memread(qts, guest_buf, rx, len);
1165
- g_assert_cmpint(memcmp(pattern, rx, len), ==, 0);
1166
-
1167
- g_free(pattern);
1168
- g_free(rx);
1169
- test_bmdma_teardown(qts);
1158
+ cdrom_read_impl(1, CDROM_DMA);
1159
}
1160
1161
int main(int argc, char **argv)