/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT    Copyright (C) 1992 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 source code is provided to you solely for       */
/*    the purpose of assisting you in your development of OS/2 device        */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Developer Connection Device Driver       */
/*    Source Kit for OS/2. This Copyright statement may not be removed.      */
/*                                                                           */
/*****************************************************************************/
/*static char *SCCSID = "src/dev/dasd/os2aspi/aspistr1.c, aspi, r206 93/03/20";*/
/**************************************************************************
 *
 * SOURCE FILE NAME = ASPISTR1.C
 *
 * DESCRIPTIVE NAME = OS2ASPI.DMD - OS/2 ASPI Device Manager
 *                    ASPI Device Manager - Strategy 1 EP
 *
 *
 * VERSION = V2.0
 *
 * DATE
 *
 * DESCRIPTION Initialization packet and handles ASPI requests
 *
 *
*/
#define VDDENTRY _pascal _far _loadds
typedef unsigned short (VDDENTRY *FPFNVDD)(unsigned long, unsigned long, unsigned long);   /* fpfnvdd */
#define INCL_NOBASEAPI
#define INCL_NOPMAPI
#include <os2.h>


#include <devcmd.h>                                                  /*@V99999*/
#include <devclass.h>

#include <strat2.h>
#include <reqpkt.h>
#include <dskinit.h>
#include <scb.h>

#include <iorb.h>
#include <addcalls.h>
#include <scsi.h>
#include <aspi.h>
#include <aspicons.h>
#include <aspitype.h>
#include <aspipro.h>

extern USHORT InitComplete;
extern FPFNVDD VDDProc;

#pragma optimize("cegl",off)        /* Disable optimization switches that    */
                                    /* are illegal for routines that contain */
                                    /* inline assembly code                  */

/*********************************************************
*                                                        *
*   Procedure Name : ASPIEntry                           *
*                                                        *
*   Description : This is the entry point for all ASPI   *
*   requests from other drivers. It follows the ASPI     *
*   specification for OS/2, and expects all SRBs to be   *
*   passed on the stack and NOT as part of a standard    *
*   device driver request packet.                        *
*                                                        *
*   Since this is an IDC entry point a request packet    *
*   is NOT required. We will verify the command type     *
*   to make sure that the request packet is valid.       *
*   All necessary information is contained in the SRB.   *
*                                                        *
*   Input :                                              *
*         ASPIDataSegment - The data selector for this   *
*            driver, obtained via DDAttach               *
*         pSRB - A pointer to the new SRB                *
*                                                        *
*   Output :                                             *
*                                                        *
*********************************************************/
VOID FAR ASPIEntry (USHORT ASPIDataSegment,PASPI_SRB_HEADER pSRB)

   {
   int segmentES;

   /* Save ES in a local variable. Don't PUSH on stack because */
   /* MSC 6.0 generates     code                               */

   _asm mov word ptr segmentES, es
   _asm pusha

   /* Handle the ASPI Request */
      ASPISRBEntr(pSRB,0);

   _asm popa
   /* Restore ES */
   _asm mov es, word ptr segmentES
   }

/*********************************************************
*                                                        *
*   Procedure Name : ASPIStr1                            *
*                                                        *
*   Description : This is the entry point for request    *
*   packets sent by the system and device drivers.       *
*   This entry point should only be used during system   *
*   initialization. All real ASPI requests must use      *
*   use ASPIEntry to conform to the specification.       *
*                                                        *
*                                                        *
*   Input :                                              *
*                                                        *
*   Output :                                             *
*                                                        *
*********************************************************/
VOID FAR ASPIStr1(VOID)

   {

   PRPH   pRPH;

   /* Setup a pointer to the driver request packet */
   _asm
   {
   mov word ptr pRPH[0], bx
   mov word ptr pRPH[2], es
   }

   /* Verify that the command is acceptable */

   if ((pRPH->Cmd == CMDInitBase) && !InitComplete)
      pRPH->Status = ASPIInit((PRPINITIN) pRPH);
   else
      {
      if (pRPH->Cmd == CMDGenIOCTL)
         {
         ASPISRBEntr((PASPI_SRB_HEADER) ((PRP_GENIOCTL)pRPH)->ParmPacket,0);
         pRPH->Status |= STDON;
         }
      else
         StatusError(pRPH,0x8103);
      }

   }

#pragma optimize("cegl",on)         /* Enable optimization switches again */

/*********************************************************
*                                                        *
*   Procedure Name : StatusError                         *
*                                                        *
*   Description : This procedure updates the status      *
*   byte with any error information that is returned.    *
*                                                        *
*   Input :                                              *
*         pRPH - A pointer to the request packet         *
*         errorCode - The error that was returned        *
*                                                        *
*   Output :                                             *
*                                                        *
*********************************************************/
VOID NEAR StatusError(PRPH pRPH, USHORT ErrorCode )

   {
   pRPH->Status |= ErrorCode;
   pRPH->Status |= STATUS_DONE;
   }
