coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num,

                                   int nb_sectors)

{

    IscsiLun *iscsilun = bs->opaque;

    struct IscsiTask iTask;

    struct unmap_list list;

    uint32_t nb_blocks;

    uint32_t max_unmap;



    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {

        return -EINVAL;

    }



    if (!iscsilun->lbp.lbpu) {

        /* UNMAP is not supported by the target */

        return 0;

    }



    list.lba = sector_qemu2lun(sector_num, iscsilun);

    nb_blocks = sector_qemu2lun(nb_sectors, iscsilun);



    max_unmap = iscsilun->bl.max_unmap;

    if (max_unmap == 0xffffffff) {

        max_unmap = ISCSI_MAX_UNMAP;

    }



    while (nb_blocks > 0) {

        iscsi_co_init_iscsitask(iscsilun, &iTask);

        list.num = nb_blocks;

        if (list.num > max_unmap) {

            list.num = max_unmap;

        }

retry:

        if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1,

                         iscsi_co_generic_cb, &iTask) == NULL) {

            return -EIO;

        }



        while (!iTask.complete) {

            iscsi_set_events(iscsilun);

            qemu_coroutine_yield();

        }



        if (iTask.task != NULL) {

            scsi_free_scsi_task(iTask.task);

            iTask.task = NULL;

        }



        if (iTask.do_retry) {

            goto retry;

        }



        if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {

            /* the target might fail with a check condition if it

               is not happy with the alignment of the UNMAP request

               we silently fail in this case */

            return 0;

        }



        if (iTask.status != SCSI_STATUS_GOOD) {

            return -EIO;

        }



        list.lba += list.num;

        nb_blocks -= list.num;

    }



    return 0;

}

coroutine_fn iscsi_co_discard(BlockDriverState *bs, int64_t sector_num,

                                   int nb_sectors)

{

    IscsiLun *iscsilun = bs->opaque;

    struct IscsiTask iTask;

    struct unmap_list list;

    uint32_t nb_blocks;

    uint32_t max_unmap;



    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {

        return -EINVAL;

    }



    if (!iscsilun->lbp.lbpu) {

        

        return 0;

    }



    list.lba = sector_qemu2lun(sector_num, iscsilun);

    nb_blocks = sector_qemu2lun(nb_sectors, iscsilun);



    max_unmap = iscsilun->bl.max_unmap;

    if (max_unmap == 0xffffffff) {

        max_unmap = ISCSI_MAX_UNMAP;

    }



    while (nb_blocks > 0) {

        iscsi_co_init_iscsitask(iscsilun, &iTask);

        list.num = nb_blocks;

        if (list.num > max_unmap) {

            list.num = max_unmap;

        }

retry:

        if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1,

                         iscsi_co_generic_cb, &iTask) == NULL) {

            return -EIO;

        }



        while (!iTask.complete) {

            iscsi_set_events(iscsilun);

            qemu_coroutine_yield();

        }



        if (iTask.task != NULL) {

            scsi_free_scsi_task(iTask.task);

            iTask.task = NULL;

        }



        if (iTask.do_retry) {

            goto retry;

        }



        if (iTask.status == SCSI_STATUS_CHECK_CONDITION) {

            





            return 0;

        }



        if (iTask.status != SCSI_STATUS_GOOD) {

            return -EIO;

        }



        list.lba += list.num;

        nb_blocks -= list.num;

    }



    return 0;

}

coroutine_fn FUNC_0(BlockDriverState *bs, int64_t sector_num,

                                   int nb_sectors)

{

    IscsiLun *iscsilun = bs->opaque;

    struct IscsiTask VAR_0;

    struct unmap_list VAR_1;

    uint32_t nb_blocks;

    uint32_t max_unmap;



    if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) {

        return -EINVAL;

    }



    if (!iscsilun->lbp.lbpu) {

        

        return 0;

    }



    VAR_1.lba = sector_qemu2lun(sector_num, iscsilun);

    nb_blocks = sector_qemu2lun(nb_sectors, iscsilun);



    max_unmap = iscsilun->bl.max_unmap;

    if (max_unmap == 0xffffffff) {

        max_unmap = ISCSI_MAX_UNMAP;

    }



    while (nb_blocks > 0) {

        iscsi_co_init_iscsitask(iscsilun, &VAR_0);

        VAR_1.num = nb_blocks;

        if (VAR_1.num > max_unmap) {

            VAR_1.num = max_unmap;

        }

retry:

        if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &VAR_1, 1,

                         iscsi_co_generic_cb, &VAR_0) == NULL) {

            return -EIO;

        }



        while (!VAR_0.complete) {

            iscsi_set_events(iscsilun);

            qemu_coroutine_yield();

        }



        if (VAR_0.task != NULL) {

            scsi_free_scsi_task(VAR_0.task);

            VAR_0.task = NULL;

        }



        if (VAR_0.do_retry) {

            goto retry;

        }



        if (VAR_0.status == SCSI_STATUS_CHECK_CONDITION) {

            





            return 0;

        }



        if (VAR_0.status != SCSI_STATUS_GOOD) {

            return -EIO;

        }



        VAR_1.lba += VAR_1.num;

        nb_blocks -= VAR_1.num;

    }



    return 0;

}

coroutine_fn FUNC_0(BlockDriverState *bs, int64_t sector_num,
int nb_sectors)
{ IscsiLun *iscsilun = bs->opaque; struct IscsiTask VAR_0; struct unmap_list VAR_1; uint32_t nb_blocks; uint32_t max_unmap; if (!is_request_lun_aligned(sector_num, nb_sectors, iscsilun)) { return -EINVAL; } if (!iscsilun->lbp.lbpu) { return 0; } VAR_1.lba = sector_qemu2lun(sector_num, iscsilun); nb_blocks = sector_qemu2lun(nb_sectors, iscsilun); max_unmap = iscsilun->bl.max_unmap; if (max_unmap == 0xffffffff) { max_unmap = ISCSI_MAX_UNMAP; } while (nb_blocks > 0) { iscsi_co_init_iscsitask(iscsilun, &VAR_0); VAR_1.num = nb_blocks; if (VAR_1.num > max_unmap) { VAR_1.num = max_unmap; } retry:
if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &VAR_1, 1,
iscsi_co_generic_cb, &VAR_0) == NULL) { return -EIO; } while (!VAR_0.complete) { iscsi_set_events(iscsilun); qemu_coroutine_yield(); } if (VAR_0.task != NULL) { scsi_free_scsi_task(VAR_0.task); VAR_0.task = NULL; } if (VAR_0.do_retry) { goto retry; } if (VAR_0.status == SCSI_STATUS_CHECK_CONDITION) { return 0; } if (VAR_0.status != SCSI_STATUS_GOOD) { return -EIO; } VAR_1.lba += VAR_1.num; nb_blocks -= VAR_1.num; } return 0; }