xref: /qemu/tests/qtest/ide-test.c (revision f7ba8d7fb6a7f22f8ecf99f61a35079accaba5c4)
1 /*
2  * IDE test cases
3  *
4  * Copyright (c) 2013 Kevin Wolf <kwolf@redhat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 #include <stdint.h>
26 #include <string.h>
27 #include <stdio.h>
28 
29 #include <glib.h>
30 
31 #include "libqtest.h"
32 #include "libqos/libqos.h"
33 #include "libqos/pci-pc.h"
34 #include "libqos/malloc-pc.h"
35 
36 #include "qemu-common.h"
37 #include "hw/pci/pci_ids.h"
38 #include "hw/pci/pci_regs.h"
39 
40 #define TEST_IMAGE_SIZE 64 * 1024 * 1024
41 
42 #define IDE_PCI_DEV     1
43 #define IDE_PCI_FUNC    1
44 
45 #define IDE_BASE 0x1f0
46 #define IDE_PRIMARY_IRQ 14
47 
48 #define ATAPI_BLOCK_SIZE 2048
49 
50 /* How many bytes to receive via ATAPI PIO at one time.
51  * Must be less than 0xFFFF. */
52 #define BYTE_COUNT_LIMIT 5120
53 
54 enum {
55     reg_data        = 0x0,
56     reg_nsectors    = 0x2,
57     reg_lba_low     = 0x3,
58     reg_lba_middle  = 0x4,
59     reg_lba_high    = 0x5,
60     reg_device      = 0x6,
61     reg_status      = 0x7,
62     reg_command     = 0x7,
63 };
64 
65 enum {
66     BSY     = 0x80,
67     DRDY    = 0x40,
68     DF      = 0x20,
69     DRQ     = 0x08,
70     ERR     = 0x01,
71 };
72 
73 enum {
74     DEV     = 0x10,
75     LBA     = 0x40,
76 };
77 
78 enum {
79     bmreg_cmd       = 0x0,
80     bmreg_status    = 0x2,
81     bmreg_prdt      = 0x4,
82 };
83 
84 enum {
85     CMD_READ_DMA    = 0xc8,
86     CMD_WRITE_DMA   = 0xca,
87     CMD_FLUSH_CACHE = 0xe7,
88     CMD_IDENTIFY    = 0xec,
89     CMD_PACKET      = 0xa0,
90 
91     CMDF_ABORT      = 0x100,
92     CMDF_NO_BM      = 0x200,
93 };
94 
95 enum {
96     BM_CMD_START    =  0x1,
97     BM_CMD_WRITE    =  0x8, /* write = from device to memory */
98 };
99 
100 enum {
101     BM_STS_ACTIVE   =  0x1,
102     BM_STS_ERROR    =  0x2,
103     BM_STS_INTR     =  0x4,
104 };
105 
106 enum {
107     PRDT_EOT        = 0x80000000,
108 };
109 
110 #define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
111 #define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
112 
113 static QPCIBus *pcibus = NULL;
114 static QGuestAllocator *guest_malloc;
115 
116 static char tmp_path[] = "/tmp/qtest.XXXXXX";
117 static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
118 
119 static void ide_test_start(const char *cmdline_fmt, ...)
120 {
121     va_list ap;
122     char *cmdline;
123 
124     va_start(ap, cmdline_fmt);
125     cmdline = g_strdup_vprintf(cmdline_fmt, ap);
126     va_end(ap);
127 
128     qtest_start(cmdline);
129     guest_malloc = pc_alloc_init();
130 
131     g_free(cmdline);
132 }
133 
134 static void ide_test_quit(void)
135 {
136     pc_alloc_uninit(guest_malloc);
137     guest_malloc = NULL;
138     qtest_end();
139 }
140 
141 static QPCIDevice *get_pci_device(uint16_t *bmdma_base)
142 {
143     QPCIDevice *dev;
144     uint16_t vendor_id, device_id;
145 
146     if (!pcibus) {
147         pcibus = qpci_init_pc();
148     }
149 
150     /* Find PCI device and verify it's the right one */
151     dev = qpci_device_find(pcibus, QPCI_DEVFN(IDE_PCI_DEV, IDE_PCI_FUNC));
152     g_assert(dev != NULL);
153 
154     vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
155     device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
156     g_assert(vendor_id == PCI_VENDOR_ID_INTEL);
157     g_assert(device_id == PCI_DEVICE_ID_INTEL_82371SB_1);
158 
159     /* Map bmdma BAR */
160     *bmdma_base = (uint16_t)(uintptr_t) qpci_iomap(dev, 4, NULL);
161 
162     qpci_device_enable(dev);
163 
164     return dev;
165 }
166 
167 static void free_pci_device(QPCIDevice *dev)
168 {
169     /* libqos doesn't have a function for this, so free it manually */
170     g_free(dev);
171 }
172 
173 typedef struct PrdtEntry {
174     uint32_t addr;
175     uint32_t size;
176 } QEMU_PACKED PrdtEntry;
177 
178 #define assert_bit_set(data, mask) g_assert_cmphex((data) & (mask), ==, (mask))
179 #define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
180 
181 static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
182                             PrdtEntry *prdt, int prdt_entries)
183 {
184     QPCIDevice *dev;
185     uint16_t bmdma_base;
186     uintptr_t guest_prdt;
187     size_t len;
188     bool from_dev;
189     uint8_t status;
190     int flags;
191 
192     dev = get_pci_device(&bmdma_base);
193 
194     flags = cmd & ~0xff;
195     cmd &= 0xff;
196 
197     switch (cmd) {
198     case CMD_READ_DMA:
199         from_dev = true;
200         break;
201     case CMD_WRITE_DMA:
202         from_dev = false;
203         break;
204     default:
205         g_assert_not_reached();
206     }
207 
208     if (flags & CMDF_NO_BM) {
209         qpci_config_writew(dev, PCI_COMMAND,
210                            PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
211     }
212 
213     /* Select device 0 */
214     outb(IDE_BASE + reg_device, 0 | LBA);
215 
216     /* Stop any running transfer, clear any pending interrupt */
217     outb(bmdma_base + bmreg_cmd, 0);
218     outb(bmdma_base + bmreg_status, BM_STS_INTR);
219 
220     /* Setup PRDT */
221     len = sizeof(*prdt) * prdt_entries;
222     guest_prdt = guest_alloc(guest_malloc, len);
223     memwrite(guest_prdt, prdt, len);
224     outl(bmdma_base + bmreg_prdt, guest_prdt);
225 
226     /* ATA DMA command */
227     outb(IDE_BASE + reg_nsectors, nb_sectors);
228 
229     outb(IDE_BASE + reg_lba_low,    sector & 0xff);
230     outb(IDE_BASE + reg_lba_middle, (sector >> 8) & 0xff);
231     outb(IDE_BASE + reg_lba_high,   (sector >> 16) & 0xff);
232 
233     outb(IDE_BASE + reg_command, cmd);
234 
235     /* Start DMA transfer */
236     outb(bmdma_base + bmreg_cmd, BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0));
237 
238     if (flags & CMDF_ABORT) {
239         outb(bmdma_base + bmreg_cmd, 0);
240     }
241 
242     /* Wait for the DMA transfer to complete */
243     do {
244         status = inb(bmdma_base + bmreg_status);
245     } while ((status & (BM_STS_ACTIVE | BM_STS_INTR)) == BM_STS_ACTIVE);
246 
247     g_assert_cmpint(get_irq(IDE_PRIMARY_IRQ), ==, !!(status & BM_STS_INTR));
248 
249     /* Check IDE status code */
250     assert_bit_set(inb(IDE_BASE + reg_status), DRDY);
251     assert_bit_clear(inb(IDE_BASE + reg_status), BSY | DRQ);
252 
253     /* Reading the status register clears the IRQ */
254     g_assert(!get_irq(IDE_PRIMARY_IRQ));
255 
256     /* Stop DMA transfer if still active */
257     if (status & BM_STS_ACTIVE) {
258         outb(bmdma_base + bmreg_cmd, 0);
259     }
260 
261     free_pci_device(dev);
262 
263     return status;
264 }
265 
266 static void test_bmdma_simple_rw(void)
267 {
268     uint8_t status;
269     uint8_t *buf;
270     uint8_t *cmpbuf;
271     size_t len = 512;
272     uintptr_t guest_buf = guest_alloc(guest_malloc, len);
273 
274     PrdtEntry prdt[] = {
275         {
276             .addr = cpu_to_le32(guest_buf),
277             .size = cpu_to_le32(len | PRDT_EOT),
278         },
279     };
280 
281     buf = g_malloc(len);
282     cmpbuf = g_malloc(len);
283 
284     /* Write 0x55 pattern to sector 0 */
285     memset(buf, 0x55, len);
286     memwrite(guest_buf, buf, len);
287 
288     status = send_dma_request(CMD_WRITE_DMA, 0, 1, prdt, ARRAY_SIZE(prdt));
289     g_assert_cmphex(status, ==, BM_STS_INTR);
290     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
291 
292     /* Write 0xaa pattern to sector 1 */
293     memset(buf, 0xaa, len);
294     memwrite(guest_buf, buf, len);
295 
296     status = send_dma_request(CMD_WRITE_DMA, 1, 1, prdt, ARRAY_SIZE(prdt));
297     g_assert_cmphex(status, ==, BM_STS_INTR);
298     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
299 
300     /* Read and verify 0x55 pattern in sector 0 */
301     memset(cmpbuf, 0x55, len);
302 
303     status = send_dma_request(CMD_READ_DMA, 0, 1, prdt, ARRAY_SIZE(prdt));
304     g_assert_cmphex(status, ==, BM_STS_INTR);
305     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
306 
307     memread(guest_buf, buf, len);
308     g_assert(memcmp(buf, cmpbuf, len) == 0);
309 
310     /* Read and verify 0xaa pattern in sector 1 */
311     memset(cmpbuf, 0xaa, len);
312 
313     status = send_dma_request(CMD_READ_DMA, 1, 1, prdt, ARRAY_SIZE(prdt));
314     g_assert_cmphex(status, ==, BM_STS_INTR);
315     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
316 
317     memread(guest_buf, buf, len);
318     g_assert(memcmp(buf, cmpbuf, len) == 0);
319 
320 
321     g_free(buf);
322     g_free(cmpbuf);
323 }
324 
325 static void test_bmdma_short_prdt(void)
326 {
327     uint8_t status;
328 
329     PrdtEntry prdt[] = {
330         {
331             .addr = 0,
332             .size = cpu_to_le32(0x10 | PRDT_EOT),
333         },
334     };
335 
336     /* Normal request */
337     status = send_dma_request(CMD_READ_DMA, 0, 1,
338                               prdt, ARRAY_SIZE(prdt));
339     g_assert_cmphex(status, ==, 0);
340     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
341 
342     /* Abort the request before it completes */
343     status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
344                               prdt, ARRAY_SIZE(prdt));
345     g_assert_cmphex(status, ==, 0);
346     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
347 }
348 
349 static void test_bmdma_one_sector_short_prdt(void)
350 {
351     uint8_t status;
352 
353     /* Read 2 sectors but only give 1 sector in PRDT */
354     PrdtEntry prdt[] = {
355         {
356             .addr = 0,
357             .size = cpu_to_le32(0x200 | PRDT_EOT),
358         },
359     };
360 
361     /* Normal request */
362     status = send_dma_request(CMD_READ_DMA, 0, 2,
363                               prdt, ARRAY_SIZE(prdt));
364     g_assert_cmphex(status, ==, 0);
365     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
366 
367     /* Abort the request before it completes */
368     status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 2,
369                               prdt, ARRAY_SIZE(prdt));
370     g_assert_cmphex(status, ==, 0);
371     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
372 }
373 
374 static void test_bmdma_long_prdt(void)
375 {
376     uint8_t status;
377 
378     PrdtEntry prdt[] = {
379         {
380             .addr = 0,
381             .size = cpu_to_le32(0x1000 | PRDT_EOT),
382         },
383     };
384 
385     /* Normal request */
386     status = send_dma_request(CMD_READ_DMA, 0, 1,
387                               prdt, ARRAY_SIZE(prdt));
388     g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
389     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
390 
391     /* Abort the request before it completes */
392     status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1,
393                               prdt, ARRAY_SIZE(prdt));
394     g_assert_cmphex(status, ==, BM_STS_INTR);
395     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
396 }
397 
398 static void test_bmdma_no_busmaster(void)
399 {
400     uint8_t status;
401 
402     /* No PRDT_EOT, each entry addr 0/size 64k, and in theory qemu shouldn't be
403      * able to access it anyway because the Bus Master bit in the PCI command
404      * register isn't set. This is complete nonsense, but it used to be pretty
405      * good at confusing and occasionally crashing qemu. */
406     PrdtEntry prdt[4096] = { };
407 
408     status = send_dma_request(CMD_READ_DMA | CMDF_NO_BM, 0, 512,
409                               prdt, ARRAY_SIZE(prdt));
410 
411     /* Not entirely clear what the expected result is, but this is what we get
412      * in practice. At least we want to be aware of any changes. */
413     g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR);
414     assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR);
415 }
416 
417 static void test_bmdma_setup(void)
418 {
419     ide_test_start(
420         "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
421         "-global ide-hd.ver=%s",
422         tmp_path, "testdisk", "version");
423     qtest_irq_intercept_in(global_qtest, "ioapic");
424 }
425 
426 static void test_bmdma_teardown(void)
427 {
428     ide_test_quit();
429 }
430 
431 static void string_cpu_to_be16(uint16_t *s, size_t bytes)
432 {
433     g_assert((bytes & 1) == 0);
434     bytes /= 2;
435 
436     while (bytes--) {
437         *s = cpu_to_be16(*s);
438         s++;
439     }
440 }
441 
442 static void test_identify(void)
443 {
444     uint8_t data;
445     uint16_t buf[256];
446     int i;
447     int ret;
448 
449     ide_test_start(
450         "-drive file=%s,if=ide,serial=%s,cache=writeback,format=raw "
451         "-global ide-hd.ver=%s",
452         tmp_path, "testdisk", "version");
453 
454     /* IDENTIFY command on device 0*/
455     outb(IDE_BASE + reg_device, 0);
456     outb(IDE_BASE + reg_command, CMD_IDENTIFY);
457 
458     /* Read in the IDENTIFY buffer and check registers */
459     data = inb(IDE_BASE + reg_device);
460     g_assert_cmpint(data & DEV, ==, 0);
461 
462     for (i = 0; i < 256; i++) {
463         data = inb(IDE_BASE + reg_status);
464         assert_bit_set(data, DRDY | DRQ);
465         assert_bit_clear(data, BSY | DF | ERR);
466 
467         ((uint16_t*) buf)[i] = inw(IDE_BASE + reg_data);
468     }
469 
470     data = inb(IDE_BASE + reg_status);
471     assert_bit_set(data, DRDY);
472     assert_bit_clear(data, BSY | DF | ERR | DRQ);
473 
474     /* Check serial number/version in the buffer */
475     string_cpu_to_be16(&buf[10], 20);
476     ret = memcmp(&buf[10], "testdisk            ", 20);
477     g_assert(ret == 0);
478 
479     string_cpu_to_be16(&buf[23], 8);
480     ret = memcmp(&buf[23], "version ", 8);
481     g_assert(ret == 0);
482 
483     /* Write cache enabled bit */
484     assert_bit_set(buf[85], 0x20);
485 
486     ide_test_quit();
487 }
488 
489 static void test_flush(void)
490 {
491     uint8_t data;
492 
493     ide_test_start(
494         "-drive file=blkdebug::%s,if=ide,cache=writeback,format=raw",
495         tmp_path);
496 
497     /* Delay the completion of the flush request until we explicitly do it */
498     qmp_discard_response("{'execute':'human-monitor-command', 'arguments': {"
499                          " 'command-line':"
500                          " 'qemu-io ide0-hd0 \"break flush_to_os A\"'} }");
501 
502     /* FLUSH CACHE command on device 0*/
503     outb(IDE_BASE + reg_device, 0);
504     outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
505 
506     /* Check status while request is in flight*/
507     data = inb(IDE_BASE + reg_status);
508     assert_bit_set(data, BSY | DRDY);
509     assert_bit_clear(data, DF | ERR | DRQ);
510 
511     /* Complete the command */
512     qmp_discard_response("{'execute':'human-monitor-command', 'arguments': {"
513                          " 'command-line':"
514                          " 'qemu-io ide0-hd0 \"resume A\"'} }");
515 
516     /* Check registers */
517     data = inb(IDE_BASE + reg_device);
518     g_assert_cmpint(data & DEV, ==, 0);
519 
520     do {
521         data = inb(IDE_BASE + reg_status);
522     } while (data & BSY);
523 
524     assert_bit_set(data, DRDY);
525     assert_bit_clear(data, BSY | DF | ERR | DRQ);
526 
527     ide_test_quit();
528 }
529 
530 static void test_retry_flush(const char *machine)
531 {
532     uint8_t data;
533     const char *s;
534 
535     prepare_blkdebug_script(debug_path, "flush_to_disk");
536 
537     ide_test_start(
538         "-vnc none "
539         "-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
540         "rerror=stop,werror=stop",
541         debug_path, tmp_path);
542 
543     /* FLUSH CACHE command on device 0*/
544     outb(IDE_BASE + reg_device, 0);
545     outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
546 
547     /* Check status while request is in flight*/
548     data = inb(IDE_BASE + reg_status);
549     assert_bit_set(data, BSY | DRDY);
550     assert_bit_clear(data, DF | ERR | DRQ);
551 
552     qmp_eventwait("STOP");
553 
554     /* Complete the command */
555     s = "{'execute':'cont' }";
556     qmp_discard_response(s);
557 
558     /* Check registers */
559     data = inb(IDE_BASE + reg_device);
560     g_assert_cmpint(data & DEV, ==, 0);
561 
562     do {
563         data = inb(IDE_BASE + reg_status);
564     } while (data & BSY);
565 
566     assert_bit_set(data, DRDY);
567     assert_bit_clear(data, BSY | DF | ERR | DRQ);
568 
569     ide_test_quit();
570 }
571 
572 static void test_flush_nodev(void)
573 {
574     ide_test_start("");
575 
576     /* FLUSH CACHE command on device 0*/
577     outb(IDE_BASE + reg_device, 0);
578     outb(IDE_BASE + reg_command, CMD_FLUSH_CACHE);
579 
580     /* Just testing that qemu doesn't crash... */
581 
582     ide_test_quit();
583 }
584 
585 static void test_pci_retry_flush(const char *machine)
586 {
587     test_retry_flush("pc");
588 }
589 
590 static void test_isa_retry_flush(const char *machine)
591 {
592     test_retry_flush("isapc");
593 }
594 
595 typedef struct Read10CDB {
596     uint8_t opcode;
597     uint8_t flags;
598     uint32_t lba;
599     uint8_t reserved;
600     uint16_t nblocks;
601     uint8_t control;
602     uint16_t padding;
603 } __attribute__((__packed__)) Read10CDB;
604 
605 static void send_scsi_cdb_read10(uint32_t lba, uint16_t nblocks)
606 {
607     Read10CDB pkt = { .padding = 0 };
608     int i;
609 
610     /* Construct SCSI CDB packet */
611     pkt.opcode = 0x28;
612     pkt.lba = cpu_to_be32(lba);
613     pkt.nblocks = cpu_to_be16(nblocks);
614 
615     /* Send Packet */
616     for (i = 0; i < sizeof(Read10CDB)/2; i++) {
617         outw(IDE_BASE + reg_data, ((uint16_t *)&pkt)[i]);
618     }
619 }
620 
621 static void nsleep(int64_t nsecs)
622 {
623     const struct timespec val = { .tv_nsec = nsecs };
624     nanosleep(&val, NULL);
625     clock_set(nsecs);
626 }
627 
628 static uint8_t ide_wait_clear(uint8_t flag)
629 {
630     int i;
631     uint8_t data;
632 
633     /* Wait with a 5 second timeout */
634     for (i = 0; i <= 12500000; i++) {
635         data = inb(IDE_BASE + reg_status);
636         if (!(data & flag)) {
637             return data;
638         }
639         nsleep(400);
640     }
641     g_assert_not_reached();
642 }
643 
644 static void ide_wait_intr(int irq)
645 {
646     int i;
647     bool intr;
648 
649     for (i = 0; i <= 12500000; i++) {
650         intr = get_irq(irq);
651         if (intr) {
652             return;
653         }
654         nsleep(400);
655     }
656 
657     g_assert_not_reached();
658 }
659 
660 static void cdrom_pio_impl(int nblocks)
661 {
662     FILE *fh;
663     int patt_blocks = MAX(16, nblocks);
664     size_t patt_len = ATAPI_BLOCK_SIZE * patt_blocks;
665     char *pattern = g_malloc(patt_len);
666     size_t rxsize = ATAPI_BLOCK_SIZE * nblocks;
667     uint16_t *rx = g_malloc0(rxsize);
668     int i, j;
669     uint8_t data;
670     uint16_t limit;
671 
672     /* Prepopulate the CDROM with an interesting pattern */
673     generate_pattern(pattern, patt_len, ATAPI_BLOCK_SIZE);
674     fh = fopen(tmp_path, "w+");
675     fwrite(pattern, ATAPI_BLOCK_SIZE, patt_blocks, fh);
676     fclose(fh);
677 
678     ide_test_start("-drive if=none,file=%s,media=cdrom,format=raw,id=sr0,index=0 "
679                    "-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
680     qtest_irq_intercept_in(global_qtest, "ioapic");
681 
682     /* PACKET command on device 0 */
683     outb(IDE_BASE + reg_device, 0);
684     outb(IDE_BASE + reg_lba_middle, BYTE_COUNT_LIMIT & 0xFF);
685     outb(IDE_BASE + reg_lba_high, (BYTE_COUNT_LIMIT >> 8 & 0xFF));
686     outb(IDE_BASE + reg_command, CMD_PACKET);
687     /* HPD0: Check_Status_A State */
688     nsleep(400);
689     data = ide_wait_clear(BSY);
690     /* HPD1: Send_Packet State */
691     assert_bit_set(data, DRQ | DRDY);
692     assert_bit_clear(data, ERR | DF | BSY);
693 
694     /* SCSI CDB (READ10) -- read n*2048 bytes from block 0 */
695     send_scsi_cdb_read10(0, nblocks);
696 
697     /* HPD3: INTRQ_Wait */
698     ide_wait_intr(IDE_PRIMARY_IRQ);
699 
700     /* HPD2: Check_Status_B */
701     data = ide_wait_clear(BSY);
702     assert_bit_set(data, DRQ | DRDY);
703     assert_bit_clear(data, ERR | DF | BSY);
704 
705     /* Read data back: occurs in bursts of 'BYTE_COUNT_LIMIT' bytes.
706      * If BYTE_COUNT_LIMIT is odd, we transfer BYTE_COUNT_LIMIT - 1 bytes.
707      * We allow an odd limit only when the remaining transfer size is
708      * less than BYTE_COUNT_LIMIT. However, SCSI's read10 command can only
709      * request n blocks, so our request size is always even.
710      * For this reason, we assume there is never a hanging byte to fetch. */
711     g_assert(!(rxsize & 1));
712     limit = BYTE_COUNT_LIMIT & ~1;
713     for (i = 0; i < DIV_ROUND_UP(rxsize, limit); i++) {
714         size_t offset = i * (limit / 2);
715         size_t rem = (rxsize / 2) - offset;
716         for (j = 0; j < MIN((limit / 2), rem); j++) {
717             rx[offset + j] = inw(IDE_BASE + reg_data);
718         }
719         ide_wait_intr(IDE_PRIMARY_IRQ);
720     }
721     data = ide_wait_clear(DRQ);
722     assert_bit_set(data, DRDY);
723     assert_bit_clear(data, DRQ | ERR | DF | BSY);
724 
725     g_assert_cmpint(memcmp(pattern, rx, rxsize), ==, 0);
726     g_free(pattern);
727     g_free(rx);
728     test_bmdma_teardown();
729 }
730 
731 static void test_cdrom_pio(void)
732 {
733     cdrom_pio_impl(1);
734 }
735 
736 static void test_cdrom_pio_large(void)
737 {
738     /* Test a few loops of the PIO DRQ mechanism. */
739     cdrom_pio_impl(BYTE_COUNT_LIMIT * 4 / ATAPI_BLOCK_SIZE);
740 }
741 
742 int main(int argc, char **argv)
743 {
744     const char *arch = qtest_get_arch();
745     int fd;
746     int ret;
747 
748     /* Check architecture */
749     if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) {
750         g_test_message("Skipping test for non-x86\n");
751         return 0;
752     }
753 
754     /* Create temporary blkdebug instructions */
755     fd = mkstemp(debug_path);
756     g_assert(fd >= 0);
757     close(fd);
758 
759     /* Create a temporary raw image */
760     fd = mkstemp(tmp_path);
761     g_assert(fd >= 0);
762     ret = ftruncate(fd, TEST_IMAGE_SIZE);
763     g_assert(ret == 0);
764     close(fd);
765 
766     /* Run the tests */
767     g_test_init(&argc, &argv, NULL);
768 
769     qtest_add_func("/ide/identify", test_identify);
770 
771     qtest_add_func("/ide/bmdma/setup", test_bmdma_setup);
772     qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw);
773     qtest_add_func("/ide/bmdma/short_prdt", test_bmdma_short_prdt);
774     qtest_add_func("/ide/bmdma/one_sector_short_prdt",
775                    test_bmdma_one_sector_short_prdt);
776     qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt);
777     qtest_add_func("/ide/bmdma/no_busmaster", test_bmdma_no_busmaster);
778     qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown);
779 
780     qtest_add_func("/ide/flush", test_flush);
781     qtest_add_func("/ide/flush/nodev", test_flush_nodev);
782     qtest_add_func("/ide/flush/retry_pci", test_pci_retry_flush);
783     qtest_add_func("/ide/flush/retry_isa", test_isa_retry_flush);
784 
785     qtest_add_func("/ide/cdrom/pio", test_cdrom_pio);
786     qtest_add_func("/ide/cdrom/pio_large", test_cdrom_pio_large);
787 
788     ret = g_test_run();
789 
790     /* Cleanup */
791     unlink(tmp_path);
792     unlink(debug_path);
793 
794     return ret;
795 }
796