/*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 =  RSMHLPR.C
 *
 * DESCRIPTIVE NAME =  Resource Management Driver - RM Helper Services
 *
 *
 *
 * VERSION = V1.01
 *
 * DATE
 *
 * DESCRIPTION :
 *
 * Purpose:
 *
 *
 *
 * FUNCTIONS  :
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 *
 *
 * EXTERNAL FUNCTIONS
 *
*/
#define  INCL_NOBASEAPI
#define  INCL_NOPMAPI
#define  INCL_DOSERRORS
#include <os2.h>

#include <dskinit.h>

#include "dhcalls.h"

#include "strat2.h"
#include "scsi.h"
#include "reqpkt.h"

#define RMCode SwapCode
#include "rmcalls.h"
#include "rmioctl.h"

#include "rsmcons.h"
#include "rsmtypes.h"
#include "rsmproto.h"
#include "rsmextrn.h"

/*--------------------------------------------------------*/
/*                                                        */
/*   RMNodeFromHandle                                     */
/*   -------------                                        */
/*                                                        */
/*                                                        */
/*                                                        */
/*--------------------------------------------------------*/

PRMNODE NEAR RMNodeFromHandle(RMHANDLE RMHandle, ULONG Cookie)
{
   PRMNODE pNode;
   ULONG   MyCookie;
   ULONG   Unique;
   ULONG   Pool;
   BOOL    Found = FALSE;
   USHORT  i;

   if ( (RMHandle & PSEUDO_KEY) == PSEUDO_KEY) {
      for ( i=0; i < LOOKUP_SIZE; i++){
         if (PseudoLookup[i].RMHandle == RMHandle){
            pNode = PseudoLookup[i].pRMNode;
            goto CookieCheck;
         }
      }
      return NULL;
   }

   Unique = (RMHandle ^ HANDLE_MAGIC);
   OFFSETOF(pNode) = (USHORT)Unique;

   Pool = ((Unique >> 16) & (POOL_MASK));

   Unique >>= 18;

   if (Pool < NUM_POOLS)
      SELECTOROF(pNode) = RMPools[Pool];
   else
      SELECTOROF(pNode) = SELECTOROF(PDevPtrs[PDEV_CPU_0]);



   if ( pNode->Unique != (USHORT)Unique ) {
      return NULL;
   }

CookieCheck:

   if (pNode->Cookie != Cookie){
      switch(Cookie){
         case ANY_PHYS_COOKIE:
            if ( (pNode->Cookie != ADAPTER_NODE_COOKIE) &&
                 (pNode->Cookie != DEVICE_NODE_COOKIE )   )
               return NULL;
            break;

         case ANY_LOG_COOKIE:
            if ( (pNode->Cookie != LDEV_NODE_COOKIE   ) &&
                 (pNode->Cookie != SYS_NODE_COOKIE    ) )
               return NULL;
            break;

         case ANY_COOKIE:
            if ( (pNode->Cookie != ADAPTER_NODE_COOKIE) &&
                 (pNode->Cookie != DEVICE_NODE_COOKIE ) &&
                 (pNode->Cookie != LDEV_NODE_COOKIE   ) &&
                 (pNode->Cookie != SYS_NODE_COOKIE    ) )
               return NULL;
            break;
         default:
            return NULL;
      }
   }

   return( pNode );
}

/*--------------------------------------------------------*/
/*                                                        */
/*   RMNodeFromBusType                                    */
/*   -------------                                        */
/*     Should only be called if hDevice is unknown.  Try  */
/*     to determine pointer to Node to connect to.        */
/*                                                        */
/*--------------------------------------------------------*/

PRMNODE NEAR RMNodeFromBusType(USHORT HostBusType)
{
   PRMNODE pNode;

   switch (HostBusType) {
      case AS_HOSTBUS_ISA   :
      case AS_HOSTBUS_EISA  :
      case AS_HOSTBUS_uCHNL :
         pNode=PDevPtrs[PDEV_SYSBUS];
         break;

      case AS_HOSTBUS_PCI :
         pNode=PDevPtrs[PDEV_PCIBUS];
         break;

      default:
         pNode=PDevPtrs[PDEV_XBUS];     /* If all else fails place on XBus */
         break;
   }


   return( pNode );
}



/*--------------------------------------------------------*/
/*                                                        */
/*   RMMakeHandle                                         */
/*   -------------                                        */
/*--------------------------------------------------------*/

RMHANDLE NEAR RMMakeHandle(PRMNODE pNode)
{
RMHANDLE  RMHandle;
ULONG     Unique;
USHORT    i;
USHORT    Pool=0;

   for ( i=0; i < LOOKUP_SIZE; i++){
      if (PseudoLookup[i].pRMNode == pNode){
         return( PseudoLookup[i].RMHandle );
      }
   }

   for ( i=0; i< NUM_POOLS; i++)
      if (RMPools[i] == SELECTOROF(pNode))
         Pool = i;


   Unique = (ULONG)pNode->Unique;

   Unique <<= 18;
   Unique += Pool;
   RMHandle = Unique + OFFSETOF(pNode);
   RMHandle ^= HANDLE_MAGIC;

   return( RMHandle );
}

/*--------------------------------------------------------*/
/*                                                        */
/*   RMEnter                                              */
/*   -------                                              */
/*--------------------------------------------------------*/

USHORT NEAR RMEntry()
{
  if ( *pCurIntLevel != -1L )
  {
    return( 1 );
  }

  if ( RSMSem )
  {
    RSMWaitCount++;

    while ( RSMSem )
    {
      DevHelp_ProcBlock( (ULONG) (PVOID) &RSMSem,
                         (ULONG) -1L,
                         (USHORT) WAIT_IS_NOT_INTERRUPTABLE);
    }

    RSMWaitCount--;
  }

  RSMSem = 1;

  return ( 0 );
}

/*--------------------------------------------------------*/
/*                                                        */
/*   RMExit                                               */
/*   ------                                               */
/*--------------------------------------------------------*/

USHORT NEAR RMExit()
{
  USHORT        rc = 0;
  USHORT        AwakeCount;

  if ( !RSMSem )
  {
    return 1;
  }

  if ( RSMWaitCount )
  {
    DevHelp_ProcRun( (ULONG)   (PVOID) &RSMSem,
                     (PUSHORT) &AwakeCount );
  }

  RSMSem = 0;

  return 0;
}

/*--------------------------------------------------------*/        /*@V103757*/
/*                                                        */        /*@VVVVVVV*/
/*   RMGetResFlags                                        */
/*   -------------                                        */
/*--------------------------------------------------------*/

USHORT NEAR RMGetResFlags( PRESNODE pResNode )
{
  switch ( pResNode->ResourceType )
  {
    case RS_TYPE_IO:
       return ( pResNode->pIO->IOFlags );
    case RS_TYPE_IRQ:
       return ( pResNode->pIRQ->IRQFlags );
    case RS_TYPE_DMA:
       return ( pResNode->pDMA->DMAFlags );
    case RS_TYPE_TIMER:
       return ( pResNode->pTMR->TMRFlags );
    case RS_TYPE_MEM:
       return ( pResNode->pMEM->MemFlags );
    default:
       ;
  }
  return ( 0 );                                                     /*@VAAAAAA*/
}                                                                   /*@V103757*/

