RISC OS SCSIdriver
==================

Author: Nick Reeves, Richard Manby, BC
Version: 0.18
 
History

1) 24-Nov-88 NR:        Initial draft
2) 02-Dec-88 NR:        Added a) timeout parameter for SCSI_Op
                              b) SCSI_Op to return operation id number, which
                                 can be used to abort operation.
                              c) parameter for number of bytes of extended
                                 sense
0.03: 31-Jan-89 RCM:    Copy placed in Arf:doc
0.04:  1-Mar-89 RCM:    Defined data returned by 'Determine Device'
0.05: 15-Mar-89 RCM:    Removed 'Establish Device' and 'Remove Device'
                        reason codes from SWI SCSI_Initialise.
                        Changed reason codes for 'Determine Device' in
                        SWI SCSI_Initialise from 4 to 2.
                        Removed 'Return error statistics' from
                        SWI SCSI_Status.
                        SWI SCSI_Op; Moved transfer direction, Scatter,
                        Poll, Retry & Background Bits in R0 into MSByte to
                        leave room for its device ID field to grow.
                        Added 'Set Error Response','Set Queue Behaviour' &
                        'Disconnect' to SWI SCSI_Control.
0.06: 17-Apr-89 RCM:    Removed the scatter list Bit from SWI SCSI_Op, this
                        Bit is now reserved.
                        Commands execute totaly in the foreground or in the
                        background. The 'return-after-some-of-the-data-has-
                        been-transfered' cannot be supported by SCSI.
                        Added section on error messages.
0.07: 25-Apr-89 RCM:    Tidied up some of the error messages
                        Full definition of Host ID and Device ID
0.08: 16-May-89 RCM:    Reordered reason codes for
                        SCSI_Control-SetErrorResponse.
                        SetErrorResponse, SetTimeout & ControlDisconnect
                        now return their previous settings.
0.09: 08-Jun-89 BC+RCM: Changed spec of SCSI_Version to indicate the
                        hardware and software types as a Bitset.  Added all
                        the error messages and their numbers,
                        documented *Devices.  Admitted to total reentrancy
                        and interrupt kosherness.
                        Scatter list reimplemented.

0.10: 26-Jun-89 RCM:    Removed restrictions on device having to be idle
                        before issuing SWI SCSI_Control (eg on SetTimeout).
                        Defined bit value for 'supports scatterlist' and for 
                        'supports device reservation'.
                        Added SWI SCSI_Reserve.
                        Added R8 (access key) to any dangerous operations.
0.11: 30-Jun-89 RCM:    Reordered the error message section, so it made
                        more sense.
                        Added recommendations to SCSI_Control about the use
                        of the control_disconnect reason code.
0.12: 04-Jul-89 RCM:    Changed "Device reserved" to "Reservation error"
0.13: 12-Jul-89 RCM:    Added SWI SCSI_List, *ScsiBlock
0.14: 23-Aug-89 RCM:    Added accesskey to *ScsiBlock
0.15: 29-Aug-89 RCM:    Added reason code 3 to SWI SCSI_Initialise.
0.16: 04-Sep-89 RCM:    Changed "Reservation error" to
                        "SCSI driver reservation error" 
0.17: 19-Oct-89 RCM:    Reset Bus restores various defaults.
0.18: 20-Oct-89 RCM:    Added SBIC bug warning.
0.19: 09-Nov-90 JSR:    Added SCSI_TargetControl details from John Ballance Computing.
0.20: 14-Nov-90 JSR:    Minor corrections to SCSI_TargetControl.
0.21: 08-Feb-92 JWB:    Added calling Host ID to SCSI_TargetControl

                ============================================
                INTERFACE FOR THE RISC OS SCSI DEVICE DRIVER
                ============================================ 


                                Introduction
                                ============
The SCSI device driver for RISC OS is a relocatable module whose
interface consists of the following SWIs:

SCSI_Version              403C0    603C0
SCSI_Initialise           403C1    603C1
SCSI_Control              403C2    603C2
SCSI_Op                   403C3    603C3
SCSI_Status               403C4    603C4
SCSI_ReadControlLines     403C5    603C5
SCSI_EEProm               403C6    603C6
SCSI_Reserve              403C7    603C7
SCSI_List                 403C8    603C8
SCSI_TargetControl        403C9    603C9

and the following * commands:

*ScsiDevices
*ScsiBlock   (N.B. NOT IMPLEMENTED BY ACORN SCSIdriver)




Note on Device ID and Host ID
-----------------------------

The device ID is a composite of the SCSI id number, the logical unit number
(LUN) within the device and the logical slot number of the SCSI card.
They are packed into 8 bits as follows:

  Bits 2..0  SCSI device id (0..7)
  Bits 4..3  Logical SCSI card number (0..3)
  Bits 7..5  Logical unit number      (0..7)


The SCSI card numbering is based on the relative slot positions of any SCSI
cards in the machine, thus in a machine with 2 cards, in physical slots 2
and 4 they are refered to as logical SCSI card numbers 0 and 1. In a machine
with 1 card it may be placed in any slot refered to as logical SCSI card
number 0.

The host ID is a similar composite, but of SCSI id number and logical slot
number, with no LUN field.

  Bits 2..0  Host device id (0..7) - Usually 7
  Bits 4..3  Logical SCSI card number (0..3)


The Host device id is usually 7 and there must be no other devices on the
bus with the same id.


                                The SWIs
                                ========

All SWIs conform to the RISC OS standard that is
a) Any registers not explicitly defined as result parameters are preserved
b) The processor flags N,Z and C are preserved.
c) Errors are indicated by setting V and returning with R0 pointing at an
   error block (If the Bit 17 clear version is called control passes to
   the error handler instead).
d) All SWIs preserve the interrupt state unless stated otherwise, and so
   they may be called from interrupt or event routines.
e) All SWIs are reentrant.


----------------------------------------------------------------------------


SCSI_Version (403C0 & 603C0)
============
This SWI is used to determine the version number of the drivers, whether it
supports any particular later extension, and what particular hardware
implementation is present.

entry: no parameters

exit:
 R0 Bits 0..7 software minor version number, 0 for any release
    Bits 8..31 software major version number eg 100 for 1.00
 R1 Bitset of software features
 R2 Bits 0..7 hardware minor version number, 0 for any release
    Bits 8..31 hardware major version number eg 100 for 1.00
 R3 Bitset of hardware features

The Bitset of software features is defined as follows;
    Bit  31     Supports target mode
    Bit  30     Supports configuration
    Bit  29     Supports reading control lines
    Bit  28     Supports device reservation
    Bit  27     Supports multiple SCSI cards (and hence SWI SCSI_List)
    Bit  26     Supports *ScsiBlock
    Bits 25..16 Reserved must be 0
    Bits 15..7  Reserved must be 1
    Bit  6      Supports *ScsiDevices
    Bit  5      Supports scatter list for SWI SCSI_Op
    Bit  4      Supports messaging
    Bit  3      Supports automatic "Request Sense"
    Bit  2      Supports command queueing
    Bit  1      Supports background data transfer
    Bit  0      Supports target disconnect/reconnect

The Bitset of hardware features is defined as follows;
    Bit  31     Supports configuration
    Bits 30..16 Reserved must be 0
    Bits 15..1  Reserved must be 1
    Bit  0      Supports target mode

errors: none


---------------------------------------------------------------------------


SCSI_Initialise (403C1 & 603C1)
===============
This SWI performs various initialisations determined by a reason code in R0.
Any additional parameters are given in subsequent registers.


'Reset Bus'
-----------
entry:
 R0 0
 R1 host ID

This call resets all options set by SCSI_Control to their default states and
removes any device reservations. In addition it sets a new host ID and
causes a full reset of the SCSI bus by driving the SCSI bus RESET line.

The default states set for each device are
  Reservation     - none
  Timeout=0       - no timeout
  Error response  - report check condition as an error
  Queue behaviour - wait until slot becomes free
  Disconnect      - allow disconnect/reselect


success exit: no results

errors:
  &00020100 - No room for SCSI driver workspace
  &00020103 - SCSI bus failed to reset
  &00020104 - Invalid SCSI host ID


'Reset Device' - initiates the reset operation and returns immediately.
--------------
entry:
 R0 1
 R1 device ID
 R8 access key

success exit: no results

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'Determine Device' - performs an Inquiry command to see what type the device
------------------   is and then performs the appropriate Read-Capacity
                     command depending on the device type.
entry:
 R0 2
 R1 device ID
 R2 pointer to buffer for description, (16 bytes, word aligned).

success exit: buffer filled in

        Offset
 R2 -->   0    Type = &00    Direct-access            (eg magnetic disk)
                      &01    Sequential-access        (eg magnetic tape)
                      &02    Printer device
                      &03    Processor device
                      &04    Write-once read-multiple (eg some optical discs)
                      &05    Read-only                (eg some optical discs)
                      &06-7E Reserved
                      &7F    Logical unit not present
                      &80-FF Vendor unique

          1    Removable medium Bit (Bit7)/Device-Type Qualifier (Bits 0..6)
          2    ISO (b7..6)/ECMA (b5..3)/ANSI (b2..0) version
          3    Reserved (reserved field returned by inquiry command)

          4   Additional length, extra data that could be obtained by an
               inquiry command
          5   }
          6   } Reserved (by device driver - currently zero) 
          7   }

        8..11  word highest logical block number  (converted to normal)
       12..15  word block length                  ( ARM byte sex)


errors:
  &00020105 - Invalid SCSI device ID
  &0002010A - Timeout


Bytes 0..4 are the first 5 bytes returned by an inquiry command, byte 5 is
provided to indicate how much additional data (vendor ID,product ID etc)
could be obtained by an Inquiry command Bytes 5..7 are reserved by the
device driver

Bytes 8..11 (word 2) & 12..15 (word 3) are the highest block count and block
size returned by a Read Capacity command but have had the byte sex reversed
to suit ARM's LDR instruction.


'Enumerate Device' - performs an Inquiry command to see what type the device
------------------   is and then performs the appropriate Read-Capacity
                     Data returned as formatted text.
entry:
 R0 3
 R1 device ID
 R2 pointer to buffer for description, word aligned).
 R3 buffer size

The data returned is a zero terminated string of the same form as that
printed by *ScsiDevices, ie

"ddd    ttttttttttttttttt cccc Mbytes vvvvvvvv pppppppppppppppp rrrr"

where the fields are device number, type, capacity, vendor, product and
revision number.

If a device doesn't respond, a string containing just the device number is
returned, if the device responds, but the 'read-capacity' call fails, the
capacity field will be set to unknown.


----------------------------------------------------------------------------


SCSI_Control (403C2 & 603C2)
============
This SWI issuess various control commands determined by a reason code in R0.
Any additional parameters are given in subsequent registers.


'Abort device' - cancels all outstanding operations on a device. 'Abort op'
--------------   should normally be used instead wherever possible.
entry:
 R0 0
 R1 device ID
 R8 access key

success exit: no results

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'Abort op' - cancels a particular operation on a device.
----------
entry:
 R0 1
 R1 device ID
 R2 operation id as returned by SCSI_Op
 R8 access key

success exit: no results

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


Reserved
--------
entry:
 R0 2
 R8 access key


'Set Timeout' - sets the default timeout for a device.
-------------   
entry:
 R0 3
 R1 device ID
 R2 timeout value in centi-seconds or zero for no timeout
 R8 access key

exit:
 R2 previous timeout setting

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'Set Error Response' - controls the behaviour of CHECK CONDITION status.
--------------------
entry:
 R0 4
 R1 device ID
 R2 0  If device returns 'check condition', return that as an error message.
       This is for badly behaved devices with non-standard request sense
       return blocks.
    1  If device returns 'check condition' do a request sense automaticaly,
       report the error.
    2  If device returns 'check condition' do a request sense automaticaly, 
       if 'unit attention', ignore it and reissue the command else report
       the error.
   -1 no action, return previous setting.
 R8 access key

exit:
 R2 previous setting

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'Set Queue Behaviour'
---------------------

  The driver supports disconnection/reselection and queueing of commands,
this implies that when a command is issued, the podule hardware may be in
use servicing another command, a command maybe queued/running for the target
device or the queue may be full.

entry:
 R0 5
 R1 device ID
 R2 0                       ie if queue full loop until a slot becomes free
                               if command operates totally in the background
                               control returns to the caller as soon as the
                               command is queued
                               if the command operates in the forground,
                               portion, control returns when the command
                               completes.
    1 Reject if queue full  ie command accepted only if it can be queued/run
                               without waiting.
                               if command operates totally in background,
                               control returns to the caller as soon as the
                               command is queued
                               if the command operates in the forground,
                               portion, control returns when the command
                               completes.
    2 Reject if device busy ie command accepted only there are no other
       (or queue full)         queued/running for this device.
    3 Reject if podule busy ie accept command only if it will run immediatly
   -1 no action, return previous setting.
 R8 access key

exit:
 R2 previous setting

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'Disconnect' - Allow/Inhibit disconnect/reselect
------------

entry:
 R0 6
 R1 device ID
 R2 0 allow disconnect/reselect
      (ie when the bus selection phase is complete, the driver will attempt
          to send an IDENTIFY message with bit6 set, this tells the target that
          it may disconnect if it wants to).
    1 inhibit disconnect/reselect, so that once started, a command will proceed
      to completion without allowing any other command to start/reconnect.
      (ie when the bus selection phase is complete the driver will attempt
          to send an IDENTIFY message with bit6 clear).
    2 inhibit disconnect/reselect by not sending an identify message
   -1 no action, return previous setting.
 R8 access key

exit:
 R2 previous setting

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


Note codes 0/1 cause SWI SCSI_Op to attempt to send an identify message once
     the bus selection phase is complete. The target may choose not to take the
     message (Not an error), in which case the driver proceedes to the command
     phase. The target may reply to the message with a message reject.
     These two cases do not produce an error from SCSI_Op, as the command may
     still complete successfully, it will however remain connected all the
     time.

Note Applications/filing systems are NOT expected to issue this call, as
     all software/hardware should work happily regardless of any disconnections
     that occur.

     It should only be issued by:

     1) The user (in his boot file) if his/her particular device mis-behaves
        when sent messages.

     2) Application/filing system software specific to one vendors product that
        is known to mis-behave when sent messages.


----------------------------------------------------------------------------


SCSI_Op (403C3 & 603C3) - issues a SCSI command to a device.
=======                   Can be called in the background.

 R0 Bits 0..7    Device ID
    Bits 24..25  00 => no data transfer, 01 => read, 10=>write, 11=>reserved
    Bit 26       Scatter Bit, if set, R3 is a pointer to a scatter list.
    Bit 27       If clear, poll escape during transfer and abort if escape
                 pressed
    Bit 28       If set, repeatedly retry on timeout
    Bit 29       Set if a background transfer (possibly 0 length).
 R1 Length of SCSI control block
 R2 Ptr to SCSI control block
 R3 RAM ptr for start of transfer or pointer to scatter list of address length
    pairs if Bit 26 of R0 is set. After each chunk in the scatter list is
    transferred the address should be incremented and the length set to 0.
 R4 Length of transfer (in bytes).
 R5 Timeout in centiseconds or 0 for default timeout
 R6 Address to call back when transfer is complete if background Bit set.
    The call is made in IRQ mode with IRQs disabled.
    If an error has occurred, V is set, R0 points to a non-dynamic error
    block, (ie a pointer to a fixed block in the module rather than built
    up in a buffer), R1 indicates the cause of the error and R2 the logical
    address on the device of where the error occured.
 R7 Workspace pointer to pass in R12 for background call back.
 R8 access key

exit (V clear)
 R0 returns a 32 Bit id incremented for each operation. Used to cancel op.
 R3 updated to indicate how much of transfer was successful (if scatter
    list, pointer to first unused/partially used entry).
 R4 updated to the amount untransferred

exit (V set)
 R0 points to an error block
 R1 indicates the cause of the error
 R2 hold the logical address on the device of where the error occured.
 R3 updated to indicate how much of transfer was successful (if scatter
    list, points to first unused entry, entry is updated to indicate amount
    transfered).
 R4 updated to the amount untransferred

errors:
 many

Interrupts may be enabled by the call, this does not affect it's reentrancy.

N.B. See below for detailed description of errors


----------------------------------------------------------------------------


SCSI_Status (403C4 & 603C4)
===========
This SWI issues various control commands determined by a reason code in R0.
Any additional parameters are given in subsequent registers.


'Check Device Status' - returns the status of the selected device
---------------------
entry:
 R0 0
 R1 device ID

success exit:
 R0 status
    1 => Idle
    2 => Busy
    4 => Error
   16 => not available

errors:
  &00020105 - Invalid SCSI device ID



----------------------------------------------------------------------------


SCSI_ReadControlLines (403C5 & 603C5)  N.B. NOT IMPLEMENTED BY ACORN SCSIdriver
=====================

Returns current state of SCSI bus lines 

entry:
 R0 host ID

success exit: 
 R0 SCSI data bus
 R1 Control lines, 1 = asserted :
    Bit  7   6   5   4   3   2   1   0
        RST BSY REQ MSG C/D I/O SEL DBP                    

 R2 Control lines, 1 = asserted : 
    Bit   7   6   5   4   3   2   1   0 
                                 ATN ACK       
    (Bits 7..2 are Bits of 5380 bus & status register)

errors:
  &00020104 - Invalid SCSI host ID


----------------------------------------------------------------------------


SCSI_EEProm (403C6 & 603C6)            N.B. NOT IMPLEMENTED BY ACORN SCSIdriver
===========

Reads/writes EEProm on SCSI podule 

entry: 
 R0 Bits 0..3 address of 16 Bit word
    Bit 10 set for write, clear for read
 R1 Bits 0..15 write data (if R0 Bit 10 set)

success exit: 
 R0 data read if R0 Bit 10 was set on entry
 R0 preserved if R0 Bit 10 was clear on entry

errors:


----------------------------------------------------------------------------


SCSI_Reserve (403C7 & 603C7)
============

This SWI allows the caller to claim exclusive use of a device and may prevent
data corruption problems that may arise if a program (by accident or on
purpose) issues a Write/Format/ModeSelect command to a device currently mounted
by SCSIFS.

It also provides for a clean change of device ownership from one user to
another, as SCSIdm for example is entitled to modify your disc, (to map out
defects/format/partition it etc) but must only do so once SCSIFS has closed
down all open files and dismounted the disc.


'Claim' - Claim exclusive use of a device
-------

This call attempts to claim exclusive use of the given device.
If the call is successful, the caller will be granted sole use of the
'dangerous' SCSIdriver calls for that device and may use them itself, only
by supplying the access key registered at 'Claim' time. Other callers
may only use safe calls such as SCSI_Initialise-DetermineDevice.

If the device has already been claimed, an error message
'SCSI driver reservation error' will be returned.

entry
  R0 0
  R1 device ID
  R2 release address
  R3 workspace pointer, to be passed in R12 when release address is called
  R8 access key

exit
  VC
  VS & R0-> error

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


'ForceClaim'
------------

This call is similar to 'Claim' above, however, if the device is already
claimed, it will ask the current claimant to release it, by calling the
release address registered for that device.
The current owner should try to tidy up, and call 'Release' but may refuse
by returning VS and R0 pointing to an error message

Aside: This call is used by SCSIdm to ask SCSIfs to close files and dismount
       etc

entry
  R0 1
  R1 device ID
  R2 release address
  R3 workspace pointer, to be passed in R12 when release address is called
  R8 access key

exit
  VC
  VS & R0-> error

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error
  OR an error message passed back by the current claimant.

When the current claimant is called R0 will hold a reason code indicating:
  R0 = 1 called from ForceClaim


'Release'
---------
This call will remove the reservation of a device.

entry
  R0 2
  R1 device ID
  R8 access key  (to prove you actually claimed it)

exit
  VC
  VS -> error

errors:
  &00020105 - Invalid SCSI device ID
  &0002010E - SCSI driver reservation error


Passing access key value to SCSI SWI's
======================================
The access key (probably WorkSpacePointer) should be passed in R8
and is only checked if the specified device is claimed and the call/reason
code is 'dangerous'.


----------------------------------------------------------------------------


SCSI_List (403C8 & 603C8)
=========

This is used by the ScsiLog module as part of the multiple SCSI card
initialisation sequence (see separate SCSILog documentation).

exit:
 R0 -> Null terminated list of podule addresses

This SWI returns a pointer to a null terminated list of SCSI podules
available to SCSIdriver. The addresses are those of the 'slow access' space
for the podule, ie, 
 &03240000, &03244000, &03248000 or &0324C000 for podule slot 0,1,2 or 3.


----------------------------------------------------------------------------


SCSI_TargetControl (403C9 & 603C9)
==================================

This SWI is to enable an application to register routines with the
SCSIDriver which provide target mode responses to commands sent from another
SCSI host via the SCSI bus. The host ID of the SCSI driver is also the
target ID seen by other hosts across the SCSI bus, but separate routines must
be registered for each of the 8 logical units (LUN) that can exist for this
ID.

On entry:
 r1 = Bit       Meaning
      0..2      Reserved, should be set to 0
      3..4      Podule number
      5..7      LUN
      8..32     Reserved, should be set to 0
 r2 = Address of the target handler routine, or 0 to deregister the target
        handler on the given podule and LUN.
 r3 = Address of the deregistration routine. This routine will be called
        when the handler on the given podule and LUN is deregistered. This
        may happen, for example, if another pair of routines is registered
        or if the SCSIDriver is reinitialised.
 r4 = Value to be passed in r12 when either of the above two routines is
        called.

On exit:
 r2 = Address of the routine to call to read bytes from the SCSI bus.
 r3 = Address of the routine to call to write bytes to the SCSI bus.
 r4 = Address of the routine to call to reconnect to a previously
        disconnected host, or 0 if this feature is not implemented.
 r5 = value to be passed in r12 when any of the above routines are called.

The target handler routines are called in SVC mode with interrupts enabled
and the return address in r14. The SCSIDriver will ensure that none of the
routines are reentered until they have returned to the SCSIDriver module.
The routines must be in the RMA.

Target handler routine:
On entry:
 r0 = Bits      Meaning
      0..7      Byte 0 of the CDB
      8..15     Byte 1 of the CDB
      16..23    Local Host mode SCSI ID
      24..31    Calling Host SCSI ID
 r12 = value passed to SCSI_TargetControl in r4
 r14 = return address

On exit:
 r0 = r0 as passed in if the command specified in byte 0 of the CDB was not
        implemented by this handler, or &1000000 if the command was
        implemented.
 r1 = Bits      Meaning
      0..7      Sense code
      8..15     Sense key
      16..23    termination status
      24..31    termination message

The target handler routine is called in SVC mode with interrupts enabled. The
SCSIDriver will ensure that this routine will not be reentered for the given
LUN until it returns control to the SCSIDriver.

If the command is not implemented by the handler, as indicated by the
handler returning &1000000 in r0, then the SCSIDriver will attempt to handle
it itself. The commands currently implemented are test ready (&00), sense
mode (&03) and identify (&12). Of course, the handler may respond to these
itself.

The final status and command complete message phases are implemented by the
driver module. If the termination message is 0, then a status phase and
message command complete phase are given before disconnection. If the
termination message is disconnection (3), then both a save pointers message
and a disconnection message are given before disconnection, but no status
phase is given.

Calling the read bytes and write bytes routines:
On entry:
 r0 = SCSI bus phase to use:
        0       Data to target
        1       Data from target
        2       Command to target
        3       Status from target
        4       Illegal
        5       Illegal
        6       Message to target
        7       Message from target
 r2 = Transfer count
 r3 = data source or destination address
 r12 = value in r5 returned from SCSI_TargetControl
 r14 = Return address

On exit:
 r0 = corrupted
 r3 = advanced past the bytes transfered

Calling the reconnection routine:
On entry:
 r0 = ID to reconnect to
On exit:
 r0 = 0 if the reconnection was successful, or a pointer to a standard
        error block if not.
 r3 corrupted.

----------------------------------------------------------------------------

SCSI messages & error codes
===========================

Errors reported by the SCSIdriver fall into 3 classes:
1) Those generated/detected by the driver
2) Interpretations of the SCSI status byte returned on command completion.
3) Interpretation of the sense data (collected on CHECK CONDITION status if
   the error response is set to 0 or 1).


Device driver errors
====================

&00020100 = "No room for SCSI driver workspace"
&00020101 = "Unknown SCSI SWI number"
&00020102 = "Unknown reason code for SCSI SWI"
&00020103 = "SCSI bus failed to reset
&00020104 = "Invalid SCSI host ID"
&00020105 = "Invalid SCSI device ID
&00020109 = "Device not idle"
&0002010A = "Timeout" ; During selection phase
&0002010B = "Timeout" ; During any other phase
&0002010C = "Command queue not empty"
&0002010D = "Command queue full"
&0002010E = "SCSI driver reservation error"
&0002010F = "Invalid parameters"
&00020110 = "Parameter error"
&00020111 = "Not callable from IRQ routine"  (reported by podule loader)
&00020112 = "Operation aborted"
&00020113 = "Unexpected disconnection"

Interpretation of the returned SCSI status byte
===============================================

On completion of the command, the target returns a status byte.
The Vendor unique Bits are masked out and the following interpretations
placed on the result.  If the returned status is GOOD then that is not an
error so there will not be an error returned.  If the status retured is not
GOOD then it will be translated into one of the following three errors;

&00020180 = "Target status - Check condition"
&00020181 = "Target status - Busy"
&00020182 = "Target status - Unknown"

Any other value, including GOOD/CHECK CONDITION/BUSY with reserved Bit 7
set, is reported as an error "Target status - Unknown"

If the error response level is 1 or 2, then on 'CHECK CONDITION', the driver
will automatically perform a request sense.


Interpretation of the Sense data
================================

The first byte of returned sense data is masked to leave the
Error-class/error-code code Bits these are interpreted as:

0x..6x vendor unique error (non extended sense) } Reported as
71..7E reserved error      (extended sense)     } "Target error - Unknown"
7F     vendor unique error (extended sense)     }

70                         (extended sense), the error is given by examination
                           of the 'sense key' in byte 2 of the sense data


&000201C0 = "Target error - No sense"
&000201C1 = "Target error - Recovered error"
&000201C2 = "Target error - Not ready"
&000201C3 = "Target error - Medium error"
&000201C4 = "Target error - Hardware error"
&000201C5 = "Target error - Illegal request"
&000201C6 = "Target error - Unit attention"
&000201C7 = "Target error - Data protect"
&000201C8 = "Target error - Blank check"
&000201C9 = "Target error - Vendor unique"
&000201CA = "Target error - Copy aborted"
&000201CB = "Target error - Aborted command"
&000201CC = "Target error - Equal"
&000201CD = "Target error - Volume overflow"
&000201CE = "Target error - Miscompare"
&000201CF = "Target error - Reserved sense key"

&000201D0 = "Target error - Unknown"


Errors produced by calling SWI SCSI_Op
======================================

When an error is returned by a call of SWI SCSI_Op, in addition to the normal
error pointer in R0, R1 and R2 provide extra information:

R0 -> error message     - a standard RISC OS error block, consisting of a 1
                          word error number, followed by an error message
R1  = error indication  - this is a composite of the LSB of the above error
                          number and the status/sense-errorclass/sense key
                          that produced the error.
R2  = logical address on the device of where the error occured.



Device driver detected errors
=============================

R1 MSB = the LSB of the RISC OS error number. ie 0..127
R1     = 0 (see note below)
R1     = TBA } If error was due to an unexpected bus phase, the phase could
R1 LSB = TBA } be indicated here - assume undefined for now.

R2     = undefined
R3     = undefined
R4     = undefined


Status byte errors
==================

R1 MSB = the LSB of the RISC OS error number. ie 128..195
R1     = 0 (see note below)
R1     = 0
R1 LSB = returned status byte (unmasked)

R2     = undefined
R3     = indicates amount of data transfered
R4     = amount of data not transfered



Returned Sense data
===================

Non-extended sense data returned
--------------------------------
R1 MSB = the LSB of the RISC OS error number. ie 196..255
R1 UMB =   Bits 23..16 holds byte 0 of the returned sense data
           Bit  23     is the 'Valid' Bit and is set if the 'Logical block
                       address' in the returned sense data (in R2) is valid.
           Bits 22..20 are the 'error class'
           Bits 19..16 are the 'error code'
R1 LMB =   Bits 15..13 are the 'vendor unique' Bits from byte 1
           Bits 12..8  are zero
R1 LSB =   Bits 7..0

R2     = 'Logical block address' returned in bytes 1..3 of the returnrd sense
          data (the vendor unique Bits masked out).
R3     = indicates amount of data transfered
R4     = amount of data not transfered


Extended sense data returned
----------------------------
R1 MSB = the LSB of the RISC OS error number. ie 196..255
R1     = byte 0 of the returned sense data
           Bit 23 is the 'Valid' Bit and is set if the 'Information bytes'
                  in the returned sense data (now in R2) are valid.
           Bits 22..20 are the 'error class'
           Bits 19..16 are the 'error code'
R1     = 'segment number' ie byte 1 of the returned sense data
R1        byte 2 of the returned sense data
            Bit7      is 'Filemark'
            Bit6      is 'EOM'
            Bit5      is 'ILI'
            Bit4      is 'reserved'
            Bits 3..0 hold the 'sense key'
R2     = the 'information bytes' returned as bytes 3..6 of the sense data,
         (byte sex reversed to suit ARM).
R3     = indicates amount of data transfered
R4     = amount of data not transfered


NOTE Bit 23 of R1 always indicates data-in-R2-is-valid, as it is either the
     'valid' Bit returned by the request sense command, or zero.



----------------------------------------------------------------------------

                                The * commands
                                ==============

*ScsiDevices
============

  *ScsiDevices displays information on the devices attached to the SCSI
 bus(es).  The resulting display shows the type of each device this can be
either "Direct-access", "Sequential-access", "Printer", "Processor", "WORM",
"Read-only", "Scanner", "Optical memory", "Changer", Communications",
"Unknown", and "Host".  The capacity is calculated by multiplying the
highest block number by the block size, as returned by a Read Capacity
command.  The Vendor, Product and Revision fields are provided by the
Inquiry command, and are displayed with mimimal formating.  An example of
the output of this command is shown below;

Device Type              Capacity    Vendor   Product          Revision
0      Direct-access       18 Mbytes RODIME   RO652            5.02
1      
2      Direct-access      100 Mbytes CONNER   Cp3100-100mb-3.5 0.0C      
3      Read-only           27 Mbytes HITACHI  CDR              0004
4
5      Direct-access       43 Mbytes RODIME   RO3000S          1.24
6
7      Host                          ACORN    SCSI expansion   0000


*ScsiBlock                       N.B. NOT IMPLEMENTED BY ACORN SCSIdriver
==========



*ScsiBlock  adr accesskey  devID  cdb0 cdb1 cdb2...



*ScsiBlock issues a SCSI command to the target device.
  adr   is the address data transfer address
  devID is the SCSI deviceID
  cbd0  onwards (maximum of 12 parameters) are the bytes of the SCSI command
        block to be sent.

errors unique to this command
&0002010F - "Invalid parameters"
&00020110 - "Parameter error"



Warning
=======
The use of SWI SCSI_Control with R0=1 (Abort Op), or the use of command
timeouts may prove unreliable with certain versions of the WD33C93A SCSI bus
interface controller. The current version of the chip, revision C, is known
to exhibit problems, it is expected that later revisions will not.

The SBIC has a tendancy to hang if a RaiseATN command (issued by the device
driver abort command code) is issued during a data-out phase.

