5.3.2 Application Interface
The functions below are provided as application interface functions, called as extended SVC. These functions cannot be called from a task-independent portion or while dispatch or interrupts are disabled
(E_CTX).
ID tk_opn_dev( UB *devnm, UINT omode )
ER tk_cls_dev( ID dd, UINT option )
ID tk_rea_dev( ID dd, INT start, VP buf, INT size, TMO tmout )
ER tk_srea_dev( ID dd, INT start, VP buf, INT size, INT *asize )
ID tk_wri_dev( ID dd, INT start, VP buf, INT size, TMO tmout )
ER tk_swri_dev( ID dd, INT start, VP buf, INT size, INT *asize )
ID tk_wai_dev( ID dd, ID reqid, INT *asize, ER *ioerr, TMO tmout )
INT tk_sus_dev( UINT mode )
INT tk_get_dev( ID devid, UB *devnm )
ID tk_ref_dev( UB *devnm, T_RDEV *rdev )
ID tk_oref_dev( ID dd, T_RDEV *rdev )
INT tk_lst_dev( T_LDEV *ldev, INT start, INT ndev )
INT tk_evt_dev( ID devid, INT evttyp, VP evtinf )
- ID tk_opn_dev( UB *devnm, UINT omode )
Devnm Device name
Omode Open mode
return code Device descriptor or error
Opens the device specified in devnm in the mode specified in omode, and prepares for device access. The device descriptor is passed in the return code.
omode := (TD_READ || TD_WRITE || TD_UPDATE) | [TD_EXCL || TD_WEXCL]| [TD_NOLOCK]
#define TD_READ 0x0001 /* read only */
#define TD_WRITE 0x0002 /* write only */
#define TD_UPDATE 0x0003 /* read/write */
#define TD_EXCL 0x0100 /* exclusive */
#define TD_WEXCL 0x0200 /* exclusive write */
#define TD_REXCL 0x0400 /* exclusive read */
#define TD_NOLOCK 0x1000 /* lock (making resident) not necessary */
TD_READ Read only
TD_WRITE Write only
TD_UPDATE Sets read and write access mode.
When TD_READ is set, tk_wri_dev() cannot be used.
When TD_WRITE is set, tk_rea_dev() cannot be used.
TD_EXCL Exclusive
TD_WEXCL Exclusive write
TD_REXCL Exclusive read
Sets the exclusive mode.
When TD_EXCL is set, all concurrent opening is prohibited.
When TD_WEXCL is set, concurrent opening in write mode (TD_WRITE or TD_UPDATE) is prohibited.
When TD_REXCL is set, concurrent opening in read mode (TD_READ or TD_UPDATE) is prohibited.
Concurrent Open Mode
Present Open Mode
No exclusive mode
TD_WEXCL
TD_EXCL
R
W
R
W
R
W
No exclusive mode
R
Yes
Yes
Yes
Yes
No
No
W
Yes
Yes
No
No
No
No
TD_WEXCL
R
Yes
No
Yes
No
No
No
W
Yes
No
No
No
No
No
TD_REXCL
R
No
Yes
No
Yes
No
No
W
No
Yes
No
No
No
No
TD_EXCL
R
No
No
No
No
No
No
W
No
No
No
No
No
No
R= TD_READ W= TD_WRITE or TD_UPDATE
Yes = Can be opened No = Cannot be opened (E_BUSY)
TD_NOLOCK Lock (making resident) not necessary
Indicates that a memory space (buf) specified in IO operations (tk_rea_dev and tk_wri_dev) has already been locked (made resident) on the calling side and does not have to be locked by the device driver. In this case the device driver does not (must not) lock the area. This is used e.g. to perform disk access for page in/page out in a virtual memory system. Generally it does not need to be specified.
The device descriptor belongs to the resource group of the task that opened the device. When a physical device is opened, the logical devices belonging to it are all treated as having been opened in the same mode, and are processed as exclusive open.
E_BUSY DevicE_BUSY (exclusive open)
E_NOEXS Device does not exist
E_LIMIT Open count exceeds the limit
Other Errors returned by device driver
- ER tk_cls_dev( ID dd, UINT option )
dd Device descriptor
option Close option
return code Error
Closes device descriptor dd.
If a request is being processed, the processing is aborted and the device is closed.
option := [TD_EJECT]
#define TD_EJECT 0x0001 /* eject media */
TD_EJECT Eject media
If the same device has not been opened by another task, the media is ejected. In the case of devices that cannot eject their media, the request is ignored.
The subsystem cleanup processing (tk_cln_ssy) closes all the device descriptors belonging to the resource group
E_ID dd is invalid or not open
Other Errors returned by device driver
- ID tk_rea_dev( ID dd, INT start, VP buf, INT size, TMO tmout )
dd Device descriptor
start Read start location (> 0: Device-specific data, < 0: Attribute data)
buf Bu.er location for putting the read data
size Read size
tmout Request acceptance timeout (ms)
return code Request ID or error
Starts reading device-specific data or attribute data from the specified device. This function starts reading only, returning to its caller without waiting for the read operation to .nish. The space specified in buf must be retained until the read operation completes. Read completion is waited for by tk_wai_dev.
The time required for read start processing di.ers with the device; return of control is not neces sarily immediate.
In the case of device-specific data, the start and size units are decided for each device. With attribute data, start is an attribute data number and size is in bytes. The attribute data of the data number specified in start is read. Normally size must be at least as large as the size of the attribute data to be read. Reading of multiple attribute data in one operation is not possible.
When size = 0 is specified, actual reading does not take place but the current size of data that can be read is checked.
Whether or not a new request can be accepted while a read or write operation is in progress depends on the device driver. If a new request cannot be accepted, the request is queued. The timeout for request waiting is set in tmout. The TMO_POL or TMO_FEVR attribute can be specified for tmout. Note that what times out is request acceptance. Once a request has been accepted, this function does not time out.
E_ID dd is invalid or not open
E_OACV Open mode is invalid (read not permitted)
E_LIMIT Number of requests exceeds the limit
E_TMOUT Busy processing other requests
E_ABORT Processing aborted
Other Errors returned by device driver
- ER tk_srea_dev( ID dd, INT start, VP buf, INT size, INT *asize )
Synchronous read. This is equivalent to the following.
ER tk_srea_dev( ID dd, INT start, VP buf, INT size, INT *asize )
{
ER er, ioer;
er = tk_rea_dev(dd, start, buf, size, TMO_FEVR);
if ( er > 0 ) {
er = tk_wai_dev(dd, er, asize, &ioer, TMO_FEVR);
if ( er > 0 ) er = ioerr;
}
return er;
}
- ID tk_wri_dev( ID dd, INT start, VP buf, INT size, TMO tmout )
dd Device descriptor
start write start location (> 0: Device-specific data, < 0: Attribute data)
buf Bu er holding data to be written
size Size of data to be written
tmout Request acceptance timeout (ms)
return code Request ID or error
Starts writing device-specific data or attribute data to a device. This function starts writing only, returning to its caller without waiting for the write operation to .nish. The space specified in buf must be retained until the write operation completes. Write completion is waited for by tk_wai_dev.
The time required for write start processing di.ers with the device; return of control is not neces sarily immediate.
In the case of device-specific data, the start and size units are decided for each device. With attribute data, start is an attribute data number and size is in bytes. The attribute data of the data number specified in start is written. Normally size must be at least as large as the size of the attribute data to be written. Multiple attribute data cannot be written in one operation.
When size = 0 is specified, actual writing does not take place but the current size of data that can be written is checked.
Whether or not a new request can be accepted while a read or write operation is in progress depends on the device driver. If a new request cannot be accepted, the request is queued. The timeout for request waiting is set in tmout. The TMO_POL or TMO_FEVR attribute can be specified for tmout. Note that what times out is request acceptance. Once a request has been accepted, this function does not time out.
E_ID dd is invalid or not open
E_OACV Open mode is invalid (write not permitted)
E_RONLY Read-only device
E_LIMIT Number of requests exceeds the limit
E_TMOUT Busy processing other requests
E_ABORT Processing aborted
Other Errors returned by device driver
- ER tk_swri_dev( ID dd, INT start, VP buf, INT size, INT *asize )
Synchronous write. This is equivalent to the following.
ER tk_swri_dev( ID dd, INT start, VP buf, INT size, INT *asize )
{
ER er, ioer;
er = tk_wri_dev(dd, start, buf, size, TMO_FEVR);
if ( er > 0 ) {
er = tk_wai_dev(dd, er, asize, &ioer, TMO_FEVR);
if ( er > 0 ) er = ioer;
}
return er;
}
- ID tk_wai_dev( ID dd, ID reqid, INT *asize, ER *ioer, TMO tmout )
dd Device descriptor
reqid Request ID
asize Returns the read/write data size
ioer Returns IO error
tmout Timeout (ms)
return code Completed request ID or error
Waits for completion of request reqid for device dd.
If reqid = 0 is set, this function waits for completion of any pending request to dd.
This function waits for completion only of requests currently processing when the function is called.
A request issued after tk_wai_dev was called is not waited for. When multiple requests are being processed concurrently, the order of their completion is not necessarily the same as the order of request but is dependent on the device driver. Processing is, however, guaranteed to be performed in a sequence such that the result is consistent with the order of requesting. When processing a read operation from a disk, for example, the sequence might be changed as follows.
Block number request sequence 1 4 3 2 5
Block number processing sequence 1 2 3 4 5
Disk access can be made more e.cient by changing the sequence as above with the aim of reducing
seek time and spin wait time.
The timeout for waiting for completion is set in tmout. The TMO_POL or TMO_FEVR attribute can be specified for tmout. If a timeout error is returned (E_TMOUT), tk_wai_dev must be called again to wait for completion, since the request processing is ongoing.
When reqid > 0 and tmout = TMO_FEVR are both set, the processing must be completed without timing out.
If the requested processing results in error (IO error, etc.) ioer is stored rather than a return code. The return code is used for errors when the request wait itself was not handled properly. When error is passed in the return code, ioer has no meaning. Note also that if error is passed in the return code, tk_wai_dev must be called again to wait for completion, since the request processing is ongoing.
If a task exception is raised during completion waiting by tk_wai_dev, the request in reqid is aborted and processing is completed. The result of aborting the requested processing is dependent on the device driver. When reqid = 0 was set, however, requests are not aborted but are treated as timeout. In this case E_ABORT rather than E_TMOUT is returned.
It is not possible for multiple tasks to wait for completion of the same request ID at the same time. If there is a task waiting for request completion with reqid = 0 set, another task cannot wait for completion for the same device descriptor. Similarly, if there is a task waiting for request completion with reqid > 0 set, another task cannot wait for completion specifying reqid = 0.
E_ID dd is invalid or not open
reqid is invalid or not a request for dd
E_OBJ Another task is already waiting for request reqid
E_NOEXS No requests are being processed (only when reqid = 0)
E_TMOUT Timeout (processing continues)
E_ABORT Processing aborted
Other Errors returned by device driver
- INT tk_su s_dev( UINT mode )
mode Mode
return code Suspend disable request count or error
Performs the processing specified in mode, then passes the resulting suspend disable request count in the return code.
mode := ( (TD_SUSPEND | [TD_FORCE]) || TD_DISSUS || TD_ENASUS || TD_CHECK)
#define TD_SUSPEND 0x0001 /* suspend */
#define TD_DISSUS 0x0002 /* disable suspension */
#define TD_ENASUS 0x0003 /* enable suspension */
#define TD_CHECK 0x0004 /* get suspend disable request count */
#define TD_FORCE 0x8000 /* forcibly suspend */
TD_SUSPEND Suspend
If suspending is enabled, suspends processing. If suspending is disabled, returns E_BUSY.
TD_SUSPEND|TD FORCE Forcibly suspend
Suspends even in suspend disabled state.
TD_DISSUS Disable suspension
Disables suspension.
TD_ENASUS Enable suspension
Enables suspension.
If the enable request count is above the disable count for the resource group, no operation is performed.
TD_CHECK Get suspend disable count
Gets only the number of times suspend disable has been requested.
Suspension is performed in the following steps.
1. Processing prior to start of suspension in each subsystem
tk_evt_ssy(0, TSEVT_SUSPEND_BEGIN, 0, 0)
2. Suspension processing in non-disk devices
3. Suspension processing in disk devices
4. Processing after completion of suspension in each subsystem
tk_evt_ssy(0, TSEVT_SUSPEND_DONE, 0, 0)
5. SUSPEND state entered
tk_set_pow(TPW_DOSUSPEND)
Resumption from SUSPEND state is performed in the following steps.
1. Return from SUSPEND state Return from tk_set_pow(TPW_DOSUSPEND)
2. Processing prior to start of resumption in each subsystem
tk_evt_ssy(0, TSEVT_RESUME_BEGIN, 0, 0)
3. Resumption processing in disk devices
4. Resumption processing in non-disk devices
5. Processing after completion of resumption in each subsystem
tk_evt_ssy(0, TSEVT_RESUME_DONE, 0, 0)
The number of suspend disable requests is counted. Suspension is enabled only if the same number of suspend enable requests is made. At system boot, the suspend disable count is 0 and suspension is enabled. There is only one suspend disable request count kept per system, but the system keeps track of the resource group making the request. It is not possible to clear suspend disable requests made in another resource group. When the cleanup function runs in a resource group, all the suspend requests made in that group are cleared and the suspend disable request count is reduced accordingly. The maximum suspend disable request count is implementation-dependent, but must be at least 255. When the upper limit is exceeded, E_QOVR is returned.
E_BUSY Suspend already disabled
E_QOVR Suspend disable request count limit exceeded
- ID tk_get_dev( ID devid, UB *devnm )
devid Device ID
devnm Device name storage location
return code Device ID of physical device or error
Gets the device name of the device specified in devid and puts the result in devnm.
devid is the device ID of either a physical device or a logical device. If devid is a physical device, the physical device name is put in devnm. If devid is a logical device, the logical device name is put in devnm. devnm requires a space of L DEVNM + 1 bytes or larger.
The device ID of the physical device to which device devid belongs is passed in the return code. E_NOEXS The device specified in devid does not exist
- ID tk_ref_dev( UB *devnm, T_RDEV *rdev )
- ID tk_oref_dev( ID dd, T_RDEV *rdev )
devnm Device name
dd Device descriptor
rdev Device information
return code Device ID or error
typedef struct t_rdev {
ATR devatr; /* device attributes */
INT blksz; /* block size of device-specific data (-1: unknown) */
INT nsub; /* subunit count */
INT subno; /* 0: physical device: 1 to nsub: subunit number+1 */
/* Implementation-dependent information may be added beyond this point.*/
} T_RDEV;
Gets device information about the device specified in devnm or dd and puts the result in rdev.
If rdev = NULL is set, the device information is not stored. nsub indicates the number of physical
device subunits belonging to the device specified in devnm or dd.
The device ID of the device specified in devnm is passed in the return code. E_NOEXS The device
specified in devnm does not exist.
- INT tk_lst_dev( T_LDEV *ldev, INT start, INT ndev )
ldev Location of registered device information (array)
start Starting number
ndev Number to acquire
return code Remaining device registration count or error
typedef struct t_ldev {
ATR devatr; /* device attributes */
INT blksz; /* device-specific data block size (-1: unknown) */
INT nsub; /* subunits */
UB devnm[L_DEVNM]; /* physical device name */
/* Implementation-dependent information may be added beyond this point.*/
} T_LDEV;
Gets information about registered devices.
Registered devices are managed per physical device. The registered device information is therefore also obtained per physical device.
When the number of registered devices is N, number are assigned serially to devices from 0 to N – 1. Starting from the number specified in start in accord with this scheme, the number of registrations specified in ndev is acquired and put in ldev. The space specified in ldev must be large enough to hold ndev registration information. The number of remaining registrations after start ( N . start ) is passed in the return code. If the number of registrations from start is fewer than ndev, all remaining registrations are stored. A value passed in return code less than or equal to ndev means all remaining registrations were obtained. Note that this numbering changes as devices are registered and deleted. For this reason, accurate information may not always be obtained if the acquisition is carried out over multiple operations.
E_NOEXS start exceeds the number of registered devices
- INT tk_evt_dev( ID devid, INT evttyp, VP evtinf )
devid Event destination device ID
evttyp Driver request event type
evtinf Information for each event type
return code Return code from device driver or error
Sends a driver request event to the device (device driver) specified in devid. The following driver request events are defined.
#define TDV_CARDEVT 1 /* PC Card event (see Card Manager) */
#define TDV_USBEVT 2 /* USB event (see USB Manager) */
The functioning of driver request events and the contents of evtinf are defined for each event type. E_NOEXS The device specified in devid does not exist E_PAR Internal device manager events (evttyp < 0) cannot be specified

Comments