man ptal-mlcd (Administration système) - hpoj reference: CWptal-mlcd
NAME
hpoj reference: CWptal-mlcd
SYNOPSIS
ptal-mlcd [mlc:]bus:name [options...]
DESCRIPTION
The CWptal-mlcd daemon implements the HP MLC (Multiple Logical Channels) and IEEE 1284.4 packetized transport protocols over parallel ports and USB, and enables access to the various MLC/1284.4 services on the device, such as print, scan, and PML. Applications use the PTAL frontend API to access local or remote devices, and CWlibptal accesses locally-connected devices controlled by CWptal-mlcd through the use of Unix-domain sockets, which, unlike TCP/IP sockets, are not accessible across a network. Currently, CWptal-mlcd performs parallel-port I/O by accessing the hardware registers and performing the IEEE 1284 ECP- and nibble-mode signalling directly from user mode, with no kernel assistance. In most cases it now makes use of bounded ECP mode and hardware assistance for faster ECP transfers, by writing/reading bytes to/from the ECP FIFO registers. However, it doesn't make use of hardware interrupts or DMA, given that it runs in user mode. On the other hand, CWptal-mlcd's USB support depends on CWlibusb and/or the Linux kernel USB printer-class driver (CWprinter.o). CWlibusb is required in order to access all device functions on certain composite USB models and to work around SMP issues in CWprinter.o, but otherwise the two methods should work equally well. See the hpoj Supported Devices page for more information about requirements for different models.
OPTIONS
- •
- CWCIbusCW is the connection type and is one of:
- •
- CWpar Parallel port
- •
- CWusb Universal Serial Bus
- •
- CWCInameCW is the desired name or number suffix for this device
- •
- Common CWCIoptionsCW for all CWCIbusCW types:
- •
- CW-devidmatch CIstringCW Matches portion of device ID string, such as the model or serial-number fields to uniquely identify a device
- •
- CW-remconsole Enables remote debug console (service name CWPTAL-MLCD-CONSOLE, socket -1), also makes log message output less susceptible to data loss but slightly more susceptible to deadlocks
- •
- Less common CWCIoptionsCW for all CWCIbusCW types:
- •
- CW-nofork Stays in the foreground, enables local console
- •
- CW-nodrain Disables channel-78 reset and reverse data drain in case they cause a problem
- •
- CW-forcemlcdot4 Forces both 1284.4 and MLC modes to be tried
- •
- CW-nodot4 or CW-nomlc Disables 1284.4 or MLC mode individually (Caution: Don't disable both, because raw mode currently does not work very well.)
- •
- CW-nopml Disables PML multiplexing
- •
- CW-nolog, CW-logwarn, CW-log Sets logging level (default=CW-nolog)
- •
- Valid CWCIoptionsCW for CWpar:
- •
- CW-base 0xCIADDRCW I/O port base address (default is CW0x378)
- •
- CW-basehigh 0xCIADDRCW ECP high base address (default is CWCIbaseCW+0x400, must be specified after CW-base)
- •
- CW-device CI/dev/lp0CW Path and filename of corresponding device node, used to lock the port and prevent interference from other processes
- •
- CW-porttype CIporttypeCW Overrides port-type detection, one of:
- •
- CWspp Standard (unidirectional) parallel port
- •
- CWbpp Bidirectional (PS/2, not ECP) parallel port
- •
- CWecp Extended Capabilities Port with no hardware assistance
- •
- CWecphw Extended Capabilities Port with hardware assistance
- •
- CWecphwfwd Extended Capabilities Port with hardware assistance in the forward direction only
- •
- CWecphwrev Extended Capabilities Port with hardware assistance in the reverse direction only
- •
- CW-nobecp Prevents bounded ECP mode from being used
- •
- CW-forcebecp Forces bounded ECP mode to be used
- •
- Valid CWCIoptionsCW for CWusb:
- •
- CW-device "CI/dev/usb/lp*CW"... Path and filename of Linux CWprinter.o device node(s) (it's OK to have multiple device nodes and/or wildcards, preferably not expanded by the shell)
- •
- CW-device %CIbusCW%CIdeviceCW CWlibusb bus and device names/numbers
- •
- CW-vpidmatch 0xCIVVVVPPPPCW Matches USB vendor and product ID instead of CW-devidmatch
- •
- CW-nocomp Disables composite-USB support (FF/D4/00 or FF/FF/FF MLC/1284.4 interface)
- •
- CW-nocompprint Disables composite-USB raw print interface (7/1/2) and always tries to print over (possibly composite) MLC/1284.4 interface
- •
- CW-forcecomp Enables extra composite-USB support (FF/FF/FF MLC/1284.4 interface) that would not normally be used in most cases
- •
- CW-noglobusb Disables implicit libusb device globbing
- •
- CW-nochannelchange Disables HP USB channel change request whenever possible
NOTES
CWptal-mlcd and CWptal-printd are typically called by CWptal-init, and it's generally unnecessary to invoke them manually from the command line except for development or debugging purposes. A CWptal-mlcd process exists in one of several overall states. When startup is complete, it is in the inactive state. When an application tries to access the device, CWptal-mlcd starts to activate, or in other words, establish an MLC/1284.4 communication session with the device. Once that is complete, CWptal-mlcd is in the active state. If a communication error happens, which could be the result of a power-off or disconnection of the device or a protocol error, CWptal-mlcd deactivates, which includes closing all active application sessions and returning to the inactive state. For each CWptal-mlcd instance, there is a main process that services application requests and implements the MLC/1284.4 protocols. When CWptal-mlcd activates as described above, it forks a sub-process which handles low-level I/O to/from the device and passes data to/from the main process using anonymous pipes. In addition, when operating in composite USB mode, it forks a separate sub-process to service application connections to the raw 7/1/2 print interface outside of the MLC/1284.4 session; this sub-process exits when the application closes the connection or when CWptal-mlcd deactivates. CWptal-mlcd special-cases the PML (Peripheral Management Language) service on the device, by keeping open a single PML channel while activated, virtualizing application requests to open the PML service, and multiplexing PML requests (gets and sets but not yet traps) from possibly multiple applications over a single PML session with the device. On the other hand, if you specify the CW-nopml switch, then this behavior is disabled, and only one application may open PML at a time but has exclusive access to the device's PML service. Parallel-specific notes The typical invocation for CWptal-mlcd on parallel, set up automatically by "CWptal-init setup", is something like the following (split into multiple lines for clarity):
ptal-mlcd mlc:par:OfficeJet_K80 [-remconsole] \ -devidmatch "MDL:OfficeJet K80; \ -devidmatch SERN:000000000010;" \ -base 0x378 -basehigh 0x778 -device /dev/lp0
Specifying the CW-device switch is recommended if your system has kernel parallel-port support, because it gives CWptal-mlcd a mechanism to lock the parallel port and prevent other processes from opening it and interfering with its signalling. Just make sure you specify the right device node, or it won't do any good. Also, unlike for USB, do not specify multiple device nodes, including using wildcards. In order to take advantage of CWptal-mlcd's new hardware-assisted parallel-port I/O, you must configure your parallel port to ECP in your BIOS setup. USB-specific notes The typical invocation for CWptal-mlcd on USB, set up automatically by "CWptal-init setup", is something like the following (split into multiple lines for clarity):
ptal-mlcd mlc:usb:OfficeJet_K80 [-remconsole] \ -devidmatch "MDL:OfficeJet K80; \ -devidmatch SERN:000000000010; \ -device /dev/usb/lp*"
This means that whenever CWptal-mlcd tries to activate, it will open up each USB printer device node in turn (including the implicitly-globbed CWlibusb devices), search the device ID string for the specified string(s) (normally the model field and possibly also the serial number field), and use the first matching device it finds. Alternatively, if you only have one USB-connected printer device, you can use a simpler command line such as the following:
ptal-mlcd mlc:usb:0 -device /dev/usb/lp0 -noglobusb [-remconsole]
CW-noglobusb is required in this case to prevent the implicit globbing of CWlibusb devices and guarantee that you'll really get the device you want. This usage is not recommended, however, because if you add another USB printer, you'll find that the CW/dev/usb/lpCI0CW device node assignment may change over time, depending on what order the devices are connected and powered on. Even if you have multiple USB printers with only one connected and powered on at a time, having a separate instance of the daemons for each model makes it easier to have different print queues/drivers and scanning profiles set up for the different devices as needed. Raw printing directly to the 7/1/2 print interface (on a composite-USB device) is very slow if done through CWlibusb instead of Linux CWprinter.o. CWlibusb and/or Linux CWusbdevfs don't indicate how many bytes were successfully transferred at a timeout condition, which can happen if the printer is busy or out of paper. Therefore, this communication path had to be reduced to sending only one runt USB packet (63 or 31 bytes) at a time, to prevent data corruption when recovering from timeout conditions. User interface CWptal-mlcd includes the following user-interface features:
- •
- Special virtual services
- •
- Log messages to standard output and syslog (CW/var/log/messsages)
- •
- A debug console
CWptal-mlcd supports the following virtual services through CWptal-connect:
- •
- CWPTAL-MLCD-CONSOLE The debug console, if enabled with the CW-remconsole switch
- •
- CWPTAL-MLCD-PID The main process ID of this instance of CWptal-mlcd
- •
- CWPTAL-MLCD-CMDLINE The command line passed to this instance of CWptal-mlcd
- •
- CWPTAL-MLCD-DEVNODE The device node, if any, in use by this instance of CWptal-mlcd
- •
- CWPTAL-MLCD-DUMP A dump of the current state of most internal data structures (useful for debugging)
- •
- CWPTAL-MLCD-GLOB-DEVNODES Used by "CWptal-init setup" to glob standard and CWlibusb device nodes (CWptal-mlcd must be in a deactivated state)
CWptal-mlcd logs various kinds of messages to standard output (which may not be visible unless started in a particular terminal window) and syslog (CW/var/log/messsages):
- •
- CWFATAL ERROR An internal error bad enough to cause CWptal-mlcd to exit. Normal behavior if a startup error (such as command-line syntax error or problem setting up socket) occurred. Otherwise, should never happen. If it does, especially if it's preceeded by a large data-structure dump, then please report the problem to the CWhpoj-devel mailing list.
- •
- CWERROR An error, such as a loss of communication with the device, which is (hopefully) recoverable without exiting. Probably not a bug, with the exception of an CWfdRegister error, which should be reported to the CWhpoj-devel mailing list.
- •
- CWWARNING An unusual situation that could potentially indicate a problem, but which is (hopefully) immediately recoverable with no adverse effect.
- •
- CWSYSLOG An information message by default logged only to syslog, not standard output, indicating successful startup or activation.
- •
- CWENTRY, CWEXIT, CWINFO Debug messages.
Here is a sample log message followed by an explanation of the components:
ptal-mlcd: ERROR at ExMgr.cpp:871, dev=<mlc:usb:OfficeJet_K80@/dev/usb/lp0>, pid=17306, e=19 t=1064276197 exClose(reason=0x0010)
- •
- CWERROR indicates the severity (see above for the possibilities).
- •
- CWExMgr.cpp:871 indicates the source-code file and line number where the message was logged. Useful for debugging.
- •
- CWdev=<mlc:usb:OfficeJet_K80@/dev/usb/lp0> indicates the device name controlled by the CWptal-mlcd instance that logged the message as well as the device node (if one is currently open). In contrast, this might look like CWdev=<mlc:usb:OfficeJet_K80@%001%006> if the device was being accessed through CWlibusb.
- •
- CWpid=17306 indicates the process ID that logged the message.
- •
- CWe=10 indicates the current value of the CWerrno variable, probably irrelevant unless it's an error message complaining about a failed system call.
- •
- CWt=1064276197 is a timestamp of when this message was logged, in the form of number of seconds since the beginning of the Unix epoch (January 1, 1970).
- •
- CWexClose(reason=0x0010) is the specific message with parameter substitution as appropriate. Some log messages, especially some fatal errors that should never happen (but occasionally they do:-) don't even have a customized second-line message.
CWptal-mlcd's debug console is accessible in either of the following ways:
- •
- Invoke CWptal-mlcd with the CW-remconsole switch, to enable the remote console capability. Issue a command such as: ptal-connect mlc:usb:OfficeJet_G85 -service PTAL-MLCD-CONSOLE This will steal the console away from standard output or from another connection to this same service. Press Control-C or Control-D to exit CWptal-connect and return the console back to standard output (and no standard input).
- •
- Invoke CWptal-mlcd with the CW-nofork switch, to prevent CWptal-mlcd from forking itself into the background and start up the local console. Press Control-C to kill CWptal-mlcd and return to the command prompt.
When the debug console is active, the following commands may be used:
- •
- CWdump Dumps all data structures.
- •
- CWpid Prints the current main process ID.
- •
- CWactivate Starts activation if not active. Prints return code of CWexActivate(), which may be 0 if already active, 1 if started (and probably finished) activating, and -1 if an error occurred.
- •
- CWdeactivate Deactivates by calling CWexClose(), which always logs an error message.
- •
- CWlog Enables all log messages, including debug messages.
- •
- CWlogwarn Enables log messages other than debug messages (CWENTRY, CWEXIT, and CWINFO).
- •
- CWnolog Returns to the default log level of logging CWERROR and "CWFATAL ERROR" to standard output and syslog and CWSYSLOG to syslog but not standard output.
File-system usage CWptal-mlcd creates Unix-domain sockets in the directory CW/var/run/ptal-mlcd with the filename based on the first command-line parameter, such as CWpar:OfficeJet_Series_700 or CWusb:OfficeJet_G85. When CWlibptal first opens the Unix-domain socket, it exchanges several request/reply packets with CWptal-mlcd, which might include getting the device ID string, service name to socket ID lookup, socket ID to service name (reverse) lookup, and channel open. In most cases, CWptal-mlcd attempts to activate if it's not already active before processing one of these requests. After a successful open reply, for all practical purposes the connection is then a pass-through connection to the requested service on the device. CWptal-mlcd maintains a fixed-maximum-size table of various kinds of session structures. Whenever a new connection is received from the named socket, it is assigned to a command session, which handles the request/reply command interaction with CWlibptal. When an open request is received, the command session is linked with either a transport session or virtual PML session, depending on whether the open request was for a peripheral socket ID corresponding to the PML service (which is virtualized) or for a different service. As the open is processed the linked sessions go through several state transitions together. If/when the open succeeds, the connection is fully transferred from the command session to the transport or PML session, but if the open fails then the linked session is freed and the connection stays with the command session ready for possibly other commands. CWptal-mlcd depends on the CW/dev/null bit-bucket device for several purposes. First of all, it substitutes CW/dev/null for the standard input, output, and/or error file descriptors if they aren't already open, which is the case when invoked from a hotplug script (not recommended). Second, it substitutes CW/dev/null file descriptors for sessions which don't have an associated file descriptor (such as the master PML session) or sessions which have been closed by CWlibptal but are not ready to be completely torn down by CWptal-mlcd (such as when CWptal-mlcd gets an error writing to a session's file descriptor, which is not the right state for tearing down the session). The basic requirements for the CW/dev/null device are that CWselect() should indicate ready to read and write, CWread() should return an end-of-file condition (zero bytes read), and CWwrite() should always succeed in writing all of the requested bytes. Class hierarchy CWParPort:
- •
- CWParPort Handles access to parallel ports with PC-style register sets:
- •
- port type detection
- •
- timeouts
- •
- parallel-port register access (for efficiency assumes PC-style parallel port accessed with the x86/Alpha I/O port read/write instructions)
- •
- IEEE 1284-1994 signalling:
- •
- negotiation into ECP and nibble modes
- •
- termination back to compatibility mode
- •
- ECP forward-to-reverse and reverse-to-forward
- •
- ECP forward data transfers
- •
- ECP and nibble reverse data transfers
- •
- ECP hardware-assisted data transfers
- •
- Reading the device ID string
CWExMgr:
- •
- CWQueueEntry, CWQueue Node and container base classes for a doubly-linked list (derived by message, watchdog timer, BDR, and lookup classes).
- •
- CWExMsgHandler Base class for CWExMgr, CWExTransport, and CWExTransportChannel classes that serves as a template for receiving messages (either dispatched explicitly or as a result of a watchdog timer).
- •
- CWExMsg Contains destination and parameter information to route a message to the correct CWExMsgHandler-derived class.
- •
- CWExMsgQueue Used to store free (available) or pending messages.
- •
- CWPolledTimer After being started with a particular timeout or delay, is polled periodically to determine if the timeout has passed. Also contains utility functions to delay a particular amount of time by blocking without polling.
- •
- CWExWatchdogTimer Once set with a timeout and started, pops if the timeout happens before being cancelled. This class takes two different forms, which determine the meaning of pop:
- •
- A message-based timer has an CWExMsg and an CWExMsgHandler destination set. When the timer pops, the message is sent to the destination. Ordered in the CWExWatchdogTimerQueue based on time remaining until pop.
- •
- A periodic timer has no CWExMsg or CWExMsgHandler set and is used only by various modules to request a maximum CWselect() timeout. Ordered in the CWExWatchdogTimerQueue based on timeout.
- •
- CWExCountingWatchdogTimer CWExWatchdogTimer-derived class that starts the underlying timer every time a start request is received, and doesn't stop it until the same number of stop requests have been received.
- •
- CWExWatchdogTimerQueue Queues CWExWatchdogTimer objects in the order they will pop.
- •
- CWExBdr Buffer Data Record Contains data buffer, offset, length, and owning transport channel (if any). BDRs for a single packet (i.e. header and multiple data BDRs) may be chained together to ensure uninterrupted transmission. Note that this is not the same as several BDRs stored in a queue, although in some situations the chain is broken up and each BDR queued separately.
- •
- CWExBdrQueue Stores BDRs containing data waiting to be processed (except when used by an CWExBufferPool).
- •
- CWExBufferPool Stores free (available) BDRs. Uses a lazy allocation algorithm, in that BDRs aren't allocated until they're needed, to reduce memory consumption in the average case.
- •
- CWExSessionLookup CWExLookup-derived class that stores an CWscd attribute missing from the CWExLookup class (see below).
- •
- CWExMgr Base class for CWParMgr and CWUsbMgr that manages lots of things:
- •
- buffer pool
- •
- transport (see below)
- •
- main runtime loop (CWexMain()) that revolves around CWselect()
- •
- file descriptor sets for CWselect() (from console, socket, sessions, and LLIO)
- •
- command-line processing
- •
- CW/dev/null
- •
- message queue and pool
- •
- timer queues
- •
- debug console
- •
- named Unix-domain socket
- •
- application sessions (command, transport, and virtual PML)
- •
- low-level I/O (LLIO), partially implemented in derived classes
- •
- CWParMgr CWExMgr-derived class for parallel-port connections to glue CWParPort functionality into CWExMgr.
- •
- CWUsbMgr --CWExMgr-derived class for USB connections to implement device enumeration, device ID retrieval, and CWlibusb access.
CWExTransport:
- •
- CWExLookup, CWExLookupQueue Stores parameters/results of requests for 1284.4 service name to socket ID (and vice versa) lookup.
- •
- CWExCounter Maintains a counter up to MAXINT (-1, to prevent wraparound).
- •
- CWExDebugCounter CWExCounter-derived class that only increments for debug purposes, and otherwise just does a plain set.
- •
- CWExCreditCounter Maintains credit count for MLC/1284.4 and maximum outstanding forward packets.
- •
- CWExTransportChannel Handles the basic logic of forward and reverse data flow and reverse buffer management for a single data channel between the host and peripheral. Base class for CWExMlcTransportChannel.
- •
- CWExTransport Pass-through (raw) transport, manages a list of CWExTransportChannel-derived objects, and provides non-channel-specific transport-level functionality.
- •
- CWExMlcCreditCounter CWExCreditCounter-derived class that sets the maximum credit count of 0xFFFF.
- •
- CWExMlcTransportChannel CWExTransportChannel-derived class that handles the specifics of an MLC/1284.4 channel, including channel open/close, forward/reverse data flow, and credit management.
- •
- CWExMlcCommandChannel CWExMlcTransportChannel-derived class that handles sending/receiving of MLC/1284.4 command packets and special credit management needed for the command channel.
- •
- CWExMlcTransport CWExTransport-derived class that manages the channel list consisting of one CWExMlcCommandChannel object and many CWExMlcTransportChannel objects, MLC/1284.4 packet header overhead, routing reverse data to the correct channel, negotiating the protocol revision (MLC or 1284.4), and service name lookup.
Porting considerations The CWExTransport classes were ported directly from the USB I/O firmware of the HP JetDirect 175X external print server, which is a VxWorks-based embedded system. The porting task was greatly simplified because the code has almost no system-level dependencies. It was designed to run in a task context with other code, so it doesn't block on anything. The rest of the necessary functionality was largely re-written for Linux and (for better or for worse) dumped into the CWExMgr class, with an auxilliary CWParPort class. The following system-level assumptions are made by CWptal-mlcd:
- •
- Standard Unix/Linux CWlibc API and system-call semantics. It works on Linux and FreeBSD, so from this standpoint it shouldn't be too hard to port it to other similar operating systems.
- •
- The CWParPort class assumes a PC-style parallel-port register set (with several annoying inverted bits in the control and status registers), that it can use x86/Alpha CWinb and CWoutb operations to access these registers, and that it can give itself permission to do this in some OS-dependent manner, currently supported on Linux and FreeBSD. Alternatively, the parallel-port support can be turned off entirely with the ./configure --without-par switch.
- •
- At a minimum, USB support depends on a (presumably kernel-mode) printer-class device driver which binds to the 7/1/3 USB interface on the device, which is for MLC or 1284.4 packetized communication, not raw print data as is the case with 7/1/1 and 7/1/2. Bidirectional support is required. Also, there needs to be some sort of CWioctl() call to retrieve the device ID string of the currently-attached device, although it's OK if it's retrieved once on plug-in and cached for subsequent queries. A CWread() error needs to be returned when the device is unplugged or powered off, and by extension, CWselect() needs to unblock and indicate that the file descriptor is readable in this situation.
- •
- For better USB support, there also need to be CWioctl() calls to query supported protocols (7/1/1, 7/1/2, 7/1/3) and which one is currently selected, select a different protocol, issue the HP vendor-specific CHANNEL_CHANGE_REQUEST USB command (in order to support channel-78 reset and running MLC/1284.4 over 7/1/2 needed for certain models), query the device's vendor and product IDs, and query the USB bus and device addresses assigned to the device. The Linux kernels 2.4.19 and 2.5.7 and later have the necessary functionality for full USB support.
- •
- For best (and most portable) USB support, CWlibusb is used, either in conjunction with the above-mentioned kernel printer-class driver for non-printer-class interfaces, or by itself for all interfaces (recommended for non-Linux platforms which don't already have sufficient printer-class driver support). If used in conjunction with a kernel printer-class driver as above, it's important to have an CWioctl() call to query the USB bus and device addresses assigned to the device, in order to match up the printer-class driver file descriptor with the appropriate CWlibusb device.