diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2015-07-05 20:35:47 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2015-07-05 20:35:47 +0100 |
| commit | f50a1640fb82708a5d528dee1ace42a224b95b15 (patch) | |
| tree | f0d398aa4decd98c0b3245c5dc4b81135c0d8878 /hw/ide/pci.c | |
| parent | 63a9294ddc9cf4f2bdcd0179324fedcbb6fae59f (diff) | |
| parent | 7c649ac5b607e2339fb54fc0fc01311ba5eacadd (diff) | |
| download | focaccia-qemu-f50a1640fb82708a5d528dee1ace42a224b95b15.tar.gz focaccia-qemu-f50a1640fb82708a5d528dee1ace42a224b95b15.zip | |
Merge remote-tracking branch 'remotes/jnsnow/tags/ide-pull-request' into staging
# gpg: Signature made Sat Jul 4 07:06:08 2015 BST using RSA key ID AAFC390E # gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>" # gpg: WARNING: This key is not certified with sufficiently trusted signatures! # gpg: It is not certain that the signature belongs to the owner. # Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB # Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E * remotes/jnsnow/tags/ide-pull-request: (35 commits) ahci: fix sdb fis semantics qtest/ahci: halted ncq migration test ahci: Do not map cmd_fis to generate response ahci: ncq migration ahci: add get_cmd_header helper ahci: add cmd header to ncq transfer state qtest/ahci: halted NCQ test ahci: correct ncq sector count ahci: correct types in NCQTransferState ahci: add rwerror=stop support for ncq ahci: factor ncq_finish out of ncq_cb ahci: refactor process_ncq_command ahci: assert is_ncq for process_ncq ahci: stash ncq command ide: add limit to .prepare_buf() qtest/ahci: ncq migration test qtest/ahci: simple ncq data test libqos/ahci: Force all NCQ commands to be LBA48 libqos/ahci: set the NCQ tag on command_commit libqos/ahci: adjust expected NCQ interrupts ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ide/pci.c')
| -rw-r--r-- | hw/ide/pci.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 4afd0cfe8c..d31ff885b7 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -53,10 +53,14 @@ static void bmdma_start_dma(IDEDMA *dma, IDEState *s, } /** - * Return the number of bytes successfully prepared. - * -1 on error. + * Prepare an sglist based on available PRDs. + * @limit: How many bytes to prepare total. + * + * Returns the number of bytes prepared, -1 on error. + * IDEState.io_buffer_size will contain the number of bytes described + * by the PRDs, whether or not we added them to the sglist. */ -static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write) +static int32_t bmdma_prepare_buf(IDEDMA *dma, int32_t limit) { BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); IDEState *s = bmdma_active_if(bm); @@ -75,7 +79,7 @@ static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write) /* end of table (with a fail safe of one page) */ if (bm->cur_prd_last || (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) { - return s->io_buffer_size; + return s->sg.size; } pci_dma_read(pci_dev, bm->cur_addr, &prd, 8); bm->cur_addr += 8; @@ -90,7 +94,14 @@ static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write) } l = bm->cur_prd_len; if (l > 0) { - qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); + uint64_t sg_len; + + /* Don't add extra bytes to the SGList; consume any remaining + * PRDs from the guest, but ignore them. */ + sg_len = MIN(limit - s->sg.size, bm->cur_prd_len); + if (sg_len) { + qemu_sglist_add(&s->sg, bm->cur_prd_addr, sg_len); + } /* Note: We limit the max transfer to be 2GiB. * This should accommodate the largest ATA transaction |