Input/Output Device Driver Reference/Parallel Port Device Driver

The OS/2 parallel port device driver is a base physical device driver that supports the parallel port device interface for OS/2. There are two distinct versions of the parallel port device driver: PRINT01.SYS manipulates the hardware ports through I/O instructions. The Micro Channel parallel port device driver does not access the hardware ports. Advanced BIOS (ABIOS), which executes on Micro Channel machines, replaces the hardware port manipulation done on the ISA/EISA bus machines.
 * PRINT01.SYS:Supporting parallel port adapters on ISA/EISA bus machines
 * PRINT02.SYS:Supporting parallel port adapters on Micro Channel machines (machines containing Micro Channel architecture).

Only one of these physical device drivers will be resident for each machine running in OS/2. Because the parallel port device driver is a base physical device driver, OS/2 determines the system's hardware configuration and automatically installs and initializes the appropriate physical device driver. OS/2 adds a BASEDEV= statement for the device driver to the CONFIG.SYS file.

Overview
The parallel port device drivers service parallel port requests from DOS, WIN-OS/2, and OS/2 applications (including those running under the Presentation Manager). Requests are serialized by the spooler so that mixed printer output will not occur. Printer requests include: In addition, the parallel port device drivers include character device monitor support. The parallel port device driver sends data to a character device monitor, if one is installed.
 * Initializing a parallel port device
 * Sending characters to a parallel port device
 * Returning the status of a parallel port device
 * Handling IOCtl function calls, including the setting of the parallel port device's frame control (characters per line and lines per inch)

The primary method of communicating with the parallel port device driver is through a request packet. When the parallel port device driver receives a request packet, it determines which device the request is for. If a request is not already in progress, the physical device driver calls an appropriate routine to handle the request. If a request is in progress, the physical device driver blocks the caller's thread until the in-progress request has completed. Once the in-progress request has been serviced, the physical device driver will run the caller's thread and process the waiting request.

To make a request of the printer, an OS/2 application pushes parameters (for example, the address of characters to be written) onto its stack, and calls the file system API (for example, DosWrite). The file system: To make a request of the printer from a DOS session, an application moves the parameters into predefined registers and issues an INT 17h or INT 21h. The INT 17h is intercepted by the virtual parallel port device driver. Refer to OS/2 Virtual Device Driver Referencefor more information. The INT 21h request is converted into a request packet and issued to the device driver strategy routine.
 * Determines that the request is for the parallel port device driver (based on the specified device handle)
 * Creates a request packet
 * Issues a call to the parallel port device driver strategy routine

Replacing the Parallel Port Device Driver
The parallel port device drivers contain four device headers in their data segments with the reserved device names PRN, LPT1, LPT2, and LPT3. These device names correspond to the three physical devices supported by this physical device driver. Notice that the names PRN and LPT1, although logically appearing different, correspond to the same physical device.

The parallel port device driver is replaceable. It is uninstalled by creating another parallel port device driver with the device name in the device header identical as the one listed above. It can then be reinstalled by specifying the new parallel port device driver in a DEVICE= statement in CONFIG.SYS.


 * Note:Installation of the files associated with the new device driver, and the addition of the corresponding DEVICE= statement in the CONFIG.SYS file, is accomplished through the DDINSTAL utility and the Device Driver Profile (DDP) for the new device driver.

When the DEVICE= statement for the new parallel port device driver is encountered in CONFIG.SYS during system initialization, the system generates a DEINSTALL request packet and sends it to the parallel port device driver. The OS/2 parallel port device driver receives the DEINSTALL request packet and releases its resources. Refer to the strategy command, "14h / DEINSTALL" in the OS/2 Physical Device Driver Reference for more information.

If the parallel port device driver successfully releases its resources, it returns a successful completion on the Deinstallation request. When the parallel port device driver has been deinstalled, the system then generates an INSTALL request packet and sends it to the new device driver. Refer to the strategy command, "0h /INIT" in the OS/2 Physical Device Driver Reference for more information.

Parallel Port IRQ Performance
The Programmable Interrupt Controller (PIC) under OS/2 2.1, IRQ3 (serial port) has the highest priority in the system. This has given IRQ7 (parallel port) a much higher priority than it would otherwise have. It is now higher in priority than the keyboard or the mouse. A system unit running multiple parallel port devices, that can receive data quickly on a combination of serial/parallel port devices at a high rate of speed (for example, a laser printer with several megabytes of memory) can experience slow user input performance from the mouse and keyboard.

Several alternatives exist to improve user input performance. One alternative, for attended print servers, is to ensure the system unit supports a direct memory access (DMA) parallel or serial port. The parallel port device driver takes advantage of DMA, which reduces the number of hardware interrupts in the system. Fewer high priority interrupts in the system allow the processor to spend more time processing lower priority interrupts.

Another alternative is to convert a parallel port device to run using the serial port and to reduce the bit rate to the serial device. The ASYNC adapter must support extended hardware buffering. For more information on this approach, refer to the Physical ASYNC Communications Device Driver in the OS/2 Physical Device Driver Reference.

A last alternative for those situations where user responsiveness is extremely important is to reduce the number of print files being sent to the print server by moving some of the devices to other system units (thus balancing the workload among several system units available) or to reduce the user installable memory within the device.

DMA Parallel Port Support
The OS/2 2.1 (and later) parallel port device driver for PS/2 systems supports DMA parallel ports using the ABIOS parallel port functions found on those system units.

Using the parallel port in a Programmed I/O (PIO) methodology causes the processor to be involved on each byte transmitted. This prevents the processor from performing other operations.

Using the parallel port in a DMA methodology causes the processor to be involved on each buffer transmitted. The larger the buffer, the fewer interrupts to the CPU, and the more time the CPU can spend doing other useful work.

Code Page Support
The parallel port device driver provides code page support through the OS/2 character device monitor mechanism (for example, the spooler). In addition, three printer IOCtl commands support code page and font switching so that an application has the ability to change the active code page and font in the middle of its print job.

Because the spooler is no longer a character monitor, code page and font switching is handled before the parallel port device driver receives the data. This section remains for compatibility.

Parallel Port (Printer) Monitors
The parallel port device driver defines a data stream for each parallel port device. In addition, each printer data stream can be monitored by parallel port device monitor applications, registered with one of two monitor chains. Character device monitor support is provided by the parallel port device driver, therefore, for each parallel port device.

To register a monitor for one of the parallel port devices, an application issues the DosMonOpen and DosMonReg monitor function calls. DosMonReg generates an IOCtl request for the application to the parallel port device driver to register a monitor on one of the two monitor chains associated with the device. See Category 0Ah, "Register Monitor" (Function 40h), which can be found in the OS/2 Physical Device Driver Reference. When the parallel port device driver receives this request, it: By setting the DosMonReg index parameter appropriately, the application specifies on which of the two monitor chains its monitors are registered. The first monitor chain (specified by the application by setting Index=1) is considered to be the data chain, and is used by the parallel port device driver to send data to a monitor. The second monitor chain (specified by the application by setting Index=2) is considered to be the code page chain.
 * Creates a monitor chain for that device by calling the DevHlp_MonitorCreate, if none was previously created as the result of another register monitor IOCtl request.
 * Registers the monitor with the monitor chain by calling the DevHlp_Register.

To ensure that printer requests are processed in order, the parallel port device driver places all data and code page requests into only the first monitor chain (referred to as the data chain). That is, the parallel port device driver issues MonWrite calls only to the data chain. The parallel port device driver does not place data into the code page chain by calling MonWrite.

To improve performance, the second monitor chain (code page chain) is used by the parallel port device driver primarily to receive the results of a code page request. Processes that issue code page requests are blocked until they receive an indication that their request is valid. Since the number of code page requests is negligible compared to the number of data requests, parallel port monitors can respond more quickly and efficiently to the physical device driver through the code page chain.

In summary, parallel port monitors:
 * Receive all data and code page requests from the first monitor chain (see DosMonRead)
 * Return data requests to the first monitor chain (see DosMonWrite)
 * Return code page requests to the first or the second monitor chain (see DosMonWrite), depending on the position of the monitor when other monitors are registered with the chain (see below)

The spooler is an example of an application that registers a parallel port monitor with both the data chain and the code page chain for a parallel port device. When the spooler registers the monitor with the second chain (see DosMonReg, with Index=2) the monitor input buffer specified is not used because no requests are placed into the second monitor chain by the parallel port device driver.
 * Note:The parallel port device driver expects to receive the monitor responses to code page requests on the code page chain. If monitor responses to code page requests are not received from any monitor on the code page chain, unpredictable results can occur.

Parallel port monitors must be designed with extreme care. They must be positioned carefully when other parallel port monitors, in particular the spooler, are registered: Because the spooler passes the code page results along the code page chain before all the data has been spooled and released to be printed, a parallel port monitor cannot easily synchronize the code page requests with the data requests.
 * If an application monitor wishes only to process character data, it registers a parallel port monitor only on the data chain (Index=1) when:
 * It is the only monitor in the monitor chain (for example, the spooler is not loaded).
 * It is registered in a position to process the data after the spooler. This monitor never sees code page requests from the spooler, because the spooler automatically sends these requests back to the physical device driver through the code page chain.
 * If an application wishes to process both character data and code page requests, it registers a parallel port monitor on the data chain (Index=1) and a parallel port monitor on the code page chain (Index=2) when:
 * It is the only monitor in the monitor chain. It must expect to receive both data and code page requests on the data chain. It must respond to the code page requests on the code page chain as quickly as possible.
 * It is registered in a position to process data after the spooler. It must expect to receive character data from the spooler on the data chain and the code page requests from the spooler on the code page chain.
 * If a parallel port monitor wishes to process character data and code page requests, and it is registered in a position to process data before the spooler, it registers on the data chain (Index=1) only.

All data and code page requests are sent to the first (nonspooler) monitor on the data chain. Because the spooler receives data and code page requests from the data chain only, this monitor must pass on to the spooler through the data chain all the information it receives in the order that it is received.

IOCtl Support of Code Page and Font Switching
The parallel port device driver has three printer-specific IOCtl commands to support the code page and font switching provided in OS/2 2.1 (and later). In order to support these IOCtl calls, there are Font Monitor Buffer command/responses in the monitor interface between the parallel port device driver and the spooler.

All of the actual code page and font switching functions for printers are provided by the code page switcher or OS/2 printer drivers. When the spooler is started, it checks to see if code page support is required. If it is, the spooler causes the code page switcher to be loaded and initialized. The spooler interfaces with the code page switcher through the DosPFSxxx API functions. If a DEVINFO= statement is not specified in the CONFIG.SYS file, the spooler redirects code page requests to the Presentation Manager device drivers.

The following illustrates the dialog between the parallel port device driver and the spooler when the parallel port device driver receives one of these special IOCtl requests from an application:
 * 1) The parallel port device driver receives an IOCtl request from an application to activate a code page.
 * 2) If the spooler is loaded, the parallel port device driver sends a Font Monitor Buffer command to the spooler in the form of a special monitor record placed into the data monitor chain (refer to MonWrite in the OS/2 Physical Device Driver Reference).
 * 3) The spooler calls DosMonRead to receive this special monitor record from its monitor input buffer registered with the data monitor chain.
 * 4) When the spooler receives this special monitor record, it either calls DosPFSActivate to get information from the Define Code Page (DCP) system files, or it calls the appropriate Presentation Manager routines to get the code page information pertaining to the particular printer. This information is placed into a temporary spooler file.
 * 5) The spooler sends a return code back to the parallel port device driver by calling DosMonWrite to place a special monitor record (that is, a Font Monitor Buffer response) into its monitor output buffer registered with the code page chain.

The three printer specific IOCtl commands to support code page and font switching are:

Activate Font: When an application issues a DosOpen for a printer (that is, PRN, LPT1, LPT2, or LPT3), the file system issues an Activate Font IOCtl to the parallel port device driver to set the active code page and font, according to the active code page of the process making the Open request. At any time, an application can also issue the IOCtl, "Activate Font" (Function 48h), to the parallel port device driver by using the handle returned from the DosOpen call to open the device. This allows the application to change the active code page and font in the middle of its print job.

If the parallel port device driver receives the Activate Font IOCtl, and the spooler or another monitor is registered, the parallel port device driver sends a Font Monitor Buffer command (in this case, an Activate Font command) to the monitor on the data chain. The monitor calls DosMonRead to receive this special monitor record from its monitor input buffer registered on the data chain. The monitor sends a Font Monitor Buffer response to this command and to the parallel port device driver by calling DosMonWrite. The monitor then places a special monitor record into its monitor output buffer registered on the code page chain. If the spooler or another monitor is not registered, the parallel port device driver returns the appropriate return code to the caller of the Activate Font IOCtl.

Query Active Font: When the parallel port device driver receives the Query Active Font IOCtl request, and if the spooler or another monitor is registered, the parallel port device driver sends a Font Monitor Buffer command (in this case, a "Query Active Font", Function 69h) to the monitor on the data chain. The monitor calls DosMonRead to receive this special monitor record from its monitor input buffer registered on the data chain. The monitor calls DosMonWrite to send a Font Monitor Buffer response to this command to the parallel port device driver. This places a special monitor record into its monitor output buffer registered on the code page chain. The parallel port device driver then returns the active code page and font information to the caller of the Query Active Font IOCtl. If the spooler or another monitor is not registered, the parallel port device driver returns the appropriate return code to the caller of the Query Active Font IOCtl.

Verify Font: If the parallel port device driver receives the Verify Font IOCtl request, and if the spooler or another monitor is registered, the parallel port device driver sends a Font Monitor Buffer command (in this case, "Verify Font", Function 6Ah, which can be found in the OS/2 Physical Device Driver Reference) to the monitor on the data chain. The monitor receives this special monitor record, from its monitor input buffer registered on the data chain, by calling DosMonRead. The monitor sends a Font Monitor Buffer response to this command to the parallel port device driver by calling DosMonWrite. This places a special monitor record into its monitor output buffer registered on the code page chain. The parallel port device driver then returns the return code to the caller of the Verify Font IOCtl. If the spooler or another monitor is not registered, the parallel port device driver returns the appropriate return code to the caller of the Verify Font IOCtl.

Refer to "Generic IOCtl Interface" and "Monitor Dispatcher Notification Interface", which can be found in the OS/2 Physical Device Driver Reference for specific interface parameters.

Character Monitor Performance
The character monitor buffer of the parallel port device driver has a size of 134 bytes. The PRINTMONBUFSIZE= command, within CONFIG.SYS, provides a method for character monitors to increase this size, and thereby increase performance of data to devices connected to the parallel port. The parallel port device driver allocates and registers its monitor chain buffer based upon the value specified.

The format of this command is: PRINTMONBUFSIZE=xxxx,xxxx,xxxx

Where: xxxx corresponds to LPT1, LPT2, and LPT3 character monitor buffer size, respectively. The minimum value allowed for compatibility with existing character monitors is 134 bytes. The maximum value is 2048 bytes. If a value that is out of the valid range is specified, a default value of 134 bytes is used.

Character monitors can dynamically determine the size of a device driver's monitor buffer by issuing a DosMonReg call with a 2-WORD buffer: DosMonReg returns with the return code ERROR_MON_BUFFER_TOO_SMALL. The character monitor then allocates the monitor buffer to the correct size and reissues the call to DosMonReg.
 * The first WORD consists of the length of the buffer (4).
 * The second WORD (on return from the call) contains the size of the device driver's monitor chain buffer.

Parallel Port IRQ Timeout Processing
The parallel port device driver sets a 120-second timer after receiving a Write request and sending the first byte to the parallel port. If a hardware interrupt is not generated after 120 seconds, the timer expires and a timeout occurs.

There are two different mechanisms for processing timeouts: When a monitor is registered, infinite retry is always enabled. The parallel port device driver sends a status monitor packet through the data chain (Index=1) when a timeout error occurs. This activity alerts all monitors of the error.
 * If infinite retry is enabled, the parallel port device driver does not terminate the request and indefinitely continues to try to send the data to the printer.
 * If infinite retry is disabled, the parallel port device driver terminates the Write request, returning the number of actual bytes sent to the device.

If a hardware interrupt does occur, the parallel port device driver resets the timer to 120 seconds and sends the next byte to the device. This activity continues until all data has been sent to the device. Once the parallel port device driver determines that all characters have been sent, it turns the timer OFF.

Parallel Port Device Driver Interfaces
The parallel port device driver has several interfaces:
 * Request Packet interface (referred to as the Strategy interface)
 * INT 21h interface
 * Generic IOCtl interface
 * Hardware Interrupt interface
 * Monitor Dispatcher Notification interface

Request Packet Interface
The file system is the primary component that interfaces with the parallel port device driver. In response to a function call, the file system creates a request packet containing the information required by the parallel port device driver to process the request. The file system then calls the parallel port device driver's strategy entry point, with the registers ES: BX containing the address of the request packet.

The Strategy interface uses the Call/Far return model and must preserve the caller's registers. The strategy entry point routes all IOCtl requests and all Open, Read, Write, Close, and Status requests to the appropriate internal parallel port device driver routines to handle the requests. For a description and format of a request packet, refer to the physical device driver strategy commands, which can be found in the OS/2 Physical Device Driver Reference.

The command code field of a request packet contains the function requested of the physical device driver. The parallel port device driver is a character device driver and supports all character device driver functions.
 * Request Packet Command Summary

A detailed description of these commands can be found in the OS/2 Physical Device Driver Reference.

On the call to the parallel port device driver, the status code is set to 0. On return from the physical device driver, the status code contains the results of the request (for example, done or error). The parallel port device driver sets the error bit, busy bit, done bit, and error code, when necessary.
 * Request Packet Status Description

The error codes that the parallel port device driver returns are listed below: 8102h Device not ready 8103h Unknown command 8109h Printer out of paper 810Ah Write fault 810Ch General failure 8111h Character I/O call interrupted 8113h Invalid parameter If the parallel port device driver does not support a request, a status of 8103h (unknown command) is returned.
 * Return Codes

INT 21h Interface
An application running in a DOS session can access the parallel port device driver through INT 21h. The file system creates a request packet from the parameters and calls the parallel port device driver at its strategy entry point. This interface maintains compatibility with DOS applications. As in the Request Packet interface, the parallel port device driver preserves the caller's registers ES:BX and points to the request packet. The strategy entry point follows the Call/Far return model.

Generic IOCtl Interface
The parallel port device driver supports a set of generic IOCtl functions. Refer to the parallel port control IOCtl commands in the OS/2 Physical Device Driver Reference for a list and detailed description of these functions.

Note: From the command line, a user can start the MODE command to perform the parallel port control functions Set/Query Frame Control and Set/Query Infinite Retry. See the description of the MODE command in the OS/2 Command Reference.

Parallel Port Device Driver Support
All the Category 05h IOCtl commands are supported by the parallel port device driver. Additionally, the following IOCtls are also supported by the parallel port device driver:

Category 0Ah Character Monitor Control. Supported by the physical keyboard, mouse, and parallel port device drivers.

Function 40h Register (A character monitor)

Category 0Bh General Device Control. Supported by all the character device drivers.

Function 01h Flush input buffer

Function 02h Flush output buffer

Function 60h Query monitor support

Character Monitor Control
The IOCtl Category 0Ah "Register Monitor" (Function 40h), which can be found in the OS/2 Physical Device Driver Reference, is supported by the physical keyboard and mouse device drivers, as well as by the parallel port device driver. The index field of the data packet received on this call is device specific. That is, it is defined differently for each physical device driver. The index field generally indicates on which monitor chain an application wishes to register a monitor.

As previously discussed, the parallel port device driver creates two monitor chains for each parallel port device - a data chain and a code page chain. An application issuing this IOCtl function call to a specified parallel port device sets the index parameter as follows:
 * Index=1Registers a monitor with the data chain.
 * Index=2Registers a monitor with the code page chain.

Hardware Interrupt (8259) Interface
When a hardware interrupt is pending on an interrupt level owned by the parallel port device driver, the hardware interrupt manager calls the parallel port device driver's hardware interrupt entry point for that interrupt level. PRINT01.SYS runs parallel port devices using hardware interrupt levels IRQ 7 and IRQ 5. PRINT02.SYS runs parallel port devices on hardware interrupt level IRQ 7. The parallel port device driver for Micro Channel machines shares the hardware interrupt level IRQ 7.

Each of the parallel port device driver's hardware entry points call a parallel port device driver general interrupt routine. This routine sends the next character to the port, issues an EOI (End-Of-Interrupt), and completes a strategy request when the last character has been received by the device.

The hardware interrupt manager saves all registers before calling the parallel port device driver interrupt entry points. On return to the hardware interrupt manager, the parallel port device driver's general interrupt routine clears the carry flag, signalling the interrupt manager that the parallel port device driver owns the interrupt. If the parallel port device driver does not own the hardware interrupt, it sets the carry flag. The parallel port device driver's hardware interrupt routine follows the Call/Return Far model and does not handle nested interrupts.

Monitor Dispatcher Notification Interface
The OS/2 parallel port device driver supports character device monitors. For a description of how that support is provided, see.

Data sent to each parallel port device can be monitored before reaching the device by parallel port monitor applications registered with one of two monitor chains. When a parallel port monitor is registered, the parallel port device driver calls the MonWrite device helper runtime to place all requests (in the form of monitor records or packets) into its monitor chains. Each parallel port monitor registered on the monitor chain can monitor the data destined for the parallel port. Parallel port data that has passed through all monitors registered on the monitor chain is placed into a parallel port device driver monitor chain buffer by the OS/2 monitor dispatcher.

A monitor chain for a parallel port device is created when the parallel port device driver calls MonitorCreate. For each monitor chain, the parallel port device driver must provide:
 * A device driver monitor chain buffer, into which the monitor dispatcher places the filtered parallel port data after it has passed through all the parallel port monitors in the monitor chain.

The length of the parallel port device driver's monitor chain buffer is 134 bytes. This length is specified by the parallel port device driver in the first WORD of the buffer when MonitorCreate is called. The length of parallel port monitor input and output buffers, registered with a parallel port monitor chain, must be greater than or equal to 134 bytes plus 20 bytes.


 * The address of a notification routine that is called by the monitor dispatcher when it has placed filtered data into the monitor chain buffer.

Before the monitor dispatcher calls the parallel port device driver's notification routine, it: The general monitor packet format for code page processing is described in the following table. The general monitor packet format for Open, Write, Close, Status, and Print -Job-Title monitor requests is described in the following table. Data items included in these data structures are defined in the descriptions of the corresponding request packet data structures. The parallel port device driver communicates with parallel port monitors using the monitor protocol.
 * 1) Places a data record in the parallel port device driver's monitor chain buffer starting at the second WORD of the buffer
 * 2) Places the length of the data record (in bytes) in the first WORD of the parallel port device driver's monitor chain buffer
 * 3) Sets the register pair ES:SI to point to the parallel port device driver's monitor chain buffer

Parallel Port Monitor Buffer Command
Each monitor record can be of variable length and contain a WORD of flags defining the type of monitor packet.

Note:Monitor packets that parallel port monitors do not understand should be returned to the parallel port device driver on the monitor chains from which they were received. Monitor Flags      Device-Driver Dependent

Byte 0              Byte 1 /---\   /---\ |7|6|5|4|3|2|1|0|    |7|6|5|4|3|2|1|0| \---/    \---/  | | | | | | | |      | | | | | | | |  | | | | | | | \-Open | | | | | | | \-Printer Font Monitor | | | | | | \-Close | | | | | | |    Buffer Command Response | | | | | \-Flush   | | | | | | \-Code Page Command Response | | | | \-Reserved  | | | | | \-INT 17H Code Page Request | | | \-Reserved    | | | | \-Status | | \-Reserved      | | | \-Reserved | \-Reserved        | | \-Job Title \-Reserved          | \-Reserved \-Reserved

Monitor Open Packet
When the Open bit (byte 0, bit 0) is set to 1, the monitor buffer contains an open packet from the parallel port device driver. In this case, the next two bytes are:

Monitor Close Packet
When the Close bit (byte 0, bit 1) is set to 1, the monitor buffer is a close packet from the parallel port device driver. In this case, the next two bytes are:

Monitor Write Packet
When the Close bit (byte 0, bit 1) is set to 0, and the Open bit (byte 0, bit 0) is set to 0, the monitor buffer is a write data packet from the parallel port device driver. In this case, the next bytes are:

Font Monitor Packet
When the Font Monitor Buffer Command/Response bit (byte 1, bit 0) is set to 1, the monitor buffer is a Font Monitor Buffer command. In this case, the next six bytes are: Byte 2-3 System File Number

Byte 4 Font Monitor Buffer Command byte, which indicates the type of command or response

Byte 5 Reserved. Must be set to 0

Byte 6-7 Reserved. Must be set to 0

When the Code Page Command Processed bit (byte 1, bit 1) is set to 1, the Font Monitor Buffer command has been processed by the spooler.

The parallel port device driver sends Font Monitor Buffer commands to its monitors through the data monitor chain (Index=1). A parallel port monitor, which services the Font Monitor Buffer command, sets the Code Page command processed bit and uses DosMonWrite to place the Font Monitor Buffer response into the code page monitor chain (Index=2). Data to be printed continues to flow on the data monitor chain. The code page monitor chain is used only for the Font Monitor Buffer responses, so the parallel port device driver does not block a program issuing a code page and font IOCtl request when print data monitor buffers are already queued ahead of the IOCtl request.

Font Monitor Buffer Commands:The valid Font Monitor Buffer commands, along with the remainder of the buffer contents for the responses, are as follows:

Byte 4 = 01h Activate Font. Command data, starting at byte 8: Return Code A value returned, starting at byte 8, which includes the following values:
 * 0000h Successful completion
 * 0002h Code page is not available
 * 0003h No code page function, because spooler not started
 * 0004h Font ID is not available (verify)
 * 0009h Error caused by switcher error, not by input parameters
 * 000Ah Error caused by invalid printer name as input
 * 000Dh Received code page request, when code page switcher not initialized
 * 000Fh SFN table full cannot activate another entry
 * 0013h DASD error reading font file
 * 0015h DASD error reading font file definition block
 * 0017h DASD error, while writing to temporary spool file
 * 0018h Disk full error, while writing to temporary spool file
 * 0019h Spool file handle was bad Code Page. The value to assign to the currently active code page.
 * 0000h If the Code Page value and Font ID are specified as 0, set printer to hardware default code page and font.
 * 0001h-FFFFh Valid code page numbers.

Font ID The ID value of the font to make currently active.

0000h If the Code Page value and Font ID are specified as 0, set printer to hardware default code page and font.

If only the Font ID is 0 and the Code Page is a valid nonzero, then any font within the specified code page is acceptable.

0001h-FFFFh Valid Font ID numbers, which are font types defined by the font file definitions as fonts that can be downloaded. For cartridge fonts, Font IDs are the numbers on the cartridge label. They are also entered in the DEVINFO statement for the printer.

The parallel port device driver passes the Font Monitor Buffer command to the monitor on the data monitor chain (Index=1). The monitor returns the Font Monitor Buffer response to the parallel port device driver on the code page monitor chain (Index=2).

Byte 4 = 02h Query Active Font. There is no additional command data. Data returned from this function call includes:

Return Code A value returned, starting at byte 8, which includes the following values:
 * 0000h Successful completion
 * 0003h No code page function, because spooler not started
 * 0009h Error caused by switcher error, not by input parameters
 * 000Ah Error caused by invalid printer name as input
 * 000Dh Received code page request, when code page switcher not initialized
 * 0010H Received request for SFN not in SFN table.

Code Page On return, is set to currently active code page:
 * 0000h If the Code Page value and Font ID are returned as zero, the printer is set to the hardware default code page and font.
 * 0001h-FFFFh Valid code page numbers.

Font ID On return, is the ID value of the Font, which is currently active:
 * 0000h If the Code Page value and Font ID are specified as zero, the printer is set to the hardware default code page and font. A Font ID value of zero can indicate the default font of a particular code page.
 * 0001h-FFFFh Valid Font ID numbers, which are font types defined by the font file definitions as fonts that can be downloaded. For cartridge fonts, Font IDs are the numbers on the cartridge label. They are also entered in the DEVINFO statement for the printer.

The parallel port device driver passes the Font Monitor Buffer command to the monitor on the data monitor chain (Index=1). The monitor returns the Font Monitor Buffer response to the parallel port device driver on the code page monitor chain (Index=2).

Byte 4 = 03h Verify Font. Command Data, starting at byte 8: Return Code A value returned, starting at byte 8, which includes the following values:
 * 0000h Successful completion
 * 0002h Code page is not available
 * 0003h No code page function, because spooler not started
 * 0004h Font ID is not available (verify)
 * 000Ah Error caused by invalid printer name as input
 * 000Dh Received code page request, when code page switcher not initialized.

Code Page The Code Page number to validate.

0000h-FFFFh Valid code page numbers.

Font ID The Font ID value to validate.

0000h-FFFFh Valid Font ID numbers.

The parallel port device driver passes the Font Monitor Buffer command to the monitor on the data monitor chain (Index=1). The monitor returns the Font Monitor Buffer response to the parallel port device driver on the code page monitor chain (Index=2).

Monitor Status Packet
When the Status bit (byte 1, bit 3) is set to 1, this indicates that the monitor buffer is a status packet from the parallel port device driver. In this case, the next four bytes are:

The parallel port device driver sends either device not ready (02h), printer out of paper (09h), or write fault (0Ah) as the error code.

Monitor-Job Title Packet
A print-monitor job title packet passes the name of the file being printed to all monitors registered with the parallel port device driver.

When the job title bit (byte 1, bit 5) is set to 1, it indicates the monitor buffer is a job title packet from the parallel port device driver. In this case, the next bytes are: The Job Title Length field includes the null character. The Job Title Buffer is terminated with the null character. The Job Title Buffer field contains bytes 6-131.

Sharing the Parallel Port With Other Device Drivers
The OS/2 parallel port device driver provides two functions in its physical device driver to physical device driver inter-device-driver communication ( PDD-PDD IDC) interface - request exclusive access and release exclusive access to the parallel port. The request exclusive access IDC function is used by device drivers to request sole ownership of the parallel port. The release exclusive access IDC function is used by device drivers to release sole ownership of the parallel port. Parameter passing is register-based and not stack-based.

Client device drivers use the DevHlp_AttachDD to obtain the OS/2 parallel port device driver IDC entry point. The client device driver requests sole ownership of the parallel port once it has work to perform and should release ownership of the parallel port once the work has completed. Client device drivers obtain and release sole ownership to the parallel port by loading the general purpose registers with the appropriate parameters and calling the OS/2 parallel port device driver.

After obtaining sole ownership of the parallel port, the client device driver should then obtain the resources it needs to perform the request ( including the hardware interrupt levels, DMA channels, and other shareable system resources). Prior to releasing ownership of the parallel port, the client device driver should release these other sharable system resources so that other client device drivers can obtain them. At a minimum, the client device driver should release ownership of the parallel port at the completion of a kernel write request packet. The process of sharing the parallel port only works when client device drivers cooperate with each other.

Exclusive port access can be overridden with the share access option in the parallel port settings dialog box of a print object. When this option is selected, all client device drivers requesting sole access to the parallel port are granted access. The parallel port device driver does not perform the serialization of access to the port. Users must perform the serialization by not trying to access two devices connected to the parallel port simultaneously. Otherwise, unpredictable results will occur.

The parallel port sharing feature is not available in the OS/2 2.1 (or later) product. It is available through the OS/2 Driver Development Support group and the IBM Developer Connection Device Driver Kit for OS/2.

Request Exclusive Access
Request Exclusive Access grants the calling device driver sole ownership of the parallel port until a Release Exclusive Access is issued.

AX = Function Code          ; 0 = Request Exclusive Access BX = Request Flags          ; Bit 0 = 0 Do not block ; Bit 0 = 1 Block until available CX = Port ID                ; LPT1 = 0, LPT2 = 1, LPT3 = 2 DS = Data Selector          ; OS/2 PPDD Data Selector ES = Data Selector of caller ; DS of caller No error Carry Flag clear AX = 0
 * Parameters
 * Returns

Error Carry Flag set AX = Error code

Possible errors: ERROR_I24_INVALID_PARAMETER ERROR_I24_DEVICE_IN_USE ERROR_I24_CHAR_CALL_INTERRUPTED

Release Exclusive Access
Release Exclusive Access releases the calling device driver from sole ownership to the parallel port. Sole ownership was granted when a Request Exclusive Access was issued.

Parameters
AX = Function Code          ; 1 = Release Exclusive Access CX = Port ID                ; LPT1 = 0, LPT2 = 1, LPT3 = 2 DS = Data Selector          ; OS/2 PPDD Data Selector ES = Data Selector of caller ; DS of caller

Results
No error Carry Flag clear AX = 0

Error Carry Flag set AX = Error code Possible errors: ERROR_I24_INVALID_PARAMETER ERROR_I24_DEVICE_IN_USE