A NOTE has been added to this issue. 
====================================================================== 
https://austingroupbugs.net/view.php?id=729 
====================================================================== 
Reported By:                Don Cragun
Assigned To:                
====================================================================== 
Project:                    1003.1(2013)/Issue7+TC1
Issue ID:                   729
Category:                   System Interfaces
Type:                       Enhancement Request
Severity:                   Objection
Priority:                   normal
Status:                     New
Name:                       Don Cragun 
Organization:               IEEE PASC 
User Reference:             Integrate 1003.26 into Issue 8 
Section:                    posix_devctl() 
Page Number:                - 
Line Number:                - 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2013-08-08 07:20 UTC
Last Modified:              2022-03-01 15:08 UTC
====================================================================== 
Summary:                    Integrate posix_devctl() from standalone IEEE Std
1003.26 into the next revision of IEEE Std 1003.1
====================================================================== 

---------------------------------------------------------------------- 
 (0005723) geoffclare (manager) - 2022-03-01 15:08
 https://austingroupbugs.net/view.php?id=729#c5723 
---------------------------------------------------------------------- 
Here's my attempt to turn Don's plan from the desired action into a fully
fledged set of editing instructions, taking into account the mailing list
discussion in August 2013.

All page and line numbers refer to the 2016/2018 edition.

On page xxxix section Referenced Documents, insert before "Sarwate
Article":<blockquote>POSIX.26: 2003<blockquote>IEEE Std 1003.26(TM)-2003,
IEEE Standard for Information Technology - Portable Operating System
Interface (POSIX) - Part 26: Device Control Application Program Interface
(API) [C Language]</blockquote></blockquote>
On page 7 line 180 section 1.7.1 Codes, insert a new
code:<blockquote>[DC]Device Control[/DC]

The functionality described is optional. The functionality described is
also an extension to the ISO C standard.

Where applicable, functions are marked with the DC margin legend in the
SYNOPSIS section.  Where additional semantics apply to a function, the
material is identified by use of the DC margin legend.</blockquote>
On page 507 line 17993 section 2.9.5.2 Cancellation Points, add
<i>posix_devctl</i>() to the list of functions that may be a cancellation
point.

On page 16 line 530 section 2.1.3.1 POSIX System Interfaces,
insert:<blockquote>_POSIX_DEVICE_CONTROL</blockquote>
On page 96 line 2957 section 4 General Concepts, insert a new
section:<blockquote>4.19 Special Device

In this standard, a <i>special device</i> is a device that requires control
operations, other than the operations that are common to most devices (such
as <i>read</i>(), <i>write</i>(), <i>open</i>(), and <i>close</i>()), but
because the device belongs to a class that is not present in the majority
of systems, standardization of a device-specific application program
interface (API) for controlling it has not been practical. The driver for a
special device may respond to the <i>write</i>() function to transfer data
to the device or the <i>read</i>() function to collect information from the
device. The interpretation of the information is defined by the implementor
of the driver.

The term <i>special device</i> refers to hardware; access to the driver for
this hardware uses the file abstraction <i>character special file</i>.
Implementations supporting the Device Control option shall provide the
means to integrate a device driver into the system. The means available to
integrate drivers into the system and the way character special files that
refer to them are created are implementation defined. Character special
files that have no structure defined by this standard can be accessed using
the <i>posix_devctl</i>() function defined in the System Interfaces volume
of POSIX.1-202x.</blockquote>
and renumber the later sections.

On page 218 insert a new <devctl.h> page:

<b>NAME</b><blockquote><devctl.h> - device control</blockquote>
<b>SYNOPSIS</b>
<blockquote><pre>[DC]#include <devctl.h>[/DC]</pre></blockquote>
<b>DESCRIPTION</b><blockquote>The following shall be declared as a function
and may also be defined as a macro. A function prototype shall be
provided.

int posix_devctl(int, int, void *restrict, size_t, int
*restrict);</blockquote>
<b>APPLICATION USAGE</b><blockquote>None.</blockquote>
<b>RATIONALE</b><blockquote>None.</blockquote>
<b>FUTURE DIRECTIONS</b><blockquote>None.</blockquote>
<b>SEE ALSO</b><blockquote><termios.h>

XSH posix_devctl()</blockquote>
<b>CHANGE HISTORY</b><blockquote>First released in Issue 8. Derived from
POSIX.26.</blockquote>
On page 426 line 14745 section <unistd.h>, insert a new
paragraph:<blockquote>[DC]_POSIX_DEVICE_CONTROL<blockquote>The
implementation supports the device control option. If this symbol is
defined in <b><unistd.h></b>, it shall be defined to be -1, 0, or 20yymmL.
The value of this symbol reported by <i>sysconf</i>() shall either be -1 or
20yymmL.[/DC]</blockquote></blockquote>
On page 435 line 15151 section <unistd.h>,
insert:<blockquote>_SC_DEVICE_CONTROL</blockquote>
On page 1430 insert a new posix_devctl() page:

<b>NAME</b><blockquote>posix_devctl - device control</blockquote>
<b>SYNOPSIS</b>
<blockquote><pre>[DC]#include <devctl.h>

int posix_devctl(int <i>fildes</i>, int <i>dcmd</i>,
    void *restrict <i>dev_data_ptr</i>, size_t <i>nbyte</i>,
    int *restrict <i>dev_info_ptr</i>);[/DC]</pre></blockquote>
<b>DESCRIPTION</b><blockquote>The <i>posix_devctl</i>() function shall
cause the device control command <i>dcmd</i> to be passed to the driver
identified by <i>fildes</i>. Associated data shall be passed to and/or from
the driver depending on direction information encoded in the <i>dcmd</i>
argument or as implied in the <i>dcmd</i> argument by the design and
implementation of the driver.

If the <i>dev_data_ptr</i> argument is not a null pointer, it shall be a
pointer to a buffer that is provided by the caller and that contains data
bytes to be passed to the driver or provides space for receiving data bytes
to be passed back from the driver, or both.

If the data bytes are to be passed to the driver, at least <i>nbyte</i>
bytes of associated data shall be made available to the driver; if the data
bytes are to be passed from the driver, no more than <i>nbyte</i> bytes
shall be passed.

The driver may be executing in an address space different from the address
space of the calling thread. Therefore, if the data bytes passed to the
driver (i.e., the contents of the memory area starting at
<i>dev_data_ptr</i> and continuing for <i>nbyte</i> bytes) contain pointers
to memory in the address space of the calling thread and the driver uses
these pointers to access that memory, the effects are unspecified.

[OB]If <i>dev_data_ptr</i> is not a null pointer and <i>nbyte</i> is zero,
the amount of data passed to and/or from the driver is unspecified. This
feature is obsolescent and is only provided for compatibility with existing
device drivers.[/OB]

If <i>dev_data_ptr</i> is a null pointer, there shall be no data bytes
passed between the caller and the driver other than the data specified in
the rest of the arguments to <i>posix_devctl</i>() and in its return
value.

The <i>dev_info_ptr</i> argument provides the opportunity to return an
integer number containing additional device information, instead of just a
success/failure indication.  For implementation-provided <i>dcmd</i>
values, it is implementation-defined whether each such value causes the
<b>int</b> pointed to by <i>dev_info_ptr</i> to be set and, if set, what
value it is set to.

For each supported device, the set of valid <i>dcmd</i> commands, the
associated data interpretation, and the effects of the command on the
device are all defined by the driver for the device identified by
<i>fildes</i>, and are therefore implementation-defined for
implementation-provided device drivers.</blockquote>
<b>RETURN VALUE</b><blockquote>Upon successful completion,
<i>posix_devctl</i>() shall return zero; otherwise an error number shall be
returned to indicate the error. The value returned in the <b>int</b> value
pointed to by <i>dev_info_ptr</i> is driver dependent.</blockquote>
<b>ERRORS</b><blockquote>The <i>posix_devctl</i>() function shall fail if:

[EBADF]<blockquote>The <i>fildes</i> argument is not a valid open file
descriptor.</blockquote>The <i>posix_devctl</i>() function may fail if:

[EINTR]<blockquote>The <i>posix_devctl</i>() function was interrupted by a
signal.</blockquote>[EINVAL]<blockquote>The <i>nbyte</i> argument is
negative, or exceeds an implementation-defined maximum, or is less than the
minimum number of bytes required for this
command.</blockquote>[EINVAL]<blockquote>The <i>dcmd</i> argument is not
valid for this device.</blockquote>[ENOTTY]<blockquote>The <i>fildes</i>
argument is not associated with a character special file that accepts
control functions.</blockquote>[EPERM]<blockquote>The requesting process
does not have the appropriate privilege to request the device to perform
the specified command.</blockquote>Driver code may detect other errors, but
the error numbers returned are driver dependent. See ``Recommended Practice
for Driver-Detected Errors'' in RATIONALE.

If the <i>posix_devctl</i>() function fails, the effect of this failed
function on the device is driver dependent. Corresponding data might be
transferred, partially transferred, or not transferred at
all.</blockquote>
<b>EXAMPLES</b><blockquote>None.</blockquote>
<b>APPLICATION USAGE</b><blockquote>None.</blockquote>
<b>RATIONALE</b><blockquote><b>Background</b>

An interface to be included in the POSIX standard should improve source
code portability of application programs. In traditional UNIX practice,
<i>ioctl</i>() was used to handle special devices. Therefore, a general
specification of its arguments cannot be written. Based on this fact, in
the past many people claimed that <i>ioctl</i>(), or something close to it,
had no place in the POSIX standards.

Against this perception stood the widespread use of <i>ioctl</i>() to
interface to all sorts of drivers for a vast variety of hardware used in
all areas of general-purpose, realtime, and embedded computing, such as
analog-digital converters, counters, and video graphic devices. These
devices provide a set of services that cannot be represented or used in
terms of <i>read</i>() or <i>write</i>() calls.

The arguments in favor of <i>ioctl</i>() standardization can be summarized
as follows:

Even if <i>ioctl</i>() addresses very different hardware, many of these
devices either are actually the same, interfaced to different computer
systems with different implementations of operating systems, or belong to
classes of devices with rather high commonality in their functions, e.g.,
analog-digital converters or digital-analog converters. Growing
standardization of the control and status register (CSR) space of these
devices allows exploitation of a growing similarity of control codes and
data for these devices. A general mechanism is needed to control these
devices.

In all these cases, a standardized interface from the application program
to drivers for these devices will improve source code portability.

Even if control codes and device data have to be changed when porting
applications from one system to another, the definition of <i>ioctl</i>()
largely improves readability of a program handling special devices. Changes
are confined to more clearly labeled places.

A driver for a specific device normally cannot be considered portable per
se, but an application that uses this driver can be made portable if all
interfaces needed are well defined and standardized. Users and integrators
of realtime systems often add device drivers for specific devices, and a
standard interface simplifies this process. Also, device drivers often
follow their special hardware from system to system.

In recognition of these reasons, The Open Group included <i>ioctl</i>() in
the The Single UNIX Specification, Version 1, and the interface was later
incorporated into POSIX.1 under the XSI STREAMS option (although that
option was subsequently removed).

The <i>posix_devctl</i>() interface defined in this standard provides an
alternative to the the various <i>ioctl</i>() implementations with a
standard interface that captures the extensibility of <i>ioctl</i>(), but
avoids several of its deficiencies, which is mentioned in ``Relationship to
<i>ioctl</i>() and the Perceived Needs for Improvement'' below.

<b>Existing Practice</b>

The <i>ioctl</i>() interface is widely used. It has provided the generality
mentioned above. Existing practice encodes into the second parameter
information about data size and direction in some systems. An example of
such an encoding is the use in BSD 4.3 of two bits of the command word as
read/write bits. However, <i>ioctl</i>() has definite problems with the way
that its sometimes optional third parameter can be interpreted.

This practice is similar to the existing POSIX <i>fcntl</i>() function, in
which the third parameter can be optional for F_GETFD, F_GETFL, an
<b>int</b> when used with the F_DUPFD, F_SETFD, or F_SETFL commands or a
<b>struct flock</b>, when used with the F_GETLK, F_SETLD, or F_SETLKW
commands. However, the <i>fcntl</i>() interface defines two distinct and
known data types as possible for the third parameter. This is not the case
in the <i>ioctl</i>() interface, where any number of device driver specific
structures and commands are used.

<b>Relationship to <i>ioctl</i>() and the Perceived Needs for
Improvement</b>

[xref to XRAT A.11] briefly mentions some of the perceived deficiencies in
existing implementations of the <i>ioctl</i>() function, in the context of
those <i>ioctl</i>() commands used to implement terminal control. The
standard developers decided that, since the set of such control operations
was fairly well defined, suitable encapsulations such as
<i>tcsetattr</i>(), <i>tcsendbreak</i>(), and <i>tcdrain</i>() could be
standardized. These interfaces, while successfully standardizing portable
terminal control operations, are not extensible to arbitrary user-supplied
devices.

There are several perceived deficiencies with the <i>ioctl</i>() function
that drove the development of the <i>posix_devctl</i>() interface as an
alternative:

<ul><li>The major problem with <i>ioctl</i>() is that the third argument
(when one is passed) varies in both size and type according to the second
(command) argument. It is not unprecedented in POSIX, or standards in
general, for a function to accept a generic pointer; consider the ISO C
function <i>fread</i>(), or the POSIX functions <i>read</i>() and
<i>mmap</i>(). However, in all such instances, the generic pointer is
accompanied by a size argument that specifies the size of the pointed-to
object. Unlike the Ada language, it is, and has always been, the C
programmer's responsibility to ensure that these two arguments form a
consistent specification of the passed object. But traditional
<i>ioctl</i>() implementations do not allow the user to specify the size of
the pointed-to object; that size is instead fixed implicitly by the
specified command (passed as another argument). The <i>posix_devctl</i>()
interface improves upon <i>ioctl</i>() in that it allows the user to
specify the object size, thereby restoring the familiar C paradigm for
passing a generic object by pointer/size pair.</li>
<li>A secondary problem with <i>ioctl</i>() is that the third argument is
sometimes permitted to be interpreted as an integer (<b>int</b>). The
<i>posix_devctl</i>() interface clearly requires the <i>dev_data_ptr</i>
argument to be a pointer.</li>
<li>A related problem with <i>ioctl</i>() is that the direction(s) in which
data are transferred to or from the pointed-to object is neither specified
explicitly as an argument (as with <i>mmap</i>()), nor implied by the
<i>ioctl</i>() function (as with <i>read()/write</i>(),
<i>fread()/fwrite</i>(), or <i>fgets()/fputs</i>()). Instead, the direction
is implied by the command argument. In traditional implementations, only
the device driver knows the interpretation of the commands and whether data
bytes are to be transferred to or from the pointed-to object. But in
networked implementations, generic portions of the operating system may
need to know the direction to ensure that data bytes are passed properly
between a client and a server, separately from device driver concerns. Two
implementation-specific solutions to this problem are to always assume data
bytes need to be transferred in both directions, or to encode the implied
direction into the command word along with the fixed data size. The
<i>posix_devctl</i>() interface already provides the implementation with an
explicit size parameter.  Since the direction is already known implicitly
to both the application and the driver and since workable methods exist for
implementations to ascertain that direction if required, this perceived
problem is strictly an implementation issue and solvable without further
impact on the interface.</li>
<li>Finally, <i>posix_devctl</i>() improves upon <i>ioctl</i>() by adopting
the new style of error return, avoiding all the problems <i>errno</i>
brings to multi-threaded applications. Because the driver-specific
information carried by the non-error return values of <i>ioctl</i>() still
potentially needs to be passed to the application, <i>posix_devctl</i>()
adds the <i>dev_info_ptr</i> argument to specify where this information
should be stored.</li> </ul>

<b>Which Differences Between <i>posix_devctl</i>() and <i>ioctl</i>() Are
Acceptable?</b>

Any differences between the definitions of <i>posix_devctl</i>() and
<i>ioctl</i>() have to be perceived as a clear improvement by the community
of potential users. Drivers for normal peripherals are typically written by
highly specialized professionals. Drivers for the special devices are very
often written by the application developer or by the hardware designer. Any
interface definition that can be seen as overly complicated will simply not
be accepted.

Nevertheless, a few simple and useful improvements to <i>ioctl</i>() are
possible, specifically the improvement of type checking, and justify the
definition of a new interface.

The major difference between the two interfaces is the addition of the size
of the device data. For enhanced compatibility with existing <i>ioctl</i>()
implementations, this size can be specified as zero; in this case the
amount of data passed is unspecified. (This allows a macro definition of
<i>ioctl</i>() that converts it into a <i>posix_devctl</i>() call.) In any
case, the data size argument does not contradict the general goal of being
able to implement <i>posix_devctl</i>() using the existing <i>ioctl</i>()
interfaces provided in current UNIX systems and other POSIX implementations
because the standard allows but does not require checking the size of the
device data. Although the third argument of the <i>ioctl</i>() function
does not specify a size, it is implicit in the specific combination of
control command and driver and, therefore, known to the driver
implementation.

The method of indicating error return values differs from traditional
<i>ioctl</i>() implementations, but it does not preclude the construction
of <i>posix_devctl</i>() as a macro built upon <i>ioctl</i>(), which was
one of the original design goals.

<b>Rationale for the <i>dev_info_ptr</i> Argument</b>

The POSIX.26 developers felt that it was important to preserve the current
<i>ioctl</i>() functionality of allowing a device driver to return some
arbitrary piece of information instead of just a success/failure
indication. Such information might be, for example, the number of bytes
received, the number of bytes that would not fit into the buffer pointed at
by <i>dev_data_ptr</i>, the data type indication, or the device status.
Current practice for device drivers and <i>ioctl</i>() usage allows such a
device-dependent return value. Thus, the concept of an additional output
argument, <i>dev_info_ptr</i>, was born.

<b>Rationale for No <i>direction</i> Argument</b>

The initial specification for <i>posix_devctl</i>() contained an additional
argument that specified the direction of data flow, i.e., to the driver
and/or from the driver. This argument was later removed for the following
reasons:

<ul><li>The argument was redundant. Most (if not all) existing
implementations encode the direction data either explicitly or implicitly
in the command word.</li>
<li>The argument increased the probability of programming errors, since it
must be made to agree with the direction information already encoded or
implied in the command word or an error would occur. </li>
<li>The only real use of the argument would be if new drivers were written
that supported generic commands such as TRANSFER_CONTROL_DATA, which was
modified by the direction argument to indicate in which direction the data
should be transferred. This is contrary to current practice that uses
command pairs such as GET_CONTROL_DATA and PUT_CONTROL_DATA.</li>
<li>The primary purpose of the direction argument was to allow higher
levels of the system to identify the direction of data transfers,
particularly in the case of remote devices, without having to understand
all the commands of all the devices on the system. Implementations that
need to ascertain the direction of data transfer from a command word will
define a consistent convention for encoding the direction into each command
word, and all device drivers supplied by the user must adhere to this
convention.</li> </ul>

Thus, the data direction argument was removed.

<b>Rationale for Not Defining the Direction Encoding in the <i>dcmd</i>
Argument</b>

The POSIX.26 developers gave consideration to defining the direction
encoding in the <i>dcmd</i> argument, but decided against doing so. No
particular benefit was seen to a predefined encoding, as long as the
encoding was used consistently across the entire implementation and was
well known to the implementation.

