/*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.                                */
/*                                                                           */
/*****************************************************************************/
/*static char *SCCSID = "src/vdev/vaspi/vainit.c, vaspi, r207 94/08/15";*/
/**************************************************************************
 *
 * SOURCE FILE NAME = VAINIT.C
 *
 * DESCRIPTIVE NAME = VASPI.SYS - OS/2 Virtual ASPI Device Driver
 *
 *
 *
 * VERSION = V1.0
 *
 * DATE
 *
 * DESCRIPTION : Initialization routines for VASPI.SYS
 *
 *      VASPI is organized as follows:
 *         VAINIT.C    - Init routine
 *         VAUSER.C    - UserHooks for VDM Creation, VDMTermination
 *         VADATA.C    - Data
 *         VAEVENT.C   - Entry point in VDD for PDD to call
 *         VAMEM.C     - Memory and queue management routines
 *         VAROUTER.C  - ASPI Router and DOS Link routines
 *
 *         VASPI.H     - Defines, etc
 *         VASPIX.H    - External data definitions
 *         VASPIP.H    - Function profile definitions
 *         VASPIMAC.H  - Macros
 *
 *
*/#include <mvdm.h>
#include <scsi.h>
#include <aspi.h>

#include "vaspi.h"
#include "vaspix.h"
#include "vaspip.h"
#include "vaspimac.h"

#pragma BEGIN_INIT_CODE

/* Init routine must be named VDDINIT.  Don't know why, it just does */

/***EP  VDDInit -  boot time initialization
 *
 *      Called when the VASPI VDD is loaded.  Arranges hooks for
 *      creation and termination calls.
 *
 *      ENTRY
 *              psz     - argument string (to be parsed)
 *
 *      EXIT-SUCCESS    - returns TRUE
 *
 *      EXIT-FAILURE    - returns FALSE (if registration failed)
 *
 *
 *
 *
 */

BOOL PASCAL VDDInit(PSZ psz)

   {
   USHORT currentAdapter;

   /* Get notification whenever a new VDM is created */
   if (!VDHInstallUserHook(VDM_CREATE,
                           (PUSERHOOK) VASPICreate))
      return FALSE;

   /* Get notification whenever a VDM is destroyed */
   if (!VDHInstallUserHook(VDM_TERMINATE,
                           (PUSERHOOK) VASPIDestroy))
      return FALSE;

   /* Create VDD memory management sem */
   if (!VDHCreateSem(&hMemorySem,
                     VDH_MUTEXSEM))
      return FALSE;

   /* Open OS2ASPI so we can make ASPI calls to it. */
   if ((PDDProc = VDHOpenPDD(PDD_NAME,
                            VASPIEventProc)))
      {
      /* Request extended adapter information for all SCSI adapters */
      GetAdapterInfo(pInquirySRB,
                     0);
      adapterInfo[0].adapterFeatures = pInquirySRB->AdapterFeatures;
      adapterInfo[0].maximumSGList = pInquirySRB->MaximumSGList;
      adapterInfo[0].maximumCDBTransfer = pInquirySRB->MaximumCDBTransfer;

      adapterCount = pInquirySRB->AdapterCount;

      /* Save the extended information in the global data area */

      for (currentAdapter = 1; currentAdapter < adapterCount; currentAdapter++)
         {
         if (currentAdapter > MAX_ADAPTER_COUNT)
            break;

         GetAdapterInfo(pInquirySRB,
                        currentAdapter);

         /* Save the extended information in the global data area */
         adapterInfo[currentAdapter].adapterFeatures = pInquirySRB->AdapterFeatures;
         adapterInfo[currentAdapter].maximumSGList = pInquirySRB->MaximumSGList;
         adapterInfo[currentAdapter].maximumCDBTransfer = pInquirySRB->MaximumCDBTransfer;
         }

      return TRUE;
      }
   else
      {
      VDHDestroySem(hMemorySem);
      return FALSE;
      }

   }

/*********************************************************
*                                                        *
*   Procedure Name : GetAdapterInfo                      *
*                                                        *
*   Description : This procedure retrieves the adapter   *
*   information for the specified adapter from OS2ASPI.  *
*                                                        *
*   Input :                                              *
*        pSRB - A pointer to the SRB being issued        *
*        currentAdapter - The adapter number that info   *
*           will be retrieved for                        *
*                                                        *
*   Output :                                             *
*                                                        *
*********************************************************/
VOID GetAdapterInfo(PASPI_SRB_INQUIRY pSRB, USHORT currentAdapter)

   {
   PVOID SRBSelector;

   /* Create an adapter info request and issue it to OS2ASPI */
   pSRB->SRBHdr.CommandCode = ASPI_CMD_ADAPTER_INQUIRY;
   pSRB->SRBHdr.ASPIStatus = ASPI_STATUS_IN_PROGRESS;
   pSRB->SRBHdr.AdapterIndex = currentAdapter;
   pSRB->SRBHdr.ASPIReqFlags = 0;
   *((PUSHORT) &pSRB->Reserved_1) = 0xAA55;
   *((((PUSHORT) &pSRB->Reserved_1)) + 1) = 8;

   /* Create a 16:16 shadow pointer to the SRB */
   ((PSEL)(&SRBSelector))[1] = VDHCreateSel(pSRB,
                                            sizeof(ASPI_SRB_INQUIRY));
   OFFSETOF16(SRBSelector) = NULL;

   /* Let PDD do all of the real work. */
   PDDProc(PDDCMD_OS2_ASPI_PASSTHRU,
           (PVOID) SRBSelector,
           (PVOID) NULL);

   /* Release the 16:16 shadow pointer to the SRB */
   VDHDestroySel((SEL) SEGMENTOF16(SRBSelector));
   }

#pragma END_INIT_CODE
