aboutsummaryrefslogtreecommitdiff
path: root/hw/ide/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/ide/pci.c')
-rw-r--r--hw/ide/pci.c111
1 files changed, 16 insertions, 95 deletions
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index e3f2054..1b3d1c1 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);
@@ -99,7 +96,7 @@ static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write)
* This should accommodate the largest ATA transaction
* for LBA48 (65,536 sectors) and 32K sector sizes. */
if (s->sg.size > INT32_MAX) {
- error_report("IDE: sglist describes more than 2GiB.\n");
+ error_report("IDE: sglist describes more than 2GiB.");
break;
}
bm->cur_prd_addr += l;
@@ -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,
};