static void draw_digit(int digit, uint8_t *dst, unsigned dst_linesize,

                       unsigned segment_width)

{

#define TOP_HBAR        1

#define MID_HBAR        2

#define BOT_HBAR        4

#define LEFT_TOP_VBAR   8

#define LEFT_BOT_VBAR  16

#define RIGHT_TOP_VBAR 32

#define RIGHT_BOT_VBAR 64

    struct {

        int x, y, w, h;

    } segments[] = {

        { 1,  0, 5, 1 }, /* TOP_HBAR */

        { 1,  6, 5, 1 }, /* MID_HBAR */

        { 1, 12, 5, 1 }, /* BOT_HBAR */

        { 0,  1, 1, 5 }, /* LEFT_TOP_VBAR */

        { 0,  7, 1, 5 }, /* LEFT_BOT_VBAR */

        { 6,  1, 1, 5 }, /* RIGHT_TOP_VBAR */

        { 6,  7, 1, 5 }  /* RIGHT_BOT_VBAR */

    };

    static const unsigned char masks[10] = {

        /* 0 */ TOP_HBAR         |BOT_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 1 */                                                        RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 2 */ TOP_HBAR|MID_HBAR|BOT_HBAR|LEFT_BOT_VBAR                             |RIGHT_TOP_VBAR,

        /* 3 */ TOP_HBAR|MID_HBAR|BOT_HBAR                            |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 4 */          MID_HBAR         |LEFT_TOP_VBAR              |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 5 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR                             |RIGHT_BOT_VBAR,

        /* 6 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR               |RIGHT_BOT_VBAR,

        /* 7 */ TOP_HBAR                                              |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 8 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR|LEFT_BOT_VBAR|RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

        /* 9 */ TOP_HBAR|BOT_HBAR|MID_HBAR|LEFT_TOP_VBAR              |RIGHT_TOP_VBAR|RIGHT_BOT_VBAR,

    };

    unsigned mask = masks[digit];

    int i;

    draw_rectangle(0, dst, dst_linesize, segment_width, 0, 0, 8, 13);

    for (i = 0; i < FF_ARRAY_ELEMS(segments); i++)

        if (mask & (1<<i))

            draw_rectangle(255, dst, dst_linesize, segment_width,

                           segments[i].x, segments[i].y, segments[i].w, segments[i].h);

}


static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)

{

    int i, j, ret;

    int scaler_count = 0, resampler_count = 0;

    int count_queried = 0, count_merged = 0, count_already_merged = 0,

        count_delayed = 0;

    for (i = 0; i < graph->nb_filters; i++) {

        AVFilterContext *f = graph->filters[i];

        if (formats_declared(f))

            continue;

        if (f->filter->query_formats)

            ret = filter_query_formats(f);

        else

            ret = ff_default_query_formats(f);

        if (ret < 0 && ret != AVERROR(EAGAIN))

            return ret;

        /* note: EAGAIN could indicate a partial success, not counted yet */

        count_queried += ret >= 0;

    }

    /* go through and merge as many format lists as possible */

    for (i = 0; i < graph->nb_filters; i++) {

        AVFilterContext *filter = graph->filters[i];

        for (j = 0; j < filter->nb_inputs; j++) {

            AVFilterLink *link = filter->inputs[j];

            int convert_needed = 0;

            if (!link)

                continue;

#define MERGE_DISPATCH(field, statement)                                     \

            if (!(link->in_ ## field && link->out_ ## field)) {              \

                count_delayed++;                                             \

            } else if (link->in_ ## field == link->out_ ## field) {          \

                count_already_merged++;                                      \

            } else {                                                         \

                count_merged++;                                              \

                statement                                                    \

            }

            MERGE_DISPATCH(formats,

                if (!ff_merge_formats(link->in_formats, link->out_formats,

                                      link->type))

                    convert_needed = 1;

            )

            if (link->type == AVMEDIA_TYPE_AUDIO) {

                MERGE_DISPATCH(channel_layouts,

                    if (!ff_merge_channel_layouts(link->in_channel_layouts,

                                                  link->out_channel_layouts))

                        convert_needed = 1;

                )

                MERGE_DISPATCH(samplerates,

                    if (!ff_merge_samplerates(link->in_samplerates,

                                              link->out_samplerates))

                        convert_needed = 1;

                )

            }

#undef MERGE_DISPATCH

            if (convert_needed) {

                AVFilterContext *convert;

                AVFilter *filter;

                AVFilterLink *inlink, *outlink;

                char scale_args[256];

                char inst_name[30];

                /* couldn't merge format lists. auto-insert conversion filter */

                switch (link->type) {

                case AVMEDIA_TYPE_VIDEO:

                    if (!(filter = avfilter_get_by_name("scale"))) {

                        av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "

                               "not present, cannot convert pixel formats.\n");

                        return AVERROR(EINVAL);

                    }

                    snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",

                             scaler_count++);

                    av_strlcpy(scale_args, "0:0", sizeof(scale_args));

                    if (graph->scale_sws_opts) {

                        av_strlcat(scale_args, ":", sizeof(scale_args));

                        av_strlcat(scale_args, graph->scale_sws_opts, sizeof(scale_args));

                    }

                    if ((ret = avfilter_graph_create_filter(&convert, filter,

                                                            inst_name, scale_args, NULL,

                                                            graph)) < 0)

                        return ret;

                    break;

                case AVMEDIA_TYPE_AUDIO:

                    if (!(filter = avfilter_get_by_name("aresample"))) {

                        av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "

                               "not present, cannot convert audio formats.\n");

                        return AVERROR(EINVAL);

                    }

                    snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",

                             resampler_count++);

                    scale_args[0] = '\0';

                    if (graph->aresample_swr_opts)

                        snprintf(scale_args, sizeof(scale_args), "%s",

                                 graph->aresample_swr_opts);

                    if ((ret = avfilter_graph_create_filter(&convert, filter,

                                                            inst_name, graph->aresample_swr_opts,

                                                            NULL, graph)) < 0)

                        return ret;

                    break;

                default:

                    return AVERROR(EINVAL);

                }

                if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)

                    return ret;

                filter_query_formats(convert);

                inlink  = convert->inputs[0];

                outlink = convert->outputs[0];

                if (!ff_merge_formats( inlink->in_formats,  inlink->out_formats,  inlink->type) ||

                    !ff_merge_formats(outlink->in_formats, outlink->out_formats, outlink->type))

                    ret |= AVERROR(ENOSYS);

                if (inlink->type == AVMEDIA_TYPE_AUDIO &&

                    (!ff_merge_samplerates(inlink->in_samplerates,

                                           inlink->out_samplerates) ||

                     !ff_merge_channel_layouts(inlink->in_channel_layouts,

                                               inlink->out_channel_layouts)))

                    ret |= AVERROR(ENOSYS);

                if (outlink->type == AVMEDIA_TYPE_AUDIO &&

                    (!ff_merge_samplerates(outlink->in_samplerates,

                                           outlink->out_samplerates) ||

                     !ff_merge_channel_layouts(outlink->in_channel_layouts,

                                               outlink->out_channel_layouts)))

                    ret |= AVERROR(ENOSYS);

                if (ret < 0) {

                    av_log(log_ctx, AV_LOG_ERROR,

                           "Impossible to convert between the formats supported by the filter "

                           "'%s' and the filter '%s'\n", link->src->name, link->dst->name);

                    return ret;

                }

            }

        }

    }

    av_log(graph, AV_LOG_DEBUG, "query_formats: "

           "%d queried, %d merged, %d already done, %d delayed\n",

           count_queried, count_merged, count_already_merged, count_delayed);

    if (count_delayed) {

        AVBPrint bp;

        if (count_queried || count_merged)

            return AVERROR(EAGAIN);

        av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);

        for (i = 0; i < graph->nb_filters; i++)

            if (!formats_declared(graph->filters[i]))

                av_bprintf(&bp, "%s%s", bp.len ? ", " : "",

                          graph->filters[i]->name);

        av_log(graph, AV_LOG_ERROR,

               "The following filters could not choose their formats: %s\n"

               "Consider inserting the (a)format filter near their input or "

               "output.\n", bp.str);

        return AVERROR(EIO);

    }

    return 0;

}


static inline void mix_2f_1r_to_stereo(AC3DecodeContext *ctx)

{

    int i;

    float (*output)[256] = ctx->audio_block.block_output;

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

        output[1][i] += output[2][i];

        output[2][i] += output[3][i];

    }

    memset(output[3], 0, sizeof(output[3]));

}


static int decode_cabac_mb_cbp_chroma( H264Context *h) {

    int ctx;

    int cbp_a, cbp_b;

    cbp_a = (h->left_cbp>>4)&0x03;

    cbp_b = (h-> top_cbp>>4)&0x03;

    ctx = 0;

    if( cbp_a > 0 ) ctx++;

    if( cbp_b > 0 ) ctx += 2;

    if( get_cabac( &h->cabac, &h->cabac_state[77 + ctx] ) == 0 )

        return 0;

    ctx = 4;

    if( cbp_a == 2 ) ctx++;

    if( cbp_b == 2 ) ctx += 2;

    return 1 + get_cabac( &h->cabac, &h->cabac_state[77 + ctx] );

}


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

{

    MP3Context  *mp3 = s->priv_data;

    if (pkt && pkt->data && pkt->size >= 4) {

        MPADecodeHeader c;

        int av_unused base;

        avpriv_mpegaudio_decode_header(&c, AV_RB32(pkt->data));

        if (!mp3->initial_bitrate)

            mp3->initial_bitrate = c.bit_rate;

        if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))

            mp3->has_variable_bitrate = 1;

#ifdef FILTER_VBR_HEADERS

        /* filter out XING and INFO headers. */

        base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1];

        if (base + 4 <= pkt->size) {

            uint32_t v = AV_RB32(pkt->data + base);

            if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v)

                return 0;

        }

        /* filter out VBRI headers. */

        base = 4 + 32;

        if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base))

            return 0;

#endif

        if (mp3->xing_offset)

            mp3_xing_add_frame(mp3, pkt);

    }

    return ff_raw_write_packet(s, pkt);

}


int has_altivec(void)

{

#ifdef __AMIGAOS4__

    ULONG result = 0;

    extern struct ExecIFace *IExec;

    IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);

    if (result == VECTORTYPE_ALTIVEC) return 1;

    return 0;

#else /* __AMIGAOS4__ */

#ifdef SYS_DARWIN

    int sels[2] = {CTL_HW, HW_VECTORUNIT};

    int has_vu = 0;

    size_t len = sizeof(has_vu);

    int err;

    err = sysctl(sels, 2, &has_vu, &len, NULL, 0);

    if (err == 0) return (has_vu != 0);

#else /* SYS_DARWIN */

/* no Darwin, do it the brute-force way */

/* this is borrowed from the libmpeg2 library */

    {

      signal (SIGILL, sigill_handler);

      if (sigsetjmp (jmpbuf, 1)) {

        signal (SIGILL, SIG_DFL);

      } else {

        canjump = 1;

        asm volatile ("mtspr 256, %0\n\t"

                      "vand %%v0, %%v0, %%v0"

                      :

                      : "r" (-1));

        signal (SIGILL, SIG_DFL);

        return 1;

      }

    }

#endif /* SYS_DARWIN */

    return 0;

#endif /* __AMIGAOS4__ */

}


static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)

{

    AVCodecContext *avctx = s->avctx;

    Mpeg1Context *s1      = (Mpeg1Context *) s;

    int ret;

    if (s->picture_structure == PICT_FRAME)

        s->first_field = 0;

    else

        s->first_field ^= 1;

    /* start frame decoding */

    if (s->first_field || s->picture_structure == PICT_FRAME) {

        AVFrameSideData *pan_scan;

        if ((ret = ff_mpv_frame_start(s, avctx)) < 0)

            return ret;

        ff_mpeg_er_frame_start(s);

        /* first check if we must repeat the frame */

        s->current_picture_ptr->f->repeat_pict = 0;

        if (s->repeat_first_field) {

            if (s->progressive_sequence) {

                if (s->top_field_first)

                    s->current_picture_ptr->f->repeat_pict = 4;

                else

                    s->current_picture_ptr->f->repeat_pict = 2;

            } else if (s->progressive_frame) {

                s->current_picture_ptr->f->repeat_pict = 1;

            }

        }

        pan_scan = av_frame_new_side_data(s->current_picture_ptr->f,

                                          AV_FRAME_DATA_PANSCAN,

                                          sizeof(s1->pan_scan));

        if (!pan_scan)

            return AVERROR(ENOMEM);

        memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));

        if (s1->a53_caption) {

            AVFrameSideData *sd = av_frame_new_side_data(

                s->current_picture_ptr->f, AV_FRAME_DATA_A53_CC,

                s1->a53_caption_size);

            if (sd)

                memcpy(sd->data, s1->a53_caption, s1->a53_caption_size);

            av_freep(&s1->a53_caption);

        }

        if (s1->has_stereo3d) {

            AVStereo3D *stereo = av_stereo3d_create_side_data(s->current_picture_ptr->f);

            if (!stereo)

                return AVERROR(ENOMEM);

            *stereo = s1->stereo3d;

            s1->has_stereo3d = 0;

        }

        if (s1->has_afd) {

            AVFrameSideData *sd =

                av_frame_new_side_data(s->current_picture_ptr->f,

                                       AV_FRAME_DATA_AFD, 1);

            if (!sd)

                return AVERROR(ENOMEM);

            *sd->data   = s1->afd;

            s1->has_afd = 0;

        }

        if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))

            ff_thread_finish_setup(avctx);

    } else { // second field

        int i;

        if (!s->current_picture_ptr) {

            av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");

            return AVERROR_INVALIDDATA;

        }

        if (s->avctx->hwaccel &&

            (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {

            if (s->avctx->hwaccel->end_frame(s->avctx) < 0)

                av_log(avctx, AV_LOG_ERROR,

                       "hardware accelerator failed to decode first field\n");

        }

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

            s->current_picture.f->data[i] = s->current_picture_ptr->f->data[i];

            if (s->picture_structure == PICT_BOTTOM_FIELD)

                s->current_picture.f->data[i] +=

                    s->current_picture_ptr->f->linesize[i];

        }

    }

    if (avctx->hwaccel) {

        if ((ret = avctx->hwaccel->start_frame(avctx, buf, buf_size)) < 0)

            return ret;

    }

#if FF_API_XVMC

FF_DISABLE_DEPRECATION_WARNINGS

// ff_mpv_frame_start will call this function too,

// but we need to call it on every field

    if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)

        if (ff_xvmc_field_start(s, avctx) < 0)

            return -1;

FF_ENABLE_DEPRECATION_WARNINGS

#endif /* FF_API_XVMC */

    return 0;

}


static inline int cris_bound_w(int v, int b)

{

	int r = v;

	asm ("bound.w\t%1, %0\n" : "+r" (r) : "ri" (b));

	return r;

}


static void mpeg_decode_picture_coding_extension(MpegEncContext *s)

{

    s->full_pel[0] = s->full_pel[1] = 0;

    s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);

    s->intra_dc_precision = get_bits(&s->gb, 2);

    s->picture_structure = get_bits(&s->gb, 2);

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

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

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

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

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

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

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

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

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

    /* composite display not parsed */

    dprintf("intra_dc_precion=%d\n", s->intra_dc_precision);

    dprintf("picture_structure=%d\n", s->picture_structure);

    dprintf("conceal=%d\n", s->concealment_motion_vectors);

    dprintf("intra_vlc_format=%d\n", s->intra_vlc_format);

    dprintf("alternate_scan=%d\n", s->alternate_scan);

    dprintf("frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);

}


static int xen_remove_from_physmap(XenIOState *state,

                                   hwaddr start_addr,

                                   ram_addr_t size)

{

    unsigned long i = 0;

    int rc = 0;

    XenPhysmap *physmap = NULL;

    hwaddr phys_offset = 0;

    physmap = get_physmapping(state, start_addr, size);

    if (physmap == NULL) {

        return -1;

    }

    phys_offset = physmap->phys_offset;

    size = physmap->size;

    DPRINTF("unmapping vram to %"HWADDR_PRIx" - %"HWADDR_PRIx", from ",

            "%"HWADDR_PRIx"\n", phys_offset, phys_offset + size, start_addr);

    size >>= TARGET_PAGE_BITS;

    start_addr >>= TARGET_PAGE_BITS;

    phys_offset >>= TARGET_PAGE_BITS;

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

        unsigned long idx = start_addr + i;

        xen_pfn_t gpfn = phys_offset + i;

        rc = xc_domain_add_to_physmap(xen_xc, xen_domid, XENMAPSPACE_gmfn, idx, gpfn);

        if (rc) {

            fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"

                    PRI_xen_pfn" failed: %d\n", idx, gpfn, rc);

            return -rc;

        }

    }

    QLIST_REMOVE(physmap, list);

    if (state->log_for_dirtybit == physmap) {

        state->log_for_dirtybit = NULL;

    }

    free(physmap);

    return 0;

}


static int mpegvideo_probe(AVProbeData *p)

{

    uint32_t code= -1;

    int pic=0, seq=0, slice=0, pspack=0, vpes=0, apes=0, res=0, sicle=0;

    int i;

    uint32_t last = 0;

    for(i=0; i<p->buf_size; i++){

        code = (code<<8) + p->buf[i];

        if ((code & 0xffffff00) == 0x100) {

            switch(code){

            case     SEQ_START_CODE:   seq++; break;

            case PICTURE_START_CODE:   pic++; break;

            case    PACK_START_CODE: pspack++; break;

            case              0x1b6:

                                        res++; break;

            }

            if (code >= SLICE_START_CODE && code <= 0x1af) {

                if (last >= SLICE_START_CODE && last <= 0x1af) {

                    if (code >= last) slice++;

                    else              sicle++;

                }else{

                    if (code == SLICE_START_CODE) slice++;

                    else                          sicle++;

                }

            }

            if     ((code & 0x1f0) == VIDEO_ID)   vpes++;

            else if((code & 0x1e0) == AUDIO_ID)   apes++;

            last = code;

        }

    }

    if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !apes && !res && slice > sicle) {

        if(vpes) return AVPROBE_SCORE_EXTENSION / 4;

        else     return pic>1 ? AVPROBE_SCORE_EXTENSION + 1 : AVPROBE_SCORE_EXTENSION / 2; // +1 for .mpg

    }

    return 0;

}


static void usb_ohci_init(OHCIState *ohci, DeviceState *dev,
                          int num_ports, dma_addr_t localmem_base,
                          char *masterbus, uint32_t firstport,
                          AddressSpace *as, Error **errp)
{
    Error *err = NULL;
    int i;
    ohci->as = as;
    if (usb_frame_time == 0) {
#ifdef OHCI_TIME_WARP
        usb_frame_time = NANOSECONDS_PER_SECOND;
        usb_bit_time = NANOSECONDS_PER_SECOND / (USB_HZ / 1000);
#else
        usb_frame_time = NANOSECONDS_PER_SECOND / 1000;
        if (NANOSECONDS_PER_SECOND >= USB_HZ) {
            usb_bit_time = NANOSECONDS_PER_SECOND / USB_HZ;
        } else {
            usb_bit_time = 1;
#endif
        trace_usb_ohci_init_time(usb_frame_time, usb_bit_time);
    ohci->num_ports = num_ports;
    if (masterbus) {
        USBPort *ports[OHCI_MAX_PORTS];
        for(i = 0; i < num_ports; i++) {
            ports[i] = &ohci->rhport[i].port;
        usb_register_companion(masterbus, ports, num_ports,
                               firstport, ohci, &ohci_port_ops,
                               USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL,
                               &err);
        if (err) {
            error_propagate(errp, err);
    } else {
        usb_bus_new(&ohci->bus, sizeof(ohci->bus), &ohci_bus_ops, dev);
        for (i = 0; i < num_ports; i++) {
            usb_register_port(&ohci->bus, &ohci->rhport[i].port,
                              ohci, i, &ohci_port_ops,
                              USB_SPEED_MASK_LOW | USB_SPEED_MASK_FULL);
    memory_region_init_io(&ohci->mem, OBJECT(dev), &ohci_mem_ops,
                          ohci, "ohci", 256);
    ohci->localmem_base = localmem_base;
    ohci->name = object_get_typename(OBJECT(dev));
    usb_packet_init(&ohci->usb_packet);
    ohci->async_td = 0;
    ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                   ohci_frame_boundary, ohci);


static void isabus_fdc_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = isabus_fdc_realize;

    dc->fw_name = "fdc";

    dc->no_user = 1;

    dc->reset = fdctrl_external_reset_isa;

    dc->vmsd = &vmstate_isa_fdc;

    dc->props = isa_fdc_properties;

    set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);

}


static int64_t expr_unary(Monitor *mon)

{

    int64_t n;

    char *p;

    int ret;

    switch(*pch) {

    case '+':

        next();

        n = expr_unary(mon);

        break;

    case '-':

        next();

        n = -expr_unary(mon);

        break;

    case '~':

        next();

        n = ~expr_unary(mon);

        break;

    case '(':

        next();

        n = expr_sum(mon);

        if (*pch != ')') {

            expr_error(mon, "')' expected");

        }

        next();

        break;

    case '\'':

        pch++;

        if (*pch == '\0')

            expr_error(mon, "character constant expected");

        n = *pch;

        pch++;

        if (*pch != '\'')

            expr_error(mon, "missing terminating \' character");

        next();

        break;

    case '$':

        {

            char buf[128], *q;

            target_long reg=0;

            pch++;

            q = buf;

            while ((*pch >= 'a' && *pch <= 'z') ||

                   (*pch >= 'A' && *pch <= 'Z') ||

                   (*pch >= '0' && *pch <= '9') ||

                   *pch == '_' || *pch == '.') {

                if ((q - buf) < sizeof(buf) - 1)

                    *q++ = *pch;

                pch++;

            }

            while (qemu_isspace(*pch))

                pch++;

            *q = 0;

            ret = get_monitor_def(&reg, buf);

            if (ret < 0)

                expr_error(mon, "unknown register");

            n = reg;

        }

        break;

    case '\0':

        expr_error(mon, "unexpected end of expression");

        n = 0;

        break;

    default:

        errno = 0;

        n = strtoull(pch, &p, 0);

        if (errno == ERANGE) {

            expr_error(mon, "number too large");

        }

        if (pch == p) {

            expr_error(mon, "invalid char in expression");

        }

        pch = p;

        while (qemu_isspace(*pch))

            pch++;

        break;

    }

    return n;

}


mst_fpga_writeb(void *opaque, target_phys_addr_t addr, uint32_t value)

{

	mst_irq_state *s = (mst_irq_state *) opaque;

	value &= 0xffffffff;

	switch (addr) {

	case MST_LEDDAT1:

		s->leddat1 = value;

		break;

	case MST_LEDDAT2:

		s->leddat2 = value;

		break;

	case MST_LEDCTRL:

		s->ledctrl = value;

		break;

	case MST_GPSWR:

		s->gpswr = value;

		break;

	case MST_MSCWR1:

		s->mscwr1 = value;

		break;

	case MST_MSCWR2:

		s->mscwr2 = value;

		break;

	case MST_MSCWR3:

		s->mscwr3 = value;

		break;

	case MST_MSCRD:

		s->mscrd =  value;

		break;

	case MST_INTMSKENA:	/* Mask interrupt */

		s->intmskena = (value & 0xFEEFF);

		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);

		break;

	case MST_INTSETCLR:	/* clear or set interrupt */

		s->intsetclr = (value & 0xFEEFF);

		qemu_set_irq(s->parent, s->intsetclr & s->intmskena);

		break;

		/* For PCMCIAx allow the to change only power and reset */

	case MST_PCMCIA0:

		s->pcmcia0 = (value & 0x1f) | (s->pcmcia0 & ~0x1f);

		break;

	case MST_PCMCIA1:

		s->pcmcia1 = (value & 0x1f) | (s->pcmcia1 & ~0x1f);

		break;

	default:

		printf("Mainstone - mst_fpga_writeb: Bad register offset "

			"0x" TARGET_FMT_plx " \n", addr);

	}

}


void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty)

{

    int reslevelno, bandno, precno;

    for (reslevelno = 0;

         comp->reslevel && reslevelno < codsty->nreslevels;

         reslevelno++) {

        Jpeg2000ResLevel *reslevel = comp->reslevel + reslevelno;

        for (bandno = 0; bandno < reslevel->nbands; bandno++) {

            Jpeg2000Band *band = reslevel->band + bandno;

            for (precno = 0; precno < reslevel->num_precincts_x * reslevel->num_precincts_y; precno++) {

                Jpeg2000Prec *prec = band->prec + precno;

                av_freep(&prec->zerobits);

                av_freep(&prec->cblkincl);

                av_freep(&prec->cblk);

            }

            av_freep(&band->prec);

        }

        av_freep(&reslevel->band);

    }

    ff_dwt_destroy(&comp->dwt);

    av_freep(&comp->reslevel);

    av_freep(&comp->i_data);

    av_freep(&comp->f_data);

}


static void do_cont(int argc, const char **argv)

{

    vm_start();

}


static inline void _t_gen_mov_TN_env(TCGv tn, int offset)

{

    if (offset > sizeof(CPUCRISState)) {

        fprintf(stderr, "wrong load from env from off=%d\n", offset);

    }

    tcg_gen_ld_tl(tn, cpu_env, offset);

}


static const char *bdrv_get_parent_name(const BlockDriverState *bs)

{

    BdrvChild *c;

    const char *name;

    /* If multiple parents have a name, just pick the first one. */

    QLIST_FOREACH(c, &bs->parents, next_parent) {

        if (c->role->get_name) {

            name = c->role->get_name(c);

            if (name && *name) {

                return name;

            }

        }

    }

    return NULL;

}


static int ehci_state_waitlisthead(EHCIState *ehci,  int async)

{

    EHCIqh qh;

    int i = 0;

    int again = 0;

    uint32_t entry = ehci->asynclistaddr;

    /* set reclamation flag at start event (4.8.6) */

    if (async) {

        ehci_set_usbsts(ehci, USBSTS_REC);

    }

    ehci_queues_rip_unused(ehci, async, 0);

    /*  Find the head of the list (4.9.1.1) */

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

        get_dwords(ehci, NLPTR_GET(entry), (uint32_t *) &qh,

                   sizeof(EHCIqh) >> 2);

        ehci_trace_qh(NULL, NLPTR_GET(entry), &qh);

        if (qh.epchar & QH_EPCHAR_H) {

            if (async) {

                entry |= (NLPTR_TYPE_QH << 1);

            }

            ehci_set_fetch_addr(ehci, async, entry);

            ehci_set_state(ehci, async, EST_FETCHENTRY);

            again = 1;

            goto out;

        }

        entry = qh.next;

        if (entry == ehci->asynclistaddr) {

            break;

        }

    }

    /* no head found for list. */

    ehci_set_state(ehci, async, EST_ACTIVE);

out:

    return again;

}


static void gen_rdhwr(DisasContext *ctx, int rt, int rd)

{

    TCGv t0;

#if !defined(CONFIG_USER_ONLY)

    /* The Linux kernel will emulate rdhwr if it's not supported natively.

       Therefore only check the ISA in system mode.  */

    check_insn(ctx, ISA_MIPS32R2);

#endif

    t0 = tcg_temp_new();

    switch (rd) {

    case 0:

        gen_helper_rdhwr_cpunum(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 1:

        gen_helper_rdhwr_synci_step(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 2:

        gen_helper_rdhwr_cc(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 3:

        gen_helper_rdhwr_ccres(t0, cpu_env);

        gen_store_gpr(t0, rt);

        break;

    case 29:

#if defined(CONFIG_USER_ONLY)

        tcg_gen_ld_tl(t0, cpu_env,

                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));

        gen_store_gpr(t0, rt);

        break;

#else

        if ((ctx->hflags & MIPS_HFLAG_CP0) ||

            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {

            tcg_gen_ld_tl(t0, cpu_env,

                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));

            gen_store_gpr(t0, rt);

        } else {

            generate_exception_end(ctx, EXCP_RI);

        }

        break;

#endif

    default:            /* Invalid */

        MIPS_INVAL("rdhwr");

        generate_exception_end(ctx, EXCP_RI);

        break;

    }

    tcg_temp_free(t0);

}


Aml *aml_shiftright(Aml *arg1, Aml *count)

{

    Aml *var = aml_opcode(0x7A /* ShiftRightOp */);

    aml_append(var, arg1);

    aml_append(var, count);

    build_append_byte(var->buf, 0x00); /* NullNameOp */

    return var;

}


static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)

{

    int ret = -EOPNOTSUPP;

    BDRVRawState *s = aiocb->bs->opaque;

    if (s->has_write_zeroes == 0) {

        return -ENOTSUP;

    }

    if (aiocb->aio_type & QEMU_AIO_BLKDEV) {

#ifdef BLKZEROOUT

        do {

            uint64_t range[2] = { aiocb->aio_offset, aiocb->aio_nbytes };

            if (ioctl(aiocb->aio_fildes, BLKZEROOUT, range) == 0) {

                return 0;

            }

        } while (errno == EINTR);

        ret = -errno;

#endif

    } else {

#ifdef CONFIG_XFS

        if (s->is_xfs) {

            return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);

        }

#endif

    }

    ret = translate_err(ret);

    if (ret == -ENOTSUP) {

        s->has_write_zeroes = false;

    }

    return ret;

}


int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,

              int flags, BlockDriver *drv, Error **errp)

{

    int ret;

    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */

    char tmp_filename[PATH_MAX + 1];

    BlockDriverState *file = NULL;

    QDict *file_options = NULL;

    const char *drvname;

    Error *local_err = NULL;

    /* NULL means an empty set of options */

    if (options == NULL) {

        options = qdict_new();

    }

    bs->options = options;

    options = qdict_clone_shallow(options);

    /* For snapshot=on, create a temporary qcow2 overlay */

    if (flags & BDRV_O_SNAPSHOT) {

        BlockDriverState *bs1;

        int64_t total_size;

        BlockDriver *bdrv_qcow2;

        QEMUOptionParameter *create_options;

        char backing_filename[PATH_MAX];

        if (qdict_size(options) != 0) {

            error_setg(errp, "Can't use snapshot=on with driver-specific options");

            ret = -EINVAL;

            goto fail;

        }

        assert(filename != NULL);

        /* if snapshot, we create a temporary backing file and open it

           instead of opening 'filename' directly */

        /* if there is a backing file, use it */

        bs1 = bdrv_new("");

        ret = bdrv_open(bs1, filename, NULL, 0, drv, &local_err);

        if (ret < 0) {

            bdrv_unref(bs1);

            goto fail;

        }

        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;

        bdrv_unref(bs1);

        ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not get temporary filename");

            goto fail;

        }

        /* Real path is meaningless for protocols */

        if (path_has_protocol(filename)) {

            snprintf(backing_filename, sizeof(backing_filename),

                     "%s", filename);

        } else if (!realpath(filename, backing_filename)) {

            ret = -errno;

            error_setg_errno(errp, errno, "Could not resolve path '%s'", filename);

            goto fail;

        }

        bdrv_qcow2 = bdrv_find_format("qcow2");

        create_options = parse_option_parameters("", bdrv_qcow2->create_options,

                                                 NULL);

        set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);

        set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE,

                             backing_filename);

        if (drv) {

            set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT,

                drv->format_name);

        }

        ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err);

        free_option_parameters(create_options);

        if (ret < 0) {

            error_setg_errno(errp, -ret, "Could not create temporary overlay "

                             "'%s': %s", tmp_filename,

                             error_get_pretty(local_err));

            error_free(local_err);

            local_err = NULL;

            goto fail;

        }

        filename = tmp_filename;

        drv = bdrv_qcow2;

        bs->is_temporary = 1;

    }

    /* Open image file without format layer */

    if (flags & BDRV_O_RDWR) {

        flags |= BDRV_O_ALLOW_RDWR;

    }

    qdict_extract_subqdict(options, &file_options, "file.");

    ret = bdrv_file_open(&file, filename, file_options,

                         bdrv_open_flags(bs, flags | BDRV_O_UNMAP), &local_err);

    if (ret < 0) {

        goto fail;

    }

    /* Find the right image format driver */

    drvname = qdict_get_try_str(options, "driver");

    if (drvname) {

        drv = bdrv_find_format(drvname);

        qdict_del(options, "driver");

        if (!drv) {

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

            ret = -EINVAL;

            goto unlink_and_fail;

        }

    }

    if (!drv) {

        ret = find_image_format(file, filename, &drv, &local_err);

    }

    if (!drv) {

        goto unlink_and_fail;

    }

    /* Open the image */

    ret = bdrv_open_common(bs, file, options, flags, drv, &local_err);

    if (ret < 0) {

        goto unlink_and_fail;

    }

    if (bs->file != file) {

        bdrv_unref(file);

        file = NULL;

    }

    /* If there is a backing file, use it */

    if ((flags & BDRV_O_NO_BACKING) == 0) {

        QDict *backing_options;

        qdict_extract_subqdict(options, &backing_options, "backing.");

        ret = bdrv_open_backing_file(bs, backing_options, &local_err);

        if (ret < 0) {

            goto close_and_fail;

        }

    }

    /* Check if any unknown options were used */

    if (qdict_size(options) != 0) {

        const QDictEntry *entry = qdict_first(options);

        error_setg(errp, "Block format '%s' used by device '%s' doesn't "

                   "support the option '%s'", drv->format_name, bs->device_name,

                   entry->key);

        ret = -EINVAL;

        goto close_and_fail;

    }

    QDECREF(options);

    if (!bdrv_key_required(bs)) {

        bdrv_dev_change_media_cb(bs, true);

    }

    return 0;

unlink_and_fail:

    if (file != NULL) {

        bdrv_unref(file);

    }

    if (bs->is_temporary) {

        unlink(filename);

    }

fail:

    QDECREF(bs->options);

    QDECREF(options);

    bs->options = NULL;

    if (error_is_set(&local_err)) {

        error_propagate(errp, local_err);

    }

    return ret;

close_and_fail:

    bdrv_close(bs);

    QDECREF(options);

    if (error_is_set(&local_err)) {

        error_propagate(errp, local_err);

    }

    return ret;

}


static void filter(struct vf_priv_s *p, uint8_t *dst[3], uint8_t *src[3], int dst_stride[3], int src_stride[3], int width, int height){

    int x, y, i;

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

        p->frame->data[i]= src[i];

        p->frame->linesize[i]= src_stride[i];

    }

    p->avctx_enc->me_cmp=

    p->avctx_enc->me_sub_cmp= FF_CMP_SAD /*| (p->parity ? FF_CMP_ODD : FF_CMP_EVEN)*/;

    p->frame->quality= p->qp*FF_QP2LAMBDA;

    avcodec_encode_video(p->avctx_enc, p->outbuf, p->outbuf_size, p->frame);

    p->frame_dec = p->avctx_enc->coded_frame;

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

        int is_chroma= !!i;

        int w= width >>is_chroma;

        int h= height>>is_chroma;

        int fils= p->frame_dec->linesize[i];

        int srcs= src_stride[i];

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

            if((y ^ p->parity) & 1){

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

                    if((x-2)+(y-1)*w>=0 && (x+2)+(y+1)*w<w*h){ //FIXME either alloc larger images or optimize this

                        uint8_t *filp= &p->frame_dec->data[i][x + y*fils];

                        uint8_t *srcp= &src[i][x + y*srcs];

                        int diff0= filp[-fils] - srcp[-srcs];

                        int diff1= filp[+fils] - srcp[+srcs];

                        int spatial_score= ABS(srcp[-srcs-1] - srcp[+srcs-1])

                                          +ABS(srcp[-srcs  ] - srcp[+srcs  ])

                                          +ABS(srcp[-srcs+1] - srcp[+srcs+1]) - 1;

                        int temp= filp[0];

#define CHECK(j)\

    {   int score= ABS(srcp[-srcs-1+(j)] - srcp[+srcs-1-(j)])\

                 + ABS(srcp[-srcs  +(j)] - srcp[+srcs  -(j)])\

                 + ABS(srcp[-srcs+1+(j)] - srcp[+srcs+1-(j)]);\

        if(score < spatial_score){\

            spatial_score= score;\

            diff0= filp[-fils+(j)] - srcp[-srcs+(j)];\

            diff1= filp[+fils-(j)] - srcp[+srcs-(j)];

                        CHECK(-1) CHECK(-2) }} }}

                        CHECK( 1) CHECK( 2) }} }}


static void test_qga_config(gconstpointer data)

{

    GError *error = NULL;

    char *cwd, *cmd, *out, *err, *str, **strv, **argv = NULL;

    char *env[2];

    int status;

    gsize n;

    GKeyFile *kf;

    cwd = g_get_current_dir();

    cmd = g_strdup_printf("%s%cqemu-ga -D",

                          cwd, G_DIR_SEPARATOR);

    g_shell_parse_argv(cmd, NULL, &argv, &error);

    g_assert_no_error(error);

    env[0] = g_strdup_printf("QGA_CONF=tests%cdata%ctest-qga-config",

                             G_DIR_SEPARATOR, G_DIR_SEPARATOR);

    env[1] = NULL;

    g_spawn_sync(NULL, argv, env, 0,

                 NULL, NULL, &out, &err, &status, &error);

    g_strfreev(argv);

    g_assert_no_error(error);

    g_assert_cmpstr(err, ==, "");

    g_assert_cmpint(status, ==, 0);

    kf = g_key_file_new();

    g_key_file_load_from_data(kf, out, -1, G_KEY_FILE_NONE, &error);

    g_assert_no_error(error);

    str = g_key_file_get_start_group(kf);

    g_assert_cmpstr(str, ==, "general");

    g_free(str);

    g_assert_false(g_key_file_get_boolean(kf, "general", "daemon", &error));

    g_assert_no_error(error);

    str = g_key_file_get_string(kf, "general", "method", &error);

    g_assert_no_error(error);

    g_assert_cmpstr(str, ==, "virtio-serial");

    g_free(str);

    str = g_key_file_get_string(kf, "general", "path", &error);

    g_assert_no_error(error);

    g_assert_cmpstr(str, ==, "/path/to/org.qemu.guest_agent.0");

    g_free(str);

    str = g_key_file_get_string(kf, "general", "pidfile", &error);

    g_assert_no_error(error);

    g_assert_cmpstr(str, ==, "/var/foo/qemu-ga.pid");

    g_free(str);

    str = g_key_file_get_string(kf, "general", "statedir", &error);

    g_assert_no_error(error);

    g_assert_cmpstr(str, ==, "/var/state");

    g_free(str);

    g_assert_true(g_key_file_get_boolean(kf, "general", "verbose", &error));

    g_assert_no_error(error);

    strv = g_key_file_get_string_list(kf, "general", "blacklist", &n, &error);

    g_assert_cmpint(n, ==, 2);

#if GLIB_CHECK_VERSION(2, 44, 0)

    g_assert_true(g_strv_contains((const char * const *)strv,

                                  "guest-ping"));

    g_assert_true(g_strv_contains((const char * const *)strv,

                                  "guest-get-time"));

#endif

    g_assert_no_error(error);

    g_strfreev(strv);

    g_free(out);

    g_free(err);

    g_free(env[0]);

    g_key_file_free(kf);

}


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

{

    if (av_get_packet(s->pb, pkt, MAX_READ_SIZE) <= 0)

        return AVERROR(EIO);

    pkt->stream_index = 0;

    return 0;

}


void helper_fitoq(CPUSPARCState *env, int32_t src)

{

    /* No possible exceptions converting int to long double.  */

    QT0 = int32_to_float128(src, &env->fp_status);

}


int gdbserver_start(const char *device)

{

    GDBState *s;

    char gdbstub_device_name[128];

    CharDriverState *chr = NULL;

    CharDriverState *mon_chr;

    if (!device)

        return -1;

    if (strcmp(device, "none") != 0) {

        if (strstart(device, "tcp:", NULL)) {

            /* enforce required TCP attributes */

            snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),

                     "%s,nowait,nodelay,server", device);

            device = gdbstub_device_name;

        }

#ifndef _WIN32

        else if (strcmp(device, "stdio") == 0) {

            struct sigaction act;

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

            act.sa_handler = gdb_sigterm_handler;

            sigaction(SIGINT, &act, NULL);

        }

#endif

        chr = qemu_chr_new("gdb", device, NULL);

        if (!chr)

            return -1;

        qemu_chr_fe_claim_no_fail(chr);

        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,

                              gdb_chr_event, NULL);

    }

    s = gdbserver_state;

    if (!s) {

        s = g_malloc0(sizeof(GDBState));

        gdbserver_state = s;

        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);

        /* Initialize a monitor terminal for gdb */

        mon_chr = qemu_chr_alloc();

        mon_chr->chr_write = gdb_monitor_write;

        monitor_init(mon_chr, 0);

    } else {

        if (s->chr)

            qemu_chr_delete(s->chr);

        mon_chr = s->mon_chr;

        memset(s, 0, sizeof(GDBState));

    }

    s->c_cpu = first_cpu;

    s->g_cpu = first_cpu;

    s->chr = chr;

    s->state = chr ? RS_IDLE : RS_INACTIVE;

    s->mon_chr = mon_chr;

    s->current_syscall_cb = NULL;

    return 0;

}


net_checksum_add_iov(const struct iovec *iov, const unsigned int iov_cnt,

                     uint32_t iov_off, uint32_t size)

{

    size_t iovec_off, buf_off;

    unsigned int i;

    uint32_t res = 0;

    uint32_t seq = 0;

    iovec_off = 0;

    buf_off = 0;

    for (i = 0; i < iov_cnt && size; i++) {

        if (iov_off < (iovec_off + iov[i].iov_len)) {

            size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size);

            void *chunk_buf = iov[i].iov_base + (iov_off - iovec_off);

            res += net_checksum_add_cont(len, chunk_buf, seq);

            seq += len;

            buf_off += len;

            iov_off += len;

            size -= len;

        }

        iovec_off += iov[i].iov_len;

    }

    return res;

}


static inline int get_phys_addr(CPUARMState *env, target_ulong address,

                                int access_type, int is_user,

                                hwaddr *phys_ptr, int *prot,

                                target_ulong *page_size)

{

    /* This is not entirely correct as get_phys_addr() can also be called

     * from ats_write() for an address translation of a specific regime.

     */

    uint32_t sctlr = A32_BANKED_CURRENT_REG_GET(env, sctlr);

    /* Fast Context Switch Extension.  */

    if (address < 0x02000000)

        address += env->cp15.c13_fcse;

    if ((sctlr & SCTLR_M) == 0) {

        /* MMU/MPU disabled.  */

        *phys_ptr = address;

        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

        *page_size = TARGET_PAGE_SIZE;

        return 0;

    } else if (arm_feature(env, ARM_FEATURE_MPU)) {

        *page_size = TARGET_PAGE_SIZE;

	return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,

				 prot);

    } else if (extended_addresses_enabled(env)) {

        return get_phys_addr_lpae(env, address, access_type, is_user, phys_ptr,

                                  prot, page_size);

    } else if (sctlr & SCTLR_XP) {

        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,

                                prot, page_size);

    } else {

        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,

                                prot, page_size);

    }

}


DriveInfo *drive_init(QemuOpts *opts, int default_to_scsi, int *fatal_error)

{

    const char *buf;

    const char *file = NULL;

    char devname[128];

    const char *serial;

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriver *drv = NULL;

    int max_devs;

    int index;

    int ro = 0;

    int bdrv_flags = 0;

    int on_read_error, on_write_error;

    const char *devaddr;

    DriveInfo *dinfo;

    int snapshot = 0;

    int ret;

    *fatal_error = 1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    if (default_to_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

        pstrcpy(devname, sizeof(devname), "scsi");

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

        pstrcpy(devname, sizeof(devname), "ide");

    }

    media = MEDIA_DISK;

    /* extract parameters */

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

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

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

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

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

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

    snapshot = qemu_opt_get_bool(opts, "snapshot", 0);

    ro = qemu_opt_get_bool(opts, "readonly", 0);

    file = qemu_opt_get(opts, "file");

    serial = qemu_opt_get(opts, "serial");

    if ((buf = qemu_opt_get(opts, "if")) != NULL) {

        pstrcpy(devname, sizeof(devname), buf);

        if (!strcmp(buf, "ide")) {

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

        } else if (!strcmp(buf, "scsi")) {

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

        } else if (!strcmp(buf, "floppy")) {

	    type = IF_FLOPPY;

            max_devs = 0;

        } else if (!strcmp(buf, "pflash")) {

	    type = IF_PFLASH;

            max_devs = 0;

	} else if (!strcmp(buf, "mtd")) {

	    type = IF_MTD;

            max_devs = 0;

	} else if (!strcmp(buf, "sd")) {

	    type = IF_SD;

            max_devs = 0;

        } else if (!strcmp(buf, "virtio")) {

            type = IF_VIRTIO;

            max_devs = 0;

	} else if (!strcmp(buf, "xen")) {

	    type = IF_XEN;

            max_devs = 0;

	} else if (!strcmp(buf, "none")) {

	    type = IF_NONE;

            max_devs = 0;

	} else {

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

            return NULL;

	}

    }

    if (cyls || heads || secs) {

        if (cyls < 1 || (type == IF_IDE && cyls > 16383)) {

            error_report("invalid physical cyls number");

	    return NULL;

	}

        if (heads < 1 || (type == IF_IDE && heads > 16)) {

            error_report("invalid physical heads number");

	    return NULL;

	}

        if (secs < 1 || (type == IF_IDE && secs > 63)) {

            error_report("invalid physical secs number");

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "trans")) != NULL) {

        if (!cyls) {

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

                         buf);

            return NULL;

        }

        if (!strcmp(buf, "none"))

            translation = BIOS_ATA_TRANSLATION_NONE;

        else if (!strcmp(buf, "lba"))

            translation = BIOS_ATA_TRANSLATION_LBA;

        else if (!strcmp(buf, "auto"))

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

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

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "media")) != NULL) {

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

	    media = MEDIA_DISK;

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

            if (cyls || secs || heads) {

                error_report("'%s' invalid physical CHS format", buf);

	        return NULL;

            }

	    media = MEDIA_CDROM;

	} else {

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

	    return NULL;

	}

    }

    if ((buf = qemu_opt_get(opts, "cache")) != NULL) {

        if (!strcmp(buf, "off") || !strcmp(buf, "none")) {

            bdrv_flags |= BDRV_O_NOCACHE;

        } else if (!strcmp(buf, "writeback")) {

            bdrv_flags |= BDRV_O_CACHE_WB;

        } else if (!strcmp(buf, "unsafe")) {

            bdrv_flags |= BDRV_O_CACHE_WB;

            bdrv_flags |= BDRV_O_NO_FLUSH;

        } else if (!strcmp(buf, "writethrough")) {

            /* this is the default */

        } else {

           error_report("invalid cache option");

           return NULL;

        }

    }

#ifdef CONFIG_LINUX_AIO

    if ((buf = qemu_opt_get(opts, "aio")) != NULL) {

        if (!strcmp(buf, "native")) {

            bdrv_flags |= BDRV_O_NATIVE_AIO;

        } else if (!strcmp(buf, "threads")) {

            /* this is the default */

        } else {

           error_report("invalid aio option");

           return NULL;

        }

    }

#endif

    if ((buf = qemu_opt_get(opts, "format")) != NULL) {

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

           error_printf("Supported formats:");

           bdrv_iterate_format(bdrv_format_print, NULL);

           error_printf("\n");

           return NULL;

        }

        drv = bdrv_find_whitelisted_format(buf);

        if (!drv) {

            error_report("'%s' invalid format", buf);

            return NULL;

        }

    }

    on_write_error = BLOCK_ERR_STOP_ENOSPC;

    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) {

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

            return NULL;

        }

        on_write_error = parse_block_error_action(buf, 0);

        if (on_write_error < 0) {

            return NULL;

        }

    }

    on_read_error = BLOCK_ERR_REPORT;

    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {

        if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI && type != IF_NONE) {

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

            return NULL;

        }

        on_read_error = parse_block_error_action(buf, 1);

        if (on_read_error < 0) {

            return NULL;

        }

    }

    if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) {

        if (type != IF_VIRTIO) {

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

            return NULL;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

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

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

            return NULL;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

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

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

        error_report("unit %d too big (max is %d)",

                     unit_id, max_devs - 1);

        return NULL;

    }

    /*

     * ignore multiple definitions

     */

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

        *fatal_error = 0;

        return NULL;

    }

    /* init */

    dinfo = qemu_mallocz(sizeof(*dinfo));

    if ((buf = qemu_opts_id(opts)) != NULL) {

        dinfo->id = qemu_strdup(buf);

    } else {

        /* no id supplied -> create one */

        dinfo->id = qemu_mallocz(32);

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

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

        if (max_devs)

            snprintf(dinfo->id, 32, "%s%i%s%i",

                     devname, bus_id, mediastr, unit_id);

        else

            snprintf(dinfo->id, 32, "%s%s%i",

                     devname, mediastr, unit_id);

    }

    dinfo->bdrv = bdrv_new(dinfo->id);

    dinfo->devaddr = devaddr;

    dinfo->type = type;

    dinfo->bus = bus_id;

    dinfo->unit = unit_id;

    dinfo->opts = opts;

    if (serial)

        strncpy(dinfo->serial, serial, sizeof(dinfo->serial) - 1);

    QTAILQ_INSERT_TAIL(&drives, dinfo, next);

    bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error);

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

    case IF_XEN:

    case IF_NONE:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

                bdrv_set_geometry_hint(dinfo->bdrv, cyls, heads, secs);

                bdrv_set_translation_hint(dinfo->bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

        /* FIXME: This isn't really a floppy, but it's a reasonable

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(dinfo->bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

        break;

    case IF_VIRTIO:

        /* add virtio block device */

        opts = qemu_opts_create(qemu_find_opts("device"), NULL, 0);

        qemu_opt_set(opts, "driver", "virtio-blk-pci");

        qemu_opt_set(opts, "drive", dinfo->id);

        if (devaddr)

            qemu_opt_set(opts, "addr", devaddr);

        break;

    case IF_COUNT:

        abort();

    }

    if (!file || !*file) {

        *fatal_error = 0;

        return NULL;

    }

    if (snapshot) {

        /* always use cache=unsafe with snapshot */

        bdrv_flags &= ~BDRV_O_CACHE_MASK;

        bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);

    }

    if (media == MEDIA_CDROM) {

        /* CDROM is fine for any interface, don't check.  */

        ro = 1;

    } else if (ro == 1) {

        if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY && type != IF_NONE) {

            error_report("readonly not supported by this bus type");

            return NULL;

        }

    }

    bdrv_flags |= ro ? 0 : BDRV_O_RDWR;

    ret = bdrv_open(dinfo->bdrv, file, bdrv_flags, drv);

    if (ret < 0) {

        error_report("could not open disk image %s: %s",

                     file, strerror(-ret));

        return NULL;

    }

    if (bdrv_key_required(dinfo->bdrv))

        autostart = 0;

    *fatal_error = 0;

    return dinfo;

}


