home *** CD-ROM | disk | FTP | other *** search
-
- $Id: NewStyleCommands 1.4 1996/07/15 18:41:23 heinz Exp $
-
- What is this about?
- ===================
-
- Up to and including OS 3.1 (V40), custom device commands usually
- started at CMD_NONSTD. Each developer added commands for custom
- device features freely. This lead to messy and incompatible
- devices and strange compatibility tricks to identify device
- capabilities.
-
- As of January 1st, 1996, Amiga Technologies reserves two ranges in
- the set of command values for future enhancements. Only commands as
- specified by Amiga Technologies may be used here. It is illegal for
- a device developer to randomly "add" custom commands or
- command features in the reserved are!
-
- There are 65536 command values possible with io_Command:
-
- $0000 - $3fff old style and 3rd party commands
- $4000 - $7fff RESERVED AREA!
- $8000 - $bfff old style and 3rd party commands
- $c000 - $ffff RESERVED AREA!
-
- To say it again: Commands in the reserved areas may only be
- assigned and specified by Amiga Technologies. Any "custom"
- implementation of these commands or other commands in these
- reserved areas is illegal and violates programming standards!
-
- A device driver is REQUIRED to return IOERR_NOCMD on any command it
- does not understand. This requirement is very old. It has been
- documented publically in 1991 already.
-
- Commands in the reserved ranges are called "new style". A device
- that supports new style commands correctly as described in this
- document is called a "new style device".
-
-
- What will new style commands do for you?
- ========================================
-
- With old style devices it is impossible to find out about the type
- of device you are accessing. You don't know if it is serial.device
- like or a trackdisk style device. New style commands will let you
- query the device for its capabilities. As capabilities are added
- to a device, device users can use more features transparently
- without compatibility hacks.
-
- There are two types of new style commands. "General" commands are
- the same for all new style devices. Depending on the device type
- there are device specific commands, too.
-
- General commands will be defined in the range $4000-$7fff, device
- specific commands are using the range $c000-$ffff. It is illegal to
- use a device specific command before using the general commands to
- confirm the device's capabilities.
-
- With a new style device, you can be sure that no 3rd party command
- will interact with the standard meaning of all the device's
- commands as documented for V40 of the OS.
-
-
- Basic requirements
- ==================
-
- Let's make a quick list about the most basic requirements for any new
- style device. Keep it in mind when reading on.
-
- - IOERR_NOCMD support
- - no redefinition of standard V40 or reserved commands
- - no 3rd party commands in reserved areas
- - NSCMD_DEVICEQUERY is supported
- - lib_IdString must contain the name, version, and creation
- date of the device and any other readable information to make
- unique identification of a device for 3rd party
- command use possible.
- - Check mn_Length of the request on OpenDevice
-
- Some devices may have additional requirements. These will be listed
- below.
-
-
- General commands
- ================
-
- At the moment there is just a single new style general command:
-
- #define NSCMD_DEVICEQUERY 0x4000
-
- It is required for all new style devices.
-
- You set up io_Data and io_Length pointing to a struct
- NSDeviceQueryResult below. You must clear SizeAvailable and set up
- DevQueryFormat before sending the command to the device. A new
- style device will set up the data in the buffer appropriately. If
- the command executed successfully the returned io_Actual value must
- be greater than zero and equal to the SizeAvailable value that has
- been set by the device. The device may only be considered a new
- style device if these conditions are met. And only in this case the
- results of the query may be considered valid.
-
- struct NSDeviceQueryResult
- {
- /*
- ** Standard information
- */
- ULONG DevQueryFormat; /* this is type 0 */
- ULONG SizeAvailable; /* bytes available */
-
- /*
- ** Common information (READ ONLY!)
- */
- UWORD DeviceType; /* what the device does */
- UWORD DeviceSubType; /* depends on the main type */
- UWORD *SupportedCommands; /* 0 terminated list of cmd's */
-
- /* May be extended in the future! Check SizeAvailable! */
- };
-
- The device will fill in the struct NSDeviceQueryResult with read
- only data for the caller. All data must remain constant and valid
- as long as the device is open. After CloseDevice(), all bets are
- off.
-
- SizeAvailable
-
- Tells you how much of the structure contains valid data. It
- is measured in bytes. Do not try to use fields in the
- strutcure that are not fully included in the SizeAvailable
- range. SizeAvailable must include SupportedCommands for any
- successful query. So the minimum valid value is 16.
-
- DeviceType
-
- This tells you about the type of device you are accessing.
- The type names often match existing devices in AmigaOS. If
- a device returns such a type, the device must be able to
- at least handle all the documented features for V40 of the
- operating system that the respective original device has.
-
- If an old style or new style command can not be supported
- in a compatible manner, the device is required to return
- IOERR_NOCMD for safety reasons. Modification of the
- specification is not allowed. Add a 3rd party command if
- needed.
-
- It is illegal to "reuse" command numbers of documented
- standard commands that cannot be supported for other
- purposes. E.g. a device driver that does not support
- TD_GETGEOMETRY and uses it for something else can never be
- a new style device and may not support new style commands.
-
- It is also illegal to use the results of an
- NSCMD_DEVICEQUERY without testing DeviceType first.
-
- #define NSDEVTYPE_UNKNOWN 0 /* No suitable category, anything */
- #define NSDEVTYPE_GAMEPORT 1 /* like gameport.device */
- #define NSDEVTYPE_TIMER 2 /* like timer.device */
- #define NSDEVTYPE_KEYBOARD 3 /* like keyboard.device */
- #define NSDEVTYPE_INPUT 4 /* like input.device */
- #define NSDEVTYPE_TRACKDISK 5 /* like trackdisk.device */
- #define NSDEVTYPE_CONSOLE 6 /* like console.device */
- #define NSDEVTYPE_SANA2 7 /* A >=SANA2R2 networking device */
- #define NSDEVTYPE_AUDIOARD 8 /* like audio.device */
- #define NSDEVTYPE_CLIPBOARD 9 /* like clipboard.device */
- #define NSDEVTYPE_PRINTER 10 /* like printer.device */
- #define NSDEVTYPE_SERIAL 11 /* like serial.device */
- #define NSDEVTYPE_PARALLEL 12 /* like parallel.device */
-
- More types will be defined by Amiga Technologies as
- necessary and requested. Each device type represents a
- certain set of minimum capabilities that the device must
- support. If the type does not match a device that does
- exist in OS V40, the exact requirements are defined below.
-
- DeviceSubType
-
- There might be special incarnations of a device with
- special capabilities beyond the standard set. At the moment
- none are defined and a device is required to return 0 here.
- As extensions that are marked by this field have to be
- upwards compatible, this field need not be tested by users
- who don't need any special capabilities beyond the standard
- set. Otherwise it must be tested first.
-
- SupportedCommands
-
- This points to a 0 terminated list of io_Command values
- that are supported by the device. This list must contain
- all legal command values, old style, new style, and special
- commands that are understood by the device and do not
- cause an IOERR_NOCMD right away.
-
-
- You might notice the similarity to the SANA2-R2 (S2R2) S2_DEVICEQUERY
- command. It is intentional.
-
- If you are developing software that needs to use 3rd party
- commands, you must try an *exact* 3rd party device identification
- via the lib_IdString in the device base and reject all devices that
- you don't know for a new style device.
-
-
- New Style Check in C
- ====================
-
- A code fragment that could help you set up a new device query
- follows.
-
- struct IOStdReq *io;
- struct NSDeviceQueryResult nsdqr;
- LONG error;
- BOOL newstyle = FALSE;
- BOOL does64bit = FALSE;
- UWORD *cmdcheck;
- struct MsgPort *replyport;
-
- ...
- /* See important caveat below! */
- io = CreateIORequest(replyport, sizeof(struct IOStdReq) + 128);
-
- ...
- nsdqr.SizeAvailable = 0;
- nsdqr.DevQueryFormat = 0;
-
- io->io_Command = NSCMD_DEVICEQUERY;
- io->io_Length = sizeof(nsdqr);
- io->io_Data = (APTR)&nsdqr;
- error = DoIO((struct IORequest *)io);
- if((!error) &&
- (io->io_Actual >= 16) &&
- (nsdqr.SizeAvailable == io->io_Actual) &&
- (nsdqr.DeviceType == NSDEVTYPE_TRACKDISK))
- {
- /* Ok, this must be a new style trackdisk device */
- newstyle = TRUE;
-
- /* Is it safe to use 64 bits with this driver? We can reject
- * bad mounts pretty easily via this check!
- */
- for(cmdcheck = nsdqr.SupportedCommands;
- *cmdcheck;
- cmdcheck++)
- {
- if(*cmdcheck == NSCMD_TD_READ64)
- {
- /* This trackdisk style device supports the complete
- * 64 bit command set without returning IOERR_NOCMD!
- */
- does64bit = TRUE;
- } /* if */
- } /* for */
- } /* if */
-
- *** CAVEAT ***: This code fragment uses a pointer to an IOStdReq to
- do the checks. Unfortunately, using a request of this size may
- result in severe problems with certain devices like SANA-II
- devices, which need a larger request structure. A current device
- should check in its OpenDevice code if the passed in request is
- large enough to work with via its mn_Length field and fail to open
- if it isn't. Unfortunately most devices don't do that check. Two
- basic assumptions are possible:
-
- 1. The trusting assumption
-
- You simply use the type and size of request structure
- appropriate for the type of device you intend to use and
- assume that the user did not give you the wrong type
- of device. This may fail and result in a system crash.
-
- 2. The safer assumption
-
- You use the type of request for the device type your are
- expecting (or an IOStdReq for a general check) with an
- extra 128 zeroed bytes when opening and checking a device.
- This will be very safe as current devices are required to
- check the minimum request length before opening
- successfully. So any wrong type of device will not cause
- problems here unless it both
-
- - uses a really strange long request that is
- referenced on OpenDevice() time
-
- and
-
- - does not implement the required mn_Length check
-
- You only need that one larger request for the check on
- opening the device. Afterwards you know what you are
- working with and can use reasonably sized requests.
-
- Obviously we cannot approve of the trusting assumption, so we
- require you to implement the safer assumption. The basic idea
- behind this is that you should always strive to make device access
- as safe as possible. Some little things like validating the
- request structure on OpenDevice will increase stability of the
- device system a lot. Play it safe. The user might have some messed
- up code accessing the device!
-
-
- Device specific requirements
- ============================
-
- Depending on the type returned by NSCMD_DEVICEQUERY, a device may
- support device specific commands in the $c000-$ffff range.
-
- It is valid and strongly suggested behaviour for a device to reject
- all new style commands except NSCMD_DEVICEQUERY with IOERR_NOCMD
- unless the caller executed a valid and successful NSCMD_DEVICEQUERY
- at least once before.
-
- There is also a minimum list of requirements for some types of
- devices.
-
- If a device type is not listed below, no device specific commands
- are defined for it at this time. The device might still support
- special custom 3rd party commands outside the reserved range,
- though. If a device type is listed below, the device driver must
- conform to the mentioned specifications. A new style device
- specific command may possibly match an old style extended command
- exactly to avoid future identification troubles or code
- misunderstanding.
-
-
- Device specific commands and behaviour
- --------------------------------------
-
- NSDEVTYPE_TRACKDISK
-
- May support all V40 trackdisk.device commands and
- possibly HD_SCSICMD as scsidisk.device is obviousy a trackdisk
- like driver. If it doesn't, IOERR_NOCMD must be returned for
- the respective command. 3rd party commands may be added in
- slots that don't conflict with the V40 command set or the
- reserved areas.
-
- A new style trackdisk like device *must* also return this
- new identifier for TD_GETDRIVETYPE. You should use
- TD_GETGEOMETRY on a new style driver to obtain geometry hints
- if needed.
-
- #define DRIVE_NEWSTYLE (0x4E535459L) /* 'NSTY' */
-
-
- At the moment, only four new style commands in the device
- specific range may be implemented.
-
- #define NSCMD_TD_READ64 0xc000
- #define NSCMD_TD_WRITE64 0xc001
- #define NSCMD_TD_SEEK64 0xc002
- #define NSCMD_TD_FORMAT64 0xc003
-
- These commands behave almost like the trackdisk commands
- CMD_READ, CMD_WRITE, TD_FORMAT, respectively, but support 64
- bit handling for large storage devices. The upper 32 bits,
- bit 32 to 63, need to be put into io_Actual before the
- commands are executed. io_Actual can be named io_HighOffset
- in that case.
-
- If you choose to implement the 64 bit commands, you must
- implement all of them, even if some of them would possibly
- return dummy results. A partial implementation with some 64
- bit commands returning IOERR_NOCMD is not acceptable.
-
- A detailed description of the 64 bit commands can be found
- in the document "trackdisk64". Implementors are required to
- read this document.
-
-
- Recommended use
- ===============
-
- Anyone who wants to take advantage of the new style device
- interface should do this:
-
- - OpenDevice() as usual
- - Try a NSCMD_DEVICEQUERY
- - If successful according to the rules mentioned above,
- use the commands as listed in "SupportedCommands".
- - Otherwise it must be an old style device. Hope and pray that
- you got what you wanted.
-
- *** EOT ***
-
- Heinz Wrobel
- <heinz@amiga.de>
-