static ssize_t _esparser_write(const char __user *buf, size_t count, u32 type, int isphybuf) { size_t r = count; const char __user *p = buf; u32 len = 0; u32 parser_type; int ret; u32 wp; if (type == BUF_TYPE_HEVC) { parser_type = PARSER_VIDEO; } else if (type == BUF_TYPE_VIDEO) { parser_type = PARSER_VIDEO; } else if (type == BUF_TYPE_AUDIO) { parser_type = PARSER_AUDIO; } else { parser_type = PARSER_SUBPIC; } wp = buf_wp(type); if (r > 0) { if (isphybuf) { len=count; } else { len = min(r, (size_t)FETCHBUF_SIZE); if (copy_from_user(fetchbuf_remap, p, len)) { return -EFAULT; } } if (isphybuf) { esparser_start_search(parser_type, (u32)buf, len); } else { esparser_start_search(parser_type, virt_to_phys((u8 *)fetchbuf), len); } ret = wait_event_interruptible_timeout(wq, search_done != 0, HZ/5); if (ret == 0) { WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); if (wp == buf_wp(type)) { /*no data fetched*/ return -EAGAIN; } else { printk("write timeout, but fetched ok,len=%d,wpdiff=%d\n", len, wp - buf_wp(type)); } } else if (ret < 0) { return -ERESTARTSYS; } } if ((type == BUF_TYPE_VIDEO) || (HAS_HEVC_VDEC && (type == BUF_TYPE_HEVC))) { video_data_parsed += len; } else if (type == BUF_TYPE_AUDIO ) { audio_data_parsed += len; } return len; }
static ssize_t _rmparser_write(const char __user *buf, size_t count) { size_t r = count; const char __user *p = buf; u32 len; int ret; static int halt_droped_len=0; u32 vwp,awp; if (r > 0) { len = min(r, (size_t)FETCHBUF_SIZE); if (copy_from_user(fetchbuf_remap, p, len)) { return -EFAULT; } fetch_done = 0; wmb(); vwp=buf_wp(BUF_TYPE_VIDEO); awp=buf_wp(BUF_TYPE_AUDIO); WRITE_MPEG_REG(PARSER_FETCH_ADDR, virt_to_phys((u8 *)fetchbuf)); WRITE_MPEG_REG(PARSER_FETCH_CMD, (7 << FETCH_ENDIAN) | len); ret = wait_event_interruptible_timeout(rm_wq, fetch_done != 0, HZ/10); if (ret == 0) { WRITE_MPEG_REG(PARSER_FETCH_CMD, 0); parse_halt ++; printk("write timeout, retry,halt_count=%d parse_control=%x \n", parse_halt,READ_MPEG_REG(PARSER_CONTROL)); vreal_set_fatal_flag(1); if(parse_halt > 10) { WRITE_MPEG_REG(PARSER_CONTROL, (ES_SEARCH | ES_PARSER_START)); printk("reset parse_control=%x\n",READ_MPEG_REG(PARSER_CONTROL)); } return -EAGAIN; } else if (ret < 0) { return -ERESTARTSYS; } if(vwp==buf_wp(BUF_TYPE_VIDEO) && awp==buf_wp(BUF_TYPE_AUDIO)){ if((parse_halt+1)%10==1) printk("Video&Audio WP not changed after write,video %x->%x,Audio:%x-->%x,parse_halt=%d\n", vwp,buf_wp(BUF_TYPE_VIDEO),awp,buf_wp(BUF_TYPE_AUDIO),parse_halt); parse_halt ++;/*wp not changed ,we think have bugs on parser now.*/ if(parse_halt > 10 && (stbuf_level(get_buf_by_type(BUF_TYPE_VIDEO))< 1000 || stbuf_level(get_buf_by_type(BUF_TYPE_AUDIO))< 100)) {/*reset while at least one is underflow.*/ WRITE_MPEG_REG(PARSER_CONTROL, (ES_SEARCH | ES_PARSER_START)); printk("reset parse_control=%x\n",READ_MPEG_REG(PARSER_CONTROL)); } if(parse_halt <= 10 || halt_droped_len <100*1024){/*drops first 10 pkt ,some times maybe no av data*/ printk("drop this pkt=%d,len=%d\n",parse_halt,len); p += len; r -= len; halt_droped_len+=len; }else{ return -EAGAIN; } }else{ halt_droped_len=0; parse_halt = 0; p += len; r -= len; } } return count - r; }