MMPM/2 Device Driver Reference:Audio Virtual Device Driver Template

The IBM Developer Connection Device Driver Kit for OS/2 includes full source for the MMPM/2 provided Virtual Device Driver, VBSAUDIO.SYS. Use VBSAUDIO.SYS to serialize DOS application access to audio hardware in the MMPM/2 environment. This VDD can communicate with multiple audio PDDs through the Inter-Device Driver Communication (IDC) Interface. However, where the services of VBSAUDIO.SYS are not sufficient, you can modify the audio VDD template to meet your device driver requirements.

You can code your Physical Device Driver to meet the interfaces of VBSAUDIO.SYS as an initial step toward virtualization. You can expand this functionality by copying and changing VBSAUDIO.SYS to take advantage of your hardware and private interfaces which can be established between the VDD and DOS or WIN-OS/2 audio device drivers.


 * Note: For further information on when to use a VDD and how it operates, see the online OS/2 Virtual Device Driver Reference provided in this package. This reference describes the types of virtual device drivers, their interfaces, and available kernel services.

Source Code
The VDD template is written using Open Watcom C and linked with the 32-bit OS/2 linker. Source code for the audio VDD sample is located in the \DDK\BASE\SRC\VDEV\MME\VBSAUDIO subdirectory. Source files include documentation headers, which provide detailed descriptions of the programming concepts and routines incorporated within the module.

VDD Architecture
The VBSAUDIO.SYS virtual device driver is a Ring 0, 32-bit device driver responsible for controlling multiple virtual DOS sessions. If there is no requirement for multiple sessions to share access to a device, a requirement for a virtual device driver is unlikely.

VDD architecture usually calls for a device driver pair: a PDD and VDD working together to serialize and control a common piece of hardware, called shared hardware. The PDD controls access to the hardware and OS/2 sessions; the VDD controls DOS sessions and communicates with the PDD to serialize access. That is, the PDD and VDD communicate to make sure DOS sessions and OS/2 sessions cannot concurrently access the shared hardware.

Without a VDD, DOS sessions have complete access to system hardware. Most DOS visible hardware resources are controlled by system VDDs, preventing DOS sessions from interfering with each other and protecting OS/2 applications from DOS sessions.

When a PDD exists with no VDD, the hardware device is visible to the OS/2 side (through the PDD) and to all DOS sessions (through the VDM Manager). This presents an opportunity for DOS sessions to take control of a hardware resource owned by an OS/2 PDD. Writing a virtual device driver corrects this situation, resulting in system-wide protected access to the hardware resource.

This PDD-VDD pair usually results in a VDD (like a PDD) being written to the specifications of a specific hardware device. VBSAUDIO.SYS supports multiple adapters by using a protocol for PDD-VDD communication where the PDD defines the characteristics of its device at system startup.

The key to supporting multiple PDDs is communication at system startup to attain a description of the physical characteristics of each adapter. PDDs are loaded and initialized prior to VDDs. When the PDD loads, it registers itself as willing to communicate with VDDs by providing its IDC name and entry point for this communication. When the VDD loads, it calls a Virtual DevHlp service (VDHOpenPDD) to resolve the IDC entry point of the PDD. On this call, the operating system calls the PDD to deliver the VDD IDC entry point. When the PDD and VDD exchange entry points, the drivers are free to communicate through whatever private protocol is chosen including exchanging register-based entry points.

For these calls to function, the VDD must know the name by which the PDD registered. In a non-generic implementation, this is not a problem as the two device drivers can refer to the name from a common include file. This "generic" VDD takes the PDD names as DEVICE=VBSAUDIO.SYS parameters on the CONFIG.SYS statement.

In the case where a single PDD supports multiple devices, the PDD should register its IDC name and entry point (specifying the name on the DEVICE= VBSAUDIO.SYS statement). During initialization, the VDD calls the PDD to establish communication and to query the hardware resources that the PDD controls. The VDD will use this information to trap DOS session attempts to access the adapter. When a DOS session takes control of a PDD-owned resource, the VDD traps the DOS session pending permission to use the hardware. As the PDD controls access, the VDD queries the PDD for permission to use the hardware. If permission is granted, the VDD disables further traps and allows the DOS session to continue uninterrupted. Traps are disabled to give maximum performance. Because the VDD does not keep track of port accesses (and does not know the details of supported adapters), it is unable to remember the state of the adapter. That is, as soon as a DOS session owns the hardware, ownership cannot be relinquished and restored, because the VDD does not know how to restore the state of the device. The VDD supports serialization (not virtualization).

If access is denied by the PDD, or if another DOS session already owns the hardware, a pop-up message is displayed asking the user for direction. The user can give instruction to terminate the session, suspend the session, or pretend the hardware does not exist. Based on this response, the VDD executes Virtual DevHlp services to perform the necessary actions. Semaphores are used to block DOS session execution when they are suspended awaiting access to hardware. When the last DOS session releases the hardware, the VDD returns hardware ownership to the PDD.


 * Note: See VDD Operations (below) for further information.

VDD Operations
When writing a PDD to control physical hardware, it is common to write a VDD to provide serialization with DOS sessions. Without a VDD, DOS sessions have complete access to system resources. That is, if an adapter has only a PDD, DOS sessions can directly access the adapter resulting in unpredictable consequences.

When DOS sessions are created, the VDD installs hooks for the indicated port ranges. On first access, the DOS session is said to be "requesting hardware access." By convention, the PDD controls hardware access. To gain use, the VDD must ask the PDD for permission to use the hardware. When granted, the DOS session traps are removed and the session is allowed to continue executing. At interrupt time, the PDD calls the VDD IDC entry point where the VDD virtualizes the hardware interrupt for the owning session.

Subsequent DOS session access attempts are denied pending hardware availability. A hard error pop-up window is displayed giving the user three options:
 * End - Terminate the DOS session
 * Retry - Block until hardware becomes free
 * Ignore - Instruct the VDD to ignore the adapter

If retry is chosen, the DOS session is blocked until the hardware becomes available. When the DOS session in use releases the hardware, the next DOS session gains access. This process continues until no more devices are waiting at which point the VDD relinquishes ownership to the PDD.

If ignore is chosen, the DOS session continues execution but with no visibility to the protected adapter. This allows sound-enabled DOS applications to execute under the impression that the system does not have an audio card installed.

For access queues, the PDD uses semaphores and the OS/2 scheduler. The VDD maintains no queues. Instead, 1 mutex and 1 event semaphore are used to control access. Only one DOS session can own the hardware at any one time. When the VDD owns the hardware, the DOS session owning the mutex semaphore is allowed to execute. All others are blocked pending hardware availability. When the owning session releases the hardware (the semaphore), the OS/2 semaphore routines and scheduler determine which session next gains access.

A DOS session can also be denied access due to OS/2 PDD refusal to relinquish ownership. This would be the case when an OS/2 application is using the services of the PDD before a DOS session attempts access. Here, all pending DOS sessions are queued waiting on an event semaphore. When the OS/2 PDD relinquishes hardware, all blocked sessions are allowed to run by posting the event semaphore. The sessions compete for ownership of the mutex semaphore. One session wins, the others block; serialization is maintained.

Inter-Device Driver Communication (IDC) Interface
Virtual device drivers (VDDs) communicate with physical device drivers (PDDs) through the inter-device driver communication (IDC) interface provided with the OS/2 operating system. The drivers exchange the address of an entry point and call each other through the exchanged addresses. A VDD communicates with a PDD directly through a callable 16:32 interface or by using the Virtual DevHlp services that map to File System APIs.

Physical device drivers and virtual device drivers use the following OS/2 DevHlp functions to establish inter-device driver communication (IDC).


 * RegisterPDD:This function is called by the PDD during initialization to advertise a 16:16 entry point for VDD-PDD communication. The PDD provides a textual name, which the VDD must supply during its initialization.
 * VDHOpenPDD:This function gets the address of the routine in a physical device driver that the virtual device driver uses to communicate with the physical device driver. The physical device driver's device must have previously registered its name and entry point using the DevHlp service, RegisterPDD. If the function is successful, it returns a pointer to the physical device driver IDC entry point.