static void pmac_ide_transfer_cb(void *opaque, int ret)

{

    DBDMA_io *io = opaque;

    MACIOIDEState *m = io->opaque;

    IDEState *s = idebus_active_if(&m->bus);

    int n = 0;

    int64_t sector_num;

    int unaligned;



    if (ret < 0) {

        MACIO_DPRINTF("DMA error\n");

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        ide_dma_error(s);

        io->remainder_len = 0;

        goto done;

    }



    if (!m->dma_active) {

        MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",

                      s->nsector, io->len, s->status);

        /* data not ready yet, wait for the channel to get restarted */

        io->processing = false;

        return;

    }



    sector_num = ide_get_sector(s);

    MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size);

    if (s->io_buffer_size > 0) {

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        n = (s->io_buffer_size + 0x1ff) >> 9;

        sector_num += n;

        ide_set_sector(s, sector_num);

        s->nsector -= n;

    }



    MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d "

                  "sector_num: %" PRId64 "\n",

                  io->remainder_len, io->len, s->nsector, sector_num);

    if (io->remainder_len && io->len) {

        /* guest wants the rest of its previous transfer */

        int remainder_len = MIN(io->remainder_len, io->len);

        uint8_t *p = &io->remainder[0x200 - remainder_len];



        MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\n",

                      remainder_len, io->addr);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            cpu_physical_memory_write(io->addr, p, remainder_len);

            break;

        case IDE_DMA_WRITE:

            cpu_physical_memory_read(io->addr, p, remainder_len);

            bdrv_write(s->bs, sector_num - 1, io->remainder, 1);

            break;

        case IDE_DMA_TRIM:

            break;

        }

        io->addr += remainder_len;

        io->len -= remainder_len;

        io->remainder_len -= remainder_len;

    }



    if (s->nsector == 0 && !io->remainder_len) {

        MACIO_DPRINTF("end of transfer\n");

        s->status = READY_STAT | SEEK_STAT;

        ide_set_irq(s->bus);

        m->dma_active = false;

    }



    if (io->len == 0) {

        MACIO_DPRINTF("end of DMA\n");

        goto done;

    }



    /* launch next transfer */



    s->io_buffer_index = 0;

    s->io_buffer_size = MIN(io->len, s->nsector * 512);



    /* handle unaligned accesses first, get them over with and only do the

       remaining bulk transfer using our async DMA helpers */

    unaligned = io->len & 0x1ff;

    if (unaligned) {

        int nsector = io->len >> 9;



        MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n",

                      unaligned, io->addr + io->len - unaligned);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            bdrv_read(s->bs, sector_num + nsector, io->remainder, 1);

            cpu_physical_memory_write(io->addr + io->len - unaligned,

                                      io->remainder, unaligned);

            break;

        case IDE_DMA_WRITE:

            /* cache the contents in our io struct */

            cpu_physical_memory_read(io->addr + io->len - unaligned,

                                     io->remainder, unaligned);

            break;

        case IDE_DMA_TRIM:

            break;

        }



        io->len -= unaligned;

    }



    MACIO_DPRINTF("io->len = %#x\n", io->len);



    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,

                     &address_space_memory);

    qemu_sglist_add(&s->sg, io->addr, io->len);

    io->addr += io->len + unaligned;

    io->remainder_len = (0x200 - unaligned) & 0x1ff;

    MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len);



    /* We would read no data from the block layer, thus not get a callback.

       Just fake completion manually. */

    if (!io->len) {

        pmac_ide_transfer_cb(opaque, 0);

        return;

    }



    io->len = 0;



    MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n",

                  sector_num, n, s->nsector, s->dma_cmd);



    switch (s->dma_cmd) {

    case IDE_DMA_READ:

        m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,

                                 pmac_ide_transfer_cb, io);

        break;

    case IDE_DMA_WRITE:

        m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,

                                  pmac_ide_transfer_cb, io);

        break;

    case IDE_DMA_TRIM:

        m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,

                               ide_issue_trim, pmac_ide_transfer_cb, io,

                               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_cb(void *opaque, int ret)

{

    DBDMA_io *io = opaque;

    MACIOIDEState *m = io->opaque;

    IDEState *s = idebus_active_if(&m->bus);

    int n = 0;

    int64_t sector_num;

    int unaligned;



    if (ret < 0) {

        MACIO_DPRINTF("DMA error\n");

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        ide_dma_error(s);

        io->remainder_len = 0;

        goto done;

    }



    if (!m->dma_active) {

        MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n",

                      s->nsector, io->len, s->status);

        

        io->processing = false;

        return;

    }



    sector_num = ide_get_sector(s);

    MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size);

    if (s->io_buffer_size > 0) {

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        n = (s->io_buffer_size + 0x1ff) >> 9;

        sector_num += n;

        ide_set_sector(s, sector_num);

        s->nsector -= n;

    }



    MACIO_DPRINTF("remainder: %d io->len: %d nsector: %d "

                  "sector_num: %" PRId64 "\n",

                  io->remainder_len, io->len, s->nsector, sector_num);

    if (io->remainder_len && io->len) {

        

        int remainder_len = MIN(io->remainder_len, io->len);

        uint8_t *p = &io->remainder[0x200 - remainder_len];



        MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\n",

                      remainder_len, io->addr);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            cpu_physical_memory_write(io->addr, p, remainder_len);

            break;

        case IDE_DMA_WRITE:

            cpu_physical_memory_read(io->addr, p, remainder_len);

            bdrv_write(s->bs, sector_num - 1, io->remainder, 1);

            break;

        case IDE_DMA_TRIM:

            break;

        }

        io->addr += remainder_len;

        io->len -= remainder_len;

        io->remainder_len -= remainder_len;

    }



    if (s->nsector == 0 && !io->remainder_len) {

        MACIO_DPRINTF("end of transfer\n");

        s->status = READY_STAT | SEEK_STAT;

        ide_set_irq(s->bus);

        m->dma_active = false;

    }



    if (io->len == 0) {

        MACIO_DPRINTF("end of DMA\n");

        goto done;

    }



    



    s->io_buffer_index = 0;

    s->io_buffer_size = MIN(io->len, s->nsector * 512);



    



    unaligned = io->len & 0x1ff;

    if (unaligned) {

        int nsector = io->len >> 9;



        MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n",

                      unaligned, io->addr + io->len - unaligned);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            bdrv_read(s->bs, sector_num + nsector, io->remainder, 1);

            cpu_physical_memory_write(io->addr + io->len - unaligned,

                                      io->remainder, unaligned);

            break;

        case IDE_DMA_WRITE:

            

            cpu_physical_memory_read(io->addr + io->len - unaligned,

                                     io->remainder, unaligned);

            break;

        case IDE_DMA_TRIM:

            break;

        }



        io->len -= unaligned;

    }



    MACIO_DPRINTF("io->len = %#x\n", io->len);



    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,

                     &address_space_memory);

    qemu_sglist_add(&s->sg, io->addr, io->len);

    io->addr += io->len + unaligned;

    io->remainder_len = (0x200 - unaligned) & 0x1ff;

    MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len);



    



    if (!io->len) {

        pmac_ide_transfer_cb(opaque, 0);

        return;

    }



    io->len = 0;



    MACIO_DPRINTF("sector_num=%" PRId64 " n=%d, nsector=%d, cmd_cmd=%d\n",

                  sector_num, n, s->nsector, s->dma_cmd);



    switch (s->dma_cmd) {

    case IDE_DMA_READ:

        m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,

                                 pmac_ide_transfer_cb, io);

        break;

    case IDE_DMA_WRITE:

        m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,

                                  pmac_ide_transfer_cb, io);

        break;

    case IDE_DMA_TRIM:

        m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,

                               ide_issue_trim, pmac_ide_transfer_cb, io,

                               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 FUNC_0(void *VAR_0, int VAR_1)

{

    DBDMA_io *io = VAR_0;

    MACIOIDEState *m = io->VAR_0;

    IDEState *s = idebus_active_if(&m->bus);

    int VAR_2 = 0;

    int64_t sector_num;

    int VAR_3;



    if (VAR_1 < 0) {

        MACIO_DPRINTF("DMA error\VAR_2");

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        ide_dma_error(s);

        io->VAR_4 = 0;

        goto done;

    }



    if (!m->dma_active) {

        MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\VAR_2",

                      s->VAR_5, io->len, s->status);

        

        io->processing = false;

        return;

    }



    sector_num = ide_get_sector(s);

    MACIO_DPRINTF("io_buffer_size = %#x\VAR_2", s->io_buffer_size);

    if (s->io_buffer_size > 0) {

        m->aiocb = NULL;

        qemu_sglist_destroy(&s->sg);

        VAR_2 = (s->io_buffer_size + 0x1ff) >> 9;

        sector_num += VAR_2;

        ide_set_sector(s, sector_num);

        s->VAR_5 -= VAR_2;

    }



    MACIO_DPRINTF("remainder: %d io->len: %d VAR_5: %d "

                  "sector_num: %" PRId64 "\VAR_2",

                  io->VAR_4, io->len, s->VAR_5, sector_num);

    if (io->VAR_4 && io->len) {

        

        int VAR_4 = MIN(io->VAR_4, io->len);

        uint8_t *p = &io->remainder[0x200 - VAR_4];



        MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\VAR_2",

                      VAR_4, io->addr);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            cpu_physical_memory_write(io->addr, p, VAR_4);

            break;

        case IDE_DMA_WRITE:

            cpu_physical_memory_read(io->addr, p, VAR_4);

            bdrv_write(s->bs, sector_num - 1, io->remainder, 1);

            break;

        case IDE_DMA_TRIM:

            break;

        }

        io->addr += VAR_4;

        io->len -= VAR_4;

        io->VAR_4 -= VAR_4;

    }



    if (s->VAR_5 == 0 && !io->VAR_4) {

        MACIO_DPRINTF("end of transfer\VAR_2");

        s->status = READY_STAT | SEEK_STAT;

        ide_set_irq(s->bus);

        m->dma_active = false;

    }



    if (io->len == 0) {

        MACIO_DPRINTF("end of DMA\VAR_2");

        goto done;

    }



    



    s->io_buffer_index = 0;

    s->io_buffer_size = MIN(io->len, s->VAR_5 * 512);



    



    VAR_3 = io->len & 0x1ff;

    if (VAR_3) {

        int VAR_5 = io->len >> 9;



        MACIO_DPRINTF("precopying VAR_3 %d bytes to %#" HWADDR_PRIx "\VAR_2",

                      VAR_3, io->addr + io->len - VAR_3);



        switch (s->dma_cmd) {

        case IDE_DMA_READ:

            bdrv_read(s->bs, sector_num + VAR_5, io->remainder, 1);

            cpu_physical_memory_write(io->addr + io->len - VAR_3,

                                      io->remainder, VAR_3);

            break;

        case IDE_DMA_WRITE:

            

            cpu_physical_memory_read(io->addr + io->len - VAR_3,

                                     io->remainder, VAR_3);

            break;

        case IDE_DMA_TRIM:

            break;

        }



        io->len -= VAR_3;

    }



    MACIO_DPRINTF("io->len = %#x\VAR_2", io->len);



    qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,

                     &address_space_memory);

    qemu_sglist_add(&s->sg, io->addr, io->len);

    io->addr += io->len + VAR_3;

    io->VAR_4 = (0x200 - VAR_3) & 0x1ff;

    MACIO_DPRINTF("set remainder to: %d\VAR_2", io->VAR_4);



    



    if (!io->len) {

        FUNC_0(VAR_0, 0);

        return;

    }



    io->len = 0;



    MACIO_DPRINTF("sector_num=%" PRId64 " VAR_2=%d, VAR_5=%d, cmd_cmd=%d\VAR_2",

                  sector_num, VAR_2, s->VAR_5, s->dma_cmd);



    switch (s->dma_cmd) {

    case IDE_DMA_READ:

        m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,

                                 FUNC_0, io);

        break;

    case IDE_DMA_WRITE:

        m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,

                                  FUNC_0, io);

        break;

    case IDE_DMA_TRIM:

        m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,

                               ide_issue_trim, FUNC_0, io,

                               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 FUNC_0(void *VAR_0, int VAR_1)
{ DBDMA_io *io = VAR_0; MACIOIDEState *m = io->VAR_0; IDEState *s = idebus_active_if(&m->bus); int VAR_2 = 0; int64_t sector_num; int VAR_3; if (VAR_1 < 0) { MACIO_DPRINTF("DMA error\VAR_2"); m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_dma_error(s); io->VAR_4 = 0; goto done; } if (!m->dma_active) { MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\VAR_2",
s->VAR_5, io->len, s->status); io->processing = false; return; } sector_num = ide_get_sector(s); MACIO_DPRINTF("io_buffer_size = %#x\VAR_2", s->io_buffer_size); if (s->io_buffer_size > 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); VAR_2 = (s->io_buffer_size + 0x1ff) >> 9; sector_num += VAR_2; ide_set_sector(s, sector_num); s->VAR_5 -= VAR_2; } MACIO_DPRINTF("remainder: %d io->len: %d VAR_5: %d "
"sector_num: %" PRId64 "\VAR_2",
io->VAR_4, io->len, s->VAR_5, sector_num); if (io->VAR_4 && io->len) { int VAR_4 = MIN(io->VAR_4, io->len); uint8_t *p = &io->remainder[0x200 - VAR_4]; MACIO_DPRINTF("copying remainder %d bytes at %#" HWADDR_PRIx "\VAR_2",
VAR_4, io->addr); switch (s->dma_cmd) { case IDE_DMA_READ:
cpu_physical_memory_write(io->addr, p, VAR_4); break; case IDE_DMA_WRITE:
cpu_physical_memory_read(io->addr, p, VAR_4); bdrv_write(s->bs, sector_num - 1, io->remainder, 1); break; case IDE_DMA_TRIM:
break; } io->addr += VAR_4; io->len -= VAR_4; io->VAR_4 -= VAR_4; } if (s->VAR_5 == 0 && !io->VAR_4) { MACIO_DPRINTF("end of transfer\VAR_2"); s->status = READY_STAT | SEEK_STAT; ide_set_irq(s->bus); m->dma_active = false; } if (io->len == 0) { MACIO_DPRINTF("end of DMA\VAR_2"); goto done; } s->io_buffer_index = 0; s->io_buffer_size = MIN(io->len, s->VAR_5 * 512); VAR_3 = io->len & 0x1ff; if (VAR_3) { int VAR_5 = io->len >> 9; MACIO_DPRINTF("precopying VAR_3 %d bytes to %#" HWADDR_PRIx "\VAR_2",
VAR_3, io->addr + io->len - VAR_3); switch (s->dma_cmd) { case IDE_DMA_READ:
bdrv_read(s->bs, sector_num + VAR_5, io->remainder, 1); cpu_physical_memory_write(io->addr + io->len - VAR_3,
io->remainder, VAR_3); break; case IDE_DMA_WRITE:
cpu_physical_memory_read(io->addr + io->len - VAR_3,
io->remainder, VAR_3); break; case IDE_DMA_TRIM:
break; } io->len -= VAR_3; } MACIO_DPRINTF("io->len = %#x\VAR_2", io->len); qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1,
&address_space_memory); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += io->len + VAR_3; io->VAR_4 = (0x200 - VAR_3) & 0x1ff; MACIO_DPRINTF("set remainder to: %d\VAR_2", io->VAR_4); if (!io->len) { FUNC_0(VAR_0, 0); return; } io->len = 0; MACIO_DPRINTF("sector_num=%" PRId64 " VAR_2=%d, VAR_5=%d, cmd_cmd=%d\VAR_2",
sector_num, VAR_2, s->VAR_5, s->dma_cmd); switch (s->dma_cmd) { case IDE_DMA_READ:
m->aiocb = dma_bdrv_read(s->bs, &s->sg, sector_num,
FUNC_0, io); break; case IDE_DMA_WRITE:
m->aiocb = dma_bdrv_write(s->bs, &s->sg, sector_num,
FUNC_0, io); break; case IDE_DMA_TRIM:
m->aiocb = dma_bdrv_io(s->bs, &s->sg, sector_num,
ide_issue_trim, FUNC_0, io,
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); }