static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,

                       const int *const_args)

{

    uint8_t *old_code_ptr = s->code_ptr;

    tcg_out_op_t(s, opc);

    switch (opc) {

    case INDEX_op_exit_tb:

        tcg_out64(s, args[0]);

        break;

    case INDEX_op_goto_tb:

        if (s->tb_jmp_offset) {

            /* Direct jump method. */

            assert(args[0] < ARRAY_SIZE(s->tb_jmp_offset));

            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;

            tcg_out32(s, 0);

        } else {

            /* Indirect jump method. */

            TODO();

        }

        assert(args[0] < ARRAY_SIZE(s->tb_next_offset));

        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;

        break;

    case INDEX_op_br:

        tci_out_label(s, args[0]);

        break;

    case INDEX_op_call:

        tcg_out_ri(s, const_args[0], args[0]);

        break;

    case INDEX_op_setcond_i32:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_ri32(s, const_args[2], args[2]);

        tcg_out8(s, args[3]);   /* condition */

        break;

#if TCG_TARGET_REG_BITS == 32

    case INDEX_op_setcond2_i32:

        /* setcond2_i32 cond, t0, t1_low, t1_high, t2_low, t2_high */

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_r(s, args[2]);

        tcg_out_ri32(s, const_args[3], args[3]);

        tcg_out_ri32(s, const_args[4], args[4]);

        tcg_out8(s, args[5]);   /* condition */

        break;

#elif TCG_TARGET_REG_BITS == 64

    case INDEX_op_setcond_i64:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_ri64(s, const_args[2], args[2]);

        tcg_out8(s, args[3]);   /* condition */

        break;

#endif

    case INDEX_op_movi_i32:

        TODO(); /* Handled by tcg_out_movi? */

        break;

    case INDEX_op_ld8u_i32:

    case INDEX_op_ld8s_i32:

    case INDEX_op_ld16u_i32:

    case INDEX_op_ld16s_i32:

    case INDEX_op_ld_i32:

    case INDEX_op_st8_i32:

    case INDEX_op_st16_i32:

    case INDEX_op_st_i32:

    case INDEX_op_ld8u_i64:

    case INDEX_op_ld8s_i64:

    case INDEX_op_ld16u_i64:

    case INDEX_op_ld16s_i64:

    case INDEX_op_ld32u_i64:

    case INDEX_op_ld32s_i64:

    case INDEX_op_ld_i64:

    case INDEX_op_st8_i64:

    case INDEX_op_st16_i64:

    case INDEX_op_st32_i64:

    case INDEX_op_st_i64:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        assert(args[2] == (uint32_t)args[2]);

        tcg_out32(s, args[2]);

        break;

    case INDEX_op_add_i32:

    case INDEX_op_sub_i32:

    case INDEX_op_mul_i32:

    case INDEX_op_and_i32:

    case INDEX_op_andc_i32:     /* Optional (TCG_TARGET_HAS_andc_i32). */

    case INDEX_op_eqv_i32:      /* Optional (TCG_TARGET_HAS_eqv_i32). */

    case INDEX_op_nand_i32:     /* Optional (TCG_TARGET_HAS_nand_i32). */

    case INDEX_op_nor_i32:      /* Optional (TCG_TARGET_HAS_nor_i32). */

    case INDEX_op_or_i32:

    case INDEX_op_orc_i32:      /* Optional (TCG_TARGET_HAS_orc_i32). */

    case INDEX_op_xor_i32:

    case INDEX_op_shl_i32:

    case INDEX_op_shr_i32:

    case INDEX_op_sar_i32:

    case INDEX_op_rotl_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */

    case INDEX_op_rotr_i32:     /* Optional (TCG_TARGET_HAS_rot_i32). */

        tcg_out_r(s, args[0]);

        tcg_out_ri32(s, const_args[1], args[1]);

        tcg_out_ri32(s, const_args[2], args[2]);

        break;

    case INDEX_op_deposit_i32:  /* Optional (TCG_TARGET_HAS_deposit_i32). */

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_r(s, args[2]);

        assert(args[3] <= UINT8_MAX);

        tcg_out8(s, args[3]);

        assert(args[4] <= UINT8_MAX);

        tcg_out8(s, args[4]);

        break;

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_mov_i64:

    case INDEX_op_movi_i64:

        TODO();

        break;

    case INDEX_op_add_i64:

    case INDEX_op_sub_i64:

    case INDEX_op_mul_i64:

    case INDEX_op_and_i64:

    case INDEX_op_andc_i64:     /* Optional (TCG_TARGET_HAS_andc_i64). */

    case INDEX_op_eqv_i64:      /* Optional (TCG_TARGET_HAS_eqv_i64). */

    case INDEX_op_nand_i64:     /* Optional (TCG_TARGET_HAS_nand_i64). */

    case INDEX_op_nor_i64:      /* Optional (TCG_TARGET_HAS_nor_i64). */

    case INDEX_op_or_i64:

    case INDEX_op_orc_i64:      /* Optional (TCG_TARGET_HAS_orc_i64). */

    case INDEX_op_xor_i64:

    case INDEX_op_shl_i64:

    case INDEX_op_shr_i64:

    case INDEX_op_sar_i64:

        /* TODO: Implementation of rotl_i64, rotr_i64 missing in tci.c. */

    case INDEX_op_rotl_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */

    case INDEX_op_rotr_i64:     /* Optional (TCG_TARGET_HAS_rot_i64). */

        tcg_out_r(s, args[0]);

        tcg_out_ri64(s, const_args[1], args[1]);

        tcg_out_ri64(s, const_args[2], args[2]);

        break;

    case INDEX_op_deposit_i64:  /* Optional (TCG_TARGET_HAS_deposit_i64). */

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_r(s, args[2]);

        assert(args[3] <= UINT8_MAX);

        tcg_out8(s, args[3]);

        assert(args[4] <= UINT8_MAX);

        tcg_out8(s, args[4]);

        break;

    case INDEX_op_div_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */

    case INDEX_op_divu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */

    case INDEX_op_rem_i64:      /* Optional (TCG_TARGET_HAS_div_i64). */

    case INDEX_op_remu_i64:     /* Optional (TCG_TARGET_HAS_div_i64). */

        TODO();

        break;

    case INDEX_op_div2_i64:     /* Optional (TCG_TARGET_HAS_div2_i64). */

    case INDEX_op_divu2_i64:    /* Optional (TCG_TARGET_HAS_div2_i64). */

        TODO();

        break;

    case INDEX_op_brcond_i64:

        tcg_out_r(s, args[0]);

        tcg_out_ri64(s, const_args[1], args[1]);

        tcg_out8(s, args[2]);           /* condition */

        tci_out_label(s, args[3]);

        break;

    case INDEX_op_bswap16_i64:  /* Optional (TCG_TARGET_HAS_bswap16_i64). */

    case INDEX_op_bswap32_i64:  /* Optional (TCG_TARGET_HAS_bswap32_i64). */

    case INDEX_op_bswap64_i64:  /* Optional (TCG_TARGET_HAS_bswap64_i64). */

    case INDEX_op_not_i64:      /* Optional (TCG_TARGET_HAS_not_i64). */

    case INDEX_op_neg_i64:      /* Optional (TCG_TARGET_HAS_neg_i64). */

    case INDEX_op_ext8s_i64:    /* Optional (TCG_TARGET_HAS_ext8s_i64). */

    case INDEX_op_ext8u_i64:    /* Optional (TCG_TARGET_HAS_ext8u_i64). */

    case INDEX_op_ext16s_i64:   /* Optional (TCG_TARGET_HAS_ext16s_i64). */

    case INDEX_op_ext16u_i64:   /* Optional (TCG_TARGET_HAS_ext16u_i64). */

    case INDEX_op_ext32s_i64:   /* Optional (TCG_TARGET_HAS_ext32s_i64). */

    case INDEX_op_ext32u_i64:   /* Optional (TCG_TARGET_HAS_ext32u_i64). */

#endif /* TCG_TARGET_REG_BITS == 64 */

    case INDEX_op_neg_i32:      /* Optional (TCG_TARGET_HAS_neg_i32). */

    case INDEX_op_not_i32:      /* Optional (TCG_TARGET_HAS_not_i32). */

    case INDEX_op_ext8s_i32:    /* Optional (TCG_TARGET_HAS_ext8s_i32). */

    case INDEX_op_ext16s_i32:   /* Optional (TCG_TARGET_HAS_ext16s_i32). */

    case INDEX_op_ext8u_i32:    /* Optional (TCG_TARGET_HAS_ext8u_i32). */

    case INDEX_op_ext16u_i32:   /* Optional (TCG_TARGET_HAS_ext16u_i32). */

    case INDEX_op_bswap16_i32:  /* Optional (TCG_TARGET_HAS_bswap16_i32). */

    case INDEX_op_bswap32_i32:  /* Optional (TCG_TARGET_HAS_bswap32_i32). */

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        break;

    case INDEX_op_div_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */

    case INDEX_op_divu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */

    case INDEX_op_rem_i32:      /* Optional (TCG_TARGET_HAS_div_i32). */

    case INDEX_op_remu_i32:     /* Optional (TCG_TARGET_HAS_div_i32). */

        tcg_out_r(s, args[0]);

        tcg_out_ri32(s, const_args[1], args[1]);

        tcg_out_ri32(s, const_args[2], args[2]);

        break;

    case INDEX_op_div2_i32:     /* Optional (TCG_TARGET_HAS_div2_i32). */

    case INDEX_op_divu2_i32:    /* Optional (TCG_TARGET_HAS_div2_i32). */

        TODO();

        break;

#if TCG_TARGET_REG_BITS == 32

    case INDEX_op_add2_i32:

    case INDEX_op_sub2_i32:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_r(s, args[2]);

        tcg_out_r(s, args[3]);

        tcg_out_r(s, args[4]);

        tcg_out_r(s, args[5]);

        break;

    case INDEX_op_brcond2_i32:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_ri32(s, const_args[2], args[2]);

        tcg_out_ri32(s, const_args[3], args[3]);

        tcg_out8(s, args[4]);           /* condition */

        tci_out_label(s, args[5]);

        break;

    case INDEX_op_mulu2_i32:

        tcg_out_r(s, args[0]);

        tcg_out_r(s, args[1]);

        tcg_out_r(s, args[2]);

        tcg_out_r(s, args[3]);

        break;

#endif

    case INDEX_op_brcond_i32:

        tcg_out_r(s, args[0]);

        tcg_out_ri32(s, const_args[1], args[1]);

        tcg_out8(s, args[2]);           /* condition */

        tci_out_label(s, args[3]);

        break;

    case INDEX_op_qemu_ld8u:

    case INDEX_op_qemu_ld8s:

    case INDEX_op_qemu_ld16u:

    case INDEX_op_qemu_ld16s:

    case INDEX_op_qemu_ld32:

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_qemu_ld32s:

    case INDEX_op_qemu_ld32u:

#endif

        tcg_out_r(s, *args++);

        tcg_out_r(s, *args++);

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

        tcg_out_r(s, *args++);

#endif

#ifdef CONFIG_SOFTMMU

        tcg_out_i(s, *args);

#endif

        break;

    case INDEX_op_qemu_ld64:

        tcg_out_r(s, *args++);

#if TCG_TARGET_REG_BITS == 32

        tcg_out_r(s, *args++);

#endif

        tcg_out_r(s, *args++);

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

        tcg_out_r(s, *args++);

#endif

#ifdef CONFIG_SOFTMMU

        tcg_out_i(s, *args);

#endif

        break;

    case INDEX_op_qemu_st8:

    case INDEX_op_qemu_st16:

    case INDEX_op_qemu_st32:

        tcg_out_r(s, *args++);

        tcg_out_r(s, *args++);

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

        tcg_out_r(s, *args++);

#endif

#ifdef CONFIG_SOFTMMU

        tcg_out_i(s, *args);

#endif

        break;

    case INDEX_op_qemu_st64:

        tcg_out_r(s, *args++);

#if TCG_TARGET_REG_BITS == 32

        tcg_out_r(s, *args++);

#endif

        tcg_out_r(s, *args++);

#if TARGET_LONG_BITS > TCG_TARGET_REG_BITS

        tcg_out_r(s, *args++);

#endif

#ifdef CONFIG_SOFTMMU

        tcg_out_i(s, *args);

#endif

        break;

    case INDEX_op_end:

        TODO();

        break;

    default:

        fprintf(stderr, "Missing: %s\n", tcg_op_defs[opc].name);

        tcg_abort();

    }

    old_code_ptr[1] = s->code_ptr - old_code_ptr;

}


static int usbredir_check_filter(USBRedirDevice *dev)

{

    if (dev->interface_info.interface_count == 0) {

        ERROR("No interface info for device\n");

        goto error;

    }

    if (dev->filter_rules) {

        if (!usbredirparser_peer_has_cap(dev->parser,

                                    usb_redir_cap_connect_device_version)) {

            ERROR("Device filter specified and peer does not have the "

                  "connect_device_version capability\n");

            goto error;

        }

        if (usbredirfilter_check(

                dev->filter_rules,

                dev->filter_rules_count,

                dev->device_info.device_class,

                dev->device_info.device_subclass,

                dev->device_info.device_protocol,

                dev->interface_info.interface_class,

                dev->interface_info.interface_subclass,

                dev->interface_info.interface_protocol,

                dev->interface_info.interface_count,

                dev->device_info.vendor_id,

                dev->device_info.product_id,

                dev->device_info.device_version_bcd,

                0) != 0) {

            goto error;

        }

    }

    return 0;

error:

    usbredir_device_disconnect(dev);

    if (usbredirparser_peer_has_cap(dev->parser, usb_redir_cap_filter)) {

        usbredirparser_send_filter_reject(dev->parser);

        usbredirparser_do_write(dev->parser);

    }

    return -1;

}


int spapr_allocate_irq_block(int num, bool lsi)

{

    int first = -1;

    int i;

    for (i = 0; i < num; ++i) {

        int irq;

        irq = spapr_allocate_irq(0, lsi);

        if (!irq) {

            return -1;

        }

        if (0 == i) {

            first = irq;

        }

        /* If the above doesn't create a consecutive block then that's

         * an internal bug */

        assert(irq == (first + i));

    }

    return first;

}


static void vfio_realize(PCIDevice *pdev, Error **errp)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);

    VFIODevice *vbasedev_iter;

    VFIOGroup *group;

    char *tmp, group_path[PATH_MAX], *group_name;

    Error *err = NULL;

    ssize_t len;

    struct stat st;

    int groupid;

    int i, ret;

    if (!vdev->vbasedev.sysfsdev) {

        if (!(~vdev->host.domain || ~vdev->host.bus ||

              ~vdev->host.slot || ~vdev->host.function)) {

            error_setg(errp, "No provided host device");

            error_append_hint(errp, "Use -vfio-pci,host=DDDD:BB:DD.F "

                              "or -vfio-pci,sysfsdev=PATH_TO_DEVICE\n");

            return;

        }

        vdev->vbasedev.sysfsdev =

            g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%01x",

                            vdev->host.domain, vdev->host.bus,

                            vdev->host.slot, vdev->host.function);

    }

    if (stat(vdev->vbasedev.sysfsdev, &st) < 0) {

        error_setg_errno(errp, errno, "no such host device");

        error_prepend(errp, ERR_PREFIX, vdev->vbasedev.sysfsdev);

        return;

    }

    vdev->vbasedev.name = g_strdup(basename(vdev->vbasedev.sysfsdev));

    vdev->vbasedev.ops = &vfio_pci_ops;

    vdev->vbasedev.type = VFIO_DEVICE_TYPE_PCI;

    tmp = g_strdup_printf("%s/iommu_group", vdev->vbasedev.sysfsdev);

    len = readlink(tmp, group_path, sizeof(group_path));

    g_free(tmp);

    if (len <= 0 || len >= sizeof(group_path)) {

        error_setg_errno(errp, len < 0 ? errno : ENAMETOOLONG,

                         "no iommu_group found");

        goto error;

    }

    group_path[len] = 0;

    group_name = basename(group_path);

    if (sscanf(group_name, "%d", &groupid) != 1) {

        error_setg_errno(errp, errno, "failed to read %s", group_path);

        goto error;

    }

    trace_vfio_realize(vdev->vbasedev.name, groupid);

    group = vfio_get_group(groupid, pci_device_iommu_address_space(pdev), errp);

    if (!group) {

        goto error;

    }

    QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {

        if (strcmp(vbasedev_iter->name, vdev->vbasedev.name) == 0) {

            error_setg(errp, "device is already attached");

            vfio_put_group(group);

            goto error;

        }

    }

    ret = vfio_get_device(group, vdev->vbasedev.name, &vdev->vbasedev, errp);

    if (ret) {

        vfio_put_group(group);

        goto error;

    }

    vfio_populate_device(vdev, &err);

    if (err) {

        error_propagate(errp, err);

        goto error;

    }

    /* Get a copy of config space */

    ret = pread(vdev->vbasedev.fd, vdev->pdev.config,

                MIN(pci_config_size(&vdev->pdev), vdev->config_size),

                vdev->config_offset);

    if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) {

        ret = ret < 0 ? -errno : -EFAULT;

        error_setg_errno(errp, -ret, "failed to read device config space");

        goto error;

    }

    /* vfio emulates a lot for us, but some bits need extra love */

    vdev->emulated_config_bits = g_malloc0(vdev->config_size);

    /* QEMU can choose to expose the ROM or not */

    memset(vdev->emulated_config_bits + PCI_ROM_ADDRESS, 0xff, 4);

    /*

     * The PCI spec reserves vendor ID 0xffff as an invalid value.  The

     * device ID is managed by the vendor and need only be a 16-bit value.

     * Allow any 16-bit value for subsystem so they can be hidden or changed.

     */

    if (vdev->vendor_id != PCI_ANY_ID) {

        if (vdev->vendor_id >= 0xffff) {

            error_setg(errp, "invalid PCI vendor ID provided");

            goto error;

        }

        vfio_add_emulated_word(vdev, PCI_VENDOR_ID, vdev->vendor_id, ~0);

        trace_vfio_pci_emulated_vendor_id(vdev->vbasedev.name, vdev->vendor_id);

    } else {

        vdev->vendor_id = pci_get_word(pdev->config + PCI_VENDOR_ID);

    }

    if (vdev->device_id != PCI_ANY_ID) {

        if (vdev->device_id > 0xffff) {

            error_setg(errp, "invalid PCI device ID provided");

            goto error;

        }

        vfio_add_emulated_word(vdev, PCI_DEVICE_ID, vdev->device_id, ~0);

        trace_vfio_pci_emulated_device_id(vdev->vbasedev.name, vdev->device_id);

    } else {

        vdev->device_id = pci_get_word(pdev->config + PCI_DEVICE_ID);

    }

    if (vdev->sub_vendor_id != PCI_ANY_ID) {

        if (vdev->sub_vendor_id > 0xffff) {

            error_setg(errp, "invalid PCI subsystem vendor ID provided");

            goto error;

        }

        vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_VENDOR_ID,

                               vdev->sub_vendor_id, ~0);

        trace_vfio_pci_emulated_sub_vendor_id(vdev->vbasedev.name,

                                              vdev->sub_vendor_id);

    }

    if (vdev->sub_device_id != PCI_ANY_ID) {

        if (vdev->sub_device_id > 0xffff) {

            error_setg(errp, "invalid PCI subsystem device ID provided");

            goto error;

        }

        vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_ID, vdev->sub_device_id, ~0);

        trace_vfio_pci_emulated_sub_device_id(vdev->vbasedev.name,

                                              vdev->sub_device_id);

    }

    /* QEMU can change multi-function devices to single function, or reverse */

    vdev->emulated_config_bits[PCI_HEADER_TYPE] =

                                              PCI_HEADER_TYPE_MULTI_FUNCTION;

    /* Restore or clear multifunction, this is always controlled by QEMU */

    if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) {

        vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION;

    } else {

        vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION;

    }

    /*

     * Clear host resource mapping info.  If we choose not to register a

     * BAR, such as might be the case with the option ROM, we can get

     * confusing, unwritable, residual addresses from the host here.

     */

    memset(&vdev->pdev.config[PCI_BASE_ADDRESS_0], 0, 24);

    memset(&vdev->pdev.config[PCI_ROM_ADDRESS], 0, 4);

    vfio_pci_size_rom(vdev);

    vfio_msix_early_setup(vdev, &err);

    if (err) {

        error_propagate(errp, err);

        goto error;

    }

    vfio_bars_setup(vdev);

    ret = vfio_add_capabilities(vdev, errp);

    if (ret) {

        goto out_teardown;

    }

    if (vdev->vga) {

        vfio_vga_quirk_setup(vdev);

    }

    for (i = 0; i < PCI_ROM_SLOT; i++) {

        vfio_bar_quirk_setup(vdev, i);

    }

    if (!vdev->igd_opregion &&

        vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) {

        struct vfio_region_info *opregion;

        if (vdev->pdev.qdev.hotplugged) {

            error_setg(errp,

                       "cannot support IGD OpRegion feature on hotplugged "

                       "device");

            goto out_teardown;

        }

        ret = vfio_get_dev_region_info(&vdev->vbasedev,

                        VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL,

                        VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion);

        if (ret) {

            error_setg_errno(errp, -ret,

                             "does not support requested IGD OpRegion feature");

            goto out_teardown;

        }

        ret = vfio_pci_igd_opregion_init(vdev, opregion, errp);

        g_free(opregion);

        if (ret) {

            goto out_teardown;

        }

    }

    /* QEMU emulates all of MSI & MSIX */

    if (pdev->cap_present & QEMU_PCI_CAP_MSIX) {

        memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff,

               MSIX_CAP_LENGTH);

    }

    if (pdev->cap_present & QEMU_PCI_CAP_MSI) {

        memset(vdev->emulated_config_bits + pdev->msi_cap, 0xff,

               vdev->msi_cap_size);

    }

    if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) {

        vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,

                                                  vfio_intx_mmap_enable, vdev);

        pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_intx_update);

        ret = vfio_intx_enable(vdev, errp);

        if (ret) {

            goto out_teardown;

        }

    }

    vfio_register_err_notifier(vdev);

    vfio_register_req_notifier(vdev);

    vfio_setup_resetfn_quirk(vdev);

    return;

out_teardown:

    pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);

    vfio_teardown_msi(vdev);

    vfio_bars_exit(vdev);

error:

    error_prepend(errp, ERR_PREFIX, vdev->vbasedev.name);

}


static void qmp_input_push(QmpInputVisitor *qiv, QObject *obj, Error **errp)

{

    GHashTable *h;

    StackObject *tos = &qiv->stack[qiv->nb_stack];

    assert(obj);

    if (qiv->nb_stack >= QIV_STACK_SIZE) {

        error_setg(errp, "An internal buffer overran");

        return;

    }

    tos->obj = obj;

    assert(!tos->h);

    assert(!tos->entry);

    if (qiv->strict && qobject_type(obj) == QTYPE_QDICT) {

        h = g_hash_table_new(g_str_hash, g_str_equal);

        qdict_iter(qobject_to_qdict(obj), qdict_add_key, h);

        tos->h = h;

    } else if (qobject_type(obj) == QTYPE_QLIST) {

        tos->entry = qlist_first(qobject_to_qlist(obj));

        tos->first = true;

    }

    qiv->nb_stack++;

}


static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    HLSContext *c = s->priv_data;

    int ret, i, minvariant = -1;

    if (c->first_packet) {

        recheck_discard_flags(s, 1);

        c->first_packet = 0;

    }

start:

    c->end_of_segment = 0;

    for (i = 0; i < c->n_variants; i++) {

        struct variant *var = c->variants[i];

        /* Make sure we've got one buffered packet from each open variant

         * stream */

        if (var->needed && !var->pkt.data) {

            while (1) {

                int64_t ts_diff;

                AVStream *st;

                ret = av_read_frame(var->ctx, &var->pkt);

                if (ret < 0) {

                    if (!url_feof(&var->pb))

                        return ret;

                    reset_packet(&var->pkt);

                    break;

                } else {

                    if (c->first_timestamp == AV_NOPTS_VALUE)

                        c->first_timestamp = var->pkt.dts;

                }

                if (c->seek_timestamp == AV_NOPTS_VALUE)

                    break;

                if (var->pkt.dts == AV_NOPTS_VALUE) {

                    c->seek_timestamp = AV_NOPTS_VALUE;

                    break;

                }

                st = var->ctx->streams[var->pkt.stream_index];

                ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE,

                                         st->time_base.den, AV_ROUND_DOWN) -

                          c->seek_timestamp;

                if (ts_diff >= 0 && (c->seek_flags  & AVSEEK_FLAG_ANY ||

                                     var->pkt.flags & AV_PKT_FLAG_KEY)) {

                    c->seek_timestamp = AV_NOPTS_VALUE;

                    break;

                }

            }

        }

        /* Check if this stream has the packet with the lowest dts */

        if (var->pkt.data) {

            struct variant *minvar = c->variants[minvariant];

            if (minvariant < 0 ||

                av_compare_ts(var->pkt.dts, var->ctx->streams[var->pkt.stream_index]->time_base,

                              minvar->pkt.dts, minvar->ctx->streams[minvar->pkt.stream_index]->time_base) > 0)

                minvariant = i;

        }

    }

    if (c->end_of_segment) {

        if (recheck_discard_flags(s, 0))

            goto start;

    }

    /* If we got a packet, return it */

    if (minvariant >= 0) {

        *pkt = c->variants[minvariant]->pkt;

        pkt->stream_index += c->variants[minvariant]->stream_offset;

        reset_packet(&c->variants[minvariant]->pkt);

        return 0;

    }

    return AVERROR_EOF;

}


static int qio_dns_resolver_lookup_sync_inet(QIODNSResolver *resolver,

                                             SocketAddressLegacy *addr,

                                             size_t *naddrs,

                                             SocketAddressLegacy ***addrs,

                                             Error **errp)

{

    struct addrinfo ai, *res, *e;

    InetSocketAddress *iaddr = addr->u.inet.data;

    char port[33];

    char uaddr[INET6_ADDRSTRLEN + 1];

    char uport[33];

    int rc;

    Error *err = NULL;

    size_t i;

    *naddrs = 0;

    *addrs = NULL;

    memset(&ai, 0, sizeof(ai));

    ai.ai_flags = AI_PASSIVE;

    if (iaddr->has_numeric && iaddr->numeric) {

        ai.ai_flags |= AI_NUMERICHOST | AI_NUMERICSERV;

    }

    ai.ai_family = inet_ai_family_from_address(iaddr, &err);

    ai.ai_socktype = SOCK_STREAM;

    if (err) {

        error_propagate(errp, err);

        return -1;

    }

    if (iaddr->host == NULL) {

        error_setg(errp, "host not specified");

        return -1;

    }

    if (iaddr->port != NULL) {

        pstrcpy(port, sizeof(port), iaddr->port);

    } else {

        port[0] = '\0';

    }

    rc = getaddrinfo(strlen(iaddr->host) ? iaddr->host : NULL,

                     strlen(port) ? port : NULL, &ai, &res);

    if (rc != 0) {

        error_setg(errp, "address resolution failed for %s:%s: %s",

                   iaddr->host, port, gai_strerror(rc));

        return -1;

    }

    for (e = res; e != NULL; e = e->ai_next) {

        (*naddrs)++;

    }

    *addrs = g_new0(SocketAddressLegacy *, *naddrs);

    /* create socket + bind */

    for (i = 0, e = res; e != NULL; i++, e = e->ai_next) {

        SocketAddressLegacy *newaddr = g_new0(SocketAddressLegacy, 1);

        InetSocketAddress *newiaddr = g_new0(InetSocketAddress, 1);

        newaddr->u.inet.data = newiaddr;

        newaddr->type = SOCKET_ADDRESS_LEGACY_KIND_INET;

        getnameinfo((struct sockaddr *)e->ai_addr, e->ai_addrlen,

                    uaddr, INET6_ADDRSTRLEN, uport, 32,

                    NI_NUMERICHOST | NI_NUMERICSERV);

        *newiaddr = (InetSocketAddress){

            .host = g_strdup(uaddr),

            .port = g_strdup(uport),

            .has_numeric = true,

            .numeric = true,

            .has_to = iaddr->has_to,

            .to = iaddr->to,

            .has_ipv4 = false,

            .has_ipv6 = false,

        };

        (*addrs)[i] = newaddr;

    }

    freeaddrinfo(res);

    return 0;

}


void helper_vmrun(target_ulong addr)

{

    uint32_t event_inj;

    uint32_t int_ctl;

    if (loglevel & CPU_LOG_TB_IN_ASM)

        fprintf(logfile,"vmrun! " TARGET_FMT_lx "\n", addr);

    env->vm_vmcb = addr;

    regs_to_env();

    /* save the current CPU state in the hsave page */

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.base), env->gdt.base);

    stl_phys(env->vm_hsave + offsetof(struct vmcb, save.gdtr.limit), env->gdt.limit);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.base), env->idt.base);

    stl_phys(env->vm_hsave + offsetof(struct vmcb, save.idtr.limit), env->idt.limit);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr0), env->cr[0]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr2), env->cr[2]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr3), env->cr[3]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr4), env->cr[4]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.cr8), env->cr[8]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr6), env->dr[6]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.dr7), env->dr[7]);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.efer), env->efer);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rflags), compute_eflags());

    SVM_SAVE_SEG(env->vm_hsave, segs[R_ES], es);

    SVM_SAVE_SEG(env->vm_hsave, segs[R_CS], cs);

    SVM_SAVE_SEG(env->vm_hsave, segs[R_SS], ss);

    SVM_SAVE_SEG(env->vm_hsave, segs[R_DS], ds);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rip), EIP);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rsp), ESP);

    stq_phys(env->vm_hsave + offsetof(struct vmcb, save.rax), EAX);

    /* load the interception bitmaps so we do not need to access the

       vmcb in svm mode */

    /* We shift all the intercept bits so we can OR them with the TB

       flags later on */

    env->intercept            = (ldq_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept)) << INTERCEPT_INTR) | INTERCEPT_SVM_MASK;

    env->intercept_cr_read    = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_read));

    env->intercept_cr_write   = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_cr_write));

    env->intercept_dr_read    = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_read));

    env->intercept_dr_write   = lduw_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_dr_write));

    env->intercept_exceptions = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.intercept_exceptions));

    env->gdt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.base));

    env->gdt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.gdtr.limit));

    env->idt.base  = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.base));

    env->idt.limit = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, save.idtr.limit));

    /* clear exit_info_2 so we behave like the real hardware */

    stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), 0);

    cpu_x86_update_cr0(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr0)));

    cpu_x86_update_cr4(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr4)));

    cpu_x86_update_cr3(env, ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr3)));

    env->cr[2] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.cr2));

    int_ctl = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.int_ctl));

    if (int_ctl & V_INTR_MASKING_MASK) {

        env->cr[8] = int_ctl & V_TPR_MASK;

        cpu_set_apic_tpr(env, env->cr[8]);

        if (env->eflags & IF_MASK)

            env->hflags |= HF_HIF_MASK;

    }

#ifdef TARGET_X86_64

    env->efer = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.efer));

    env->hflags &= ~HF_LMA_MASK;

    if (env->efer & MSR_EFER_LMA)

       env->hflags |= HF_LMA_MASK;

#endif

    env->eflags = 0;

    load_eflags(ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rflags)),

                ~(CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C | DF_MASK));

    CC_OP = CC_OP_EFLAGS;

    CC_DST = 0xffffffff;

    SVM_LOAD_SEG(env->vm_vmcb, ES, es);

    SVM_LOAD_SEG(env->vm_vmcb, CS, cs);

    SVM_LOAD_SEG(env->vm_vmcb, SS, ss);

    SVM_LOAD_SEG(env->vm_vmcb, DS, ds);

    EIP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rip));

    env->eip = EIP;

    ESP = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rsp));

    EAX = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.rax));

    env->dr[7] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr7));

    env->dr[6] = ldq_phys(env->vm_vmcb + offsetof(struct vmcb, save.dr6));

    cpu_x86_set_cpl(env, ldub_phys(env->vm_vmcb + offsetof(struct vmcb, save.cpl)));

    /* FIXME: guest state consistency checks */

    switch(ldub_phys(env->vm_vmcb + offsetof(struct vmcb, control.tlb_ctl))) {

        case TLB_CONTROL_DO_NOTHING:

            break;

        case TLB_CONTROL_FLUSH_ALL_ASID:

            /* FIXME: this is not 100% correct but should work for now */

            tlb_flush(env, 1);

        break;

    }

    helper_stgi();

    regs_to_env();

    /* maybe we need to inject an event */

    event_inj = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj));

    if (event_inj & SVM_EVTINJ_VALID) {

        uint8_t vector = event_inj & SVM_EVTINJ_VEC_MASK;

        uint16_t valid_err = event_inj & SVM_EVTINJ_VALID_ERR;

        uint32_t event_inj_err = ldl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj_err));

        stl_phys(env->vm_vmcb + offsetof(struct vmcb, control.event_inj), event_inj & ~SVM_EVTINJ_VALID);

        if (loglevel & CPU_LOG_TB_IN_ASM)

            fprintf(logfile, "Injecting(%#hx): ", valid_err);

        /* FIXME: need to implement valid_err */

        switch (event_inj & SVM_EVTINJ_TYPE_MASK) {

        case SVM_EVTINJ_TYPE_INTR:

                env->exception_index = vector;

                env->error_code = event_inj_err;

                env->exception_is_int = 1;

                env->exception_next_eip = -1;

                if (loglevel & CPU_LOG_TB_IN_ASM)

                    fprintf(logfile, "INTR");

                break;

        case SVM_EVTINJ_TYPE_NMI:

                env->exception_index = vector;

                env->error_code = event_inj_err;

                env->exception_is_int = 1;

                env->exception_next_eip = EIP;

                if (loglevel & CPU_LOG_TB_IN_ASM)

                    fprintf(logfile, "NMI");

                break;

        case SVM_EVTINJ_TYPE_EXEPT:

                env->exception_index = vector;

                env->error_code = event_inj_err;

                env->exception_is_int = 0;

                env->exception_next_eip = -1;

                if (loglevel & CPU_LOG_TB_IN_ASM)

                    fprintf(logfile, "EXEPT");

                break;

        case SVM_EVTINJ_TYPE_SOFT:

                env->exception_index = vector;

                env->error_code = event_inj_err;

                env->exception_is_int = 1;

                env->exception_next_eip = EIP;

                if (loglevel & CPU_LOG_TB_IN_ASM)

                    fprintf(logfile, "SOFT");

                break;

        }

        if (loglevel & CPU_LOG_TB_IN_ASM)

            fprintf(logfile, " %#x %#x\n", env->exception_index, env->error_code);

    }

    if ((int_ctl & V_IRQ_MASK) || (env->intercept & INTERCEPT_VINTR)) {

        env->interrupt_request |= CPU_INTERRUPT_VIRQ;

    }

    cpu_loop_exit();

}


void qxl_spice_update_area(PCIQXLDevice *qxl, uint32_t surface_id,

                           struct QXLRect *area, struct QXLRect *dirty_rects,

                           uint32_t num_dirty_rects,

                           uint32_t clear_dirty_region,

                           qxl_async_io async)

{

    if (async == QXL_SYNC) {

        qxl->ssd.worker->update_area(qxl->ssd.worker, surface_id, area,

                        dirty_rects, num_dirty_rects, clear_dirty_region);

    } else {

#if SPICE_INTERFACE_QXL_MINOR >= 1

        spice_qxl_update_area_async(&qxl->ssd.qxl, surface_id, area,

                                    clear_dirty_region, 0);

#else

        abort();

#endif

    }

}


static int audio_validate_settings (audsettings_t *as)

{

    int invalid;

    invalid = as->nchannels != 1 && as->nchannels != 2;

    invalid |= as->endianness != 0 && as->endianness != 1;

    switch (as->fmt) {

    case AUD_FMT_S8:

    case AUD_FMT_U8:

    case AUD_FMT_S16:

    case AUD_FMT_U16:

    case AUD_FMT_S32:

    case AUD_FMT_U32:

        break;

    default:

        invalid = 1;

        break;

    }

    invalid |= as->freq <= 0;

    return invalid ? -1 : 0;

}


const ppc_def_t *kvmppc_host_cpu_def(void)

{

    uint32_t host_pvr = mfpvr();

    const ppc_def_t *base_spec;

    ppc_def_t *spec;

    uint32_t vmx = kvmppc_get_vmx();

    uint32_t dfp = kvmppc_get_dfp();

    base_spec = ppc_find_by_pvr(host_pvr);

    spec = g_malloc0(sizeof(*spec));

    memcpy(spec, base_spec, sizeof(*spec));

    /* Now fix up the spec with information we can query from the host */

    alter_insns(&spec->insns_flags, PPC_ALTIVEC, vmx > 0);

    alter_insns(&spec->insns_flags2, PPC2_VSX, vmx > 1);

    alter_insns(&spec->insns_flags2, PPC2_DFP, dfp);

    return spec;

}


I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,

                      qemu_irq sci_irq, qemu_irq smi_irq,

                      int kvm_enabled, FWCfgState *fw_cfg,

                      DeviceState **piix4_pm)

{

    DeviceState *dev;

    PIIX4PMState *s;

    dev = DEVICE(pci_create(bus, devfn, TYPE_PIIX4_PM));

    qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base);

    if (piix4_pm) {

        *piix4_pm = dev;

    }

    s = PIIX4_PM(dev);

    s->irq = sci_irq;

    s->smi_irq = smi_irq;

    s->kvm_enabled = kvm_enabled;

    if (xen_enabled()) {

        s->use_acpi_pci_hotplug = false;

    }

    qdev_init_nofail(dev);

    if (fw_cfg) {

        uint8_t suspend[6] = {128, 0, 0, 129, 128, 128};

        suspend[3] = 1 | ((!s->disable_s3) << 7);

        suspend[4] = s->s4_val | ((!s->disable_s4) << 7);

        fw_cfg_add_file(fw_cfg, "etc/system-states", g_memdup(suspend, 6), 6);

    }

    return s->smb.smbus;

}


static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE )

{

	int i;

	double rate;

	/* make attack rate & decay rate tables */

	for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0;

	for (i = 4;i <= 60;i++){

		rate  = OPL->freqbase;						/* frequency rate */

		if( i < 60 ) rate *= 1.0+(i&3)*0.25;		/* b0-1 : x1 , x1.25 , x1.5 , x1.75 */

		rate *= 1<<((i>>2)-1);						/* b2-5 : shift bit */

		rate *= (double)(EG_ENT<<ENV_BITS);

		OPL->AR_TABLE[i] = rate / ARRATE;

		OPL->DR_TABLE[i] = rate / DRRATE;

	}

	for (i = 60; i < ARRAY_SIZE(OPL->AR_TABLE); i++)

	{

		OPL->AR_TABLE[i] = EG_AED-1;

		OPL->DR_TABLE[i] = OPL->DR_TABLE[60];

	}

#if 0

	for (i = 0;i < 64 ;i++){	/* make for overflow area */

		LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i,

			((double)(EG_ENT<<ENV_BITS) / OPL->AR_TABLE[i]) * (1000.0 / OPL->rate),

			((double)(EG_ENT<<ENV_BITS) / OPL->DR_TABLE[i]) * (1000.0 / OPL->rate) ));

	}

#endif

}


static int colo_packet_compare_all(Packet *spkt, Packet *ppkt)

{

    trace_colo_compare_main("compare all");

    return colo_packet_compare(ppkt, spkt);

}


static uint64_t fw_cfg_data_mem_read(void *opaque, target_phys_addr_t addr,

                                     unsigned size)

{

    return fw_cfg_read(opaque);

}


static void mov_write_uuidprof_tag(ByteIOContext *pb, AVFormatContext *s)

{

    AVCodecContext *VideoCodec = s->streams[0]->codec;

    AVCodecContext *AudioCodec = s->streams[1]->codec;

    int AudioRate = AudioCodec->sample_rate;

    int FrameRate = ((VideoCodec->time_base.den) * (0x10000))/ (VideoCodec->time_base.num);

    int audio_kbitrate= AudioCodec->bit_rate / 1000;

    int video_kbitrate= FFMIN(VideoCodec->bit_rate / 1000, 800 - audio_kbitrate);

    put_be32(pb, 0x94 ); /* size */

    put_tag(pb, "uuid");

    put_tag(pb, "PROF");

    put_be32(pb, 0x21d24fce ); /* 96 bit UUID */

    put_be32(pb, 0xbb88695c );

    put_be32(pb, 0xfac9c740 );

    put_be32(pb, 0x0 );  /* ? */

    put_be32(pb, 0x3 );  /* 3 sections ? */

    put_be32(pb, 0x14 ); /* size */

    put_tag(pb, "FPRF");

    put_be32(pb, 0x0 );  /* ? */

    put_be32(pb, 0x0 );  /* ? */

    put_be32(pb, 0x0 );  /* ? */

    put_be32(pb, 0x2c );  /* size */

    put_tag(pb, "APRF");   /* audio */

    put_be32(pb, 0x0 );

    put_be32(pb, 0x2 );   /* TrackID */

    put_tag(pb, "mp4a");

    put_be32(pb, 0x20f );

    put_be32(pb, 0x0 );

    put_be32(pb, audio_kbitrate);

    put_be32(pb, audio_kbitrate);

    put_be32(pb, AudioRate );

    put_be32(pb, AudioCodec->channels );

    put_be32(pb, 0x34 );  /* size */

    put_tag(pb, "VPRF");   /* video */

    put_be32(pb, 0x0 );

    put_be32(pb, 0x1 );    /* TrackID */

    put_tag(pb, "mp4v");

    put_be32(pb, 0x103 );

    put_be32(pb, 0x0 );

    put_be32(pb, video_kbitrate);

    put_be32(pb, video_kbitrate);

    put_be32(pb, FrameRate);

    put_be32(pb, FrameRate);

    put_be16(pb, VideoCodec->width);

    put_be16(pb, VideoCodec->height);

    put_be32(pb, 0x010001); /* ? */

}


static void xilinx_spips_reset(DeviceState *d)

{

    XilinxSPIPS *s = XILINX_SPIPS(d);

    int i;

    for (i = 0; i < XLNX_SPIPS_R_MAX; i++) {

        s->regs[i] = 0;

    }

    fifo8_reset(&s->rx_fifo);

    fifo8_reset(&s->rx_fifo);

    /* non zero resets */

    s->regs[R_CONFIG] |= MODEFAIL_GEN_EN;

    s->regs[R_SLAVE_IDLE_COUNT] = 0xFF;

    s->regs[R_TX_THRES] = 1;

    s->regs[R_RX_THRES] = 1;

    /* FIXME: move magic number definition somewhere sensible */

    s->regs[R_MOD_ID] = 0x01090106;

    s->regs[R_LQSPI_CFG] = R_LQSPI_CFG_RESET;

    s->link_state = 1;

    s->link_state_next = 1;

    s->link_state_next_when = 0;

    s->snoop_state = SNOOP_CHECKING;

    s->cmd_dummies = 0;

    s->man_start_com = false;

    xilinx_spips_update_ixr(s);

    xilinx_spips_update_cs_lines(s);

}


static void show_chapters(WriterContext *w, AVFormatContext *fmt_ctx)

{

    int i;

    writer_print_section_header(w, SECTION_ID_CHAPTERS);

    for (i = 0; i < fmt_ctx->nb_chapters; i++) {

        AVChapter *chapter = fmt_ctx->chapters[i];

        writer_print_section_header(w, SECTION_ID_CHAPTER);

        print_int("id", chapter->id);

        print_q  ("time_base", chapter->time_base, '/');

        print_int("start", chapter->start);

        print_time("start_time", chapter->start, &chapter->time_base);

        print_int("end", chapter->end);

        print_time("end_time", chapter->end, &chapter->time_base);

        show_tags(w, chapter->metadata, SECTION_ID_CHAPTER_TAGS);

        writer_print_section_footer(w);

    }

    writer_print_section_footer(w);

}


static void spr_write_403_pbr (void *opaque, int sprn)

{

    DisasContext *ctx = opaque;

    gen_op_store_403_pb(sprn - SPR_403_PBL1);

    RET_STOP(ctx);

}


static int vhdx_create_new_metadata(BlockDriverState *bs,

                                    uint64_t image_size,

                                    uint32_t block_size,

                                    uint32_t sector_size,

                                    uint64_t metadata_offset,

                                    VHDXImageType type)

{

    int ret = 0;

    uint32_t offset = 0;

    void *buffer = NULL;

    void *entry_buffer;

    VHDXMetadataTableHeader *md_table;

    VHDXMetadataTableEntry  *md_table_entry;

    /* Metadata entries */

    VHDXFileParameters     *mt_file_params;

    VHDXVirtualDiskSize    *mt_virtual_size;

    VHDXPage83Data         *mt_page83;

    VHDXVirtualDiskLogicalSectorSize  *mt_log_sector_size;

    VHDXVirtualDiskPhysicalSectorSize *mt_phys_sector_size;

    entry_buffer = g_malloc0(VHDX_METADATA_ENTRY_BUFFER_SIZE);

    mt_file_params = entry_buffer;

    offset += sizeof(VHDXFileParameters);

    mt_virtual_size = entry_buffer + offset;

    offset += sizeof(VHDXVirtualDiskSize);

    mt_page83 = entry_buffer + offset;

    offset += sizeof(VHDXPage83Data);

    mt_log_sector_size = entry_buffer + offset;

    offset += sizeof(VHDXVirtualDiskLogicalSectorSize);

    mt_phys_sector_size = entry_buffer + offset;

    mt_file_params->block_size = cpu_to_le32(block_size);

    if (type == VHDX_TYPE_FIXED) {

        mt_file_params->data_bits |= VHDX_PARAMS_LEAVE_BLOCKS_ALLOCED;

        cpu_to_le32s(&mt_file_params->data_bits);

    }

    vhdx_guid_generate(&mt_page83->page_83_data);

    cpu_to_leguids(&mt_page83->page_83_data);

    mt_virtual_size->virtual_disk_size        = cpu_to_le64(image_size);

    mt_log_sector_size->logical_sector_size   = cpu_to_le32(sector_size);

    mt_phys_sector_size->physical_sector_size = cpu_to_le32(sector_size);

    buffer = g_malloc0(VHDX_HEADER_BLOCK_SIZE);

    md_table = buffer;

    md_table->signature   = VHDX_METADATA_SIGNATURE;

    md_table->entry_count = 5;

    vhdx_metadata_header_le_export(md_table);

    /* This will reference beyond the reserved table portion */

    offset = 64 * KiB;

    md_table_entry = buffer + sizeof(VHDXMetadataTableHeader);

    md_table_entry[0].item_id = file_param_guid;

    md_table_entry[0].offset  = offset;

    md_table_entry[0].length  = sizeof(VHDXFileParameters);

    md_table_entry[0].data_bits |= VHDX_META_FLAGS_IS_REQUIRED;

    offset += md_table_entry[0].length;

    vhdx_metadata_entry_le_export(&md_table_entry[0]);

    md_table_entry[1].item_id = virtual_size_guid;

    md_table_entry[1].offset  = offset;

    md_table_entry[1].length  = sizeof(VHDXVirtualDiskSize);

    md_table_entry[1].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |

                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;

    offset += md_table_entry[1].length;

    vhdx_metadata_entry_le_export(&md_table_entry[1]);

    md_table_entry[2].item_id = page83_guid;

    md_table_entry[2].offset  = offset;

    md_table_entry[2].length  = sizeof(VHDXPage83Data);

    md_table_entry[2].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |

                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;

    offset += md_table_entry[2].length;

    vhdx_metadata_entry_le_export(&md_table_entry[2]);

    md_table_entry[3].item_id = logical_sector_guid;

    md_table_entry[3].offset  = offset;

    md_table_entry[3].length  = sizeof(VHDXVirtualDiskLogicalSectorSize);

    md_table_entry[3].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |

                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;

    offset += md_table_entry[3].length;

    vhdx_metadata_entry_le_export(&md_table_entry[3]);

    md_table_entry[4].item_id = phys_sector_guid;

    md_table_entry[4].offset  = offset;

    md_table_entry[4].length  = sizeof(VHDXVirtualDiskPhysicalSectorSize);

    md_table_entry[4].data_bits |= VHDX_META_FLAGS_IS_REQUIRED |

                                   VHDX_META_FLAGS_IS_VIRTUAL_DISK;

    vhdx_metadata_entry_le_export(&md_table_entry[4]);

    ret = bdrv_pwrite(bs, metadata_offset, buffer, VHDX_HEADER_BLOCK_SIZE);

    if (ret < 0) {

        goto exit;

    }

    ret = bdrv_pwrite(bs, metadata_offset + (64 * KiB), entry_buffer,

                      VHDX_METADATA_ENTRY_BUFFER_SIZE);

    if (ret < 0) {

        goto exit;

    }

exit:

    g_free(buffer);

    g_free(entry_buffer);

    return ret;

}


create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)

{

    size_t *sizes = calloc(nr_iov, sizeof(size_t));

    size_t count = 0;

    void *buf = NULL;

    void *p;

    int i;

    for (i = 0; i < nr_iov; i++) {

        char *arg = argv[i];

        int64_t len;

        len = cvtnum(arg);

        if (len < 0) {

            printf("non-numeric length argument -- %s\n", arg);

            goto fail;

        }

        /* should be SIZE_T_MAX, but that doesn't exist */

        if (len > INT_MAX) {

            printf("too large length argument -- %s\n", arg);

            goto fail;

        }

        if (len & 0x1ff) {

            printf("length argument %" PRId64

                   " is not sector aligned\n", len);

            goto fail;

        }

        sizes[i] = len;

        count += len;

    }

    qemu_iovec_init(qiov, nr_iov);

    buf = p = qemu_io_alloc(count, pattern);

    for (i = 0; i < nr_iov; i++) {

        qemu_iovec_add(qiov, p, sizes[i]);

        p += sizes[i];

    }

fail:

    free(sizes);

    return buf;

}


void net_tx_pkt_reset(struct NetTxPkt *pkt)

{

    int i;

    /* no assert, as reset can be called before tx_pkt_init */

    if (!pkt) {

        return;

    }

    memset(&pkt->virt_hdr, 0, sizeof(pkt->virt_hdr));

    g_free(pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base);

    pkt->vec[NET_TX_PKT_L3HDR_FRAG].iov_base = NULL;

    assert(pkt->vec);

    for (i = NET_TX_PKT_L2HDR_FRAG;

         i < pkt->payload_frags + NET_TX_PKT_PL_START_FRAG; i++) {

        pkt->vec[i].iov_len = 0;

    }

    pkt->payload_len = 0;

    pkt->payload_frags = 0;

    assert(pkt->raw);

    for (i = 0; i < pkt->raw_frags; i++) {

        assert(pkt->raw[i].iov_base);

        cpu_physical_memory_unmap(pkt->raw[i].iov_base, pkt->raw[i].iov_len,

                                  false, pkt->raw[i].iov_len);

        pkt->raw[i].iov_len = 0;

    }

    pkt->raw_frags = 0;

    pkt->hdr_len = 0;

    pkt->packet_type = 0;

    pkt->l4proto = 0;

}


static void tcg_s390_program_interrupt(CPUS390XState *env, uint32_t code,

                                       int ilen)

{

#ifdef CONFIG_TCG

    trigger_pgm_exception(env, code, ilen);

    cpu_loop_exit(CPU(s390_env_get_cpu(env)));

#else

    g_assert_not_reached();

#endif

}


static int vpc_open(BlockDriverState *bs, QDict *options, int flags,

                    Error **errp)

{

    BDRVVPCState *s = bs->opaque;

    int i;

    VHDFooter *footer;

    VHDDynDiskHeader *dyndisk_header;

    uint8_t buf[HEADER_SIZE];

    uint32_t checksum;

    int disk_type = VHD_DYNAMIC;

    int ret;

    ret = bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE);

    if (ret < 0) {

        goto fail;

    }

    footer = (VHDFooter *) s->footer_buf;

    if (strncmp(footer->creator, "conectix", 8)) {

        int64_t offset = bdrv_getlength(bs->file);

        if (offset < 0) {

            ret = offset;

            goto fail;

        } else if (offset < HEADER_SIZE) {

            ret = -EINVAL;

            goto fail;

        }

        /* If a fixed disk, the footer is found only at the end of the file */

        ret = bdrv_pread(bs->file, offset-HEADER_SIZE, s->footer_buf,

                         HEADER_SIZE);

        if (ret < 0) {

            goto fail;

        }

        if (strncmp(footer->creator, "conectix", 8)) {

            ret = -EMEDIUMTYPE;

            goto fail;

        }

        disk_type = VHD_FIXED;

    }

    checksum = be32_to_cpu(footer->checksum);

    footer->checksum = 0;

    if (vpc_checksum(s->footer_buf, HEADER_SIZE) != checksum)

        fprintf(stderr, "block-vpc: The header checksum of '%s' is "

            "incorrect.\n", bs->filename);

    /* Write 'checksum' back to footer, or else will leave it with zero. */

    footer->checksum = be32_to_cpu(checksum);

    // The visible size of a image in Virtual PC depends on the geometry

    // rather than on the size stored in the footer (the size in the footer

    // is too large usually)

    bs->total_sectors = (int64_t)

        be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;

    /* images created with disk2vhd report a far higher virtual size

     * than expected with the cyls * heads * sectors_per_cyl formula.

     * use the footer->size instead if the image was created with

     * disk2vhd.

     */

    if (!strncmp(footer->creator_app, "d2v", 4)) {

        bs->total_sectors = be64_to_cpu(footer->size) / BDRV_SECTOR_SIZE;

    }

    /* Allow a maximum disk size of approximately 2 TB */

    if (bs->total_sectors >= 65535LL * 255 * 255) {

        ret = -EFBIG;

        goto fail;

    }

    if (disk_type == VHD_DYNAMIC) {

        ret = bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf,

                         HEADER_SIZE);

        if (ret < 0) {

            goto fail;

        }

        dyndisk_header = (VHDDynDiskHeader *) buf;

        if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {

            ret = -EINVAL;

            goto fail;

        }

        s->block_size = be32_to_cpu(dyndisk_header->block_size);

        s->bitmap_size = ((s->block_size / (8 * 512)) + 511) & ~511;

        s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);

        s->pagetable = g_malloc(s->max_table_entries * 4);

        s->bat_offset = be64_to_cpu(dyndisk_header->table_offset);

        ret = bdrv_pread(bs->file, s->bat_offset, s->pagetable,

                         s->max_table_entries * 4);

        if (ret < 0) {

            goto fail;

        }

        s->free_data_block_offset =

            (s->bat_offset + (s->max_table_entries * 4) + 511) & ~511;

        for (i = 0; i < s->max_table_entries; i++) {

            be32_to_cpus(&s->pagetable[i]);

            if (s->pagetable[i] != 0xFFFFFFFF) {

                int64_t next = (512 * (int64_t) s->pagetable[i]) +

                    s->bitmap_size + s->block_size;

                if (next > s->free_data_block_offset) {

                    s->free_data_block_offset = next;

                }

            }

        }

        if (s->free_data_block_offset > bdrv_getlength(bs->file)) {

            error_setg(errp, "block-vpc: free_data_block_offset points after "

                             "the end of file. The image has been truncated.");

            ret = -EINVAL;

            goto fail;

        }

        s->last_bitmap_offset = (int64_t) -1;

#ifdef CACHE

        s->pageentry_u8 = g_malloc(512);

        s->pageentry_u32 = s->pageentry_u8;

        s->pageentry_u16 = s->pageentry_u8;

        s->last_pagetable = -1;

#endif

    }

    qemu_co_mutex_init(&s->lock);

    /* Disable migration when VHD images are used */

    error_set(&s->migration_blocker,

              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,

              "vpc", bs->device_name, "live migration");

    migrate_add_blocker(s->migration_blocker);

    return 0;

fail:

    g_free(s->pagetable);

#ifdef CACHE

    g_free(s->pageentry_u8);

#endif

    return ret;

}


static always_inline void check_mips_mt(CPUState *env, DisasContext *ctx)

{

    if (unlikely(!(env->CP0_Config3 & (1 << CP0C3_MT))))

        generate_exception(ctx, EXCP_RI);

}


static void dxva_adjust_hwframes(AVCodecContext *avctx, AVHWFramesContext *frames_ctx)

{

    FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx);

    int surface_alignment, num_surfaces;

    frames_ctx->format = sctx->pix_fmt;

    /* decoding MPEG-2 requires additional alignment on some Intel GPUs,

    but it causes issues for H.264 on certain AMD GPUs..... */

    if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO)

        surface_alignment = 32;

    /* the HEVC DXVA2 spec asks for 128 pixel aligned surfaces to ensure

    all coding features have enough room to work with */

    else if (avctx->codec_id == AV_CODEC_ID_HEVC)

        surface_alignment = 128;

    else

        surface_alignment = 16;

    /* 4 base work surfaces */

    num_surfaces = 4;

    /* add surfaces based on number of possible refs */

    if (avctx->codec_id == AV_CODEC_ID_H264 || avctx->codec_id == AV_CODEC_ID_HEVC)

        num_surfaces += 16;

    else

        num_surfaces += 2;

    /* add extra surfaces for frame threading */

    if (avctx->active_thread_type & FF_THREAD_FRAME)

        num_surfaces += avctx->thread_count;

    frames_ctx->sw_format = avctx->sw_pix_fmt == AV_PIX_FMT_YUV420P10 ?

                            AV_PIX_FMT_P010 : AV_PIX_FMT_NV12;

    frames_ctx->width = FFALIGN(avctx->coded_width, surface_alignment);

    frames_ctx->height = FFALIGN(avctx->coded_height, surface_alignment);

    frames_ctx->initial_pool_size = num_surfaces;

#if CONFIG_DXVA2

    if (frames_ctx->format == AV_PIX_FMT_DXVA2_VLD) {

        AVDXVA2FramesContext *frames_hwctx = frames_ctx->hwctx;

        frames_hwctx->surface_type = DXVA2_VideoDecoderRenderTarget;

    }

#endif

#if CONFIG_D3D11VA

    if (frames_ctx->format == AV_PIX_FMT_D3D11) {

        AVD3D11VAFramesContext *frames_hwctx = frames_ctx->hwctx;

        frames_hwctx->BindFlags |= D3D11_BIND_DECODER;

    }

#endif

}


USBDevice *usb_msd_init(const char *filename)

{

    MSDState *s;

    BlockDriverState *bdrv;

    BlockDriver *drv = NULL;

    const char *p1;

    char fmt[32];

    p1 = strchr(filename, ':');

    if (p1++) {

        const char *p2;

        if (strstart(filename, "format=", &p2)) {

            int len = MIN(p1 - p2, sizeof(fmt));

            pstrcpy(fmt, len, p2);

            drv = bdrv_find_format(fmt);

            if (!drv) {

                printf("invalid format %s\n", fmt);

                return NULL;

            }

        } else if (*filename != ':') {

            printf("unrecognized USB mass-storage option %s\n", filename);

            return NULL;

        }

        filename = p1;

    }

    if (!*filename) {

        printf("block device specification needed\n");

        return NULL;

    }

    s = qemu_mallocz(sizeof(MSDState));

    bdrv = bdrv_new("usb");

    if (bdrv_open2(bdrv, filename, 0, drv) < 0)

        goto fail;

    if (qemu_key_check(bdrv, filename))

        goto fail;

    s->bs = bdrv;

    s->dev.speed = USB_SPEED_FULL;

    s->dev.handle_packet = usb_generic_handle_packet;

    s->dev.handle_reset = usb_msd_handle_reset;

    s->dev.handle_control = usb_msd_handle_control;

    s->dev.handle_data = usb_msd_handle_data;

    s->dev.handle_destroy = usb_msd_handle_destroy;

    snprintf(s->dev.devname, sizeof(s->dev.devname), "QEMU USB MSD(%.16s)",

             filename);

    s->scsi_dev = scsi_disk_init(bdrv, 0, usb_msd_command_complete, s);

    usb_msd_handle_reset((USBDevice *)s);

    return (USBDevice *)s;

 fail:

    qemu_free(s);

    return NULL;

}


static bool append_open_options(QDict *d, BlockDriverState *bs)

{

    const QDictEntry *entry;

    QemuOptDesc *desc;

    bool found_any = false;

    for (entry = qdict_first(bs->options); entry;

         entry = qdict_next(bs->options, entry))

    {

        /* Only take options for this level */

        if (strchr(qdict_entry_key(entry), '.')) {

            continue;

        }

        /* And exclude all non-driver-specific options */

        for (desc = bdrv_runtime_opts.desc; desc->name; desc++) {

            if (!strcmp(qdict_entry_key(entry), desc->name)) {

                break;

            }

        }

        if (desc->name) {

            continue;

        }

        qobject_incref(qdict_entry_value(entry));

        qdict_put_obj(d, qdict_entry_key(entry), qdict_entry_value(entry));

        found_any = true;

    }

    return found_any;

}


static void gen_eob(DisasContext *s)

{

    gen_eob_inhibit_irq(s, false);

}


hwaddr s390_cpu_get_phys_page_debug(CPUState *cs, vaddr vaddr)

{

    S390CPU *cpu = S390_CPU(cs);

    CPUS390XState *env = &cpu->env;

    target_ulong raddr;

    int prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

    int old_exc = cs->exception_index;

    uint64_t asc = env->psw.mask & PSW_MASK_ASC;

    /* 31-Bit mode */

    if (!(env->psw.mask & PSW_MASK_64)) {

        vaddr &= 0x7fffffff;

    }

    mmu_translate(env, vaddr, 2, asc, &raddr, &prot);

    cs->exception_index = old_exc;

    return raddr;

}


void spapr_drc_detach(sPAPRDRConnector *drc, DeviceState *d, Error **errp)

{

    trace_spapr_drc_detach(spapr_drc_index(drc));

    /* if we've signalled device presence to the guest, or if the guest

     * has gone ahead and configured the device (via manually-executed

     * device add via drmgr in guest, namely), we need to wait

     * for the guest to quiesce the device before completing detach.

     * Otherwise, we can assume the guest hasn't seen it and complete the

     * detach immediately. Note that there is a small race window

     * just before, or during, configuration, which is this context

     * refers mainly to fetching the device tree via RTAS.

     * During this window the device access will be arbitrated by

     * associated DRC, which will simply fail the RTAS calls as invalid.

     * This is recoverable within guest and current implementations of

     * drmgr should be able to cope.

     */

    if (!drc->signalled && !drc->configured) {

        /* if the guest hasn't seen the device we can't rely on it to

         * set it back to an isolated state via RTAS, so do it here manually

         */

        drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED;

    }

    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {

        trace_spapr_drc_awaiting_isolated(spapr_drc_index(drc));

        drc->awaiting_release = true;

        return;

    }

    if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&

        drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {

        trace_spapr_drc_awaiting_unusable(spapr_drc_index(drc));

        drc->awaiting_release = true;

        return;

    }

    if (drc->awaiting_allocation) {

        drc->awaiting_release = true;

        trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));

        return;

    }

    drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE;

    /* Calling release callbacks based on spapr_drc_type(drc). */

    switch (spapr_drc_type(drc)) {

    case SPAPR_DR_CONNECTOR_TYPE_CPU:

        spapr_core_release(drc->dev);

        break;

    case SPAPR_DR_CONNECTOR_TYPE_PCI:

        spapr_phb_remove_pci_device_cb(drc->dev);

        break;

    case SPAPR_DR_CONNECTOR_TYPE_LMB:

        spapr_lmb_release(drc->dev);

        break;

    case SPAPR_DR_CONNECTOR_TYPE_PHB:

    case SPAPR_DR_CONNECTOR_TYPE_VIO:

    default:

        g_assert(false);

    }

    drc->awaiting_release = false;

    g_free(drc->fdt);

    drc->fdt = NULL;

    drc->fdt_start_offset = 0;

    object_property_del(OBJECT(drc), "device", NULL);

    drc->dev = NULL;

}


static XICSState *try_create_xics(const char *type, int nr_servers,

                                  int nr_irqs)

{

    DeviceState *dev;

    dev = qdev_create(NULL, type);

    qdev_prop_set_uint32(dev, "nr_servers", nr_servers);

    qdev_prop_set_uint32(dev, "nr_irqs", nr_irqs);

    if (qdev_init(dev) < 0) {

        return NULL;

    }

    return XICS(dev);

}


static void vhost_user_stop(VhostUserState *s)

{

    if (vhost_user_running(s)) {

        vhost_net_cleanup(s->vhost_net);

    }

    s->vhost_net = 0;

}


static int blk_check_byte_request(BlockBackend *blk, int64_t offset,

                                  size_t size)

{

    int64_t len;

    if (size > INT_MAX) {

        return -EIO;

    }

    if (!blk_is_available(blk)) {

        return -ENOMEDIUM;

    }

    len = blk_getlength(blk);

    if (len < 0) {

        return len;

    }

    if (offset < 0) {

        return -EIO;

    }

    if (offset > len || len - offset < size) {

        return -EIO;

    }

    return 0;

}


static void spr_write_ibatl_h (void *opaque, int sprn)

{

    DisasContext *ctx = opaque;

    gen_op_store_ibatl((sprn - SPR_IBAT4L) / 2);

    RET_STOP(ctx);

}


static int vscsi_queue_cmd(VSCSIState *s, vscsi_req *req)

{

    union srp_iu *srp = &req->iu.srp;

    SCSIDevice *sdev;

    int n, id, lun;

    vscsi_decode_id_lun(be64_to_cpu(srp->cmd.lun), &id, &lun);

    /* Qemu vs. linux issue with LUNs to be sorted out ... */

    sdev = (id < 8 && lun < 16) ? s->bus.devs[id] : NULL;

    if (!sdev) {

        dprintf("VSCSI: Command for id %d with no drive\n", id);

        if (srp->cmd.cdb[0] == INQUIRY) {

            vscsi_inquiry_no_target(s, req);

        } else {

            vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0x00);

            vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);

        } return 1;

    }

    req->lun = lun;

    req->sreq = scsi_req_new(sdev, req->qtag, lun, req);

    n = scsi_req_enqueue(req->sreq, srp->cmd.cdb);

    dprintf("VSCSI: Queued command tag 0x%x CMD 0x%x ID %d LUN %d ret: %d\n",

            req->qtag, srp->cmd.cdb[0], id, lun, n);

    if (n) {

        /* Transfer direction must be set before preprocessing the

         * descriptors

         */

        req->writing = (n < 1);

        /* Preprocess RDMA descriptors */

        vscsi_preprocess_desc(req);

        /* Get transfer direction and initiate transfer */

        if (n > 0) {

            req->data_len = n;

        } else if (n < 0) {

            req->data_len = -n;

        }

        scsi_req_continue(req->sreq);

    }

    /* Don't touch req here, it may have been recycled already */

    return 0;

}


int coroutine_fn laio_co_submit(BlockDriverState *bs, LinuxAioState *s, int fd,

                                uint64_t offset, QEMUIOVector *qiov, int type)

{

    int ret;

    struct qemu_laiocb laiocb = {

        .co         = qemu_coroutine_self(),

        .nbytes     = qiov->size,

        .ctx        = s,

        .is_read    = (type == QEMU_AIO_READ),

        .qiov       = qiov,

    };

    ret = laio_do_submit(fd, &laiocb, offset, type);

    if (ret < 0) {

        return ret;

    }

    qemu_coroutine_yield();

    return laiocb.ret;

}


static void balloon_stats_poll_cb(void *opaque)

{

    VirtIOBalloon *s = opaque;

    VirtIODevice *vdev = VIRTIO_DEVICE(s);

    if (!balloon_stats_supported(s)) {

        /* re-schedule */

        balloon_stats_change_timer(s, s->stats_poll_interval);

        return;

    }

    virtqueue_push(s->svq, &s->stats_vq_elem, s->stats_vq_offset);

    virtio_notify(vdev, s->svq);

}


static void pxa2xx_mm_write(void *opaque, hwaddr addr,

                            uint64_t value, unsigned size)

{

    PXA2xxState *s = (PXA2xxState *) opaque;

    switch (addr) {

    case MDCNFG ... SA1110:

        if ((addr & 3) == 0) {

            s->mm_regs[addr >> 2] = value;

            break;

        }

    default:

        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);

        break;

    }

}


static void omap_l4_io_writeh(void *opaque, target_phys_addr_t addr,

                uint32_t value)

{

    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;

    return omap_l4_io_writeh_fn[i](omap_l4_io_opaque[i], addr, value);

}


BlockBackend *blk_new_open(const char *filename, const char *reference,

                           QDict *options, int flags, Error **errp)

{

    BlockBackend *blk;

    BlockDriverState *bs;

    uint64_t perm;

    /* blk_new_open() is mainly used in .bdrv_create implementations and the

     * tools where sharing isn't a concern because the BDS stays private, so we

     * just request permission according to the flags.

     *

     * The exceptions are xen_disk and blockdev_init(); in these cases, the

     * caller of blk_new_open() doesn't make use of the permissions, but they

     * shouldn't hurt either. We can still share everything here because the

     * guest devices will add their own blockers if they can't share. */

    perm = BLK_PERM_CONSISTENT_READ;

    if (flags & BDRV_O_RDWR) {

        perm |= BLK_PERM_WRITE;

    }

    if (flags & BDRV_O_RESIZE) {

        perm |= BLK_PERM_RESIZE;

    }

    blk = blk_new(perm, BLK_PERM_ALL);

    bs = bdrv_open(filename, reference, options, flags, errp);

    if (!bs) {

        blk_unref(blk);

        return NULL;

    }

    blk->root = bdrv_root_attach_child(bs, "root", &child_root,

                                       perm, BLK_PERM_ALL, blk, errp);

    if (!blk->root) {

        bdrv_unref(bs);

        blk_unref(blk);

        return NULL;

    }

    return blk;

}


static int mpc_probe(AVProbeData *p)

{

    const uint8_t *d = p->buf;

    if (p->buf_size < 32)

        return 0;

    if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))

        return AVPROBE_SCORE_MAX;

    if (d[0] == 'I' && d[1] == 'D' && d[2] == '3')

        return AVPROBE_SCORE_MAX / 2;

    return 0;

}


av_cold void ff_hpeldsp_init_x86(HpelDSPContext *c, int flags)

{

    int cpu_flags = av_get_cpu_flags();

    if (INLINE_MMX(cpu_flags))

        hpeldsp_init_mmx(c, flags);

    if (EXTERNAL_AMD3DNOW(cpu_flags))

        hpeldsp_init_3dnow(c, flags);

    if (EXTERNAL_MMXEXT(cpu_flags))

        hpeldsp_init_mmxext(c, flags);

    if (EXTERNAL_SSE2_FAST(cpu_flags))

        hpeldsp_init_sse2_fast(c, flags);

    if (CONFIG_VP3_DECODER)

        ff_hpeldsp_vp3_init_x86(c, cpu_flags, flags);

}


static int guess_ni_flag(AVFormatContext *s)

{

    int i;

    int64_t last_start = 0;

    int64_t first_end  = INT64_MAX;

    int64_t oldpos     = avio_tell(s->pb);

    int *idx;

    int64_t min_pos, pos;

    for (i = 0; i < s->nb_streams; i++) {

        AVStream *st = s->streams[i];

        int n        = st->nb_index_entries;

        unsigned int size;

        if (n <= 0)

            continue;

        if (n >= 2) {

            int64_t pos = st->index_entries[0].pos;

            avio_seek(s->pb, pos + 4, SEEK_SET);

            size = avio_rl32(s->pb);

            if (pos + size > st->index_entries[1].pos)

                last_start = INT64_MAX;

        }

        if (st->index_entries[0].pos > last_start)

            last_start = st->index_entries[0].pos;

        if (st->index_entries[n - 1].pos < first_end)

            first_end = st->index_entries[n - 1].pos;

    }

    avio_seek(s->pb, oldpos, SEEK_SET);

    if (last_start > first_end)

        return 1;

    idx= av_calloc(s->nb_streams, sizeof(*idx));

    if (!idx)

        return 0;

    for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) {

        int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2;

        min_pos = INT64_MAX;

        for (i=0; i<s->nb_streams; i++) {

            AVStream *st = s->streams[i];

            AVIStream *ast = st->priv_data;

            int n= st->nb_index_entries;

            while (idx[i]<n && st->index_entries[idx[i]].pos < pos)

                idx[i]++;

            if (idx[i] < n) {

                min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));

                min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);

            }

            if (idx[i])

                max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q));

        }

        if (max_dts - min_dts > 2*AV_TIME_BASE) {

            av_free(idx);

            return 1;

        }

    }

    av_free(idx);

    return 0;

}


int av_opencl_buffer_read_image(uint8_t **dst_data, int *plane_size, int plane_num,

                                       cl_mem src_cl_buf, size_t cl_buffer_size)

{

    int i,buffer_size = 0,ret = 0;

    uint8_t *temp;

    void *mapped;

    cl_int status;

    if ((unsigned int)plane_num > 8) {

        return AVERROR(EINVAL);

    }

    for (i = 0;i < plane_num;i++) {

        buffer_size += plane_size[i];

    }

    if (buffer_size > cl_buffer_size) {

        av_log(&openclutils, AV_LOG_ERROR, "Cannot write image to CPU buffer: OpenCL buffer too small\n");

        return AVERROR(EINVAL);

    }

    mapped = clEnqueueMapBuffer(gpu_env.command_queue, src_cl_buf,

                                      CL_TRUE,CL_MAP_READ, 0, buffer_size,

                                      0, NULL, NULL, &status);

    if (status != CL_SUCCESS) {

        av_log(&openclutils, AV_LOG_ERROR, "Could not map OpenCL buffer: %s\n", opencl_errstr(status));

        return AVERROR_EXTERNAL;

    }

    temp = mapped;

    if (ret >= 0) {

        for (i = 0;i < plane_num;i++) {

            memcpy(dst_data[i], temp, plane_size[i]);

            temp += plane_size[i];

        }

    }

    status = clEnqueueUnmapMemObject(gpu_env.command_queue, src_cl_buf, mapped, 0, NULL, NULL);

    if (status != CL_SUCCESS) {

        av_log(&openclutils, AV_LOG_ERROR, "Could not unmap OpenCL buffer: %s\n", opencl_errstr(status));

        return AVERROR_EXTERNAL;

    }

    return 0;

}


static void rtsp_cmd_describe(HTTPContext *c, const char *url)

{

    FFStream *stream;

    char path1[1024];

    const char *path;

    uint8_t *content;

    int content_length, len;

    struct sockaddr_in my_addr;

    /* find which url is asked */

    url_split(NULL, 0, NULL, 0, NULL, path1, sizeof(path1), url);

    path = path1;

    if (*path == '/')

        path++;

    for(stream = first_stream; stream != NULL; stream = stream->next) {

        if (!stream->is_feed && stream->fmt == &rtp_mux &&

            !strcmp(path, stream->filename)) {

            goto found;

        }

    }

    /* no stream found */

    rtsp_reply_error(c, RTSP_STATUS_SERVICE); /* XXX: right error ? */

    return;

 found:

    /* prepare the media description in sdp format */

    /* get the host IP */

    len = sizeof(my_addr);

    getsockname(c->fd, (struct sockaddr *)&my_addr, &len);

    content_length = prepare_sdp_description(stream, &content, my_addr.sin_addr);

    if (content_length < 0) {

        rtsp_reply_error(c, RTSP_STATUS_INTERNAL);

        return;

    }

    rtsp_reply_header(c, RTSP_STATUS_OK);

    url_fprintf(c->pb, "Content-Type: application/sdp\r\n");

    url_fprintf(c->pb, "Content-Length: %d\r\n", content_length);

    url_fprintf(c->pb, "\r\n");

    put_buffer(c->pb, content, content_length);

}


static char *shorts2str(int *sp, int count, const char *sep)

{

    int i;

    char *ap, *ap0;

    if (!sep) sep = ", ";

    ap = av_malloc((5 + strlen(sep)) * count);

    if (!ap)

        return NULL;

    ap0   = ap;

    ap[0] = '\0';

    for (i = 0; i < count; i++) {

        int l = snprintf(ap, 5 + strlen(sep), "%d%s", sp[i], sep);

        ap += l;

    }

    ap0[strlen(ap0) - strlen(sep)] = '\0';

    return ap0;

}


uint64_t blk_mig_bytes_transferred(void)

{

    BlkMigDevState *bmds;

    uint64_t sum = 0;

    blk_mig_lock();

    QSIMPLEQ_FOREACH(bmds, &block_mig_state.bmds_list, entry) {

        sum += bmds->completed_sectors;

    }

    blk_mig_unlock();

    return sum << BDRV_SECTOR_BITS;

}


void palette8torgb16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)

{

	long i;

	for(i=0; i<num_pixels; i++)

		((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ];

}


RTCState *rtc_init(int base_year)

{

    ISADevice *dev;

    dev = isa_create("mc146818rtc");

    qdev_prop_set_int32(&dev->qdev, "base_year", base_year);

    qdev_init(&dev->qdev);

    return DO_UPCAST(RTCState, dev, dev);

}


static int headroom(int *la)

{

    int l;

    if (*la == 0) {

        return 31;

    }

    l = 30 - av_log2(FFABS(*la));

    *la <<= l;

    return l;

}


static int decode_nal_unit(HEVCContext *s, const uint8_t *nal, int length)
{
    HEVCLocalContext *lc = &s->HEVClc;
    GetBitContext *gb    = &lc->gb;
    int ctb_addr_ts, ret;
    ret = init_get_bits8(gb, nal, length);
    if (ret < 0)
        return ret;
    ret = hls_nal_unit(s);
    if (ret < 0) {
        av_log(s->avctx, AV_LOG_ERROR, "Invalid NAL unit %d, skipping.\n",
               s->nal_unit_type);
        if (s->avctx->err_recognition & AV_EF_EXPLODE)
            return ret;
        return 0;
    } else if (!ret)
        return 0;
    switch (s->nal_unit_type) {
    case NAL_VPS:
        ret = ff_hevc_decode_nal_vps(s);
        if (ret < 0)
            return ret;
        break;
    case NAL_SPS:
        ret = ff_hevc_decode_nal_sps(s);
        if (ret < 0)
            return ret;
        break;
    case NAL_PPS:
        ret = ff_hevc_decode_nal_pps(s);
        if (ret < 0)
            return ret;
        break;
    case NAL_SEI_PREFIX:
    case NAL_SEI_SUFFIX:
        ret = ff_hevc_decode_nal_sei(s);
        if (ret < 0)
            return ret;
        break;
    case NAL_TRAIL_R:
    case NAL_TRAIL_N:
    case NAL_TSA_N:
    case NAL_TSA_R:
    case NAL_STSA_N:
    case NAL_STSA_R:
    case NAL_BLA_W_LP:
    case NAL_BLA_W_RADL:
    case NAL_BLA_N_LP:
    case NAL_IDR_W_RADL:
    case NAL_IDR_N_LP:
    case NAL_CRA_NUT:
    case NAL_RADL_N:
    case NAL_RADL_R:
    case NAL_RASL_N:
    case NAL_RASL_R:
        ret = hls_slice_header(s);
        if (ret < 0)
            return ret;
        if (s->max_ra == INT_MAX) {
            if (s->nal_unit_type == NAL_CRA_NUT || IS_BLA(s)) {
                s->max_ra = s->poc;
            } else {
                if (IS_IDR(s))
                    s->max_ra = INT_MIN;
        if ((s->nal_unit_type == NAL_RASL_R || s->nal_unit_type == NAL_RASL_N) &&
            s->poc <= s->max_ra) {
            s->is_decoded = 0;
            break;
        } else {
            if (s->nal_unit_type == NAL_RASL_R && s->poc > s->max_ra)
                s->max_ra = INT_MIN;
        if (s->sh.first_slice_in_pic_flag) {
            ret = hevc_frame_start(s);
            if (ret < 0)
                return ret;
        } else if (!s->ref) {
            av_log(s->avctx, AV_LOG_ERROR, "First slice in a frame missing.\n");
        if (!s->sh.dependent_slice_segment_flag &&
            s->sh.slice_type != I_SLICE) {
            ret = ff_hevc_slice_rpl(s);
            if (ret < 0) {
                av_log(s->avctx, AV_LOG_WARNING,
                       "Error constructing the reference lists for the current slice.\n");
                if (s->avctx->err_recognition & AV_EF_EXPLODE)
                    return ret;
        ctb_addr_ts = hls_slice_data(s);
        if (ctb_addr_ts >= (s->sps->ctb_width * s->sps->ctb_height)) {
            s->is_decoded = 1;
            if ((s->pps->transquant_bypass_enable_flag ||
                 (s->sps->pcm.loop_filter_disable_flag && s->sps->pcm_enabled_flag)) &&
                s->sps->sao_enabled)
                restore_tqb_pixels(s);
        if (ctb_addr_ts < 0)
            return ctb_addr_ts;
        break;
    case NAL_EOS_NUT:
    case NAL_EOB_NUT:
        s->seq_decode = (s->seq_decode + 1) & 0xff;
        s->max_ra     = INT_MAX;
        break;
    case NAL_AUD:
    case NAL_FD_NUT:
        break;
    default:
        av_log(s->avctx, AV_LOG_INFO,
               "Skipping NAL unit %d\n", s->nal_unit_type);
    return 0;


static void xen_read_physmap(XenIOState *state)

{

    XenPhysmap *physmap = NULL;

    unsigned int len, num, i;

    char path[80], *value = NULL;

    char **entries = NULL;

    snprintf(path, sizeof(path),

            "/local/domain/0/device-model/%d/physmap", xen_domid);

    entries = xs_directory(state->xenstore, 0, path, &num);

    if (entries == NULL)

        return;

    for (i = 0; i < num; i++) {

        physmap = g_malloc(sizeof (XenPhysmap));

        physmap->phys_offset = strtoull(entries[i], NULL, 16);

        snprintf(path, sizeof(path),

                "/local/domain/0/device-model/%d/physmap/%s/start_addr",

                xen_domid, entries[i]);

        value = xs_read(state->xenstore, 0, path, &len);

        if (value == NULL) {

            free(physmap);

            continue;

        }

        physmap->start_addr = strtoull(value, NULL, 16);

        free(value);

        snprintf(path, sizeof(path),

                "/local/domain/0/device-model/%d/physmap/%s/size",

                xen_domid, entries[i]);

        value = xs_read(state->xenstore, 0, path, &len);

        if (value == NULL) {

            free(physmap);

            continue;

        }

        physmap->size = strtoull(value, NULL, 16);

        free(value);

        snprintf(path, sizeof(path),

                "/local/domain/0/device-model/%d/physmap/%s/name",

                xen_domid, entries[i]);

        physmap->name = xs_read(state->xenstore, 0, path, &len);

        QLIST_INSERT_HEAD(&state->physmap, physmap, list);

    }

    free(entries);

}


static int img_map(int argc, char **argv)

{

    int c;

    OutputFormat output_format = OFORMAT_HUMAN;

    BlockBackend *blk;

    BlockDriverState *bs;

    const char *filename, *fmt, *output;

    int64_t length;

    MapEntry curr = { .length = 0 }, next;

    int ret = 0;

    bool image_opts = false;

    fmt = NULL;

    output = NULL;

    for (;;) {

        int option_index = 0;

        static const struct option long_options[] = {

            {"help", no_argument, 0, 'h'},

            {"format", required_argument, 0, 'f'},

            {"output", required_argument, 0, OPTION_OUTPUT},

            {"object", required_argument, 0, OPTION_OBJECT},

            {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},

            {0, 0, 0, 0}

        };

        c = getopt_long(argc, argv, "f:h",

                        long_options, &option_index);

        if (c == -1) {

            break;

        }

        switch (c) {

        case '?':

        case 'h':

            help();

            break;

        case 'f':

            fmt = optarg;

            break;

        case OPTION_OUTPUT:

            output = optarg;

            break;

        case OPTION_OBJECT: {

            QemuOpts *opts;

            opts = qemu_opts_parse_noisily(&qemu_object_opts,

                                           optarg, true);

            if (!opts) {

                return 1;

            }

        }   break;

        case OPTION_IMAGE_OPTS:

            image_opts = true;

            break;

        }

    }

    if (optind != argc - 1) {

        error_exit("Expecting one image file name");

    }

    filename = argv[optind];

    if (output && !strcmp(output, "json")) {

        output_format = OFORMAT_JSON;

    } else if (output && !strcmp(output, "human")) {

        output_format = OFORMAT_HUMAN;

    } else if (output) {

        error_report("--output must be used with human or json as argument.");

        return 1;

    }

    if (qemu_opts_foreach(&qemu_object_opts,

                          user_creatable_add_opts_foreach,

                          NULL, NULL)) {

        return 1;

    }

    blk = img_open(image_opts, filename, fmt, 0, false, false);

    if (!blk) {

        return 1;

    }

    bs = blk_bs(blk);

    if (output_format == OFORMAT_HUMAN) {

        printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");

    }

    length = blk_getlength(blk);

    while (curr.start + curr.length < length) {

        int64_t nsectors_left;

        int64_t sector_num;

        int n;

        sector_num = (curr.start + curr.length) >> BDRV_SECTOR_BITS;

        /* Probe up to 1 GiB at a time.  */

        nsectors_left = DIV_ROUND_UP(length, BDRV_SECTOR_SIZE) - sector_num;

        n = MIN(1 << (30 - BDRV_SECTOR_BITS), nsectors_left);

        ret = get_block_status(bs, sector_num, n, &next);

        if (ret < 0) {

            error_report("Could not read file metadata: %s", strerror(-ret));

            goto out;

        }

        if (entry_mergeable(&curr, &next)) {

            curr.length += next.length;

            continue;

        }

        if (curr.length > 0) {

            dump_map_entry(output_format, &curr, &next);

        }

        curr = next;

    }

    dump_map_entry(output_format, &curr, NULL);

out:

    blk_unref(blk);

    return ret < 0;

}


static int jpeg_read_close(AVFormatContext *s1)

{

    JpegContext *s = s1->priv_data;

    av_free(s);

    return 0;

}


static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,

        BlockDriverState *base,

        int64_t sector_num,

        int nb_sectors,

        int *pnum,

        BlockDriverState **file)

{

    BlockDriverState *p;

    int64_t ret = 0;

    assert(bs != base);

    for (p = bs; p != base; p = backing_bs(p)) {

        ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum, file);

        if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) {

            break;

        }

        /* [sector_num, pnum] unallocated on this layer, which could be only

         * the first part of [sector_num, nb_sectors].  */

        nb_sectors = MIN(nb_sectors, *pnum);

    }

    return ret;

}


static av_cold int psy_3gpp_init(FFPsyContext *ctx) {

    AacPsyContext *pctx;

    float bark;

    int i, j, g, start;

    float prev, minscale, minath, minsnr, pe_min;

    int chan_bitrate = ctx->avctx->bit_rate / ((ctx->avctx->flags & CODEC_FLAG_QSCALE) ? 2.0f : ctx->avctx->channels);

    const int bandwidth    = ctx->avctx->cutoff ? ctx->avctx->cutoff : AAC_CUTOFF(ctx->avctx);

    const float num_bark   = calc_bark((float)bandwidth);

    ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext));

    if (!ctx->model_priv_data)

        return AVERROR(ENOMEM);

    pctx = (AacPsyContext*) ctx->model_priv_data;

    pctx->global_quality = (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120) * 0.01f;

    if (ctx->avctx->flags & CODEC_FLAG_QSCALE) {

        /* Use the target average bitrate to compute spread parameters */

        chan_bitrate = (int)(chan_bitrate / 120.0 * (ctx->avctx->global_quality ? ctx->avctx->global_quality : 120));

    }

    pctx->chan_bitrate = chan_bitrate;

    pctx->frame_bits   = FFMIN(2560, chan_bitrate * AAC_BLOCK_SIZE_LONG / ctx->avctx->sample_rate);

    pctx->pe.min       =  8.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);

    pctx->pe.max       = 12.0f * AAC_BLOCK_SIZE_LONG * bandwidth / (ctx->avctx->sample_rate * 2.0f);

    ctx->bitres.size   = 6144 - pctx->frame_bits;

    ctx->bitres.size  -= ctx->bitres.size % 8;

    pctx->fill_level   = ctx->bitres.size;

    minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD);

    for (j = 0; j < 2; j++) {

        AacPsyCoeffs *coeffs = pctx->psy_coef[j];

        const uint8_t *band_sizes = ctx->bands[j];

        float line_to_frequency = ctx->avctx->sample_rate / (j ? 256.f : 2048.0f);

        float avg_chan_bits = chan_bitrate * (j ? 128.0f : 1024.0f) / ctx->avctx->sample_rate;

        /* reference encoder uses 2.4% here instead of 60% like the spec says */

        float bark_pe = 0.024f * PSY_3GPP_BITS_TO_PE(avg_chan_bits) / num_bark;

        float en_spread_low = j ? PSY_3GPP_EN_SPREAD_LOW_S : PSY_3GPP_EN_SPREAD_LOW_L;

        /* High energy spreading for long blocks <= 22kbps/channel and short blocks are the same. */

        float en_spread_hi  = (j || (chan_bitrate <= 22.0f)) ? PSY_3GPP_EN_SPREAD_HI_S : PSY_3GPP_EN_SPREAD_HI_L1;

        i = 0;

        prev = 0.0;

        for (g = 0; g < ctx->num_bands[j]; g++) {

            i += band_sizes[g];

            bark = calc_bark((i-1) * line_to_frequency);

            coeffs[g].barks = (bark + prev) / 2.0;

            prev = bark;

        }

        for (g = 0; g < ctx->num_bands[j] - 1; g++) {

            AacPsyCoeffs *coeff = &coeffs[g];

            float bark_width = coeffs[g+1].barks - coeffs->barks;

            coeff->spread_low[0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_LOW);

            coeff->spread_hi [0] = pow(10.0, -bark_width * PSY_3GPP_THR_SPREAD_HI);

            coeff->spread_low[1] = pow(10.0, -bark_width * en_spread_low);

            coeff->spread_hi [1] = pow(10.0, -bark_width * en_spread_hi);

            pe_min = bark_pe * bark_width;

            minsnr = exp2(pe_min / band_sizes[g]) - 1.5f;

            coeff->min_snr = av_clipf(1.0f / minsnr, PSY_SNR_25DB, PSY_SNR_1DB);

        }

        start = 0;

        for (g = 0; g < ctx->num_bands[j]; g++) {

            minscale = ath(start * line_to_frequency, ATH_ADD);

            for (i = 1; i < band_sizes[g]; i++)

                minscale = FFMIN(minscale, ath((start + i) * line_to_frequency, ATH_ADD));

            coeffs[g].ath = minscale - minath;

            start += band_sizes[g];

        }

    }

    pctx->ch = av_mallocz_array(ctx->avctx->channels, sizeof(AacPsyChannel));

    if (!pctx->ch) {

        av_freep(&ctx->model_priv_data);

        return AVERROR(ENOMEM);

    }

    lame_window_init(pctx, ctx->avctx);

    return 0;

}