2025-04-27 07:49:33 -04:00

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 */);
}