static OSDEV_IoctlEntrypoint( H264ppIoctl ) { OSDEV_Status_t Status; H264ppContext_t *H264ppContext; /* --- */ OSDEV_IoctlEntry(); H264ppContext = (H264ppContext_t *)OSDEV_PrivateData; switch( OSDEV_IoctlCode ) { case H264_PP_IOCTL_QUEUE_BUFFER: Status = H264ppIoctlQueueBuffer( H264ppContext, OSDEV_ParameterAddress ); break; case H264_PP_IOCTL_GET_PREPROCESSED_BUFFER: Status = H264ppIoctlGetPreprocessedBuffer( H264ppContext, OSDEV_ParameterAddress ); break; default: OSDEV_Print( "H264ppIoctl : Invalid ioctl %08x\n", OSDEV_IoctlCode ); Status = OSDEV_Error; } /* --- */ OSDEV_IoctlExit( Status ); }
static OSDEV_OpenEntrypoint( AllocatorOpen ) { AllocatorContext_t *AllocatorContext; // // Entry // OSDEV_OpenEntry(); // // Allocate and initialize the private data structure. // AllocatorContext = (AllocatorContext_t *)OSDEV_Malloc( sizeof(AllocatorContext_t) ); OSDEV_PrivateData = (void *)AllocatorContext; if( AllocatorContext == NULL ) { OSDEV_Print( "AllocatorOpen - Unable to allocate memory for open context.\n" ); OSDEV_OpenExit( OSDEV_Error ); } // memset( AllocatorContext, 0x00, sizeof(AllocatorContext_t) ); AllocatorContext->Size = 0; AllocatorContext->Memory = NULL; // OSDEV_OpenExit( OSDEV_NoError ); }
OS_Status_t OS_GetMessageCode(OS_MessageQueue_t Queue, unsigned int *Code, bool Blocking) { OSDEV_Print("%s not implemented\n", __FUNCTION__); return OS_ERROR; }
static void __exit StmUnloadModule (void) { Mpeg2InterruptUninstall(); UnMapRegisters(); OSDEV_Print("Module unloaded\n"); }
static int __init StmLoadModule(void) { MME_ERROR status = MME_SUCCESS; // Now do the MME Init status = MME_RegisterTransformer( mmeName, abortCmd, getTransformerCapability, initTransformer, processCommand, termTransformer); if (status == MME_SUCCESS) OSDEV_Print("%s loaded\n", MODULE_NAME); else OSDEV_Print("Error registering %s with MME (%d)\n", MODULE_NAME, status); return status; }
static OSDEV_CloseEntrypoint( AllocatorClose ) { AllocatorContext_t *AllocatorContext; // OSDEV_CloseEntry(); AllocatorContext = (AllocatorContext_t *)OSDEV_PrivateData; // // Perform the release activity // if( AllocatorContext->Memory != NULL ) { // Do what is necessary to free up any mapping here // OSDEV_Print( "Freeing up bpa 2 partition - phys %p - C %p - UC %p\n", AllocatorContext->PhysicalAddress,AllocatorContext->CachedAddress,AllocatorContext->UnCachedAddress); #if defined(MULTICOM406) ICS_ERROR IcsErr; IcsErr = ICS_region_remove(AllocatorContext->CachedRegion, 0); if( IcsErr != ICS_SUCCESS ) { OSDEV_Print( "Close Entry Point - Unable to remove Cached ICS region.\n" ); } IcsErr = ICS_region_remove(AllocatorContext->UnCachedRegion, 0); if( IcsErr != ICS_SUCCESS ) { OSDEV_Print( "Close Entry Point - Unable to remove Uncached ICS region.\n" ); } #endif OSDEV_IOUnMap( (unsigned int)AllocatorContext->UnCachedAddress ); OSDEV_IOUnMap( (unsigned int)AllocatorContext->CachedAddress ); OSDEV_FreePartitioned( AllocatorContext->PartitionName, AllocatorContext->PhysicalAddress ); } OSDEV_Free( AllocatorContext ); // OSDEV_CloseExit( OSDEV_NoError ); }
static OSDEV_Status_t AllocatorIoctlAllocateData( AllocatorContext_t *AllocatorContext, unsigned int ParameterAddress ) { allocator_ioctl_allocate_t params; // OSDEV_CopyToDeviceSpace( ¶ms, ParameterAddress, sizeof(allocator_ioctl_allocate_t) ); // AllocatorContext->Size = params.RequiredSize; memcpy( AllocatorContext->PartitionName, params.PartitionName, ALLOCATOR_MAX_PARTITION_NAME_SIZE ); // AllocatorContext->Memory = OSDEV_MallocPartitioned( AllocatorContext->PartitionName, AllocatorContext->Size ); if( AllocatorContext->Memory == NULL ) { OSDEV_Print( "AllocatorIoctlAllocateData : Unable to allocate memory\n" ); return OSDEV_Error; } // // The memory supplied by BPA2 is physical, get the necessary mappings // AllocatorContext->CachedAddress = NULL; AllocatorContext->UnCachedAddress = NULL; AllocatorContext->PhysicalAddress = NULL; AllocatorContext->CachedAddress = ioremap_cache((unsigned int)AllocatorContext->Memory,AllocatorContext->Size); AllocatorContext->PhysicalAddress = AllocatorContext->Memory ; AllocatorContext->UnCachedAddress = (unsigned char *)OSDEV_IOReMap( (unsigned int)AllocatorContext->PhysicalAddress, AllocatorContext->Size ); /* OSDEV_Print("Alloc - Phys %p - C %p - UC %p -- Size 0x%x\n",AllocatorContext->PhysicalAddress, AllocatorContext->CachedAddress, AllocatorContext->UnCachedAddress,AllocatorContext->Size); */ // // Copy the data into the parameters and pass back // params.CachedAddress = AllocatorContext->CachedAddress; params.UnCachedAddress = AllocatorContext->UnCachedAddress; params.PhysicalAddress = AllocatorContext->PhysicalAddress; OSDEV_CopyToUserSpace( ParameterAddress, ¶ms, sizeof(allocator_ioctl_allocate_t) ); // return OSDEV_NoError; }
static OSDEV_Status_t H264ppIoctlGetPreprocessedBuffer( H264ppContext_t *H264ppContext, unsigned int ParameterAddress ) { h264pp_ioctl_dequeue_t params; H264ppProcessedBuffer_t *Record; // do { // // Anything to report // if( H264ppContext->BufferProcessed[H264ppContext->BufferProcessedExtract].Filled ) { Record = &H264ppContext->BufferProcessed[H264ppContext->BufferProcessedExtract++]; H264ppContext->BufferProcessedExtract %= H264_PP_MAX_SUPPORTED_BUFFERS; #if 0 if( Record->PP_ITS != PP_ITM__DMA_CMP ) printk( "H264ppIoctlGPB (PP %d) - Took %dms - ITS = %04x - QID = %d\n", Record->PP, Record->DecodeTime, Record->PP_ITS, Record->QueueIdentifier ); #endif // // Take the buffer // params.QueueIdentifier = Record->QueueIdentifier; params.OutputSize = Record->OutputSize; params.ErrorMask = Record->PP_ITS & ~(PP_ITM__SRS_COMP | PP_ITM__DMA_CMP); OSDEV_CopyToUserSpace( ParameterAddress, ¶ms, sizeof(h264pp_ioctl_dequeue_t) ); // // Free up the record for re-use // Record->Filled = 0; OSDEV_ReleaseSemaphore( &H264ppContext->ProcessedBufferListEntry ); return OSDEV_NoError; } // // Wait for a buffer completed signal // OSDEV_ClaimSemaphore( &H264ppContext->ProcessedBuffer ); } while( !H264ppContext->Closing ); // OSDEV_Print( "H264ppIoctlGetPreprocessedBuffer - device closing.\n" ); return OSDEV_Error; }
static OSDEV_MmapEntrypoint( H264ppMmap ) { H264ppContext_t *H264ppContext; OSDEV_Status_t MappingStatus; // OSDEV_MmapEntry(); H264ppContext = (H264ppContext_t *)OSDEV_PrivateData; // OSDEV_Print( "H264ppMmap - No allocated memory to map.\n" ); MappingStatus = OSDEV_Error; // OSDEV_MmapExit( MappingStatus ); }
static OSDEV_IoctlEntrypoint( AllocatorIoctl ) { OSDEV_Status_t Status; AllocatorContext_t *AllocatorContext; /* --- */ OSDEV_IoctlEntry(); AllocatorContext = (AllocatorContext_t *)OSDEV_PrivateData; switch( OSDEV_IoctlCode ) { case ALLOCATOR_IOCTL_ALLOCATE_DATA: Status = AllocatorIoctlAllocateData( AllocatorContext, OSDEV_ParameterAddress ); break; default: OSDEV_Print( "AllocatorIoctl : Invalid ioctl %08x\n", OSDEV_IoctlCode ); Status = OSDEV_Error; } /* --- */ OSDEV_IoctlExit( Status ); }
static OSDEV_Status_t AllocatorIoctlAllocateData( AllocatorContext_t *AllocatorContext, unsigned int ParameterAddress ) { allocator_ioctl_allocate_t params; #if defined(MULTICOM406) ICS_ERROR IcsErr; #endif // OSDEV_CopyToDeviceSpace( ¶ms, ParameterAddress, sizeof(allocator_ioctl_allocate_t) ); // AllocatorContext->Size = params.RequiredSize; memcpy( AllocatorContext->PartitionName, params.PartitionName, ALLOCATOR_MAX_PARTITION_NAME_SIZE ); // AllocatorContext->Memory = OSDEV_MallocPartitioned( AllocatorContext->PartitionName, AllocatorContext->Size ); if( AllocatorContext->Memory == NULL ) { OSDEV_Print( "AllocatorIoctlAllocateData : Unable to allocate memory\n" ); return OSDEV_Error; } // // The memory supplied by BPA2 is physical, get the necessary mappings // AllocatorContext->CachedAddress = NULL; AllocatorContext->UnCachedAddress = NULL; AllocatorContext->PhysicalAddress = NULL; AllocatorContext->CachedAddress = ioremap_cache((unsigned int)AllocatorContext->Memory,AllocatorContext->Size); AllocatorContext->PhysicalAddress = AllocatorContext->Memory ; AllocatorContext->UnCachedAddress = (unsigned char *)OSDEV_IOReMap( (unsigned int)AllocatorContext->PhysicalAddress, AllocatorContext->Size ); #if defined(MULTICOM406) IcsErr = ICS_region_add(AllocatorContext->CachedAddress, AllocatorContext->PhysicalAddress, AllocatorContext->Size, ICS_CACHED, ics_cpu_mask(), &AllocatorContext->CachedRegion); if( IcsErr != ICS_SUCCESS ) { OSDEV_Print( "AllocatorIoctlAllocateData : - Unable to allocate Cached ICS region.\n" ); return OSDEV_Error; } IcsErr = ICS_region_add(AllocatorContext->UnCachedAddress, AllocatorContext->PhysicalAddress, AllocatorContext->Size, ICS_UNCACHED, ics_cpu_mask(), &AllocatorContext->UnCachedRegion); if( IcsErr != ICS_SUCCESS ) { OSDEV_Print( "AllocatorIoctlAllocateData : - Unable to allocate Uncached ICS region.\n" ); return OSDEV_Error; } #endif /* OSDEV_Print("Alloc - Phys %p - C %p - UC %p -- Size 0x%x\n",AllocatorContext->PhysicalAddress, AllocatorContext->CachedAddress, AllocatorContext->UnCachedAddress,AllocatorContext->Size); */ // // Copy the data into the parameters and pass back // params.CachedAddress = AllocatorContext->CachedAddress; params.UnCachedAddress = AllocatorContext->UnCachedAddress; params.PhysicalAddress = AllocatorContext->PhysicalAddress; OSDEV_CopyToUserSpace( ParameterAddress, ¶ms, sizeof(allocator_ioctl_allocate_t) ); // return OSDEV_NoError; }
OS_Status_t OS_SendMessageCode(OS_MessageQueue_t Queue, unsigned int Code) { OSDEV_Print("%s not implemented\n", __FUNCTION__); return OS_ERROR; }
OS_Status_t OS_InitializeMessageQueue(OS_MessageQueue_t *Queue) { OSDEV_Print("%s not implemented\n", __FUNCTION__); return OS_ERROR; }
static void H264ppWorkAroundGNBvd42331( H264ppIndividualContext_t *SubContext, unsigned int N ) { unsigned int i; unsigned int mb_adaptive_frame_field_flag; unsigned int entropy_coding_mode_flag; unsigned int PerformWorkaround; unsigned int SavedITM; unsigned int BufferBase; unsigned int SourceAddress; unsigned int EndAddress; unsigned int SliceErrorStatusAddress; unsigned int IntermediateAddress; unsigned int IntermediateEndAddress; // // Do we have to worry. // mb_adaptive_frame_field_flag = ((SubContext->Parameters.Cfg & 1) != 0); entropy_coding_mode_flag = ((SubContext->Parameters.Cfg & 2) != 0); PerformWorkaround = !mb_adaptive_frame_field_flag && SubContext->last_mb_adaptive_frame_field_flag && entropy_coding_mode_flag; SubContext->last_mb_adaptive_frame_field_flag = mb_adaptive_frame_field_flag; if( !PerformWorkaround && !SubContext->ForceWorkAroundGNBvd42331 ) return; //OSDEV_Print( "H264ppWorkAroundGNBvd42331 - Deploying GNBvd42331 workaround block to PP %d - %08x.\n", N, SubContext->Parameters.Cfg ); SubContext->ForceWorkAroundGNBvd42331 = 0; // // we transfer the workaround stream to the output buffer (offset by 64k to not interfere with the output). // memcpy( (void *)((unsigned int)SubContext->Parameters.BufferCachedAddress + 0x10000), GNBvd42331Data, sizeof(GNBvd42331Data) ); GNBvd42331DataPhysicalAddress = (unsigned char *)SubContext->Parameters.BufferPhysicalAddress + 0x10000; #ifdef __TDT__ /* found somewhere this patch which should increase performance about 1%. * ->should be revised! */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30) dma_cache_wback((SubContext->Parameters.BufferCachedAddress + 0x10000),sizeof(GNBvd42331Data)); #else writeback_ioremap_region(0, (SubContext->Parameters.BufferCachedAddress + 0x10000), 0, sizeof(GNBvd42331Data)); #endif #else flush_cache_all(); #endif // // Derive the pointers - we use the next buffer to be queued as output as our output // BufferBase = (unsigned int)SubContext->Parameters.BufferPhysicalAddress; SliceErrorStatusAddress = BufferBase; IntermediateAddress = BufferBase + H264_PP_SESB_SIZE; IntermediateEndAddress = IntermediateAddress + H264_PP_OUTPUT_SIZE - 1; SourceAddress = (unsigned int)GNBvd42331DataPhysicalAddress; EndAddress = (unsigned int)GNBvd42331DataPhysicalAddress + sizeof(GNBvd42331Data) - 1; // // Launch the workaround block // SavedITM = OSDEV_ReadLong(PP_ITM(N)); // Turn off interrupts OSDEV_WriteLong( PP_ITM(N), 0 ); OSDEV_WriteLong( PP_BBG(N), (SourceAddress & 0xfffffff8) ); OSDEV_WriteLong( PP_BBS(N), (EndAddress | 0x7) ); OSDEV_WriteLong( PP_READ_START(N), SourceAddress ); OSDEV_WriteLong( PP_READ_STOP(N), EndAddress ); OSDEV_WriteLong( PP_ISBG(N), SliceErrorStatusAddress ); OSDEV_WriteLong( PP_IPBG(N), IntermediateAddress ); OSDEV_WriteLong( PP_IBS(N), IntermediateEndAddress ); OSDEV_WriteLong( PP_CFG(N), GNBvd42331_CFG ); OSDEV_WriteLong( PP_PICWIDTH(N), GNBvd42331_PICWIDTH ); OSDEV_WriteLong( PP_CODELENGTH(N), GNBvd42331_CODELENGTH ); OSDEV_WriteLong( PP_ITS(N), 0xffffffff ); // Clear interrupt status OSDEV_WriteLong( PP_START(N), 1 ); // // Wait for it to complete // for( i=0; i<H264_PP_RESET_TIME_LIMIT; i++ ) { OSDEV_SleepMilliSeconds( 1 ); if( (OSDEV_ReadLong(PP_ITS(N)) & PP_ITM__DMA_CMP) != 0 ) break; } if( (i == H264_PP_RESET_TIME_LIMIT) || (OSDEV_ReadLong(PP_ITS(N)) != PP_ITM__DMA_CMP) ) OSDEV_Print( "H264ppWorkAroundGNBvd42331 - Failed to execute GNBvd42331 workaround block to PP %d (ITS %08x).\n", N, OSDEV_ReadLong(PP_ITS(N)) ); // // Restore the interrupts // OSDEV_WriteLong( PP_ITS(N), 0xffffffff ); // Clear interrupt status OSDEV_WriteLong( PP_ITM(N), SavedITM ); }
static OSDEV_Status_t H264ppIoctlQueueBuffer( H264ppContext_t *H264ppContext, unsigned int ParameterAddress ) { unsigned int i; H264ppIndividualContext_t *SubContext; h264pp_ioctl_queue_t *params; unsigned int N; unsigned int BufferBase; unsigned int SourceAddress; unsigned int EndAddress; unsigned int SliceErrorStatusAddress; unsigned int IntermediateAddress; unsigned int IntermediateEndAddress; // // Claim resources // OSDEV_ClaimSemaphore( &H264ppContext->ProcessedBufferListEntry ); // Claim somewhere to store a record of the preprocessor output OSDEV_ClaimSemaphore( &H264ppContext->PreProcessor ); // Claim the preprocessor hardware if( H264ppContext->Closing ) { OSDEV_Print( "H264ppIoctlQueueBuffer - device closing.\n" ); return OSDEV_Error; } for( i=0; i<H264_PP_PER_INSTANCE; i++ ) if( !H264ppContext->SubContext[i].Busy ) { SubContext = &H264ppContext->SubContext[i]; N = H264ppContext->Index + i; SubContext->Busy = 1; break; } if( i >= H264_PP_PER_INSTANCE ) { OSDEV_Print( "H264ppIoctlQueueBuffer - No free sub-context - implementation error (should be one, the semaphore says there is).\n" ); return OSDEV_Error; } // params = &SubContext->Parameters; OSDEV_CopyToDeviceSpace( params, ParameterAddress, sizeof(h264pp_ioctl_queue_t) ); // // Optionally check for and perform the workaround to GNBvd42331 // if( h264_pp_workaround_gnbvd42331 ) H264ppWorkAroundGNBvd42331( SubContext, N ); // // Calculate the address values // BufferBase = (unsigned int)params->BufferPhysicalAddress; SliceErrorStatusAddress = BufferBase; IntermediateAddress = BufferBase + H264_PP_SESB_SIZE; IntermediateEndAddress = IntermediateAddress + H264_PP_OUTPUT_SIZE - 1; SourceAddress = IntermediateAddress + H264_PP_OUTPUT_SIZE; EndAddress = SourceAddress + params->InputSize - 1; // // Program the preprocessor // // Standard pre-processor initialization // flush_cache_all(); OSDEV_WriteLong( PP_ITS(N), 0xffffffff ); // Clear interrupt status #if 1 OSDEV_WriteLong( PP_ITM(N), PP_ITM__BIT_BUFFER_OVERFLOW | // We are interested in every interrupt PP_ITM__BIT_BUFFER_UNDERFLOW | PP_ITM__INT_BUFFER_OVERFLOW | PP_ITM__ERROR_BIT_INSERTED | PP_ITM__ERROR_SC_DETECTED | PP_ITM__SRS_COMP | PP_ITM__DMA_CMP ); #else OSDEV_WriteLong( PP_ITM(N), PP_ITM__DMA_CMP ); #endif // // Setup the decode // OSDEV_WriteLong( PP_BBG(N), (SourceAddress & 0xfffffff8) ); OSDEV_WriteLong( PP_BBS(N), (EndAddress | 0x7) ); OSDEV_WriteLong( PP_READ_START(N), SourceAddress ); OSDEV_WriteLong( PP_READ_STOP(N), EndAddress ); OSDEV_WriteLong( PP_ISBG(N), SliceErrorStatusAddress ); OSDEV_WriteLong( PP_IPBG(N), IntermediateAddress ); OSDEV_WriteLong( PP_IBS(N), IntermediateEndAddress ); OSDEV_WriteLong( PP_CFG(N), PP_CFG__CONTROL_MODE__START_STOP | params->Cfg ); OSDEV_WriteLong( PP_PICWIDTH(N), params->PicWidth ); OSDEV_WriteLong( PP_CODELENGTH(N), params->CodeLength ); // // Launch the pre-processor // SubContext->BufferProcessedInsert = H264ppContext->BufferProcessedInsert++; SubContext->DecodeTime = OSDEV_GetTimeInMilliSeconds(); SubContext->Accumulated_ITS = 0; OSDEV_WriteLong( PP_START(N), 1 ); // H264ppContext->BufferProcessedInsert %= H264_PP_MAX_SUPPORTED_BUFFERS; // return OSDEV_NoError; }
static OSDEV_OpenEntrypoint( H264ppOpen ) { unsigned int i,j; H264ppContext_t *H264ppContext; int Status; unsigned int N; // // Entry // OSDEV_OpenEntry(); // // Is there a set of PPs to get. // OSDEV_ClaimSemaphore( &Lock ); if( OpenMask == ((1 << H264_PP_NUMBER_OF_PRE_PROCESSORS) - 1) ) { OSDEV_Print( "H264ppOpen - Too many opens.\n" ); OSDEV_ReleaseSemaphore( &Lock ); OSDEV_OpenExit( OSDEV_Error ); } // // Allocate and initialize the private data structure. // H264ppContext = (H264ppContext_t *)OSDEV_Malloc( sizeof(H264ppContext_t) ); OSDEV_PrivateData = (void *)H264ppContext; if( H264ppContext == NULL ) { OSDEV_Print( "H264ppOpen - Unable to allocate memory for open context.\n" ); OSDEV_ReleaseSemaphore( &Lock ); OSDEV_OpenExit( OSDEV_Error ); } // memset( H264ppContext, 0x00, sizeof(H264ppContext_t) ); H264ppContext->Closing = false; // // Find a free pair of PPs // for( H264ppContext->Index = 0; ((OpenMask & (H264_PP_PER_INSTANCE_MASK<<H264ppContext->Index)) != 0); H264ppContext->Index += H264_PP_PER_INSTANCE ); OpenMask |= (H264_PP_PER_INSTANCE_MASK<<H264ppContext->Index); // // Initialize the processed buffer list indices // H264ppContext->BufferProcessedInsert = 0; H264ppContext->BufferProcessedExtract = 0; // // Initialize the semaphores // OSDEV_InitializeSemaphore( &H264ppContext->PreProcessor, H264_PP_PER_INSTANCE ); // No one currently using the pre-processors - so they are free OSDEV_InitializeSemaphore( &H264ppContext->ProcessedBufferListEntry, H264_PP_MAX_SUPPORTED_BUFFERS ); // The table contains this many entries OSDEV_InitializeSemaphore( &H264ppContext->ProcessedBuffer, 0 ); // There are no processed buffers to signal // // Ensure we will have no interrupt surprises and install the interrupt handler // for( i=0; i<H264_PP_PER_INSTANCE; i++ ) { N = H264ppContext->Index + i; OSDEV_WriteLong( PP_ITS(N), 0xffffffff ); // Clear interrupt status OSDEV_WriteLong( PP_ITM(N), 0x00000000 ); // // Initialize subcontect data // H264ppContext->SubContext[i].ForceWorkAroundGNBvd42331 = 1; H264ppContext->SubContext[i].last_mb_adaptive_frame_field_flag = 0; // Doesn't matter, will be initialized on first frame // // Perform soft reset // OSDEV_WriteLong( PP_SRS(N), 1 ); // Perform a soft reset for( j=0; j<H264_PP_RESET_TIME_LIMIT; j++ ) { if( (OSDEV_ReadLong(PP_ITS(N)) & PP_ITM__SRS_COMP) != 0 ) break; OSDEV_SleepMilliSeconds( 1 ); } if( j == H264_PP_RESET_TIME_LIMIT ) OSDEV_Print( "H264ppOpen - Failed to soft reset PP %d.\n", N ); OSDEV_WriteLong( PP_ITS(N), 0xffffffff ); // Clear interrupt status // OSDEV_WriteLong( PP_MAX_OPC_SIZE(N), 5 ); // Setup the ST bus parameters OSDEV_WriteLong( PP_MAX_CHUNK_SIZE(N), 0 ); OSDEV_WriteLong( PP_MAX_MESSAGE_SIZE(N), 3 ); // Status = request_irq( H264_PP_INTERRUPT(N), H264ppInterruptHandler, 0, "H264 PP", (void *)((unsigned int)H264ppContext + i) ); if( Status != 0 ) { OSDEV_Print( "H264ppOpen - Unable to request an IRQ for PP %d.\n", N ); OSDEV_DeInitializeSemaphore( &H264ppContext->PreProcessor ); OSDEV_DeInitializeSemaphore( &H264ppContext->ProcessedBufferListEntry ); OSDEV_DeInitializeSemaphore( &H264ppContext->ProcessedBuffer ); for( j=0; j<i; j++ ) free_irq( H264_PP_INTERRUPT((H264ppContext->Index + j)), (void *)((unsigned int)H264ppContext+j) ); OpenMask ^= (H264_PP_PER_INSTANCE_MASK<<H264ppContext->Index); OSDEV_ReleaseSemaphore( &Lock ); OSDEV_OpenExit( OSDEV_Error ); } } // OSDEV_ReleaseSemaphore( &Lock ); OSDEV_OpenExit( OSDEV_NoError ); }