Writing OS/2 2.0 Device Drivers in C errata
Jump to navigation
Jump to search
The following is errata for Writing OS/2 2.0 Device Drivers in C as of 29 May, 1992.
- Page 9, last paragraph, line 2, replace "Figure 3-2" with "Figure 2-3"
- Page 16, first paragraph, replace entire paragraph with:
Processors are generally referred to by the size of the data which can be handled at any one given time. The 8088 is referred to as a 16-bit processor, although technically it can only handle 8 bits at a time (The 8088 performs 16-bit operations by transparently multiplexing two 8-bit operations). The 80286, for example, is called a 16-bit processor because it can handle data 16 bits at a time. The 80386 and 80486 are referred to as 32-bit processors because they can directly manipulate data 32 bits at a time."
- Page 17, first paragraph, line 2, replace "eight-bit" with "16-bit"
- Page 18, last paragraph, first sentence, replace "30" with "25".
- Page 19, first paragraph, line 2, replace "25" with "33".
- Page 19, last paragraph, third sentence which begins "The processor speed", delete entire sentence.
- Page 49, last paragraph, second sentence, replace "Figure 5-3" with "Figure 5-5".
- Page 308, Delete last paragraph, beginning with "Note", in its entirety.
- Page 399, Listings, change "#define WRITE_POS_REG_CARD 0x0D" with "#define WRITE_POS_REG_CARD 0x0E"
Replace the listing for the standard driver include file in the LISTINGS section with the following listing:
/* file drvlib.h standard driver include file */ typedef unsigned char UCHAR; typedef unsigned short USHORT; typedef unsigned short BOOLEAN; typedef unsigned long ULONG; typedef UCHAR near *PUCHAR; typedef UCHAR far *FPUCHAR; typedef USHORT near *PUSHORT; typedef ULONG near *PULONG; typedef char near *PCHAR; typedef short near *PSHORT; typedef long near *PLONG; typedef void near *POINTER; typedef POINTER near *PPOINTER; typedef void far *FARPOINTER; typedef FARPOINTER near *PFARPOINTER; typedef FARPOINTER far *FPFARPOINTER; typedef USHORT ERRCODE; /* error code returned */ typedef ERRCODE far *PERRCODE; /* pointer to an error code */ typedef UCHAR FLAG; /* 8-bit flag */ typedef FLAG far *PFLAG; /* pointer to 8-bit flag */ typedef USHORT SEL; /* 16-bit selector */ typedef SEL near *PSEL; /* pointer to a selector */ typedef USHORT SEG; /* 16-bit segment */ typedef USHORT OFF; /* 16-bit offset */ typedef USHORT PID; /* Process ID */ typedef USHORT TID; /* Task ID */ typedef ULONG PHYSADDR; /* 32-bit physical address */ typedef PHYSADDR far *PPHYSADDR; /* pointer to 32-bit physical address */ typedef char near *PSTRING; /* pointer to character string */ typedef USHORT SHANDLE; /* short (16-bit) handle */ typedef SHANDLE far *PSHANDLE; /* pointer to a short handle */ typedef ULONG LHANDLE; /* long (32-bit) handle */ typedef LHANDLE far *PLHANDLE; /* pointer to a long handle */ /* pointers to functions */ typedef int (pascal near *PFUNCTION) (); typedef int (pascal near * near *PPFUNCTION) (); typedef int (pascal far *FPFUNCTION) (); typedef int (pascal far * near *PFPFUNCTION) (); /* macros */ #define FALSE 0 #define TRUE 1 #define NP near pascal /* far pointer from selector-offset */ #define MAKEP(sel, off) ( (void far *) MAKEULONG(off, sel) ) /* get selector or offset from far pointer */ #define SELECTOROF(p) ( ((USHORT far *) &(p)) [1]) #define OFFSETOF(p) ( ((USHORT far *) &(p)) [0]) /* Combine l(ow) & h(igh) to form a 32 bit quantity. */ #define MAKEULONG(l, h) ((ULONG)(((USHORT)(l)) | ((ULONG)((USHORT)(h))) << 16)) #define MAKELONG(l, h) ((LONG)MAKEULONG(l, h)) /* Combine l(ow) & h(igh) to form a 16 bit quantity. */ #define MAKEUSHORT(l, h) (((USHORT)(l)) | ((USHORT)(h)) << 8) #define MAKESHORT(l, h) ((SHORT)MAKEUSHORT(l, h)) /* get high and low order parts of a 16 and 32 bit quantity */ #define LOBYTE(w) LOUCHAR(w) #define HIBYTE(w) HIUCHAR(w) #define LOUCHAR(w) ((UCHAR)(w)) #define HIUCHAR(w) (((USHORT)(w) >> 8) & 0xff) #define LOUSHORT(l) ((USHORT)(l)) #define HIUSHORT(l) ((USHORT)(((ULONG)(l) >> 16) & 0xffff)) /* the driver device header */ typedef struct DeviceHdr { struct DeviceHdr far *DHnext; /* pointer to next header, or FFFF */ USHORT DHattribute; /* device attribute word */ OFF DHstrategy; /* offset of strategy routine */ OFF DHidc; /* offset of IDC routine */ UCHAR DHname[8]; /* dev name (char) or #units (blk) */ char reserved[8]; ULONG bit_strip; /* bit 0 DevIOCtl2, bit 1 32 bit addr */ } DEVICEHDR; typedef DEVICEHDR near *PDEVICEHDR; /* driver device attributes word */ #define DAW_CHR 0x8000 /* 1=char, 0=block */ #define DAW_IDC 0x4000 /* 1=IDC available in this DD */ #define DAW_IBM 0x2000 /* 1=non-IBM block format */ #define DAW_SHR 0x1000 /* 1=supports shared device access */ #define DAW_OPN 0x0800 /* 1=open/close, or removable media */ #define DAW_LEVEL1 0x0080 /* level 1 */ #define DAW_LEVEL2 0x0100 /* level 2 DosDevIOCtl2 */ #define DAW_LEVEL3 0x0180 /* level 3 bit strip */ #define DAW_GIO 0x0040 /* 1=generic IOCtl supported */ #define DAW_CLK 0x0008 /* 1=CLOCK device */ #define DAW_NUL 0x0004 /* 1=NUL device */ #define DAW_SCR 0x0002 /* 1=STDOUT (screen) */ #define DAW_KBD 0x0001 /* 1=STDIN (keyboard) */ /* capabilities bit strip */ #define CBS_SHD 0x0001 /* 1=shutdown/DevIOCtl2 */ #define CBS_HMEM 0x0002 /* hign memory map for adapters */ #define CBS_PP 0x0004 /* supports parallel ports */ /* DispMsg structure */ typedef struct MessageTable { USHORT id; USHORT fill_in_item; FARPOINTER item1; FARPOINTER item2; FARPOINTER item_last; } MESSAGETABLE; /* OS/2 circular character queues */ #define QUEUE_SIZE 512 /* size of queues */ typedef struct CharQueue { USHORT qsize; /* number of bytes in queue */ USHORT qchrout; /* index of next char to put out */ USHORT qcount; /* number of charactes in queue */ UCHAR qbuf[QUEUE_SIZE]; } CHARQUEUE; typedef CHARQUEUE near *PCHARQUEUE; /* AttachDD inter device driver communication data area */ typedef struct AttachArea { OFF realOFF; /* real-mode offset of idc entry point */ SEG realCS; /* real-mode CS of IDC entry point */ SEG realDS; /* real-mode DS of IDC DD */ OFF protOFF; /* protect-mode offset of entry point */ SEL protCS; /* protect-mode CS of entry point */ SEL protDS; /* protect-mode DS of other DD */ } ATTACHAREA; typedef ATTACHAREA near *PATTACHAREA; /* driver request packet */ typedef struct ReqPacket { UCHAR RPlength; /* request packet length */ UCHAR RPunit; /* unit code for block DD only */ UCHAR RPcommand; /* command code */ USHORT RPstatus; /* status word */ UCHAR RPreserved[4]; /* reserved bytes */ ULONG RPqlink; /* queue linkage */ union { /* command-specific data */ UCHAR avail[19]; struct { /* init */ UCHAR units; /* number of units */ FPFUNCTION DevHlp; /* &DevHlp */ char far *args; /* &args */ UCHAR drive; /* drive # */ }Init; struct { UCHAR units; /* same as input */ OFF finalCS; /* final offset, 1st code segment */ OFF finalDS; /* final offset, 1st data segment */ FARPOINTER BPBarray; /* &BPB */ } InitExit; struct { /* read, write, write w/verify */ UCHAR media; /* media descriptor */ PHYSADDR buffer; /* transfer address */ USHORT count; /* bytes/sectors */ ULONG startsector; /* starting sector# */ USHORT reserved; } ReadWrite; struct { /* cached read, write, write w/verify */ UCHAR media; /* media descriptor */ PHYSADDR buffer; /* transfer address */ USHORT count; /* bytes/sectors */ ULONG startsector; /* starting sector# */ USHORT reserved; } CReadWrite; struct { /* system shutdown */ UCHAR subcode; /* sub request code */ ULONG reserved; } Shutdown; struct { /* open/close */ USHORT sysfilenum; /* system file number */ } OpenClose; struct { /* IOCtl */ UCHAR category; /* category code */ UCHAR function; /* function code */ FARPOINTER parameters; /* ¶meters */ FARPOINTER buffer; /* &buffer */ } IOCtl; struct { /* read, no wait */ UCHAR char_returned; /* char to return */ } ReadNoWait; struct { /* media check */ UCHAR media; /* media descriptor */ UCHAR return_code; /* see #defines */ FARPOINTER prev_volume; /* &previous volume ID */ } MediaCheck; struct { /* build BPB */ UCHAR media; /* media descriptor */ FARPOINTER buffer; /* 1-sector buffer FAT */ FARPOINTER BPBarray; /* &BPB array */ UCHAR drive; /* drive # */ } BuildBPB; struct { /* query partitionalble fixed disks */ UCHAR count; /* # disks */ ULONG reserved; } Partitionable; struct { /* fixed disk LU map */ ULONG units; /* units supported */ ULONG reserved; } GetFixedMap; struct { /* get driver capabilities */ UCHAR reserved[3]; FARPOINTER capstruct; /* 16:16 pointer to DCS */ FARPOINTER volcharstruct; /* 16:16 pointer to VCS */ } GetDriverCaps; } s; /* command info */ } REQPACKET; typedef REQPACKET far *PREQPACKET; typedef PREQPACKET far *PPREQPACKET; typedef PREQPACKET QHEAD; /* Queue Head is &ReqPacket */ typedef QHEAD near *PQHEAD; /* Global Info Seg */ typedef struct _GINFOSEG { ULONG time; ULONG msecs; UCHAR hour; UCHAR minutes; UCHAR seconds; UCHAR hundredths; USHORT timezone; USHORT cusecTimerInterval; UCHAR day; UCHAR month; USHORT year; UCHAR weekday; UCHAR uchMajorVersion; UCHAR uchMinorVersion; UCHAR chRevisionLetter; UCHAR sgCurrent; UCHAR sgMax; UCHAR cHugeShift; UCHAR fProtectModeOnly; USHORT pidForeground; UCHAR fDynamicSched; UCHAR csecMaxWait; USHORT cmsecMinSlice; USHORT cmsecMaxSlice; USHORT bootdrive; UCHAR amecRAS[32]; UCHAR csgWindowableVioMax; UCHAR csgPMMax; } GINFOSEG; typedef GINFOSEG far *PGINFOSEG; /* local info seg */ typedef struct _LINFOSEG { PID pidCurrent; PID pidParent; USHORT prtyCurrent; TID tidCurrent; USHORT sgCurrent; UCHAR rfProcStatus; UCHAR dummy1; USHORT fForeground; UCHAR typeProcess; UCHAR dummy2; SEL selEnvironment; USHORT offCmdLine; USHORT cbDataSegment; USHORT cbStack; USHORT cbHeap; USHORT hmod; SEL selDS; } LINFOSEG; typedef LINFOSEG far *PLINFOSEG; /* mainifest constants */ /* RPstatus bit values */ #define RPERR 0x8000 /* error occurred, err in RPstatus */ #define RPDEV 0x4000 /* error code defined by driver */ #define RPBUSY 0x0200 /* device is busy */ #define RPDONE 0x0100 /* driver done with request packet */ /* error codes returned in RPstatus */ #define ERROR_WRITE_PROTECT 0x0000 #define ERROR_BAD_UNIT 0x0001 #define ERROR_NOT_READY 0x0002 #define ERROR_BAD_COMMAND 0x0003 #define ERROR_CRC 0x0004 #define ERROR_BAD_LENGTH 0x0005 #define ERROR_SEEK 0x0006 #define ERROR_NOT_DOS_DISK 0x0007 #define ERROR_SECTOR_NOT_FOUND 0x0008 #define ERROR_OUT_OF_PAPER 0x0009 #define ERROR_WRITE_FAULT 0x000A #define ERROR_READ_FAULT 0x000B #define ERROR_GEN_FAILURE 0x000C #define ERROR_DISK_CHANGE 0x000D #define ERROR_WRONG_DISK 0x000F #define ERROR_UNCERTAIN_MEDIA 0x0010 #define ERROR_CHAR_CALL_INTERRUPTED 0x0011 #define ERROR_NO_MONITOR_SUPPORT 0x0012 #define ERROR_INVALID_PARAMETER 0x0013 #define ERROR_DEVICE_IN_USE 0x0014 /* driver request codes B=block, C=character */ #define RPINIT 0x00 /* BC */ #define RPMEDIA_CHECK 0x01 /* B */ #define RPBUILD_BPB 0x02 /* B */ #define RPREAD 0x04 /* BC */ #define RPREAD_NO_WAIT 0x05 /* C */ #define RPINPUT_STATUS 0x06 /* C */ #define RPINPUT_FLUSH 0x07 /* C */ #define RPWRITE 0x08 /* BC */ #define RPWRITE_VERIFY 0x09 /* BC */ #define RPOUTPUT_STATUS 0x0a /* C */ #define RPOUTPUT_FLUSH 0x0b /* C */ #define RPOPEN 0x0d /* BC */ #define RPCLOSE 0x0e /* BC */ #define RPREMOVABLE 0x0f /* B */ #define RPIOCTL 0x10 /* BC */ #define RPRESET 0x11 /* B */ #define RPGET_DRIVE_MAP 0x12 /* B */ #define RPSET_DRIVE_MAP 0x13 /* B */ #define RPDEINSTALL 0x14 /* C */ #define RPPARTITIONABLE 0x16 /* B */ #define RPGET_FIXED_MAP 0x17 /* B */ #define RPSHUTDOWN 0x1c /* BC */ #define RPGET_DRIVER_CAPS 0x1d /* B */ /* check for monitor call in DosOpen/DosClose */ #define MON_OPEN_STATUS 0x08 /* open from DosMonOpen */ #define MON_CLOSE_STATUS 0x08 /* close from DosMonClose */ /* media descriptor byte */ #define MDB_REMOVABLE 0x04 /* 1=removable */ #define MDB_EIGHT_SECTORS 0x02 /* 1=8 sectors per track */ #define MDB_DOUBLE_SIDED 0x01 /* 1=double-sided media */ /* return codes from MediaCheck */ #define MC_MEDIA_UNCHANGED 0x01 #define MC_MEDIA_CHANGED 0xFF #define MC_MEDIA_UNSURE 0x01 /* event numbers for SendEvent */ #define EVENT_SM_MOUSE 0x00 /* session switch via mouse */ #define EVENT_CTRLBRK 0x01 /* control break */ #define EVENT_CTRLC 0x02 /* control C */ #define EVENT_CTRLNUMLK 0x03 /* control num lock */ #define EVENT_CTRLPRTSC 0x04 /* control printscreen */ #define EVENT_SHFTPRTSC 0x05 /* shift printscreen */ #define EVENT_SM_KBD 0x06 /* session switch hot key */ /* MCA specific */ int NP GetLIDEntry (USHORT, USHORT, USHORT, FARPOINTER); int NP FreeLIDEntry (USHORT); int NP ABIOSCall (USHORT, USHORT, FARPOINTER); int NP ABIOSComm (USHORT, FARPOINTER); /* special routines */ void NP INT3 (void); void NP Enable (void); void NP Disable (void); void NP Abort (void); int NP SegLimit (SEL, OFF far *); int NP MoveBytes (FARPOINTER,FARPOINTER,USHORT); /* system services and misc. */ int NP GetDOSVar (UCHAR, FPFARPOINTER); int NP SendEvent (UCHAR, USHORT); void NP SchedClockAddr (PFARPOINTER); int NP AttachDD (PSTRING, PATTACHAREA); /* process mgmt */ void NP Yield (void); void NP TCYield (void); int NP Block (ULONG, ULONG, FLAG, PERRCODE); void NP Run (ULONG); void NP DevDone (ULONG); /* memory management */ int NP AllocPhys (ULONG, FLAG, PPHYSADDR); int NP FreePhys (PHYSADDR); int NP VerifyAccess (SEL, OFF, USHORT, FLAG); int NP LockSeg (SEL, FLAG, FLAG, PLHANDLE); int NP UnLockSeg (LHANDLE); /* address conversion */ int NP AllocGDTSelector(USHORT, FARPOINTER); int NP PhysToGDTSelector(PHYSADDR, USHORT, SEL, PERRCODE); int NP VirtToPhys (FARPOINTER, PPHYSADDR); int NP PhysToUVirt (PHYSADDR, USHORT, FLAG, FPFARPOINTER); int NP PhysToVirt (PHYSADDR, USHORT, USHORT, FARPOINTER); int NP UnPhysToVirt (void); /* request packet queue stuff */ int NP AllocReqPacket (FLAG, PPREQPACKET); void NP FreeReqPacket (PREQPACKET); void NP PushReqPacket (PQHEAD, PREQPACKET); void NP SortReqPacket (PQHEAD, PREQPACKET); int NP PullReqPacket (PQHEAD, PPREQPACKET); int NP PullParticular (PQHEAD, PREQPACKET); /* driver semaphores */ int NP SemHandle (LHANDLE, FLAG, PLHANDLE); int NP SemRequest (LHANDLE, ULONG, PERRCODE); void NP SemClear (LHANDLE); /* circular character queues */ void NP QueueInit (PCHARQUEUE); void NP QueueFlush (PCHARQUEUE); int NP QueueWrite (PCHARQUEUE, UCHAR); int NP QueueRead (PCHARQUEUE, FPUCHAR); /* interrupt stuff */ int NP SetIRQ (UCHAR, PFUNCTION, FLAG); int NP UnSetIRQ (UCHAR); int NP EOI (UCHAR); /* timer stuff */ int NP SetTimer (PFUNCTION); int NP ResetTimer (PFUNCTION); int NP TickCount (PFUNCTION, USHORT); /* device monitors */ int NP MonCreate (PSHANDLE, FARPOINTER, FARPOINTER, PERRCODE); int NP Register (SHANDLE, FLAG, PID, FARPOINTER, OFF, PERRCODE); int NP MonWrite (SHANDLE, POINTER, USHORT, FLAG, PERRCODE); int NP MonFlush (SHANDLE, PERRCODE); int NP DeRegister (SHANDLE, PID, PERRCODE); /* 2.0 specfic */ int NP RegisterPDD(FPUCHAR,FPFUNCTION); int NP RegisterBeep(FPFUNCTION); int NP Beep(USHORT,USHORT); int NP FreeGDTSelector(USHORT); int NP PhysToGDTSel(PHYSADDR,USHORT,USHORT,PERRCODE); int NP VMLock(PHYSADDR,ULONG,FARPOINTER,PLHANDLE,ULONG,PULONG); int NP VMUnlock(LHANDLE); int NP VMAlloc(PHYSADDR,ULONG,ULONG,PFARPOINTER); int NP VMFree(PHYSADDR); int NP VMProcessToGlobal(PHYSADDR,ULONG,ULONG,PFARPOINTER); int NP VMGlobalToProcess(PHYSADDR,ULONG,ULONG,FPFARPOINTER); int NP VirtToLin(SEL,ULONG,PFARPOINTER); int NP LinToGDTSelector(SEL,PHYSADDR,ULONG); int NP GetDescInfo(SEL,PUSHORT,PULONG,PULONG); int NP LinToPageList(PHYSADDR,ULONG,FPFARPOINTER,PULONG); int NP PageListToLin(ULONG,FPFARPOINTER,PULONG); int NP PageListToGDTSelector(SEL,ULONG,FPFARPOINTER,USHORT,PSEL); int NP RegisterTmrDD(FARPOINTER,FARPOINTER,FARPOINTER); int NP AllocateCtxHook(OFF,ULONG,PULONG); int NP FreeCtxHook(LHANDLE); int NP ArmCtxHook(ULONG,LHANDLE,ULONG); int NP VMSetMem(PHYSADDR,ULONG,ULONG); int NP OpenEventSem(LHANDLE); int NP CloseEventSem(LHANDLE); int NP PostEventSem(LHANDLE); int NP ResetEventSem(LHANDLE,ULONG); int NP DynamicAPI(FARPOINTER,USHORT,USHORT); /* these are the only API's available to the driver at Init time */ #define APIENTRY far pascal USHORT APIENTRY DosBeep(USHORT, USHORT); USHORT APIENTRY DosCaseMap(USHORT, FARPOINTER, FARPOINTER); USHORT APIENTRY DosChgFilePtr(SHANDLE, long, USHORT, FARPOINTER); USHORT APIENTRY DosClose(SHANDLE); USHORT APIENTRY DosDelete(FARPOINTER, ULONG); USHORT APIENTRY DosDevConfig(FARPOINTER, USHORT, USHORT); USHORT APIENTRY DosDevIOCtl(FARPOINTER, FARPOINTER, USHORT, USHORT, USHORT); USHORT APIENTRY DosFindClose(SHANDLE); USHORT APIENTRY DosFindFirst(FARPOINTER, FARPOINTER, USHORT, FARPOINTER, USHORT, FARPOINTER, ULONG); USHORT APIENTRY DosFindNext(SHANDLE, FARPOINTER, USHORT, FARPOINTER); USHORT APIENTRY DosGetEnv(FARPOINTER, FARPOINTER); USHORT APIENTRY DosGetMessage(FARPOINTER, USHORT, FARPOINTER, USHORT, USHORT, FARPOINTER, FARPOINTER); USHORT APIENTRY DosOpen(FARPOINTER, FARPOINTER, FARPOINTER, ULONG, USHORT, USHORT, USHORT, ULONG); USHORT APIENTRY DosPutMessage(SHANDLE, USHORT, FARPOINTER); USHORT APIENTRY DosQCurDir(USHORT, FARPOINTER, FARPOINTER); USHORT APIENTRY DosQCurDisk(FARPOINTER, FARPOINTER); USHORT APIENTRY DosQFileInfo(SHANDLE, USHORT, FARPOINTER, USHORT); USHORT APIENTRY DosQFileMode(FARPOINTER, FARPOINTER, ULONG); USHORT APIENTRY DosRead(SHANDLE, FARPOINTER, USHORT, FARPOINTER); USHORT APIENTRY DosWrite(SHANDLE, FARPOINTER, USHORT, FARPOINTER); /* end of DRVLIB.H */