📄 oemioctl.c
字号:
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
case IOCTL_HAL_ALLOCATE_DMA_CHANNEL:
EnterCriticalSection(&csDMAChannelAllocation);
if( !AllocateDMAChannel((PALLOCATE_DMA_PARAMS)lpInBuf,
(PALLOCATE_DMA_RESULT)lpOutBuf) )
{
LeaveCriticalSection(&csDMAChannelAllocation);
return FALSE;
}
{
int InitAudioDmaTransfer( PALLOCATE_DMA_PARAMS param , PALLOCATE_DMA_RESULT result);
InitAudioDmaTransfer( (PALLOCATE_DMA_PARAMS)lpInBuf, (PALLOCATE_DMA_RESULT)lpOutBuf) ;
}
LeaveCriticalSection(&csDMAChannelAllocation);
break;
case IOCTL_HAL_INITIALIZE_DMA_CHANNEL:
if( !InitializeDMAChannel((PINITIALIZE_DMA_PARAMS)lpInBuf,
(PINITIALIZE_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_FREE_DMA_CHANNEL:
EnterCriticalSection(&csDMAChannelAllocation);
if( !FreeDMAChannel((PFREE_DMA_PARAMS)lpInBuf,
(PFREE_DMA_RESULT)lpOutBuf) )
{
LeaveCriticalSection(&csDMAChannelAllocation);
return FALSE;
}
LeaveCriticalSection(&csDMAChannelAllocation);
break;
case IOCTL_HAL_START_DMA_TRANSFER:
if( !StartDMATransfer((PSTART_DMA_PARAMS)lpInBuf,
(PSTART_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_HALT_DMA_TRANSFER:
if( !HaltDMATransfer((PHALT_DMA_PARAMS)lpInBuf,
(PHALT_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_RESTART_DMA_TRANSFER:
if( !RestartDMATransfer((PRESTART_DMA_PARAMS)lpInBuf,
(PRESTART_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_STOP_DMA_TRANSFER:
if( !StopDMATransfer((PSTOP_DMA_PARAMS)lpInBuf,
(PSTOP_DMA_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_GET_ERROR_STATUS:
if( !GetErrorStatus((PGET_ERROR_PARAMS)lpInBuf,
(PGET_ERROR_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_CLEAR_ERROR_STATUS:
if( !ClearErrorStatus((PCLEAR_ERROR_PARAMS)lpInBuf,
(PCLEAR_ERROR_RESULT)lpOutBuf) )
return FALSE;
break;
case IOCTL_HAL_FREE_DMA_SYSINTR:
if( !FreeDmaSysIntr((PFREE_DMA_SYSINTR_PARAMS)lpInBuf,
(PFREE_DMA_SYSINTR_RESULT)lpOutBuf) )
return FALSE;
break;
case HAL_IOCTL_GPIO :
{
if( lpInBuf )
{
OEM_IOCTL_GPIO* gpio = (OEM_IOCTL_GPIO*)lpInBuf;
return SharedGPIOControl( gpio->num , gpio->pin , gpio->code , gpio->value ) ;
}
return FALSE;
}
break;
case HAL_IOCTL_AACI_DMA:
{
int StartAudioDmaTransfer( PSTART_DMA_PARAMS params , int*buffered );
int ret;
ret = StartAudioDmaTransfer( (PSTART_DMA_PARAMS)lpInBuf , (int*)lpOutBuf );
if( ret == 0 )
return TRUE;
else
return FALSE;
}
break;
case HAL_IOCTL_AACI_GETBUFFER:
{
int GetAudioDmaStatus( int*, int* );
GetAudioDmaStatus( (int*)lpInBuf , (int*)lpOutBuf );
return TRUE;
}
break;
case HAL_IOCTL_AACI_CLEARSTATUS:
{
int ClearAudioDmaStatus( int , int );
ClearAudioDmaStatus( *(int*)lpInBuf , *(int*)lpOutBuf );
return TRUE;
}
default:
#ifdef INTERNAL_HAL_TESTING
if (!InternalHalTesting(dwIoControlCode, lpInBuf,
nInBufSize, lpOutBuf,
nOutBufSize, lpBytesReturned))
{
return(FALSE);
}
break;
#endif
SetLastError(ERROR_NOT_SUPPORTED);
return(FALSE);
// Post kernel-init initialization, good place to initialize critical sections
case IOCTL_HAL_POSTINIT:
// Initialize critical sections
InitializeCriticalSection(&csWakeIntMask);
InitializeCriticalSection(&csRequestSysIntr);
InitializeCriticalSection(&csDMAChannelAllocation);
return TRUE;
}
return(TRUE);
}
static int PlayAudioStart = 0;
static int RecordAudioStart = 0;
#define AudioMaxBuffer 3
static struct AudioDmaData
{
DWORD interrupt;
int channel;
START_DMA_PARAMS param[AudioMaxBuffer];
DWORD pagelist[AudioMaxBuffer][0x1000];
DWORD fifo[AudioMaxBuffer];
int addindex;
int completeindex;
}PlayConfig , RecordConfig;
int InitAudioDmaTransfer( PALLOCATE_DMA_PARAMS param , PALLOCATE_DMA_RESULT result)
{
if( param->ucDestDevice == 14 && param->ucSourceDevice == 0 )
{
PlayConfig.interrupt = result->dwInterruptID;
PlayConfig.channel = result->ucChannelNumber;
PlayConfig.addindex = PlayConfig.completeindex = 0;
PlayAudioStart = 1;
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : play init %d %d\r\n" ) , PlayConfig.interrupt ,PlayConfig.channel ));
}
else if( param->ucDestDevice == 0 && param->ucSourceDevice == 13 )
{
RecordConfig.interrupt = result->dwInterruptID;
RecordConfig.channel = result->ucChannelNumber;
RecordAudioStart = 1;
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : record init %d %d\r\n" ) , RecordConfig.interrupt ,RecordConfig.channel ));
}
return 0;
}
int ClearAudioDmaStatus( int play , int record)
{
struct AudioDmaData* config;
if( play )
{
STOP_DMA_PARAMS param;
config = &PlayConfig;
param.ucChannelNumber = config->channel;
OEMInterruptDisable( config->interrupt );
StopDMATransfer( ¶m , 0 );
OEMInterruptEnable( config->interrupt , 0 , 0 );
config->addindex = config->completeindex = 0;
}
if( record )
{
STOP_DMA_PARAMS param;
config = &RecordConfig;
param.ucChannelNumber = config->channel;
OEMInterruptDisable( config->interrupt );
StopDMATransfer( ¶m , 0 );
OEMInterruptEnable( config->interrupt , 0 , 0 );
config->addindex = config->completeindex = 0;
}
return 0;
}
int GetAudioDmaStatus( int*play , int*record )
{
if( play )
*play = PlayConfig.addindex - PlayConfig.completeindex;
if( record )
*record = RecordConfig.addindex - RecordConfig.completeindex;
return 0;
}
int maxback = 0;
int StartAudioDmaTransfer( PSTART_DMA_PARAMS params , int*buffered )
{
int error = 0;
if( params->ucChannelNumber == PlayConfig.channel )
{
struct AudioDmaData* config = &PlayConfig;
if( config->addindex - config->completeindex < AudioMaxBuffer )
{
int index = config->addindex%AudioMaxBuffer ;
int pagecnt = ( params->dwTransferSize + (params->pdwSourceBuffer[0]&0xfff) + 0xfff ) / 0x1000;
config->param[index] = *params;
memcpy( config->pagelist[index] , params->pdwSourceBuffer , pagecnt*sizeof(DWORD) );
config->fifo[index] = params->pdwDestBuffer[0];
config->param[index].pdwSourceBuffer = config->pagelist[index];
config->param[index].pdwDestBuffer = &config->fifo[index];
config->addindex ++;
if( config->addindex - config->completeindex == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : do dma transfer\r\n" ) ));
OEMInterruptEnable( config->interrupt , NULL , 0 );
if( !StartDMATransfer( params, 0 ) )
{
error = 2;
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : dma error \r\n" ) ));
}
else
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : start dma ok\r\n" ) ));
}
*buffered = config->addindex - config->completeindex;
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : add dma buffer %d\r\n" ),
config->addindex ));
}
else
{
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : too many buffers\r\n" ) ));
error = 1;
}
}
else if( params->ucChannelNumber == RecordConfig.channel )
{
struct AudioDmaData* config = &RecordConfig;
if( config->addindex - config->completeindex < AudioMaxBuffer )
{
int index = config->addindex%AudioMaxBuffer ;
int pagecnt = ( params->dwTransferSize + (params->pdwDestBuffer[0]&0xfff) + 0xfff ) / 0x1000;
config->param[index] = *params;
memcpy( config->pagelist[index] , params->pdwDestBuffer , pagecnt*sizeof(DWORD) );
config->fifo[index] = params->pdwSourceBuffer[0];
config->param[index].pdwSourceBuffer = &config->fifo[index];
config->param[index].pdwDestBuffer = config->pagelist[index];
config->addindex ++;
if( config->addindex - config->completeindex == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("kernel : do record dma\r\n" ) ));
maxback = 0;
OEMInterruptEnable( config->interrupt , NULL , 0 );
if( !StartDMATransfer( params, 0 ) )
error = 3;
}
else
RETAILMSG( (DebugMsgMask&DebugMsg_Normal) , (TEXT("backup record dma\r\n")));
*buffered = config->addindex - config->completeindex;
}
else
{
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : too many record buffers %d\r\n" ) ,
config->addindex = config->completeindex));
error = 2;
}
}
else
error = -1;
return error;
}
int CompleteAudioDmaTransfer( DWORD interrupt )
{
int error = 0;
struct AudioDmaData* config;
if( interrupt == PlayConfig.interrupt && PlayAudioStart == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : complete play interrupt\r\n" ) ));
config = &PlayConfig;
}
else if( interrupt == RecordConfig.interrupt && RecordAudioStart == 1 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : complete record interrupt\r\n" ) ));
config = &RecordConfig;
}
else
error = -1;
if( !error )
{
if( config->addindex - config->completeindex > 0 )
{
RETAILMSG( (DebugMsgMask&DebugMsg_Trace) , (TEXT("kernel : complete dma transfer %d %d\r\n" ),
config->addindex , config->completeindex));
config->completeindex ++;
if( config->addindex - config->completeindex > 0 )
{
int index = config->completeindex % AudioMaxBuffer;
OEMInterruptEnable( interrupt , NULL , 0 );
StartDMATransfer( &config->param[index] , 0 );
maxback ++;
}
else
{
static volatile PDMAC_REGS pDMACRegs = (PDMAC_REGS)DMAC_BASE;
OEMInterruptEnable( interrupt , NULL , 0 );
// if( interrupt == PlayConfig.interrupt )
// RETAILMSG( 1 , (TEXT("kernel : no more play buffer \r\n" ) ));
// else
// RETAILMSG( 1 , (TEXT("kernel : no more record buffer \r\n" ) ));
}
}
else
{
static volatile PDMAC_REGS pDMACRegs = (PDMAC_REGS)DMAC_BASE;
RETAILMSG( (DebugMsgMask&DebugMsg_Important) , (TEXT("kernel : audio continue error %x %x\r\n" ) ,
pDMACRegs->DMACIntStatus , pDMACRegs->DMACC1Configuration ));
return 0;
}
return config->interrupt;
}
return error;
}
/* EOF oemioctl.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -