/* SCCSID = "src/dev/usb/HID/HIDSTRAT.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:  HIDSTRAT.C                                            */
/*                                                                            */
/*   DESCRIPTIVE NAME:  HID Class driver strategy routine.                    */
/*                                                                            */
/*   FUNCTION: These routines handle the task time routines for the strategy  */
/*             entry point of HID Class device driver.                        */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             HIDStrategy                                                    */
/*             CmdError                                                       */
/*             HIDInitComplete                                                */
/*             HIDGetUSBDIDC                                                  */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          98/01/31  MB                                                      */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include        "hid.h"

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  HIDStrategy                                      */
/*                                                                    */
/* DESCRIPTIVE NAME:  Strategy 1 entry point for the USB HID Class    */
/*                    device driver.                                  */
/*                                                                    */
/* FUNCTION:  The function of this routine is pass the OS/2 kernel    */
/*            request packet and to appropriate worker routine.       */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Task time                                                 */
/*                                                                    */
/* ENTRY POINT:  HIDStrategy                                          */
/*    LINKAGE:  CALL FAR                                              */
/*                                                                    */
/* INPUT:  es:bx -> kernel request packet                             */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS: None                                                      */
/*                                                                    */
/* INTERNAL REFERENCES:  CmdError                                     */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
#pragma optimize("eglt", off)
void far HIDStrategy()
{
   RPH        FAR  *pRP;
   USHORT       Cmd;

   _asm
   {
      mov word ptr pRP[0], bx
      mov word ptr pRP[2], es
   }

   Cmd = pRP->Cmd;

   if (Cmd > MAX_USB_CMD)
   {
      CmdError( pRP );
   }
   else
   {
      // Call Worker Routine */
      (*gStratList[Cmd])(pRP);
   }
}
#pragma optimize("", on)

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  CmdError                                         */
/*                                                                    */
/* DESCRIPTIVE NAME:  Command not supported in the device driver      */
/*                                                                    */
/* FUNCTION:  The function of this routine is to return command not   */
/*            supported for the request.                              */
/*                                                                    */
/* NOTES: This is an immediate command that is not put on the FIFO    */
/*        queue.                                                      */
/*                                                                    */
/* CONTEXT: Task time                                                 */
/*                                                                    */
/* ENTRY POINT:  CmdError                                             */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  pRP-> kernel request packet                                */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS: pRP->Status = STDON + STERR + ERROR_I24_BAD_COMMAND       */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void CmdError( RPH FAR *pRP)
{
#ifdef DEBUG
   dsPrint1( DBG_CRITICAL, "HID : CmdError - Strategy Command = %d\r\n", pRP->Cmd );
#endif

   pRP->Status = STDON + STERR + ERROR_I24_BAD_COMMAND;
   return;
}


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  HIDInitComplete                                  */
/*                                                                    */
/* DESCRIPTIVE NAME:  Initialization complete                         */
/*                                                                    */
/* FUNCTION:  The function of this routine is to finish driver's      */
/*            initialization by registering them to USBD driver.      */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Initialization time                                       */
/*                                                                    */
/* ENTRY POINT:  HIDInitComplete                                      */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  pRP-> kernel request packet                                */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS: pRP->Status = STATUS_DONE                                 */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void HIDInitComplete(  RPH FAR *pRP)
{
   RP_GENIOCTL    rp_USBDReg;
   USBDClass      classRegData;
#ifdef DEBUG
   dsPrint( DBG_HLVLFLOW, "HID : HIDInitComplete started\r\n" );
#endif

   pRP->Status = STATUS_DONE;

   if (!gpUSBDIDC || !gdsUSBIDC)
      HIDGetUSBDIDC();

   if (!gpUSBDIDC || !gdsUSBIDC)
      pRP->Status = STATUS_DONE | STERR | STATUS_ERR_UNKCMD;

   //  register HID Class Driver within USBD
   if (pRP->Status == STATUS_DONE)
   {
      setmem((PSZ)&rp_USBDReg, 0, sizeof(rp_USBDReg));
      rp_USBDReg.rph.Cmd=CMDGenIOCTL;   // IOCTL
      rp_USBDReg.Category=USB_IDC_CATEGORY_USBD;
      rp_USBDReg.Function=USB_IDC_FUNCTION_REGISTER;
      rp_USBDReg.ParmPacket=(PVOID)&classRegData;
      classRegData.usbIDC=(PUSBIDCEntry)&HIDidc;
      classRegData.usbDS=GetDS();
      USBCallIDC( gpUSBDIDC, gdsUSBIDC, (RP_GENIOCTL FAR *)&rp_USBDReg );
      pRP->Status=rp_USBDReg.rph.Status;
   }

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

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  HIDGetUSBDIDC                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  Retrieves USBD driver IDC routine address & ds  */
/*                                                                    */
/* FUNCTION:  Retrieves USBD driver IDC routine address & data        */
/*            segment value.                                          */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Task time                                                 */
/*                                                                    */
/* ENTRY POINT:  HIDGetUSBDIDC                                        */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  none                                                       */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS: Sets gpUSBDIDC and gdsUSBIDC with USBD driver IDC ref data*/
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void HIDGetUSBDIDC(void)
{
   setmem((PSZ)&gDDTable, 0, sizeof(gDDTable));

   gpUSBDIDC=NULL;
   gdsUSBIDC=0;

   if (DevHelp_AttachDD( gUSBDriverName, (NPBYTE)&gDDTable))
      return;      /* Couldn't find USBD's IDC */

   gpUSBDIDC = (PUSBIDCEntry)gDDTable.ProtIDCEntry;
   gdsUSBIDC = gDDTable.ProtIDC_DS;
}


