NAME | SYNOPSIS | DESCRIPTION | IOCTLS | ERRORS | FILES | SEE ALSO
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ecppio.h>
fd=open("/dev/ecpp0",flags);
The ecpp driver provides a bi-directional interface to IEEE 1284 compliant devices as well as a forward single-directional interface to Centronics devices. The ecpp driver supports the IEEE 1284 Compatibility, Nibble, and ECP protocols as well as the Centronic protocol. ECPP_COMPAT_MODE and ECPP_CENTRONICS modes of operation have logically identical handshaking protocols; however devices that support ECPP_COMPAT_MODE are IEEE 1284 compliant devices. IEEE 1284 compliant devices support at least ECPP_COMPAT_MODE and ECPP_NIBBLE_MODE. Centronics devices will support only ECPP_CENTRONICS mode.
By default, ECPP_COMPAT_MODE devices have a strobe handshaking pulse width of 500ns. For this mode, forward data transfers are conducted by DMA. By default, the strobe pulse width for ECPP_CENTRONICS devices is two microsecond. Forward transfers for these devices are managed through PIO. The default characteristics for both ECPP_COMPAT_MODE and ECPP_CENTRONICS devices may be changed through tunable variables defined in ecpp.conf. The ecpp driver is an exclusive-use device; if the device has already been opened, subsequent opens fail with EBUSY.
Each time the ecpp device is opened, the device is marked as EBUSY and the configuration variables are set to their default values. The write_timeout period is set to 90 seconds.
The driver sets the mode variable according to the following algorithm: The driver initially attempts to negotiate the device into ECP mode. If this fails, the driver will attempt to negotiate into Nibble mode. If Nibble mode negotiation fails, the driver will operate in Centronics mode. The application may attempt to negotiate the device into a specific mode or set the write_timeout values through the ECPPIOC_SETPARMS ioctl(2) call. For the negotiation to be successful, both the host workstation and the peripheral must support the requested mode.
For an IEEE 1284 compliant device, bi-directional ECP mode is the preferred mode of operation. Data transfers in the forward and reverse direction are DMA transfers. Handshaking with the peripheral is managed by the parallel port hardware. Consequently, ECP mode is highly efficient.
Nibble mode is a unidirectional backchannel mode. Under ECPP_NIBBLE_MODE, handshaking is controlled by software while data movement is managed by PIO.
Characteristics of the ecpp driver may be tuned by the variables described in /kernel/drv/ecpp.conf. These variables are read while the driver is being attached to the kernel. If the driver is currently attached, ecpp must be unloaded before the driver can be re-attached and the tuneable variables read again. See modunload (1M)
Some Centronics peripherals and certain IEEE 1284 compatible peripherals will not operate with the parallel port operating in a fast handshaking mode. If printing problems occur, set "fast-centronics" and "fast-1284-compatible" to "false." See /kernel/drv/ecpp.conf for more information.
The ecpp driver is a full duplex STREAMS device driver. While an application is writing to an IEEE 1284 compliant device, another thread may read from it.
A write(2) operation returns the number of bytes successfully written to the stream head. If a failure occurs while a Centronics device is transfering data, the content of the status bits will be captured at the time of the error, and can be retrieved by the application program, using the ECPPIOC_GETERR ioctl(2) call. The captured status information will be overwritten each time an attempted transfer or a ECPPIOC_TESTIO ioctl(2) occurs.
Intelligent IEEE 1284 compliant devices (such as Postscript printers) return error information through a backchannel. This data may be retrieved with the read(2) call.
If a failure or error condition occurs during a read(2), the number of bytes successfully read is returned (short read). When attempting to read the port that has no data currently available, read(2) returns 0 if O_NDELAY is set. If O_NONBLOCK is set, read(2) returns -1 and sets errno to EAGAIN. If O_NDELAY and O_NONBLOCK are clear, read(2) blocks until data become available.
The following ioctl(2) calls are supported:
Get current transfer parameters. The argument is a pointer to a struct ecpp_transfer_parms. See below for a description of the elements of this structure. If no parameters have been configured since the device was opened, the structure will be set to its default configuration. See Default Operation above for more information.
Set transfer parameters. The argument is a pointer to a struct ecpp_transfer_parms. If a parameter is out of range, EINVAL is returned. If the peripheral or host device cannot support the requested mode, EPROTONOSUPPORT is returned. See below for a description of ecpp_transfer_parms and its valid parameters.
The Transfer Parameters Structure is defined in <sys/ecppio.h>.
struct ecpp_transfer_parms { int write_timeout; int mode; };
The mode field reflects the IEEE 1284 mode to which the parallel port is currently configured. The mode may be set to only one of the following bit values.
#define ECPP_CENTRONICS 0x01 #define ECPP_COMPAT_MODE 0x02 #define ECPP_NIBBLE_MODE 0x04 #define ECPP_FAILURE_MODE 0x06
This command may set the mode value to ECPP_CENTRONICS, ECPP_COMPAT_MODE, or ECPP_NIBBLE_MODE. All other values are invalid. If the requested mode is not supported, ECPPIOC_SETPARMS will return EPROTONOSUPPORT. Under this circumstance, ECPPIOC_GETPARMS will return to its original mode. If a non-recoverable IEEE 1284 error occurs, the driver will be set to ECPP_FAILURE_MODE. For instance, if the port is not capable of returning to its original mode, ECPPIOC_GETPARMS will return ECPP_FAILURE_MODE.
Tests the transfer readiness of ECPP_CENTRONICS or ECPP_COMPAT_MODE devices. If the current mode of the port is ECPP_CENTRONICS or ECPP_COMPAT_MODE, this command determines if write(2) would succeed. If it is not one of these modes, EINVAL is returned. BPPIOC_TESTIO determines if a write(2) would succeed by checking the open flag and status pins. If any status pins are set, a transfer will fail. If a transfer succeeds, zero is returned. If a transfer fails, -1 is returned, and errno is set to EIO, and the state of the status pins is captured. The captured status can be retrieved using the BPPIOC_GETERR ioctl(2) call. The timeout_occurred and bus_error fields will never be set by this ioctl(2). BPPIOC_TESTIO and BPPIOC_GETERR are compatible to the ioctls specified in bpp(7D). However, bus_error is not used in this interface.
Get last error status.The argument is a pointer to a struct bpp_error_status. This structure is described below. This structure indicates the status of all the appropriate status bits at the time of the most recent error condition during a write() call, or the status of the bits at the most recent BPPIOC_TESTIO ioctl() call.
The timeout_occurred value is set when a timeout occurs during write(). bus_error is not used in this interface.
pin_status indicates possible error conditions under ECPP_CENTRONICS or ECPP_COMPAT_MODE. Under these modes, the state of the status pins will indicate the state of the device. For instance, many Centronics printers lower the nErr signal when a paper jam occurs. The behavior of the status pins depends on the device. As defined in the IEEE 1284 specification, status signals do not represent the error status of ECP devices. Error information is formatted by a printer specific protocol such as PostScript, and is returned through the backchannel.
The Error Status Structure struct bpp_error_status is defined in the include file <sys/bpp_io.h>. The valid bits for pin_status are shown below. A set bit indicates that the associated pin is asserted. For example, if BPP_ERR_ERR is set, nErr is asserted:
struct bpp_error_status { char timeout_occurred; /* 1=timeout */ char bus_error; /* not used */ uchar_t pin_status; /* status of pins which /* could cause error */ }; /* pin_status values */ #define BPP_ERR_ERR 0x01 /* nErr=0 */ #define BPP_SLCT_ERR 0x02 /* Select=1 */ #define BPP_PE_ERR 0x04 /* PE =1 */ #define BPP_BUSY_ERR 0x40 /* Busy = 1 */
The device is opened for write-only access and a read is attempted, or the device is opened for read-only access and a write is attempted.
The device has been opened and another open is attempted. An attempt has been made to unload the driver while one of the units is open.
A ECPPIOC_SETPARMS ioctl() is attempted with an out of range value in the ecpp_transfer_parms structure.
A ECPPIOC_SETREGS ioctl() is attempted with an invalid value in the ecpp_regs structure. An ioctl() is attempted with an invalid value in the command argument.
An invalid command argument is received from the vd driver during modload(1M), modunload(1M).
The driver encountered a bus error when attempting an access.
A read or write did not complete properly, due to a peripheral error or a transfer timeout.
The driver has received an open request for a unit for which the attach failed. The driver has received a write request for a unit which has an active peripheral error.
NAME | SYNOPSIS | DESCRIPTION | IOCTLS | ERRORS | FILES | SEE ALSO