Switch to SpeakEasy.net DSL

The Modular Manual Browser

Home Page
Manual: (Debian-3.1)
Apropos / Subsearch:
optional field

PTAL-MLCD(8)                TTF2PT1 Font Converter                PTAL-MLCD(8)

       hpoj reference: "ptal-mlcd"

       ptal-mlcd [mlc:]bus:name [options...]

       The "ptal-mlcd" daemon implements the HP MLC (Multiple Logical Chan-
       nels) 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 "libptal" accesses
       locally-connected devices controlled by "ptal-mlcd" through the use of
       Unix-domain sockets, which, unlike TCP/IP sockets, are not accessible
       across a network.  Currently, "ptal-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 assis-
       tance.  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,
       "ptal-mlcd"'s USB support depends on "libusb" and/or the Linux kernel
       USB printer-class driver ("printer.o").  "libusb" is required in order
       to access all device functions on certain "composite USB" models and to
       work around SMP issues in "printer.o", but otherwise the two methods
       should work equally well.  See the hpoj Supported Devices page for more
       information about requirements for different models.

       o   "bus" is the connection type and is one of:

           o   "par" -- Parallel port

           o   "usb" -- Universal Serial Bus

       o   "name" is the desired name or number suffix for this device

       o   Common "options" for all "bus" types:

           o   "-devidmatch string" -- Matches portion of device ID string,
               such as the model or serial-number fields to uniquely identify
               a device

           o   "-remconsole" -- Enables remote debug console (service name
               "PTAL-MLCD-CONSOLE", socket -1), also makes log message output
               less susceptible to data loss but slightly more susceptible to

       o   Less common "options" for all "bus" types:

           o   "-nofork" -- Stays in the foreground, enables local console

           o   "-nodrain" -- Disables channel-78 reset and reverse data drain
               in case they cause a problem

           o   "-forcemlcdot4" -- Forces both 1284.4 and MLC modes to be tried

           o   "-nodot4" or "-nomlc" -- Disables 1284.4 or MLC mode individu-
               ally (Caution: Don't disable both, because "raw" mode currently
               does not work very well.)

           o   "-nopml" -- Disables PML multiplexing

           o   "-nolog", "-logwarn", "-log" -- Sets logging level

       o   Valid "options" for "par":

           o   "-base 0xADDR" -- I/O port base address (default is 0x378)

           o   "-basehigh 0xADDR" -- ECP high base address (default is
               "base"+0x400, must be specified after "-base")

           o   "-device /dev/lp0" -- Path and filename of corresponding device
               node, used to lock the port and prevent interference from other

           o   "-porttype porttype" -- Overrides port-type detection, one of:

               o   "spp" -- Standard (unidirectional) parallel port

               o   "bpp" -- Bidirectional (PS/2, not ECP) parallel port

               o   "ecp" -- Extended Capabilities Port with no hardware assis-

               o   "ecphw" -- Extended Capabilities Port with hardware assis-

               o   "ecphwfwd" -- Extended Capabilities Port with hardware
                   assistance in the forward direction only

               o   "ecphwrev" -- Extended Capabilities Port with hardware
                   assistance in the reverse direction only

           o   "-nobecp" -- Prevents bounded ECP mode from being used

           o   "-forcebecp" -- Forces bounded ECP mode to be used

       o   Valid "options" for "usb":

           o   "-device "/dev/usb/lp*"..." -- Path and filename of Linux
               "printer.o" device node(s) (it's OK to have multiple device
               nodes and/or wildcards, preferably not expanded by the shell)

           o   "-device %bus%device" -- "libusb" bus and device names/numbers

           o   "-vpidmatch 0xVVVVPPPP" -- Matches USB vendor and product ID
               instead of "-devidmatch"

           o   "-nocomp" -- Disables composite-USB support (FF/D4/00 or
               FF/FF/FF MLC/1284.4 interface)

           o   "-nocompprint" -- Disables composite-USB "raw" print interface
               (7/1/2) and always tries to print over (possibly composite)
               MLC/1284.4 interface

           o   "-forcecomp" -- Enables extra composite-USB support (FF/FF/FF
               MLC/1284.4 interface) that would not normally be used in most

           o   "-noglobusb" -- Disables implicit libusb device globbing

           o   "-nochannelchange" -- Disables HP USB "channel change" request
               whenever possible

       "ptal-mlcd" and "ptal-printd" are typically called by "ptal-init", and
       it's generally unnecessary to invoke them manually from the command
       line except for development or debugging purposes.  A "ptal-mlcd"
       process exists in one of several overall states.  When startup is com-
       plete, it is in the inactive state.  When an application tries to
       access the device, "ptal-mlcd" starts to activate, or in other words,
       establish an MLC/1284.4 communication session with the device.  Once
       that is complete, "ptal-mlcd" is in the active state.  If a communica-
       tion error happens, which could be the result of a power-off or discon-
       nection of the device or a protocol error, "ptal-mlcd" deactivates,
       which includes closing all active application sessions and returning to
       the inactive state.  For each "ptal-mlcd" instance, there is a main
       process that services application requests and implements the
       MLC/1284.4 protocols.  When "ptal-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 "ptal-mlcd" deacti-
       vates.  "ptal-mlcd" special-cases the PML (Peripheral Management Lan-
       guage) service on the device, by keeping open a single PML channel
       while activated, virtualizing application requests to open the PML ser-
       vice, 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 "-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 "ptal-mlcd" on parallel, set
       up automatically by ""ptal-init setup"", is something like the follow-
       ing (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 "-device" switch is recommended if your system has ker-
       nel parallel-port support, because it gives "ptal-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 "ptal-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 "ptal-mlcd" on USB, set
       up automatically by ""ptal-init setup"", is something like the follow-
       ing (split into multiple lines for clarity):

       ptal-mlcd mlc:usb:OfficeJet_K80 [-remconsole] \ -devidmatch
       "MDL:OfficeJet K80;" \ -devidmatch "SERN:000000000010;" \ -device

       This means that whenever "ptal-mlcd" tries to activate, it will open up
       each USB printer device node in turn (including the implicitly-globbed
       "libusb" 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]

       "-noglobusb" is required in this case to prevent the implicit globbing
       of "libusb" 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 "/dev/usb/lp0" 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 differ-
       ent 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 "libusb"
       instead of Linux "printer.o".  "libusb" and/or Linux "usbdevfs" don't
       indicate how many bytes were successfully transferred at a timeout con-
       dition, 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 cor-
       ruption when recovering from timeout conditions.  User interface
       "ptal-mlcd" includes the following user-interface features:

       o   Special "virtual" services

       o   Log messages to standard output and syslog ("/var/log/messsages")

       o   A debug console

       "ptal-mlcd" supports the following "virtual" services through

       o   "PTAL-MLCD-CONSOLE" -- The debug console, if enabled with the
           "-remconsole" switch

       o   "PTAL-MLCD-PID" -- The main process ID of this instance of

       o   "PTAL-MLCD-CMDLINE" -- The command line passed to this instance of

       o   "PTAL-MLCD-DEVNODE" -- The device node, if any, in use by this
           instance of "ptal-mlcd"

       o   "PTAL-MLCD-DUMP" -- A dump of the current state of most internal
           data structures (useful for debugging)

       o   "PTAL-MLCD-GLOB-DEVNODES" -- Used by ""ptal-init setup"" to glob
           standard and "libusb" device nodes ("ptal-mlcd" must be in a deac-
           tivated state)

       "ptal-mlcd" logs various kinds of messages to standard output (which
       may not be visible unless started in a particular terminal window) and
       syslog ("/var/log/messsages"):

       o   "FATAL ERROR" -- An internal error bad enough to cause "ptal-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
           "hpoj-devel" mailing list.

       o   "ERROR" -- 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 "fdRegister" error, which
           should be reported to the "hpoj-devel" mailing list.

       o   "WARNING" -- An unusual situation that could potentially indicate a
           problem, but which is (hopefully) immediately recoverable with no
           adverse effect.

       o   "SYSLOG" -- An information message by default logged only to sys-
           log, not standard output, indicating successful startup or activa-

       o   "ENTRY", "EXIT", "INFO" -- Debug messages.

       Here is a sample log message followed by an explanation of the compo-

       ptal-mlcd: ERROR at ExMgr.cpp:871, dev=<mlc:usb:Office-
       Jet_K80@/dev/usb/lp0>, pid=17306, e=19 t=1064276197 exClose(rea-

       o   "ERROR" indicates the severity (see above for the possibilities).

       o   "ExMgr.cpp:871" indicates the source-code file and line number
           where the message was logged.  Useful for debugging.

       o   "dev=<mlc:usb:OfficeJet_K80@/dev/usb/lp0>" indicates the device
           name controlled by the "ptal-mlcd" instance that logged the message
           as well as the device node (if one is currently open).  In con-
           trast, this might look like "dev=<mlc:usb:OfficeJet_K80@%001%006>"
           if the device was being accessed through "libusb".

       o   "pid=17306" indicates the process ID that logged the message.

       o   "e=10" indicates the current value of the "errno" variable, proba-
           bly irrelevant unless it's an error message complaining about a
           failed system call.

       o   "t=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).

       o   "exClose(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.

       "ptal-mlcd"'s debug console is accessible in either of the following

       o   Invoke "ptal-mlcd" with the "-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 Con-
           trol-D to exit "ptal-connect" and return the console back to stan-
           dard output (and no standard input).

       o   Invoke "ptal-mlcd" with the "-nofork" switch, to prevent
           "ptal-mlcd" from forking itself into the background and start up
           the "local" console.  Press Control-C to kill "ptal-mlcd" and
           return to the command prompt.

       When the debug console is active, the following commands may be used:

       o   "dump" -- Dumps all data structures.

       o   "pid" -- Prints the current main process ID.

       o   "activate" -- Starts activation if not active.  Prints return code
           of "exActivate()", which may be 0 if already active, 1 if started
           (and probably finished) activating, and -1 if an error occurred.

       o   "deactivate" -- Deactivates by calling "exClose()", which always
           logs an error message.

       o   "log" -- Enables all log messages, including debug messages.

       o   "logwarn" -- Enables log messages other than debug messages
           ("ENTRY", "EXIT", and "INFO").

       o   "nolog" -- Returns to the default log level of logging "ERROR" and
           ""FATAL ERROR"" to standard output and syslog and "SYSLOG" to sys-
           log but not standard output.

       File-system usage "ptal-mlcd" creates Unix-domain sockets in the direc-
       tory "/var/run/ptal-mlcd" with the filename based on the first command-
       line parameter, such as "par:OfficeJet_Series_700" or "usb:Office-
       Jet_G85".  When "libptal" first opens the Unix-domain socket, it
       exchanges several request/reply packets with "ptal-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, "ptal-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.  "ptal-mlcd" main-
       tains a fixed-maximum-size table of various kinds of "session" struc-
       tures.  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 "libptal".  When an open request is received,
       the command session is linked with either a "transport session" or vir-
       tual "PML session", depending on whether the open request was for a
       peripheral socket ID corresponding to the PML service (which is virtu-
       alized) 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 ses-
       sion ready for possibly other commands.  "ptal-mlcd" depends on the
       "/dev/null" "bit-bucket" device for several purposes.  First of all, it
       substitutes "/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 substi-
       tutes "/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 "libptal" but are not ready to be completely
       torn down by "ptal-mlcd" (such as when "ptal-mlcd" gets an error writ-
       ing to a session's file descriptor, which is not the right state for
       tearing down the session).  The basic requirements for the "/dev/null"
       device are that "select()" should indicate ready to read and write,
       "read()" should return an end-of-file condition (zero bytes read), and
       "write()" should always "succeed" in writing all of the requested
       bytes.  Class hierarchy "ParPort":

       o   "ParPort" -- Handles access to parallel ports with PC-style regis-
           ter sets:

           o   port type detection

           o   timeouts

           o   parallel-port register access (for efficiency assumes PC-style
               parallel port accessed with the x86/Alpha I/O port read/write

           o   IEEE 1284-1994 signalling:

               o   negotiation into ECP and nibble modes

               o   termination back to compatibility mode

               o   ECP forward-to-reverse and reverse-to-forward

               o   ECP forward data transfers

               o   ECP and nibble reverse data transfers

               o   ECP hardware-assisted data transfers

           o   Reading the device ID string


       o   "QueueEntry", "Queue" -- Node and container base classes for a dou-
           bly-linked list (derived by message, watchdog timer, "BDR", and
           lookup classes).

       o   "ExMsgHandler" -- Base class for "ExMgr", "ExTransport", and
           "ExTransportChannel" classes that serves as a template for receiv-
           ing messages (either dispatched explicitly or as a result of a
           watchdog timer).

       o   "ExMsg" -- Contains destination and parameter information to route
           a message to the correct "ExMsgHandler"-derived class.

       o   "ExMsgQueue" -- Used to store free (available) or pending messages.

       o   "PolledTimer" -- 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.

       o   "ExWatchdogTimer" -- 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":

           o   A message-based timer has an "ExMsg" and an "ExMsgHandler" des-
               tination set.  When the timer pops, the message is sent to the
               destination.  Ordered in the "ExWatchdogTimerQueue" based on
               time remaining until pop.

           o   A periodic timer has no "ExMsg" or "ExMsgHandler" set and is
               used only by various modules to request a maximum "select()"
               timeout.  Ordered in the "ExWatchdogTimerQueue" based on time-

       o   "ExCountingWatchdogTimer" -- "ExWatchdogTimer"-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.

       o   "ExWatchdogTimerQueue" -- Queues "ExWatchdogTimer" objects in the
           order they will pop.

       o   "ExBdr" -- "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.

       o   "ExBdrQueue" -- Stores BDRs containing data waiting to be processed
           (except when used by an "ExBufferPool").

       o   "ExBufferPool" -- Stores free (available) BDRs.  Uses a "lazy allo-
           cation" algorithm, in that BDRs aren't allocated until they're
           needed, to reduce memory consumption in the average case.

       o   "ExSessionLookup" -- "ExLookup"-derived class that stores an "scd"
           attribute missing from the "ExLookup" class (see below).

       o   "ExMgr" -- Base class for "ParMgr" and "UsbMgr" that manages lots
           of things:

           o   buffer pool

           o   transport (see below)

           o   main runtime loop ("exMain()") that revolves around "select()"

           o   file descriptor sets for "select()" (from console, socket, ses-
               sions, and LLIO)

           o   command-line processing

           o   "/dev/null"

           o   message queue and pool

           o   timer queues

           o   debug console

           o   named Unix-domain socket

           o   application sessions (command, transport, and virtual PML)

           o   low-level I/O ("LLIO"), partially implemented in derived

       o   "ParMgr" -- "ExMgr"-derived class for parallel-port connections to
           glue "ParPort" functionality into "ExMgr".

       o   "UsbMgr" --"ExMgr"-derived class for USB connections to implement
           device enumeration, device ID retrieval, and "libusb" access.


       o   "ExLookup", "ExLookupQueue" -- Stores parameters/results of
           requests for 1284.4 service name to socket ID (and vice versa)

       o   "ExCounter" -- Maintains a counter up to MAXINT (-1, to prevent

       o   "ExDebugCounter" -- "ExCounter"-derived class that only increments
           for debug purposes, and otherwise just does a plain set.

       o   "ExCreditCounter" -- Maintains "credit" count for MLC/1284.4 and
           maximum outstanding forward packets.

       o   "ExTransportChannel" -- 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

       o   "ExTransport" -- Pass-through (raw) transport, manages a list of
           "ExTransportChannel"-derived objects, and provides non-channel-spe-
           cific transport-level functionality.

       o   "ExMlcCreditCounter" -- "ExCreditCounter"-derived class that sets
           the maximum credit count of 0xFFFF.

       o   "ExMlcTransportChannel" -- "ExTransportChannel"-derived class that
           handles the specifics of an MLC/1284.4 channel, including channel
           open/close, forward/reverse data flow, and credit management.

       o   "ExMlcCommandChannel" -- "ExMlcTransportChannel"-derived class that
           handles sending/receiving of MLC/1284.4 command packets and special
           credit management needed for the command channel.

       o   "ExMlcTransport" -- "ExTransport"-derived class that manages the
           channel list consisting of one "ExMlcCommandChannel" object and
           many "ExMlcTransportChannel" 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 "ExTransport" 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 depen-
       dencies.  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 "ExMgr" class, with an auxilliary "ParPort" class.  The fol-
       lowing system-level assumptions are made by "ptal-mlcd":

       o   "Standard" Unix/Linux "libc" 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.

       o   The "ParPort" class assumes a PC-style parallel-port register set
           (with several annoying inverted bits in the control and status reg-
           isters), that it can use x86/Alpha "inb" and "outb" 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.

       o   At a minimum, USB support depends on a (presumably kernel-mode)
           printer-class device driver which binds to the "7/1/3" USB inter-
           face on the device, which is for MLC or 1284.4 packetized communi-
           cation, 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 "ioctl()" call to retrieve the device ID string of the cur-
           rently-attached device, although it's OK if it's retrieved once on
           plug-in and cached for subsequent queries.  A "read()" error needs
           to be returned when the device is unplugged or powered off, and by
           extension, "select()" needs to unblock and indicate that the file
           descriptor is readable in this situation.

       o   For better USB support, there also need to be "ioctl()" 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 ven-
           dor-specific CHANNEL_CHANGE_REQUEST USB command (in order to sup-
           port 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 func-
           tionality for full USB support.

       o   For best (and most portable) USB support, "libusb" 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 suf-
           ficient printer-class driver support).  If used in conjunction with
           a kernel printer-class driver as above, it's important to have an
           "ioctl()" 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 "libusb" device.

current                         March 13, 2005                    PTAL-MLCD(8)