This is file: 03_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)
==============================================================================

!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref: GU2)
I have to port a DOS DLLMAC driver to OS/2 VDD.  Is it possible from the VDD
support the callback mechanism for DOS/WINDOWS session?  Can I call a
DOS/WiNDOWS Application entry point from the VDD?


ANSWER:
Yes, you can call a DOS/Windows application entry point from the VDD.  You
could use the VDHPushFarCall or VDHPushInt devhelps to call a DOS/WINDOWS
application entry point (Ref: VDD ref).

Refer to sources
    ddkx86\src\vdev\vtouch\vthook.c
    ddkx86\src\vdev\vmouse\vmhook.c  on use of VDHPushFarCall.

Refer to sources
    ddkx86\src\vdev\vvideo\vvmode.c
    ddkx86\src\vdev\vkbd\vkbdinit.c  on use of VDHPushInt.

Before calling DOS (V86 mode)/windows (v86 protected mode) entry points you
need to detect the VDM mode and switch to either v86/v86 protected mode.  To
do that use the flVdmStatus flag (defined in ddkx86\h\v8086.h).  Refer to
ddkx86\src\vdev\vvideo\vvuser.c on using the flags and use of VDHSwitchToVPM
and VDHSwitchToV86 devhelps calls.

Also refer to the "Context issues" in the VDD ref for use of each of the above
mentioned devhelp calls.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GT9)
I'm looking to obtain a software techincal reference for the 601 (for PowerPC
work), to understand the details of the assembly code instructions.  Where
would I get such a beast from?


ANSWER:
Read DUDE BBS bulletin dated 6/27/94.  It describes the recomended books for
PPC development.




!OTHER__________________________________**********
March 31, 1995
QUESTION:  (Ref: GT7)
Is it possible to build a VDD with the Borland C 4.0 compiler?  Are there any
restrictions?  Can you give me a brief description of how I can do it?  I
found the BORLAND.TXT file that specifies command line options for DDs but I
do not understand which one it is for, PDDs or VDDs.


ANSWER:
If Borland 4.0 is a 16-bit compiler, then the answer is no because VDDs are
32-bit drivers.  Use a 32-bit compiler for VDDs and a 16-bit compiler for
PDDs.




!I/O____________________________________**********
March 31, 1995
QUESTION: (Ref: GT5)
I have modified the code for the ibm1s506 driver to use it with our adapter.
Among other changes, I have added code to allow 32 bit i/o transfers since our
adapter supports it.  On OS/2 2.1 the driver works fine.  On WARP, when
config.sys has been set so that it boots only to the command line, it works
fine.  However, when it is set to boot to pmshell, the system either hangs
just before it should come up, or it gives the following message and then
hangs up:  The file PMMERGE->DOSCALLS specified in the PROTSHELL statement on
line 1 of the CONFIG.SYS file does not contain a valid program.  When I remove
the code for 32bit xfers, the driver works fine and is able to boot to
pmshell.  I have traced through the 32 bit xfers, and they seem to behave
properly.  I would greatly appreciate any clues as to why the 32 bit xfers
might cause this problem when booting to pmshell.


ANSWER:
This generally indicates a data integrity problem with the driver especially
transfers >64KB or handling requests in a multithreaded environment.

There is no inherent reason that OS/2 would operate differently depending on
the data transfer width from the adapter.




!STORAGE________________________________**********
March 31, 1995
QUESTION: (Ref: GT5)
Our card is a PCI SCSI adapter which MAY or MAY NOT have an expansion ROM.  We
also have a config.sys loadable device driver for DOS and are currently
debugging one for OS/2.  The int 13h ROM driver, of course, only handles
disks, but it's enough to get the system off the ground.  The problem is:
during initialization of the .add driver, we need to know if the ROM driver is
present.  This is because (1), until system initialization has completed, we
need to know to pass any interrupts for our card not caused by a request in
the .add driver back to the ROM driver (until system initialization is
complete), and (2), after system initialization completion, we need to disable
that driver.

Under DOS, we detect the presence of the ROM driver by issuing a non-standard
int 13h call; if we get the "proper response," we then issue that same int 13h
call with a different parameter, which causes the ROM driver to disable
itself.

How can we accomplish this in our .add driver?  Is there a better way of
detecting the presence of the ROM driver and causing it to disable itself?  We
have tried executing the int 13h call from the .add driver, but this causes
OS/2 to trap.


ANSWER:
There is no capability of executing INT instructions from an ADD driver.  If
your ROM is designed to run in 16:16 protect mode you could arrange to call it
in protect mode, however, this approach is discouraged.

Option roms may be located by mapping a selector to the C0000-DFFFF region of
physical memory and doing a scan a 2K boundaries for your copyright or other
item unique to your ROM.

We do not understand the scenarios posed in #'s 1,2 of your note.

During system initialization, calls to your ADD Driver and BIOS are
serialized, i.e.  your BIOS will not be entered while you are servicing an ADD
request and vice-a-versa.  Therefore there should be no need to reflect an
interrupt the ADD driver receives back to your BIOS.  When your BIOS rom is
called the system is actually operating in Real Mode so again, no interrupt
reflection is necessary.

You just need to make sure that during system initialization (until you
receive an IOCM_COMPLETE_INIT IORB) that when your ADD driver completes a
request, you leave the adapter in a state that is compatible with your BIOS.

After IOCM_COMPLETE_INIT is received, your BIOS will no longer be used so you
would not need to reset the card back to a BIOS compatible state after
processing an ADD request.




!I/O____________________________________**********
March 31,1995
QUESTION: (Ref: GT1)
I have a user defined IOCTL (i.e.  the category is greater than 127).  I issue
a DevHlp ProcBlock call.  If the ProcBlock is interrupted, it appears that I
am supposed to return an error code of:

  ERROR_CHAR_CALL_INTERRUPTED

What do I place in the REQPACKET status field?  If I code:

  return( RPERR | RPDONE | ERROR_CHAR_CALL_INTERRUPTED );

I would expect my calling routine to get a return code of 0xFF11 because I
have a user defined IOCTL.  Does the suggestion regarding an interrupted
ProcBlock only apply to IOCTL categories 0-127?


ANSWER:
If bit 15 in the RP status field is set it indicates that low 8 bits (0-7) of
the status WORD indicate the error code.

This error code is processed by OS/2 in the following way -

1) If IOCtl category is user defined, FF00H is ORed with error code
2) If not user defined and bit 14 is set, FE00H is ORed with error code
3) Else error code must be one of 00h - 15h and is mapped to one of the
standard OS/2 API return codes.

The error code (bits 0 - 7) can be anything in case 1, case 2. It is user
dependent. RPDONE and RPERR have to be set in any case.

In your case, the DD returns (RPERR | RPDONE | ERROR_CHAR_CALL_INTERRUPTED) to
the Kernel and the Kernel would return 0xFF11 to the application.  Refer to
the Physical Device Driver Ref.,Chapter - Generic IOCtl Commands.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GT0)
I am attempting to build the com.sys driver contained in the atcom directory
of 1.2 ddk.  During the assembly of atintrpt.asm I get an error
..\dos\inc\osmaca.inc(925) error A2009: Symbol not defined: FLAT
I have tried the source from the devcon 6 directory and get the same. Can
someone try this for me as a sanity check?


ANSWER:
Check your PATH and make sure that you are using the tools directory included
with the DDK.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref: GS0)
I finally received the Microsoft Window 3.1 DDK Modified Code for WIN-OS/2
Seamless VGA, and I tried to use DebugOut defined in

  WINOS231\DRIVERS\DISPLAY\4PLANE\DEBUG.ASM

with my own seamless driver so that I can see debugging information from my
kernel debugger terminal.  I have no luck with it at all.  When I trace into
the module, I can see that it is doing everythign correctly until it gets to
terminate_and_send:

;       /* NULL terminate the string and make the call to VXMS */
;       /* ES:DI = array;
;       /* DS:SI = "VXMS";
;       /* AH    = 2;

        mov     BYTE PTR es:[di], 0
        mov     di, OFFSET array
        mov     si, OFFSET vxms_id
        mov     ah, 2
        int     66h


and nothing hapens.

1. Does this only work with the VGA seamless driver, or can I use DebugOut
with my own seamless driver?

2. Is there any documentation about this int 66h call?


ANSWER:
1.In DEBUG.ASM ,instead of the INT 66h Section of the code,use the Windows API
- OutputDebugString. Let us know if this helps.

2. We do not have any additional documentation on the int 66h call.
==============================================================================

FOLLOW-UP QUESTION:
I tried using OutputDebugString as you have suggested, but the linker cannot
find this function.  I looked in the Windows 3.11 DDK and found that there is
a function called DebugOutput used to build the macro DebugErr in
/286/display/4plane/debug.inc, which I tried to use, but this turned out to be
a dummy function (it does a retf and nothing else).

I don't think calling either DebugOutput or OutputDebugString (if it exists)
will help because these function are presumably present only the the debug
version of the Widows kernel, which will not work under OS/2.

I also tried outputting to the port directly using BIOS int 14, but this
invariably hang the whole computer after sending some garbage on the screen.

I would really appreciate it if you can give me some sample code that will
show me how to make it work.


FOLLOW-UP ANSWER:
OutputDebugString is a Windows 3.1 API - refer to the documentation on Windows
Kernel Functions.  Try using the library - swinlibc.lib.  Here is the sample
code -

externFP    OutputDebugString

public DebugOut
DebugOut PROC FAR

        :
        :
        :
        :
;<001> Start
        ; NULL terminate the string and call OutputDebugString.
        mov     BYTE PTR es:[di], 0
        mov     di, OFFSET array
        push    es
        push    di
        call    OutputDebugString
;<001> End.


if 0    ;<001>
;       /* NULL terminate the string and make the call to VXMS */
;       /* ES:DI = array;
;       /* DS:SI = "VXMS";
;       /* AH    = 2;

        mov     BYTE PTR es:[di], 0

        mov     di, OFFSET array
        mov     si, OFFSET vxms_id
        mov     ah, 2
        int     66h
endif   ;<001> if 0
        :
        :
        :
DebugOut ENDP




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GR8)
I am trying to compile the SERIAL.PRD dll (serial port driver) in the DDK
source (\DDKX86\SRC\SERIAL\SERIAL.C).  NMAKE fails looking for a file
"..\..\h\version.h".  I can't find it?


ANSWER:
The nmake is looking for - ddkx86\h\version.mak.  This file is included on the
DDK.  If you have made changes to the makefile, please change version.h to
version.mak in the makefile.  Let us know if this helps.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GR7)
The device driver kernel services seem to have been designed and implemented
as an arbitrary combination of the 16 and 32-bit Intel addressesing models.
Please confirm that the following understanding of kernel services is correct.

Due to unsupported kernal services, it is necessary to develop in a 16-bit
model not only WITHIN the device driver, but also in any application designed
to "wait" on a semaphore that is signalled by interrupt context device driver
code.  This is because OS/2 does not support semaphore operations on 32-bit
semaphores during interrupt context.

We chose OS/2 specifically because it is promoted as an operating system that
provides preemptive multi-tasking (multi-threading) capabilities and
synchronization primitives for 32-bit applications.  The application we are
attempting to port to OS/2 contains external processors that send messages to
the PC via dualport memory and then interrupt the PC to signify that the
message data is available to be read.  Our 32-bit application is already
implemented to read the data generated by the external subprocessor whenever
the interrupt event occurs, so a natural design was to develop a 32-bit thread
that

- creates a 32-bit event semaphore
- passes its handle to the device driver via an IOCtl call
- loops forever, synchronizing each loop execution with a wait on the
32-bit semaphore. The wait would be signalled by the ISR, which would result
in the application thread executing and reading data from dualport only when
the external processor had provided notification that data was available...

The above design strategy was even discussed with the instructor at the
OS2DD101 course we recently attended.  Seemed reasonable at the time, to us
and to him.  But of course, as we discovered when we proceeded to
implementation, the needed kernel service, DevHlp_PostEventSem, is unavailable
to an ISR.

We now believe that we will be forced into a solution that is a bastardization
of our design:  the device driver will have to issue DevHlp Block and Run
calls, similar to the design used for synchronous Read/Write implementations.

1) Please confirm this belief.

If our belief is true, it seems to indicate a really serious flaw in OS/2:  it
means that those that applications designed to use all of the synchronization
primatives provided by the operating system can't be pure 32-bit applications
if they interface with the device driver world; it means that not only device
drivers BUT ALSO APPLICATIONS are not insulated from the 16-bit addressing
model.  And that's not what's being advertized.


ANSWER:
1. Indeed the DevHelpPostEventSem is NOT available at interrupt time as you
have found.  However, one can easily make use of the 16 bit system semaphore
from your 32 bit code to do exactly what you want.

Dos16CreateSem(state,&handle,pszname); then pass THAT semaphore to the DD,
which can then use the DevHelp_SemClear to post the semaphore for the waiting
thread.

I have sent the header file for this - ICADOS16.H

/**************************************************************************/
/*  icados16.h                                                            */
/* To use the ICARICDL routines from a 32 bit application, the            */
/* corrwsponding 16 bit OS/2 API's must also be used.  The following      */
/* declarations are drawn from the OS/2 1.3 Toolkit.  They have been      */
/* modified with the necessary C Set/2 keywords to identify the 16:16     */
/* items for thunking.                                                    */
/*                                                                        */
/**************************************************************************/

typedef unsigned short          HFILE16;
typedef HFILE16 *               PHFILE16;
typedef VOID * _Seg16           HSEM16;
typedef HSEM16 *                PHSEM16;
typedef unsigned char * _Seg16  PSZ16;
typedef unsigned short * _Seg16 PUSHORT16;
/*typedef VOID * _Seg16           PVOID16;*/   /* PVOID16 is in OS2DEF.h */

typedef struct _MUXSEM16 {
    USHORT zero;                        /* zero             */
    HSEM16 hsem;                        /* semaphore handle */
} MUXSEM16;
typedef MUXSEM16 * _Seg16 PMUXSEM16;

typedef struct _MUXSEMLIST16 {
    USHORT    cmxs;                     /* count of MUXSEM structures */
    MUXSEM16  amxs[16];                 /* array of MUXSEM structures */
} MUXSEMLIST16;
typedef MUXSEMLIST16 * _Seg16 PMUXSEMLIST16;

#define DEFINEMUXSEMLIST(name, size) \
    struct {                         \
        USHORT cmxs;                 \
        MUXSEM16 amxs[size];         \
    } name;



APIRET16 APIENTRY16 Dos16Open (
        PSZ16,                          /* path name of file to be opened */
        PHFILE16,                       /* file handle (returned )        */
        PUSHORT16,                      /* action taken (returned)        */
        ULONG,                          /* file's new size                */
        USHORT,                         /* file attribute                 */
        USHORT,                         /* action take if file exists     */
        USHORT,                         /* open mode                      */
        ULONG);                         /* reserved (must be 0)           */

APIRET16 APIENTRY16 Dos16Close (
        HFILE16);                       /* file handle                    */


/* Dos Semaphore routines                                                 */

APIRET16 APIENTRY16 Dos16CreateSem(
        USHORT,                         /* indicate no exclusive ownership*/
        PHSEM16,                        /* semaphore handle (returned)    */
        PSZ16);                         /* semaphore name string          */

APIRET16 APIENTRY16 Dos16OpenSem(
        PHSEM16,                        /* semaphore handle (returned)    */
        PSZ16);                         /* semaphore name string          */

APIRET16 APIENTRY16 Dos16CloseSem(
        HSEM16);                        /* semaphore handle               */

APIRET16 APIENTRY16 Dos16SemClear(
        HSEM16);                        /* semaphore handle               */

APIRET16 APIENTRY16 Dos16SemSet(
        HSEM16);                        /* semaphore handle               */

APIRET16 APIENTRY16 Dos16SemWait(
        HSEM16,                         /* semaphore handle               */
        LONG);                          /* timeout (in milliseconds)      */

APIRET16 APIENTRY16 Dos16MuxSemWait(
        PUSHORT16,                      /* index number of event(returned)*/
        PVOID16,                        /* semaphore list                 */
        LONG);                          /* timeout (in milliseconds)      */


****************************************************************************

2.The other alternative would be to allocate a context hook (using
Devhlp_AllocateCtxHook) during init/task time.  From the ISR issue a
DevHlp_ArmCtxHook.  The hook handler which runs in task context can issue
DevHlp_PostEventSem call.


RESPONSE TO ANSWER:
Thank you for a satisfactory solution. You made our day.

Consider our view of your two alternatives.  The second context-hook solution
is far superior since it completely shields the application from the 16-bit
implementation model.  All the workaround (unfortunately it's still a
workaround) aspects of the solution are imbedded in the device driver, which
will probably have to be completely rewritten for the 32-bit device driver
model, anyway.  Choosing the context-hook solution should allow the
application to suffer fewer changes when OS/2 finally becomes a native 32-bit
operating system, so that's what we're implementing...




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GR2)
Do you know if anyone has written an assert() function for Warp that I can get
my hands on for debugging purposes?


ANSWER:
Refer to the Minidriver Sample Code in DevCon DDK Version 1.The following
files define the assert macro -

ddkx86\src\prntdd\mdriver\assert.c
ddkx86\src\prntdd\mdriver\assert.h




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GQ7)
I have a 16bit OS/2 device driver that must "upcall" a ring 3 application.
This works fine when the ring 3 application is also compiled and linked as a
16bit.  We would like to have the application in ring 3 to be 32 bit for
compatibility and performance reasons.

I know that I could make the portion of the application that is upcalled from
the DD a 16 bit DLL, but then we will get into this multiple compiler
environment for building the application and other problems.

I would like to know if you can give me any advice on upcalling a 32 bit
function call from a 16 bit DD.  I assume the major problem in doing this is
the stack, but I believe we could fabricate a 32 bit stack before calling.

BTW, we use MSC 6.0a for the DD and IBM CSET++ for the app.


ANSWER:
1) Normally a R0 application cannot upcall or call a R3 application as it
violates the protection mechanism of the 80386 CPU.  Indirectly you could
achieve the same effect by having the R3 application spawn a R3 thread, which
creates an Event Semaphore, passes the handle to the DD via IOCtl call and
then blocks on the semaphore.  Once the thread awakens after unblocking from
the semaphore the thread could do a call to the required application code
(upcall routine) and then go back to wait on the semaphore after returning
from the upcall routine.

2) The DD can trigger the semaphore at task time using the PostEventSemaphore
devhelp whenever it wants to initiate an upcall sequence.  In case the upcall
has to be done during an interrupt sequence (interrupt time), the DD can use a
context hook (refer to AllocateCtxHook, ArmContextHook devhelps in PDD
reference) routine to do a PostEventSemaphore for initiating an upcall
sequence.




!BASE___________________________________**********
March 31, 1995
QUESTION: (Ref: GQ5)
For debugging purposes, at strategy INIT time, I wanted to issue a
DosPutMessage() with the physical address of my device driver's code and data
segments.

While describing the DevHlp VirtToPhys function, the Physical Device Driver
Reference mentions that the segment whose address is being converted should be
locked.  I issue the VirtToPhys for the data segment with no problem.  When I
attempt to issue the VirtToPhys for my code segment, very bad things happen
(tombstone).  I assume that the system is trying to tell me that the code
segment is not locked.

Q1:
At strategy INIT time, is is true that:

      a) The data segment is locked.
      b) The code segment is not locked.

A1:
The first data and code segments are always resident in physical memory.
Refer to PDD Ref., Chapter - PDD Architecture & Structure, Section - PDD
Programming Model.  Both the first Code & Data Segments of the DD are Locked
by the Kernel and an explicit Lock again is therefore not necessary for these
segments.

The Lock and VirtToPhys calls are useful only for extra segments (other than
the first code and data segments) or for objects allocated at INIT time and
used at interrupt time.
==============================================================================

Q2:
If I display the physical address for my data segment at INIT time, is that
physical address going to be the same as when I am in KERNEL or INTERRUPT
mode?

A2:
The physical address that you obtain for the Data Segment at INIT time will
remain the same in the KERNEL or the INTERRUPT modes as well.
==============================================================================

Q3:
Is it possible that OS/2 will move my data segment after strategy INIT?

A3:
OS/2 will not move your data segment after INIT.  If you just want to access
the physical addresses for debugging purposes then you may want to use the
kernel debugger to examine them at run-time.




!PRINTER________________________________**********
March 31, 1995
QUESTION: (Ref: GQ3)
The PM Chart application that comes with OS/2 2.1 contains a sample file
called green.grf.  The Postscript code that is generated by the Postscript
driver when this sample file is printed creates such a long complex path that
it causes a limitcheck error (offending command:  lineto) in our printer's
Postscript interpreter.  The problem is that at one location in the raw
Postscript file, there are over 3000 contiguous calls to the Postscript lineto
operator, all in a single path.  The driver is attempting to generate a
polygon on the page and then do a fill.  The function generating the
Postscript code is prdl_PolyLine() defined in module polystuf.c.  There is a
while loop in this file that is getting executed for a 3000 point polygon.

Since the limits placed on the Postscript path in our interpreter cannot be
expanded, I need to rewrite the driver so that once the number of points in a
polygon exceed a certain limit, the stroke and newpath operators are called to
clear the path.  In other words, polygon's will have to be rendered in
"sub-sections".  The concern I have is that there are fill operators and
possibly other operators that affect how polygons are rendered, and I don't
want to cause major regressions.

1) Is this rewrite do-able?

2) Can I just rewrite the prdl_PolyLine() function, or are there other
dependencies?

3) What other operators would affect how the polygon is rendered?  Any other
suggestions on how to solve this problem.


ANSWER:
We could not simulate the problem here.  The test was carried out in 2
different configurations :
1. HP Laserjet 4M Plus with the Warp Level Postscript Driver
2. IBM LaserPrinter 4039 10R with the OS/2 2.1 Level PostScript Driver.

If changing the driver does not help, you could consider the following
approaches :
1. Your presentation driver could hook the GrePloygonSet Function call.
2. Divide the area into Paths & Subpaths




!STORAGE________________________________**********
March 31, 1995
QUESTION: (Ref: GP9)
Currently, we are developing a 32-bit communication application for OS/2 and
we would like to catch requests for a remote file system from applicatons.  We
understand that a file system driver must be developed to accomplish what we
want, but we cannot find the IFS specification and the library for the file
system helper anywhere.  Could you please give me a reference to get the
information or better yet send me the information if possible?


ANSWER:
Download IFS.ZIP and IFSSRC.ZIP from the main file area of the DUDE BBS.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GP7)
Is it possible to switch to a new stack mapped to the data segment of the ADD?
I tried this, but I get a Double Fault when I execute an instruction that
loads the SS register.

e.g.    MOV     SS,AX

generates a trap 8.


ANSWER:
The ADD has to use the stack provided by the OS/2 kernel.  The OS/2 kernel
stores context information on the stack before calling the ADD.  When you
switched stacks the kernel lost track of the context info and therefore you
got a trap 8. Trap 8 is a double fault (request help on 1938 for more info on
this trap).

You cannot use your own stack instead of the kernelstack in the ADD.  This
would interfere with task switching by the kernel and the DevHelp services.
The kernel stack is 8K and you can expect about 4K when the DD strategy is
entered.  Please try to minimize stack usage by moving out large local data
structures to global data area.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GP6)
I need to know how to determine the version of OS/2, from a CMD file.  It is
my understanding, that our driver should not replace DSPINSTL.EXE if the user
has Warp.  So, I need to be able to determine the version of OS/2.


ANSWER:
Refer to the Procedures Language 2/REXX User's Guide - REXX Utility -
SysOS2Ver(). This utility returns the OS/2 Version Information in the form
'x.xx'.  You could use this result to determine future course of action.




!STORAGE________________________________**********
March 31, 1995
QUESTION: (Ref: GP5)
I am working on a DMD for an optical disk.  I am using an Adaptec AHA-1542
SCSI controller with the AHA154X.ADD driver.  The test machine has 16 MB RAM.
The hardware is validated and known to be good, including the SCSI controller,
bus, and peripherals.

During the (base) init routine, my DMD gets a device table and finds its units
(flagged to the ADD with the "/!DM" switch) using the IORB interface.  The DMD
successfully uses the IORB interface to allocate these units.  Return codes
and status are checked.

The DMD, still in init context, builds a scatter-gather buffer consisting of
one element that is 4096 bytes long, allocated with DevHelp_AllocPhys to be
contiguous (although one page is always contiguous).  Actually, the allocated
buffer resides at %%000b7000.  A scatter-gather list is built in the
DMWorkSpace area for this one buffer.  A CDB is built that sends SCSI_INQUIRY
with all fields (LUN, EVPD) set to zero, except for an allocation length (in
the CDB) of 0xFF, the maximum allowed in a 6-byte CDB, but which is certainly
smaller than 4096.  An IOCC_ADAPTER_PASSTHRU/ IOCM_EXECUTE_CDB is used to send
the SCSI_INQUIRY.

If I set RequestControl to zero, the SCSI bus hangs permanently, regardless of
whatever setting is used for Timeout.  If I set RequestControl to
IORB_DISABLE_RETRY, I can breakpoint the DMD immediately after the ADD call,
and I can inspect the various data structures with the kernel debugger.  All
of the data is valid, and my scatter-gather buffer contains the correct
response to the SCSI_INQUIRY command.  However, the IORB Status and ErrorCode
fields are both 0, including the IORB_DONE flag bit.

What appears to be happening is that the ADD is returning from the call into
it immediately, before the I/O has been performed.  Eventually the I/O does
get performed, but the IORB_DONE flag never gets set to notify me of this.  I
am not setting the IORB_ASYNC_POST flag bit in RequestControl, since there is
not much point to it in the init routine.

Q1:
I was under the impression that the ADD should not return from the call into
it until it was done processing my request, as long as the IORB_ASYNC_POST
flag is not set.  Am I wrong on this?

A1:
The add will ALWAYS return IMMEDIATELY, as this is an ASYNCRONOUS protocol
REQUIRING ASYNC_NOTIFY to be set.

See the OS2CDROM.DMD CDINIT.C code for the proceedure for handling this
syncronous use of the asyncronous callback ( you spin in the DMD waiting for
DONE to be set)

while ( (pIORB->iorbh.Status & IORB_DONE) ) /* Wait till done */
==============================================================================

Q2:
Why does the IORB_DONE bit in the IORB Status field never get set?  Why does
the SCSI bus hang permanently without IORB_DISABLE_RETRY?  I assume that the
bus hangs because the request is never completed, and that these two questions
may really be the same question.

A2:
Part of the problem is that the compiler optimized away a critical test for
the IORB_DONE flag bit.  The other part is that the SCSI bus hang problem will
not occur if the SCSI controller is programmed to avoid sending a "start unit"
command at power-on time.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GP4)
Where can I find specs on the OS/2 ASPI & VASPI programming interface?

1) Where is the documentation?
2) Can it be purchased in printed form?
3) Is OS/2 ASPI compatible with Adaptec's Specification?


ANSWER:
1)  OS/2 ASPI Spec's are located on the DDK. (Search on 'Adaptec')
    For VASPI you should contact ADAPTEC.

2)  A hard copy is avaialable from:

    Adaptec
    Literature Dept.
    MS/40
    691 South Milpitas Blvd
    Milpitas, CA 95035

    Adaptec BBS (408)945-7727

3)  OS/2 ASPI is Adaptec's Specification.




!I/O____________________________________**********
March 31, 1995
QUESTION: (Ref: GP3)
I have a 'basic' device driver that accepts DosDevIOCtl commands.  I do a
DosHlp.VerifyAccess for the parameters and buffer passed in the DosDevIOCtl.
I then write some information to an adapter board and issue a
DevHlp.ProcBlock.  My interrupt handler then gains control, and issues a
DevHlp.ProcRun for the blocked thread.

The Physical Device Driver Reference for DevHlp.VerifyAccess says that I do
not have to issue a DevHlp.Lock unless I yield the CPU.  Do the
DevHlp.ProcBlock and DevHlp.ProcRun calls constitute a yield?

The DevHlp.VerifyAccess description states that a device driver could yield
the CPU by:

  a)  Accessing a NOT-PRESENT-SEGMENT exiting its strategy routine.

  b)  Calling a DevHlp service that yields.

In the case of (a), I cannot find any other reference in the manual to a
"NOT-PRESENT-SEGMENT exiting its strategy routine" and am not sure what the
heck it means.

In the case of (b) I do not see any spot that documents whether a DevHlp
service may yield while performing its service.

Or should I just be a coward and always lock everything?


ANSWER:
ProcBlock call amounts to yielding. The thread making this call yields the CPU
to the next most eligible thread to run.

ProcRun does not amount to yielding. The target thread is removed from the
blocked queue and put in the ready queue. It will run at the next available
oppurtunity.

The "NOT-PRESENT-SEGMENT exiting its strategy routine" is to be read as
"NOT-PRESENT-SEGMENTand then exiting its strategy routine".  The implication
is the the DD trying to access a Not Present Segment and then reports an ERROR
to the kernel after exiting its Strategy Routine.

Some of the DevHlp services viz. SemRequest,AllocReqPacket,MonWrite to name a
few have provision to wait (specified in the flag parameter). If you specify
the wait option then the call will block and the thread will yield the CPU
otherwise not.

Yield & TCYield also yield the CPU.

When the DD yields CPU, all address access verifications that it has done
become unreliable, except for segments that have been locked.  That is why it
is advisable to lock segments before yielding.

Since you are using the Block it would be better to Lock the Segment.




!NETWORK________________________________**********
March 31, 1995
QUESTION:  (Ref: GP1)
I'm looking for documentation on the API for any form of network drivers that
will allow me to issue datagram-style messages from my OS/2 apps to my DOS
apps.  I've got the LAN developer DDK and cannot find a way to integrate the
DOS side.  I could, for example, use native NETBIOS datagrams.  For this I
need the NETBIOS$ or NETBEUI$ API.  Using NB30, I cannot talk to the DOS
client.

I'm not limited to NETBIOS, IPX or IP would be fine.  I just need to make sure
that I can get on the wire in a format that the DOS client can pickup.


ANSWER:
The NB30 netbios interface will allow OS/2 apps to communicate with DOS apps.
The LAN Tech Ref is an excellent pub describing the netbios NB30 interface.
The pub number is SC30-3587-00.  Please call 1-800-879-2755 to order the
publication.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref: GP0)
I am writting graphics accelerator driver with virtual screen support.  I want
to set mode when I receive a message from an application.  In eddq_Escape()
function, when I receive the mode setting message, I call
Vio32SetMode(&VioModeInfo, 0L) to set mode.  However, it didn't pass to BVH to
set mode.  I would like to know which functions I should call to invoke BVH to
set mode.


ANSWER:
Look at the setmode.c in the DDK xga/s3 display driver sources.  The call to
VIO is a 16bit call, so you need to link in the setmode.c as a 16bit file and
call the setmode function with thunked input parameters (see eddesres.c which
calls the switchtochosenmode).  If the new suggestion doesn't work, we suggest
you trace thru the DDK source for any VIO calls which occured before the
fillpdb (see eddefpbd.c) invoked the switchtochosenmode function.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GO6)
I am trying to output debug string messages through the kernel debugger to my
development system.

I have been trying to use the Debug32Output function but have not had any
success.  I have been able to compile and link successfully, but during
execution, when the function gets called, nothing happens.

Is there some setup magic that I am missing that I need to do before I use
this function?


ANSWER:
If we look at the debug routine code (defined in edddebug.c) the routines dump
output to the debug terminal only if the variable DebugOn is defined.  We need
some minor changes in the makefile.  Define EDD_DEBUG and XGADEBUG in the
makefile under the debug section.  When you do the debug build you should see
these variables defined for the compiler.  After building this version you may
verify the presence of the variable _debugOn in the map file.  This should
enable the output if everything else is fine.
==============================================================================

FOLLOW-UP QUESTION:
I have verified that the _debugOn flag is set to TRUE and have even put
breakpoints on the _OutputString function in edddebug.c to make sure that the
were getting called.

I am totally stumped as to why I don't get any debug output.  Any additional
suggestions would be greatly appreciated.

FOLLOW-UP ANSWER:
Add the /C1 switch to the DEVICE=C:\OS2\BOOT\PMDD.SYS statement in the
config.sys file.  If your null modem cable is connected to com2 of your test
machine, then you should use /C2.




!OTHER__________________________________**********
March 31, 1995
QUESTION:  (Ref: GO5)
Q1:
After installing our interrupt handler in the driver by hooking IRQ 0xA using
DevHlp_SetIRQ, we perform port i/o to instruct the DSP task running on our
board to generate interrupts and we read and update the masks for the 8529 PIC
controller at port address 0xA0 to enable interrupts.

While debugging the code with ASDT32, I get an "NMI Switch Interrupt (int 2)"
after enabling the appropriate bit of the 8529 mask for IRQ A. When this fault
occurs, I am expecting to hit a breakpoint in my interrupt handler.  Is it a
problem to set a breakpoint in an interrupt handler with a debugger so that I
can trace the execution of the interrupt routine?  Regardless of whether or
not I have a breakpoint in my interrupt handler I get the NMI fault.  I have
no evidence to believe that my interrupt has occurred nor have I any clue
regarding what is causing the fault.

A1:
You will not be able to debug Interrupts if you use ASDT32.  Try the Kernel
Debugger and let us know if it helps.
==============================================================================

Q2:
I have a hunch that it may be a problem for a PDD to talk directly to 8529
controllers at port 0x20 and 0xA0.  Should my driver be using IDC
(inter-device driver communications) to obtain services from the VPIC (virtual
programmable interrupt controller) driver?  I thought that calling VPIC is
usually done from a VDD.  Can you give me an example of how to call VPIC
services from a 16-bit PDD.

A2:
If you have a virtual device driver, then you can use any exported VPIC
interfaces.  Generally, a PDD does not call a virtual device driver, other
than its own (COM.SYS and VCOM.SYS communicate).

A PDD should not have to talk directly with the 8259.  The OS/2 Device Driver
Architecture does not want you to.  The only requests that a device driver
needs to make to the 8259 are to enable/disable an interrupt level and to mark
the end of an interrupt.  These functions are provided by the following DevHlp
Services (SetIRQ, UnsetIRQ, and EOI).

1) You can directly access the 8259 PIC (after disabling interrupts during PIC
access and restoring the previous interrupt status after accessing PIC is
complete).  But such an approach is not recommended because then your driver
needs to be modified if OS/2 is ported onto newer platforms or if there are
changes in DD architecture due to support for multiple processors as in OS/2
for SMP.

2) VPIC services do not provide you with the means to access 8259 registers
for setting interrupt masks etc.  VPIC is used to provide virtualization of
PIC for DOS sessions.  Ref:  VDD reference)

If you still want to use VPIC services you need to develop a VDD and establish
an IDC with this VDD.  The VDD can avail of VPIC services.

   Ref: Chapter 9, Mastrianni's book "Writing OS/2 2.1 Device Drivers in C".
         ddkx86\mmos2\samples\audiodd\audiodd.c
         ddkx86\mmos2\samples\audiovdd\vddinit.asm

3) Also, check with the kernel debugger if the mask status for your interrupt
is enabled on the PIC when the DSP init routine pauses for 100 ms and also
check status reported by DSP chip regarding interrupt pending status.
==============================================================================

Q3:
I have installed the kernel debugger rather than ASDT32 to debug my PDD as you
indicated that ASDT32 should not be used for debugging interrupt code.  At the
same location in my code I get the following fault message:

    "NWD WARNING: a failsafe timeout was detected at cs:eip = 170:fff458ac"

What does this message mean?

A3:
This warning is from the watchdog timer.  This means IRQ0 (timer) has not been
serviced.  Usually it is due to a device driver disabling interrupts too long.
The CS:IP values tell you what was executing at that time.

In OS/2 you cannot disable interrupts for more than 400 micro seconds.  This
is for performance reasons.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref:GO3)
I am writing graphics accelerator driver with virtual screen support.  I set
virtual screen to 1024x768 and set mode to 640x480x256.  OS/2 will start
correctly and the cursor can move anywhere inside the 1024x768 range.
However, if I open a DOS window, switch to background, and switch back to
foreground, the cursor movement is limitted to 640x480 range.  The cursor
movement range will not be set (restore) correctly from data given by PM
display driver, but somewhere it gets data from the actual set mode.

To show the cursor movement range is not set from data given by the PM display
driver but rather from the set mode, in eddm_Resurrection() function, I use
debug to trick the driver to set to another mode.  (No other parameter or
variables are modified; just use local struct variable to tell width, height,
and color depth).  The result is that if I set to 800x600x256 mode, the
movement range will be 800x600.  If I set 1024x768x256 mode, the movement
range will be 1024x768.

I would like to know how, in a PM display driver, I can tell the cursor (mouse
driver?)  to set movement range to virtual_screen_width x
virtual_screen_height when I switch back from DOS full screen.

ANSWER:
The boundaries used by the physical mouse device driver are set via a
DOSDEVIOCTL (cat 7 - function 51h - SetMode).  The base video handler is
typically the one who calls the mouse driver, informing it of the new video
mode.  The mouse driver will bound the pointer to the video mode limits.

The display driver writer can certainly call the mouse driver to give it the
virtual mode coordinates.
==============================================================================

FOLLOW_UP QUESTION:
You said that I can call the mouse driver to give it the virtual mode
coordinates.  Can I do it in PM display driver?  If yes, which category and
function # should I use?

In device driver reference, it said that cat 7 - function 51h will set to mode
which match the mode data specified in the Parameter Packet.  What I want is
to pass virtual mode coordinates, not to set mode.

FOLLOW-UP ANSWER:
The SetMode IOCTL in MOUSE.SYS (cat 7 - function 51h) does not set a video
mode.  It simply informs the mouse dd as to what the screen dimensions are so
that the relative mouse movements are correctly calculated to absolute
coordinates.  Please refer to the PDD ref for the specifics of this IOCTL.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: G02)
I am having trouble installing the debug kernel on my two machines.

The first, a 486DX2/66 running Warp (without WIN-OS/2), has a CD-ROM drive.  I
executed the CDINST.CMD command file on the Developer's Connection CD (vol 5),
and it said that it installed the debug kernel, but it doesn't produce any
output on a connected terminal, on COM1, when rebooted.

The second machine is a 386DX/20 running OS/2 2.1 (v6.514) without a CD drive.
I manually copied and renamed the files to install the debug kernel.  On
reboot, the initial "banner" display (3 lines of text stating this is OS/2
2.1, version 6.514, etc.)  displays very slowly, but then the rest of the boot
picks up, without any output on the connected terminal on COM1.

In both cases I use the other computer as the connected terminal.  I have
tried it with data and control leads connected, and with only data leads.  I
have tested the link using a terminal program on both sides and it works fine.
It just seems like the debug kernel doesn't use the COM port at all.  It
doesn't respond to the Ctrl-C, p, d, etc.  commands that it's supposed to.

ANSWER:
Check the DEBUG KERNEL Reference on the DDK. Do a search on PMDD.SYS.
It talks about a /cn parameter which will change the comport drive.





!I/O____________________________________**********
March 31, 1995
QUESTION: (Ref: GO0)
Q1:
In the PhysToGDTSelector call you pass the length of the physical address in
the CX register. I need to map 65536 bytes (i.e.  64K), so do I pass 0x0000
as the length?

A1:
Yes - A value of zero in CX indicates 65536 bytes.
==============================================================================

Q2:
The 32-bit DosDevIOCtl function has nine parameters:

  DosDevIOCtl( HFILE  DevHandle,
               ULONG  ulCategory,
               ULONG  ulFunction,
               PVOID  pParmList,
               ULONG  ulParmLengthMax,
               PULONG pParmLengthInOut,
               PVOID  pDataArea,
               ULONG  ulDataLengthMax,
               PULONG pDataLengthInOut );

In my device driver I want to fill in pParmLengthInout and pDataLengthInOut
with the number of bytes I am returning in the pParmList and pDataArea
fields.

I have not found any documentation on how you do this. Do I just replace the
lengths in the REQPACKET parm_buf_length and data_buf_length fields?

A2:
Yes, you could replace the parm_buf_length & data_buf_length fields in the
IOCtl request packet.  This will update the pParmLengthInOut &
pDataLengthInOut.  Refer to the CP Programming Reference - DosDevIOCtl API.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref:GN4)
I am writing a VDD to facilitate bidirectional communication:

        - between apps executing in VDM's,

        - between OS/2 apps and apps executing in VDM's, and

        - between OS/2 apps (this function is not a design goal
          but should follow as a matter of course)

The basic theory of operation is that a VDM app can call the VDD (via a
registered API) to either send or receive a message which is pointed to by
es:bx.  The DOS app is notified that the send/receive has taken place via a
call back, so a corresponding receive/send from the OS/2 or DOS app being
communicated with may occur subsequently.  Similarly, OS/2 apps call the VDD
via DosRequestVDD and are notified of send/receive completions via posting a
semaphore.

The problem that I am running into may be summarized as follows:

When called from an OS/2 app, the VDD can address VDM memory and OS/2 app
memory.  Specifically, a DOS app calls in with the address of a message to be
sent to an OS/2 app.  Subsequently, the OS/2 app calls in to receive the
message.  When the OS/2 app calls in, the two addresses passed into the VDD
interface procedure are accessible to the VDD as is the DOS app's memory.

However, when called from a DOS app, the VDD can NOT access the OS/2 app's
memory.  That is, an OS/2 app calls in to the VDD with a message for a DOS
app.  The addresses passed in are saved.  Subsequently the DOS app calls in to
retrieve the message and can not access the OS/2 app memory.

Q1) How can the VDD "nail down" the memory passed in from an OS/2 app?

Q2) How can that memory be subsequently accessed from the VDM context?

Q3) Can the VDM access memory in the OS/2 app other than that referenced by
pReqIn and pReqOut?


ANSWER:
A1) Use VDHLockMem DevHlp service to nail down memory passed by an OS/2
application. Ref VDD Ref Chapter 6 - VDHLockMem

A2) As per the design suggested by you, you could use VDHCopyMem Devhlp
service to copy data from an OS/2 application to a particular VDM.  You could
consider allocating memory per VDM basis for IPC between VDM's and OS/2
applications (using VDHAllocMem).

A3) No, not without using undocumented calls.

FOLLOW-UP QUESTION:
I probably should have been a little clearer in stating my first question.  I
realize that I have to lock the physical memory using VDHLockMem.  By "nail
down the memory" I really meant to say "create a pointer that can be used
subsequently from a VDM context or from another OS/2 context".  You see, the
problem is that I cannot (or don't know how to) ADDRESS the OS/2 program's
memory from a VDM context even though I am locking it (while still in the OS/2
context) with VDHLockMem.

I have tried using VDHCopyMem.  It seems to have exactly the same results as
programmatically moving the memory.

FOLLOW_UP ANSWER:
Refer to following sources in DevCon for OS/2 CD-ROM Vol-5
(Disk 1) \source\devnews\vol2\sample3\vdft.c   and
         \source\devnews\vol2\sample3\os2thrd.c

Here a message is posted by os2thrd.c using DosRequestVDD to the VDD generated
in VDFT.C.  In VDFT.C the OS2PostMessage routine copies the original OS/2
message into a buffer allocated via VDHAllocMem.  The pointer to this buffer
could be used in subsequent VDM context and could be freed up after use.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GN3)
1. What is the structure of the basedev init packet (1b?)  I don't have a ddk
so I can't look there for examples.  How do I release a basedev driver?

2. In a normal driver, I wan't to init some hardware and then release my
memory back to os/2.  I know how to do this.  How to I keep os/2 from
complaining?  I have to press a key to continue.  What bit's can I return (if
any!)  that will stop this?

I'm working on a couple of drivers for my sound card, a Cardinal Technologies.
If I write a basedev driver that writes the addres ad irq of my mitsumi cd-rom
to a port on the card, os/2 talks to my cd-rom.  Downloading some emulation
code into the card allows the Soundblaster driver to work.


ANSWER:
1) typedef struct _RPINIT {
    RPH rph;
    UCHAR Unit;
    PFN DevHlpEP;
    PSZ InitArgs;
    UCHAR DriveNum;
    } RPINITIN, FAR *PRPINITIN;

InitArgs member of the RPINITIN structure points to the following structure
typedef struct _DDD_Parm_List {
USHORT cache_parm_list; /* addr of InitCache_Parameter List */
USHORT disk_config_table; /* addr of disk config table */
USHORT init_req_vec_table; /* addr of IRQ vector table */
USHORT cmd_line_args; /* addr of command line args */
USHORT machine_config_table; /* addr of machine config info */
} DDD_PARM_LIST, FAR *PDDD_PARM_LIST;

Ref : ddkx86\src\dev\dasd\diskh\reqpkt.h
      ddkx86\h\dskinit.h

We would like to like to know what exactly you mean by "release a basedev
driver"?  If you do not want to install the DD after initilisation you could
return 0 in the EndCode & EndData Offset parameters in the InitExit Structure.

2) To prevent the system from pausing before starting the command processor
during the processing of CONFIG.SYS enter the following in your CONFIG.SYS:

   PAUSEONERROR=NO


FOLLOWUP QUESTION:
If I understand correctly, the difference between the INIT (0x00) and INITBASE
(0x1B) request packets is that INIT contains a pointer to the command line
args while the INITBASE contains a pointer to a structure (struct
_DDD_Parm_List).

Do they both use the same InitEnd packet?

What I meant by "releasing a basedev driver" was rleasing all memory back to
the system.  Returning 0 for both EndCode and EndData in the InitExit
structure.

FOLLOWUP ANSWER:
The Base Device Driver sends out the same InitEnd Packet as the DEVICE= Device
driver.  You could refer to some sample Block Base Device Drivers in the DDK.
One of them would be - ddkx86\src\dev\dasd\cdrom\atapi

The Request Packet structure is defined in ddkx86\src\dev\dasd\diskh\reqpkt.h




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GM9)
I am trying to compile a library (.LIB, not DLL) to bind in with my graphics
accelerator driver.  The library is for common graphics functions (host to
offscreen memory, set up ROP, etc.).

I have been compiling the LIB file with CL386.  With CL386, even with the /Ze
compiler switch, I can't seem to have any Microsoft C extensions in the code
(can't include ddk\h\memory.h without the compiler complaining it doesn't
recognize _far, for example).

Likewise, the in-line assembly code I've included (to get around the inability
to use the DDK\H include files) also doesn't work with the compiler (it
doesn't recognize _asm).

I've used "CL386 -help", but that's all the information I seem to get for
CL386, and as I say, the /Ze switch it mentions doesn't seem to work for me.

The three functions I'm trying to use are memcpy, inp (byte), and outp (byte).
Can you suggest how I might implement these in my library code some other way
(or give me an idea what mistake I'm making with the compiler)?


ANSWER:
You will have to include header files defined in ddk\h386 directory.  Memcmp
is defined in string.h in the same directory.  CL386 is a 32-bit compiler so
'far' keyword is not defined for it.  We did not face any problem with _asm
keyword . It should go thru.  As far as inp, outp are concerned, embed inline
assembly code for them.

MEMORY.H is not on the DDK.

You could also refer to some sample codes on the DDK -
ddk\src\vdev\vmouse\vmio.c
ddk\src\vdev\vvideo\vv8514.c



FOLLOWUP QUESTION:
I did have a MEMORY.H file in the \DDK\H path.  Perhaps it was from an earlier
DDK?  Anyway, I'm still curious to know why using CL386 with the /Ze (enable
extensions) compiler switch did not seem to enable the compiler to recognize
"_far".

I was able to get around my problems with memcpy, inp, and outp by NOT using
them from a library, but turning on the intrinsic inline compiler switch
(/Oi).  The old Microsoft C compiler documentation I have (which refers to
"Microsoft OS/2", ie it's that old!)  has a warning that you can't use
intrinsic inlining of the inp or outp functions with OS/2.  This is old
documentation, but I don't have any good detailed documentation for the CL386
compiler with OS/2 2.x.

Can you verify to me whether there is any problem using the intrinsic version
of inp, outp, inpw, or outpw under OS/2 (versus using the library version)?

FOLLOWUP ANSWER:
1.Refer to sample in the DDK - ddkx86\src\pmvideo\32bit.  inp,outp are used as
library functions in the sample source code.

2.Inline Assembly is used in ddkx86\src\vdev\vvideo\vv8514.c The DDK has
sample codes to both the approaches and hence both of them should work.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GM6)
I am currently writing a device driver for a LAN and Modem PCMCIA Card under
OS/2.  I have to redirect the IRQ if it is not my interrupt.  For instance,
redirect IRQ5 to IRQ3.  Under DOS, I just need to find IRQ3's vector and do a
far jump.  I don't know how to do this under OS/2 . So my complete question
is, how do I find another IRQ's ISR entry and jump during the interrupt time
under OS/2?


ANSWER:
IRQ redirection is not supported under OS/2.  The hardware interrupt manager
registers for all hardware interrupts in the interrupt vector table (IVT),
receives control on each interrupt and then calls device drivers that are in
its internal data structure.  A device driver's interrupt routine is added to
the internal data structure after calling DevHlp_SetIRQ.  There is no way for
a device driver to have access to this data structure to transfer ownership of
an interrupt to a device driver which is registered for a different interrupt
level.

There is a form of interrupt sharing that exists under OS/2.  Both drivers
register for the same interrupt level.  When the first determines that its
hardware did not generate the interrupt, it returns to the OS/2 hardware
interrupt manager with the carry flag set to indicate that it is not claiming
the interrupt.  The hardware interrupt manager then calls the next device
driver that has registered for the same interrupt level to service the
interrupt.  A device driver can register for more than one interrupt level.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref: GM2)
My PM display driver calls DosCreateThread, specifying the CREATE_READY
option.  It then calls DosWaitThread, to wait for the new thread to complete.

Unfortunately, the new thread appears not to start.  I see the new slot using
the kernel debugger, and its cs:eip point to the start of the thread function.
However, the thread does not execute (and the creating thread never,
therefore, resumes).  The .p debugger command reveals the new thread's status
to be crt.  I don't know what this means, but it doesn't sound good.

The creating thread is executing at ring 2 and I suspect this lies at the root
of the problem. The new thread has a ring 3 selector (which is what I want).

1. Is there a fundamental problem with creating a thread from ring 2?

2. Is there a better way to get my ring 2 thread to execute some ring 3 code
(I want to do a DosLoadModule on a DLL with a loadtime initialisation
function)?


ANSWER:
The crt status tells you that some other thread within the process is declared
a critical section.  This is keeping your thread from ever resuming.  Instead
of using DosCreateThread you may look into using _beginthread.  For example:

tid=_beginthread
DosSetPriority(PRTYS_THREAD, PRTYL_TIMECRITICAL...)

thread
        :
        :
        :
        DosSetPriority(Reg)

......................................................

ADDITIONAL NOTE:
I've tried out your suggestion and it works.  The crucial part turned out to
be setting the newly created thread's priority to TIMECRITICAL.  With this
priority, both _beginthread and DosCreateThread allowed me to create a ring 3
thread to call DosLoadModule.




!MULTIMEDIA_____________________________**********
March 31, 1995
QUESTION: (Ref: GL9)
We are having problems using the Video IOCtl Category 140 calls with the OS/2
Warp Real Magic Device Driver.  We are using the calls documented in the
Developer Connection Device Driver Kit for OS/2 V.1 1994.

The Device Driver is loaded and the Real Magic board works with the sample
OS/2 digital video player.  Our program opens the device driver, makes 4 query
calls, and closes the device driver.  Open and close are both successful, only
the Query Video Adjustments returns successfully but does'nt retrieve the
desired info.  The other 3 calls return with undocumented return codes in the
65xxx range.  The output we are getting is:

Q1:
Query Product Info
ulBytesRead = 194
Get Prod Info Call Error 65281

A1:
I do not recommend writing directly to the DD IOCTL interface.  Applications
should use the MCI APIs to talk to the DD.  As you will see in my answers to
your questions, some of the commands currently documented in the DD IOCTL
interface are intended for future expansion and are not currently being used.
By the way, the IOCTLs you refer to and the ones I mention below are the only
ones I know of that aren't supported by the RealMagic DD.  If a DD supports
the additional commands it should guarantee forward compatibility even though
they may not be used by the MMPM/2 subsystem currently.

As for your error above (Q1), the problem you are seeing is the structure you
are passing in is too_small.  Don't forget that OS/2 takes any Return code
from a DD and ORs the Return Code from the DD with 0xFF00.  So the return code
from the DD is 1 (VCA_INVALID_BUFFER) - the buffer address is INVALID or
TOO_SMALL.  The size of this stucture tends to grow from one release to the
next.  You may be using a back level VCADEVINFO structure, the current one
ends with a field HasPolarization.
==============================================================================

Q2:
Query Video Adjustments
ulBytesRead = 32
Call returned successful
set -1 -1 -1 -1
ret 1 2 3 4

A2:
This command is not supported by the RealMagic H/W and the DD is returning
something just to make the rest of the subsystem happy.  I am not sure if the
subsystem requires this command to be excepted and give a successful return
code (0).  If it does, the DD should return -1 (VCA_NOT_SUPPORT) for all
values to be exact.
==============================================================================

Q3:
Query Microcode
ulBytesRead = 272
Query Microcode Call Error 65535

A3:
This command is not supported by the RealMagic DD or the MMPM/2 MPEG H/W
CODEC.  The CODEC currently has the DSP filename hard- coded
"MMOS2\DSP\VREEL.BIN" and never asks the DD.  The MPEG H/W CODEC and RealMagic
DD will be changing to support this command.  Also, the unload Microcode will
give the same return code as this DD and H/W only support one Microcode load.
==============================================================================

Q4:
Query Image Restore Format
ulBytesRead = 268
Query Image Restore Format Call Error 65316

A4:
Again, this command is not currently support by the RealMagic DD and the rest
of the MMPM/2 subsystem never issues this command.  Currently the H/W MPEG
CODEC tells the rest of the subsystem what image formats are supported.  Also,
Set Image Format returns the same error as this H/W and DD only support one
image format.  Normally the image format is passed back in the Query Product
Info in the image format field.  The RC from the DD 0x24 function is not
supported.
==============================================================================

Q5:
We are currently trying to convert our current DVI application over to MPEG
and are trying to figure out what calls we need to make to accomplish the same
functions we use with DVI.  You said that we should use the MCI APIs to talk
to the RealMagic DD.  We are writing OS/2 FULL SCREEN applications and DO NOT
use PM.  Can we still use the MCI calls under a full screen environment?

I have been able to issue the following IOCTL commands with successful return
codes:

      VCAI_GETDEVINFO
      VCAI_SETCAPTRECT
      VCAI_PLAY

A5:
No, I still recommend using the MCI interface.  As you are starting to see,
the MCI/MMPM/2 subsystem does a lot to stuff for you.  Using the IOCTL
interface directly means you will have to read the MPEG file, split out the
audio and video data, send the audio data to the audio DD, and send the video
data to the video DD.  What I have heard about other people doing is to create
a small PM program that issues the MCI command and gets back responses from
the MCI.  Then have your full screen application talk to it thru shared memory
to cause the PM program to issue the MCI commands.  I think this would be the
least amount of effort on your part.
==============================================================================

Q6:
Are there any other calls I need to make before being able to playback MPG
files?  Do I need to explicitly set the Frames Per Second, Key Color and
enable Color Keying or are this already set by default?

A6:
No, they are already set by default.
==============================================================================

Q7:
In the structure below, what are ulSCR, ulPTS and ulAudioTime for?  Are these
something I need to fill in or something that is returned to me?

   typedef struct VCASTREAM {      /* STRM                           */
       ULONG ulLength;             /* Lenght of Image Data           */
       PVOID pImageData;           /* Pointer to Image Data          */
       ULONG ulFlags;              /* Flag info                      */
       ULONG ulSCR;                /* Video Stream Clock             */
       ULONG ulPTS;                /* Presentation Time Stamp        */
       ULONG ulAudioTime;          /* Current Audio Stream Time      */
   } VCASTREAM;

A7:
If you are playing a video only file (.VBS), these fields can be set to zero.
If you have audio (.MPG or .DAT), you will need to parse these values from the
MPEG file headers.  SCR is System Clock Reference, PTS is Presentation Time
Stamp - Time to display the video image on the screen.  AudioTime is the last
Time reported back from the audio DD (note:  this time is in MMTime format)
used to keep the video in sync with the audio.  The SCR and PTS values are in
the MPEG 90KHz clock values found in the file if the packet does not have a
SCR or PTS the field should be filled with zero.  For .VBS files you just read
in approx 2K of the file at a time and issue one play_Data after another once
the play_start is issued.
==============================================================================

Q8:
(a) How do I know when the board needs more data?  We can't just malloc 34
Megs for an MPG file, read the entire file in and point pImageData to it.  So
how do we know when to point pImageData to a new buffer?  (b) How can we check
the status of the playback and what frame the file is currently at?

A8:
If the board is given too much data it will put the calling thread to sleep.
The Idea is the caller will send data to the DD as fast as the device driver
will let it.  The buffers passed to the drive should be a packet's size,
usually about 2K.  The DD doesn't report this back currently but the MCI
interface does.
==============================================================================

Q9:
Re: the ulFlags field, I found this in the vidvci.h file:

      /* ulFlag    Defines  for VCASTREAM */
      #define  VCA_PLAY_START         0x01
      #define  VCA_PLAY_DATA           0x02
      #define  VCA_PLAY_STOP           0x04
      #define  VCA_PLAY_FLUSH          0x08
      #define  VCA_PLAY_PAUSE          0x10

START, STOP and PAUSE seem pretty obvious.  (a) Nevertheless, what are the
differences between STOP and PAUSE?  (b) Does FLUSH reset the board to prepare
it for more playback?  (c) What does DATA do and when do I need to use it?

A9:
VCA_PLAY_START - Start the playback
VCA_PLAY_DATA - Send data to be played back
VCA_PLAY_STOP  - Stop playback and discard unplayed data
VCA_PLAY_FLUSH - Flush out any unplayed data (must be paused)
VCA_PLAY_PAUSE - Pause playback do not discard unplayed data
==============================================================================

Q10:
In feeding MPG data to the board, do we just send it the data portions of the
file or do we need to send it all of the header information as well?

A10:
The packet level headers are removed and only the video (not audio) data is
sent to the video DD.
==============================================================================

Q11:
Where can I get a copy of the MPEG-1 file spec?  If there was a sample MPEG
device driver excersizing program, we would be able to figure all of this out
from that code.

A11:
I am not sure, but I've heard the MPEG committee charges $150+ for it.  Our
test cases are mainly at the MCI layer.




!STORAGE________________________________**********
March 31, 1995
QUESTION: (Ref: GL5)
I would like to know if I can use a filter driver to implement an IOCTL.  The
documentation says that only IORB request are passed thru the filter driver.
I would like to monitor commands sent to the ST506 driver and support an IOCTL
that would send commands to the ST506 driver.  So my questions are:

1. Are IOCTL requests to an ADD passed thru the filter driver?

2. Can the filter driver be opened like an ADD driver an support it's own set
of IOCTL command?


ANSWER:
1. Only DMD has IOCtl interface.  DMD converts IOCtl request packet to IORB
and passes it thru filter (if it is present) to the ADD.

2. A filter cannot be opened like an ADD.  It cannot have its own IOCtl
command set.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GL0)
Can you tell me how a application would go about issuing a SCSI pass thru
command?  I know my SCSI driver supports the IORB CDB pass thru, but I don't
understand how an app would get access to it?  Is there an interface to
OS2SCSI.DMD or SCSI.SYS?


ANSWER:
You can refer to sample source ASPIAPP.C in online "Storage Device Driver
Reference", under "Advanced SCSI programming Interface (ASPI) OS/2
specification".  This is for ASPI, but it holds for SCSI also.




!MULTIMEDIA_____________________________**********
March 31, 1995
QUESTION (Ref: GK2)
We have successfully written our device driver for Warp.  Now that this driver
is installed we only have one little problem.

Under a DOS session the IRQ's that we use for the Driver (IRQ 10) can't be
reused.  What we would like is for the device driver to have IRQ 10 for
standard sound effects while using the desktop, but when using DOS we would
like to use the same IRQ so that it is easier to configure the system.

We wrote our own file based on the AD1848 driver and are using the
AUDIOVDD.SYS file for the virtual device driver.

Is there a way to virtualize this IRQ without having to rewrite the
AUDIOVDD.SYS file?  We have the device driver DDK with the source for
AUDIOVDD.SYS.  Is there an easy way to modify this file to perform this
operation?


ANSWER:
Yes.  You need to modify your audio PDD based on AD1848 sample driver.  The
audio VDD expects the PDD to provide support for 5 IDC function calls and also
provides two functions for PDD IDC.  Refer to:

     ddkx86\mmos2\samples\pastk\audiovdm.c
     ddkx86\mmos2\samples\audiovdd\vddinit.asm
     ddkx86\mmos2\samples\audiovdd\vddstruc.inc

The PDD should inform two events to the audio VDD via the IDC interface
     - call VDD during PDD hardware interrupt processing when VDM owns the
       given adapter. Refer to AVDD_IDCEntry in:
            ddkx86\mmos2\samples\audiovdd\audioreq.asm
            ddkx86\mmos2\samples\pastk\audsubs.c, audintr.c, audiovdm.c

     - call VDD to inform that PDD does not require hardware adapter.
       Support provided in _vdd_report_device_free routine in
            ddkx86\mmos2\samples\ ad1848\entry.asm .

Note:  for details regarding the architecture and communication protocol
between PDD and VDD refer to Ch-3, VDD operations of MMPM/2 device driver
reference.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GK0)

Q1. Why is there no prototype for the Resource Manager function
RMGetDriverName?  It is in the RMCALLS.LIB and it is used by FLP1INIT.C

What is the prototype and can it be used?

Q2. The format of output from RMParseScsiInquiry is not like what I see in
RMVIEW for any of the adaptec device drivers.  What is the proper format?

Q3. Is Pbuf meant to be a near or farpointer?


ANSWER:

A1.
/************************************************************************
 *
 * FUNCTION NAME = RMGetDriverName
 *
 * DESCRIPTION   = Get init parms from BASEDEV command line
 *
 *                 VOID GetInitParms (PRPINITIN pRP);
 *
 * INPUT         = pRP              - Pointer to init request packet
 *                          pBuf             - Pointer to char buffer
 *                           size             - Buffer size
 *
 * OUTPUT        = none
 *
 * RETURN-NORMAL = contents of PSZ will be device driver name
 * RETURN-ERROR   = contents of PSZ will be nul
 *
 *************************************************************************/

VOID RMGetDriverName (pRP, pBuf, size )

      ---------------------------------------------------

A2. If RMVIEW reports something like:

    DISK_(#,#)  Quantum LPS240 .........

    Then you did not supply an Adjunct Structure containing the
    device's Target/Lun when the device was declared via RMCreateDevice.

    See "Resource Manager for OS/2" pp 1-6 "Device Adapter Keys" -
    Chapter 1 on Resource Management Architecture.


A3. pBuf is type PSZ which is a FAR POINTER to char.  On a successful
return,the contents of pBuf would contain the null-terminated device driver
name.If unable to determine the DD name,the contents of pBuf will be a zero -
length null-terminated string.




!I/O____________________________________**********
March 31, 1995
QUESTION: (Ref: GJ2)
While doing the 32 bit transfers, there is a problem after boot time which
seems to be caused by a scatter-gather segment which contains a number of
bytes which is not divisible by four, thus leaving one, two, or three bytes
leftover.

I was confused when trying to understand the rationale behind the way the code
in the addxferIOW function in the addservc.c file handles the case of one
leftover byte after word transfers.  It would greatly help me in trying to
solve this problem if I were able to better understand why this problem occurs
and what needs to be done to solve it.


ANSWER:
The rationale behind the way the code in the add_xferIOW function in the
addservc.c seems to be to -

   - do all I/O transfers as word transfers (since both the DMD & the ADD are
     16 bit drivers)

   - the data received from I/O transfer needs to be read/written from/to
     the S/G list which may not be always word aligned, hence the logic of
     using the Byteheld flag and the Data variable.

   - During I/O read operations the Byteheld flag indicates that the high
     byte of the Data variable contains the residual byte data to be written
     into the appropriate S/G buffer list.

   - During I/O write operations the Byteheld flag indicates that low byte
     of Data variable contains the residual byte read from the previous S/G
     buffer list.




!BASE___________________________________**********
March 31, 1995
QUESTION: (Ref: GI7)
Q1:
There is no device help or linker support that allows allocation of named
physical memory.  If an adapter maps memory outside the 640K-1Meg hole, the
only allocation solution seems to be trial and error, and this solution may
not always work.  Even if the adapter maps into the 640K-1Meg region, more
that one adapter mapping that area may result in collisions.  Need device help
enhancements that allow us to allocate named memory.

A1:
Besides VMAlloc there are no devhlps that allow allocation of named memory.
On Warp you could use the Resource Manager and reserve your resources with the
following statement as the first line in CONFIG.SYS:

             BASEDEV=RESERVE.SYS /MEM:CA00,100 /EXC

This would reserve memory CA00 : 0 for 100 byte Exclusive Access.
==============================================================================

Q2:
Can you direct me to documentation on the <RESERVE.SYS> device driver referred
to in the answer or provide a complete description?  The answer indicates the
subject memory would be reserved with "Exclusive Access."  What does that
mean?  Where do I obtain documentation on the "Exclusive Access" memory
attribute?

A2:
RESERVE.SYS and the "Exclusive Access" memory attribute is documented in the
Resource Manager documentation which is on the DUDE BBS(RMBASE).




!MULTIMEDIA_____________________________**********
March 31, 1995
QUESTION:  (Ref: GI2)

Q1:
We're writing an MPEG Video PDD.  Our customer does not like the idea of
having his DSP code filename being VREEL.BIN.  This filename appears to be
hardcoded.  Is there anyway to change it?

A1:
The CODEC currently has the DSP filename hardcoded "MMOS2\DSP\VREEL.BIN" and
never queries the DD.  The MPEG H/W CODEC and RealMagic DD will be changing to
support this.  The DD interface has an IOCTL defined to query the DSP filename
but the RealMagic DD doesn't support it.  However, we should ask the DD to
load their filename otherwise default to VREEL.BIN.
==============================================================================

Q2:
Why does the compressed video data come in through an IOCTL instead of through
the streaming interface?  I thought the stream handler device driver was a
much more efficient method of getting large amounts of data to a device
driver.

A2:
I am not sure the streaming interface is more efficient.  The reason the video
data is sent thru the IOCTL interface is that the CODECs are at Ring 3 and the
synchronous nature of the CODEC interfaced mapped better to the IOCTL
interface.  Also, the less code at ring 0 the better.
==============================================================================

Q3:
Is it possible for the MPEG Video PDD to get at the full system bitstream?
There are some new MPEG decompression suites coming out which will allow you
to send over the full system bitstream and it will automatically demultiplex
the data and play the video and audio completely synced.

A3:
Yes, we have a group that has written a CODEC and DD to this model.  At this
time I am not sure what the ship vehicle for this CODEC will be.




!OTHER__________________________________**********
March 31, 1995
QUESTION:  (Ref: GH3)
I have written a small assembler device driver which returns a pointer to
physical memory and will allow a ring-3 process to view or make changes to
linear memory outside its normal limits.

I need to hook the trap gates for several traps.  Right now I am using the
device driver to swap IDT entries (like old PC-DOS vector swapping).  This
seems to work to some degree.

The reason for needing to hook the IDT is that we wish to create a system that
will analyze a trap, at error time, for any given program, without any
modifications having to be made to the target program to allow analysis.

Q1:
Is there an easier, i.e. undocumented, way to accomplish this?

A1:
Exceptions can be trapped by a program using an exception handler as described
in the Warp Control Program Guide.  A new Device Helper,
DevHlp_RegisterKernelExit, was added to allow a physical device driver to trap
exceptions at ring 0.
==============================================================================

Q2:
Where is the new DevHlp routine documented?  I have the DDK v1.0/1994 and the
Developer CD #5.  I can't seem to find reference to it in my DDK.

A2:
I will mail the DevHlp_RegisterKrnlExit documentation to you.  Also, please
keep in mind that this new DevHlp is to be used only when trapping exceptions
at Ring 0. If you wish to trap exceptions at Ring 3, as your original question
suggested, please see examples in the Warp Control Program Guide.
==============================================================================

Q3:
Are there any examples of its usage, i.e.  a sample DD utilizing this helper
routine?

A3:
There are no examples of its usage.
==============================================================================

Q4:
Is the new routine only in Warp, or is it an undocumented function in 2.1 or
2.11?

A4:
This new routine is in Warp and OS/2 2.11 build 6.624 or higher.
==============================================================================

Q5:
Thanks for your help but I still have one problem.  The
DevHlp_RegisterKrnlExit symbol is not in the devhlp.inc file in the warp
toolkit on my developers CD #6.  Am I looking in the wrong place?  Is there
another library I should link with other than the os2286.lib in the warp
toolkit from the developers cd #6?  This devhlp routine sounds like what I
need, but I can't find it.

A5:
The DevHlp_RegisterKrnlExit is a device driver include file and is not
included with Devcon Volume 5 or 6. It is included with the Devcon DDK 1.0
product in the ddkx86\inc\devhlp.inc directory.




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: GH1)
How does one make BIOS calls from a PDD?  I can't find documentation on how to
do it and I've tried to do it and failed.  I'm just hoping for a "you're right
- you can't do that" or a "here's a pointer to where to see how to do that"
sort of answer on this.  It would make sense to me if the old interrupt
interface to the BIOS is not available in OS/2.


ANSWER:
You're right - you can't do that since OS/2 is in the Protected Mode and does
not support the BIOS Interrupts directly.  But what you can do is write a VDD,
which can issue BIOS calls.  PDD and VDD could communicate using the PDD-VDD
communication services defined in PDD reference.

You can also refer to OEMHLP$ driver described in "Writing OS/2 2.1 Device
Drivers in C", by Steve J. Mastrianni (Appendix-D).  Also, refer to ABIOS
services (Appendix-B, PDD reference)




!STORAGE________________________________**********
March 31, 1995
QUESTION: (Ref: GF3)
Our device supports 2 channels and 2 drives per channel.  Our driver will
determine if any or all drives support multi-word DMA and handle each one
accordingly.

For each DMA capable drive, we use hardware scatter/gather.  For the remaining
drives we use PIO or block PIO as appropriate.

1) The question is if one drive is PIO and the other drive is DMA on the same
channel, how should I set the AF_HW_SCATGAT flag?

2) What does OS/2 do differently based on whether you claim to support
hardware S/G or not?


ANSWER:
This flag has no real affect on the system since all addresses are passed to
the ADD as a scatter/gather list.




!BASE___________________________________**********
March 31, 1995
QUESTION: (Ref: GE8)
I'm still having problems with the VDHFindFreePages call. The documentation
says that one must supply a Starting Address that lies within 0 and 1MB+64k,
this is ok.  But, if I give it a range of pages that is 250 it won't return an
address. EG: VDHFindFreePages((PVOID)0L, 250L);

1. Does this mean that the entire space below 1MB is unavailable?

If I use 512 instead of 250, the call returns an address.  (I can't tell what
it is yet because I'm in the process of getting a 2nd machine to run a
terminal for the Kernel Debbugger.)

Even though it returns an address, if I use that address in the
VDHReservePages call, when I VDHMapPages in the CREATE hooked function using
the reserved area as target, I get a protection violation from the VDM.

If I specify 0xc1000 in the VDHReservePages at INIT, I can successfully
VDHMapPages in the CREATE.

2. Why do you suppose this is?  Could it be that VBIOS is using this area?

3. If so, what's the purpose of the VDHReservePages if it won't prevent VBIOS
from taking it?

I thought I should describe what I'm trying to accomplish so that you might
have better insight as to wether my approach is reasonable.

Background:
We sell a security package that provides resource security on DOS, OS/2,
UNIX etc..  In addition to this product, there are add on products that
provide single sign on security that manages IDs and PWds for secured
products such as Novell Netware, Terminal Emulation software accessing Host
secured product like TSO, VM, UNIX hosts, and so on.

The add on products that run in the DOS env. get access to the security area
via a device driver, which returns a pointer to the start of this area.  Yes,
I know of the potential problems with this approach, but lots of programs are
already written that use this access method and re-writing them to run in a
VDM would not be as cool as providing a VDD that simulates the real Dos DD.
We can load the DosDDs in each VDM via DOS Settings but this has the effect of
requiring the user to enter an ID and Passwd. for each new VDM that is
started. Not particularly sexy when we are supposed to be a Single Sign On
product (SSO).

My approach:
I have in mind taking the OS/2 security items area that is a replica of the
DOS area, and making it available to all VDMs as if it were owned by each VDM.

In the DOS env.  a pointer to that area is located right after the header of
the DD.  This is where the "little Dos Device Driver" comes in to play.  I've
created a little stub DD using VCDROM as a model.  It loads a device driver in
the VDM by calling VDHSetDosDevice.

Ideally, I would like to map (using VDHMapPages) the OS2 security area to an
address that falls in an area inside the little Dos DD.  This presents some
problems, one being that the target for the map needs to be page aligned,
another being that the Map function won't let me because it complains of the
segment being in use by another process, I'm supposing that the VDM Manager
owns it.

The reason for mapping into the DosDD is that I don't think that 0xC1000 will
always be available.  I don't think it would be good practice to hard code
this address in the DosDD.  If I could get an area above 640k with
VDHFindFreePages, I would use it by sticking that address into the DosDD after
it gets loaded using a VDD to Dos Link function (also in VCDROM).  The problem
remains that I can't seem to use the address returned by VDHFindFreePages in
the ReservePages without conflicts in the MapPages.


ANSWER:
There seems to be a minor error in your VDHFindFreePages((PVOID) 0L,250L);
Here the second parameter (250L) should be the address of a ULONG variable in
which VDHFindFreePages call expects count of pages to scan and also returns
the count of pages in a free region if the call is successful (Ref : vdd ref
for VDHFindFreePages).

In order to get free mapped area above 640KB with VDHFindFreePages as per
your design, we suggest you do the following :-

Add the following lines to your code ---

#define PAGESIZE 4096
#define STARTDOSMAPADDR 160 * PAGESIZE /* start scan from 640KB and above */

/* VDD global vars */
PVOID pFreeDOSMem, pLinAddr;
ULONG ReqPages = 1 /* number of pages requested to be reserved */
VDHMAPSOURCE Source;
VDHMAPTARGET Target;
/* end of globals */

/* VDD init code */

VDDInit()
{
PVOID pStartAddr = STARTDOSMAPADDR,pMapDOSMem;
ULONG NumPages = ((256 * PAGESIZE) - STARTDOSMAPADDR)/PAGESIZE,LoopCnt;

/* Determine free DOS above STARTDOSMAPADDR */
if((pFreeDOSMem = VDHFindFreePages(pStartAddr,SSToDS(&NumPages))) == 0)
     return FALSE;
if(ReqPages > NumPages)
     return FALSE;

if((VDHReservePages(pFreeDOSMem,ReqPages)) == 0)
     return FALSE;

 if((pLinAddr = VDHAllocPages((PVOID) 0L,ReqPages,VDHAP_SYSTEM  VDHAP_FIXED))
 == 0)
      return FALSE;

 pMapDOSMem = pLinAddr;

 for(LoopCnt = 0;LoopCnt < (ReqPages * PAGESIZE);LoopCnt++)
           *pMapDOSMem++ = FILLPATTERN;  /* pattern to fill in allocated mem */
 }   /* end of VDD init */

 /* start of hook routine for VDM create */
 BOOL HOOKENTRY VDMCreate(HVDM hvdm)
 {
 Source.vdhms_laddr = (ULONG) pLinAddr;
 Source.vdhms_hobj  = 0;
 Target.vdhmt_laddr = (ULONG) pFreeDOSMem;
 Target.vdhmt_cpg   = ReqPages;
 Target.vdhmt_hmap  = 0

if(VDHMapPages((PVDHMAPSOURCE) &Source,(PVDHMAPTARGET) &Target,VDHMT_LINEAR)) =
= 0)
      return FALSE;

Points to be borne in mind :
a) Other VDD's (ex. VXMS,VEMM etc.) would also reserve memory within v86 addr
   space, so you may need to place your VDD before them in config.sys file
   in case they consume all of the v86 map address.

b) As suggested by you, you could use the VCDROM example code to pass the
   mapped address to your DOS DD.




!VIDEO__________________________________**********
March 31, 1995
QUESTION: (Ref: GC6)
1. How do I read out the video BIOS (normally located at C000h) under OS/2?

2. In which library do the PhysToVirt and UnPhysToVirt routines reside?  I
want to scan the BIOS from a normal PM application (a video card selection
tool).

3. What shall I do, if I want to detect my hardware thru the BIOS with a PM
application at install time?


ANSWER:
I assume that you want to access the video BIOS from a PDD.  If you want to
access the video BIOS both from interrupt context and task context then map
the physical address to a GDT entry by using the PhysToGDTSelector call.  Use
the returned sel:off pair to access the video BIOS.  If you want to access the
video BIOS only during task context then use PhysToVirt to convert the 32-bit
physical address to a virtual address (16:16) Use this vitual address to
access the video BIOS.

Refer to the following sources in DevCon DDK for the usage of the calls:
PhysToGDTSelector  --> ddkx86\src\dev\atcom\atsub.asm

ddkx86\src\dev\dasd\os2scsi\scxfrscb.c

PhysToVirt         --> ddkx86\src\dev\atcom\atqueue.asm
                                  ddkx86\src\dev\testcfg\testcfg.c

To access it from a Virtual Device Driver Reference,refer to
\DDKX86\SRC\VDEV\VXGA\VVXGA.C

TESTCFG.C has a routine which reads C0000 - CFG_Read_ADPMEM which
Copy areas between 0xC0000 and 0xFFFFF to user space.The sequence is -
VerifyAccess
PhysToVirt
Read Memory
UnPhysToVirt


2. PhysToVirt and UnPhysToVirt are DevHlps which are available in DHCALLS.LIB.
This library is available with the DDK.  However these DevHlps can be called
from a Device Driver only.  The normal PM Application is at Ring 3 and will be
unable to access these Kernel Calls (DevHlps).


3. You can get access to BIOS info thru OEMHLP$ driver.  From your application
open OEMHLP$ and issue Ioctl calls.  Refer to Appendix - 'D' in "Writing OS/2
2.1 device drivers in C", by Steve J. Mastrianni

Alternately, develop a VDD, issue BIOS calls from it.  Develop a PDD to
communicate to VDD.  Develop an application to communicate to PDD.




!OTHER__________________________________**********
March 31, 1995
QUESTION:(Ref: GA0)
I am making a Card Services call ReleaseIO (AF1B) and I am frequently (but not
always) getting caught in the following loop within CardServices:  0DDA cmp
[8de],-1

                   jz xxxx
                   cmp [2e],1
                   jz 0E20
              0E20 cmp [223],0
                   jnz 0CCD
              0E29 cmp [8de],-1
                   jnz 0CCD
                   etc.

I have triple-checked that I am releaseIO that has been in fact previously
requested, and there doesn't seem to be any problem with my handle.  I am a
device driver and making direct access calls into CardServices.  Could
CardServices be busy and I need to check that first?  This error has only
shown up with a ReleaseIO call, nothing else.


ANSWER:
The card services was stuck in an infinite loop.  Problem has been solved with
a new build of the card services (pcmcia.sys)




!OTHER__________________________________**********
March 31, 1995
QUESTION: (Ref: G26)
Q1.
I am looking for info, sample code, specs, etc.  to develop an X.25 driver for
OS/2.  Can you suggest sources of info?  There is no spec of where in the
protocol stack X.25 lives and what the data structures and call entry points
look like from the device drivers' perspective.

X.25 is a protocol, so I would actually imagine that its implementations would
be defined in the layers of the protocol manager and that IT (the X.25 layer)
would in turn talk to the MAC device driver.

A1.
We currently have no samples we could give you.  We are currently planning to
create an NDIS X.25 Deep Adapter implementation for the ARTIC960, but we are
still in the initial design stages.

Our current cards (C1X, C2X) as you know, use the proprietary TITN microcode
which we are not allowed to give to anyone.  The following publication should
be helpful to you:

         "Communications Manager/2 Version 1
         Realtime Interface Coprocessor
         Device Driver Programming Reference"

To order this publication, please call 1-800-879-2755 and ask for publication
SC31-6164-00

Second, I found a reference to Communication Manager's implementation of X.25
in the book "Client/Server Programming with OS/2 2.1" (authors Robert Orfali &
Dan Harkey).  While the reference is rather small (I wouldn't go purchase the
book just for its X.25 info), it indicates that the implentation is
independent of the NDIS drivers.  That is X.25 has its own low level driver
and higher level API layer.
==============================================================================

Q2.
My needs have to do with Protocol layers (in particular X.25) -- the Network
Layer Interface (NLI) -- that are ABOVE the NDIS/ANDIS MAC.  Questions like
what are the implications of the ANDIS MAC setting bits in the PPAT saying
that the connection is "X.25 deep"?  Does that mean that the MAC will be doing
the X.25 packetizing or that it is expecting the Protocol layer above it to
give it X.25 packets?  Things like that.

A2.
For CM/2 1.2 my understanding is that an ANDIS MAC can talk to the X25V MAC to
perform X.25 communications on a shallow adapter card.

In the case above, X25V MAC (supplied by CM/2) handles the X.25 packets and
the protocol associated with them.  That is, X25V MAC takes care of the
Network Layer (Layer 3).

If the Deep Adapter option is specified, the X25V MAC is bypassed, and and the
Null DLC Protocol Driver is executed instead.  In this case, the system
expects it is talking to an intelligent adapter in which all three layers of
the X.25 protocol are handled down on the adapter card.
==============================================================================

Q3.
I have gotten some of the books you previously suggested.  My conclusions from
these manuals is primarily that the CM/2 API's that talk to X.25 are custom to
IBM's implementation of it on the Arctic Card (the intelligent "realtime
interface coprocessor..").

Meaning that applications running with the CM/2 libraries will only talk to
that set of drivers:  the applications API's make X25() library calls which
(as far as I can gather) DEPEND on the custom set of IOCTL's provided by the
ICARICIO.SYS on the Arctic card.  That there is, in fact, NO hardware
independent specification for an X.25 interface to CM/2 applications.

Obviously if this in fact is the case then my project is mute.  Please
comment.

A3.
From what I understand, your assumption is correct.  The term "independence"
is very broad.  If you are intending to use any X.25 adapter with CM/2, then
it is not possible even with the Deep Adapter function.  With Deep Adapter,
CM/2 can support other adapters, however, the adapter must also implement the
Deep Adapter capability.  Thus, if another adapter such as X.25 EICON
implemented Deep Adapter, then the you can use the adapter with CM/2.
However, you can't just buy any X.25 adapter and use CM/2 with it.

Also, if there is any shallow adapter out there (i.e.  implements ANDIS), then
in theory CM/2 should be able to work with the adapter.  This works similiar
to the WAC card.  To date and to my knowledge, I think WAC is the only card
that implements ANDIS.  CM/2 implements ANDIS for MPA, ARTIC Multiport, and
ARTIC PortMaster adapters, thus, we will support it in shallow mode.





!OTHER__________________________________**********
March 14, 1995
QUESTION: (Ref: GL3)
This problem concerns an IBM internal product, PET (Portable Enhanced
Terminal).  The current version of PET, the replacement for IBM Service
Support's PT, runs in a DOS box under OS/2 2.11 on a ThinkPad 750.  The
application needs to be notified of APM Suspend and Resume events, either by
polling a device driver or by making APM BIOS calls (Int 15h, AH=53h).  Int
15h/53h is not supported in a DOS box for some reason, so I either need
information on an existing device driver which supports IOCTL calls for APM
(VAPM.SYS?)  or I need to write a VDD which can access the 750's APM BIOS or
OS/2's APM.SYS.


ANSWER:
OS/2 does not support APM BIOS in a DOS or Win-OS/2 session.  VAPM.SYS traps
all access to APM BIOS via int 15h and returns not supported.  There is a way
to get what you want.

OS/2 does provide IOCtls for applications to query APM BIOS and to be notified
of suspend/resume.  This support is provided via the APM.SYS device driver.
It is documented in Chapter 13 APM Architecture of the Input/Output Device
Driver Reference (part of the DDK).  Unfortunately, the notification is an
asynchronous notification.  This means you may be notified after you are
resumed.  This may not be what you want.  The application can poll APM.SYS for
suspend/resume however this method also does not guarrantee that you will be
notified (you may miss the event between polls).  If you develop an OS/2
device driver, you can be notified synchronously of suspend/resume.  You can
then pass this information to a virtual device driver that you also develop.
Your application can then be notified by the virtual device driver.  The
virtual device driver information can be found in the Virtual Device Driver
Reference (also part of the OS/2 Technical Library in the DDK).




!OTHER__________________________________**********
March 14, 1995
QUESTION: (Ref: GF4)
I am building a device driver for a commercial product that will allow a given
task to view/edit any existing real or linear memory.

The purpose is for an OS/2 add-on product to capture any traps in the system
and dump appropreiate/interesting areas for analysis later or at failure time.

I have already developed a device driver that does not use the capability
strip that performs this functionality.  If there is a more 'approved' way of
doing this I would like to know for future oS/2 compatibility.


ANSWER:
Try DOS32FLATDS,the 32 bit r/w FLAT selector.  This is an undocumented
selector.  However, there are instances in which they have been used in the
DDK.  Refer to -

\ddkx86\src\DEV\VDISK\VDISK.ASM
\ddkx86\mmos2\SAMPLES\PCVIDEO\VBCL.ASM
\ddkx86\mmos2\SAMPLES\PCVIDEO\VBCLINIT.ASM
\ddkx86\mmos2\SAMPLES\VCADDT\VCA32.ASM
\ddkx86\mmos2\SAMPLES\VCADDT\VCAINIT.AS




!NETWORK________________________________**********
March 14, 1995
QUESTION: (Ref: GB2)
We need some help about the above topic.  There's a customer planning a
network with >200 nodes.  As we currently know, there are plans to run several
LANServer 4.0 on multiprocessor machines running OS-2 2.1 .

Is there something new, that a driver developer should know when the driver is
run in a multiprocessor environment?


ANSWER:
There are several things which work differently when using SMP.  First, the
worst thing a device driver can do which works fine in uni mode but not in SMP
is to access the APIC directly, especially when doing an EOI.  Use the DevHelp
routines and you'll be okay.  Also, remember that the usual use of STI-CLI
don't have the same effect in SMP (use Spin Locks instead).




!OTHER__________________________________**********
March 9, 1995
QUESTION: (Ref: GM8)
Q1. The device driver code samples (from the CD-ROM) include a call to
function DosQueryABIOSSupport().  This function is used to determine whether
the workstation has a MicroChannel bus.  Is there any documentation on the
USHORT that is returned by this function?  I have tried the function and it
works, but I was wondering if this was THE recommended method of determining
bus type in a device driver.  I hate using undocumented functions.

A1. The USHORT that is returned is either 0 or 1. The second parameter if you
specify as HW_CFG_MCA and the return value is 1, it means bus type is MCA.  If
0 it means bustype is not MCA.
==============================================================================

Q2. The IBM Physical Device Driver reference states that you can use GetDOSVar
index 7 to obtain the address of YieldFlag.  The reference says:

YieldFlag:BYTE.  Indicator for performing yields.  Valid only at task time.

Does this mean that the address returned by the DevHlp function is only valid
at task time, or that the contents of the byte are only valid at task time?
By the way, the Physical Device Driver reference doesn't seem to mention what
values YieldFlag takes on.  I assume non-zero means I shoud yield.


A2. Address returned by DevHelp is valid at task time.  Yield flag set implies
yield to TC thread.  What the documentation implies is that the value of the
Yield Flag is valid only at Task Time and not at Init time.  The address
however is valid both at Init & Task time.
==============================================================================

Q3. Some of the code samples from the CD-ROM get the address every time, the
VDISK sample though gets the address at INIT time and then checks the flag at
task time.  This implies that the address returned by GetDOSVar is valid at
INIT time.  But why is everyone else issuing the GetDOSVar each time?

A3. Yes, the address is valid at INIT time also.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GM7)
1. Can you give me a pointer to where I might find an adequate description of
the usage of DevHlp_RegisterStackUsage?

I've been trying to debug a driver that when it finishes, the process somehow
manages to freeze up, and I can't kill it.  I have to reboot before I can run
again.  I'm hoping it's just 'cause I haven't yet registered my expected stack
usage.

2. How am I supposed to count this stuff?  I'm using Steve's 'C' library for
access.


ANSWER:
In general, if an application does not go away, the driver probably has memory
still locked.  ResgisterStackUsage registers the amount of stack space a
driver requires, up to 8K.  Problems in device drivers are rarely caused by
failure to call RegisterStackUsage.

We do not have any other additional info on RegisterStackUsage besides what is
contained in the PDD Ref.




!PRINTER________________________________**********
March 3, 1995
QUESTION: (Ref: GL8)
I've suddenly acquired a problem while compiling using EA.exe.  It crashes
with an access violation.

I'm currently building a Postscript Level 2 printer driver using OS/2 WARP,
the Developers' connection kit, and the Toolkit for OS/2 WARP.  The makefile
uses EA.exe (in \ddkx86\tools directory) to add extended attributes to my
driver.

The driver is still built but I can't load it.  The error that I get is access
violation at 1:00002248 in EA.EXE.  Ea is called out several times from the
makefile.  The 2 instances where it crashes are on the lines that add
"RequiredDriverFiles" and "OptionalDriverFiles" extended attributes to my
driver.


ANSWER:
Make sure you are building the non optimised version of the driver.  The
compiler option OPT should be set to /O-




!STORAGE________________________________**********
March 9, 1995
QUESTION:  (Ref: GK7)
I have made a lot of progress in my ADD and now have a question, regarding how
long I can stay in an ADD call.  My ADD talks to a SCSI device on the parallel
port and some calls can take up to 5 seconds.  This does not seem to be a
problem with my ADD; however I am experiencing a weird problem:

The ADD installs fine and the OS/2 file system recognizes the SCSI CD-ROM that
my host adapter is attached to.  The directory of the CD-ROM shows up fine
when I access it and when I attempt to run an EXE off of the CD-ROM (e.g.
DDKINST from the DEVCON DDK CD), the EXE runs some distance and then the whole
system freezes, with some garbage on the Debug Kernel Vt100 monitor.  At this
point, OS/2 (Version 2.1) is frozen.  I have to power down and start again.
Do you have any ideas as to what is happening?


ANSWER:
I assume you are using Polling mode.  Note that when you callback to say IORB
Complete to the Async notify routine, you MIGHT be called IMMEDIATELY at your
IORB Entrypoint again.  This gets recursive until you eat up the kernel thread
stack.

You must use some queueing mechanism.  If you have the DDK, see
/src/dev/dasd/cdrom/mitsumi/cdinit.c near the bottom.




!OTHER__________________________________**********
March 9, 1995
QUESTION:  (Ref: GK1)
I wasn't sure where to report this, operating system or driver group.

A customer sent us some code.  The program opens a device which is contained
in my driver.  He then spawns a child thread.  In the child thread he calls
DosRead looking for 1 byte of data to be placed in storage in the variable
'inchar'.  The problem is, the driver is crashing the application by trying to
write more than 1 byte back to the application storage space.

Using the kernel debugger, I trapped the DosRead call to my driver.  The
request packet I receive from the OS indicates a read call for 4096 bytes!
If, in the application code, I take the declaration of 'inchar' and make it
external to the 'thrd1' function, compile and run the app again, the read
request packet I receive looks correct (1 byte expected).

I don't get it...

This makes my driver look to be at fault even though I'm just processing what
I get from the kernel.

Also, are async serial hardware/drivers ever going to be certified so that we
can use the OS/2 logo, etc.?  None of your forms or programs seem to support
serial stuff.



ANSWER:
1. If you use DosCreateThread are you having the same problem?

2. What happens when you reduce the stack size to 4096 or less in the
_beginthread function call?  This could be a _beginthread limitation.

3. Below is the answer from one of the Q&A files on the DUDE, We feel your
problem is similar.  Please see 12_94QA.TXT Ref:  FR6 for complete details.

I would be really nervous with a stack size of only 8K in a C++ function.
Your described symptoms look very much like those experienced when you run out
of stack.  Note the automatic off- stream object in testhost1().  It will eat
up a *lot* of stack.

By the way, our current recommendation is to make the stack size a multiple of
64K.  With the "lazy commit" behavior of the OS, there is usually no
additional cost to rounding the stack size up to a multiple of 64K.

The big difference between DosCreateThread and _beginthread() is that
_beginthread will register the C/C++ exception handlers.  These can chew up a
fair amount of stack on thread termination.

4. In regards to certifying an async device driver, an OS/2 Device Driver
Certification package is being mailed to you.




!OTHER__________________________________**********
March 9, 1995
QUESTION: (Ref: GJ6)
1. Is it possible to access the BIOS (not ABIOS) from a physical device
driver?  How?

2. Is it possible to read and write the CMOS from a PDD?


ANSWER:
1) A VDD could be developed from which BIOS calls can be issued.  From the PDD
connection can be established to the VDD and thereby access BIOS info.

Alternately, from the PDD connect via IDC interface to OEMHLP$ PDD.  OEMHLP$
provides access to some BIOS info.  For details about OEMHLP$ refer to
Appendix-D, "Writing OS/2 2.1 Device Drivers in C", Steve J. Mastrianni.  This
book is available online as part of Devcon DDK.

2) Yes, it is possible to read/write the CMOS.  Refer to the following source
ddkx86\src\dev\clock\clock01\clock01.asm The cmos_write_clock macro is defined
in - ddkx86\src\dev\clock\rtc.inc




!VIDEO__________________________________**********
March 9, 1995
QUESTION: (Ref: GJ3)
I'm building a user driver installation disk for our display device.  I have
the following questions:

1. Can I ship IBM files: DMQSPROF.dll, Dspres.dll, display.dll...?

2. What is the function of dspres.dll, display.dll?

3. How can I compress a group of driver files into 1 compressed file and put
in the user driver installation disk?  For example, the file 'XGA' in the xga
driver package.  Where can I get the compression program?


ANSWER:
1. Consult the DDK licensing agreement.
2. This information is documented in the Video Device Driver Reference manual.
3. You may want to consider using the PACK utilities.

PACK.EXE is not on the DUDE.  However, it is available, along with PACK2.EXE,
on DEVCON Volume 5. The location depends on whether you are working with the
original volume 5 or the special edition volume 5.

ORIGINAL:
DEVTOOLS\TKBETA\BIN           - PACK, PACK2
DEVTOOLS\TOOLKT21\OS2BIN      - PACK

SPECIAL EDITION:
DEVTOOLS\TOOLTK21\OS2BIN      - PACK
DEVTOOLS\WARPTLKT\TOOLKIT\BIN - PACK, PACK2




!I/O____________________________________**********
March 9, 1995
QUESTION: (Ref: GH9)
1. How do you create a configuration utility which appears in the System Setup
folder to configure a (device dependent) device driver?

2. What if there are multiple devices - can there be multiple configuration
utilties for the same device type?


ANSWER:
1) The device driver install icon (calls DDINSTAL.EXE) in the system setup
folder is the configuration utility for configuring device dependent device
drivers.  Ref :  Ch-7 of PDD reference and Ch-2 of Storage device driver
reference

2) For multiple devices write the appropriate device driver profile (.DDP)
file along with the presence check executable file.




!I/O____________________________________**********
March 9, 1995
QUESTION: (Ref: GH8)
Are there specific services to support screen savers?  What's the easiest way
to implement a screen saver?  I'm writing drivers for an industrial PC, and I
need to provide a 'backlight saver' (not a full-fledged screen saver), which
turns off the backlight after a period of inactivity.  So I'm not looking to
write a fancy graphics package, just to determine system (in)activity.  My
guess is I need to write a device monitor, but I understand I can't monitor PM
keyboard activity.

ANSWER:
You should consult the I/O Device Driver Reference manual.  There is
information on APM architecture.




!I/O____________________________________**********
March 9, 1995
QUESTION: (Ref: GH7)
During system startup, does the default mouse driver query the PS/2 port?  We
will be connecting custom devices to this port, so we need to know how to
respond to queries appropriately, and ensure the port is not locked.


ANSWER:
YES, the mouse driver does query the port.  Refer to CheckMSSDevice procedure
in ddkx86\src\dev\mouse\serial.asm (DDK v1.0) for interaction between the
mouse device connected to the port and the device driver.




!I/O____________________________________**********
March 9, 1995
QUESTION: (Ref: GH6)
This is my understanding of mouse driver initialization:

  device dependent driver loads
  MOUSE$ loads, sees TYPE= modifier from config.sys, sends Read_Enable
         message to device dependent driver => IDC connection established

If multiple devices (mice) are connected, how do they connect to the device
independent driver MOUSE$?  Multiple 'TYPE=' modifiers on DEVICE= line in
config.sys?  Second device dependent driver initiates connection somehow?

I thought I read somewhere that OS/2 would support multiple mice.  If the
mouse driver can have up to five device dependent drivers registered to it,
how do the last four register?  If the DID doesn't get the DDD name from the
DEVICE= line in config.sys, the DID can't initiate the connection.  I thought
the DDD had to wait for the Read_Enable before is could talk to the DID.

I'm building a driver for a touch screen which will emulate a mouse and
keyboard.  But of course we want to use a real mouse and keyboard as well.
The 8516 touch screen allows a mouse to be plugged in to it, and the 8516
driver includes a mouse driver.  I guess that's what I'll have to do too, and
only support one mouse type.  I was hoping I could leave the real mouse
support to the existing drivers, as long as we could all connect to the device
independent driver as needed.


ANSWER:
You are correct in your understanding of the mouse initailization for mice
that need a device dependent driver.  We currently support only one mouse on
the system at a time.  On the 8515 monitors the mouse fits in back of the
monitor.  This allows both devices to be present.  I know that there is
another touch monitor out there that doesn't have the mouse hooked into it,
but I don't know how they do it.  I am assuming that they later connect to the
mouse IDC and send packets in that way.  The mouse driver can have up to five
device dependent drivers registered to it if I am not mistaken.

During DD init time, physical mouse DD checks to see if TYPE= overrider is
used If the DEVICE=C:\OS2\MOUSE.SYS line in the CONFIG.SYS file contains TYPE=
overrider, then pointing device support is established thru an IDC.  Device
dependent DD must be loaded before MOUSE.SYS

If a TYPE= overrider has NOT been specified, it is assumed that generic
pointing device support is desired.  During init the command line is parsed
and the device driver name following TYPE= is grabbed and a DevHlp_AttachDD is
issued to connect to it.  Ref :  Mouse_Init() routine, in
ddkx86\src\dev\mouse\init.asm

Only the first TYPE= is recognized.


Also, there is a STYPE= that can go on the MOUSE.SYS line in CONFIG.SYS.  This
STYPE is for a secondary device dependent mouse driver.  For example if you
had a serial mouse with the 8516 touch monitor both the PDIMOU$ and SERIAL$
mouse drivers would be needed.  One as a TYPE= and the other as an STYPE=.




!STORAGE________________________________**********
March 9, 1995
QUESTION: (Ref: GH4)
Q1. My BASEDEV scans the MCA slots looking for the presence of our card.  When
I single step through the slot scan routine using the kernal debugger,
everything works fine.  If I execute the slot scan procedure using the "P"
command, the machine reboots and brings me back to the boot manager.  This is
true under WARP and I haven't tested under 2.11 yet.  Can I assume there is
some speed dependency involved with accessing the POS registers?

My code is something like this:

   for (slotNo = 0; (slotNo < 8) && (id != CARD_ID); slotNo++) {
     OutPort (0x96, slotNo | 0x08);
     id = InPort (0x100);
     id = id | (InPort (0x101) << 8);
   }

   OutPort (SLOT_SEL_REG, 0);

   if (id != CARD_ID) {
     ***CARD NOT FOUND ERROR CODE**
   }

Can you illuminate me as to why the machine reboots when executed at machine
speed, but works well when single-stepped?

A1. We don't have an explanation but you could try the following alternative:
Normally DD accesses the POS registers using the ABIOS routines.  Refer
chapter-8 of "Writing OS/2 device drivers in C" by Steve Mastrianni for
details and sample code.  You can also refer to Appendix-B of PDD reference
for details.
==============================================================================

Q2. After a lot of experimenting I have come to the following conclusions
about DDINSTAL:

     1: The PRESENCECHECK program MUST have the .EXE extension,
     2: There cannot be any command line arguements associated with it,
     3: If DDINSTAL finds and executes the PRESENCECHECK program, it will
        automatically install the associated files and make the CONFIG.SYS
        changes without prompting the installer.

While numbers 1 & 2 don't seem to have much impact, number 3 is unfortunate if
you want to give the installer a couple of options for the same card.

Can you verify that the results of my experiments are correct?

A2. Your observation that the presence check program must be an EXE file and
cannot have command line arguments is correct.  If presence check routine
returns 0, then DDINSTL will automatically install all the associated files
and make required modifications to the CONFIG.SYS as per the .DDP commands.
Refer to PDD reference, Ch-7 and Storage reference Ch-2 for details.

If you need to provide options to the installer you need to develop the
presence check program as a PM application which could -

   a) do the necessary processing other than that provided by DDINSTL

   b) provide user interaction and return 0 or 1 depending on whether you
      need to complete the installation or not.




!NETWORK________________________________**********
March 9, 1995
QUESTION: (Ref: GG8)
We would like to be your LAN Distance industry partner, and to enable our
async board to support the IBM LAN Distance Family of Products.  I am starting
to write a device driver for the board.

The board is an intelligent board with i386 CPU, supporting 8 ports.  From the
IBM Software Announcement for LAN Distance, I know that there are, besides
IBM, third-party vendors providing similar hardware, such as CUBIX, DIgiBoard,
EICON, and Star Gate.

I have joined the IBM developer connection and orderd the OS/2 DDK.  But for a
beginner in the OS/2 environment, I need your help on the following questions
to get started quickly:

Q1. I noticed in the DDK that there is an ASYNC (RS232) type of driver.  Is
there a spec for async driver development so developers like us can write an
async driver to that spec and become IBM LAN Distance enabled?

A1. Refer to the Input/Output Device Driver reference, included with the
DevCon DDK product, for the async spec.
==============================================================================

Q2. How can I test and certify the driver?

A2. To get your card and driver certified you need a contract.  The cost of
the test is $3,295.00.  Once you sign the contract, pay for the test, and we
receive the card and driver then we will test the driver and card.  Once you
have passed the test we will publish the results on the BBSs, IBM4FAX,
National Solution data base, MAX CD ROM, Ziff Davis CD ROM etc etc etc.  For
further information on driver testing and certification, please contact
Lockett Pitman in Austin, Texas at 512-838-1641.
==============================================================================

Q3. What is ANDIS?

A3. ANDIS is an API that extends the IBM NDIS interface used by low level MAC
drivers of LAN Adapters to WAN adapters.  Using ANDIS, it is possible to use
serial ports, ISDN ports, and other similar switched network equipment to
remotely attach PCs to LANs.  ANDIS is used by the IBM LAN Distance product.
==============================================================================

Q4. Is there a class for the LAN distance compatible ASYNC adapter driver
development?

A4. There is an OS/2 NDIS-MAC LAN Device Drivers Workshop scheduled for
11/6/95.  This is the only LAN Workshop scheduled at this time.  However, you
may request that we offer an ASYNC adapter Device Drivers Workshop or atleast
address this type of driver in the LAN Workshop.




!OTHER__________________________________**********
March 9, 1995
QUESTION: (Ref: GG3)
I am trying to gain access to a CD writer thru the IBM scsi aspi driver
system.  After removing a few bugs the drivers compiled and installed.  I can
now issue DEVICE_INQUIRY commands and DEVICE_TYPE commands.  However trying to
issue EXECUTE_IO commands hangs the window that I'm running in.  A specific
bug that I found was in ASPIDRV.  Two of the parameters in a
DosDev_VerifyAccess command were switched.  Is there a corrected version of
these drivers and sample application, or is there a published list of fixes?


ANSWER:
A change ASPIDRV.C is required. Change the sequence of parameters to:

 VerifyAccess(SEL Selector,USHORT Length,USHORT MemOffset,USHORT AccessFlag)

This would then be compatible with the DDK Library - DHCALLS.LIB.  There are
no further changes nor is an updated version available.  We will fix the above
defect in the next Release of OS/2.




!MULTIMEDIA_____________________________**********
March 9, 1995
QUESTION: (Ref: GC8)
Q1. OS/2 generates a trap 13 after some time after returning to the kernel
from my IDC calling stub.  I have copied the assembler code from the DDK
example but is supect that it is not enough due to the fact that I am using
the Watcom compiler and while processing the DDCMD messages some registers may
be changed that shouldn't be.

A1. The sample code that you have sent to us declares DDCMEntryPoint as a near
procedure which is incorrect.  It is a far procedure.  This could be the
reason for the Trap 13 that you are experiencing.  Ref:
ddkx86\mmos2\samples\audiodd\startup.asm
==============================================================================

Q2. What registers does the Kernel expect to be changed and what registers
should not be changed while processing calls to the IDC routine?

A2. The IDC interface protocol is defined by the driver providing the IDC
service.  The driver using the IDC interface need to support and conform to
this protocol.  The kernel has no role to play in this exchange.
==============================================================================

Q3. In which registers does the kernel expect the return (long) value?

A3. Refer to above response and ddkx86\mmos2\samples\audiodd\startup.asm
regarding specific protocol implementation by the audio DD.

Your Stack is probably getting messed up.  From the Kernel Debugger use the
"k" command when the Code enters your DDCMDEntryPoint Procedure.  Note the
Return Address.Check the Stack again before your "add sp,4" Instruction.




!MULTIMEDIA_____________________________**********
March 9, 1995
QUESTION: (Ref: GC7)
Q1. The MMPM/2 subsystem sends an IOCTL cat 80 function 42-AUDIO_CONTROL
message with AUDIO_CHANGE when it requests a volume change from the DD.  My
card supports several different volume settings like separate left/right for
both record and playback.

By looking at values in the audio_change structure (passed as a parameter) I
cannot tell whether the volume change applies for left or right channels or
whether it applies to record or playback volume settings.

Does MMPM/2 allow and send to the DD volume change messages separately for
left and right audio channels?

A1. Please refer to the MMPM/2 Device Driver Reference in DevCon DDK V1.0.
The following IOCtls are new additions to the AUDIO IOCTL category:

  o MIX_GETCONNECTIONS
  o MIX_SETCONNECTIONS
  o MIX_GETLINEINFO
  o MIX_GETCONTROL
  o MIX_SETCONTROL
==============================================================================

Q2. How do I differentiate between a volume change request for record
respective playback?

A2. MIX_SETCONTROL(64h) The device driver should return the current setting of
the line in ulSetting of the MIXERCONTROL structure.  For stereo controls, the
high-order word should contain information for the left-channel and the
low-order word contains the right channel setting.  A value of 0xFFFF
represents full intensity and a value of 0x0000 is full cutout.
==============================================================================

Q3. The volume setting can be a value between 0x0 and 07FFFFFFF. What is
smallest possible increment?

A3. Category:  AUDIO_IOCTL_CAT (80h)
    Function:  AUDIO_CAPABILITY(48h)
Description: Determine If a Group of Audio Settings is Supported

This IOCtl enables an application to determine if a particular group of audio
settings can be supported.  If the mode is supported, resource management
information will be returned to the caller.  The data packet parameter is a
pointer to the following data structure - MCI_AUDIO_CAPS; which has a
parameter to distinguish OPERATION_PLAY or OPERATION_RECORD - ulOperation.
IOCtl func 41h could also be issued and the 'operation' field could be
examined.  If 0x80000001 => PLAY, If 0x80000002 => RECORD
==============================================================================

Q4. During the same message processing the MMPM/2 subsystem may request a
balance change by setting an appropriate structure member in the audio_change
structure.  What relation does this balance control exactly have on with the
volume?

A4. MIX_GETLINEINFO(67h) This IOCtl enables an application to determine the
capabilities of a particular line.  For instance, an application will call
this function to determine if an individual line (for example, the microphone)
allows adjustments for volume or balance.
==============================================================================

Q5. Also what is the range and minimum increment for this balance control
change?

A5. See function LRVolumeFromVolumeBalance in ddkx86\mmos2\pastk\audsubs.c




!STORAGE________________________________**********
March 9, 1995
QUESTION: (Ref: G78)
I am trying to develop an ADD for my SCSI host adapter, which connects to the
parallel port of an IBM PC/AT or Compatible.  For writing this code, I needed
to start with a template ADD, for which I chose ATAPI driver IBMIDECD.FLT.

Q1. Can you point me to a better template for an ADD, which has to serve
function of an ASPI Manager so that the other OS/2 drivers can talk thru' my
host adapter to SCSI devices?

A1. ASPI Drivers should be the right template for your development.  However,
ASPI ADD drivers are not contained in the DDK.  You should approach Adaptec
for sample drivers.
==============================================================================

Q2. If I try to build some other device driver in DEBUG mode, would I still
need the files that are missing in the LIBOBJ directory?

I have started Driver development using IBM's ADD for ST506/IDE.  I am
changing the Init code presently and have a few questions:

A2. You could always modify the source code to include an INT 3 and use the
Kernel Debugger to trace through the modified driver.

In case you do not want to modify the source code,you could set the following
BreakPoint :

    BP syiInitializeDeviceDriver.

Refer to Setting Useful Breakpoints in the Kernel Debugger Reference in DevCon
DDK Version 1.

This will interrupt the Device Driver just before it initialises.In this case
however you would have to go through all the Device Drivers that are loaded
before your relevant driver.When the relevant driver symbol file is loaded,you
could trace through the execution.
==============================================================================

Q3. I need to locate my host adapter, which can be installed on any one of the
three LPTs (278H, 378H or 3BCH).  In order to auto-detect the host adapter, I
need to query each one of these ports and see if I can detect my adapter.  Do
I need to make any call to OS/2 to temporarily take control of the parallel
port, for my testing or can I just look at BIOS 40:08, determine the list of
printer ports and start accessing them rightaway?  Do I need to do anything
differently when processing IORB calls from DMDs (OS2ASPI or OS2SCSI...)?

A3. The OS/2 parallel port device driver (print01.sys) is loaded before any
adapter device drivers (*.add).  The parallel port dd provides an IDC enabling
other drivers to request and release exclusive access to the parallel port.
Since both drivers are base device drivers, they init at ring 0 and the IDC
address is a ring 0 address.  This means the .add can call the parallel port
dd at init time and request exclusive access to the parallel port hardware.
Once the .add has exclusive access the parallel port will not touch the
hardware until the .add releases access.  This is documented in the I/O Device
Driver Ref, parallel port dd chapter, Section on Sharing the Parallel Port
with other Device Drivers (in the DDK).  You could also refer to an article
that was written in the Developer Connection News (Vol 4) which gives a source
code example how to issue the IDC calls.  The .add must not access the
parallel ports without first gaining access otherwise the parallel port device
driver may not coexist with your .add.
==============================================================================

Q4. As part of the parallel port type detection, I need to make some EPP BIOS
DOS INT17H API extension calls, which cause a Trap 14!  The format of these
calls is given below:

        MOV  AX, 00
        MOV  CH, 'E'
        ...
        INT  17H

How do I work around this problem?

A4. Are the EPP BIOS calls able to be called in protect mode?  I don't think
so!  The standard BIOS int 17h parallel port calls are only callable in real
mode.  This may be the cause of the page fault (trap 14).  The BIOS may be
trying to load a segment register with a segment value rather than a selector
value.  You may not be able to call the BIOS to do what you want to do.
==============================================================================

Q5. Since DS != SS, I am using as less a space on Stack as possible.  (usually
around 20 bytes).  The IDM ST506/IDE driver seems to use the same amount.
However, I am experiencing some stack variables getting trashed when making
lower level function calls.  Is there a safe limit on the amount of stack
space that can be used?

A5. If you are a device driver you do not have a stack, you run on the kernel
stack.  There is plenty enough room on the kernel stack to do calls to BIOS.
Our drivers do it regularly.  Are you specifically changing the kernel stack
to your own stack?  This is not valid and will cause you problems especially
at interrupt time.
==============================================================================

Q6. IBM Storage INF documentation says ADDs should not block IORB calls but
can do so at Init time.  I need some more documentation on what "Blocking"
means.  Could you please provide me some light on this?

I am writing an ADD for a SCSI interface attached to the parallel port of a
computer and I need to know how to modify my existing DOS state machine code
for OS/2.

A6. When you Block an IORB Request,the ADD Strategy routine put itself to
sleep, waiting for an Interrupt to wakeup.  The Scheduler will resume this
thread when

- Run is issued
- Timeout occurs
- Interrupt occurs ( Ctrl-C etc.)

Consequently on Blocking data transfer would be accomplished only in Multiple
Passes through the ADD.  On the contrary if Block is not used,the Transfer is
accomplished in one Pass through the ADD.  During Initialisation there is only
one source for the Requests and hence Blocking can be done at Init time.
Please refer to the DevHlps Block & Run in the Physical Device Driver Ref.
==============================================================================

Q7. Also, if you have come across any Storage ADDs on the parallel port,
please let me know.

A7. At the moment we do not have any Storage ADDs on the parallel port in the
DDK.




!STORAGE________________________________**********
March 9, 1995
QUESTION: (Ref: FT5)
I'm in the process of writing a SCSI device driver for our PCI proprietary
chip.  A problem has arisen of being able to communicate with our BIOS.  We
use INT 13 to read the configuration from our SCSI card.  I can send CAM
commands to each and every device to see if they exist, but I'm afraid that
the overhead will be too high.  Also, there are certain register values/flags
that the INT 13 gives me without the necessity of "PEEKING" and "POKING" to
obtain those values.

In any case, as you know at the moment in OS/2 Warp, a device driver cannot do
an INT 13.  Any suggestions?  I need an interface much like the ABIOS has but
for NON IBM SCSI adapters.


ANSWER:
There is no facility in OS/2 to allow a device driver invoke the SCSI BIOS in
real mode.  The BIOS simply does not support the functionality.

At this time, IBM has no plans to implement a change.  Numerious manufacturers
of both intelligent and dumb SCSI adapters have implemented their drivers to
the ADD/DM spec without undue complexity.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: xxx)
Last time I asked about how (which pack.exe & unpack.exe) to compress a group
of files into a combined file (for example, the file 'XGA').  A gentlemen
called me and told me the OS2image/disk_2/unpack.exe can un-pack the file.
But my main question is how to build (PACK) the files to put in our user
diskette?  Is the pack.exe in any of the dev con or ddk CD?


ANSWER:
The following is taken from the file 02_95QA.TXT (on the DUDE), reference GD0:

PACK.EXE is available, along with PACK2.EXE, on DEVCON Volume 5. The location
depends on whether you are working with the original volume 5 or the special
edition volume 5.

      ORIGINAL:
      DEVTOOLS\TKBETA\BIN           - PACK, PACK2
      DEVTOOLS\TOOLKT21\OS2BIN      - PACK

      SPECIAL EDITION:
      DEVTOOLS\TOOLTK21\OS2BIN      - PACK
      DEVTOOLS\WARPTLKT\TOOLKIT\BIN - PACK, PACK2

We ask that developers download these "Q&A" files and look to see if their
question has been asked previously. The files also make good reading if you
suffer from insomnia.

For your reference, here is the path information for the UNPACK.EXE and
UNPACK2.EXE:

      ORIGINAL:
      OS2SE21\DISK_2

      SPECIAL EDITION:
      OS2IMAGE\DISK_2




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GJ7)
Is it possible to start an application from a physical device driver?  I'm
writing a touch screen driver, and we'd like to only recalibrate when
necessary.  I can determine during driver initialization if it is necessary.
The calibration utility will be an application.

The only idea I've had is to autostart the calibration utility in the
background and have it open and read from the device.  When calibration is
required, it could send data to the application.  But is there a more elegant
method or kludge?


ANSWER:
No, it is not possible to start an application from a device driver.

If you just want to calibrate during bootup you can place the calibrate app in
your startup folder.  This will kick it off at bootup and then it can close if
the driver says that it doesn't need to calibrate.  If you might need to
calibrate at any given time then I don't know of any other way then what you
have mentioned.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GH2)
We have a customer that wants an ADD to be APM aware.  I would like to find
out what information you can provide me on how OS/2 supports the Advanced
Power Management Specification version 1.0 or 1.1?


ANSWER:
You should consult the I/O Device Driver reference manual.  There is a section
on APM Architecture




!OTHER__________________________________**********
March 3, 1995
QUESTION:  (Ref: GG6)
I can't get my device driver to install.  I'm sure it's a misconfiguration of
my software but I have not been able to figure it out yet.  My source and
makefile are both patterned after files I received with my DDK, namely from
DDKX86\SRC\DEV\SCREENDD\SCREEN01.ASM and the associated makefile.

After doing an nmake in that directory, I can't get the SCREEN01 device driver
to load either.  It results in the same message during system startup that my
xxxx.SYS generates:  "SYS1201:  The device driver D:\OS2\xxxx.SYS" specified
in the device command on line 78 of the config.sys file was not installed.
Line 78 is ignored.  Press Enter To Continue."

Except for a warning message, the nmake for both drivers is error-free.  The
warning message is "No entry point:  assume 0000:0100."

I am new to device driver development and have built my system from scratch
with OS/2 2.11 from CD and the Device Drivers Developer's Kit CD.  I also
installed toolkit 2.1 from the Developer Connection for OS/2 but I don't think
any of that software is coming into play.

I've noticed that the data and code segments in my .SYS files seem to be
page-aligned despite the use of Word or even Byte in the SEGMENT statements,
but I haven't been able to find a way to stop aligning on the page boundary.
I'm not sure I need to.

Could someone take a look at the code and see if they can spot something
obvious?


ANSWER:
I solved my problem.  I was using CMDInitBase instead of CmdInit and my code
wasn't recognizing the Init command and returning undefined command status.




!OTHER__________________________________**********
March 3, 1995
QUESTION:  (Ref:  GG4)
I am currently enhancing a running device driver which allows access to a
memory mapped block of registers.  I am trying to add code to the INIT section
of the driver in order to dump disk files out to our own hardware in order to
initialize it.  I understand that DosOpen and DosClose APIs are allowed in the
INIT section.

Prior to adding this new code, the device driver successfully utilizes the
DOsWrite API so I believe my k# linking process is O.K.  (and the makefile).
However, when I try to add a DosOpen API (or even a DosBeep) I find that the
make builds the driver O.K.  but on reboot I get the message that the device
driver is invalid and was not loaded.  The error number I get is SYS1719.

Q1. Can you tell me what this error number is and if possible let me know where
    I can find full details of all SYSxxxx messages?

A1. Use the HELP command at the OS/2 command prompt to receive an explanation
    of SYS errors.  For example, type "HELP SYS1719" at the OS/2 command prompt
    to receive the explanation for a SYS1719 error.
==============================================================================

Q2. Do you have any idea why this driver is failing to load?  I checked and the
    Device Header hadn't moved, it was still at 0001:0000

A2. Link in the 'DOSCALLS.LIB' library from the DDK CDRom.
==============================================================================

Q3. Is there a debug kernel available for WARP?

A3. The Warp Debug Kernel is shipped with Warp.  However, Warp does not include
    an install utility for the kernel so you will need to manually install it.
    It is also shipped with the DevCon DDK 1.0 product which does include an
    install utility for the kernel.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GG1)
I recently bought the OS/2 Device Driver Source Kit, only to find it has been
replaced by the OS/2 Device Driver Developer Connection (or something), which
I am automatically being transferred to, BUT have missed the first issue (next
issue due after I should have finished my current driver development).

I have got the Resource Manager .INF file from your BBS, but would like to
know if there is any example code available that uses it.


ANSWER:
On DevCon DDK Version 1, the following samples use RMCalls :

 1) ddkx86\src\dev\dasd\ibm\ibm1flpy
 2) ddkx86\src\dev\kbd\ibmkbd
 3) ddkx86\src\dev\atcom
 4) ddkx86\src\dev\testcfg




!STORAGE________________________________**********
March 3, 1995
QUESTION: (Ref: GF8)
I am developing a floppy disk driver for Warp that will not unload if a floppy
drive is not present at boot (like OS/2 2.1's).  I recently received the
DevCon DDK 1.0 and was looking through the floppy driver source code.  The
source code states that it is source for an OS/2 2.1 driver, but the files
have fairly new dates.  Does the floppy driver source code on the DevCon DDK
1.0 include the changes made for Warp?


ANSWER:
The IBM1FLPY driver uses the Resource Manager features of WARP.  The IBM2FLPY
driver has been updated but there is no dependency on the resource manager
APIs that comes with WARP.

If you need more info on using the resource manager in WARP, please download
RMBASE.ZIP from the Main file area on the DUDE.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GF2)
I am writing an OS/2 PCMCIA device driver installation program for a PCMCIA
modem.  The installation program needs to determine whether or not EasyPlaying
or PlayAtWill are installed on the PC.  If they are not, our device driver
will be installed.  If EasyPlaying or PlayAtWill are installed, the
installation program will not install our driver, as we don't want two device
drivers attempting to enable the same card.

What I would like to do is simply make calls to Card Services to determine if
our card is configued (it would be if EasyPlaying or PlayAtWill) is installed.

My problem is, since this program is being executed from a floppy disk, it is
not registered as a PCMCIA device.  Is there any way of making calls to Card
Services?


ANSWER:
You actually want to know if the AUTODRV2.SYS driver is loaded since it is the
PCMCIA Modem SuperClient Driver.  This driver may or may not be loaded when
PlayAtWill, EasyPlaying, or other PCMCIA packages are installed.  I suggest
that the install program issue a DosOpen API with a device name of "AUTODRV$".
If successful then the Modem SuperClient driver is installed and you could
therefore not install your driver (you will also need to issue a DosClose on
the returned DosOpen Handle).  If the DosOpen fails then the Modem SuperClient
is not installed and your driver can therefore installed.




!I/O____________________________________**********
March 3, 1995
QUESTION: (Ref: GD2)
I would like to hook into the device monitor list for COM.SYS.  It appears as
though the COM.SYS DD does not support device monitors.  I want to get at
serial I/O statistics.  What are my options?


ANSWER:
COM.SYS does not support device monitors for performance reasons.  One could
hack the driver to make these kind of measurements especially if you are going
to write a monitor anyway.




!VIDEO__________________________________**********
March 3, 1995
QUESTION: (Ref: GC2)
Q1. I am writing a VDD for OS/2 2.x, using the C/Set compiler and 2.0 toolkits.
    I have installed hooks to intercept the VDM_FOREGROUND and VDM_BACKGROUND
    messages.  All works as it should if I am messing around with FULL SCREEN
    DOS Sessions, the messages are sent as expected.  But, if I am in a DOS
    window or I start my DOS app from an OS/2 prompt that auto-spawns a DOS
    session, the messages are never received.  The only message that I get, of
    these two, is the BACKGROUND message, and this comes only one time
    immediately following the CREATE message.  Is there a known problem or am I
    not understanding this correctly?

A1. When you start a VDM in the background (either full screen or windowed) the
    only notification sent is the background one.  There can't be a foreground
    notification until their VDM has become foreground full screen, either due
    to the ALT-HOME on a window or CTRL-ESC to it thru the task list (if it was
    full screen background).  The purpose of the foreground notifications is to
    tell them that from now on the VDM is running as it would be under real DOS
    (full ownership of the input and output resources).  They can not structure
    their VDD around an assumption that there will be a foreground notification
    or that they will execute in the foreground.  When running windowed (for
    example, seamless) there never will be a change, since such session may
    never be made full screen.
==============================================================================

Q2. I understand now how this works.  But, if this is the case, then how can I
    retrieve the VDM handle during interrupt time?  That is the handle of the
    DOS session that issued the interrupt?  There must be a way to get this.

A2. I believe that the interrupt context is the same as the VDM task context
    when it comes to handles:  in other words the VDM instance handle (HVDM) is
    0. The only times the handle is not 0 is when vvid is invoked in a context
    of non-VDM thread, like during the session switch or in DosRequestVDD
    functions.  In that context, the passed hvdm represents the linear offset
    of the VDM instance in the linear address space of the caller.  I suggest
    that you look at the vvideo code in the DDK source tree.  All of the INT10
    emulation and fault hook (vvmode.c vvpage.c) code addresses the instance
    directly as VDMData., where functions that may be possibly called by other
    contexts (sample vvuser.c) are passed HVDM which may be 0 when in VDM
    context or non-0 in other contexts, so they address the instance data using
    pVDM-> . The virtual driver is not allowed to stash the handles and use
    them at will:  its functions have to be structured around the context in
    which they may be called.  The system passes the handle in all of the
    non-VDM task external calls.
==============================================================================

Q3. Here is a brief description of how and what my VDD is doing:  I develop
    code for DCA/Attachmates 3270 emulator for OS/2.  We have a customer who
    has a series of DOS applications that utilize our HLLAPI interface.  The
    customer wanted to use these apps, but with the OS/2 package.  Hence, I
    wrote a VDD to intercept the interrupt calls made by the DOS applications
    and pipe them over to the OS/2 resources and then return any appropriate
    return codes back to the DOS app.

    My problem arose when mutliple apps were running and utilizing the same
    resources on the OS/2 side.  I am developing a new version of the VDD to
    allow for multiple apps running concurrently, but in the interim, I am
    limiting the customer to a single DOS app at any given time.  So, I needed
    a way to track which DOS session has control of the VDD, i.e.  which DOS
    session is running the app that issued the most recent interrupt.

    I was hoping to be able to do this by keeping track of the VDM handles for
    each DOS session, and when a session comes into the FOREGROUND (by
    capturing this message ) I can compare this to a handle that last issued an
    interrupt and determine whether this session is the 'owning' session.

    My problem is that if the apps are run from a windowed DOS session or
    started from a windowed OS/2 session, the FOREGROUND messages do not get
    posted.  FOREGROUND process session does not compare to the FOREGROUND
    focus message.  Hence, I was hoping to find a way to get the session handle
    at interrupt time, of the session that issued the interrupt.

    Is there some way to do this or maybe some way to determine anything
    specific about the DOS session that issued interrupt?

    Perhaps toggling a data bit that is stored/created at session creation time
    and then accessing this bit at interrupt time to either toggle or check it.


A3. If you need to determine the DOS session which issued the interrupt for
    HLLAPI service to OS/2 then the following needs to be done:

    a) Save the VDM handles received via VDM_Create event in VDHInstallUserHook
    for each DOS session created.

    b) Install VDHInstallIntHook for the v86 interrupt used by DOS
    appplications for HLLAPI service.  This need to done for each DOS session
    created.  The same routine is registered for all VDMs.

    c) When one of the DOS sessions runs the applications needing HLLAPI
    service then the hook routine of the VDD installed (step b) is called.  In
    this hook routine, call VDHQuerySysValue to determine the handle of the DOS
    session (index value = VDHLSV_HVDM for VDHQuerySysValue).

    d) Validate the handle received with the list of valid DOS session handles
    stored in step (a).  Save the handle after validation as the DOS session
    owner for subsequent use.  You need to invalidate this handle on the
    termination of the owning DOS session.  (Use VDM_TERMINATE event in
    VDHInstallUSerHook to register a hook handler which could do the
    invalidation.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: GB6)
I need to use the DEVHLP call RegisterKernelExit, which is listed in the
DEVHLP.INC file as function 0x6F.  The following was taken from the DEVHLP.INC
file:

###########################################################################

DevHlp_RegisterFreq     EQU     107    ; 6BH   register PTD freq service
                                       ;       entry point with kernel

DevHlp_DynamicAPI       EQU     108    ; 6CH add a dynamic API
;
; Request bit definitions used in DevHlp_DynamicAPI
DHDYNAM_16B_CALLGATE    EQU     1       ; 1 = 16 bit callgate, 0 = 32 bit
DHDYNAM_16B_APIRTN      EQU     2       ; 1 = 16 bit API rtn,  0 = 32 rtn

DevHlp_ProcRun2         EQU   109     ; 6DH  Unblock process via procrun2
;
DevHlp_CreateInt13VDM   EQU   110 ;6EH Create Int13 VDM (Internal Only) OEMINT13
;
DevHlp_RegisterKrnlExit EQU   111 ;6FH Used to capture Kernel Exits   F78693

DevHlp_PMPostEventSem   EQU   112     ; 70h  PM Post Event Semaphore


This shows that DevHlp_RegisterKrnlExit is setup to use 0x6F.

I then went to the PDDREF.INF to get more information on the call.  There is
no DevHlp_RegisterKrnlExit listed in the INF, but there is a call listed that
uses function number 0x6F.  The following came from the PDDREF.INF:

 The DevHlp services, listed by function codes, are shown below:

 Ĵ
 AcquireSpinLock       6F  Acquire a Spin Lock               
 Ĵ
 Release SpinLock      70  Release a Spin Lock               
 


This information states that the DevHlp AcquireSpinLock uses the the function
code 0x6F.

I then went to the SMP.INF to verify this, and while it lists a function that
uses code 0x6F, it is not the same as the previous two sources of information.
The following came from the SMP.INF:

###########################################################################

 The OS/2 kernel will provide new DevHlps for OS/2 for SMP V2.11 as follows.

 DevHlp_CreateSpinLock         EQU    111     ; 6F Create a spinlock - SMP
 DevHlp_FreeSpinLock           EQU    112     ; 70 Free a spinlock - SMP
 DevHlp_AcquireSpinLock        EQU    113     ; 71 Acquire a spinlock - SMP
 DevHlp_ReleaseSpinLock        EQU    114     ; 72 Release a spinlock - SMP
 DevHlp_PortIO                 EQU    118     ; 76 Port I/O
 DevHlp_SetIRQMask             EQU    119     ; 77 Set/Unset an IRQ mask
 DevHlp_GetIRQMask             EQU    120     ; 78 Get an IRQ mask


###########################################################################

This INF file states that DevHlp_CreateSpinLock uses function code 0x6F.

So I now have three different definitions for for function code 0x6F:

DEVHLP.INC      says DevHlp_RegisterKrnlExit
PDDREF.INF      says DevHlp_AcquireSpinLock
SMP.INF         says DevHlp_CreateSpinLock


What I need is DevHlp_RegisterKrnlExit, and I would like to have it in OS/2
v2.11 AND OS/2 for SMP v2.11.

1. Is this function only in OS/2 2.x BUT not in OS/2 for SMP?

2. Also, what are the correct codes for the SpinLock DevHlps?  Two different
INFs, list them differently.

Please clarify this situation for me.


ANSWER:
There is an error in the Physical Device Driver Reference.  A defect has been
opened and the Function Codes in the Physical Device Driver Reference will be
modified in the next Release.  The Codes defined in the SMP.INF are correct.

The correct Function Codes are as follows :

6Fh   RegisterKrnlExit  (For UniProcessor OS/2)
6Fh   CreateSpinLock  (OS/2 SMP Only)
70h   FreeSpinLock    (       ,,         ,,        )
71h   AcquireSpinLock (       ,,         ,,        )
72h   ReleaseSpinLock (       ,,         ,,        )
79h   RegisterKrnlExit(       ,,         ,,        )

1.The RegisterKrnlExit could be used both in OS/2 2.x as well as in OS/2 SMP.
However,the Function Codes are different (6Fh in OS/2 2.x & 79h for OS/2 SMP)

2. The SpinLock Functions Codes in SMP.INF are correct.




!MULTIMEDIA_____________________________**********
March 3, 1995
QUESTION:  (Ref:  GB3)
SetIRQ fails when I specify shared interrupts on my EISA machine (IBM PC
Server 8640).  SetIRQ works fine on the EISA machine when the request is for
non-shared interrupts.  (Also, SetIRQ works just fine WITH or without shared
interrupts on a Microchannel computer I use -- so there is nothing wrong with
the code.)

The following is a section out of the Physical Device Driver Reference:

     The attempt to register an interrupt handler for an IRQ to be
     shared will fail under any of the following circumstances -

     1.  If the IRQ is already owned by another device drive as
         not-shared.
     2.  If the IRQ is the IRQ used to cascade the slave 8259
         Interrupt controller (IRQ 2).

I have determined that neither of the two is causing my problem.  So my next
thought was that my EISA machine may not support shared interrupts or that I
had to do something to enable them (perhaps something in the SETUP utility).
However, IBM Support Technical Specialsts assured me that my machine did have
interrupt sharing (no special configuration necessary to turn it on).

I was advised that it is up to the device driver to enable the interrupt
sharing.  I believe that is what SetIRQ is supposed to do.  Is there something
I'm overlooking?  Is there something else besides SetIRQ that I should do to
get shared interrupts?


ANSWER:
Eisa systems can share interrupts on a per-IRQ bases.  However, if there is
any one device (adapter) that does not support interrupt sharing, then no
other devices (adapters) can use that IRQ.

The best thing to do would probably be to call OEMHLP (see the PDD reference
or Steve Mastrianni's book, Writing OS/2 2.1 Device Drivers in C) to read the
EISA slot information.  This will tell you if the device (adapter) does indeed
support interrupt sharing.  In fact, you could do this for all slots to see if
there is a conflict.

Second, you could use the debug kernel and set up your KDB.INI file to stop on
g_INTSetIRQ.  When this entry point is called:

                       AX = Interrupt Handler Address offset
                       BX = IRQ level
                       CX = Interrupt handler's address selector
                       DX = .... ...0 Interrupt level is not shared
                            .... ...1 Interrupt level is shared
                            .... 0... Not the NPX interrupt level
                            .... 1... NPX interrupt level.
                       DS = Interrupt Handler's DS value.

You can do ".d dev ds:0", or "db ds:0" to see the device driver's header and
figure out who is calling.  Maybe another device driver is requesting the
interrupt level as non-shared if the system is not a micro-channel (perhaps
that device driver doesn't know that EISA and PCI can share interrupts).




!MULTIMEDIA_____________________________**********
March 3, 1995
QUESTION: (Ref: G96)
PROBLEM TYPE
OS/2 refuses to install driver if IDC enabled.

PROBLEM (1)
I am working on a device driver that currently processes only Strategy command
0(INIT).  The driver has two headers and successfully completes initialization
and installs without errors untill the IDC bit14 is set to 1 in the device
attribute words and the IDC offset is set(also in the header).  (the full
device attribute word is 1101100010000000 ).

After enabling IDC the device driver is still called once for each header, and
completes INIT processing without errors each time.  However after returning
from the INIT routine the second time OS/2 puts the following message on the
screen while refusing to install the driver:

SYS1201:  The device driver ......  specified in the DEVICE command on line XX
of the config sys file was not installed.  Line XX is ignored.  Press Enter to
continue...

Since the initialization of the driver completes successfully (no errors I can
detect) I would expect that the next thing to happen is for the AUDIOVDD to
try to establish IDC link with my driver(Unless I am off base here in which
case please correct me!).  Therefore I made sure that the IDC offset in both
headers is correct pointing to the following assembler stub":

-------- example code follows --------------

;*********************************************************************
;* SUBROUTINE NAME: _DDCMDEntryPoint             (DEBUGGED)
;*
;* DESCRIPTION:  Stub for calling internal DDCMD handler
;*
;* C PROTOCOL
;*
;*   none
;*********************************************************************
;*

DDCMDEntryPoint_ proc near

int 3
        push   bp                               ; Save stack pointer
        mov    bp, sp

        push   ds                               ; Create own data segment
        mov    ax, DGROUP
        mov    ds, ax


        push   [bp+8]                           ; high address
        push   [bp+6]                           ; low address
                                                ; +4[bp] has old CS register

        call dword ptr _DDCmdInternalEntryPoint ; C routine to process
                                                ; DDCMDs

        add    sp, 4                            ; toss calling address

        pop    ds                               ; restore registers ds, bp
        pop    bp
        ret

DDCMDEntryPoint_ endp

-------- example code ends -----------------

...  of course execution never reaches the "int 3" so the whole thing must
abort before.

I also made sure that there are no inconsistencies between the two headers and
that the device name "AUDIO1$ " in the first header is arrived at by making
sure that no other drivers have claimed these names(calls to DevHlp_AttachDD).

Q1.  Since I am stuck I am turning to you for some ideas about what could be
going wrong.

PROBLEM (2)
I am trying to get a clear picture about the sequence of events for the full
initalization of the DD environment.  The following is my understanding:

-Kernel calls myDD once for each header
-AUDIOVDD tries to attach to myDD via "AUDIOx$"(for example)
-MMPM/2 sends IOCTL OPEN to to myDD strategy routine
-MMPM/2 sends DDCMD_REG_STREAM to myDD IDC routine
... at this point DD should be ready to play/record data...

Q2.  Is this sequence of events correct?  If not, what is the correct
sequence?



PROBLEM (3)
This third issue may be related to the previous ones...  Now that I have taken
care of the initialization of the DD I am ready to move on to the next phase.
The thing is that I am not sure what the next step is.  My approach from now
on would be to write a function (Strategy or DDCMD) and test it using the
PMADDE tool from the toolkit.

However!
According to the the MMPM/2 DD reference manual step 2 and so on involves the
creation of a vendor specific resource file,modification of the CARDINFO.RC
file, the creation of an audio installation dll, etc...  for the purpose of
registering the driver with MMPM/2.

Q3.  The question is, do I have to follow step 2 and so on from the MMPM/2 DD
reference manual before I can go on with the development and tesing of the DD
functions(Strategy or DDCMD)?

Q4.  Is there a recomended order in which the function(s) (strategy or DDCMD)
should be written and tested?


ANSWER:
1. AUDIOVDD would not be using the IDC offset addr specified in your device
header.  This IDC addr is used by the Stream Handler Device Driver for
communicating with the AUDIO PDD.  ( Refer Chap 2 of MMPM/2 Device Driver Ref
for OS/2).  The AUDIOVDD uses the addr specified in the DevHlp_Register PDD
call performed by the AUDIO PDD...

The IDC Entry point(i.e.  _DDCMDEntryPoint ) should be declared as a far proc
( Refer Physical Device Driver Ref:DevHlp_AttachDD remarks) and not near as
declared.(Also refer Startup.asm in - \MMOS2\MMTOOLKT\SAMPLES\AUDIODD) Also
Declare DDCMDEntryPoint as PUBLIC in your DDCMD Handler IDC EntryPoint of the
Target Device Driver must follow the Far Call/Return Model.

Your AUDIO PDD need to support IDC entry as well as provide support for AUDIO
IOCTL commands ( Refer Ch-9 & 10 of MMPM/2 Device Driver Ref )

Also Suggest to insert a INT3 at the Entry Point of the Device Driver,where
you can intercept the Request Packet.After the INIT Request Packet the kernel
sends other Request Packets and only on their successful execution the driver
gets loaded.This should isolate the Request Packet which is causing the
failure.

2. The sequence of events are correct.Only the AudioVDD should use the the
DevHlp_RegisterPDD.

3. The process specified in the MMPM/2 Device Driver Reference is used if you
wanted to automate the whole Installation Process and let MINSTAL work for you.
For your development stage you could just have the DEVICE= Statement in the
CONFIG.SYS and handcraft the MMPM2.INI file.  Once you have the Streaming
Protocol up & running you could also use the PMADDE




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: G93)
I'm looking for some technical information on Warp.

Q1. I would like to know what the OS/2 System folder SCREEN option does.

A1. The SCREEN option allows the user to change the screen resolution.  This
    change will take effect on the next boot after the user makes the change.
    Basically, the users OS2.INI gets updated with the new resolution.  The PM
    display driver obtains this mode info at boot time and sets the video mode
    accordingly.
==============================================================================

Q2. What happens when the "Workplace shell palette aware" option is selected?
    I am looking into a problem whose behavior varies depending on how this
    option is set.  I'd like to know what happens, at a low-level (interface
    with graphics drivers, etc.)  when this option is set or not set.  Any
    messages sent to different Windows, any system wide flags changed, etc.?
    I'm working on a device driver and am looking for information at that
    level.

A2. When the Workplace Shell Palette Aware option is selected, the window
    procedures for the icon, tree, and details views of a folder recognize and
    respond to the WM_REALIZEPALETTE messages from Presentation Manager.

    Here are some more details.  When the user specifies a background bitmap on
    a folder, when we open a view of that folder and the display device driver
    supports palette management, we construct a palette which matches the
    bitmap colors.  When we display the bitmap, we select that palette into the
    presentation space before copying the bitmap to the screen, if the palette
    aware option was selected.  We also call WinRealizePalette to inform the
    palette manager that we are using a palette.  If this window has the focus,
    the system automatically broadcasts WM_REALIZEPALETTE messages to all open
    windows.  When the folder view window procedures receive the
    WM_REALIZEPALETTE messages from the system, they respond by calling
    WinRealizePalette to inform the palette manager of their palettes if 1) the
    folder has a background bitmap which has a palette and 2) the Workplace
    Shell palette aware option is selected.

    When a Workplace Shell folder view gets focus from a non-Workplace Shell
    window, the window procedure calls WinRealizePalette for either 1) the
    palette for the folder's bitmap, if it has one or 2) the palette for the
    desktop's bitmap, if it has one.  If neither the folder nor the desktop
    have a palette, the window procedure calls WinRealizePalette for a default
    palette.  All of this takes place only if the Workplace Shell palette aware
    option is set.

    As I remember it, this describes the main affect that the Workplace Shell
    palette aware option has on the shell.  It makes the folder view windows
    operate in palette aware mode if they have background bitmaps.

    We have noticed "strange behavior" in the system when the palette aware
    option is turned on, but this is apparently the normal behavior of the
    palette manager.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: G80)
The DDINSTALL program doesn't seem to afford a way of REMing out existing
obsolete driver install statements (e.g.  BASEDEV=IBM1S506.ADD) in the
CONFIG.SYS file after a new driver reference is added to the end of the file.
(In my opinion this should be an option!!!)

What I tried doing was to scan the CONFIG.SYS file within the Existance Check
program and make the change.  For some reason I'm unable to modify the
CONFIG.SYS file.  I get no errors or indications that the file is in use; it
simply won't show the update I've made to it.


ANSWER:
You are correct in saying that the DDINSTALL program doesn't seem to afford a
way of REMing out existing drivers.  But, you may reference the following code
as an example of remming out a driver in the config.sys.

 #include <stdio.h>
 #include <memory.h>
 #define  MAX_LEN  100

 int main(void)
 {
        FILE *pInFile,*pOutFile;
        char *str;
        char line[MAX_LEN], *result;

        if ((pInFile = fopen("C:\\CONFIG.sys","r")) == NULL)
                {
                return 1;
                }

        if ((pOutFile = fopen("C:\\CONFIG.$$$","w")) == NULL)
                {
                perror("Error Opening CONFIG.$$$\n");
                fclose(pInFile);
                return 1;
                }


    while((result = fgets(line,MAX_LEN,pInFile)))
    {
        printf("The string is %s\n",result );
        if (memicmp("BASEDEV=IBM1S506.ADD",result,20) == 0)
           {
             fputs("REM BASEDEV=IBM1S506.ADD\n",pOutFile);
           }
        else
             fputs(result,pOutFile);

    }

        fclose(pInFile);
        fclose(pOutFile);

        if (rename("C:\\CONFIG.sys","C:\\CONFIG.SLI") != 0)
                perror("Error in renaming .sys to .SLI");
        else
                if (rename("C:\\CONFIG.$$$","C:\\CONFIG.sys") != 0)
                        perror("Error in renaming .$$$ to .sys");
 }




!MULTIMEDIA_____________________________**********
March 3, 1995
QUESTION: (Ref: G76)
The OS/2 developers connection contains a directory of source code to build a
AD1848 audio PDD.  I have compiled this code successfully and am trying to get
MMPM2 to recognize it as an audio device driver.  What do I have to do to get
MMPM2 to recognize this driver?


ANSWER:
Please refer to the README file in the DDK directory :
    \DDKX86\MMOS2\SAMPLES\AUDINST\

This subdirectory contains the Audio Installation Sample.  This sample shows
how the manufacturer of a audio adapter can install that adapter into the
MMPM/2 system so that the adapter can then be used by MMPM/2 to play and
record digital audio and to play MIDI files.




!I/O____________________________________**********
March 3, 1995
QUESTION: (Ref: G54)
I'm hoping you can help me out as you always do.  I'm currently writting a
device driver for OS/2 Warp for our new IDE PCI DMA busmaster controller.

Problem:

I believe that for PCI DMA, DMA mode F must be used.  We don't have any specs
on DMA.

1. Anybody there at IBM ever do any DMA for BusMaster IDE?

2. Is DMA mode F the one to use for IDE?

3. Can I use DMA Mode A or B?

4. Also, does the DMA channel that I use to do the DMA transfer need be
"registered" with OS/2 to resolve channel conflicts?  It appears not as the
IBMFLOPPY driver seems to just choose a channel (From the CONFIG.SYS device=
line) and use it.


ANSWER:
The DMA used on the PCI busmaster IDE device should be restricted to the IDE
channel since the PCI bus does not support DMA nor does it require it since it
is a busmaster.  I suspect what is going on here is that the chip is
converting IDE DMA transfers into PCI busmaster cycles.  If this is the case,
then the DMA for IDE operates independently of the other DMA channels in the
system and you should not have to tell OS/2 what system DMA channel you are
using since the IDE DMA channel is not linked to the rest of the system.  DMA
on the IDE interface, whether it be type A, B, or F, is simply a protocol on
the IDE bus that can be used to transfer data to/from the hardfile.  As far as
the intricacies on IDE DMA protocol, see below(TIMING MODE).  I do know that
to determine which DMA mode to use, you need to query the hardfile attached to
see what it can support.  This works most of the time, except for when the
hardfile returns the incorrect info.

(TIMING MODE)
The DMA timing mode that is supported by each drive can be found by examining
words 49, 52, 62, 63 and 65 of the Identify Drive data.  The definition of
these words is documented in the ATA-2 standard which I can provide you a copy
of if you don't have one.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: G24)
(1) IOctl Category for the device driver is 0x91.

(2) The device driver sets the request packet status to 0x8000 | 0x4000 |
0x100 | 0x13 (error, device driver error, done bit and invalid parameter
error).

(3) assembly startup code is as follows:

          push 0
          jmp start
        start:
          push es
          push bx
          call _main
          pop bx
          pop es
          add sp,2
          ret

I watched using Periscope debugger the value of es:bx+3 (the request packet
status) before returning.  It seems to be the value 0xC113 (0x8000 | 0x4000 |
0x100 | 0x13);

But the system code changes it to return code 1 instead of 0xFF13.

I noticed the following code execution:

          call _main
          pop bx
          pop es
          add sp,2
          ret

At this point, es:bx+3(Request packet status) is 0xc113.  The system code is
after my startup assembly code is as follows:

X       1000:359  POP BX
X       1000:35A LES BX[BP-4]
X       1000:35E CLI
X       1000:364 JNZ 036B
       1000:366 CALL 3301
X       1000:36B STI
X       1000:36C TEST BYTE PTR [BP-A],FF
X       1000:370 JZ 0381
       1000:372 TEST WORD PTR ES:[BX+3],8000
       1000:378 JNZ 0381
       1000:37A MOV AL,[BP-B]
       1000:37D MOV SS:[FF34],AL
X       1000:381 LDS SI[BP-08]

In the above code, the X mark denotes the instructions executed.  I was
wondering 1000:36c, 1000:370 and 1000:372 have significance in error
reporting.  When 1000:36c was executing I was watching BP-A and it was just
00.  It was not FF.  What is in BP-A?

Please throw light on this problem of IOctl call reporting the device driver
error in the format of 0xFF13.


ANSWER:
Refer to the Generic IOCtl Commands Section in the Physical Device Driver Ref.
It describes the Category & Function Code.Cat.  0x91 is a User Defined IOCtl.
The Function Code should also be set appropriately.Please confirm if the
Function Code being used is as per the Standards defined in the PDD Ref.

RPSTATUS = 0x8000 | 0x4000 | 0x0100 | 0x13 Since the IOCtl Category is User
Defined, 0xFF00 is ORed with the Byte-Wide Error Code and the Kernel should
return 0xFF13.

Regarding BYTE PTR [BP - A],it could be the Higher Byte of the Return Code.
Confirm by checking the value pointed to by [BP - B].This would contain the
User Defined Error Code,in your case 0x13




!STORAGE________________________________**********
March 3, 1995
QUESTION: (Ref: G22)
I am writing a device driver for a PCI IDE accelerator chip which supports
hardware DMA.  The device can be a PCI bus master if the drive in question
supports DMA transfers.

I am starting with the IBM1S506 source code from the DDK.

Q1. What does OS/2 do differently based on the bus width specified in
    AdapterDevBus and AdapterHostBus fields of the AdapterInfo structure?

    I am aware why I should set the bus width fields, but I would like to know
    what the kernel does differently based on the bus width.  In other words,
    why should the kernel care how wide the bus is between my adapter and the
    device since it is transparent to the kernel?

A1. These fields are currently used for informational purposes only.  We do
    want to limit the possible uses to these fields in the future, therefore we
    cannot say they are unused.
==============================================================================

Q2. Does OS/2 align the S/G list on a DWORD boundary?

A2. Data buffers pointed to by SG descriptors are DWORD aligned.
==============================================================================

Q3. In the AdapterInfo structure, why is the AdapterFlags field set to
    AF_HW_SCATGAT?  (In S506IORB.C)

A3. It means support for S/G exists in hardware i.e.  ST-506/IDE H/W supports
    s/g, so the flag is set to true in the driver.  If not set then it means
    that the DD is emulating s/g functions in S/W.
==============================================================================

Q4. In S506INIT.C the routine DetermineUnitGeometry, why is the variable
    npUCB->SecsPerBlk limited to 16?

A4. It was felt that larger multiple mode block sizes would increase ring 3
    application latency beyond what was acceptable, i.e.  we would spend too
    much continuous time doing PIO in the driver.

    This becomes a problem for applications which run time-critical threads
    such as network and multimedia and do I/O but do not perform well when
    their threads are held off too long.

    This limit was also based on a recommendation of some drive suppliers that
    even though their drives had larger multiple mode buffers, the 8K limit was
    the optimal buffer size.  Keep in mind that the Identify command returns
    the maximum multiple mode buffer size not the optimal size.

    Driver latency considerations would generally not apply to DMA based
    transfers since the processor would continue to execute while the drive was
    transferring data to the host.
==============================================================================

Q5. Where is OEMHLP?

A5. OEMHLP.ZIP is available in the Main file area of the DUDE.




!NETWORK________________________________**********
March 3, 1995
QUESTION: (Ref: FZ9)
Since the OEMHLP - PCI support is available only on OS/2 Warp, what if I want
to access PCI BIOS under OS/2 2.x & 1.x?  Say I'm developing a MAC driver for
PCI network adapter to run under OS/2 LAN Server on OS/2 2.x & 1.X, could you
give me some clues about how to do it?


ANSWER:
There are two types of PCI BIOS:  16 bit mode and 32 bit mode.  Accessing PCI
Configuration Space using the 16 bit PCI BIOS requires INT instruction.  In
OS2, INT instruction is not available.  The OS2 MAC driver can not access the
PCI Conf.  Space using 16 bit PCI BIOS.  It is possible to access the 32bit
bios by the MAC driver.  The driver must switch to protected mode, use 32 bit
far calls to the 32 bit BIOS.  The PCI BIOS Specifications explains how to
find and use the the 32 bit BIOS.  I did not attempt to use the PCI BIOS for
the OS2 drivers.  I used the PCI Controller IO registers.  These registers are
specified in the PCI Functional Specifications.




!OTHER__________________________________**********
March 3, 1995
QUESTION: (Ref: FZ4)
Many of our customers are porting from Intel's iRMX on Multibus, OS/9, QNX etc
and are putting OS/2 on their machine controllers.  This works fine since they
get full multitasking, a good set of tools and excellent support.  BUT, their
users are in the habit of just switching off their machines without shutting
down.

This of course fails to write the cache back!.  Even worse if checkdisk is
running, the disk gets screwed up.

At the moment I am suggesting the following strategy:-

i) Build resilience into your powersupply and arrange for an interrupt to
occur when the main supply goes down.

ii) Write a device driver to handle this interrupt and post a DosRead from a
Hi Pri process on this driver.

iii) When the interrupt goes off, the driver can complete the read and the
process can call shutdown.

Questions:-
1) In what order does shutdown do things?

2) Is there any way for this Power Monitor Driver to tell the file system
directly to write back the cache?

3) What is the maximum time required to ensure that the disk state is
consistent?

4) Anyone have any other ideas?


ANSWER:
1) In what order does shutdown do things?

First of all, there is more than one "shutdown" in the system.  There is the
shutdown processing that is invoked when an application calls DosShutdown.
That processing will commit all files, quiece the IO devices and shut down the
file system.  Then there is the processing that is invoked when the user
choosed the Shutdown option in the work place shell.  That option does a bunch
of additional processing prior to calling DosShutdown.  To get a rundown of
that function see bottom(Function).

DosShutdown has two flavors.  When the ShutdownValue parameter is 1, all the
data in the buffers is committed and the system is quiesced.  When the
parameter is 0, the data is committed, the system is quiesced, all the system
components are shutdown and the file system is locked.  I believe the shell
calls with ShutdownValue 1 and then after all the programs have exitted does
the final shutdown with ShutdownValue 0.

The order of function in DosShutdown is as follows:

If ShutDownValue is 1
   Go inform every file system to flush all buffers
   return
If ShutDownValue is 0
   If the user specified a message but the parameters are bad
     Set the message to the generic message (it will not return since the
         caller probably can't handle DosShutdown returning)
   Otherwise set up the appropriate message.
     Set the shutdown flags on each open file to stop counting routines
     wait for all threads to clear counting shutdown checks.
     block access to most file system functions except for the shutdown
     thread and the swapper.
     notify each device driver that shutdown is beginning.
     notify each FSD  to inform it shutdown is beginning
     for each open file instance in the system
         commit the file
     notify each FSD shutdown is completing
     notify each device that shutdown is completing
     if caller wanted us to print a message
       print the message associated with the passed in error code
       print the error code and any string passed in
     return

2) Is there any way for this Power Monitor Driver to tell the file system
directly to write back the cache?


Use the device helper "send event" with a Event_SM_CAD- if you need more info,
let me know.  This is how boot.com does it.

3) What is the maximum time required to ensure that the disk state is
consistent?

From the point that all threads have cleared the counting checks, this is
device speed, cache size, device driver, and file system dependent.  Of those
items, the biggest factors are your device speed and cache size.

The counting checks are in mkdir, rmdir and allocage swapper space.  These
should be very fast routines, but it is possible in mkdir and rmdir to get a
hard error if a removable media drive is not ready and the shutdown will wait
until the user processes the hard error.

In general you can make a good estimate if you have control of the software
configuration and hardware setup.  If the user is free to add slow devices,
and change the cache size there are no guarantees.

A general worse case:  assuming an 8M cache with 30ms drive access and the
cache is completely dirty, about 2 minutes.  This is about as bad as it can
get excluding any unusual device driver or non-standard file system hangups.

4) Anyone have any other ideas?  Ever thought of taping over the power switch?

(FUNCTION)
The shutdown thread attempts to close all Winthorn applications in two passes.
The first pass shuts down threads that own windows.  The second pass shuts
down any remaining threads with message queues.

Shutdown enumerates all queues and sets an internal flag for each of them.
Then it enters a loop in which it enumerates all messages queues.  For each
queue found it posts a WM_QUIT message.  After that the shutdown function
blocks itself on an internal semaphore.

After posting a WM_QUIT message to a thread's message queue, we wait for the
semaphore to be cleared by either WinDestroyMsgQueue or WinCancelShutdown
before going on to the next thread.  Therefore, if the application never
WinDestroyMsgQueues or WinCancelShutdowns, we will block until the next
WinSystemShutdown call.

For this reason, an application's main thread should always be responsive to
system messages.  If the application's main thread blocks itself on a
semaphore to be cleared by one of its children, then shutdown will fail since
the WM_QUIT message gets sent to the main thread which will not respond.




!PRINT__________________________________**********
March 3, 1995
QUESTION: (Ref: FX6)
We developed a printer driver based on the MDRIVER driver shipped with the
last version of the DDK.  It is a simple enhacement that prints to a user-
specified FAX file.  This works perfectly under OS/2 2.1 but an error occurrs
under Warp.

We tested the original MDRIVER that is still shipped with the current DDK and
it gives the same error.

When running with the debug kernel and when compiled as the debug version, a
DelayHardError occurs.  I have not been able to find any documentation on this
error, nor have I been able to determine exactly where it occurs.


ANSWER:
There is a fix needed for the MiniDriver-1 in order for it to operate
correctly on OS/2 Warp.

The graphics engine (GRE) in OS/2 Warp defines a new enable subfunction,
subfunction 14 (decimal).  MiniDriver-1 should return -1, GPI_ALTERROR, from
OS2_PM_DRV_ENABLE() when the Warp GRE calls with subfunction 14, but in error,
the MiniDriver-1 returns the contents of an uninitialized, automatic variable
(ulrc) which is usually zero.  To correct the MiniDriver-1 code, add a
"default" case to the switch statement in OS2_PM_DRV_ENABLE function in
ENABLE.C.  The default case will look something like this...

       default:
       // unknown, unsupported enable subfunction
       ulrc = -1;
       break;

and should be inserted at line 696 in ENABLE.C from DevCon Device Driver Kit
for OS/2 Version 1 - 1994.




!OTHER__________________________________**********
March 3, 1995
QUESTION:  (Ref: FW3)
Q1. We are proposing to implement an access control system for OS/2 2.x and
    3.0 WARP.  The following strategy is planned:

    During initial boot of OS/2 a small BIOS INT 13h intercept program will be
    loaded into memory.  Once loaded, it will initiate the original, normal
    OS/2 boot loader to bring the OS/2 kernel into memory.  However, this BIOS
    intercept should remain in memory and not be stomped on by the booting
    system.

    The IBM1S506.ADD driver will be loaded, followed by a .FLT filter driver
    which will redirect requests as needed to the .ADD.  Once these two drivers
    are activated, there will be no need for the BIOS INT 13 routine.  The .FLT
    driver should take over from the previously resident INT 13 handler.

    I need clarification on exactly when during boot, the INT 13 is no longer
    used by OS/2.  Are the following assumptions true?

    - The boot loader runs in real mode, using INT 13 to read CONFIG.SYS.

    - The device drivers are loaded in real mode, still using INT 13.

    - Once all drivers have been loaded, OS/2 switches into protected mode,
      THEN initializes the drivers.


A1. Here is the OS/2 boot sequence:

    - Boot Sector executed
    - OS2BOOT loaded/executed (via INT 13h)
    - OS2LDR loaded/executed (via INT 13h)
    - OS2KRNL loaded/executed (via INT 13h)
    - CONFIG.SYS is read (via INT 13h) and parsed, but nothing is executed.
      Lists are created and will be processed later (such as a list for
      BASEDEV= or CALL= or DEVICE=, see below).
    - 4 base device drivers from a list (KBD, SCREEN, CLOCK, and RESOURCE) and
      are loaded (via INT 13h) and initialized (One is loaded and initialized,
      then the next is loaded and initialized, etc)
    - Then the BASEDEV= statements (loadable base device drivers) are loaded
      (via INT 13h) and initialized, order is determined by extension (see
      online reference)
    - *** Then we switch to Ring 3 , stop using INT 13h and start using base
      device drivers to access DASD ***
    - Then we load some system DLL's
    - Then we load and initialize DEVICE= and IFS= statements, in the order the
      appear in CONFIG.SYS
    - Then the swapper is initialized
    - *** Then you can write to DASD.  Before this point, access was read-only
      ***
    - Then we process RUN= and CALL= statements from CONFIG.SYS
    - Then we initialize MVDM (load virtual device drivers, etc)
    - Then we start the protect mode shell (PM or Install)
==============================================================================

Q1. How/where should this routine be loaded, so that it remains resident during
    initial load and redirects BIOS INT 13 requests?

A2. IF you could hook the INT 13h vector somewhere before OS2BOOT, and have the
    same functionality in a BASEDEV=???.FLT file, then I suppose you could
    encrypt/scramble/etc the hardfile so that only they would know how to
    interpret it.  Booting a DOS diskette or OS/2 boot diskette would not allow
    access to the hardfile (unless you had the magic TSR laoded for DOS or the
    .FLT file loaded for OS/2.  You don't need the INT 13h vector for OS/2 boot
    disk, just the .FLT).

    I'm not sure how you would do the INT 13h hooking, but you could look at
    the IFS OEMI document that is available in the Main file area on the DUDE.
    The filenames are IFSSRC.ZIP and IFS.ZIP.  Maybe some of the techniques
    available for loading micro-FSD could be applied to loading this INT 13H
    routine.
==============================================================================

Q3. I have loaded an INT 13 hook at location 9FC0:0000 (i.e.  last 1K Bytes
    below 640K).  This also alters the BIOS INT 12 returned available memory,
    which should return 639K to all subsequent requesters.  Will this strategy
    actually reserve this area of memory?

A3. This should work fine but be careful about BIOS's that also take memory
    from the area just below 640K.  Sometimes only 639K or 638K or even 636K
    will be available by the time the master boot record is executed.
==============================================================================

Q4. It would seem that as long as this small routine is not overwritten by the
    OS2LDR or OS2KRNL during loading, it should remain effective while INT 13
    requests are still being serviced.

A4. This is correct.
==============================================================================

Q5. Is there any way I can get a memory map of the major components of OS/2
    during loading?  i.e.  the locations of OS2LDR, OS2KRNL, BASEDEVS,
    CONFIG.SYS tables, etc?  Specifically, how is the 640K or more of real
    memory allocated?

A5. There is no easy/documented way of doing this.  It changes from system to
    system, and would change if you changed your CONFIG.SYS, configuration,
    etc.  You would have to find the arena records at the time you are
    interested in the memory layout, and interpret them.
==============================================================================

Q6. Accessing of the Master Boot Record is obviously critical during boot.  Any
    program attempting to protect the Partition Table must control this.
    When/where exactly is the Master Boot Record/Partition Table read?

A6. The Master Boot Record is read by Bios in the first sector.  Specifically,
    cylinder 0, head 0, sector 1.
==============================================================================

Q7. Is there anywhere else the Partition Table is read again from disk?

A7. Yes, FDISK and Boot Manager.
==============================================================================

Q8. If I go into a DISKEDIT program and erase the Partition table data (just
    the Boot and Sys Indicator bytes in the primary partition) and reboot, then
    I see the following problem.  First, OS/2 appears to go a long way to
    booting, but afer the logo screen is erased I get the dreaded:

    The system cannot find the file C:\OS2\SYSTEM\COUNTRY.SYS specified in the
    COUNTRY command on line 30 of the CONFIG.SYS file.  Line 30 is ignored.

    The system is stopped.

    Correct the preceding error and restart the system.

A8. At some point during boot we stop using BIOS INT 13h to read the hardfile
    and start using the device drivers (OS2DASD ->.FLT ->.ADD).  The first file
    that is opened (before OS/2 WARP) was country.SYS.  The message above
    indicates that the DosOpen of COUNTRY.SYS failed.  In OS/2 Warp, you would
    likely have gotten a message about "Cannot operate the diskette or hard
    disk..."  because the missing country.sys message did not really convey the
    problem.  In OS/2 Warp, we simply DosOpen the boot drive.
==============================================================================

Q9. I deduce from this, that the OS2DASD.DMD is not the only guy looking at the
    partition table.  I think my changes have covered that.  So someone else
    appears to be going out to read the Master Boot Record.  Obviously the
    above message is coming from OS2LDR, but I also thought that the INT 13
    hook would take care of any references OS2LDR might make to the Master Boot
    Record.  In fact, since the interrupt vector is hooked, I would expect the
    system to crash altogether without any kind of message if the code pointed
    to by the interrupt vector was corrupted.

A9. No, this request should be going through OS2DASD, at least the request to
    read the FAT.
==============================================================================

Q10. Could it be that the INT 13 hook established before OS2BOOT, has been
     eliminated or preempted by OS2LDR?

A10. No, the the INT 13h hook is no longer used at this point, OS2DASD->
     .FLT-> .ADD is being used.




!NETWORK________________________________**********
March 3, 1995
QUESTION: (Ref: FQ8)
The problem with the etherlink driver is it requests resources in an interrupt
routine.  This is how it happens, Card Services calls into the etherlink
drivers IDC entry point with a Card Insertion event at interrupt time.  At
this point the etherlink driver calls into card services asking for resources.
Due to a change in design you can not ask for resources during an interrupt
handler routine.  Card Services fails the request for resources and therefore
the etherlink driver fails initialization.


ANSWER:
This problem will only occur for drivers that loop to wait for Register
Complete.  Here is what needs to be done so that Card Services will not call
the IDC of the client driver at interrupt time.  In the client driver move
RegisterClient to the Init_Complete code.  This will force the register client
to be be at ring 0 instead of ring 3 as in the init command.  At the end of
the init_complete do not loop on register complete.  Instead issue a
proc_block.  In the IDC under registration complete issue a proc_run command
to finish the init_complete code.

init_command:
    Parse INI file
    Save DevHlp entry point
    DevHlp_AttachDD (CardServices)
    return(success)


init_complete_command:
    registerclient;
    Devhlp_ProcBlock(BlockID); /* put -1 in timeout high and low, set
          interruptable */
    return(success);

Registration_complete
    if (BlockID !=0) Devhlp_ProcRun(BlockID);
    return(success);




