static void iv_Decode_Chunk(Indeo3DecodeContext *s,

        uint8_t *cur, uint8_t *ref, int width, int height,

        const uint8_t *buf1, int cb_offset, const uint8_t *hdr,

        const uint8_t *buf2, int min_width_160)

{

    uint8_t bit_buf;

    unsigned int bit_pos, lv, lv1, lv2;

    int *width_tbl, width_tbl_arr[10];

    const signed char *ref_vectors;

    uint8_t *cur_frm_pos, *ref_frm_pos, *cp, *cp2;

    uint32_t *cur_lp, *ref_lp;

    const uint32_t *correction_lp[2], *correctionloworder_lp[2], *correctionhighorder_lp[2];

    uint8_t *correction_type_sp[2];

    struct ustr strip_tbl[20], *strip;

    int i, j, k, lp1, lp2, flag1, cmd, blks_width, blks_height, region_160_width,

        rle_v1, rle_v2, rle_v3;

    unsigned short res;

    bit_buf = 0;

    ref_vectors = NULL;

    width_tbl = width_tbl_arr + 1;

    i = (width < 0 ? width + 3 : width)/4;

    for(j = -1; j < 8; j++)

        width_tbl[j] = i * j;

    strip = strip_tbl;

    for(region_160_width = 0; region_160_width < (width - min_width_160); region_160_width += min_width_160);

    strip->ypos = strip->xpos = 0;

    for(strip->width = min_width_160; width > strip->width; strip->width *= 2);

    strip->height = height;

    strip->split_direction = 0;

    strip->split_flag = 0;

    strip->usl7 = 0;

    bit_pos = 0;

    rle_v1 = rle_v2 = rle_v3 = 0;

    while(strip >= strip_tbl) {

        if(bit_pos <= 0) {

            bit_pos = 8;

            bit_buf = *buf1++;

        }

        bit_pos -= 2;

        cmd = (bit_buf >> bit_pos) & 0x03;

        if(cmd == 0) {

            strip++;

            if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {

                av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");

                break;

            }

            memcpy(strip, strip-1, sizeof(*strip));

            strip->split_flag = 1;

            strip->split_direction = 0;

            strip->height = (strip->height > 8 ? ((strip->height+8)>>4)<<3 : 4);

            continue;

        } else if(cmd == 1) {

            strip++;

            if(strip >= strip_tbl + FF_ARRAY_ELEMS(strip_tbl)) {

                av_log(s->avctx, AV_LOG_WARNING, "out of range strip\n");

                break;

            }

            memcpy(strip, strip-1, sizeof(*strip));

            strip->split_flag = 1;

            strip->split_direction = 1;

            strip->width = (strip->width > 8 ? ((strip->width+8)>>4)<<3 : 4);

            continue;

        } else if(cmd == 2) {

            if(strip->usl7 == 0) {

                strip->usl7 = 1;

                ref_vectors = NULL;

                continue;

            }

        } else if(cmd == 3) {

            if(strip->usl7 == 0) {

                strip->usl7 = 1;

                ref_vectors = (const signed char*)buf2 + (*buf1 * 2);

                buf1++;

                continue;

            }

        }

        cur_frm_pos = cur + width * strip->ypos + strip->xpos;

        if((blks_width = strip->width) < 0)

            blks_width += 3;

        blks_width >>= 2;

        blks_height = strip->height;

        if(ref_vectors != NULL) {

            ref_frm_pos = ref + (ref_vectors[0] + strip->ypos) * width +

                ref_vectors[1] + strip->xpos;

        } else

            ref_frm_pos = cur_frm_pos - width_tbl[4];

        if(cmd == 2) {

            if(bit_pos <= 0) {

                bit_pos = 8;

                bit_buf = *buf1++;

            }

            bit_pos -= 2;

            cmd = (bit_buf >> bit_pos) & 0x03;

            if(cmd == 0 || ref_vectors != NULL) {

                for(lp1 = 0; lp1 < blks_width; lp1++) {

                    for(i = 0, j = 0; i < blks_height; i++, j += width_tbl[1])

                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];

                    cur_frm_pos += 4;

                    ref_frm_pos += 4;

                }

            } else if(cmd != 1)

                return;

        } else {

            k = *buf1 >> 4;

            j = *buf1 & 0x0f;

            buf1++;

            lv = j + cb_offset;

            if((lv - 8) <= 7 && (k == 0 || k == 3 || k == 10)) {

                cp2 = s->ModPred + ((lv - 8) << 7);

                cp = ref_frm_pos;

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

                    int v = *cp >> 1;

                    *(cp++) = cp2[v];

                }

            }

            if(k == 1 || k == 4) {

                lv = (hdr[j] & 0xf) + cb_offset;

                correction_type_sp[0] = s->corrector_type + (lv << 8);

                correction_lp[0] = correction + (lv << 8);

                lv = (hdr[j] >> 4) + cb_offset;

                correction_lp[1] = correction + (lv << 8);

                correction_type_sp[1] = s->corrector_type + (lv << 8);

            } else {

                correctionloworder_lp[0] = correctionloworder_lp[1] = correctionloworder + (lv << 8);

                correctionhighorder_lp[0] = correctionhighorder_lp[1] = correctionhighorder + (lv << 8);

                correction_type_sp[0] = correction_type_sp[1] = s->corrector_type + (lv << 8);

                correction_lp[0] = correction_lp[1] = correction + (lv << 8);

            }

            switch(k) {

            case 1:

            case 0:                    /********** CASE 0 **********/

                for( ; blks_height > 0; blks_height -= 4) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2];

                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2];

                            if ((uint8_t *)cur_lp >= cur_end-3)

                                break;

                            switch(correction_type_sp[0][k]) {

                            case 0:

                                *cur_lp = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                                break;

                            case 1:

                                res = ((av_le2ne16(((unsigned short *)(ref_lp))[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;

                                ((unsigned short *)cur_lp)[0] = av_le2ne16(res);

                                res = ((av_le2ne16(((unsigned short *)(ref_lp))[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;

                                ((unsigned short *)cur_lp)[1] = av_le2ne16(res);

                                buf1++;

                                lp2++;

                                break;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 2; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 += 2;

                                }

                                break;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < (3 - lp2); i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 = 3;

                                }

                                break;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    if(rle_v1 == 1 || ref_vectors != NULL) {

                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                            cur_lp[j] = ref_lp[j];

                                    }

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                    break;

                                } else {

                                    rle_v1 = 1;

                                    rle_v2 = *buf1 - 1;

                                }

                            case 5:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                                for(i = 0, j = 0; i < (4 - lp2); i++, j += width_tbl[1])

                                    cur_lp[j] = ref_lp[j];

                                lp2 = 4;

                                break;

                            case 7:

                                if(rle_v3 != 0)

                                    rle_v3 = 0;

                                else {

                                    buf1--;

                                    rle_v3 = 1;

                                }

                            case 6:

                                if(ref_vectors != NULL) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                }

                                lp2 = 4;

                                break;

                            case 9:

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                break;

                            default:

                                return;

                            }

                        }

                        cur_frm_pos += 4;

                        ref_frm_pos += 4;

                    }

                    cur_frm_pos += ((width - blks_width) * 4);

                    ref_frm_pos += ((width - blks_width) * 4);

                }

                break;

            case 4:

            case 3:                    /********** CASE 3 **********/

                if(ref_vectors != NULL)

                    return;

                flag1 = 1;

                for( ; blks_height > 0; blks_height -= 8) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                            ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];

                            switch(correction_type_sp[lp2 & 0x01][k]) {

                            case 0:

                                cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)

                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                else

                                    cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                                break;

                            case 1:

                                res = ((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + correction_lp[lp2 & 0x01][*buf1]) << 1;

                                ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res);

                                res = ((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1;

                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res);

                                if(lp2 > 0 || flag1 == 0 || strip->ypos != 0)

                                    cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                else

                                    cur_lp[0] = cur_lp[width_tbl[1]];

                                buf1++;

                                lp2++;

                                break;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = *ref_lp;

                                    lp2 += 2;

                                }

                                break;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])

                                        cur_lp[j] = *ref_lp;

                                    lp2 = 3;

                                }

                                break;

                            case 6:

                                lp2 = 4;

                                break;

                            case 7:

                                if(rle_v3 != 0)

                                    rle_v3 = 0;

                                else {

                                    buf1--;

                                    rle_v3 = 1;

                                }

                                lp2 = 4;

                                break;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    if(rle_v1 == 1) {

                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                            cur_lp[j] = ref_lp[j];

                                    }

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                    break;

                                } else {

                                    rle_v2 = (*buf1) - 1;

                                    rle_v1 = 1;

                                }

                            case 5:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])

                                    cur_lp[j] = *ref_lp;

                                lp2 = 4;

                                break;

                            case 9:

                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                break;

                            default:

                                return;

                            }

                        }

                        cur_frm_pos += 4;

                    }

                    cur_frm_pos += (((width * 2) - blks_width) * 4);

                    flag1 = 0;

                }

                break;

            case 10:                    /********** CASE 10 **********/

                if(ref_vectors == NULL) {

                    flag1 = 1;

                    for( ; blks_height > 0; blks_height -= 8) {

                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {

                            for(lp2 = 0; lp2 < 4; ) {

                                k = *buf1++;

                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                                ref_lp = ((uint32_t *)cur_frm_pos) + width_tbl[(lp2 * 2) - 1];

                                lv1 = ref_lp[0];

                                lv2 = ref_lp[1];

                                if(lp2 == 0 && flag1 != 0) {

#if HAVE_BIGENDIAN

                                    lv1 = lv1 & 0xFF00FF00;

                                    lv1 = (lv1 >> 8) | lv1;

                                    lv2 = lv2 & 0xFF00FF00;

                                    lv2 = (lv2 >> 8) | lv2;

#else

                                    lv1 = lv1 & 0x00FF00FF;

                                    lv1 = (lv1 << 8) | lv1;

                                    lv2 = lv2 & 0x00FF00FF;

                                    lv2 = (lv2 << 8) | lv2;

#endif

                                }

                                switch(correction_type_sp[lp2 & 0x01][k]) {

                                case 0:

                                    cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);

                                    cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionhighorder_lp[lp2 & 0x01][k]) << 1);

                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        cur_lp[0] = cur_lp[width_tbl[1]];

                                        cur_lp[1] = cur_lp[width_tbl[1]+1];

                                    }

                                    lp2++;

                                    break;

                                case 1:

                                    cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(lv1) >> 1) + correctionloworder_lp[lp2 & 0x01][*buf1]) << 1);

                                    cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(lv2) >> 1) + correctionloworder_lp[lp2 & 0x01][k]) << 1);

                                    if(lp2 > 0 || strip->ypos != 0 || flag1 == 0) {

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        cur_lp[0] = cur_lp[width_tbl[1]];

                                        cur_lp[1] = cur_lp[width_tbl[1]+1];

                                    }

                                    buf1++;

                                    lp2++;

                                    break;

                                case 2:

                                    if(lp2 == 0) {

                                        if(flag1 != 0) {

                                            for(i = 0, j = width_tbl[1]; i < 3; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            }

                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                        } else {

                                            for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            }

                                        }

                                        lp2 += 2;

                                    }

                                    break;

                                case 3:

                                    if(lp2 < 2) {

                                        if(lp2 == 0 && flag1 != 0) {

                                            for(i = 0, j = width_tbl[1]; i < 5; i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            }

                                            cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                            cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                        } else {

                                            for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {

                                                cur_lp[j] = lv1;

                                                cur_lp[j+1] = lv2;

                                            }

                                        }

                                        lp2 = 3;

                                    }

                                    break;

                                case 8:

                                    if(lp2 == 0) {

                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                        if(rle_v1 == 1) {

                                            if(flag1 != 0) {

                                                for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {

                                                    cur_lp[j] = lv1;

                                                    cur_lp[j+1] = lv2;

                                                }

                                                cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                                cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                            } else {

                                                for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {

                                                    cur_lp[j] = lv1;

                                                    cur_lp[j+1] = lv2;

                                                }

                                            }

                                        }

                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                        break;

                                    } else {

                                        rle_v1 = 1;

                                        rle_v2 = (*buf1) - 1;

                                    }

                                case 5:

                                    LP2_CHECK(buf1,rle_v3,lp2)

                                case 4:

                                    if(lp2 == 0 && flag1 != 0) {

                                        for(i = 0, j = width_tbl[1]; i < 7; i++, j += width_tbl[1]) {

                                            cur_lp[j] = lv1;

                                            cur_lp[j+1] = lv2;

                                        }

                                        cur_lp[0] = ((cur_lp[-width_tbl[1]] >> 1) + (cur_lp[width_tbl[1]] >> 1)) & 0xFEFEFEFE;

                                        cur_lp[1] = ((cur_lp[-width_tbl[1]+1] >> 1) + (cur_lp[width_tbl[1]+1] >> 1)) & 0xFEFEFEFE;

                                    } else {

                                        for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {

                                            cur_lp[j] = lv1;

                                            cur_lp[j+1] = lv2;

                                        }

                                    }

                                    lp2 = 4;

                                    break;

                                case 6:

                                    lp2 = 4;

                                    break;

                                case 7:

                                    if(lp2 == 0) {

                                        if(rle_v3 != 0)

                                            rle_v3 = 0;

                                        else {

                                            buf1--;

                                            rle_v3 = 1;

                                        }

                                        lp2 = 4;

                                    }

                                    break;

                                case 9:

                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                    lv1 = *buf1;

                                    lv = (lv1 & 0x7F) << 1;

                                    lv += (lv << 8);

                                    lv += (lv << 16);

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        cur_lp[j] = lv;

                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                    break;

                                default:

                                    return;

                                }

                            }

                            cur_frm_pos += 8;

                        }

                        cur_frm_pos += (((width * 2) - blks_width) * 4);

                        flag1 = 0;

                    }

                } else {

                    for( ; blks_height > 0; blks_height -= 8) {

                        for(lp1 = 0; lp1 < blks_width; lp1 += 2) {

                            for(lp2 = 0; lp2 < 4; ) {

                                k = *buf1++;

                                cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                                ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];

                                switch(correction_type_sp[lp2 & 0x01][k]) {

                                case 0:

                                    lv1 = correctionloworder_lp[lp2 & 0x01][k];

                                    lv2 = correctionhighorder_lp[lp2 & 0x01][k];

                                    cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1);

                                    cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1);

                                    cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);

                                    cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);

                                    lp2++;

                                    break;

                                case 1:

                                    lv1 = correctionloworder_lp[lp2 & 0x01][*buf1++];

                                    lv2 = correctionloworder_lp[lp2 & 0x01][k];

                                    cur_lp[0] = av_le2ne32(((av_le2ne32(ref_lp[0]) >> 1) + lv1) << 1);

                                    cur_lp[1] = av_le2ne32(((av_le2ne32(ref_lp[1]) >> 1) + lv2) << 1);

                                    cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + lv1) << 1);

                                    cur_lp[width_tbl[1]+1] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]+1]) >> 1) + lv2) << 1);

                                    lp2++;

                                    break;

                                case 2:

                                    if(lp2 == 0) {

                                        for(i = 0, j = 0; i < 4; i++, j += width_tbl[1]) {

                                            cur_lp[j] = ref_lp[j];

                                            cur_lp[j+1] = ref_lp[j+1];

                                        }

                                        lp2 += 2;

                                    }

                                    break;

                                case 3:

                                    if(lp2 < 2) {

                                        for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1]) {

                                            cur_lp[j] = ref_lp[j];

                                            cur_lp[j+1] = ref_lp[j+1];

                                        }

                                        lp2 = 3;

                                    }

                                    break;

                                case 8:

                                    if(lp2 == 0) {

                                        RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                        for(i = 0, j = 0; i < 8; i++, j += width_tbl[1]) {

                                            ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)ref_frm_pos)[j];

                                            ((uint32_t *)cur_frm_pos)[j+1] = ((uint32_t *)ref_frm_pos)[j+1];

                                        }

                                        RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                        break;

                                    } else {

                                        rle_v1 = 1;

                                        rle_v2 = (*buf1) - 1;

                                    }

                                case 5:

                                case 7:

                                    LP2_CHECK(buf1,rle_v3,lp2)

                                case 6:

                                case 4:

                                    for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1]) {

                                        cur_lp[j] = ref_lp[j];

                                        cur_lp[j+1] = ref_lp[j+1];

                                    }

                                    lp2 = 4;

                                    break;

                                case 9:

                                    av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                    lv1 = *buf1;

                                    lv = (lv1 & 0x7F) << 1;

                                    lv += (lv << 8);

                                    lv += (lv << 16);

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        ((uint32_t *)cur_frm_pos)[j] = ((uint32_t *)cur_frm_pos)[j+1] = lv;

                                    LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                    break;

                                default:

                                    return;

                                }

                            }

                            cur_frm_pos += 8;

                            ref_frm_pos += 8;

                        }

                        cur_frm_pos += (((width * 2) - blks_width) * 4);

                        ref_frm_pos += (((width * 2) - blks_width) * 4);

                    }

                }

                break;

            case 11:                    /********** CASE 11 **********/

                if(ref_vectors == NULL)

                    return;

                for( ; blks_height > 0; blks_height -= 8) {

                    for(lp1 = 0; lp1 < blks_width; lp1++) {

                        for(lp2 = 0; lp2 < 4; ) {

                            k = *buf1++;

                            cur_lp = ((uint32_t *)cur_frm_pos) + width_tbl[lp2 * 2];

                            ref_lp = ((uint32_t *)ref_frm_pos) + width_tbl[lp2 * 2];

                            switch(correction_type_sp[lp2 & 0x01][k]) {

                            case 0:

                                cur_lp[0] = av_le2ne32(((av_le2ne32(*ref_lp) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                cur_lp[width_tbl[1]] = av_le2ne32(((av_le2ne32(ref_lp[width_tbl[1]]) >> 1) + correction_lp[lp2 & 0x01][k]) << 1);

                                lp2++;

                                break;

                            case 1:

                                lv1 = (unsigned short)(correction_lp[lp2 & 0x01][*buf1++]);

                                lv2 = (unsigned short)(correction_lp[lp2 & 0x01][k]);

                                res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[0]) >> 1) + lv1) << 1);

                                ((unsigned short *)cur_lp)[0] = av_le2ne16(res);

                                res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[1]) >> 1) + lv2) << 1);

                                ((unsigned short *)cur_lp)[1] = av_le2ne16(res);

                                res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]]) >> 1) + lv1) << 1);

                                ((unsigned short *)cur_lp)[width_tbl[2]] = av_le2ne16(res);

                                res = (unsigned short)(((av_le2ne16(((unsigned short *)ref_lp)[width_tbl[2]+1]) >> 1) + lv2) << 1);

                                ((unsigned short *)cur_lp)[width_tbl[2]+1] = av_le2ne16(res);

                                lp2++;

                                break;

                            case 2:

                                if(lp2 == 0) {

                                    for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 += 2;

                                }

                                break;

                            case 3:

                                if(lp2 < 2) {

                                    for(i = 0, j = 0; i < 6 - (lp2 * 2); i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    lp2 = 3;

                                }

                                break;

                            case 8:

                                if(lp2 == 0) {

                                    RLE_V3_CHECK(buf1,rle_v1,rle_v2,rle_v3)

                                    for(i = 0, j = 0; i < 8; i++, j += width_tbl[1])

                                        cur_lp[j] = ref_lp[j];

                                    RLE_V2_CHECK(buf1,rle_v2, rle_v3,lp2)

                                    break;

                                } else {

                                    rle_v1 = 1;

                                    rle_v2 = (*buf1) - 1;

                                }

                            case 5:

                            case 7:

                                LP2_CHECK(buf1,rle_v3,lp2)

                            case 4:

                            case 6:

                                for(i = 0, j = 0; i < 8 - (lp2 * 2); i++, j += width_tbl[1])

                                    cur_lp[j] = ref_lp[j];

                                lp2 = 4;

                                break;

                            case 9:

                                av_log(s->avctx, AV_LOG_ERROR, "UNTESTED.\n");

                                lv1 = *buf1++;

                                lv = (lv1 & 0x7F) << 1;

                                lv += (lv << 8);

                                lv += (lv << 16);

                                for(i = 0, j = 0; i < 4; i++, j += width_tbl[1])

                                    cur_lp[j] = lv;

                                LV1_CHECK(buf1,rle_v3,lv1,lp2)

                                break;

                            default:

                                return;

                            }

                        }

                        cur_frm_pos += 4;

                        ref_frm_pos += 4;

                    }

                    cur_frm_pos += (((width * 2) - blks_width) * 4);

                    ref_frm_pos += (((width * 2) - blks_width) * 4);

                }

                break;

            default:

                return;

            }

        }

        for( ; strip >= strip_tbl; strip--) {

            if(strip->split_flag != 0) {

                strip->split_flag = 0;

                strip->usl7 = (strip-1)->usl7;

                if(strip->split_direction) {

                    strip->xpos += strip->width;

                    strip->width = (strip-1)->width - strip->width;

                    if(region_160_width <= strip->xpos && width < strip->width + strip->xpos)

                        strip->width = width - strip->xpos;

                } else {

                    strip->ypos += strip->height;

                    strip->height = (strip-1)->height - strip->height;

                }

                break;

            }

        }

    }

}


static int bethsoftvid_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    BethsoftvidContext * vid = avctx->priv_data;

    char block_type;

    uint8_t * dst;

    uint8_t * frame_end;

    int remaining = avctx->width;          // number of bytes remaining on a line

    const int wrap_to_next_line = vid->frame.linesize[0] - avctx->width;

    int code;

    int yoffset;

    if (avctx->reget_buffer(avctx, &vid->frame)) {

        av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");

        return -1;

    }

    dst = vid->frame.data[0];

    frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height;

    switch(block_type = *buf++){

        case PALETTE_BLOCK:

            return set_palette(&vid->frame, buf, buf_size);

        case VIDEO_YOFF_P_FRAME:

            yoffset = bytestream_get_le16(&buf);

            if(yoffset >= avctx->height)

                return -1;

            dst += vid->frame.linesize[0] * yoffset;

    }

    // main code

    while((code = *buf++)){

        int length = code & 0x7f;

        // copy any bytes starting at the current position, and ending at the frame width

        while(length > remaining){

            if(code < 0x80)

                bytestream_get_buffer(&buf, dst, remaining);

            else if(block_type == VIDEO_I_FRAME)

                memset(dst, buf[0], remaining);

            length -= remaining;      // decrement the number of bytes to be copied

            dst += remaining + wrap_to_next_line;    // skip over extra bytes at end of frame

            remaining = avctx->width;

            if(dst == frame_end)

                goto end;

        }

        // copy any remaining bytes after / if line overflows

        if(code < 0x80)

            bytestream_get_buffer(&buf, dst, length);

        else if(block_type == VIDEO_I_FRAME)

            memset(dst, *buf++, length);

        remaining -= length;

        dst += length;

    }

    end:

    *data_size = sizeof(AVFrame);

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

    return buf_size;

}


static int get_S2prot(CPUARMState *env, int s2ap, int xn)

{

    int prot = 0;

    if (s2ap & 1) {

        prot |= PAGE_READ;

    }

    if (s2ap & 2) {

        prot |= PAGE_WRITE;

    }

    if (!xn) {

        prot |= PAGE_EXEC;

    }

    return prot;

}


void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,

                void (*func)(QVirtioDevice *d, void *data), void *data)

{

    QVirtioPCIForeachData d = { .func = func,

                                .device_type = device_type,

                                .user_data = data };

    qpci_device_foreach(bus, PCI_VENDOR_ID_REDHAT_QUMRANET, -1,

                                qvirtio_pci_foreach_callback, &d);

}


static void gen_slbmfee(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);

        return;

    }

    gen_helper_load_slb_esid(cpu_gpr[rS(ctx->opcode)], cpu_env,

                             cpu_gpr[rB(ctx->opcode)]);

#endif

}


static int qcow2_make_empty(BlockDriverState *bs)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t offset, end_offset;

    int step = QEMU_ALIGN_DOWN(INT_MAX, s->cluster_size);

    int l1_clusters, ret = 0;

    l1_clusters = DIV_ROUND_UP(s->l1_size, s->cluster_size / sizeof(uint64_t));

    if (s->qcow_version >= 3 && !s->snapshots &&

        3 + l1_clusters <= s->refcount_block_size &&

        s->crypt_method_header != QCOW_CRYPT_LUKS) {

        /* The following function only works for qcow2 v3 images (it requires

         * the dirty flag) and only as long as there are no snapshots (because

         * it completely empties the image). Furthermore, the L1 table and three

         * additional clusters (image header, refcount table, one refcount

         * block) have to fit inside one refcount block. It cannot be used

         * for LUKS (yet) as it throws away the LUKS header cluster(s) */

        return make_completely_empty(bs);

    }

    /* This fallback code simply discards every active cluster; this is slow,

     * but works in all cases */

    end_offset = bs->total_sectors * BDRV_SECTOR_SIZE;

    for (offset = 0; offset < end_offset; offset += step) {

        /* As this function is generally used after committing an external

         * snapshot, QCOW2_DISCARD_SNAPSHOT seems appropriate. Also, the

         * default action for this kind of discard is to pass the discard,

         * which will ideally result in an actually smaller image file, as

         * is probably desired. */

        ret = qcow2_cluster_discard(bs, offset, MIN(step, end_offset - offset),

                                    QCOW2_DISCARD_SNAPSHOT, true);

        if (ret < 0) {

            break;

        }

    }

    return ret;

}


static VncBasicInfoList *qmp_query_server_entry(QIOChannelSocket *ioc,

                                                bool websocket,

                                                VncBasicInfoList *prev)

{

    VncBasicInfoList *list;

    VncBasicInfo *info;

    Error *err = NULL;

    SocketAddress *addr;

    addr = qio_channel_socket_get_local_address(ioc, &err);

    if (!addr) {

        error_free(err);

        return prev;

    }

    info = g_new0(VncBasicInfo, 1);

    vnc_init_basic_info(addr, info, &err);

    qapi_free_SocketAddress(addr);

    if (err) {

        qapi_free_VncBasicInfo(info);

        error_free(err);

        return prev;

    }

    info->websocket = websocket;

    list = g_new0(VncBasicInfoList, 1);

    list->value = info;

    list->next = prev;

    return list;

}


uint32_t HELPER(get_cp_reg)(CPUARMState *env, void *rip)

{

    const ARMCPRegInfo *ri = rip;

    return ri->readfn(env, ri);

}


static NetSocketState *net_socket_fd_init_dgram(VLANState *vlan, int fd,

                                          int is_connected)

{

    struct sockaddr_in saddr;

    int newfd;

    socklen_t saddr_len;

    NetSocketState *s;

    /* fd passed: multicast: "learn" dgram_dst address from bound address and save it

     * Because this may be "shared" socket from a "master" process, datagrams would be recv()

     * by ONLY ONE process: we must "clone" this dgram socket --jjo

     */

    if (is_connected) {

	if (getsockname(fd, (struct sockaddr *) &saddr, &saddr_len) == 0) {

	    /* must be bound */

	    if (saddr.sin_addr.s_addr==0) {

		fprintf(stderr, "qemu: error: init_dgram: fd=%d unbound, cannot setup multicast dst addr\n",

			fd);

		return NULL;

	    }

	    /* clone dgram socket */

	    newfd = net_socket_mcast_create(&saddr);

	    if (newfd < 0) {

		/* error already reported by net_socket_mcast_create() */

		close(fd);

		return NULL;

	    }

	    /* clone newfd to fd, close newfd */

	    dup2(newfd, fd);

	    close(newfd);

	} else {

	    fprintf(stderr, "qemu: error: init_dgram: fd=%d failed getsockname(): %s\n",

		    fd, strerror(errno));

	    return NULL;

	}

    }

    s = qemu_mallocz(sizeof(NetSocketState));

    if (!s)

        return NULL;

    s->fd = fd;

    s->vc = qemu_new_vlan_client(vlan, net_socket_receive_dgram, s);

    qemu_set_fd_handler(s->fd, net_socket_send_dgram, NULL, s);

    /* mcast: save bound address as dst */

    if (is_connected) s->dgram_dst=saddr;

    snprintf(s->vc->info_str, sizeof(s->vc->info_str),

	    "socket: fd=%d (%s mcast=%s:%d)",

	    fd, is_connected? "cloned" : "",

	    inet_ntoa(saddr.sin_addr), ntohs(saddr.sin_port));

    return s;

}


static int filter_frame(AVFilterLink *link, AVFilterBufferRef *picref)

{

    AVFilterContext *ctx = link->dst;

    YADIFContext *yadif = ctx->priv;

    av_assert0(picref);

    if (picref->video->h < 3 || picref->video->w < 3) {

        av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or lines is not supported\n");

        return AVERROR(EINVAL);

    }

    if (yadif->frame_pending)

        return_frame(ctx, 1);

    if (yadif->prev)

        avfilter_unref_buffer(yadif->prev);

    yadif->prev = yadif->cur;

    yadif->cur  = yadif->next;

    yadif->next = picref;

    if (!yadif->cur)

        return 0;

    if (yadif->auto_enable && !yadif->cur->video->interlaced) {

        yadif->out  = avfilter_ref_buffer(yadif->cur, ~AV_PERM_WRITE);

        if (!yadif->out)

            return AVERROR(ENOMEM);

        avfilter_unref_bufferp(&yadif->prev);

        if (yadif->out->pts != AV_NOPTS_VALUE)

            yadif->out->pts *= 2;

        return ff_filter_frame(ctx->outputs[0], yadif->out);

    }

    if (!yadif->prev &&

        !(yadif->prev = avfilter_ref_buffer(yadif->cur, ~AV_PERM_WRITE)))

        return AVERROR(ENOMEM);

    yadif->out = ff_get_video_buffer(ctx->outputs[0], PERM_RWP,

                                     link->w, link->h);

    if (!yadif->out)

        return AVERROR(ENOMEM);

    avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);

    yadif->out->video->interlaced = 0;

    if (yadif->out->pts != AV_NOPTS_VALUE)

        yadif->out->pts *= 2;

    return return_frame(ctx, 0);

}


void ff_put_h264_qpel16_mc23_msa(uint8_t *dst, const uint8_t *src,

                                 ptrdiff_t stride)

{

    avc_luma_midv_qrt_16w_msa(src - (2 * stride) - 2,

                              stride, dst, stride, 16, 1);

}


static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){

    int i;

    // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)

    CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance

    s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;

     //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer()

    CHECKED_ALLOCZ(s->me.scratchpad,  (s->width+64)*4*16*2*sizeof(uint8_t))

    s->me.temp=         s->me.scratchpad;

    s->rd_scratchpad=   s->me.scratchpad;

    s->b_scratchpad=    s->me.scratchpad;

    s->obmc_scratchpad= s->me.scratchpad + 16;

    if (s->encoding) {

        CHECKED_ALLOCZ(s->me.map      , ME_MAP_SIZE*sizeof(uint32_t))

        CHECKED_ALLOCZ(s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t))

        if(s->avctx->noise_reduction){

            CHECKED_ALLOCZ(s->dct_error_sum, 2 * 64 * sizeof(int))

        }

    }

    CHECKED_ALLOCZ(s->blocks, 64*12*2 * sizeof(DCTELEM))

    s->block= s->blocks[0];

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

        s->pblocks[i] = &s->block[i];

    }

    return 0;

fail:

    return -1; //free() through MPV_common_end()

}


void ff_put_h264_qpel4_mc31_msa(uint8_t *dst, const uint8_t *src,

                                ptrdiff_t stride)

{

    avc_luma_hv_qrt_4w_msa(src - 2,

                           src - (stride * 2) +

                           sizeof(uint8_t), stride, dst, stride, 4);

}


yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,

                       const uint16_t *ubuf0, const uint16_t *ubuf1,

                       const uint16_t *vbuf0, const uint16_t *vbuf1,

                       const uint16_t *abuf0, uint8_t *dest, int dstW,

                       int uvalpha, enum PixelFormat dstFormat,

                       int flags, int y, enum PixelFormat target)

{

    int i;

    if (uvalpha < 2048) {

        for (i = 0; i < (dstW >> 1); i++) {

            int Y1 = buf0[i * 2]     >> 7;

            int Y2 = buf0[i * 2 + 1] >> 7;

            int U  = ubuf1[i]        >> 7;

            int V  = vbuf1[i]        >> 7;

            const uint8_t *r = (const uint8_t *) c->table_rV[V],

                          *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),

                          *b = (const uint8_t *) c->table_bU[U];

            dest[ 0] = dest[ 1] = r_b[Y1];

            dest[ 2] = dest[ 3] =   g[Y1];

            dest[ 4] = dest[ 5] = b_r[Y1];

            dest[ 6] = dest[ 7] = r_b[Y2];

            dest[ 8] = dest[ 9] =   g[Y2];

            dest[10] = dest[11] = b_r[Y2];

            dest += 12;

        }

    } else {

        for (i = 0; i < (dstW >> 1); i++) {

            int Y1 =  buf0[i * 2]          >> 7;

            int Y2 =  buf0[i * 2 + 1]      >> 7;

            int U  = (ubuf0[i] + ubuf1[i]) >> 8;

            int V  = (vbuf0[i] + vbuf1[i]) >> 8;

            const uint8_t *r = (const uint8_t *) c->table_rV[V],

                          *g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),

                          *b = (const uint8_t *) c->table_bU[U];

            dest[ 0] = dest[ 1] = r_b[Y1];

            dest[ 2] = dest[ 3] =   g[Y1];

            dest[ 4] = dest[ 5] = b_r[Y1];

            dest[ 6] = dest[ 7] = r_b[Y2];

            dest[ 8] = dest[ 9] =   g[Y2];

            dest[10] = dest[11] = b_r[Y2];

            dest += 12;

        }

    }

}


int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan)

{

    TAPState *s;

    int fd, vnet_hdr = 0;

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

        if (qemu_opt_get(opts, "ifname") ||

            qemu_opt_get(opts, "script") ||

            qemu_opt_get(opts, "downscript") ||

            qemu_opt_get(opts, "vnet_hdr")) {

            error_report("ifname=, script=, downscript= and vnet_hdr= is invalid with fd=");

            return -1;

        }

        fd = net_handle_fd_param(mon, qemu_opt_get(opts, "fd"));

        if (fd == -1) {

            return -1;

        }

        fcntl(fd, F_SETFL, O_NONBLOCK);

        vnet_hdr = tap_probe_vnet_hdr(fd);

    } else {

        if (!qemu_opt_get(opts, "script")) {

            qemu_opt_set(opts, "script", DEFAULT_NETWORK_SCRIPT);

        }

        if (!qemu_opt_get(opts, "downscript")) {

            qemu_opt_set(opts, "downscript", DEFAULT_NETWORK_DOWN_SCRIPT);

        }

        fd = net_tap_init(opts, &vnet_hdr);

        if (fd == -1) {

            return -1;

        }

    }

    s = net_tap_fd_init(vlan, "tap", name, fd, vnet_hdr);

    if (!s) {

        close(fd);

        return -1;

    }

    if (tap_set_sndbuf(s->fd, opts) < 0) {

        return -1;

    }

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

        snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd);

    } else {

        const char *ifname, *script, *downscript;

        ifname     = qemu_opt_get(opts, "ifname");

        script     = qemu_opt_get(opts, "script");

        downscript = qemu_opt_get(opts, "downscript");

        snprintf(s->nc.info_str, sizeof(s->nc.info_str),

                 "ifname=%s,script=%s,downscript=%s",

                 ifname, script, downscript);

        if (strcmp(downscript, "no") != 0) {

            snprintf(s->down_script, sizeof(s->down_script), "%s", downscript);

            snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname);

        }

    }

    if (qemu_opt_get_bool(opts, "vhost", !!qemu_opt_get(opts, "vhostfd") ||

                          qemu_opt_get_bool(opts, "vhostforce", false))) {

        int vhostfd, r;

        bool force = qemu_opt_get_bool(opts, "vhostforce", false);

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

            r = net_handle_fd_param(mon, qemu_opt_get(opts, "vhostfd"));

            if (r == -1) {

                return -1;

            }

            vhostfd = r;

        } else {

            vhostfd = -1;

        }

        s->vhost_net = vhost_net_init(&s->nc, vhostfd, force);

        if (!s->vhost_net) {

            error_report("vhost-net requested but could not be initialized");

            return -1;

        }

    } else if (qemu_opt_get(opts, "vhostfd")) {

        error_report("vhostfd= is not valid without vhost");

        return -1;

    }

    return 0;

}


static int get_uint64_equal(QEMUFile *f, void *pv, size_t size)

{

    uint64_t *v = pv;

    uint64_t v2;

    qemu_get_be64s(f, &v2);

    if (*v == v2) {

        return 0;

    }

    return -EINVAL;

}


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

{

    trace_spapr_drc_detach(spapr_drc_index(drc));

    if (drc->isolation_state != SPAPR_DR_ISOLATION_STATE_ISOLATED) {

        trace_spapr_drc_awaiting_isolated(spapr_drc_index(drc));

        drc->awaiting_release = true;

        return;

    }

    if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI &&

        drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE) {

        trace_spapr_drc_awaiting_unusable(spapr_drc_index(drc));

        drc->awaiting_release = true;

        return;

    }

    if (drc->awaiting_allocation) {

        drc->awaiting_release = true;

        trace_spapr_drc_awaiting_allocation(spapr_drc_index(drc));

        return;

    }

    spapr_drc_release(drc);

}


static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,

                                   struct vhost_log *log)

{

    int fds[VHOST_MEMORY_MAX_NREGIONS];

    size_t fd_num = 0;

    bool shmfd = virtio_has_feature(dev->protocol_features,

                                    VHOST_USER_PROTOCOL_F_LOG_SHMFD);

    VhostUserMsg msg = {

        .request = VHOST_USER_SET_LOG_BASE,

        .flags = VHOST_USER_VERSION,

        .u64 = base,

        .size = sizeof(m.u64),

    };

    if (shmfd && log->fd != -1) {

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

    }

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

    if (shmfd) {

        msg.size = 0;

        if (vhost_user_read(dev, &msg) < 0) {

            return 0;

        }

        if (msg.request != VHOST_USER_SET_LOG_BASE) {

            error_report("Received unexpected msg type. "

                         "Expected %d received %d",

                         VHOST_USER_SET_LOG_BASE, msg.request);

            return -1;

        }

    }

    return 0;

}


static void *vmstate_base_addr(void *opaque, VMStateField *field, bool alloc)

{

    void *base_addr = opaque + field->offset;

    if (field->flags & VMS_POINTER) {

        if (alloc && (field->flags & VMS_ALLOC)) {

            gsize size = 0;

            if (field->flags & VMS_VBUFFER) {

                size = vmstate_size(opaque, field);

            } else {

                int n_elems = vmstate_n_elems(opaque, field);

                if (n_elems) {

                    size = n_elems * field->size;

                }

            }

            if (size) {

                *((void **)base_addr + field->start) = g_malloc(size);

            }

        }

        base_addr = *(void **)base_addr + field->start;

    }

    return base_addr;

}


static void add_pixels_clamped_c(const int16_t *block, uint8_t *av_restrict pixels,

                                 ptrdiff_t line_size)

{

    int i;

    /* read the pixels */

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

        pixels[0] = av_clip_uint8(pixels[0] + block[0]);

        pixels[1] = av_clip_uint8(pixels[1] + block[1]);

        pixels[2] = av_clip_uint8(pixels[2] + block[2]);

        pixels[3] = av_clip_uint8(pixels[3] + block[3]);

        pixels[4] = av_clip_uint8(pixels[4] + block[4]);

        pixels[5] = av_clip_uint8(pixels[5] + block[5]);

        pixels[6] = av_clip_uint8(pixels[6] + block[6]);

        pixels[7] = av_clip_uint8(pixels[7] + block[7]);

        pixels   += line_size;

        block    += 8;

    }

}


const char *avio_enum_protocols(void **opaque, int output)

{

    URLProtocol *p;

    *opaque = ffurl_protocol_next(*opaque);

    if (!(p = *opaque))

        return NULL;

    if ((output && p->url_write) || (!output && p->url_read))

        return p->name;

    return avio_enum_protocols(opaque, output);

}


static int read_highpass(AVCodecContext *avctx, uint8_t *ptr, int plane, AVFrame *frame)
{
    PixletContext *ctx = avctx->priv_data;
    ptrdiff_t stride = frame->linesize[plane] / 2;
    int i, ret;
    for (i = 0; i < ctx->levels * 3; i++) {
        int32_t a = bytestream2_get_be32(&ctx->gb);
        int32_t b = bytestream2_get_be32(&ctx->gb);
        int32_t c = bytestream2_get_be32(&ctx->gb);
        int32_t d = bytestream2_get_be32(&ctx->gb);
        int16_t *dest = (int16_t *)frame->data[plane] + ctx->band[plane][i + 1].x +
                                               stride * ctx->band[plane][i + 1].y;
        unsigned size = ctx->band[plane][i + 1].size;
        uint32_t magic;
        magic = bytestream2_get_be32(&ctx->gb);
        if (magic != 0xDEADBEEF) {
            av_log(avctx, AV_LOG_ERROR, "wrong magic number: 0x%08"PRIX32
                   " for plane %d, band %d\n", magic, plane, i);
        }
        ret = read_high_coeffs(avctx, ptr + bytestream2_tell(&ctx->gb), dest, size,
                               c, (b >= FFABS(a)) ? b : a, d,
                               ctx->band[plane][i + 1].width, stride);
        if (ret < 0) {
            av_log(avctx, AV_LOG_ERROR, "error in highpass coefficients for plane %d, band %d\n", plane, i);
            return ret;
        }
        bytestream2_skip(&ctx->gb, ret);
    }
    return 0;
}


static int vp9_superframe_split_filter(AVBSFContext *ctx, AVPacket *out)

{

    VP9SFSplitContext *s = ctx->priv_data;

    AVPacket *in;

    int i, j, ret, marker;

    int is_superframe = !!s->buffer_pkt;

    if (!s->buffer_pkt) {

        ret = ff_bsf_get_packet(ctx, &s->buffer_pkt);

        if (ret < 0)

            return ret;

        in = s->buffer_pkt;

        marker = in->data[in->size - 1];

        if ((marker & 0xe0) == 0xc0) {

            int length_size = 1 + ((marker >> 3) & 0x3);

            int   nb_frames = 1 + (marker & 0x7);

            int    idx_size = 2 + nb_frames * length_size;

            if (in->size >= idx_size && in->data[in->size - idx_size] == marker) {

                GetByteContext bc;

                int total_size = 0;

                bytestream2_init(&bc, in->data + in->size + 1 - idx_size,

                                 nb_frames * length_size);

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

                    int frame_size = 0;

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

                        frame_size |= bytestream2_get_byte(&bc) << (j * 8);

                    total_size += frame_size;

                    if (total_size > in->size - idx_size) {

                        av_log(ctx, AV_LOG_ERROR,

                               "Invalid frame size in a superframe: %d\n", frame_size);

                        ret = AVERROR(EINVAL);

                        goto fail;

                    }

                    s->sizes[i] = frame_size;

                }

                s->nb_frames         = nb_frames;

                s->next_frame        = 0;

                s->next_frame_offset = 0;

                is_superframe        = 1;

            }

        }

    }

    if (is_superframe) {

        GetBitContext gb;

        int profile, invisible = 0;

        ret = av_packet_ref(out, s->buffer_pkt);

        if (ret < 0)

            goto fail;

        out->data += s->next_frame_offset;

        out->size  = s->sizes[s->next_frame];

        s->next_frame_offset += out->size;

        s->next_frame++;

        if (s->next_frame >= s->nb_frames)

            av_packet_free(&s->buffer_pkt);

        ret = init_get_bits8(&gb, out->data, out->size);

        if (ret < 0)

            goto fail;

        get_bits(&gb, 2); // frame_marker

        profile  = get_bits1(&gb);

        profile |= get_bits1(&gb) << 1;

        if (profile == 3)

            get_bits1(&gb);

        if (!get_bits1(&gb)) {

            get_bits1(&gb);

            invisible = !get_bits1(&gb);

        }

        if (invisible)

            out->pts = AV_NOPTS_VALUE;

    } else {

        av_packet_move_ref(out, s->buffer_pkt);

        av_packet_free(&s->buffer_pkt);

    }

    return 0;

fail:

    av_packet_free(&s->buffer_pkt);

    return ret;

}


static int coroutine_fn v9fs_complete_renameat(V9fsPDU *pdu, int32_t olddirfid,

                                               V9fsString *old_name,

                                               int32_t newdirfid,

                                               V9fsString *new_name)

{

    int err = 0;

    V9fsState *s = pdu->s;

    V9fsFidState *newdirfidp = NULL, *olddirfidp = NULL;

    olddirfidp = get_fid(pdu, olddirfid);

    if (olddirfidp == NULL) {

        err = -ENOENT;

        goto out;

    }

    if (newdirfid != -1) {

        newdirfidp = get_fid(pdu, newdirfid);

        if (newdirfidp == NULL) {

            err = -ENOENT;

            goto out;

        }

    } else {

        newdirfidp = get_fid(pdu, olddirfid);

    }

    err = v9fs_co_renameat(pdu, &olddirfidp->path, old_name,

                           &newdirfidp->path, new_name);

    if (err < 0) {

        goto out;

    }

    if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) {

        /* Only for path based fid  we need to do the below fixup */

        v9fs_fix_fid_paths(pdu, &olddirfidp->path, old_name,

                           &newdirfidp->path, new_name);

    }

out:

    if (olddirfidp) {

        put_fid(pdu, olddirfidp);

    }

    if (newdirfidp) {

        put_fid(pdu, newdirfidp);

    }

    return err;

}


static int decode_bytes(const uint8_t *input, uint8_t *out, int bytes)

{

    int i, off;

    uint32_t c;

    const uint32_t *buf;

    uint32_t *output = (uint32_t *)out;

    off = (intptr_t)input & 3;

    buf = (const uint32_t *)(input - off);

    c   = av_be2ne32((0x537F6103 >> (off * 8)) | (0x537F6103 << (32 - (off * 8))));

    bytes += 3 + off;

    for (i = 0; i < bytes / 4; i++)

        output[i] = c ^ buf[i];

    if (off)

        avpriv_request_sample(NULL, "Offset of %d", off);

    return off;

}


static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){

    SnowContext *s = avctx->priv_data;

    CABACContext * const c= &s->c;

    AVFrame *pict = data;

    const int width= s->avctx->width;

    const int height= s->avctx->height;

    int used_count= 0;

    int log2_threshold, level, orientation, plane_index, i;

    ff_init_cabac_encoder(c, buf, buf_size);

    ff_init_cabac_states(c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64);

    s->input_picture = *pict;

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

    s->keyframe=avctx->gop_size==0 || avctx->frame_number % avctx->gop_size == 0;

    pict->pict_type= s->keyframe ? FF_I_TYPE : FF_P_TYPE;

    if(pict->quality){

        s->qlog= rint(QROOT*log(pict->quality / (float)FF_QP2LAMBDA)/log(2));

        //<64 >60

        s->qlog += 61;

    }else{

        s->qlog= LOSSLESS_QLOG;

    }

    for(i=0; i<s->mb_band.stride * s->mb_band.height; i++){

        s->mb_band.buf[i]= s->keyframe;

    }

    frame_start(s);

    if(pict->pict_type == P_TYPE){

        int block_width = (width +15)>>4;

        int block_height= (height+15)>>4;

        int stride= s->current_picture.linesize[0];

        uint8_t *src_plane= s->input_picture.data[0];

        int src_stride= s->input_picture.linesize[0];

        int x,y;

        assert(s->current_picture.data[0]);

        assert(s->last_picture.data[0]);

        s->m.avctx= s->avctx;

        s->m.current_picture.data[0]= s->current_picture.data[0];

        s->m.   last_picture.data[0]= s->   last_picture.data[0];

        s->m.    new_picture.data[0]= s->  input_picture.data[0];

        s->m.current_picture_ptr= &s->m.current_picture;

        s->m.   last_picture_ptr= &s->m.   last_picture;

        s->m.linesize=

        s->m.   last_picture.linesize[0]=

        s->m.    new_picture.linesize[0]=

        s->m.current_picture.linesize[0]= stride;

        s->m.width = width;

        s->m.height= height;

        s->m.mb_width = block_width;

        s->m.mb_height= block_height;

        s->m.mb_stride=   s->m.mb_width+1;

        s->m.b8_stride= 2*s->m.mb_width+1;

        s->m.f_code=1;

        s->m.pict_type= pict->pict_type;

        s->m.me_method= s->avctx->me_method;

        s->m.me.scene_change_score=0;

        s->m.flags= s->avctx->flags;

        s->m.quarter_sample= (s->avctx->flags & CODEC_FLAG_QPEL)!=0;

        s->m.out_format= FMT_H263;

        s->m.unrestricted_mv= 1;

        s->m.lambda= pict->quality * 3/2; //FIXME bug somewhere else

        s->m.qscale= (s->m.lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);

        s->m.lambda2= (s->m.lambda*s->m.lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;

        if(!s->motion_val8){

            s->motion_val8 = av_mallocz(s->m.b8_stride*block_height*2*2*sizeof(int16_t));

            s->motion_val16= av_mallocz(s->m.mb_stride*block_height*2*sizeof(int16_t));

        }

        s->m.mb_type= s->mb_type;

        //dummies, to avoid segfaults

        s->m.current_picture.mb_mean  = s->mb_mean;

        s->m.current_picture.mb_var   = (int16_t*)s->dummy;

        s->m.current_picture.mc_mb_var= (int16_t*)s->dummy;

        s->m.current_picture.mb_type  = s->dummy;

        s->m.current_picture.motion_val[0]= s->motion_val8;

        s->m.p_mv_table= s->motion_val16;

        s->m.dsp= s->dsp; //move

        ff_init_me(&s->m);

        s->m.me.pre_pass=1;

        s->m.me.dia_size= s->avctx->pre_dia_size;

        s->m.first_slice_line=1;

        for(y= block_height-1; y >= 0; y--) {

            uint8_t src[stride*16];

            s->m.new_picture.data[0]= src - y*16*stride; //ugly

            s->m.mb_y= y;

            for(i=0; i<16 && i + 16*y<height; i++){

                memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);

                for(x=width; x<16*block_width; x++)

                    src[i*stride+x]= src[i*stride+x-1];

            }

            for(; i<16 && i + 16*y<16*block_height; i++)

                memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);

            for(x=block_width-1; x >=0 ;x--) {

                s->m.mb_x= x;

                ff_init_block_index(&s->m);

                ff_update_block_index(&s->m);

                ff_pre_estimate_p_frame_motion(&s->m, x, y);

            }

            s->m.first_slice_line=0;

        }

        s->m.me.pre_pass=0;

        s->m.me.dia_size= s->avctx->dia_size;

        s->m.first_slice_line=1;

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

            uint8_t src[stride*16];

            s->m.new_picture.data[0]= src - y*16*stride; //ugly

            s->m.mb_y= y;

            assert(width <= stride);

            assert(width <= 16*block_width);

            for(i=0; i<16 && i + 16*y<height; i++){

                memcpy(&src[i*stride], &src_plane[(i+16*y)*src_stride], width);

                for(x=width; x<16*block_width; x++)

                    src[i*stride+x]= src[i*stride+x-1];

            }

            for(; i<16 && i + 16*y<16*block_height; i++)

                memcpy(&src[i*stride], &src[(i-1)*stride], 16*block_width);

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

                int mb_xy= x + y*(s->mb_band.stride);

                s->m.mb_x= x;

                ff_init_block_index(&s->m);

                ff_update_block_index(&s->m);

                ff_estimate_p_frame_motion(&s->m, x, y);

                s->mb_band   .buf[mb_xy]= (s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER)

                 ? 0 : 2;

                s->mv_band[0].buf[mb_xy]= s->motion_val16[x + y*s->m.mb_stride][0];

                s->mv_band[1].buf[mb_xy]= s->motion_val16[x + y*s->m.mb_stride][1];

                if(s->mb_band   .buf[x + y*(s->mb_band.stride)]==2 && 0){

                    int dc0=128, dc1=128, dc, dc2, dir;

                    int offset= (s->avctx->flags & CODEC_FLAG_QPEL) ? 64 : 32;

                    dc       =s->mb_mean[x +  y   *s->m.mb_stride    ];

                    if(x) dc0=s->mb_mean[x +  y   *s->m.mb_stride - 1];

                    if(y) dc1=s->mb_mean[x + (y-1)*s->m.mb_stride    ];

                    dc2= (dc0+dc1)>>1;

#if 0

                    if     (ABS(dc0 - dc) < ABS(dc1 - dc) && ABS(dc0 - dc) < ABS(dc2 - dc))

                        dir= 1;

                    else if(ABS(dc0 - dc) >=ABS(dc1 - dc) && ABS(dc1 - dc) < ABS(dc2 - dc))

                        dir=-1;

                    else

                        dir=0;

#endif

                    if(ABS(dc0 - dc) < ABS(dc1 - dc) && x){

                        s->mv_band[0].buf[mb_xy]= s->mv_band[0].buf[x + y*(s->mb_band.stride)-1] - offset;

                        s->mv_band[1].buf[mb_xy]= s->mv_band[1].buf[x + y*(s->mb_band.stride)-1];

                        s->mb_mean[x +  y   *s->m.mb_stride    ]= dc0;

                    }else if(y){

                        s->mv_band[0].buf[mb_xy]= s->mv_band[0].buf[x + (y-1)*(s->mb_band.stride)];

                        s->mv_band[1].buf[mb_xy]= s->mv_band[1].buf[x + (y-1)*(s->mb_band.stride)] - offset;

                        s->mb_mean[x +  y   *s->m.mb_stride    ]= dc1;

                    }

                }

//                s->mb_band   .buf[x + y*(s->mb_band.stride)]=1; //FIXME intra only test

            }

            s->m.first_slice_line=0;

        }

        assert(s->m.pict_type == P_TYPE);

        if(s->m.me.scene_change_score > s->avctx->scenechange_threshold){

            s->m.pict_type=

            pict->pict_type =I_TYPE;

            for(i=0; i<s->mb_band.stride * s->mb_band.height; i++){

                s->mb_band.buf[i]= 1;

                s->mv_band[0].buf[i]=

                s->mv_band[1].buf[i]= 0;

            }

    //printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);

        }

    }

    s->m.first_slice_line=1;

    s->qbias= pict->pict_type == P_TYPE ? 2 : 0;

    encode_header(s);

    decorrelate(s, &s->mb_band   , s->mb_band   .buf, s->mb_band   .stride, 0, 1);

    decorrelate(s, &s->mv_band[0], s->mv_band[0].buf, s->mv_band[0].stride, 0, 1);

    decorrelate(s, &s->mv_band[1], s->mv_band[1].buf, s->mv_band[1].stride, 0 ,1);

    encode_subband(s, &s->mb_band   , s->mb_band   .buf, NULL, s->mb_band   .stride, 0);

    encode_subband(s, &s->mv_band[0], s->mv_band[0].buf, NULL, s->mv_band[0].stride, 0);

    encode_subband(s, &s->mv_band[1], s->mv_band[1].buf, NULL, s->mv_band[1].stride, 0);

//FIXME avoid this

    correlate(s, &s->mb_band   , s->mb_band   .buf, s->mb_band   .stride, 1, 1);

    correlate(s, &s->mv_band[0], s->mv_band[0].buf, s->mv_band[0].stride, 1, 1);

    correlate(s, &s->mv_band[1], s->mv_band[1].buf, s->mv_band[1].stride, 1, 1);

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

        Plane *p= &s->plane[plane_index];

        int w= p->width;

        int h= p->height;

        int x, y;

        int bits= put_bits_count(&s->c.pb);

        //FIXME optimize

     if(pict->data[plane_index]) //FIXME gray hack

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

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

                s->spatial_dwt_buffer[y*w + x]= pict->data[plane_index][y*pict->linesize[plane_index] + x]<<8;

            }

        }

        predict_plane(s, s->spatial_dwt_buffer, plane_index, 0);

        if(s->qlog == LOSSLESS_QLOG){

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

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

                    s->spatial_dwt_buffer[y*w + x]= (s->spatial_dwt_buffer[y*w + x] + 127)>>8;

                }

            }

        }

        ff_spatial_dwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);

        for(level=0; level<s->spatial_decomposition_count; level++){

            for(orientation=level ? 1 : 0; orientation<4; orientation++){

                SubBand *b= &p->band[level][orientation];

                quantize(s, b, b->buf, b->stride, s->qbias);

                if(orientation==0)

                    decorrelate(s, b, b->buf, b->stride, pict->pict_type == P_TYPE, 0);

                encode_subband(s, b, b->buf, b->parent ? b->parent->buf : NULL, b->stride, orientation);

                assert(b->parent==NULL || b->parent->stride == b->stride*2);

                if(orientation==0)

                    correlate(s, b, b->buf, b->stride, 1, 0);

            }

        }

//        av_log(NULL, AV_LOG_DEBUG, "plane:%d bits:%d\n", plane_index, put_bits_count(&s->c.pb) - bits);

        for(level=0; level<s->spatial_decomposition_count; level++){

            for(orientation=level ? 1 : 0; orientation<4; orientation++){

                SubBand *b= &p->band[level][orientation];

                dequantize(s, b, b->buf, b->stride);

            }

        }

        ff_spatial_idwt(s->spatial_dwt_buffer, w, h, w, s->spatial_decomposition_type, s->spatial_decomposition_count);

        if(s->qlog == LOSSLESS_QLOG){

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

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

                    s->spatial_dwt_buffer[y*w + x]<<=8;

                }

            }

        }

        predict_plane(s, s->spatial_dwt_buffer, plane_index, 1);

        //FIXME optimize

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

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

                int v= (s->spatial_dwt_buffer[y*w + x]+128)>>8;

                if(v&(~255)) v= ~(v>>31);

                s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x]= v;

            }

        }

        if(s->avctx->flags&CODEC_FLAG_PSNR){

            int64_t error= 0;

    if(pict->data[plane_index]) //FIXME gray hack

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

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

                    int d= s->current_picture.data[plane_index][y*s->current_picture.linesize[plane_index] + x] - pict->data[plane_index][y*pict->linesize[plane_index] + x];

                    error += d*d;

                }

            }

            s->avctx->error[plane_index] += error;

            s->avctx->error[3] += error;

        }

    }

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

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

    emms_c();

    return put_cabac_terminate(c, 1);

}


static void rtas_ibm_set_eeh_option(PowerPCCPU *cpu,

                                    sPAPREnvironment *spapr,

                                    uint32_t token, uint32_t nargs,

                                    target_ulong args, uint32_t nret,

                                    target_ulong rets)

{

    sPAPRPHBState *sphb;

    sPAPRPHBClass *spc;

    uint32_t addr, option;

    uint64_t buid;

    int ret;

    if ((nargs != 4) || (nret != 1)) {

        goto param_error_exit;

    }

    buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2);

    addr = rtas_ld(args, 0);

    option = rtas_ld(args, 3);

    sphb = find_phb(spapr, buid);

    if (!sphb) {

        goto param_error_exit;

    }

    spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb);

    if (!spc->eeh_set_option) {

        goto param_error_exit;

    }

    ret = spc->eeh_set_option(sphb, addr, option);

    rtas_st(rets, 0, ret);

    return;

param_error_exit:

    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);

}


static bool nvic_user_access_ok(NVICState *s, hwaddr offset)

{

    /* Return true if unprivileged access to this register is permitted. */

    switch (offset) {

    case 0xf00: /* STIR: accessible only if CCR.USERSETMPEND permits */

        return s->cpu->env.v7m.ccr & R_V7M_CCR_USERSETMPEND_MASK;

    default:

        /* All other user accesses cause a BusFault unconditionally */

        return false;

    }

}


static void kvm_arm_gic_realize(DeviceState *dev, Error **errp)
{
    int i;
    GICState *s = KVM_ARM_GIC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
    KVMARMGICClass *kgc = KVM_ARM_GIC_GET_CLASS(s);
    Error *local_err = NULL;
    int ret;
    kgc->parent_realize(dev, &local_err);
    if (local_err) {
        error_propagate(errp, local_err);
    i = s->num_irq - GIC_INTERNAL;
    /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU.
     * GPIO array layout is thus:
     *  [0..N-1] SPIs
     *  [N..N+31] PPIs for CPU 0
     *  [N+32..N+63] PPIs for CPU 1
     *   ...
     */
    i += (GIC_INTERNAL * s->num_cpu);
    qdev_init_gpio_in(dev, kvm_arm_gic_set_irq, i);
    /* We never use our outbound IRQ/FIQ lines but provide them so that
     * we maintain the same interface as the non-KVM GIC.
     */
    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_irq[i]);
    for (i = 0; i < s->num_cpu; i++) {
        sysbus_init_irq(sbd, &s->parent_fiq[i]);
    /* Try to create the device via the device control API */
    s->dev_fd = -1;
    ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V2, false);
    if (ret >= 0) {
        s->dev_fd = ret;
    } else if (ret != -ENODEV && ret != -ENOTSUP) {
        error_setg_errno(errp, -ret, "error creating in-kernel VGIC");
    if (kvm_gic_supports_attr(s, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0)) {
        uint32_t numirqs = s->num_irq;
        kvm_gic_access(s, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, 0, &numirqs, 1);
    /* Tell the kernel to complete VGIC initialization now */
    if (kvm_gic_supports_attr(s, KVM_DEV_ARM_VGIC_GRP_CTRL,
                              KVM_DEV_ARM_VGIC_CTRL_INIT)) {
        kvm_gic_access(s, KVM_DEV_ARM_VGIC_GRP_CTRL,
                          KVM_DEV_ARM_VGIC_CTRL_INIT, 0, 0, 1);
    /* Distributor */
    memory_region_init_reservation(&s->iomem, OBJECT(s),
                                   "kvm-gic_dist", 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);
    kvm_arm_register_device(&s->iomem,
                            (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
                            | KVM_VGIC_V2_ADDR_TYPE_DIST,
                            KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_V2_ADDR_TYPE_DIST,
                            s->dev_fd);
    /* CPU interface for current core. Unlike arm_gic, we don't
     * provide the "interface for core #N" memory regions, because
     * cores with a VGIC don't have those.
     */
    memory_region_init_reservation(&s->cpuiomem[0], OBJECT(s),
                                   "kvm-gic_cpu", 0x1000);
    sysbus_init_mmio(sbd, &s->cpuiomem[0]);
    kvm_arm_register_device(&s->cpuiomem[0],
                            (KVM_ARM_DEVICE_VGIC_V2 << KVM_ARM_DEVICE_ID_SHIFT)
                            | KVM_VGIC_V2_ADDR_TYPE_CPU,
                            KVM_DEV_ARM_VGIC_GRP_ADDR,
                            KVM_VGIC_V2_ADDR_TYPE_CPU,
                            s->dev_fd);


void inter_predict(VP8Context *s, uint8_t *dst[3], VP8Macroblock *mb,

                   int mb_x, int mb_y)

{

    int x_off = mb_x << 4, y_off = mb_y << 4;

    int width = 16*s->mb_width, height = 16*s->mb_height;

    AVFrame *ref = s->framep[mb->ref_frame];

    VP56mv *bmv = mb->bmv;

    switch (mb->partitioning) {

    case VP8_SPLITMVMODE_NONE:

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 0, 16, 16, width, height, &mb->mv);

        break;

    case VP8_SPLITMVMODE_4x4: {

        int x, y;

        VP56mv uvmv;

        /* Y */

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

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

                vp8_mc(s, 1, dst[0] + 4*y*s->linesize + x*4,

                       ref->data[0], &bmv[4*y + x],

                       4*x + x_off, 4*y + y_off, 4, 4,

                       width, height, s->linesize,

                       s->put_pixels_tab[2]);

            }

        }

        /* U/V */

        x_off >>= 1; y_off >>= 1; width >>= 1; height >>= 1;

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

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

                uvmv.x = mb->bmv[ 2*y    * 4 + 2*x  ].x +

                         mb->bmv[ 2*y    * 4 + 2*x+1].x +

                         mb->bmv[(2*y+1) * 4 + 2*x  ].x +

                         mb->bmv[(2*y+1) * 4 + 2*x+1].x;

                uvmv.y = mb->bmv[ 2*y    * 4 + 2*x  ].y +

                         mb->bmv[ 2*y    * 4 + 2*x+1].y +

                         mb->bmv[(2*y+1) * 4 + 2*x  ].y +

                         mb->bmv[(2*y+1) * 4 + 2*x+1].y;

                uvmv.x = (uvmv.x + 2 + (uvmv.x >> (INT_BIT-1))) >> 2;

                uvmv.y = (uvmv.y + 2 + (uvmv.y >> (INT_BIT-1))) >> 2;

                if (s->profile == 3) {

                    uvmv.x &= ~7;

                    uvmv.y &= ~7;

                }

                vp8_mc(s, 0, dst[1] + 4*y*s->uvlinesize + x*4,

                       ref->data[1], &uvmv,

                       4*x + x_off, 4*y + y_off, 4, 4,

                       width, height, s->uvlinesize,

                       s->put_pixels_tab[2]);

                vp8_mc(s, 0, dst[2] + 4*y*s->uvlinesize + x*4,

                       ref->data[2], &uvmv,

                       4*x + x_off, 4*y + y_off, 4, 4,

                       width, height, s->uvlinesize,

                       s->put_pixels_tab[2]);

            }

        }

        break;

    }

    case VP8_SPLITMVMODE_16x8:

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 0, 16, 8, width, height, &bmv[0]);

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 8, 16, 8, width, height, &bmv[1]);

        break;

    case VP8_SPLITMVMODE_8x16:

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 0, 8, 16, width, height, &bmv[0]);

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    8, 0, 8, 16, width, height, &bmv[1]);

        break;

    case VP8_SPLITMVMODE_8x8:

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 0, 8, 8, width, height, &bmv[0]);

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    8, 0, 8, 8, width, height, &bmv[1]);

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    0, 8, 8, 8, width, height, &bmv[2]);

        vp8_mc_part(s, dst, ref, x_off, y_off,

                    8, 8, 8, 8, width, height, &bmv[3]);

        break;

    }

}


static int64_t cpu_get_icount_locked(void)

{

    int64_t icount;

    CPUState *cpu = current_cpu;

    icount = timers_state.qemu_icount;

    if (cpu) {

        if (!cpu_can_do_io(cpu)) {

            fprintf(stderr, "Bad clock read\n");

        }

        icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);

    }

    return timers_state.qemu_icount_bias + cpu_icount_to_ns(icount);

}


static void sigp_start(CPUState *cs, run_on_cpu_data arg)

{

    S390CPU *cpu = S390_CPU(cs);

    SigpInfo *si = arg.host_ptr;

    if (s390_cpu_get_state(cpu) != CPU_STATE_STOPPED) {

        si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;

        return;

    }

    s390_cpu_set_state(CPU_STATE_OPERATING, cpu);

    si->cc = SIGP_CC_ORDER_CODE_ACCEPTED;

}


static void pchip_write(void *opaque, hwaddr addr,

                        uint64_t v32, unsigned size)

{

    TyphoonState *s = opaque;

    uint64_t val, oldval;

    if (addr & 4) {

        val = v32 << 32 | s->latch_tmp;

        addr ^= 4;

    } else {

        s->latch_tmp = v32;

        return;

    }

    switch (addr) {

    case 0x0000:

        /* WSBA0: Window Space Base Address Register.  */

        s->pchip.win[0].base_addr = val;

        break;

    case 0x0040:

        /* WSBA1 */

        s->pchip.win[1].base_addr = val;

        break;

    case 0x0080:

        /* WSBA2 */

        s->pchip.win[2].base_addr = val;

        break;

    case 0x00c0:

        /* WSBA3 */

        s->pchip.win[3].base_addr = val;

        break;

    case 0x0100:

        /* WSM0: Window Space Mask Register.  */

        s->pchip.win[0].mask = val;

        break;

    case 0x0140:

        /* WSM1 */

        s->pchip.win[1].mask = val;

        break;

    case 0x0180:

        /* WSM2 */

        s->pchip.win[2].mask = val;

        break;

    case 0x01c0:

        /* WSM3 */

        s->pchip.win[3].mask = val;

        break;

    case 0x0200:

        /* TBA0: Translated Base Address Register.  */

        s->pchip.win[0].translated_base_pfn = val >> 10;

        break;

    case 0x0240:

        /* TBA1 */

        s->pchip.win[1].translated_base_pfn = val >> 10;

        break;

    case 0x0280:

        /* TBA2 */

        s->pchip.win[2].translated_base_pfn = val >> 10;

        break;

    case 0x02c0:

        /* TBA3 */

        s->pchip.win[3].translated_base_pfn = val >> 10;

        break;

    case 0x0300:

        /* PCTL: Pchip Control Register.  */

        oldval = s->pchip.ctl;

        oldval &= ~0x00001cff0fc7ffull;       /* RW fields */

        oldval |= val & 0x00001cff0fc7ffull;

        s->pchip.ctl = oldval;

        break;

    case 0x0340:

        /* PLAT: Pchip Master Latency Register.  */

        break;

    case 0x03c0:

        /* PERROR: Pchip Error Register.  */

        break;

    case 0x0400:

        /* PERRMASK: Pchip Error Mask Register.  */

        break;

    case 0x0440:

        /* PERRSET: Pchip Error Set Register.  */

        break;

    case 0x0480:

        /* TLBIV: Translation Buffer Invalidate Virtual Register.  */

        break;

    case 0x04c0:

        /* TLBIA: Translation Buffer Invalidate All Register (WO).  */

        break;

    case 0x0500:

        /* PMONCTL */

    case 0x0540:

        /* PMONCNT */

    case 0x0800:

        /* SPRST */

        break;

    default:

        cpu_unassigned_access(current_cpu, addr, true, false, 0, size);

        return;

    }

}


static void vga_precise_update_retrace_info(VGAState *s)

{

    int htotal_chars;

    int hretr_start_char;

    int hretr_skew_chars;

    int hretr_end_char;

    int vtotal_lines;

    int vretr_start_line;

    int vretr_end_line;

    int div2, sldiv2, dots;

    int clocking_mode;

    int clock_sel;

    const int hz[] = {25175000, 28322000, 25175000, 25175000};

    int64_t chars_per_sec;

    struct vga_precise_retrace *r = &s->retrace_info.precise;

    htotal_chars = s->cr[0x00] + 5;

    hretr_start_char = s->cr[0x04];

    hretr_skew_chars = (s->cr[0x05] >> 5) & 3;

    hretr_end_char = s->cr[0x05] & 0x1f;

    vtotal_lines = (s->cr[0x06]

                    | (((s->cr[0x07] & 1) | ((s->cr[0x07] >> 4) & 2)) << 8)) + 2

        ;

    vretr_start_line = s->cr[0x10]

        | ((((s->cr[0x07] >> 2) & 1) | ((s->cr[0x07] >> 6) & 2)) << 8)

        ;

    vretr_end_line = s->cr[0x11] & 0xf;

    div2 = (s->cr[0x17] >> 2) & 1;

    sldiv2 = (s->cr[0x17] >> 3) & 1;

    clocking_mode = (s->sr[0x01] >> 3) & 1;

    clock_sel = (s->msr >> 2) & 3;

    dots = (s->msr & 1) ? 8 : 9;

    chars_per_sec = hz[clock_sel] / dots;

    htotal_chars <<= clocking_mode;

    r->total_chars = vtotal_lines * htotal_chars;

    if (r->freq) {

        r->ticks_per_char = ticks_per_sec / (r->total_chars * r->freq);

    } else {

        r->ticks_per_char = ticks_per_sec / chars_per_sec;

    }

    r->vstart = vretr_start_line;

    r->vend = r->vstart + vretr_end_line + 1;

    r->hstart = hretr_start_char + hretr_skew_chars;

    r->hend = r->hstart + hretr_end_char + 1;

    r->htotal = htotal_chars;

#if 0

    printf (

        "hz=%f\n"

        "htotal = %d\n"

        "hretr_start = %d\n"

        "hretr_skew = %d\n"

        "hretr_end = %d\n"

        "vtotal = %d\n"

        "vretr_start = %d\n"

        "vretr_end = %d\n"

        "div2 = %d sldiv2 = %d\n"

        "clocking_mode = %d\n"

        "clock_sel = %d %d\n"

        "dots = %d\n"

        "ticks/char = %lld\n"

        "\n",

        (double) ticks_per_sec / (r->ticks_per_char * r->total_chars),

        htotal_chars,

        hretr_start_char,

        hretr_skew_chars,

        hretr_end_char,

        vtotal_lines,

        vretr_start_line,

        vretr_end_line,

        div2, sldiv2,

        clocking_mode,

        clock_sel,

        hz[clock_sel],

        dots,

        r->ticks_per_char

        );

#endif

}


int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt,

                          const char *filename, void *logctx,

                          unsigned int offset, unsigned int max_probe_size)

{

    AVProbeData pd = { filename ? filename : "", NULL, -offset };

    uint8_t *buf = NULL;

    uint8_t *mime_type;

    int ret = 0, probe_size, buf_offset = 0;

    int score = 0;

    if (!max_probe_size) {

        max_probe_size = PROBE_BUF_MAX;

    } else if (max_probe_size > PROBE_BUF_MAX) {

        max_probe_size = PROBE_BUF_MAX;

    } else if (max_probe_size < PROBE_BUF_MIN) {

        av_log(logctx, AV_LOG_ERROR,

               "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN);

        return AVERROR(EINVAL);

    }

    if (offset >= max_probe_size) {

        return AVERROR(EINVAL);

    }

    if (!*fmt && pb->av_class && av_opt_get(pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type) >= 0 && mime_type) {

        if (!av_strcasecmp(mime_type, "audio/aacp")) {

            *fmt = av_find_input_format("aac");

        }

        av_freep(&mime_type);

    }

    for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt;

        probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) {

        if (probe_size < offset) {

            continue;

        }

        score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0;

        /* read probe data */

        if ((ret = av_reallocp(&buf, probe_size + AVPROBE_PADDING_SIZE)) < 0)

            return ret;

        if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {

            /* fail if error was not end of file, otherwise, lower score */

            if (ret != AVERROR_EOF) {

                av_free(buf);

                return ret;

            }

            score = 0;

            ret = 0;            /* error was end of file, nothing read */

        }

        buf_offset += ret;

        pd.buf_size = buf_offset - offset;

        pd.buf = &buf[offset];

        memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);

        /* guess file format */

        *fmt = av_probe_input_format2(&pd, 1, &score);

        if(*fmt){

            if(score <= AVPROBE_SCORE_RETRY){ //this can only be true in the last iteration

                av_log(logctx, AV_LOG_WARNING, "Format %s detected only with low score of %d, misdetection possible!\n", (*fmt)->name, score);

            }else

                av_log(logctx, AV_LOG_DEBUG, "Format %s probed with size=%d and score=%d\n", (*fmt)->name, probe_size, score);

#if 0

            FILE *f = fopen("probestat.tmp", "ab");

            fprintf(f, "probe_size:%d format:%s score:%d filename:%s\n", probe_size, (*fmt)->name, score, filename);

            fclose(f);

#endif

        }

    }

    if (!*fmt) {

        av_free(buf);

        return AVERROR_INVALIDDATA;

    }

    /* rewind. reuse probe buffer to avoid seeking */

    ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size);

    return ret < 0 ? ret : score;

}


static ssize_t drop_sync(QIOChannel *ioc, size_t size)

{

    ssize_t ret = 0;

    char small[1024];

    char *buffer;

    buffer = sizeof(small) < size ? small : g_malloc(MIN(65536, size));

    while (size > 0) {

        ssize_t count = read_sync(ioc, buffer, MIN(65536, size));

        if (count <= 0) {

            goto cleanup;

        }

        assert(count <= size);

        size -= count;

        ret += count;

    }

 cleanup:

    if (buffer != small) {

        g_free(buffer);

    }

    return ret;

}


void *qemu_get_virtqueue_element(VirtIODevice *vdev, QEMUFile *f, size_t sz)

{

    VirtQueueElement *elem;

    VirtQueueElementOld data;

    int i;

    qemu_get_buffer(f, (uint8_t *)&data, sizeof(VirtQueueElementOld));

    /* TODO: teach all callers that this can fail, and return failure instead

     * of asserting here.

     * When we do, we might be able to re-enable NDEBUG below.

     */

#ifdef NDEBUG

#error building with NDEBUG is not supported

#endif

    assert(ARRAY_SIZE(data.in_addr) >= data.in_num);

    assert(ARRAY_SIZE(data.out_addr) >= data.out_num);

    elem = virtqueue_alloc_element(sz, data.out_num, data.in_num);

    elem->index = data.index;

    for (i = 0; i < elem->in_num; i++) {

        elem->in_addr[i] = data.in_addr[i];

    }

    for (i = 0; i < elem->out_num; i++) {

        elem->out_addr[i] = data.out_addr[i];

    }

    for (i = 0; i < elem->in_num; i++) {

        /* Base is overwritten by virtqueue_map.  */

        elem->in_sg[i].iov_base = 0;

        elem->in_sg[i].iov_len = data.in_sg[i].iov_len;

    }

    for (i = 0; i < elem->out_num; i++) {

        /* Base is overwritten by virtqueue_map.  */

        elem->out_sg[i].iov_base = 0;

        elem->out_sg[i].iov_len = data.out_sg[i].iov_len;

    }

    virtqueue_map(vdev, elem);

    return elem;

}


static void mirror_read_complete(void *opaque, int ret)

{

    MirrorOp *op = opaque;

    MirrorBlockJob *s = op->s;

    if (ret < 0) {

        BlockDriverState *source = s->common.bs;

        BlockErrorAction action;

        bdrv_set_dirty(source, op->sector_num, op->nb_sectors);

        action = mirror_error_action(s, true, -ret);

        if (action == BLOCK_ERROR_ACTION_REPORT && s->ret >= 0) {

            s->ret = ret;

        }

        mirror_iteration_done(op, ret);

        return;

    }

    bdrv_aio_writev(s->target, op->sector_num, &op->qiov, op->nb_sectors,

                    mirror_write_complete, op);

}


static BlockDriverAIOCB *qcow_aio_writev(BlockDriverState *bs,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockDriverCompletionFunc *cb, void *opaque)

{

    BDRVQcowState *s = bs->opaque;

    QCowAIOCB *acb;

    s->cluster_cache_offset = -1; /* disable compressed cache */

    acb = qemu_aio_get(bs, cb, opaque);

    if (!acb)

        return NULL;

    acb->hd_aiocb = NULL;

    acb->sector_num = sector_num;

    acb->qiov = qiov;

    if (qiov->niov > 1) {

        acb->buf = acb->orig_buf = qemu_memalign(512, qiov->size);

        qemu_iovec_to_buffer(qiov, acb->buf);

    } else {

        acb->buf = (uint8_t *)qiov->iov->iov_base;

    }

    acb->nb_sectors = nb_sectors;

    acb->n = 0;

    qcow_aio_write_cb(acb, 0);

    return &acb->common;

}


static uint32_t vmsvga_bios_read(void *opaque, uint32_t address)

{

    printf("%s: what are we supposed to return?\n", __FUNCTION__);

    return 0xcafe;

}


static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track)

{

    int64_t pos = avio_tell(pb);

    avio_wb32(pb, 0);

    avio_wl32(pb, track->tag); // store it byteswapped

    track->enc->codec_tag = av_bswap16(track->tag >> 16);

    ff_put_wav_header(pb, track->enc, 0);

    return update_size(pb, pos);

}


static int copy_to_pbr(DCAXllDecoder *s, uint8_t *data, int size, int delay)

{

    if (size > DCA_XLL_PBR_BUFFER_MAX)

        return AVERROR(ENOSPC);

    if (!s->pbr_buffer && !(s->pbr_buffer = av_malloc(DCA_XLL_PBR_BUFFER_MAX + DCA_BUFFER_PADDING_SIZE)))

        return AVERROR(ENOMEM);

    memcpy(s->pbr_buffer, data, size);

    s->pbr_length = size;

    s->pbr_delay = delay;

    return 0;

}


static void sigill_handler (int sig)

{

    if (!canjump) {

        signal (sig, SIG_DFL);

        raise (sig);

    }

    canjump = 0;

    siglongjmp (jmpbuf, 1);

}


static void v9fs_lcreate(void *opaque)

{

    int32_t dfid, flags, mode;

    gid_t gid;

    ssize_t err = 0;

    ssize_t offset = 7;

    V9fsString name;

    V9fsFidState *fidp;

    struct stat stbuf;

    V9fsQID qid;

    int32_t iounit;

    V9fsPDU *pdu = opaque;

    pdu_unmarshal(pdu, offset, "dsddd", &dfid, &name, &flags,

                  &mode, &gid);

    fidp = get_fid(pdu, dfid);

    if (fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    flags = get_dotl_openflags(pdu->s, flags);

    err = v9fs_co_open2(pdu, fidp, &name, gid,

                        flags | O_CREAT, mode, &stbuf);

    if (err < 0) {

        goto out;

    }

    fidp->fid_type = P9_FID_FILE;

    fidp->open_flags = flags;

    if (flags & O_EXCL) {

        /*

         * We let the host file system do O_EXCL check

         * We should not reclaim such fd

         */

        fidp->flags |= FID_NON_RECLAIMABLE;

    }

    iounit =  get_iounit(pdu, &fidp->path);

    stat_to_qid(&stbuf, &qid);

    offset += pdu_marshal(pdu, offset, "Qd", &qid, iounit);

    err = offset;

out:

    put_fid(pdu, fidp);

out_nofid:

    trace_v9fs_lcreate_return(pdu->tag, pdu->id,

                              qid.type, qid.version, qid.path, iounit);

    complete_pdu(pdu->s, pdu, err);

    v9fs_string_free(&name);

}