summary refs log tree commit diff stats
path: root/hw/ide/pci.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-03-10 14:01:22 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-03-10 14:01:22 +0000
commit1976058109890892db8ec88bfd3273f79c459f6b (patch)
tree3819ee5d4406491751f99828f961a4b938f1e180 /hw/ide/pci.c
parent8437f7be3b1c49631e435c652707f2cee477149d (diff)
parent280458a34abcca2ba70843a089a35468c81e3740 (diff)
downloadfocaccia-qemu-1976058109890892db8ec88bfd3273f79c459f6b.tar.gz
focaccia-qemu-1976058109890892db8ec88bfd3273f79c459f6b.zip
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block patches for 2.3

# gpg: Signature made Tue Mar 10 13:03:17 2015 GMT using RSA key ID C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"

* remotes/kevin/tags/for-upstream: (73 commits)
  MAINTAINERS: Add jcody as blockjobs, block devices maintainer
  iotests: add O_DIRECT alignment probing test
  block/raw-posix: fix launching with failed disks
  MAINTAINERS: Add jsnow as IDE maintainer
  sheepdog: Fix misleading error messages in sd_snapshot_create()
  Add testcase for scsi-hd devices without drive property
  scsi-hd: fix property unset case
  block/vdi: Add locking for parallel requests
  iotests: Drop vpc from 004's and 104's format list
  iotests: Remove 006
  iotests: Fix 051's reference output
  virtio-blk: Remove the stale FIXME comment
  tests: Check QVIRTIO_F_ANY_LAYOUT flag in virtio-blk test
  libqos: Solve bug in interrupt checking when using MSIX in virtio-pci.c
  sheepdog: fix confused return values
  qtest/ahci: add fragmented dma test
  qtest/ahci: Add PIO and LBA48 tests
  qtest/ahci: Add DMA test variants
  libqos/ahci: add ahci command helpers
  qtest/ahci: Add a macro bootup routine
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/ide/pci.c')
-rw-r--r--hw/ide/pci.c109
1 files changed, 15 insertions, 94 deletions
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 913a9762d6..1b3d1c12ad 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -42,13 +42,10 @@ static void bmdma_start_dma(IDEDMA *dma, IDEState *s,
 {
     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
 
-    bm->unit = s->unit;
     bm->dma_cb = dma_cb;
     bm->cur_prd_last = 0;
     bm->cur_prd_addr = 0;
     bm->cur_prd_len = 0;
-    bm->sector_num = ide_get_sector(s);
-    bm->nsector = s->nsector;
 
     if (bm->status & BM_STATUS_DMAING) {
         bm->dma_cb(bmdma_active_if(bm), 0);
@@ -163,20 +160,11 @@ static int bmdma_rw_buf(IDEDMA *dma, int is_write)
     return 1;
 }
 
-static int bmdma_set_unit(IDEDMA *dma, int unit)
-{
-    BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
-    bm->unit = unit;
-
-    return 0;
-}
-
 static void bmdma_set_inactive(IDEDMA *dma, bool more)
 {
     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
 
     bm->dma_cb = NULL;
-    bm->unit = -1;
     if (more) {
         bm->status |= BM_STATUS_DMAING;
     } else {
@@ -184,83 +172,11 @@ static void bmdma_set_inactive(IDEDMA *dma, bool more)
     }
 }
 
-static void bmdma_restart_dma(BMDMAState *bm, enum ide_dma_cmd dma_cmd)
-{
-    IDEState *s = bmdma_active_if(bm);
-
-    ide_set_sector(s, bm->sector_num);
-    s->io_buffer_index = 0;
-    s->io_buffer_size = 0;
-    s->nsector = bm->nsector;
-    s->dma_cmd = dma_cmd;
-    bm->cur_addr = bm->addr;
-    bm->dma_cb = ide_dma_cb;
-    bmdma_start_dma(&bm->dma, s, bm->dma_cb);
-}
-
-/* TODO This should be common IDE code */
-static void bmdma_restart_bh(void *opaque)
-{
-    BMDMAState *bm = opaque;
-    IDEBus *bus = bm->bus;
-    bool is_read;
-    int error_status;
-
-    qemu_bh_delete(bm->bh);
-    bm->bh = NULL;
-
-    if (bm->unit == (uint8_t) -1) {
-        return;
-    }
-
-    is_read = (bus->error_status & IDE_RETRY_READ) != 0;
-
-    /* The error status must be cleared before resubmitting the request: The
-     * request may fail again, and this case can only be distinguished if the
-     * called function can set a new error status. */
-    error_status = bus->error_status;
-    bus->error_status = 0;
-
-    if (error_status & IDE_RETRY_DMA) {
-        if (error_status & IDE_RETRY_TRIM) {
-            bmdma_restart_dma(bm, IDE_DMA_TRIM);
-        } else {
-            bmdma_restart_dma(bm, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
-        }
-    } else if (error_status & IDE_RETRY_PIO) {
-        if (is_read) {
-            ide_sector_read(bmdma_active_if(bm));
-        } else {
-            ide_sector_write(bmdma_active_if(bm));
-        }
-    } else if (error_status & IDE_RETRY_FLUSH) {
-        ide_flush_cache(bmdma_active_if(bm));
-    } else {
-        IDEState *s = bmdma_active_if(bm);
-
-        /*
-         * We've not got any bits to tell us about ATAPI - but
-         * we do have the end_transfer_func that tells us what
-         * we're trying to do.
-         */
-        if (s->end_transfer_func == ide_atapi_cmd) {
-            ide_atapi_dma_restart(s);
-        }
-    }
-}
-
-static void bmdma_restart_cb(void *opaque, int running, RunState state)
+static void bmdma_restart_dma(IDEDMA *dma)
 {
-    IDEDMA *dma = opaque;
     BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma);
 
-    if (!running)
-        return;
-
-    if (!bm->bh) {
-        bm->bh = qemu_bh_new(bmdma_restart_bh, &bm->dma);
-        qemu_bh_schedule(bm->bh);
-    }
+    bm->cur_addr = bm->addr;
 }
 
 static void bmdma_cancel(BMDMAState *bm)
@@ -286,8 +202,6 @@ static void bmdma_reset(IDEDMA *dma)
     bm->cur_prd_last = 0;
     bm->cur_prd_addr = 0;
     bm->cur_prd_len = 0;
-    bm->sector_num = 0;
-    bm->nsector = 0;
 }
 
 static void bmdma_irq(void *opaque, int n, int level)
@@ -404,6 +318,9 @@ static void ide_bmdma_pre_save(void *opaque)
     BMDMAState *bm = opaque;
     uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
 
+    bm->migration_retry_unit = bm->bus->retry_unit;
+    bm->migration_retry_sector_num = bm->bus->retry_sector_num;
+    bm->migration_retry_nsector = bm->bus->retry_nsector;
     bm->migration_compat_status =
         (bm->status & ~abused_bits) | (bm->bus->error_status & abused_bits);
 }
@@ -420,6 +337,11 @@ static int ide_bmdma_post_load(void *opaque, int version_id)
         bm->status = bm->migration_compat_status & ~abused_bits;
         bm->bus->error_status |= bm->migration_compat_status & abused_bits;
     }
+    if (bm->bus->error_status) {
+        bm->bus->retry_sector_num = bm->migration_retry_sector_num;
+        bm->bus->retry_nsector = bm->migration_retry_nsector;
+        bm->bus->retry_unit = bm->migration_retry_unit;
+    }
 
     return 0;
 }
@@ -456,9 +378,9 @@ static const VMStateDescription vmstate_bmdma = {
         VMSTATE_UINT8(cmd, BMDMAState),
         VMSTATE_UINT8(migration_compat_status, BMDMAState),
         VMSTATE_UINT32(addr, BMDMAState),
-        VMSTATE_INT64(sector_num, BMDMAState),
-        VMSTATE_UINT32(nsector, BMDMAState),
-        VMSTATE_UINT8(unit, BMDMAState),
+        VMSTATE_INT64(migration_retry_sector_num, BMDMAState),
+        VMSTATE_UINT32(migration_retry_nsector, BMDMAState),
+        VMSTATE_UINT8(migration_retry_unit, BMDMAState),
         VMSTATE_END_OF_LIST()
     },
     .subsections = (VMStateSubsection []) {
@@ -482,7 +404,7 @@ static int ide_pci_post_load(void *opaque, int version_id)
     for(i = 0; i < 2; i++) {
         /* current versions always store 0/1, but older version
            stored bigger values. We only need last bit */
-        d->bmdma[i].unit &= 1;
+        d->bmdma[i].migration_retry_unit &= 1;
         ide_bmdma_post_load(&d->bmdma[i], -1);
     }
 
@@ -523,9 +445,8 @@ static const struct IDEDMAOps bmdma_ops = {
     .start_dma = bmdma_start_dma,
     .prepare_buf = bmdma_prepare_buf,
     .rw_buf = bmdma_rw_buf,
-    .set_unit = bmdma_set_unit,
+    .restart_dma = bmdma_restart_dma,
     .set_inactive = bmdma_set_inactive,
-    .restart_cb = bmdma_restart_cb,
     .reset = bmdma_reset,
 };