208 lines
5.2 KiB
C
208 lines
5.2 KiB
C
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dvdirq.c
|
|
|
|
Abstract:
|
|
|
|
Device interrupt logic for DVDTS
|
|
|
|
Environment:
|
|
|
|
Kernel mode only
|
|
|
|
Notes:
|
|
|
|
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
|
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
|
PURPOSE.
|
|
|
|
Copyright (c) 1998 Microsoft Corporation. All Rights Reserved.
|
|
|
|
Some portions adapted with permission from code Copyright (c) 1997-1998 Toshiba Corporation
|
|
|
|
Revision History:
|
|
|
|
5/1/98: created
|
|
|
|
--*/
|
|
#include "strmini.h"
|
|
#include "ksmedia.h"
|
|
|
|
#include "debug.h"
|
|
#include "dvdinit.h"
|
|
#include "dvdcmd.h"
|
|
#include "DvdTDCod.h" // header for DvdTDCod.lib routines hiding proprietary HW stuff
|
|
|
|
|
|
void HwIntDMA( PHW_DEVICE_EXTENSION pHwDevExt, UCHAR val );
|
|
|
|
|
|
/*
|
|
** HwInterrupt()
|
|
*/
|
|
BOOLEAN STREAMAPI HwInterrupt( IN PHW_DEVICE_EXTENSION pHwDevExt )
|
|
{
|
|
UCHAR val;
|
|
BOOLEAN fInterrupt = TRUE;
|
|
|
|
|
|
// interrupt may be shared; see if its ours and exactly which of ours it is
|
|
val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_INT );
|
|
|
|
// DebugPrint( (DebugLevelVerbose, "DVDTS:HwInterrupt 0x%x\r\n", (DWORD)val ) );
|
|
|
|
if( val & 0x03 ) {
|
|
HwIntDMA( pHwDevExt, (UCHAR)(val & 0x03) );
|
|
}
|
|
else if( val & 0x08 ) {
|
|
decHwIntVideo( pHwDevExt ); //routine in dvdtdcod.lib to hide propriotary stuff
|
|
}
|
|
else if( val & 0x10 ) {
|
|
decHwIntVSync( pHwDevExt ); ////routine in dvdtdcod.lib to hide propriotary stuff
|
|
}
|
|
else if( val != 0 ) {
|
|
DebugPrint( (DebugLevelTrace, "DVDTS:Interrupt! Not impliment\r\n") );
|
|
TRAP;
|
|
}
|
|
else {
|
|
// this can happen for a shared interrupt
|
|
// DebugPrint( (DebugLevelTrace, "DVDTS:Other Board Interrupt ??\r\n") );
|
|
// TRAP;
|
|
fInterrupt = FALSE;
|
|
}
|
|
|
|
|
|
|
|
return( fInterrupt );
|
|
}
|
|
|
|
void HwIntDMA( PHW_DEVICE_EXTENSION pHwDevExt, UCHAR val )
|
|
{
|
|
if( pHwDevExt->bKeyDataXfer ) {
|
|
|
|
if( val & 0x01 )
|
|
WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_INT, 0x01 );
|
|
else
|
|
TRAP;
|
|
|
|
pHwDevExt->pfnEndKeyData( pHwDevExt );
|
|
|
|
return;
|
|
}
|
|
|
|
if( val & 0x01 ) {
|
|
WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_INT, 0x01 );
|
|
|
|
if( pHwDevExt->pSrbDMA0 == NULL ) {
|
|
DebugPrint( (DebugLevelTrace, "DVDTS: Bad Status! DMA0 HwIntDMA\r\n") );
|
|
// TRAP;
|
|
return;
|
|
}
|
|
|
|
// error check for debug
|
|
{
|
|
UCHAR val;
|
|
val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_CNTL );
|
|
if( val & 0x01 ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS: Bad Irq? DMA0\r\n" ));
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if( pHwDevExt->fSrbDMA0last ) {
|
|
DebugPrint(( DebugLevelVerbose, "DVDTS:HWInt SrbDMA0 0x%x\r\n", pHwDevExt->pSrbDMA0 ) );
|
|
|
|
// must fix!
|
|
// other place that call StreamRequestComplete() does not clear pHwDevExt->bEndCpp;
|
|
|
|
if( ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->pfnEndSrb ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS:exist pfnEndSrb(HWint0) srb = 0x%x\r\n", pHwDevExt->pSrbDMA0 ));
|
|
if( pHwDevExt->pSrbDMA0 == pHwDevExt->pSrbDMA1 || pHwDevExt->pSrbDMA1 == NULL ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS:Call TimerCppReset(HWint0)\r\n" ));
|
|
StreamClassScheduleTimer(
|
|
NULL,
|
|
pHwDevExt,
|
|
// BUG - must fix
|
|
// need wait underflow?
|
|
500000,
|
|
((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->pfnEndSrb,
|
|
((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->parmSrb
|
|
);
|
|
}
|
|
}
|
|
|
|
pHwDevExt->pSrbDMA0->Status = STATUS_SUCCESS;
|
|
StreamClassStreamNotification( StreamRequestComplete,
|
|
pHwDevExt->pSrbDMA0->StreamObject,
|
|
pHwDevExt->pSrbDMA0 );
|
|
|
|
}
|
|
|
|
// Next DMA
|
|
pHwDevExt->pSrbDMA0 = NULL;
|
|
pHwDevExt->fSrbDMA0last = FALSE;
|
|
}
|
|
|
|
if( val & 0x02 ) {
|
|
WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_INT, 0x02 );
|
|
|
|
if( pHwDevExt->pSrbDMA1 == NULL ) {
|
|
DebugPrint( (DebugLevelTrace, "DVDTS: Bad Status! DMA1 HwIntDMA\r\n") );
|
|
// TRAP;
|
|
return;
|
|
}
|
|
|
|
// error check for debug
|
|
{
|
|
UCHAR val;
|
|
val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + IFLG_CNTL );
|
|
if( val & 0x02 ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS: Bad Irq? DMA1\r\n" ));
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if( pHwDevExt->fSrbDMA1last ) {
|
|
DebugPrint(( DebugLevelVerbose, "DVDTS:HWInt SrbDMA1 0x%x\r\n", pHwDevExt->pSrbDMA1 ) );
|
|
|
|
// must fix!
|
|
// other place that call StreamRequestComplete() does not clear pHwDevExt->bEndCpp;
|
|
|
|
if( ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->pfnEndSrb ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS:exist pfnEndSrb(HWint1) srb = 0x%x\r\n", pHwDevExt->pSrbDMA1 ));
|
|
if( pHwDevExt->pSrbDMA0 == NULL ) {
|
|
DebugPrint(( DebugLevelTrace, "DVDTS:Call TimerCppReset(HWint1)\r\n" ));
|
|
StreamClassScheduleTimer(
|
|
NULL,
|
|
pHwDevExt,
|
|
1,
|
|
((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->pfnEndSrb,
|
|
((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->parmSrb
|
|
);
|
|
}
|
|
}
|
|
|
|
pHwDevExt->pSrbDMA1->Status = STATUS_SUCCESS;
|
|
StreamClassStreamNotification( StreamRequestComplete,
|
|
pHwDevExt->pSrbDMA1->StreamObject,
|
|
pHwDevExt->pSrbDMA1 );
|
|
}
|
|
|
|
// Next DMA
|
|
pHwDevExt->pSrbDMA1 = NULL;
|
|
pHwDevExt->fSrbDMA1last = FALSE;
|
|
}
|
|
|
|
PreDMAxfer( pHwDevExt/*, val & 0x03 */);
|
|
}
|
|
|
|
|
|
|