static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)

{

    uint8_t data[4096];

    struct mfi_config_data *info;

    int num_pd_disks = 0, array_offset, ld_offset;

    BusChild *kid;



    if (cmd->iov_size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        num_pd_disks++;

    }

    info = (struct mfi_config_data *)&data;

    /*

     * Array mapping:

     * - One array per SCSI device

     * - One logical drive per SCSI device

     *   spanning the entire device

     */

    info->array_count = num_pd_disks;

    info->array_size = sizeof(struct mfi_array) * num_pd_disks;

    info->log_drv_count = num_pd_disks;

    info->log_drv_size = sizeof(struct mfi_ld_config) * num_pd_disks;

    info->spares_count = 0;

    info->spares_size = sizeof(struct mfi_spare);

    info->size = sizeof(struct mfi_config_data) + info->array_size +

        info->log_drv_size;

    if (info->size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    array_offset = sizeof(struct mfi_config_data);

    ld_offset = array_offset + sizeof(struct mfi_array) * num_pd_disks;



    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);

        BlockConf *conf = &sdev->conf;

        uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);

        struct mfi_array *array;

        struct mfi_ld_config *ld;

        uint64_t pd_size;

        int i;



        array = (struct mfi_array *)(data + array_offset);

        bdrv_get_geometry(conf->bs, &pd_size);

        array->size = cpu_to_le64(pd_size);

        array->num_drives = 1;

        array->array_ref = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.device_id = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.seq_num = 0;

        array->pd[0].fw_state = MFI_PD_STATE_ONLINE;

        array->pd[0].encl.pd = 0xFF;

        array->pd[0].encl.slot = (sdev->id & 0xFF);

        for (i = 1; i < MFI_MAX_ROW_SIZE; i++) {

            array->pd[i].ref.v.device_id = 0xFFFF;

            array->pd[i].ref.v.seq_num = 0;

            array->pd[i].fw_state = MFI_PD_STATE_UNCONFIGURED_GOOD;

            array->pd[i].encl.pd = 0xFF;

            array->pd[i].encl.slot = 0xFF;

        }

        array_offset += sizeof(struct mfi_array);

        ld = (struct mfi_ld_config *)(data + ld_offset);

        memset(ld, 0, sizeof(struct mfi_ld_config));

        ld->properties.ld.v.target_id = (sdev->id & 0xFF);

        ld->properties.default_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->properties.current_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->params.state = MFI_LD_STATE_OPTIMAL;

        ld->params.stripe_size = 3;

        ld->params.num_drives = 1;

        ld->params.span_depth = 1;

        ld->params.is_consistent = 1;

        ld->span[0].start_block = 0;

        ld->span[0].num_blocks = cpu_to_le64(pd_size);

        ld->span[0].array_ref = cpu_to_le16(sdev_id);

        ld_offset += sizeof(struct mfi_ld_config);

    }



    cmd->iov_size -= dma_buf_read((uint8_t *)data, info->size, &cmd->qsg);

    return MFI_STAT_OK;

}

static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)

{

    uint8_t data[4096];

    struct mfi_config_data *info;

    int num_pd_disks = 0, array_offset, ld_offset;

    BusChild *kid;



    if (cmd->iov_size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        num_pd_disks++;

    }

    info = (struct mfi_config_data *)&data;

    











    info->array_count = num_pd_disks;

    info->array_size = sizeof(struct mfi_array) * num_pd_disks;

    info->log_drv_count = num_pd_disks;

    info->log_drv_size = sizeof(struct mfi_ld_config) * num_pd_disks;

    info->spares_count = 0;

    info->spares_size = sizeof(struct mfi_spare);

    info->size = sizeof(struct mfi_config_data) + info->array_size +

        info->log_drv_size;

    if (info->size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    array_offset = sizeof(struct mfi_config_data);

    ld_offset = array_offset + sizeof(struct mfi_array) * num_pd_disks;



    QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

        SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);

        BlockConf *conf = &sdev->conf;

        uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);

        struct mfi_array *array;

        struct mfi_ld_config *ld;

        uint64_t pd_size;

        int i;



        array = (struct mfi_array *)(data + array_offset);

        bdrv_get_geometry(conf->bs, &pd_size);

        array->size = cpu_to_le64(pd_size);

        array->num_drives = 1;

        array->array_ref = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.device_id = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.seq_num = 0;

        array->pd[0].fw_state = MFI_PD_STATE_ONLINE;

        array->pd[0].encl.pd = 0xFF;

        array->pd[0].encl.slot = (sdev->id & 0xFF);

        for (i = 1; i < MFI_MAX_ROW_SIZE; i++) {

            array->pd[i].ref.v.device_id = 0xFFFF;

            array->pd[i].ref.v.seq_num = 0;

            array->pd[i].fw_state = MFI_PD_STATE_UNCONFIGURED_GOOD;

            array->pd[i].encl.pd = 0xFF;

            array->pd[i].encl.slot = 0xFF;

        }

        array_offset += sizeof(struct mfi_array);

        ld = (struct mfi_ld_config *)(data + ld_offset);

        memset(ld, 0, sizeof(struct mfi_ld_config));

        ld->properties.ld.v.target_id = (sdev->id & 0xFF);

        ld->properties.default_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->properties.current_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->params.state = MFI_LD_STATE_OPTIMAL;

        ld->params.stripe_size = 3;

        ld->params.num_drives = 1;

        ld->params.span_depth = 1;

        ld->params.is_consistent = 1;

        ld->span[0].start_block = 0;

        ld->span[0].num_blocks = cpu_to_le64(pd_size);

        ld->span[0].array_ref = cpu_to_le16(sdev_id);

        ld_offset += sizeof(struct mfi_ld_config);

    }



    cmd->iov_size -= dma_buf_read((uint8_t *)data, info->size, &cmd->qsg);

    return MFI_STAT_OK;

}

static int FUNC_0(MegasasState *VAR_0, MegasasCmd *VAR_1)

{

    uint8_t data[4096];

    struct mfi_config_data *VAR_2;

    int VAR_3 = 0, VAR_4, VAR_5;

    BusChild *kid;



    if (VAR_1->iov_size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    QTAILQ_FOREACH(kid, &VAR_0->bus.qbus.children, sibling) {

        VAR_3++;

    }

    VAR_2 = (struct mfi_config_data *)&data;

    











    VAR_2->array_count = VAR_3;

    VAR_2->array_size = sizeof(struct mfi_array) * VAR_3;

    VAR_2->log_drv_count = VAR_3;

    VAR_2->log_drv_size = sizeof(struct mfi_ld_config) * VAR_3;

    VAR_2->spares_count = 0;

    VAR_2->spares_size = sizeof(struct mfi_spare);

    VAR_2->size = sizeof(struct mfi_config_data) + VAR_2->array_size +

        VAR_2->log_drv_size;

    if (VAR_2->size > 4096) {

        return MFI_STAT_INVALID_PARAMETER;

    }



    VAR_4 = sizeof(struct mfi_config_data);

    VAR_5 = VAR_4 + sizeof(struct mfi_array) * VAR_3;



    QTAILQ_FOREACH(kid, &VAR_0->bus.qbus.children, sibling) {

        SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);

        BlockConf *conf = &sdev->conf;

        uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);

        struct mfi_array *array;

        struct mfi_ld_config *ld;

        uint64_t pd_size;

        int i;



        array = (struct mfi_array *)(data + VAR_4);

        bdrv_get_geometry(conf->bs, &pd_size);

        array->size = cpu_to_le64(pd_size);

        array->num_drives = 1;

        array->array_ref = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.device_id = cpu_to_le16(sdev_id);

        array->pd[0].ref.v.seq_num = 0;

        array->pd[0].fw_state = MFI_PD_STATE_ONLINE;

        array->pd[0].encl.pd = 0xFF;

        array->pd[0].encl.slot = (sdev->id & 0xFF);

        for (i = 1; i < MFI_MAX_ROW_SIZE; i++) {

            array->pd[i].ref.v.device_id = 0xFFFF;

            array->pd[i].ref.v.seq_num = 0;

            array->pd[i].fw_state = MFI_PD_STATE_UNCONFIGURED_GOOD;

            array->pd[i].encl.pd = 0xFF;

            array->pd[i].encl.slot = 0xFF;

        }

        VAR_4 += sizeof(struct mfi_array);

        ld = (struct mfi_ld_config *)(data + VAR_5);

        memset(ld, 0, sizeof(struct mfi_ld_config));

        ld->properties.ld.v.target_id = (sdev->id & 0xFF);

        ld->properties.default_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->properties.current_cache_policy = MR_LD_CACHE_READ_AHEAD |

            MR_LD_CACHE_READ_ADAPTIVE;

        ld->params.state = MFI_LD_STATE_OPTIMAL;

        ld->params.stripe_size = 3;

        ld->params.num_drives = 1;

        ld->params.span_depth = 1;

        ld->params.is_consistent = 1;

        ld->span[0].start_block = 0;

        ld->span[0].num_blocks = cpu_to_le64(pd_size);

        ld->span[0].array_ref = cpu_to_le16(sdev_id);

        VAR_5 += sizeof(struct mfi_ld_config);

    }



    VAR_1->iov_size -= dma_buf_read((uint8_t *)data, VAR_2->size, &VAR_1->qsg);

    return MFI_STAT_OK;

}

static int FUNC_0(MegasasState *VAR_0, MegasasCmd *VAR_1)
{ uint8_t data[4096]; struct mfi_config_data *VAR_2; int VAR_3 = 0, VAR_4, VAR_5; BusChild *kid; if (VAR_1->iov_size > 4096) { return MFI_STAT_INVALID_PARAMETER; } QTAILQ_FOREACH(kid, &VAR_0->bus.qbus.children, sibling) { VAR_3++; } VAR_2 = (struct mfi_config_data *)&data; VAR_2->array_count = VAR_3; VAR_2->array_size = sizeof(struct mfi_array) * VAR_3; VAR_2->log_drv_count = VAR_3; VAR_2->log_drv_size = sizeof(struct mfi_ld_config) * VAR_3; VAR_2->spares_count = 0; VAR_2->spares_size = sizeof(struct mfi_spare); VAR_2->size = sizeof(struct mfi_config_data) + VAR_2->array_size +
VAR_2->log_drv_size; if (VAR_2->size > 4096) { return MFI_STAT_INVALID_PARAMETER; } VAR_4 = sizeof(struct mfi_config_data); VAR_5 = VAR_4 + sizeof(struct mfi_array) * VAR_3; QTAILQ_FOREACH(kid, &VAR_0->bus.qbus.children, sibling) { SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child); BlockConf *conf = &sdev->conf; uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF); struct mfi_array *array; struct mfi_ld_config *ld; uint64_t pd_size; int i; array = (struct mfi_array *)(data + VAR_4); bdrv_get_geometry(conf->bs, &pd_size); array->size = cpu_to_le64(pd_size); array->num_drives = 1; array->array_ref = cpu_to_le16(sdev_id); array->pd[0].ref.v.device_id = cpu_to_le16(sdev_id); array->pd[0].ref.v.seq_num = 0; array->pd[0].fw_state = MFI_PD_STATE_ONLINE; array->pd[0].encl.pd = 0xFF; array->pd[0].encl.slot = (sdev->id & 0xFF); for (i = 1; i < MFI_MAX_ROW_SIZE; i++) { array->pd[i].ref.v.device_id = 0xFFFF; array->pd[i].ref.v.seq_num = 0; array->pd[i].fw_state = MFI_PD_STATE_UNCONFIGURED_GOOD; array->pd[i].encl.pd = 0xFF; array->pd[i].encl.slot = 0xFF; } VAR_4 += sizeof(struct mfi_array); ld = (struct mfi_ld_config *)(data + VAR_5); memset(ld, 0, sizeof(struct mfi_ld_config)); ld->properties.ld.v.target_id = (sdev->id & 0xFF); ld->properties.default_cache_policy = MR_LD_CACHE_READ_AHEAD |
MR_LD_CACHE_READ_ADAPTIVE; ld->properties.current_cache_policy = MR_LD_CACHE_READ_AHEAD |
MR_LD_CACHE_READ_ADAPTIVE; ld->params.state = MFI_LD_STATE_OPTIMAL; ld->params.stripe_size = 3; ld->params.num_drives = 1; ld->params.span_depth = 1; ld->params.is_consistent = 1; ld->span[0].start_block = 0; ld->span[0].num_blocks = cpu_to_le64(pd_size); ld->span[0].array_ref = cpu_to_le16(sdev_id); VAR_5 += sizeof(struct mfi_ld_config); } VAR_1->iov_size -= dma_buf_read((uint8_t *)data, VAR_2->size, &VAR_1->qsg); return MFI_STAT_OK; }