📄 example1.c
字号:
// Example1.c -- Some ATA command examples
#if 0
Some simple instructions for those of you that would like to
compile my driver code and try it.
1) I've always used Borland C (or C++, the driver code is plain C
code). One file contains a few lines of embedded ASM code. You will
need Borland's TASM too.
2) I've always used small memory model but I think the driver code
will work with any memory mode. See the MEMMOD variable in the
make file (EXAMPLE1.MAK).
3) The EXAMPLE1.EXE program is a DOS real mode program. It will
not execute in a DOS session (a virtual x86 session) under Windows!
You should make a DOS boot floppy and boot your system for it and
execute the EXAMPLE1.EXE program from that floppy.
4) Here is a very small program that shows how to use the driver
code to issue some ATA commands.
This program has one required command line parameter to specify
the device to run on: P0, P1, S0 or S1.
#endif
//---------- options to include LBA48 and/or PCI Bus Mastering DMA
#define INCL_LBA48 0 // set to 1 to include 48-bit LBA
#define INCL_PCI_DMA 1 // set to 1 to include PCI DMA
//---------- begin
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include "ataio.h"
int pciBus = -1;
int pciDev = -1;
int pciFun = -1;
int priSec = -1;
int dev = -1;
int irqNum = -1;
unsigned int cmdBase = 0xffff;
unsigned int ctrlBase = 0xffff;
unsigned int bmcrBase = 0xffff;
unsigned char * devTypeStr[]
= { "NO DEVICE", "UNKNOWN TYPE", "ATA", "ATAPI" };
#define BUFFER_SIZE 4096
unsigned char buffer[BUFFER_SIZE];
unsigned char far * bufferPtr;
/*********************************************************/
static void pause( void );
static void pause( void )
{
// clear any queued up keys
while ( kbhit() )
{
if ( getch() == 0 )
getch();
}
// pause until key hit
printf( "Press any key to continue...\n" );
while ( ! kbhit() )
/* do nothing */ ;
// clear any queued up keys
while ( kbhit() )
{
if ( getch() == 0 )
getch();
}
}
/*********************************************************/
static long get_dnumber( unsigned char * s );
static long get_dnumber( unsigned char * s )
{
char * cp;
long val;
strupr( s );
if ( strspn( s, "0123456789" ) != strlen( s ) )
return -1L;
val = strtol( s, & cp, 0 );
if ( * cp != 0 )
return -1L;
return val;
}
/**********************************************************
**
** get a word of PCI config data from BIOS INT 1AH
**
**********************************************************/
unsigned int GetPciWord( unsigned int busNum, unsigned int devNum,
unsigned int funNum, unsigned int regNum );
unsigned int GetPciWord( unsigned int busNum, unsigned int devNum,
unsigned int funNum, unsigned int regNum )
{
union REGS ir, or;
if ( regNum & 0x0001 )
return 0xffff;
ir.x.ax = 0xb109;
ir.x.bx = ( busNum << 8 ) | ( devNum << 3 ) | funNum;
ir.x.di = regNum;
int86( 0x1a, & ir, & or );
if ( or.x.cflag )
return 0xffff;
return or.x.cx;
}
//**********************************************
// a little function to display all the error
// and trace information from the driver
void ShowAll( void );
void ShowAll( void )
{
int lc = 0;
unsigned char * cp;
printf( "ERROR !\n" );
// display the command error information
trc_err_dump1(); // start
while ( 1 )
{
cp = trc_err_dump2(); // get and display a line
if ( cp == NULL )
break;
printf( "* %s\n", cp );
}
pause();
// display the command history
trc_cht_dump1(); // start
while ( 1 )
{
cp = trc_cht_dump2(); // get and display a line
if ( cp == NULL )
break;
printf( "* %s\n", cp );
lc ++ ;
if ( ! ( lc & 0x000f ) )
pause();
}
// display the low level trace
trc_llt_dump1(); // start
while ( 1 )
{
cp = trc_llt_dump2(); // get and display a line
if ( cp == NULL )
break;
printf( "* %s\n", cp );
lc ++ ;
if ( ! ( lc & 0x000f ) )
pause();
}
if ( lc & 0x000f )
pause();
}
//**********************************************
void ClearTrace( void );
void ClearTrace( void )
{
// clear the command history and low level traces
trc_cht_dump0(); // zero the command history
trc_llt_dump0(); // zero the low level trace
}
//**********************************************
int main( int ac, char * av[] )
{
int numDev;
int rc;
printf( "ATADRVR EXAMPLE1 Version " ATA_DRIVER_VERSION ".\n" );
//---------- initialization and command line option processing
printf( "Usage: EXAMPLE1 pciBus pciDev pciFun dev irqNum\n" );
// av[n] 1 2 3 4 5
printf( " If irqNum is zero it will be defaulted.\n" );
if ( ac != 6 )
{
printf( "Missing or extra command line options !\n" );
return 1;
}
pciBus = (int) get_dnumber( av[1] );
pciDev = (int) get_dnumber( av[2] );
pciFun = (int) get_dnumber( av[3] );
if ( ! stricmp( av[4], "P0" ) )
{ priSec = 0; dev = 0; }
if ( ! stricmp( av[4], "P1" ) )
{ priSec = 0; dev = 1; }
if ( ! stricmp( av[4], "S0" ) )
{ priSec = 1; dev = 0; }
if ( ! stricmp( av[4], "S1" ) )
{ priSec = 1; dev = 1; }
irqNum = (int) get_dnumber( av[5] );
printf( "Device %d %d %d %s%d, IRQ %d in not shared mode.\n",
pciBus, pciDev, pciFun,
priSec ? "S" : "P", dev,
irqNum );
if ( ( pciBus < 0 ) || ( pciDev < 0 ) || ( pciFun < 0 )
|| ( priSec < 0 ) || ( dev < 0 ) || ( irqNum < 0 ) )
{
printf( "Invalid command line option(s) !\n" );
return 1;
}
cmdBase = GetPciWord( pciBus, pciDev, pciFun, 0x10 + ( 8 * priSec ) );
ctrlBase = GetPciWord( pciBus, pciDev, pciFun, 0x14 + ( 8 * priSec ) );
bmcrBase = GetPciWord( pciBus, pciDev, pciFun, 0x20 );
if ( ( cmdBase == 0xffff )
|| ( ctrlBase == 0xffff )
|| ( bmcrBase == 0xffff ) )
{
printf( "PCI information invalid !\n" );
return 1;
}
cmdBase &= 0xfffe;
ctrlBase &= 0xfffe;
bmcrBase &= 0xfffe;
if ( cmdBase == 0 )
{
cmdBase = priSec ? 0x170 : 0x1f0;
ctrlBase = priSec ? 0x370 : 0x3f0;
irqNum = priSec ? 15 : 14;
}
else
{
ctrlBase -= 4;
}
if ( priSec )
bmcrBase += 8;
printf( "ATA CMD base %04X, ATA CTRL base %04X, BMCR base %04X\n",
cmdBase, ctrlBase, bmcrBase );
if ( ! irqNum )
{
irqNum = GetPciWord( pciBus, pciDev, pciFun, 0x3c );
irqNum &= 0x00ff;
printf( "IRQ defaulted to %d\n", irqNum );
}
//---------- initialization
// initialize far pointer to the I/O buffer
bufferPtr = (unsigned char far *) buffer;
// tell ATADRVR how big the buffer is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -