📄 ataiotrc.c
字号:
if ( reg_cmd_info.flg == TRC_FLAG_EMPTY )
return NULL;
if ( errDmpLine == 1 )
{
errDmpLine = 2;
if ( reg_cmd_info.flg == TRC_FLAG_SRST )
sprintf( trcDmpBuf, "ATA Reset: SR = %s (%s)",
trc_get_cmd_name( CMD_SRST ),
trc_get_type_name( reg_cmd_info.ct ) );
else
if ( reg_cmd_info.flg == TRC_FLAG_ATAPI )
sprintf( trcDmpBuf, "PACKET Command: %02X = %s (%s)",
reg_cmd_info.cmd,
trc_get_cmd_name( reg_cmd_info.cmd ),
trc_get_type_name( reg_cmd_info.ct ) );
else
sprintf( trcDmpBuf, "ATA Command: %02X = %s (%s)",
reg_cmd_info.cmd,
trc_get_cmd_name( reg_cmd_info.cmd ),
trc_get_type_name( reg_cmd_info.ct ) );
return trcDmpBuf;
}
if ( errDmpLine == 2 )
{
errDmpLine = 3;
if ( reg_cmd_info.flg == TRC_FLAG_ATA )
{
if ( reg_cmd_info.lbaSize == LBA48 )
{
// LBA48 before and after
sprintf( trcDmpBuf, "LBA48 SC %ld %lXH, "
"before %lu.%lu %lX.%lXH, "
"after %lu.%lu %lX.%lXH",
reg_cmd_info.ns, reg_cmd_info.ns,
reg_cmd_info.lbaHigh1, reg_cmd_info.lbaLow1,
reg_cmd_info.lbaHigh1, reg_cmd_info.lbaLow1,
reg_cmd_info.lbaHigh2, reg_cmd_info.lbaLow2,
reg_cmd_info.lbaHigh2, reg_cmd_info.lbaLow2 );
}
else
if ( reg_cmd_info.lbaSize == LBA28 )
{
// LBA28 before and after
sprintf( trcDmpBuf, "LBA28 SC %ld %lXH, "
"before %lu %lXH, "
"after %lu %lXH",
reg_cmd_info.ns, reg_cmd_info.ns,
reg_cmd_info.lbaLow1, reg_cmd_info.lbaLow1,
reg_cmd_info.lbaLow2, reg_cmd_info.lbaLow2 );
}
else
{
// CHS before and after
unsigned int cyl1, head1, sect1;
unsigned int cyl2, head2, sect2;
cyl1 = (unsigned int) ( reg_cmd_info.ch1 << 8 ) | reg_cmd_info.cl1;
head1 = (unsigned int) reg_cmd_info.dh1 & 0x0f;
sect1 = (unsigned int) reg_cmd_info.sn1;
cyl2 = (unsigned int) ( reg_cmd_info.ch2 << 8 ) | reg_cmd_info.cl2;
head2 = (unsigned int) reg_cmd_info.dh2 & 0x0f;
sect2 = (unsigned int) reg_cmd_info.sn2;
sprintf( trcDmpBuf, "CHS SC %ld %lXH, "
"before %u.%u.%u %X.%X.%XH, "
"after %u.%u.%u %X.%X.%XH ",
reg_cmd_info.ns, reg_cmd_info.ns,
cyl1, head1, sect1, cyl1, head1, sect1,
cyl2, head2, sect2, cyl2, head2, sect2 );
}
return trcDmpBuf;
}
if ( reg_cmd_info.flg == TRC_FLAG_ATAPI )
{
if ( reg_atapi_cp_size == 12 )
{
sprintf( trcDmpBuf, "CDB %02X %02X %02X %02X "
"%02X %02X %02X %02X "
"%02X %02X %02X %02X ",
reg_atapi_cp_data[0], reg_atapi_cp_data[1],
reg_atapi_cp_data[2], reg_atapi_cp_data[3],
reg_atapi_cp_data[4], reg_atapi_cp_data[5],
reg_atapi_cp_data[6], reg_atapi_cp_data[7],
reg_atapi_cp_data[8], reg_atapi_cp_data[9],
reg_atapi_cp_data[10], reg_atapi_cp_data[11] );
}
else
{
sprintf( trcDmpBuf, "CDB %02X %02X %02X %02X "
"%02X %02X %02X %02X "
"%02X %02X %02X %02X "
"%02X %02X %02X %02X ",
reg_atapi_cp_data[0], reg_atapi_cp_data[1],
reg_atapi_cp_data[2], reg_atapi_cp_data[3],
reg_atapi_cp_data[4], reg_atapi_cp_data[5],
reg_atapi_cp_data[6], reg_atapi_cp_data[7],
reg_atapi_cp_data[8], reg_atapi_cp_data[9],
reg_atapi_cp_data[10], reg_atapi_cp_data[11],
reg_atapi_cp_data[12], reg_atapi_cp_data[13],
reg_atapi_cp_data[14], reg_atapi_cp_data[15] );
}
return trcDmpBuf;
}
}
if ( errDmpLine == 3 )
{
errDmpLine = 4;
sprintf( trcDmpBuf, "Driver ErrCode: %d %s ",
reg_cmd_info.ec, trc_get_err_name( reg_cmd_info.ec ) );
return trcDmpBuf;
}
if ( errDmpLine == 4 )
{
errDmpLine = 5;
if ( reg_cmd_info.to )
{
sprintf( trcDmpBuf, " "
"Driver timed out (see low level trace for details) !" );
return trcDmpBuf;
}
}
if ( errDmpLine == 5 )
{
errDmpLine = 6;
sprintf( trcDmpBuf, "Bytes transferred: %ld (%lXH); DRQ packets: %ld (%lXH) ",
reg_cmd_info.totalBytesXfer, reg_cmd_info.totalBytesXfer,
reg_cmd_info.drqPackets, reg_cmd_info.drqPackets );
return trcDmpBuf;
}
if ( errDmpLine == 6 )
{
errDmpLine = 7;
sprintf( trcDmpBuf, "Device Status: %02X = %s ", reg_cmd_info.st2,
trc_get_st_bit_name( reg_cmd_info.st2 ) );
return trcDmpBuf;
}
if ( errDmpLine == 7 )
{
errDmpLine = 8;
sprintf( trcDmpBuf, "Device Error: %02X = %s ", reg_cmd_info.er2,
trc_get_er_bit_name( reg_cmd_info.er2 ) );
return trcDmpBuf;
}
if ( errDmpLine == 8 )
{
errDmpLine = 9;
sprintf( trcDmpBuf, "ATA Intf Regs: FR ER SC SN CL CH DH CM ST AS DC " );
return trcDmpBuf;
}
if ( errDmpLine == 9 )
{
errDmpLine = 10;
if ( reg_cmd_info.flg == TRC_FLAG_SRST )
sprintf( trcDmpBuf, " Cmd Params: "
// fr er sc sn cl ch dh cm st as dc
"-- -- -- -- -- -- -- -- -- -- 04 " );
else
sprintf( trcDmpBuf, " Cmd Params: "
// fr er sc sn cl ch dh cm st as dc
"%02X -- %02X %02X %02X %02X %02X %02X -- -- %02X ",
reg_cmd_info.fr1 & 0x00ff,
reg_cmd_info.sc1 & 0x00ff,
reg_cmd_info.sn1,
reg_cmd_info.cl1, reg_cmd_info.ch1, reg_cmd_info.dh1,
reg_cmd_info.cmd, reg_cmd_info.dc1 );
return trcDmpBuf;
}
if ( errDmpLine == 10 )
{
errDmpLine = 11;
sprintf( trcDmpBuf, " After Cmd: "
// fr er sc sn cl ch dh cm st as dc
"-- %02X %02X %02X %02X %02X %02X -- %02X %02X -- ",
reg_cmd_info.er2, reg_cmd_info.sc2 & 0x00ff,
reg_cmd_info.sn2, reg_cmd_info.cl2, reg_cmd_info.ch2,
reg_cmd_info.dh2, reg_cmd_info.st2, reg_cmd_info.as2 );
return trcDmpBuf;
}
if ( ( errDmpLine == 11 ) && reg_cmd_info.failbits )
{
errDmpLine = 12;
errDmpLine2 = 0;
sprintf( trcDmpBuf, " ATA/ATAPI protocol errors bits (%04XH):",
reg_cmd_info.failbits );
return trcDmpBuf;
}
if ( errDmpLine == 12 )
{
while ( ( errDmpLine2 < 16 )
&&
( ! ( reg_cmd_info.failbits & pErrNames[errDmpLine2].pErrCode ) )
)
errDmpLine2 ++ ;
if ( errDmpLine2 < 16 )
{
sprintf( trcDmpBuf, " - %s", pErrNames[errDmpLine2].pErrName );
errDmpLine2 ++ ;
return trcDmpBuf;
}
}
return NULL;
}
//**********************************************************
// command types to trace, see TRC_TYPE_xxx in ataio.h and
// see trc_cht_types() below.
static unsigned int chtTypes = 0xffff; // default is trace all cmd types
// command history trace buffer
#define MAX_CHT 100
static struct
{
// entry type, entry flag, command code, etc
unsigned char flg; // see TRC_FLAG_xxx in ataio.h
unsigned char ct; // see TRC_TYPE_xxx in ataio.h
unsigned char cmd; // command code
long ns; // number of sectors (sector count)
int mc; // multiple count
unsigned int fr1; // feature (8 or 16 bits)
unsigned char dh1; // device head
// starting CHS/LBA
unsigned char lbaSize; // CHS/LBA addr mode
unsigned int cyl; // CHS cyl or ATAPI BCL
unsigned char head; // CHS head
unsigned char sect; // CHS sect
unsigned long lbaLow1; // LBA lower 32-bits
// ending status and driver error codes
unsigned char st2; // status reg
unsigned char er2; // error reg
unsigned char ec; // detailed error code
unsigned char to; // not zero if time out error
// ATAPI CDB size and CDB data
unsigned char cdbSize; // CDB size (12 or 16)
unsigned char cdbBuf[16]; // CDB data
} chtBuf[MAX_CHT];
static int chtCur = 0;
static int chtDmpLine = 0;
static int chtDmpNdx = 0;
static unsigned char * chtTypeName[] =
{ "?????",
"DR ", "DW ",
"ND ", "PDI ", "PDO ",
"RESET",
"DPR ", "DPW ",
"PN ", "PR ", "PW " } ;
//**************************************************************
// set the commands types that are traced,
// see TRC_TYPE_xxx in ataio.h and chtTypes above.
void trc_cht_types( int type )
{
if ( type < 1 )
chtTypes = 0x0000; // trace nothing
else
if ( type > 15 )
chtTypes = 0xffff; // trace all
else
chtTypes |= 0x0001 << type; // selective
}
//**************************************************************
// place an command or reset entry into
// the command history trace buffer
void trc_cht( void )
{
int ndx;
if ( ! ( ( 0x0001 << reg_cmd_info.ct ) & chtTypes ) )
return;
// entry type, entry flag, command code, etc
chtBuf[chtCur].flg = reg_cmd_info.flg;
chtBuf[chtCur].ct = reg_cmd_info.ct ;
chtBuf[chtCur].cmd = reg_cmd_info.cmd;
chtBuf[chtCur].ns = reg_cmd_info.ns;
chtBuf[chtCur].mc = reg_cmd_info.mc;
chtBuf[chtCur].fr1 = reg_cmd_info.fr1;
chtBuf[chtCur].dh1 = reg_cmd_info.dh1;
// starting CHS/LBA
chtBuf[chtCur].lbaSize = reg_cmd_info.lbaSize;
chtBuf[chtCur].cyl = ( reg_cmd_info.ch1 << 8 ) | reg_cmd_info.cl1;
chtBuf[chtCur].head = reg_cmd_info.dh1 & 0x0f;
chtBuf[chtCur].sect = reg_cmd_info.sn1;
chtBuf[chtCur].lbaLow1 = reg_cmd_info.lbaLow1;
// ending status and driver error codes
chtBuf[chtCur].st2 = reg_cmd_info.st2;
chtBuf[chtCur].er2 = reg_cmd_info.er2;
chtBuf[chtCur].ec = reg_cmd_info.ec ;
chtBuf[chtCur].to = reg_cmd_info.to ;
// ATAPI CDB size and CDB data
chtBuf[chtCur].cdbSize = reg_atapi_cp_size;
for ( ndx = 0; ndx < reg_atapi_cp_size; ndx ++ )
chtBuf[chtCur].cdbBuf[ndx] = reg_atapi_cp_data[ndx];
// move to next entry
chtCur ++ ;
if ( chtCur >= MAX_CHT )
chtCur = 0;
}
//**************************************************************
// clear the command history trace buffer
void trc_cht_dump0( void )
{
for ( chtCur = 0; chtCur < MAX_CHT; chtCur ++ )
chtBuf[chtCur].flg = TRC_FLAG_EMPTY;
chtCur = 0;
}
//**************************************************************
// start a dump of the command history trace buffer
void trc_cht_dump1( void )
{
chtDmpLine = 1;
chtDmpNdx = chtCur + 1;
if ( chtDmpNdx >= MAX_CHT )
chtDmpNdx = 0;
}
//**************************************************************
// return one line of the command history trace buffer,
// returns NULL at end.
//
// lines are formated in the style of ATADEMO commands.
// there are three ATADEMO commands per line (DEV, LBAx,
// and the I/O command). The three values at the end of the
// line (following the //) are the driver result error code,
// driver timeout flag, status register and error register.
static unsigned char esStr[24];
static unsigned char atStr[24];
static unsigned char saStr[24];
static unsigned char mcStr[24];
unsigned char * trc_cht_dump2( void )
{
if ( chtDmpLine == 1 ) // 1st line is 1st heading line
{
strcpy( trcDmpBuf,
//0 1 2 3 4 5 6 7
//123456789012345678901234567890123456789012345678901234567890123456789012
//DEV n, LBAnn, ttttt xxH xxxxH nnnnn nnnnnnnnn nnn ; nn nn xxH xxH
"Dev n, LBAnn, Type- Cmd FR--- SC--- LBA--------- MC- ; EC TO ST- ER-" );
chtDmpLine = 2;
return trcDmpBuf;
}
if ( chtDmpLine == 2 ) // 2nd line is 2nd heading line
{
strcpy( trcDmpBuf,
//0 1 2 3 4 5 6 7
//123456789012345678901234567890123456789012345678901234567890123456789012
//DEV n, CHS, ttttt xxH xxxxH nnnnn ccccc hh sss nnn ; nn nn xxH xxH
"Dev n, CHS, Type- Cmd FR--- SC--- Cyl-- Hd Sec MC- ; EC TO ST- ER-" );
chtDmpLine = 3;
return trcDmpBuf;
}
// search for oldest entry
while ( 1 )
{
if ( chtDmpNdx == chtCur )
return NULL;
if ( chtBuf[chtDmpNdx].flg != TRC_FLAG_EMPTY )
break;
chtDmpNdx ++ ;
if ( chtDmpNdx >= MAX_CHT )
chtDmpNdx = 0;
}
// return one trace table entry...
// first format the result data
sprintf( esStr, " ; %2d %2d %02XH %02XH",
chtBuf[chtDmpNdx].ec,
chtBuf[chtDmpNdx].to,
chtBuf[chtDmpNdx].st2,
chtBuf[chtDmpNdx].er2 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -