/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME =  PRTRM.C
 *
 * DESCRIPTIVE NAME =  Parallel Port Helper interface to RM subsystem.
 *
 *
 *
 * VERSION = V1.0
 *
 * DATE  09/02/94
 *
 * DESCRIPTION : (see above)
 *
 * Purpose: (see above)
 *
 * FUNCTIONS  :
 *
 * NOTES
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define INCL_NOPMAPI
#include <os2.h>

#include "rmcalls.h" // brings in rmbase.h

/*--------------------------------------------------------*/
/* # D E F I N E S                                        */
/*--------------------------------------------------------*/

#define DECODE_WIDTH 10
#define RM_PRT_ERR_RESOURCECLAIMED -1

PFN Device_Help = NULL;
/*----------------------------------------------*/
/* GLOBAL VARS FOR RM                           */
/*                                              */
/* RM.LIB needs these declared                  */
/*----------------------------------------------*/
ULONG           RMFlags               = 0L;  /*VPNP*/
PFN             RM_Help0              = 0L;  /*VPNP*/
PFN             RM_Help3              = 0L;  /*VPNP*/

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

/*----------------------------------------------*/
/* Driver Description   (rmbase.h)              */
/*----------------------------------------------*/
DRIVERSTRUCT DriverStruct =
{
   NULL,                                     /* DrvrName                */
   "IBM Parallel Port Device Driver",        /* DrvrDescript            */
   "IBM - OS/2",                             /* VendorName              */
   CMVERSION_MAJOR,                          /* MajorVer                */
   CMVERSION_MINOR,                          /* MinorVer                */
   1994,9,12,                                /* Date                    */
   NULL,                                     /* DrvrFlags               */
   DRT_OS2,                                  /* DrvrType                */
   DRS_CHAR,                                 /* DrvrSubType             */
   NULL                                      /* DrvrCallback            */
};

/*----------------------------------------------*/
/* Adapter Description  (rmbase.h)              */
/*----------------------------------------------*/
ADAPTERSTRUCT AdapterStruct =
{
  "PARALLEL_# Parallel Port Adapter", /* AdaptDescriptName; */
  NULL,                               /* AdaptFlags;        */
  AS_BASE_COMM,                       /* BaseType;          */
  AS_SUB_PARALLEL,                    /* SubType;           */
  NULL,                               /* InterfaceType;     */
  NULL,                               /* HostBusType;       */
  AS_BUSWIDTH_8BIT,                   /* HostBusWidth;      */
  NULL,                               /* pAdjunctList;      */
  NULL
};

/*----------------------------------------------*/
/* GLOBAL HANDLE VARIABLES                      */
/*                                              */
/* These variables get the handles for          */
/* drivers, adapters, and resources.            */
/*----------------------------------------------*/

HDRIVER   hDriver   = NULL;      /* global handle to driver          */
HADAPTER  hAdapter1 = NULL;      /* global handle to adapter1        */
HADAPTER  hAdapter2 = NULL;      /* global handle to adapter2        */
HADAPTER  hAdapter3 = NULL;      /* global handle to adapter3        */
HRESOURCE hResPorts = NULL;      /* global handle to ports resource  */
HRESOURCE hResIRQs  = NULL;      /* global handle to IRQs resource   */
HRESOURCE hResDMAs  = NULL;      /* global handle to DMA resource    */

/*--------------------------------------------------------*/
/* RM_PRT_CreateDriver - registers to RM susbsystem       */
/*                       (which initializes the DD to     */
/*                        RM connection)                  */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* PSZ DrvrName - ptr to driver name (taken from command  */
/*                line)                                   */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* This function is a thin wrapper for the RMCreateDriver */
/* call. Modifications for specific drivers might include */
/* adding more parameters to be set into the              */
/* DriverStruct and actually returning the hDriver        */
/* to the caller (instead of maintaining it in a global   */
/* var). In any case, modifications to the DriverStruct   */
/* declared above will have to made.                      */
/*--------------------------------------------------------*/

USHORT RM_PRT_CreateDriver( PSZ DrvrName)
{
   DriverStruct.DrvrName = DrvrName;      /* set the driver name */
   /*---------------------------------------------------*/
   /* Allocate Driver Handle                            */
   /*---------------------------------------------------*/
   return( RMCreateDriver( &DriverStruct, &hDriver));

}

/*--------------------------------------------------------*/
/* RM_PRT_DestroyDriver - deregisters the driver from     */
/*                        RM sub-system and releases all  */
/*                        claimed resources               */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* This function is a thin wrapper for the RMDestroyDriver*/
/* call. Modifications for specific drivers might include */
/* adding a parameter for hDriver, if RMCreateDriver has  */
/* been modified to return it to the DD layer.            */
/*                                                        */
/*--------------------------------------------------------*/

VOID RM_PRT_DestroyDriver( VOID)
{
   /*---------------------------------------------------*/
   /* Destroy Driver Handle                             */
   /*---------------------------------------------------*/
   RMDestroyDriver( hDriver);

   hDriver   = NULL;
   hAdapter1 = NULL;
   hAdapter2 = NULL;
   hAdapter3 = NULL;
   hResPorts = NULL;
   hResIRQs  = NULL;
   hResDMAs  = NULL;
}

/*--------------------------------------------------------*/
/* RM_PRT_CreateAdapter - tells RM to associate adapter   */
/*                        to driver and resources to      */
/*                        adapter                         */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT bustype - 0x0001 = ISA                          */
/*                  0x0002 = EISA                         */
/*                  0x0003 = MC                           */
/* USHORT adaptnum - 0x0001 = first adapter               */
/*                   0x0002 = second adapter              */
/*                   0x0003 = third adapter               */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* This function builds up the AHRESOURCE array for the   */
/* the call to RMCreateAdapter. To modify this for a      */
/* specfic DD the handles to resource variables set into  */
/* the array will have to be touched along with the lines */
/* that set the NumResource. Also, AdapterStruct (see     */
/* above) will have to be set up apropriately.            */
/*                                                        */
/*--------------------------------------------------------*/

USHORT RM_PRT_CreateAdapter( USHORT bustype, USHORT adaptnum)
{
   UCHAR       ResourceBuf[ 12 ];
   PAHRESOURCE pResourceList = (PAHRESOURCE)ResourceBuf;
   PHADAPTER   phAdapter;
   ADJUNCT     AdjAdaptNum;

   if (hResIRQs == NULL)                  /* if irq not allocated */
     pResourceList->NumResource = 1;      /* only port resource */
   else
     pResourceList->NumResource = 2;      /* port and irq resource */

   pResourceList->hResource[0] = hResPorts;
   pResourceList->hResource[1] = hResIRQs;

   hResPorts = NULL;
   hResIRQs = NULL;

   switch (bustype)
   {
     case 0x0001:
      AdapterStruct.HostBusType = AS_HOSTBUS_ISA;
      break;

     case 0x0002:
      AdapterStruct.HostBusType = AS_HOSTBUS_EISA;
      break;

     case 0x0004:
      AdapterStruct.HostBusType = AS_HOSTBUS_uCHNL;
      break;

   default:
      AdapterStruct.HostBusType = AS_HOSTBUS_UNKNOWN;
      break;

   } /* endswitch */

   switch (adaptnum)
   {
     case 0x0000:                      /* first adapter with parallel port */
      phAdapter = &hAdapter1;
      break;

     case 0x0001:                      /* second adapter with parallel port */
      phAdapter = &hAdapter2;
      break;

     case 0x0002:                      /* third adapter with parallel port */
      phAdapter = &hAdapter3;
      break;

   default:
      phAdapter = 0;
      break;

   } /* endswitch */

   /*---------------------------------------------------*/
   /* Initialize AdjunctList                            */
   /*---------------------------------------------------*/

   AdjAdaptNum.pNextAdj       = NULL;
   AdjAdaptNum.AdjLength      = sizeof(ADJUNCT);
   AdjAdaptNum.AdjType        = ADJ_ADAPTER_NUMBER;
   AdjAdaptNum.Adapter_Number = adaptnum;

   AdapterStruct.pAdjunctList = &AdjAdaptNum;

   /*---------------------------------------------------*/
   /* Create Adapter Handle                             */
   /*---------------------------------------------------*/
   return ( RMCreateAdapter( hDriver,
                             phAdapter,
                             &AdapterStruct,
                             NULL,
                             pResourceList ));
}

/*--------------------------------------------------------*/
/* RM_PRT_DestroyAdapter - tells RM to delete adapter     */
/*                        and associated resources from   */
/*                        driver.                         */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT adaptnum - 0x0001 = first adapter               */
/*                   0x0002 = second adapter              */
/*                   0x0003 = third adapter               */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* This function builds up the AHRESOURCE array for the   */
/* the call to RMCreateAdapter. To modify this for a      */
/* specfic DD the handles to resource variables set into  */
/* the array will have to be touched along with the lines */
/* that set the NumResource. Also, AdapterStruct (see     */
/* above) will have to be set up apropriately.            */
/*                                                        */
/*--------------------------------------------------------*/

USHORT RM_PRT_DestroyAdapter( USHORT adaptnum)
{
   HADAPTER   hAdapter;

   switch (adaptnum)
   {
     case 0x0000:                      /* first adapter with parallel port */
      hAdapter = hAdapter1;
      break;

     case 0x0001:                      /* second adapter with parallel port */
      hAdapter = hAdapter2;
      break;

     case 0x0002:                      /* third adapter with parallel port */
      hAdapter = hAdapter3;
      break;

   default:
      hAdapter = 0;
      break;

   } /* endswitch */

   /*---------------------------------------------------*/
   /* Destroy Adapter Handle                            */
   /*---------------------------------------------------*/
   return ( RMDestroyAdapter( hDriver,
                              hAdapter));
}

/*--------------------------------------------------------*/
/* RM_PRT_AllocPorts - attempts to claim a port resource  */
/*                       from RM subsystem                */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT baseport - base IO port.                        */
/* USHORT nPorts   - number of prts inclusive of base port*/
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* Modifying this for a specific DD might consist of:     */
/*                                                        */
/* 1 Setting the res handle to a variable ptr passed in   */
/* 2 Assigning IOResource members proper values (see      */
/*   rmbase.h for all the allowed values)                 */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_AllocPorts( USHORT baseport)
{

   RESOURCESTRUCT Resource;

   if ( hResPorts)
   {
         return( RM_PRT_ERR_RESOURCECLAIMED);
   }

   if (baseport == 0x3BC)
     Resource.IOResource.NumIOPorts = 0x0004;
   else
     Resource.IOResource.NumIOPorts = 0x0008;

   Resource.ResourceType              = RS_TYPE_IO;
   Resource.IOResource.BaseIOPort     = baseport;
   Resource.IOResource.IOFlags        = RS_IO_MULTIPLEXED;
   Resource.IOResource.IOAddressLines = DECODE_WIDTH;

   /*---------------------------------------------------*/
   /* Allocate Port Resource                            */
   /*---------------------------------------------------*/
   return( RMAllocResource( hDriver, &hResPorts, &Resource));

}

/*--------------------------------------------------------*/
/* RM_PRT_DeallocPorts - attempts to release a port       */
/*                       resource allocation from the RM  */
/*                       subsystem.                       */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_DeallocPorts( VOID)
{

   /*---------------------------------------------------*/
   /* Deallocate Port Resource                          */
   /*---------------------------------------------------*/
   return( RMDeallocResource( hDriver, hResPorts));

}

/*--------------------------------------------------------*/
/* RM_PRT_AllocIRQ   - attempts to claim a IRQ resource   */
/*                     from the RM subsystem              */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT IRQlevel - IRQ level to claim                   */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* Modifying this for a specific DD might consist of:     */
/*                                                        */
/* 1 Setting the IRQ handle to a variable ptr passed in   */
/* 2 Assigning IRQResource members proper values (see     */
/*   rmbase.h for all the allowed values)                 */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_AllocIRQ( USHORT bustype, USHORT IRQlevel)
{

   RESOURCESTRUCT Resource;

   if ( hResIRQs)
   {
         return( RM_PRT_ERR_RESOURCECLAIMED);
   }

   switch (bustype)
   {
     case 0x0001:                                           /* ISA Bus */
      Resource.IRQResource.IRQFlags  = RS_IRQ_MULTIPLEXED;
      break;

     case 0x0002:                                           /* EISA Bus */
      Resource.IRQResource.IRQFlags  = RS_IRQ_SHARED;
      break;

     case 0x0004:                                           /* MC Bus */
      Resource.IRQResource.IRQFlags  = RS_IRQ_SHARED;
      break;

   default:
      Resource.IRQResource.IRQFlags  = RS_IRQ_EXCLUSIVE;
      break;

   } /* endswitch */

   /*------------------------------------------------*/
   /* Request IRQ Resource  from RM......            */
   /*------------------------------------------------*/
   Resource.ResourceType          = RS_TYPE_IRQ;
   Resource.IRQResource.IRQLevel  = IRQlevel;
   Resource.IRQResource.PCIIrqPin = RS_PCI_INT_NONE;
   Resource.IRQResource.Reserved  = 0;
   Resource.IRQResource.pfnIntHandler = 0;

   /*---------------------------------------------------*/
   /* Allocate IRQ Resource                             */
   /*---------------------------------------------------*/
   return( RMAllocResource( hDriver, &hResIRQs , &Resource));

}

/*--------------------------------------------------------*/
/* RM_PRT_DeallocIRQ - attempts to release an IRQ         */
/*                     resource allocation from the RM    */
/*                     subsystem.                         */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_DeallocIRQ( VOID)
{

   /*---------------------------------------------------*/
   /* Deallocate IRQ Resource                           */
   /*---------------------------------------------------*/
   return( RMDeallocResource( hDriver, hResIRQs));

}

/*--------------------------------------------------------*/
/* RM_PRT_AllocDMA   - attempts to claim a DMA resource   */
/*                       from RM subsystem                */
/*                                                        */
/* ARGS:                                                  */
/*                                                        */
/* USHORT DMAchannel   - DMA channel to claim             */
/*                                                        */
/* HINT (Using this generically):                         */
/*                                                        */
/* Modifying this for a specific DD might consist of:     */
/*                                                        */
/* 1 Setting the DMA handle to a variable ptr passed in   */
/* 2 Assigning DMAResource members proper values (see     */
/*   rmbase.h for all the allowed values)                 */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_AllocDMA( USHORT DMAChannel)
{

   RESOURCESTRUCT Resource;

   if ( hResDMAs)
   {
         return( RM_PRT_ERR_RESOURCECLAIMED);
   }

   /*------------------------------------------------*/
   /* Request DMA Resource  from RM......            */
   /*------------------------------------------------*/

   Resource.ResourceType           = RS_TYPE_DMA;
   Resource.DMAResource.DMAChannel = DMAChannel;
   Resource.DMAResource.DMAFlags   = RS_DMA_SHARED;

   /*---------------------------------------------------*/
   /* Allocate DMA Resource                             */
   /*---------------------------------------------------*/
   return( RMAllocResource( hDriver, &hResDMAs , &Resource));

}

/*--------------------------------------------------------*/
/* RM_PRT_DeallocDMA - attempts to release a DMA resource */
/*                     allocation from the RM subsystem.  */
/*                                                        */
/*--------------------------------------------------------*/
USHORT RM_PRT_DeallocDMA( VOID)
{

   /*---------------------------------------------------*/
   /* Deallocate IRQ Resource                           */
   /*---------------------------------------------------*/
   return( RMDeallocResource( hDriver, hResDMAs));

}

