Title |
Fsys changes from QNX 4.1x/4.22 to 4.25 |
Ref. No. |
QNX.000010352 |
Category(ies) |
Filesystem, Development |
Issue |
We are porting a Fsys driver from an older version of QNX to QNX 4.25. We are having problems however with the commands and the changes made to the Fsys module. What are the changes that have been made to the module that is preventing us from porting our driver? |
Solution |
32-bit Fsys/Driver Interface Differences from 16-bit Interface August 23, 1995
This document is a preliminary document, intended for experienced Fsys driver authors. It is not a complete description of the Fsys/driver interface. Instead it is intended to document the differences between the 16-bit and the 32-bit interface.
<sys/_dskdrvr.h> header file:
If you examine this file you will notice a number of differences. One is that the 32-bit Fsys attaches a different name: "qnx/fsys32" instead of "qnx/fsys". However to minimize changes for existing drivers, the macro _FSYS_NAME is given the appropriate value depending on the compiler model.
To allow for possible future extensions, the 32-bit interface allows for 20 entry points instead of just 16 entry points. However at this time no new entry points have been defined.
One key difference which will impact existing 16-bit drivers which will be ported is that the _block structure has been radically changed. Instead of the driver being given a being a linked list of struct _block for read and write operations, it now is given an array. This eliminates the pointer member. In reality, the linked list which 16-bit drivers have been passed is actually a list through an array and has been for some time -- originally (4.0x) this was not true.
Another change to this structure is the elimination of the block number; since all I/O is sequential, this is passed at the start of an I/O operation (as documented below).
Finally, the 16-bit __far pointer has been replaced with both a 32-bit pointer (b_virt) and a physical address (b_phys) useful for drivers which can DMA directly to/from the Fsys cache.
A note about the Fsys cache is in order at this point: in the 16-bit Fsys, the cache was "DMA safe" -- that is the cache was all below the 16M point and no block crossed a segment boundary. This effectively limited the cache size to about 14M in a typical system. In the 32-bit Fsys the cache is no longer restricted to any particular portion of memory. The only guarentee which Fsys makes about the cache placement is that no block will cross a page boundary (4K). If your hardware cannot DMA anywhere in memory (such as PCI bus mastering controllers can do) then it is up to you to supply your own DMA safe intermediate buffer. For a read, it is still acceptable to leave the data in the DMA buffer and have Fsys copy it out by setting the d_dma_seg field in struct _disk.
In struct _disk, you'll notice that little has changed except the fields have been rearranged. The only exception to this is the addition of the 'd_attention' field. It is anticipated that this field will be used by a driver to asynchronously gain the attention of Fsys (i.e. when there are no I/O operations occurring) to inform Fsys, for example, that a removable drive has been removed (as a signal for Fsys to flush its cache perhaps). However at the time of writing this, the field is not yet used and the full details of how it will be used have yet to be resolved.
The 4.3 Fsys supports some new unit status bits. This bit flags are assigned to a 'd_stat' field in struct _disk. This field is examined after every read, write and ioctl (both synchronous and asynchronous). The new fields are:
#define _DRVR_LOCKED_MEDIA 0x0004 /* Removable media locked in drive */ /* will be treated like a hard disk. */ /* If removable is not locked, it will */ /* be treated like a floppy and the */ /* cache timed out after 2 seconds */ /* of inactivity. (v4.3+) */ #define _DRVR_ASYNCH_WRITE 0x0008 /* Regardless of Fsys flags, */ /* all system (metadata) writes will */ /* be asynchronouns. Synchronous data */ /* writes are unaffected. (v4.3+) */
One possible use for this is an ioctl which locks and unlocks the drive door for a removable cartridge disk, with the Fsys cache being invalidated (or at least beginning a timeout) when it is unlocked.
Driver entry points:
In defining the 32-bit interface, two sometimes conflicting goals were used: to minimize the changes and to rationalize the interface for a 32-bit system.
_DRIVER_INITIALIZE: Instead of the number of cache segments and a pointer to an array of segments being passed to the driver, the 32-bit Fsys passes the number of cache blocks and a pointer to the start of the cache. With a 32-bit Fsys, all the cache can fit in the one data segment.
_DRIVER_TERMINATE: Called after all the block special files which were created by Fsys have been unlinked by an appropriately priviliged user. (Finally, a controlled way to terminate a driver!)
_DRIVER_UNIT_INIT: No change.
_DRIVER_UNIT_TERM: Not used.
_DRIVER_IO: As mentioned, for reading and writing the driver is now passed the starting block number (instead of it being in the struct _block entries) and a pointer to an array of type struct _block (instead of a pointer to a linked list).
_DRIVER_CONTROL: The ioctl interface has some significant changes: instead of being passed a 16-bit request type and a pointer to a 512-byte data buffer, the driver is now passed a 32-bit ioctl request (as defined in <sys/ioctl.h>) and a pointer to an array of type struct _block allowing ioctls of up to 8191 bytes. The ioctl request follows the BSD conventions and encodes whether the ioctl has no parameters (IOC_VOID), or whether it copies parameters in (IOC_IN), out (IOC_OUT) or both (IOC_INOUT). The ioctl request also encodes the size of the parameters (see the IOCPARM_LEN() macro). Since that information is in the ioctl request type, Fsys does not pass the size or the number of blocks for the ioctl to the driver -- the driver can trivially obtain that information for itself.
_DRIVER_CONTROL_MASK: Changes as above:
_DRIVER_UNIT_OPEN: No change.
_DRIVER_UNIT_CLOSE: No change.
_DRIVER_ABORT_CMD: No change. |
|