📄 idedma_if.c
字号:
/*
* description : ATA/ATAPI Interface
* Maker : Hideyuki Nekoshima
* Copyright : (C)2003,SEIKO EPSON Corp. All Rights Reserved.
*/
#include "SPRDEF.h"
#include "SPRSTS.h"
#include "IDEDMA_IF.h"
#include "Reg72V05.h"
#define BIT_ON 0x01 /* Bit */
#define BIT_OFF 0x00 /* Bit */
#define IDE_DMA_PIO0 0xFF /* IDE DMA PIO Mode0 Rate */
#define IDE_DMA_PIO1 0x88 /* IDE DMA PIO Mode1 Rate */
#define IDE_DMA_PIO2 0x44 /* IDE DMA PIO Mode2 Rate */
#define IDE_DMA_PIO3 0x22 /* IDE DMA PIO Mode3 Rate */
#define IDE_DMA_PIO4 0x10 /* IDE DMA PIO Mode4 Rate */
#define IDE_DMA_MULTI0 0xBB /* IDE MultiWord DMA Mode0 Rate */
#define IDE_DMA_MULTI1 0x20 /* IDE MultiWord DMA Mode1 Rate */
#define IDE_DMA_MULTI2 0x10 /* IDE MultiWord DMA Mode2 Rate */
#define IDE_DMA_ULTRA0 0x06 /* IDE Ultra DMA Mode0 Rate */
#define IDE_DMA_ULTRA1 0x04 /* IDE Ultra DMA Mode1 Rate */
#define IDE_DMA_ULTRA2 0x03 /* IDE Ultra DMA Mode2 Rate */
#define IDE_DMA_ULTRA3 0x02 /* IDE Ultra DMA Mode3 Rate */
#define IDE_DMA_ULTRA4 0x01 /* IDE Ultra DMA Mode3 Rate */
#define IDE_DMA_ULTRA5 0x00 /* IDE Ultra DMA Mode3 Rate */
static UCHAR IDEDmaPortLock[IDEDMA_IF_MAX_PORT]; /* PORT LOCK Flag */
static UCHAR IDEDmaPortExecFlag[IDEDMA_IF_MAX_PORT]; /* PORT Execution Flag */
static UCHAR IDEDmaPioCyc[IDEDMA_IF_MAX_PORT]; /* PIO DMA Cycle */
static UCHAR IDEDmaMultiCyc[IDEDMA_IF_MAX_PORT]; /* MultiWord DMA Cycle */
static UCHAR IDEDmaUltraCyc[IDEDMA_IF_MAX_PORT]; /* Ultra DMA Cycle */
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFReset
//
// description : Initialize IDE DMA Interface Module.
//
// : Initialize the internal variables in IDE DMA Interface Module,
// and intialize the hard ware.
//
// argument : none
//
// return : LONG status Processing result
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFReset( void )
{
UCHAR i;
/* PORT Execution Flag Clear */
for(i=0; i<IDEDMA_IF_MAX_PORT; i++){
IDEDmaPortLock[i] = IDEDMA_IF_PORT_UNLOCK;
IDEDmaPortExecFlag[i] = IDEDMA_IF_STOP;
IDEDmaPioCyc[i] = 0x00;
IDEDmaMultiCyc[i] = 0x00;
IDEDmaUltraCyc[i] = 0x00;
}
/* IDE DMA Stop */
RegClear( REG08_IDE_Control, BIT_IDE_Go );
/* Activate IDE Bus */
RegSet( REG08_IDE_Config_1, BIT_ActiveIDE );
RegWrite( REG08_IDE_Rmod, 0x00 ); /* IDE Register Mode */
RegWrite( REG08_IDE_Tmod, 0x00 ); /* IDE Transfer Mode */
RegWrite( REG08_IDE_Umod, 0x00 ); /* IDE Ultra-DMA Transfer Mode Clear*/
/* Complete */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFOpen
//
// description : Open IDEDMA Interface Module.
//
// Open the IDEDMA Interface Module, Enter the usable state.
// In the case that open is not executed,API processing in Module is not done.
//
// argument : non
//
// return : LONG status Processing result
//
// flag : UCHAR OpenFlag PASS Indicate if the Interface Module is usable.
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFOpen( void )
{
UCHAR i;
/* PORT Execution Flag Clear */
for(i=0; i<IDEDMA_IF_MAX_PORT; i++){
IDEDmaPortLock[i] = IDEDMA_IF_PORT_UNLOCK;
IDEDmaPortExecFlag[i] = IDEDMA_IF_STOP;
IDEDmaPioCyc[i] = 0x00; /* IDE PIO Access Cycle Clear */
IDEDmaMultiCyc[i] = 0x00; /* IDE MultiWord DMA Access Cycle Clear */
IDEDmaUltraCyc[i] = 0x00; /* IDE UltraDMA Access Cycle Clear */
}
/* Complete */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFInitPort
//
// description : Initialize the specified port.
// Unlock the port.
//
//
// argument : USHORT portNumber Initialized port No
//
// return : LONG status Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFInitPort( USHORT portNumber )
{
/* IDE DMA Stop */
RegClear( REG08_IDE_Control, BIT_IDE_Go );
/* InActivated IDE Bus */
RegClear( REG08_IDE_Config_1, BIT_ActiveIDE );
RegWrite( REG08_IDE_Rmod, 0x00 ); /* IDE Register Mode */
RegWrite( REG08_IDE_Tmod, 0x00 ); /* IDE Transfer Mode */
RegWrite( REG08_IDE_Umod, 0x00 ); /* IDE Ultra-DMA Transfer Mode Clear*/
IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_UNLOCK;
/* Complete */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFLockPort
//
// description : Lock the cpecified port.
//
// : As long as the port is not locked,can not do the serials
// functions below.
//
// argument : USHORT portNumber Port No. to lock
//
// return : LONG status Processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFLockPort( USHORT portNumber )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_LOCK ){
/* The specified port is already locked */
return STATUS_LOCKED_PORT;
}
IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_LOCK;
/* ALL Device Reset */
/* Activate IDE Bus */
RegSet( REG08_IDE_Config_1, BIT_ActiveIDE );
/* Compelte */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFUnlockPort
//
// description : Unlock the specified port.
// : When the port is released, can not do the serials
// functions below.
//
// argument : USHORT portNumber Device No. to be unlocked
//
// return : LONG status processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFUnlockPort( USHORT portNumber )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
/* The specified port had not been locked. */
return STATUS_UNLOCK_PORT;
}
if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
/* The specified port is in operating */
return STATUS_EXECUTION_PORT;
}
IDEDmaPortLock[portNumber] = IDEDMA_IF_PORT_UNLOCK;
/* ALL Device Reset */
/* Compelte */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFSetTransferRate
//
// description : Set the transfer rate for the specifed port.
// Once the transfer rate is set,it will maintained until the unlock
// and the parameter is set again.
//
// argument : USHORT portNumber Port No. to Unlock
//
// return : LONG status processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFSetTransferRate( USHORT portNumber, UCHAR pioRate, UCHAR multiRate, UCHAR ultraRate )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
/* The specified port had not been locked. */
return STATUS_UNLOCK_PORT;
}
if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
/* The specified port is in operating */
return STATUS_EXECUTION_PORT;
}
/* PIO Transfer Rate Set */
switch( pioRate ){
case IDEDMA_IF_PIO_MODE0:
IDEDmaPioCyc[portNumber] = IDE_DMA_PIO0;
break;
case IDEDMA_IF_PIO_MODE1:
IDEDmaPioCyc[portNumber] = IDE_DMA_PIO1;
break;
case IDEDMA_IF_PIO_MODE2:
IDEDmaPioCyc[portNumber] = IDE_DMA_PIO2;
break;
case IDEDMA_IF_PIO_MODE3:
IDEDmaPioCyc[portNumber] = IDE_DMA_PIO3;
break;
case IDEDMA_IF_PIO_MODE4:
IDEDmaPioCyc[portNumber] = IDE_DMA_PIO4;
break;
default:
/* Parameter error */
return STATUS_INVALID_PARAMETER;
}
/* Multi Word DMA Transfer Rate Set */
switch( multiRate ){
case IDEDMA_IF_MULTI_MODE0:
IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI0;
break;
case IDEDMA_IF_MULTI_MODE1:
IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI1;
break;
case IDEDMA_IF_MULTI_MODE2:
IDEDmaMultiCyc[portNumber] = IDE_DMA_MULTI2;
break;
default:
/* Parameter error */
return STATUS_INVALID_PARAMETER;
}
/* Ultra DMA Transfer Rate Set */
switch( ultraRate ){
case IDEDMA_IF_ULTRA_MODE0:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA0;
break;
case IDEDMA_IF_ULTRA_MODE1:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA1;
break;
case IDEDMA_IF_ULTRA_MODE2:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA2;
break;
case IDEDMA_IF_ULTRA_MODE3:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA3;
break;
case IDEDMA_IF_ULTRA_MODE4:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA4;
break;
case IDEDMA_IF_ULTRA_MODE5:
case IDEDMA_IF_ULTRA_MODE6:
IDEDmaUltraCyc[portNumber] = IDE_DMA_ULTRA5;
break;
default:
/* Parameter error */
return STATUS_INVALID_PARAMETER;
}
/* Compelte */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFTransferStartA
//
// description : Start the data transfer of the specified port.
// After start the transfer,the control returns to the upperlayer at once.
//
// argument : USHORT portNumber The prot No. that executes the data transfer
// UCHAR direction Data transfer direction
// UCHAR transferMode Data transfer mode
// ULONG transferLba Start LBA of data transfer
//
// return : LONG status processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFTransferStartA( USHORT portNumber, UCHAR direction, UCHAR transferMode, ULONG transferSize, ULONG transferLba )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
/* The specified port had not been locked. */
return STATUS_UNLOCK_PORT;
}
if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
/* The specified port is in operating */
return STATUS_EXECUTION_PORT;
}
switch(transferMode ){
case IDEDMA_IF_PIO:
RegWrite( REG08_IDE_Tmod, IDEDmaPioCyc[portNumber] );
RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_PIO );
break;
case IDEDMA_IF_MULTI:
RegWrite( REG08_IDE_Tmod, IDEDmaMultiCyc[portNumber] );
RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_Multi );
break;
case IDEDMA_IF_ULTRA:
RegWrite( REG08_IDE_Umod, IDEDmaUltraCyc[portNumber] );
RegModify( REG08_IDE_Config_0, MASK_UltraMulti, BIT_Ultra );
break;
default:
/* Parameter error */
return STATUS_INVALID_PARAMETER;
}
if( direction > IDEDMA_IF_IDE_OUT ){
return STATUS_INVALID_PARAMETER;
}
// Because SWAPbit is lost
// So revive the SWAP bit
// IDE SWAP correspondence(SWAP Bit is ON by default)
#ifdef IDE_SWAP_BIT_OFF
RegSet( REG08_IDE_Config_1, BIT_Swap_None );
#endif
RegWrite( REG08_IDE_Count_H, (UCHAR)( transferSize / 0x10000 ) );
RegWrite( REG08_IDE_Count_M, (UCHAR)( transferSize / 0x100 ) );
RegWrite( REG08_IDE_Count_L, (UCHAR)( transferSize ) );
if (direction == IDEDMA_IF_IDE_IN) {
RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_IDEtoFIFO);
} else {
RegModify( REG08_IDE_Control, MASK_IDE_Dir, BIT_FIFOtoIDE);
}
/* When join,make sure to set the transfer direction */
IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_EXEC;
/* IDE DMA Go */
RegSet( REG08_IDE_Control, BIT_IDE_Go );
/* Compelte */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFTransferStop
//
// description : Stop the data transfer of the specified port.
//
// argument : USHORT portNumber Port No where data transfer is stopped
//
// return : LONG status processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFTransferStop( USHORT portNumber )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
/* The specified port had not been locked. */
return STATUS_UNLOCK_PORT;
}
IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;
/* IDE DMA Stop */
RegClear( REG08_IDE_Control, BIT_IDE_Go );
/* Compelte */
return STATUS_SUCCESS;
}
/*
////////////////////////////////////////////////////////////////////////
// Function_Name: IDEDMA_IFGetTransferStatus
//
// description : Get the IDE DMA transfer state
//
// : Get the transfer state of the specified port
//
// argument : USHORT portNumber Port No where state is acquired
// ULONG *pStatus Status memory field
//
// return : LONG status processing result
//
////////////////////////////////////////////////////////////////////////
*/
LONG IDEDMA_IFGetTransferStatus( USHORT portNumber, ULONG *pStatus )
{
if( IDEDmaPortLock[portNumber] == IDEDMA_IF_PORT_UNLOCK ){
/* The specified port had not been locked. */
return STATUS_UNLOCK_PORT;
}
if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_COMP ){
*pStatus = IDEDmaPortExecFlag[portNumber];
IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;
}
if( IDEDmaPortExecFlag[portNumber] == IDEDMA_IF_EXEC ){
if( RegRead( REG08_IDE_Control ) & BIT_IDE_Go ){
*pStatus = IDEDmaPortExecFlag[portNumber];
}else{
*pStatus = IDEDMA_IF_COMP;
IDEDmaPortExecFlag[portNumber] = IDEDMA_IF_STOP;
}
}
/* Compelte */
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -