📄 xp_osi_chann.c
字号:
/*----------------------------------------------------------------------------+| 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 : Ian Govett| Component : xp| File : xp_chann.c| Purpose : Channel Management Functions| Changes :|| Date: By Comment:| --------- --- --------| 15-Jan-98 IG Created| 30-Sep-01 LGH Ported to Linux, combine codes of 3 devices, take it as| part of os independent layer| 22-Jul-03 TJC Corrected bug in xp_osi_set_key and xp_osi_set_pid such that| UnloadType was used instead of Descram to set the Descrambler| enable bit.+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| Demux Channel Management+-----------------------------------------------------------------------------+| The following functions provide channel management services for the| MPEG transport driver. The xp0_channel_allocate() function allocates a| channel for the type specified. The transport demux hardware has one| audio (30), and one video (31) channel available for the driver. The| driver reserves a channel for subtitle (0), and one channel for| teletext (1). The remaining 28 channels (2..29) may be freely used by| the application. Allocation of all channels is managed by the driver| using the xp0_channel_allocate() function, which returns the channel id.| number. This wChannelId is used to define queues, attach filters, and| manage interrupts.|| After the channel is allocated, the xp0_channel_set_pid() defines the| pid value, and xp0_channel_set_unload_type() determines the type of data| (table sections, adaptation, payload, ...) to deliver to the queue| associated with the channel. See the transport specification for| information on the numerous unload types.|| The xp0_channel_set_notification_fn() registers the application callback| function. This function is called whenever data is available on the| channel. The callback function is provided with a pointer to the data,| length of the data, wChannelId, and a match word. The match word is| used for table section filtering to determine which filter(s) matched| the data.|| The xp0_channel_free() frees the channel and any associated resources| such as queues, filters, and pending interrupts.|| The application uses the xp0_channel_control() function to enable,| disable, or reset the channel.|+----------------------------------------------------------------------------*//* The necessary header files */#include <linux/config.h>#include <linux/version.h>#ifdef MODVERSIONS#include <linux/modversions.h>#endif#define __NO_VERSION__#include <linux/module.h>#include <linux/kernel.h>#include <linux/types.h>#include "xp_osi_global.h"#include "xp_atom_reg.h"/*----------------------------------------------------------------------------+| Local Defines+----------------------------------------------------------------------------*/#define CHANNEL_MIN 0/*----------------------------------------------------------------------------+| Define the list of interrupts to register for the table section channels+----------------------------------------------------------------------------*/#define CHANNEL_NOTIFY_SECTION_MASK XP_INTERRUPT_QSTAT_RPI | \ XP_INTERRUPT_QSTAT_TSC | \ XP_INTERRUPT_QSTAT_CRCE | \ XP_INTERRUPT_QSTAT_TSLE | \ XP_INTERRUPT_QSTAT_PSE#define CHANNEL_NOTIFY_STREAM_MASK XP_INTERRUPT_QSTAT_RPI | \ XP_INTERRUPT_QSTAT_BTI | \ XP_INTERRUPT_QSTAT_PSE//Internalstatic void channel_data_notify(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId,ULONG ulInterrupt);//External/*----------------------------------------------------------------------------+| 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+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| channel_data_notify+----------------------------------------------------------------------------*/static void channel_data_notify(GLOBAL_RESOURCES *pGlobal,SHORT wChannelId, ULONG ulInterrupt){ /*------------------------------------------------------------------------+ | Process available data +------------------------------------------------------------------------*/ if (ulInterrupt & (XP_INTERRUPT_QSTAT_TSC | XP_INTERRUPT_QSTAT_BTI)) { xp_osi_queue_process_data(pGlobal, wChannelId, pGlobal->ChannInfo.XpChannelData[wChannelId].UnloadType, pGlobal->ChannInfo.XpChannelData[wChannelId].notify_fn); } /*------------------------------------------------------------------------+ | Process errors data including the read pointer error +------------------------------------------------------------------------*/ xp_osi_queue_process_interrupt(pGlobal,wChannelId, ulInterrupt);}/*----------------------------------------------------------------------------+| XXXXXXX XXX XXX XXXXXX XXXXXXX XXXXXX XX XX XX XXXX| XX X XX XX X XX X XX X XX XX XXX XX XXXX XX| XX X XXX XX XX X XX XX XXXX XX XX XX XX| XXXX X XX XXXX XXXXX XX XXXX XX XX XX| XX X XXX XX XX X XX XX XX XXX XXXXXX XX| XX X XX XX XX XX X XX XX XX XX XX XX XX XX| XXXXXXX XXX XXX XXXX XXXXXXX XXX XX XX XX XX XX XXXXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| xp0_channel_get_status+----------------------------------------------------------------------------*/SHORT xp_osi_channel_get_status(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId, XP_CHANNEL_STATUS *pStatus){ SHORT wRc;// xp_os_semaphore_wait(); wRc = xp_osi_channel_valid(pGlobal,wChannelId); if(wRc == 0) { *pStatus = pGlobal->ChannInfo.XpChannelData[wChannelId].Status; }// xp_os_semaphore_signal(); return(wRc);}/*----------------------------------------------------------------------------+| xp0_channel_restart+----------------------------------------------------------------------------*/SHORT xp_osi_channel_restart(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId){ SHORT wRc; UINT32 flag;// xp_os_semaphore_wait(); PDEBUG("entering into xp_osi_channel_restart\n"); wRc = xp_osi_channel_valid(pGlobal,wChannelId); /*------------------------------------------------------------------------+ | Clear the interrupts to get rid of any latent interrupts +------------------------------------------------------------------------*/ if(wRc == 0) { PDEBUG("xp_osi_channel_valid success\n"); wRc = xp_osi_interrupt_channel_control(pGlobal, wChannelId, XP_INTERRUPT_CONTROL_RESET); } /*------------------------------------------------------------------------+ | Rewrite the pid to start the channel +------------------------------------------------------------------------*/ if(wRc == 0) { PDEBUG("xp_osi_interrupt_channel_control success\n"); if(pGlobal->ChannInfo.XpChannelData[wChannelId].Status == XP_CHANNEL_ENABLED) { PDEBUG(" if(pGlobal->ChannInfo.XpChannelData[wChannelId].Status == XP_CHANNEL_ENABLED)\n"); if(wChannelId == pGlobal->ChannInfo.wXpChannelBucketId) { flag = os_enter_critical_section(); xp_atom_dcr_write_register(pGlobal->uDeviceIndex, XP_BUCKET1Q_REG_INDX, pGlobal->ChannInfo.wXpChannelBucketId); os_leave_critical_section(flag); } else { flag = os_enter_critical_section(); xp_atom_dcr_write_register_channel(pGlobal->uDeviceIndex, XP_PID_FILTER_REG_PIDV, wChannelId, pGlobal->ChannInfo.XpChannelData[wChannelId].uwPid); os_leave_critical_section(flag); } } }// xp_os_semaphore_signal(); PDEBUG("before return\n"); return(wRc);}/*----------------------------------------------------------------------------+| xp_osi_channel_valid+----------------------------------------------------------------------------*/SHORT xp_osi_channel_valid(GLOBAL_RESOURCES *pGlobal, SHORT wChannelId){ if((wChannelId < CHANNEL_MIN) || (wChannelId >= XP_CHANNEL_COUNT)) { return((SHORT)XP_ERROR_CHANNEL_INVALID); } if((pGlobal->ChannInfo.XpChannelData[wChannelId].Status == XP_CHANNEL_UNUSED)) { return((SHORT)XP_ERROR_CHANNEL_UNUSED); } return(0);}/*----------------------------------------------------------------------------+| XX XXXXXX XXXXXX XXXXX| XXXX XX XX XX XX XX| XX XX XX XX XX XX| XX XX XXXXX XX XX| XXXXXX XX XX XX| XX XX XX XX XX XX| XX XX XX XXXXXX XXXXX+----------------------------------------------------------------------------*//*----------------------------------------------------------------------------+| xp0_channel_init+----------------------------------------------------------------------------*/SHORT xp_osi_channel_init(GLOBAL_RESOURCES *pGlobal){ short i; /*------------------------------------------------------------------------+ | Setup the channels +------------------------------------------------------------------------*/ for(i=0; i < XP_CHANNEL_COUNT; i++) { pGlobal->ChannInfo.XpChannelData[i].Status = XP_CHANNEL_UNUSED; pGlobal->ChannInfo.XpChannelData[i].uwPid = XP_CHANNEL_NULL_PID; } pGlobal->ChannInfo.wXpChannelBucketId = XP_CHANNEL_COUNT; return(0);}/*----------------------------------------------------------------------------+| xp0_channel_allocate+-----------------------------------------------------------------------------+|| DESCRIPTION: allocates a channel for the requested type|| PROTOTYPE : xp0_channel_allocate(| SHORT channel_type)|| ARGUMENTS : channel_type - type of data channel|| XP_CHANNEL_AUDIO - audio pes data| XP_CHANNEL_VIDEO - video pes data| XP_CHANNEL_SYSTEM - non audio/video data| XP_CHANNEL_TELETEXT- teletext data| XP_CHANNEL_PES - non audio/video data|| RETURNS : a channel id, or a negative value if an error occurs|| ERRORS : XP_ERROR_CHANNEL_INUSE|| COMMENTS : This reserves a new channel. Only 1 AUDIO, and 1 VIDEO| channel are available. This function fails with an error,| XP_ERROR_CHANNEL_INUSE if the audio or video channels have| not been freed.|+----------------------------------------------------------------------------*/SHORT xp_osi_channel_allocate(GLOBAL_RESOURCES *pGlobal, XP_CHANNEL_TYPE type){ SHORT wIndex; UINT32 flag;// xp_os_semaphore_wait(); switch(type) { case XP_CHANNEL_TYPE_AUDIO: wIndex = (pGlobal->ChannInfo.XpChannelData[XP_CHANNEL_AUDIO].Status == XP_CHANNEL_UNUSED) ? XP_CHANNEL_AUDIO : XP_ERROR_CHANNEL_INUSE; break; case XP_CHANNEL_TYPE_VIDEO: wIndex = (pGlobal->ChannInfo.XpChannelData[XP_CHANNEL_VIDEO].Status == XP_CHANNEL_UNUSED) ? XP_CHANNEL_VIDEO : XP_ERROR_CHANNEL_INUSE; break; case XP_CHANNEL_TYPE_SUBTITLE: wIndex = (pGlobal->ChannInfo.XpChannelData[XP_CHANNEL_SUBTITLE].Status == XP_CHANNEL_UNUSED) ? XP_CHANNEL_SUBTITLE : XP_ERROR_CHANNEL_INUSE; break; case XP_CHANNEL_TYPE_TELETEXT: wIndex = (pGlobal->ChannInfo.XpChannelData[XP_CHANNEL_TELETEXT].Status == XP_CHANNEL_UNUSED) ? XP_CHANNEL_TELETEXT : XP_ERROR_CHANNEL_INUSE; break; case XP_CHANNEL_TYPE_BUCKET: /*------------------------------------------------------------------------+ | Make sure we've not already allocated the bucket +------------------------------------------------------------------------*/ if(pGlobal->ChannInfo.wXpChannelBucketId != XP_CHANNEL_COUNT) { wIndex = XP_ERROR_CHANNEL_INUSE; } else { for(wIndex=XP_CHANNEL_PES_MAX; wIndex >= XP_CHANNEL_PES_MIN; wIndex--) { if (pGlobal->ChannInfo.XpChannelData[wIndex].Status == XP_CHANNEL_UNUSED) { pGlobal->ChannInfo.wXpChannelBucketId = wIndex; break; } } if(wIndex < XP_CHANNEL_PES_MIN) { wIndex = XP_ERROR_CHANNEL_INUSE; } } break; default: for(wIndex=XP_CHANNEL_PES_MAX; wIndex >= XP_CHANNEL_PES_MIN; wIndex--) { if(pGlobal->ChannInfo.XpChannelData[wIndex].Status == XP_CHANNEL_UNUSED) { break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -