Sharing the Parallel Port

by Frank J. Schroeder

Because of its standard interface, the parallel port is being used to connect peripherals, such as CD-ROM drives, to personal computers. Because of this, OS/2 needs to enable multiple OS/2 device drivers to share the same parallel port without software reconfiguration.

The strategy, then, is to let both device drivers coexist in the system and manage their access to the hardware so that one device driver will not corrupt another by accessing the shared hardware while the first is still using it. This removes the contention at the port. This also enables device drivers to be knowledgeable only about the device they support, rather than all of the possible devices that can be attached to the parallel port.

This article explains how to implement this strategy, as well as describes the new OS/2 2.1 level 3 device driver model as it relates to the initialization complete strategy command. The complete source code can be found on your accompanying Developer Connection CD-ROM.

The Design
OS/2 does not prevent multiple device drivers that want to control the same hardware port from being initialized. Contention occurs; however, when trying to obtain required resources, such as the hardware interrupt level, the DMA channel, or when actually programming the port. By managing access to these resources, a device driver can obtain exclusive access to these resources, thereby eliminating contention. When the device driver has completed its use of these resources, it must release exclusive access to the resources so that other device drivers can access them.

The parallel port device driver manages exclusive access to the parallel port through a physical device driver to physical device driver inter-device-driver communication (PDD-PDD IDC). Figure 1 shows a component-level view of two OS/2 device drivers coexisting in the system and the IDC interface that enables them to share the parallel port.



''Figure 1. Component level view of two OS/2 device drivers''

OS/2 Application A sends requests to the prototype device driver and OS/2 Application B sends requests to the OS/2 parallel port device driver. Both use the file system application programming interface (API). The file system converts the requests into kernel request packets and passes them to their respective device drivers. Both device drivers need to access the parallel port hardware. The OS/2 parallel port device driver grants exclusive access to the parallel port to the device driver whose thread asks for exclusive access first. Where threads are waiting for exclusive access, the driver grants next access to the thread that has highest priority.

The prototype device driver is an example showing how a device driver uses the IDC interface to request and release exclusive access to the parallel port.

The OS/2 parallel port device driver provides two functions in its IDC interface, request exclusive access and release exclusive access to the parallel port. The device drivers use the request exclusive access IDC function to request sole ownership of the parallel port. The device drivers use the release exclusive access IDC function to release sole ownership of the parallel port. Parameter passing is register-based and not stack-based.

The Implementation
Perform the following steps to share the parallel port with other device drivers:
 * Obtain the IDC interface
 * Request exclusive port access
 * Set the hardware interrupt level
 * Perform the data transfer
 * Release the hardware interrupt level
 * Release exclusive port access

The ProWrite routine is the strategy write routine for the prototype device driver used to show how to perform these steps (Sample Code 1). The ProWrite routine calls two worker routines, proreqexclusive and prorelexclusive. The Device Helper Services are defined in the OS/2 2.1 Physical Device Driver Reference. ''Sample Code 1. Prototype Device Driver ProWrite Routine''

Obtain the IDC Interface
The initialization complete command (31) is a new strategy command for OS/2 2.1. System initialization calls all level-three device drivers that have the initialization complete flag set in the capabilities bit strip of the device driver header. A level-3 device driver is one that specifies level 3 in the attribute variable in the device driver header and provides the new 32-bit capabilities bit strip at the end of the device driver header. The capabilities bit strip is 32 bits of flags used to spe cify certain device driver capabilities such as processing of IOCtl2 commands, support for physical addresses above 16MB for 32-bit DMA controllers, and support for the new initialization complete strategy command.

The initialization complete command is issued to device drivers after all device drivers are initialized so they can set up their IDC interfaces. The primary benefit of the initialization complete command is that it removes DEVICE= statement ordering dependencies from CONFIG.SYS. The device driver can use either its initialization routine or the new initialization complete routine to obtain the OS/2 parallel port device driver IDC interface.

OS/2 provides the AttachDD Device Helper Service to enable device drivers to communicate with each other. The AttachDD Device Helper Service requires a pointer to the device name and a pointer to a structure that upon return from the AttachDD call, contains the data selector and the far pointer (16:16) to the protect-mode IDC entry point. The device driver uses these return values when calling the OS/2 parallel port device driver's IDC entry point.

Request Exclusive Access
After the device driver receives a request that requires it to access the parallel port hardware, the device driver must call the OS/2 parallel port device driver to request exclusive access to the parallel port. The parallel port device driver uses the general purpose registers for passing parameters. The ProReqExclusive routine loads the register with the function to be performed (REQEXCLUSIVE), the bx register with the processing flags (REQWAIT), the cx register with the port index (LPT1), the ds register with the OS/2 parallel port device driver data selector address, and the es register with the data selector of the caller before calling the protect mode IDC entry point. The ax register returns any errors; zero indicates no error. The REQWAIT flag specifies to wait until exclusive access is granted before returning. The REQWAIT flag improves performance by not requiring device drivers poll the OS/2 parallel port device driver for exclusive access to the parallel port.

Set the Hardware Interrupt Level
After the parallel port device driver grants the prototype device driver exclusive access to the parallel port (the request exclusive access call completes without an error), all other device drivers are prevented from obtaining exclusive port access. This assumes that all device drivers that want access to the parallel port are first requesting exclusive access through the request exclusive access IDC entry point. After the device driver gets sole ownership, it should set the hardware interrupt level using the SetIRQ Device Helper Service.

The parallel port hardware interrupt levels are IRQ7 and IRQ5. If the system supports hardware interrupt sharing (EISA (Extended Industry Standard Architecture) or MC (Micro Channel)), the device driver can choose instead to issue this call once in its initialization routine. The device driver's interrupt service routine (ISR) should not touch the parallel port unless it has exclusive access. If the system does not support hardware interrupt sharing (ISA (Industry Standard Architecture)), the device driver must set the hardware interrupt level now using the not shared SetIRQ parameter. The OS/2 hardware interrupt manager does not allow multiple device drivers to set the same hardware interrupt level on ISA-bus systems.

Perform the Data Transfer
After the parallel port device driver grants the prototype device driver exclusive access to the parallel port, it can program the parallel port. Usually the device driver starts the data transfer and then blocks the thread waiting for hardware interrupts to occur. On completion of the data transfer, the ISR wakes the blocked thread so that it can return to the caller. The device driver should release the hardware interrupt level and release exclusive access to the parallel port after the data transfer completes.

Other activities that require the device driver to program the parallel port can also be performed after it receives exclusive access. These other activities might include determining the state of the device attached to the parallel port or initializing that device.

Release the Hardware Interrupt Level
Before the thread can return to the caller, it might need to release the hardware interrupt level back to the operating system. This is done using the UnSetIRQ Device Helper Service. On EISA- or MC-bus systems, multiple devices can interrupt on the same level and multiple device drivers can remain registered on an interrupt level, so it is not necessary to release the hardware interrupt level. On ISA-bus systems, the device driver must release the hardware interrupt level so that other device drivers requesting exclusive access to the parallel port can obtain the interrupt level. The OS/2 hardware interrupt manager will not let a device driver register for an interrupt level on an ISA-bus system when another device driver already has access to the hardware interrupt level.

Release Exclusive Port Access
The final step the device driver must take before returning to the caller is to release exclusive access to the parallel port by calling the OS/2 parallel port device driver. The ProRelExclusive routine loads the ax register with the function to be performed (RELEXCLUSIVE), the cx register with the port index (LPT1), the ds register with the OS/2 parallel port device driver data selector address, and the es register with the data selector of the caller before calling the protect-mode IDC entry point. The ax register returns any errors; zero indicates no error. After exclusive access has been released, the device driver can no longer access the parallel port until another request exclusive access call is made and access is granted.

Fairness Between Device Drivers
Sharing of the parallel port only works when all client device drivers are considerate of the other device drivers that also want to use the parallel port. If one device driver monopolizes the parallel port, it may be at the expense of other device drivers. Therefore, it is recommended that device drivers release exclusive access at completion of each write request packet.

Share Access Port Setting
The share access feature can be used to override exclusive port access. It is a checkbox that can be found in the Parallel Port Settings dialogue box. When the share access feature is checked, the OS/2 parallel port device driver allows all requests for exclusive port access to succeed, regardless of whether another device driver already has exclusive access. For example, the user should not attempt to access a parallel-port-attached CD-ROM drive on LPT1 at the same time as the user is printing to a printer also attached to LPT1. This can cause unpredictable results.

Summary
Connecting devices to the parallel port is gaining widespread popularity among personal computer users. As acceptance of this technology increases, it is important for OS/2 to increase its level of hardware support by providing a mechanism for device drivers to share the parallel port.

About the Author - Frank Schroeder
Frank Schroeder is an OS/2 developer who has worked on various OS/2 components including the OS/2 parallel port device driver, the virtual parallel port device driver, the CD-ROM installable file system, the virtual CD-ROM device driver, and the advanced power management device driver. His contributions to OS/2 include DMA parallel port support, parallel port sharing, MSCDEX CD-ROM support, and the 32-bit APM enhancements.

Distribution
The OS/2 Version 2.1 parallel port device driver does not contain the IDC interface for sharing of the parallel port. The OS/2 Driver Development Support group has a copy of the updated parallel port device driver on the DUDE (Phonemail (407) 982-4239, Modem (407) 982-3217).

The updated parallel port device driver also is available in OS/2 2.11 (or CSDXR06200).

For more information on the DUDE, see the Directory in this Newsletter.