This is file: 11_95QA.TXT

This file contains questions asked of the Driver Development Support Center
(DDSC) and the answers given to that particular question.  Entries are
appended to the top, so the most recent entry is available first.

Each entry starts with a header line that has a KEY WORD (or words) included
to allow the reader to "search" on KEY WORDS of particular interest.  Each KEY
WORD starts with the exclamation point character (!).  This allows for search
arguments that will limit matches to the header lines.

The following KEY WORDS are supported in this file.

KEYWORD                      DEVICES/TYPES OF QUESTIONS
===========   ==========================================================
!BASE         Loader, Memory Management, Strategy/Architecture
!I/O          Serial/Parallel, Pointing Device, Trackball, Keyboard, Pen
!MULTIMEDIA   Motion, Sound
!NETWORK      LAN,
!OTHER        PCMCIA, APM, Miscellaneous
!PRINT        Printer, Scanner
!STORAGE      DASD, SCSI, Tape, CD-ROM, ASPI, IFS
!VIDEO        VGA, SVGA, XGA, 8514, Display
**********    Entry separator (10 *'s)
==============================================================================



!MULTIMEDIA !DISPLAY____________________**********
November 20, 1995
QUESTION: (Ref: IR7)
I would like to call a DEVESC from within a customized VSD.  I know that to
call the DEVESC I need to call GreEscape, and to call GreEscape I first need a
device context from DevOpenDC, but how do I get an Anchor Block Handle (HAB)
needed to call DevOpenDC?  I need the HAB at the time I first open the
multimedia driver from within samples\ibmvidt\swvrcapt.c.


ANSWER:
You can use some dummy (-1) HAB  value. Refer to the following program for
sample DevOpenDC/DecEscape calls: \ddkx86\src\pmprint\qpapi.c


QUESTION:
I need to call DIVE whenever the Media Player opens my PDD for playing MPEG
files.  I understand that this call should be placed in a VSD.  My question
is:  what is the name of the VSD that the Media Player uses when opening its
PDDs?  Where is the source for this VSD to be found in the DDK, so I can
modify it?  If there is no VSD currently used by the Digital Video Media
Player, how do I couse one to be invoked, and is there a blank template for
one in the DDK?

ANSWER:
The Video Capture/Playback VSD is VIDVCIT.DLL.  The source is available in
DevCon DDK 2. The directory is - DDKX86\MMOS2\SAMPLES\IBMVIDT



!VIDEO__________________________________**********
November 1, 1995
QUESTION: (Ref: IS1)
I am currently working on a software MPEG player for OS/2.  The video portion
(using DIVE) is working fine but I can not get the audio portion to work.  The
audio data is produced by our software decoder and placed into a memory
buffer, and I thought that the best way to play out this data is to send it
directly to the audio PDD using DosWrite (Using a playlist seems too slow, and
I have little little control over it).  I wrote a small test program to see if
this work, but my program will get blocked inside the DosWrite call.

Here is my code (which is based on \ddkx86\TESTTOOL\PMADDE\pmadspi.c) (code
removed by DDSC):


Since both openAudioDriver and audioInit returned NO_ERROR, I am lost as to
what can cause the DosWrite to block inside the driver.  I would have thought
that even with bad data I should at least hear something.

Question:

1. What methods besides accessing the PDD directly can I play the decoded
audio data?  If there is a better way, I would appreciated it you can provide
me with some source code.

2. If accessing the PDD directly is the best way in this situation, I would
appreciate it if you can provided me with some working source code (preferably
with sample data) that shows me how to do it.


ANSWER:
1. Refer to DevCon 8 , Disc 3 , Directory Path -
\TOOLKITS\WARPTLKT\TOOLKIT\BETA\SAMPLES\ENTOOLKT\AUDIO\DAUDIO

DAUDIO.C -This program provides sample code for using the Multimedia API's
related to direct audio support.

2. The driver must make AUDIO_INIT and AUDIO_CONTROL IOCtl calls.  The
audioinit() routine in your code makes only AUDIO_INIT IOCtl call.

The member ulOperation of MCI_AUDIO_INIT structure must have the MSB set to 1.
Your code has the MSB set to 0. If the application specifies invalid data, the
device driver will probably not return an error.  Refer Remarks section of
AUDIO_INIT IOCtl call, chapter IOCtl functions in MMPM/2 Device Driver
Reference.  You should not use DosWrite.  We suggest you to use mmio calls
instead of Dos API calls.  You can use playlists to playout data as they have
higher performance.  Refer "10 Tips to Effective Multimedia Programs" in The
DevCon News Vol 3. for more information.  There are some sample codes
available in \source\mmpm2src directory in DevCon CD.




!OTHER__________________________________**********
November 1, 1995
QUESTION: (Ref: IU1)
1. How do I use multiple device headers?

I want to implement a single driver that controls multiple device objects.  I
have set up the assembly start up code to push the appropriate device indeces
on the stack before I dispatch to the driver's strategy routine and that works
fine.  BUT, the problem with multiple device objects in OS/2 is the discarding
of code and how to handle an error condition during initialization of a device
in the chain.

2. Is there any example code for initializing devices when using multiple
device headers?  Any tech notes?


ANSWER:
1) For each device header the corresponding strategy routine will be called at
its INIT entry point.You could have separate set of variables for each device.
Eventhough there are multiple device headers and strategy routines they all
finally call the same main() routine.  The final DS,CS values to be returned
correspond to this main() routine only.  Ref :  "Writing OS/2 2.1 Device
Drivers in C", Steve J. Mastrianni, Appendix-C, "C startup routine", Ch-5 fig
5-8, section titled "Strategy Section".  The kernel releases this memory after
calling all strategy routines at their INIT entry point.  Kernel waits till it
encounters the device header link terminator.  Even if the first INIT fails,
the kernel calls the INIT entry point of remaining devices.  You could however
have a global variable which could be set on any device failure.  On receiving
the the Init Request Packet,you would check for this variable and continue
further processing only if the global variable is cleared.

2) The printer driver in DevCon DDK uses multiple device header.  The source
code is available in the following directory \ddkx86\src\dev\printer.  You
could also refer to the Serial COMM Driver - \ddkx86\src\dev\atcom



!DISPLAY__________________________________**********
November 30, 1995
QUESTION: (Ref: IU2)
I am currently working on a new piece of hardware that support an overlay
scaler.  The hardware takes a source image (which must be in offscreen VRAM),
multiplies the image by a scale factor, and shows the image as an overlay on
top of the PM desktop.  I am already aware of the existance of the EnDIVE
template code in \DDKX86\SRC\PMVIDEO\PMACCEL in DDK 2.0, but is there any
source code that you can give me that implements EnDIVE on a similar device?

ANSWER:
The only other driver that implements EnDive & is available on the DDK is in
ddkx86\src\pmvideo\s3tiger Directory.This is the S3 PM Display Driver with
PMVideo Acceleration support.




!STORAGE__________________________________**********
November 30, 1995
QUESTION: (Ref: IU3)
We would like to support ATAPI Tape drives under OS/2.  What are our options?
I have noticed Warp takes over the atapi irq's (14,15) which is natural so we
must have some means to send CDB's to the drive.  Thanks for any info.

ANSWER:
I would recommend using the ATAPI CDROM filter as a guide in creating another
filter for the ATAPI tape.  Using the latest DDK , the scenario would be that
the tape filter would hook into the ibm1s506.add drive the same way as the
cdrom filter does.  Also, since the st506.add actually owns the IRQ, we can
have an interface card with both an atapi CDROM and the Tape on the same
channel.  Each would issue suspends to the ibm1s506.add driver when it wanted
control.  If one filter has the st506.add driver suspended, the suspend coming
from the second filter should be queued up so that we can share the resource.

QUESTION2:
That seems like a good idea.  I tried this but noticed the IBM1S506 driver
does not appear to support IOCC_ADAPTER_PASSTHRU.  Since tape drives use a
command set relatively disjoint from direct access devices, we cannot get by
with the subset that is implemented.  What now?

ANSWER2:
The ATAPI CDROM filter driver filters the ATAPI commands and services them.
Please refer to GetATAPIUnits() routine in ATAPINIT.C and ATAPIADDEntry()
routine in ATAPIORB.C in \ddkx86\src\dev\dasd\cdrom\atapi directory.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IU6)
When we try to lock a memory page not present with DevHelp_VMLock with EAX
(actions flag) set to 0x10, is the page made present by DevHelp_VMLock?

I'am not sure about the behaviour of VMLock when a requested page is not
present (physically mapped) in memory.  If everything is OK (plenty of
free memory for example) will VMLock fail or map the page in physical
memory?


ANSWER: (Ref:  IU6)
The VMLock will block until the page is available, if the VMDHL_NOBLOCK (Bit
0) is clear and the page is not present.  The VMLock will not bring the page
into the memory.

The page will be made present by the page fault handler if there is any
reference to the page.

If you try to long-term lock a memory which is already short-term locked, it
may not work.  How you are allocating the memory?  Are you commiting it?  If
this is ok and if you have enough free memory available then there should not
be any problem in locking.

Also ,if the user's buffer was allocated in the LDT tiled region,use the
SelToFlat Macro to convert the address to a linear address.This macro is
defined in DEVHLP.INC in the DDK.This linear address should then be passed to
VMLock.

QUESTION2:
An application is calling our device driver through a DYNAMIC API callgate.
It passes a 16:16 pointer to a buffer in its own local address space.  To be
sure the buffer is accessible at interrupt time, the device driver locks the
application buffer.  Here is what we do:

    struct something * pRequest;       /* pointer to application's buffer */
    LIN pLinRequest;
    UCHAR LockHandle[12];
    PUCHAR pVirtLckHndl;
    LIN pLockHandle;
    ULONG PageListCount;
    ULONG Length;                      /* length of application's buffer */

    DevHelp_VirtToLin(SELECTOROF(pRequest), (ULONG)OFFSETOF(pRequest),
                      (PLIN)&pLinRequest);

    pVirtLckHndl = (PUCHAR)LockHandle;

    DevHelp_VirtToLin(SELECTOROF(pVirtLckHndl), OFFSETOF(pVirtLckHndl),
                      (PLIN)&pLockHandle);

    DevHelp_VMLock(16L, pLinRequest, Length, -1L,
                   pLockHandle, &PageListCount);

Sometimes the last call (VMLock) blocks the calling thread forever, why?  What
would be the conditions that makes VMLock block forever?  Is there a way to
check prior to the call, if it will block?

ANSWER2:
The bit 0 of Action Flags in VMLock DevHelp call is set to 0 indicating that
if the region is unavailable, VMLock will block until the region is available.
If satisfying the lock request will reduce the amount of memory in the system
below a predetermined minimum, VMLock can fail.

The customer could check if he has sufficient memory in his system.  This
depends upon the number of drivers loaded previously and memory allocated by
them, the tasks running and the memory of the machine.

Refer section "VMLock", chapter "Device Helper Services" in Physical Device
Driver Reference.



!VIDEO__________________________________**********
November 9, 1995
QUESTION: (Ref: IU7)
I have a question involving the Presentation Manager driver for our graphics
board.

The entire VRAM for our board is memory mapped, and we would like to access it
from the PM driver.  Since the VRAM space is greater than 64k, we cannot use a
global selector to access it.  What we do is map the VRAM into the calling
processes memory space (using the routines based on MATROX.C).

We keep a table (PIDTable) of process IDs along with where the VRAM is mapped
within that process; so that we don't have to remap every time that process
calls the PM driver.

The problem is that if we don't clear PIDTable entries after a process ends,
the table eventually gets filled up.  We added code to clear PIDTable entries
in a procedure called TidyUp_Termination; and we added this procedure to the
process' exit list (using DosExitList during
OS2_PM_DRV_ENABLE(FillLogicalDeviceBlock)).

This works nicely most of the time; but there seems to be some applications
that call the PM driver after TidyUp_Termination; and since TidyUp_Termination
has removed that process' ID from the PIDTable, the driver does not know where
the VRAM is mapped within the caller's memory space.

Are we clearing PIDTable entries too soon?  Is there some call to the driver
that indicates that the calling process will never ever call the PM driver to
do anything again

ANSWER:
In DosExitList call, the invocation order can be specified.  A value of 0 are
invoked first and 255 are invoked last.  The Presentation Manager uses
A0h-A8h.

Use a value above this, preferably 255.  Refer to OS/2 programming reference
for more information about DosExitList call.




!OTHER__________________________________**********
November 1, 1995
QUESTION: (Ref: IU8)
I am trying to invoke a WIN-OS2 procedure from my vvd.

A winos2 program registeres a procedure which the vdd must call.

In my context hook I have the following code :

   VOID HOOKENTRY vmSendEvent(PHVDM phvdm,PCRF pcrf)
   {
      USHORT               x;

      for(x = 0;x < 100 && Session[x].hvdm != *phvdm;x++);
      if(x < 100)
         VDHPushFarCall(Session[x].pCallBack);
      //   Session[x].pCallBack is registered earlier by an winos2 program
   }

This code works perfect when I use a DOS based test program, unfortunally it
crashes WINOS2.

If I add VDHSwitchToVPM() before VDHPushFarCall(..)  then the WINOS2 procedure
is called a few times before WINOS2 crashes.  It has clearly something to do
with VPM and V86 mode, unfortunally I can not make it work :-(

I have also been unable to find any documentation on VWIN.SYS which should
support communication between win and os/2 programms, or is VWIN.SYS reserved
for use by display device drivers only ?

ANSWER:
Please refer to the article "Communication between OS/2 and Windows Processes"
in DevCon News Vol 2-4, by David Kenner.

The parameter to VDHPushFarCall should be V86-mode segment:offset address of
the V86-mode code to call, or selector:offset of protected-mode to call.  Make
sure yor are setting this address properly and you are in the proper mode
(V86/VPM).

You can switch to another protected mode stack (other than the default) by
using:

    VDHBeginUseVPMStack
    VDHEndUseVPMStack

Refer to \ddkx86\src\vdev\vvideo\vvuser.c for use of VDHBeginUseVPMStack and
also in detecting the VDM state (V86/VPM).  Since you mentioned that it works
sometimes, suggest you look for stack overflow.  You may need to check stack
usage within your winos2 program.  (Reduce nesting of calls and number of
local variables if possible in the function you are calling via
VDHPushFarCall).

Refer to "Virtual WIN-OS2 Support Device Driver" in Section "DOS Prorect-Mode
Interface Device Driver" in Chapter "InstallableVirtual Device Driver" in
Virtual Device Driver Reference.  Also refer to Display Device Driver for more
information about VWIN.SYS.

If the above do not help us ,give us some more specifics regarding the
interface exported for OS/2 and windows environment to support IPC by VWIN.SYS
(Virtual WIN-OS/2 support DD).




!NETWORK________________________________**********
Noember 9, 1995
QUESTION: (Ref: IV1)
I am looking for the NDIS-MAC sample code for both DOS and OS/2 version. How
can I get that ?  So far, I own DEVCON LAN system cds Volume 4, but I still
can not find it ?


ANSWER:
At this time, there are no NDIS-MAC samples for OS/2.




!VIDEO__________________________________**********
November 1, 1995
QUESTION: (Ref: IV3)
We use the SVGADATA.PMI file for our S3 card because we are NOT working with a
normal multisync monitor.  Unfortunately, we need to twiddle some bits on the
RAMDAC to change clock frequencies.  The PMI file looks like quasi C code, but
we need to know if how to modify it to our needs.  Is there any info on this?

ANSWER:
This information is documentted in the DISPLAY.INF file from the DDK.  Do a
search under "pmi" and you can find the information you are looking for.



!OTHER__________________________________**********
November 1, 1995
QUESTION: (Ref: IV5)
I recently installed OS/2 on a Compaq XL 5/90.  Just about everything works
except for kernel debugging.  I copied the following files into my root
directory from my installation CD

1) E:\os2images\debug\os2krnl   Size 724344
   E:\os2images\debug\os2krnl.sym
   E:\os2images\debug\os2ldr

Furthermore, I did a dir > com1 as per the instructions in Mastrianni's device
driver book and saw the listing on my terminal.

I believe that the connectivity is working.

However, when I reboot, I don't see a prompt on my terminal, nor can I break
into the debugger using ^C.

This worked on my Micron 486 box.

Is there something else that I should check?

ANSWER:
Create a text file (KDB.INI) on the root directory of the boot drive.  Inside
the text file, add the followign lines:

                .B 9600T 1
                G

Since you are using COM1, the ini file will set communications to com1.




!OTHER__________________________________**********
November 06, 1995
QUESTION: (Ref: IV8)
1:  I have a driver based on IBM1S506.ADD, and would like to use a 'better'
compiler that is more up to date than MSC6.  One of the key points I an
looking for is the use of 386/486 registers in all instructions when possible.
(i.e.  not -> mov ax, lo_word, mov dx, hi_word...  but -> mov eax,dword).

I bought Watcom C10.0, but found that their -3 (use 386 instructions) flag
really didn't work.  The 32-bit compiler does generate 32--bit register using
instructions, but it also insists on putting things into 32-bit segments,
which as far as I can tell, doesn't work in ADD-land.

Is there some experience with this sort of thing there at IBM?  I've tried
Watcom's Compuserve forum, and either get no answer or a 'well, thats the way
it is'...

I know that there isn't a really large performance hit for this, but we would
like to provide the best, fastest driver possible, and I would really dislike
having to take MSC's .COD output and edit it for 32-bit regs ans then assemble
it.....

2:  Are the DDTT testing scripts for the IDE disks on the DDK 2 really clean
and tested?  I had to do some editing to get them to run, and (especially the
lower level tests) ended up with a lot of what looked like errors, even when
using the most recent IBM supplied IBM1S506.ADD on a recently formatted and
installed disk drive.  Are these tests considered 'definitive' as far ase
driver functionality is concerned?  (OK, that's 3 questions...)

ANSWER:
1)You could use "USE16" segment attribute to create 16-bit segments with
32-bit instructions.  Refer to article "Writing OS/2 Device Drivers with
Watcom C" in Vol 7 of DevCon News.

The MAD16 Physical Device Driver uses Watcom C compiler 10.0 (B)to create a
16-bit segment with 386 instruction '-3'.  Refer SEGS.ASM which defines the
segment attributes.  Refer to the sample source code in the following
directory :  \ddkx86\mmos2\samples\mad16\pdd.

2) There were some bugs with the SCSI ADD Script file (extra blanks were not
allowed before & after the assignment operator).There are no known bugs with
the DASD IOCtl Scripts.If you could be more specific about the errors
encountered, in using the IDE Scripts,we could fix/clarify your doubts.  These
tests are not definitive and you should modify to test the extra functionality
that your driver has.




!OTHER__________________________________**********
November 20, 1995
QUESTION: (Ref: IV9)
I urgently need some information about memory mapping PCI boards.  I've got an
Imaging Technology PCI based frame grabber board with 4M image memory and 16K
of config space.  I have used the OEMHLP calls at the app level to read all
the registers and data and get the physical addresses of these 2 areas.  I am
using a PDD to try and map the addresses, similar to what I have done before
with ISA memory mapped adaptors.  This involves sending the physical address
down to the driver with a generic IOCTL call to map the address.  My driver
then does a PhysToUVirt to get a 16 bit LDT entry which is passed back up to
the application.  The application(written in VACPP) then takes the _Seg16
pointer and assigns is to a flat pointer which essentially performs the
thunk(I think, since this has always worked before on ISA bus) and I have
traced into the assembly code and it seems to be OK.  The problem is that I
get an exception every time I try to access any of the memory from the
application.  If I dereference the pointer in the debugger, it says that the
memory is not allocated.  Please help me.

One other thing, the PhysToUVirt docs say that it can only map 64K chunks.  Is
there any way to map the whole 4Meg buffer segment, or do I have to map 64
chunks of memory and keep track of them in the application?

ANSWER:
The PhysToUVirt DevHelp call returns virtual address.  Convert this virtual
address to flat address using VirtToLin DevHelp call.  The flat address could
then be passed to the application.  The application can now access data using
this flat address.

Set the request type for PhysToUVirt call according to your requirement (
SELTYPE_R3DATA for making the segment readable/writable with application
program privilege ).

PhysToUVirt DevHelp call can map only 64K chunks of memory.

You can overcome this limitation using VMAlloc call in the following manner:
1) Use VirtToLin DevHelp call to get the linear address of the variable
containing the physical address to be mapped.

2) Make VMAlloc DevHelp call with the Flags set to 0x30 ( VMDHA_PHYS |
VMDHA_PROCESS ) and the linear address obtained from step 1).Now this returns
the linear address of the memory location in the process context.

3) You can pass this flat address to the application, using which you can
acces the data in the application.  This method allows you to map more than
64K memory.

Refer sections "VMAlloc" and "VirtToLin", chapter "Device Helper Services" in
Physical Device Driver Reference.




!OTHER__________________________________**********
November 7, 1995
QUESTION: (Ref: IW1)
I need to write a PDD in either Medium or Large model (>64K code) and I can't
seem to get the Data segment in the right place.  When I build with small
model, the data segment is the first segment and my device header is where I
expect it to be.  However, any attempt to compile using either Medium or Large
model causes the Data segment to be placed at the end.  Steve Mastrianni's
book claims that large model PDDs are possible in special circumstances, but
he doesn't say how.  Can you help?

ANSWER:
You could create a large model driver with -Alfw complier flag(if you are
using C 6.0).  Use the appropriate library and change your .DEF file to order
the segments correctly,and to mark the extra segment as IOPL.

Refer to The Developer Connection News Vol.7 ,Article - Writing Device
Drivers:  Multiple Segments by Steve Mastrianni.

You could also refer to the sample large model driver in the following
directory - \ddkx86\src\dev\touchdd\didd & \dddd

An assembly program is required to order the segments.  The segments can be
ordered using the GROUP directive.  Sample assembly program is available in
\ddkx86\src\dev\touch\didd\segdef.asm file.




!OTHER__________________________________**********
November 20, 1995
QUESTION: (Ref: IW5)
I am looking for a possibility to provide VDPMI.SYS with a parameter to change
the Memory Limit Standard value from 4 MB to 64MB.  Unfortunately, both
VDPMI.SYS and VDPX.SYS are not documented in the Command reference (and not
very much in the redbooks as well ;-((

Why would I want to do such "global changes"?:

I need to change the settings for DOS-Sessions that can not be represented by
a WPS object, but rather are created "on the fly".  This happens if you call
COMMAND or ANY.BAT from an OS/2 Prompt, or, as in my problem, have a WIN
Application creating and executing a BATch file.  In this case there seems to
be NO possible way to change the settings of such a "Standard DOS Session."

I would also want to know if it is possible to switch the behavior of a
"Standard DOS Session" to FullScreen.

ANSWER:
1. The DosStartSession() function provides an environment pointer as one of
its parameters, which points to a buffer and is used when creating a VDM.
This buffer contains one or more DOS settings.  The user could use this to set
the memory limit using a small program which will also spawn the user's
application after creating a VDM session.  Here he can also specify the window
type.  Refer to section 11.1.3 "Starting a VDM from Another Application" Page
No.  206 in RedBook Volume 2 "DOS and Windows Environment".

2. OS/2 for the PowerPC has a new DOS setting DOS_SET that would control your
settings.This setting is not supported presently on OS/2 - Intel Platform.

3. From a windowed DOS screen the user can switch to FullScreen by

a) selecting the FullScreen option from the system menu
b) pressing Alt+Home key combination

4. You could have a Device Driver that monitors session switches and inject an
ALT+HOME when switch to a Window Session is desired.



!VIDEO__________________________________**********
November 27, 1995
QUESTION: (Ref: IX1)
As I recognized, the windows fullscreen VDD as selected with the entry
"display" in the section [386enh] of the "system.ini" gets not loaded
when I start a Win-OS/2 fullscreen session.

Therefore, I get serious problems, when I want to run a dual board
configuration under windows, because I have to switch between the boards.

Is it possible to load my own windows VDD under OS/2???

ANSWER:
The display driver in the "display" entry should be an OS/2 VDD.

It is not possible to load Windows VDDs under OS/2.You have to write VDDs
under OS/2.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IX2)
I am developing an os/2 device driver where I am using DMA buffers in memory.
When I allocate high memory with devhelp, how can I insure that the memory
will be in the range of DMA (First 16 Megs)?

ANSWER:
You have 2 options:

1. You could use DevHelp_AllocPhys.  Because this is a call from OS/2 1.3, it
is not capable of allocating memory that is located above 16MB.  It is not
recommended however, because of performance reasons.  Make sure MemType is set
to MEMTYPE_ABOVE_1MB to allocate high DMA memory.

2. The recommended approach would be to use DevHelp_VMAlloc.  This is faster
when considering performance.  Make sure the following bits are set in the
flag section of the call:

                --VMDHA_16MB to allocate memory under 16MB
                --VMDHA_FIXED to allocate memory that won't be swapped
                --VMDHA_CONTIG so the memory is contiguous
                --Do not set VMDHA_USEHIGHMEM

Here is the calling convention:

ULONG Flags = VMDHA_16MB | VMDHA_FIXED | VMDHA_CONTIG;
ULONG Size; /* Initialize to size of DMA buffer
ULONG PhysicalAddress = 0; /* Set this to anything but -1 */
LIN LinearPointerPhysAddr;
LIN LinearAddr;
PVOID SysReserved = 0; /* Not used */
.
.
.
DevHelp_VirtToLin( SELECTOROF(&PhysicalAddress),
                     OFFSETOF(&PhysicalAddress),
                     &LinearPointerPhysAddr);

DevHelp_VMAlloc(Flags, Size,
                   LinearPointerPhysAddr,
                   &LinearAddr, &SysReserved);

Now the physical address of the buffer you have allocated is located in
PhysicalAddress.  A linear address is also returned, if you want to access the
memory at device driver time, you must allocate a GDT selector and use
DevHelp_LinToGDTSelector call to access the memory.  If the memory should be
accessed by the application, use DevHelp_VMGlobalToProcess to convert the
linear address to a process virtual address.  If you call VMAlloc at init
time, you are garunteed to recieve your buffer, however if you must allocate
the buffer afterward, you may have problems getting it, since its a contiguous
buffer that DMA needs.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IX3)
PDD Reference info for DevHlp_VMProcessToGlobal refers in number 5 of a set of
numbered remarks to "using the FLAT selector".  How can a PDD reliably
determine what the FLAT selector is?

I know that 0158 and 0160 are what seem to be used for CODE and DATA FLAT
selectors, but I'd really hate to assume those values in the future and hard
code them.  Is there a service of some sort that will give me the FLAT
selector?  Is there somewhere I can look for it?

ANSWER:  (Ref:IX3)
You should not use hard coded values for FLAT selectors.  You could obtain a
GDT selector by using AllocGDTSelector DevHelp call.  You could then map the
linear address obtained from VMProcessToGlobal to the GDT selector using
LinToGDTSelector DevHelp call.

Refer sections "AllocGDTSelector" and "LinToGDTSelector", chapter " Device
Helper Services" in Physical Device Driver Reference.

Alternatively you could use DOS32FLATDS.References to it could be found in the
DDK Code.  To use DOS32FLATDS you could include the following in your .ASM
file :

extern          DOS32FLATDS : ABS
                :
                :
                mov     ax,DOS32FLATDS
                mov     ds,ax

Link the DOSCALLS.LIB and in the .DEF file IMPORT the following :

IMPORTS
DOS32FLATDS = DOSCALLS.370

FOLLOWUP:
I have no intention to use a hard-coded FLAT selector value in my code.  My
question referred to the matter-of-fact statement in the
DevHlp_VMProcessToGlobal documentation notes about "using the FLAT selector".
In developing OS/2 DDs for the past three years, I'd never come across a way
to obtain the FLAT selector from the kernel, so I was curious about just what
that statement referred to.  I'm well up to speed on mapping GDT selectors.  I
was hoping for a way to avoid having to allocate a whole bunch of them (a
couple hundred or so) to deal with some far pointers in my DD code.  I have
some legacy DOS driver code that is very much based around far pointers that I
use in an OS/2 PDD.  At any rate, I'll look for the DOS32FLATDS reference in
the PDD Ref.  That's one I've not run into before.




!STORAGE________________________________**********
November 30, 1995
QUESTION: (Ref: IX4)
How is the filterADDhandle derived?

The storage.inf file in DDK 1.2 seems to me to be rather ambiguous in some
areas when discussing how to build .FLT modules.

Are there any other sources for info on Filter drivers, besides Lockdrv?


ANSWER:
The FilterADDHandle can be obtained from the RegisterDeviceClass DevHelp call.
Refer to ATAPINIT.C in \ddkx86\src\dev\dasd\cdrom\atapi directory.

The Filter driver samples are available in the following directories under
\ddkx86\src\dev\dasd\cdrom directory.  \ATAPI, \HITACHI, \NEC, \SONY,
\TOSHIBA.




!STORAGE________________________________**********
November 30, 1995
QUESTION: (Ref: IX5)


Is there any sample filter driver that shows an encryption function such as
discussed in your storage.inf reference?

I wish to develop a modules that applies encryption to a particular partition
(drive letter) between OS@DASD.DMD and ST1S506.ADD

Is the lock filter the only *filter * sample in the DDK?


ANSWER:
There is no sample encryption filter driver available in the DDK.

Sample filter drivers are available in the following directories under
\ddkx86\src\dev\dasd\cdrom directory:

\ATAPI, \HITACHI, \NEC, \SONY, \TOSHIBA.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IY2)

I would like some clarification on the DevHelp_GetDosVar system service.  In
particular, I would like some further information on several of the fields
defined in the GlobalInfoSeg structure.

The Millisecs (ULONG) field is defined as "Time in milliseconds"

Is this a rollover from the Time (ULONG) field showing the current time?  If
that was the case, I'd expect that the Millisecs field would always have a
value in the range 0-999

If it isn't a rollover, what time is 0?  Is this an uptime counter?



ANSWER:

Time          - Time in seconds since 1/1/1970

Milliseconds - Value of a 32 bit free running millisecond counter.This value
               is zero when the system is started.  Hours - Refers to the
               current hour

Minute     - Refers to the current minute

Seconds    - Refers to the current second

HundredSec - Current hundredth of a second




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IY3)
We have developed a remote control software for DOS and Windows 3.x (with
communication via ISDN for the german market).  We would like to extend this
remote control package in such a way that user can remotely control an OS/2
Warp system.  There are *3* main questions for us.

1. How can a program simulate keyboard inputs for PM, protected mode character
and DOS applications ?

2. How can a program simulate mouse inputs for PM, protected mode character
and DOS applications ?

3. How can a program hook all output operations to the display ?


Before we set up a new os/2 project, we must be sure If we can handle the
above topics successfully.  It would be very nice if you could help us !

ANSWER: (Ref:  IY3)
(1), (2) :  You could use the MsgInputHook call to simulate user input, only
Keyboard and mouse for the PM.  Mouse and Keyboard messages injected into this
hook will have the same effect as if they were generated by the mouse or
keyboard device driver.  The messages are routed in the same manner as normal
user input.  Refer OS/2 V3 PM Program Reference for more info.

You could use Device Monitors to simulate inputs for protected mode character
applications.  The device monitor could insert the simulated data in the
required format to the physical device driver.  Refer chapter Character Device
Monitors in Physical Device Driver Reference for more info.  Also refer
section "Keystroke Monitors ", chapter " Physical Keyboard Device Driver" in
Input/Output Device Driver Reference.

There is a sample code available which simulates keyboard input to DOS
windows.  You could refer to this sample code ( CTRLAPPS.ZIP )

 - CTRLAPPS.ZIP

3) Refer article "Monitoring Display Driver Interface calls" by Mike Cooper in
DevCon News Vol 6 for info on hooking the display driver for redirecting
output.




!OTHER__________________________________**********
Novenber 30, 1995
QUESTION: (Ref: IY4)

I am looking for documentation, source code examples, ddk support, etc.  to
begin the development of this device driver.  I have developed a similar
device driver for a VMEbus embedded PC but this piece of hardware has an isa
style bus.

I have the PCI spec and it refers to BIOS support, I can see that my machine
is capable of the BIOS32 Services but as far as I know OS/2 device drivers are
16bit only and thus I would not be able to drive these.  The 16bit and 16
protect mode interfaces are described in the book but one must issue an int
1Ah for these services.  Am I able to do this from a device driver?  Are there
any DevHlp routines to drive these PCI services?


ANSWER:
Download OEMHLP.ZIP from the BBS.This contains sample codes for invoking PCI
Services both from Ring 3 & Ring 0. The Ring 3 Approach is for applications
which invoke the appropriate IOCtl.  (PCISAMPL.C) The Ring 0 Approach is the
one that you will be using from the Device Driver.  This basically utilises
the IDC to establish link with OEMHLP$ . The PCI Services are supported on
Warp and not on OS/2 2.1





!OTHER__________________________________**********
November 20, 1995
QUESTIONl (Ref: IY5)
Where is the kernel debugger for OS/2 Warp Connect OS2KRNL date 4/5/95?

I attempted to do a CDINST from the Developer connection (8) and was told that
no symbols match my installed version.

ANSWER:
The KDEBUG for Connect is on the Connect cd \os2image\debug directory.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IZ2)
I would like some clarification on the INITIALIZATION COMPLETE strategy
command, 0x1f.  This is also refered to CMDInitComplete in Mastrianni's book.

Our device driver requires that some initialization be done at Ring-0.
Currently, we are waiting for the first request, checking a flag, and then
doing the initialization at that time.

Unfortunately, this initialization takes some time.

Does the 0x1f Strategy command execute at Ring 3 time like the INIT Strategy
command or Ring 0 time?  If it runs at Ring 0, our plan is to modify the
header to say we are a level 3 device and that we want to receive this
command.  When we get it, we will do our Ring 0 init.

Are there problems with this scheme?

ANSWER: (Ref: IZ2)
You have 2 choices:

1. INITIALISATION COMPLETE command is received at Ring 0.You could do your
Ring 0 INIT when you receive this command.

2.Alternatively, you can convert your driver to a BASEDEV.Base device drivers
are initialised at ring 0 .The INIT request packet command code is 0x1B rather
than 0x0.

- Device attribute field - Bits 8, 7 Bits 8 and 7 define driver as a Level 3
device driver, which indicates usage of the DWORD capabilities bit strip in
the header file.

- Capabilities Bit Strip - Bit 3 Bit 3 indicates that the driver is
participating in the adapter device driver strategy which, in turn, selects an
alternate INIT request packet format from the kernel.




!OTHER__________________________________**********
November 30, 1995
QUESTION: (Ref: IZ7)
When I attempt to use DosDevIOCtl ( 0x80, 0x0B ) to access the PCI Find Device
(sub function 1) I get a return code ov 65292 from DosDevIOCtl.  The handle
that I'm using is 15.  The Bus number and Device Function number are completly
invalid in the data packet.  I tried using the sample PCI code in DUDE, but
had to modify it for the 9 parameter version of DosDevIOCtl.

I'm calling it as such:

   rc = DosDevIOCtl ( hFileHandle,
                      OEMHLP_IOCTL,  /* 0x80 */
                      PCI_FUNC,      /* 0x0B */
                      (PVOID)&PCIParamPkt,
                      paramPktLen = sizeof ( PCI_PARAM ),
                      &paramPktLen,
                      (PVOID)&PCIDataPkt,
                      dataPktLen = sizeof ( PCI_DATA ),
                      &paramPktLen
                    );

The PCITEST program works correctly on DUDE and I can see the PCI registers on
the Miami chip through the Artic 960 debugger (mon960).  I have also written a
Windows VxD which calls the extended bios on the machine to get all the
necessary information so I know it works.  Do you have any thoughts?  Could
there be a problem with the 9 param version of DosDevIOCtl?  How can I use the
5 param version (I'm currently using VisualAge C++).



ANSWER:
1. There seems to be a problem in passing the FindPCIDevice parameter
structure.  Your application being a 32 bit, this structure may not be packed
to a byte boundary.  The byte alignment of the members in this structure is a
must , to be properly accessed by a 16 bit PDD such as OEMHLP$.  That is why
you may be getting the error 0xff0c for the FindPCIDevice call.  You could add
following statement before declaring the structure FindPCIDeviceParameters :

  #pragma pack(1)

and regenerate the program.  Let us know if this solves your problem.

2. Also,you should be use the 16-bit DosDevIOCtl interface (5 Parameters).
This is defined in BSEDOS16.H

#define DosDevIOCtl     Dos16DevIOCtl
extern "C"
{
USHORT  _Far16 _Pascal DosDevIOCtl(char * _Seg16 pData,
                                   char * _Seg16 pParms,
                                   USHORT usFun,
                                   USHORT usCategory,
                                   USHORT hDev);
}



