The purpose of the XHDI (`eXtended HardDisk Interface') specification is to enhance the communication with drivers for block-oriented mass storage media. We started with the thought of creating a uniform interface for some additional driver features. One goal was to create a standard method for virtual memory systems to lock the eject button of Syquest hard disk drives (you don't want the user to remove the cartridge with the swap partition).
After further discussion, it was clear that the information available via the PUN_INFO structure just wasn't enough and that the missing information should be available with the help of this XHDI specification. Reasons:
The PUN_INFO structure only has room for 16 devices, but BIOS (and some GEMDOS replacements) allow 32 devices
It is impossible to install more than one AHDI-compatible hard disk driver in the system (there is only one PUN_INFO structure)
Atari's definition of device numbers only works for drives with Logical Unit Number 0
For these reasons, the purpose of the XHDI specification is:
To provide more information about the installed devices
To support new driver features like Stop/Start or Lock/Unlock
The XHDI specification doesn't define new driver features - it should be easy to retrofit it into existing drivers.
See also:
XHDI cookie XHDI terminology Partition types Arbitration XHDI
functions SCSI specification
Cookie ID: 'XHDI'. The contents of the cookie points to the start address of a function which provides procedures for dealing with block storage devices. As an additional check, the function is preceded by the LONG constant 0x27011992.
The contents of the XHDI cookie may change (because it can be used by more than one driver). Therefore, in some applications (example: Desk accessories) the cookie contents must be inquired each time before the handler is called.
How to install more than one XHDI driver:
(1) | During the installation, check whether the cookie is already set. If so: |
(2) | For XHGetVersion first jump through the old vector and return the minimum of this and your own version number. |
(3) | For XHDrvMap first jump through the old vector and then OR in the drive bits for the devices supported by you. |
(4) | For all other functions: Check whether it is one of your devices. If not, jump through the old vector. |
See also: XHDI specification About the GEMDOS About the BIOS Cookie jar SCSI specification
Definition of data types:
UWORD: 16-bit, unsigned LONG: 32-bit, signed ULONG: 32-bit, unsigned char *: 32-bit, pointer to a zero terminated string
major: | Major Device Number
| ||||||||||||||||
minor: | Minor Device Number (for `major' 0..15: LUN of the ACSI or SCSI device), maximal 255. | ||||||||||||||||
key: | A 16-bit key, returned by XHReserve, or 0 if the device is not locked or if the key is unknown |
Notation:
Numerical values are, when not specified otherwise, decimal. Hex values (base 16) are introduced by a dollar sign (0x).
See also: XHDI specification About the GEMDOS About the BIOS SCSI specification
For device drivers which support SCSI arbitration, the machine needs an own SCSI device number which must be unique and shouldn't be stored on disk. Atari has reserved byte 16 in the non-volatile memory (NVRAM) of the Atari TT030 and Falcon030 computers. Bit assignments:
Bit 0..2: | Device number |
Bit 7: | Arbitration on (1) or off (0) |
The current arbitration number could be inquired this way:
WORD arbitration_id (VOID) { LONG ret = EINVFN; UBYTE nvmdata = 0; OSHEADER *Sys; LONG oldstack = Super(0L); Sys = *_sysbase; Super((VOID *)oldstack); host_id = -1; /* no arbitration by default */ if (Sys->os_version >= 0x300) ret = NVMaccess (0, 16, (WORD) sizeof (nvmdata), &nvmdata); if (ret == E_OK && (nvmdata & 0x80)) host_id = nvmdata & 7; return host_id; }
See also: XHDI specification SCSI specification About the GEMDOS About the BIOS
Type | Meaning |
BGM | GEMDOS partition > 16 MB |
GEM] | GEMDOS partition < 16 MB |
RAW | Partition type RAW |
The following types can be supported optionally (for example with a configurable list of partition ID's in the driver).
See also: XHDI specification About the GEMDOS About the BIOS
XHDI-1.10 compliant drivers shall support the third partition type RAW (in addition to GEM and BGM). For these partitions, the following should be true:
(1) | The partition size is `arbitrary' (32-bit sector numbers). |
(2) | The partition can be accessed as a BIOS device; Getbpb returns a NULL pointer (so that GEMDOS won't access it; however, calling Getbpb resets the driver internal media change state). |
(3) | Rwabs (in physical or logical mode) and XHReadWrite may be used to access the partition. The physical block size of the medium is used (see XHInqTarget). |
(4) | XHInqDev2 (as compared to XHInqDev) returns size and type of the partition. |
These extensions have been made to make it easier to create drivers for new filesystems for MiNT or MagiC (like the Minix filesystem).
See also: XHDI specification About the GEMDOS About the BIOS
All functions have to be called from supervisor-mode. The effects of a call in user-mode are undefined. All processor registers except d0 are preserved. EINVFN is returned for invalid opcodes.
Some of the function calls - notably `XHReadWrite' - might be implemented by calls to BIOS or XBIOS functions and therefore can activate the `Critical Error Handler'. It's the responsibility of the caller to switch of the `CEH', if this is needed.
The following return values are defined for all functions:
TOS error-codes:
0: | OK (OK) |
-1: | Unspecified error (ERROR) |
-2: | Device not responding (EDRVNR) |
-15: | Unknown device (EUNDEV) |
-32: | Invalid function number (EINVFN) |
-36: | Access denied, device is reserved (EACCDN) |
-46: | Invalid drive number (EDRIVE) |
SCSI error-codes (ranging from -200 to -455)
(-200 - N): | SCSI error-code N (the `Additional Sense Code', byte 12 in the `Extended Sense Format', see Appendix B in `Draft proposed American National Standard for information systems - Revision 11a - SCSI-3 Primary Commands, 28 March 1997) |
IDE error-codes (ranging from -456 to -711)
(-456 - N): | IDE error-code N (value of the IDE error register) |
Note: Obviously, you can get SCSI error-codes only for ACSI or SCSI devices. For other device types like IDE drives the following assignments may be used:
Bit in IDE- | |||
error register | Meaning | SCSI error | XHDI error |
1 | Track 0 not found | $06 | -206 |
0 | DAM not found | $13 | -219 |
4 | ID-Field not found | $12 | -218 |
7 | Bad block mark | $10 | -216 |
6 | Uncorrectable error | $11 | -217 |
2 | Command aborted | $20 | -232 |
5 | Media Change | $28 | -240 |
3 | Media Change requested | $5A | -290 |
(It is recommended to test the bits in the above order).
For other devices (like disk drives connected to the floppy controller) there may be other, not yet defined, error-codes.
Parameters are passed the same way as to GEMDOS functions. All values are put onto the stack, with the 16-bit opcode last, i.e. at the lowest address. The 32-bit result is returned in d0.
Wherever it is specified that `the caller may pass a zero pointer' for a pointer parameter, then passing such a zero pointer indicates that the caller is not interested in the value to be returned. Drivers must always check pointers for zero before dereferencing them.
See also: XHDI specification SCSI specification About the BIOS
Name: | »XHDOSLimits« - Set/get internal limits of DOS. | ||||||||||||||||||||||||||||
Opcode: | 17 | ||||||||||||||||||||||||||||
Syntax: | LONG XHDOSLimits ( UWORD which, ULONG limit ); | ||||||||||||||||||||||||||||
Description: | The function XHDOSLimits asks the driver for the internal
limits of the currently running DOS (or sets the driver's limits).
Example: it can be used by a FAT filesystem driver to inform
the driver about the change of some of the limits. which
describes the type of limit, limit is the new value (with zero
meaning that the value shouldn't be changed). The function returns the
previous value for the limit. As a required functionality starting with XHDI release 1.30 a driver shall retrieve limit values from previously started XHDI drivers, if these exist. When a limit is changed, this information then shall be passed through to other XHDI drivers.
- With XHDI version 1.30 and above:
Note: This function is optional, hence a call may be answered with EINVFN. | ||||||||||||||||||||||||||||
Return value: | The function returns the value of the previous limit. | ||||||||||||||||||||||||||||
Group: | XHDI functions | ||||||||||||||||||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHDriverSpecial« - Use driver-specific extensions. |
Opcode: | 13 |
Syntax: | LONG XHDriverSpecial ( ULONG key1, ULONG key2, UWORD subopcode, VOID *data ); |
Description: | This opcode may be used for driver-specific extensions. It's up
to the driver how to interpret the arguments in subopcode and
data. key1 and key2 are used to specify for
which driver the call is intended: key1 should contain four printable ASCII characters, key2 a random ULONG value (example: date of definition in BCD format). Note: OPTIONAL function, may return EINVFN. |
Return value: | XHDI error-codes. |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHDrvMap« - Return bit-vector with BIOS XHDI device numbers. |
Opcode: | 6 |
Syntax: | ULONG XHDrvMap ( VOID ); |
Description: | XHDrvMap returns a bit-mask of BIOS devices supported by the XHDI driver(s) (like the return value from Drvmap). |
Return value: | The return value is the corresponding bit-vector. |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHEject« - Eject medium or reinsert it again. | ||||||||||||
Opcode: | 5 | ||||||||||||
Syntax: | LONG XHEject ( UWORD major, UWORD minor, UWORD do_eject, UWORD key ); | ||||||||||||
Description: | XHEject ejects or inserts the medium.
| ||||||||||||
Return value: | The code returned in case of errors is undefined. But more information is not really required, since one can make a targeted test for this capability beforehand with XHInqTarget. | ||||||||||||
Group: | XHDI functions | ||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHGetCapacity« - Obtain number of addressable sectors and their size. ermitteln |
Opcode: | 14 |
Syntax: | LONG XHGetCapacity ( UWORD major, UWORD minor, ULONG *blocks, ULONG *blocksize ); |
Description: | The XHGetCapacity functions returns the number of adressable
sectors in blocks and their size in blocksize. Note
that - depending of the device used - this function may need several
seconds to complete. Note: This function is optional, may return EINVFN. |
Return value: | XHDI error-codes |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHGetVersion« - Inquire protocol version. |
Opcode: | 0 |
Syntax: | UWORD XHGetVersion ( VOID ); |
Description: | XHGetVersion returns the current protocol version. Example: 0x0119 is Version 1.19 (the format is similar to that returned by Sversion but high and low bytes are not reversed). This version of the XHDI specification has the version number 0x0130. |
Return value: | The return value describes the version number of the XHDI protocol, with the high byte containing the version number and the low byte the revision. |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHInqDev« - Obtain major and minor device number, start sector and Bios parameter block (BPB of a BIOS device. |
Opcode: | 7 |
Syntax: | LONG XHInqDev ( UWORD bios_device, UWORD *major, UWORD *minor, ULONG *start_sector, BPB *bpb ); |
Description: | XHInqDev returns major device number, minor device number,
starting sector and BPB of a given BIOS device. (Note:
Getting the BPB this way will not reset the internal
media-change state). Note 2: The caller provides a pointer to the BPB structure, which is filled by the driver. |
Return value: | E_OK, EDRNVR (device not responding, e.g. medium not
inserted), EDRIVE (wrong BIOS device number) or some other
applicable error-code. If the error-code is EDRVNR, major and
minor contain the correct values anyway. If start_sector is 0xFFFFFFFF, the device is only temporarily inaccessible (example: you have inserted a cartridge with two partitions, but three drive bits have been reserved for the device). The BPB is invalid if the structure element recsiz is zero. Note: A filesystem is fully described by major and minor device number and the starting block number. This does not mean that it is necessarily a FAT filesystem. The caller may pass a zero pointer for major, minor, start_sector and bpb. |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHInqDev2« - Inquire major and minor device number, start sector and Bios parameter block (BPB) of a device. |
Opcode: | 12 |
Syntax: | LONG XHInqDev2 ( UWORD bios_device, UWORD *major, UWORD *minor, ULONG *start_sector, BPB *bpb, ULONG *blocks, BYTE *partid ); |
Description: | XHInqDev2 returns major device number, minor device number,
starting sector, BPB, size and partition ID of a given BIOS device
(Note: Getting the BPB this way will not reset the
internal media-change state). Note 2: The caller provides a pointer to the BPB structure, which is filled by the driver. The function is available only with XHDI version 1.10 and above. |
Return value: | E_OK, EDRNVR (device not responding, e,g. medium not
inserted), EDRIVE (wrong BIOS device number) or some other
applicable error-code. If the error-code is EDRVNR, major and
minor start_sector contain the correct values anyway. If start_sector is 0xFFFFFFFF, the device is only temporarily inaccessible (example: you have inserted a cartridge with two partitions, but three drive bits have been reserved for the device). The BPB is invalid if the structure element recsiz is zero. If the partition ID isn't available (possible reason: no standard Atari root sector or no root sector at all), an empty string is returned. Starting with XHDI 1.20 for MSDOS-compatible media the one byte partition code is returned as: partid[0] = '\0' (zero byte) partid[1] = 'D' (for 'DOS') partid[2] = Partition code Note: A filesystem is fully described by major and minor device number and the starting block number. This does not mean that it is necessarily a FAT filesystem. Note 2: The caller may pass a zero pointer for major, minor, start_sector, bpb, blocks and partid. |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHInqDriver« - Obtain information about the driver. | ||||||||||||||
Opcode: | 8 | ||||||||||||||
Syntax: | LONG XHInqDriver ( UWORD bios_device, BYTE *name, BYTE *version, BYTE *company, UWORD *ahdi_version, UWORD *maxIPL ); | ||||||||||||||
Description: | XHInqDriver gets information about the driver for the bios_device. | ||||||||||||||
Return value: |
Note: The caller may pass a zero pointer for name, version, company, ahdi_version and maxIPL. | ||||||||||||||
Group: | XHDI functions | ||||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHInqTarget« - Return information about a device. | ||||||||||||||||||||||||||||||
Opcode: | 1 | ||||||||||||||||||||||||||||||
Syntax: | LONG XHInqTarget ( UWORD major, UWORD minor, ULONG *block_size, ULONG *device_flags, BYTE *product_name ); | ||||||||||||||||||||||||||||||
Description: | XHInqTarget returns information about the device specified by major and minor. Reservations made with XHReserve are reflected in device_flags. | ||||||||||||||||||||||||||||||
Return value: |
| ||||||||||||||||||||||||||||||
Group: | XHDI functions | ||||||||||||||||||||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHInqTarget2« - Obtain information about a device. | ||||||||||||||||||||||||||||
Opcode: | 11 | ||||||||||||||||||||||||||||
Syntax: | LONG XHInqTarget2 ( UWORD major, UWORD minor, ULONG *block_size, ULONG *device_flags, BYTE *product_name, UWORD stringlen ); | ||||||||||||||||||||||||||||
Description: | XHInqTarget2 returns information about the device specified by
major and minor (in device_flags: an attribute
vector, in product_name: optionally the product descriptin of
the device). Reservations made with XHReserve are respected. This function is available only with XHDI version 1.01 and above. | ||||||||||||||||||||||||||||
Return value: |
| ||||||||||||||||||||||||||||
Group: | XHDI functions | ||||||||||||||||||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHLastAccess« - Obtain number of milliseconds since the last access. |
Opcode: | 18 |
Syntax: | LONG XHLastAccess ( UWORD major, UWORD minor, ULONG *ms ); |
Description: | XHLastAccess returns in ms the amount of milliseconds
since the last successfull read or write operation on the device. This function is available only with XHDI version 1.25 and above. |
Return value: | XHDI error-codes |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHLock« - Lock or unlock eject button. | ||||||||||||
Opcode: | 3 | ||||||||||||
Syntax: | LONG XHLock ( UWORD major, UWORD minor, UWORD do_lock, UWORD key ); | ||||||||||||
Description: | XHLock locks or unlocks the eject mechanism of the device. The driver has to attend to whether this command is passed on to the device or not (in case the medium is not capable of being locked).
| ||||||||||||
Return value: | The code returned in case of errors is undefined. But more information is not really required, since one can make a targeted test for this capability beforehand with XHInqTarget. | ||||||||||||
Group: | XHDI functions | ||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHMediumChanged« - Informs the driver about mediachange |
Opcode: | 15 |
Syntax: | LONG XHMediumChanged ( UWORD major, UWORD minor ); |
Description: | XHMediumChanged informs the driver that the medium in the given
device has been changed. Upon receiving this notice, the driver should
do the same things as if the device itself had returned a media-change
status. Note: This function is optional and may return EINVFN. |
Return value: | The return value is E_OK if, and only if, this information has been correctly interpreted (this means: all logical drives on the device are either disabled or ready to use). |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHMiNTInfo« - Set or inquire MiNT-specific information. |
Opcode: | 16 |
Syntax: | LONG XHMiNTInfo ( UWORD opcode, VOID *data ); |
Description: | XHMiNTInfo is a function for setting/inquiring MiNT-related
information. The following opcodes are defined (for unknown opcodes EINVFN is returned; E_OK is returned if, and only if, the call has been executed correctly). XH_MI_SETKERINFO (0) [struct kerinfo *data] Sends (through data) a pointer to the MiNT kernel info structure to the driver. The driver can use it for direct calls of kernel functions. XH_MI_GETKERINFO (1) [struct kerinfo **data] Inquires for a previously set MiNT kernel info pointer. The pointer is returned in the struct kerinfo * pointed to by data. If the adress of the MiNT kernel info structure is unknown, data is filled with a NULL pointer. Note: This function is optional and may return EINVFN. |
Return value: | XHDI error-codes |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHNewCookie« - Install additional XHDI handler. | ||||||||
Opcode: | 9 | ||||||||
Syntax: | LONG XHNewCookie ( ULONG newcookie ); | ||||||||
Description: | XHNewCookie installs an additional XHDI handler. Advantage:
The XHDI cookie continues to point to the same address. Those who want
to support this function must do the following:
Those who would like to perform a multiple installation should proceed as follows:
Note: This function is optional and may return EINVFN. | ||||||||
Return value: | XHDI error-codes | ||||||||
Group: | XHDI functions | ||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHReaccess« - Check device for media-change. |
Opcode: | 19 |
Syntax: | LONG XHReaccess ( UWORD major, UWORD minor ); |
Description: | Calling the XHReaccess function causes the driver to check the
device for a possible media-change and to update the partition
information if needed (like XHMediumChange, but the driver checks for
the media- change status before continuing). This function is available only with XHDI version 1.25 and above. |
Return value: | XHDI error-codes |
Group: | XHDI functions |
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHReadWrite« - Read/write physical block numbers. | ||||||||||||||||
Opcode: | 10 | ||||||||||||||||
Syntax: | LONG XHReadWrite ( UWORD major, UWORD minor, UWORD rwflag, ULONG recno, UWORD count, VOID *buf ); | ||||||||||||||||
Description: | XHReadWrite reads or writes physical blocks, like the BIOS
function Rwabs.
| ||||||||||||||||
Return value: | XHDI error-codes | ||||||||||||||||
Group: | XHDI functions | ||||||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHReserve« - Reserve a device, or release it again. | ||||||||||||
Opcode: | 2 | ||||||||||||
Syntax: | LONG XHReserve ( UWORD major, UWORD minor, UWORD do_reserve, UWORD key ); | ||||||||||||
Description: | XHReserve reserves or releases a device. XHLock, XHStop and
XHEject only work for reserved devices if the correct key
parameter is passed. Example: Take a virtual memory manager which has locked a removable hard disk with the swap partition. You don't want the user to be able to unlock this device with a CPX module!
| ||||||||||||
Return value: | On success, a 16-bit key different from 0 is returned. This key must be specified for all further accesses to the device, as well as for releasing it again. | ||||||||||||
Group: | XHDI functions | ||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |
Name: | »XHStop« - Stop device, or restart it again. | ||||||||||||
Opcode: | 4 | ||||||||||||
Syntax: | LONG XHStop ( UWORD major, UWORD minor, UWORD do_stop, UWORD key ); | ||||||||||||
Description: | XHStop stops (ships) or starts the device.
Note: if the drive is accessed, the driver should restart it without an explicit restart call. | ||||||||||||
Return value: | The code returned in case of errors is undefined. But more information is not really required, since one can make a targeted test for this capability beforehand with XHInqTarget. | ||||||||||||
Group: | XHDI functions | ||||||||||||
See also: | Arbitration _drvbits Partition types System variables XHDI cookie XHDI terminology |