static void test_visitor_in_struct(TestInputVisitorData *data,

                                   const void *unused)

{

    TestStruct *p = NULL;

    Visitor *v;

    v = visitor_input_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");

    visit_type_TestStruct(v, NULL, &p, &error_abort);

    g_assert_cmpint(p->integer, ==, -42);

    g_assert(p->boolean == true);

    g_assert_cmpstr(p->string, ==, "foo");

    g_free(p->string);

    g_free(p);

}


static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,

                           unsigned bar_nr, unsigned bar_size)

{

    int config_offset;

    uint8_t *config;

    uint32_t new_size;

    if (nentries < 1 || nentries > PCI_MSIX_FLAGS_QSIZE + 1)

        return -EINVAL;

    if (bar_size > 0x80000000)

        return -ENOSPC;

    /* Add space for MSI-X structures */

    if (!bar_size) {

        new_size = MSIX_PAGE_SIZE;

    } else if (bar_size < MSIX_PAGE_SIZE) {

        bar_size = MSIX_PAGE_SIZE;

        new_size = MSIX_PAGE_SIZE * 2;

    } else {

        new_size = bar_size * 2;

    }

    pdev->msix_bar_size = new_size;

    config_offset = pci_add_capability(pdev, PCI_CAP_ID_MSIX,

                                       0, MSIX_CAP_LENGTH);

    if (config_offset < 0)

        return config_offset;

    config = pdev->config + config_offset;

    pci_set_word(config + PCI_MSIX_FLAGS, nentries - 1);

    /* Table on top of BAR */

    pci_set_long(config + PCI_MSIX_TABLE, bar_size | bar_nr);

    /* Pending bits on top of that */

    pci_set_long(config + PCI_MSIX_PBA, (bar_size + MSIX_PAGE_PENDING) |

                 bar_nr);

    pdev->msix_cap = config_offset;

    /* Make flags bit writable. */

    pdev->wmask[config_offset + MSIX_CONTROL_OFFSET] |= MSIX_ENABLE_MASK |

	    MSIX_MASKALL_MASK;

    pdev->msix_function_masked = true;

    return 0;

}


void qmp_memsave(int64_t addr, int64_t size, const char *filename,

                 bool has_cpu, int64_t cpu_index, Error **errp)

{

    FILE *f;

    uint32_t l;

    CPUState *cpu;

    uint8_t buf[1024];

    if (!has_cpu) {

        cpu_index = 0;

    }

    cpu = qemu_get_cpu(cpu_index);

    if (cpu == NULL) {

        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "cpu-index",

                  "a CPU number");

        return;

    }

    f = fopen(filename, "wb");

    if (!f) {

        error_setg_file_open(errp, errno, filename);

        return;

    }

    while (size != 0) {

        l = sizeof(buf);

        if (l > size)

            l = size;

        cpu_memory_rw_debug(cpu, addr, buf, l, 0);

        if (fwrite(buf, 1, l, f) != l) {

            error_set(errp, QERR_IO_ERROR);

            goto exit;

        }

        addr += l;

        size -= l;

    }

exit:

    fclose(f);

}


static void xen_platform_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->init = xen_platform_initfn;

    k->vendor_id = PCI_VENDOR_ID_XEN;

    k->device_id = PCI_DEVICE_ID_XEN_PLATFORM;

    k->class_id = PCI_CLASS_OTHERS << 8 | 0x80;

    k->subsystem_vendor_id = PCI_VENDOR_ID_XEN;

    k->subsystem_id = PCI_DEVICE_ID_XEN_PLATFORM;

    k->revision = 1;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

    dc->desc = "XEN platform pci device";

    dc->reset = platform_reset;

    dc->vmsd = &vmstate_xen_platform;

}


int net_init_slirp(QemuOpts *opts,

                   Monitor *mon,

                   const char *name,

                   VLANState *vlan)

{

    struct slirp_config_str *config;

    const char *vhost;

    const char *vhostname;

    const char *vdhcp_start;

    const char *vnamesrv;

    const char *tftp_export;

    const char *bootfile;

    const char *smb_export;

    const char *vsmbsrv;

    char *vnet = NULL;

    int restricted = 0;

    int ret;

    vhost       = qemu_opt_get(opts, "host");

    vhostname   = qemu_opt_get(opts, "hostname");

    vdhcp_start = qemu_opt_get(opts, "dhcpstart");

    vnamesrv    = qemu_opt_get(opts, "dns");

    tftp_export = qemu_opt_get(opts, "tftp");

    bootfile    = qemu_opt_get(opts, "bootfile");

    smb_export  = qemu_opt_get(opts, "smb");

    vsmbsrv     = qemu_opt_get(opts, "smbserver");

    if (qemu_opt_get(opts, "ip")) {

        const char *ip = qemu_opt_get(opts, "ip");

        int l = strlen(ip) + strlen("/24") + 1;

        vnet = qemu_malloc(l);

        /* emulate legacy ip= parameter */

        pstrcpy(vnet, l, ip);

        pstrcat(vnet, l, "/24");

    }

    if (qemu_opt_get(opts, "net")) {

        if (vnet) {

            qemu_free(vnet);

        }

        vnet = qemu_strdup(qemu_opt_get(opts, "net"));

    }

    if (qemu_opt_get(opts, "restrict") &&

        qemu_opt_get(opts, "restrict")[0] == 'y') {

        restricted = 1;

    }

    qemu_opt_foreach(opts, net_init_slirp_configs, NULL, 0);

    ret = net_slirp_init(vlan, "user", name, restricted, vnet, vhost,

                         vhostname, tftp_export, bootfile, vdhcp_start,

                         vnamesrv, smb_export, vsmbsrv);

    while (slirp_configs) {

        config = slirp_configs;

        slirp_configs = config->next;

        qemu_free(config);

    }

    if (ret != -1 && vlan) {

        vlan->nb_host_devs++;

    }

    qemu_free(vnet);

    return ret;

}


static QOSState *qvirtio_9p_start(void)

{

    const char *cmd = "-fsdev local,id=fsdev0,security_model=none,path=%s "

                      "-device virtio-9p-pci,fsdev=fsdev0,mount_tag=%s";

    test_share = g_strdup("/tmp/qtest.XXXXXX");

    g_assert_nonnull(mkdtemp(test_share));

    return qtest_pc_boot(cmd, test_share, mount_tag);

}


static void test_read_without_media(void)

{

    uint8_t ret;

    ret = send_read_command();

    g_assert(ret == 0);

}


static void set_acpi_power_state(IPMIBmcSim *ibs,

                          uint8_t *cmd, unsigned int cmd_len,

                          uint8_t *rsp, unsigned int *rsp_len,

                          unsigned int max_rsp_len)

{

    IPMI_CHECK_CMD_LEN(4);

    ibs->acpi_power_state[0] = cmd[2];

    ibs->acpi_power_state[1] = cmd[3];

}


static void usb_uas_unrealize(USBDevice *dev, Error **errp)
{
    UASDevice *uas = USB_UAS(dev);
    qemu_bh_delete(uas->status_bh);
}


static int sdp_parse(AVFormatContext *s, const char *content)

{

    const char *p;

    int letter;

    /* Some SDP lines, particularly for Realmedia or ASF RTSP streams,

     * contain long SDP lines containing complete ASF Headers (several

     * kB) or arrays of MDPR (RM stream descriptor) headers plus

     * "rulebooks" describing their properties. Therefore, the SDP line

     * buffer is large.

     *

     * The Vorbis FMTP line can be up to 16KB - see sdp_parse_fmtp. */

    char buf[16384], *q;

    SDPParseState sdp_parse_state, *s1 = &sdp_parse_state;

    memset(s1, 0, sizeof(SDPParseState));

    p = content;

    for(;;) {

        skip_spaces(&p);

        letter = *p;

        if (letter == '\0')

            break;

        p++;

        if (*p != '=')

            goto next_line;

        p++;

        /* get the content */

        q = buf;

        while (*p != '\n' && *p != '\r' && *p != '\0') {

            if ((q - buf) < sizeof(buf) - 1)

                *q++ = *p;

            p++;

        }

        *q = '\0';

        sdp_parse_line(s, s1, letter, buf);

    next_line:

        while (*p != '\n' && *p != '\0')

            p++;

        if (*p == '\n')

            p++;

    }

    return 0;

}


static void flush_change(H264Context *h)

{

    h->outputed_poc = h->next_outputed_poc = INT_MIN;

    h->prev_interlaced_frame = 1;

    idr(h);

    h->prev_frame_num = -1;

    if (h->s.current_picture_ptr)

        h->s.current_picture_ptr->f.reference = 0;

    h->s.first_field = 0;

    memset(h->ref_list[0], 0, sizeof(h->ref_list[0]));

    memset(h->ref_list[1], 0, sizeof(h->ref_list[1]));

    memset(h->default_ref_list[0], 0, sizeof(h->default_ref_list[0]));

    memset(h->default_ref_list[1], 0, sizeof(h->default_ref_list[1]));

    ff_h264_reset_sei(h);

    h->recovery_frame= -1;

    h->sync= 0;

    h->list_count = 0;

    h->current_slice = 0;

}


int qcrypto_cipher_decrypt(QCryptoCipher *cipher,

                           const void *in,

                           void *out,

                           size_t len,

                           Error **errp)

{

    QCryptoCipherNettle *ctx = cipher->opaque;

    switch (cipher->mode) {

    case QCRYPTO_CIPHER_MODE_ECB:

        ctx->alg_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,

                         len, out, in);

        break;

    case QCRYPTO_CIPHER_MODE_CBC:

        cbc_decrypt(ctx->ctx_decrypt ? ctx->ctx_decrypt : ctx->ctx_encrypt,

                    ctx->alg_decrypt, ctx->niv, ctx->iv,

                    len, out, in);

        break;

    default:

        error_setg(errp, "Unsupported cipher algorithm %d",

                   cipher->alg);

        return -1;

    }

    return 0;

}


static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)

{

    QOSState *tmp = to->parent;

    QPCIDevice *dev = to->dev;

    char *uri_local = NULL;

    if (uri == NULL) {

        uri_local = g_strdup_printf("%s%s", "unix:", mig_socket);

        uri = uri_local;

    }

    /* context will be 'to' after completion. */

    migrate(from->parent, to->parent, uri);

    /* We'd like for the AHCIState objects to still point

     * to information specific to its specific parent

     * instance, but otherwise just inherit the new data. */

    memcpy(to, from, sizeof(AHCIQState));

    to->parent = tmp;

    to->dev = dev;

    tmp = from->parent;

    dev = from->dev;

    memset(from, 0x00, sizeof(AHCIQState));

    from->parent = tmp;

    from->dev = dev;

    verify_state(to);

    g_free(uri_local);

}


static int kvm_virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,

                                        unsigned int queue_no,

                                        unsigned int vector,

                                        MSIMessage msg)

{

    VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);

    EventNotifier *n = virtio_queue_get_guest_notifier(vq);

    VirtIOIRQFD *irqfd = &proxy->vector_irqfd[vector];

    int ret;

    if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {

        ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);

        if (ret < 0) {

            return ret;

        }

    }

    /* If guest supports masking, irqfd is already setup, unmask it.

     * Otherwise, set it up now.

     */

    if (proxy->vdev->guest_notifier_mask) {

        proxy->vdev->guest_notifier_mask(proxy->vdev, queue_no, false);

        /* Test after unmasking to avoid losing events. */

        if (proxy->vdev->guest_notifier_pending &&

            proxy->vdev->guest_notifier_pending(proxy->vdev, queue_no)) {

            event_notifier_set(n);

        }

    } else {

        ret = kvm_virtio_pci_irqfd_use(proxy, queue_no, vector);

    }

    return ret;

}


static int vvfat_open(BlockDriverState *bs, const char* dirname, int flags)

{

    BDRVVVFATState *s = bs->opaque;

    int floppy = 0;

    int i;

#ifdef DEBUG

    vvv = s;

#endif

DLOG(if (stderr == NULL) {

    stderr = fopen("vvfat.log", "a");

    setbuf(stderr, NULL);

})

    s->bs = bs;

    s->fat_type=16;

    /* LATER TODO: if FAT32, adjust */

    s->sectors_per_cluster=0x10;

    /* 504MB disk*/

    bs->cyls=1024; bs->heads=16; bs->secs=63;

    s->current_cluster=0xffffffff;

    s->first_sectors_number=0x40;

    /* read only is the default for safety */

    bs->read_only = 1;

    s->qcow = s->write_target = NULL;

    s->qcow_filename = NULL;

    s->fat2 = NULL;

    s->downcase_short_names = 1;

    if (!strstart(dirname, "fat:", NULL))

	return -1;

    if (strstr(dirname, ":floppy:")) {

	floppy = 1;

	s->fat_type = 12;

	s->first_sectors_number = 1;

	s->sectors_per_cluster=2;

	bs->cyls = 80; bs->heads = 2; bs->secs = 36;

    }

    if (strstr(dirname, ":32:")) {

	fprintf(stderr, "Big fat greek warning: FAT32 has not been tested. You are welcome to do so!\n");

	s->fat_type = 32;

    } else if (strstr(dirname, ":16:")) {

	s->fat_type = 16;

    } else if (strstr(dirname, ":12:")) {

	s->fat_type = 12;

	bs->secs = 18;

    }

    s->sector_count=bs->cyls*bs->heads*bs->secs-(s->first_sectors_number-1);

    if (strstr(dirname, ":rw:")) {

	if (enable_write_target(s))

	    return -1;

	bs->read_only = 0;

    }

    i = strrchr(dirname, ':') - dirname;

    assert(i >= 3);

    if (dirname[i-2] == ':' && qemu_isalpha(dirname[i-1]))

	/* workaround for DOS drive names */

	dirname += i-1;

    else

	dirname += i+1;

    bs->total_sectors=bs->cyls*bs->heads*bs->secs;

    if(init_directories(s, dirname))

	return -1;

    s->sector_count = s->faked_sectors + s->sectors_per_cluster*s->cluster_count;

    if(s->first_sectors_number==0x40)

	init_mbr(s);

    /* for some reason or other, MS-DOS does not like to know about CHS... */

    if (floppy)

	bs->heads = bs->cyls = bs->secs = 0;

    //    assert(is_consistent(s));

    qemu_co_mutex_init(&s->lock);

    return 0;

}


VirtIODevice *virtio_scsi_init(DeviceState *dev, VirtIOSCSIConf *proxyconf)

{

    VirtIOSCSI *s;

    static int virtio_scsi_id;

    size_t sz;

    int i;

    sz = sizeof(VirtIOSCSI) + proxyconf->num_queues * sizeof(VirtQueue *);

    s = (VirtIOSCSI *)virtio_common_init("virtio-scsi", VIRTIO_ID_SCSI,

                                         sizeof(VirtIOSCSIConfig), sz);

    s->qdev = dev;

    s->conf = proxyconf;

    /* TODO set up vdev function pointers */

    s->vdev.get_config = virtio_scsi_get_config;

    s->vdev.set_config = virtio_scsi_set_config;

    s->vdev.get_features = virtio_scsi_get_features;

    s->vdev.reset = virtio_scsi_reset;

    s->ctrl_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,

                                   virtio_scsi_handle_ctrl);

    s->event_vq = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,

                                   NULL);

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

        s->cmd_vqs[i] = virtio_add_queue(&s->vdev, VIRTIO_SCSI_VQ_SIZE,

                                         virtio_scsi_handle_cmd);

    }

    scsi_bus_new(&s->bus, dev, &virtio_scsi_scsi_info);

    if (!dev->hotplugged) {

        scsi_bus_legacy_handle_cmdline(&s->bus);

    }

    register_savevm(dev, "virtio-scsi", virtio_scsi_id++, 1,

                    virtio_scsi_save, virtio_scsi_load, s);

    return &s->vdev;

}


static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
                                    double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta,
                                    double precision, int cheby){
    double cutoff = cutoff0? cutoff0 : 0.97;
    double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
    int phase_count= 1<<phase_shift;
    if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
           || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
           || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
        c = av_mallocz(sizeof(*c));
        if (!c)
            return NULL;
        c->format= format;
        c->felem_size= av_get_bytes_per_sample(c->format);
        switch(c->format){
        case AV_SAMPLE_FMT_S16P:
            c->filter_shift = 15;
            break;
        case AV_SAMPLE_FMT_S32P:
            c->filter_shift = 30;
            break;
        case AV_SAMPLE_FMT_FLTP:
        case AV_SAMPLE_FMT_DBLP:
            c->filter_shift = 0;
            break;
        default:
            av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
            av_assert0(0);
        c->phase_shift   = phase_shift;
        c->phase_mask    = phase_count - 1;
        c->linear        = linear;
        c->factor        = factor;
        c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
        c->filter_alloc  = FFALIGN(c->filter_length, 8);
        c->filter_bank   = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
        c->filter_type   = filter_type;
        c->kaiser_beta   = kaiser_beta;
        if (!c->filter_bank)
        if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
        memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
        memcpy(c->filter_bank + (c->filter_alloc*phase_count  )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
    c->compensation_distance= 0;
    if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
    c->ideal_dst_incr= c->dst_incr;
    c->index= -phase_count*((c->filter_length-1)/2);
    c->frac= 0;
    return c;
error:
    av_freep(&c->filter_bank);
    av_free(c);
    return NULL;


static void test_properties(const char *path)

{

    char *child_path;

    QDict *response, *tuple;

    QList *list;

    QListEntry *entry;

    g_test_message("Obtaining properties of %s", path);

    response = qmp("{ 'execute': 'qom-list',"

                   "  'arguments': { 'path': '%s' } }", path);

    g_assert(response);

    g_assert(qdict_haskey(response, "return"));

    list = qobject_to_qlist(qdict_get(response, "return"));

    QLIST_FOREACH_ENTRY(list, entry) {

        tuple = qobject_to_qdict(qlist_entry_obj(entry));

        if (strstart(qdict_get_str(tuple, "type"), "child<", NULL)) {

            child_path = g_strdup_printf("%s/%s",

                                         path, qdict_get_str(tuple, "name"));

            test_properties(child_path);

            g_free(child_path);

        } else {

            const char *prop = qdict_get_str(tuple, "name");

            g_test_message("Testing property %s.%s", path, prop);

            response = qmp("{ 'execute': 'qom-get',"

                           "  'arguments': { 'path': '%s',"

                           "                 'property': '%s' } }",

                           path, prop);

            /* qom-get may fail but should not, e.g., segfault. */

            g_assert(response);

        }

    }

}


static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr,

                         AVPacket* avpkt)

{

    WmallDecodeCtx *s = avctx->priv_data;

    GetBitContext* gb  = &s->pgb;

    const uint8_t* buf = avpkt->data;

    int buf_size       = avpkt->size;

    int num_bits_prev_frame, packet_sequence_number, spliced_packet;

    s->frame.nb_samples = 0;

    if (s->packet_done || s->packet_loss) {

        s->packet_done = 0;

        /* sanity check for the buffer length */

        if (buf_size < avctx->block_align)

            return 0;

        s->next_packet_start = buf_size - avctx->block_align;

        buf_size             = avctx->block_align;

        s->buf_bit_size      = buf_size << 3;

        /* parse packet header */

        init_get_bits(gb, buf, s->buf_bit_size);

        packet_sequence_number = get_bits(gb, 4);

        skip_bits(gb, 1);   // Skip seekable_frame_in_packet, currently ununused

        spliced_packet = get_bits1(gb);

        if (spliced_packet)

            avpriv_request_sample(avctx, "Bitstream splicing");

        /* get number of bits that need to be added to the previous frame */

        num_bits_prev_frame = get_bits(gb, s->log2_frame_size);

        /* check for packet loss */

        if (!s->packet_loss &&

            ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) {

            s->packet_loss = 1;

            av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n",

                   s->packet_sequence_number, packet_sequence_number);

        }

        s->packet_sequence_number = packet_sequence_number;

        if (num_bits_prev_frame > 0) {

            int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb);

            if (num_bits_prev_frame >= remaining_packet_bits) {

                num_bits_prev_frame = remaining_packet_bits;

                s->packet_done = 1;

            }

            /* Append the previous frame data to the remaining data from the

             * previous packet to create a full frame. */

            save_bits(s, gb, num_bits_prev_frame, 1);

            /* decode the cross packet frame if it is valid */

            if (num_bits_prev_frame < remaining_packet_bits && !s->packet_loss)

                decode_frame(s);

        } else if (s->num_saved_bits - s->frame_offset) {

            av_dlog(avctx, "ignoring %x previously saved bits\n",

                    s->num_saved_bits - s->frame_offset);

        }

        if (s->packet_loss) {

            /* Reset number of saved bits so that the decoder does not start

             * to decode incomplete frames in the s->len_prefix == 0 case. */

            s->num_saved_bits = 0;

            s->packet_loss    = 0;

            init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);

        }

    } else {

        int frame_size;

        s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3;

        init_get_bits(gb, avpkt->data, s->buf_bit_size);

        skip_bits(gb, s->packet_offset);

        if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size &&

            (frame_size = show_bits(gb, s->log2_frame_size)) &&

            frame_size <= remaining_bits(s, gb)) {

            save_bits(s, gb, frame_size, 0);

            s->packet_done = !decode_frame(s);

        } else if (!s->len_prefix

                   && s->num_saved_bits > get_bits_count(&s->gb)) {

            /* when the frames do not have a length prefix, we don't know the

             * compressed length of the individual frames however, we know what

             * part of a new packet belongs to the previous frame therefore we

             * save the incoming packet first, then we append the "previous

             * frame" data from the next packet so that we get a buffer that

             * only contains full frames */

            s->packet_done = !decode_frame(s);

        } else {

            s->packet_done = 1;

        }

    }

    if (s->packet_done && !s->packet_loss &&

        remaining_bits(s, gb) > 0) {

        /* save the rest of the data so that it can be decoded

         * with the next packet */

        save_bits(s, gb, remaining_bits(s, gb), 0);

    }

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

    *got_frame_ptr   = s->frame.nb_samples > 0;

    s->packet_offset = get_bits_count(gb) & 7;

    return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3;

}


static void mpegts_write_pes(AVFormatContext *s, AVStream *st,

                             const uint8_t *payload, int payload_size,

                             int64_t pts, int64_t dts, int key)

{

    MpegTSWriteStream *ts_st = st->priv_data;

    MpegTSWrite *ts = s->priv_data;

    uint8_t buf[TS_PACKET_SIZE];

    uint8_t *q;

    int val, is_start, len, header_len, write_pcr, is_dvb_subtitle, is_dvb_teletext, flags;

    int afc_len, stuffing_len;

    int64_t pcr = -1; /* avoid warning */

    int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE);

    int force_pat = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key;

    is_start = 1;

    while (payload_size > 0) {

        retransmit_si_info(s, force_pat);

        force_pat = 0;

        write_pcr = 0;

        if (ts_st->pid == ts_st->service->pcr_pid) {

            if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames

                ts_st->service->pcr_packet_count++;

            if (ts_st->service->pcr_packet_count >=

                ts_st->service->pcr_packet_period) {

                ts_st->service->pcr_packet_count = 0;

                write_pcr = 1;

        if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE &&

            (dts - get_pcr(ts, s->pb)/300) > delay) {

            /* pcr insert gets priority over null packet insert */

            if (write_pcr)

                mpegts_insert_pcr_only(s, st);

            else

                mpegts_insert_null_packet(s);

            continue; /* recalculate write_pcr and possibly retransmit si_info */

        /* prepare packet header */

        q = buf;

        *q++ = 0x47;

        val = (ts_st->pid >> 8);

        if (is_start)

            val |= 0x40;

        *q++ = val;

        *q++ = ts_st->pid;

        ts_st->cc = (ts_st->cc + 1) & 0xf;

        *q++ = 0x10 | ts_st->cc; // payload indicator + CC

        if (key && is_start && pts != AV_NOPTS_VALUE) {

            // set Random Access for key frames

            if (ts_st->pid == ts_st->service->pcr_pid)

                write_pcr = 1;

            set_af_flag(buf, 0x40);

            q = get_ts_payload_start(buf);

        if (write_pcr) {

            set_af_flag(buf, 0x10);

            q = get_ts_payload_start(buf);

            // add 11, pcr references the last byte of program clock reference base

            if (ts->mux_rate > 1)

                pcr = get_pcr(ts, s->pb);

            else

                pcr = (dts - delay)*300;

            if (dts != AV_NOPTS_VALUE && dts < pcr / 300)

                av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n");

            extend_af(buf, write_pcr_bits(q, pcr));

            q = get_ts_payload_start(buf);

        if (is_start) {

            int pes_extension = 0;

            int pes_header_stuffing_bytes = 0;

            /* write PES header */

            *q++ = 0x00;

            *q++ = 0x00;

            *q++ = 0x01;

            is_dvb_subtitle = 0;

            is_dvb_teletext = 0;

                if (st->codec->codec_id == AV_CODEC_ID_DIRAC) {

                    *q++ = 0xfd;

                } else

                    *q++ = 0xe0;

            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&

                       (st->codec->codec_id == AV_CODEC_ID_MP2 ||

                        st->codec->codec_id == AV_CODEC_ID_MP3 ||

                        st->codec->codec_id == AV_CODEC_ID_AAC)) {

                *q++ = 0xc0;

            } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&

                        st->codec->codec_id == AV_CODEC_ID_AC3 &&

                        ts->m2ts_mode) {

                *q++ = 0xfd;

            } else {

                *q++ = 0xbd;

                if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {

                    if (st->codec->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {

                        is_dvb_subtitle = 1;

                    } else if (st->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT) {

                        is_dvb_teletext = 1;

            header_len = 0;

            flags = 0;

            if (pts != AV_NOPTS_VALUE) {

                header_len += 5;

                flags |= 0x80;

            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {

                header_len += 5;

                flags |= 0x40;

            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&

                st->codec->codec_id == AV_CODEC_ID_DIRAC) {

                /* set PES_extension_flag */

                pes_extension = 1;

                flags |= 0x01;

                /*

                * One byte for PES2 extension flag +

                * one byte for extension length +

                * one byte for extension id

                */

                header_len += 3;

            /* for Blu-ray AC3 Audio the PES Extension flag should be as follow

             * otherwise it will not play sound on blu-ray

             */

            if (ts->m2ts_mode &&

                st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&

                st->codec->codec_id == AV_CODEC_ID_AC3) {

                        /* set PES_extension_flag */

                        pes_extension = 1;

                        flags |= 0x01;

                        header_len += 3;

            if (is_dvb_teletext) {

                pes_header_stuffing_bytes = 0x24 - header_len;

                header_len = 0x24;

            len = payload_size + header_len + 3;

            /* 3 extra bytes should be added to DVB subtitle payload: 0x20 0x00 at the beginning and trailing 0xff */

            if (is_dvb_subtitle) {

                len += 3;

                payload_size++;

            if (len > 0xffff)

            *q++ = len >> 8;

            *q++ = len;

            val = 0x80;

            /* data alignment indicator is required for subtitle and data streams */

            if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA)

                val |= 0x04;

            *q++ = val;

            *q++ = flags;

            *q++ = header_len;

            if (pts != AV_NOPTS_VALUE) {

                write_pts(q, flags >> 6, pts);

                q += 5;

            if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) {

                write_pts(q, 1, dts);

                q += 5;

            if (pes_extension && st->codec->codec_id == AV_CODEC_ID_DIRAC) {

                flags = 0x01;  /* set PES_extension_flag_2 */

                *q++ = flags;

                *q++ = 0x80 | 0x01;  /* marker bit + extension length */

                /*

                * Set the stream id extension flag bit to 0 and

                * write the extended stream id

                */

                *q++ = 0x00 | 0x60;

            /* For Blu-ray AC3 Audio Setting extended flags */

          if (ts->m2ts_mode &&

              pes_extension &&

              st->codec->codec_id == AV_CODEC_ID_AC3) {

                      flags = 0x01; /* set PES_extension_flag_2 */

                      *q++ = flags;

                      *q++ = 0x80 | 0x01; /* marker bit + extension length */

                      *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */

            if (is_dvb_subtitle) {

                /* First two fields of DVB subtitles PES data:

                 * data_identifier: for DVB subtitle streams shall be coded with the value 0x20

                 * subtitle_stream_id: for DVB subtitle stream shall be identified by the value 0x00 */

                *q++ = 0x20;

                *q++ = 0x00;

            if (is_dvb_teletext) {

                memset(q, 0xff, pes_header_stuffing_bytes);

                q += pes_header_stuffing_bytes;

            is_start = 0;

        /* header size */

        header_len = q - buf;

        /* data len */

        len = TS_PACKET_SIZE - header_len;

        if (len > payload_size)

            len = payload_size;

        stuffing_len = TS_PACKET_SIZE - header_len - len;

        if (stuffing_len > 0) {

            /* add stuffing with AFC */

            if (buf[3] & 0x20) {

                /* stuffing already present: increase its size */

                afc_len = buf[4] + 1;

                memmove(buf + 4 + afc_len + stuffing_len,

                        buf + 4 + afc_len,

                        header_len - (4 + afc_len));

                buf[4] += stuffing_len;

                memset(buf + 4 + afc_len, 0xff, stuffing_len);

            } else {

                /* add stuffing */

                memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4);

                buf[3] |= 0x20;

                buf[4] = stuffing_len - 1;

                if (stuffing_len >= 2) {

                    buf[5] = 0x00;

                    memset(buf + 6, 0xff, stuffing_len - 2);

        if (is_dvb_subtitle && payload_size == len) {

            memcpy(buf + TS_PACKET_SIZE - len, payload, len - 1);

            buf[TS_PACKET_SIZE - 1] = 0xff; /* end_of_PES_data_field_marker: an 8-bit field with fixed contents 0xff for DVB subtitle */

        } else {

            memcpy(buf + TS_PACKET_SIZE - len, payload, len);

        payload += len;

        payload_size -= len;

        mpegts_prefix_m2ts_header(s);

        avio_write(s->pb, buf, TS_PACKET_SIZE);

    avio_flush(s->pb);

    ts_st->prev_payload_key = key;