MMPM/2 Device Driver Reference:DDCMD Messages
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. |
Contents
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