📄 atadrvr.ug
字号:
ATADRVR
ATA/ATAPI Low Level Driver
User's Guide
by Hale Landis
Version 16J and higher
INTRODUCTION
------------
ATADRVR is Hale Landis' C code that shows the low level
programming required to configure and execute commands on ATA and
ATAPI devices. Over the years this code has been updated to
support all of the ATA and now ATA/ATAPI standards. This C code
has been placed into the public domain by Hale Landis. This C
code has no copyright or other restrictions on how it is used.
USING ATADRVR
-------------
Before using ATADRVR in your project you should read the
PIO.UG, DMA.UG and SATA.UG documentation files.
ATADRVR and the EXAMPLE1 and EXAMPLE2 programs are DOS "real
mode" programs. This software will not execute in a Windows DOS
session (a virtual x86 session). You must use a compiler and
linker that are able to create DOS real mode programs. Hale uses
Borland C/C++ 4.5. Note that the free (or low cost) Borland C++
5.x compiler will not compile this code -- you need the full
Borland C++ 5.x compiler.
The best way to see how this code can be used is shown in the C
program files EXAMPLE1.C and EXAMPLE2.C. ATADRVR provides all of
the funcitons and facilities needed to perform the low level I/O
port activities on an x86 computer so that ATA and ATAPI commands
can be executed.
ATADRVR also includes detailed low level and command history
tracing funcitons.
FILE ORGANIZATION
-----------------
ATADRVR source code is organized into two H files and several C
files.
The H files are:
ATAIO.H
The file ATAIO.H defines all of the "public" functions and data
for ATADRVR. This file should be included into any program using
the ATADRVR functions.
The C files are:
ATAIOINT.C
ATAIOISA.C
ATAIOPCI.C
ATAIOPIO.C
ATAIOREG.C
ATAIOSUB.C
ATAIOTMR.C
ATAIOTRC.C
EXAMPLE1.C
EXAMPLE2.C
The file ATAIOINT.C contains the x86 interrupt setup and handling
data and functions. The public symbols in this file begin with
the characters "int_".
The file ATAIOISA.C contains the x86 ISA bus DMA functions. The
public symbols in this file begin with characters "dma_isa_".
The file ATAIOPCI.C contains the x86 PCI Bus Mastering DMA
functions. The public symbols in this file begin with characters
"dma_pci_".
The file ATAIOPIO.C contains the lowest level I/O port access
functions. The public symbols in this file begin with characters
"pio_".
The file ATAIOREG.C contains ATA and ATAPI functions to perform
ATA Soft Reset, Non-Data, PIO Data IN, PIO Data Out and ATAPI
Packet command protocols. The public symbols in this file begin
with characters "reg_".
The file ATAIOSUB.C contains severals "private" functions used by
ATADRVR.
The file ATAIOTMR.C contains the timer reading and command
timeout functions. The public symbols in this file begin with
characters "tmr_".
The file ATAIOTRC.C contains the low level and command history
trace functions. The public symbols in this file begin with
characters "trc_".
The file EXAMPLE1.C is an example of using ATADRVR to configure
an ATA device and execute a few commands.
The file EXAMPLE2.C is an example of using ATADRVR to configure
an ATAPI CD-ROM device and execute a few commands.
NOTE
----
If you use ATADRVR in a program you should use only the public
symbols. This will allow you too upgrade to newer versions of
ATADRVR (assuming there will be new versions in the future)
with minimum effort. The private data and functions are
subject to change in future versions of ATADRVR.
USING ATADRVR
-------------
Before using the ATADRVR code in your program, please review the
EXAMPLE1.C, EXAMPLE1.MAK, EXAMPLE2.C and EXAMPLE2.MAK files.
These files will provide a basic overview of how this driver code
can be used.
The basics of using ATADRVR, as shown in EXAMPLE1.C or
EXAMPLE2.C, are these:
1) #include "ataio.h" in your program.
2) Call pio_set_iobase_addr() or pio_set_memory_addr() to set the
base I/O or memory address used by the ATA host adapter.
3) Call reg_config() so that ATADRVR can determine what devices
are attached to the ATA host adapter.
4) Call reg_reset() or any of the other "reg" functions to issue
ATA or ATAPI commands in PIO data transfer mode.
ATADRVR has been developed using Borland C and can be compiled in
any x86 real mode memory mode.
48-BIT LBA PIO DATA TRANSFERS
-----------------------------
One of the dumber things T13 did was to allow the 48-bit LBA
commands to transfer huge amounts of data, up to 65536 sectors
(33Mbytes) in a single command. ATADRVR is able to support these
huge transfers even if the data buffer is not that big. The I/O
buffer must be at least the size of the largest DRQ block that
will be transferred by a PIO data transfer command. For
READ/WRITE SECTORS that is a single sector buffer. For
READ/WRITE MULTIPLE that is a buffer that holds the current
multiple block count number of sectors. For PACKET commands
the size of a DRQ data block can not exceed the buffer size
and (according to all ATA/ATAPI protocol rules) can not exceed
the PACKET command's Byte Count Limit (BCL).
This mode of PIO data transfer is enabled when the
reg_drq_block_call_back function pointer is not NULL. Note that
this facility of ATADRVR can be used with any PIO Data In/Out
command and/or any PIO PACKET command.
ATADRVR supports these transfers by calling back to a user
supplied function at these times:
* For ATA or PACKET PIO Data In commands, after each DRQ block
has been read from the device. The call back function should
use this call to access the data buffer.
* For ATA or PACKET PIO Data Out commands, before each DRQ block
is written to the device. The call back function should use
this call to fill the data buffer.
The call back function receives a pointer to a REG_CMD_INFO
structure. It must use the data in this structure to determine
what is happening. The call back function has no return value.
The reg_drq_block_call_back function pointer is set to NULL
before the ATA or PACKET PIO Data In/Out functions return.
ATADRVR REFERENCE
-----------------
Each of the public functions and symbols of ATADRVR are described
below in alphabetical order.
Functions And Data In ATAIOINT.C
--------------------------------
These functions setup interrupt handling for the ATA host
adapter. Interrupts are not required in order to execute nost
ATA or ATAPI commands but are usually used. Interrupts are
required in order to execute DMA data transfer commands. If
int_enable_irq() is called, then int_disable_irq() MUST be called
before your program exits (otherwise your system may hang). The
functions int_enable_irq() and int_disable_irq() may be called
multiple times in order to switch between polling and interrupt
mode on a command by command basis.
void int_disable_irq( void );
Disable interrupt use.
int int_enable_irq( int shared, int irqNum,
unsigned int bmAddr, unsigned int ataAddr );
Enable interrupt use. shared is 0 or not 0. shared is not 0
to use the IRQ in shared mode. irqNum is 1 to 15. bmAddr is
the I/O port address for the BMCR/BMIDE Status regiser. This
value is found in BAR 4 (offset 20H) of the ATA controllers
PCI configuration space data. bmAddr is that value +2 for the
primary side of the controller and +10 for the secondary side
of the controller. ataAddr is the I/O port address for the
ATA Status register (not the Alternate Status register!).
int int_use_intr_flag;
This value is READONLY -- DO NOT ALTER.
The value is not zero if an IRQ is currently configured.
Functions And Data In ATAIOISA.C
--------------------------------
These functions setup ISA bus DMA (ATA Multiword DMA) and perform
ATA and ATAPI commands using DMA. The function dma_isa_config()
MUST be called with no error before any of the other functions
will attempt to execute a command.
int dma_isa_chs( int dev, // device (0 or 1)
int cmd, // command register
int fr, // feature register
int sc, // sector count
unsigned int cyl, // CHS cylinder high/low
int head, // CHS head
int sect, // CHS sector
unsigned seg, // buffer address
unsigned off ); // buffer address
Execute an ATA Read DMA (C8H) or ATA Write DMA (CAH) command
using CHS sector addressing.
Returns 0 if no error or 1 if there is an error. See the
contents of reg_cmd_info.
int dma_isa_lba28( int dev, // device (0 or 1)
int cmd, // command register
int fr, // feature register
int sc, // sector count
long lba, // LBA
unsigned seg, // buffer address
unsigned off ); // buffer address
Execute an ATA Read DMA (C8H) or ATA Write DMA (CAH) command
using LBA sector addressing.
Returns 0 if no error or 1 if there is an error. See the
contents of reg_cmd_info.
int dma_isa_lba48( int dev, // device (0 or 1)
int cmd, // command register
int fr, // feature register
int sc, // sector count
long lbahi, // LBA upper 16-bits
long lbalo, // LBA lower 32 bits
unsigned seg, // buffer address
unsigned off ); // buffer address
Execute an ATA Read DMA (C8H) or ATA Write DMA (CAH) command
using LBA sector addressing.
Returns 0 if no error or 1 if there is an error. See the
contents of reg_cmd_info.
int dma_isa_config( int chan );
Configure ATADRVR to use ISA bus DMA (ATA Multiword DMA) on
ISA DMA Channel 5, 6 or 7.
int dma_isa_packet( int dev, // device (0 or 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -