diff options
author | Kevin Wolf <kwolf@redhat.com> | 2013-03-13 13:30:24 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2013-05-08 15:28:49 +0200 |
commit | 948eaed171e0dac541a59b42867f80881399bbd0 (patch) | |
tree | 8b361db778c8b3ec6df3f6dcd5682120926cd6c1 /tests/ide-test.c | |
parent | b95739dcf5ae1dfa8cd5b2a5be27d427835e693b (diff) |
qtest/ide-test: Test short and long PRDTs
This tests the behaviour of the DMA engine when the given PRDT contains
physical region descriptors for either more or less bytes than the
IDE request is for.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'tests/ide-test.c')
-rw-r--r-- | tests/ide-test.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tests/ide-test.c b/tests/ide-test.c index 5fc496fd0a..bdc1da7dfe 100644 --- a/tests/ide-test.c +++ b/tests/ide-test.c @@ -77,6 +77,8 @@ enum { CMD_READ_DMA = 0xc8, CMD_WRITE_DMA = 0xca, CMD_IDENTIFY = 0xec, + + CMDF_ABORT = 0x100, }; enum { @@ -170,9 +172,13 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, size_t len; bool from_dev; uint8_t status; + int flags; dev = get_pci_device(&bmdma_base); + flags = cmd & ~0xff; + cmd &= 0xff; + switch (cmd) { case CMD_READ_DMA: from_dev = true; @@ -209,6 +215,10 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors, /* Start DMA transfer */ outb(bmdma_base + bmreg_cmd, BM_CMD_START | (from_dev ? BM_CMD_WRITE : 0)); + if (flags & CMDF_ABORT) { + outb(bmdma_base + bmreg_cmd, 0); + } + /* Wait for the DMA transfer to complete */ do { status = inb(bmdma_base + bmreg_status); @@ -289,6 +299,48 @@ static void test_bmdma_simple_rw(void) g_free(cmpbuf); } +static void test_bmdma_short_prdt(void) +{ + uint8_t status; + + PrdtEntry prdt[] = { + { .addr = 0, .size = 0x10 | PRDT_EOT }, + }; + + /* Normal request */ + status = send_dma_request(CMD_READ_DMA, 0, 1, + prdt, ARRAY_SIZE(prdt)); + g_assert_cmphex(status, ==, 0); + assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); + + /* Abort the request before it completes */ + status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1, + prdt, ARRAY_SIZE(prdt)); + g_assert_cmphex(status, ==, 0); + assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); +} + +static void test_bmdma_long_prdt(void) +{ + uint8_t status; + + PrdtEntry prdt[] = { + { .addr = 0, .size = 0x1000 | PRDT_EOT }, + }; + + /* Normal request */ + status = send_dma_request(CMD_READ_DMA, 0, 1, + prdt, ARRAY_SIZE(prdt)); + g_assert_cmphex(status, ==, BM_STS_ACTIVE | BM_STS_INTR); + assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); + + /* Abort the request before it completes */ + status = send_dma_request(CMD_READ_DMA | CMDF_ABORT, 0, 1, + prdt, ARRAY_SIZE(prdt)); + g_assert_cmphex(status, ==, BM_STS_INTR); + assert_bit_clear(inb(IDE_BASE + reg_status), DF | ERR); +} + static void test_bmdma_setup(void) { ide_test_start( @@ -375,6 +427,8 @@ int main(int argc, char **argv) qtest_add_func("/ide/bmdma/setup", test_bmdma_setup); qtest_add_func("/ide/bmdma/simple_rw", test_bmdma_simple_rw); + qtest_add_func("/ide/bmdma/short_prdt", test_bmdma_short_prdt); + qtest_add_func("/ide/bmdma/long_prdt", test_bmdma_long_prdt); qtest_add_func("/ide/bmdma/teardown", test_bmdma_teardown); ret = g_test_run(); |