/* SCCSID = "src/dev/usb/USBMOUSE/MOUIRQ.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:  MOUINIT.C                                              */
/*                                                                            */
/*  DESCRIPTIVE NAME:  USB Mouse Device Driver initialization routines        */
/*                                                                            */
/*  FUNCTION:                                                                 */
/*                                                                            */
/*  NOTES:                                                                    */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*  ENTRY POINTS:                                                             */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer         Comment                              */
/*  ----    --------  ----------         -------                              */
/*          98/02/01  Vjacheslav Chibis                                       */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include "mouse.h"   /* USB mouse DD master include file */


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  SendLegacyIRQ                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  Send legacy IRQ                                 */
/*                                                                    */
/* FUNCTION: This routine send USB mouse IRQ data to legacy driver    */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  SendLegacyIRQ                                        */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  PRP_GENIOCTL pRP_GENIOCTL                                  */
/*                                                                    */
/* EXIT-NORMAL: n/a                                                   */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS: None                                                      */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  LMOUCallIDC                                  */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/

void SendLegacyIRQ(PRP_GENIOCTL pRP_GENIOCTL)
{
   BOOL   Buttons[3];
   UCHAR  DX;
   UCHAR  DY;
   UCHAR  tmp;
   UCHAR  Wheel;
   USBRB  FAR    *processedRB=(USBRB FAR *)pRP_GENIOCTL->ParmPacket;
   USHORT deviceIndex=LOUSHORT(processedRB->requestData2); /* get device index */
   USHORT i;

#ifdef DEBUG
   dsPrint(DBG_DETAILED, "USBMOUSE : intbuffer= ");
   for( i=0;i<gActiveMice[deviceIndex].intBufferLength;i++ )
      dsPrint1(DBG_DETAILED, "%d ", gActiveMice[deviceIndex].IntBuffer[i]);

   dsPrint(DBG_DETAILED, "\r\n");
   dsPrint2(DBG_DETAILED, "X size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].itemOffset
   );
   dsPrint2(DBG_DETAILED, "Y size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].itemOffset
   );
   dsPrint2(DBG_DETAILED, "Wheel size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].itemOffset
   );
   dsPrint2(DBG_DETAILED, "Button_1 size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_1].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_1].itemOffset
   );
   dsPrint2(DBG_DETAILED, "Button_2 size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_2].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_2].itemOffset
   );
   dsPrint2(DBG_DETAILED, "Button_3 size=%d offset=%d\r\n", 
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_3].itemSize,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_3].itemOffset
   );

#endif
   /*******************/
   /* head values set */
   /*******************/

   setmem((PSZ)&Buttons, sizeof(Buttons), FALSE); // 11/03/1998 VC

#ifdef DEBUG
   dsPrint2(DBG_SPECIFIC, "X= index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].mask);
   dsPrint2(DBG_SPECIFIC, "Y= index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].mask);
   dsPrint2(DBG_SPECIFIC, "b1= index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_1].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_1].mask);
   dsPrint2(DBG_SPECIFIC, "b2= index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_2].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_2].mask);
   dsPrint2(DBG_SPECIFIC, "b3= index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_3].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_BUTTON_3].mask);

   dsPrint2(DBG_SPECIFIC, "wheel = index in buffer=%d mask=%d\r\n", gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].indexInBuffer,
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].mask);
#endif

   /********************************/
   /* check if buttons are pressed */
   /********************************/


   for( i=0;i<3;i++ )
   {
      Buttons[i]=
      (gActiveMice[deviceIndex].IntBuffer[gActiveMice[deviceIndex].DeviceData.items[i+REPORT_ITEM_BUTTON_1].indexInBuffer]&
      gActiveMice[deviceIndex].DeviceData.items[i+REPORT_ITEM_BUTTON_1].mask)==
      gActiveMice[deviceIndex].DeviceData.items[i+REPORT_ITEM_BUTTON_1].mask;

   }


   /*******************************/
   /* calculate relative values   */
   /*******************************/

   DX=gActiveMice[deviceIndex].IntBuffer[gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].indexInBuffer]&
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].mask;

   DY=gActiveMice[deviceIndex].IntBuffer[gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].indexInBuffer]&
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].mask;

   /*****************************/
   /* calculate absolute values */
   /*****************************/



   if( (gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].itemType&ITEM_TYPE_ABSOLUTE_RELATIVE)==FALSE )
   {
      //absolute data

      if( (!gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].used)||(gAbsolute!=deviceIndex) )
      {
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].lastAbsoluteData=DX;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].used=TRUE;

         // we need it to set cursor to upper left position

         for( tmp=0;tmp<10;tmp++ )
         {
            CallLegasyIRQ(-100, -100, 0, (BOOL FAR *)&Buttons);
         }
         //set cursor to head value from absolute device
         CallLegasyIRQ(DX, DY, Wheel, (BOOL FAR *)&Buttons);
      }
      else
      {
         tmp=DX;
         DX-=(UCHAR)gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].lastAbsoluteData;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].lastAbsoluteData=tmp;

      }
   }

   if( ((gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].itemType&ITEM_TYPE_ABSOLUTE_RELATIVE)==FALSE) )
   {
      //absolute data

      // we need it to set cursor to upper left position
      //CallLegasyIRQ(-100, -100, 0, (BOOL FAR *)&Buttons);

      //set cursor to head value from absolute device
      //CallLegasyIRQ(DX, DY, Wheel, (BOOL FAR *)&Buttons);

      if( (gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].used==FALSE)||(gAbsolute!=deviceIndex) )
      {
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].lastAbsoluteData=DY;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].used=TRUE;

      }
      else
      {

         tmp=DY;
         DY-=(UCHAR)gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].lastAbsoluteData;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].lastAbsoluteData=tmp;

      }
   }
   Wheel=gActiveMice[deviceIndex].IntBuffer[gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].indexInBuffer]&
   gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].mask;


   if( !(gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].itemType&ITEM_TYPE_ABSOLUTE_RELATIVE) )
   {
      //relative data

      if( !gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].used )
      {
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].lastAbsoluteData=0;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].used=TRUE;

      }
      else
      {
         Wheel=Wheel-(UCHAR)gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].lastAbsoluteData;
         gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_WHEEL].lastAbsoluteData=Wheel;

      }
   }


