> Calls                

Title: Device Calls
Authors: David De Vorchik, Tim Dobson
Last updated: 29-Jul-91
History:
        15-Apr-91 DDV Created.
        15-Apr-91 DDV Added note about special field staying intact.
        16-Apr-91 DDV Added stream created reason, issued when fs_open exits.
        29-May-91 TMD Corrected some typos.
        29-Jul-91 TMD Updated with Mark Taunton's comments
        01-Aug-91 TMD Updated StreamCreated call
	30-Apr-96 RWB Added reason code 14


INTRODUCTION
============

This document explains the device call interface between devices and the
DeviceFS device manager.  The device when registering with DeviceFS passes a
vector to the manager which is called with an array of reason codes.  All
reason codes with bit 31 clear are reserved for use by Acorn.  With bit 31
set these are reserved for specific drivers, these do not need to be
registered within Acorn, although it is suggested that some consistency is
maintained between devices.



Calls from DeviceFS to devices
==============================

These calls are made at specific points when files are being opened and
closed, streams halted etc..

In all cases the following applies.  On return from any device call V should
reflect the error state with r0 -> error block if an error occurs, else
r0, r1 should be preserved along with any other undocumented registers.

        r0  = reason code
                        0: Initialise
                        1: Finalise
                        2: Wake up for TX
                        3: Wake up for RX
                        4: Sleep RX
                        5: EnumDir
                        6: Create buffer for TX
                        7: Create buffer for RX
                        8: Halt
                        9: Resume
                       10: End of data
                       11: Stream created
|                      12:
|		       13:
|		       14: IOCtl

        r1  = reserved (contains meaningless data)
   r2...r7  = parameters for call
        r8  = private word (specified when device registered)
        wp -> workspace for call

So here goes an explanation of the currently used reason codes.


0: Initialise
-------------

        in:  r0  = reason code (0)
             r2  = external handle used for call
                        bit 0 clear => stream opened for RX
                        bit 0 set   => stream opened for TX
                               
                        all others bits should be ignored.

             r3  = flags for opening the stream
             r6 -> special field control block

       out:  r2  = internal handle for stream.

This call is passed as a stream is being opened onto the device by DeviceFS,
the call is passed an external handle and returns the internal handle.  The
external handle is used by the outside world to communicate with DeviceFS,
this includes the actual device driver calling to get or pass on characters
back to the system.

The internal handle returned should NOT be zero, this is a reserved value
and passing this back will cause some strange effects.

The device is also passed a pointer to the special field string, this is
described in the documentation about special fields.

It can be assumed that the special field block will remain intact until the
stream has been closed.


1: Finalise 
-----------
        
        in:  r0  = reason code (1)
             r2  = internal handle / =0 for all

This call is made to the device when a stream is being closed.  The device
is assumed to tidy up and ensure that all vectors have been released.  This
call is also made when a device is being removed, although in this case r0
is set to contain 0 indicating that all devices should be closed.



2: Wake up for TX
-----------------

        in:  r0  = reason code (2)
             r2  = internal handle

        out: r0 = 0       => device wishes to remain dormant
             r0 preserved => device wishes to become active

This call is made when data is ready to be transmitted, the device should
then start passing data to the device, calling DeviceFS_TransmitCharacter
to obtain data to be transmitted.


3: Wake up for RX
-----------------

        in:  r0  = reason code (3)
             r2  = internal handle

This call is made when data is being requested from the device, it is really
issued to wake up any dormant devices, although you will always receive it
when data is going to be read.

The device should then return data using the DeviceFS_ReceivedCharacter SWI,
this will unblock any task waiting on data being returned.


4: Sleep RX
-----------

       in:  r0  = reason code (4)
            r2  = internal handle

To save bandwidth when DeviceFS has finished removing characters from the
device it will issue this as a call to the manager, this is so that the
device can stop receiving characters and no longer call
DeviceFS_ReceivedCharacter, and wait to be woken up again using the 'Wake up
for RX' event.

This call is not applicable to all devices, most buffered devices would wait
for a halt and resume sequence to be triggered on their buffers.



5: EnumDir
----------

       in:  r0  = reason code (5)
            r2 -> path being enumerated
      
This call is made as a broadcast to all devices when the directory structure
for DeviceFS is about to be read.  This allows them to add and remove
non-permanent devices (such as net connections) as required.

The path supplied will be full, ie. $.<foo>.<poo> and null terminated.



6: Create buffer for TX 
7: Create buffer for RX
-----------------------

        in:  r0  = reason code (6 or 7)
             r2  = internal handle
             r3  = suggested flags for buffer being created
             r4  = suggested size for buffer
             r5  = suggested buffer handle (-1 for unique generated one)
             r6  = suggested threshold for buffer

       out:  r3, r4, r5 and r6 modified as the device requires.

This call is made just before the buffer for a stream is going to be
created, it allows the device to modify the parameters as required.

r3 contains the flags as specified when the device was registered, see the
buffer manager documentation for further details.  r4 contains the suggested
buffer size, this should be non-zero.  

r5 contains a suggested buffer handle, this is by default set to -1, this
indicates that the buffer manager must attempt to generate a free handle. 
If the buffer already exists then it will be used and not removed when
finished with.  This is used by the kernel devices which specify that they
want to link upto buffers 1,2 or 3 (for compatibility)

r6 contains the threshold at which a halt event is received, this usually
only applies to receive streams which want to halt the receive process,
although it can be supplied on either.  This value may be changed by calling
'DeviceFS_Threshold'.



8: Halt
-------

        in:  r0  = reason code (8)
             r2  = internal handle

When this is received then the free space has dropped below the specified
threshold (on creation or by DeviceFS_Threshold).  The device should only
resume receiving data when the next event has been received:-



9: Resume
---------

        in:  r0  = reason code (9)
             r2  = internal handle

This is the opposite to the halt reason, the free space is now greater than
the specified threshold so data receiving can continue.



10: End of data
---------------

        in:  r0  = reason code
             r2  = internal handle
             r3  = -1

       out:  r3  = 0  (more data coming eventually)
                 = -1 (no more data coming)

This call is made to enquire with the device about the end of data from this
stream.  In most cases devices will ignore this and return r3 =-1
(unchanged) to indicate that the end of data has been received, but there
will be some cases where this is suitable so the process goes something like
this:

   Is the stream buffered?
                Yes:- Does the buffer still contain data?
                        Yes:- don't return end of data
                        No :- call end of data and check flag, return state.

                No :- Is the RX/TX word empty?
                        Yes:- don't return end of data
                        No:-  call end of data and check flag, return state.



11: Stream created
------------------

        in:  r0  = reason code (11)
             r2  = internal handle
             r3  = buffer handle (-1 if none)

This is broadcast after the stream has finally been generated, this allows
any devices that have important interrupt handling to be performed can set
themselves up and start receiving.

(Aside: This call may be extended in the future to supply entry points to
        DeviceFS for speed, this is a matter for debate though!)


| 14: IOCtl

	in: r0 = reason code (14)
	    r2-r7 parameters depending upon call
	    
This routine is entered if the SWI DeviceFS_CallDevice has been made or the SWI
OS_Args 9 has been called. It is intended to perform device specific control
such as setting control bits, changing baud rates (on serial ports) etc.