In addition, although only one encoding (BSD's) employed for <i>ioctl</i>()
was known among the members of the small working group, it could not be
ruled out that other encodings already existed, and no reason for
precluding these encodings was seen.

Finally, system or architectural constraints might make a chosen standard
encoding difficult to use on a given implementation.

Thus, this standard does not define a direction encoding. Specifying a
standard encoding is actually a small part of a larger and more contentious
objective, that of specifying a complete set of interfaces for portable
device drivers. If a future POSIX standard specifies such interfaces, the
issue of device control direction encoding will necessarily be addressed as
part of that specification.

<b>Recommended Practice for Handling Data Size Errors</b>

In the event that the amount of data from the device is too large to fit
into the specified buffer, as much data as will fit should be transferred,
and the error posted. The retained data will aid in debugging, even if some
of the data is lost.

<b>Recommended Practice for <i>nbyte</i> == 0</b>

The feature that permits an unspecified amount of control data to be
transferred if <i>nbyte</i> is zero exists only for compatibility with
existing device driver usage of <i>ioctl</i>(), i.e., when <i>ioctl</i>()
is implemented on top of <i>posix_devctl</i>() and the device driver
transfers an amount of data implied by the command.

Implementations in which <i>posix_devctl</i>() is built as a library
routine on top of <i>ioctl</i>() may not be able to make checks on the
<i>nbyte</i> argument. However, newly developed applications using
<i>posix_devctl</i>() should always use an appropriate value for the
<i>nbyte</i> argument, for portability to implementations directly
supporting <i>posix_devctl</i>() in which the device drivers may be able to
honor the application's <i>nbyte</i> argument or return the error [EINVAL]
if the argument is an unacceptable value. Device drivers designed for those
systems should interpret a zero value of <i>nbyte</i> as no data to be
transferred.

<b>Recommended Practice for Driver-Detected Errors</b>

If the driver detects the following error conditions, it is recommended
that the <i>posix_devctl</i>() function fail and return the corresponding
error number:

[EBUSY]<blockquote>The control operation could not complete successfully
because the device was in use by another process, or the driver was unable
to carry out the request due to an outstanding operation in
progress.</blockquote>[EINVAL]<blockquote>The arguments <i>dev_dta_ptr</i>
and <i>nbyte</i> define a buffer too small to hold the amount of data
expected by or to be returned by this
driver.</blockquote>[EIO]<blockquote>The control operation could not
complete successfully because the driver detected a hardware
error.</blockquote></blockquote>
<b>FUTURE DIRECTIONS</b><blockquote>None.</blockquote>
<b>SEE ALSO</b><blockquote>XBD 4.19 Special Device,
<devctl.h></blockquote>
On page 2059 line 66728 section sysconf(),
insert:<blockquote>_POSIX_DEVICE_CONTROL     
_SC_DEVICE_CONTROL</blockquote>
On page 3440 line 117435 section A.4 General Concepts, insert a new
section:<blockquote>POSIX systems interact with their physical environment
using a variety of devices (such as analog-digital converters,
digital-analog converters, counters, and video graphic equipment), which
provide a set of services that cannot be fully utilized in terms of read
and/or write semantics. Traditional practice uses a single function, called
<i>ioctl</i>(), to encapsulate all the control operations on the different
devices connected to the system, both special or common devices. The
POSIX.1-1988 developers decided not to standardize this interface because
it was not type safe, it had a variable number of parameters, and it had
behaviors that could not be specified by the standard because they were
driver-dependent. Instead, POSIX.1-1988 defined a device-specific
application program interface (API) for a common class of drivers,
Terminals. Later, The Single UNIX Specification, Version 1 included the
<i>ioctl</i>() function, but restricted it to control of STREAMS devices.

Although the POSIX.1-1988 solution for common classes of devices is the
best from the point of view of application portability, there is still a
need for a way to interact with special, or even common devices, for which
developing a full standard API is not practical. The device control option
standardized in POSIX.26 and now included in this standard is a general
method for interfacing to the widest possible range of devices, through a
new service to pass control information and commands between the
application and the device drivers.

A driver for a special device will normally not be portable between POSIX
implementations, but an application that uses such a driver can be made
portable if all functions calling the driver are well defined and
standardized. Users and integrators of realtime systems often add drivers
for special devices, and a standardized function format for interfacing
with these devices greatly simplifies this process.</blockquote>
and renumber the later sections. 

Issue History 
Date Modified    Username       Field                    Change               
====================================================================== 
2013-08-08 07:20 Don Cragun     New Issue                                    
2013-08-08 07:20 Don Cragun     Name                      => Don Cragun      
2013-08-08 07:20 Don Cragun     Organization              => IEEE PASC       
2013-08-08 07:20 Don Cragun     User Reference            => Integrate 1003.26
into Issue 8
2013-08-08 07:20 Don Cragun     Section                   => posix_devctl()  
2013-08-08 07:20 Don Cragun     Page Number               => -               
2013-08-08 07:20 Don Cragun     Line Number               => -               
2013-08-08 07:20 Don Cragun     Interp Status             => ---             
2013-08-08 07:46 Don Cragun     Tag Attached: issue8                         
2022-03-01 15:08 geoffclare     Note Added: 0005723                          
======================================================================


  • [1003.1(2013... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group

Reply via email to