This is file: 10_94QA.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)
==============================================================================

!OTHER__________________________________**********
October 28, 1994
QUESTION: (Ref: FH6)
There is a bug in the DevHlp_PhysToUVirt 'C-wrapper' found in
           \DDK\SRC\DEV\DASD\DEVHELP\DHCALL2.ASM

This file contains assembly code to convert stack-based C calling conventions
to the register based model used by the DevHlp functions. The definitions
rely heavily on MACROs defined in \DDK\SRC\DEV\DASD\DEVHELP\DHMACS.ASM


The DHDef  MACRO creates the function name and sets up a stack frame.
The DHArgs MACRO creates a name for arguments passed in on the stack and
                 sets up an offset into the stack frame for that argument.
The DHCall MACRO executes the appropriate DevHlp function call.
The DHRetx MACRO produces code to destroy the stack frame and return.

Arguments on the stack are referenced using offsets from the base pointer,
[BP] which are generated, in part, from the DHArgs MACRO. See DHMACS.INC for
details.

The text for the DevHlp_PhysToUVirt function as it appears in the DDK is
shown below.

;*
;*
;* BOOL APIENTRY DevHlp_PhysToUVirt( ULONG PhysAddr, USHORT usLength,
;*                                   USHORT Flags, USHORT TagType,
;*                                   PVOID SelOffset);
;*
;*
;*


        DHDef   PhysToUVirt
        DHArgs  ULONG,   PhysAddr
        DHArgs  USHORT,  usLength
        DHArgs  USHORT,  Flags
        DHArgs  USHORT,  TagType
        DHArgs  PVOID,   SelOffset


        mov     ax, Stk.PhysAddr[2]
        mov     bx, Stk.PhysAddr[0]
        mov     cx, Stk.usLength
        mov     dh, Stk.Flags
        mov     si, Stk.TagType

        DHCall

        push    es
        push    bx
        les     si, Stk.PhysAddr
        pop     es:[si][0]
        pop     es:[si][2]

        DHRet1


After the initial declarations, the 32-bit physical address is loaded into
AX:BX, the length of the segment is loaded into CX, and the values of the
flags and tag are loaded into DH and SI respectively.  Following the call to
the DevHelp function, the virtual address is found in ES:BX.  The code
*SHOULD* put this virtual address into the space pointed to by the address on
the stack referenced by "SelOffset".  Instead, however, the code uses the
32-bit physical address, "PhysAddr".  This will, in most cases, cause a
general protection fault when it is dereferenced.

To fix this problem, replace the line

        les     si, Stk.PhysAddr

with the line

        les     si, Stk.SelOffset

The complete result is shown below:

;*
;*
;* BOOL APIENTRY DevHlp_PhysToUVirt( ULONG PhysAddr, USHORT usLength,
;*                                   USHORT Flags, USHORT TagType,
;*                                   PVOID SelOffset);
;*
;*
;*


        DHDef   PhysToUVirt
        DHArgs  ULONG,   PhysAddr
        DHArgs  USHORT,  usLength
        DHArgs  USHORT,  Flags
        DHArgs  USHORT,  TagType
        DHArgs  PVOID,   SelOffset


        mov     ax, Stk.PhysAddr[2]
        mov     bx, Stk.PhysAddr[0]
        mov     cx, Stk.usLength
        mov     dh, Stk.Flags
        mov     si, Stk.TagType

        DHCall

        push    es
        push    bx
        les     si, Stk.SelOffset
        pop     es:[si][0]
        pop     es:[si][2]

        DHRet1


After making the change, remake the library DHCALLS.LIB using the makefile in
the subdirectory.  The result should then be copied to \DDK\LIB.


ANSWER:
APAR 74979 has been fixed and the modified version is now contained in
DDKX86\SRC\DEV\DASD\DEVHELP\DHCALL2B.ASM.Corresponding update of DHCALL.LIB
has also been implemented.  These changes come into effect in the next DDK
release.




!OTHER__________________________________**********
October 28, 1994
QUESTION: (Ref: FG0)
Does ASDT only work on PS/2 type machines ??  I can't get it to work on a AT
type machine.  It enters the debug window , but the machine locks up
completely.


ANSWER:
Although the ASDT debugger is provided "as is" on the DDK, and it is only
stipulated to work on the PS/2 (see documentation on DDK), I worked a problem
similar to this before. The owner of the program is in Lexington, Kentucky.
He has provided us with the following patch that solves 90% of your type of
problems. Give it a try. If it doesn't work, he will deal with you directly if
you have an Internet ID. So, if the patch doesn't work, send me your ID and I
will pass it to the program owner.

              2 patches for latest ASDT32 and clone kbds:

                   find 0x752BB96400E464

                   change 0x75 to 0x74

                   find 0x50B00AE620EB00

                   change 0x50B0 to 0xEB0F




!OTHER__________________________________**********
October 28, 1994
QUESTION: (Ref: FF4)
Is the device helper SendEvent useful for changing the foreground session from
a program that is not running in the foreground ?

If so do you have an example of doing this ?


ANSWER:
There is no documented event for switching a background session to the
foreground thru SendEvent devhelp.  Switching sessions between FG and BG is
done by the Session Manager component of the kernel thru hotkeys like ALT+ESC.
Applications that spawn sessions can switch its child sessions between FG and
BG thru system calls like DosSelectSession.

If this facility is needed for a specific session, then this app can setup a
hotkey.  The driver can pass this hotkey to the session manager.  The App, on
receiving this hotkey, can then switch one of its child sessions to its
foreground.

SendEvent is called by a Device Driver to indicate the occurrence of any of a
given set of keyboard events-Session Manager request from Mouse or Session
Manager Hot Key from Keyboard etc.  This DevHlp is used in the KeyBoard Device
Driver in the DDK.  One of the samples in which the driver looks for the Hot
Key Event is in ddk\src\dev\kbd\kbdsubs.asm.




!OTHER__________________________________**********
October 28, 1994
QUESTION: (Ref: FF2)
Is the format of the .sym files used by the OS/2 kernel debugger documented
anywhere?


ANSWER:
The format of the .sym files that the OS/2 Kernel Debugger uses is not
documented.




!VIDEO__________________________________**********
October 20, 1994
QUESTION: (Ref: FF9)
I'm here because a client asked us for OS2 drivers for his video adapter.  He
has an Asem computer, with an HT (Headland Technology ?) 216 adapter.  The
PCMTABLE lists only the 209, but he wants a driver for the 216.  Does IBM have
or plan on developing one for this chip set?


ANSWER:
Bad news. Headland technology has been out of business for about a year. There
is no plan within IBM to write a device driver for the HT 216 chip set. Sorry.




!OTHER__________________________________**********
October 20, 1994
QUESTION: (Ref: FF7)
We have an inventory application that we are porting over to OS/2 and it
appears that the code we use to determine the existence of a math coprocessor
is emulated in OS/2, thereby giving us a false report that a coprocessor
exists.  Is there a recommended way in OS/2 to determine the processor type
and existence of the coprocessor (and type)?


ANSWER:
1. Write a Device Driver to execute a floating point command.  The results can
   be used to determine the existence of a coprocessor.

2. Use a bios call to determine processor type.




!STORAGE________________________________**********
October 20, 1994
QUESTION: (Ref: FE8)
Is there a way to determine if a CD-ROM drive, without a CD in it, is a CD-ROM
drive (and not some other type of removeable drive)?

We have tried DosQueryFSAttach(), but it returns an error if the CD-ROM drive
is empty.


ANSWER:
Download TESTDEV.ZIP from the Main file area on the DUDE bbs.




!STORAGE________________________________**********
October 20, 1994
QUESTION: (Ref: FD9)
Q1:  I am writting a SCSI Device Driver for our PCI to SCSI adapter
      for OS/2 2.0.  I am unclear on how to access the ROM BIOS code
      on our card.  The purpose is to find out if our ROM code is
      controlling any device.  I know that in DOS drivers we can call
      Interrupt 13h.

A1:  The OEMHLP device support supports several IOCtls to access
       necessary BIOS Information.  These have been documented in the
       Physical Device Driver Reference - OEMHLP IOCtls.

       Use DosOpen to obtain a FileHandle to OEMHLP$ and then use
       DosDevIOCtl with relevant Category & Function Codes.
==============================================================================

Q2:  Could you also tell me about any good books on OS/2 for
      programmers (device drivers)?

A2:  "Writing OS/2 2.1 Device Drivers in C" by Steve Mastrianni
      "The Design of OS/2" by H.M. Deitel & M.S. Kogan




!OTHER__________________________________**********
October 20, 1994
QUESTION: (Ref: FD4)
Q1: Can you tell me whether there were any changes in the specs for
     DASD block device drivers between OS/2 V1.2 and V2.x?  Or,
     rephrased, can I expect a driver written for V1.2 but no longer
     supported by the MFR to run on V2.x without modification?

A1: There are some OS/2 v1.2 device drivers that run fine in OS/2 v2.x
     without modification.  There is no guarantee that ALL OS/2 v1.2
     device drivers will run in OS/2 v2.x without modification.
==============================================================================

Q2:  Is there, by any chance, a way to use a Netware V3.1 Disk DD
      under OS/2?  (I'm not familiar with the OS/2 virtual/physical DD
      distinction, but their names suggest that there might be a way
      to to an oddball force-fit of that sort.)

A2:  If the Netware v3.1 Disk DD was not written for OS/2 then it will
      not run in OS/2 except MAYBE in an OS/2 Dos session.




!OTHER__________________________________**********
October 20, 1994
QUESTION: (Ref: FD1)
We need to perform 12 microsecond - 13 millisecond delays in a PDD.  What is
the best way to perform this?  I have heard the 8254 timer chip channel 0 can
be used.  Is this true?  We use it in dos.  My concern would be other PDD's
that also think they can use it and reprogram it differently than our PDD
programs it, causing problems.

We have 2 delay types:

1. DELAY(n) - wait for n microseconds to elapse.
2. check time.
   while (n micro/milliseconds have not elapsed)
     check hardware for ready and return if so.


ANSWER:
1. A high resolution timer device driver (timer.sys) is available.
   There was an article about it in the Fall '91 issue of "IBM
   Personal Systems Developer" by Derek Williams.  It accesses the
   8253/8254 counters and can record timer ticks down to 840
   nanoseconds.  You can read from the driver via DosRead's which
   your driver can do at Init time.  A source listing of the driver
   is available in the above mentioned Journal.  Contact Derek
   Williams at Charlotte for the driver.  This has the risk of, as you
   mentioned, other applications trying to use the same channel.

2. Currently there is no way of getting Microsecond resolution with
   the OS/2 timer. The only way to get timer interrupts faster than
   32 milliseconds is to use a hardware timer card that supplies
   interrupts at a faster rate and provide a physical device driver
   to field the interrupts thru DevHelp_SetIrq.

3. The simplest way to get millisecond delays is to call DosBeep()
   with the required value and with a frequency range out of the
   audible range.  However, this interval is not accurate but close
   enough for delays.  This could be used at Init Time and for
   delays in milliseconds.




!VIDEO__________________________________**********
October 20, 1994
QUESTION: (Ref: FA1)
The following statement works under OS/2 2.11 but failed on Japanese OS/2 2.11

rc=DosRequestVDD(hvdd, sessId, VVDSYSREQ_SETACCESS, ACCESS_PMREQUEST,0, 0, 0);

rc = DosRequestVDD( hvdd, sessId, VVDSYSREQ_QUERYMODE, 0, 0, sizeof(VVMODE),
pvvMode);

First statement return 0. The second statement return 87 which is invalid
parameter.  Since the first statement passed, the hvdd and sessId must be
fine.  I checked the source code of virtual video device driver, the invalid
parameter is caused by:

if(ul2<sizeof(VVMODE) || !pvvmDst || hvdm==INVALID_HVDM)
        return ERROR_INVALID_PARAMETER;

Since we pass the SETACCESS, the hvdm test must be fine.  But why the ul2 or
pvvmDst failed the test under Japanese OS/2 but works fine under regular OS/2?


ANSWER:
James, if you are having a problem with the Japanese version of OS/2 (2.11),
you must contact the Japanese DAP program.  You can fax your question to the
Japanese DAP people at 81-3-3495-2045.




!STORAGE________________________________**********
October 20, 1994
QUESTION: (Ref: F85)
As part of our product we added some exta user defined DosDevioctl calls to
the os2dasd.dmd driver, using the source code on ddk1.2.  We found that this
worked if the system, was connected to an ide type drive, thus all hd request
were pased through OS2dasd.dmd.

To obtain the handle that the DosDevioctl call required, we did a direct open,
with the dasd flag set to 1. Unfortunatly if the drive being used for the
dirrect access handle is not managed by the OS2dasd.dmd driver, our extral
calls fails as other dmd such as OS2aspi.dmd do not recognize them.

What is the correct way to obtain a handle that will force the requests to go
through the modified os2dasd.dmd?  We tried adding a character based header
entry to the one that exists in dmheader.c, but in doing this the driver fails
to work and crashes with a trap 0xd , just after the loading msg appears,
before the os/2 has loaded any parts of the pm system.

The modified dmheader.c file is listed below  (code removed for security)

As part of our system, we also need to have a handle that is permantly open,
for a link with our msg system, running at ring 3. Our msg system is designed
to open the link, block and wait for a msg from our driver, and then display a
msg on either the pm of text base d screen.  This works, using the method out
lined above, and has the same problems as noted.  The msg system also suffers
from a problem of not terminating, when the computer, is shutdown using the
shutdown menu option, for example, when boot.com, setboot or ctrl alt del is
pressed.


ANSWER:
The DASD flag used in DosOpen is a direct open flag.  It is used to indicate
to the kernel that the caller is not interested in the file system stored on
the disk, but to return a handle for working with the whole disk.  The disk
could actually be managed by any DMD.  Therefore it is not possible to put an
ioctl only in OS2DASD and expect that to be invoked thru a DASD handle.  If
the idea is work with OS2DASD DMD specifically regardless of the type of the
disk attached then this has to handled thru IDC mechanisms or do IOCTL
directly with this DMD.

In the given code, the strategy function for the character DH should be
DMStrat1b (it is again DMStart1, which is an error)

A shutdown function should be implemented in strategy routine to unblock the
msg thread with an error return.  This may be used to terminate the msg
process.  Note that the device header flags will have to indicate SHUTDOWN
capability.




!VIDEO__________________________________**********
October 20, 1994
QUESTION: (Ref: F50)
In a seamless Windows session, when selecting an item from a menu bar, the
pull-down menu drops down and the whole client area of the windows program is
repainted.  The windows client area is also repainted, when the window of the
program is moved over the desktop.

Q: How can I suppress the repaint of the windows client area ?
   Who is responsible for the redrawing ?
-----------------------------------------------------------
For the FastSafeRamSemStruc I can't find the definition for the fs_RAMSem
sub-elements named RamSemOwner and RamSemFlag. I currently use

RamSemaphore            struc
    RamSemOwner         db ?
    RamSemFlag          db ?
    RamSemReserved1     db ?
    RamSemReserved2     db ?
RamSemaphore            ends

Q: Is this correct ?
   What is in the fields RamSemReserved? ?
--------------------------------------------------------------------------

Q: How can I use the win_callback function pointer provided by
   SEAMLESS_ESC_INIT ?  Could you please provide a short sample of source how
   to setup the parameters for the call(s) ?

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

From the file SEAMLESS.TXT, I retrieved the seamless_enable function.  I think
the code is incorrect in using the gs selector.

.DATA
hw_access       dd      0

.CODE

public seamless_enable
seamless_enable:                         ;DEV ESC 6002h

         les     di,lpOutData            ;
;        push    gs                      ; get addressability to the
         mov     bx, DataBASE            ; data segment
;        mov     gs, bx
;        assumes gs, Data
         lea     si, hw_access
;???     mov     WORD PTR gs:[di+2],bx   ; Data segment selector
;???     mov     WORD PTR gs:[di],si     ; Offset of hw_access
         mov     WORD PTR es:[di+2],bx   ; Data segment selector
         mov     WORD PTR es:[di],si     ; Offset of hw_access
;        pop     gs
;        assumes gs, Nothing

        jmp     short exit_control_inc_ax ;exit successful

Q: Am I right ?
   Who reads/writes from/to hw_access ? (Seamless Windows Drv of PM Drv ?)


ANSWER:
RamSemReserved1 & RamSemReserved2 constitute the RUN/BLOCK ID (Lower Word).
This has been documented in the WINOS231\DRIVERS\DISPLAY\4PLANE\IPC.INC Include
File where it is defined as :  RamSemID dw ?

The seamless windows driver must always check the hardware state before
requesting the video FSRamSemaphore.  If the hardware is disabled or in the
"read-only" state, and the output destination is the screen, the driver should
call Win Shield,requesting Win Shield to accumulate the screen areas
(rectangles) requiring update.

        There are two options when calling Win Shield for a repaint:
           SEAMLESS_FORCEPAINT  To cause the entire Windows desktop to be
                                   repainted.
           SEAMLESS_POSTPAINT   To repaint the accumulated area collected
                                   by Win Shield.

Normally, when a Windows session is switched to the background, its output is
disabled.  Then, when switched to the foreground, a repaint is forced, even if
no modifications were made to the current screen.  This is acceptable when
running a full-screen Windows session.  However, when running seamlessly, the
PM Driver automatically saves the contents of the screen when it is switched to
the background.  When Presentation Manager returns to foreground, the whole
screen is restored (including the seamless windows).  As a result, no refreshes
from the seamless windows will be necessary unless the Windows program
attempted a repaint while output was disabled.  As a performance improvement, a
repaint flag is implemented in Win Shield, which is set initially to FALSE.
When the seamless windows driver is in the background, this flag is set by Win
Shield to TRUE if any refresh of the screen is attempted by the driver (for
example, if the driver calls-back to the Win Shield, passing a clip region).
When the seamless driver is switched to the foreground, a repaint is forced
only if the flag is TRUE.

* Errors have been observed in seamless windows due to the Windows driver's
failure to account for being in the Disabled state.  For example, damage to the
Min/Max buttons for a seamless window was observed.  This occurred because the
Min/Max button conversion was performed in the DIBtoScreen function.  In some
scenarios, when this function was invoked, the seamless windows driver was
disabled.  In this case, the Windows driver could not process the DIBtoScreen
and ignored it.  However, when finally enabled, the driver was told only to do
a block logical transfer (Blt) and not a DIBtoScreen.  The solution was for the
seamless windows driver to store a flag indicating that the button conversion
had not been performed, and to process it at a later time, when enabled.

* Previous seamless windows design assumed that the FS and GS registers were
not modified once loaded.  Under Windows 3.1 this is no longer a valid
assumption.  The seamless windows driver must save the FS and GS contents to
global variables when FS and GS are initially loaded.  Then, before these
registers are used, the seamless driver should compare the contents to the
global variables.  If the contents have been modified, the registers must be
reloaded.

 - The following information is contained in the fast safe semaphore data
     structure:

         - 16 bit length field that specifies the length of the semaphore
            data structure, in bytes.

         - 32 bit process/thread ID that uniquely identifies the thread of
           execution that owns the semaphore.  If this field is zero then the
           semaphore is unowned.

         - 16 bit client field that is not interpreted by the functions in
           this module.  Instead it is a field provided to the caller as a
           means for identifying which resource is currently owned by the owner
           of the semaphore.  It is initialized to zero when a semaphore is
           first acquired, and thereafter the value of the field is under the
           control of the caller, until the semaphore is released.  It is
           useful to a DosExitList handler in figuring out the appropriate
           cleanup action.

         - 16 bit usage count.  This count is incremented each time the
           current owner acquires the semaphore and decrement each time the
           current owner releases the semaphore.  The current owner does not
           actually release its ownership until the count decrements to zero.

         - a 32 bit CPDOS RAM semaphore.  This RAM semaphore is manipulated by
           the functions in this module in the same manner as the the ring 3
           semaphore code in CPDOS (e.g. DOSSEMREQUEST and DOSSEMCLEAR).

         - a 32 bit time out value to use when waiting on the CPDOS RAM
           semaphore.

 This structure is documented in the ddk\src\vga32\ibmvga32\sem.inc file.
 FastSafeRamSemStruc     struc
         fs_Length       dw  ?                ; #bytes in this data
                                              ; structure
         fs_Padding      dw  ?                ; padding for 32 bit
                                              ;  alignment
         fs_ProcID       dw  ?                ; Process ID of owner or zero
         fs_ThrdID       dw  ?                ; Thread ID of owner or zero
         fs_Usage        dw  ?                ; reference count
         fs_Client       dw  ?                ; 16 bit field for use by
                                              ;  owner
         fs_Timeout      dd  ?                ; Timeout value
         fs_RAMSem       dd  ?                ; CPDOS RAM Semaphore
 FastSafeRamSemStruc     ends

 o  rc = Escape( hDC, SEAMLESS_ESC_INIT, nCount, lpInData, lpOutData )

            hDC       = GetDC( hWnd )
            nEscape   = 6000 - SEAMLESS_ESC_INIT
            nCount    = 0
            lpInData  = Pointer to Win Shield "call-back" entry point
            lpOutData = NULL

            On Exit: rc = negative......Error
                     rc = positive......Success

The SEAMLESS_ESC_INIT call is made by Win Shield at initialization time.  On
input, Win Shield provides the address of a call-back entry point.  The
seamless windows driver uses this entry point, in addition to passing a clip
region, to cause an area of the Windows Desktop to be repainted.  This function
is used whenever the seamless windows driver is disabled but must write to the
screen.  Win Shield is responsible for accumulating the clip regions passed to
it.

 Note:
 1. This call is made before the screen is enabled by the Win Shield via INT
 2Fh.

 2. The seamless driver must always invalidate the Windows Desktop when
 OEMUpdateColors is called and the driver is in the disabled state.
 Miscellaneous translation table and color-mapping problems can otherwise
 occur.

 o  rc = Escape( hDC, SEAMLESS_ESC_ENABLE, nCount, lpInData, lpOutData )

            hDC       = GetDC( hWnd )
            nEscape   = 6002 - SEAMLESS_ESC_ENABLE
            nCount    = 0
            lpInData  = NULL
            lpOutData = Pointer to hw_access

            On Exit: rc = negative......Error
                     rc = positive......Success

SEAMLESS_ESC_ENABLE permits a Windows program to determine the current hardware
state.  The escape returns the address of the driver's internal variable,
hw_access, which reflects the hardware state at any time.




!STORAGE________________________________**********
October 20, 1994
QUESTION: (Ref: F36)
We use a procedure to read raw data from CD-ROM.  It works fine with MSCDEX
Ver2.22 and 2.23.  However, when we use this one on OS/2 2.11 VCDROM driver,
the system responeds that it does not support this functon call.  Would you
please advise us whether the following procedure is correct or not.
(code removed for security)


ANSWER:
MSCDEX v2.21 is fully supported under OS/2.  The format of the Request is
described in the Microsoft MSCDEX spec, which I presume you must be following.
DOS applications that issue a MSCDEX int 2fh call will be trapped by the
device driver's CDROMInt2f routine and sent to VCDROM VCDROMDosLink for
processing.  Int 2fh with AH=1510h then calls the SendDeviceRequest with the
Request Header as the first parameter & the drive number as the second
parameter.  Source codes in ddk\src\vdev\vcdrom\vcdrom2f.c and cdstub.asm
document these.  Hence the application need not do an explicit
Send_Device_Request,since VCDROM.SYS will take care of Mapping the INT 2Fh.




!OTHER__________________________________**********
October 20, 1994
QUESTION: (Ref: E22)
I'm trying to build a POSTSCRIPT printer driver for OS/2.  I purchased the DDK
CD and Watcom v 10.  When I tried to use the makefile that shipped with the
DDK, I got an error message saying that on Line 104 of OS2DEF.H file expecting
',' or ';' but found 'PUCHAR'.  What is going on here?

First of all, can I use Watcom to build this driver?  I have revised the
CC=ICC to CC=wcl in the makefile.  What else needs to be changed?


ANSWER:
The Code for the POSTSCRIPT printer driver in DDK has been compiled on IBM
CSet/2 Compiler.  The code presently is not compatible with the Watcom
Compiler.  The Makefile has to be rewritten for the Watcom Compiler and the
DDK source presently does not support the Watcom Compiler.


FOLLOW_UP QUESTION:
In regards to PS makefile, I recently bought IBM C Set++.  After I install IBM
C++, I try NMAKE /F MAKEFILE under \DDK\SRC\PRNTDD\POST32.  It doesn't compile
the codes.  Original source with unmodified MAKEFILE.  What do I have to do
now?  The MAKEFILE contains some reference to \IBMC\CBIN, \IBMH,
\IBMC\CINCLUDE...  None of these exist in IBMCPP.  The compiler complained
about STDIO.H, OS2.H...  not found!


ANSWER:
The POST32 Build requires Microsoft MASM 5.1 & IBM CSet/2.  After installing
the DDK, make sure you execute "COPYCSET.CMD".  This copies all relevant files
from the installed directory to the proper directories under the DDK Base
Directory.  After this,you could go to the relevant directory and just execute
"NMAKE" without any parameters.




!OTHER__________________________________**********
October 20, 1994
QUESTION: (Ref: D44)
Is there a document anywhere that details the issues involved in writing
drivers for SMP?


ANSWER:
Download SMPDOC.ZIP from the Main file area on the DUDE bbs.  The information
in SMPDOC.ZIP is also available online with the OS/2 for SMP Version 2.11
product.




!STORAGE________________________________**********
October 13, 1994
QUESTION: (Ref: FB0)
Q1. I am using PhysToVirt to access data buffers passed to my IFS during READ
    and WRITE while in the context of my ring 3 daemon process.  I am of course
    locking down the memory first and using VirtToPhys in the context of the
    IFS request before calling PhysToVirt in the context of the ring 3 daemon.
    All this seems to work for 1 application but with a heavier load I start
    encountering error 8 (out of memory).  I have heard that OS/2 has a "locked
    memory area" but cannot find any documentation on it.  If there is such a
    thing as a locked memory area I am probably running out of it.  What can I
    do to alleviate this problem?  What are the various OS/2 memory areas and
    how do they work?

A1. The buffers passed via READ/WRITE will be locked into memory and converted
    into physical address by the kernel before it is passed to the drivers.  It
    is only the non-parameter pointers (like pointers passed in user structures
    in IOCTL calls) that need attention.  The PhysToVirt function picks up
    selectors from a limited pool of temporary selectors.  Therefore, it is
    possible to run out of memory if these are not freed quickly.  Refer to
    \ddk\src\dev\mouse\ioget.asm for a sample usage of PhysToVirt.

    The various memory areas in OS/2 2.x are explained in detail in the book
    "The Design of OS/2" by H. M. Deital and M. Kogan.  Refer to the redbook
    vol 0:  Control Program Reference for a broad introduction.  If you are
    using OS/2 2.x, there are 32-bit memory management DevHelps which are
    described in the latter book that may be worth taking a look at.  You may
    also want to see if you can use shared memory rather than pinned memory to
    transfer data.  With 32-bit paged memory, you dont have to lock an entire
    segment at a time; you can do it 4K pages at a time.

    PhysToVirt yields a GDT Based Pointer which is not usable from a Ring 3
    Thread.  Ring 3 Threads do not have GDT Access, they only have LDT Access.
    PhysToUVirt yields a virtual address mapped to the Application's LDT.
==============================================================================

Q2. I am also using PhysToUVirt to support network RAW data transfers.  It
    seems to work fine while copying files but if I try to run a application
    from a network drive (thru my IFS) I get error # 176.  Why would
    PhysToUVirt work fine except when running applications?

A2. The error #176 (in decimal) is Reserved by the System and is not
    documented.

    PhysToUVirt returns a fabricated segment for private use between a Physical
    Device Driver & an Application.  Data within such a segment cannot be
    passed on system calls and can be used by the receiving application only to
    return data variables.




!I/O____________________________________**********
October 13, 1994
QUESTION: (Ref: FA0)
For the READ strategy call, the kernel passes a 32-bit physical pointer, which
I must convert to a 16:16 pointer via DevHelp_PhysToVirt.  The documentation
for DevHelp_PhysToVirt says that the pointer returned is temporary and is
valid until I call another DevHelp.  Does this mean that I cannot call
DevHelp_VerifyAccess?  And if I can't, how can I tell whether the pointer
passed to be is valid?


ANSWER:
1. DevHelp_PhysToVirt creates a mapping from a temporary pool of selectors.
The assigned selector will be reused if this thread yields control.  Special
care is required in calling other DevHlps because they may trash some of the
special registers loaded by this call.  If you need to use
DevHlp_VerifyAccess, refer to the sample code in \ddk\src\dev\mouse\ioget.asm
(DDK v1.2).

2. You could also use PhysToGDTSel/PhysToGDTSelector before calling
VerifyAccess.

3. PhysToVirt gives an address in the Global Address Range.  PhysToUVirt
yields an address in the Process Address Space.  You could use this DevHlp if
you do not need a Ring 0 Address.




!STORAGE________________________________**********
October 13, 1994
QUESTION: (Ref: F84)
When using the HD with our Parallel/SCSI converter, the IORB Entry is being
called consecutively twice with the same IORB.  We are testing the ADD driver
we wrote, if "xcopy c:\ e:  /s" command is executed (e:  is the external SCSI
HD assigned), we found out the ADD will be called twice with the same IORB,
although we specified the ADD queue length to be 1 in the Build_device table.
We cannot queue the IORB due to the same IORB.  The result is the system hangs
in OS/2 waiting for a new job (we can still do CTRL C from the debug monitor,
however the window executing the XCOPY is hung).

I think the problem happpens while the IORB is finished or after the
ThisIORB_Complete routine.  In the routine, the ADD will call the
NotifyAddress if the ASYNC_POST flag is set.  Since the ADD is not blocking
the thread, the NotifyAddress routine specified in the IORB may or may not be
able to finish before returning back to after calling the NotifyAddress
routine which is essential to our ADD to complete the IORB.  At the same time,
another CallADD is issued causing the ADD to be called twice even though we
specified the QueuingCount in the UnitInfo to be one.

Is this making any sense?  Is it possible that OS2DASD will call an ADD twice
with the same IORB?  How can we resolve this problem?  The only thing I do not
understand is "Why the second IORB has the same address as the first one?"


ANSWER:
Please check on IORB_EXECUTE_IO Control Block for the Block Count Field.  This
indicates the number of blocks to transfer.  If this value exceeds the
adapter's maximum transfer size, the driver is responsible for issuing
multiple operations to the Unit to complete the Caller's request.

If the IORB_ASYNC_POST flag is set, the ADD will call Notify routine when the
IORB request is completed.  A sample of this routine - NotifyIORBDone could be
found in ddk\src\dev\dasd\os2dasd\dmqueue.c.  This could be incorporated into
your code.

Also check on the status returned by the ADD after the first IORB Request.
The IORB_REQ_STATUSBLOCK should be set and the ADD should return the command's
associated information.




!PRINT__________________________________**********
October 13, 1994
QUESTION: (Ref: F70)
My goal is to make a printer driver that uses SCSI download instead of going
thru the regular parallel line.  Does IBM have any such products or have any
interests in developing such a product?  Who do I call or contact?


ANSWER:
We do not have this kind of a driver nor any plans to write one.  We can ask
Development to take writing one into consideration.




!OTHER__________________________________**********
October 13, 1994
QUESTION: (Ref: F62)
I want to protect myself from Windows apps that forget to use dpmi.  How do I
determine that the app forgot to use dpmi?  See below:

    an app going via dpmi would do
            ...                         ; copy buffers to real mode
            mov     bx,6eh       ; interrupt to simulate
            mov     ax,300h      ; int 31 function code for...
            int     31h              ; simulate real-mode interrupt

    an app that fogets to use dpmi would do
            int 6e


ANSWER:
By only hooking the int 6e in v86 mode, there is no way to tell if the app
issued the int 6e in V86 mode or if it used the DPMI simulate real mode
interrupt function.  The only way to tell for sure if the interrupt was issued
in protected mode is to hook the int 6e in both V86 and protected mode (you
can hook int 6e in protect mode by issuing an int 31, function 205, there may
also be a Windows call that allows you to hook protected mode interrupts).




!NETWORK________________________________**********
October 07, 1994
QUESTION: (Ref: FC7)
What I am looking for is where I can obtain a document that describes the
structure of the .NIF files used when installing NDIS drivers in either the
LSP or thr LAN Server LAPS.  I have been able to determine some of the
information by looking at other vendors .NIF files but would prefer to obtain
a document defining all the possible entries.


ANSWER:
There is a set of documents called the IBM Driver Implementation Package.
This package contains information on NDIS and NIF formats.  This is the only
information that we are aware of.  To obtain a copy, send a request to:

    IBM Corporation
    Dept 483
    ATTN: NDIS
    11501 Burnet Road
    Austin Texas 78758




!OTHER__________________________________**********
October 07, 1994
QUESTION: (Ref: FB8)
The ultimate problem I have is getting my Device Driver to convert 32 bit
applications pointers to Device Driver pointers.  I am doing an IOCtl call
from a 32 bit app.  that has pointers embedded in the structure that gets
passed to the IOCtl call.

My solutions is/was to use DevHelp_LinToGDTSelector call.  This requires the
linear address to first be locked.  Thus I want to use DevHelp_VMLOCK, and
this is the problem I am blocked on.  Could I get a sample piece of code to
demonstrate the proper use of VMLOCK?  I am confused about all the pointer
that VMLOCK takes.  Thus any code that show all the data structres and
variable definitions to all the parameters being passed to VMLOCK would help.

I have read the OS/2 2.0 Technical Library Physical Device Driver Reference
Version 2.00, First Edition (March 1992) description of VMLock on page 17-103;
this is confsing to me.  There is not a good description of what gets put into
EDI and ESI.  I have also read Writing OS/2 2.1 Device Drivers in C, and it is
basically just the same information for the VMLock call.


ANSWER:
1. It is not necessary to go thru LinToGDTSelector in OS/2 2.x.  The VMLock
returns a physical address(es) (in the PageList_s Structure) that can be used
in all modes.

2. There are lots of examples of VMLock usage in the code samples supplied in
the DDK v1.2 CDROM.  For example,

    \DDK\SRC\DEV\DASD\OS2DASD\{DMFAULT.C,DMIOCTL.C}
    \DDK\SRC\DEV\CLOCK\CLOCKDD.ASM
    \DDK\SRC\DEV\KBD\KBDIOAB.ASM

3. ESI should contain the address of a 12-byte buffer, where the kernel stores
the handle to the locked area.  This handle returned by the DevHlp is used in
DevHlp_VMUnlock.  EDI should contain the address of an array of PageList
structures.

When a region in locked into physical memory, the locked area could occupy one
or more page ranges that could be discontinuous.  This is what is returned in
the array.  If you plan to do a contigous lock, then only one page range will
be involved.  The PageList structure is defined in \ddk\h\vdmm.h (for C) and
\ddk\inc\vdmm.inc (for assembly).  Each Pagelist_s Structure describes a
single physically contiguous subregion of the physical memory that was
locked.The format of the PageList_s structure is :

PageList_s struc
  pl_PhysAddr  DD  ?  ;Physical Address of first byte in this subregion
  pl_cb        DD  ?  ;No.of contiguous bytes starting at pl_PhysAddr
 PageList_s ends

4. For more info on VMLock and other 32-bit memory management DevHlps please
refer to the following books :  Redbook GG24-3730 (OS/2 Version 2.0 Volume 1:
Control Program) The Design of OS/2 by H. M. Deitel and M. Kogan




!STORAGE________________________________**********
October 07, 1994
QUESTION: (Ref: FB1)
During FS_OpenPageFile I specified a max SGlist size of 255.  I have never
seen more than 8 at a time; and then only with all 8 being WRITE commands.  I
don't think I have ever seen a mixed write/read set.  Also, READs are always
set individually.  Why?

This is despite a program that allocates/commits 16mb of memory and does a
memset() on it.  I was expecting to see much larger s/g requests.


ANSWER:
The SGList is set to 8 because the tuning that went on for the paging said
that 32k was the best tradeoff, so far.  Obviously this could change.




!OTHER__________________________________**********
October 07, 1994
QUESTION: (Ref: F98)
I have a physical device driver.  A pointer to a buffer is passed to the
driver via the IOCtl parameters.  The buffer contains pointers to more
buffers.  The driver does some work on these buffers, then locks them down
using DevHelp_Lock.  The buffer is now physical contiguous memory.  The driver
does a VirtToPhys and then passes the physical address on to a lower level
driver.

This all works fine for 16:16 bit apps.  I need to get this working for DOS
apps.  I thought I had this working by doing the following steps:

        - DevHelp_AllocGDTSelector
        - convert dos pointer to linear pointer
        - DevHelp_LinToGDTSelector
        - DevHelp_Lock
        - DevHelp_VirtToPhys

Then I found out that the DEVHelp_Lock was not putting the buffer into a
physical contiguous memory.  Reading some of the QA files on the DUDE I found
that DEVHelp_Lock seems to only work with 16 bit apps, and I must use
DevHelp_VMLock.

I changed my method to

        - convert dos pointer to linear pointer
        - DevHelp_VMLock
        - DevHelp_AllocGDTSelector
        - DevHelp_LinToGDTSelector
        - DevHelp_VirtToPhys

Should this sequence work?  At present I can't get past the DevHelp_VMLock.
The code is 8005.  What does that mean?


ANSWER:
The Error Code 0x8005 is listed in ddk\ibmh\bseerr.h Header File.  The error
is caused due to the System not being able to initialise the SWAPPER
(ERROR_CANT_INIT_SWAPPER).

Use of short term locks for greater than 2 seconds can cause a shortage of
pages that are available for system use.  Under these circumstances a system
halt could occur.If satisfying the Lock Request will reduce the amount of free
memory in the system below a predetermined min., both short term & long term
locks can fail.  Try reducing the count of Bytes to confirm this problem.




!PRINT__________________________________**********
October 07, 1994
QUESTION: (Ref: F74)
I'd like to build and install the 32 bit PostScript printer driver sample code
from the DDK 1.2 as a preliminary to further driver development.  I've
followed all of the instructions in the DDK USE book about compiler versions,
MASM and updating PATH and I can build the driver without error messages.  The
resultant driver is 494449 bytes in size.

When I try to install the driver from the c:\ddk\mri\prntdd\post32\retail
directory I get the following message after selecting Refresh in the Install
New Printer Driver dialog - "A program in this session encountered a problem
and cannot continue".  In the display register info dialog I get " A program
generated an access violation at 11bea7ab PSCRIPT.DR 0001:0000a79b.

Is this a known problem?  Is there a workaround?


ANSWER:
Please remove the Optimisation Options from the Compiler Options and rebuild
with a "nmake /a ".

Look for the OPT Macro in the makefile.  The first occurrence is at the
following instance:

    #Retail Options
    OPT=-UDEBUG -Oilt

Please change the above line to - OPT=-UDEBUG

The next instance where the change is made is at :

    #Optimise
    !ifdef noopt
    :::::::::::
    !else
    OPT=/O+
    Change the above line to OPT=/O-
    Rebuild with nmake /a option.




!BASE___________________________________**********
October 07,1994
QUESTION: (Ref: F71)
I need to steal some bytes out of the master boot record on each physical hard
drive.  Ideally I need about 6 or 8 bytes at 19Eh but any area will do.
Certainly the bootstrap loader doesn't use all 446 bytes!

Please let me know what bytes are safe to use.  I see 8 bytes at 1A0h and they
seemed to be OK.  I realize the FDISK will probably write over what I use but
that is OK as well.  It would be real nice if it didn't, but I can live with
it.

This is needed for data security on the disk and is necessary when the device
drivers are loaded.  The data space needs to be 8 contigious bytes if
possible.  We normally use a little space in the master boot record which all
OS's leave alone.


ANSWER:
The bootloader area is strictly offbounds.  Its actual size may vary between
models and the OS that is used to format the volume.  There is no specific
area in the MBR that could be considered 'free' for storing user or OEM data
since the Master Boot could be different even for the same version of OS/2.

On a given machine that is not likely to go thru an OS installation, you could
experiment and steal space that is considered safe but there is no 'safe' way
in which this can be used generally.  If this were to be true then viruses
(both benign and malign) would have a field day.

If your intention is to hide a security code, you could try using up a
partition table entry.  Some disk space will be wasted.  I do notice however,
that MBR uses up only 1 sector on CH (0,0).  User partitions begin only after
CH (0,1).  You could contact the disk manufacturers to check how much of this
space is used by them for storing OEM info.




!STORAGE________________________________**********
October 07, 1994
QUESTION: (Ref: F65)
I am in the process of developing a OS/2 Device Driver for a Parallel port
based Hard Disk.  The Hard disk interfaces with the parallel port and has
print-thru capability.  I have a working DOS device driver and am using that
as the base for coding the OS/2 device driver.

Should the device driver be a base device driver or an installable device
driver?  Based on my readings so far, the base device driver works in
conjunction with the OS/2 DASD manager (OS2DASD.DMD).  The OS/2 kernel and
file system interacts with the DASD manager, which in turn interacts with the
Base device driver.  In case of the installable device driver,the OS/2 kernel
and file system interact directly with the driver.

Does IBM have an "official" stance on which approach the OEM's should take?


ANSWER:
The Base Device Driver is a part of the Split Device Driver Model.  This Model
has been used by IBM for all SCSI Devices except the SCSI fixed disk, which
use the OS/2 DASD Manager.  The Device Class Driver is the upper level driver
and the SCSI driver is the lower level driver.  This model facilitates the
development & maintenance of new SCSI device drivers.  The hardware dependant
layer is seperated from the hardware independent layer in this model.  The
choice of the type of driver lies entirely with the Developer .If there are
possibilities of upgrading the driver,the Split Model is definitely a better
alternative.




!OTHER__________________________________**********
October 07, 1994
QUESTION: (Ref: F60)
The DevHelp_Lock function is randomly returning error 0x8018 (32792)
ERROR_NOBLOCK.  This error is not listed under the possible errors for this
function and has puzzled us as to what it actually means.


ANSWER:
If the Segment is unavailable, the caller must specify whether the Lock should
block execution until the segment is available or should return immediately.
You must have probably set the WaitFlag, which means if the segment is
unavailable it immediately returns without locking the segment.




!OTHER__________________________________**********
October 07, 1994
QUESTION: (Ref: F32)
Can you tell me what the difference is between a call to InnerGreGetAttributes
and InnerGreDeviceGetAttributes?  Am I right in hypothesizing that the former
returns attributes of the current DC that the graphics engine stores and the
latter gets the attributes for the DC directly from the device driver?  The
Presentation Driver manual doesn't say that it explicitly.


ANSWER:
GreDeviceGetAttributes is a mandatory graphic engine function.  It is
mandatory to all Presentation Drivers.  If it is not present, the driver
returns a PMERR_DEV_FUNC_NOT_INSTALLED Error.  GreDeviceGetAttributes gets the
Attributes directly from the Device Driver.  GreGetAttributes is a device
support function in the GRE (similar to DevHlp calls).




!VIDEO__________________________________**********
October 07, 1994
QUESTION: (Ref: F31)
If I use true color mode and the 32x32 icon (640x480), the system icons are
monochrome on the display.  If I use the 40x40 icon, then the system icons are
OK.  What's wrong?


ANSWER:
The standard ICON Size in VGA is 32x32.  For High Res.(such as 8514) the icon
size is 40x40.  The VGA format (32x32) cannot be used on the XGA System
running in High Resolution because of the physical dimension differences.
This is the reason for the Icon going monochrome when set to 32x32.


FOLLOW-UP QUESTION:
Yes, I know that the icon size for high res.  is 40x40.  I use 640x480x16.7
million, then I select the driver for 32x32 icon size, like it is for the
640x480x65k and 640x480x256.  Under 16.7 million I got monochrome bitmaps for
the icon.  To prevent this, I changed my driver for 16.7 million to select the
40x40 driver.  That works, but I don't think it's the right way and the icons
are too big.  Under 65k I don't have the problem.  So, do I have to use under
16.7 million with the 40x40 icon size or is there another solution for that?


ANSWER:
The Display drivers on DDK support Colored Icons at a Resolution of 640x480x24
bit Color

In the absence of information about specfic version numbers of OS/2, DDK, and
drivers, I can only provide some clues about how to go about tracing the bugs.

In the case of 16.7 million colors, RGB values for pixels are not indexed.
24-bit pixel values are directly used in the color bitmap.  Could there be an
error in the way the bitmaps are built in the case of 32x32 ?

Please check if the code segments that handle this case (in the sample source
supplied in DDK 1.2 the compilation switch BPP24 envelopes these code
segments) have introduced a bug in the during bitmap conversions.  For the
high res mode the icons will have to be generated from the supplied icons and
there could be a bug in the conversion process.Also the test tools supplied
with DDK can be used to check if this happens only with system icons or even
with user-generated icons.  The icon editor can be used to generate some
sample icons to test these theories.




!STORAGE________________________________**********
October 07, 1994
QUESTION: (Ref: F22)
I've got a question regarding the OS2SCSI.DMD driver.  I've developed a device
driver that talks to OS2SCSI.DMD in order to control SCSI tape drives.  It
works quite well on my IBM PS/2 Model 77 and P75.  We've also tested it on an
NCR ISA machine with an Adaptec 1522 and it works great.  However, one of our
beta testers is trying this out on an EISA machine with an Adaptec 1742 and on
this system OS2SCSI.DMD returns 0xa000 when we attempt to actually write data
to the device.

We are using the 'Send Other' SCB to pass SCSI CDBs to the device, so our
logic goes like this:

  1) Receive write request from app
  2) Build SCSI write CDB
  3) Build the transfer SCB to send other (pass CDB to device directly)
  4) Pass the SCB to OS2SCSI.DMD
  5) Get result from OS2SCSI.DMD
  6) Translate the SCSI sense codes into an OS/2 error code
  7) Return to caller

It is at step 5 where we receive the 0xa000 code back from OS2SCSI.DMD.  What
does this result mean?  After looking through the DDK materials, I _think_ it
means that OS2SCSI couldn't get any sense information from the device; is this
correct?

If this is correct, can I assume that the command completed but sense
information wasn't passed back quickly enough for OS2SCSI.DMD?  If this is the
case, I can do a manual sense data request.  If not, do you have any
suggestions?


ANSWER:
Since the Bit 7 of the Error Code is not set,the error is not SCSI specific,as
mentioned earlier.  Had Bit 7 been set and Bit 0-6 been 0 it would have
pointed to a Device Error and the Sense Data would have been returned.

The Sense Information comes into play only when it is a SCSI driver specific
error.  In your case, this is not true and hence there is no possibility of
the sense information being passed and OS2SCSI.DMD not being able to grab it.

You could use a Get Command Complete Status SCB after executing the Send Other
SCSI Command (SCSI CDB).




!STORAGE________________________________**********
October 07, 1994
QUESTION: (Ref: F18)
I am currently working on communicating with a SCSI device and have been
working with the DosDevIOCtl calls.  The easier calls such as Command 80,
Function 43 or Command 80, Function 55, are communicating fine and send back
correct information.  I would like to start using the TransferSCB(command 80,
function 52) IOCtl, but have been having some trouble with the call.

The call completes with a return code of 0, but then the next time I make a
kernal request from a prompt (after a short delay), the machine gets a system
failure and locks up after printing some diagnostic information on the screen
(if this info would be helpful, I could recreate, and copy it down for you).

I believe that I must be setting up my SCB or SCB header incorrectly and
perhaps am giving a wrong pointer somewhere.  I am a bit confused as to the
difference between the logical and physical pointer references.  I am using
the definitions for SCB, SCBH, TSB, and SenseData from the corresponding DDK
1.2 header files.  If you could tell me of an example of the IOCtl call for a
TransferSCB, that would be great...  I will include my structure definitions
(besides the SCB, SCBH, TSB, and SenseData), my initialization section, and
the DosDevIOCtl call.

I thank you, in advance, for any light you can shed on the subject.  Oh, and
by the way, is there any way to load a device driver in memory without the
config.sys line which needs a reboot everytime?  It gets tiresome rebooting
every time I make a change to test the driver!


ANSWER:
There is no way to avoid rebooting for driver changes to take effect.
However, the turnaround time can be minimised by using a kernel debugger
(preferably a source level).  For debugging drivers, it may be a good idea to
use CMD.EXE instead of PMSHELL.EXE as the workplace shell.

If the PMSHELL is really required, there is a nifty tool called SHIFTRUN
developed by Michael Harris of IBM Cary, NC that can be called from the
config.sys file.  It lets the user invoke a command shell before invoking the
workplace Shell.

You could also go through the DDK v1.2 code located in
ddk\src\dev\dasd\ibm\ibm2scsi\scsisubs.c & scsiint.c to get a feel of how the
parameters are initialised for TransferSCB.  The logical pointer to the SCB
Chain Header comes into play when a chain of SCB's are to be sent to the
Adapter.This is a linear address.  Please let us know what is the Device Class
Driver you are tring to use?  Are you trying to develop your own Device Class
Driver?


FOLLOW-UP QUESTION:
I have been looking over the example that you suggested, and I believe that it
will help me see how to initialize the SCB.  However, before today, I was
calling the generic IOCtl's that are documented in the storage driver
reference from an Application program that is capable of calling
DosDevIOCtl().  Now the SCB's and the TransferSCB IOCtl call seems useless.

Today, I began putting the IOCtl calls into my actual driver, and have
discovered that I will not be able to use the DosDevIOCtl call from within my
strategy section.  I read the one sentence in the reference that said I need
to call these using an IDC entry point.  I may be blind, but I have not found
one source example of a Device-Class Driver.  I know if I had one example, I
could use that as a guide, but where to find it, I don't know!

In answer to your questions, I am trying to develop my own device-class driver
to request commands from an image scanner.  There aren't too many commands
that it supports, and I was hoping to just use the TransferSCB request within
my strategy section to support these commands to an application programmer.

I have a device driver, SCANNER.SYS which is basically a skeleton now, that
has an Init section, and a strategy section.  This driver will accept
DosDevIOCtl calls from an application program...supporting a SCAN_CATEGORY,
and some various FUNCTIONS.  Now it just runs through some case statements,
executes a DosBeep for each command, function pair and returns RPDONE.

I was hoping to just slide the various SCB initializations and DosDevIOCtl
calls into this skeleton...but, now I guess that I will have to send the SCB,
Command, Function, pBuffer, and pParms a different way.

I don't understand why the reference discusses the TransferSCB and other calls
as if you could use them from a DosDevIOCtl, when that is not the way you call
them!

Any source example of these kinds of calls to the OS2SCSI.DMD would be most
helpful.  I just want to send an SCB of the format discussed in the reference
to the OS2SCSI.DMD along with a corresponding pXferBuf and have this sent to
the scanner causing it to execute my SCB, and return SenseData and whatever
pXferBuf data the command calls for.

Anything you have will be appreciated, as I haven't found much documentation
along this device-class driver quest at all.  I did find a reference to an
OPTICAL.SYS that is an IBM device-class driver, but I couldn't find the actual
source for this anywhere.  So an example of any sort of device-class driver
using OS2SCSI.DMD would be wonderful.  Thanks.


FOLLOW-UP ANSWER:
We are sorry, but there is no Device Class Driver Source on the DDK at this
time.  We are working to include some in future releases.

TransferSCB is to be used with a DosDevIOCtl call.  You just have to make sure
that your SCB/SCBs is properly initialised before issuing the DosDevIOCtl
function call for TransferSCB.




!BASE___________________________________**********
October 07, 1994
QUESTION: (Ref: F14)
I am presently involved in writing an OS/2 PDD that talks as a character mode
DD to an Emulex Coprocessor board.  The Coprocessor board works on an ISA bus
machine and resides at Physical Address 000d0000 hex and contains a 64K area
of dual ported memory.

I presently have a driver that will load under OS/2 and in the INIT section
can access the Coprocessors memory.  By this I an able to clear the 64k block,
load in a binary program, and start the coprocessor's processor and verify
that it is functioning.

Later After an Open to the driver is done I can access the coprocessor memory
using IOctl functions, and a PhyToUVirt mapping through an LDT.

Q1. I tried to use VMLock to Lock down then physical address.  VMLock always
    returns an error code 57 in the eax register.  I looked this up in the
    BSEERR.h file on the DDK CDROM and it says "ERROR_ADAP_HDW_ERR".  I am
    assuming Adapter Hardware Error.

    Why can I not access this memory in the coprocessor card under a GDT
    selector assignment?

A1. Even though the GDT Selectors are allocated at INIT time,they cannot be
    used at INIT since they are at Ring 3 which has no access to the GDT.  If
    you intend to access the memory during the Interrupt use
    PhysToGDTSelector.
==============================================================================

Q2. As Per page 17-54 of the Physical Device Driver Reference Manual version
    2.00 manual number S10G-6266-00 Where it states the following:

        MOV ECX,Size       ; Size of segment mapped
                           ;  must be less than or equal to 64KB
                           ;(a 0 value will map a 64KB segment)

    The value zero does map memory somewhere in virtual land, but not where
    you want it.  Is the reference manual incomplete, or am I not reading
    between the lines?

    Answer #1 also stated, that at interrupt time, use the PhysToGDTSelector.
    Again from the same reference manual Page 17-55 it states that the
    following:

        A segment created with PhysToGDTSelector cannot be passed on system
        calls, and can be used by the Physical device driver only to FETCH
        DATA

    Does this mean only to read memory?  If so what should be used if the
    interrupt function needs to write to this area?  Or maybe this means that
    this area can hold only data, not program code.

A2. The PhysToGDTSelector gives a Selector usable at Ring 0 only.The interrupt
    handler of a device driver must be able to address data buffers regardless
    of the context of the current process.  Hence this is useful for the
    Interrupt Handler.The Segment created from PhysToGDTSelector cannot be
    shared, however it can be read & written by the Device Driver.  You are
    right,this function provides addressability through a GDT Selector to
    Data.
==============================================================================

Q3. Which is the preferred way to access this adapter card memory from the
    physical device driver, not during interrupt time, through the
    PhysToGDTSel address returned, or through the PhysToUVirt address
    returned.

A3. Since you are not using Interrupts,PhysToUVirt should be preferred.
==============================================================================

Q4. Is there any way to lock this memory in the adapter card down and have it
    only available to the OS/2 program/physical device driver, so that if a
    Dos program is loaded and tries to access this same memory, it will not be
    present?

A4. To lock a memory object you could use the VMLock function.  An alternative
    approach would be to use VMAlloc to map the Adapter Memory Address to a
    Linear Address in the Global Address Space.This way you could also lock
    the segment using the same DevHlp Function.




!OTHER !STORAGE_________________________**********
October 07, 1994
QUESTION: (Ref: D24)
How can I delete a file from the hard disk within the context of a VDD? I can
find VDH calls to Open/Close/Read/Write a file from a VDD. These calls
correspond to similar OS/2 API calls. I cannot find references or documentation
on a VDH function that might correspond to the DosDelete API call.


ANSWER:
Use the BIOS INTERRUPT 21h , AH=41h to delete a file.

  mov dx,offset FileName
  mov ah,41h
  int 21h




!OTHER__________________________________**********
October 05, 1994
QUESTION: (Ref: FB7)
What is the purpose of DOS.SYS?


ANSWER:
It supplies an IOCtl interface to simulate a Ctrl-Alt-Del to the OS/2; DOS.SYS
will then call DevHlp SendEvent to alert kernel of Ctrl-Alt-Del event.




!OTHER__________________________________**********
October 05, 1994 (Ref: F92)
QUESTION:
What does the second parameter of GetDOSVar DevHelp mean?  The PDD reference
is missing the description.  Also, Can I assume that the fields described for
the individual variables are packed?  The DDK does not seem to have header
files defining these structures.


ANSWER:
The second parameter of GetDosVar DevHlp function contains supplementary
information to the first parameter(AL or VarNumber).  It is meaningful for
index value DHGETDOSV_DEVICETABLE.  Here the second parameter represents
Device_Class and it is passed in CX.  The GetDosVar DevHlp function is
modified in OS/2 2.0 to accomodate this variable call.  Please refer to
GetDosVar in Storage Device Driver Reference and also DDK source code in
\DDK\SRC\DEV\MOUSE\INIT.ASM file for sample usage.  If you are not interested
in the Pointer to the Device Class Table, you can ignore this parameter.

The structures returned by GetDosVar DevHlp function are packed binary values.
The relevant header files are devhlp.inc and devclass.inc in \DDK\INC
directory.




!VIDEO__________________________________**********
October 4, 1994
QUESTION: (Ref: F88)
In order to support PCI compatibility, we need to access the PCI BIOS software
interrupt handler at vector 1AH from within our PM display device driver.  We
cannot find any OS/2 service routine which can be called from our DLL or .SYS
file.  In the SVGA driver sample source code we found a call to IOCTL 74H, but
unfortunately it does not return what we need.  Using the INT instruction
causes the system to hang.


ANSWER:
1. There is a CLOCK device driver in \ddk\src\dev\clock which is a driver for
the real-time CMOS clock.

    CLOCK01 for AT
    CLOCK02 for MCA

This provides read/write and other functions like the INT 1A functions.  This
has been documented in the Input/Output Device Driver Reference for OS/2,
Chapter on Vtimer & Physical CLOCK$ Device Driver.  The DevHlp_AttachDD
returns the address of the IDC Entry Point to CLOCK$.This entry point (RTENTR)
provides access to 8 Functions.

2. The DosOpen call could also be used on CLOCK$ to get a handle to this
driver from the PM display driver.DosDevIOCtl could then be used on the
Returned Handle.Sample is provided in - ddk\src\vdh\vdhsubs.c.  However, this
DosDevIOCtl is not documented and is private to IBM, so you are better off not
using it.

The functionality needed is not described.  The sample source for the clock
driver can be checked out to see if this driver has the required functionality
for the display driver.

3. You could also refer to the Virtual Device Driver Reference for OS/2
Chapter on Virtual Device Driver Architecture & Operations.  The virtual CMOS
device driver component supports read-only access to the Real Time Clock
Device.Because of this restriction,the following BIOS INT 1Ah functions are
not supported in a DOS Session:  01h, 03h, 05h, 06h, 07h, 08h, 0bh, & 80h




!STORAGE________________________________**********
October 05, 1994 (Ref: F86)
Q1. I am building a filter driver that sits between the DASD.DMD and any
    DASD.ADD drivers.  I read a sector of the disk during my init time.  All
    works fine except with the IBMINT13.I13 driver.  When I make a read
    request the IORB status never gets done.  I compared my IORB with the one
    that DASD.DMD creates and the only difference is in the DM workspace where
    I place my scatter/gather list in a slightly different place.  All
    pointers are correct.  What is different about the IBMINT13.I13 driver?
    All other .ADD drivers are fine.

A1. Generic INT 13h driver - IBMINT13.I13 does not support IOCM_READ &
    IOCM_WRITE.  Check the status which should be IORB_ERROR and the Error
    Code would be IOERR_CMD_NOT_SUPPORTED.

    The Read/Write itself is failing due to a hardware error.  You could do a
    Read/Write using the Interrupt 13h functions which are hooked by the
    driver in a DOS Session.
==============================================================================

Q2. How does the DASD.DMD talk to the hard drives if it is not using
    IBMINT13.I13?  When I intercept the calls between them, they work.  When I
    use the IORB call to it, it never sets the done bit in the IORB.  I need
    to read and write to the disk from my filter driver.

A2. IOCM_READ & IOCM_WRITE are supported by IBMINT13.INT.  Set the
    IORB_REQ_STATUSBLOCK in the RequestControl Field of the IORB Header and
    the ADD will return the command's associated status information.




!PRINT________________________________**********
October 05,1994
QUESTION: (Ref: F75)
I am running OS/2 2.1 with an HP LaserJet 4. I need to know what the settings
for the printer are.  If I manually change DPI, I do not see a change in the
information returned from DevQueryHardcopyCaps or DevQueryCaps.  When
enumerating a queue, I get the data structure DRIVDATA which I use during the
DevOpenDC.  DRIVDATA looks very similar to DEVMODE in Windows.  In DEVMODE
there is enough information to determine the DPI setting of the printer.  From
experi- menting it appears this data is also in DRIVDATA in OS2 for the HP4.
Is this structure only for the device driver or is there a predefined OS2
structure to be able to read this data for all printers?  If this is not for
everyone's eyes, is there another command in OS2 that will give the DPI for
the printer?


ANSWER:
The predefined structure is on \src\prntdd\ibmh\os2def.h file and has been
reproduced for your convenience.
/* structure for Device Driver data */

typedef struct _DRIVDATA       /* driv */
{
   LONG    cb;
   LONG    lVersion;
   CHAR    szDeviceName32;
   CHAR    abGeneralData1;
} DRIVDATA;
typedef DRIVDATA *PDRIVDATA;
DriverData (PDRIVDATA) - input
NuLL or pointer to memory location for DRIVDATA structure:

cb                  Number of bytes in the structure.
lVersion            Version number of the presentation driver.
                    Subsequently used by the presentation driver
                    to verify its entry in the INI file.
szDeviceName32    Device name.
abGeneralData|1|    Driver-specific data for job or printer
                    properties.

If pDriverData is NULL, the handling routine in the presentation driver must
return the length of the driver's DRIVDATA structure for either job or printer
properties.

For further details you could refer to the Presentation Device Driver Manual.

You could also browse through ddk\src\prntdd\42xx\inc\prdmtypt.h This Header
File has the DRIVDATA General Data Structure for Device Drivers.

GreQueryDeviceCaps is called by DevQueryCaps function.  GreQueryDeviceCaps is
a mandatory function and must be supported by the Presentation Driver.Hence if
this Gre function is supported by the Driver,you should have no problems using
DevQueryCaps.




!NETWORK !STORAGE_______________________**********
October 05, 1994
QUESTION: (Ref: F39)
I am developing a network redirector using a split model IFS.  The IFS
receives network services via a ring 3 daemon.  I am attempting to pass
address's passed to the IFS to NETBIOS.  I am using VMLock, VMProcessToGlobal
and VMGlobalToProcess to accomplish this task.  My ring 3 daemon seems to have
no problems using the selector generated by VMGlobalToProcess, neither does
the SPX protocol, However; when I pass the address to NETBIOS the data does
get to the buffer but when I attempt to free the mappings created by
VMProcessToGlobal and VMGlobalToProcess (using VMFree) or use VMUnLock the
entire system locks up.  Basically VMFree or VMUnlock will never return to the
IFS therby locking the system.  I have a few questions having to do with the
above scenario.

        1. Is this supposed to work?

        2. Is the mapping created by VMProcessToGlobal or VMGlobalToProcess a
           fabricated process mapping like the one generated by PhysToUVirt?

        3. Is there another way to accomplish what I'm trying to do?

        4. Is there a way to generate your own GDT or LDT descriptor tables?

        5. I am thinking about writing another IFS for hardware devices
           and am wondering how the FAT IFS access's physical harddrives?
           (IE Does it use the 16 bit ROM BIOS or access hardware directly)

By the way I found the below bugs or problems with the device helper system in
the past few days.

        1. PhysToGDTSel returns the new selector in SI not AX like the
           documentation says.

        2. LinToGDTSel blows up when passed a range size of 0.


ANSWER:
I assume that it is the redirector IFS that is responsible for the memory and
other SPX, NETBIOS and the R3DMON attempt accessing the global memory by
getting the offset to the object in the global memory from the driver.

1. There should not be any problem as long as the 'owner' process IFS goes
through the VMLock, VMProcessToGlobal, pass the address to other clients to
VMGlobalToProcess, wait till the clients call VMFree with their mappings,
VMFree and then VMUnLock in that order.  It is not clear from the description
if the VMProcessToGlobal mapping is freed by IFS after NETBIOS frees its
VMGlobalToProcess mapping.  Is there a possibility of a race condition here ?

2. No, the resulting addresses are not fabricated.  They are backed by real
page table entries in the system tables.  The global address is to be used
only in ring0 code and the process pointer only within the specific process.
The process pointer can be passed in system calls like any other pointer.

3. I am not sure that I understand what you need, especially about the various
processes, drivers and ring levels that are involved.  Is it that the R3DMON
has to pass data to the NETBIOS driver thru IFS driver?  Then why does the
daemon call VMGlobalToProcess?  If IFS driver maintains a pool of global
memory and blocks from this memory are allocated to the processes and then
shared between them there should not be any problem.

4. Only thru the DevHlp calls provided.  You cannot manipulate the GDT/LDT
entries bypassing the kernel without affecting system integrity.

5. There is no explicit FAT IFS.  Interpreting FAT layout is built into the
kernel by default.  Support for other file systems like HPFS is thru IFS.
Physical drives are accessed thru Adapter Device Drivers (ADD).  The sample
files DDK\SRC\DEV\DASD\IBM\IBM2FLPY of DDK v1.2 contain code to access floppy
controllers through ABIOS services.  It is left to the Adapter Device Driver
writer to decide the means of access.  You will find the disk driver
architecture described in the Storage Device Driver Reference manual supplied
with the DDK.

Regarding the problems you observed :

6. For PhysToGDTSel, EAX will contain the error code if the segment is not
available.  If the pages are locked then AX should contain the selector with
the RIPL bits modified.  Did you check the carry bit before looking into AX
register ?  SI should be loaded with the GDT Selector obtained from
AllocGDTSelecto before calling PhysToGDTSel.This selector is merely mapped to
a specified physical address.The documentation in the Physical Device Driver
Reference should be referred to.

7. Size of the range should be less than or equal to 64KB.For Range Size 0,the
DevHlp should return an ERROR_INVALID_PARAMETER(87). The Memory that is being
mapped must be fixed or locked prior to a call to this function




!OTHER__________________________________**********
October 05, 1994
QUESTION: (Ref: D81)
I would like to be able to print messages out to the kernel debugger terminal.
Is there a printf or print buffer routine in the kernel debugger that I can
use?


ANSWER:
Use the following conditional directive:
    #ifdef VDDDEBUG
    <user code with printf statements>
    #endif

While linking use the vdh.lib.

If VDDDEBUG is defined debug printfs (PRINTDEBUG) are generated.

These printfs have been used in DDKv1.2.
Refer to the following files:
   ddk\src\vdev\vkbd\vkbdio.c
   ddk\src\vdev\vkbd\vkbdp.h




!I/O____________________________________**********
October 05, 1994
QUESTION: (Ref: C78)
The Pen Toolkit comes with samples for calibration and a Pen Device driver.
It contains 4 files used to cause OS2 to add it as a device driver to the
system.  The DDK doc says that to install, you must use the PEN EXTENSION
install option.  WHAT IS IT!  WHERE IS IT!  Trying to install using the SYSTEM
Device driver installing does not work!  Where do I get the PEN for OS2
Extension product?


ANSWER:
You can find this information in a text file called PENPUB.TXT.  Download this
file from the DUDE BBS.




