?? atapi.c
字號(hào):
g_oDevice[0].CurrentMultiple = nSector;
WriteOnTaskFileReg(DEV_CONTROL,0);
WriteOnTaskFileReg(DEV_SECTOR,nSector&0xff);
WriteOnTaskFileReg(DEV_LOWLBA,0x00);
WriteOnTaskFileReg(DEV_MIDLBA,0x00);
WriteOnTaskFileReg(DEV_HIGHLBA,0x00);
WriteOnTaskFileReg(DEV_DEVICE,0x40);
WriteOnTaskFileReg(DEV_COMMAND,0xC6); //Set Multiple mode (implemented in ATA IP ??)
WaitForNoBusyStatus();
}
void SetUdmaMode(UDMAMODE umode)
{
UINT8 nMode;
UINT32 uTdvh1;
UINT32 uTdvs;
UINT32 uTrp;
UINT32 uTss;
UINT32 uTackenv;
UINT32 i;
UINT32 uUdmaTime[5];
UINT32 uUdmaTdvh[5] = {20,20,10,10,10}; //{7,7,7,7,7};
UINT32 uUdmaTdvs[5] = {100,60,50,35,20}; //{70,48,31,20,7};
UINT32 uUdmaTrp[5] = {160,125,100,100,100};
UINT32 uUdmaTss[5] = {50,50,50,50,50};
UINT32 uUdmaTackenvMin[5] = {20,20,20,20,20};
UINT32 uUdmaTackenvMax[5] = {70,70,70,55,55};
UINT32 uCycleTime = (UINT32)(1000000000/S3C2443_HCLK);
#ifdef __EVT1
g_vIOPORTRegs->GPADAT &= ~(1<<5); // GPA10 RDATA_fOEN setting
// rGPACDH = 0xaa8a; // GPA10 RDATA_OEN setting
// rGPBCON = rGPBCON & ~(3<<12) | (1<<12); // GPB6 output setting (nXBREQ)
// rGPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable
#else
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0xf<<10)) | (5<<10); // GPB5,6 output mode
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0x3<<8)) |( 1<<8); // GPB4 output mode
g_vIOPORTRegs->GPBCON = (g_vIOPORTRegs->GPBCON & ~(0x3<<0)) |( 1<<0); // GPB4 output mode
g_vIOPORTRegs->GPBDAT |= (3<<5); // GPB5,6 -> H
#endif
// ChangeBufferControl(PIO_CPU);
for (i=0; i<5; i++)
{
uTdvh1 = (uUdmaTdvh[i] / uCycleTime + 1)&0x0f;
uTdvs = (uUdmaTdvs[i] / uCycleTime + 1)&0xff;
uTrp = (uUdmaTrp[i] / uCycleTime + 1)&0xff;
uTss = (uUdmaTss[i] / uCycleTime + 1)&0x0f;
uTackenv= (uUdmaTackenvMin[i]/uCycleTime + 1)&0x0f;
uUdmaTime[i] = (uTdvh1<<24)|(uTdvs<<16)|(uTrp<<8)|(uTss<<4)|uTackenv;
// DbgAta(("UDMA%dTIME = %x\n", i, uUdmaTime[i]));
}
g_vATAPIRegs->ATA_IRQ_MASK=0xfffffffe;
g_vATAPIRegs->ATA_IRQ =0xff;
WriteOnTaskFileReg(DEV_CONTROL,0);
WriteOnTaskFileReg(DEV_FEATURE,0x03);
WriteOnTaskFileReg(DEV_SECTOR,0x40|(nMode&0x7));
WriteOnTaskFileReg(DEV_LOWLBA,0x00);
WriteOnTaskFileReg(DEV_MIDLBA,0x00);
WriteOnTaskFileReg(DEV_HIGHLBA,0x00);
WriteOnTaskFileReg(DEV_DEVICE,0x40);
WriteOnTaskFileReg(DEV_COMMAND,SETFEATURES);
WaitForNoBusyStatus();
switch(umode) {
case UDMA0:
nMode = 0;
g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[0];
break;
case UDMA1:
nMode = 1;
g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[1];
break;
case UDMA2:
nMode = 2;
g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[2];
break;
case UDMA3:
nMode = 3;
g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[3];
break;
case UDMA4:
nMode = 4;
g_vATAPIRegs->ATA_UDMA_TIME = uUdmaTime[4];
break;
default:
RETAILMSG(1,(TEXT("UDMA mode is supported between 0 to 4 !!!! . %d\r\n"),umode));
break;
}
g_oDevice[0].CurrentUdmaMode = nMode;
}
int CheckDevice(void)
{
UINT8 rRead;
if (!(ReadDeviceReg(DEV_SECTOR, &rRead)))
return FALSE;
if (rRead != 0x10)
g_oDevice[0].DeviceType = ATA_ABSENT;
if (!(ReadDeviceReg(DEV_LOWLBA, &rRead)))
return FALSE;
if (rRead != 0x10)
g_oDevice[0].DeviceType = ATA_ABSENT;
if (!(ReadDeviceReg(DEV_MIDLBA, &rRead)))
return FALSE;
if (rRead == 0x00) {
g_oDevice[0].DeviceType = ATA_ATA;
//DbgAta(("ATA_ATA\n"));
}
else if(rRead == 0x14)
g_oDevice[0].DeviceType = ATA_ATAPI;
return TRUE;
}
int ReadSector_PioDma(UINT32 uLBA, UINT32 uDesAddress)
{
if (!(StartReadingBlocks(uLBA, 0x1, uDesAddress)))
return FALSE;
return IsReadingBlocksDone();
}
int StartReadingBlocks(UINT32 uStBlock, UINT32 uBlocks, UINT32 uBufAddr)
{
UINT32 deviceCmd = (g_eMode == UDMA) ? READDMA : READSECTOR;
RETAILMSG(RTL_MSG,(TEXT("### Current MOde is %d %d\r\n"),g_eMode,PIO_DMA));
/*Track Buffer 1 Setting*/
g_vATAPIRegs->ATA_TBUF_START = (UINT32)PIODMA_BUFFER_PA;
g_vATAPIRegs->ATA_TBUF_SIZE = uBlocks*ATA_SECTORSIZE;
g_vATAPIRegs->ATA_XFR_NUM = (uBlocks*ATA_SECTORSIZE);
if (!(SetAtaDevice(uStBlock, uBlocks)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND, deviceCmd)))
return FALSE;
if (!(WaitForNoBusyStatus()))
return FALSE;
SetConfigMode(g_eMode,FALSE);
// ChangeBufferControl(UDMA);
#if 0
if (g_eMode == UDMA) // apply at specific set using buffer control
{
SetBufferDirection(READDMA);
}
#endif
if (!(SetTransferCommand(ATA_CMD_START)))
return FALSE;
return TRUE;
}
#if 0
void ChangeBufferControl(ATA_MODE mode) // added by junon for second UDMA test b'd 060902
{
if (mode == UDMA)
{
g_vIOPORTRegs->GPBDAT = g_vIOPORTRegs->GPBDAT & ~((1<<4)|(1)); // GPB0->low,GPB1->low => UDMA mode
else // PIO
{
g_vIOPORTRegs->GPBDAT = g_vIOPORTRegs->GPBDAT & ~((1<<4) |(1))|(1<<4); // GPB0->low,GPB1->high => ATA mode
}
}
#endif
#if 0
void SetBufferDirection(UINT32 uDirection) // only for SMDK b'd 060812
{
switch(uDirection)
{
case READDMA :
g_vIOPORTRegs->GPBDAT &= ~(3<<5); // GPB5 -> L, buffer direction - read setting
// GPB6 -> L, buffer Output enable
break;
case WRITEDMA :
g_vIOPORTRegs->GPBDAT |= (1<<5); // GPB5 -> H, buffer direction - write setting
g_vIOPORTRegs->GPBDAT &= ~(1<<6); // GPB6 -> L, buffer Output enable 060812
break;
default : // clear
g_vIOPORTRegs->GPBDAT |= (3<<5); // GPB5 -> H, buffer direction - write setting
// GPB6 -> H, buffer Output disable
break;
}
}
#endif
int ReadSectors_Udma(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
UINT32 uCurrentCount;
UINT32 uRemainderCount;
UINT32 uCurrentLba;
UINT32 uCurrentDstAddr;
UINT32 uRound,uLoop;
UINT32 start_time;
UINT32 end_time;
int dwRet;
RETAILMSG(RTL_MSG,(TEXT("ReadSectors_Udma::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));
uRemainderCount = usNumSec;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = dStartSec + uRound*256;
uCurrentDstAddr = pTargetBuf + uRound*256*ATA_SECTORSIZE;
#ifdef USE_MUTEX
GetMutex(g_hMutex);
#endif //USE_MUTEX
StartReadingBlocks(uCurrentLba, uCurrentCount, uCurrentDstAddr);
// IsReadingBlocksDone();
#if 1
dwRet = WaitForSingleObject(g_hATAEvent, 1000); // time out 1sec
if ( dwRet != WAIT_OBJECT_0 )
{
RETAILMSG(1,(TEXT("### ATA_INTERRUPT IS NOT OCCURED.\nATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));
return FALSE;
}
if (!(IsDmaDone()))
return FALSE;
InterruptDone(g_dwATASysIrq);
// RETAILMSG(1,(TEXT("ATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));
#endif
#ifdef USE_MUTEX
ReleaseMutex(g_hMutex);
#endif //USE_MUTEX
memcpy((PBYTE)uCurrentDstAddr,g_vDmaBuffer,uCurrentCount*ATA_SECTORSIZE);
uRound++;
}
return TRUE;
}
int WriteSectors_Udma(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
UINT32 uCurrentCount;
UINT32 uRemainderCount;
UINT32 uCurrentLba;
UINT32 uCurrentSrcAddr;
UINT32 uRound;
DWORD dwRet;
uRemainderCount = usNumSec;
uRound = 0;
while(uRemainderCount != 0) {
if(uRemainderCount>256) {
uCurrentCount = 256; //0 means 256
uRemainderCount -= 256;
} else {
uCurrentCount = uRemainderCount;
uRemainderCount = 0;
}
uCurrentLba = dStartSec + uRound*256;
uCurrentSrcAddr = pTargetBuf + uRound*256*ATA_SECTORSIZE;
memcpy(g_vDmaBuffer,(PBYTE)uCurrentSrcAddr,uCurrentCount*ATA_SECTORSIZE);
#ifdef USE_MUTEX
GetMutex(g_hMutex);
#endif //USE_MUTEX
// RETAILMSG(1,(TEXT("INTPEND = %x
StartWritingBlocks(uCurrentLba, uCurrentCount, uCurrentSrcAddr);
// IsWritingBlocksDone();
#if 1
dwRet = WaitForSingleObject(g_hATAEvent, 1000); // time out 1sec
if ( dwRet != WAIT_OBJECT_0 )
{
RETAILMSG(1,(TEXT("### ATA_INTERRUPT IS NOT OCCURED.\nATA_IRQ 0x%x ATA_IRQMASK 0x%x ATA_XFR_CNT 0x%x\r\n"),g_vATAPIRegs->ATA_IRQ,g_vATAPIRegs->ATA_IRQ_MASK,g_vATAPIRegs->ATA_XFR_CNT));
return FALSE;
}
if (!(IsDmaDone()))
return FALSE;
InterruptDone(g_dwATASysIrq);
#endif
#ifdef USE_MUTEX
ReleaseMutex(g_hMutex);
#endif //USE_MUTEX
uRound++;
}
return TRUE;
}
void SetConfigMode(ATA_MODE mode, int isWriteMode)
{
switch(mode)
{
case PIO_CPU:
g_uCfgReg = ((g_uCfgReg&0x1F3) | (0<<2)); // set PIO_CPU class
break;
case PIO_DMA:
g_uCfgReg = ((g_uCfgReg&0x1F3) | (1<<2)); // set PDMA class
if (isWriteMode == TRUE)
g_uCfgReg |= 0x10; // DMA write mode
else
g_uCfgReg &= (~0x10); // DMA read mode
break;
case UDMA:
g_uCfgReg = ((g_uCfgReg&0x1F3) | (2<<2)); // set UDMA class
g_uCfgReg |= 0x200; // set ATA DMA auto mode (enable multi block transfer)
if (isWriteMode == TRUE)
g_uCfgReg |= 0x10; // DMA write mode
else
g_uCfgReg &= (~0x10); // DMA read mode
break;
default:
break;
}
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}
int SetTransferCommand(ATA_TRANSFER_CMD command)
{
UINT8 cmd = (command == ATA_CMD_STOP) ? 0 :
(command == ATA_CMD_START) ? 1 :
(command == ATA_CMD_ABORT) ? 2 : 3;
if (!(WaitForDeviceAccessReady()))
return FALSE;
g_vATAPIRegs->ATA_COMMAND = cmd;
return TRUE;
}
int IsReadingBlocksDone(void)
{
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 3.\r\n")));
return IsWritingBlocksDone();
}
int IsWritingBlocksDone(void)
{
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 4.\r\n")));
if (!(WaitForTransferDone()))
return FALSE;
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 6.\r\n")));
return IsDmaDone();
}
int WaitForTransferDone(void)
{
UINT32 x;
UINT32 count=1;
UINT16 retVal=TRUE;
do {
count++;
if(!(WaitForDeviceAccessReady())) // timeout
return FALSE;
if(count == 10000000 ) // timeout
{
retVal = FALSE;
break;
}
x = g_vATAPIRegs->ATA_STATUS;
} while((x & 3)!=0);
return retVal;
}
int IsDmaDone(void)
{
if (!(SetTransferCommand(ATA_CMD_ABORT)))
return FALSE;
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 7.\r\n")));
// SetBufferDirection(0); // clear to H
// ChangeBufferControl(PIO_CPU);
SetConfigMode(PIO_CPU, TRUE);
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 8.\r\n")));
if (!(WaitForNoBusyStatus()))
return FALSE;
RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 9.\r\n")));
if (g_eMode == UDMA)
{
g_uCfgReg &= (~0x200); // disable ATA DMA auto mode
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}
return TRUE;
}
int WriteSector_PioDma(UINT32 uLBA, UINT32 uSrcAddress)
{
if (!(StartWritingBlocks(uLBA, 1, uSrcAddress)))
return FALSE;
return IsWritingBlocksDone();
}
int StartWritingBlocks(UINT32 uStBlock, UINT32 uBlocks, UINT32 uBufAddr)
{
UINT32 deviceCmd = (g_eMode == UDMA) ? WRITEDMA : WRITESECTOR;
g_vATAPIRegs->ATA_SBUF_START = (UINT32)PIODMA_BUFFER_PA;
g_vATAPIRegs->ATA_SBUF_SIZE = uBlocks*ATA_SECTORSIZE;
g_vATAPIRegs->ATA_XFR_NUM = uBlocks*ATA_SECTORSIZE;
if (!(SetAtaDevice(uStBlock, uBlocks)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND, deviceCmd)))
return FALSE;
if (!(WaitForNoBusyStatus()))
return FALSE;
SetConfigMode(g_eMode,TRUE);
// ChangeBufferControl(UDMA);
#if 0
if (g_eMode == UDMA) // apply at specific set using buffer control
{
SetBufferDirection(WRITEDMA); // for SMDK buffer direction only
}
#endif
if (!(SetTransferCommand(ATA_CMD_START)))
return FALSE;
return TRUE;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -