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

                     Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    int len, i, shift, ret;

    QCowHeader header;

    ret = bdrv_pread(bs->file, 0, &header, sizeof(header));

    if (ret < 0) {

        goto fail;

    }

    be32_to_cpus(&header.magic);

    be32_to_cpus(&header.version);

    be64_to_cpus(&header.backing_file_offset);

    be32_to_cpus(&header.backing_file_size);

    be32_to_cpus(&header.mtime);

    be64_to_cpus(&header.size);

    be32_to_cpus(&header.crypt_method);

    be64_to_cpus(&header.l1_table_offset);

    if (header.magic != QCOW_MAGIC) {

        error_setg(errp, "Image not in qcow format");

        ret = -EINVAL;

        goto fail;

    }

    if (header.version != QCOW_VERSION) {

        char version[64];

        snprintf(version, sizeof(version), "QCOW version %" PRIu32,

                 header.version);

        error_set(errp, QERR_UNKNOWN_BLOCK_FORMAT_FEATURE,

                  bs->device_name, "qcow", version);

        ret = -ENOTSUP;

        goto fail;

    }

    if (header.size <= 1) {

        error_setg(errp, "Image size is too small (must be at least 2 bytes)");

        ret = -EINVAL;

        goto fail;

    }

    if (header.cluster_bits < 9 || header.cluster_bits > 16) {

        error_setg(errp, "Cluster size must be between 512 and 64k");

        ret = -EINVAL;

        goto fail;

    }

    /* l2_bits specifies number of entries; storing a uint64_t in each entry,

     * so bytes = num_entries << 3. */

    if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) {

        error_setg(errp, "L2 table size must be between 512 and 64k");

        ret = -EINVAL;

        goto fail;

    }

    if (header.crypt_method > QCOW_CRYPT_AES) {

        error_setg(errp, "invalid encryption method in qcow header");

        ret = -EINVAL;

        goto fail;

    }

    s->crypt_method_header = header.crypt_method;

    if (s->crypt_method_header) {

        bs->encrypted = 1;

    }

    s->cluster_bits = header.cluster_bits;

    s->cluster_size = 1 << s->cluster_bits;

    s->cluster_sectors = 1 << (s->cluster_bits - 9);

    s->l2_bits = header.l2_bits;

    s->l2_size = 1 << s->l2_bits;

    bs->total_sectors = header.size / 512;

    s->cluster_offset_mask = (1LL << (63 - s->cluster_bits)) - 1;

    /* read the level 1 table */

    shift = s->cluster_bits + s->l2_bits;

    if (header.size > UINT64_MAX - (1LL << shift)) {

        error_setg(errp, "Image too large");

        ret = -EINVAL;

        goto fail;

    } else {

        uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift;

        if (l1_size > INT_MAX / sizeof(uint64_t)) {

            error_setg(errp, "Image too large");

            ret = -EINVAL;

            goto fail;

        }

        s->l1_size = l1_size;

    }

    s->l1_table_offset = header.l1_table_offset;

    s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t));

    ret = bdrv_pread(bs->file, s->l1_table_offset, s->l1_table,

               s->l1_size * sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }

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

        be64_to_cpus(&s->l1_table[i]);

    }

    /* alloc L2 cache */

    s->l2_cache = g_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint64_t));

    s->cluster_cache = g_malloc(s->cluster_size);

    s->cluster_data = g_malloc(s->cluster_size);

    s->cluster_cache_offset = -1;

    /* read the backing file name */

    if (header.backing_file_offset != 0) {

        len = header.backing_file_size;

        if (len > 1023) {

            len = 1023;

        }

        ret = bdrv_pread(bs->file, header.backing_file_offset,

                   bs->backing_file, len);

        if (ret < 0) {

            goto fail;

        }

        bs->backing_file[len] = '\0';

    }

    /* Disable migration when qcow images are used */

    error_set(&s->migration_blocker,

              QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,

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

    migrate_add_blocker(s->migration_blocker);

    qemu_co_mutex_init(&s->lock);

    return 0;

 fail:

    g_free(s->l1_table);

    g_free(s->l2_cache);

    g_free(s->cluster_cache);

    g_free(s->cluster_data);

    return ret;

}


static AVFilterBufferRef *copy_buffer_ref(AVFilterContext *ctx,

                                          AVFilterBufferRef *ref)

{

    AVFilterLink *outlink = ctx->outputs[0];

    AVFilterBufferRef *buf;

    int channels, data_size, i;

    switch (outlink->type) {

    case AVMEDIA_TYPE_VIDEO:

        buf = avfilter_get_video_buffer(outlink, AV_PERM_WRITE,

                                        ref->video->w, ref->video->h);

        av_image_copy(buf->data, buf->linesize,

                      (void*)ref->data, ref->linesize,

                      ref->format, ref->video->w, ref->video->h);

        break;

    case AVMEDIA_TYPE_AUDIO:

        buf = ff_get_audio_buffer(outlink, AV_PERM_WRITE,

                                        ref->audio->nb_samples);

        channels = av_get_channel_layout_nb_channels(ref->audio->channel_layout);

        av_samples_copy(buf->extended_data, ref->buf->extended_data,

                        0, 0, ref->audio->nb_samples,

                        channels,

                        ref->format);

        break;

    default:

    }

    avfilter_copy_buffer_ref_props(buf, ref);

    return buf;

}


void qmp_block_commit(const char *device,

                      bool has_base, const char *base, const char *top,

                      bool has_speed, int64_t speed,

                      Error **errp)

{

    BlockDriverState *bs;

    BlockDriverState *base_bs, *top_bs;

    Error *local_err = NULL;

    /* This will be part of the QMP command, if/when the

     * BlockdevOnError change for blkmirror makes it in

     */

    BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;

    /* drain all i/o before commits */

    bdrv_drain_all();

    bs = bdrv_find(device);

    if (!bs) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

    if (base && has_base) {

        base_bs = bdrv_find_backing_image(bs, base);

    } else {

        base_bs = bdrv_find_base(bs);

    }

    if (base_bs == NULL) {

        error_set(errp, QERR_BASE_NOT_FOUND, base ? base : "NULL");

        return;

    }

    /* default top_bs is the active layer */

    top_bs = bs;

    if (top) {

        if (strcmp(bs->filename, top) != 0) {

            top_bs = bdrv_find_backing_image(bs, top);

        }

    }

    if (top_bs == NULL) {

        error_setg(errp, "Top image file %s not found", top ? top : "NULL");

        return;

    }

    commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,

                &local_err);

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        return;

    }

    /* Grab a reference so hotplug does not delete the BlockDriverState from

     * underneath us.

     */

    drive_get_ref(drive_get_by_blockdev(bs));

}


static int mkv_check_tag(AVDictionary *m)

{

    AVDictionaryEntry *t = NULL;

    while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))

        if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode"))

            return 1;

    return 0;

}


int ff_h2645_extract_rbsp(const uint8_t *src, int length,

                          H2645NAL *nal)

{

    int i, si, di;

    uint8_t *dst;

    nal->skipped_bytes = 0;

#define STARTCODE_TEST                                                  \

        if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) {     \

            if (src[i + 2] != 3 && src[i + 2] != 0) {                   \

                /* startcode, so we must be past the end */             \

                length = i;                                             \

            }                                                           \

            break;                                                      \

        }

#if HAVE_FAST_UNALIGNED

#define FIND_FIRST_ZERO                                                 \

        if (i > 0 && !src[i])                                           \

            i--;                                                        \

        while (src[i])                                                  \

            i++

#if HAVE_FAST_64BIT

    for (i = 0; i + 1 < length; i += 9) {

        if (!((~AV_RN64A(src + i) &

               (AV_RN64A(src + i) - 0x0100010001000101ULL)) &

              0x8000800080008080ULL))

            continue;

        FIND_FIRST_ZERO;

        STARTCODE_TEST;

        i -= 7;

    }

#else

    for (i = 0; i + 1 < length; i += 5) {

        if (!((~AV_RN32A(src + i) &

               (AV_RN32A(src + i) - 0x01000101U)) &

              0x80008080U))

            continue;

        FIND_FIRST_ZERO;

        STARTCODE_TEST;

        i -= 3;

    }

#endif /* HAVE_FAST_64BIT */

#else

    for (i = 0; i + 1 < length; i += 2) {

        if (src[i])

            continue;

        if (i > 0 && src[i - 1] == 0)

            i--;

        STARTCODE_TEST;

    }

#endif /* HAVE_FAST_UNALIGNED */

    if (i >= length - 1) { // no escaped 0

        nal->data     =

        nal->raw_data = src;

        nal->size     =

        nal->raw_size = length;

        return length;

    }

    av_fast_malloc(&nal->rbsp_buffer, &nal->rbsp_buffer_size,

                   length + AV_INPUT_BUFFER_PADDING_SIZE);

    if (!nal->rbsp_buffer)

        return AVERROR(ENOMEM);

    dst = nal->rbsp_buffer;

    memcpy(dst, src, i);

    si = di = i;

    while (si + 2 < length) {

        // remove escapes (very rare 1:2^22)

        if (src[si + 2] > 3) {

            dst[di++] = src[si++];

            dst[di++] = src[si++];

        } else if (src[si] == 0 && src[si + 1] == 0 && src[si + 2] != 0) {

            if (src[si + 2] == 3) { // escape

                dst[di++] = 0;

                dst[di++] = 0;

                si       += 3;

                if (nal->skipped_bytes_pos) {

                    nal->skipped_bytes++;

                    if (nal->skipped_bytes_pos_size < nal->skipped_bytes) {

                        nal->skipped_bytes_pos_size *= 2;

                        av_assert0(nal->skipped_bytes_pos_size >= nal->skipped_bytes);

                        av_reallocp_array(&nal->skipped_bytes_pos,

                                nal->skipped_bytes_pos_size,

                                sizeof(*nal->skipped_bytes_pos));

                        if (!nal->skipped_bytes_pos) {

                            nal->skipped_bytes_pos_size = 0;

                            return AVERROR(ENOMEM);

                        }

                    }

                    if (nal->skipped_bytes_pos)

                        nal->skipped_bytes_pos[nal->skipped_bytes-1] = di - 1;

                }

                continue;

            } else // next start code

                goto nsc;

        }

        dst[di++] = src[si++];

    }

    while (si < length)

        dst[di++] = src[si++];

nsc:

    memset(dst + di, 0, AV_INPUT_BUFFER_PADDING_SIZE);

    nal->data = dst;

    nal->size = di;

    nal->raw_data = src;

    nal->raw_size = si;

    return si;

}


static int encode_mode(CinepakEncContext *s, CinepakMode mode, int h, int v1_size, int v4_size, int v4, AVPicture *scratch_pict, strip_info *info, unsigned char *buf)

{

    int x, y, z, flags, bits, temp_size, header_ofs, ret = 0, mb_count = s->w * h / MB_AREA;

    int needs_extra_bit, should_write_temp;

    unsigned char temp[64]; //32/2 = 16 V4 blocks at 4 B each -> 64 B

    mb_info *mb;

    AVPicture sub_scratch;

    //encode codebooks

    if(v1_size)

        ret += encode_codebook(s, info->v1_codebook, v1_size, 0x22, 0x26, buf + ret);

    if(v4_size)

        ret += encode_codebook(s, info->v4_codebook, v4_size, 0x20, 0x24, buf + ret);

    //update scratch picture

    for(z = y = 0; y < h; y += MB_SIZE) {

        for(x = 0; x < s->w; x += MB_SIZE, z++) {

            mb = &s->mb[z];

            if(mode == MODE_MC && mb->best_encoding == ENC_SKIP)

                continue;

            get_sub_picture(s, x, y, scratch_pict, &sub_scratch);

            if(mode == MODE_V1_ONLY || mb->best_encoding == ENC_V1)

                decode_v1_vector(s, &sub_scratch, mb, info);

            else if(mode != MODE_V1_ONLY && mb->best_encoding == ENC_V4)

                decode_v4_vector(s, &sub_scratch, mb->v4_vector[v4], info);

        }

    }

    switch(mode) {

    case MODE_V1_ONLY:

        //av_log(s->avctx, AV_LOG_INFO, "mb_count = %i\n", mb_count);

        ret += write_chunk_header(buf + ret, 0x32, mb_count);

        for(x = 0; x < mb_count; x++)

            buf[ret++] = s->mb[x].v1_vector;

        break;

    case MODE_V1_V4:

        //remember header position

        header_ofs = ret;

        ret += CHUNK_HEADER_SIZE;

        for(x = 0; x < mb_count; x += 32) {

            flags = 0;

            for(y = x; y < FFMIN(x+32, mb_count); y++)

                if(s->mb[y].best_encoding == ENC_V4)

                    flags |= 1 << (31 - y + x);

            AV_WB32(&buf[ret], flags);

            ret += 4;

            for(y = x; y < FFMIN(x+32, mb_count); y++) {

                mb = &s->mb[y];

                if(mb->best_encoding == ENC_V1)

                    buf[ret++] = mb->v1_vector;

                else

                    for(z = 0; z < 4; z++)

                        buf[ret++] = mb->v4_vector[v4][z];

            }

        }

        write_chunk_header(buf + header_ofs, 0x30, ret - header_ofs - CHUNK_HEADER_SIZE);

        break;

    case MODE_MC:

        //remember header position

        header_ofs = ret;

        ret += CHUNK_HEADER_SIZE;

        flags = bits = temp_size = 0;

        for(x = 0; x < mb_count; x++) {

            mb = &s->mb[x];

            flags |= (mb->best_encoding != ENC_SKIP) << (31 - bits++);

            needs_extra_bit = 0;

            should_write_temp = 0;

            if(mb->best_encoding != ENC_SKIP) {

                if(bits < 32)

                    flags |= (mb->best_encoding == ENC_V4) << (31 - bits++);

                else

                    needs_extra_bit = 1;

            }

            if(bits == 32) {

                AV_WB32(&buf[ret], flags);

                ret += 4;

                flags = bits = 0;

                if(mb->best_encoding == ENC_SKIP || needs_extra_bit) {

                    memcpy(&buf[ret], temp, temp_size);

                    ret += temp_size;

                    temp_size = 0;

                } else

                    should_write_temp = 1;

            }

            if(needs_extra_bit) {

                flags = (mb->best_encoding == ENC_V4) << 31;

                bits = 1;

            }

            if(mb->best_encoding == ENC_V1)

                temp[temp_size++] = mb->v1_vector;

            else if(mb->best_encoding == ENC_V4)

                for(z = 0; z < 4; z++)

                    temp[temp_size++] = mb->v4_vector[v4][z];

            if(should_write_temp) {

                memcpy(&buf[ret], temp, temp_size);

                ret += temp_size;

                temp_size = 0;

            }

        }

        if(bits > 0) {

            AV_WB32(&buf[ret], flags);

            ret += 4;

            memcpy(&buf[ret], temp, temp_size);

            ret += temp_size;

        }

        write_chunk_header(buf + header_ofs, 0x31, ret - header_ofs - CHUNK_HEADER_SIZE);

        break;

    }

    return ret;

}


static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    ByteIOContext *pb = &s->pb;
    SmackerContext *smk = (SmackerContext *)s->priv_data;
    AVStream *st, *ast[7];
    int i, ret;
    int tbase;
    /* read and check header */
    smk->magic = get_le32(pb);
    if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
    smk->width = get_le32(pb);
    smk->height = get_le32(pb);
    smk->frames = get_le32(pb);
    smk->pts_inc = (int32_t)get_le32(pb);
    smk->flags = get_le32(pb);
    for(i = 0; i < 7; i++)
        smk->audio[i] = get_le32(pb);
    smk->treesize = get_le32(pb);
    smk->mmap_size = get_le32(pb);
    smk->mclr_size = get_le32(pb);
    smk->full_size = get_le32(pb);
    smk->type_size = get_le32(pb);
    for(i = 0; i < 7; i++)
        smk->rates[i] = get_le32(pb);
    smk->pad = get_le32(pb);
    /* setup data */
    if(smk->frames > 0xFFFFFF) {
        av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
    smk->frm_size = av_malloc(smk->frames * 4);
    smk->frm_flags = av_malloc(smk->frames);
    smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2'));
    /* read frame info */
    for(i = 0; i < smk->frames; i++) {
        smk->frm_size[i] = get_le32(pb);
    for(i = 0; i < smk->frames; i++) {
        smk->frm_flags[i] = get_byte(pb);
    /* init video codec */
    st = av_new_stream(s, 0);
    if (!st)
    smk->videoindex = st->index;
    st->codec->width = smk->width;
    st->codec->height = smk->height;
    st->codec->pix_fmt = PIX_FMT_PAL8;
    st->codec->codec_type = CODEC_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_SMACKVIDEO;
    st->codec->codec_tag = smk->is_ver4;
    /* Smacker uses 100000 as internal timebase */
    if(smk->pts_inc < 0)
        smk->pts_inc = -smk->pts_inc;
    else
        smk->pts_inc *= 100;
    tbase = 100000;
    av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1);
    av_set_pts_info(st, 33, smk->pts_inc, tbase);
    /* handle possible audio streams */
    for(i = 0; i < 7; i++) {
        smk->indexes[i] = -1;
        if((smk->rates[i] & 0xFFFFFF) && !(smk->rates[i] & SMK_AUD_BINKAUD)){
            ast[i] = av_new_stream(s, 0);
            smk->indexes[i] = ast[i]->index;
            av_set_pts_info(ast[i], 33, smk->pts_inc, tbase);
            ast[i]->codec->codec_type = CODEC_TYPE_AUDIO;
            ast[i]->codec->codec_id = (smk->rates[i] & SMK_AUD_PACKED) ? CODEC_ID_SMACKAUDIO : CODEC_ID_PCM_U8;
            ast[i]->codec->codec_tag = 0;
            ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
            ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
            ast[i]->codec->bits_per_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;
            if(ast[i]->codec->bits_per_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8)
                ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
    /* load trees to extradata, they will be unpacked by decoder */
    st->codec->extradata = av_malloc(smk->treesize + 16);
    st->codec->extradata_size = smk->treesize + 16;
    if(!st->codec->extradata){
        av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
        av_free(smk->frm_size);
        av_free(smk->frm_flags);
    ret = get_buffer(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
    if(ret != st->codec->extradata_size - 16){
        av_free(smk->frm_size);
        av_free(smk->frm_flags);
        return AVERROR_IO;
    ((int32_t*)st->codec->extradata)[0] = le2me_32(smk->mmap_size);
    ((int32_t*)st->codec->extradata)[1] = le2me_32(smk->mclr_size);
    ((int32_t*)st->codec->extradata)[2] = le2me_32(smk->full_size);
    ((int32_t*)st->codec->extradata)[3] = le2me_32(smk->type_size);
    smk->curstream = -1;
    smk->nextpos = url_ftell(pb);
    return 0;


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

{

    EduState *edu = DO_UPCAST(EduState, pdev, pdev);

    uint8_t *pci_conf = pdev->config;

    timer_init_ms(&edu->dma_timer, QEMU_CLOCK_VIRTUAL, edu_dma_timer, edu);

    qemu_mutex_init(&edu->thr_mutex);

    qemu_cond_init(&edu->thr_cond);

    qemu_thread_create(&edu->thread, "edu", edu_fact_thread,

                       edu, QEMU_THREAD_JOINABLE);

    pci_config_set_interrupt_pin(pci_conf, 1);

    if (msi_init(pdev, 0, 1, true, false, errp)) {

        return;

    }

    memory_region_init_io(&edu->mmio, OBJECT(edu), &edu_mmio_ops, edu,

                    "edu-mmio", 1 << 20);

    pci_register_bar(pdev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &edu->mmio);

}


uint64_t pc_dimm_get_free_addr(uint64_t address_space_start,

                               uint64_t address_space_size,

                               uint64_t *hint, uint64_t size,

                               Error **errp)

{

    GSList *list = NULL, *item;

    uint64_t new_addr, ret = 0;

    uint64_t address_space_end = address_space_start + address_space_size;

    assert(address_space_end > address_space_size);

    object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &list);

    if (hint) {

        new_addr = *hint;

    } else {

        new_addr = address_space_start;

    }

    /* find address range that will fit new DIMM */

    for (item = list; item; item = g_slist_next(item)) {

        PCDIMMDevice *dimm = item->data;

        uint64_t dimm_size = object_property_get_int(OBJECT(dimm),

                                                     PC_DIMM_SIZE_PROP,

                                                     errp);

        if (errp && *errp) {

            goto out;

        }

        if (ranges_overlap(dimm->addr, dimm_size, new_addr, size)) {

            if (hint) {

                DeviceState *d = DEVICE(dimm);

                error_setg(errp, "address range conflicts with '%s'", d->id);

                goto out;

            }

            new_addr = dimm->addr + dimm_size;

        }

    }

    ret = new_addr;

    if (new_addr < address_space_start) {

        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64

                   "] at 0x%" PRIx64, new_addr, size, address_space_start);

    } else if ((new_addr + size) > address_space_end) {

        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64

                   "] beyond 0x%" PRIx64, new_addr, size, address_space_end);

    }

out:

    g_slist_free(list);

    return ret;

}


static int wma_decode_block(WMACodecContext *s)

{

    int n, v, a, ch, bsize;

    int coef_nb_bits, total_gain;

    int nb_coefs[MAX_CHANNELS];

    float mdct_norm;

    FFTContext *mdct;

#ifdef TRACE

    tprintf(s->avctx, "***decode_block: %d:%d\n", s->frame_count - 1, s->block_num);

#endif

    /* compute current block length */

    if (s->use_variable_block_len) {

        n = av_log2(s->nb_block_sizes - 1) + 1;

        if (s->reset_block_lengths) {

            s->reset_block_lengths = 0;

            v = get_bits(&s->gb, n);

            if (v >= s->nb_block_sizes){

                av_log(s->avctx, AV_LOG_ERROR, "prev_block_len_bits %d out of range\n", s->frame_len_bits - v);

                return -1;

            s->prev_block_len_bits = s->frame_len_bits - v;

            v = get_bits(&s->gb, n);

            if (v >= s->nb_block_sizes){

                av_log(s->avctx, AV_LOG_ERROR, "block_len_bits %d out of range\n", s->frame_len_bits - v);

                return -1;

            s->block_len_bits = s->frame_len_bits - v;

        } else {

            /* update block lengths */

            s->prev_block_len_bits = s->block_len_bits;

            s->block_len_bits = s->next_block_len_bits;

        v = get_bits(&s->gb, n);

        if (v >= s->nb_block_sizes){

            av_log(s->avctx, AV_LOG_ERROR, "next_block_len_bits %d out of range\n", s->frame_len_bits - v);

            return -1;

        s->next_block_len_bits = s->frame_len_bits - v;

    } else {

        /* fixed block len */

        s->next_block_len_bits = s->frame_len_bits;

        s->prev_block_len_bits = s->frame_len_bits;

        s->block_len_bits = s->frame_len_bits;

    if (s->frame_len_bits - s->block_len_bits >= s->nb_block_sizes){

        av_log(s->avctx, AV_LOG_ERROR, "block_len_bits not initialized to a valid value\n");

        return -1;

    /* now check if the block length is coherent with the frame length */

    s->block_len = 1 << s->block_len_bits;

    if ((s->block_pos + s->block_len) > s->frame_len){

        av_log(s->avctx, AV_LOG_ERROR, "frame_len overflow\n");

        return -1;

    if (s->avctx->channels == 2) {

        s->ms_stereo = get_bits1(&s->gb);

    v = 0;

    for(ch = 0; ch < s->avctx->channels; ch++) {

        a = get_bits1(&s->gb);

        s->channel_coded[ch] = a;

        v |= a;

    bsize = s->frame_len_bits - s->block_len_bits;

    /* if no channel coded, no need to go further */

    /* XXX: fix potential framing problems */

    if (!v)

        goto next;

    /* read total gain and extract corresponding number of bits for

       coef escape coding */

    total_gain = 1;

    for(;;) {

        a = get_bits(&s->gb, 7);

        total_gain += a;

        if (a != 127)

            break;

    coef_nb_bits= ff_wma_total_gain_to_bits(total_gain);

    /* compute number of coefficients */

    n = s->coefs_end[bsize] - s->coefs_start;

    for(ch = 0; ch < s->avctx->channels; ch++)

        nb_coefs[ch] = n;

    /* complex coding */

    if (s->use_noise_coding) {

        for(ch = 0; ch < s->avctx->channels; ch++) {

            if (s->channel_coded[ch]) {

                int i, n, a;

                n = s->exponent_high_sizes[bsize];

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

                    a = get_bits1(&s->gb);

                    s->high_band_coded[ch][i] = a;

                    /* if noise coding, the coefficients are not transmitted */

                    if (a)

                        nb_coefs[ch] -= s->exponent_high_bands[bsize][i];

        for(ch = 0; ch < s->avctx->channels; ch++) {

            if (s->channel_coded[ch]) {

                int i, n, val, code;

                n = s->exponent_high_sizes[bsize];

                val = (int)0x80000000;

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

                    if (s->high_band_coded[ch][i]) {

                        if (val == (int)0x80000000) {

                            val = get_bits(&s->gb, 7) - 19;

                        } else {

                            code = get_vlc2(&s->gb, s->hgain_vlc.table, HGAINVLCBITS, HGAINMAX);

                            if (code < 0){

                                av_log(s->avctx, AV_LOG_ERROR, "hgain vlc invalid\n");

                                return -1;

                            val += code - 18;

                        s->high_band_values[ch][i] = val;

    /* exponents can be reused in short blocks. */

    if ((s->block_len_bits == s->frame_len_bits) ||

        get_bits1(&s->gb)) {

        for(ch = 0; ch < s->avctx->channels; ch++) {

            if (s->channel_coded[ch]) {

                if (s->use_exp_vlc) {

                    if (decode_exp_vlc(s, ch) < 0)

                        return -1;

                } else {

                    decode_exp_lsp(s, ch);

                s->exponents_bsize[ch] = bsize;

    /* parse spectral coefficients : just RLE encoding */

    for (ch = 0; ch < s->avctx->channels; ch++) {

        if (s->channel_coded[ch]) {

            int tindex;

            WMACoef* ptr = &s->coefs1[ch][0];

            /* special VLC tables are used for ms stereo because

               there is potentially less energy there */

            tindex = (ch == 1 && s->ms_stereo);

            memset(ptr, 0, s->block_len * sizeof(WMACoef));

            ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex],

                  s->level_table[tindex], s->run_table[tindex],

                  0, ptr, 0, nb_coefs[ch],

                  s->block_len, s->frame_len_bits, coef_nb_bits);

        if (s->version == 1 && s->avctx->channels >= 2) {

            align_get_bits(&s->gb);

    /* normalize */

    {

        int n4 = s->block_len / 2;

        mdct_norm = 1.0 / (float)n4;

        if (s->version == 1) {

            mdct_norm *= sqrt(n4);

    /* finally compute the MDCT coefficients */

    for (ch = 0; ch < s->avctx->channels; ch++) {

        if (s->channel_coded[ch]) {

            WMACoef *coefs1;

            float *coefs, *exponents, mult, mult1, noise;

            int i, j, n, n1, last_high_band, esize;

            float exp_power[HIGH_BAND_MAX_SIZE];

            coefs1 = s->coefs1[ch];

            exponents = s->exponents[ch];

            esize = s->exponents_bsize[ch];

            mult = pow(10, total_gain * 0.05) / s->max_exponent[ch];

            mult *= mdct_norm;

            coefs = s->coefs[ch];

            if (s->use_noise_coding) {

                mult1 = mult;

                /* very low freqs : noise */

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

                    *coefs++ = s->noise_table[s->noise_index] *

                      exponents[i<<bsize>>esize] * mult1;

                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                n1 = s->exponent_high_sizes[bsize];

                /* compute power of high bands */

                exponents = s->exponents[ch] +

                    (s->high_band_start[bsize]<<bsize>>esize);

                last_high_band = 0; /* avoid warning */

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

                    n = s->exponent_high_bands[s->frame_len_bits -

                                              s->block_len_bits][j];

                    if (s->high_band_coded[ch][j]) {

                        float e2, v;

                        e2 = 0;

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

                            v = exponents[i<<bsize>>esize];

                            e2 += v * v;

                        exp_power[j] = e2 / n;

                        last_high_band = j;

                        tprintf(s->avctx, "%d: power=%f (%d)\n", j, exp_power[j], n);

                    exponents += n<<bsize>>esize;

                /* main freqs and high freqs */

                exponents = s->exponents[ch] + (s->coefs_start<<bsize>>esize);

                for(j=-1;j<n1;j++) {

                    if (j < 0) {

                        n = s->high_band_start[bsize] -

                            s->coefs_start;

                    } else {

                        n = s->exponent_high_bands[s->frame_len_bits -

                                                  s->block_len_bits][j];

                    if (j >= 0 && s->high_band_coded[ch][j]) {

                        /* use noise with specified power */

                        mult1 = sqrt(exp_power[j] / exp_power[last_high_band]);

                        /* XXX: use a table */

                        mult1 = mult1 * pow(10, s->high_band_values[ch][j] * 0.05);

                        mult1 = mult1 / (s->max_exponent[ch] * s->noise_mult);

                        mult1 *= mdct_norm;

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

                            noise = s->noise_table[s->noise_index];

                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                            *coefs++ =  noise *

                                exponents[i<<bsize>>esize] * mult1;

                        exponents += n<<bsize>>esize;

                    } else {

                        /* coded values + small noise */

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

                            noise = s->noise_table[s->noise_index];

                            s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

                            *coefs++ = ((*coefs1++) + noise) *

                                exponents[i<<bsize>>esize] * mult;

                        exponents += n<<bsize>>esize;

                /* very high freqs : noise */

                n = s->block_len - s->coefs_end[bsize];

                mult1 = mult * exponents[((-1<<bsize))>>esize];

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

                    *coefs++ = s->noise_table[s->noise_index] * mult1;

                    s->noise_index = (s->noise_index + 1) & (NOISE_TAB_SIZE - 1);

            } else {

                /* XXX: optimize more */

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

                    *coefs++ = 0.0;

                n = nb_coefs[ch];

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

                    *coefs++ = coefs1[i] * exponents[i<<bsize>>esize] * mult;

                n = s->block_len - s->coefs_end[bsize];

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

                    *coefs++ = 0.0;

#ifdef TRACE

    for (ch = 0; ch < s->avctx->channels; ch++) {

        if (s->channel_coded[ch]) {

            dump_floats(s, "exponents", 3, s->exponents[ch], s->block_len);

            dump_floats(s, "coefs", 1, s->coefs[ch], s->block_len);

#endif

    if (s->ms_stereo && s->channel_coded[1]) {

        /* nominal case for ms stereo: we do it before mdct */

        /* no need to optimize this case because it should almost

           never happen */

        if (!s->channel_coded[0]) {

            tprintf(s->avctx, "rare ms-stereo case happened\n");

            memset(s->coefs[0], 0, sizeof(float) * s->block_len);

            s->channel_coded[0] = 1;

        s->fdsp.butterflies_float(s->coefs[0], s->coefs[1], s->block_len);

next:

    mdct = &s->mdct_ctx[bsize];

    for (ch = 0; ch < s->avctx->channels; ch++) {

        int n4, index;

        n4 = s->block_len / 2;

        if(s->channel_coded[ch]){

            mdct->imdct_calc(mdct, s->output, s->coefs[ch]);

        }else if(!(s->ms_stereo && ch==1))

            memset(s->output, 0, sizeof(s->output));

        /* multiply by the window and add in the frame */

        index = (s->frame_len / 2) + s->block_pos - n4;

        wma_window(s, &s->frame_out[ch][index]);

    /* update block number */

    s->block_num++;

    s->block_pos += s->block_len;

    if (s->block_pos >= s->frame_len)

        return 1;

    else

        return 0;


static int floppy_probe_device(const char *filename)

{

    int fd, ret;

    int prio = 0;

    struct floppy_struct fdparam;

    struct stat st;

    if (strstart(filename, "/dev/fd", NULL))

        prio = 50;

    fd = open(filename, O_RDONLY | O_NONBLOCK);

    if (fd < 0) {

        goto out;

    }

    ret = fstat(fd, &st);

    if (ret == -1 || !S_ISBLK(st.st_mode)) {

        goto outc;

    }

    /* Attempt to detect via a floppy specific ioctl */

    ret = ioctl(fd, FDGETPRM, &fdparam);

    if (ret >= 0)

        prio = 100;

outc:

    close(fd);

out:

    return prio;

}


struct XenDevice *xen_be_find_xendev(const char *type, int dom, int dev)

{

    struct XenDevice *xendev;

    TAILQ_FOREACH(xendev, &xendevs, next) {

	if (xendev->dom != dom)

	    continue;

	if (xendev->dev != dev)

	    continue;

	if (strcmp(xendev->type, type) != 0)

	    continue;

	return xendev;

    }

    return NULL;

}


static void dct_unquantize_mpeg1_mmx(MpegEncContext *s,

                                     DCTELEM *block, int n, int qscale)

{

    int i, level;

    const UINT16 *quant_matrix;

    if (s->mb_intra) {

        if (n < 4)

            block[0] = block[0] * s->y_dc_scale;

        else

            block[0] = block[0] * s->c_dc_scale;

        if (s->out_format == FMT_H263) {

            i = 1;

            goto unquant_even;

        }

        /* XXX: only mpeg1 */

        quant_matrix = s->intra_matrix;

	i=1;

	/* Align on 4 elements boundary */

	while(i&3)

	{

            level = block[i];

            if (level) {

                if (level < 0) level = -level;

                    level = (int)(level * qscale * quant_matrix[i]) >> 3;

                    level = (level - 1) | 1;

                if (block[i] < 0) level = -level;

                block[i] = level;

            }

	    i++;

	}

	__asm __volatile(

	"movd	%0, %%mm6\n\t"       /* mm6 = qscale | 0  */

	"punpckldq %%mm6, %%mm6\n\t" /* mm6 = qscale | qscale */

	"movq	%2, %%mm4\n\t"

	"movq	%%mm6, %%mm7\n\t"

	"movq	%1, %%mm5\n\t"

	"packssdw %%mm6, %%mm7\n\t" /* mm7 = qscale | qscale | qscale | qscale */

	"pxor	%%mm6, %%mm6\n\t"

	::"g"(qscale),"m"(mm_wone),"m"(mm_wabs):"memory");

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

		__asm __volatile(

			"movq	%1, %%mm0\n\t"

			"movq	%%mm7, %%mm1\n\t"

			"movq	%%mm0, %%mm2\n\t"

			"movq	%%mm0, %%mm3\n\t"

			"pcmpgtw %%mm6, %%mm2\n\t"

			"pmullw	%2, %%mm1\n\t"

			"pandn	%%mm4, %%mm2\n\t"

			"por	%%mm5, %%mm2\n\t"

			"pmullw	%%mm2, %%mm0\n\t" /* mm0 = abs(block[i]). */

			"pcmpeqw %%mm6, %%mm3\n\t"

			"pmullw	%%mm0, %%mm1\n\t"

			"psraw	$3, %%mm1\n\t"

			"psubw	%%mm5, %%mm1\n\t"   /* block[i] --; */

			"pandn	%%mm4, %%mm3\n\t"  /* fake of pcmpneqw : mm0 != 0 then mm1 = -1 */

			"por	%%mm5, %%mm1\n\t"   /* block[i] |= 1 */

			"pmullw %%mm2, %%mm1\n\t"   /* change signs again */

			"pand	%%mm3, %%mm1\n\t" /* nullify if was zero */

			"movq	%%mm1, %0"

			:"=m"(block[i])

			:"m"(block[i]), "m"(quant_matrix[i])

			:"memory");

        }

    } else {

        i = 0;

    unquant_even:

        quant_matrix = s->non_intra_matrix;

	/* Align on 4 elements boundary */

	while(i&7)

	{

	    level = block[i];

            if (level) {

                if (level < 0) level = -level;

                    level = (((level << 1) + 1) * qscale *

                             ((int) quant_matrix[i])) >> 4;

                    level = (level - 1) | 1;

                if(block[i] < 0) level = -level;

                block[i] = level;

	    }

	    i++;

	}

asm volatile(

		"pcmpeqw %%mm7, %%mm7		\n\t"

		"psrlw $15, %%mm7		\n\t"

		"movd %2, %%mm6			\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

		"packssdw %%mm6, %%mm6		\n\t"

		"1:				\n\t"

		"movq (%0, %3), %%mm0		\n\t"

		"movq 8(%0, %3), %%mm1		\n\t"

		"movq (%1, %3), %%mm4		\n\t"

		"movq 8(%1, %3), %%mm5		\n\t"

		"pmullw %%mm6, %%mm4		\n\t" // q=qscale*quant_matrix[i]

		"pmullw %%mm6, %%mm5		\n\t" // q=qscale*quant_matrix[i]

		"pxor %%mm2, %%mm2		\n\t"

		"pxor %%mm3, %%mm3		\n\t"

		"pcmpgtw %%mm0, %%mm2		\n\t" // block[i] < 0 ? -1 : 0

		"pcmpgtw %%mm1, %%mm3		\n\t" // block[i] < 0 ? -1 : 0

		"pxor %%mm2, %%mm0		\n\t"

		"pxor %%mm3, %%mm1		\n\t"

		"psubw %%mm2, %%mm0		\n\t" // abs(block[i])

		"psubw %%mm3, %%mm1		\n\t" // abs(block[i])

		"paddw %%mm0, %%mm0		\n\t" // abs(block[i])*2

		"paddw %%mm1, %%mm1		\n\t" // abs(block[i])*2

		"paddw %%mm7, %%mm0		\n\t" // abs(block[i])*2 + 1

		"paddw %%mm7, %%mm1		\n\t" // abs(block[i])*2 + 1

		"pmullw %%mm4, %%mm0		\n\t" // (abs(block[i])*2 + 1)*q

		"pmullw %%mm5, %%mm1		\n\t" // (abs(block[i])*2 + 1)*q

		"pxor %%mm4, %%mm4		\n\t"

		"pxor %%mm5, %%mm5		\n\t" // FIXME slow

		"pcmpeqw (%0, %3), %%mm4	\n\t" // block[i] == 0 ? -1 : 0

		"pcmpeqw 8(%0, %3), %%mm5	\n\t" // block[i] == 0 ? -1 : 0

		"psraw $4, %%mm0		\n\t"

		"psraw $4, %%mm1		\n\t"

		"psubw %%mm7, %%mm0		\n\t"

		"psubw %%mm7, %%mm1		\n\t"

		"por %%mm7, %%mm0		\n\t"

		"por %%mm7, %%mm1		\n\t"

		"pxor %%mm2, %%mm0		\n\t"

		"pxor %%mm3, %%mm1		\n\t"

		"psubw %%mm2, %%mm0		\n\t"

		"psubw %%mm3, %%mm1		\n\t"

		"pandn %%mm0, %%mm4		\n\t"

		"pandn %%mm1, %%mm5		\n\t"

		"movq %%mm4, (%0, %3)		\n\t"

		"movq %%mm5, 8(%0, %3)		\n\t"

		"addl $16, %3			\n\t"

		"cmpl $128, %3			\n\t"

		"jb 1b				\n\t"

		::"r" (block), "r"(quant_matrix), "g" (qscale), "r" (2*i)

		: "memory"

	);

#if 0

	__asm __volatile(

	"movd	%0, %%mm6\n\t"       /* mm6 = qscale | 0  */

	"punpckldq %%mm6, %%mm6\n\t" /* mm6 = qscale | qscale */

	"movq	%2, %%mm4\n\t"

	"movq	%%mm6, %%mm7\n\t"

	"movq	%1, %%mm5\n\t"

	"packssdw %%mm6, %%mm7\n\t" /* mm7 = qscale | qscale | qscale | qscale */

	"pxor	%%mm6, %%mm6\n\t"

	::"g"(qscale),"m"(mm_wone),"m"(mm_wabs));

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

		__asm __volatile(

			"movq	%1, %%mm0\n\t"

			"movq	%%mm7, %%mm1\n\t"

			"movq	%%mm0, %%mm2\n\t"

			"movq	%%mm0, %%mm3\n\t"

			"pcmpgtw %%mm6, %%mm2\n\t"

			"pmullw	%2, %%mm1\n\t"

			"pandn	%%mm4, %%mm2\n\t"

			"por	%%mm5, %%mm2\n\t"

			"pmullw	%%mm2, %%mm0\n\t" /* mm0 = abs(block[i]). */

			"psllw	$1, %%mm0\n\t" /* block[i] <<= 1 */

			"paddw	%%mm5, %%mm0\n\t" /* block[i] ++ */

			"pmullw	%%mm0, %%mm1\n\t"

			"psraw	$4, %%mm1\n\t"

			"pcmpeqw %%mm6, %%mm3\n\t"

			"psubw	%%mm5, %%mm1\n\t"   /* block[i] --; */

			"pandn	%%mm4, %%mm3\n\t"  /* fake of pcmpneqw : mm0 != 0 then mm1 = -1 */

			"por	%%mm5, %%mm1\n\t"   /* block[i] |= 1 */

			"pmullw %%mm2, %%mm1\n\t"   /* change signs again */

			"pand	%%mm3, %%mm1\n\t" /* nullify if was zero */

			"movq	%%mm1, %0"

			:"=m"(block[i])

			:"m"(block[i]), "m"(quant_matrix[i]));

        }

#endif

    }

}


static int virtio_ccw_set_vqs(SubchDev *sch, VqInfoBlock *info,

                              VqInfoBlockLegacy *linfo)

{

    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);

    uint16_t index = info ? info->index : linfo->index;

    uint16_t num = info ? info->num : linfo->num;

    uint64_t desc = info ? info->desc : linfo->queue;

    if (index >= VIRTIO_CCW_QUEUE_MAX) {

        return -EINVAL;

    }

    /* Current code in virtio.c relies on 4K alignment. */

    if (linfo && desc && (linfo->align != 4096)) {

        return -EINVAL;

    }

    if (!vdev) {

        return -EINVAL;

    }

    if (info) {

        virtio_queue_set_rings(vdev, index, desc, info->avail, info->used);

    } else {

        virtio_queue_set_addr(vdev, index, desc);

    }

    if (!desc) {

        virtio_queue_set_vector(vdev, index, VIRTIO_NO_VECTOR);

    } else {

        if (info) {

            /* virtio-1 allows changing the ring size. */

            if (virtio_queue_get_max_num(vdev, index) < num) {

                /* Fail if we exceed the maximum number. */

                return -EINVAL;

            }

            virtio_queue_set_num(vdev, index, num);

        } else if (virtio_queue_get_num(vdev, index) > num) {

            /* Fail if we don't have a big enough queue. */

            return -EINVAL;

        }

        /* We ignore possible increased num for legacy for compatibility. */

        virtio_queue_set_vector(vdev, index, index);

    }

    /* tell notify handler in case of config change */

    vdev->config_vector = VIRTIO_CCW_QUEUE_MAX;

    return 0;

}


void qemu_system_debug_request(void)

{

    debug_requested = 1;

    vm_stop(VMSTOP_DEBUG);

}


static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,

                                             int64_t offset, int count,

                                             BdrvRequestFlags flags)

{

    return bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags);

}


void monitor_flush(Monitor *mon)

{

    int i;

    if (term_outbuf_index > 0) {

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

            if (monitor_hd[i] && monitor_hd[i]->focus == 0)

                qemu_chr_write(monitor_hd[i], term_outbuf, term_outbuf_index);

        term_outbuf_index = 0;

    }

}


void qemu_co_queue_restart_all(CoQueue *queue)

{

    while (qemu_co_queue_next(queue)) {

        /* Do nothing */

    }

}


static void nvdimm_dsm_func_read_fit(AcpiNVDIMMState *state, NvdimmDsmIn *in,

                                     hwaddr dsm_mem_addr)

{

    NvdimmFitBuffer *fit_buf = &state->fit_buf;

    NvdimmFuncReadFITIn *read_fit;

    NvdimmFuncReadFITOut *read_fit_out;

    GArray *fit;

    uint32_t read_len = 0, func_ret_status;

    int size;

    read_fit = (NvdimmFuncReadFITIn *)in->arg3;

    le32_to_cpus(&read_fit->offset);

    qemu_mutex_lock(&fit_buf->lock);

    fit = fit_buf->fit;

    nvdimm_debug("Read FIT: offset %#x FIT size %#x Dirty %s.\n",

                 read_fit->offset, fit->len, fit_buf->dirty ? "Yes" : "No");

    if (read_fit->offset > fit->len) {

        func_ret_status = 3 /* Invalid Input Parameters */;

        goto exit;

    }

    /* It is the first time to read FIT. */

    if (!read_fit->offset) {

        fit_buf->dirty = false;

    } else if (fit_buf->dirty) { /* FIT has been changed during RFIT. */

        func_ret_status = 0x100 /* fit changed */;

        goto exit;

    }

    func_ret_status = 0 /* Success */;

    read_len = MIN(fit->len - read_fit->offset,

                   4096 - sizeof(NvdimmFuncReadFITOut));

exit:

    size = sizeof(NvdimmFuncReadFITOut) + read_len;

    read_fit_out = g_malloc(size);

    read_fit_out->len = cpu_to_le32(size);

    read_fit_out->func_ret_status = cpu_to_le32(func_ret_status);

    memcpy(read_fit_out->fit, fit->data + read_fit->offset, read_len);

    cpu_physical_memory_write(dsm_mem_addr, read_fit_out, size);

    g_free(read_fit_out);

    qemu_mutex_unlock(&fit_buf->lock);

}


static void tftp_send_error(struct tftp_session *spt,

                            uint16_t errorcode, const char *msg,

                            struct tftp_t *recv_tp)

{

  struct sockaddr_in saddr, daddr;

  struct mbuf *m;

  struct tftp_t *tp;

  m = m_get(spt->slirp);

  if (!m) {

    goto out;

  }

  memset(m->m_data, 0, m->m_size);

  m->m_data += IF_MAXLINKHDR;

  tp = (void *)m->m_data;

  m->m_data += sizeof(struct udpiphdr);

  tp->tp_op = htons(TFTP_ERROR);

  tp->x.tp_error.tp_error_code = htons(errorcode);

  pstrcpy((char *)tp->x.tp_error.tp_msg, sizeof(tp->x.tp_error.tp_msg), msg);

  saddr.sin_addr = recv_tp->ip.ip_dst;

  saddr.sin_port = recv_tp->udp.uh_dport;

  daddr.sin_addr = spt->client_ip;

  daddr.sin_port = spt->client_port;

  m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -

        sizeof(struct ip) - sizeof(struct udphdr);

  udp_output2(NULL, m, &saddr, &daddr, IPTOS_LOWDELAY);

out:

  tftp_session_terminate(spt);

}


static void omap_rtc_alarm_update(struct omap_rtc_s *s)

{

    s->alarm_ti = mktimegm(&s->alarm_tm);

    if (s->alarm_ti == -1)

        printf("%s: conversion failed\n", __FUNCTION__);

}


static int http_send_data(HTTPContext *c)

{

    int len, ret;

    for(;;) {

        if (c->buffer_ptr >= c->buffer_end) {

            ret = http_prepare_data(c);

            if (ret < 0)

                return -1;

            else if (ret != 0)

                /* state change requested */

                break;

        } else {

            if (c->is_packetized) {

                /* RTP data output */

                len = c->buffer_end - c->buffer_ptr;

                if (len < 4) {

                    /* fail safe - should never happen */

                fail1:

                    c->buffer_ptr = c->buffer_end;

                    return 0;

                }

                len = (c->buffer_ptr[0] << 24) |

                    (c->buffer_ptr[1] << 16) |

                    (c->buffer_ptr[2] << 8) |

                    (c->buffer_ptr[3]);

                if (len > (c->buffer_end - c->buffer_ptr))

                    goto fail1;

                if ((get_packet_send_clock(c) - get_server_clock(c)) > 0) {

                    /* nothing to send yet: we can wait */

                    return 0;

                }

                c->data_count += len;

                update_datarate(&c->datarate, c->data_count);

                if (c->stream)

                    c->stream->bytes_served += len;

                if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) {

                    /* RTP packets are sent inside the RTSP TCP connection */

                    AVIOContext *pb;

                    int interleaved_index, size;

                    uint8_t header[4];

                    HTTPContext *rtsp_c;

                    rtsp_c = c->rtsp_c;

                    /* if no RTSP connection left, error */

                    if (!rtsp_c)

                        return -1;

                    /* if already sending something, then wait. */

                    if (rtsp_c->state != RTSPSTATE_WAIT_REQUEST)

                        break;

                    if (avio_open_dyn_buf(&pb) < 0)

                        goto fail1;

                    interleaved_index = c->packet_stream_index * 2;

                    /* RTCP packets are sent at odd indexes */

                    if (c->buffer_ptr[1] == 200)

                        interleaved_index++;

                    /* write RTSP TCP header */

                    header[0] = '$';

                    header[1] = interleaved_index;

                    header[2] = len >> 8;

                    header[3] = len;

                    avio_write(pb, header, 4);

                    /* write RTP packet data */

                    c->buffer_ptr += 4;

                    avio_write(pb, c->buffer_ptr, len);

                    size = avio_close_dyn_buf(pb, &c->packet_buffer);

                    /* prepare asynchronous TCP sending */

                    rtsp_c->packet_buffer_ptr = c->packet_buffer;

                    rtsp_c->packet_buffer_end = c->packet_buffer + size;

                    c->buffer_ptr += len;

                    /* send everything we can NOW */

                    len = send(rtsp_c->fd, rtsp_c->packet_buffer_ptr,

                                rtsp_c->packet_buffer_end - rtsp_c->packet_buffer_ptr, 0);

                    if (len > 0)

                        rtsp_c->packet_buffer_ptr += len;

                    if (rtsp_c->packet_buffer_ptr < rtsp_c->packet_buffer_end) {

                        /* if we could not send all the data, we will

                           send it later, so a new state is needed to

                           "lock" the RTSP TCP connection */

                        rtsp_c->state = RTSPSTATE_SEND_PACKET;

                        break;

                    } else

                        /* all data has been sent */

                        av_freep(&c->packet_buffer);

                } else {

                    /* send RTP packet directly in UDP */

                    c->buffer_ptr += 4;

                    ffurl_write(c->rtp_handles[c->packet_stream_index],

                                c->buffer_ptr, len);

                    c->buffer_ptr += len;

                    /* here we continue as we can send several packets per 10 ms slot */

                }

            } else {

                /* TCP data output */

                len = send(c->fd, c->buffer_ptr, c->buffer_end - c->buffer_ptr, 0);

                if (len < 0) {

                    if (ff_neterrno() != AVERROR(EAGAIN) &&

                        ff_neterrno() != AVERROR(EINTR))

                        /* error : close connection */

                        return -1;

                    else

                        return 0;

                } else

                    c->buffer_ptr += len;

                c->data_count += len;

                update_datarate(&c->datarate, c->data_count);

                if (c->stream)

                    c->stream->bytes_served += len;

                break;

            }

        }

    } /* for(;;) */

    return 0;

}


static inline bool vtd_iova_range_check(uint64_t iova, VTDContextEntry *ce)

{

    /*

     * Check if @iova is above 2^X-1, where X is the minimum of MGAW

     * in CAP_REG and AW in context-entry.

     */

    return !(iova & ~(vtd_iova_limit(ce) - 1));

}


DriveInfo *drive_new(QemuOpts *all_opts, BlockInterfaceType block_default_type)

{

    const char *value;

    BlockBackend *blk;

    DriveInfo *dinfo = NULL;

    QDict *bs_opts;

    QemuOpts *legacy_opts;

    DriveMediaType media = MEDIA_DISK;

    BlockInterfaceType type;

    int cyls, heads, secs, translation;

    int max_devs, bus_id, unit_id, index;

    const char *devaddr;

    const char *werror, *rerror;

    bool read_only = false;

    bool copy_on_read;

    const char *serial;

    const char *filename;

    Error *local_err = NULL;

    int i;

    const char *deprecated[] = {

        "serial", "trans", "secs", "heads", "cyls", "addr"

    };

    /* Change legacy command line options into QMP ones */

    static const struct {

        const char *from;

        const char *to;

    } opt_renames[] = {

        { "iops",           "throttling.iops-total" },

        { "iops_rd",        "throttling.iops-read" },

        { "iops_wr",        "throttling.iops-write" },

        { "bps",            "throttling.bps-total" },

        { "bps_rd",         "throttling.bps-read" },

        { "bps_wr",         "throttling.bps-write" },

        { "iops_max",       "throttling.iops-total-max" },

        { "iops_rd_max",    "throttling.iops-read-max" },

        { "iops_wr_max",    "throttling.iops-write-max" },

        { "bps_max",        "throttling.bps-total-max" },

        { "bps_rd_max",     "throttling.bps-read-max" },

        { "bps_wr_max",     "throttling.bps-write-max" },

        { "iops_size",      "throttling.iops-size" },

        { "group",          "throttling.group" },

        { "readonly",       BDRV_OPT_READ_ONLY },

    };

    for (i = 0; i < ARRAY_SIZE(opt_renames); i++) {

        qemu_opt_rename(all_opts, opt_renames[i].from, opt_renames[i].to,

                        &local_err);

        if (local_err) {

            error_report_err(local_err);

            return NULL;

        }

    }

    value = qemu_opt_get(all_opts, "cache");

    if (value) {

        int flags = 0;

        bool writethrough;

        if (bdrv_parse_cache_mode(value, &flags, &writethrough) != 0) {

            error_report("invalid cache option");

            return NULL;

        }

        /* Specific options take precedence */

        if (!qemu_opt_get(all_opts, BDRV_OPT_CACHE_WB)) {

            qemu_opt_set_bool(all_opts, BDRV_OPT_CACHE_WB,

                              !writethrough, &error_abort);

        }

        if (!qemu_opt_get(all_opts, BDRV_OPT_CACHE_DIRECT)) {

            qemu_opt_set_bool(all_opts, BDRV_OPT_CACHE_DIRECT,

                              !!(flags & BDRV_O_NOCACHE), &error_abort);

        }

        if (!qemu_opt_get(all_opts, BDRV_OPT_CACHE_NO_FLUSH)) {

            qemu_opt_set_bool(all_opts, BDRV_OPT_CACHE_NO_FLUSH,

                              !!(flags & BDRV_O_NO_FLUSH), &error_abort);

        }

        qemu_opt_unset(all_opts, "cache");

    }

    /* Get a QDict for processing the options */

    bs_opts = qdict_new();

    qemu_opts_to_qdict(all_opts, bs_opts);

    legacy_opts = qemu_opts_create(&qemu_legacy_drive_opts, NULL, 0,

                                   &error_abort);

    qemu_opts_absorb_qdict(legacy_opts, bs_opts, &local_err);

    if (local_err) {

        error_report_err(local_err);

        goto fail;

    }

    /* Deprecated option boot=[on|off] */

    if (qemu_opt_get(legacy_opts, "boot") != NULL) {

        fprintf(stderr, "qemu-kvm: boot=on|off is deprecated and will be "

                "ignored. Future versions will reject this parameter. Please "

                "update your scripts.\n");

    }

    /* Other deprecated options */

    if (!qtest_enabled()) {

        for (i = 0; i < ARRAY_SIZE(deprecated); i++) {

            if (qemu_opt_get(legacy_opts, deprecated[i]) != NULL) {

                error_report("'%s' is deprecated, please use the corresponding "

                             "option of '-device' instead", deprecated[i]);

            }

        }

    }

    /* Media type */

    value = qemu_opt_get(legacy_opts, "media");

    if (value) {

        if (!strcmp(value, "disk")) {

            media = MEDIA_DISK;

        } else if (!strcmp(value, "cdrom")) {

            media = MEDIA_CDROM;

            read_only = true;

        } else {

            error_report("'%s' invalid media", value);

            goto fail;

        }

    }

    /* copy-on-read is disabled with a warning for read-only devices */

    read_only |= qemu_opt_get_bool(legacy_opts, BDRV_OPT_READ_ONLY, false);

    copy_on_read = qemu_opt_get_bool(legacy_opts, "copy-on-read", false);

    if (read_only && copy_on_read) {

        error_report("warning: disabling copy-on-read on read-only drive");

        copy_on_read = false;

    }

    qdict_put_str(bs_opts, BDRV_OPT_READ_ONLY, read_only ? "on" : "off");

    qdict_put_str(bs_opts, "copy-on-read", copy_on_read ? "on" : "off");

    /* Controller type */

    value = qemu_opt_get(legacy_opts, "if");

    if (value) {

        for (type = 0;

             type < IF_COUNT && strcmp(value, if_name[type]);

             type++) {

        }

        if (type == IF_COUNT) {

            error_report("unsupported bus type '%s'", value);

            goto fail;

        }

    } else {

        type = block_default_type;

    }

    /* Geometry */

    cyls  = qemu_opt_get_number(legacy_opts, "cyls", 0);

    heads = qemu_opt_get_number(legacy_opts, "heads", 0);

    secs  = qemu_opt_get_number(legacy_opts, "secs", 0);

    if (cyls || heads || secs) {

        if (cyls < 1) {

            error_report("invalid physical cyls number");

            goto fail;

        }

        if (heads < 1) {

            error_report("invalid physical heads number");

            goto fail;

        }

        if (secs < 1) {

            error_report("invalid physical secs number");

            goto fail;

        }

    }

    translation = BIOS_ATA_TRANSLATION_AUTO;

    value = qemu_opt_get(legacy_opts, "trans");

    if (value != NULL) {

        if (!cyls) {

            error_report("'%s' trans must be used with cyls, heads and secs",

                         value);

            goto fail;

        }

        if (!strcmp(value, "none")) {

            translation = BIOS_ATA_TRANSLATION_NONE;

        } else if (!strcmp(value, "lba")) {

            translation = BIOS_ATA_TRANSLATION_LBA;

        } else if (!strcmp(value, "large")) {

            translation = BIOS_ATA_TRANSLATION_LARGE;

        } else if (!strcmp(value, "rechs")) {

            translation = BIOS_ATA_TRANSLATION_RECHS;

        } else if (!strcmp(value, "auto")) {

            translation = BIOS_ATA_TRANSLATION_AUTO;

        } else {

            error_report("'%s' invalid translation type", value);

            goto fail;

        }

    }

    if (media == MEDIA_CDROM) {

        if (cyls || secs || heads) {

            error_report("CHS can't be set with media=cdrom");

            goto fail;

        }

    }

    /* Device address specified by bus/unit or index.

     * If none was specified, try to find the first free one. */

    bus_id  = qemu_opt_get_number(legacy_opts, "bus", 0);

    unit_id = qemu_opt_get_number(legacy_opts, "unit", -1);

    index   = qemu_opt_get_number(legacy_opts, "index", -1);

    max_devs = if_max_devs[type];

    if (index != -1) {

        if (bus_id != 0 || unit_id != -1) {

            error_report("index cannot be used with bus and unit");

            goto fail;

        }

        bus_id = drive_index_to_bus_id(type, index);

        unit_id = drive_index_to_unit_id(type, index);

    }

    if (unit_id == -1) {

       unit_id = 0;

       while (drive_get(type, bus_id, unit_id) != NULL) {

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    if (max_devs && unit_id >= max_devs) {

        error_report("unit %d too big (max is %d)", unit_id, max_devs - 1);

        goto fail;

    }

    if (drive_get(type, bus_id, unit_id) != NULL) {

        error_report("drive with bus=%d, unit=%d (index=%d) exists",

                     bus_id, unit_id, index);

        goto fail;

    }

    /* Serial number */

    serial = qemu_opt_get(legacy_opts, "serial");

    /* no id supplied -> create one */

    if (qemu_opts_id(all_opts) == NULL) {

        char *new_id;

        const char *mediastr = "";

        if (type == IF_IDE || type == IF_SCSI) {

            mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";

        }

        if (max_devs) {

            new_id = g_strdup_printf("%s%i%s%i", if_name[type], bus_id,

                                     mediastr, unit_id);

        } else {

            new_id = g_strdup_printf("%s%s%i", if_name[type],

                                     mediastr, unit_id);

        }

        qdict_put_str(bs_opts, "id", new_id);

        g_free(new_id);

    }

    /* Add virtio block device */

    devaddr = qemu_opt_get(legacy_opts, "addr");

    if (devaddr && type != IF_VIRTIO) {

        error_report("addr is not supported by this bus type");

        goto fail;

    }

    if (type == IF_VIRTIO) {

        QemuOpts *devopts;

        devopts = qemu_opts_create(qemu_find_opts("device"), NULL, 0,

                                   &error_abort);

        if (arch_type == QEMU_ARCH_S390X) {

            qemu_opt_set(devopts, "driver", "virtio-blk-ccw", &error_abort);

        } else {

            qemu_opt_set(devopts, "driver", "virtio-blk-pci", &error_abort);

        }

        qemu_opt_set(devopts, "drive", qdict_get_str(bs_opts, "id"),

                     &error_abort);

        if (devaddr) {

            qemu_opt_set(devopts, "addr", devaddr, &error_abort);

        }

    }

    filename = qemu_opt_get(legacy_opts, "file");

    /* Check werror/rerror compatibility with if=... */

    werror = qemu_opt_get(legacy_opts, "werror");

    if (werror != NULL) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO &&

            type != IF_NONE) {

            error_report("werror is not supported by this bus type");

            goto fail;

        }

        qdict_put_str(bs_opts, "werror", werror);

    }

    rerror = qemu_opt_get(legacy_opts, "rerror");

    if (rerror != NULL) {

        if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI &&

            type != IF_NONE) {

            error_report("rerror is not supported by this bus type");

            goto fail;

        }

        qdict_put_str(bs_opts, "rerror", rerror);

    }

    /* Actual block device init: Functionality shared with blockdev-add */

    blk = blockdev_init(filename, bs_opts, &local_err);

    bs_opts = NULL;

    if (!blk) {

        if (local_err) {

            error_report_err(local_err);

        }

        goto fail;

    } else {

        assert(!local_err);

    }

    /* Create legacy DriveInfo */

    dinfo = g_malloc0(sizeof(*dinfo));

    dinfo->opts = all_opts;

    dinfo->cyls = cyls;

    dinfo->heads = heads;

    dinfo->secs = secs;

    dinfo->trans = translation;

    dinfo->type = type;

    dinfo->bus = bus_id;

    dinfo->unit = unit_id;

    dinfo->devaddr = devaddr;

    dinfo->serial = g_strdup(serial);

    blk_set_legacy_dinfo(blk, dinfo);

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

    case IF_NONE:

        dinfo->media_cd = media == MEDIA_CDROM;

        break;

    default:

        break;

    }

fail:

    qemu_opts_del(legacy_opts);

    QDECREF(bs_opts);

    return dinfo;

}


void qerror_report_internal(const char *file, int linenr, const char *func,

                            const char *fmt, ...)

{

    va_list va;

    QError *qerror;

    va_start(va, fmt);

    qerror = qerror_from_info(file, linenr, func, fmt, &va);

    va_end(va);

    if (cur_mon) {

        monitor_set_error(cur_mon, qerror);

    } else {

        qerror_print(qerror);

        QDECREF(qerror);

    }

}


static void qdev_prop_set(DeviceState *dev, const char *name, void *src, enum PropertyType type)

{

    Property *prop;

    prop = qdev_prop_find(dev, name);

    if (!prop) {

        fprintf(stderr, "%s: property \"%s.%s\" not found\n",

                __FUNCTION__, object_get_typename(OBJECT(dev)), name);

        abort();

    }

    if (prop->info->type != type) {

        fprintf(stderr, "%s: property \"%s.%s\" type mismatch\n",

                __FUNCTION__, object_get_typename(OBJECT(dev)), name);

        abort();

    }

    qdev_prop_cpy(dev, prop, src);

}


void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name,

                                BlockDriverState *value)

{

    if (qdev_prop_set_drive(dev, name, value) < 0) {

        exit(1);

    }

}


static int piix3_post_load(void *opaque, int version_id)

{

    PIIX3State *piix3 = opaque;

    int pirq;

    /* Because the i8259 has not been deserialized yet, qemu_irq_raise

     * might bring the system to a different state than the saved one;

     * for example, the interrupt could be masked but the i8259 would

     * not know that yet and would trigger an interrupt in the CPU.

     *

     * Here, we update irq levels without raising the interrupt.

     * Interrupt state will be deserialized separately through the i8259.

     */

    piix3->pic_levels = 0;

    for (pirq = 0; pirq < PIIX_NUM_PIRQS; pirq++) {

        piix3_set_irq_level_internal(piix3, pirq,

                            pci_bus_get_irq_level(piix3->dev.bus, pirq));

    }

    return 0;

}


static void unset_dirty_tracking(void)

{

    BlkMigDevState *bmds;

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

        aio_context_acquire(blk_get_aio_context(bmds->blk));

        bdrv_release_dirty_bitmap(blk_bs(bmds->blk), bmds->dirty_bitmap);

        aio_context_release(blk_get_aio_context(bmds->blk));

    }

}


static void cb_hmp_change_bdrv_pwd(Monitor *mon, const char *password,

                                   void *opaque)

{

    Error *encryption_err = opaque;

    Error *err = NULL;

    const char *device;

    device = error_get_field(encryption_err, "device");

    qmp_block_passwd(device, password, &err);

    hmp_handle_error(mon, &err);

    error_free(encryption_err);

    monitor_read_command(mon, 1);

}


av_cold int ff_ivi_decode_close(AVCodecContext *avctx)

{

    IVI45DecContext *ctx = avctx->priv_data;

    ivi_free_buffers(&ctx->planes[0]);

    if (ctx->mb_vlc.cust_tab.table)

        ff_free_vlc(&ctx->mb_vlc.cust_tab);

#if IVI4_STREAM_ANALYSER

    if (ctx->is_indeo4) {

    if (ctx->is_scalable)

        av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n");

    if (ctx->uses_tiling)

        av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n");

    if (ctx->has_b_frames)

        av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n");

    if (ctx->has_transp)

        av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n");

    if (ctx->uses_haar)

        av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n");

    if (ctx->uses_fullpel)

        av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n");

    }

#endif

    av_frame_free(&ctx->p_frame);

    return 0;

}


static av_cold int cinepak_decode_init(AVCodecContext *avctx)

{

    CinepakContext *s = avctx->priv_data;

    s->avctx = avctx;

    s->width = (avctx->width + 3) & ~3;

    s->height = (avctx->height + 3) & ~3;

    s->sega_film_skip_bytes = -1;  /* uninitialized state */

    // check for paletted data

    if (avctx->bits_per_coded_sample != 8) {

        s->palette_video = 0;

        avctx->pix_fmt = AV_PIX_FMT_YUV420P;

    } else {

        s->palette_video = 1;

        avctx->pix_fmt = AV_PIX_FMT_PAL8;

    }

    s->frame.data[0] = NULL;

    return 0;

}


static int xen_host_pci_config_open(XenHostPCIDevice *d)

{

    char path[PATH_MAX];

    int rc;

    rc = xen_host_pci_sysfs_path(d, "config", path, sizeof (path));

    if (rc) {

        return rc;

    }

    d->config_fd = open(path, O_RDWR);

    if (d->config_fd < 0) {

        return -errno;

    }

    return 0;

}


void cpu_exec_init(CPUArchState *env)

{

    CPUState *cpu = ENV_GET_CPU(env);

    CPUClass *cc = CPU_GET_CLASS(cpu);

    CPUState *some_cpu;

    int cpu_index;

#if defined(CONFIG_USER_ONLY)

    cpu_list_lock();

#endif

    cpu_index = 0;

    CPU_FOREACH(some_cpu) {

        cpu_index++;

    }

    cpu->cpu_index = cpu_index;

    cpu->numa_node = 0;

    QTAILQ_INIT(&cpu->breakpoints);

    QTAILQ_INIT(&cpu->watchpoints);

#ifndef CONFIG_USER_ONLY

    cpu->as = &address_space_memory;

    cpu->thread_id = qemu_get_thread_id();

#endif

    QTAILQ_INSERT_TAIL(&cpus, cpu, node);

#if defined(CONFIG_USER_ONLY)

    cpu_list_unlock();

#endif

    if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {

        vmstate_register(NULL, cpu_index, &vmstate_cpu_common, cpu);

    }

#if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY)

    register_savevm(NULL, "cpu", cpu_index, CPU_SAVE_VERSION,

                    cpu_save, cpu_load, env);

    assert(cc->vmsd == NULL);

    assert(qdev_get_vmsd(DEVICE(cpu)) == NULL);

#endif

    if (cc->vmsd != NULL) {

        vmstate_register(NULL, cpu_index, cc->vmsd, cpu);

    }

}


static int vhost_set_vring_file(struct vhost_dev *dev,

                                VhostUserRequest request,

                                struct vhost_vring_file *file)

{

    int fds[VHOST_MEMORY_MAX_NREGIONS];

    size_t fd_num = 0;

    VhostUserMsg msg = {

        .request = request,

        .flags = VHOST_USER_VERSION,

        .payload.u64 = file->index & VHOST_USER_VRING_IDX_MASK,

        .size = sizeof(msg.payload.u64),

    };

    if (ioeventfd_enabled() && file->fd > 0) {

        fds[fd_num++] = file->fd;

    } else {

        msg.payload.u64 |= VHOST_USER_VRING_NOFD_MASK;

    }

    vhost_user_write(dev, &msg, fds, fd_num);

    return 0;

}


char *qdist_pr(const struct qdist *dist, size_t n_bins, uint32_t opt)

{

    const char *border = opt & QDIST_PR_BORDER ? "|" : "";

    char *llabel, *rlabel;

    char *hgram;

    GString *s;

    if (dist->n == 0) {

        return NULL;

    }

    s = g_string_new("");

    llabel = qdist_pr_label(dist, n_bins, opt, true);

    rlabel = qdist_pr_label(dist, n_bins, opt, false);

    hgram = qdist_pr_plain(dist, n_bins);

    g_string_append_printf(s, "%s%s%s%s%s",

                           llabel, border, hgram, border, rlabel);

    g_free(llabel);

    g_free(rlabel);

    g_free(hgram);

    return g_string_free(s, FALSE);

}


static int qemu_rdma_write_one(QEMUFile *f, RDMAContext *rdma,

                               int current_index, uint64_t current_addr,

                               uint64_t length)

{

    struct ibv_sge sge;

    struct ibv_send_wr send_wr = { 0 };

    struct ibv_send_wr *bad_wr;

    int reg_result_idx, ret, count = 0;

    uint64_t chunk, chunks;

    uint8_t *chunk_start, *chunk_end;

    RDMALocalBlock *block = &(rdma->local_ram_blocks.block[current_index]);

    RDMARegister reg;

    RDMARegisterResult *reg_result;

    RDMAControlHeader resp = { .type = RDMA_CONTROL_REGISTER_RESULT };

    RDMAControlHeader head = { .len = sizeof(RDMARegister),

                               .type = RDMA_CONTROL_REGISTER_REQUEST,

                               .repeat = 1,

                             };

retry:

    sge.addr = (uint64_t)(block->local_host_addr +

                            (current_addr - block->offset));

    sge.length = length;

    chunk = ram_chunk_index(block->local_host_addr, (uint8_t *) sge.addr);

    chunk_start = ram_chunk_start(block, chunk);

    if (block->is_ram_block) {

        chunks = length / (1UL << RDMA_REG_CHUNK_SHIFT);

        if (chunks && ((length % (1UL << RDMA_REG_CHUNK_SHIFT)) == 0)) {

            chunks--;

        }

    } else {

        chunks = block->length / (1UL << RDMA_REG_CHUNK_SHIFT);

        if (chunks && ((block->length % (1UL << RDMA_REG_CHUNK_SHIFT)) == 0)) {

            chunks--;

        }

    }

    DDPRINTF("Writing %" PRIu64 " chunks, (%" PRIu64 " MB)\n",

        chunks + 1, (chunks + 1) * (1UL << RDMA_REG_CHUNK_SHIFT) / 1024 / 1024);

    chunk_end = ram_chunk_end(block, chunk + chunks);

    if (!rdma->pin_all) {

#ifdef RDMA_UNREGISTRATION_EXAMPLE

        qemu_rdma_unregister_waiting(rdma);

#endif

    }

    while (test_bit(chunk, block->transit_bitmap)) {

        (void)count;

        DDPRINTF("(%d) Not clobbering: block: %d chunk %" PRIu64

                " current %" PRIu64 " len %" PRIu64 " %d %d\n",

                count++, current_index, chunk,

                sge.addr, length, rdma->nb_sent, block->nb_chunks);

        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);

        if (ret < 0) {

            fprintf(stderr, "Failed to Wait for previous write to complete "

                    "block %d chunk %" PRIu64

                    " current %" PRIu64 " len %" PRIu64 " %d\n",

                    current_index, chunk, sge.addr, length, rdma->nb_sent);

            return ret;

        }

    }

    if (!rdma->pin_all || !block->is_ram_block) {

        if (!block->remote_keys[chunk]) {

            /*

             * This chunk has not yet been registered, so first check to see

             * if the entire chunk is zero. If so, tell the other size to

             * memset() + madvise() the entire chunk without RDMA.

             */

            if (can_use_buffer_find_nonzero_offset((void *)sge.addr, length)

                   && buffer_find_nonzero_offset((void *)sge.addr,

                                                    length) == length) {

                RDMACompress comp = {

                                        .offset = current_addr,

                                        .value = 0,

                                        .block_idx = current_index,

                                        .length = length,

                                    };

                head.len = sizeof(comp);

                head.type = RDMA_CONTROL_COMPRESS;

                DDPRINTF("Entire chunk is zero, sending compress: %"

                    PRIu64 " for %d "

                    "bytes, index: %d, offset: %" PRId64 "...\n",

                    chunk, sge.length, current_index, current_addr);

                compress_to_network(&comp);

                ret = qemu_rdma_exchange_send(rdma, &head,

                                (uint8_t *) &comp, NULL, NULL, NULL);

                if (ret < 0) {

                    return -EIO;

                }

                acct_update_position(f, sge.length, true);

                return 1;

            }

            /*

             * Otherwise, tell other side to register.

             */

            reg.current_index = current_index;

            if (block->is_ram_block) {

                reg.key.current_addr = current_addr;

            } else {

                reg.key.chunk = chunk;

            }

            reg.chunks = chunks;

            DDPRINTF("Sending registration request chunk %" PRIu64 " for %d "

                    "bytes, index: %d, offset: %" PRId64 "...\n",

                    chunk, sge.length, current_index, current_addr);

            register_to_network(&reg);

            ret = qemu_rdma_exchange_send(rdma, &head, (uint8_t *) &reg,

                                    &resp, &reg_result_idx, NULL);

            if (ret < 0) {

                return ret;

            }

            /* try to overlap this single registration with the one we sent. */

            if (qemu_rdma_register_and_get_keys(rdma, block,

                                                (uint8_t *) sge.addr,

                                                &sge.lkey, NULL, chunk,

                                                chunk_start, chunk_end)) {

                fprintf(stderr, "cannot get lkey!\n");

                return -EINVAL;

            }

            reg_result = (RDMARegisterResult *)

                    rdma->wr_data[reg_result_idx].control_curr;

            network_to_result(reg_result);

            DDPRINTF("Received registration result:"

                    " my key: %x their key %x, chunk %" PRIu64 "\n",

                    block->remote_keys[chunk], reg_result->rkey, chunk);

            block->remote_keys[chunk] = reg_result->rkey;

            block->remote_host_addr = reg_result->host_addr;

        } else {

            /* already registered before */

            if (qemu_rdma_register_and_get_keys(rdma, block,

                                                (uint8_t *)sge.addr,

                                                &sge.lkey, NULL, chunk,

                                                chunk_start, chunk_end)) {

                fprintf(stderr, "cannot get lkey!\n");

                return -EINVAL;

            }

        }

        send_wr.wr.rdma.rkey = block->remote_keys[chunk];

    } else {

        send_wr.wr.rdma.rkey = block->remote_rkey;

        if (qemu_rdma_register_and_get_keys(rdma, block, (uint8_t *)sge.addr,

                                                     &sge.lkey, NULL, chunk,

                                                     chunk_start, chunk_end)) {

            fprintf(stderr, "cannot get lkey!\n");

            return -EINVAL;

        }

    }

    /*

     * Encode the ram block index and chunk within this wrid.

     * We will use this information at the time of completion

     * to figure out which bitmap to check against and then which

     * chunk in the bitmap to look for.

     */

    send_wr.wr_id = qemu_rdma_make_wrid(RDMA_WRID_RDMA_WRITE,

                                        current_index, chunk);

    send_wr.opcode = IBV_WR_RDMA_WRITE;

    send_wr.send_flags = IBV_SEND_SIGNALED;

    send_wr.sg_list = &sge;

    send_wr.num_sge = 1;

    send_wr.wr.rdma.remote_addr = block->remote_host_addr +

                                (current_addr - block->offset);

    DDDPRINTF("Posting chunk: %" PRIu64 ", addr: %lx"

              " remote: %lx, bytes %" PRIu32 "\n",

              chunk, sge.addr, send_wr.wr.rdma.remote_addr,

              sge.length);

    /*

     * ibv_post_send() does not return negative error numbers,

     * per the specification they are positive - no idea why.

     */

    ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);

    if (ret == ENOMEM) {

        DDPRINTF("send queue is full. wait a little....\n");

        ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_RDMA_WRITE, NULL);

        if (ret < 0) {

            fprintf(stderr, "rdma migration: failed to make "

                            "room in full send queue! %d\n", ret);

            return ret;

        }

        goto retry;

    } else if (ret > 0) {

        perror("rdma migration: post rdma write failed");

        return -ret;

    }

    set_bit(chunk, block->transit_bitmap);

    acct_update_position(f, sge.length, false);

    rdma->total_writes++;

    return 0;

}


static int init_directories(BDRVVVFATState* s,

	const char* dirname)

{

    bootsector_t* bootsector;

    mapping_t* mapping;

    unsigned int i;

    unsigned int cluster;

    memset(&(s->first_sectors[0]),0,0x40*0x200);

    s->cluster_size=s->sectors_per_cluster*0x200;

    s->cluster_buffer=qemu_malloc(s->cluster_size);

    /*

     * The formula: sc = spf+1+spf*spc*(512*8/fat_type),

     * where sc is sector_count,

     * spf is sectors_per_fat,

     * spc is sectors_per_clusters, and

     * fat_type = 12, 16 or 32.

     */

    i = 1+s->sectors_per_cluster*0x200*8/s->fat_type;

    s->sectors_per_fat=(s->sector_count+i)/i; /* round up */

    array_init(&(s->mapping),sizeof(mapping_t));

    array_init(&(s->directory),sizeof(direntry_t));

    /* add volume label */

    {

	direntry_t* entry=array_get_next(&(s->directory));

	entry->attributes=0x28; /* archive | volume label */

	snprintf((char*)entry->name,11,"QEMU VVFAT");

    }

    /* Now build FAT, and write back information into directory */

    init_fat(s);

    s->faked_sectors=s->first_sectors_number+s->sectors_per_fat*2;

    s->cluster_count=sector2cluster(s, s->sector_count);

    mapping = array_get_next(&(s->mapping));

    mapping->begin = 0;

    mapping->dir_index = 0;

    mapping->info.dir.parent_mapping_index = -1;

    mapping->first_mapping_index = -1;

    mapping->path = strdup(dirname);

    i = strlen(mapping->path);

    if (i > 0 && mapping->path[i - 1] == '/')

	mapping->path[i - 1] = '\0';

    mapping->mode = MODE_DIRECTORY;

    mapping->read_only = 0;

    s->path = mapping->path;

    for (i = 0, cluster = 0; i < s->mapping.next; i++) {

	/* MS-DOS expects the FAT to be 0 for the root directory

	 * (except for the media byte). */

	/* LATER TODO: still true for FAT32? */

	int fix_fat = (i != 0);

	mapping = array_get(&(s->mapping), i);

        if (mapping->mode & MODE_DIRECTORY) {

	    mapping->begin = cluster;

	    if(read_directory(s, i)) {

		fprintf(stderr, "Could not read directory %s\n",

			mapping->path);

		return -1;

	    }

	    mapping = array_get(&(s->mapping), i);

	} else {

	    assert(mapping->mode == MODE_UNDEFINED);

	    mapping->mode=MODE_NORMAL;

	    mapping->begin = cluster;

	    if (mapping->end > 0) {

		direntry_t* direntry = array_get(&(s->directory),

			mapping->dir_index);

		mapping->end = cluster + 1 + (mapping->end-1)/s->cluster_size;

		set_begin_of_direntry(direntry, mapping->begin);

	    } else {

		mapping->end = cluster + 1;

		fix_fat = 0;

	    }

	}

	assert(mapping->begin < mapping->end);

	/* next free cluster */

	cluster = mapping->end;

	if(cluster > s->cluster_count) {

	    fprintf(stderr,"Directory does not fit in FAT%d (capacity %s)\n",

		    s->fat_type,

		    s->fat_type == 12 ? s->sector_count == 2880 ? "1.44 MB"

								: "2.88 MB"

				      : "504MB");

	    return -EINVAL;

	}

	/* fix fat for entry */

	if (fix_fat) {

	    int j;

	    for(j = mapping->begin; j < mapping->end - 1; j++)

		fat_set(s, j, j+1);

	    fat_set(s, mapping->end - 1, s->max_fat_value);

	}

    }

    mapping = array_get(&(s->mapping), 0);

    s->sectors_of_root_directory = mapping->end * s->sectors_per_cluster;

    s->last_cluster_of_root_directory = mapping->end;

    /* the FAT signature */

    fat_set(s,0,s->max_fat_value);

    fat_set(s,1,s->max_fat_value);

    s->current_mapping = NULL;

    bootsector=(bootsector_t*)(s->first_sectors+(s->first_sectors_number-1)*0x200);

    bootsector->jump[0]=0xeb;

    bootsector->jump[1]=0x3e;

    bootsector->jump[2]=0x90;

    memcpy(bootsector->name,"QEMU    ",8);

    bootsector->sector_size=cpu_to_le16(0x200);

    bootsector->sectors_per_cluster=s->sectors_per_cluster;

    bootsector->reserved_sectors=cpu_to_le16(1);

    bootsector->number_of_fats=0x2; /* number of FATs */

    bootsector->root_entries=cpu_to_le16(s->sectors_of_root_directory*0x10);

    bootsector->total_sectors16=s->sector_count>0xffff?0:cpu_to_le16(s->sector_count);

    bootsector->media_type=(s->fat_type!=12?0xf8:s->sector_count==5760?0xf9:0xf8); /* media descriptor */

    s->fat.pointer[0] = bootsector->media_type;

    bootsector->sectors_per_fat=cpu_to_le16(s->sectors_per_fat);

    bootsector->sectors_per_track=cpu_to_le16(s->bs->secs);

    bootsector->number_of_heads=cpu_to_le16(s->bs->heads);

    bootsector->hidden_sectors=cpu_to_le32(s->first_sectors_number==1?0:0x3f);

    bootsector->total_sectors=cpu_to_le32(s->sector_count>0xffff?s->sector_count:0);

    /* LATER TODO: if FAT32, this is wrong */

    bootsector->u.fat16.drive_number=s->fat_type==12?0:0x80; /* assume this is hda (TODO) */

    bootsector->u.fat16.current_head=0;

    bootsector->u.fat16.signature=0x29;

    bootsector->u.fat16.id=cpu_to_le32(0xfabe1afd);

    memcpy(bootsector->u.fat16.volume_label,"QEMU VVFAT ",11);

    memcpy(bootsector->fat_type,(s->fat_type==12?"FAT12   ":s->fat_type==16?"FAT16   ":"FAT32   "),8);

    bootsector->magic[0]=0x55; bootsector->magic[1]=0xaa;

    return 0;

}


static int mpegts_read_header(AVFormatContext *s)

{

    MpegTSContext *ts = s->priv_data;

    AVIOContext *pb   = s->pb;

    uint8_t buf[8 * 1024] = {0};

    int len;

    int64_t pos, probesize = s->probesize;

    if (ffio_ensure_seekback(pb, probesize) < 0)

        av_log(s, AV_LOG_WARNING, "Failed to allocate buffers for seekback\n");

    /* read the first 8192 bytes to get packet size */

    pos = avio_tell(pb);

    len = avio_read(pb, buf, sizeof(buf));

    ts->raw_packet_size = get_packet_size(buf, len);

    if (ts->raw_packet_size <= 0) {

        av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n");

        ts->raw_packet_size = TS_PACKET_SIZE;

    }

    ts->stream     = s;

    ts->auto_guess = 0;

    if (s->iformat == &ff_mpegts_demuxer) {

        /* normal demux */

        /* first do a scan to get all the services */

        seek_back(s, pb, pos);

        mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1);

        mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1);

        handle_packets(ts, probesize / ts->raw_packet_size);

        /* if could not find service, enable auto_guess */

        ts->auto_guess = 1;

        av_log(ts->stream, AV_LOG_TRACE, "tuning done\n");

        s->ctx_flags |= AVFMTCTX_NOHEADER;

    } else {

        AVStream *st;

        int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l;

        int64_t pcrs[2], pcr_h;

        int packet_count[2];

        uint8_t packet[TS_PACKET_SIZE];

        const uint8_t *data;

        /* only read packets */

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        avpriv_set_pts_info(st, 60, 1, 27000000);

        st->codecpar->codec_type = AVMEDIA_TYPE_DATA;

        st->codecpar->codec_id   = AV_CODEC_ID_MPEG2TS;

        /* we iterate until we find two PCRs to estimate the bitrate */

        pcr_pid    = -1;

        nb_pcrs    = 0;

        nb_packets = 0;

        for (;;) {

            ret = read_packet(s, packet, ts->raw_packet_size, &data);

            if (ret < 0)

                return ret;

            pid = AV_RB16(data + 1) & 0x1fff;

            if ((pcr_pid == -1 || pcr_pid == pid) &&

                parse_pcr(&pcr_h, &pcr_l, data) == 0) {

                finished_reading_packet(s, ts->raw_packet_size);

                pcr_pid = pid;

                packet_count[nb_pcrs] = nb_packets;

                pcrs[nb_pcrs] = pcr_h * 300 + pcr_l;

                nb_pcrs++;

                if (nb_pcrs >= 2)

                    break;

            } else {

                finished_reading_packet(s, ts->raw_packet_size);

            }

            nb_packets++;

        }

        /* NOTE1: the bitrate is computed without the FEC */

        /* NOTE2: it is only the bitrate of the start of the stream */

        ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]);

        ts->cur_pcr  = pcrs[0] - ts->pcr_incr * packet_count[0];

        s->bit_rate  = TS_PACKET_SIZE * 8 * 27000000LL / ts->pcr_incr;

        st->codecpar->bit_rate = s->bit_rate;

        st->start_time      = ts->cur_pcr;

        av_log(ts->stream, AV_LOG_TRACE, "start=%0.3f pcr=%0.3f incr=%d\n",

                st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr);

    }

    seek_back(s, pb, pos);

    return 0;

}


static QPCIDevice *get_ahci_device(uint32_t *fingerprint)

{

    QPCIDevice *ahci;

    uint32_t ahci_fingerprint;

    QPCIBus *pcibus;

    pcibus = qpci_init_pc();

    /* Find the AHCI PCI device and verify it's the right one. */

    ahci = qpci_device_find(pcibus, QPCI_DEVFN(0x1F, 0x02));

    g_assert(ahci != NULL);

    ahci_fingerprint = qpci_config_readl(ahci, PCI_VENDOR_ID);

    switch (ahci_fingerprint) {

    case AHCI_INTEL_ICH9:

        break;

    default:

        /* Unknown device. */

        g_assert_not_reached();

    }

    if (fingerprint) {

        *fingerprint = ahci_fingerprint;

    }

    return ahci;

}


static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)

{

    int i;

    uint16_t limit;

    switch (data[0]) {

    case 0:

	if (len == 1)

	    return 20;

	set_pixel_format(vs, read_u8(data, 4), read_u8(data, 5),

			 read_u8(data, 6), read_u8(data, 7),

			 read_u16(data, 8), read_u16(data, 10),

			 read_u16(data, 12), read_u8(data, 14),

			 read_u8(data, 15), read_u8(data, 16));

	break;

    case 2:

	if (len == 1)

	    return 4;

	if (len == 4)

	    return 4 + (read_u16(data, 2) * 4);

	limit = read_u16(data, 2);

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

	    int32_t val = read_s32(data, 4 + (i * 4));

	    memcpy(data + 4 + (i * 4), &val, sizeof(val));

	}

	set_encodings(vs, (int32_t *)(data + 4), limit);

	break;

    case 3:

	if (len == 1)

	    return 10;

	framebuffer_update_request(vs,

				   read_u8(data, 1), read_u16(data, 2), read_u16(data, 4),

				   read_u16(data, 6), read_u16(data, 8));

	break;

    case 4:

	if (len == 1)

	    return 8;

	key_event(vs, read_u8(data, 1), read_u32(data, 4));

	break;

    case 5:

	if (len == 1)

	    return 6;

	pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4));

	break;

    case 6:

	if (len == 1)

	    return 8;

	if (len == 8) {

            uint32_t dlen = read_u32(data, 4);

            if (dlen > 0)

                return 8 + dlen;

        }

	client_cut_text(vs, read_u32(data, 4), data + 8);

	break;

    case 255:

        if (len == 1)

            return 2;

        switch (read_u8(data, 1)) {

        case 0:

            if (len == 2)

                return 12;

            ext_key_event(vs, read_u16(data, 2),

                          read_u32(data, 4), read_u32(data, 8));

            break;

        case 1:

            if (len == 2)

                return 4;

            switch (read_u16 (data, 2)) {

            case 0:

                audio_add(vs);

                break;

            case 1:

                audio_del(vs);

                break;

            case 2:

                if (len == 4)

                    return 10;

                switch (read_u8(data, 4)) {

                case 0: vs->as.fmt = AUD_FMT_U8; break;

                case 1: vs->as.fmt = AUD_FMT_S8; break;

                case 2: vs->as.fmt = AUD_FMT_U16; break;

                case 3: vs->as.fmt = AUD_FMT_S16; break;

                case 4: vs->as.fmt = AUD_FMT_U32; break;

                case 5: vs->as.fmt = AUD_FMT_S32; break;

                default:

                    printf("Invalid audio format %d\n", read_u8(data, 4));

                    vnc_client_error(vs);

                    break;

                }

                vs->as.nchannels = read_u8(data, 5);

                if (vs->as.nchannels != 1 && vs->as.nchannels != 2) {

                    printf("Invalid audio channel coount %d\n",

                           read_u8(data, 5));

                    vnc_client_error(vs);

                    break;

                }

                vs->as.freq = read_u32(data, 6);

                break;

            default:

                printf ("Invalid audio message %d\n", read_u8(data, 4));

                vnc_client_error(vs);

                break;

            }

            break;

        default:

            printf("Msg: %d\n", read_u16(data, 0));

            vnc_client_error(vs);

            break;

        }

        break;

    default:

	printf("Msg: %d\n", data[0]);

	vnc_client_error(vs);

	break;

    }

    vnc_read_when(vs, protocol_client_msg, 1);

    return 0;

}


static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
                        AVPacket *avpkt) {
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    AVSubtitle *sub = data;
    const uint8_t *buf_end = buf + buf_size;
    uint8_t *bitmap;
    int w, h, x, y, i, ret;
    int64_t packet_time = 0;
    GetBitContext gb;
    int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A');
    // check that at least header fits
    if (buf_size < 27 + 7 * 2 + 4 * (3 + has_alpha)) {
        av_log(avctx, AV_LOG_ERROR, "coded frame size %d too small\n", buf_size);
        return -1;
    }
    // read start and end time
    if (buf[0] != '[' || buf[13] != '-' || buf[26] != ']') {
        av_log(avctx, AV_LOG_ERROR, "invalid time code\n");
        return -1;
    }
    if (avpkt->pts != AV_NOPTS_VALUE)
        packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000});
    sub->start_display_time = parse_timecode(buf +  1, packet_time);
    sub->end_display_time   = parse_timecode(buf + 14, packet_time);
    buf += 27;
    // read header
    w = bytestream_get_le16(&buf);
    h = bytestream_get_le16(&buf);
    if (av_image_check_size(w, h, 0, avctx) < 0)
        return -1;
    x = bytestream_get_le16(&buf);
    y = bytestream_get_le16(&buf);
    // skip bottom right position, it gives no new information
    bytestream_get_le16(&buf);
    bytestream_get_le16(&buf);
    // The following value is supposed to indicate the start offset
    // (relative to the palette) of the data for the second field,
    // however there are files in which it has a bogus value and thus
    // we just ignore it
    bytestream_get_le16(&buf);
    // allocate sub and set values
    sub->rects =  av_mallocz(sizeof(*sub->rects));
    if (!sub->rects)
        return AVERROR(ENOMEM);
    sub->rects[0] = av_mallocz(sizeof(*sub->rects[0]));
    if (!sub->rects[0]) {
        av_freep(&sub->rects);
        return AVERROR(ENOMEM);
    }
    sub->rects[0]->x = x; sub->rects[0]->y = y;
    sub->rects[0]->w = w; sub->rects[0]->h = h;
    sub->rects[0]->type = SUBTITLE_BITMAP;
    sub->rects[0]->linesize[0] = w;
    sub->rects[0]->data[0] = av_malloc(w * h);
    sub->rects[0]->nb_colors = 4;
    sub->rects[0]->data[1] = av_mallocz(AVPALETTE_SIZE);
    if (!sub->rects[0]->data[0] || !sub->rects[0]->data[1]) {
        av_freep(&sub->rects[0]->data[1]);
        av_freep(&sub->rects[0]->data[0]);
        av_freep(&sub->rects[0]);
        av_freep(&sub->rects);
        return AVERROR(ENOMEM);
    }
    sub->num_rects = 1;
    // read palette
    for (i = 0; i < sub->rects[0]->nb_colors; i++)
        ((uint32_t*)sub->rects[0]->data[1])[i] = bytestream_get_be24(&buf);
    if (!has_alpha) {
        // make all except background (first entry) non-transparent
        for (i = 1; i < sub->rects[0]->nb_colors; i++)
            ((uint32_t *)sub->rects[0]->data[1])[i] |= 0xff000000;
    } else {
        for (i = 0; i < sub->rects[0]->nb_colors; i++)
            ((uint32_t *)sub->rects[0]->data[1])[i] |= *buf++ << 24;
    }
#if FF_API_AVPICTURE
FF_DISABLE_DEPRECATION_WARNINGS
{
    AVSubtitleRect *rect;
    int j;
    rect = sub->rects[0];
    for (j = 0; j < 4; j++) {
        rect->pict.data[j] = rect->data[j];
        rect->pict.linesize[j] = rect->linesize[j];
    }
}
FF_ENABLE_DEPRECATION_WARNINGS
#endif
    // process RLE-compressed data
    if ((ret = init_get_bits8(&gb, buf, buf_end - buf)) < 0)
        return ret;
    bitmap = sub->rects[0]->data[0];
    for (y = 0; y < h; y++) {
        // interlaced: do odd lines
        if (y == (h + 1) / 2) bitmap = sub->rects[0]->data[0] + w;
        for (x = 0; x < w; ) {
            int log2 = ff_log2_tab[show_bits(&gb, 8)];
            int run = get_bits(&gb, 14 - 4 * (log2 >> 1));
            int color = get_bits(&gb, 2);
            run = FFMIN(run, w - x);
            // run length 0 means till end of row
            if (!run) run = w - x;
            memset(bitmap, color, run);
            bitmap += run;
            x += run;
        }
        // interlaced, skip every second line
        bitmap += w;
        align_get_bits(&gb);
    }
    *data_size = 1;
    return buf_size;
}


static void tpm_tis_initfn(Object *obj)

{

    ISADevice *dev = ISA_DEVICE(obj);

    TPMState *s = TPM(obj);

    memory_region_init_io(&s->mmio, OBJECT(s), &tpm_tis_memory_ops,

                          s, "tpm-tis-mmio",

                          TPM_TIS_NUM_LOCALITIES << TPM_TIS_LOCALITY_SHIFT);

    memory_region_add_subregion(isa_address_space(dev), TPM_TIS_ADDR_BASE,

                                &s->mmio);

}


static int process_frame(FFFrameSync *fs)

{

    AVFilterContext *ctx = fs->parent;

    LUT2Context *s = fs->opaque;

    AVFilterLink *outlink = ctx->outputs[0];

    AVFrame *out, *srcx, *srcy;

    int ret;

    if ((ret = ff_framesync2_get_frame(&s->fs, 0, &srcx, 0)) < 0 ||

        (ret = ff_framesync2_get_frame(&s->fs, 1, &srcy, 0)) < 0)

        return ret;

    if (ctx->is_disabled) {

        out = av_frame_clone(srcx);

        if (!out)

            return AVERROR(ENOMEM);

    } else {

        out = ff_get_video_buffer(outlink, outlink->w, outlink->h);

        if (!out)

            return AVERROR(ENOMEM);

        av_frame_copy_props(out, srcx);

        s->lut2(s, out, srcx, srcy);

    }

    out->pts = av_rescale_q(s->fs.pts, s->fs.time_base, outlink->time_base);

    return ff_filter_frame(outlink, out);

}


static int handle_primary_tcp_pkt(NetFilterState *nf,

                                  Connection *conn,

                                  Packet *pkt)

{

    struct tcphdr *tcp_pkt;

    tcp_pkt = (struct tcphdr *)pkt->transport_header;

    if (trace_event_get_state_backends(TRACE_COLO_FILTER_REWRITER_DEBUG)) {

        trace_colo_filter_rewriter_pkt_info(__func__,

                    inet_ntoa(pkt->ip->ip_src), inet_ntoa(pkt->ip->ip_dst),

                    ntohl(tcp_pkt->th_seq), ntohl(tcp_pkt->th_ack),

                    tcp_pkt->th_flags);

        trace_colo_filter_rewriter_conn_offset(conn->offset);

    }

    if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) == TH_SYN)) {

        /*

         * we use this flag update offset func

         * run once in independent tcp connection

         */

        conn->syn_flag = 1;

    }

    if (((tcp_pkt->th_flags & (TH_ACK | TH_SYN)) == TH_ACK)) {

        if (conn->syn_flag) {

            /*

             * offset = secondary_seq - primary seq

             * ack packet sent by guest from primary node,

             * so we use th_ack - 1 get primary_seq

             */

            conn->offset -= (ntohl(tcp_pkt->th_ack) - 1);

            conn->syn_flag = 0;

        }

        if (conn->offset) {

            /* handle packets to the secondary from the primary */

            tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset);

            net_checksum_calculate((uint8_t *)pkt->data, pkt->size);

        }

    }

    return 0;

}