#ifdef DEBUG
   dsPrint4(DBG_DETAILED, "USBMOUSE :  DX=%d, DY=%d, Button1=%d, Button2=%d\r\n", DX, DY, Buttons[0], Buttons[1]);
#endif


   if( ((gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_X].itemType&ITEM_TYPE_ABSOLUTE_RELATIVE)==FALSE)||
   ((gActiveMice[deviceIndex].DeviceData.items[REPORT_ITEM_AXE_Y].itemType&ITEM_TYPE_ABSOLUTE_RELATIVE)==FALSE) )
   {
      gAbsolute=deviceIndex;
   }
   else
      gAbsolute=FULL_WORD;

   CallLegasyIRQ(DX, DY, Wheel, (BOOL FAR *)&Buttons);

   return;  

}


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  CallLegasyIRQ                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  process legacy mouse driver IRQ                 */
/*                                                                    */
/* FUNCTION:   Sends the request to process IRQ event from USB mouse  */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  CallLegasyIRQ                                        */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  NONE                                                       */
/*                                                                    */
/* EXIT-NORMAL:  n/a                                                  */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS: None                                                      */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  CallLegasyIRQ                                */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/


void CallLegasyIRQ(UCHAR DX, UCHAR DY, UCHAR Wheel, BOOL FAR *pButtons)
{
   BOOL  Moved;
   MouseData MD;
   RP_GENIOCTL  rp;
   BOOL Buttons[3];



   Buttons[0]=*pButtons++;
   Buttons[1]=*pButtons++;
   Buttons[2]=*pButtons;

   Moved=!DX&&!DY?FALSE:TRUE; /* to simplify calculations */


   /* set struct values, which will be send to legacy mouse DD */
   MD.DeltaX=DX;
   MD.DeltaY=DY;

   MD.DeviceStatus=Moved?(UCHAR)1:(UCHAR)0;


   /*******************************************/
   /* convert USB mouse data to legacy values */
   /*******************************************/

   if( Moved )
   {
      if( Buttons[0] )
         MD.DeviceStatus|=0x2;
      if( Buttons[1] )
         MD.DeviceStatus|=0x8;
      if( Buttons[2] )
         MD.DeviceStatus|=0x20;
   }
   else
   {
      if( Buttons[0] )
         MD.DeviceStatus|=0x4;
      if( Buttons[1] )
         MD.DeviceStatus|=0x10;
      if( Buttons[2] )
         MD.DeviceStatus|=0x40;
   }

   MD.Wheel=Wheel;
   #ifdef DEBUG
   if( MD.Wheel )
      dsPrint1(DBG_SPECIFIC, "USBMOUSE : SendLegacyIRQ : Wheel data =%d\r\n", MD.Wheel);
   #endif
   setmem((PSZ)&rp, 0, sizeof(rp));
   rp.Category=USB_IDC_CATEGORY_LEGACY; /* legacy driver category */
   rp.Function=USB_IDC_FUNCTION_PRCIRQ; /* function ID = process IRQ */
   rp.ParmPacket=(PVOID)&MD;

   /* call legacy mouse driver to process USB mouse IRQ */
   LMOUcallIDC( pLMOUSEIDC, dsLMOUSEIDC, (RP_GENIOCTL FAR *)&rp );
   return;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  SetIdleTime                                      */
/*                                                                    */
/* DESCRIPTIVE NAME:  Set idle time                                   */
/*                                                                    */
/* FUNCTION:   Sets idle time for specified device                    */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  SetIdleTime                                          */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  NONE                                                       */
/*                                                                    */
/* EXIT-NORMAL:  n/a                                                  */
/*                                                                    */
/* EXIT-ERROR:  n/a                                                   */
/*                                                                    */
/* EFFECTS: None                                                      */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  USBCallIDC                                   */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/



void SetIdleTime( USHORT deviceIndex )
{
   USBRB        hcdReqBlock;
   RP_GENIOCTL  rp_USBReq;



   if( deviceIndex==LAST_INDEX )
   {
#ifdef DEBUG
      dsPrint(DBG_CRITICAL, "USBMOUSE : SetIdleTime failed : invalid deviceIndex\r\n");
#endif
      return;
   }

#ifdef DEBUG
   dsPrint2(DBG_SPECIFIC, "USBMOUSE : SetIdleTime : deviceIndex=%d deviceAddress=%d\r\n",
   deviceIndex,
   gActiveMice[deviceIndex].pDeviceInfo->deviceAddress);
#endif

   /* device data */
   hcdReqBlock.controllerId=gActiveMice[deviceIndex].pDeviceInfo->ctrlID;
   hcdReqBlock.deviceAddress=gActiveMice[deviceIndex].pDeviceInfo->deviceAddress;




   hcdReqBlock.endPointId=USB_DEFAULT_CTRL_ENDPT;    // 0, default control endpoint
   hcdReqBlock.status=0;        // not used
   hcdReqBlock.flags=USRB_FLAGS_TTYPE_SETUP;
   hcdReqBlock.buffer1=(PUCHAR)&gActiveMice[deviceIndex].stdPacket;  
   // pointer to set device address setup packet
   gActiveMice[deviceIndex].stdPacket.bmRequestType=REQTYPE_TYPE_CLASS|REQTYPE_RECIPIENT_INTERFACE;    // Characteristics of request
   gActiveMice[deviceIndex].stdPacket.bRequest=HID_REQUEST_SET_IDLE;         // Specific Request
   gActiveMice[deviceIndex].stdPacket.wValue=0;           // Word-sized field (value depends on request)
   gActiveMice[deviceIndex].stdPacket.wIndex=gActiveMice[deviceIndex].ReportInterface;           // typically Index or Offset
   gActiveMice[deviceIndex].stdPacket.wLength=0;  

   // Number of bytes to Transfer
   hcdReqBlock.buffer1Length=sizeof(gActiveMice[deviceIndex].stdPacket); // setup packet size
   hcdReqBlock.buffer2=NULL;     // no additonal data to be sent to/from host
   hcdReqBlock.buffer2Length=0;  // to complete this request
   hcdReqBlock.serviceTime=USB_DEFAULT_SRV_INTV;    // Required service frequency for isohronous requests in ms. Valid range - [1,1024].
   hcdReqBlock.maxPacketSize=USB_DEFAULT_PKT_SIZE;  // max packet size to be sent at once
   hcdReqBlock.maxErrorCount=USB_MAX_ERROR_COUNT;  // 
   hcdReqBlock.usbIDC=(PUSBIDCEntry)USBMOUSEidc;          // Address of IRQ processing routine to be called for this request
   hcdReqBlock.usbDS=GetDS();
   hcdReqBlock.category=USB_IDC_CATEGORY_CLIENT;        // set USBD layer as IRQ processor
   hcdReqBlock.requestData1=CLIENT_IRQ_SETIDLE;  // USBD I/O call type ID - set device address
   hcdReqBlock.requestData2=MAKEULONG(deviceIndex,0);        // index in device table to current device
   hcdReqBlock.requestData3=0;                        // not used

   setmem((PSZ)&rp_USBReq, 0, sizeof(rp_USBReq));
   rp_USBReq.rph.Cmd=CMDGenIOCTL;   // IOCTL
   rp_USBReq.Category=USB_IDC_CATEGORY_CLASS;
   rp_USBReq.Function=USB_IDC_FUNCTION_ACCIO;
   rp_USBReq.ParmPacket=(PVOID)&hcdReqBlock;

#ifdef DEBUG
   dsPrint(DBG_SPECIFIC, "USBMOUSE : usbcallidc to set idle time\r\n");
#endif

   USBCallIDC( gpUSBHIDIDC, gdsUSBIDC, (RP_GENIOCTL FAR *)&rp_USBReq );

#ifdef   DEBUG
   dsPrint(DBG_SPECIFIC, "USBMOUSE : SetIdleTime ended. \r\n");
#endif
   return;
}


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  ReadInterruptPipe                                */
/*                                                                    */
/* DESCRIPTIVE NAME:  USB interrupt service routine                   */
/*                                                                    */
/* FUNCTION:  Send a request to read interrupt dat from specified     */
/*               device                                               */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT:                                                           */
/*                                                                    */
/* ENTRY POINT:  ReadInterruptPipe                                    */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  NONE                                                       */
/*                                                                    */
/* EXIT-NORMAL: n/a                                                   */
/*                                                                    */
/* EXIT-ERROR: n/a                                                    */
/*                                                                    */
/* EFFECTS: None                                                      */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  GetInterruptPipeAddr                         */
/*                       USBCallIDC                                   */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void ReadInterruptPipe( PRP_GENIOCTL pRP_GENIOCTL )
{
   USBRB FAR    *processedRB;
   USBRB        hcdReqBlock;
   RP_GENIOCTL  rp_USBReq;
   USHORT       deviceIndex;

   processedRB=(USBRB FAR *)pRP_GENIOCTL->ParmPacket;

   deviceIndex=LOUSHORT(processedRB->requestData2);


#ifdef DEBUG
   dsPrint2(DBG_IRQFLOW, "USBMOUSE : ReadInterruptPipe : deviceIndex=%d deviceAddress=%d\r\n",
   LOUSHORT(processedRB->requestData2),
   gActiveMice[deviceIndex].pDeviceInfo->deviceAddress);
#endif


   if( pRP_GENIOCTL->rph.Status!=USB_IDC_RC_OK )
   {  // stop processing if failed to set configuration

#ifdef   DEBUG
      dsPrint1(DBG_CRITICAL, "USBMOUSE : ReadInterruptPipe failed. Status=%x\r\n", pRP_GENIOCTL->rph.Status);
#endif
      return;
   }


   hcdReqBlock.controllerId=processedRB->controllerId;
   hcdReqBlock.deviceAddress=processedRB->deviceAddress; // use default address to set address for unconfigured devices

   hcdReqBlock.endPointId=GetInterruptPipeAddr(gActiveMice[deviceIndex].pDeviceInfo->configurationData, 
   gActiveMice[deviceIndex].pDeviceInfo->descriptor.bNumConfigurations,
   gActiveMice[deviceIndex].pDeviceInfo->bConfigurationValue, gActiveMice[deviceIndex].ReportInterface);
   hcdReqBlock.status=0;        // not used
   hcdReqBlock.flags=USRB_FLAGS_TTYPE_IN|USRB_FLAGS_DET_INTRPT;

   if( !(processedRB->flags&USRB_FLAGS_DET_DTGGLEON) )
      hcdReqBlock.flags|=USRB_FLAGS_DET_DTGGLEON;

   hcdReqBlock.buffer1=(PUCHAR)gActiveMice[deviceIndex].IntBuffer;/* pointer to interrupt buffer */
   hcdReqBlock.buffer1Length=gActiveMice[deviceIndex].intBufferLength; // setup packet size
   hcdReqBlock.buffer2=NULL;     // no additonal data to be sent to/from host
   hcdReqBlock.buffer2Length=0;  // to complete this request
   hcdReqBlock.serviceTime=USB_DEFAULT_SRV_INTV;    // Required service frequency for isohronous requests in ms. Valid range - [1,1024].
   hcdReqBlock.maxPacketSize=USB_DEFAULT_PKT_SIZE;  // max packet size to be sent at once
   hcdReqBlock.maxErrorCount=USB_MAX_ERROR_COUNT;  // 
   hcdReqBlock.usbIDC=(PUSBIDCEntry)USBMOUSEidc;          // Address of IRQ processing routine to be called for this request
   hcdReqBlock.usbDS=GetDS();
   hcdReqBlock.category=USB_IDC_CATEGORY_CLIENT;        
   hcdReqBlock.requestData1=CLIENT_IRQ_READPIPE;  
   hcdReqBlock.requestData2=MAKEULONG(deviceIndex,0);//(LONG)deviceIndex;        // index in device table to current device
   hcdReqBlock.requestData3=0;                        // not used

   setmem((PSZ)&rp_USBReq, 0, sizeof(rp_USBReq));
   rp_USBReq.rph.Cmd=CMDGenIOCTL;   // IOCTL
   rp_USBReq.Category=USB_IDC_CATEGORY_CLASS;
   rp_USBReq.Function=USB_IDC_FUNCTION_ACCIO;
   rp_USBReq.ParmPacket=(PVOID)&hcdReqBlock;

#ifdef   DEBUG
   dsPrint2(DBG_IRQFLOW, "USBMOUSE : ReadInterruptPipe  Status=%x, endpt=%d\r\n",
   pRP_GENIOCTL->rph.Status,hcdReqBlock.endPointId);
#endif

   USBCallIDC( gpUSBHIDIDC, gdsUSBIDC, (RP_GENIOCTL FAR *)&rp_USBReq );
   return;
}


