void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)

{

    BMDMAState *bm = opaque;

#ifdef DEBUG_IDE

    printf("%s: 0x%08x\n", __func__, val);

#endif



    /* Ignore writes to SSBM if it keeps the old value */

    if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {

        if (!(val & BM_CMD_START)) {

            /*

             * We can't cancel Scatter Gather DMA in the middle of the

             * operation or a partial (not full) DMA transfer would reach

             * the storage so we wait for completion instead (we beahve

             * like if the DMA was completed by the time the guest trying

             * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not

             * set).

             *

             * In the future we'll be able to safely cancel the I/O if the

             * whole DMA operation will be submitted to disk with a single

             * aio operation with preadv/pwritev.

             */

            if (bm->bus->dma->aiocb) {

                qemu_aio_flush();

#ifdef DEBUG_IDE

                if (bm->bus->dma->aiocb)

                    printf("ide_dma_cancel: aiocb still pending\n");

                if (bm->status & BM_STATUS_DMAING)

                    printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n");

#endif

            }

        } else {

            bm->cur_addr = bm->addr;

            if (!(bm->status & BM_STATUS_DMAING)) {

                bm->status |= BM_STATUS_DMAING;

                /* start dma transfer if possible */

                if (bm->dma_cb)

                    bm->dma_cb(bmdma_active_if(bm), 0);

            }

        }

    }



    bm->cmd = val & 0x09;

}

void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val)

{

    BMDMAState *bm = opaque;

#ifdef DEBUG_IDE

    printf("%s: 0x%08x\n", __func__, val);

#endif



    

    if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {

        if (!(val & BM_CMD_START)) {

            























            if (bm->bus->dma->aiocb) {

                qemu_aio_flush();

#ifdef DEBUG_IDE

                if (bm->bus->dma->aiocb)

                    printf("ide_dma_cancel: aiocb still pending\n");

                if (bm->status & BM_STATUS_DMAING)

                    printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n");

#endif

            }

        } else {

            bm->cur_addr = bm->addr;

            if (!(bm->status & BM_STATUS_DMAING)) {

                bm->status |= BM_STATUS_DMAING;

                

                if (bm->dma_cb)

                    bm->dma_cb(bmdma_active_if(bm), 0);

            }

        }

    }



    bm->cmd = val & 0x09;

}

void FUNC_0(void *VAR_0, uint32_t VAR_1, uint32_t VAR_2)

{

    BMDMAState *bm = VAR_0;

#ifdef DEBUG_IDE

    printf("%s: 0x%08x\n", __func__, VAR_2);

#endif



    

    if ((VAR_2 & BM_CMD_START) != (bm->cmd & BM_CMD_START)) {

        if (!(VAR_2 & BM_CMD_START)) {

            























            if (bm->bus->dma->aiocb) {

                qemu_aio_flush();

#ifdef DEBUG_IDE

                if (bm->bus->dma->aiocb)

                    printf("ide_dma_cancel: aiocb still pending\n");

                if (bm->status & BM_STATUS_DMAING)

                    printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n");

#endif

            }

        } else {

            bm->cur_addr = bm->VAR_1;

            if (!(bm->status & BM_STATUS_DMAING)) {

                bm->status |= BM_STATUS_DMAING;

                

                if (bm->dma_cb)

                    bm->dma_cb(bmdma_active_if(bm), 0);

            }

        }

    }



    bm->cmd = VAR_2 & 0x09;

}

void FUNC_0(void *VAR_0, uint32_t VAR_1, uint32_t VAR_2)
{ BMDMAState *bm = VAR_0; #ifdef DEBUG_IDE
printf("%s: 0x%08x\n", __func__, VAR_2); #endif
if ((VAR_2 & BM_CMD_START) != (bm->cmd & BM_CMD_START)) { if (!(VAR_2 & BM_CMD_START)) { if (bm->bus->dma->aiocb) { qemu_aio_flush(); #ifdef DEBUG_IDE
if (bm->bus->dma->aiocb)
printf("ide_dma_cancel: aiocb still pending\n"); if (bm->status & BM_STATUS_DMAING)
printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n"); #endif
} } else { bm->cur_addr = bm->VAR_1; if (!(bm->status & BM_STATUS_DMAING)) { bm->status |= BM_STATUS_DMAING; if (bm->dma_cb)
bm->dma_cb(bmdma_active_if(bm), 0); } } } bm->cmd = VAR_2 & 0x09; }