> 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

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
        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!)