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