/* SCCSID = "src/dev/usb/HID/HIDINIT.C, usb, c.basedd 98/07/10" */
/*
*   Licensed Material -- Property of IBM
*
*   (c) Copyright IBM Corp. 1997, 1998  All Rights Reserved
*/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  HIDINIT.C                                             */
/*                                                                            */
/*   DESCRIPTIVE NAME:  Human Interface Device Class driver initialization    */
/*                      routines.                                             */
/*                                                                            */
/*   FUNCTION: These routines handle HID driver initialization process.       */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             HIDInit                                                        */
/*             RegisterHID                                                    */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          98/01/31  MB                                                      */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include "hid.h"

static BOOL RegisterHID(void);

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  HIDInit                                          */
/*                                                                    */
/* DESCRIPTIVE NAME:  Initializes HID Class device driver.            */
/*                                                                    */
/* FUNCTION:  The function of this routine is to initialize the       */
/*            USB port device driver.                                 */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Initialization time                                       */
/*                                                                    */
/* ENTRY POINT:  HIDInit                                              */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  pRP-> kernel request packet                                */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS:  pRPO->CodeEnd = end of code segment                      */
/*           pRPO->DataEnd = end of data segment                      */
/*           pRP->Status = STATUS_DONE                                */
/*           pRP->Status = STDON + STERR + ERROR_I24_GEN_FAILURE      */
/*                                                                    */
/* INTERNAL REFERENCES:  HIDGetUSBDIDC                                */
/*                       RegisterHID                                  */
/*                                                                    */
/* EXTERNAL REFERENCES:  none                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void HIDInit( RPH FAR *pRP)
{
   PRPINITOUT      pRPO;          /* output request packet far pointer */
   PRPINITIN       pRPI;          /* input request packet far pointer */
   KeyData         keyData[1]={"V",CFSTR_TYPE_DEC,0,0};
   PSZ             cmdLine;
   ULONG           cmdRStatus, errColumn;
   USHORT          cmdRc;

#ifdef   DEBUG
   dsPrint(DBG_HLVLFLOW, "HID : HIDInit started\r\n");
#endif

   pRP->Status = STATUS_DONE;
   if (ghDriver) // initilization already passed
      return;

   setmem((PSZ)&gClientDrivers, 0, sizeof(gClientDrivers));
   setmem((PSZ)&gActiveDevices, 0, sizeof(gActiveDevices));
   setmem((PSZ)&gReportItemData, 0, sizeof(gReportItemData));
   setmem((PSZ)&gItemUsage, 0, sizeof(gItemUsage));
   setmem((PSZ)&gItemDesignator, 0, sizeof(gItemDesignator));
   setmem((PSZ)&gItemString, 0, sizeof(gItemString));

   pRPI = (PRPINITIN) pRP;
   pRPO = (PRPINITOUT) pRP;
   Device_Help = ((PRPINITIN)pRP)->DevHlpEP;  /* save devhlp entry point */

   // process CONFIG.SYS BASEDEV= line parameters
   cmdLine=(PSZ) MAKEP( SELECTOROF(pRPI->InitArgs),
                        OFFSETOF(((PDDD_PARM_LIST)pRPI->InitArgs)->cmd_line_args) );
   cmdRStatus=ProcessConfigString(cmdLine, 1, (KeyData FAR *)&keyData);
   cmdRc=LOUSHORT(cmdRStatus); errColumn=(ULONG)HIUSHORT(cmdRStatus);
   switch (cmdRc)  // set cmd line processing errors
   {
   case CFSTR_UNKWN_KEYS:
      SetLongValue( gVMessages[INIT_MESSAGE_UNKNOWNKWD], errColumn );
      gMessageCount=AddToMsgArray( gMessageIDs, INIT_MESSAGE_UNKNOWNKWD, gMessageCount, MAX_INIT_MESSAGE_COUNT );
      break;
   case CFSTR_CONVERR:
      SetLongValue( gVMessages[INIT_MESSAGE_INVNUMERIC], errColumn );
      gMessageCount=AddToMsgArray( gMessageIDs, INIT_MESSAGE_INVNUMERIC, gMessageCount, MAX_INIT_MESSAGE_COUNT );
      break;
   default:
      break;
   }
   gVerbose= keyData[0].keyStatus!=CFSTR_STATUS_NOTFOUND;

   HIDGetUSBDIDC();  // see USBD driver?
   if (!gpUSBDIDC || !gdsUSBIDC)
   {
      pRP->Status = STATUS_DONE | STERR | STATUS_ERR_UNKCMD; //  no - fail to install
      gMessageCount=AddToMsgArray( gMessageIDs, INIT_MESSAGE_NO_USBD, gMessageCount, MAX_INIT_MESSAGE_COUNT );
   }

   /*---------------------------------------------------*/
   /* Register device driver with resource manager      */
   /*---------------------------------------------------*/
   if (pRP->Status == STATUS_DONE)
      RegisterHID();

   if (pRP->Status == STATUS_DONE)
   {
      pRPO->CodeEnd = ((USHORT) &HIDInit) - 1;        /* set end of code segment */
      pRPO->DataEnd = ((USHORT) &gInitDataStart) - 1; /* set end of data segment */
      SetLongValue( gVMessages[INIT_MESSAGE_LOADED], (ULONG)gDriverStruct.MajorVer );   
      SetLongValue( gVMessages[INIT_MESSAGE_LOADED], (ULONG)gDriverStruct.MinorVer );   
      gMessageCount=AddToMsgArray( gMessageIDs, INIT_MESSAGE_LOADED, gMessageCount, MAX_INIT_MESSAGE_COUNT );
   }
   else
   {
      pRPO->CodeEnd = 0; /* set end of code segment */
      pRPO->DataEnd = 0; /* set end of data segment */
   }

   TTYWrite(gVMessages, gMessageIDs, gMessageCount);

#ifdef   DEBUG
   dsPrint1(DBG_HLVLFLOW, "HID : HIDInit ended. Status = %x\r\n", pRP->Status);
#endif
}


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  RegisterHID                                      */
/*                                                                    */
/* DESCRIPTIVE NAME:  HID Class driver RM resource registration       */
/*                                                                    */
/* FUNCTION:  The function of this routine register HID Class driver  */
/*            and corresponding adapter resources.                    */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Initialization time                                       */
/*                                                                    */
/* ENTRY POINT:  RegisterHID                                          */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  none                                                       */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS:  ghDriver, ghAdapter recieves RM handles                  */
/*                                                                    */
/* INTERNAL REFERENCES:  none                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  none                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
static BOOL RegisterHID(void)
{
   APIRET      rc=RMRC_SUCCESS;
   UCHAR       ResourceBuf[ 12 ];  
   ADJUNCT     AdjAdaptNum;
   PAHRESOURCE pResourceList = (PAHRESOURCE)ResourceBuf;

   rc=RMCreateDriver( &gDriverStruct, &ghDriver);

   if (rc==RMRC_SUCCESS)
   {
      pResourceList->NumResource = 0;

      gAdapterStruct.HostBusType = AS_HOSTBUS_PCI;
      AdjAdaptNum.pNextAdj       = NULL;
      AdjAdaptNum.AdjLength      = sizeof(ADJUNCT);
      AdjAdaptNum.AdjType        = ADJ_ADAPTER_NUMBER;
      AdjAdaptNum.Adapter_Number = 0;
      gAdapterStruct.pAdjunctList = &AdjAdaptNum;

      rc=RMCreateAdapter(ghDriver, &ghAdapter,  &gAdapterStruct,
                         NULL, pResourceList);
   }

   return (rc==RMRC_SUCCESS);
}

