📄 ata_driver.c
字号:
return (kCSWPhaseError);
}
if (mCheckBit(ATAERR,Status)) // ATA error found
{
Status = ATA_DER_B;
error = ATA_WaitRegBusy();
if (error)
return(error);
Status = ATA_DER_B;
if (mCheckBit(ATAICRC,Status)) // CRC error
{
gATAError = kSCSISKRecoveredError;
}
else
{
if (mCheckBit(ATAUNC,Status)) // uncorrectable data
{
gATAError = kSCSISKMediumError;
}
else
{
if ( (Status & (1<<ATAMC)) | (Status & (1<<ATAMCR))) // media changed
{
gATAError = kSCSISKUnitAttention;
}
else
{
if (mCheckBit(ATAABRT,Status))
{
gATAError = kSCSISKAbortedCommand;
}
else
{
if (mCheckBit(ATANM,Status))
{
gATAError = kSCSISKNotReady;
}
else
return(kCSWPass);
}
}
}
}
return(kCSWFailed);
}
return(kCSWPass);
}
// ==================================================================
// ATA_WaitATABusyDRQ() -
//
// To wait until device not busy
//
// Input - = nil
//
// Output - = nil
//
// Function returns error code
//
// ==================================================================
ATAErrorCode ATA_WaitATABusyDRQ()
{
muint16 BegTime, CurTime;
muint8 Status;
ATAErrorCode error;
BegTime = MK_GetCurrentTime(); // begin time
do
{
error = ATA_WaitRegBusy();
if (error)
return(error);
Status = ATA_DSR_B; // get Status register
error = ATA_WaitRegBusy();
if (error)
return(error);
Status = ATA_DSR_B;
if ( mCheckBit(ATABSY,Status) ^ mCheckBit(ATADRQ,Status))
return(kATAPass);
// if (mCheckBit(ATADRQ,Status))
// return(kATAPass); // exit if not busy
CurTime = MK_GetCurrentTime(); // current time
}
while ( ((CurTime-BegTime) < kATATimeout) || ((BegTime - CurTime) < kATATimeout));
if (mCheckBit(ATABSY,Status)) // ATA still busy, timeout
{
#ifdef __kEnableSciDebugger__
(void)MK_Debug_StrPrint((muint8*)"ATA Device Timout!\r\n");
ATA_Delay(100);
#endif
gATAError = kSCSISKHardwareError; // timeout => hardware error
return(kCSWPhaseError);
}
if (mCheckBit(ATADF,Status)) // ATA Device Fault
{
gATAError = kSCSISKHardwareError; // device fault => hardware error
return (kCSWPhaseError);
}
if (mCheckBit(ATAERR,Status)) // ATA error found
{
#ifdef __kEnableSciDebugger__
(void)MK_Debug_StrPrint((muint8*)"ATA Device Error!\r\n");
ATA_Delay(100);
#endif
Status = ATA_DER_B;
error = ATA_WaitRegBusy();
if (error)
return(error);
Status = ATA_DER_B;
if (mCheckBit(ATAICRC,Status)) // CRC error
{
gATAError = kSCSISKRecoveredError;
}
else
{
if (mCheckBit(ATAUNC,Status)) // uncorrectable data
{
gATAError = kSCSISKMediumError;
}
else
{
if ( (Status & (1<<ATAMC)) | (Status & (1<<ATAMCR))) // media changed
{
gATAError = kSCSISKUnitAttention;
}
else
{
if (mCheckBit(ATAABRT,Status))
{
gATAError = kSCSISKAbortedCommand;
}
else
{
if (mCheckBit(ATANM,Status))
{
gATAError = kSCSISKNotReady;
}
}
}
}
}
return(kCSWFailed);
}
return(kCSWPass);
}
// ==================================================================
// ATA_SetRPIOTiming() -
//
// To set PIO timing read/write for register
//
// Input - = pio mode (0 - 4)
//
// Output - = nil
//
// Function returns: nil
//
// ==================================================================
void ATA_SetRPIOTiming(muint8 pio)
{
ATA_SetPIOTiming(pio);
ATA_PIO1 = kATARPIOReg1[pio];
}
// ==================================================================
// ATA_SetPIOTiming() -
//
// To set PIO timing read/write for data
//
// Input - = pio mode (0 - 4)
//
// Output - = nil
//
// Function returns: nil
//
// ==================================================================
void ATA_SetPIOTiming(muint8 pio)
{
ATA_PIO1 = kATAPIOReg1[pio];
ATA_PIO2 = kATAPIOReg2[pio];
ATA_PIO3 = kATAPIOReg3[pio];
ATA_PIO4 = kATAPIOReg4[pio];
}
// ==================================================================
// ATA_SetUDMATiming() -
//
// To set UDMA timing read/write for dat
//
// Input - = udma mode (0 - 4)
//
// Output - = nil
//
// Function returns: nil
//
// ==================================================================
void ATA_SetUDMATiming(muint8 udma)
{
ATA_UDMA1 = kATAUDMAReg1[udma];
ATA_UDMA2 = kATAUDMAReg2[udma];
ATA_UDMA3 = kATAUDMAReg3[udma];
ATA_UDMA4 = kATAUDMAReg4[udma];
ATA_UDMA5 = kATAUDMAReg5[udma];
ATA_UDMA6 = kATAUDMAReg6[udma];
ATA_UDMA7 = kATAUDMAReg7[udma];
ATA_UDMA8 = kATAUDMAReg8[udma];
ATA_UDMA9 = kATAUDMAReg9[udma];
}
// ==================================================================
// ATA_SetMDMATiming() -
//
// To set Multi-Word DMA timing read/write for dat
//
// Input - = MDMA mode (0 - 2)
//
// Output - = nil
//
// Function returns: nil
//
// ==================================================================
void ATA_SetMDMATiming(muint8 mdma)
{
ATA_DMA1 = kATAUDMAReg1[mdma];
ATA_DMA2 = kATAUDMAReg2[mdma];
ATA_DMA3 = kATAUDMAReg3[mdma];
ATA_DMA4 = kATAUDMAReg4[mdma];
}
// ==================================================================
// ATA_GetDeviceInfo() -
//
// Get device information and do the initization
//
// Input - = NIL
//
// Output - = Data wrote to ATA device
//
// Function returns ATA error code
//
// ==================================================================
ATAErrorCode ATA_GetSetDeviceInfo()
{
muint16 *pBuffer;
muint8 LBAHigh, LBAMid, UDMAMode;
volatile ATAErrorCode error;
sATACommand sATACmd;
pBuffer = (muint16 *) (kIQUERAMBegin+0x400);
ATA_DDHR = 0;
error = ATA_WaitRegBusy();
if (error)
return(error);
LBAMid = ATA_LBAM_B;
error = ATA_WaitRegBusy();
if (error)
return(error);
LBAMid = ATA_LBAM_B;
LBAHigh = ATA_LBAH_B;
error = ATA_WaitRegBusy();
if (error)
return(error);
LBAHigh = ATA_LBAH_B;
error = ATA_WaitATABusy();
if (error)
return(error);
// INITEE = 0x21;
if ((LBAHigh==0xeb) && (LBAMid==0x14))
mSetBit(bitATAATAPI,gATADevInfo); // ATAPI device
else // ATA device
gATADevInfo = 0; // ATA device
UTL_LoopDelay(0x1000);
error = ATA_IdentifyDevice(pBuffer, 0x100);
if (error)
return (error);
if ( pBuffer[kATADevInfoGen] & kBit8)
gATAPacketLen = 8; // 8 word packet length
else
gATAPacketLen = 6; // 6 word
gATAPIOMode = (muint8) (pBuffer[kATADevInfoPIO] >> kOneByte);
if ((*pBuffer != 0x8a84) && (!gATAPIOMode || (gATAPIOMode>4)))
return(kCSWFailed);
gATAMaxCapacity = (muint32) (pBuffer[kATADevInfoMaxCap+1]) << kThreeByte \
| (pBuffer[kATADevInfoMaxCap+1]) >>kOneByte ;
gATAMaxCapacity = (gATAMaxCapacity << kTwoByte) \
| (pBuffer[kATADevInfoMaxCap]) << kOneByte | (pBuffer[kATADevInfoMaxCap]) >> kOneByte;
gATAMaxCapacity--;
sATACmd.features = kATAFCmdSetTransfer;
sATACmd.lba_low = 0;
sATACmd.lba_mid = 0;
sATACmd.lba_high = 0;
sATACmd.device = 0;
sATACmd.command = kATACmdSetFeatures;
sATACmd.dmamode = 0;
if (gATAPIOMode)
{
do
{
sATACmd.count = kATAPIO2Mode[gATAPIOMode];
error = ATA_Command(&sATACmd);
if (!error)
{
ATA_SetPIOTiming(gATAPIOMode);
}
else // error happen
{
if (!gATAPIOMode--) // if error happens and ATAPIOMode = 0)
return (kATASetPIOError);
}
}
while (error);
}
UDMAMode = (muint8) (pBuffer[kATADevInfoUDMA] >> 8) & 0x1f;
if (UDMAMode)
{
// UDMAMode=0x7;
if (UDMAMode & kBit0)
gATAUDMAMode = 0;
if (UDMAMode & kBit1)
gATAUDMAMode = 1;
if (UDMAMode & kBit2)
gATAUDMAMode = 2;
if (UDMAMode & kBit3)
gATAUDMAMode = 3;
if (UDMAMode & kBit4)
gATAUDMAMode = 4;
do
{
sATACmd.count = kATAUDMA2Mode[gATAUDMAMode];
error = ATA_Command(&sATACmd);
if (!error)
{
ATA_SetUDMATiming(gATAUDMAMode);
mSetBit(bitATAUDMAMode,gATAStatus);
}
else // error happen
{
if (!gATAUDMAMode--) // if error happens and ATAPIOMode = 0)
return (kATASetPIOError);
}
}
while (error);
}
return (ATA_WaitATABusy());
}
void ATA_FillNZero(muint16 XferWordLen)
{
muint16 i;
for (i=0; i<XferWordLen; i++)
{
ATA_DDR = 0x0000;
(void) ATA_WaitRegBusy();
}
}
void ATA_UDMARead(muint8 pIQUEBuffer)
{
mSetBit(DBRST,QC34DCR); // reset QC34 double buffer
QC3SZB = 0x10 | pIQUEBuffer;
QC3REQ = kQCREQUSBTx;
QC4REQ = kQCREQATARx; // QC3 = ATA Tx
while (!mCheckBit(ATAINTRQ,PORTS));
(void) ATA_WaitATABusy();
QC3REQ = kQCREQNone; // QC1 = none
QC4REQ = kQCREQNone; // QC2 = none
(void) ATA_WaitATABusy();
}
void ATA_UDMAWrite(muint8 pIQUEBuffer)
{
mSetBit(DBRST,QC12DCR); // reset QC12 double buffer
QC1SZB = 0x10 | pIQUEBuffer;
QC1REQ = kQCREQUSBRx;
QC2REQ = kQCREQATATx; // QC2 = ATA Tx
UTL_LoopDelay(0x100);
mSetBit(RXDA,QC12DTR);
//while ((QC12DSR & 0x03) != 0);
while (!mCheckBit(ATAINTRQ,PORTS));
(void) ATA_WaitATABusy();
QC1REQ = kQCREQNone; // QC1 = USB Rx
QC2REQ = kQCREQNone; // QC2 = ATA Tx
}
//
// The end of file ATA_Driver.c
// *********************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -