⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xp_osd_drv.c

📁 IBM source for pallas/vulcan/vesta
💻 C
📖 第 1 页 / 共 5 页
字号:
/*----------------------------------------------------------------------------+||       This source code has been made available to you by IBM on an AS-IS|       basis.  Anyone receiving this source is licensed under IBM|       copyrights to use it in any way he or she deems fit, including|       copying it, modifying it, compiling it, and redistributing it either|       with or without modifications.  No license under IBM patents or|       patent applications is to be implied by the copyright license.||       Any user of this software should understand that IBM cannot provide|       technical support for this software and will not be responsible for|       any consequences resulting from the use of this software.||       Any person who transfers this source code or any derivative work|       must include the IBM copyright notice, this paragraph, and the|       preceding two paragraphs in the transferred software.||       COPYRIGHT   I B M   CORPORATION 1998|       LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M|+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+||  Author    :  Lin Guo Hui|  File      :  xp_osd_drv.c|  Purpose   :  The set of functions provide a interface to Linux user|               space, as os dependent layer|  Changes   :|  Date         Comments|  ----------------------------------------------------------------------|  25-Jun-2001  Created|  06-Jul-2001  Add audio and video PES reading feature|  24-Jul-2001  Fix the semaphore bug, and add demux_channel_free() when|               DmxFilterAlloc() fail. Add xp_os_enter_critical_section()|               in DmxFilterRead()|  30-Sep-2001  Updated for Pallas|  10-Oct-2001  Add ts_res set and select source|  08-Jan-2002  Fix filter length bug when section filtering|  10-Jan-2002  Add PCR sync when enable filterring PCR|  25-Mar-2002  Allow two and more section filters added to a channel|  10-Apil-02   Add positive enable in section filter para, add get|               filter num ioctl, for PLR|  11-May-2002  Change the buffer to circle queue for section filter|  02-Jun-2002  Add STC event|  18-jun-2002  Support VESTA and VULCAN|  19-Jun-2002  Add notification when the filter is stoped to avoid reading|               waiting forever|  12-aug-2002  Add condition(pDmxfilter->chid != ILLEGAL_CHANNEL) for the|               operation chid[pDmxfilter->chid].inuse++|  17-aug-2002  Fix the bug foe queue management when multiple filters|               attached to on queue|  22-Jul-2003  Corrected problem such that filters with the same PID and|               channel can be opened, set, and started in any order instead|               of in-sequence.|  22-Jul-2003  Removed all "demux_" functions to eliminate similarity to|               proprietary API definitions.+----------------------------------------------------------------------------*/#include <linux/config.h>#include <linux/version.h>#ifdef MODVERSIONS#include <linux/modversions.h>#endif#include <linux/kernel.h>#define    __NO_VERSION__#include <linux/module.h>#include <linux/sched.h>#include <linux/fs.h>#include <linux/ptrace.h>#include <linux/string.h>#include <linux/ioport.h>#include <linux/version.h>#include <linux/delay.h>#include <linux/errno.h>#include <linux/fcntl.h>#include <linux/in.h>#include <linux/interrupt.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/vmalloc.h>#include <linux/slab.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/bitops.h>#include <asm/io.h>#include <asm/irq.h>#include "xp_osi_global.h"#include "xp_atom_reg.h"#include "xp_osd_drv.h"/*----------------------------------------------------------------------------+| Local Defines+----------------------------------------------------------------------------*/#ifdef PDEBUG#undef PDEBUG#endif#define PDEBUG(fmt,args...)#define PDEBUG1(fmt,args...) /*----------------------------------------------------------------------------+| Type Declarations+----------------------------------------------------------------------------*/typedef struct demux_channel_acquire_type {    XP_CHANNEL_TYPE         channel_type;   /* channel type                  */    XP_CHANNEL_UNLOAD_TYPE  unload_type;    /* type of data to unload        */    XP_CHANNEL_NOTIFY_FN    notify_data_fn; /* func to call when data recv   */    unsigned short          bthreshold;     /* boundary threshold            */    unsigned short          pid;            /* program id                    */    unsigned long           queue_size;     /* queue size                    */} DEMUX_CHANNEL_ACQUIRE_TYPE, *DEMUX_CHANNEL_ACQUIRE_PTR;/*----------------------------------------------------------------------------+| Static Declarations+----------------------------------------------------------------------------*/static INT uAlreadyInit = 0;static INT DEFAULT_FILTER_LENGTH = 9;static void vma_open(struct vm_area_struct *vma);static void vma_close(struct vm_area_struct *vma);static struct vm_operations_struct my_vm_ops ={    open:       vma_open,    close:      vma_close};/*----------------------------------------------------------------------------+| Global Declarations+----------------------------------------------------------------------------*/DEMUX_DEVICE     *pDemux_dev[MAX_XP_NUM];GLOBAL_RESOURCES XpGlobal[MAX_XP_NUM];MUTEX_T          hMutex;/*----------------------------------------------------------------------------+| External Declarations+----------------------------------------------------------------------------*/extern XP_STC_NOTIFY_FN stc_notify_fn;/*----------------------------------------------------------------------------+| Prototype Definitions+----------------------------------------------------------------------------*/static DECLARE_WAIT_QUEUE_HEAD(stc_WaitQ);DECLARE_WAIT_QUEUE_HEAD(temp_queue);/*----------------------------------------------------------------------------+|  XX   XX   XXXXXX   XXXXXX   XXXX   XXXXXXX  XX   XXX|  XXX  XX   XX  XX   X XX X    XX     XX       XX  XX|  XXXX XX   XX  XX     XX      XX     XX        XXXX|  XX XXXX   XX  XX     XX      XX     XXXX       XX|  XX  XXX   XX  XX     XX      XX     XX         XX|  XX   XX   XX  XX     XX      XX     XX         XX|  XX   XX   XXXXXX    XXXX    XXXX   XXXX        XX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+|  DemuxGetQPBase+----------------------------------------------------------------------------*/static UCHAR *DemuxGetQPBase(   GLOBAL_RESOURCES *pGlobal,   DEMUX_FILTER     *pDmxfilter,   UCHAR            *plBuffer){   UCHAR *ppBQueue;   UCHAR *ppBuffer;   UCHAR *plBQueue;   plBQueue = (UCHAR*)os_get_logical_address(              pGlobal->QueueInfo.XpQueueChData[pDmxfilter->chid].hMem);   ppBQueue = (UCHAR*)os_get_physical_address(              pGlobal->QueueInfo.XpQueueChData[pDmxfilter->chid].hMem);   ppBuffer = (UCHAR*)((ULONG)ppBQueue + (ULONG)plBuffer  - (ULONG)plBQueue);   return(ppBuffer);}/*----------------------------------------------------------------------------+|  DemuxCopyToCBuf+----------------------------------------------------------------------------*/static void DemuxCopyToCBuf(   DEMUX_FILTER_BUF        *pDmxfbuf,   XP_CHANNEL_NOTIFY_DATA  *pInfo){   ULONG       BErem, QErem;   ULONG       nulWrite;   UCHAR       *pBloc, *pQloc;   UCHAR       *pBstart, *pQstart;   /*-------------------------------------------------------------------------+   |  Determine Queue and Circular Buffer Start and Wrap point   +-------------------------------------------------------------------------*/   nulWrite = (pDmxfbuf->ulWrite + 1) % pDmxfbuf->ulSize;   pBstart  = pDmxfbuf->plData;   pQstart  = pDmxfbuf->plBQueue;   pBloc    = &pDmxfbuf->plData[nulWrite];   pQloc    = pInfo->plData;   BErem    = pDmxfbuf->ulSize   - nulWrite;   QErem    = pDmxfbuf->plEQueue - pInfo->plData;  /*-------------------------------------------------------------------------+   |  Transfer Transport Queue Data to Internal Circular Buffer   |  Manage Wrap on both Circular Queues   +-------------------------------------------------------------------------*/   if ((BErem < pInfo->ulLength) && (QErem < pInfo->ulLength)) {      if (QErem > BErem) {         memcpy(&pBloc[0],     &pQloc[0],     BErem);         memcpy(&pBstart[0],   &pQloc[BErem], QErem-BErem);         memcpy(&pBstart[QErem-BErem], &pQstart[0], pInfo->ulLength-QErem);      } else if (BErem > QErem) {         memcpy(&pBloc[0],     &pQloc[0],     QErem);         memcpy(&pBloc[QErem], &pQstart[0],   BErem-QErem);         memcpy(&pBstart[0],   &pQstart[BErem-QErem], pInfo->ulLength-BErem);      } else {         memcpy(&pBloc[0],     &pQloc[0],     BErem);         memcpy(&pBstart[0],   &pQstart[0],   pInfo->ulLength-BErem);      }   } else if (BErem < pInfo->ulLength) {         memcpy(&pBloc[0],     &pQloc[0],     BErem);         memcpy(&pBstart[0],   &pQloc[BErem], pInfo->ulLength-BErem);   } else if (QErem < pInfo->ulLength) {         memcpy(&pBloc[0],     &pQloc[0],     QErem);         memcpy(&pBloc[QErem], &pQstart[0],   pInfo->ulLength-QErem);   } else {         memcpy(&pBloc[0],     &pQloc[0],     pInfo->ulLength);   }   /*-------------------------------------------------------------------------+   |  Bump Internal Circular Buffer pointers   +-------------------------------------------------------------------------*/   pDmxfbuf->count   = pDmxfbuf->count + pInfo->ulLength;   pDmxfbuf->ulWrite = (pDmxfbuf->ulWrite + pInfo->ulLength) % pDmxfbuf->ulSize;   return;}/*----------------------------------------------------------------------------+|  DemuxSectioncallback+----------------------------------------------------------------------------*/static void DemuxSectionCallback(   XP_CHANNEL_NOTIFY_DATA * pInfo){   int                i;   int                j;   int                MatchCount = 0;   int                match[32];   ULONG              bytes_available;   ULONG              notify_length;   unsigned char      *data;   unsigned char      *b_data;   unsigned char      *e_data;   unsigned char      *s;   UCHAR              *ppBuffer;   DEMUX_FILTER       *pDmxfilter=NULL;   SECTION_HEADER_PTR SectionHeader;   GLOBAL_RESOURCES   *pGlobal;   DEMUX_DEVICE       *pDemuxDev;   PDEBUG1("DemuxSectioncallback(): Entering\n");   pGlobal = pInfo->pGlobal;   pDemuxDev = pDemux_dev[pGlobal->uDeviceIndex];   //Find the filter which matched the recieved section   for (i = 0; i < pDemuxDev->uFilterNum; i++)   {      if (pDemuxDev->filter[i].chid == pInfo->wChannelId &&         ((pDemuxDev->filter[i].ulMatchWord & pInfo->ulMatchWord) ==           pDemuxDev->filter[i].ulMatchWord))      {         match[MatchCount] = i;         MatchCount++;      }   }   if (!MatchCount)   {      printk("DemuxSectioncallback(): Error - no filter matched section received\n");      return;   }   for(j=0;j<MatchCount;j++)   {      i = match[j];      pDmxfilter = (DEMUX_FILTER *) (&pDemuxDev->filter[i]);      //If received section data 's size is smaller than 3 bytes, ehich is the minimum byte      //of the section. retun      if (pInfo->ulLength < 3)      {         ppBuffer = DemuxGetQPBase(pGlobal,pDmxfilter,pInfo->plData);         xp_osi_queue_unlock_data(pGlobal, pDmxfilter->chid,                (UCHAR *)ppBuffer, (ULONG)pInfo->ulLength);         printk("DemuxSectioncallback(): Error - notify length =0\n");         return;      }      //bytes_availbale is the size of the received data      bytes_available = pDmxfilter->buffer.plEQueue - pInfo->plData;      data = pInfo->plData;      SectionHeader = (SECTION_HEADER_PTR) (data);      //Notify_length is the size of a complete table section      notify_length = SectionHeader->sectionLength + 3;      if (SectionHeader->sectionLength == 0)      {         ppBuffer = DemuxGetQPBase(pGlobal,pDmxfilter,pInfo->plData);         xp_osi_queue_unlock_data(pGlobal, pDmxfilter->chid,                (UCHAR *) ppBuffer, (ULONG) pInfo->ulLength);         printk("DemuxSectioncallback(): Error - Section Filter length =0\n");         return;      }      if (notify_length > pInfo->ulLength)      {         ppBuffer = DemuxGetQPBase(pGlobal,pDmxfilter,pInfo->plData);         xp_osi_queue_unlock_data(pGlobal,pDmxfilter->chid,                (UCHAR *)ppBuffer, (ULONG)pInfo->ulLength);         printk("DemuxSectioncallback(): Warning - notify length > available_length\n");         notify_length = pInfo->ulLength;         return;      }      b_data = pInfo->plData;      if (notify_length >= bytes_available)      {         e_data = pDmxfilter->buffer.plBQueue + (notify_length - bytes_available);      } else {         e_data = pInfo->plData + notify_length;      }      pDmxfilter->ulNotifySize = notify_length;      //special process when the queue is wrap      if (pDmxfilter->buffer.plData)      {         if(pDmxfilter->buffer.count + notify_length >= pDmxfilter->buffer.ulSize)         {            printk("DemuxSectioncallback(): Error - Buffer is full\n");         } else {            for (i = 0, s = b_data; i < notify_length; i++, s++)            {               if (s == pDmxfilter->buffer.plEQueue)               {                  s = pDmxfilter->buffer.plBQueue;               }               pDmxfilter->buffer.count++;               pDmxfilter->buffer.ulWrite =                  (pDmxfilter->buffer.ulWrite + 1)%pDmxfilter->buffer.ulSize;               pDmxfilter->buffer.plData[pDmxfilter->buffer.ulWrite] = *s;            }         }      }      if(pDmxfilter->async_queue != NULL)        kill_fasync(&pDmxfilter->async_queue, SIGIO, POLL_IN);      // unlock queue      wake_up_interruptible(&pDmxfilter->buffer.queue);   }   ppBuffer = DemuxGetQPBase(pGlobal,pDmxfilter,pInfo->plData);   xp_osi_queue_unlock_data(pGlobal,pDmxfilter->chid,              (UCHAR *)ppBuffer, (ULONG)pInfo->ulLength);   return;}/*----------------------------------------------------------------------------+|  DemuxPESCallback+----------------------------------------------------------------------------*/static void DemuxPESCallback(   XP_CHANNEL_NOTIFY_DATA * pInfo){   int              i;   ULONG            BTrem;   UCHAR            *ppBuffer;   DEMUX_FILTER     *pDmxfilter;   DEMUX_DEVICE     *pDemuxDev;   GLOBAL_RESOURCES *pGlobal;   PDEBUG1("DemuxPESCallback(): Entering\n");   /*-------------------------------------------------------------------------+   |  Find Filter Associated with PES Callback   +-------------------------------------------------------------------------*/   pGlobal = pInfo->pGlobal;   pDemuxDev = pDemux_dev[pGlobal->uDeviceIndex];   for (i = 0; i < pDemuxDev->uFilterNum; i++) {      if (pDemuxDev->filter[i].chid == pInfo->wChannelId) {         break;      }   }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -