📄 atapi.c
字号:
RETAILMSG(INFO_MSG,(TEXT("Max PIO Mode : %d\n"),g_oDevice[0].MaxPioMode));
g_oDevice[0].MaxUdmaMode =0;
tempBuffer = readBuffer[88]>>8;
for(i=4;i>=0;i--) {
if(tempBuffer&(0x01<<i)) {
g_oDevice[0].MaxUdmaMode = i;
break;
}
}
RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 1.%d\n"),g_oDevice[0].MaxPioMode));
g_oDevice[0].CurrentUdmaMode =0;
tempBuffer = readBuffer[88]&0x00ff;
for(i=0;i<5;i++) {
if(tempBuffer&(0x01<<i)) {
g_oDevice[0].CurrentUdmaMode = i;
break; ///
}
}
RETAILMSG(RTL_MSG,(TEXT("+++ Last Check 2.%d\n"),g_oDevice[0].MaxPioMode));
RETAILMSG(INFO_MSG,(TEXT("Max UDMA Mode : %d\n"),g_oDevice[0].MaxUdmaMode));
RETAILMSG(INFO_MSG,(TEXT("Current UDMA Mode : %d\n"),g_oDevice[0].CurrentUdmaMode));
//
//verify identify data~~~~~~~~~~~~~~~~~~~~~~~END
//
g_uCfgReg &= (~0x40); // set Little endian
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
//Outp32(ATA_CFG, g_uCfgReg);
return TRUE;
}
void SetLittleEndian(void)
{
// set Little endian
g_uCfgReg &= (~0x40);
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
}
void SetAtaOnOff(UINT8 OnOff)
{
UINT32 temp;
//Inp32(ATA_CONTROL, temp);
temp = g_vATAPIRegs->ATA_CONTROL;
if(OnOff==1)
//Outp32(ATA_CONTROL, temp | 0x1);
g_vATAPIRegs->ATA_CONTROL = temp | 0x1;
else if(OnOff == 0)
//Outp32(ATA_CONTROL, temp &0xfffffffe);
g_vATAPIRegs->ATA_CONTROL = temp & 0xfffffffe;
}
void Init(void)
{
SetLittleEndian();
SetAtaOnOff(1);
Sleep(200);
g_uCfgReg = 0;
//CheckDevice();
}
void Init12(PIOMODE pmode, UINT32 multisize, UDMAMODE umode)
{
SetAtaOnOff(1);
g_uCfgReg = 0;
g_uCfgReg &= (~0x40); // set Little endian
//Outp32(ATA_CFG, m_uCfgReg);
g_vATAPIRegs->ATA_CFG = g_uCfgReg;
SetPioMode(pmode);
SetMultiple(multisize);
//SetUdmaMode(umode);
CheckDevice();
}
int OpenMedia()
{
ATA_MODE mode;
UDMAMODE udmaMode;
Init();
if (!(IdentifyDevice()))
return FALSE;
if (g_oDevice[0].MaxUdmaMode == 0 )
{
mode = PIO_CPU;
}
else
{
#ifdef USE_MUTEX
RETAILMSG(1, (TEXT("### This CF Card is running by using UDMA %d\r\n")));
mode = UDMA; // to only use PIO mode 061024 hsjang
#else
RETAILMSG(1, (TEXT("### This CF Card is running by using PIO %d\r\n")));
mode = PIO_CPU; // to only use PIO mode 061024 hsjang
#endif //USE_MUTEX
}
SetAtaMode(mode);
if (mode == PIO_CPU || mode == PIO_DMA)
{
RETAILMSG(1, (TEXT("### ATAPI MAXPIOMODE %d\r\n"),g_oDevice[0].MaxPioMode));
if (!(SetPioMode(g_oDevice[0].MaxPioMode)))
return FALSE;
}
else
{
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 AtaDiskRead(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
// Assert(uStBlock+uBlocks <= m_uMaxSectors);
UINT32 k;
ATA_MODE mode = g_eMode;
int status;
Lock();
RETAILMSG(RTL_MSG,(TEXT("ATADISKREAD::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));
switch(mode)
{
case PIO_CPU:
status = ReadSectors_Pio( dStartSec, pTargetBuf, usNumSec);
break;
case PIO_DMA:
for(k=0; k<usNumSec; k++)
{
ReadSector_PioDma(dStartSec+k, pTargetBuf+ATA_SECTORSIZE*k);
WaitForTransferDone();
}
status = TRUE; // need to move..
break;
case UDMA:
status = ReadSectors_Udma( dStartSec, pTargetBuf, usNumSec);
//status = ReadSectors_Pio( dStartSec, pTargetBuf, usNumSec);
break;
default:
RETAILMSG(1,(TEXT("Not supported mode in ReadBlocks()\n")));
break;
}
UnLock();
return status;
}
int ReadSectors_Pio(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
UINT32 resCount;
UINT32 remainCount;
UINT32 goingLBA;
UINT32 goingDstAddr;
UINT32 wCount;
UINT8* uAtaHostAddr;
UINT32 i;
remainCount = usNumSec;
goingLBA = dStartSec;
wCount = 0;
SetLittleEndian();
while(remainCount != 0)
{
if(remainCount>256)
{
resCount = 256; //0 means 256
remainCount -= 256;
}
else
{
resCount = remainCount;
remainCount = 0;
}
goingLBA = dStartSec + wCount*256;
uAtaHostAddr = pTargetBuf + wCount*256*ATA_SECTORSIZE;
SetAtaDevice(goingLBA, resCount);
WriteOnTaskFileReg(DEV_COMMAND, READSECTOR);
while(resCount-- ) {
if (!(WaitForNoBusyStatus()))
return FALSE;
for (i=0;i<ATA_SECTORSIZE/2;i++) {
GetByteDataFromDevice(uAtaHostAddr);
uAtaHostAddr+=2;
}
}
if (!(WaitForNoBusyStatus()))
return FALSE;
wCount++;
}
return TRUE;
}
int PutDataToDevice(UINT16 *data)
{
if (!(WaitForDeviceAccessReady()))
return FALSE;
g_vATAPIRegs->ATA_PIO_DTR = *data;
return TRUE;
}
int AtaDiskWrite(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
// Assert(uStBlock+uBlocks <= m_uMaxSectors);
UINT32 k;
ATA_MODE mode = g_eMode;
int status;
Lock();
RETAILMSG(RTL_MSG,(TEXT("ATADISKWRITE::: 0x%x 0x%x 0x%x \r\n"),dStartSec,pTargetBuf,usNumSec));
switch(mode)
{
case PIO_CPU:
status = WriteSector_Pio( dStartSec, pTargetBuf, usNumSec);
break;
case PIO_DMA:
for(k=0; k<usNumSec; k++)
{
ReadSector_PioDma(dStartSec+k, pTargetBuf+ATA_SECTORSIZE*k);
WaitForTransferDone();
}
status = TRUE; // need to move..
break;
case UDMA:
//status = WriteSector_Pio( dStartSec, pTargetBuf, usNumSec);
status = WriteSectors_Udma( dStartSec, pTargetBuf, usNumSec);
break;
default:
RETAILMSG(1,(TEXT("Not supported mode in ReadBlocks()\n")));
break;
}
UnLock();
return status;
}
int WriteSector_Pio(DWORD dStartSec, BYTE *pTargetBuf, UINT16 usNumSec)
{
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)
{
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;
}
g_vIOPORTRegs->GPFDAT &= ~(3<<6);
for (i=0;i<ATA_SECTORSIZE/2;i++)
{
if (!(PutDataToDevice(uAtaHostAddr)))
{
return FALSE;
}
uAtaHostAddr++;
}
g_vIOPORTRegs->GPFDAT |= (1<<6);
}
if (!(WaitForNoBusyStatus()))
{
return FALSE;
}
wCount++;
}
RETAILMSG(RTL_MSG,(TEXT("+++ ATADISK:::Write() Check Point 3.\r\n")));
return TRUE;
}
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/S3C2443_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)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -