/* SCCSID = "src/dev/usb/COM/COMINIT.C, usb, c.basedd 98/10/26" */
/*
*   Licensed Material -- Property of IBM
*
*   (c) Copyright IBM Corp. 1998  All Rights Reserved
*/

/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  COMINIT.C                                             */
/*                                                                            */
/*   DESCRIPTIVE NAME:  USB Communication Device Class Driver                 */
/*                      initialization routines                               */
/*                                                                            */
/*   FUNCTION: These routines handle USB Communication Device Class Driver    */
/*             initialization process.                                        */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:  COMInit                                                   */
/*                  RegisterCOM                                               */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          98/10/26  LR                                                      */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include "usbcom.h"

static BOOL RegisterCOM (void);

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  COMInit                                          */
/*                                                                    */
/* DESCRIPTIVE NAME: USB Communication Device Class Driver            */
/*                   initialization                                   */
/*                                                                    */
/* FUNCTION:  The function of this routine is to initialize the       */
/*            USB Communication Device Class Driver.                  */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Initialization time                                       */
/*                                                                    */
/* ENTRY POINT:  COMInit                                              */
/*    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:  RegisterCOM                                  */
/*                                                                    */
/* EXTERNAL REFERENCES:  COMInfoInit                                  */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/

void COMInit (PRPH pRP)
{
   PRPINITIN   pRPI;    // Input Request Packet far pointer
   PRPINITOUT  pRPO;    // Output Request Packet far pointer

   KeyData     keyData[2] = {"V",  CFSTR_TYPE_DEC,    0, 0,
                             "N:", CFSTR_TYPE_STRING, 0, 0};
   PSZ         cmdLine;
   ULONG       cmdRStatus, errColumn;
   USHORT      cmdRc, index;

#ifdef DEBUG
   dsPrint (DBG_HLVLFLOW, "USBCOM: Init\r\n");
#endif

   pRP->Status = STATUS_DONE;

   if (ghDriver) return;            // initilization already passed

   pRPI = (PRPINITIN)pRP;
   pRPO = (PRPINITOUT)pRP;
   Device_Help = pRPI->DevHlpEP;    // save DevHelp Entry Point
   /*
      process CONFIG.SYS DEVICE= line parameters
   */
   cmdLine = (PSZ)MAKEP (SELECTOROF (pRPI->InitArgs), OFFSETOF (pRPI->InitArgs));
   cmdRStatus = ProcessConfigString (cmdLine, 2, (KeyData FAR *)&keyData);
   cmdRc = LOUSHORT (cmdRStatus);
   errColumn = (ULONG)HIUSHORT (cmdRStatus);
   switch (cmdRc)
   {
   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;

   if (keyData[1].keyStatus == CFSTR_STATUS_OK)
   {
      USHORT start  = LOUSHORT (keyData[1].value);
      USHORT length = HIUSHORT (keyData[1].value) - start;
      if (length <= 8)
      {
         setmem (gCOMn, ' ', 8);
         movmem (gCOMn, &cmdLine[start], length);
      }
   }
   else
   {
      for (gCOMn[3] = '1'; gCOMn[3] <= '9'; gCOMn[3]++)
      {
         if (DevHelp_AttachDD (gCOMn, (NPBYTE)&gIDCTable)) break;
         else if (OFFSETOF (gIDCTable.ProtIDCEntry) == NULL) break;
      }
      if (gCOMn[3] > '9') gCOMn[3] = '$';
   }
   if (DevHelp_AttachDD ("USBD$   ", (NPBYTE)&gIDCTable))
   {
      pRP->Status |= STERR;
      gMessageCount = AddToMsgArray (gMessageIDs, INIT_MESSAGE_NO_USBD, gMessageCount, MAX_INIT_MESSAGE_COUNT);
   }
   else
   {
      gpUSBDIDC = (PUSBIDCEntry)gIDCTable.ProtIDCEntry;
      gdsUSBDIDC = gIDCTable.ProtIDC_DS;

      if (DevHelp_AllocGDTSelector ((PSEL)&gCOM.wGDTSel, 2))
      {
         pRP->Status |= STERR;
      }
      else
      {
         RegisterCOM();

         for (index = 0; index < MAX_MDMS; index++) gMDM[index].active = TURNOFF;
         gNoOfMDMs = 0;

         gCOM.iModem = MAX_MDMS;
         gCOM.wNOpens = 0;

         gCOM.dcb.wWriteTO = WRITE_TO_INIT;
         gCOM.dcb.wReadTO  = READ_TO_INIT;
         gCOM.dcb.bmF1     = F1_DTR_ENABLE;
         gCOM.dcb.bmF2     = F2_RTS_ENABLE;
         gCOM.dcb.bmF3     = F3_READ_TO_NORM;
         gCOM.dcb.bError   = 0;
         gCOM.dcb.bBreak   = 0;
         gCOM.dcb.bXON     = XON_INIT;
         gCOM.dcb.bXOFF    = XOFF_INIT;
         
         gCOM.prevline.dwDTERate    = DEFAULT_BITRATE;
         gCOM.prevline.bDataBits    = DEFAULT_DATABITS;
         gCOM.prevline.bParityType  = DEFAULT_PARITY;
         gCOM.prevline.bCharFormat  = DEFAULT_STOPBITS;

         gCOM.wEvent = gCOM.wError = 0;

         for (index = NULL; index < NUM_POINTERS; index++)
         {
            gCOM.pRPRead[index]  = NULL;
            gCOM.pRPWrite[index] = NULL;
         }
         gCOM.inq.iIn = gCOM.inq.iOut = gCOM.inq.wCount = 0;
         gCOM.outq.iIn = gCOM.outq.iOut = gCOM.outq.wCount = 0;
         
         COMInfoInit();
      }
   }
   if (pRP->Status == STDON)
   {
      pRPO->CodeEnd = ((USHORT)&COMInit) - 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
   }
   if (gVerbose) TTYWrite (gVMessages, gMessageIDs, gMessageCount);
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  RegisterCOM                                      */
/*                                                                    */
/* DESCRIPTIVE NAME: USB Communication Device Class Driver            */
/*                   resource registration                            */
/*                                                                    */
/* FUNCTION:   The function of this routine is to register            */
/*             USB Communication Device Class Driver and              */
/*             corresponding adapter resources.                       */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Initialization time                                       */
/*                                                                    */
/* ENTRY POINT:  RegisterCOM                                          */
/*    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 RegisterCOM (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);
}

