diff --git a/tests/ahci-test.c b/tests/ahci-test.c index 2bee2a2cbb..31fb1f9476 100644 --- a/tests/ahci-test.c +++ b/tests/ahci-test.c @@ -1413,6 +1413,98 @@ static void test_ncq_simple(void) ahci_shutdown(ahci); } +static int prepare_iso(size_t size, unsigned char **buf, char **name) +{ + char cdrom_path[] = "/tmp/qtest.iso.XXXXXX"; + unsigned char *patt; + ssize_t ret; + int fd = mkstemp(cdrom_path); + + g_assert(buf); + g_assert(name); + patt = g_malloc(size); + + /* Generate a pattern and build a CDROM image to read from */ + generate_pattern(patt, size, ATAPI_SECTOR_SIZE); + ret = write(fd, patt, size); + g_assert(ret == size); + + *name = g_strdup(cdrom_path); + *buf = patt; + return fd; +} + +static void remove_iso(int fd, char *name) +{ + unlink(name); + g_free(name); + close(fd); +} + +static int ahci_cb_cmp_buff(AHCIQState *ahci, AHCICommand *cmd, + const AHCIOpts *opts) +{ + unsigned char *tx = opts->opaque; + unsigned char *rx = g_malloc0(opts->size); + + bufread(opts->buffer, rx, opts->size); + g_assert_cmphex(memcmp(tx, rx, opts->size), ==, 0); + g_free(rx); + + return 0; +} + +static void ahci_test_cdrom(int nsectors, bool dma) +{ + AHCIQState *ahci; + unsigned char *tx; + char *iso; + int fd; + AHCIOpts opts = { + .size = (ATAPI_SECTOR_SIZE * nsectors), + .atapi = true, + .atapi_dma = dma, + .post_cb = ahci_cb_cmp_buff, + }; + + /* Prepare ISO and fill 'tx' buffer */ + fd = prepare_iso(1024 * 1024, &tx, &iso); + opts.opaque = tx; + + /* Standard startup wonkery, but use ide-cd and our special iso file */ + ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw " + "-M q35 " + "-device ide-cd,drive=drive0 ", iso); + + /* Build & Send AHCI command */ + ahci_exec(ahci, ahci_port_select(ahci), CMD_ATAPI_READ_10, &opts); + + /* Cleanup */ + g_free(tx); + ahci_shutdown(ahci); + remove_iso(fd, iso); +} + +static void test_cdrom_dma(void) +{ + ahci_test_cdrom(1, true); +} + +static void test_cdrom_dma_multi(void) +{ + ahci_test_cdrom(3, true); +} + +static void test_cdrom_pio(void) +{ + ahci_test_cdrom(1, false); +} + +static void test_cdrom_pio_multi(void) +{ + ahci_test_cdrom(3, false); +} + /******************************************************************************/ /* AHCI I/O Test Matrix Definitions */ @@ -1697,6 +1789,11 @@ int main(int argc, char **argv) qtest_add_func("/ahci/io/ncq/retry", test_halted_ncq); qtest_add_func("/ahci/migrate/ncq/halted", test_migrate_halted_ncq); + qtest_add_func("/ahci/cdrom/dma/single", test_cdrom_dma); + qtest_add_func("/ahci/cdrom/dma/multi", test_cdrom_dma_multi); + qtest_add_func("/ahci/cdrom/pio/single", test_cdrom_pio); + qtest_add_func("/ahci/cdrom/pio/multi", test_cdrom_pio_multi); + ret = g_test_run(); /* Cleanup */