/* SCCSID = "%W% %E%" */
/****************************************************************************/
/*                                                                          */
/*                           IBM Confidential                               */
/*                                                                          */
/*                 Copyright (c) IBM Corporation 1996                       */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  PARDATA.C                                             */
/*                                                                            */
/*   DESCRIPTIVE NAME:  PARALLEL port device driver data segment              */
/*                                                                            */
/*   FUNCTION: This module allocates the global data area for the             */
/*             PARALLEL port device driver.                                   */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             None                                                           */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*             None                                                           */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          96/03/01  Frank Schroeder                                         */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include "par.h"

/*--------------------------------------------------------*/
/* Dispatch table for strategy commands (pre FIFO queue)  */
/*--------------------------------------------------------*/
USHORT (*Strat1[])() =
{                     /*--------------------------------------*/
   CmdError,          /* 0x00  initialize device driver       */
   CmdError,          /* 0x01  check the media                */
   CmdError,          /* 0x02  build BPB                      */
   CmdError,          /* 0x03  reserved                       */
   parInstanceQueue,  /* 0x04  read                           */
   CmdError,          /* 0x05  non-destructive read           */
   CmdError,          /* 0x06  input status                   */
   parDataReadFlush,  /* 0x07  input flush                    */
   parInstanceQueue,  /* 0x08  write                          */
   CmdError,          /* 0x09  write with verify              */
   CmdError,          /* 0x0A  get output status              */
   parDataWriteFlush, /* 0x0B  flush output                   */
   CmdError,          /* 0x0C  reserved                       */
   parDeviceOpen,     /* 0x0D  open                           */
   parDeviceClose,    /* 0x0E  close                          */
   CmdError,          /* 0x0F  removable media                */
   parInstanceQueue,  /* 0x10  generic IOCTL                  */
   CmdError,          /* 0x11  reset uncertain media          */
   CmdError,          /* 0x12  get Logical Drive Map          */
   CmdError,          /* 0x13  set Logical Drive Map          */
   CmdError,          /* 0x14  de-Install this device         */
   CmdError,          /* 0x15  reserved                       */
   CmdError,          /* 0x16  get number of partitions       */
   CmdError,          /* 0x17  get unit map                   */
   CmdError,          /* 0x18  no caching read                */
   CmdError,          /* 0x19  no caching write               */
   CmdError,          /* 0x1A  no caching write/verify        */
   parInit,           /* 0x1B  initialize device driver       */
   CmdError,          /* 0x1C  reserved for Request List code */
   CmdError,          /* 0x1D  get driver capabilities        */
   CmdError,          /* 0x1E  reserved                       */
   parInitComplete    /* 0x1F  initialization complete        */
};                    /*--------------------------------------*/

/*--------------------------------------------------------*/
/* Dispatch table for strategy commands (post FIFO queue) */
/*--------------------------------------------------------*/
void (*QueueRouteTable[])() =
{                     /*--------------------------------------*/
   0,                 /* 0x00  now an error                   */
   0,                 /* 0x01  check the media                */
   0,                 /* 0x02  build BPB                      */
   0,                 /* 0x03  reserved                       */
   parDataRead,       /* 0x04  read                           */
   0,                 /* 0x05  non-destructive read           */
   0,                 /* 0x06  input status                   */
   0,                 /* 0x07  input flush                    */
   parDataWrite,      /* 0x08  write                          */
   0,                 /* 0x09  write with verify              */
   0,                 /* 0x0A  get output status              */
   0,                 /* 0x0B  flush output                   */
   0,                 /* 0x0C  reserved                       */
   0,                 /* 0x0D  open                           */
   0,                 /* 0x0E  close                          */
   0,                 /* 0x0F  removable media                */
   parGenIOCTL        /* 0x10  generic IOCTL                  */
};                    /*--------------------------------------*/

CHAR     plptname[] = "LPT";   /* device driver name for DevHelp_RegisterPDD */

/*--------------------------------------------------------*/
/* Dispatch table for virtual IDC requests                */
/*--------------------------------------------------------*/
USHORT (*vidcRouteTable[])() =
{                       /*--------------------------------------*/
   vdmRegister,         /* 0x00  register vlpt entry point      */
   vdmDeregister,       /* 0x01  deregister vlpt entry point    */
   parReqExclusive,     /* 0x02  request access to hardware     */
   parRelExclusive,     /* 0x03  release access to hardware     */
   vdmRetParBufSize     /* 0x04  return parallel buffer size    */
};                      /*--------------------------------------*/

/*--------------------------------------------------------*/
/* Dispatch table for IOCtl commands                      */
/*                                                        */
/* Index into IOCtlComb must match index into             */
/* IOCTLRoutineTable                                      */
/*--------------------------------------------------------*/
void    (*IOCTLRouteTable[])() =
{
   parFrameControlSet,
   parInfinRetrySet,
   parDeviceReset,
   parWriteTimeoutSet,
   parDirectAccessSet,
   parCommModeSet,
   parDataXferModeSet,
   parFrameControlQuery,
   parInfinRetryQuery,
   parStatusPortQuery,
   parWriteTimeoutQuery,
   parDirectAccessQuery,
   parCommModeQuery,
   parDataXferModeQuery,
   parDeviceIDQuery
};

/*--------------------------------------------------------*/
/* Valid IOCtl combinations                               */
/*--------------------------------------------------------*/
IOCTLCOMB IOCtlComb[] = {        /* valid ioctl func/cat code combinations */
               {IOC_PC,IOLW_FC}, /* 05,42 set frame control */
               {IOC_PC,IOLW_IR}, /* 05,44 set infinite retry */
               {IOC_PC,IOLW_IP}, /* 05,46 initialize parallel port */
               {IOC_PC,IOLW_TO}, /* 05,4E set write timeout value */
               {IOC_PC,IOLW_DM}, /* 05,51 set direct hardware access mode */
               {IOC_PC,IOLW_CM}, /* 05,52 set communication mode */
               {IOC_PC,IOLW_DT}, /* 05,53 set data transfer mode */
               {IOC_PC,IOLR_FC}, /* 05,62 query frame control */
               {IOC_PC,IOLR_IR}, /* 05,44 query infinite retry */
               {IOC_PC,IOLR_GS}, /* 05,66 query parallel status port */
               {IOC_PC,IOLR_TO}, /* 05,6E query write timeout value */
               {IOC_PC,IOLR_DM}, /* 05,71 query direct hardware access mode */
               {IOC_PC,IOLR_CM}, /* 05,72 query communication mode */
               {IOC_PC,IOLR_DT}, /* 05,73 query data transfer mode */
               {IOC_PC,IOLR_ID}, /* 05,74 query device id */
                      };

USHORT MAXIOCTLCOMB = (sizeof(IOCtlComb)/sizeof(IOCtlComb[0]));

/*--------------------------------------------------------*/
/* Valid Set Frame Control Combinations                   */
/*--------------------------------------------------------*/
parFrameCtrlSetPkt FrameCtrlComb[] = {
                               {CPS_80,LPI_6},  /* 80,6 */
                               {CPS_80,LPI_8},  /* 80,8 */
                               {CPS_132,LPI_6}, /* 132,6 */
                               {CPS_132,LPI_8}  /* 132,8 */
                                     };

USHORT MAXFRAMECOMB = (sizeof(FrameCtrlComb)/sizeof(FrameCtrlComb[0]));

/*--------------------------------------------------------*/
/* Printer Control Command Combinations                   */
/*--------------------------------------------------------*/
parFrameCtrlSetPkt FrameCtrlCmds[] = {
                          {ENDCOMPRESSED,ONESIXTH},   /* 80,6 */
                          {ENDCOMPRESSED,ONEEIGHTH},  /* 80,8 */
                          {COMPRESSED,ONESIXTH},      /* 132,6 */
                          {COMPRESSED,ONEEIGHTH}      /* 132,8 */
                                     };

PFN      Device_Help    = NULL;  /* devhelp entry point; used by dhcalls.lib */

/*--------------------------------------------------------*/
/* Global data for parallel port device driver            */
/*--------------------------------------------------------*/

USHORT             cInstances = 0;

parInstance_t      *pFreeInstanceList = 0;
parInstance_t      *pInstanceHead = 0;
parInstance_t      *pInstanceFoot = 0;

USHORT             MSPerTick = 32L;
USHORT             fInitTime = FALSE;

LPTInfo_t          LPTInfo[MAX_LPT] = {0};
IRQInfo_t          IRQInfo[MAX_LPT] = {0};
LastRead_t         LastRead[MAX_LPT] = {0};

parInstance_t      InstanceCBs[MAX_LPT] = {0};

/*----------------------------------------------*/
/* Initialization Data                          */
/*----------------------------------------------*/
BYTE               InitDataStart = 0;   /* Marks the end of the data segment. */
                                        /* that must persist after init time. */
BOOL               FirstInit = TRUE;
/*----------------------------------------------*/
/* GLOBAL VARS FOR RM                           */
/*                                              */
/* RM.LIB needs these declared                  */
/*----------------------------------------------*/
ULONG       RMFlags     = 0L;
PFN         RM_Help0    = 0L;
PFN         RM_Help3    = 0L;

/*--------------------------------------------------------*/
/* Set the DRIVERSTRUCT and DETECTEDSTRUCT data areas     */
/*--------------------------------------------------------*/

char  near  DDName[];                  /* device driver name */
char  near  DDDesc[];                  /* device driver description */
char  near  VendorID[];                /* vendor identification */
char  near  AdapterName[];             /* adapter name */

/*----------------------------------------------*/
/* Driver Description   (rmbase.h)              */
/*----------------------------------------------*/
DRIVERSTRUCT DriverStruct =
{
   DDName,                             /* DrvrName                */
   DDDesc,                             /* DrvrDescript            */
   VendorID,                           /* VendorName              */
   CMVERSION_MAJOR,                    /* MajorVer                */
   CMVERSION_MINOR,                    /* MinorVer                */
   1996,3,1,                           /* Date                    */
   DRF_STATIC,                         /* DrvrFlags               */
   DRT_OS2,                            /* DrvrType                */
   DRS_CHAR,                           /* DrvrSubType             */
   NULL                                /* DrvrCallback            */
};

/*----------------------------------------------*/
/* Adapter Description                          */
/*----------------------------------------------*/
ADAPTERSTRUCT AdapterStruct =
{
   AdapterName,                        /* AdaptDescriptName; */
   AS_NO16MB_ADDRESS_LIMIT,            /* AdaptFlags;        */
   AS_BASE_COMM,                       /* BaseType;          */
   AS_SUB_PARALLEL,                    /* SubType;           */
   AS_INTF_BIDI,                       /* InterfaceType;     */
   NULL,                               /* HostBusType;       */
   AS_BUSWIDTH_8BIT,                   /* HostBusWidth;      */
   NULL,                               /* pAdjunctList;      */
   NULL                                /* reserved           */
};

/*----------------------------------------------*/
/* Device Description                           */
/*----------------------------------------------*/
DEVICESTRUCT DeviceStruct =
{
  NULL,                              /* DevDescriptName;   */
  0,                                 /* DevFlags;          */
  DS_TYPE_PRINTER,                   /* DevType;           */
  NULL                               /* pAdjunctList;      */
};

/*----------------------------------------------*/
/* GLOBAL HANDLE VARIABLES                      */
/*                                              */
/* These variables are assigned the handles for */
/* drivers, detected hardware and resources.    */
/*----------------------------------------------*/

HDRIVER     hDriver     = NULL;        /* global handle to driver          */

/*----------------------------------------------*/
/* global control blocks and variables          */
/*----------------------------------------------*/
USHORT   PortCount   = 0;        /* number of ports reserved with res mgr */
USHORT   IRQCount    = 0;        /* number of IRQs reserved with res mgr */
PORTCB   PortCB[MAX_PORTS] = {   /* port control block */
                    {0,0,0,0,0}, {0,0,0,0,0}, {0,0,0,0,0}
                    };
IRQCB    IrqCB[MAX_IRQS] = {     /* irq control block */
                   {IRQ5, 0}, {IRQ7, 0}
                   };

DETECTCB DetectCB = {0, 0, TRUE}; /* detect control block */

UCHAR    QryIDBuf[512] = {0};     /* temporary buffer */
