/*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.      */
/*                                                                           */
/*****************************************************************************/
/* SCCSID = "src/snooper/parallel/parneg.c, parsnp, c.basedd, currbld 96/04/12" */
/****************************************************************************/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  PARNEG.C                                              */
/*                                                                            */
/*   DESCRIPTIVE NAME:  PARALLEL port device driver IEEE-1284 negotiation     */
/*                      routines.                                             */
/*                                                                            */
/*   FUNCTION: These routines handle the IEEE-1284 negotiations for the       */
/*             parallel port device driver.                                   */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: None                                                    */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             do_negotiate                                                   */
/*             CommModeToExtReq                                               */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*                                                                            */
/* Change Log                                                                 */
/*                                                                            */
/*  Mark    yy/mm/dd  Programmer      Comment                                 */
/*  ----    --------  ----------      -------                                 */
/*          96/03/01  Frank Schroeder Original developer.                     */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include        "par.h"

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  do_negotiate                                     */
/*                                                                    */
/* DESCRIPTIVE NAME:  Negotiate an IEEE-1284 mode                     */
/*                                                                    */
/* FUNCTION:  The function of this routine is to negotiate into or    */
/*            out of an IEEE-1284 mode.                               */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: Task or Interrupt Time                                    */
/*                                                                    */
/* ENTRY POINT:  do_negotiate                                         */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  parInstance_t   pInst    - ptr to adapter instance         */
/*                                                                    */
/* EXIT-NORMAL: N/A                                                   */
/*                                                                    */
/* EXIT-ERROR:  N/A                                                   */
/*                                                                    */
/* EFFECTS: pInst->ReturnCode                                         */
/*                                                                    */
/* INTERNAL REFERENCES:  LockInstance                                 */
/*                       UnlockInstance                               */
/*                       IOWrite8                                     */
/*                       IORead8                                      */
/*                       IODelay                                      */
/*                       ResetInstanceFlags                           */
/*                       setDelayTimer                                */
/*                       cancelDelayTimer                             */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
void do_negotiate( parInstance_t *pInst )
{
  UCHAR                 status;
  BOOL                  XFlag;
  USHORT                fWaitState;


#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate\r\n");
#endif

  /*-------------------------------------------------*/
  /* A reentrant call results in pInst->UseCount     */
  /* being incremented with no further action until  */
  /* the original instance completes.                */
  /*-------------------------------------------------*/
  LockInstance( pInst );

  if ( ++pInst->UseCount > 1 )
  {
    UnLockInstance( pInst );
    return;
  }

  do
  {
    fWaitState = 0;

    UnLockInstance( pInst );

    do
    {
      switch ( pInst->State )
      {
        /*-----------------------------------------------------*/
        /* Return the chipset to compatibility mode. The       */
        /* IEEE-1284 spec requires all negotiations to start   */
        /* from compatibility mode.                            */
        /*                                                     */
        /* If a negotiation was not required, i.e. the current */
        /* mode is the same as the new mode, this will be      */
        /* detected by layers above this routine.              */
        /*-----------------------------------------------------*/
        case NEGS_INIT :
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_INIT\r\n");
#endif

          pInst->StatusReg  =  IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
#endif

          ResetInstanceFlags( pInst, F_DIR_REVERSE );

          /*---------------------------------------------------*/
          /* P1284 D2.00 - State 22 (also see Sec 6.8)         */
          /*                                                   */
          /* Assert HOSTBUSY. This tells the attached device   */
          /* not to request a reverse channel transfer while   */
          /* we are exiting 1284 mode.                         */
          /*---------------------------------------------------*/
          pInst->ControlReg |= (SPP_CONTROL_HOSTCLK | SPP_CONTROL_HOSTBUSY);

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          /*----------------------------------------------------*/
          /* Allow a TL (35ms) delay here.                      */
          /*                                                    */
          /* Although this delay is not explicitly required. It */
          /* avoids a potential race caused by changing HOSTBUSY*/
          /* and 1284ACTIVE at the same time. A shorter in-line */
          /* delay may also work.                               */
          /*----------------------------------------------------*/
          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL );

          fWaitState = 1;

          pInst->State  = NEGS_RESET1284_0;

          break;

        /*---------------------------------------------------*/
        /* P1284 D2.00 - State 22 - Continued                */
        /*                                                   */
        /* Drop 1284ACTIVE (ACTIVE) to complete State 22.    */
        /*---------------------------------------------------*/
        case NEGS_RESET1284_0:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_RESET1284_0\r\n");
#endif

          pInst->ControlReg &= ~SPP_CONTROL_ACTIVE;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          /*-----------------------------------------------------*/
          /* Allow TL (35ms) for the attached device to respond. */
          /*                                                     */
          /* After this delay we will verify the attach device   */
          /* responded per P1284 D2.00 - State 24                */
          /*-----------------------------------------------------*/
          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL );

          fWaitState = 1;

          pInst->State  = NEGS_RESET1284_1;

          break;

        /*---------------------------------------------------*/
        /* P1284 D2.00 - State 24                            */
        /*                                                   */
        /* Verify the device has responded properly to our   */
        /* attempt to exit 1284 mode. If the device does not */
        /* respond as expected, we assume that the device was*/
        /* originally in compatibility mode and start the    */
        /* negotiation immediately.                          */
        /*---------------------------------------------------*/
        case NEGS_RESET1284_1:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_RESET1284_1\r\n");
#endif

          /*-----------------------------------------------------*/
          /* Its been at least 35ms since we dropped 1284Active. */
          /*                                                     */
          /* A device should immediately stop driving the        */
          /* parallel bus when 1284 Active is dropped, so it     */
          /* should be 'safe' at this point reenable to host's   */
          /* parallel port drivers.                              */
          /*-----------------------------------------------------*/
          pInst->ControlReg &= ~SPP_CONTROL_DIR;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          /*-------------------------------------------------*/
          /* Verify the device is following 1284 termination */
          /* protocol.                                       */
          /*                                                 */
          /* We expect: PTRCLK    = 0                        */
          /*            PTRBUSY   = 1                        */
          /*            DATAAVAIL = 0                        */
          /*                                                 */
          /* If the device responded as expected we continue */
          /* 1284 termination.                               */
          /*-------------------------------------------------*/
          pInst->StatusReg = IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
#endif

          pInst->StatusReg ^= SPP1284_STATUS_INVERT;

          status = pInst->StatusReg & (SPP_STATUS_PTRCLK  | \
                                       SPP_STATUS_PTRBUSY | \
                                       SPP_STATUS_DATAAVAIL );

#ifdef DEBUG
  dprintf( "par1284.sys: Device status = %b\r\n", status );
#endif
          if ( status != SPP_STATUS_PTRBUSY )
          {
            pInst->State = NEGS_START;
            break;
          }

          pInst->State = NEGS_RESET1284_2;

          break;

        /*----------------------------------------------------*/
        /* P1284 D2.00 - State 25                             */
        /*                                                    */
        /* We enter State 25 by dropping HOSTBUSY and waiting */
        /* TL (35ms) for the device to respond.               */
        /*----------------------------------------------------*/
        case NEGS_RESET1284_2:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_RESET1284_2\r\n");
#endif

          pInst->ControlReg &= ~SPP_CONTROL_HOSTBUSY;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          pInst->State = NEGS_RESET1284_3;

          fWaitState = 1;

          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL );

          break;

        /*----------------------------------------------------*/
        /* P1284 D2.00 - State 28                             */
        /*                                                    */
        /* We have allowed 35ms for the device to respond.    */
        /*                                                    */
        /* The expected response of the device is:            */
        /*   PTRCLK  = 1                                      */
        /*   PTRBUSY = 1                                      */
        /*                                                    */
        /* We do not check whether the device responded       */
        /* properly at this point since there is no recourse  */
        /* but to complete the termination protocol by        */
        /* raising HOSTBUSY.                                  */
        /*----------------------------------------------------*/
        case NEGS_RESET1284_3:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_RESET1284_3\r\n");
#endif

          pInst->StatusReg = IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
#endif

          pInst->ControlReg |= SPP_CONTROL_HOSTBUSY;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          fWaitState = 1;


          /*--------------------------------------------------------*/
          /* P1284 D2.00 - State 29                                 */
          /*                                                        */
          /* We allow TL (35ms) prior to starting the negotiation.  */
          /*                                                        */
          /* The 1284 Spec specifically requires .5us, however,     */
          /* it seems a longer delay may allow things too settle.   */
          /* This delay is optional and a shorter delay may be      */
          /* substituted.                                           */
          /*                                                        */
          /* The device and host should be in P1284 D2.00 - State 0 */
          /* after this delay.                                      */
          /*--------------------------------------------------------*/
          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL );

          pInst->State = NEGS_START;

          break;

        /*---------------------------------------------------*/
        /* P1284 D2.00 - State 1                             */
        /*                                                   */
        /* Start a IEEE-1284 negotiation cycle setting the   */
        /* 1284 control lines as follows:                    */
        /*                                                   */
        /*   Data 0-7   = Extensibility Request Byte         */
        /*   HOSTBUSY   = 0                                  */
        /*   HOSTCLK    = 1                                  */
        /*   1284ACTIVE = 1                                  */
        /*                                                   */
        /* Allow a maximum delay of 35ms to for the attached */
        /* printer to respond.                               */
        /*                                                   */
        /*---------------------------------------------------*/
        case NEGS_START:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_START\r\n");
#endif
          pInst->StatusReg = IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
  dprintf( "par1284.sys: Control          = %b\r\n",
                pInst->ControlReg ^ SPP1284_CONTROL_INVERT );
#endif
          pInst->StatusReg  ^= SPP1284_STATUS_INVERT;

          /*----------------------------------------------*/
          /* If we just needed to return to compatibility */
          /* mode, then quit while we're ahead            */
          /*----------------------------------------------*/
          if ( pInst->ExtReqByte == (UCHAR)-1)
          {
            /*-----------------------------------------------*/
            /* However, we need to translate the CONTROL and */
            /* STATUS register images settings back to their */
            /* SPP (non-1284) definitions                    */
            /*-----------------------------------------------*/
            pInst->ControlReg ^= (SPP1284_CONTROL_INVERT ^ SPP_CONTROL_INVERT);
            pInst->StatusReg  ^= (SPP1284_STATUS_INVERT  ^ SPP_STATUS_INVERT);

            pInst->State =  NEGS_COMPLETE;
            break;
          }

          /*--------------------------------------*/
          /* State 0 - Extensibility Request Byte */
          /*--------------------------------------*/
          IOWrite8( pInst->pIO[0], SPP_DATA_REG, pInst->ExtReqByte );

          IODelay();

          /*----------------------------------------*/
          /* State 1 - Signal IEEE-1284 Negotiation */
          /*----------------------------------------*/
          pInst->ControlReg |=  (SPP_CONTROL_ACTIVE | SPP_CONTROL_HOSTCLK);
          pInst->ControlReg &=  ~SPP_CONTROL_HOSTBUSY;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          /*--------------------------*/
          /* Wait for device response */
          /*--------------------------*/
          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL );

          fWaitState = 1;
          pInst->State =  NEGS_ACK1284;
          break;

        /*---------------------------------------------------*/
        /* P1284 D2.00 - State 2-3                           */
        /*                                                   */
        /* Check if the device responded as a IEEE-1284      */
        /* compliant device. If not end the negotiation      */
        /* cycle here.                                       */
        /*                                                   */
        /* A 1284 compliant device should set the its 1284   */
        /* status lines as follows:                          */
        /*                                                   */
        /*    PTRCLK     = 0                                 */
        /*    DATAAVAIL  = 0                                 */
        /*    XFLAG      = 1                                 */
        /*    ACKDATAREQ = 1                                 */
        /*                                                   */
        /* If the device responds as expected we generate    */
        /* a strobe pulse (1us) on HOSTCLK to clock the      */
        /* Extensibility Request into the device and then    */
        /* raise HOSTBUSY.                                   */
        /*                                                   */
        /* We then allow a maximum delay of 35ms to for the  */
        /* device to respond to the Extensibility Request    */
        /* byte.                                             */
        /*                                                   */
        /*---------------------------------------------------*/
        case NEGS_ACK1284:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_ACK1284\r\n");
#endif

          /*-----------------------------------*/
          /* State 2 - Verify IEEE-1284 Device */
          /*-----------------------------------*/
          pInst->StatusReg = IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
#endif

          pInst->StatusReg ^=  SPP1284_STATUS_INVERT;

          status = pInst->StatusReg & ( SPP_STATUS_PTRCLK     |
                                        SPP_STATUS_DATAAVAIL  |
                                        SPP_STATUS_XFLAG      |
                                        SPP_STATUS_ACKDATAREQ  );

          if ( status != (SPP_STATUS_XFLAG | SPP_STATUS_ACKDATAREQ) )
          {
            pInst->ReturnCode     = RC_NOT_1284_DEVICE;
            pInst->State          = NEGS_COMPLETE;
            break;
          }

          /*-----------------------------------*/
          /* State 3 - Set HOSTCLK strobe low  */
          /*-----------------------------------*/
          pInst->ControlReg &= ~SPP_CONTROL_HOSTCLK;

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          IODelay();
          IODelay();

          /*-----------------------------------*/
          /* State 4 - Set HOSTCLK strobe high */
          /*-----------------------------------*/
          pInst->ControlReg |= (SPP_CONTROL_HOSTBUSY | SPP_CONTROL_HOSTCLK );

          IOWrite8( pInst->pIO[0],
                    SPP_CONTROL_REG,
                    ((UCHAR)pInst->ControlReg ^ SPP1284_CONTROL_INVERT));

          /*--------------------------*/
          /* Wait for device response */
          /*--------------------------*/
          setDelayTimer( pInst,
                         TIMER_ID_0,
                         do_negotiate,
                         DELAY1284_TL       );

          fWaitState = 1;
          pInst->State =  NEGS_RESPONSE;
          break;


        /*---------------------------------------------------*/
        /* P1284 D2.00 - State 5, 6                          */
        /*                                                   */
        /* If the attached device completed the negotiation  */
        /* handshake properly, it will set:                  */
        /*                                                   */
        /*  ACKDATAREQ = 0                                   */
        /*  PTRCLK     = 1                                   */
        /*                                                   */
        /* If the device accepted our Extensibility Request  */
        /* byte it will also set XFLAG.                      */
        /*                                                   */
        /* Note:                                             */
        /*   In the case of Nibble Mode (ExtReqByte = 0)     */
        /*   XFLAG = 0 indicates a successful negotiation    */
        /*   for all other ExtReqBytes, XFLAG must be set    */
        /*   1.                                              */
        /*                                                   */
        /* At this point the printer may have data for us.   */
        /* This is handled by the called requesting a data   */
        /* transfer in the negotiated mode.                  */
        /*                                                   */
        /*---------------------------------------------------*/
        case NEGS_RESPONSE:
#ifdef DEBUG
  dprintf( "par1284.sys: do_negotiate - NEGS_RESPONSE\r\n");
#endif

          pInst->State = NEGS_COMPLETE;

          /*---------------------------------*/
          /* Get IEEE-1284 Status Lines      */
          /*---------------------------------*/
          pInst->StatusReg = IORead8( pInst->pIO[0], SPP_STATUS_REG );

#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate status = %b\r\n", pInst->StatusReg );
#endif

          pInst->StatusReg ^=  SPP1284_STATUS_INVERT;

          status = pInst->StatusReg & SPP_STATUS_PTRCLK;

          /*---------------------------------*/
          /* State 6 - Check for PTRCLK high */
          /*---------------------------------*/
          if ( status != SPP_STATUS_PTRCLK )
          {
            pInst->ReturnCode = RC_TIMEOUT;
            break;
          }

          /*-------------------------------------------*/
          /* State 5 - Check for correct XFLAG setting */
          /*                                           */
          /* We generate C boolean(s) based on the     */
          /* value of XFLAG and ExtReqByte. If these   */
          /* booleans agree, i.e. both TRUE or both    */
          /* FALSE then the negotiation was successful.*/
          /*                                           */
          /* This checks the expected XFLAG values vs  */
          /* ExtReqByte in P1284 D2.00 Table 4.        */
          /*-------------------------------------------*/
          XFlag = ((pInst->StatusReg & SPP_STATUS_XFLAG) != 0);

          if ( (pInst->ExtReqByte != 0) != XFlag )
          {
            pInst->ReturnCode = RC_INVALID_MODE;
          }
          break;


        /*---------------------------------------------------*/
        /* Negotiation Complete                              */
        /*                                                   */
        /* If the negotiation failed in some previous state  */
        /* we set an invalid current CommMode to force       */
        /* a new negotiation. Otherwise, we assume the       */
        /* caller set the new CommMode.                      */
        /*---------------------------------------------------*/
        case NEGS_COMPLETE:
          if ( pInst->ReturnCode != RC_SUCCESS )
          {
            pInst->CurCommMode = PAR_INVALID_COMM_MODE;
          }

          cancelDelayTimer( pInst, TIMER_ID_0 );
          fWaitState = 1;

          break;
      }
    }
    while ( !fWaitState );

    LockInstance( pInst );
  }
  while ( --pInst->UseCount );

  /* Note: We must remain locked here until we done */
  /*       with pInst->State.                       */

  if ( pInst->State == NEGS_COMPLETE )
  {
    UnLockInstance( pInst );
    /*----------------------------------------------*/
    /* Async callback to originator of negotiation. */
    /*----------------------------------------------*/
    (*pInst->DoneRtn)( pInst );
  }
  else
  {
    UnLockInstance( pInst );
  }
}


/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  CommModeToExtReq                                 */
/*                                                                    */
/* DESCRIPTIVE NAME:  Convert the communication mode to an            */
/*                    extensibility request byte.                     */
/*                                                                    */
/* FUNCTION:  The function of this routine is to convert the          */
/*            communication mode to an extensibility request byte.    */
/*            This routine enforces checks to determine whether the   */
/*            hardware adequately supports the requested mode.        */
/*                                                                    */
/* NOTES:  The extensibility request byte is the byte sent to the     */
/*         device to request the device communicate bidirectionally   */
/*         using a particular protocol (nibble, byte, ecp, etc.).     */
/*                                                                    */
/* CONTEXT: Task or Interrupt Time                                    */
/*                                                                    */
/* ENTRY POINT:  CommModeToExtReq                                     */
/*    LINKAGE:  CALL NEAR                                             */
/*                                                                    */
/* INPUT:  parInstance_t   pInst    - ptr to adapter instance         */
/*         UCHAR           ReqCommMode - requested communication mode */
/*         UCHAR           *pExtReqByte - ptr to ext req byte returned*/
/*                                                                    */
/* EXIT-NORMAL: FALSE                                                 */
/*                                                                    */
/* EXIT-ERROR:  TRUE - unsupported communication mode                 */
/*                                                                    */
/* EFFECTS: pExtReqByte                                               */
/*                                                                    */
/* INTERNAL REFERENCES:  None                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  None                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
USHORT CommModeToExtReq( parInstance_t *pInst,
                         UCHAR         ReqCommMode,
                         UCHAR         *pExtReqByte )
{
#ifdef DEBUG
  dprintf( "par1284.sys: CommModeToExtReq\r\n" );
#endif

  switch ( ReqCommMode )
  {
    case PAR_COMPATIBILITY:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate Compatibility Mode\r\n" );
#endif
      *pExtReqByte = -1;
      break;

    case PAR_NIBBLE:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate Nibble Mode\r\n" );
#endif
      *pExtReqByte =  NEGOTIATE_NIBBLE_MODE;
      break;

    case PAR_BYTE:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate Byte Mode\r\n" );
#endif
      *pExtReqByte =  NEGOTIATE_BYTE_MODE;
      break;

    case PAR_EPP:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate EPP Mode\r\n" );
#endif
      if ( !(pInst->Flags & F_EPP_SUPPORT) )
      {
#ifdef DEBUG
  dprintf( "par1284.sys: EPP Mode Not Supported\r\n" );
#endif
        return( 1 );
      }
      *pExtReqByte =  NEGOTIATE_EPP_MODE;
      break;

    case PAR_ECP_WITH_RLE:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate ECP With RLE Mode\r\n" );
#endif
      if ( !(pInst->Flags & F_FIFO_SUPPORT) )
      {
#ifdef DEBUG
  dprintf( "par1284.sys: ECP Mode Not Supported\r\n" );
#endif
        return( 1 );
      }
      *pExtReqByte =  NEGOTIATE_ECP_RLE_MODE;
      break;

    case PAR_ECP_WITHOUT_RLE:
#ifdef DEBUG
  dprintf( "par1284.sys: Negotiate ECP Without RLE Mode\r\n" );
#endif
      if ( !(pInst->Flags & F_FIFO_SUPPORT) )
      {
#ifdef DEBUG
  dprintf( "par1284.sys: ECP Mode Not Supported\r\n" );
#endif
        return( 1 );
      }
      *pExtReqByte =  NEGOTIATE_ECP_MODE;
      break;

    default:
#ifdef DEBUG
  dprintf( "par1284.sys: CommModeToExtReq - Unknown Comm Mode\r\n" );
#endif
      return( 1 );
  }

  return( 0 );
}
