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>
This commit is contained in:
parent
b95739dcf5
commit
948eaed171
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user