18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include "dvb_filter.h" 38c2ecf20Sopenharmony_ci#include "av7110_ipack.h" 48c2ecf20Sopenharmony_ci#include <linux/string.h> /* for memcpy() */ 58c2ecf20Sopenharmony_ci#include <linux/vmalloc.h> 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_civoid av7110_ipack_reset(struct ipack *p) 98c2ecf20Sopenharmony_ci{ 108c2ecf20Sopenharmony_ci p->found = 0; 118c2ecf20Sopenharmony_ci p->cid = 0; 128c2ecf20Sopenharmony_ci p->plength = 0; 138c2ecf20Sopenharmony_ci p->flag1 = 0; 148c2ecf20Sopenharmony_ci p->flag2 = 0; 158c2ecf20Sopenharmony_ci p->hlength = 0; 168c2ecf20Sopenharmony_ci p->mpeg = 0; 178c2ecf20Sopenharmony_ci p->check = 0; 188c2ecf20Sopenharmony_ci p->which = 0; 198c2ecf20Sopenharmony_ci p->done = 0; 208c2ecf20Sopenharmony_ci p->count = 0; 218c2ecf20Sopenharmony_ci} 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciint av7110_ipack_init(struct ipack *p, int size, 258c2ecf20Sopenharmony_ci void (*func)(u8 *buf, int size, void *priv)) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci if (!(p->buf = vmalloc(size))) { 288c2ecf20Sopenharmony_ci printk(KERN_WARNING "Couldn't allocate memory for ipack\n"); 298c2ecf20Sopenharmony_ci return -ENOMEM; 308c2ecf20Sopenharmony_ci } 318c2ecf20Sopenharmony_ci p->size = size; 328c2ecf20Sopenharmony_ci p->func = func; 338c2ecf20Sopenharmony_ci p->repack_subids = 0; 348c2ecf20Sopenharmony_ci av7110_ipack_reset(p); 358c2ecf20Sopenharmony_ci return 0; 368c2ecf20Sopenharmony_ci} 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_civoid av7110_ipack_free(struct ipack *p) 408c2ecf20Sopenharmony_ci{ 418c2ecf20Sopenharmony_ci vfree(p->buf); 428c2ecf20Sopenharmony_ci} 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cistatic void send_ipack(struct ipack *p) 468c2ecf20Sopenharmony_ci{ 478c2ecf20Sopenharmony_ci int off; 488c2ecf20Sopenharmony_ci struct dvb_audio_info ai; 498c2ecf20Sopenharmony_ci int ac3_off = 0; 508c2ecf20Sopenharmony_ci int streamid = 0; 518c2ecf20Sopenharmony_ci int nframes = 0; 528c2ecf20Sopenharmony_ci int f = 0; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci switch (p->mpeg) { 558c2ecf20Sopenharmony_ci case 2: 568c2ecf20Sopenharmony_ci if (p->count < 10) 578c2ecf20Sopenharmony_ci return; 588c2ecf20Sopenharmony_ci p->buf[3] = p->cid; 598c2ecf20Sopenharmony_ci p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); 608c2ecf20Sopenharmony_ci p->buf[5] = (u8)((p->count - 6) & 0x00ff); 618c2ecf20Sopenharmony_ci if (p->repack_subids && p->cid == PRIVATE_STREAM1) { 628c2ecf20Sopenharmony_ci off = 9 + p->buf[8]; 638c2ecf20Sopenharmony_ci streamid = p->buf[off]; 648c2ecf20Sopenharmony_ci if ((streamid & 0xf8) == 0x80) { 658c2ecf20Sopenharmony_ci ai.off = 0; 668c2ecf20Sopenharmony_ci ac3_off = ((p->buf[off + 2] << 8)| 678c2ecf20Sopenharmony_ci p->buf[off + 3]); 688c2ecf20Sopenharmony_ci if (ac3_off < p->count) 698c2ecf20Sopenharmony_ci f = dvb_filter_get_ac3info(p->buf + off + 3 + ac3_off, 708c2ecf20Sopenharmony_ci p->count - ac3_off, &ai, 0); 718c2ecf20Sopenharmony_ci if (!f) { 728c2ecf20Sopenharmony_ci nframes = (p->count - off - 3 - ac3_off) / 738c2ecf20Sopenharmony_ci ai.framesize + 1; 748c2ecf20Sopenharmony_ci p->buf[off + 2] = (ac3_off >> 8) & 0xff; 758c2ecf20Sopenharmony_ci p->buf[off + 3] = (ac3_off) & 0xff; 768c2ecf20Sopenharmony_ci p->buf[off + 1] = nframes; 778c2ecf20Sopenharmony_ci ac3_off += nframes * ai.framesize - p->count; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci } 808c2ecf20Sopenharmony_ci } 818c2ecf20Sopenharmony_ci p->func(p->buf, p->count, p->data); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci p->buf[6] = 0x80; 848c2ecf20Sopenharmony_ci p->buf[7] = 0x00; 858c2ecf20Sopenharmony_ci p->buf[8] = 0x00; 868c2ecf20Sopenharmony_ci p->count = 9; 878c2ecf20Sopenharmony_ci if (p->repack_subids && p->cid == PRIVATE_STREAM1 888c2ecf20Sopenharmony_ci && (streamid & 0xf8) == 0x80) { 898c2ecf20Sopenharmony_ci p->count += 4; 908c2ecf20Sopenharmony_ci p->buf[9] = streamid; 918c2ecf20Sopenharmony_ci p->buf[10] = (ac3_off >> 8) & 0xff; 928c2ecf20Sopenharmony_ci p->buf[11] = (ac3_off) & 0xff; 938c2ecf20Sopenharmony_ci p->buf[12] = 0; 948c2ecf20Sopenharmony_ci } 958c2ecf20Sopenharmony_ci break; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci case 1: 988c2ecf20Sopenharmony_ci if (p->count < 8) 998c2ecf20Sopenharmony_ci return; 1008c2ecf20Sopenharmony_ci p->buf[3] = p->cid; 1018c2ecf20Sopenharmony_ci p->buf[4] = (u8)(((p->count - 6) & 0xff00) >> 8); 1028c2ecf20Sopenharmony_ci p->buf[5] = (u8)((p->count - 6) & 0x00ff); 1038c2ecf20Sopenharmony_ci p->func(p->buf, p->count, p->data); 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci p->buf[6] = 0x0f; 1068c2ecf20Sopenharmony_ci p->count = 7; 1078c2ecf20Sopenharmony_ci break; 1088c2ecf20Sopenharmony_ci } 1098c2ecf20Sopenharmony_ci} 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci 1128c2ecf20Sopenharmony_civoid av7110_ipack_flush(struct ipack *p) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci if (p->plength != MMAX_PLENGTH - 6 || p->found <= 6) 1158c2ecf20Sopenharmony_ci return; 1168c2ecf20Sopenharmony_ci p->plength = p->found - 6; 1178c2ecf20Sopenharmony_ci p->found = 0; 1188c2ecf20Sopenharmony_ci send_ipack(p); 1198c2ecf20Sopenharmony_ci av7110_ipack_reset(p); 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_cistatic void write_ipack(struct ipack *p, const u8 *data, int count) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci u8 headr[3] = { 0x00, 0x00, 0x01 }; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if (p->count < 6) { 1288c2ecf20Sopenharmony_ci memcpy(p->buf, headr, 3); 1298c2ecf20Sopenharmony_ci p->count = 6; 1308c2ecf20Sopenharmony_ci } 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_ci if (p->count + count < p->size){ 1338c2ecf20Sopenharmony_ci memcpy(p->buf+p->count, data, count); 1348c2ecf20Sopenharmony_ci p->count += count; 1358c2ecf20Sopenharmony_ci } else { 1368c2ecf20Sopenharmony_ci int rest = p->size - p->count; 1378c2ecf20Sopenharmony_ci memcpy(p->buf+p->count, data, rest); 1388c2ecf20Sopenharmony_ci p->count += rest; 1398c2ecf20Sopenharmony_ci send_ipack(p); 1408c2ecf20Sopenharmony_ci if (count - rest > 0) 1418c2ecf20Sopenharmony_ci write_ipack(p, data + rest, count - rest); 1428c2ecf20Sopenharmony_ci } 1438c2ecf20Sopenharmony_ci} 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ciint av7110_ipack_instant_repack (const u8 *buf, int count, struct ipack *p) 1478c2ecf20Sopenharmony_ci{ 1488c2ecf20Sopenharmony_ci int l; 1498c2ecf20Sopenharmony_ci int c = 0; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci while (c < count && (p->mpeg == 0 || 1528c2ecf20Sopenharmony_ci (p->mpeg == 1 && p->found < 7) || 1538c2ecf20Sopenharmony_ci (p->mpeg == 2 && p->found < 9)) 1548c2ecf20Sopenharmony_ci && (p->found < 5 || !p->done)) { 1558c2ecf20Sopenharmony_ci switch (p->found) { 1568c2ecf20Sopenharmony_ci case 0: 1578c2ecf20Sopenharmony_ci case 1: 1588c2ecf20Sopenharmony_ci if (buf[c] == 0x00) 1598c2ecf20Sopenharmony_ci p->found++; 1608c2ecf20Sopenharmony_ci else 1618c2ecf20Sopenharmony_ci p->found = 0; 1628c2ecf20Sopenharmony_ci c++; 1638c2ecf20Sopenharmony_ci break; 1648c2ecf20Sopenharmony_ci case 2: 1658c2ecf20Sopenharmony_ci if (buf[c] == 0x01) 1668c2ecf20Sopenharmony_ci p->found++; 1678c2ecf20Sopenharmony_ci else if (buf[c] == 0) 1688c2ecf20Sopenharmony_ci p->found = 2; 1698c2ecf20Sopenharmony_ci else 1708c2ecf20Sopenharmony_ci p->found = 0; 1718c2ecf20Sopenharmony_ci c++; 1728c2ecf20Sopenharmony_ci break; 1738c2ecf20Sopenharmony_ci case 3: 1748c2ecf20Sopenharmony_ci p->cid = 0; 1758c2ecf20Sopenharmony_ci switch (buf[c]) { 1768c2ecf20Sopenharmony_ci case PROG_STREAM_MAP: 1778c2ecf20Sopenharmony_ci case PRIVATE_STREAM2: 1788c2ecf20Sopenharmony_ci case PROG_STREAM_DIR: 1798c2ecf20Sopenharmony_ci case ECM_STREAM : 1808c2ecf20Sopenharmony_ci case EMM_STREAM : 1818c2ecf20Sopenharmony_ci case PADDING_STREAM : 1828c2ecf20Sopenharmony_ci case DSM_CC_STREAM : 1838c2ecf20Sopenharmony_ci case ISO13522_STREAM: 1848c2ecf20Sopenharmony_ci p->done = 1; 1858c2ecf20Sopenharmony_ci fallthrough; 1868c2ecf20Sopenharmony_ci case PRIVATE_STREAM1: 1878c2ecf20Sopenharmony_ci case VIDEO_STREAM_S ... VIDEO_STREAM_E: 1888c2ecf20Sopenharmony_ci case AUDIO_STREAM_S ... AUDIO_STREAM_E: 1898c2ecf20Sopenharmony_ci p->found++; 1908c2ecf20Sopenharmony_ci p->cid = buf[c]; 1918c2ecf20Sopenharmony_ci c++; 1928c2ecf20Sopenharmony_ci break; 1938c2ecf20Sopenharmony_ci default: 1948c2ecf20Sopenharmony_ci p->found = 0; 1958c2ecf20Sopenharmony_ci break; 1968c2ecf20Sopenharmony_ci } 1978c2ecf20Sopenharmony_ci break; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci case 4: 2008c2ecf20Sopenharmony_ci if (count-c > 1) { 2018c2ecf20Sopenharmony_ci p->plen[0] = buf[c]; 2028c2ecf20Sopenharmony_ci c++; 2038c2ecf20Sopenharmony_ci p->plen[1] = buf[c]; 2048c2ecf20Sopenharmony_ci c++; 2058c2ecf20Sopenharmony_ci p->found += 2; 2068c2ecf20Sopenharmony_ci p->plength = (p->plen[0] << 8) | p->plen[1]; 2078c2ecf20Sopenharmony_ci } else { 2088c2ecf20Sopenharmony_ci p->plen[0] = buf[c]; 2098c2ecf20Sopenharmony_ci p->found++; 2108c2ecf20Sopenharmony_ci return count; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci break; 2138c2ecf20Sopenharmony_ci case 5: 2148c2ecf20Sopenharmony_ci p->plen[1] = buf[c]; 2158c2ecf20Sopenharmony_ci c++; 2168c2ecf20Sopenharmony_ci p->found++; 2178c2ecf20Sopenharmony_ci p->plength = (p->plen[0] << 8) | p->plen[1]; 2188c2ecf20Sopenharmony_ci break; 2198c2ecf20Sopenharmony_ci case 6: 2208c2ecf20Sopenharmony_ci if (!p->done) { 2218c2ecf20Sopenharmony_ci p->flag1 = buf[c]; 2228c2ecf20Sopenharmony_ci c++; 2238c2ecf20Sopenharmony_ci p->found++; 2248c2ecf20Sopenharmony_ci if ((p->flag1 & 0xc0) == 0x80) 2258c2ecf20Sopenharmony_ci p->mpeg = 2; 2268c2ecf20Sopenharmony_ci else { 2278c2ecf20Sopenharmony_ci p->hlength = 0; 2288c2ecf20Sopenharmony_ci p->which = 0; 2298c2ecf20Sopenharmony_ci p->mpeg = 1; 2308c2ecf20Sopenharmony_ci p->flag2 = 0; 2318c2ecf20Sopenharmony_ci } 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci break; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci case 7: 2368c2ecf20Sopenharmony_ci if (!p->done && p->mpeg == 2) { 2378c2ecf20Sopenharmony_ci p->flag2 = buf[c]; 2388c2ecf20Sopenharmony_ci c++; 2398c2ecf20Sopenharmony_ci p->found++; 2408c2ecf20Sopenharmony_ci } 2418c2ecf20Sopenharmony_ci break; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci case 8: 2448c2ecf20Sopenharmony_ci if (!p->done && p->mpeg == 2) { 2458c2ecf20Sopenharmony_ci p->hlength = buf[c]; 2468c2ecf20Sopenharmony_ci c++; 2478c2ecf20Sopenharmony_ci p->found++; 2488c2ecf20Sopenharmony_ci } 2498c2ecf20Sopenharmony_ci break; 2508c2ecf20Sopenharmony_ci } 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if (c == count) 2548c2ecf20Sopenharmony_ci return count; 2558c2ecf20Sopenharmony_ci 2568c2ecf20Sopenharmony_ci if (!p->plength) 2578c2ecf20Sopenharmony_ci p->plength = MMAX_PLENGTH - 6; 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci if (p->done || ((p->mpeg == 2 && p->found >= 9) || 2608c2ecf20Sopenharmony_ci (p->mpeg == 1 && p->found >= 7))) { 2618c2ecf20Sopenharmony_ci switch (p->cid) { 2628c2ecf20Sopenharmony_ci case AUDIO_STREAM_S ... AUDIO_STREAM_E: 2638c2ecf20Sopenharmony_ci case VIDEO_STREAM_S ... VIDEO_STREAM_E: 2648c2ecf20Sopenharmony_ci case PRIVATE_STREAM1: 2658c2ecf20Sopenharmony_ci if (p->mpeg == 2 && p->found == 9) { 2668c2ecf20Sopenharmony_ci write_ipack(p, &p->flag1, 1); 2678c2ecf20Sopenharmony_ci write_ipack(p, &p->flag2, 1); 2688c2ecf20Sopenharmony_ci write_ipack(p, &p->hlength, 1); 2698c2ecf20Sopenharmony_ci } 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci if (p->mpeg == 1 && p->found == 7) 2728c2ecf20Sopenharmony_ci write_ipack(p, &p->flag1, 1); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci if (p->mpeg == 2 && (p->flag2 & PTS_ONLY) && 2758c2ecf20Sopenharmony_ci p->found < 14) { 2768c2ecf20Sopenharmony_ci while (c < count && p->found < 14) { 2778c2ecf20Sopenharmony_ci p->pts[p->found - 9] = buf[c]; 2788c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 2798c2ecf20Sopenharmony_ci c++; 2808c2ecf20Sopenharmony_ci p->found++; 2818c2ecf20Sopenharmony_ci } 2828c2ecf20Sopenharmony_ci if (c == count) 2838c2ecf20Sopenharmony_ci return count; 2848c2ecf20Sopenharmony_ci } 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci if (p->mpeg == 1 && p->which < 2000) { 2878c2ecf20Sopenharmony_ci 2888c2ecf20Sopenharmony_ci if (p->found == 7) { 2898c2ecf20Sopenharmony_ci p->check = p->flag1; 2908c2ecf20Sopenharmony_ci p->hlength = 1; 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci while (!p->which && c < count && 2948c2ecf20Sopenharmony_ci p->check == 0xff){ 2958c2ecf20Sopenharmony_ci p->check = buf[c]; 2968c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 2978c2ecf20Sopenharmony_ci c++; 2988c2ecf20Sopenharmony_ci p->found++; 2998c2ecf20Sopenharmony_ci p->hlength++; 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci if (c == count) 3038c2ecf20Sopenharmony_ci return count; 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci if ((p->check & 0xc0) == 0x40 && !p->which) { 3068c2ecf20Sopenharmony_ci p->check = buf[c]; 3078c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 3088c2ecf20Sopenharmony_ci c++; 3098c2ecf20Sopenharmony_ci p->found++; 3108c2ecf20Sopenharmony_ci p->hlength++; 3118c2ecf20Sopenharmony_ci 3128c2ecf20Sopenharmony_ci p->which = 1; 3138c2ecf20Sopenharmony_ci if (c == count) 3148c2ecf20Sopenharmony_ci return count; 3158c2ecf20Sopenharmony_ci p->check = buf[c]; 3168c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 3178c2ecf20Sopenharmony_ci c++; 3188c2ecf20Sopenharmony_ci p->found++; 3198c2ecf20Sopenharmony_ci p->hlength++; 3208c2ecf20Sopenharmony_ci p->which = 2; 3218c2ecf20Sopenharmony_ci if (c == count) 3228c2ecf20Sopenharmony_ci return count; 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci if (p->which == 1) { 3268c2ecf20Sopenharmony_ci p->check = buf[c]; 3278c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 3288c2ecf20Sopenharmony_ci c++; 3298c2ecf20Sopenharmony_ci p->found++; 3308c2ecf20Sopenharmony_ci p->hlength++; 3318c2ecf20Sopenharmony_ci p->which = 2; 3328c2ecf20Sopenharmony_ci if (c == count) 3338c2ecf20Sopenharmony_ci return count; 3348c2ecf20Sopenharmony_ci } 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci if ((p->check & 0x30) && p->check != 0xff) { 3378c2ecf20Sopenharmony_ci p->flag2 = (p->check & 0xf0) << 2; 3388c2ecf20Sopenharmony_ci p->pts[0] = p->check; 3398c2ecf20Sopenharmony_ci p->which = 3; 3408c2ecf20Sopenharmony_ci } 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci if (c == count) 3438c2ecf20Sopenharmony_ci return count; 3448c2ecf20Sopenharmony_ci if (p->which > 2){ 3458c2ecf20Sopenharmony_ci if ((p->flag2 & PTS_DTS_FLAGS) == PTS_ONLY) { 3468c2ecf20Sopenharmony_ci while (c < count && p->which < 7) { 3478c2ecf20Sopenharmony_ci p->pts[p->which - 2] = buf[c]; 3488c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 3498c2ecf20Sopenharmony_ci c++; 3508c2ecf20Sopenharmony_ci p->found++; 3518c2ecf20Sopenharmony_ci p->which++; 3528c2ecf20Sopenharmony_ci p->hlength++; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci if (c == count) 3558c2ecf20Sopenharmony_ci return count; 3568c2ecf20Sopenharmony_ci } else if ((p->flag2 & PTS_DTS_FLAGS) == PTS_DTS) { 3578c2ecf20Sopenharmony_ci while (c < count && p->which < 12) { 3588c2ecf20Sopenharmony_ci if (p->which < 7) 3598c2ecf20Sopenharmony_ci p->pts[p->which - 2] = buf[c]; 3608c2ecf20Sopenharmony_ci write_ipack(p, buf + c, 1); 3618c2ecf20Sopenharmony_ci c++; 3628c2ecf20Sopenharmony_ci p->found++; 3638c2ecf20Sopenharmony_ci p->which++; 3648c2ecf20Sopenharmony_ci p->hlength++; 3658c2ecf20Sopenharmony_ci } 3668c2ecf20Sopenharmony_ci if (c == count) 3678c2ecf20Sopenharmony_ci return count; 3688c2ecf20Sopenharmony_ci } 3698c2ecf20Sopenharmony_ci p->which = 2000; 3708c2ecf20Sopenharmony_ci } 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci } 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci while (c < count && p->found < p->plength + 6) { 3758c2ecf20Sopenharmony_ci l = count - c; 3768c2ecf20Sopenharmony_ci if (l + p->found > p->plength + 6) 3778c2ecf20Sopenharmony_ci l = p->plength + 6 - p->found; 3788c2ecf20Sopenharmony_ci write_ipack(p, buf + c, l); 3798c2ecf20Sopenharmony_ci p->found += l; 3808c2ecf20Sopenharmony_ci c += l; 3818c2ecf20Sopenharmony_ci } 3828c2ecf20Sopenharmony_ci break; 3838c2ecf20Sopenharmony_ci } 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci 3868c2ecf20Sopenharmony_ci if (p->done) { 3878c2ecf20Sopenharmony_ci if (p->found + count - c < p->plength + 6) { 3888c2ecf20Sopenharmony_ci p->found += count - c; 3898c2ecf20Sopenharmony_ci c = count; 3908c2ecf20Sopenharmony_ci } else { 3918c2ecf20Sopenharmony_ci c += p->plength + 6 - p->found; 3928c2ecf20Sopenharmony_ci p->found = p->plength + 6; 3938c2ecf20Sopenharmony_ci } 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci if (p->plength && p->found == p->plength + 6) { 3978c2ecf20Sopenharmony_ci send_ipack(p); 3988c2ecf20Sopenharmony_ci av7110_ipack_reset(p); 3998c2ecf20Sopenharmony_ci if (c < count) 4008c2ecf20Sopenharmony_ci av7110_ipack_instant_repack(buf + c, count - c, p); 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci } 4038c2ecf20Sopenharmony_ci return count; 4048c2ecf20Sopenharmony_ci} 405