void ide_dma_cb(void *opaque, int ret)

{

    IDEState *s = opaque;

    int n;

    int64_t sector_num;

    bool stay_active = false;



    if (ret < 0) {

        int op = BM_STATUS_DMA_RETRY;



        if (s->dma_cmd == IDE_DMA_READ)

            op |= BM_STATUS_RETRY_READ;

        else if (s->dma_cmd == IDE_DMA_TRIM)

            op |= BM_STATUS_RETRY_TRIM;



        if (ide_handle_rw_error(s, -ret, op)) {

            return;





    n = s->io_buffer_size >> 9;

    if (n > s->nsector) {

        





        n = s->nsector;

        stay_active = true;




    sector_num = ide_get_sector(s);

    if (n > 0) {

        dma_buf_commit(s);

        sector_num += n;

        ide_set_sector(s, sector_num);

        s->nsector -= n;




    

    if (s->nsector == 0) {

        s->status = READY_STAT | SEEK_STAT;

        ide_set_irq(s->bus);

        goto eot;




    

    n = s->nsector;

    s->io_buffer_index = 0;

    s->io_buffer_size = n * 512;

    if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) {

        



        goto eot;




#ifdef DEBUG_AIO

    printf("ide_dma_cb: sector_num=%" PRId64 " n=%d, cmd_cmd=%d\n",

           sector_num, n, s->dma_cmd);

#endif



    switch (s->dma_cmd) {

    case IDE_DMA_READ:

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

                                           ide_dma_cb, s);

        break;

    case IDE_DMA_WRITE:

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

                                            ide_dma_cb, s);

        break;

    case IDE_DMA_TRIM:

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

                                         ide_issue_trim, ide_dma_cb, s,

                                         DMA_DIRECTION_TO_DEVICE);

        break;


    return;



eot:

    if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) {

        bdrv_acct_done(s->bs, &s->acct);


    ide_set_inactive(s);



