📄 xp_osd_drv.c
字号:
if (i == pDemuxDev->uFilterNum) { printk("DemuxPESCallback(): Error - Cannot find filter for PES Callback\n"); return; } /*-------------------------------------------------------------------------+ | Get No. of Free Bytes and check for Internal Circular Buffer Overflow +-------------------------------------------------------------------------*/ pDmxfilter = (DEMUX_FILTER *) (&pDemuxDev->filter[i]); ppBuffer = DemuxGetQPBase(pGlobal,pDmxfilter,pInfo->plData); BTrem = pDmxfilter->buffer.ulSize - pDmxfilter->buffer.count; if (BTrem < pInfo->ulLength) { xp_osi_queue_unlock_data(pGlobal,pDmxfilter->chid, (UCHAR *)ppBuffer, (ULONG)pInfo->ulLength); printk("DemuxPESCallback(): Error - Internal Buffer is full for chid=%d\n", pDmxfilter->chid); return; } /*-------------------------------------------------------------------------+ | Transfer data in Transport Queue to Internal Circular Buffer +-------------------------------------------------------------------------*/ DemuxCopyToCBuf(&pDmxfilter->buffer, pInfo); /*-------------------------------------------------------------------------+ | Unlock Transport Queue +-------------------------------------------------------------------------*/ xp_osi_queue_unlock_data(pGlobal,pDmxfilter->chid, (UCHAR *)ppBuffer, (ULONG)pInfo->ulLength); /*-------------------------------------------------------------------------+ | Wake-up Signal Handler +-------------------------------------------------------------------------*/ if(pDmxfilter->async_queue != NULL) { kill_fasync(&pDmxfilter->async_queue, SIGIO, POLL_IN); } /*-------------------------------------------------------------------------+ | Wake-up Blocked Reads waiting for Data +-------------------------------------------------------------------------*/ wake_up_interruptible(&pDmxfilter->buffer.queue); return;}/*----------------------------------------------------------------------------+| DemuxCallback_nb+----------------------------------------------------------------------------*/static void DemuxCallback_nb( GLOBAL_RESOURCES *pGlobal,SHORT wChannelId,ULONG ulInterrupt){ int i; DEMUX_FILTER *pDmxfilter; DEMUX_DEVICE *pDemuxDev; QUEUE_PTR pQue; /* channel information */ ULONG writep; ULONG ppBQueue; ULONG ppEQueue; ULONG rp; if(ulInterrupt & XP_INTERRUPT_QSTAT_RPI) { printk("DemuxCallback_nb: RPI interrupt\n"); } if(~ulInterrupt & XP_INTERRUPT_QSTAT_BTI) return; pDemuxDev = pDemux_dev[pGlobal->uDeviceIndex]; for (i = 0; i < pDemuxDev->uFilterNum; i++) { if (pDemuxDev->filter[i].chid == wChannelId) { break; } } if (i == pDemuxDev->uFilterNum) { printk("DemuxCallback_nb(): Error - Cannot find filter for Callback\n"); return; } pDmxfilter = (DEMUX_FILTER *) (&pDemuxDev->filter[i]); pQue = &pGlobal->QueueInfo.XpQueueChData[pDmxfilter->chid]; if(pQue->hMem == 0) { printk("DemuxCallback_nb: queue not allocated"); return; } ppBQueue = (ULONG)(pQue->ulQueueAddr) & 0x00FFFF00; ppEQueue = ppBQueue + pQue->ulQueueSize; xp_atom_dcr_read_register_channel(pGlobal->uDeviceIndex,XP_QSTATD_REG_WSTART, pDmxfilter->chid, &writep); xp_atom_dcr_read_register_channel(pGlobal->uDeviceIndex,XP_QCONFIGB_REG_RPTR, pDmxfilter->chid, &rp); writep = writep & 0x00FFFF00; if(writep < ppBQueue || writep > ppEQueue) return; if(writep == ppEQueue) writep = ppBQueue; pDmxfilter->buffer.ulWrite = writep - ppBQueue; if(pDmxfilter->async_queue != NULL) kill_fasync(&pDmxfilter->async_queue, SIGIO, POLL_IN); wake_up_interruptible(&pDmxfilter->buffer.queue); return;}/*----------------------------------------------------------------------------+| XXXX XXXXX XXXXXXX| XX XX XX X XX| XX XX XX XX| XX XX XXXXX| XX XX XX XX| XX XX XX XX XX| XXXX XXXXX XXX XX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| xp_isr+----------------------------------------------------------------------------*/static void xp_isr( int irq, void *dev_id, struct pt_regs *regs){ xp_osi_interrupt();}/*----------------------------------------------------------------------------+| XXXX XX XX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX| XX XXX XX X XX X XX X XX XX XXX XX XXXX XX| XX XXXX XX XX XX X XX XX XXXX XX XX XX XX| XX XX XXXX XX XXXX XXXXX XX XXXX XX XX XX| XX XX XXX XX XX X XX XX XX XXX XXXXXX XX| XX XX XX XX XX X XX XX XX XX XX XX XX XX| XXXX XX XX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| DemuxStcEvent+----------------------------------------------------------------------------*/static void DemuxStcEvent( GLOBAL_RESOURCES *pGlobal, XP_STC_EVENT stc_event){ PDEBUG("DemuxStcEvent(): Entering\n"); pGlobal->stc_event = stc_event; wake_up_interruptible(&stc_WaitQ);}/*----------------------------------------------------------------------------+| DemuxSelectSource+----------------------------------------------------------------------------*/static int DemuxSelectSource( GLOBAL_RESOURCES *pGlobal, STREAM_SOURCE source){#ifndef __DRV_FOR_VESTA__ XP_CONFIG_VALUES Config; PDEBUG("DemuxSelectSource(): Entering - source=%d\n", source); switch(source) { case INPUT_FROM_CHANNEL0: os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.insel = 0; xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break;#ifdef __DRV_FOR_PALLAS__ case INPUT_FROM_CHANNEL1: os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.insel = 1; xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break; case INPUT_FROM_1394: os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.insel = 2; xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break;#endif case INPUT_FROM_PVR: if (pGlobal->uDeviceIndex != 0) { return(-1); } os_get_mutex(hMutex); xp_osi_get_config_values(pGlobal,&Config); Config.insel = 3; xp_osi_set_config_values(pGlobal,&Config); os_release_mutex(hMutex); break; default: return(-1); }#endif return(0);}/*----------------------------------------------------------------------------+| DemuxFilterStop+----------------------------------------------------------------------------*/static int DemuxFilterStop( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ int rc=0; ULONG reg; ULONG flag; XP_BUCKET1Q_REGP pBucket; DEMUX_DEVICE *pDemuxDev; PDEBUG("DemuxFilterStop(): Entering - pDmxfilter->type=%d\n", pDmxfilter->type); pDemuxDev = pDemux_dev[pGlobal->uDeviceIndex]; if (pDmxfilter->states < FILTER_STAT_START) { return(0); } switch (pDmxfilter->type) { case FILTER_TYPE_SEC: os_get_mutex(hMutex); rc = xp_osi_filter_control(pGlobal,(short)pDmxfilter->fid, XP_FILTER_CONTROL_DISABLE); os_release_mutex(hMutex); if (rc) { printk("DemuxFilterStop(): Error disabling filter\n"); return(-1); } if ((pDmxfilter->chid != ILLEGAL_CHANNEL) && (pDemuxDev->chid[pDmxfilter->chid].inuse == 1)) { os_get_mutex(hMutex); rc = xp_osi_channel_control(pGlobal,(short)pDmxfilter->chid, XP_CHANNEL_CONTROL_DISABLE); os_release_mutex(hMutex); if (rc) { printk("DemuxFilterStop(): Error disabling Channel\n"); return(-1); } pDemuxDev->chid[pDmxfilter->chid].state = XP_CHANNEL_DISABLED; } break; case FILTER_TYPE_PES: if (pDmxfilter->pes_para.pesType == DMX_PES_PCR) { os_get_mutex(hMutex); xp_osi_pcr_cchan_auto(pGlobal,0x1fff); os_release_mutex(hMutex); if (stc_notify_fn != NULL) { (*stc_notify_fn)(pGlobal,STC_REMOVED); } break; } if (pDmxfilter->chid != ILLEGAL_CHANNEL) { os_get_mutex(hMutex); rc = xp_osi_channel_control(pGlobal,(short)pDmxfilter->chid, XP_CHANNEL_CONTROL_DISABLE); os_release_mutex(hMutex); if (rc) { printk("DemuxFilterStop(): Error disabling PES channel\n"); return(-1); } } break; case FILTER_TYPE_TS: if (pDmxfilter->chid != ILLEGAL_CHANNEL) { os_get_mutex(hMutex); rc = xp_osi_channel_control(pGlobal,(short)pDmxfilter->chid, XP_CHANNEL_CONTROL_DISABLE); os_release_mutex(hMutex); if (rc) { printk("DemuxFilterStop(): Error disabling TS channel\n"); return(-1); } xp_osi_stop_parse_bypass(pGlobal); } break; case FILTER_TYPE_BUCKET: reg = 0; pBucket = (void *)® pBucket->bqdt = 0; pBucket->bvalid = 0; pBucket->indx = ILLEGAL_CHANNEL; flag = os_enter_critical_section(); xp_atom_dcr_write(pGlobal->uDeviceIndex,XP_DCR_ADDR_BUCKET1Q,reg); os_leave_critical_section(flag); break; default: return(-EINVAL); } pDmxfilter->states = FILTER_STAT_READY; //wake up thread sleeping on that queue wake_up_interruptible(&pDmxfilter->buffer.queue); return(0);}/*----------------------------------------------------------------------------+| DemuxFilterStart+----------------------------------------------------------------------------*/static int DemuxFilterStart( GLOBAL_RESOURCES *pGlobal, DEMUX_FILTER *pDmxfilter){ int rc=0; ULONG reg; ULONG flag; XP_BUCKET1Q_REGP pBucket; DEMUX_DEVICE *pDemuxDev; PDEBUG("DemuxFilterStart(): Entering - pDmxfilter->type=%d\n", pDmxfilter->type); pDemuxDev = pDemux_dev[pGlobal->uDeviceIndex]; //If the filter has already been started for channel changes, return if (pDmxfilter->states == FILTER_STAT_START_CC) { return(0); } //If the filter has been started, stop the filter if (pDmxfilter->states == FILTER_STAT_START) { DemuxFilterStop(pGlobal,pDmxfilter); } if (pDmxfilter->states == FILTER_STAT_SET) { if((pDmxfilter->flags & FILTER_FLAG_UNBUFFERED) == 0) { if (pDmxfilter->buffer.plData) { vfree(pDmxfilter->buffer.plData); } pDmxfilter->buffer.plData = vmalloc(pDmxfilter->buffer.ulSize); if (!pDmxfilter->buffer.plData) { return(-ENOMEM); } } pDmxfilter->states = FILTER_STAT_READY; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -