www.riscos.com Technical Support: |
|
DeviceFS does not know how to communicate directly with the hardware that your device driver uses. Your module must provide these facilities, and declare the entry points to DeviceFS.
This section describes how to add a device driver to DeviceFS. You should also see the chapter entitled Modules for more information on how to write a module.
When your module initialises, it must register itself and its devices with DeviceFS. You must call DeviceFS_Register (see DeviceFS_Register) to register your device driver and any associated devices. Note that modules can hold more than one driver; in such cases you must call DeviceFS_Register for each one.
When you register your device driver with DeviceFS you pass it the location of an entry point to your driver's low level routines that interface with the hardware. A reason code is used to determine which of your driver's routines has been called.
You may later register additional devices by calling DeviceFS_RegisterObject (see DeviceFS_RegisterObjects). This is most commonly needed for devices on a network.
You may deregister devices by calling DeviceFS_DeregisterObject (see DeviceFS_DeregisterObjects).
The finalise entry of your module must deregister all registered drivers and devices by calling DeviceFS_Deregister (see DeviceFS_Deregister). It must make this call for each device driver it registered.
The principal part of a device driver is the set of low-level routines that control the device's hardware. There are certain conventions that apply to them.
R8 on entry to the device driver is set to the value of R3 it passed to DeviceFS when registering by calling DeviceFS_Register. Conventionally, this is used as a private word to indicate which hardware platform is being used.
R12 on entry to the device driver is set to the value of R4 it passed to DeviceFS when registering by calling DeviceFS_Register. Conventionally, this is used as a pointer to its workspace.
If a routine wishes to return an error, it should return to DeviceFS with V set and R0 pointing to a standard format error block.
Device driver routines must preserve R0, R1, and all other undocumented registers.
These are the interfaces that your device driver must provide. The entry point must be declared to DeviceFS by calling DeviceFS_Register when your device driver module is initialised.
Various calls are made by DeviceFS through this entry point when files are being opened and closed, streams halted etc. The actions are specified by R0 as follows:
R0 = 0
R2 = DeviceFS stream handle
R3 = flags for opening the stream:
R2 = device driver stream handle
This entry point is called as a stream is being opened onto the device driver by DeviceFS. The stream handle passed in must be stored, as you need to quote it when calling DeviceFS SWIs such as DeviceFS_Threshold, DeviceFS_ReceivedCharacter, and DeviceFS_TransmitCharacter.
The stream handle returned will be passed by DeviceFS when calling the device driver's other entry routines. It must not be zero, which is a reserved value.
The device driver is also passed a pointer to the special field string: see the chapter entitled Special fields.
You can be assumed that the special field block will remain intact until the stream has been closed.
R0 = 1
R2 = device driver stream handle, or 0 for all streams
--
This entry point is called when a stream is being closed. Your device driver must tidy up and ensure that all vectors have been released. This entry point is also called when a device driver is being removed, although in this case R2 is set to contain 0 indicating that all streams should be closed.
R0 = 2
R2 = device driver stream handle
R0 = 0 if the device driver wishes to remain dormant, else preserved
This entry point is called when data is ready to be transmitted. Your device driver should set R0 to 0 if it wishes to remain dormant, or else start passing data to the physical device, calling DeviceFS_TransmitCharacter to obtain the data to be transmitted.
R0 = 3
R2 = device driver stream handle
--
This entry point is called when data is being requested from the device driver. It is really issued to wake up any dormant device drivers, although you will always receive it when data is going to be read.
The device driver should return any data it receives from the physical device by calling DeviceFS_ReceivedCharacter. This will unblock any task waiting on data being returned.
This call is not applicable to all device drivers; most interrupt-driven buffered device drivers would be ready to receive data at any time.
R0 = 4
R2 = device driver stream handle
--
This entry point is called when data is no longer being requested from the device driver. If appropriate, the device driver can then wait to be woken up again using the 'Wake up for RX' entry point.
This call is not applicable to all device drivers; most interrupt-driven buffered device drivers would continue to receive and buffer data even after this call.
R0 = 5
R2 = pointer to path being enumerated
--
This entry point is called as a broadcast to all device drivers 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 (eg $.foo.poo) and null terminated.
R0 = 6 or 7
R2 = device driver stream 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
R3 - R6 modified as the device driver requires
This entry point is called just before the buffer for a stream is going to be created; it allows the device driver to modify the parameters as required.
If you specify the handle of an existing buffer, then it will be used and not removed when finished with. For compatibility, the kernel devices use this feature to link up to buffers 1,2 or 3.
R0 = 8
R2 = device driver stream handle
--
This entry point is called when the free space has dropped below the specified threshold (set on creation, or by DeviceFS_Threshold). It is called so the device driver can - if necessary - try to stop its device from receiving more data (eg a serial device driver might perform handshaking by sending an XOff character, or asserting the RTS line) until the Resume entry point is called.
R0 = 9
R2 = device driver stream handle
--
This entry point is called when the free space has risen above the specified threshold (set on creation, or by DeviceFS_Threshold). It is called so the device driver can - if necessary - try to resume its device receiving more data (eg a serial device driver might perform handshaking by sending an XOn character, or de-asserting the RTS line) until the Halt entry point is again called.
R0 = 10
R2 = device driver stream handle
R3 = -1
R3 = 0 if more data coming eventually, else -1 (ie no more data coming)
This entry point is called as a result of FileSwitch calling DeviceFS to check on EOF, and DeviceFS believing that there is no more data to come. In more detail:
DeviceFS informs FileSwitch that more data is coming eventually - without calling this entry point - if:
Otherwise it calls this entry point. In most cases a device driver should ignore this, and return with all registers preserved (so R3 = -1, thus there is no more data coming). In some cases, such as a scanner, you may be able to give an accurate return.
R0 = 11
R2 = device driver stream handle
R3 = buffer handle (-1 if none)
--
This entry point is called after a stream has finally been generated. Your device driver can then perform any important interrupt handling, set itself up and start receiving or transmitting.