aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2014-10-31 16:03:37 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2014-11-14 09:20:34 +0000
commit36334faf35ccc48d61ca3431a5c0787b125dd306 (patch)
treecea0c9130a481f7ad550dfa3c8fe87bc7f22751b
parenta395f3fa2f26c94dac03b37e3dfb1074bfe2ddea (diff)
ide: repair PIO transfers for cases where nsector > 1
Currently, for emulated PIO transfers through the AHCI device, any attempt made to request more than a single sector's worth of data will result in the same sector being transferred over and over. For example, if we request 8 sectors via PIO READ SECTORS, the AHCI device will give us the same sector eight times. This patch adds offset tracking into the PIO pathways so that we can fulfill these requests appropriately. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Message-id: 1414785819-26209-2-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--hw/ide/ahci.c2
-rw-r--r--hw/ide/core.c4
2 files changed, 5 insertions, 1 deletions
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index 1f3f951b50..dbd6773f8e 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -1093,7 +1093,7 @@ static void ahci_start_transfer(IDEDMA *dma)
goto out;
}
- if (!ahci_populate_sglist(ad, &s->sg, 0)) {
+ if (!ahci_populate_sglist(ad, &s->sg, s->io_buffer_offset)) {
has_sglist = 1;
}
diff --git a/hw/ide/core.c b/hw/ide/core.c
index d316ccf961..dab21f06c3 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -592,6 +592,7 @@ static void ide_sector_read_cb(void *opaque, int ret)
ide_set_sector(s, ide_get_sector(s) + n);
s->nsector -= n;
+ s->io_buffer_offset += 512 * n;
}
void ide_sector_read(IDEState *s)
@@ -832,6 +833,8 @@ static void ide_sector_write_cb(void *opaque, int ret)
n = s->req_nb_sectors;
}
s->nsector -= n;
+ s->io_buffer_offset += 512 * n;
+
if (s->nsector == 0) {
/* no more sectors to write */
ide_transfer_stop(s);
@@ -1824,6 +1827,7 @@ void ide_exec_cmd(IDEBus *bus, uint32_t val)
s->status = READY_STAT | BUSY_STAT;
s->error = 0;
+ s->io_buffer_offset = 0;
complete = ide_cmd_table[val].handler(s, val);
if (complete) {