📄 atapi.c
字号:
g_vATAPIRegs->ATA_CONTROL = temp | 0x1;
else if(OnOff == 0)
//Outp32(ATA_CONTROL, temp &0xfffffffe);
g_vATAPIRegs->ATA_CONTROL = temp & 0xfffffffe;*/
}
void Init(void)
{
SetAtaOnOff(1);
g_uCfgReg = 0;
//jungpil
CheckDevice();
}
int OpenMedia(ATA_MODE mode)
{
Init();
if (!(IdentifyDevice()))
{
RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : IdentifyDevice Error\r\n")));
return FALSE;
}
SetAtaMode(mode);
if (mode == PIO_CPU || mode == PIO_DMA)
{
//RETAILMSG(RTL_MSG, (TEXT("### ATAPI MAXPIOMODE %d\r\n"),g_oDevice[0].MaxPioMode));
if (!(SetPioMode(g_oDevice[0].MaxPioMode)))
return FALSE;
}
else
{
UDMAMODE udmaMode =
(g_oDevice[0].MaxPioMode == 0) ? UDMA0 :
(g_oDevice[0].MaxPioMode == 1) ? UDMA1 :
(g_oDevice[0].MaxPioMode == 2) ? UDMA2 :
(g_oDevice[0].MaxPioMode == 3) ? UDMA3 : UDMA4;
SetPioMode(PIO0);
//SetUdmaMode(udmaMode);
}
return TRUE;
}
int SetAtaDevice(UINT32 uLBA, UINT32 uSectorCount)
{
if (!(WriteOnTaskFileReg(DEV_SECTOR,uSectorCount&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_LOWLBA,uLBA&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_MIDLBA,(uLBA>>8)&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_HIGHLBA,(uLBA>>16)&0xFF)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_DEVICE,((uLBA>>24)&0xF)|0x40)))
return FALSE;
return TRUE;
}
int waitDRQ(void)
{
UINT8 bStatus;
UINT32 timeoutCount=MAX_DELAY_BUSY_TO_DRQ;
do
{
bStatus = g_vATAPIRegs->ATA_PIO_DAD;
if (bStatus & 0x80)
{
}
else if(bStatus & 0x01)
{
RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : ERROR in waitDRQ %x\r\n"),bStatus));
return DRQ_ERROR;
}
else if(bStatus & 0x08)
{
return DRQ_OK;
}
else // some wrong state
{
}
}while(--timeoutCount);
return DRQ_TIMEOUT;
}
int AtaDiskRead(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
UINT32 resCount;
UINT32 remainCount;
UINT32 goingLBA;
UINT32 wCount;
UINT8* pTargetBuffer;
UINT32 i;
UINT16 tempRead;
UINT8 bStatus;
L_READ_AGAIN:;
remainCount = usNumSec;
goingLBA = dStartSec;
wCount = 0;
// RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : READ Sector from:%d num:%d\r\n"),dStartSec,usNumSec));
while(remainCount != 0)
{
if(remainCount>256)
{
resCount = 256; //0 means 256
remainCount -= 256;
}
else
{
resCount = remainCount;
remainCount = 0;
}
goingLBA = dStartSec + wCount*256;
pTargetBuffer = pTargetBuf + wCount*256*ATA_SECTORSIZE;
if (!(SetAtaDevice(goingLBA, resCount)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND, READSECTOR)))
return FALSE;
while(resCount-- )
{
int retWait = waitDRQ();
if(retWait == DRQ_TIMEOUT) goto L_READ_AGAIN;
else if(retWait == DRQ_ERROR) return FALSE;
for (i=0;i<ATA_SECTORSIZE/2;i++)
{
tempRead = g_vATAPIRegs->ATA_PIO_DAT;
*pTargetBuffer++ = (UINT8)(tempRead&0xFF);
*pTargetBuffer++ =(UINT8)((tempRead>>8)&0xFF);
/* if(i == 0)
RETAILMSG(RTL_MSG, (TEXT("%02X %02X\n"),tempRead & 0xff, (tempRead>>8)&0xFF)); */
}
// bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt
}
if (!(WaitForNoBusyStatus()))
return FALSE;
wCount++;
}
bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt
#define CHECK_READ_SECNUM
#ifdef CHECK_READ_SECNUM
{
DWORD secNumRead;
secNumRead = (g_vATAPIRegs->ATA_PIO_LLR) & 0x000000ff |
(g_vATAPIRegs->ATA_PIO_LMR << 8) & 0x0000ff00 |
(g_vATAPIRegs->ATA_PIO_LHR << 16) & 0x00ff0000 |
((g_vATAPIRegs->ATA_PIO_DVR & 0x0f) <<24) & 0xff000000;
if((dStartSec + usNumSec - 1) != secNumRead)
{
// RETAILMSG(RTL_MSG, (TEXT("AGAIN!!! sec:%d num:%d last:%d\n"), dStartSec, usNumSec, secNumRead));
goto L_READ_AGAIN;
}
}
#endif
return TRUE;
}
int PutDataToDevice(UINT16 *data)
{
if (!(WaitForDeviceAccessReady()))
return FALSE;
g_vATAPIRegs->ATA_PIO_DAT= *data;
return TRUE;
}
int AtaDiskWrite(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
UINT32 resCount;
UINT32 remainCount;
UINT32 goingLBA;
UINT32 wCount;
UINT16* pTargetBuffer;
UINT32 i;
UINT32 numReCommand;
UINT8 bStatus;
L_WRITE_AGAIN:;
numReCommand = 0;
remainCount = usNumSec;
goingLBA = dStartSec;
wCount = 0;
while(remainCount != 0)
{
if(remainCount>256)
{
resCount = 256; //0 means 256
remainCount -= 256;
}
else
{
resCount = remainCount;
remainCount = 0;
}
goingLBA = dStartSec+ wCount*256;
(UINT8 *)pTargetBuffer = pTargetBuf + wCount*256*ATA_SECTORSIZE;
if (!(SetAtaDevice(goingLBA, resCount)))
return FALSE;
if (!(WriteOnTaskFileReg(DEV_COMMAND, WRITESECTOR)))
return FALSE;
while(resCount-- )
{
int retWait = waitDRQ();
if(retWait == DRQ_TIMEOUT) goto L_WRITE_AGAIN;
else if(retWait == DRQ_ERROR) return FALSE;
for (i=0;i<ATA_SECTORSIZE/2;i++)
{
g_vATAPIRegs->ATA_PIO_DAT= *pTargetBuffer;
pTargetBuffer++;
}
}
if (!(WaitForNoBusyStatus()))
return FALSE;
wCount++;
}
bStatus = g_vATAPIRegs->ATA_PIO_CSD; // clear pending interrupt
//RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 3.\r\n")));
return TRUE;
//Need CHECK_READ_SECNUM ???
}
void SetAtaMode(ATA_MODE mode)
{
g_eMode = mode;
}
int SetPioMode(PIOMODE pmode)
{
UINT8 bStatus;
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/S3C2440A_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;
}
// g_vATAPIRegs->ATA_IRQ=0xff;
// g_vATAPIRegs->ATA_IRQ_MASK = ATAPI_MASK;
if (!(WriteOnTaskFileReg(DEV_CONTROL,0)))
return FALSE;
if (!(WriteOnTaskFileReg((UINT8 *)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
// if (!(WriteOnTaskFileReg(DEV_SECTOR,1))) // 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;
bStatus = g_vATAPIRegs->ATA_PIO_DAD;
RETAILMSG(RTL_MSG, (TEXT("+++ ATAPI_CF : Set PIO Mode %x\r\n"),bStatus));
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();
}
// jungpil can't understand. initial values are all zero
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;
}
void CFHDDTest()
{
AtapiDeviceInit();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -