Beispiel #1
0
/* 1 second timer tick, poll active cm's */
VOID
CmPollFunction(VOID *a1, ADAPTER *Adapter, VOID *a3, VOID *a4)
{
    ULONG       n;

    /* if terminated, ignore */
    if ( cm_terminated )
        return;

    /* poll active cm's */
    for ( n = 0; n < MAX_CM_PER_ADAPTER ; n++)
	{
		CM	*cm = Adapter->CmTbl[n];

		if (cm)
		{
			cm__timer_tick(cm);
			if (cm->PrevState != cm->state || cm->StateChangeFlag == TRUE)
			{
				cm->PrevState = cm->state;
				cm->StateChangeFlag = FALSE;
				DoTapiStateCheck(cm);
			}
		}
	}

    /* rearm timer */
    NdisMSetTimer(&Adapter->CmPollTimer, CM_POLL_T);
}
Beispiel #2
0
/* tick process */
VOID
MtlPollFunction(VOID *a1, ADAPTER *Adapter, VOID *a3, VOID *a4)
{
	ULONG	n;

	for (n = 0; n < MAX_MTL_PER_ADAPTER; n++)
	{
		MTL	*mtl = Adapter->MtlTbl[n];

		if (mtl)
		{
			mtl__rx_tick(mtl);

			mtl__tx_tick(mtl);

			MtlRecvCompleteFunction(Adapter);

			MtlSendCompleteFunction(Adapter);
		}
	}

	NdisMSetTimer(&Adapter->MtlPollTimer, MTL_POLL_T);
}
Beispiel #3
0
VOID
NE3200ResetHandler(
    IN PVOID SystemSpecific1,
    IN PNE3200_ADAPTER Adapter,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
    )

/*++

Routine Description:

    This manages the reset/download process.  It is
    responsible for resetting the adapter, waiting for proper
    status, downloading MAC.BIN, waiting for MAC.BIN initialization,
    and optionally sending indications to the appropriate protocol.

    Since the NE3200's status registers must be polled during the
    reset/download process, this is implemented as a state machine.

Arguments:

    Adapter - The adapter whose hardware is to be initialized.

Return Value:

    None.

--*/
{

    //
    // Physical address of the MAC.BIN buffer.
    //
    NDIS_PHYSICAL_ADDRESS MacBinPhysicalAddress;

    //
    // Status from the adapter.
    //
    UCHAR Status;

    //
    // Simple iteration counter.
    //
    UINT i;

    //
    // Loop until the reset has completed.
    //
    while (Adapter->ResetState != NE3200ResetStateComplete) {

        switch (Adapter->ResetState) {

            //
            // The first stage of resetting an NE3200
            //
            case NE3200ResetStateStarting :

                //
                // Unfortunately, a hardware reset to the NE3200 does *not*
                // reset the BMIC chip.  To ensure that we read a proper status,
                // we'll clear all of the BMIC's registers.
                //
                NE3200_WRITE_SYSTEM_INTERRUPT(
                    Adapter,
                    0
                    );

                //
                // I changed this to ff since the original 0 didn't work for
                // some cases. since we don't have the specs....
                //
                NE3200_WRITE_LOCAL_DOORBELL_INTERRUPT(
                    Adapter,
                    0xff
                    );

                NE3200_WRITE_SYSTEM_DOORBELL_MASK(
                    Adapter,
                    0
                    );

                NE3200_SYNC_CLEAR_SYSTEM_DOORBELL_INTERRUPT(
                    Adapter
                    );

                for (i = 0 ; i < 16 ; i += 4 ) {

                    NE3200_WRITE_MAILBOX_ULONG(
                        Adapter,
                        i,
                        0L
                        );

                }

                //
                // Toggle the NE3200's reset line.
                //
                NE3200_WRITE_RESET(
                    Adapter,
                    NE3200_RESET_BIT_ON
                    );

                NE3200_WRITE_RESET(
                    Adapter,
                    NE3200_RESET_BIT_OFF
                    );

                //
                // Switch to the next state.
                //
                Adapter->ResetState = NE3200ResetStateResetting;
                Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_RESET;

                //
                // Loop to the next processing
                //
                break;

            //
            // Part Deux.  The actual downloading of the software.
            //
            case NE3200ResetStateResetting :

                //
                // Read the status mailbox.
                //
                NE3200_READ_MAILBOX_UCHAR(Adapter, NE3200_MAILBOX_RESET_STATUS, &Status);

                if (Status == NE3200_RESET_PASSED) {

                    //
                    // We have good reset.  Initiate the MAC.BIN download.
                    //

                    //
                    // The station address for this adapter can be forced to
                    // a specific value at initialization time.  When MAC.BIN
                    // first gets control, it reads mailbox 10.  If this mailbox
                    // contains a 0xFF, then the burned-in PROM station address
                    // is used.  If this mailbox contains any value other than
                    // 0xFF, then mailboxes 10-15 are read.  The six bytes
                    // stored in these mailboxes then become the station address.
                    //
                    // Since we have no need for this feature, we will always
                    // initialize mailbox 10 with a 0xFF.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_STATION_ID,
                        0xFF
                        );


                    //
                    // Get the MAC.BIN buffer.
                    //
                    MacBinPhysicalAddress = NE3200Globals.MacBinPhysicalAddress;

                    //
                    // Download MAC.BIN to the card.
                    //
                    NE3200_WRITE_MAILBOX_USHORT(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_LENGTH,
                        NE3200Globals.MacBinLength
                        );

                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_DOWNLOAD_MODE,
                        NE3200_MACBIN_DIRECT
                        );

                    NE3200_WRITE_MAILBOX_ULONG(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_POINTER,
                        NdisGetPhysicalAddressLow(MacBinPhysicalAddress)
                        );

                    NE3200_WRITE_MAILBOX_USHORT(
                        Adapter,
                        NE3200_MAILBOX_MACBIN_TARGET,
                        NE3200_MACBIN_TARGET_ADDRESS >> 1
                        );

                    //
                    // This next OUT "kicks" the loader into action.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_RESET_STATUS,
                        0
                        );

                    //
                    // Switch to the next state.
                    //
                    Adapter->ResetState = NE3200ResetStateDownloading;
                    Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_DOWNLOAD;

                    //
                    // Loop to the next state.
                    //

                } else if (Status == NE3200_RESET_FAILED) {

                    //
                    // Reset failure.  Notify the authorities and
                    // next of kin.
                    //
                    Adapter->ResetResult = NE3200ResetResultResetFailure;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                } else {

                    //
                    // Still waiting for results, check if we have
                    // timed out waiting.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.  Notify the death.
                        //
                        Adapter->ResetResult = NE3200ResetResultResetTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Try again later.
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);

                            return;

                        }

                    }

                }

                break;

            //
            // Part Three: The download was started.  Check for completion,
            // and reload the current station address.
            //
            case NE3200ResetStateDownloading :

                //
                // Read the download status.
                //
                NE3200_READ_MAILBOX_UCHAR(Adapter, NE3200_MAILBOX_STATUS, &Status);

                if (Status == NE3200_INITIALIZATION_PASSED) {

                    //
                    // According to documentation from Compaq, this next port
                    // write will (in a future MAC.BIN) tell MAC.BIN whether or
                    // not to handle loopback internally.  This value is currently
                    // not used, but must still be written to the port.
                    //
                    NE3200_WRITE_MAILBOX_UCHAR(
                        Adapter,
                        NE3200_MAILBOX_STATUS,
                        1
                        );

                    //
                    // Initialization is good, the card is ready.
                    //
                    NE3200StartChipAndDisableInterrupts(Adapter,
                                                        Adapter->ReceiveQueueHead
                                                       );

                    {

                        //
                        // Do the work for updating the current address
                        //

                        //
                        // This points to the public Command Block.
                        //
                        PNE3200_SUPER_COMMAND_BLOCK CommandBlock;

                        //
                        // This points to the adapter's configuration block.
                        //
                        PNE3200_CONFIGURATION_BLOCK ConfigurationBlock =
                            Adapter->ConfigurationBlock;

                        //
                        // Get a public command block.
                        //
                        NE3200AcquirePublicCommandBlock(Adapter,
                                                        &CommandBlock
                                                       );

                        Adapter->ResetHandlerCommandBlock = CommandBlock;

                        //
                        // Setup the command block.
                        //

                        CommandBlock->NextCommand = NULL;

                        CommandBlock->Hardware.State = NE3200_STATE_WAIT_FOR_ADAPTER;
                        CommandBlock->Hardware.Status = 0;
                        CommandBlock->Hardware.NextPending = NE3200_NULL;
                        CommandBlock->Hardware.CommandCode =
                            NE3200_COMMAND_CONFIGURE_82586;
                        CommandBlock->Hardware.PARAMETERS.CONFIGURE.ConfigurationBlock =
                            NdisGetPhysicalAddressLow(Adapter->ConfigurationBlockPhysical);

                        //
                        // Now that we've got the command block built,
                        // let's do it!
                        //
                        NE3200SubmitCommandBlock(Adapter, CommandBlock);

                        Adapter->ResetState = NE3200ResetStateReloadAddress;
                        Adapter->ResetTimeoutCounter = NE3200_TIMEOUT_DOWNLOAD;

                    }

                } else if (Status == NE3200_INITIALIZATION_FAILED) {

                    //
                    // Initialization failed.  Notify the wrapper.
                    //
                    Adapter->ResetResult = NE3200ResetResultInitializationFailure;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                } else {

                    //
                    // See if we've timed-out waiting for the download to
                    // complete.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.
                        //
                        Adapter->ResetResult = NE3200ResetResultInitializationTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Try again later.
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);
                            return;

                        }

                    }

                }

                break;

            //
            // Part Last: Waiting for the configuring of the adapter
            // to complete
            //
            case NE3200ResetStateReloadAddress :

                //
                // Read the command block status.
                //
                if (Adapter->ResetHandlerCommandBlock->Hardware.State ==
                    NE3200_STATE_EXECUTION_COMPLETE) {

                    //
                    // return this command block
                    //
                    NE3200RelinquishCommandBlock(Adapter,
                                                 Adapter->ResetHandlerCommandBlock
                                                );

                    //
                    // Reset is complete.  Do those indications.
                    //
                    Adapter->ResetResult = NE3200ResetResultSuccessful;
                    Adapter->ResetState = NE3200ResetStateComplete;

                    NE3200DoResetIndications(Adapter, NDIS_STATUS_SUCCESS);

                } else {

                    //
                    // See if we've timed-out.
                    //
                    Adapter->ResetTimeoutCounter--;

                    if (Adapter->ResetTimeoutCounter == 0) {

                        //
                        // We've timed-out.  Bad news.
                        //

                        //
                        // return this command block
                        //
                        NE3200RelinquishCommandBlock(Adapter,
                                                     Adapter->ResetHandlerCommandBlock
                                                    );

                        Adapter->ResetResult = NE3200ResetResultInitializationTimeout;
                        Adapter->ResetState = NE3200ResetStateComplete;

                        NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                    } else {

                        if ( Adapter->ResetTimeoutCounter ==
                                (NE3200_TIMEOUT_DOWNLOAD/2) ) {

                            //
                            // The command may have stalled, try again.
                            //
                            NE3200_WRITE_LOCAL_DOORBELL_INTERRUPT(
                                Adapter,
                                NE3200_LOCAL_DOORBELL_NEW_COMMAND
                                );

                        }

                        //
                        // For Synchronous resets, we stall.  For async,
                        // we set a timer to check later.
                        //
                        if (!Adapter->ResetAsynchronous) {

                            //
                            // Otherwise, wait and try again.
                            //
                            NdisStallExecution(10000);

                        } else{

                            //
                            // Check again later
                            //
                            NdisMSetTimer(&Adapter->ResetTimer, 100);
                            return;

                        }

                    }

                }

                break;

            default :

                //
                // Somehow, we reached an invalid state.
                //

                //
                // We'll try to salvage our way out of this.
                //
                Adapter->ResetResult = NE3200ResetResultInvalidState;
                Adapter->ResetState = NE3200ResetStateComplete;

                NE3200DoResetIndications(Adapter, NDIS_STATUS_HARD_ERRORS);

                NdisWriteErrorLogEntry(
                    Adapter->MiniportAdapterHandle,
                    NDIS_ERROR_CODE_HARDWARE_FAILURE,
                    3,
                    resetDpc,
                    NE3200_ERRMSG_BAD_STATE,
                    (ULONG)(Adapter->ResetState)
                    );

                break;
        }
Beispiel #4
0
VOID NetFlexDeferredTimer(
    IN PVOID SystemSpecific1,
    IN PACB  acb,
    IN PVOID SystemSpecific2,
    IN PVOID SystemSpecific3
)
{
    USHORT ReceivesProcessed = 0;
    USHORT sifint_reg;
    UINT   IntAve;

    //
    // Indicate that a timer has expired.
    //
    DebugPrint(3,("NF(%d) - Defered Timer Expired!\n",acb->anum));

    //
    // If we are resetting, get out...
    //
    if (acb->acb_state == AS_RESETTING)
    {
        return;
    }

    //
    // See if there are any recieves to do...
    //

    if (acb->acb_rcv_head->RCV_CSTAT & RCSTAT_COMPLETE)
    {
		//
		//	Increment the interrupt count.
		//
		acb->acb_int_count++;

        // yes, do them...
        //
        ReceivesProcessed = acb->ProcessReceiveHandler(acb);
    }

	//
	//	See if there are any transmits to do...
	//
	NetFlexProcessXmit(acb);

    //
    // Processed any receives which need IndicateReceiveComplete?
    //
    if (ReceivesProcessed)
    {
        if (acb->acb_gen_objs.media_type_in_use == NdisMedium802_5)
        {
            // Token Ring
            //
            NdisMTrIndicateReceiveComplete(acb->acb_handle);
        }
        else
        {
            // Ethernet
            //
            NdisMEthIndicateReceiveComplete(acb->acb_handle);
        }
    }


    if ( ++acb->timer_run_count >= RatioCheckCount )
    {
        acb->timer_run_count = 0;

#ifdef ALLOW_DISABLE_DYNAMIC_RATIO
        if ( EnableDynamicRatio )
        {
#endif

#ifdef NEW_DYNAMIC_RATIO

            //
            // Should we increase the ratio?
            //
            if ( acb->handled_interrupts > RaiseIntThreshold)
            {
                acb->current_run_down = 0;
                if (acb->XmitIntRatio == 1)
                {
                    if ( ++acb->current_run_up > RunThreshold )
                    {
#ifdef XMIT_INTS
                        acb->XmitIntRatio = acb->acb_maxtrans;
#endif
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run_up = 0;
                        DebugPrint(1,("NF(%d) - RcvIntRatio = %d\n",acb->anum,acb->RcvIntRatio));
                    }
                }
            }
            //
            // Or, should we decrease it?
            //
            else //if ( acb->handled_interrupts < LowerIntThreshold )
            {
                acb->current_run_up = 0;
                if (acb->XmitIntRatio != 1)

                {
                    if ( ++acb->current_run_down > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = 1;
#endif
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run_down = 0;
                        DebugPrint(1,("NF(%d) - RcvIntRatio = %d\n",acb->anum,acb->RcvIntRatio));
                    }
                }
            }

#else   //  !defined(NEW_DYNAMIC_RATIO)

            if ( acb->XmitIntRatio != 1 )
            {
                if ( acb->handled_interrupts < sw21 )
                {
                    if ( ++acb->current_run > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = 1;
#endif
                        acb->RcvIntRatio = 1;
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run = 0;
                        acb->sw24 += 3;

                        acb->cleartime = 0;
                    }
                }
                else
                {
                    acb->current_run = 0;
                }
            }
            else
            {
                if ( acb->handled_interrupts > sw24 )
                {
                    if ( ++acb->current_run > RunThreshold )
                    {

#ifdef XMIT_INTS
                        acb->XmitIntRatio = ratio;
#endif
                        acb->RcvIntRatio = ratio;
                        acb->acb_gen_objs.interrupt_ratio_changes++;
                        acb->current_run = 0;
                    }
                }
                else
                {
                    acb->current_run = 0;
                }
            }

#ifdef DYNAMIC_RATIO_HISTORY
            acb->IntHistory[acb->Hndx] = acb->handled_interrupts;
            acb->RatioHistory[acb->Hndx] = (UCHAR)acb->RcvIntRatio;

            if ( ++acb->Hndx >= 1024 )
            {
                acb->Hndx = 0;
            }
#endif
            //
            // The switchover value to turbo gets incremented each time
            // we drop to normal mode.  We reset this value every x seconds.
            // This will prevent the driver from toggling rapidly between
            // turbo <-> normal mode.
            //
            if ( ++acb->cleartime > 50 )
            {
                acb->sw24 = sw24;
                acb->cleartime = 0;
            }

#endif // !NEW_DYNAMIC_RATIO

#ifdef ALLOW_DISABLE_DYNAMIC_RATIO
        }
        else
        {

#ifdef XMIT_INTS
            acb->XmitIntRatio = ratio;
#endif
            acb->RcvIntRatio = ratio;
        }
#endif // ALLOW_DISABLE_DYNAMIC_RATIO

        acb->acb_gen_objs.interrupt_count = acb->handled_interrupts;
        acb->handled_interrupts = 0;
    }

    //
    // Set the timer...
    //
    NdisMSetTimer(&acb->DpcTimer, 10);

} // NetFlexDeferredTimer
Beispiel #5
0
/******************************************************************************
 *
 *  Name: MrvDrvReset()
 *
 *  Description:
 *      NDIS miniport reset routine.
 *
 *  Conditions for Use:
 *      Will be called by NDIS wrapper to reset the device
 *
 *  Arguments:
 *      OUT PBOOLEAN AddressingReset
 *      IN  NDIS_HANDLE MiniportAdapterContext
 *
 *  Return Value:
 *
 *  Notes:
 *
 *****************************************************************************/
NDIS_STATUS
MrvDrvReset(
    OUT PBOOLEAN AddressingReset,
    IN  NDIS_HANDLE MiniportAdapterContext
)
{

    PMRVDRV_ADAPTER Adapter;
    BOOLEAN  bDoNotify = FALSE;
    BOOLEAN                            timerStatus;
    DBGPRINT(DBG_ERROR,(L"WARNING: +MrvDrvReset() \r\n"));


    //MrvPrintFile("\nMrvDrvReset");


    Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;

    Adapter->bIsPendingReset = TRUE; // tt cetk_1
    /* tt ra fail
      Adapter->bIsPendingReset = TRUE;
    */

    // Set AddressingReset indication
    *AddressingReset = FALSE;
    // report link status change
    //ResetDisconnectStatus(Adapter);

    if ( Adapter->MediaConnectStatus == NdisMediaStateConnected)
    {
        bDoNotify = TRUE;
        DBGPRINT(DBG_LOAD, (L"set Disconnected(2)!\n"));
        Adapter->MediaConnectStatus = NdisMediaStateDisconnected;
        if(Adapter->bAvoidScanAfterConnectedforMSecs == TRUE)
        {
            NdisMCancelTimer(&Adapter->MrvDrvAvoidScanAfterConnectedTimer, &timerStatus);
            Adapter->bAvoidScanAfterConnectedforMSecs=FALSE;
        }
    }

    //tx
    CleanUpSingleTxBuffer(Adapter);

    // rx
    ResetRxPDQ(Adapter);

    // Enable interrupt
    If_EnableInterrupt(Adapter);

    if (bDoNotify == TRUE)
    {
        NdisMSetTimer(&Adapter->MrvDrvIndicateConnectStatusTimer, 10);
        Adapter->DisconnectTimerSet = TRUE;
    }
    else
    {
        Adapter->bIsPendingReset = FALSE;
    }

    return NDIS_STATUS_SUCCESS;

}
Beispiel #6
0
/******************************************************************************
 *
 *  Name: MrvDrvCheckForHang()
 *
 *  Description:
 *      NDIS miniport check for hang routine.
 *
 *  Conditions for Use:
 *      Will be called by NDIS wrapper to determine current station operation status.
 *      If the station is not responding, NDIS wrapper will call MrvDrvReset() to reset
 *      the station. Driver first check and use current HW status stored in device
 *      object to report system then update the status and send command to query HW status.
 *
 *  Arguments:
 *      IN NDIS_HANDLE MiniportAdapterContext
 *
 *  Return Value:
 *    TRUE if the NIC HW is not operating properly
 *    FALSE if the NIC HW is OK
 *
 *  Notes: According to Microsoft NDIS document, this function is normally called
 *         by NDIS wrapper approximately every 2 seconds.
 *
 *****************************************************************************/
BOOLEAN
MrvDrvCheckForHang(
    IN NDIS_HANDLE MiniportAdapterContext
)
{
    PMRVDRV_ADAPTER  Adapter;

    UCHAR            ucHostIntStatus;
    UCHAR            ucCardStatus;
    SD_API_STATUS    status;

    DBGPRINT(DBG_LOAD|DBG_WARNING,(L"INIT - Enter MrvDrvCheckForHang\n"));
    //return FALSE; //tt ra fail

    Adapter = (PMRVDRV_ADAPTER)MiniportAdapterContext;

    if ( Adapter->SurpriseRemoved )
    {
        DBGPRINT(DBG_WARNING, (L"[MRVL] in CheckForHang, card is removed, return FALSE directly\n") );
        return FALSE;
    }


    if ( Adapter->SentPacket )
    {
        Adapter->dwTxTimeoutCount ++;
        if ( Adapter->dwTxTimeoutCount > MRVDRV_TX_TIMEOUT_COUNT_THRESHOLD )
        {
            DBGPRINT( DBG_ERROR, (L"Tx timeout!\n") );
            Adapter->TxPktTimerIsSet=TRUE;
            NdisMSetTimer(&Adapter->MrvDrvTxPktTimer, 0);
            Adapter->dwTxTimeoutCount = 0;
        }
    }


    //012207
    // We won't check in deepsleep, ps mode, HostSleep and D3 state.
    // In Deep Sleep Mode no packet can be sent out
    if( !IsThisDsState(Adapter, DS_STATE_NONE) )
        return FALSE;

    if( (!IsThisHostPowerState(Adapter, HTWK_STATE_FULL_POWER)) ||
            (Adapter->psState == PS_STATE_SLEEP) ||
            (Adapter->CurPowerState != NdisDeviceStateD0)
      )
        return FALSE;
    if ( Adapter->IntWARTimeoutCount )
        AutoDeepSleepCounter(Adapter);
    else
        Adapter->AutoDsRec.timer = 0;

    //060407 flag to start auto deep sleep counter
    //This flag also used to interrupt missing.
    if(((++Adapter->IntWARTimeoutCount) & 0x1) == 0 )
        return FALSE;

    //Adapter->IntWARTimeoutCount = 0;

    if( IsThisDsState(Adapter, DS_STATE_SLEEP) )
        return FALSE;

    status = If_ReadRegister(Adapter,
                             //SD_IO_READ ,
                             1, // function 1
                             HCR_HOST_INT_STATUS_REGISTER,
                             FALSE,
                             &ucHostIntStatus,
                             sizeof(ucHostIntStatus));

    if (!SD_API_SUCCESS(status))
    {
        DBGPRINT(DBG_ERROR, (L"Read error in CheckForHang()\r\n") );
        return FALSE;
    }

    if( ucHostIntStatus & (UPLOAD_HOST_INT_STATUS_RDY | DOWNLOAD_HOST_INT_STATUS_RDY) )
    {

        EnterCriticalSection(&Adapter->IntCriticalSection);
        Adapter->ucGHostIntStatus |= ucHostIntStatus;
        LeaveCriticalSection(&Adapter->IntCriticalSection);
        ucCardStatus = ~ucHostIntStatus;
        ucCardStatus &= 0x1f;
        status = If_WriteRegister(Adapter,
                                  //SD_IO_WRITE,
                                  1,
                                  HCR_HOST_INT_STATUS_REGISTER,
                                  FALSE,
                                  &ucCardStatus,   // reg
                                  sizeof(ucCardStatus));

        if (!SD_API_SUCCESS(status))
        {
            DBGPRINT(DBG_ISR,(L"Unable to clear Host interrupt status register\r\n"));
            return FALSE;
        }

        SetEvent(Adapter->hControllerInterruptEvent);
    }



    return FALSE;

}