[PATCH 02/15] tests/qtest/ide-test: cover a CHS translation with zero sectors
"Denis V. Lunev" <[email protected]>
| Newsgroups | gmane.comp.emulators.qemu,gmane.comp.emulators.qemu.block |
|---|---|
| Message-ID | <[email protected]> |
From: Denis V. Lunev <[email protected]> Ask for zero sectors per logical track via INITIALIZE DEVICE PARAMETERS and check that the command is aborted, that IDENTIFY DEVICE still reports the translation that was in effect before, and that a CHS read then completes normally rather than killing QEMU with SIGFPE. Cc: John Snow <[email protected]> Cc: Peter Maydell <[email protected]> Signed-off-by: Denis V. Lunev <[email protected]> --- tests/qtest/ide-test.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/tests/qtest/ide-test.c b/tests/qtest/ide-test.c index b36b0f8875..99aa5e039c 100644 --- a/tests/qtest/ide-test.c +++ b/tests/qtest/ide-test.c @@ -95,6 +95,7 @@ enum { enum { CMD_DSM = 0x06, + CMD_READ = 0x20, /* READ SECTOR(S) */ CMD_DIAGNOSE = 0x90, CMD_INIT_DP = 0x91, /* INITIALIZE DEVICE PARAMETERS */ CMD_READ_DMA = 0xc8, @@ -1194,6 +1195,66 @@ static void cdrom_read_impl(int nblocks, unsigned flags) free_pci_device(dev); } +/* Zero sectors per track has to abort (ATA-5 8.16.6), not divide by zero */ +static void test_specify_zero_sectors(void) +{ + QTestState *qts; + QPCIDevice *dev; + QPCIBar bmdma_bar, ide_bar; + uint16_t buf[256]; + uint8_t data; + int i; + + qts = ide_test_start( + "-blockdev driver=file,node-name=hda,filename=%s " + "-device ide-hd,drive=hda,bus=ide.0,unit=0 ", + tmp_path[0]); + + dev = get_pci_device(qts, &bmdma_bar, &ide_bar); + + qpci_io_writeb(dev, ide_bar, reg_nsectors, 0); + qpci_io_writeb(dev, ide_bar, reg_device, 0); + qpci_io_writeb(dev, ide_bar, reg_command, CMD_INIT_DP); + + assert_bit_set(qpci_io_readb(dev, ide_bar, reg_status), ERR); + assert_bit_set(qpci_io_readb(dev, ide_bar, reg_error), ABRT); + + /* The refused request has to leave the default translation in effect */ + qpci_io_writeb(dev, ide_bar, reg_device, 0); + qpci_io_writeb(dev, ide_bar, reg_command, CMD_IDENTIFY); + for (i = 0; i < 256; i++) { + buf[i] = qpci_io_readw(dev, ide_bar, reg_data); + } + g_assert_cmpint(buf[55], ==, 16); + g_assert_cmpint(buf[56], ==, 63); + + /* READ SECTOR(S) of CHS 0/0/1, which used to crash QEMU */ + qpci_io_writeb(dev, ide_bar, reg_nsectors, 1); + qpci_io_writeb(dev, ide_bar, reg_lba_low, 1); + qpci_io_writeb(dev, ide_bar, reg_lba_middle, 0); + qpci_io_writeb(dev, ide_bar, reg_lba_high, 0); + qpci_io_writeb(dev, ide_bar, reg_device, 0); + qpci_io_writeb(dev, ide_bar, reg_command, CMD_READ); + + data = ide_wait_clear(qts, BSY); + assert_bit_set(data, DRQ); + assert_bit_clear(data, ERR | DF); + for (i = 0; i < 256; i++) { + buf[i] = qpci_io_readw(dev, ide_bar, reg_data); + } + assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), ERR | DF | DRQ); + + /* A supported translation is still accepted */ + qpci_io_writeb(dev, ide_bar, reg_nsectors, 32); + qpci_io_writeb(dev, ide_bar, reg_device, 7); + qpci_io_writeb(dev, ide_bar, reg_command, CMD_INIT_DP); + + assert_bit_clear(qpci_io_readb(dev, ide_bar, reg_status), ERR); + + ide_test_quit(qts); + free_pci_device(dev); +} + static void test_cdrom_pio(void) { cdrom_read_impl(1, CDROM_PIO); @@ -1265,6 +1326,7 @@ int main(int argc, char **argv) g_test_init(&argc, &argv, NULL); qtest_add_func("/ide/read_native", test_specify); + qtest_add_func("/ide/specify/zero_sectors", test_specify_zero_sectors); qtest_add_func("/ide/identify", test_identify); -- 2.53.0