📄 id5_util.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 + -