QUOTE (LLXX @ Jul 9 2006, 12:29 AM)

Another alternative is to check for drives via hardware I/O through the ports starting at 1F0 (primary IDE controller) and 170 (secondary IDE controller)
That method seems to yield the best results (including an
ASCII model name) - even on older computers where the
BIOS is incapable of detecting or supporting the drive.
I copied and pasted a chunk below from an IDE document
I didn't know I had.
If you have SCSI like me, the simple method is to load an
ASPI driver from CONFIG.SYS. Both Adaptec and LSI drivers
will scan the bus and list all devices by default. The hard
but more interesting way is to program the SCSI host
adapter card directly - get the data sheet/manual first.
(Also, if you ever wondered why a proper SCSI driver
consumes less CPU, the manual should be enlightening.)
LSI53C1010 - PCI to Dual-Channel Ultra160 SCSI ControllerController technical manualIDE doc quote follows...[code]
5. Register Address Decoding
The host addresses the drive with programmed I/O. Host address lines A0, A1,
A2, chip select CS1FX- and CS3FX-, IOR- and IOW- address the disk registers.
Host address lines A3...A9 generate the two chip selects: CS1FX- and CS3FX-.
Chip select CS1FX- accesses the eight hard disk Command Block Registers.
Chip select CS3FX- is valid during 8 bit transfers to/from the Control Block
registers alternate status and Device Control, and drive address.
The drive selects the primary or alternate command block addresses using
address bit A7.
(Note: What the above sentence means is that there is a provision for a
primary host adapter at I/O address 1FX/3FX and a secondary host adapter at
I/O adress 17X/37X. Each host adapter can have up to two hard drives
MASTER/SLAVED off it).
See below for a graphical explanation:
HEX BINARY DESCRIPTION
1FX 0001 1111 XXXX Primary Command Registers
3FX 0011 1111 XXXX Primary Control Registers
17X 0001 0111 XXXX Alternate Command Registers
37X 0011 0111 XXXX Alternate Control Registers
^
|
+--- Address bit A7
X means "don't care" i.e. X can be 0h, 1h, 2h, ..., Dh, Eh, Fh or 0b, 1b).
Data bus lines D8...D15 are valid only when IOCS16- is active and the drive
is transferring data. The transfer of ECC information occurs only on data
bus lines D0...D7 and data bus lines D8...D15 are invalid during such
transfer.
7. I/O Port Functions
+----+------+------+---+---+---+----------------+---------------+
|Addr|-CS1FX|-CS3FX|SA2|SA1|SA0| Read (-IOR) | Write (-IOW) |
+----+------+------+---+---+---+----------------+---------------+-----------+
| | 0 | 0 | X | X | X | ILLEGAL | ILLEGAL | <--+ |
| | 1 | 1 | X | X | X | High Impedance | Not Used | Control |
|3FX | 1 | 0 | 0 | X | X | High Impedance | Not Used | Block |
|3FX | 1 | 0 | 1 | 0 | X | High Impedance | Not Used | Registers |
|3F6 | 1 | 0 | 1 | 1 | 0 | Altern Status | Device Control| | |
|3F7 | 1 | 0 | 1 | 1 | 1 | Drive Address | Not Used | <--+ |
+----+------+------+---+---+---+----------------+---------------+-----------+
|1F0 | 0 | 1 | 0 | 0 | 0 | Data Port | Data Port | <--+ |
|1F1 | 0 | 1 | 0 | 0 | 1 | Error Register | Precomp | | |
|1F2 | 0 | 1 | 0 | 1 | 0 | Sector Count | Sector Count | Command |
|1F3 | 0 | 1 | 0 | 1 | 1 | Sector Number | Sector Number | Block |
|1F4 | 0 | 1 | 1 | 0 | 0 | Cylinder Low | Cylinder Low | Registers |
|1F5 | 0 | 1 | 1 | 0 | 1 | Cylinder High | Cylinder High | | |
|1F6 | 0 | 1 | 1 | 1 | 0 | Drive / Head | Drive / Head | | |
|1F7 | 0 | 1 | 1 | 1 | 1 | Status | Command | <--+ |
+----+------+------+---+---+---+----------------+---------------+-----------+
At power-up or after reset, the Command Block Registers are initialized to
the following values:
REGISTER VALUE
1F1 Error : 01
1F2 Sector Count : 01
1F3 Sector Number : 01
1F4 Cylinder Low : 00
1F5 Cylinder High : 00
1F6 Drive / Head : 00
------------------------------------------------------------------------
8. Register Descriptions
1F0: Read/Write: DATA PORT REGISTER
All data transferred between the device data buffer and the host passes
through this register. Also, the port to which the sector table is
transferred during execution of the Format command. Transfers of ECC
bytes during the execution of Read/Write Long commands are 8 bit
transfers.
1F1: Read: ERROR REGISTER
Contains status information about the last command executed by the
drive. The contents of this register are valid only when the error bit
(ERR) in the Status Register is set, except at drive power-up or at the
completion of the drive's internal diagnostics, when the register
contains a status code. When the error bit (ERR) is set, Error Register
bits are interpreted as such:
+-----+--------+-------------------------------------------------------------+
| BIT | Mnemon | Description |
+-----+--------+-------------------------------------------------------------+
| 7 | BBK | Bad block mark detected in the requested sector's ID field |
| 6 | UNC | Uncorrectable data error encountered |
| 5 | | Not used |
| 4 | IDNF | Requested sector's ID field not found |
| 3 | | Not used |
| 2 | ABRT | Command aborted due to drive status error or invalid command|
| 1 | TK0NF | Track 0 not found during execution of Recalibrate command |
| 0 | AMNF | Data address mark not found after correct ID field found |
+-----+--------+-------------------------------------------------------------+
1F1: Write: WRITE PRECOMPENSATION
The drive ignores the write precompensation value passed by the host.
1F2: Read/Write: SECTOR COUNT REGISTER
Defines the number of sectors of data to be transferred across the host
bus, for the subsequent command. If the value in this register is zero,
the sector count is 256 sectors. If the command executes successfully,
the value in this register at command completion is zero. As each
sector is transferred, the Sector Count register is decremented by one
to reflect the number of sectors remaining to be transferred. If the
command execution is not successful, this register contains the number
of sectors that must be transferred to complete the original request.
1F3: Read/Write: SECTOR NUMBER REGISTER
Contains the ID number of the first sector to be accessed by the
subsequent command. The sector can be from one to the maximum number of
sectors per track. See the command description for additional
information about the contents of the Sector Number Register following
command completion whether successful or unsuccessful.
1F4: Read/Write: CYLINDER LOW REGISTER
Contains the eight low order bits of the starting cylinder address for
any disk access. On multiple sector transfers that cross cylinder
boundaries, this register is updated at the end of the command to
reflect the current cylinder number. The least significant bits of the
cylinder address are loaded into the cylinder low register.
1F5: Read/Write: CYLINDER HIGH REGISTER
Contains the eight high order bits of the starting cylinder address for
any disk access. On multiple sector transfers that cross cylinder
boundaries, this register is updated at hte end of the command to
reflect the current cylinder number. The most significant bits of the
cylinder address are loaded into the cylinder high register.
1F6: Read/Write: DRIVE/HEAD REGISTER
Contains the drive ID number and its head number for any disk access.
The contents of the Drive/Head Register are defined on execution of the
Initialize Drive Parameters command. The bits are defined as follows:
+-----+----------+---------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+---------------------------------------------------------+
| 7 | Reserved | Always one. |
| 6 | Reserved | Always zero. |
| 5 | Reserved | Always one. |
| 4 | DRV | 0 to select primary drive, 1 to select secondary drive. |
| 3 | HS3 | MSB of head number. |
| 2 | HS2 | |
| 1 | HS1 | |
| 0 | HS0 | LSB of head number. |
+-----+----------+---------------------------------------------------------+
Upon command completion this register is updated to refplect the head
number currently selected.
1F7: Read: STATUS REGISTER
Contains information about the status of the drive and controller. The
contents of this register are updated at the completion of each
command. When the busy bit is set, no other bits in the Command Block
Registers are valid. When the busy bit is not set, the information in
the Status Register and Command Block Registers is valid.
+-----+----------+----------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+----------------------------------------------------------+
| 7 | BUSY | Busy bit. Set by the controller logic of the drive when |
| | | ever the drive has access to and the host is locked out |
| | | of the Command Block Registers. Set under the following |
| | | conditions: |
| | | o Within 400 nsec after the negation of RESET or after |
| | | SRST is set in the Device Control Register. After a |
| | | reset it is recomended that BUSY be set no more than |
| | | 30 seconds. |
| | | o Within 400 nsec of a host write to the Command |
| | | Register with a Recalibrate, Read Long, Read Buffer, |
| | | Read, Read Verify, Initialize Drive Parameters, Seek |
| | | Identify Drive, or Execute Drive Diagnostic command. |
| | | o Within 5 microseconds following the transfer of 512 |
| | | bytes of data during the execution of a Write, Write |
| | | Buffer or Format Track command; or 512 bytes of data |
| | | and the appropriate number of ECC bytes during the |
| | | execution of a Write Long command. |
| | | When BUSY is set no Command Block Register can be |
| | | written too and a read of any Command Block Register |
| | | returns the contents of the Status Register. |
| | | |
| 6 | DRDY | Drive Ready bit. Indicates that the drive is ready to |
| | | accept commands. When and error occurs, this bit stays |
| | | unchanged until the host reads the Status Register then |
| | | again indicates that hte drive is ready. On power up, |
| | | this bit should be cleared and should remain cleared |
| | | until the drive is up to speed and ready to accept a |
| | | command. |
| | | |
| 5 | DWF | Drive Write Fault bit. When an error occurs, this bit |
| | | remains unchanged until the host reads the Status |
| | | Register, then again indicates the current write fault |
| | | status. |
| | | |
| 4 | DSC | Drive Seek Complete bit. This bit is set when a seek |
| | | operation is complete and the heads are settled over a |
| | | track. When an error occurs, this bit remains unchanged |
| | | until the host reads the Status Register, then again it |
| | | indicates the current seek complete status. |
| | | |
| 3 | DRQ | Data Request bit. When set it indicates that the drive |
| | | is ready to transfer a word or byte of data between the |
| | | host and the data port. |
| | | |
| 2 | CORR | Corrected Data bit. When a correctable data error has |
| | | been encountered and the data has been corrected, this |
| | | bit is set. This condition does not terminate a multi |
| | | sector read operation. |
| | | |
| 1 | INDEX | Index bit. Set when the index mark is detected once per |
| | | disk revolution. |
| | | |
| 0 | ERROR | Error bit. When set indicates that the previous command |
| | | ended in an error. The other bits in the Error Register |
| | | and Status Register contain additional information about |
| | | the cause of the error. |
+-----+----------+----------------------------------------------------------+
1F7: Write: COMMAND REGISTER
When the host request a command it is transferred to the hard drive
through an eight bit code written to the command register. As soon as
the drive receives a command in its command register, it begins
execution of the command. The following table lists the commands in
alphabetical order and the parameters for each executable command:
+--------+---------------------------------+-----------------+
| Command| Command Description | Parameters Used |
| Code | | PC SC SN CY DH |
+--------+---------------------------------+-----------------+
| 98h @ | Check Power Mode | V D |
| E5h @ | Check Power Mode (same as 98h) | V D |
| 90h | Execute Drive Diagnostic | D+ |
| 50h | Format Track | V V |
| ECh @ | Identify Drive | D |
| 97h @ | Idle | V D |
| E3h @ | Idle (same as 97h) | V D |
| 95h @ | Idle Immediate | D |
| E1h @ | Idle Immadiate (same as 95h) | D |
| 91h | Initialize Drive Parameters | V V |
| E4h @ | Read Buffer | D |
| C8h @ | Read DMA With Retry | >> Unknown << |
| C9h @ | Read DMA | >> Unknown << |
| C4h @ | Read Multiple | V V V V |
| 20h | Read Sectors With Retry | V V V V |
| 21h | Read Sectors | V V V V |
| 22h | Read Long With Retry | V V V V |
| 23h | Read Long | V V V V |
| 40h | Read Verify Sectors With Retry | V V V V |
| 41h | Read Verify Sectors | V V V V |
| 1Xh | Recalibrate | D |
| 7Xh | Seek | V V |
| EFh @ | Set Features | V D |
| C6h @ | Set Multiple Mode | V D |
| 99h @ | Set Sleep Mode | D |
| E6h @ | Set Sleep Mode (same as 99h) | D |
| 96h @ | Standby | V D |
| E2h @ | Standby (same as 96h) | V D |
| 94h @ | Standby Immediate | D |
| E0h @ | Standby Immediate (same as 94h) | D |
| 8Xh | Vendor Unique | >> Unknown << |
| 9Ah | Vendor Unique | >> Unknown << |
| C0h | Vendor Unique | >> Unknown << |
| C1h | Vendor Unique | >> Unknown << |
| C2h | Vendor Unique | >> Unknown << |
| C3h | Vendor Unique | >> Unknown << |
| F5h | Vendor Unique | >> Unknown << |
| F6h | Vendor Unique | >> Unknown << |
| F7h | Vendor Unique | >> Unknown << |
| F8h | Vendor Unique | >> Unknown << |
| F9h | Vendor Unique | >> Unknown << |
| FAh | Vendor Unique | >> Unknown << |
| FBh | Vendor Unique | >> Unknown << |
| FCh | Vendor Unique | >> Unknown << |
| FDh | Vendor Unique | >> Unknown << |
| FEh | Vendor Unique | >> Unknown << |
| FFh | Vendor Unique | >> Unknown << |
| E8h @ | Write Buffer | D |
| CAh @ | Write DMA With Retry | >> Unknown << |
| CBh @ | Write DMA | >> Unknown << |
| C5h @ | Write Multiple | V V V V |
| E9h @ | Write Same | >> Unknown << |
| 30h | Write Sectors With Retry | V V V V |
| 31h | Write Sectors | V V V V |
| 32h | Write Long With Retry | V V V V |
| 33h | Write Long | V V V V |
| 3Ch @ | Write Verify | V V V V |
+--------+---------------------------------+-----------------+
KEY FOR SYMBOLS IN ABOVE TABLE:
PC Register 1F1: Write Precompensation
SC Register 1F2: Sector Count
SN Register 1F3: Sector Number
CY Register 1F4+1F5: Cylinder low + high
DH Register 1F6: Drive / Head
@ These commands are optional and may not be supported by some drives.
D Only DRIVE parameter is valid, HEAD parameter is ignored.
D+ Both drives execute this command regardless of the DRIVE parameter.
V Indicates that the register contains a valid paramterer.
Commands with >> Unknown << Parameters are not described in this
document.
If a parameter is blank, then the command does not require the contents
of that register.
3F6: Read: Alternate Status Register
Contains the same information as the Status Register in the Command
Block. Reading the Alternate Status Register does not imply an
interrupt acknowledge from the host or clear a pending interrupt. See
the description of the Status Register above for a definition of bits
in this register.
3F6: Write: Device Control Register
The bits in the Device Control Register are lister in the table below:
+-----+----------+----------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+----------------------------------------------------------+
| 7 | Reserved | |
| 6 | Reserved | |
| 5 | Reserved | |
| 4 | Reserved | |
| 3 | 1 | Always set. |
| 2 | SRST | Host Software Reset bit. When this bit is set the drive |
| | | is held reset. If two drives are daisy chained on the |
| | | interface, this bit resets both drives simultaneously. |
| | | |
| 1 | nIEN | Drive Interrupt Enable bit. The enable bit for the drive |
| | | interrupt to the host. When nIEN is 0 or the drive is |
| | | selected the host interrupt signal INTRQ is enabled |
| | | through a tri state buffer to the host. When nIEN is 1 |
| | | or the drive is not selected the host interrupt signal |
| | | INTRQ is in a hig himpedance state regardless of the |
| | | presence or absence of a pending interrupt. |
| | | |
| 0 | 0 | Always clear. |
+-----+----------+----------------------------------------------------------+
3F7: Read: Drive Address Register
This port returns the drive select and head select addresses for the
drive currently selected. The Drive Address bits are listed in the
table below:
+-----+----------+------------------------------------------------------+
| BIT | Mnemonic | Description |
+-----+----------+------------------------------------------------------+
| 7 | HiZ | This bit is in high impedance when read. |
| 6 | nWTG | Write Gate bit. When a write to the hard drive is in |
| | | progress, nWTG is 0 |
| 5 | nHS3 | Negated MSB of head number |
| 4 | nHS2 | |
| 3 | nHS1 | |
| 2 | nHS0 | Negated LSB of head number. |
| 1 | nDS1 | Drive 1 Select bit. When 0, Drive 1 is selected. |
| 0 | nDS0 | Drive 0 Select bit. When 0, Drive 0 is selected. |
+-----+----------+------------------------------------------------------+
------------------------------------------------------------------------
9. Command Descriptions
The drive decodes and executes commands loaded into the Command Register. In
applications involving two hard drives, both drives receive all commands but
only the selected drive executes commands. The recommended procedure for
executing a command on the selected drive is:
1. Wait for drive to clear BUSY.
2. Load required parameters in the Command Block Registers.
3. Activate the Interrupt Enable (nIEN) bit.
4. Wait for drive to set DRDY.
5. Write the command code to the Command Register.
Execution of the command begins as soon as the drive loads the Command Block
Register. The remainder of this section describes the function of each
command.
90h: Execute Drive Diagnostic
Performs internal diagnostic tests implemented by the drive. Drive 0
sets BUSY within 400 nsec of the receipt of the command.
If Drive 1 is present:
o Both drives execute diagnostics.
o Drive 0 waits up to 5 seconds for Drive 1 to assert PDIAG-
o If Drive 1 does not assert PDIAG-, indicatinf a failure, Drive 0
appends 80h with its own diagnostic status.
o If the host detects a Drive 1 diagnostic failure when reading
Drive 0 status it sets the DRV bit then reads the Drive 1 status.
If Drive 1 is not present:
o Drive 0 reports only its own diagnostic results.
o Drive 0 clears BUSY and generates an interrupt.
If Drive 1 fails diagnostics, Drive 0 appends 80h with its own
diagnostic status and loads that code in the Error Register. If Drive 1
passes its diagnostics or no Drive 1 is present, Drive 0 appends 00h
with its own diagnostic status and loads that in the Error Register.
The Diagnostic Code written to the Error Register is a unique 8 bit
code as listed below.
+------+----------------------------------+
| Code | Description |
+------+----------------------------------+
| 01 | No error detected. |
| 02 | Formatter device error. |
| 03 | Sector buffer error. |
| 04 | ECC circuitry error. |
| 05 | Controller microprocessor error. |
| 8X | Drive 1 failed. |
+------+----------------------------------+
50h: Format Track
The track address is specified in the Sector Count Register. When the
drive accepts this command, it sets the DRQ bit then waits for the host
to fill the sector buffer. When the buffer is full, the drive clears
DRQ, sets BUSY and begins command execution.
ECh: Identify Drive
This command enables the host to receive paramater information from the
drive. When the host issues this command, the drive sets BUSY, stores
the required parameter information in the sector buffer, sets DRQ and
generates an interrupt. The host then reads the information from the
sector buffer. The table below defines the words stored in the buffer.
All reserved fields should be zeros.
+-------+-----------------------------------------------------------------+
| Word | Description |
+-------+-----------------------------------------------------------------+
| 00h | Bit mapped general configuration information. True when bit set |
| | Bit 15: Reserved for non magnetic drives. &nbs