--- qemu/hw/ide/macio.c 2018/04/24 17:40:35 1.1.1.1 +++ qemu/hw/ide/macio.c 2018/04/24 19:50:59 1.1.1.6 @@ -26,8 +26,6 @@ #include #include #include "block.h" -#include "block_int.h" -#include "sysemu.h" #include "dma.h" #include @@ -36,10 +34,13 @@ /* MacIO based PowerPC IDE */ typedef struct MACIOIDEState { + MemoryRegion mem; IDEBus bus; BlockDriverAIOCB *aiocb; } MACIOIDEState; +#define MACIO_PAGE_SIZE 4096 + static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) { DBDMA_io *io = opaque; @@ -50,8 +51,7 @@ static void pmac_ide_atapi_transfer_cb(v m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); - io->dma_end(opaque); - return; + goto done; } if (s->io_buffer_size > 0) { @@ -69,15 +69,14 @@ static void pmac_ide_atapi_transfer_cb(v ide_atapi_cmd_ok(s); if (io->len == 0) { - io->dma_end(opaque); - return; + goto done; } /* launch next transfer */ s->io_buffer_size = io->len; - qemu_sglist_init(&s->sg, io->len / TARGET_PAGE_SIZE + 1); + qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len; io->len = 0; @@ -85,14 +84,12 @@ static void pmac_ide_atapi_transfer_cb(v m->aiocb = dma_bdrv_read(s->bs, &s->sg, (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), pmac_ide_atapi_transfer_cb, io); - if (!m->aiocb) { - qemu_sglist_destroy(&s->sg); - /* Note: media not present is the most likely case */ - ide_atapi_cmd_error(s, SENSE_NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - io->dma_end(opaque); - return; - } + return; + +done: + bdrv_acct_done(s->bs, &s->acct); + io->dma_end(opaque); + return; } static void pmac_ide_transfer_cb(void *opaque, int ret) @@ -107,8 +104,7 @@ static void pmac_ide_transfer_cb(void *o m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); - io->dma_end(io); - return; + goto done; } sector_num = ide_get_sector(s); @@ -128,10 +124,8 @@ static void pmac_ide_transfer_cb(void *o } /* end of DMA ? */ - if (io->len == 0) { - io->dma_end(io); - return; + goto done; } /* launch next transfer */ @@ -139,19 +133,33 @@ static void pmac_ide_transfer_cb(void *o s->io_buffer_index = 0; s->io_buffer_size = io->len; - qemu_sglist_init(&s->sg, io->len / TARGET_PAGE_SIZE + 1); + qemu_sglist_init(&s->sg, io->len / MACIO_PAGE_SIZE + 1); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len; io->len = 0; - if (s->is_read) + switch (s->dma_cmd) { + case IDE_DMA_READ: m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); - else + break; + case IDE_DMA_WRITE: m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num, pmac_ide_transfer_cb, io); - if (!m->aiocb) - pmac_ide_transfer_cb(io, -1); + break; + case IDE_DMA_TRIM: + m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num, + ide_issue_trim, pmac_ide_transfer_cb, s, + DMA_DIRECTION_TO_DEVICE); + break; + } + return; + +done: + if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { + bdrv_acct_done(s->bs, &s->acct); + } + io->dma_end(io); } static void pmac_ide_transfer(DBDMA_io *io) @@ -160,11 +168,23 @@ static void pmac_ide_transfer(DBDMA_io * IDEState *s = idebus_active_if(&m->bus); s->io_buffer_size = 0; - if (s->is_cdrom) { + if (s->drive_kind == IDE_CD) { + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); pmac_ide_atapi_transfer_cb(io, 0); return; } + switch (s->dma_cmd) { + case IDE_DMA_READ: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_READ); + break; + case IDE_DMA_WRITE: + bdrv_acct_start(s->bs, &s->acct, io->len, BDRV_ACCT_WRITE); + break; + default: + break; + } + pmac_ide_transfer_cb(io, 0); } @@ -172,8 +192,9 @@ static void pmac_ide_flush(DBDMA_io *io) { MACIOIDEState *m = io->opaque; - if (m->aiocb) - qemu_aio_flush(); + if (m->aiocb) { + bdrv_drain_all(); + } } /* PowerMac IDE memory IO */ @@ -223,9 +244,7 @@ static void pmac_ide_writew (void *opaqu MACIOIDEState *d = opaque; addr = (addr & 0xFFF) >> 4; -#ifdef TARGET_WORDS_BIGENDIAN val = bswap16(val); -#endif if (addr == 0) { ide_data_writew(&d->bus, 0, val); } @@ -242,9 +261,7 @@ static uint32_t pmac_ide_readw (void *op } else { retval = 0xFFFF; } -#ifdef TARGET_WORDS_BIGENDIAN retval = bswap16(retval); -#endif return retval; } @@ -254,9 +271,7 @@ static void pmac_ide_writel (void *opaqu MACIOIDEState *d = opaque; addr = (addr & 0xFFF) >> 4; -#ifdef TARGET_WORDS_BIGENDIAN val = bswap32(val); -#endif if (addr == 0) { ide_data_writel(&d->bus, 0, val); } @@ -273,22 +288,24 @@ static uint32_t pmac_ide_readl (void *op } else { retval = 0xFFFFFFFF; } -#ifdef TARGET_WORDS_BIGENDIAN retval = bswap32(retval); -#endif return retval; } -static CPUWriteMemoryFunc * const pmac_ide_write[] = { - pmac_ide_writeb, - pmac_ide_writew, - pmac_ide_writel, -}; - -static CPUReadMemoryFunc * const pmac_ide_read[] = { - pmac_ide_readb, - pmac_ide_readw, - pmac_ide_readl, +static const MemoryRegionOps pmac_ide_ops = { + .old_mmio = { + .write = { + pmac_ide_writeb, + pmac_ide_writew, + pmac_ide_writel, + }, + .read = { + pmac_ide_readb, + pmac_ide_readw, + pmac_ide_readl, + }, + }, + .endianness = DEVICE_NATIVE_ENDIAN, }; static const VMStateDescription vmstate_pmac = { @@ -313,22 +330,20 @@ static void pmac_ide_reset(void *opaque) /* hd_table must contain 4 block drivers */ /* PowerMac uses memory mapped registers, not I/O. Return the memory I/O index to access the ide. */ -int pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, - void *dbdma, int channel, qemu_irq dma_irq) +MemoryRegion *pmac_ide_init (DriveInfo **hd_table, qemu_irq irq, + void *dbdma, int channel, qemu_irq dma_irq) { MACIOIDEState *d; - int pmac_ide_memory; - d = qemu_mallocz(sizeof(MACIOIDEState)); - ide_init2(&d->bus, hd_table[0], hd_table[1], irq); + d = g_malloc0(sizeof(MACIOIDEState)); + ide_init2_with_non_qdev_drives(&d->bus, hd_table[0], hd_table[1], irq); if (dbdma) DBDMA_register_channel(dbdma, channel, dma_irq, pmac_ide_transfer, pmac_ide_flush, d); - pmac_ide_memory = cpu_register_io_memory(pmac_ide_read, - pmac_ide_write, d); - vmstate_register(0, &vmstate_pmac, d); + memory_region_init_io(&d->mem, &pmac_ide_ops, d, "pmac-ide", 0x1000); + vmstate_register(NULL, 0, &vmstate_pmac, d); qemu_register_reset(pmac_ide_reset, d); - return pmac_ide_memory; + return &d->mem; }