⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atapi.c

📁 支持三星原产的S3C2413开发板
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -