📄 ataiotrc.c
字号:
//********************************************************************
// ATA LOW LEVEL I/O DRIVER -- ATAIOTRC.C
//
// by Hale Landis (hlandis@ibm.net)
//
// There is no copyright and there are no restrictions on the use
// of this ATA Low Level I/O Driver code. It is distributed to
// help other programmers understand how the ATA device interface
// works and it is distributed without any warranty. Use this
// code at your own risk.
//
// This code is based on the ATA-2, ATA-3 and ATA-4 standards and
// on interviews with various ATA controller and drive designers.
//
// This code has been run on many ATA (IDE) drives and
// MFM/RLL controllers. This code may be a little
// more picky about the status it sees at various times. A real
// BIOS probably would not check the status as carefully.
//
// Compile with one of the Borland C or C++ compilers.
//
// This C source contains the low level I/O trace functions.
//********************************************************************
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include "ataio.h"
#include "ataiopd.h"
//**************************************************************
// trace dump buffer returned by trc_err_dump2()
// trc_cht_dump2() and trc_llt_dump2()
static unsigned char trcDmpBuf[100];
// buffer used to assemble print lines
static unsigned char prtBuf[64];
//**************************************************************
// command name lookup table and lookup function
static struct
{
unsigned char cmdCode;
unsigned char * cmdName;
} cmdNames[] =
{
0xC0 , "CFA ERASE SECTORS" ,
0x03 , "CFA REQUEST EXT ERR CODE" ,
0x87 , "CFA TRANSLATE SECTOR" ,
0xCD , "CFA WRITE MULTIPLE WO ERASE" ,
0x38 , "CFA WRITE SECTORS WO ERASE" ,
0xE5 , "CHECK POWER MODE" ,
0x98 , "CHECK POWER MODE" ,
0x08 , "DEVICE RESET" ,
0x90 , "EXECUTE DEVICE DIAGNOSTIC" ,
0xE7 , "FLUSH CACHE" ,
0x50 , "FORMAT TRACK" ,
0xEC , "IDENTIFY DEVICE" ,
0xA1 , "IDENTIFY PACKET DEVICE" ,
0xE3 , "IDLE" ,
0x97 , "IDLE" ,
0xE1 , "IDLE IMMEDIATE" ,
0x95 , "IDLE IMMEDIATE" ,
0x91 , "INITIALIZE DEVICE PARAMETERS" ,
0x00 , "NOP" ,
0xA0 , "PACKET" ,
0xE4 , "READ BUFFER" ,
0xC7 , "READ DMA QUEUED" ,
0xC8 , "READ DMA" ,
0xC4 , "READ MULTIPLE" ,
0x20 , "READ SECTORS" ,
0x40 , "READ VERIFY SECTORS" ,
0x10 , "RECALIBRATE" ,
0x70 , "SEEK" ,
0xEF , "SET FEATURES" ,
0xC6 , "SET MULTIPLE MODE" ,
0xE6 , "SLEEP" ,
0x99 , "SLEEP" ,
0xE2 , "STANDBY" ,
0x96 , "STANDBY" ,
0xE0 , "STANDBY IMMEDIATE" ,
0x94 , "STANDBY IMMEDIATE" ,
0xE8 , "WRITE BUFFER" ,
0xCA , "WRITE DMA" ,
0xCC , "WRITE DMA QUEUED" ,
0xC5 , "WRITE MULTIPLE" ,
0x30 , "WRITE SECTORS" ,
0x3C , "WRITE VERIFY" ,
0x00 , "" // end of table
} ;
unsigned char * trc_get_cmd_name( unsigned char flg, unsigned char cc )
{
int ndx = 0;
if ( ( flg == TRC_FLAG_EMPTY ) || ( flg == TRC_FLAG_CDB ) )
return "";
if ( flg == TRC_FLAG_SRST )
return "SOFT RESET";
while ( * cmdNames[ndx].cmdName )
{
if ( cc == cmdNames[ndx].cmdCode )
return cmdNames[ndx].cmdName;
ndx ++ ;
}
return "";
}
//**************************************************************
// ATA status names lookup table and lookup function
static struct
{
unsigned char bitPos;
unsigned char * bitName;
} ataStatusNames[] =
{
0x80 , "BSY " ,
0x40 , "DRDY " ,
0x20 , "DF " ,
0x10 , "DSC " ,
0x08 , "DRQ " ,
0x04 , "CORR " ,
0x02 , "IDX " ,
0x01 , "ERR "
} ;
static unsigned char ataStatusNameBuf[48];
unsigned char * trc_get_st_bit_name( unsigned char st )
{
int ndx;
if ( st & 0x80 )
st = 0x80;
* ataStatusNameBuf = 0;
for ( ndx = 0; ndx < 8; ndx ++ )
{
if ( st & ataStatusNames[ndx].bitPos )
strcat( ataStatusNameBuf, ataStatusNames[ndx].bitName );
}
return ataStatusNameBuf;
}
//**************************************************************
// ATA error names lookup table and lookup function
static struct
{
unsigned char bitPos;
unsigned char * bitName;
} ataErrorNames[] =
{
0x80 , "BBK:ICRC " ,
0x40 , "UNC " ,
0x20 , "MC " ,
0x10 , "IDNF " ,
0x08 , "MCR " ,
0x04 , "ABRT " ,
0x02 , "TK0NF " ,
0x01 , "AMNF "
} ;
static unsigned char ataErrorNameBuf[48];
unsigned char * trc_get_er_bit_name( unsigned char er )
{
int ndx;
* ataErrorNameBuf = 0;
for ( ndx = 0; ndx < 8; ndx ++ )
{
if ( er & ataErrorNames[ndx].bitPos )
strcat( ataErrorNameBuf, ataErrorNames[ndx].bitName );
}
return ataErrorNameBuf;
}
//**************************************************************
// error name lookup table and lookup function
static struct
{
int errCode;
unsigned char * errName;
} errNames[] =
{
1 , "Soft Reset timed out polling for device 0 to set BSY=0" ,
2 , "Soft Reset timed out polling device 1" ,
3 , "Soft Reset timed out polling for device 1 to set BSY=0" ,
11 , "Device selection timed out polling for BSY=0" ,
12 , "Device selection timed out polling for RDY=1" ,
21 , "Non-Data command ended with bad status" ,
22 , "Non-Data command timed out waiting for an interrupt" ,
23 , "Non-Data command timed out polling for BSY=0" ,
24 , "Exec Dev Diag command timed out polling device 1" ,
31 , "PIO Data In command terminated by error status" ,
32 , "Device should be ready to transfer data but DRQ=0" ,
33 , "PIO Data In command ended with bad status" ,
34 , "PIO Data In command timed out waiting for an interrupt" ,
35 , "PIO Data In command timed out polling for BSY=0" ,
41 , "PIO Data Out command terminated by error status" ,
42 , "Device should be ready to transfer data but DRQ=0" ,
43 , "PIO Data Out command ended with bad status" ,
44 , "PIO Data Out command timed out waiting for an interrupt" ,
45 , "PIO Data Out command timed out polling for BSY=0" ,
46 , "Extra interrupt at start of a PIO Data Out command" ,
47 , "PIO Data Out command timed out polling for BSY=0" ,
51 , "Timeout waiting for BSY=0/DRQ=1 for cmd packet transfer" ,
52 , "Bad status at command packet transfer time" ,
53 , "Timeout waiting for interrupt for data packet transfer" ,
54 , "Timeout polling for BSY=0/DRQ=1 for a data packet" ,
55 , "Bad status at data packet transfer time" ,
56 , "Timout waiting for final interrupt at end of command" ,
57 , "Timeout polling for final BSY=0 at end of command" ,
58 , "Bad status at end of command" ,
59 , "Buffer overrun (host buffer too small)" ,
60 , "Byte count for data packet is zero" ,
70 , "No DMA channel is setup" ,
71 , "End of command without complete data transfer" ,
72 , "Timeout waiting for 1st transfer to complete" ,
73 , "Timeout waiting for command to complete" ,
74 , "Bad status at end of command" ,
75 , "Timeout waiting for BSY=0/DRQ=1 for cmd packet transfer" ,
76 , "Bad status at command packet transfer time" ,
77 , "ATA command code is not C8H or CAH" ,
80 , "No tag available now" ,
81 , "Timeout polling for SERV=1" ,
0 , "" // end of table
} ;
unsigned char * trc_get_err_name( int ec )
{
int ndx = 0;
while ( * errNames[ndx].errName )
{
if ( ec == errNames[ndx].errCode )
return errNames[ndx].errName;
ndx ++ ;
}
return "";
}
//**************************************************************
static struct
{
unsigned int pErrCode;
unsigned char * pErrName;
} pErrNames[] =
{
FAILBIT0 , "slow setting BSY=1 or DRQ=1 after A0 cmd" ,
FAILBIT1 , "got interrupt before cmd packet xfer" ,
FAILBIT2 , "SC wrong at cmd packet xfer time" ,
FAILBIT3 , "byte count wrong at cmd packet xfer time" ,
FAILBIT4 , "SC (CD bit) wrong at data packet xfer time" ,
FAILBIT5 , "SC (IO bit) wrong at data packet xfer time" ,
FAILBIT6 , "byte count wrong at data packet xfer time" ,
FAILBIT7 , "byte count odd at data packet xfer time" ,
FAILBIT8 , "SC (CD and IO bits) wrong at end of cmd" ,
FAILBIT9 , "fail bit 9" ,
FAILBIT10 , "fail bit 10" ,
FAILBIT11 , "fail bit 11" ,
FAILBIT12 , "fail bit 12" ,
FAILBIT13 , "fail bit 13" ,
FAILBIT14 , "fail bit 14" ,
FAILBIT15 , "extra interrupts detected"
} ;
//**************************************************************
// command or reset error display data
static int errDmpLine = 0;
static int errDmpLine2 = 0;
//**************************************************************
// start the display of a command or reset error display
void trc_err_dump1( void )
{
errDmpLine = 1;
errDmpLine2 = 0;
}
//**************************************************************
// return one line of a command or reset error display,
// returns NULL at end
unsigned char * trc_err_dump2( void )
{
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, " Command Code: -- %s ",
trc_get_cmd_name( TRC_FLAG_SRST, 0 ) );
else
sprintf( trcDmpBuf, " Command Code: %02X = %s ",
reg_cmd_info.cmd,
trc_get_cmd_name( TRC_FLAG_CMD, reg_cmd_info.cmd ) );
return trcDmpBuf;
}
if ( errDmpLine == 2 )
{
errDmpLine = 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -