mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-15 13:05:43 +01:00
157 lines
6.0 KiB
ObjectPascal
157 lines
6.0 KiB
ObjectPascal
{
|
|
This file is part of the Free Pascal run time library.
|
|
|
|
A file in Amiga system run time library.
|
|
Copyright (c) 1998-2003 by Nils Sjoholm
|
|
member of the Amiga RTL development team.
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
{
|
|
History:
|
|
|
|
Update for AmigaOS 3.9.
|
|
Added const.
|
|
31 Jan 2003.
|
|
|
|
nils.sjoholm@mailbox.swipnet.se
|
|
}
|
|
|
|
{
|
|
SCSI exec-level device command
|
|
}
|
|
|
|
unit scsidisk;
|
|
|
|
INTERFACE
|
|
|
|
uses exec;
|
|
|
|
{--------------------------------------------------------------------
|
|
*
|
|
* SCSI Command
|
|
* Several Amiga SCSI controller manufacturers are converging on
|
|
* standard ways to talk to their controllers. This include
|
|
* file describes an exec-device command (e.g. for hddisk.device)
|
|
* that can be used to issue SCSI commands
|
|
*
|
|
* UNIT NUMBERS
|
|
* Unit numbers to the OpenDevice call have encoded in them which
|
|
* SCSI device is being referred to. The three decimal digits of
|
|
* the unit number refer to the SCSI Target ID (bus address) in
|
|
* the 1's digit, the SCSI logical unit (LUN) in the 10's digit,
|
|
* and the controller board in the 100's digit.
|
|
*
|
|
* Examples:
|
|
* 0 drive at address 0
|
|
* 12 LUN 1 on multiple drive controller at address 2
|
|
* 104 second controller board, address 4
|
|
* 88 not valid: both logical units and addresses
|
|
* range from 0..7.
|
|
*
|
|
* CAVEATS
|
|
* Original 2090 code did not support this command.
|
|
*
|
|
* Commodore 2090/2090A unit numbers are different. The SCSI
|
|
* logical unit is the 100's digit, and the SCSI Target ID
|
|
* is a permuted 1's digit: Target ID 0..6 maps to unit 3..9
|
|
* (7 is reserved for the controller).
|
|
*
|
|
* Examples:
|
|
* 3 drive at address 0
|
|
* 109 drive at address 6, logical unit 1
|
|
* 1 not valid: this is not a SCSI unit. Perhaps
|
|
* it's an ST506 unit.
|
|
*
|
|
* Some controller boards generate a unique name (e.g. 2090A's
|
|
* iddisk.device) for the second controller board, instead of
|
|
* implementing the 100's digit.
|
|
*
|
|
*
|
|
* With the advent of wide SCSI the scheme above fails miserably.
|
|
* A new scheme was adopted by Phase V, who appear to be the only
|
|
* source of wide SCSI for the Amiga at this time. Thus their
|
|
* numbering system kludge is adopted here. When the ID or LUN is
|
|
* above 7 the new numbering scheme is used.
|
|
*
|
|
* Unit =
|
|
* Board * 10 * 1000 * 1000 +
|
|
* LUN * 10 * 1000 +
|
|
* ID * 10 +
|
|
* HD_WIDESCSI;
|
|
*
|
|
* There are optional restrictions on the alignment, bus
|
|
* accessability, and size of the data for the data phase.
|
|
* Be conservative to work with all manufacturer's controllers.
|
|
*
|
|
*------------------------------------------------------------------}
|
|
|
|
Const
|
|
HD_WIDESCSI = 8;
|
|
HD_SCSICMD = 28; { issue a SCSI command to the unit }
|
|
{ io_Data points to a SCSICmd }
|
|
{ io_Length is sizeof(struct SCSICmd) }
|
|
{ io_Actual and io_Offset are not used }
|
|
|
|
Type
|
|
|
|
pSCSICmd = ^tSCSICmd;
|
|
tSCSICmd = record
|
|
scsi_Data : Pointer; { word aligned data for SCSI Data Phase }
|
|
{ (optional) data need not be byte aligned }
|
|
{ (optional) data need not be bus accessable }
|
|
scsi_Length : ULONG; { even length of Data area }
|
|
{ (optional) data can have odd length }
|
|
{ (optional) data length can be > 2**24 }
|
|
scsi_Actual : ULONG; { actual Data used }
|
|
scsi_Command : Pointer; { SCSI Command (same options as scsi_Data) }
|
|
scsi_CmdLength : Word; { length of Command }
|
|
scsi_CmdActual : Word; { actual Command used }
|
|
scsi_Flags : Byte; { includes intended data direction }
|
|
scsi_Status : Byte; { SCSI status of command }
|
|
scsi_SenseData : STRPTR; { sense data: filled IF SCSIF_[OLD]AUTOSENSE }
|
|
{ is set AND scsi_Status has CHECK CONDITION }
|
|
{ (bit 1) set }
|
|
scsi_SenseLength : Word; { size of scsi_SenseData, also bytes to }
|
|
{ request w/ SCSIF_AUTOSENSE, must be 4..255 }
|
|
scsi_SenseActual : Word; { amount actually fetched (0 means no sense) }
|
|
end;
|
|
|
|
|
|
Const
|
|
|
|
{----- scsi_Flags -----}
|
|
SCSIF_WRITE = 0; { intended data direction is out }
|
|
SCSIF_READ = 1; { intended data direction is in }
|
|
SCSIB_READ_WRITE = 0; { (the bit to test) }
|
|
|
|
SCSIF_NOSENSE = 0; { no automatic request sense }
|
|
SCSIF_AUTOSENSE = 2; { do standard extended request sense }
|
|
{ on check condition }
|
|
SCSIF_OLDAUTOSENSE = 6; { do 4 byte non-extended request }
|
|
{ sense on check condition }
|
|
SCSIB_AUTOSENSE = 1; { (the bit to test) }
|
|
SCSIB_OLDAUTOSENSE = 2; { (the bit to test) }
|
|
|
|
|
|
{----- SCSI io_Error values -----}
|
|
HFERR_SelfUnit = 40; { cannot issue SCSI command to self }
|
|
HFERR_DMA = 41; { DMA error }
|
|
HFERR_Phase = 42; { illegal or unexpected SCSI phase }
|
|
HFERR_Parity = 43; { SCSI parity error }
|
|
HFERR_SelTimeout = 44; { Select timed out }
|
|
HFERR_BadStatus = 45; { status and/or sense error }
|
|
|
|
{----- OpenDevice io_Error values -----}
|
|
HFERR_NoBoard = 50; { Open failed for non-existant board }
|
|
|
|
IMPLEMENTATION
|
|
|
|
end.
|