예제 #1
0
// For PurgeComm. The PDD only handle The clean up the hardware.
BOOL CSerialPDD::PurgeComm( DWORD fdwAction)
{
    if (fdwAction & PURGE_RXCLEAR ) {
        CancelReceive();
    }
    if (fdwAction & PURGE_TXCLEAR ) {
        CancelXmit();
    }
    return TRUE;
}
예제 #2
0
BOOL CommonCmdHandler (
   IN  void                         *pvCmdBuf,          // Address of buffer contaiing command packet
   IN  size_t                       tCmdSize,           // Size of command packet
   OUT void                         *pvRspBuf,          // Address of buffer for response packet
   IN  size_t                       tRspSize            // Expected size of response packet
   )
{
   BOOL           bSucceeded = FALSE;     // Success indicator
   DWORD          dwCount;                // Count returned by WriteFile()/ReadFile()
   DWORD          dwStatus;               // Buffer for status codes
   int            iRetries;               // Retry counter

   // Obtain (thread) exclusive access to resources

   switch( WaitForSingleObject( hMutex, INFINITE ) )
   {
   case WAIT_ABANDONED:
   case WAIT_OBJECT_0:

      break;

   default:

      return( FALSE );
   }

   // Attach to HECI driver if we aren't already

   if( !bAttached && !AttachDriver() )
   {
      // Couldn't attach the driver...

      dwStatus = GetLastError();
   }
   else
   {
      // Attached; now have info to verify max command/response size...

      if( (tCmdSize > stProperties.minRxBufferSize) || (tRspSize > stProperties.minRxBufferSize) )
         dwStatus = ERROR_BAD_LENGTH;

      // Length ok, attempt communication...

      else
      {
         // Support retries during communication...

         for( iRetries = 0; iRetries < RETRY_COUNT; iRetries++ )
         {
            bReceivePosted = FALSE;

            // Post Receive Buffer if a response expected

            if( (tRspSize == 0) || PostReceive( pvBuffer, stProperties.minRxBufferSize ) )
            {
               // Send Command Packet

               if( DoSend( pvCmdBuf, tCmdSize ) )
               {
                  // If no response is desired, we're done!

                  if( tRspSize == 0 )
                  {
                     bSucceeded = TRUE;
                     break;
                  }

                  // Receive and process Response Packet

                  dwCount = CompleteReceive( TRUE );

                  if( dwCount )
                  {
                     // Have a response; verify it

                     if( (dwCount != tRspSize) && (CheckRspSuccess(pvBuffer)) )
                     {
                        // Data received is larger/smaller than expected

                        dwStatus = ERROR_BAD_LENGTH;
                     }
                     else
                     {
                        // Data received is right length (or QST rejected command)
                        // Place info available into caller's buffer

                        memcpy( pvRspBuf, pvBuffer, __min(dwCount, tRspSize) );
                        bSucceeded = TRUE;
                     }

                     // We're done!

                     break;
                  }
               }

               // Remember ccode from first failed operation...

               if( iRetries == 0 )
                  dwStatus = GetLastError();

               // Won't need the buffer we posted...

               if( tRspSize != 0 )
                  CancelReceive();
            }

            // A retry is necessary; recreate attachment to driver in case lost due to PM transition, etc.

            DetachDriver();

            if( !AttachDriver() )
               break;                           // Can't reattach, time to give up

            if( !AsyncDelay( RETRY_DELAY ) )    // Delay retry to give driver a break
               break;
         }
      }
   }

   ReleaseMutex( hMutex );

   if( !bSucceeded )
      SetLastError( dwStatus );       // Indicate why we're failing

   return (bSucceeded);
}