diff options
author | Alexander Graf <agraf@suse.de> | 2010-12-15 00:23:00 +0100 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2010-12-17 16:11:01 +0100 |
commit | 40a6238a20134a4687f67072d9be99cd97aab59a (patch) | |
tree | 85856a4343e8d7dcd4b6daf60ccbf355883ecebe /hw/ide/internal.h | |
parent | 6ef2ba5ea64e9feffdd1a8ffff66749323f719c8 (diff) |
ide: Split out BMDMA code from ATA core
The ATA core is currently heavily intertwined with BMDMA code. Let's loosen
that a bit, so we can happily replace the DMA backend with different
implementations.
Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'hw/ide/internal.h')
-rw-r--r-- | hw/ide/internal.h | 69 |
1 files changed, 32 insertions, 37 deletions
diff --git a/hw/ide/internal.h b/hw/ide/internal.h index 029c76c28f..aadb505a1f 100644 --- a/hw/ide/internal.h +++ b/hw/ide/internal.h @@ -20,7 +20,8 @@ typedef struct IDEBus IDEBus; typedef struct IDEDevice IDEDevice; typedef struct IDEDeviceInfo IDEDeviceInfo; typedef struct IDEState IDEState; -typedef struct BMDMAState BMDMAState; +typedef struct IDEDMA IDEDMA; +typedef struct IDEDMAOps IDEDMAOps; /* Bits of HD_STATUS */ #define ERR_STAT 0x01 @@ -367,6 +368,11 @@ typedef enum { IDE_HD, IDE_CD, IDE_CFATA } IDEDriveKind; typedef void EndTransferFunc(IDEState *); +typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *); +typedef int DMAFunc(IDEDMA *); +typedef int DMAIntFunc(IDEDMA *, int); +typedef void DMARestartFunc(void *, int, int); + /* NOTE: IDEState represents in fact one drive */ struct IDEState { IDEBus *bus; @@ -443,13 +449,32 @@ struct IDEState { uint8_t *smart_selftest_data; }; +struct IDEDMAOps { + DMAStartFunc *start_dma; + DMAFunc *start_transfer; + DMAIntFunc *prepare_buf; + DMAIntFunc *rw_buf; + DMAIntFunc *set_unit; + DMAIntFunc *add_status; + DMAFunc *set_inactive; + DMARestartFunc *restart_cb; + DMAFunc *reset; +}; + +struct IDEDMA { + const struct IDEDMAOps *ops; + struct iovec iov; + QEMUIOVector qiov; + BlockDriverAIOCB *aiocb; +}; + struct IDEBus { BusState qbus; IDEDevice *master; IDEDevice *slave; - BMDMAState *bmdma; IDEState ifs[2]; int bus_id; + IDEDMA *dma; uint8_t unit; uint8_t cmd; qemu_irq irq; @@ -480,46 +505,14 @@ struct IDEDeviceInfo { #define BM_CMD_START 0x01 #define BM_CMD_READ 0x08 -struct BMDMAState { - uint8_t cmd; - uint8_t status; - uint32_t addr; - - IDEBus *bus; - /* current transfer state */ - uint32_t cur_addr; - uint32_t cur_prd_last; - uint32_t cur_prd_addr; - uint32_t cur_prd_len; - uint8_t unit; - BlockDriverCompletionFunc *dma_cb; - BlockDriverAIOCB *aiocb; - struct iovec iov; - QEMUIOVector qiov; - int64_t sector_num; - uint32_t nsector; - IORange addr_ioport; - QEMUBH *bh; -}; - static inline IDEState *idebus_active_if(IDEBus *bus) { return bus->ifs + bus->unit; } -static inline IDEState *bmdma_active_if(BMDMAState *bmdma) -{ - assert(bmdma->unit != (uint8_t)-1); - return bmdma->bus->ifs + bmdma->unit; -} - static inline void ide_set_irq(IDEBus *bus) { - BMDMAState *bm = bus->bmdma; if (!(bus->cmd & IDE_CMD_DISABLE_IRQ)) { - if (bm) { - bm->status |= BM_STATUS_INT; - } qemu_irq_raise(bus->irq); } } @@ -542,10 +535,7 @@ void ide_bus_reset(IDEBus *bus); int64_t ide_get_sector(IDEState *s); void ide_set_sector(IDEState *s, int64_t sector_num); -void ide_dma_cancel(BMDMAState *bm); -void ide_dma_restart_cb(void *opaque, int running, int reason); void ide_dma_error(IDEState *s); -void ide_dma_reset(BMDMAState *bm); void ide_atapi_cmd_ok(IDEState *s); void ide_atapi_cmd_error(IDEState *s, int sense_key, int asc); @@ -568,6 +558,11 @@ void ide_init2_with_non_qdev_drives(IDEBus *bus, DriveInfo *hd0, void ide_init_ioport(IDEBus *bus, int iobase, int iobase2); void ide_exec_cmd(IDEBus *bus, uint32_t val); +void ide_read_dma_cb(void *opaque, int ret); +void ide_write_dma_cb(void *opaque, int ret); +void ide_sector_write(IDEState *s); +void ide_sector_read(IDEState *s); +void ide_flush_cache(IDEState *s); /* hw/ide/qdev.c */ void ide_bus_new(IDEBus *idebus, DeviceState *dev, int bus_id); |