📄 atapi.c
字号:
return TRUE;
#else
UINT32 k=0;
UINT16 uDmaCount=0;
ATA_MODE mode = g_eMode;
int status=TRUE;
UINT32 uTempBuff = (UINT32)pTargetBuf;
switch(mode)
{
case PIO_CPU:
//status = ReadSectors_Pio( dStartSec, usNumSec, uBufAddr);
break;
case PIO_DMA:
//RETAILMSG(RTL_MSG,(TEXT("### PIO_DMA Check Point 1. NumSec = %d\r\n"),usNumSec));
for(k=0; k<usNumSec; k++)
{
if (!(ReadSector_PioDma(dStartSec+k, k%128)))
return FALSE;
if (!(WaitForTransferDone()))
return FALSE;
if ( (k%128) == 127 )
{
memcpy((UINT8 *)uTempBuff+ATA_SECTORSIZE*128*uDmaCount,g_vDmaBuffer,512*128);
uDmaCount++;
}
}
if ( (k%128) <= 127 && (k%128) != 0)
memcpy((UINT8 *)uTempBuff+ATA_SECTORSIZE*128*uDmaCount,g_vDmaBuffer,512*(k%128));
status = TRUE; // need to move..
break;
case UDMA:
//status = ReadSectors_Udma( uStBlock, uBlocks, uBufAddr);
break;
default:
//DbgAta(("Not supported mode in ReadBlocks()\n"));
break;
}
return status;
#endif
}
int PutDataToDevice(UINT16 *data)
{
if (!(WaitForDeviceAccessReady()))
return FALSE;
g_vATAPIRegs->ATA_PIO_DTR = *data;
return TRUE;
}
int AtaDiskWrite(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
#if 1
UINT32 resCount;
UINT32 remainCount;
UINT32 goingLBA;
UINT32 goingSrcAddr;
UINT32 wCount;
UINT16* uAtaHostAddr;
UINT32 i;
remainCount = usNumSec;
goingLBA = dStartSec;
wCount = 0;
//RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 1.\r\n")));
SetLittleEndian();
while(remainCount != 0)
{
//RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 2.\r\n")));
if(remainCount>256)
{
resCount = 256; //0 means 256
remainCount -= 256;
}
else
{
resCount = remainCount;
remainCount = 0;
}
goingLBA = dStartSec+ wCount*256;
(UINT8 *)uAtaHostAddr = pTargetBuf + wCount*256*ATA_SECTORSIZE;
if (!(SetAtaDevice(goingLBA, resCount)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR)))
return FALSE;
while(resCount-- )
{
if (!(WaitForNoBusyStatus()))
return FALSE;
for (i=0;i<ATA_SECTORSIZE/2;i++)
{
if (!(PutDataToDevice(uAtaHostAddr)))
return TRUE;
uAtaHostAddr++;
}
}
if (!(WaitForNoBusyStatus()));
return TRUE;
wCount++;
}
//RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 3.\r\n")));
return TRUE;
#else
UINT32 k,i,j,uTempBuff=(UINT32)pTargetBuf;
ATA_MODE mode = g_eMode;
int status=TRUE;
switch(mode)
{
case PIO_CPU:
//status = WriteSectors_Pio( uStBlock, uBlocks, uBufAddr);
break;
case PIO_DMA:
#if 1
for(i = 0, j = usNumSec ; j > 128 ; j -= 128 , i++)
{
//RETAILMSG(1,(TEXT("### PIO_DMA Check Point 1. NumSec = %d\r\n"),j));
memcpy(g_vDmaBuffer,(UINT8 *)uTempBuff+ATA_SECTORSIZE*128*i,ATA_SECTORSIZE*128);
for ( k = 0 ; k < 128 ; k++)
{
if (!(WriteSector_PioDma(dStartSec+i*128+k, k)))
return FALSE;
if (!(WaitForTransferDone()))
return FALSE;
}
}
if ( j > 0 )
{
//RETAILMSG(1,(TEXT("### PIO_DMA Check Point 2. NumSec = %d\r\n"),j));
memcpy(g_vDmaBuffer,(UINT8 *)uTempBuff+ATA_SECTORSIZE*128*i,ATA_SECTORSIZE*j);
for ( k = 0 ; k < j ; k++)
{
if (!(WriteSector_PioDma(dStartSec+i*128+k, k)))
return FALSE;
if (!(WaitForTransferDone()))
return FALSE;
}
}
status = TRUE; // need to move..
break;
#else
for ( k = 0 ; k < usNumSec; k++)
{
memcpy(g_vDmaBuffer,(UINT8 *)uTempBuff+ATA_SECTORSIZE*k,ATA_SECTORSIZE);
WriteSector_PioDma(dStartSec+k, 0);
WaitForTransferDone();
}
#endif
/* case PIO_DMA:
for(k=0; k<uBlocks; k++)
{
WriteSector_PioDma(uStBlock+k, uBufAddr+ATA_SECTORSIZE*k);
WaitForTransferDone();
}
status = true;
break; */
case UDMA:
//status = WriteSectors_Udma( uStBlock, uBlocks, uBufAddr);
break;
default:
//DbgAta(("Not supported mode in WriteBlocks()\n"));
break;
}
return status;
#endif
}
void SetAtaMode(ATA_MODE mode)
{
g_eMode = mode;
}
int SetPioMode(PIOMODE pmode)
{
UINT8 nMode = (pmode == PIO0) ? 0 :
(pmode == PIO1) ? 1 :
(pmode == PIO2) ? 2 :
(pmode == PIO3) ? 3 :
(pmode == PIO4) ? 4 : 0;
UINT32 uT1;
UINT32 uT2;
UINT32 uTeoc;
UINT32 i;
UINT32 uPioTime[5];
UINT32 m_uPioT1[5] = {200,50,30,50,30}; // min = {70,50,30,30,25};
UINT32 m_uPioT2[5] = {300,300,290,100,70}; // min = {290,290,290,80,70};
UINT32 m_uPioTeoc[5] = {100,40,20,30,20}; // min = {20,15,10,10,10};
UINT32 uCycleTime = (UINT32)(1000000000/S3C2413_HCLK);
for (i=0; i<5; i++)
{
uT1 = (m_uPioT1[i] /uCycleTime + 1)&0xff;
uT2 = (m_uPioT2[i] /uCycleTime + 1)&0xff;
uTeoc = (m_uPioTeoc[i]/uCycleTime + 1)&0x0f;
uPioTime[i] = (uTeoc<<12)|(uT2<<4)|uT1;
// DbgAta(("PIO%dTIME = %x\n", i, uPioTime[i]));
}
g_vATAPIRegs->ATA_IRQ=0xff;
g_vATAPIRegs->ATA_IRQ_MASK = ATAPI_MASK;
if (!(WriteOnTaskFileReg(DEV_CONTROL,0)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_FEATURE,0x03))) //set transfer mode based on value in Sector Count register
return FALSE;
if (!(WriteOnTaskFileReg(DEV_SECTOR,0x08|(nMode&0x7)))) // PIO flow control transfer mode
return FALSE;
if (!(WriteOnTaskFileReg(DEV_LOWLBA,0x00)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_MIDLBA,0x00)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_HIGHLBA,0x00)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_DEVICE,0x40)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND,SETFEATURES)))
return FALSE;
if (!(WaitForNoBusyStatus()))
return FALSE;
switch(pmode) { // modified by Bryan W. Lee (Oct. 19th, 2005)
case PIO1:
g_uCfgReg &= (~0x2); //IORDY disable
g_vATAPIRegs->ATA_PIO_TIME=uPioTime[1];
break;
case PIO2:
g_uCfgReg &= (~0x2); //IORDY disable
g_vATAPIRegs->ATA_PIO_TIME=uPioTime[2];
break;
case PIO3:
g_uCfgReg |= 0x2; //IORDY enable
g_vATAPIRegs->ATA_PIO_TIME=uPioTime[3];
break;
case PIO4:
g_uCfgReg |= 0x2; //IORDY enable
g_vATAPIRegs->ATA_PIO_TIME=uPioTime[4];
break;
default:
g_uCfgReg &= (~0x2); //IORDY disable
g_vATAPIRegs->ATA_PIO_TIME=uPioTime[0];
break;
}
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
//Outp32(ATA_CFG, m_uCfgReg);
g_oDevice[0].CurrentPioMode = nMode;
return TRUE;
}
//nSector: the number of sectors per block
// if the block count is not supported, an Abort Command error is posted,
// and the Read Multiple and Write Multiple commands are disabled.
void SetMultiple(UINT32 nSector)
{
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();
}
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 + (ATA_SECTORSIZE * uBufAddr );
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);
if (!(SetTransferCommand(ATA_CMD_START)))
return FALSE;
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")));
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 + (ATA_SECTORSIZE * uBufAddr );
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);
if (!(SetTransferCommand(ATA_CMD_START)))
return FALSE;
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -