MMPM/2 Device Driver Reference:DDCMD Messages

From EDM2
Jump to: navigation, search
MMPM/2 Device Driver Reference
  1. Adding Support for Audio and Video Adapters
  2. Audio Physical Device Driver Template
  3. Audio Virtual Device Driver Template
  4. MAD16 PDD and VDD Sample Device Drivers
  5. PDD Sample for Video Capture Adapters
  6. PDD Sample for MPEG Video Playback Devices
  7. Audio Sample for Vendor-Specific Drivers
  8. Using the High-Resolution Timer
  9. Real-Time MIDI Subsystem
  10. Audio Device Driver Exerciser (PMADDE) Tool
  11. AP2/P2STRING Tool
  12. Ultimotion Data Stream Specification
  13. DDCMD Messages
  14. SHD Messages
  15. Vendor-Specific Driver Commands
  16. IOCtl Functions
  17. Data Types
  18. Types of MIDI Messages
  19. Notices
  20. Glossary

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation

The device driver commands are an interface used by a stream handler to communicate with a physical device driver. This interface uses the inter- device driver communication (IDC) mechanism provided by OS/2 AttachDD DevHelp. The stream handler must attach to the device driver using AttachDD DevHelp to receive the DDCMD entry point address of the device driver. This must be done prior to issuing any DDCMDs. Some device drivers also might require that a DosOpen call be used to open the device driver before it can be used through the AttachDD entry point.

The DDCMDs are provided through a single entry point, DDCMDEntryPoint, which accepts a parameter structure on input.

typedef ULONG (FAR*PSHDFN)        (PVOID pParmIn);
typedef ULONG (FAR*PDDCMDFN)      (PVOID pParmIn);

For the Ring 3 DLL interface, all pointers are 0:32 linear; for Ring 0 stream handlers all pointers are 16:16 far pointers to enable the 16-bit device driver model to be used. The following list contains the message numbers for all DDCMDs. It should be used in the ulFunction field, of the parameter structure passed on the call, to indicate which function is being requested by the stream handler.

Message Number Message Description
4L DDCMD_CONTROL Performs a device-specific command.
6L DDCMD_DEREG_STREAM Removes a stream instance from a device driver.
1L DDCMD_READ Performs a read from the device into a buffer.
5L DDCMD_REG_STREAM Registers a stream instance with a device driver.
0L DDCMD_SETUP Performs a device-specific stream instance setup.
3L DDCMD_STATUS Requests status from the device.
2L DDCMD_WRITE Performs a write from a buffer to the device.

DDCMDEntryPoint

This function enables device driver stream handlers to interface with the hardware physical device driver (PDD).

#include <os2me.h>

PDDCMDCOMMON    pCommon;  /*  Pointer to DDCMDCOMMON. */
ULONG           rc;       /*  Return codes. */

rc = DDCMDEntryPoint(pCommon);
Parameter - pCommon

pCommon (PDDCMDCOMMON) - input A pointer to a DDCMD message-specific input parameter block. See DDCMDCOMMON.

Return Value - rc

rc (ULONG) - returns Return codes indicating success or the type of failure :

  • NO_ERROR
Successful.
  • ERROR_INVALID_FUNCTION
Invalid function requested.
  • FAILURE
A DDCMD message-specific error return code.
Remarks

Device driver stream handlers communicate with the hardware PDD through the DDCmdEntryPoint. This is accomplished through the use of Device Driver Command (DDCMD) messages, which enable a stream handler to request a PDD to perform functions such as starting, stopping, or resuming operation of a device. This interface uses the IDC mechanism provided by the ATTACHDD DevHelp function. The stream handler must attach to the device driver to receive the DDCMD entry point address of the device driver. This function is performed prior to issuing device driver command messages.

DDCMD_CONTROL

This message performs a device-specific command.

Parameter - pParmIn

pParmIn (PDDCMDCONTROL) A pointer to a DDCMDCONTROL data structure. The pParmand ulParmSize fields refer to the CONTROL_PARM data structure. Values for ulCmd include:

  • DDCMD_START
Start a device.
  • DDCMD_STOP
Stop a device and return current position.
  • DDCMD_PAUSE
Pause a device and return current position.
  • DDCMD_RESUME
Resume a paused device
  • DDCMD_ENABLE_EVENT
Enable event detection.
  • DDCMD_DISABLE_EVENT
Disable event detection in the device driver.
  • DDCMD_PAUSE_TIME
Pause time but do not pause stream.
  • DDCMD_RESUME_TIME
Resume time.
Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_REQUEST
Device driver does not support events. (Returned when ulCmd of DDCMDCONTROL is set to DDCMD_ENABLE_EVENT.)
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • ERROR_INVALID_SEQUENCE
Invalid device control command.
  • ERROR_INSUFF_BUFFER
The device driver does not have buffers to perform the requested action.
  • ERROR_STREAM_NOT_STARTED
The stream cannot perform the requested action unless the stream has been started.
  • ERROR_TOO_MANY_EVENTS
The stream handler attempted to enable too many events.
  • FAILURE
Device-driver-specific error return code.
Remarks

The stream handler uses this command to control the actions of the physical device driver.

Example Code

The following code illustrates the stream handler requesting the PDD to stop its current task, for example, the PDD stops playing audio.

#include        "os2.h"
#include        "os2me.h"
#include        "shdd.h"

  ULONG         ulRC;                      /* Error return code      */
  HSTREAM       hstream;                   /* Stream handle          */
  DDCMDCONTROL  ddcmdpb;                   /* Parameter block        */
  PDDCMDFN      pddcmdfn;                  /* Pointer to DDCMD entry
                                              point                  */
                            .
                            .
                            .
/*-------------------------------------------------------------------*/
/*  The stream handler directs the physical device driver to stop.   */
/*-------------------------------------------------------------------*/
  ddcmdpb.ulFunction = DDCMD_CONTROL;
  ddcmdpb.hstream = hstream;
  ddcmdpb.pParm = NULL;
  ddcmdpb.ulParmSize = NULL;
  ddcmdpb.ulCmd = DDCMD_STOP;

   if (ulRC = pddcmdfn (&ddcmdpb))
     return (ulRC);    /* error!  */

DDCMD_DEREG_STREAM

This message removes a stream instance from a device driver. The stream handler directs the device driver to deregister the stream-destroy the stream and all associated data.

Parameter - pParmIn

pParmIn (PDDCMDDEREGISTER) A pointer to a DDCMDDEREGISTER data structure.

Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • FAILURE
Device-driver-specific error.
Remarks
  • This message removes the communication link between the physical device driver and the stream handler for a particular stream instance. The only input is the stream handle, which indicates to the device driver which stream to destroy.
  • After a deregister, the VSD (or device driver) no longer has access to any buffers, and the buffers will be returned to SSM by the stream handler. The VSD does not have to return the buffers; they are returned for the it. The VSD should not return from the destroy until it has stopped using all buffers.
Example Code

The following code illustrates the stream handler requesting the stream to be de-registered.

#include        "os2.h"
#include        "os2me.h"
#include        "shdd.h"

  ULONG           ulRC;                    /* Error return code      */
  HSTREAM         hstream;                 /* Stream handle          */
  DDCMDDEREGISTER ddcmdpb;                 /* Parameter block        */
  PDDCMDFN        pddcmdfn;                /* Pointer to DDCMD entry */
                                           /* point                  */
                            .
                            .
                            .
/*-------------------------------------------------------------------*/
/*   The stream handler deregisters with the physical device driver. */
/*-------------------------------------------------------------------*/
  ddcmdpb.ulFunction = DDCMD_DEREG_STREAM;
  ddcmdpb.hstream = hstream;

  if (ulRC = pddcmdfn (&ddcmdpb))
    return (ulRC);    /* error! */

DDCMD_READ

This message performs a read from the device into a buffer.

Parameter - pParmIn

pParmIn (PDDCMDREADWRITE) A pointer to a DDCMDREADWRITE data structure.

Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • ERROR_INVALID_BLOCK
Invalid address passed in parameter block.
  • FAILURE
Device-driver-specific error return code.
Remarks

This message is used by a stream handler to give an empty buffer to the physical device driver. An example would be in an audio recording, where the physical device driver fills the buffer it gets from the stream handler . The pBuffer parameter is a pointer to the buffer to be filled in by the physical device driver. This pointer is either a physical 0:32 pointer, 16: 16 far pointer or a global linear pointer. This is defined when the stream handler registers a stream with the device driver using DDCMD_REG_STREAM.

Many devices cannot handle a 0 length buffer. If the driver receives a 0 length buffer, it should not reject the buffer. The driver should do nothing with the buffer and return it in the same order in which it was sent.

Example Code

The following code illustrates the PDD ready to receive an empty buffer from the stream handler.

#include        "os2.h"
#include        "os2me.h"
#include        "shdd.h"

  ULONG           ulRC;              /* Error return code            */
  HSTREAM         hstream;           /* Stream handle                */
  DDCMDREADWRITE  ddcmdpb;           /* Parameter block              */
  PDDCMDFN        pddcmdfn;          /* Pointer to DDCMD entry point */
  PVOID           pBuffer;           /* Pointer to buffer            */
                            .
                            .
                            .
/*-------------------------------------------------------------------*/
/*  Perform a read from the physical device driver.                  */
/*-------------------------------------------------------------------*/
  ddcmdpb.ulFunction = DDCMD_READ;
  ddcmdpb.hstream = hstream;
  ddcmdpb.pBuffer = pBuffer;
  ddcmdpb.ulBufferSize = 32768;

  if (ulRC = pddcmdfn (&ddcmdpb))
    return (ulRC);    /* error!*/

DDCMD_REG_STREAM

This message registers a stream instance with a device driver for the first time.

Parameter - pParmIn

pParmIn (PDDCMDREGISTER) A pointer to a DDCMDREGISTER data structure.

Values for ulStreamOperation include:

  • STREAM_OPERATION_CONSUME
  • STREAM_OPERATION_PRODUCE

Values for ulAddressType include:

  • ADDRESS_TYPE_VIRTUAL
  • ADDRESS_TYPE_PHYSICAL
  • ADDRESS_TYPE_LINEAR
Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • ERROR_HNDLR_REGISTERED
Stream had already been registered with the Sync/ Stream Manager.
  • ERROR_INVALID_SPCBKEY
Invalid SPCBKEY.
  • ERROR_INITIALIZATION
An error occurred during device initialization.
  • ERROR_STREAM_CREATION
An error occurred during the creation of this stream instance.
  • FAILURE
Device-driver-specific error return code.
Remarks

A stream handler must register its entry point with the device driver once for each stream instance. This message sets up the communication link between the stream handler and the physical device driver.

Example Code

The following code illustrates how to register a stream instance with a device driver.

 #include        "os2.h"
 #include        "os2me.h"
 #include        "shdd.h"

   ULONG           ulRC;                    /* Error return code      */
   HSTREAM         hstream;                 /* Stream handle          */
   DDCMDREGISTER   ddcmdpb;                 /* Parameter block        */
   PDDCMDFN        pddcmdfn;                /* Pointer to DDCMD entry */
                                            /* point                  */
   ULONG           ulSysFileNum;            /* Global file handle     */
   PSHDFN          pshdfn;                  /* Pointer to SHD entry   */
                                            /* point                  */
   SPCBKEY         spcbkey;                 /* Stream protocol key    */
                             .
                             .
                             .
 /*-------------------------------------------------------------------*/
 /*  Register a stream instance with a physical device driver.        */
 /*-------------------------------------------------------------------*/
   ddcmdpb.ulFunction = DDCMD_REGISTER;
   ddcmdpb.hstream = hstream;
   ddcmdpb.ulSysFileNum = ulSysFileNum;
   ddcmdpb.pSHDEntryPoint = pshdfn;
   ddcmdpb.ulStreamOperation = STREAM_OPERATION_CONSUME;
   ddcmdpb.spcbkey = spcbkey;

  if (ulRC = pddcmdfn (&ddcmdpb))
    return (ulRC);    /* error!*/

DDCMD_SETUP

This message performs device-specific stream instance setup.

Parameter - pParmIn

pParmIn (PDDCMDSETUP) A pointer to a DDCMDSETUP data structure. The pSetupParmand ulSetupParmSize fields refer to the SETUP_PARM data structure.

Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • ERROR_INVALID_REQUEST
Invalid setup request.
  • ERROR_STREAM_NOT_STOP
The stream cannot perform the requested function unless the stream has been stopped.
  • FAILURE
Device-driver-specific error return code.
Remarks

This message indicates to the physical device driver that a specific stream instance will become the active stream instance. The pSetupParm field is used for device-specific information. Typically, it is used to pass the current stream time from the stream handler to the PDD because a seek might have been requested on the stream prior to the stream start; thus, the PDD should adjust its time to this new reference time. Time is passed as a pointer to the time in milliseconds.

Example Code

The following code illustrates how to perform device-specific stream instance setup.

 #include        "os2.h"
 #include        "os2me.h"
 #include        "shdd.h"

   ULONG           ulRC;                    /* Error return code     */
   HSTREAM         hstream;                 /* Stream handle         */
   DDCMDSETUP      ddcmdpb;                 /* Parameter block       */
   PDDCMDFN        pddcmdfn;                /* Pointer to DDCMD entry*/
                                            /* point                 */
   ULONG           ulStreamTime             /* Stream time           */
   PVOID           pBuffer;                 /* Pointer to buffer     */
                             .
                             .
                             .
 /*------------------------------------------------------------------*/
 /*Activate a stream instance in a physical device driver (Switch    */
 /*                                                         context) */
 /*------------------------------------------------------------------*/
   ddcmdpb.ulFunction = DDCMD_SETUP;
   ddcmdpb.hstream = hstream;
   ddcmdpb.pSetupParm = &ulStreamTime;    /* Setting stream time */
   ddcmdpbp.ulSetupParmSize = sizeof(ulStreamTime);

   if (ulRC = pddcmdfn (&ddcmdpb))
     return (ulRC);    /* error!*/

DDCMD_STATUS

This message requests status from the device.

Parameter - pParmIn

pParmIn (PDDCMDSTATUS) A pointer to a DDCMDSTATUS data structure. The pStatusand ulStatusSize fields refer to the STATUS_PARM data structure.

Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • FAILURE
Device-driver-specific error return code.
Remarks

This message queries the status of physical device driver. This message might not be supported by all physical device drivers. It is commonly used by the stream handler to request the current stream time from the physical device driver.

Example Code

The following code illustrates how to request status from the device.

#include        "os2.h"
#include        "os2me.h"
#include        "shdd.h"

  ULONG           ulRC;                     /* Error return code      */
  HSTREAM         hstream;                  /* Stream handle          */
  DDCMDSTATUS     ddcmdpb;                  /* Parameter block        */
  PDDCMDFN        pddcmdfn;                 /* Pointer to DDCMD entry */
                                            /* point                  */
                            .
                            .
                            .
/*--------------------------------------------------------------------*/
/*  Get the current stream time from the physical device driver.      */
/*--------------------------------------------------------------------*/
  ddcmdpb.ulFunction = DDCMD_STATUS;
  ddcmdpb.hstream = hstream;
  ddcmdpb.pStatus =NULL;                    /* Return stream time*/
  ddcmdpb.ulStatusSize = 0;

  if (ulRC = pddcmdfn (&ddcmdpb))
    return (ulRC);    /* error!*/

DDCMD_WRITE

This message performs a write from the buffer to the device.

Parameter - pParmIn

pParmIn (PDDCMDREADWRITE) A pointer to a DDCMDREADWRITE data structure.

Return Value - rc

rc (ULONG) Error code indicating success or the type of failure:

  • NO_ERROR
Success.
  • ERROR_INVALID_FUNCTION
Illegal function requested.
  • ERROR_INVALID_STREAM
Invalid stream handle.
  • ERROR_INVALID_BLOCK
Invalid address passed in parameter block.
  • FAILURE
Device-driver-specific error return code.
Remarks

This message is used by a stream handler to give a full buffer to the physical device driver. An example would be the case of audio playback, where the stream handler passes a buffer with data to the physical device driver.

The pBuffer parameter is a pointer to the data buffer. Note that this pointer is either a physical 0:32 pointer, 16:16 far pointer, or a global linear pointer. The pointer type is defined when the stream registers a stream with the device driver (DDCMD_REG_STREAM).

Many devices cannot handle a 0 length buffer. If the driver receives a 0 length buffer, it should not reject the buffer. The driver should do nothing with the buffer and return it in the same order in which it was sent.

Example Code

The following code illustrates how to perform a write to the physical device driver.

 #include        "os2.h"
 #include        "os2me.h"
 #include        "shdd.h"

   ULONG           ulRC;                     /* Error return code      */
   HSTREAM         hstream;                  /* Stream handle          */
   DDCMDREADWRITE  ddcmdpb;                  /* Parameter block        */
   PDDCMDFN        pddcmdfn;                 /* Pointer to DDCMD entry */
                                             /* point                  */
   PVOID           pBuffer;                  /* Pointer to buffer      */
                             .
                             .
                             .
 /*--------------------------------------------------------------------*/
 /*  Perform a write to the physical device driver.                    */
 /*--------------------------------------------------------------------*/
   ddcmdpb.ulFunction = DDCMD_WRITE;
   ddcmdpb.hstream = hstream;
   ddcmdpb.pBuffer = pBuffer;
   ddcmdpb.ulBufferSize = 32768;

   if (ulRC = pddcmdfn (&ddcmdpb))
     return (ulRC);    /* error! */

Reprint Courtesy of International Business Machines Corporation, © International Business Machines Corporation