Printing in the Solaris Environment: More Tips and Ideas
This collection of tips and ideas is
written for developers of printing solutions for the SolarisTM operating environment and is made up of two parts:
Contents
Solaris System Startup Processes
Solstice Enterprise Agents (SEA)
Parallel Communications
Packaging and Installation
Common Desktop Environment (CDE) Integration
Documentation Guidelines
Compiling Guidelines
Other Suggestions
Known Issues
Where to Find More Information
Appendix: Revised Man Page for the eccp Driver
This section describes what happens
when Solaris boots, which may be useful when developing processes
that need to start at system startup.
Startup Scripts
When Solaris boots, the system runs a
process named init(1M).
Init
uses the contents of the inittab(4)
and a variety of shell scripts to bring the system into and out of
various run-levels. At each run-level, scripts are run to perform
startup tasks. These scripts are located in /etc/rcX.d
where X
is the run-level the system is moving to. The startup scripts are
named /etc/rcX.d/SNN...
where NN
is a number from 00-99 and any trailing characters help identify
their functions. These scripts are run in lexical order, so S01f
would run before S02f.
For a more complete description, see the man pages init(1M)
and inittab(4).
LP Server Startup
When Solaris is entering run-level 2,
/etc/rc2.d/S80lp
is run. This script starts up the Solaris LP service daemon
lpsched(1M).
This daemon is at the core of the print server. It handles all local
print requests. If print job processing requires communication with
an external daemon or processing using some external resource that
needs initialization, the external resource should be started or
initialized before lpsched
is started. To do this, a startup script would be placed in
/etc/rc2.d/S[0-7][0-9]...
Example Scenario
As an example, when developing a
host-based Raster Image Processor (RIP) service that requires a daemon to run under LP, the
daemon needs to be started before lpsched.
A host-based RIP is a utility in which the input is a job (for
example, a PostScript file) that gets interpreted and converted into
some binary form specific to the target printer. If the host-based
RIP service daemon is ran after lpsched
was started, an unexplainable hang might occur if a print queue had a
print job ready to be processed while the system was booting. This
could occur if the host-based RIP service daemon opened and listened
for requests on a named pipe. If lp
were running before the host-based RIP service daemon, the request to
RIP the data could be lost, thus hanging the queue.
For example, if the host-based RIP
service daemon is started using a startup script (named, for example,
/etc/rc2.d/S82ripd),
the solution would be to move the host-based RIP service daemon to
start before the LP print system startup. Do this by naming the RIP
startup script to /etc/rc2.d/S79ripd.
This section contains tips on
Solstice Enterprise Agents (SEA). Solstice Enterprise
Agents are based on Simple Network Management Protocol (SNMP)
technology to provide an open, extensible standard to separately
manage different components and applications within a single device.
SNMP has been widely used to effectively manage network elements and
computer subsystem components in a monolithic framework. SEAs utilize
the concept of master agent and subagents to extend the SNMP
technology to manage various components within a single device.
Debugging
When debugging snmpdx,
check for messages that are syslogged in /var/adm/messages
or modify script /etc/init.d/init.snmpdx
so that snmpdx
runs with the -d 4
option.
Master Agents and Subagents
When a master agent receives
information from a subagent and then provides the subagent with
management of a Management Information Based (MIB) subtree,
registration has occurred between the master agent and the subagent.
A subtree is indicated by a single oid, an SNMP object
identifier. The oid prefix is a registration point that
identifies the Desktop Management Interface (DMI) component to the
master agent. The master agent cannot identify a subtree is without
an MIB specification.
The SNMP master agent handles SNMP
requests and responses between management applications and registered
Subagents in the system. The snmpd
executable file installed with SEA replaces any snmpd
file that is already installed in the system.
The SNMP Master Agent communicates with
Subagents in the system through SNMP PDUs. A process acting as a
Subagent may register an MIB subtree with the SNMP agent. Any request
received by the Master Agent for a registered variable is passed
through snmpdXdmid
to the Subagent, which then performs the request and returns a
response to the Master Agent.
Known Issues
The
snmpdx has been observed to die without understood
cause. The problem may be the way the subagent responds or does not
respond to snmpdx
in a particular situation. When snmpdx
passes an oid to a subagent that it does not recognize, the
agent should at least respond with the noSuchName
PDU.
snmpdx
passes an oid to the wrong subagent. This would be an oid
that does not belong to the subagents tree and does not fall
under the subagent's purview.
snmpdx
dies, possibly because the subagent is not responding or because of
an unexpected response from the subagent.
Note: The SEA team is interested in fixing this problem but does not have a reproducible test case to further investigate the problem. If you observe any of the problems described above, call SunService at 1-800-USA-4SUN to provide details on replicating the problem.
IEEE 1284-1994 Bidirectional Parallel Communication (ECPP)
The parallel communication released on
PCI-based SPARCTM Ultras (for example, Ultra 5, 10, 30,
60, 450, and so on) is IEEE 1284-1994 compliant and requires an IEEE
1284-1994 compliant cable. The parallel port driver that supports
this standard is called ecpp.
Required Patches
An ecpp
patch is required for Solaris 2.5.1 and Solaris 2.6 releases in order
for the parallel port of a SunTM PCI-based sun4u
hardware to work. The latest revision for the respective Solaris OS
should be used. The patch IDs are as follows:
- 104605 (Solaris 2.5.1)
- 105741 (Solaris 2.6)
In addition, the ecpp
patch for Solaris 2.5.1 and Solaris 2.6 depends on the latest lp
patch. The respective patch IDs are:
- 103959 (Solaris 2.5.1)
- 106235 (Solaris 2.6)
If there are problems using the
parallel port on a Sun PCI-based sun4u
hardware installed with Solaris 7, there is an optional ecpp
patch. The latest version should be used. The patch ID is:
nInit Signal
As of patch #104605-06 (Solaris 2.5.1),
patch #105741-03 (Solaris 2.6), and the Solaris 7 and Solaris 8
releases, the open
function for the ecpp
driver no longer makes an nInit
call due to conflicts with some printers. If an nInit
call is required for a particular printer, the respective vendor will
be required to make this call in their printer driver. The nInit
signal is not available in a public interface but is available in the
"consolidation private" interface.
Example
The example below shows how to use the
nInit
signal. With this code, an application can toggle the outpins (reset
the printer by toggling the nInit
signal).
/* Change to DIAG_MODE in order to write to
* control register. The SuperIO chip is put
* into PIO mode in DIAG_MODE.
*/
tp.write_timeout = 90;
tp.mode = ECPP_DIAG_MODE;
if (ioctl(ecpp_fd,ECPPIOC_SETPARMS, &tp) < 0) {
printf("1:SETPARMS failed.n");
perror("SETPARMS:");
close(ecpp_fd);
return;
}
else
printf("ECPPIOC_SETPARMS ok. mode=%x, timeout=%dn",
tp.mode, tp.write_timeout);
/* toggle the ninit signal */
if (ioctl(ecpp_fd,ecppioc_getregs, ®s) < 0) {
printf("GETREGS failed.n");
perror("GETREGS:");
close(ecpp_fd);
return;
}
else
printf("ECPPIOC_GETREGS ok: dcr=%x, dsr=%xn",
regs.dcr, regs.dsr);
orig_dcr = regs.dcr;
regs.dcr = orig_dcr & ~ecpp_ninit;
if (ioctl(ecpp_fd,ecppioc_setregs, ®s) < 0) {
printf("1:SETREGS failed.n");
perror("SETREGS:");
close(ecpp_fd);
return;
}
else
printf("1:ECPPIOC_SETREGS ok.n");
regs.dcr = orig_dcr | ecpp_ninit;
if (ioctl(ecpp_fd,ecppioc_setregs, ®s) < 0) {
printf("2:SETREGS failed.n");
perror("SETREGS:");
close(ecpp_fd); return;
}
else
printf("2:ECPPIOC_SETREGS ok.n");
/* set the port back into the desired mode.
* if it is desired to operate the device in nibble
* mode, the device should be set to ecpp_compat_mode or
* nibble_mode. if desired to run the device in the
* old centronics mode, the port should be set to
* ecpp_centronics.
*/
tp.write_timeout = 90;
tp.mode = ECPP_CENTRONICS;
if (ioctl(ecpp_fd,ECPPIOC_SETPARMS, &tp) < 0) {
printf("2:SETPARMS failed.n");
perror("SETPARMS:");
close(ecpp_fd);
return;
}
else
printf("ECPPIOC_SETPARMS ok. mode=%x, timeout=%dn",
tp.mode, tp.write_timeout);
Testing the Port Driver
The following command purely tests the
parallel port driver:
% cat /etc/motd > /dev/ecpp0
Flow Diagram
The ecpp
driver is a data streams driver (as opposed to a character driver
like the bpp
Centronics driver). Data streams are asynchronous; whereas,
characters are synchronous. In asynchronous, a call may return before
data is actually transferred; in synchronous, the call returns after
data is transferred.
The flow of write
for the ecpp
driver is as follows:
Support for ECPP Modes
The following lists the various ecpp
modes and status of their support in Suns ecpp
driver:
Modes
Backchannel
Status*
->
ECP_COMPAT
<-
ECP_NIBBLE
supported
->
Centronics
supported
<->
ECP
N/A
not supported
<->
EPP
not supported
<-
Byte mode
not supported
* As of the first release of Solaris 8
Corrected Man Page
A corrected version of the man page for
ecpp
is included in Appendix: Revised Man Page for eccp Driver.
Centronics Parallel Communication (BPP)
Parallel communication on legacy Sun
platforms (for example, sun4c,
sun4m,
sun4d,
and non-PCI based sun4u)
and on the add-on S-bus parallel interface card, took place through
the Centronics Parallel Communication. The parallel port driver that
supports the Centronics Parallel Communication is bpp.
Known Issues
The following are known issues with the
legacy platform and bpp
driver.
Some older SPARCstation 20 models
have a defective built-in parallel port that requires either a
motherboard replacement or use of an Sbus card in place of its
built-in parallel port. This is fixed by upgrading to the SS20
motherboard 500-2324-11 or higher. ECO WO_07914 implemented the
changes.
A bug exists with
BPPIOC_GETOUTPINS.
Instead of returning values that reflect the actual parallel port
signals, BPPIOC_GETOUTPINS
reflects the last request. The workaround is to call
BPPIOC_GETOUTPINS
twice, discarding the first value returned. The internal Sun BUGID
is 4061814.
This section contains tips on building
an application package. Application Packaging is the vehicle Solaris
uses for delivering application software. Packaging used with Solaris
is compliant with the System V Application Binary Interface. Details
and examples of Application Packaging can be found in the online
documentation.
Installation Scripts
By default, the pkgadd
command automatically performs all the actions necessary to install a
package using the package information files as input. However, there
are many instances where a product requires more than just having
files copied from source to target disk. As part of the installation,
a product might require some user input or perform some action at a
particular phase of the installation. Application Packaging in
Solaris allows for this customization through the use of installation
scripts. There are four types of installation scripts:
The Request script, which
requests input from the user.
The Checkinstall script,
which performs special file system verification. It can exit in one
of four ways, one of which is successful installation. It is
available beginning with Solaris 2.5. For releases earlier than
Solaris 2.4, a request script would be used to test the file system.
Procedure scripts, which
define actions that occur at particular points during package
installation and removal. There are four procedure scripts that can
be created and are predefined: preinstall, postinstall,
preremove, and postremove. Details of these can be
found in the online documentation.
Class Action scripts, which
define a set of actions to be performed on a group of objects at
installation or removal. Files in a package may be grouped by some
common relationship such as by function (for example, SNMP, MarkNet,
and so on.) and are assigned to a class in the prototype file. A
series of actions as defined in a class action script may be
performed on a class. The following is an example of a prototype
file with class assignment for startup:
f
stuff/etc/init.d/lxphan
l start/etc/rc2.d/S79Lxphan =
../init.d/Lxphan
Installation Location
BASE_DIR,
the location of the base installation, cannot be changed or
reassigned in Solaris 2.4 packaging, but can be beginning with
Solaris 2.5. BASE_DIR
should reflect the installation location specified by the end-user if
the default location is not used.
Patch Releases
Maintenance updates that are to include
only a partial package release should follow the patch release method
detailed in the Advanced Package Creation Techniques chapter of the
Application Packaging Developer's Guide, available at
http://docs.sun.com.
The Common Desktop Environment (CDE) is
the desktop migration path for the Solaris platform. All software
packages for the Solaris platform are expected to integrate well with
the CDE. This section highlights items to help ease the integration
with CDE.
Use dtappintegrate
to integrate components into the CDE. This interface will register an
application at the top level of the Application Manager. A
command-line option exists to reverse the process.
Further details are available in the
online documentation.
This section provides some guidelines
for documentation that developers provide to end-users.
BUGIDs and Patch Numbers
Sun BUGIDs are not to be listed in
third-party documentation. The corresponding patch numbers
should be listed instead. The patch number should include the
earliest revision number for which the fix is available. For example,
if the patch number is 123456 and the required fix is in revision 7,
the documentation should list patch number 123456-07 or later
as a requirement. Patches are to be obtained through Sun Service (at
1-800-USA-4SUN in the U.S.) and are not to be included on third-party
media.
Man Pages
Any interface that is considered public
should have a man page describing its use. Man pages should be placed
in a man
subdirectory of the directory in which the application is installed.
To access the man pages in the subdirectory, use:
man -M<path to manpage subdirectory>.
This section provides information for
use with the cc
compiler.
- Compiler flags for multithreading:
-xparallel
-xautopar
- When using network host database
functions such as
endhostent,
gethostbyaddr,
gethostbyname,
gethostent,
and sethostent,
the library to use is -lxnet
(beginning with Solaris 2.6) and -lnsl
(for releases before Solaris 2.6).
- To ensure that a software package
can survive in future Solaris platforms, the code must be
dynamically linked (that is, not statically linked). To be fully
dynamically-linked,
-Bstatic
and -dn
flags must not be used.
- You must use
truss
to trace system calls and signals. Starting
with the Solaris 8 release, truss
can be used not only to trace systems calls and signals, but also to
trace Solaris library calls. Using the -u
flag, truss
will trace anything in the user space.
This section documents various other
useful information.
- The most current version of the
documentation for the latest Solaris OS release is available online
at:
http://docs.sun.com.
- Ideally, there should be no
dependency on commands in
/usr/ucb/.
SUNWscpu
is not automatically installed on every system.
- Use
poll(2)
and select(3C)
to block stdin.
- To make processes immune from
SIGHUP,
use nohup.
For details, see the man pages.
- Solaris ABI (Application Binary
Interface) Tool is recommended to test binary compatibility of your
application on new Solaris releases. The
appcert
tool checks the application's compatibility with the Solaris
operating environment. Details about the tool and its availability can be found at: Solaris
ABI Tools - Appcert Tool
- Starting with the Solaris 8
release, the Solaris ABI Tools includes
apptrace,
which only traces Solaris library calls made from an application.
This section lists known problems that
are yet to be addressed by Sun. Because there is a workaround for
these problems, they are not a priority.
- There is a shell bug that pings
the CPU at 100% in OpenWindows and kills the shell windows when run
in CDE. The Sun BUGID is 40069899, which includes a sample program
that describes this problem.
- There is a blocking issue using
named pipes with
select()
and poll().
The Sun BUGID is 1148050 and has been closed. A workaround would be
to open a dummy file descriptor (fd)
on the pipe as O_WRONLY
so there is always a writer for the pipe.
Where to Find More Information
The Printer Working Group web
site, at http://www.pwg.org/,
contains information on:
- The Printer MIB Working Group
- Internet Printing Protocol (IPP)
- The Job Monitoring Project (JMP)
- Universal Printer Description
Files (UPDFs)
- The working group developing
printing over the IEEE-1394 High Speed Serial Bus
The IEEE Standards Association
site, at http://standards.ieee.org/,
contains information on all IEEE standards.
The IEEE-1284 site at
http://www.fapo.com/ieee1284.htm,
sponsored by Warp Nine Engineering, deals with the IEEE-1284 parallel
port.
The site of the USB Implementors
Forum, http://www.usb.org,
includes approved USB Device Class Specification documents
(http://www.usb.org/developers/docs/).
The 1394 Trade Association site,
at http://www.1394ta.org/,
provides further information about the IEEE-1394 High Speed Serial
Bus (FireWire) standard.
For information on the Common UNIX
Printing System (CUPS), see http://www.cups.org/.
CUPS is based on the Internet Printing Protocol (IETF-IPP), and
supports network browsing and PostScript Printer Descriptions (PPDs).
The site includes a customized version of GhostScript and an image
file RIP for non-PostScript printers.
For information on printing with
Jini, subscribe to the jini-printing forum
at www.jini.org.
Appendix: Revised Man Page for the eccp Driver
ecpp(7)
NAME
ecpp - IEEE 1284 ecp, nibble and centronics compatible
parallel port driver
SYNOPSIS
#include <sys/types.h>
#include <fcntl.h>
#include <sys/ecppio.h>
fd = open("/dev/ecpp0", flags);
DESCRIPTION
The ecpp driver provides a bi-directional interface to IEEE
1284 compliant devices. The driver will operate in Centron-
ics mode for non-IEEE 1284 compliant devices. An IEEE 1284
compliant peripheral device must operate at least in Compa-
tibility mode and Nibble mode. The ecpp driver supports
Compatibility, Nibble and ECP modes of operation as defined
by IEEE 1284. Centronics and Compatibility modes of opera-
tion have identical physical characteristics. However,
non-IEEE 1284 compliant devices will be logically defined as
ECPP_CENTRONICS. IEEE 1284 devices that are in a similar
mode will be logically defined as ECPP_COMPAT_MODE.
ECPP_COMPAT_MODE operates in conjunction with
ECPP_NIBBLE_MODE. The ecpp driver is an exclusive-use dev-
ice. If the device has already been opened, subsequent
opens fail with EBUSY.
Default Operation
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 60
seconds. The driver sets the mode variable according to the
following algorithm: The driver initially attempts to nego-
tiate the device into ECP mode. If this should fail, the
driver will attempt to negotiate into Nibble mode. If Nib-
ble mode negotiation should fail, 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. In order
for the negotiation to be successful, both the host worksta-
tion and the peripheral must support the requested mode.
The preferred mode of operation of an IEEE 1284 device is
the bi-directional ECP mode. Nibble mode is a unidirec-
tional backchannel mode. It utilizes a PIO method of
transfer and consequently, is inefficient. For devices that
primarly receive data from the workstation, such as
printers, Nibble operation will have limited impact to sys-
tem performance. Nibble mode should not be used for devices
such as a scanner, that primarily send data to the worksta-
tion. Forward transfers under all modes are conducted
through a DMA method of transfer.
Read/Write Operation
ecpp is a full duplex STREAMS device driver. While an
application is writing to an IEEE 1284 compliant device,
another thread may read from it. write(2) will return when
all the data has been successfully transferred to the device.
Write Operation
write(2) returns the number of bytes successfully written to
the stream head. If a failure occurs while a Centronics dev-
ice 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.
Read Operation
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.
IOCTLS
The following ioctl(2) calls are supported:
ECPPIOC_GETPARMS
Get current transfer parameters.
The argument is a pointer to a struct
ecpp_transfer_parms. See below for a descrip-
tion of the elements of this structure. If no
parameters have been configured since the dev-
ice was opened, the structure will be set to
its default configuration. (see Default Opera-
tion above).
ECPPIOC_SETPARMS
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 can not support the requested mode,
EPROTONOSUPPORT is returned. See below for a
description of ecpp_transfer_parms and its
valid parameters.
Transfer Parameters Structure
This structure is defined in <sys/ecppio.h>.
struct ecpp_transfer_parms {
int write_timeout;
int mode;
};
The write_timeout field is set to
ECPP_W_TIMEOUT_DEFAULT. The write_timeout field
specifies how long the driver will wait for the
peripheral to respond to a transfer request.
The value must be greater than 0 and less than
ECPP_MAX_TIMEOUT. Any other values are out of
range.
The mode field reflects the IEEE 1284 mode that
the parallel port is currently configured to.
The mode may be set to only one of the follow-
ing bit values.
#define ECPP_CENTRONICS 0x1
#define ECPP_COMPAT_MODE 0x2
#define ECPP_NIBBLE_MODE 0x3
#define ECPP_ECP_MODE 0x4
#define ECPP_FAILURE_MODE 0x5
/************* CONSOLIDATION PRIVATE ***
#define ECPP_DIAG_MODE 0x6
*****************************************/
This command may set the mode value to
ECPP_CENTRONICS, ECPP_COMPAT_MODE,
ECPP_NIBBLE_MODE, or ECPP_ECP_MODE. All other
values are not valid. If the requested mode is
not supported, ECPPIOC_SETPARMS will return
EPROTONOSUPPORT. Under this circumstance,
ECPPIOC_GETPARMS will return to its orignal
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 orignal
mode, ECPPIOC_GETPARMS will return
ECPP_FAILURE_MODE.
/************* CONSOLIDATION PRIVATE ***
To change the parallel port characteristics to
one of the diagnostic characteristics, the mode
must be first set to ECPP_DIAG_MODE. Once
ECPPIOC_SETPARMS sets the driver into
ECPP_DIAG_MODE, port_type will default to
ECPP_PORT_PIO (see TRANSFER METHOD below).
Afterwards, applications may call
ECPPIOC_SETPORT to change the port type to
ECPP_PORT_TDMA.
*****************************************/
BPPIOC_TESTIO
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 of the status pins
are set, a transfer would fail. If a transfer
would succeed, zero is returned. If a transfer
would fail, -1 is returned, and errno is set to
EIO , and the state of the status pins is cap-
tured. The captured status can be retrieved
using the BPPIOC_GETERR ioctl (2) call. Note
that 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(7). However,
bus_error is not used in this interface.
BPPIOC_GETERR
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(2) call, or the status of the bits at the
most recent BPPIOC_TESTIO ioctl(2) call.
The timeout_occurred value is set when a
timeout occurs during write(2). 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 Specifica-
tion, 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.
Error Status Structure
struct bpp_error_status is defined in the
include file <sys/bpp_io.h>. The valid bits
for pin_status are presented 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 */
u_char 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 */
/************* CONSOLIDATION PRIVATE ***
TRANSFER METHOD
Under default operation, the driver conducts
I/O through a highly efficient DMA method.
However, the ecpp driver provides an interface
to change the method the device transfers data.
The device may be configured to transport data
under direct PIO control. In addition, ecpp
may be configured to test the DMA hardware.
The PIO interface allows applications to
directly program the parallel port pins.
Although this is an extremely slow transfer
method, an application may control the data
handshaking through the ECPPIOC_GETREGS and
ECPPIOC_SETREGS commands. The DMA hardware may
be tested by conducting DMA transfers from
memory to the parallel port FIFO. Under this
port type, data does not leave the FIFO.
An application changes the port transfer method
by invoking the ECPPIOC_SETPORT command. How-
ever, before this command (or ECPPIOC_GETPORT )
is called, the application must call
ECPPIOC_SETPARMS to set the mode to
ECPP_DIAG_MODE. Upon changing the mode back to
a non-ECPP_DIAG_MODE such as ECPP_CENTRONICS,
the port will default to operating under DMA
characteristics.
If port_type is set to ECPP_PORT_TDMA, forward
transfers may be conducted through
ECPPIOC_SETDATA or write(2). ECPPIOC_SETDATA
will directly PIO transfer a byte to the parallel
port FIFO. write(2) will DMA transfer the
buffer to the FIFO.
If port_type is ECPP_PORT_PIO, ECPPIOC_SETDATA
sends data to the data pins. Under this
transfer method, ECPPIOC_GETTDATA retrieves
data from the data pins. Handshaking with the
peripheral device must be conducted through
ECPPIOC_GETREGS and ECPPIOC_SETREGS.
The ioctl(2) commands and their corresponding
values discussed in the TRANSFER METHOD section
of this manpage are defined in ecppdiag.h.
ECPPIOC_GETPORT
Gets ecpp port_type value.
The argument is a pointer to a u_char port_type
variable. port_type returns the current
transfer method the driver is set to. If ecpp
is not in ECPP_DIAG_MODE, EINVAL is returned.
See below for a description of port_type and
its valid parameters.
ECPPIOC_SETPORT
Sets ecpp port_type values.
The argument is a pointer to a u_char port_type
variable. If driver is not in ECPP_DIAG_MODE,
or if the parameter is out of range EINVAL is
returned. See below for a description of
port_type and its valid parameters.
/* port types */
#define ECPP_PORT_PIO 0x2
#define ECPP_PORT_TDMA 0x3 /* test fifo */
ECPPIOC_SETDATA
Sets data pins.
The argument is a u_char data value. If the
port_type is ECPP_PORT_PIO, this command sets
the data pins to the data value. If ecpp is not
in ECPP_DIAG_MODE, this command will return
EINVAL.
If the port_type is ECPP_PORT_TDMA,
ECPPIOC_SETDATA will write directly to the top
byte of the FIFO under a PIO transfer. Under
ECPP_PORT_TDMA, bytes may be directly written
to the FIFO through write(2).
ECPPIOC_GETDATA
Reads data pins.
The argument is a u_char data value. If the
port_type is ECPP_PORT_PIO, data returns the
current value in the data pins. If ecpp is not
in ECPP_DIAG_MODE, this command will return
EINVAL.
If the port_type is ECPP_PORT_TDMA, data
returns the first byte available in the FIFO.
The following ioctls are used to directly read and write
the parallel port input and output pins.
ECPPIOC_GETREGS
Read register values.
The argument is a pointer to a struct
ecpp_regs. See below for a description of this
structure.
ECPPIOC_SETREGS
Set ecpp register values.
The argument is a pointer to a struct
ecpp_regs. See below for a description of thi
structure. If a parameter is out of range,
EINVAL is returned.
Port Register Structure
This structure is defined in <sys/ecppio.h>.
struct ecpp_regs {
u_char dsr; /* status reg */
u_char dcr; /* control reg */
};
The status (dsr) register is READ-ONLY. The
ECPPIOC_SETREGS ioctl has no affect on this
register. Bits 0, 1 and 2 of the dsr are
reserved and will always return 1.
/* Values for dsr field */
#define ECPP_nERR 0x08
#define ECPP_SLCT 0x10
#define ECPP_PE 0x20
#define ECPP_nACK 0x40
#define ECPP_nBUSY 0x80
The control resister (dcr) is read/write. Bits
4, 5, 6, & 7 of the dcr are reserved. While
writing to this register, bits 4-7 must be 1.
Reading these bits will always return 1. An
attempt to write 0s into bits 4-7 will result
in EINVAL.
/* Values for the dcr field */
#define ECPP_STB 0x01
#define ECPP_AFX 0x02
#define ECPP_nINIT 0x04
#define ECPP_SLCTIN 0x08
*****************************************/
ERRORS
EBADF 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.
EBUSY 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.
EINVAL 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 a
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).
EIO The driver encountered a bus error when attempting
an access.
A read or write does not complete properly, due to
a peripheral error or a transfer timeout.
ENXIO 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.
FILES
/dev/ecpp0 1284 compatible and ecp mode parallel
port device
SEE ALSO
ioctl(2), read(2), write(2) streamio(7)
June 2000