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

📄 id5_util.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
字号:
/***************************************************************************
**     File name   : id5_util.c
**     Author      : x.cheng
**     Create date :
**
**	   Comment:
**			utility function.
**
**     Revisions: 
**     $Log: id5_util.c,v $
**     Revision 1.3  2005/08/19 14:57:54  x.cheng
**     new function,sendcommand, draft
**
**     Revision 1.2  2005/08/11 14:41:52  x.cheng
**     ide channel 1 supurted, attach cdrom to channel 1, master
**
**     Revision 1.1  2005/08/09 16:09:33  x.cheng
**     add into repositories
**
**
***************************************************************************/

#include "const.h"
#include "type.h"
#include "stdarg.h"

#define __IDE_HD_SRC__ 
#include "..\..\Inc\i386\io.h"
#include "..\..\Inc\i386\system.h"
#include "..\..\Inc\i386\x86.h"
#include "..\..\Inc\tui.h"
#include "..\..\Inc\ide.h"
#include "..\..\Inc\debug.h"

#include "..\inc\def_ata.h"
#include "..\inc\def_ide.h"

/* debug preprocessor instrument
	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
				
	#endif
	#endif	
***************************/














/************************************************************
*************************************************************
**      Function Name:			iId5WaitIdeStatus
**      Author:                 x.cheng
**
**      Comment:
**			wait for ide Status mask.
**
**      List of parameters:
**			
**
**      Return value:   
**          0 on success, other on fail
**
**      Revisions:
**
*************************************************************
*************************************************************/
int iId5WaitIdeStatus( int iChannel, int iMask, int iVal)
{
	unsigned char ucStatus;
	unsigned long ulLoopCount = TIMEOUT;

//	POSITION();
	do {
		if ( iChannel == IDE_CHANNEL_0 ) {
			vOutPortDelay( ATA_PRIMARY_CURRENT, ATA_DEVICE0);
			ucStatus = ucInPortDelay( ATA_PRIMARY_STATUS );
		} else {
			ucStatus = ucInPortDelay( ATAPI_PRIMARY_STATUS );
		}

		if ( (ucStatus&iMask ) == iVal ) {
			return 0;
		}
		UDelay(1);
	} while ( ulLoopCount-- );

#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
    kprintf("%s(), chn= %d, stat= %d\n", __FUNCTION__, iChannel, ucStatus);
#endif
#endif
	return (-1);
}

/************************************************************
*************************************************************
**      Function Name:			iId5ControllerReady
**      Author:                 x.cheng
**
**      Comment:
**			查询IDE控制器,不忙且就绪
**
**      List of parameters:
**			
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
int iId5ControllerReady(int iChannel)
{
/*
	int iRetries = 5000;
	unsigned char ucStatus;

	//			 0xC0=1100 0000
	//READY_STAT=0x40=0100 0000
	//BUSY_STAT =0x80=1000 0000
	//**************************
	if ( iChannel == IDE_CHANNEL_0 ) {
		while ( --iRetries && (ucInPortDelay(ATA_PRIMARY_STATUS)&0xC0)!=READY_STAT ) ;
	}else {
		while ( --iRetries && (ucInPortDelay(ATAPI_PRIMARY_STATUS)&0xC0)!=READY_STAT ) ;
	}
	
#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
    kprintf("%s(), chn= %d, stat= %d, rety= %d\n", __FUNCTION__, iChannel, 
		ucInPortDelay(ATAPI_PRIMARY_STATUS), iRetries);
#endif
#endif
	return iRetries;
*/
	int iRetries = INT_MAX;
	unsigned char ucStatus;

	while( --iRetries ) {
		if ( iChannel == IDE_CHANNEL_0 ) {
			ucStatus = ucInPortDelay(ATA_PRIMARY_STATUS);
		} else {
			ucStatus = ucInPortDelay(ATAPI_PRIMARY_STATUS);
		}
		if ( !(ucStatus&BUSY_STATUS) && (ucStatus&READY_STATUS) )
			break;
	}

#ifdef _DEBUG__
#ifdef _DEBUG_IDE__
    kprintf("%s(), chn= %d, stat= %d, rety= %d\n", __FUNCTION__, iChannel, 
		ucStatus, iRetries);
#endif
#endif
	return iRetries;
}

/************************************************************
*************************************************************
**      Function Name:			ucId5InterruptDevice
**      Author:                 x.cheng
**
**      Comment:
**			查询ATA_PRIMARY_CURRENT, 看看当前哪个设备是活动的。
**
**      List of parameters:
**			
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
#define DEVICE_MASK	0x10	//00010000
unsigned char ucId5InterruptDevice(int iChannel)
{
	if ( iChannel == IDE_CHANNEL_0 )
		return(ucInPortDelay(ATA_PRIMARY_CURRENT)&DEVICE_MASK);
	else
		return(ucInPortDelay(ATAPI_PRIMARY_CURRENT)&DEVICE_MASK);
}

/************************************************************
*************************************************************
**      Function Name:			ucId5CmdResult
**      Author:                 x.cheng
**
**      Comment:
**			判断硬盘执行命令后的状态
**
**      List of parameters:
**			
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
unsigned char ucId5CmdResult(int iChannel) 
{
	unsigned char ucStatus;
	
	if ( iChannel == IDE_CHANNEL_0 ) 
		ucStatus = ucInPortDelay(ATA_PRIMARY_STATUS);
	else 
		ucStatus = ucInPortDelay(ATAPI_PRIMARY_STATUS);
	//kprintf("ucResult = %x\n", ucResult);
/*
	if ( ucResult & DRQ_STAT )   // 当向硬盘写数据时,如果是这个状态,则 
		return DRQ_STAT;		 //表示硬盘已经准备好接受用户数据了 

					//0x01		0x10		0x20		0x40	0x80 
	if ( (ucResult & (ERR_STAT|SEEK_STAT|WRERR_STAT|READY_STAT|BUSY_STAT))
		== (READY_STAT|BUSY_STAT) )
		return (0);	//OK
*/
					//0x01		0x10		0x20		0x40	0x80 
	if ( (ucStatus & (ERR_STAT|SEEK_STAT|WRERR_STAT|READY_STAT|BUSY_STAT))
		== (READY_STAT|SEEK_STAT) )
		return (0);	//OK

	if ( ucStatus & ERR_STAT ) ucStatus = ucInPortDelay(ATA_PRIMARY_ERROR);
	
	//return ucResult;
	return 1;
}

/************************************************************
*************************************************************
**      Function Name:			ucId5DeviceStatus
**      Author:                 x.cheng
**
**      Comment:
**			判断硬盘执行命令后的状态
**
**      List of parameters:
**			
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
unsigned char ucId5DeviceStatus(int iChannel)
{
	int iRetries = (-1);
	unsigned char ucStatus;

	while( --iRetries ) {
		if ( iChannel == IDE_CHANNEL_0) 
			ucStatus = ucInPortDelay(ATA_PRIMARY_STATUS);
		else
			ucStatus = ucInPortDelay(ATAPI_PRIMARY_STATUS);
		if ( !(ucStatus&DRQ_STATUS) && !(ucStatus&ERR_STATUS) )
			continue;
		else
			break;
	}
	
	if ( ucStatus&ERR_STATUS ) {
		if ( iChannel == IDE_CHANNEL_0) 
			return ucInPortDelay( ATA_PRIMARY_ERROR );
		else
			return ucInPortDelay( ATAPI_PRIMARY_ERROR );
	}

	return (ucStatus);
}

/************************************************************
*************************************************************
**      Function Name:			ucId5SendCommand
**      Author:                 x.cheng
**
**      Comment:
**			判断硬盘执行命令后的状态
**
**      List of parameters:
**			
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
unsigned char ucId5SendCommand(unsigned char ucCmd, unsigned char* pucBuffer)
{

	if ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) )
		PANIC1("ide channel 0 is too busy...\n");

	vOutPortDelay(ATA_PRIMARY_CURRENT, ATA_DEVICE0);
	if ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) )
		PANIC1("device 0 isn't ready\n");
//	vOutPortDelay(ATA_PRIMARY_CMD, 0 );	// use interrupt.
	vOutPortDelay(ATA_PRIMARY_COMMAND, ucCmd);

	DELAY400NS();
	while ( iId5WaitIdeStatus(IDE_CHANNEL_0, BUSY_STATUS, 0) ) ;

	ReadPortString(ATA_PRIMARY_DATA, pucBuffer, SECTOR_SIZE); 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -