static av_always_inline void hl_decode_mb_internal(H264Context *h, int simple){

    MpegEncContext * const s = &h->s;

    const int mb_x= s->mb_x;

    const int mb_y= s->mb_y;

    const int mb_xy= h->mb_xy;

    const int mb_type= s->current_picture.mb_type[mb_xy];

    uint8_t  *dest_y, *dest_cb, *dest_cr;

    int linesize, uvlinesize /*dct_offset*/;

    int i;

    int *block_offset = &h->block_offset[0];

    const int transform_bypass = !simple && (s->qscale == 0 && h->sps.transform_bypass);

    const int is_h264 = simple || s->codec_id == CODEC_ID_H264;

    void (*idct_add)(uint8_t *dst, DCTELEM *block, int stride);

    void (*idct_dc_add)(uint8_t *dst, DCTELEM *block, int stride);

    dest_y  = s->current_picture.data[0] + (mb_x + mb_y * s->linesize  ) * 16;

    dest_cb = s->current_picture.data[1] + (mb_x + mb_y * s->uvlinesize) * 8;

    dest_cr = s->current_picture.data[2] + (mb_x + mb_y * s->uvlinesize) * 8;

    s->dsp.prefetch(dest_y + (s->mb_x&3)*4*s->linesize + 64, s->linesize, 4);

    s->dsp.prefetch(dest_cb + (s->mb_x&7)*s->uvlinesize + 64, dest_cr - dest_cb, 2);

    if (!simple && MB_FIELD) {

        linesize   = h->mb_linesize   = s->linesize * 2;

        uvlinesize = h->mb_uvlinesize = s->uvlinesize * 2;

        block_offset = &h->block_offset[24];

        if(mb_y&1){ //FIXME move out of this function?

            dest_y -= s->linesize*15;

            dest_cb-= s->uvlinesize*7;

            dest_cr-= s->uvlinesize*7;

        }

        if(FRAME_MBAFF) {

            int list;

            for(list=0; list<h->list_count; list++){

                if(!USES_LIST(mb_type, list))

                    continue;

                if(IS_16X16(mb_type)){

                    int8_t *ref = &h->ref_cache[list][scan8[0]];

                    fill_rectangle(ref, 4, 4, 8, (16+*ref)^(s->mb_y&1), 1);

                }else{

                    for(i=0; i<16; i+=4){

                        int ref = h->ref_cache[list][scan8[i]];

                        if(ref >= 0)

                            fill_rectangle(&h->ref_cache[list][scan8[i]], 2, 2, 8, (16+ref)^(s->mb_y&1), 1);

                    }

                }

            }

        }

    } else {

        linesize   = h->mb_linesize   = s->linesize;

        uvlinesize = h->mb_uvlinesize = s->uvlinesize;

//        dct_offset = s->linesize * 16;

    }

    if (!simple && IS_INTRA_PCM(mb_type)) {

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

            memcpy(dest_y + i*  linesize, h->mb       + i*8, 16);

        }

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

            memcpy(dest_cb+ i*uvlinesize, h->mb + 128 + i*4,  8);

            memcpy(dest_cr+ i*uvlinesize, h->mb + 160 + i*4,  8);

        }

    } else {

        if(IS_INTRA(mb_type)){

            if(h->deblocking_filter)

                xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 1, simple);

            if(simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)){

                h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cb, uvlinesize);

                h->hpc.pred8x8[ h->chroma_pred_mode ](dest_cr, uvlinesize);

            }

            if(IS_INTRA4x4(mb_type)){

                if(simple || !s->encoding){

                    if(IS_8x8DCT(mb_type)){

                        if(transform_bypass){

                            idct_dc_add =

                            idct_add    = s->dsp.add_pixels8;

                        }else if(IS_8x8DCT(mb_type)){

                            idct_dc_add = s->dsp.h264_idct8_dc_add;

                            idct_add    = s->dsp.h264_idct8_add;

                        }

                        for(i=0; i<16; i+=4){

                            uint8_t * const ptr= dest_y + block_offset[i];

                            const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ];

                            if(transform_bypass && h->sps.profile_idc==244 && dir<=1){

                                h->hpc.pred8x8l_add[dir](ptr, h->mb + i*16, linesize);

                            }else{

                                const int nnz = h->non_zero_count_cache[ scan8[i] ];

                                h->hpc.pred8x8l[ dir ](ptr, (h->topleft_samples_available<<i)&0x8000,

                                                            (h->topright_samples_available<<i)&0x4000, linesize);

                                if(nnz){

                                    if(nnz == 1 && h->mb[i*16])

                                        idct_dc_add(ptr, h->mb + i*16, linesize);

                                    else

                                        idct_add   (ptr, h->mb + i*16, linesize);

                                }

                            }

                        }

                    }else{

                        if(transform_bypass){

                            idct_dc_add =

                            idct_add    = s->dsp.add_pixels4;

                        }else{

                            idct_dc_add = s->dsp.h264_idct_dc_add;

                            idct_add    = s->dsp.h264_idct_add;

                        }

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

                        uint8_t * const ptr= dest_y + block_offset[i];

                        const int dir= h->intra4x4_pred_mode_cache[ scan8[i] ];

                        if(transform_bypass && h->sps.profile_idc==244 && dir<=1){

                            h->hpc.pred4x4_add[dir](ptr, h->mb + i*16, linesize);

                        }else{

                            uint8_t *topright;

                            int nnz, tr;

                            if(dir == DIAG_DOWN_LEFT_PRED || dir == VERT_LEFT_PRED){

                                const int topright_avail= (h->topright_samples_available<<i)&0x8000;

                                assert(mb_y || linesize <= block_offset[i]);

                                if(!topright_avail){

                                    tr= ptr[3 - linesize]*0x01010101;

                                    topright= (uint8_t*) &tr;

                                }else

                                    topright= ptr + 4 - linesize;

                            }else

                                topright= NULL;

                            h->hpc.pred4x4[ dir ](ptr, topright, linesize);

                            nnz = h->non_zero_count_cache[ scan8[i] ];

                            if(nnz){

                                if(is_h264){

                                    if(nnz == 1 && h->mb[i*16])

                                        idct_dc_add(ptr, h->mb + i*16, linesize);

                                    else

                                        idct_add   (ptr, h->mb + i*16, linesize);

                                }else

                                    svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, 0);

                            }

                        }

                    }

                    }

                }

            }else{

                h->hpc.pred16x16[ h->intra16x16_pred_mode ](dest_y , linesize);

                if(is_h264){

                    if(!transform_bypass)

                        h264_luma_dc_dequant_idct_c(h->mb, s->qscale, h->dequant4_coeff[0][s->qscale][0]);

                }else

                    svq3_luma_dc_dequant_idct_c(h->mb, s->qscale);

            }

            if(h->deblocking_filter)

                xchg_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, 0, simple);

        }else if(is_h264){

            hl_motion(h, dest_y, dest_cb, dest_cr,

                      s->me.qpel_put, s->dsp.put_h264_chroma_pixels_tab,

                      s->me.qpel_avg, s->dsp.avg_h264_chroma_pixels_tab,

                      s->dsp.weight_h264_pixels_tab, s->dsp.biweight_h264_pixels_tab);

        }

        if(!IS_INTRA4x4(mb_type)){

            if(is_h264){

                if(IS_INTRA16x16(mb_type)){

                    if(transform_bypass){

                        if(h->sps.profile_idc==244 && (h->intra16x16_pred_mode==VERT_PRED8x8 || h->intra16x16_pred_mode==HOR_PRED8x8)){

                            h->hpc.pred16x16_add[h->intra16x16_pred_mode](dest_y, block_offset, h->mb, linesize);

                        }else{

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

                                if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16])

                                    s->dsp.add_pixels4(dest_y + block_offset[i], h->mb + i*16, linesize);

                            }

                        }

                    }else{

                         s->dsp.h264_idct_add16intra(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);

                    }

                }else if(h->cbp&15){

                    if(transform_bypass){

                        const int di = IS_8x8DCT(mb_type) ? 4 : 1;

                        idct_add= IS_8x8DCT(mb_type) ? s->dsp.add_pixels8 : s->dsp.add_pixels4;

                        for(i=0; i<16; i+=di){

                            if(h->non_zero_count_cache[ scan8[i] ]){

                                idct_add(dest_y + block_offset[i], h->mb + i*16, linesize);

                            }

                        }

                    }else{

                        if(IS_8x8DCT(mb_type)){

                            s->dsp.h264_idct8_add4(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);

                        }else{

                            s->dsp.h264_idct_add16(dest_y, block_offset, h->mb, linesize, h->non_zero_count_cache);

                        }

                    }

                }

            }else{

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

                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){ //FIXME benchmark weird rule, & below

                        uint8_t * const ptr= dest_y + block_offset[i];

                        svq3_add_idct_c(ptr, h->mb + i*16, linesize, s->qscale, IS_INTRA(mb_type) ? 1 : 0);

                    }

                }

            }

        }

        if((simple || !ENABLE_GRAY || !(s->flags&CODEC_FLAG_GRAY)) && (h->cbp&0x30)){

            uint8_t *dest[2] = {dest_cb, dest_cr};

            if(transform_bypass){

                idct_add = idct_dc_add = s->dsp.add_pixels4;

            }else{

                idct_add = s->dsp.h264_idct_add;

                idct_dc_add = s->dsp.h264_idct_dc_add;

                chroma_dc_dequant_idct_c(h->mb + 16*16, h->chroma_qp[0], h->dequant4_coeff[IS_INTRA(mb_type) ? 1:4][h->chroma_qp[0]][0]);

                chroma_dc_dequant_idct_c(h->mb + 16*16+4*16, h->chroma_qp[1], h->dequant4_coeff[IS_INTRA(mb_type) ? 2:5][h->chroma_qp[1]][0]);

            }

            if(is_h264){

                if(transform_bypass && IS_INTRA(mb_type) && h->sps.profile_idc==244 && (h->chroma_pred_mode==VERT_PRED8x8 || h->chroma_pred_mode==HOR_PRED8x8)){

                    h->hpc.pred8x8_add[h->chroma_pred_mode](dest[0], block_offset + 16, h->mb + 16*16, uvlinesize);

                    h->hpc.pred8x8_add[h->chroma_pred_mode](dest[1], block_offset + 20, h->mb + 20*16, uvlinesize);

                }else{

                    for(i=16; i<16+8; i++){

                        if(h->non_zero_count_cache[ scan8[i] ])

                            idct_add   (dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize);

                        else if(h->mb[i*16])

                            idct_dc_add(dest[(i&4)>>2] + block_offset[i], h->mb + i*16, uvlinesize);

                    }

                }

            }else{

                for(i=16; i<16+8; i++){

                    if(h->non_zero_count_cache[ scan8[i] ] || h->mb[i*16]){

                        uint8_t * const ptr= dest[(i&4)>>2] + block_offset[i];

                        svq3_add_idct_c(ptr, h->mb + i*16, uvlinesize, chroma_qp[s->qscale + 12] - 12, 2);

                    }

                }

            }

        }

    }

    if(h->deblocking_filter) {

        backup_mb_border(h, dest_y, dest_cb, dest_cr, linesize, uvlinesize, simple);

        fill_caches(h, mb_type, 1); //FIXME don't fill stuff which isn't used by filter_mb

        h->chroma_qp[0] = get_chroma_qp(h, 0, s->current_picture.qscale_table[mb_xy]);

        h->chroma_qp[1] = get_chroma_qp(h, 1, s->current_picture.qscale_table[mb_xy]);

        if (!simple && FRAME_MBAFF) {

            filter_mb     (h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);

        } else {

            filter_mb_fast(h, mb_x, mb_y, dest_y, dest_cb, dest_cr, linesize, uvlinesize);

        }

    }

}


static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,

                                    void *opaque)

{

    const VMStateSubsection *sub = vmsd->subsections;

    while (sub && sub->needed) {

        if (sub->needed(opaque)) {

            const VMStateDescription *vmsd = sub->vmsd;

            uint8_t len;

            qemu_put_byte(f, QEMU_VM_SUBSECTION);

            len = strlen(vmsd->name);

            qemu_put_byte(f, len);

            qemu_put_buffer(f, (uint8_t *)vmsd->name, len);

            qemu_put_be32(f, vmsd->version_id);

            assert(!vmsd->subsections);

            vmstate_save_state(f, vmsd, opaque);

        }

        sub++;

    }

}


static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],

                          const SoftFloat *g_filt, int m_max, intptr_t ixh)

{

    int m;

    int64_t accu;

    for (m = 0; m < m_max; m++) {

        int64_t r = 1LL << (22-g_filt[m].exp);

        accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);

        Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));

        accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);

        Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));

    }

}


static int output_frame(AVFilterLink *outlink, int need_request)

{

    AVFilterContext *ctx = outlink->src;

    MixContext      *s = ctx->priv;

    AVFrame *out_buf, *in_buf;

    int nb_samples, ns, ret, i;

    ret = calc_active_inputs(s);

    if (ret < 0)

        return ret;

    if (s->input_state[0] & INPUT_ON) {

        /* first input live: use the corresponding frame size */

        nb_samples = frame_list_next_frame_size(s->frame_list);

        for (i = 1; i < s->nb_inputs; i++) {

            if (s->input_state[i] & INPUT_ON) {

                ns = av_audio_fifo_size(s->fifos[i]);

                if (ns < nb_samples) {

                    if (!(s->input_state[i] & INPUT_EOF))

                        /* unclosed input with not enough samples */

                        return need_request ? ff_request_frame(ctx->inputs[i]) : 0;

                    /* closed input to drain */

                    nb_samples = ns;

                }

            }

        }

    } else {

        /* first input closed: use the available samples */

        nb_samples = INT_MAX;

        for (i = 1; i < s->nb_inputs; i++) {

            if (s->input_state[i] & INPUT_ON) {

                ns = av_audio_fifo_size(s->fifos[i]);

                nb_samples = FFMIN(nb_samples, ns);

            }

        }

        if (nb_samples == INT_MAX)

            return AVERROR_EOF;

    }

    s->next_pts = frame_list_next_pts(s->frame_list);

    frame_list_remove_samples(s->frame_list, nb_samples);

    calculate_scales(s, nb_samples);

    if (nb_samples == 0)

        return 0;

    out_buf = ff_get_audio_buffer(outlink, nb_samples);

    if (!out_buf)

        return AVERROR(ENOMEM);

    in_buf = ff_get_audio_buffer(outlink, nb_samples);

    if (!in_buf) {

        av_frame_free(&out_buf);

        return AVERROR(ENOMEM);

    }

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

        if (s->input_state[i] & INPUT_ON) {

            int planes, plane_size, p;

            av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data,

                               nb_samples);

            planes     = s->planar ? s->nb_channels : 1;

            plane_size = nb_samples * (s->planar ? 1 : s->nb_channels);

            plane_size = FFALIGN(plane_size, 16);

            if (out_buf->format == AV_SAMPLE_FMT_FLT ||

                out_buf->format == AV_SAMPLE_FMT_FLTP) {

                for (p = 0; p < planes; p++) {

                    s->fdsp->vector_fmac_scalar((float *)out_buf->extended_data[p],

                                                (float *) in_buf->extended_data[p],

                                                s->input_scale[i], plane_size);

                }

            } else {

                for (p = 0; p < planes; p++) {

                    s->fdsp->vector_dmac_scalar((double *)out_buf->extended_data[p],

                                                (double *) in_buf->extended_data[p],

                                                s->input_scale[i], plane_size);

                }

            }

        }

    }

    av_frame_free(&in_buf);

    out_buf->pts = s->next_pts;

    if (s->next_pts != AV_NOPTS_VALUE)

        s->next_pts += nb_samples;

    return ff_filter_frame(outlink, out_buf);

}


static const char *token_get_value(QObject *obj)

{

    return qdict_get_str(qobject_to_qdict(obj), "token");

}


static void channel_store_d(struct fs_dma_ctrl *ctrl, int c)

{

	target_phys_addr_t addr = channel_reg(ctrl, c, RW_SAVED_DATA);

	/* Encode and store. FIXME: handle endianness.  */

	D(printf("%s ch=%d addr=" TARGET_FMT_plx "\n", __func__, c, addr));

	cpu_physical_memory_write (addr,

				  (void *) &ctrl->channels[c].current_d,

				  sizeof ctrl->channels[c].current_d);

}


static void omap_ulpd_pm_init(MemoryRegion *system_memory,

                target_phys_addr_t base,

                struct omap_mpu_state_s *mpu)

{

    memory_region_init_io(&mpu->ulpd_pm_iomem, &omap_ulpd_pm_ops, mpu,

                          "omap-ulpd-pm", 0x800);

    memory_region_add_subregion(system_memory, base, &mpu->ulpd_pm_iomem);

    omap_ulpd_pm_reset(mpu);

}


static void ahci_reset_port(AHCIState *s, int port)

{

    AHCIDevice *d = &s->dev[port];

    AHCIPortRegs *pr = &d->port_regs;

    IDEState *ide_state = &d->port.ifs[0];

    int i;

    DPRINTF(port, "reset port\n");

    ide_bus_reset(&d->port);

    ide_state->ncq_queues = AHCI_MAX_CMDS;

    pr->scr_stat = 0;

    pr->scr_err = 0;

    pr->scr_act = 0;

    pr->tfdata = 0x7F;

    pr->sig = 0xFFFFFFFF;

    d->busy_slot = -1;

    d->init_d2h_sent = false;

    ide_state = &s->dev[port].port.ifs[0];

    if (!ide_state->bs) {

        return;

    }

    /* reset ncq queue */

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

        NCQTransferState *ncq_tfs = &s->dev[port].ncq_tfs[i];

        if (!ncq_tfs->used) {

            continue;

        }

        if (ncq_tfs->aiocb) {

            bdrv_aio_cancel(ncq_tfs->aiocb);

            ncq_tfs->aiocb = NULL;

        }

        /* Maybe we just finished the request thanks to bdrv_aio_cancel() */

        if (!ncq_tfs->used) {

            continue;

        }

        qemu_sglist_destroy(&ncq_tfs->sglist);

        ncq_tfs->used = 0;

    }

    s->dev[port].port_state = STATE_RUN;

    if (!ide_state->bs) {

        pr->sig = 0;

        ide_state->status = SEEK_STAT | WRERR_STAT;

    } else if (ide_state->drive_kind == IDE_CD) {

        pr->sig = SATA_SIGNATURE_CDROM;

        ide_state->lcyl = 0x14;

        ide_state->hcyl = 0xeb;

        DPRINTF(port, "set lcyl = %d\n", ide_state->lcyl);

        ide_state->status = SEEK_STAT | WRERR_STAT | READY_STAT;

    } else {

        pr->sig = SATA_SIGNATURE_DISK;

        ide_state->status = SEEK_STAT | WRERR_STAT;

    }

    ide_state->error = 1;

    ahci_init_d2h(d);

}


int usb_device_detach(USBDevice *dev)

{

    USBBus *bus = usb_bus_from_device(dev);

    USBPort *port;

    if (!dev->attached) {

        error_report("Error: tried to detach unattached usb device %s\n",

                dev->product_desc);

        return -1;

    }

    dev->attached--;

    QTAILQ_FOREACH(port, &bus->used, next) {

        if (port->dev == dev)

            break;

    }

    assert(port != NULL);

    QTAILQ_REMOVE(&bus->used, port, next);

    bus->nused--;

    usb_attach(port, NULL);

    QTAILQ_INSERT_TAIL(&bus->free, port, next);

    bus->nfree++;

    return 0;

}


make_setup_request (AVFormatContext *s, const char *host, int port, int protocol)

{

    RTSPState *rt = s->priv_data;

    int j, i, err;

    RTSPStream *rtsp_st;

    AVStream *st;

    RTSPHeader reply1, *reply = &reply1;

    char cmd[2048];

    /* for each stream, make the setup request */

    /* XXX: we assume the same server is used for the control of each

       RTSP stream */

    for(j = RTSP_RTP_PORT_MIN, i = 0; i < rt->nb_rtsp_streams; ++i) {

        char transport[2048];

        rtsp_st = rt->rtsp_streams[i];

        /* compute available transports */

        transport[0] = '\0';

        /* RTP/UDP */

        if (protocol == RTSP_PROTOCOL_RTP_UDP) {

            char buf[256];

            /* first try in specified port range */

            if (RTSP_RTP_PORT_MIN != 0) {

                while(j <= RTSP_RTP_PORT_MAX) {

                    snprintf(buf, sizeof(buf), "rtp://%s?localport=%d", host, j);

                    j += 2; /* we will use two port by rtp stream (rtp and rtcp) */

                    if (url_open(&rtsp_st->rtp_handle, buf, URL_RDWR) == 0) {

                        goto rtp_opened;

                    }

                }

            }

/*            then try on any port

**            if (url_open(&rtsp_st->rtp_handle, "rtp://", URL_RDONLY) < 0) {

**                err = AVERROR_INVALIDDATA;

**                goto fail;

**            }

*/

        rtp_opened:

            port = rtp_get_local_port(rtsp_st->rtp_handle);

            if (transport[0] != '\0')

                av_strlcat(transport, ",", sizeof(transport));

            snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,

                     "RTP/AVP/UDP;unicast;client_port=%d-%d",

                     port, port + 1);

        }

        /* RTP/TCP */

        else if (protocol == RTSP_PROTOCOL_RTP_TCP) {

            if (transport[0] != '\0')

                av_strlcat(transport, ",", sizeof(transport));

            snprintf(transport + strlen(transport), sizeof(transport) - strlen(transport) - 1,

                     "RTP/AVP/TCP");

        }

        else if (protocol == RTSP_PROTOCOL_RTP_UDP_MULTICAST) {

            if (transport[0] != '\0')

                av_strlcat(transport, ",", sizeof(transport));

            snprintf(transport + strlen(transport),

                     sizeof(transport) - strlen(transport) - 1,

                     "RTP/AVP/UDP;multicast");

        }

        snprintf(cmd, sizeof(cmd),

                 "SETUP %s RTSP/1.0\r\n"

                 "Transport: %s\r\n",

                 rtsp_st->control_url, transport);

        rtsp_send_cmd(s, cmd, reply, NULL);

        if (reply->status_code == 461 /* Unsupported protocol */ && i == 0) {

            err = 1;

            goto fail;

        } else if (reply->status_code != RTSP_STATUS_OK ||

                   reply->nb_transports != 1) {

            err = AVERROR_INVALIDDATA;

            goto fail;

        }

        /* XXX: same protocol for all streams is required */

        if (i > 0) {

            if (reply->transports[0].protocol != rt->protocol) {

                err = AVERROR_INVALIDDATA;

                goto fail;

            }

        } else {

            rt->protocol = reply->transports[0].protocol;

        }

        /* close RTP connection if not choosen */

        if (reply->transports[0].protocol != RTSP_PROTOCOL_RTP_UDP &&

            (protocol == RTSP_PROTOCOL_RTP_UDP)) {

            url_close(rtsp_st->rtp_handle);

            rtsp_st->rtp_handle = NULL;

        }

        switch(reply->transports[0].protocol) {

        case RTSP_PROTOCOL_RTP_TCP:

            rtsp_st->interleaved_min = reply->transports[0].interleaved_min;

            rtsp_st->interleaved_max = reply->transports[0].interleaved_max;

            break;

        case RTSP_PROTOCOL_RTP_UDP:

            {

                char url[1024];

                /* XXX: also use address if specified */

                snprintf(url, sizeof(url), "rtp://%s:%d",

                         host, reply->transports[0].server_port_min);

                if (rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) {

                    err = AVERROR_INVALIDDATA;

                    goto fail;

                }

            }

            break;

        case RTSP_PROTOCOL_RTP_UDP_MULTICAST:

            {

                char url[1024];

                struct in_addr in;

                in.s_addr = htonl(reply->transports[0].destination);

                snprintf(url, sizeof(url), "rtp://%s:%d?ttl=%d",

                         inet_ntoa(in),

                         reply->transports[0].port_min,

                         reply->transports[0].ttl);

                if (url_open(&rtsp_st->rtp_handle, url, URL_RDWR) < 0) {

                    err = AVERROR_INVALIDDATA;

                    goto fail;

                }

            }

            break;

        }

        /* open the RTP context */

        st = NULL;

        if (rtsp_st->stream_index >= 0)

            st = s->streams[rtsp_st->stream_index];

        if (!st)

            s->ctx_flags |= AVFMTCTX_NOHEADER;

        rtsp_st->rtp_ctx = rtp_parse_open(s, st, rtsp_st->rtp_handle, rtsp_st->sdp_payload_type, &rtsp_st->rtp_payload_data);

        if (!rtsp_st->rtp_ctx) {

            err = AVERROR(ENOMEM);

            goto fail;

        } else {

            if(rtsp_st->dynamic_handler) {

                rtsp_st->rtp_ctx->dynamic_protocol_context= rtsp_st->dynamic_protocol_context;

                rtsp_st->rtp_ctx->parse_packet= rtsp_st->dynamic_handler->parse_packet;

            }

        }

    }

    return 0;

fail:

    for (i=0; i<rt->nb_rtsp_streams; i++) {

        if (rt->rtsp_streams[i]->rtp_handle) {

            url_close(rt->rtsp_streams[i]->rtp_handle);

            rt->rtsp_streams[i]->rtp_handle = NULL;

        }

    }

    return err;

}


static int add_metadata(int count, int type,

                        const char *name, const char *sep, TiffContext *s)

{

    switch(type) {

    case TIFF_DOUBLE: return add_doubles_metadata(count, name, sep, s);

    case TIFF_SHORT : return add_shorts_metadata(count, name, sep, s);

    case TIFF_STRING: return add_string_metadata(count, name, s);

    default         : return AVERROR_INVALIDDATA;

    };

}


e1000_receive(NetClientState *nc, const uint8_t *buf, size_t size)

{

    E1000State *s = qemu_get_nic_opaque(nc);

    struct e1000_rx_desc desc;

    dma_addr_t base;

    unsigned int n, rdt;

    uint32_t rdh_start;

    uint16_t vlan_special = 0;

    uint8_t vlan_status = 0, vlan_offset = 0;

    uint8_t min_buf[MIN_BUF_SIZE];

    size_t desc_offset;

    size_t desc_size;

    size_t total_size;

    if (!(s->mac_reg[RCTL] & E1000_RCTL_EN))

        return -1;

    /* Pad to minimum Ethernet frame length */

    if (size < sizeof(min_buf)) {

        memcpy(min_buf, buf, size);

        memset(&min_buf[size], 0, sizeof(min_buf) - size);

        buf = min_buf;

        size = sizeof(min_buf);

    }

    /* Discard oversized packets if !LPE and !SBP. */

    if ((size > MAXIMUM_ETHERNET_LPE_SIZE ||

        (size > MAXIMUM_ETHERNET_VLAN_SIZE

        && !(s->mac_reg[RCTL] & E1000_RCTL_LPE)))

        && !(s->mac_reg[RCTL] & E1000_RCTL_SBP)) {

        return size;

    }

    if (!receive_filter(s, buf, size))

        return size;

    if (vlan_enabled(s) && is_vlan_packet(s, buf)) {

        vlan_special = cpu_to_le16(be16_to_cpup((uint16_t *)(buf + 14)));

        memmove((uint8_t *)buf + 4, buf, 12);

        vlan_status = E1000_RXD_STAT_VP;

        vlan_offset = 4;

        size -= 4;

    }

    rdh_start = s->mac_reg[RDH];

    desc_offset = 0;

    total_size = size + fcs_len(s);

    if (!e1000_has_rxbufs(s, total_size)) {

            set_ics(s, 0, E1000_ICS_RXO);

            return -1;

    }

    do {

        desc_size = total_size - desc_offset;

        if (desc_size > s->rxbuf_size) {

            desc_size = s->rxbuf_size;

        }

        base = rx_desc_base(s) + sizeof(desc) * s->mac_reg[RDH];

        pci_dma_read(&s->dev, base, &desc, sizeof(desc));

        desc.special = vlan_special;

        desc.status |= (vlan_status | E1000_RXD_STAT_DD);

        if (desc.buffer_addr) {

            if (desc_offset < size) {

                size_t copy_size = size - desc_offset;

                if (copy_size > s->rxbuf_size) {

                    copy_size = s->rxbuf_size;

                }

                pci_dma_write(&s->dev, le64_to_cpu(desc.buffer_addr),

                              buf + desc_offset + vlan_offset, copy_size);

            }

            desc_offset += desc_size;

            desc.length = cpu_to_le16(desc_size);

            if (desc_offset >= total_size) {

                desc.status |= E1000_RXD_STAT_EOP | E1000_RXD_STAT_IXSM;

            } else {

                /* Guest zeroing out status is not a hardware requirement.

                   Clear EOP in case guest didn't do it. */

                desc.status &= ~E1000_RXD_STAT_EOP;

            }

        } else { // as per intel docs; skip descriptors with null buf addr

            DBGOUT(RX, "Null RX descriptor!!\n");

        }

        pci_dma_write(&s->dev, base, &desc, sizeof(desc));

        if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])

            s->mac_reg[RDH] = 0;

        /* see comment in start_xmit; same here */

        if (s->mac_reg[RDH] == rdh_start) {

            DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",

                   rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);

            set_ics(s, 0, E1000_ICS_RXO);

            return -1;

        }

    } while (desc_offset < total_size);

    s->mac_reg[GPRC]++;

    s->mac_reg[TPR]++;

    /* TOR - Total Octets Received:

     * This register includes bytes received in a packet from the <Destination

     * Address> field through the <CRC> field, inclusively.

     */

    n = s->mac_reg[TORL] + size + /* Always include FCS length. */ 4;

    if (n < s->mac_reg[TORL])

        s->mac_reg[TORH]++;

    s->mac_reg[TORL] = n;

    n = E1000_ICS_RXT0;

    if ((rdt = s->mac_reg[RDT]) < s->mac_reg[RDH])

        rdt += s->mac_reg[RDLEN] / sizeof(desc);

    if (((rdt - s->mac_reg[RDH]) * sizeof(desc)) <= s->mac_reg[RDLEN] >>

        s->rxbuf_min_shift)

        n |= E1000_ICS_RXDMT0;

    set_ics(s, 0, n);

    return size;

}


real_parse_asm_rule(AVStream *st, const char *p, const char *end)

{

    do {

        /* can be either averagebandwidth= or AverageBandwidth= */

#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI

        if (sscanf(p, " %*1[Aa]verage%*1[Bb]andwidth=%d", &st->codec->bit_rate) == 1)

#else

        if (sscanf(p, " %*1[Aa]verage%*1[Bb]andwidth=%"SCNd64, &st->codec->bit_rate) == 1)

#endif

            break;

        if (!(p = strchr(p, ',')) || p > end)

            p = end;

        p++;

    } while (p < end);

}


int select_watchdog(const char *p)

{

    WatchdogTimerModel *model;

    if (watchdog) {

        fprintf(stderr,

                 "qemu: only one watchdog option may be given\n");

        return 1;

    }

    /* -watchdog ? lists available devices and exits cleanly. */

    if (strcmp(p, "?") == 0) {

        LIST_FOREACH(model, &watchdog_list, entry) {

            fprintf(stderr, "\t%s\t%s\n",

                     model->wdt_name, model->wdt_description);

        }

        return 2;

    }

    LIST_FOREACH(model, &watchdog_list, entry) {

        if (strcasecmp(model->wdt_name, p) == 0) {

            watchdog = model;

            return 0;

        }

    }

    fprintf(stderr, "Unknown -watchdog device. Supported devices are:\n");

    LIST_FOREACH(model, &watchdog_list, entry) {

        fprintf(stderr, "\t%s\t%s\n",

                 model->wdt_name, model->wdt_description);

    }

    return 1;

}


static int vp3_decode_frame(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    Vp3DecodeContext *s = avctx->priv_data;

    GetBitContext gb;

    static int counter = 0;

    int i;

    init_get_bits(&gb, buf, buf_size * 8);

    if (s->theora && get_bits1(&gb))

    {

        av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n");

        return -1;

    }

    s->keyframe = !get_bits1(&gb);

    if (!s->theora)

        skip_bits(&gb, 1);

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

        s->last_qps[i] = s->qps[i];

    s->nqps=0;

    do{

        s->qps[s->nqps++]= get_bits(&gb, 6);

    } while(s->theora >= 0x030200 && s->nqps<3 && get_bits1(&gb));

    for (i = s->nqps; i < 3; i++)

        s->qps[i] = -1;

    if (s->avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n",

            s->keyframe?"key":"", counter, s->qps[0]);

    counter++;

    if (s->qps[0] != s->last_qps[0])

        init_loop_filter(s);

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

        // reinit all dequantizers if the first one changed, because

        // the DC of the first quantizer must be used for all matrices

        if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])

            init_dequantizer(s, i);

    if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)

        return buf_size;

    s->current_frame.reference = 3;

    if (avctx->get_buffer(avctx, &s->current_frame) < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return -1;

    }

    if (s->keyframe) {

        if (!s->theora)

        {

            skip_bits(&gb, 4); /* width code */

            skip_bits(&gb, 4); /* height code */

            if (s->version)

            {

                s->version = get_bits(&gb, 5);

                if (counter == 1)

                    av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version);

            }

        }

        if (s->version || s->theora)

        {

                if (get_bits1(&gb))

                    av_log(s->avctx, AV_LOG_ERROR, "Warning, unsupported keyframe coding type?!\n");

            skip_bits(&gb, 2); /* reserved? */

        }

    } else {

        if (!s->golden_frame.data[0]) {

            av_log(s->avctx, AV_LOG_ERROR, "vp3: first frame not a keyframe\n");

            avctx->release_buffer(avctx, &s->current_frame);

            return -1;

        }

    }

    s->current_frame.qscale_table= s->qscale_table; //FIXME allocate individual tables per AVFrame

    s->current_frame.qstride= 0;

    init_frame(s, &gb);

    if (unpack_superblocks(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");

        return -1;

    }

    if (unpack_modes(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");

        return -1;

    }

    if (unpack_vectors(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");

        return -1;

    }

    if (unpack_block_qpis(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");

        return -1;

    }

    if (unpack_dct_coeffs(s, &gb)){

        av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");

        return -1;

    }

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

        if (s->flipped_image)

            s->data_offset[i] = 0;

        else

            s->data_offset[i] = ((s->height>>!!i)-1) * s->current_frame.linesize[i];

    }

    s->last_slice_end = 0;

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

        render_slice(s, i);

    // filter the last row

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

        int row = (s->height >> (3+!!i)) - 1;

        apply_loop_filter(s, i, row, row+1);

    }

    vp3_draw_horiz_band(s, s->height);

    *data_size=sizeof(AVFrame);

    *(AVFrame*)data= s->current_frame;

    /* release the last frame, if it is allocated and if it is not the

     * golden frame */

    if ((s->last_frame.data[0]) &&

        (s->last_frame.data[0] != s->golden_frame.data[0]))

        avctx->release_buffer(avctx, &s->last_frame);

    /* shuffle frames (last = current) */

    s->last_frame= s->current_frame;

    if (s->keyframe) {

        if (s->golden_frame.data[0])

            avctx->release_buffer(avctx, &s->golden_frame);

        s->golden_frame = s->current_frame;

    }

    s->current_frame.data[0]= NULL; /* ensure that we catch any access to this released frame */

    return buf_size;

}


static void mainstone_common_init(MemoryRegion *address_space_mem,

                ram_addr_t ram_size,

                const char *kernel_filename,

                const char *kernel_cmdline, const char *initrd_filename,

                const char *cpu_model, enum mainstone_model_e model, int arm_id)

{

    uint32_t sector_len = 256 * 1024;

    target_phys_addr_t mainstone_flash_base[] = { MST_FLASH_0, MST_FLASH_1 };

    PXA2xxState *mpu;

    DeviceState *mst_irq;

    DriveInfo *dinfo;

    int i;

    int be;

    MemoryRegion *rom = g_new(MemoryRegion, 1);

    if (!cpu_model)

        cpu_model = "pxa270-c5";

    /* Setup CPU & memory */

    mpu = pxa270_init(address_space_mem, mainstone_binfo.ram_size, cpu_model);

    memory_region_init_ram(rom, "mainstone.rom", MAINSTONE_ROM);

    vmstate_register_ram_global(rom);

    memory_region_set_readonly(rom, true);

    memory_region_add_subregion(address_space_mem, 0, rom);

#ifdef TARGET_WORDS_BIGENDIAN

    be = 1;

#else

    be = 0;

#endif

    /* There are two 32MiB flash devices on the board */

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

        dinfo = drive_get(IF_PFLASH, 0, i);

        if (!dinfo) {

            fprintf(stderr, "Two flash images must be given with the "

                    "'pflash' parameter\n");

            exit(1);

        }

        if (!pflash_cfi01_register(mainstone_flash_base[i], NULL,

                                   i ? "mainstone.flash1" : "mainstone.flash0",

                                   MAINSTONE_FLASH,

                                   dinfo->bdrv, sector_len,

                                   MAINSTONE_FLASH / sector_len, 4, 0, 0, 0, 0,

                                   be)) {

            fprintf(stderr, "qemu: Error registering flash memory.\n");

            exit(1);

        }

    }

    mst_irq = sysbus_create_simple("mainstone-fpga", MST_FPGA_PHYS,

                    qdev_get_gpio_in(mpu->gpio, 0));

    /* setup keypad */

    printf("map addr %p\n", &map);

    pxa27x_register_keypad(mpu->kp, map, 0xe0);

    /* MMC/SD host */

    pxa2xx_mmci_handlers(mpu->mmc, NULL, qdev_get_gpio_in(mst_irq, MMC_IRQ));

    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[0],

            qdev_get_gpio_in(mst_irq, S0_IRQ),

            qdev_get_gpio_in(mst_irq, S0_CD_IRQ));

    pxa2xx_pcmcia_set_irq_cb(mpu->pcmcia[1],

            qdev_get_gpio_in(mst_irq, S1_IRQ),

            qdev_get_gpio_in(mst_irq, S1_CD_IRQ));

    smc91c111_init(&nd_table[0], MST_ETH_PHYS,

                    qdev_get_gpio_in(mst_irq, ETHERNET_IRQ));

    mainstone_binfo.kernel_filename = kernel_filename;

    mainstone_binfo.kernel_cmdline = kernel_cmdline;

    mainstone_binfo.initrd_filename = initrd_filename;

    mainstone_binfo.board_id = arm_id;

    arm_load_kernel(mpu->cpu, &mainstone_binfo);

}


static void gicv3_cpuif_el_change_hook(ARMCPU *cpu, void *opaque)

{

    /* Do nothing for now. */

}


static ssize_t gem_receive(NetClientState *nc, const uint8_t *buf, size_t size)

{

    unsigned    desc[2];

    target_phys_addr_t packet_desc_addr, last_desc_addr;

    GemState *s;

    unsigned   rxbufsize, bytes_to_copy;

    unsigned   rxbuf_offset;

    uint8_t    rxbuf[2048];

    uint8_t   *rxbuf_ptr;

    s = DO_UPCAST(NICState, nc, nc)->opaque;

    /* Do nothing if receive is not enabled. */

    if (!(s->regs[GEM_NWCTRL] & GEM_NWCTRL_RXENA)) {

        return -1;

    }

    /* Is this destination MAC address "for us" ? */

    if (gem_mac_address_filter(s, buf) == GEM_RX_REJECT) {

        return -1;

    }

    /* Discard packets with receive length error enabled ? */

    if (s->regs[GEM_NWCFG] & GEM_NWCFG_LERR_DISC) {

        unsigned type_len;

        /* Fish the ethertype / length field out of the RX packet */

        type_len = buf[12] << 8 | buf[13];

        /* It is a length field, not an ethertype */

        if (type_len < 0x600) {

            if (size < type_len) {

                /* discard */

                return -1;

            }

        }

    }

    /*

     * Determine configured receive buffer offset (probably 0)

     */

    rxbuf_offset = (s->regs[GEM_NWCFG] & GEM_NWCFG_BUFF_OFST_M) >>

                   GEM_NWCFG_BUFF_OFST_S;

    /* The configure size of each receive buffer.  Determines how many

     * buffers needed to hold this packet.

     */

    rxbufsize = ((s->regs[GEM_DMACFG] & GEM_DMACFG_RBUFSZ_M) >>

                 GEM_DMACFG_RBUFSZ_S) * GEM_DMACFG_RBUFSZ_MUL;

    bytes_to_copy = size;

    /* Strip of FCS field ? (usually yes) */

    if (s->regs[GEM_NWCFG] & GEM_NWCFG_STRIP_FCS) {

        rxbuf_ptr = (void *)buf;

    } else {

        unsigned crc_val;

        int      crc_offset;

        /* The application wants the FCS field, which QEMU does not provide.

         * We must try and caclculate one.

         */

        memcpy(rxbuf, buf, size);

        memset(rxbuf + size, 0, sizeof(rxbuf) - size);

        rxbuf_ptr = rxbuf;

        crc_val = cpu_to_le32(crc32(0, rxbuf, MAX(size, 60)));

        if (size < 60) {

            crc_offset = 60;

        } else {

            crc_offset = size;

        }

        memcpy(rxbuf + crc_offset, &crc_val, sizeof(crc_val));

        bytes_to_copy += 4;

        size += 4;

    }

    /* Pad to minimum length */

    if (size < 64) {

        size = 64;

    }

    DB_PRINT("config bufsize: %d packet size: %ld\n", rxbufsize, size);

    packet_desc_addr = s->rx_desc_addr;

    while (1) {

        DB_PRINT("read descriptor 0x%x\n", packet_desc_addr);

        /* read current descriptor */

        cpu_physical_memory_read(packet_desc_addr,

                                 (uint8_t *)&desc[0], sizeof(desc));

        /* Descriptor owned by software ? */

        if (rx_desc_get_ownership(desc) == 1) {

            DB_PRINT("descriptor 0x%x owned by sw.\n", packet_desc_addr);

            s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_NOBUF;

            /* Handle interrupt consequences */

            gem_update_int_status(s);

            return -1;

        }

        DB_PRINT("copy %d bytes to 0x%x\n", MIN(bytes_to_copy, rxbufsize),

                rx_desc_get_buffer(desc));

        /*

         * Let's have QEMU lend a helping hand.

         */

        if (rx_desc_get_buffer(desc) == 0) {

            DB_PRINT("Invalid RX buffer (NULL) for descriptor 0x%x\n",

                       packet_desc_addr);

            break;

        }

        /* Copy packet data to emulated DMA buffer */

        cpu_physical_memory_write(rx_desc_get_buffer(desc) + rxbuf_offset,

                                  rxbuf_ptr, MIN(bytes_to_copy, rxbufsize));

        bytes_to_copy -= MIN(bytes_to_copy, rxbufsize);

        rxbuf_ptr += MIN(bytes_to_copy, rxbufsize);

        if (bytes_to_copy == 0) {

            break;

        }

        /* Next descriptor */

        if (rx_desc_get_wrap(desc)) {

            packet_desc_addr = s->regs[GEM_RXQBASE];

        } else {

            packet_desc_addr += 8;

        }

    }

    DB_PRINT("set length: %ld, EOF on descriptor 0x%x\n", size,

            (unsigned)packet_desc_addr);

    /* Update last descriptor with EOF and total length */

    rx_desc_set_eof(desc);

    rx_desc_set_length(desc, size);

    cpu_physical_memory_write(packet_desc_addr,

                              (uint8_t *)&desc[0], sizeof(desc));

    /* Advance RX packet descriptor Q */

    last_desc_addr = packet_desc_addr;

    packet_desc_addr = s->rx_desc_addr;

    s->rx_desc_addr = last_desc_addr;

    if (rx_desc_get_wrap(desc)) {

        s->rx_desc_addr = s->regs[GEM_RXQBASE];

    } else {

        s->rx_desc_addr += 8;

    }

    DB_PRINT("set SOF, OWN on descriptor 0x%08x\n", packet_desc_addr);

    /* Count it */

    gem_receive_updatestats(s, buf, size);

    /* Update first descriptor (which could also be the last) */

    /* read descriptor */

    cpu_physical_memory_read(packet_desc_addr,

                             (uint8_t *)&desc[0], sizeof(desc));

    rx_desc_set_sof(desc);

    rx_desc_set_ownership(desc);

    cpu_physical_memory_write(packet_desc_addr,

                              (uint8_t *)&desc[0], sizeof(desc));

    s->regs[GEM_RXSTATUS] |= GEM_RXSTATUS_FRMRCVD;

    /* Handle interrupt consequences */

    gem_update_int_status(s);

    return size;

}


static int dxva2_vc1_end_frame(AVCodecContext *avctx)

{

    VC1Context *v = avctx->priv_data;

    struct dxva2_picture_context *ctx_pic = v->s.current_picture_ptr->hwaccel_picture_private;

    int ret;

    if (ctx_pic->bitstream_size <= 0)

        return -1;

    ret = ff_dxva2_common_end_frame(avctx, &v->s.current_picture_ptr->f,

                                    &ctx_pic->pp, sizeof(ctx_pic->pp),

                                    NULL, 0,

                                    commit_bitstream_and_slice_buffer);

    if (!ret)

        ff_mpeg_draw_horiz_band(&v->s, 0, avctx->height);

    return ret;

}


static char *vnc_socket_remote_addr(const char *format, int fd) {

    struct sockaddr_storage sa;

    socklen_t salen;

    salen = sizeof(sa);

    if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0)

        return NULL;

    return addr_to_string(format, &sa, salen);

}


static int qemu_gluster_open(BlockDriverState *bs,  QDict *options,

                             int bdrv_flags, Error **errp)

{

    BDRVGlusterState *s = bs->opaque;

    int open_flags = 0;

    int ret = 0;

    BlockdevOptionsGluster *gconf = NULL;

    QemuOpts *opts;

    Error *local_err = NULL;

    const char *filename;

    opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);

    qemu_opts_absorb_qdict(opts, options, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto out;

    }

    filename = qemu_opt_get(opts, GLUSTER_OPT_FILENAME);

    s->debug_level = qemu_opt_get_number(opts, GLUSTER_OPT_DEBUG,

                                         GLUSTER_DEBUG_DEFAULT);

    if (s->debug_level < 0) {

        s->debug_level = 0;

    } else if (s->debug_level > GLUSTER_DEBUG_MAX) {

        s->debug_level = GLUSTER_DEBUG_MAX;

    }

    gconf = g_new0(BlockdevOptionsGluster, 1);

    gconf->debug_level = s->debug_level;

    gconf->has_debug_level = true;

    s->glfs = qemu_gluster_init(gconf, filename, options, errp);

    if (!s->glfs) {

        ret = -errno;

        goto out;

    }

#ifdef CONFIG_GLUSTERFS_XLATOR_OPT

    /* Without this, if fsync fails for a recoverable reason (for instance,

     * ENOSPC), gluster will dump its cache, preventing retries.  This means

     * almost certain data loss.  Not all gluster versions support the

     * 'resync-failed-syncs-after-fsync' key value, but there is no way to

     * discover during runtime if it is supported (this api returns success for

     * unknown key/value pairs) */

    ret = glfs_set_xlator_option(s->glfs, "*-write-behind",

                                          "resync-failed-syncs-after-fsync",

                                          "on");

    if (ret < 0) {

        error_setg_errno(errp, errno, "Unable to set xlator key/value pair");

        ret = -errno;

        goto out;

    }

#endif

    qemu_gluster_parse_flags(bdrv_flags, &open_flags);

    s->fd = glfs_open(s->glfs, gconf->path, open_flags);

    if (!s->fd) {

        ret = -errno;

    }

    s->supports_seek_data = qemu_gluster_test_seek(s->fd);

out:

    qemu_opts_del(opts);

    qapi_free_BlockdevOptionsGluster(gconf);

    if (!ret) {

        return ret;

    }

    if (s->fd) {

        glfs_close(s->fd);

    }

    if (s->glfs) {

        glfs_fini(s->glfs);

    }

    return ret;

}


static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h)

{

    BitBuf bb;

    int res, val;

    int i, j;

    int bx, by;

    int l0x, l1x, l0y, l1y;

    int mx, my;

    kmvc_init_getbits(bb, &ctx->g);

    for (by = 0; by < h; by += 8)

        for (bx = 0; bx < w; bx += 8) {

            if (!bytestream2_get_bytes_left(&ctx->g)) {

                av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");

                return AVERROR_INVALIDDATA;

            }

            kmvc_getbit(bb, &ctx->g, res);

            if (!res) {         // fill whole 8x8 block

                val = bytestream2_get_byte(&ctx->g);

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

                    BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;

            } else {            // handle four 4x4 subblocks

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

                    l0x = bx + (i & 1) * 4;

                    l0y = by + (i & 2) * 2;

                    kmvc_getbit(bb, &ctx->g, res);

                    if (!res) {

                        kmvc_getbit(bb, &ctx->g, res);

                        if (!res) {     // fill whole 4x4 block

                            val = bytestream2_get_byte(&ctx->g);

                            for (j = 0; j < 16; j++)

                                BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;

                        } else {        // copy block from already decoded place

                            val = bytestream2_get_byte(&ctx->g);

                            mx = val & 0xF;

                            my = val >> 4;

                            if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {

                                av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");

                                return AVERROR_INVALIDDATA;

                            }

                            for (j = 0; j < 16; j++)

                                BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =

                                    BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);

                        }

                    } else {    // descend to 2x2 sub-sub-blocks

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

                            l1x = l0x + (j & 1) * 2;

                            l1y = l0y + (j & 2);

                            kmvc_getbit(bb, &ctx->g, res);

                            if (!res) {

                                kmvc_getbit(bb, &ctx->g, res);

                                if (!res) {     // fill whole 2x2 block

                                    val = bytestream2_get_byte(&ctx->g);

                                    BLK(ctx->cur, l1x, l1y) = val;

                                    BLK(ctx->cur, l1x + 1, l1y) = val;

                                    BLK(ctx->cur, l1x, l1y + 1) = val;

                                    BLK(ctx->cur, l1x + 1, l1y + 1) = val;

                                } else {        // copy block from already decoded place

                                    val = bytestream2_get_byte(&ctx->g);

                                    mx = val & 0xF;

                                    my = val >> 4;

                                    if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {

                                        av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");

                                        return AVERROR_INVALIDDATA;

                                    }

                                    BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);

                                    BLK(ctx->cur, l1x + 1, l1y) =

                                        BLK(ctx->cur, l1x + 1 - mx, l1y - my);

                                    BLK(ctx->cur, l1x, l1y + 1) =

                                        BLK(ctx->cur, l1x - mx, l1y + 1 - my);

                                    BLK(ctx->cur, l1x + 1, l1y + 1) =

                                        BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);

                                }

                            } else {    // read values for block

                                BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);

                                BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);

                                BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);

                                BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);

                            }

                        }

                    }

                }

            }

        }

    return 0;

}


static uint32_t pci_unin_main_config_readl (void *opaque,

                                            target_phys_addr_t addr)

{

    UNINState *s = opaque;

    uint32_t val;

    val = s->config_reg;

#ifdef TARGET_WORDS_BIGENDIAN

    val = bswap32(val);

#endif

    UNIN_DPRINTF("config_readl addr " TARGET_FMT_plx " val %x\n", addr, val);

    return val;

}


static int ram_save_init_globals(void)

{

    int64_t ram_bitmap_pages; /* Size of bitmap in pages, including gaps */

    dirty_rate_high_cnt = 0;

    bitmap_sync_count = 0;

    migration_bitmap_sync_init();

    qemu_mutex_init(&migration_bitmap_mutex);

    if (migrate_use_xbzrle()) {

        XBZRLE_cache_lock();

        ZERO_TARGET_PAGE = g_malloc0(TARGET_PAGE_SIZE);

        XBZRLE.cache = cache_init(migrate_xbzrle_cache_size() /

                                  TARGET_PAGE_SIZE,

                                  TARGET_PAGE_SIZE);

        if (!XBZRLE.cache) {

            XBZRLE_cache_unlock();

            error_report("Error creating cache");

            return -1;

        }

        XBZRLE_cache_unlock();

        /* We prefer not to abort if there is no memory */

        XBZRLE.encoded_buf = g_try_malloc0(TARGET_PAGE_SIZE);

        if (!XBZRLE.encoded_buf) {

            error_report("Error allocating encoded_buf");

            return -1;

        }

        XBZRLE.current_buf = g_try_malloc(TARGET_PAGE_SIZE);

        if (!XBZRLE.current_buf) {

            error_report("Error allocating current_buf");

            g_free(XBZRLE.encoded_buf);

            XBZRLE.encoded_buf = NULL;

            return -1;

        }

        acct_clear();

    }

    /* For memory_global_dirty_log_start below.  */

    qemu_mutex_lock_iothread();

    qemu_mutex_lock_ramlist();

    rcu_read_lock();

    bytes_transferred = 0;

    reset_ram_globals();

    ram_bitmap_pages = last_ram_offset() >> TARGET_PAGE_BITS;

    migration_bitmap_rcu = g_new0(struct BitmapRcu, 1);

    migration_bitmap_rcu->bmap = bitmap_new(ram_bitmap_pages);

    bitmap_set(migration_bitmap_rcu->bmap, 0, ram_bitmap_pages);

    if (migrate_postcopy_ram()) {

        migration_bitmap_rcu->unsentmap = bitmap_new(ram_bitmap_pages);

        bitmap_set(migration_bitmap_rcu->unsentmap, 0, ram_bitmap_pages);

    }

    /*

     * Count the total number of pages used by ram blocks not including any

     * gaps due to alignment or unplugs.

     */

    migration_dirty_pages = ram_bytes_total() >> TARGET_PAGE_BITS;

    memory_global_dirty_log_start();

    migration_bitmap_sync();

    qemu_mutex_unlock_ramlist();

    qemu_mutex_unlock_iothread();

    rcu_read_unlock();

    return 0;

}


static uint16_t nvme_dma_read_prp(NvmeCtrl *n, uint8_t *ptr, uint32_t len,

    uint64_t prp1, uint64_t prp2)

{

    QEMUSGList qsg;

    QEMUIOVector iov;

    uint16_t status = NVME_SUCCESS;

    if (nvme_map_prp(&qsg, &iov, prp1, prp2, len, n)) {

        return NVME_INVALID_FIELD | NVME_DNR;

    }

    if (qsg.nsg > 0) {

        if (dma_buf_read(ptr, len, &qsg)) {

            status = NVME_INVALID_FIELD | NVME_DNR;

        }

        qemu_sglist_destroy(&qsg);

    } else {

        if (qemu_iovec_to_buf(&iov, 0, ptr, len) != len) {

            status = NVME_INVALID_FIELD | NVME_DNR;

        }

        qemu_iovec_destroy(&iov);

    }

    return status;

}


static int asf_read_metadata_obj(AVFormatContext *s, const GUIDParseTable *g)

{

    ASFContext *asf   = s->priv_data;

    AVIOContext *pb   = s->pb;

    uint64_t size     = avio_rl64(pb);

    uint16_t nb_recs  = avio_rl16(pb); // number of records in the Description Records list

    int i, ret;

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

        uint16_t name_len, buflen, type, val_len, st_num;

        uint8_t *name = NULL;

        avio_skip(pb, 2); // skip reserved field

        st_num   = avio_rl16(pb);

        name_len = avio_rl16(pb);

        buflen   = 2 * name_len + 1;

        if (!name_len)

            break;

        type     = avio_rl16(pb);

        val_len  = avio_rl32(pb);

        name     = av_malloc(name_len);

        if (!name)

            return AVERROR(ENOMEM);

        avio_get_str16le(pb, name_len, name,

                         buflen);

        if (!strcmp(name, "AspectRatioX") || !strcmp(name, "AspectRatioY")) {

            asf_store_aspect_ratio(s, st_num, name);

        } else {

            if (st_num < ASF_MAX_STREAMS) {

                if ((ret = process_metadata(s, name, name_len, val_len, type,

                                            &asf->asf_sd[st_num].asf_met)) < 0)

                    break;

            } else

                av_freep(&name);

        }

    }

    align_position(pb, asf->offset, size);

    return 0;

}


static int check_refcounts_l1(BlockDriverState *bs,

                              BdrvCheckResult *res,

                              uint16_t *refcount_table,

                              int64_t refcount_table_size,

                              int64_t l1_table_offset, int l1_size,

                              int flags)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t *l1_table, l2_offset, l1_size2;

    int i, ret;

    l1_size2 = l1_size * sizeof(uint64_t);

    /* Mark L1 table as used */

    inc_refcounts(bs, res, refcount_table, refcount_table_size,

        l1_table_offset, l1_size2);

    /* Read L1 table entries from disk */

    if (l1_size2 == 0) {

        l1_table = NULL;

    } else {

        l1_table = g_try_malloc(l1_size2);

        if (l1_table == NULL) {

            ret = -ENOMEM;

            goto fail;

        }

        if (bdrv_pread(bs->file, l1_table_offset,

                       l1_table, l1_size2) != l1_size2)

            goto fail;

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

            be64_to_cpus(&l1_table[i]);

    }

    /* Do the actual checks */

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

        l2_offset = l1_table[i];

        if (l2_offset) {

            /* Mark L2 table as used */

            l2_offset &= L1E_OFFSET_MASK;

            inc_refcounts(bs, res, refcount_table, refcount_table_size,

                l2_offset, s->cluster_size);

            /* L2 tables are cluster aligned */

            if (offset_into_cluster(s, l2_offset)) {

                fprintf(stderr, "ERROR l2_offset=%" PRIx64 ": Table is not "

                    "cluster aligned; L1 entry corrupted\n", l2_offset);

                res->corruptions++;

            }

            /* Process and check L2 entries */

            ret = check_refcounts_l2(bs, res, refcount_table,

                                     refcount_table_size, l2_offset, flags);

            if (ret < 0) {

                goto fail;

            }

        }

    }

    g_free(l1_table);

    return 0;

fail:

    fprintf(stderr, "ERROR: I/O error in check_refcounts_l1\n");

    res->check_errors++;

    g_free(l1_table);

    return -EIO;

}


DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr)

{

    DeviceState *dev;

    dev = qdev_create(&bus->qbus, name);

    qdev_prop_set_uint8(dev, "address", addr);

    qdev_init(dev);

    return dev;

}


static void strongarm_gpio_write(void *opaque, hwaddr offset,

                                 uint64_t value, unsigned size)

{

    StrongARMGPIOInfo *s = opaque;

    switch (offset) {

    case GPDR:        /* GPIO Pin-Direction registers */

        s->dir = value;

        strongarm_gpio_handler_update(s);

        break;

    case GPSR:        /* GPIO Pin-Output Set registers */

        s->olevel |= value;

        strongarm_gpio_handler_update(s);

        s->gpsr = value;

        break;

    case GPCR:        /* GPIO Pin-Output Clear registers */

        s->olevel &= ~value;

        strongarm_gpio_handler_update(s);

        break;

    case GRER:        /* GPIO Rising-Edge Detect Enable registers */

        s->rising = value;

        break;

    case GFER:        /* GPIO Falling-Edge Detect Enable registers */

        s->falling = value;

        break;

    case GAFR:        /* GPIO Alternate Function registers */

        s->gafr = value;

        break;

    case GEDR:        /* GPIO Edge Detect Status registers */

        s->status &= ~value;

        strongarm_gpio_irq_update(s);

        break;

    default:

        printf("%s: Bad offset 0x" TARGET_FMT_plx "\n", __func__, offset);

    }

}


static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,

                        int rs, int lsb, int msb)

{

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    gen_load_gpr(t1, rs);

    switch (opc) {

    case OPC_EXT:

        if (lsb + msb > 31)

            goto fail;

        tcg_gen_shri_tl(t0, t1, lsb);

        if (msb != 31) {

            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);

        } else {

            tcg_gen_ext32s_tl(t0, t0);

        }

        break;

#if defined(TARGET_MIPS64)

    case OPC_DEXTM:

        tcg_gen_shri_tl(t0, t1, lsb);

        if (msb != 31) {

            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);

        }

        break;

    case OPC_DEXTU:

        tcg_gen_shri_tl(t0, t1, lsb + 32);

        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);

        break;

    case OPC_DEXT:

        tcg_gen_shri_tl(t0, t1, lsb);

        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);

        break;

#endif

    case OPC_INS:

        if (lsb > msb)

            goto fail;

        gen_load_gpr(t0, rt);

        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);

        tcg_gen_ext32s_tl(t0, t0);

        break;

#if defined(TARGET_MIPS64)

    case OPC_DINSM:

        gen_load_gpr(t0, rt);

        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);

        break;

    case OPC_DINSU:

        gen_load_gpr(t0, rt);

        tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);

        break;

    case OPC_DINS:

        gen_load_gpr(t0, rt);

        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);

        break;

#endif

    default:

fail:

        MIPS_INVAL("bitops");

        generate_exception(ctx, EXCP_RI);

        tcg_temp_free(t0);

        tcg_temp_free(t1);

        return;

    }

    gen_store_gpr(t0, rt);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

}


static int vhost_scsi_exit(DeviceState *qdev)

{

    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);

    VHostSCSI *s = VHOST_SCSI(qdev);

    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev);

    migrate_del_blocker(s->migration_blocker);

    error_free(s->migration_blocker);

    /* This will stop vhost backend. */

    vhost_scsi_set_status(vdev, 0);

    g_free(s->dev.vqs);

    return virtio_scsi_common_exit(vs);

}


static inline void RENAME(rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_t *udst, uint8_t *vdst,

	unsigned int width, unsigned int height,

	int lumStride, int chromStride, int srcStride)

{

	unsigned y;

	const unsigned chromWidth= width>>1;

#ifdef HAVE_MMX

	for(y=0; y<height-2; y+=2)

	{

		unsigned i;

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

		{

			asm volatile(

				"mov %2, %%"REG_a"		\n\t"

				"movq "MANGLE(bgr2YCoeff)", %%mm6		\n\t"

				"movq "MANGLE(w1111)", %%mm5		\n\t"

				"pxor %%mm7, %%mm7		\n\t"

				"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"\n\t"

				".balign 16			\n\t"

				"1:				\n\t"

				PREFETCH" 64(%0, %%"REG_b")	\n\t"

				"movd (%0, %%"REG_b"), %%mm0	\n\t"

				"movd 3(%0, %%"REG_b"), %%mm1	\n\t"

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

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

				"movd 6(%0, %%"REG_b"), %%mm2	\n\t"

				"movd 9(%0, %%"REG_b"), %%mm3	\n\t"

				"punpcklbw %%mm7, %%mm2		\n\t"

				"punpcklbw %%mm7, %%mm3		\n\t"

				"pmaddwd %%mm6, %%mm0		\n\t"

				"pmaddwd %%mm6, %%mm1		\n\t"

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

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

#ifndef FAST_BGR2YV12

				"psrad $8, %%mm0		\n\t"

				"psrad $8, %%mm1		\n\t"

				"psrad $8, %%mm2		\n\t"

				"psrad $8, %%mm3		\n\t"

#endif

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

				"packssdw %%mm3, %%mm2		\n\t"

				"pmaddwd %%mm5, %%mm0		\n\t"

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

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

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

				"movd 12(%0, %%"REG_b"), %%mm4	\n\t"

				"movd 15(%0, %%"REG_b"), %%mm1	\n\t"

				"punpcklbw %%mm7, %%mm4		\n\t"

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

				"movd 18(%0, %%"REG_b"), %%mm2	\n\t"

				"movd 21(%0, %%"REG_b"), %%mm3	\n\t"

				"punpcklbw %%mm7, %%mm2		\n\t"

				"punpcklbw %%mm7, %%mm3		\n\t"

				"pmaddwd %%mm6, %%mm4		\n\t"

				"pmaddwd %%mm6, %%mm1		\n\t"

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

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

#ifndef FAST_BGR2YV12

				"psrad $8, %%mm4		\n\t"

				"psrad $8, %%mm1		\n\t"

				"psrad $8, %%mm2		\n\t"

				"psrad $8, %%mm3		\n\t"

#endif

				"packssdw %%mm1, %%mm4		\n\t"

				"packssdw %%mm3, %%mm2		\n\t"

				"pmaddwd %%mm5, %%mm4		\n\t"

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

				"add $24, %%"REG_b"		\n\t"

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

				"psraw $7, %%mm4		\n\t"

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

				"paddusb "MANGLE(bgr2YOffset)", %%mm0	\n\t"

				MOVNTQ" %%mm0, (%1, %%"REG_a")	\n\t"

				"add $8, %%"REG_a"		\n\t"

				" js 1b				\n\t"

				: : "r" (src+width*3), "r" (ydst+width), "g" ((long)-width)

				: "%"REG_a, "%"REG_b

			);

			ydst += lumStride;

			src  += srcStride;

		}

		src -= srcStride*2;

		asm volatile(

			"mov %4, %%"REG_a"		\n\t"

			"movq "MANGLE(w1111)", %%mm5		\n\t"

			"movq "MANGLE(bgr2UCoeff)", %%mm6		\n\t"

			"pxor %%mm7, %%mm7		\n\t"

			"lea (%%"REG_a", %%"REG_a", 2), %%"REG_b"\n\t"

			"add %%"REG_b", %%"REG_b"	\n\t"

			".balign 16			\n\t"

			"1:				\n\t"

			PREFETCH" 64(%0, %%"REG_b")	\n\t"

			PREFETCH" 64(%1, %%"REG_b")	\n\t"

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

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

			"movq (%1, %%"REG_b"), %%mm1	\n\t"

			"movq 6(%0, %%"REG_b"), %%mm2	\n\t"

			"movq 6(%1, %%"REG_b"), %%mm3	\n\t"

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

			PAVGB" %%mm3, %%mm2		\n\t"

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

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

			"psrlq $24, %%mm0		\n\t"

			"psrlq $24, %%mm2		\n\t"

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

			PAVGB" %%mm3, %%mm2		\n\t"

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

			"punpcklbw %%mm7, %%mm2		\n\t"

#else

			"movd (%0, %%"REG_b"), %%mm0	\n\t"

			"movd (%1, %%"REG_b"), %%mm1	\n\t"

			"movd 3(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 3(%1, %%"REG_b"), %%mm3	\n\t"

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

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

			"punpcklbw %%mm7, %%mm2		\n\t"

			"punpcklbw %%mm7, %%mm3		\n\t"

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

			"paddw %%mm3, %%mm2		\n\t"

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

			"movd 6(%0, %%"REG_b"), %%mm4	\n\t"

			"movd 6(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 9(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 9(%1, %%"REG_b"), %%mm3	\n\t"

			"punpcklbw %%mm7, %%mm4		\n\t"

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

			"punpcklbw %%mm7, %%mm2		\n\t"

			"punpcklbw %%mm7, %%mm3		\n\t"

			"paddw %%mm1, %%mm4		\n\t"

			"paddw %%mm3, %%mm2		\n\t"

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

			"psrlw $2, %%mm0		\n\t"

			"psrlw $2, %%mm2		\n\t"

#endif

			"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

			"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

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

			"pmaddwd %%mm2, %%mm3		\n\t"

			"pmaddwd %%mm6, %%mm0		\n\t"

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

#ifndef FAST_BGR2YV12

			"psrad $8, %%mm0		\n\t"

			"psrad $8, %%mm1		\n\t"

			"psrad $8, %%mm2		\n\t"

			"psrad $8, %%mm3		\n\t"

#endif

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

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

			"pmaddwd %%mm5, %%mm0		\n\t"

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

			"packssdw %%mm1, %%mm0		\n\t" // V1 V0 U1 U0

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

#if defined (HAVE_MMX2) || defined (HAVE_3DNOW)

			"movq 12(%0, %%"REG_b"), %%mm4	\n\t"

			"movq 12(%1, %%"REG_b"), %%mm1	\n\t"

			"movq 18(%0, %%"REG_b"), %%mm2	\n\t"

			"movq 18(%1, %%"REG_b"), %%mm3	\n\t"

			PAVGB" %%mm1, %%mm4		\n\t"

			PAVGB" %%mm3, %%mm2		\n\t"

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

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

			"psrlq $24, %%mm4		\n\t"

			"psrlq $24, %%mm2		\n\t"

			PAVGB" %%mm1, %%mm4		\n\t"

			PAVGB" %%mm3, %%mm2		\n\t"

			"punpcklbw %%mm7, %%mm4		\n\t"

			"punpcklbw %%mm7, %%mm2		\n\t"

#else

			"movd 12(%0, %%"REG_b"), %%mm4	\n\t"

			"movd 12(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 15(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 15(%1, %%"REG_b"), %%mm3	\n\t"

			"punpcklbw %%mm7, %%mm4		\n\t"

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

			"punpcklbw %%mm7, %%mm2		\n\t"

			"punpcklbw %%mm7, %%mm3		\n\t"

			"paddw %%mm1, %%mm4		\n\t"

			"paddw %%mm3, %%mm2		\n\t"

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

			"movd 18(%0, %%"REG_b"), %%mm5	\n\t"

			"movd 18(%1, %%"REG_b"), %%mm1	\n\t"

			"movd 21(%0, %%"REG_b"), %%mm2	\n\t"

			"movd 21(%1, %%"REG_b"), %%mm3	\n\t"

			"punpcklbw %%mm7, %%mm5		\n\t"

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

			"punpcklbw %%mm7, %%mm2		\n\t"

			"punpcklbw %%mm7, %%mm3		\n\t"

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

			"paddw %%mm3, %%mm2		\n\t"

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

			"movq "MANGLE(w1111)", %%mm5		\n\t"

			"psrlw $2, %%mm4		\n\t"

			"psrlw $2, %%mm2		\n\t"

#endif

			"movq "MANGLE(bgr2VCoeff)", %%mm1		\n\t"

			"movq "MANGLE(bgr2VCoeff)", %%mm3		\n\t"

			"pmaddwd %%mm4, %%mm1		\n\t"

			"pmaddwd %%mm2, %%mm3		\n\t"

			"pmaddwd %%mm6, %%mm4		\n\t"

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

#ifndef FAST_BGR2YV12

			"psrad $8, %%mm4		\n\t"

			"psrad $8, %%mm1		\n\t"

			"psrad $8, %%mm2		\n\t"

			"psrad $8, %%mm3		\n\t"

#endif

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

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

			"pmaddwd %%mm5, %%mm4		\n\t"

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

			"add $24, %%"REG_b"		\n\t"

			"packssdw %%mm1, %%mm4		\n\t" // V3 V2 U3 U2

			"psraw $7, %%mm4		\n\t"

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

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

			"punpckhdq %%mm4, %%mm1		\n\t"

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

			"paddb "MANGLE(bgr2UVOffset)", %%mm0	\n\t"

			"movd %%mm0, (%2, %%"REG_a")	\n\t"

			"punpckhdq %%mm0, %%mm0		\n\t"

			"movd %%mm0, (%3, %%"REG_a")	\n\t"

			"add $4, %%"REG_a"		\n\t"

			" js 1b				\n\t"

			: : "r" (src+chromWidth*6), "r" (src+srcStride+chromWidth*6), "r" (udst+chromWidth), "r" (vdst+chromWidth), "g" ((long)-chromWidth)

			: "%"REG_a, "%"REG_b

		);

		udst += chromStride;

		vdst += chromStride;

		src  += srcStride*2;

	}

	asm volatile(   EMMS" \n\t"

			SFENCE" \n\t"

			:::"memory");

#else

	y=0;

#endif

	for(; y<height; y+=2)

	{

		unsigned i;

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

		{

			unsigned int b= src[6*i+0];

			unsigned int g= src[6*i+1];

			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			unsigned int V  =  ((RV*r + GV*g + BV*b)>>RGB2YUV_SHIFT) + 128;

			unsigned int U  =  ((RU*r + GU*g + BU*b)>>RGB2YUV_SHIFT) + 128;

			udst[i] 	= U;

			vdst[i] 	= V;

			ydst[2*i] 	= Y;

			b= src[6*i+3];

			g= src[6*i+4];

			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i+1] 	= Y;

		}

		ydst += lumStride;

		src  += srcStride;

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

		{

			unsigned int b= src[6*i+0];

			unsigned int g= src[6*i+1];

			unsigned int r= src[6*i+2];

			unsigned int Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i] 	= Y;

			b= src[6*i+3];

			g= src[6*i+4];

			r= src[6*i+5];

			Y  =  ((RY*r + GY*g + BY*b)>>RGB2YUV_SHIFT) + 16;

			ydst[2*i+1] 	= Y;

		}

		udst += chromStride;

		vdst += chromStride;

		ydst += lumStride;

		src  += srcStride;

	}

}


static void dec_wcsr(DisasContext *dc)

{

    int no;

    LOG_DIS("wcsr r%d, %d\n", dc->r1, dc->csr);

    switch (dc->csr) {

    case CSR_IE:

        tcg_gen_mov_tl(cpu_ie, cpu_R[dc->r1]);

        tcg_gen_movi_tl(cpu_pc, dc->pc + 4);

        dc->is_jmp = DISAS_UPDATE;

        break;

    case CSR_IM:

        /* mark as an io operation because it could cause an interrupt */

        if (use_icount) {

            gen_io_start();

        }

        gen_helper_wcsr_im(cpu_env, cpu_R[dc->r1]);

        tcg_gen_movi_tl(cpu_pc, dc->pc + 4);

        if (use_icount) {

            gen_io_end();

        }

        dc->is_jmp = DISAS_UPDATE;

        break;

    case CSR_IP:

        /* mark as an io operation because it could cause an interrupt */

        if (use_icount) {

            gen_io_start();

        }

        gen_helper_wcsr_ip(cpu_env, cpu_R[dc->r1]);

        tcg_gen_movi_tl(cpu_pc, dc->pc + 4);

        if (use_icount) {

            gen_io_end();

        }

        dc->is_jmp = DISAS_UPDATE;

        break;

    case CSR_ICC:

        /* TODO */

        break;

    case CSR_DCC:

        /* TODO */

        break;

    case CSR_EBA:

        tcg_gen_mov_tl(cpu_eba, cpu_R[dc->r1]);

        break;

    case CSR_DEBA:

        tcg_gen_mov_tl(cpu_deba, cpu_R[dc->r1]);

        break;

    case CSR_JTX:

        gen_helper_wcsr_jtx(cpu_env, cpu_R[dc->r1]);

        break;

    case CSR_JRX:

        gen_helper_wcsr_jrx(cpu_env, cpu_R[dc->r1]);

        break;

    case CSR_DC:

        tcg_gen_mov_tl(cpu_dc, cpu_R[dc->r1]);

        break;

    case CSR_BP0:

    case CSR_BP1:

    case CSR_BP2:

    case CSR_BP3:

        no = dc->csr - CSR_BP0;

        if (dc->env->num_bps <= no) {

            cpu_abort(dc->env, "breakpoint #%i is not available\n", no);

        }

        tcg_gen_mov_tl(cpu_bp[no], cpu_R[dc->r1]);

        break;

    case CSR_WP0:

    case CSR_WP1:

    case CSR_WP2:

    case CSR_WP3:

        no = dc->csr - CSR_WP0;

        if (dc->env->num_wps <= no) {

            cpu_abort(dc->env, "watchpoint #%i is not available\n", no);

        }

        tcg_gen_mov_tl(cpu_wp[no], cpu_R[dc->r1]);

        break;

    case CSR_CC:

    case CSR_CFG:

        cpu_abort(dc->env, "invalid write access csr=%x\n", dc->csr);

        break;

    default:

        cpu_abort(dc->env, "write_csr unknown csr=%x\n", dc->csr);

        break;

    }

}


void pmac_format_nvram_partition (MacIONVRAMState *nvr, int len)

{

    unsigned int i;

    uint32_t start = 0, end;

    struct OpenBIOS_nvpart_v1 *part_header;

    // OpenBIOS nvram variables

    // Variable partition

    part_header = (struct OpenBIOS_nvpart_v1 *)nvr->data;

    part_header->signature = OPENBIOS_PART_SYSTEM;

    pstrcpy(part_header->name, sizeof(part_header->name), "system");

    end = start + sizeof(struct OpenBIOS_nvpart_v1);

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

        end = OpenBIOS_set_var(nvr->data, end, prom_envs[i]);

    // End marker

    nvr->data[end++] = '\0';

    end = start + ((end - start + 15) & ~15);

    /* XXX: OpenBIOS is not able to grow up a partition. Leave some space for

       new variables. */

    if (end < DEF_SYSTEM_SIZE)

        end = DEF_SYSTEM_SIZE;

    OpenBIOS_finish_partition(part_header, end - start);

    // free partition

    start = end;

    part_header = (struct OpenBIOS_nvpart_v1 *)&nvr->data[start];

    part_header->signature = OPENBIOS_PART_FREE;

    pstrcpy(part_header->name, sizeof(part_header->name), "free");

    end = len;

    OpenBIOS_finish_partition(part_header, end - start);

}


static void gen_slq(DisasContext *ctx)

{

    int l1 = gen_new_label();

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x1F);

    tcg_gen_shl_tl(t0, cpu_gpr[rS(ctx->opcode)], t1);

    tcg_gen_subfi_tl(t1, 32, t1);

    tcg_gen_shr_tl(t1, cpu_gpr[rS(ctx->opcode)], t1);

    tcg_gen_or_tl(t1, t0, t1);

    gen_store_spr(SPR_MQ, t1);

    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0x20);

    tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);

    tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);

    tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);

    gen_set_label(l1);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

    if (unlikely(Rc(ctx->opcode) != 0))

        gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);

}


vmxnet3_pop_rxc_descr(VMXNET3State *s, int qidx, uint32_t *descr_gen)

{

    uint8_t ring_gen;

    struct Vmxnet3_RxCompDesc rxcd;

    hwaddr daddr =

        vmxnet3_ring_curr_cell_pa(&s->rxq_descr[qidx].comp_ring);

    pci_dma_read(PCI_DEVICE(s), daddr,

                 &rxcd, sizeof(struct Vmxnet3_RxCompDesc));

    ring_gen = vmxnet3_ring_curr_gen(&s->rxq_descr[qidx].comp_ring);

    if (rxcd.gen != ring_gen) {

        *descr_gen = ring_gen;

        vmxnet3_inc_rx_completion_counter(s, qidx);

        return daddr;

    }

    return 0;

}


build_madt(GArray *table_data, GArray *linker, AcpiCpuInfo *cpu)

{

    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());

    int madt_start = table_data->len;

    AcpiMultipleApicTable *madt;

    AcpiMadtIoApic *io_apic;

    AcpiMadtIntsrcovr *intsrcovr;

    AcpiMadtLocalNmi *local_nmi;

    int i;

    madt = acpi_data_push(table_data, sizeof *madt);

    madt->local_apic_address = cpu_to_le32(APIC_DEFAULT_ADDRESS);

    madt->flags = cpu_to_le32(1);

    for (i = 0; i < pcms->apic_id_limit; i++) {

        AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);

        apic->type = ACPI_APIC_PROCESSOR;

        apic->length = sizeof(*apic);

        apic->processor_id = i;

        apic->local_apic_id = i;

        if (test_bit(i, cpu->found_cpus)) {

            apic->flags = cpu_to_le32(1);

        } else {

            apic->flags = cpu_to_le32(0);

        }

    }

    io_apic = acpi_data_push(table_data, sizeof *io_apic);

    io_apic->type = ACPI_APIC_IO;

    io_apic->length = sizeof(*io_apic);

#define ACPI_BUILD_IOAPIC_ID 0x0

    io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;

    io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);

    io_apic->interrupt = cpu_to_le32(0);

    if (pcms->apic_xrupt_override) {

        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);

        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;

        intsrcovr->length = sizeof(*intsrcovr);

        intsrcovr->source = 0;

        intsrcovr->gsi    = cpu_to_le32(2);

        intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus specifications */

    }

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

#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))

        if (!(ACPI_BUILD_PCI_IRQS & (1 << i))) {

            /* No need for a INT source override structure. */

            continue;

        }

        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);

        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;

        intsrcovr->length = sizeof(*intsrcovr);

        intsrcovr->source = i;

        intsrcovr->gsi    = cpu_to_le32(i);

        intsrcovr->flags  = cpu_to_le16(0xd); /* active high, level triggered */

    }

    local_nmi = acpi_data_push(table_data, sizeof *local_nmi);

    local_nmi->type         = ACPI_APIC_LOCAL_NMI;

    local_nmi->length       = sizeof(*local_nmi);

    local_nmi->processor_id = 0xff; /* all processors */

    local_nmi->flags        = cpu_to_le16(0);

    local_nmi->lint         = 1; /* ACPI_LINT1 */

    build_header(linker, table_data,

                 (void *)(table_data->data + madt_start), "APIC",

                 table_data->len - madt_start, 1, NULL);

}


matroska_parse_blockgroup (MatroskaDemuxContext *matroska,

                           uint64_t              cluster_time)

{

    int res = 0;

    uint32_t id;

    AVPacket *pkt = NULL;

    int is_keyframe = PKT_FLAG_KEY, last_num_packets = matroska->num_packets;

    uint64_t duration = AV_NOPTS_VALUE;

    int track = -1;

    uint8_t *data;

    int size = 0;

    int64_t pos = 0;

    av_log(matroska->ctx, AV_LOG_DEBUG, "parsing blockgroup...\n");

    while (res == 0) {

        if (!(id = ebml_peek_id(matroska, &matroska->level_up))) {

            res = AVERROR_IO;

            break;

        } else if (matroska->level_up) {

            matroska->level_up--;

            break;

        }

        switch (id) {

            /* one block inside the group. Note, block parsing is one

             * of the harder things, so this code is a bit complicated.

             * See http://www.matroska.org/ for documentation. */

            case MATROSKA_ID_BLOCK: {

                pos = url_ftell(&matroska->ctx->pb);

                res = ebml_read_binary(matroska, &id, &data, &size);

                break;

            }

            case MATROSKA_ID_BLOCKDURATION: {

                if ((res = ebml_read_uint(matroska, &id, &duration)) < 0)

                    break;

                break;

            }

            case MATROSKA_ID_BLOCKREFERENCE:

                /* We've found a reference, so not even the first frame in

                 * the lace is a key frame. */

                is_keyframe = 0;

                if (last_num_packets != matroska->num_packets)

                    matroska->packets[last_num_packets]->flags = 0;

                res = ebml_read_skip(matroska);

                break;

            default:

                av_log(matroska->ctx, AV_LOG_INFO,

                       "Unknown entry 0x%x in blockgroup data\n", id);

                /* fall-through */

            case EBML_ID_VOID:

                res = ebml_read_skip(matroska);

                break;

        }

        if (matroska->level_up) {

            matroska->level_up--;

            break;

        }

    }

    if (res)

        return res;

    if (size > 0)

        res = matroska_parse_block(matroska, data, size, pos, cluster_time,

                                   is_keyframe, &track, &pkt);

    if (pkt)

    {

        if (duration != AV_NOPTS_VALUE)

            pkt->duration = duration;

        else if (track >= 0 && track < matroska->num_tracks)

            pkt->duration = matroska->tracks[track]->default_duration / matroska->time_scale;

    }

    return res;

}


void vncws_tls_handshake_peek(void *opaque)

{

    VncState *vs = opaque;

    long ret;

    if (!vs->ws_tls.session) {

        char peek[4];

        ret = qemu_recv(vs->csock, peek, sizeof(peek), MSG_PEEK);

        if (ret && (strncmp(peek, "\x16", 1) == 0

                    || strncmp(peek, "\x80", 1) == 0)) {

            VNC_DEBUG("TLS Websocket connection recognized");

            vnc_tls_client_setup(vs, 1);

            vncws_start_tls_handshake(vs);

        } else {

            vncws_handshake_read(vs);

        }

    } else {

        qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs);

    }

}


bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)

{

    target_ulong dr6;

    int reg;

    bool hit_enabled = false;

    dr6 = env->dr[6] & ~0xf;

    for (reg = 0; reg < DR7_MAX_BP; reg++) {

        bool bp_match = false;

        bool wp_match = false;

        switch (hw_breakpoint_type(env->dr[7], reg)) {

        case DR7_TYPE_BP_INST:

            if (env->dr[reg] == env->eip) {

                bp_match = true;

            }

            break;

        case DR7_TYPE_DATA_WR:

        case DR7_TYPE_DATA_RW:

            if (env->cpu_watchpoint[reg] &&

                env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {

                wp_match = true;

            }

            break;

        case DR7_TYPE_IO_RW:

            break;

        }

        if (bp_match || wp_match) {

            dr6 |= 1 << reg;

            if (hw_breakpoint_enabled(env->dr[7], reg)) {

                hit_enabled = true;

            }

        }

    }

    if (hit_enabled || force_dr6_update) {

        env->dr[6] = dr6;

    }

    return hit_enabled;

}


static int ipvideo_decode_block_opcode_0x7(IpvideoContext *s)

{

    int x, y;

    unsigned char P[2];

    unsigned int flags;

    /* 2-color encoding */

    CHECK_STREAM_PTR(2);

    P[0] = *s->stream_ptr++;

    P[1] = *s->stream_ptr++;

    if (P[0] <= P[1]) {

        /* need 8 more bytes from the stream */

        CHECK_STREAM_PTR(8);

        for (y = 0; y < 8; y++) {

            flags = *s->stream_ptr++ | 0x100;

            for (; flags != 1; flags >>= 1)

                *s->pixel_ptr++ = P[flags & 1];

            s->pixel_ptr += s->line_inc;

        }

    } else {

        /* need 2 more bytes from the stream */

        CHECK_STREAM_PTR(2);

        flags = bytestream_get_le16(&s->stream_ptr);

        for (y = 0; y < 8; y += 2) {

            for (x = 0; x < 8; x += 2, flags >>= 1) {

                s->pixel_ptr[x                ] =

                s->pixel_ptr[x + 1            ] =

                s->pixel_ptr[x +     s->stride] =

                s->pixel_ptr[x + 1 + s->stride] = P[flags & 1];

            }

            s->pixel_ptr += s->stride * 2;

        }

    }

    /* report success */

    return 0;

}


void arm_translate_init(void)

{

    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");

    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG1, "T0");

    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_I32, TCG_AREG2, "T1");

}


void virtio_9p_push_and_notify(V9fsPDU *pdu)

{

    V9fsState *s = pdu->s;

    V9fsVirtioState *v = container_of(s, V9fsVirtioState, state);

    VirtQueueElement *elem = &v->elems[pdu->idx];

    /* push onto queue and notify */

    virtqueue_push(v->vq, elem, pdu->size);

    /* FIXME: we should batch these completions */

    virtio_notify(VIRTIO_DEVICE(v), v->vq);

}


int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs,

    int64_t offset, unsigned int bytes, QEMUIOVector *qiov,

    BdrvRequestFlags flags)

{

    BdrvTrackedRequest req;

    uint64_t align = bs->request_alignment;

    uint8_t *head_buf = NULL;

    uint8_t *tail_buf = NULL;

    QEMUIOVector local_qiov;

    bool use_local_qiov = false;

    int ret;

    if (!bs->drv) {

        return -ENOMEDIUM;

    }

    if (bs->read_only) {

        return -EPERM;

    }

    assert(!(bs->open_flags & BDRV_O_INACTIVE));

    ret = bdrv_check_byte_request(bs, offset, bytes);

    if (ret < 0) {

        return ret;

    }

    /*

     * Align write if necessary by performing a read-modify-write cycle.

     * Pad qiov with the read parts and be sure to have a tracked request not

     * only for bdrv_aligned_pwritev, but also for the reads of the RMW cycle.

     */

    tracked_request_begin(&req, bs, offset, bytes, BDRV_TRACKED_WRITE);

    if (!qiov) {

        ret = bdrv_co_do_zero_pwritev(bs, offset, bytes, flags, &req);

        goto out;

    }

    if (offset & (align - 1)) {

        QEMUIOVector head_qiov;

        struct iovec head_iov;

        mark_request_serialising(&req, align);

        wait_serialising_requests(&req);

        head_buf = qemu_blockalign(bs, align);

        head_iov = (struct iovec) {

            .iov_base   = head_buf,

            .iov_len    = align,

        };

        qemu_iovec_init_external(&head_qiov, &head_iov, 1);

        bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD);

        ret = bdrv_aligned_preadv(bs, &req, offset & ~(align - 1), align,

                                  align, &head_qiov, 0);

        if (ret < 0) {

            goto fail;

        }

        bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_HEAD);

        qemu_iovec_init(&local_qiov, qiov->niov + 2);

        qemu_iovec_add(&local_qiov, head_buf, offset & (align - 1));

        qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);

        use_local_qiov = true;

        bytes += offset & (align - 1);

        offset = offset & ~(align - 1);

        /* We have read the tail already if the request is smaller

         * than one aligned block.

         */

        if (bytes < align) {

            qemu_iovec_add(&local_qiov, head_buf + bytes, align - bytes);

            bytes = align;

        }

    }

    if ((offset + bytes) & (align - 1)) {

        QEMUIOVector tail_qiov;

        struct iovec tail_iov;

        size_t tail_bytes;

        bool waited;

        mark_request_serialising(&req, align);

        waited = wait_serialising_requests(&req);

        assert(!waited || !use_local_qiov);

        tail_buf = qemu_blockalign(bs, align);

        tail_iov = (struct iovec) {

            .iov_base   = tail_buf,

            .iov_len    = align,

        };

        qemu_iovec_init_external(&tail_qiov, &tail_iov, 1);

        bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);

        ret = bdrv_aligned_preadv(bs, &req, (offset + bytes) & ~(align - 1), align,

                                  align, &tail_qiov, 0);

        if (ret < 0) {

            goto fail;

        }

        bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_AFTER_TAIL);

        if (!use_local_qiov) {

            qemu_iovec_init(&local_qiov, qiov->niov + 1);

            qemu_iovec_concat(&local_qiov, qiov, 0, qiov->size);

            use_local_qiov = true;

        }

        tail_bytes = (offset + bytes) & (align - 1);

        qemu_iovec_add(&local_qiov, tail_buf + tail_bytes, align - tail_bytes);

        bytes = ROUND_UP(bytes, align);

    }

    ret = bdrv_aligned_pwritev(bs, &req, offset, bytes, align,

                               use_local_qiov ? &local_qiov : qiov,

                               flags);

fail:

    if (use_local_qiov) {

        qemu_iovec_destroy(&local_qiov);

    }

    qemu_vfree(head_buf);

    qemu_vfree(tail_buf);

out:

    tracked_request_end(&req);

    return ret;

}


static int kvm_s390_check_clear_cmma(KVMState *s)

{

    struct kvm_device_attr attr = {

        .group = KVM_S390_VM_MEM_CTRL,

        .attr = KVM_S390_VM_MEM_CLR_CMMA,

    };

    return kvm_vm_ioctl(s, KVM_HAS_DEVICE_ATTR, &attr);

}


static int bdrv_fill_options(QDict **options, const char **pfilename, int flags,

                             BlockDriver *drv, Error **errp)

{

    const char *filename = *pfilename;

    const char *drvname;

    bool protocol = flags & BDRV_O_PROTOCOL;

    bool parse_filename = false;

    Error *local_err = NULL;

    /* Parse json: pseudo-protocol */

    if (filename && g_str_has_prefix(filename, "json:")) {

        QDict *json_options = parse_json_filename(filename, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return -EINVAL;

        }

        /* Options given in the filename have lower priority than options

         * specified directly */

        qdict_join(*options, json_options, false);

        QDECREF(json_options);

        *pfilename = filename = NULL;

    }

    /* Fetch the file name from the options QDict if necessary */

    if (protocol && filename) {

        if (!qdict_haskey(*options, "filename")) {

            qdict_put(*options, "filename", qstring_from_str(filename));

            parse_filename = true;

        } else {

            error_setg(errp, "Can't specify 'file' and 'filename' options at "

                             "the same time");

            return -EINVAL;

        }

    }

    /* Find the right block driver */

    filename = qdict_get_try_str(*options, "filename");

    drvname = qdict_get_try_str(*options, "driver");

    if (drv) {

        if (drvname) {

            error_setg(errp, "Driver specified twice");

            return -EINVAL;

        }

        drvname = drv->format_name;

        qdict_put(*options, "driver", qstring_from_str(drvname));

    } else {

        if (!drvname && protocol) {

            if (filename) {

                drv = bdrv_find_protocol(filename, parse_filename, errp);

                if (!drv) {

                    return -EINVAL;

                }

                drvname = drv->format_name;

                qdict_put(*options, "driver", qstring_from_str(drvname));

            } else {

                error_setg(errp, "Must specify either driver or file");

                return -EINVAL;

            }

        } else if (drvname) {

            drv = bdrv_find_format(drvname);

            if (!drv) {

                error_setg(errp, "Unknown driver '%s'", drvname);

                return -ENOENT;

            }

        }

    }

    assert(drv || !protocol);

    /* Driver-specific filename parsing */

    if (drv && drv->bdrv_parse_filename && parse_filename) {

        drv->bdrv_parse_filename(filename, *options, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return -EINVAL;

        }

        if (!drv->bdrv_needs_filename) {

            qdict_del(*options, "filename");

        }

    }

    return 0;

}