📄 reset.c
字号:
/*++
Copyright (c) 2000 Microsoft Corporation. All rights reserved.
File: reset.c
Developed for Toshiba by Elisa Research Inc., CA
http://www.elisaresearch.com
(510) 770-4920
Abstract:
Author:
A. Wang
Environment:
Kernel mode
Revision History:
01/07/97 awang Initial of Toshiba ATM 155 Device Driver.
--*/
#include "precomp.h"
#pragma hdrstop
#define MODULE_NUMBER MODULE_RESET
UCHAR
tbAtm155CheckConnectionStatus(
IN PADAPTER_BLOCK pAdapter
)
/*++
Routine Description:
This routine check connection of Meteor and set LED accordingly.
1. turn ON/OFF of Led LED_LNKUP by check PHY chip.
2. trun ON/OFF of Led LED_TXRX by checking Meteor Tx/Rx
report queue registers.
Arguments:
pAdapter - Pointer to the adapter block.
Return Value:
NDIS_STATUS_FAILURE if the adapter is not supported.
NDIS_STATUS_SUCCESS otherwise.
--*/
{
BOOLEAN fLinkUp = FALSE;
PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
UCHAR LedValue = pHwInfo->LedVal;
TX_REPORT_PTR TxReportPtrReg;
RX_REPORT_PTR RxReportPtrReg;
PXMIT_DMA_QUEUE pXmitDmaQ = &pHwInfo->SarInfo->XmitDmaQ;
do {
//
// Check if SAR is receiving/transmitting data.
// if yes, turn on the LED, otherwise, turn the LED off.
//
TBATM155_READ_PORT(
&pHwInfo->TbAtm155_SAR->Tx_Report_Ptr,
&TxReportPtrReg.reg);
TxReportPtrReg.reg = TxReportPtrReg.reg & ~0x3;
TBATM155_READ_PORT(
&pHwInfo->TbAtm155_SAR->Rx_Report_Ptr,
&RxReportPtrReg.reg);
RxReportPtrReg.reg = RxReportPtrReg.reg & ~0x3;
#if TB_CHK4HANG
if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_EXPECT_TXIOC))
{
ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_EXPECT_TXIOC);
if (TxReportPtrReg.reg == pHwInfo->PrevTxReportPa)
{
ADAPTER_SET_FLAG(pAdapter, fADAPTER_HARDWARE_FAILURE);
#if DBG
DbgPrint("TBATM155: Adapter %p, Flags %x: tx hang!\n",
pAdapter, pAdapter->Flags);
#endif // DBG
}
}
else
{
if ((pXmitDmaQ->RemainingTransmitSlots != pXmitDmaQ->MaximumTransmitSlots) &&
(TxReportPtrReg.reg == pHwInfo->PrevTxReportPa))
{
ADAPTER_SET_FLAG(pAdapter, fADAPTER_EXPECT_TXIOC);
}
}
#endif // end of TB_CHK4HANG
if ((TxReportPtrReg.reg != pHwInfo->PrevTxReportPa) ||
(RxReportPtrReg.reg != pHwInfo->PrevRxReportPa))
{
LedValue |= LED_TXRX_ON_GREEN;
//
// Save the current pointer of report queues got from SAR.
//
pHwInfo->PrevTxReportPa = TxReportPtrReg.reg;
pHwInfo->PrevRxReportPa = RxReportPtrReg.reg;
}
else
{
LedValue &= ~LED_TXRX_ON_GREEN;
}
//
// Check if PHY is still link up the remote device or not.
// if PHY is linked up with remote device, turn on the LED,
// otherwise, turn the LED off.
//
// For PLC2, handle in PLC2 interrupt service routine.
//
if (pHwInfo->fAdapterHw & TBATM155_PHY_SUNI_LITE)
{
fLinkUp = tbAtm155CheckSuniLiteLinkUp(pAdapter);
LedValue &= ~(LED_LNKUP_ON_GREEN | LED_LNKUP_ON_ORANGE);
if (fLinkUp == TRUE)
{
LedValue |= LED_LNKUP_ON_GREEN;
}
}
if (pHwInfo->LedVal != LedValue)
{
TBATM155_PH_WRITE_DEV(
pAdapter,
LED_OFFSET,
LedValue,
&Status);
}
} while (FALSE);
return(LedValue);
}
BOOLEAN
TbAtm155CheckForHang(
IN NDIS_HANDLE MiniportAdapterContext
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PADAPTER_BLOCK pAdapter = (PADAPTER_BLOCK)MiniportAdapterContext;
BOOLEAN fReset = FALSE;
PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
UCHAR LedValue;
NdisDprAcquireSpinLock(&pAdapter->lock);
//
// Is the adapter currently resetting or shutting down?
//
if (!ADAPTER_TEST_FLAG(pAdapter, fADAPTER_RESET_IN_PROGRESS) &&
!ADAPTER_TEST_FLAG(pAdapter, fADAPTER_SHUTTING_DOWN))
{
dbgDumpActivateVcInfo(pAdapter);
//
// Check LEDs based Meteor status.
//
// this is the implementation of the NDIS 4 feature for detecting
// link status change. It effectively checks every two seconds
// for link.
//
LedValue = tbAtm155CheckConnectionStatus(pAdapter);
if ((pHwInfo->LedVal & LED_LNKUP_ALL_BITS) != (LedValue & LED_LNKUP_ALL_BITS))
{
//
// Linkup status has been changed. Handle it.
//
if ((LedValue & LED_LNKUP_ON_GREEN) &&
(NdisMediaStateConnected != pAdapter->MediaConnectStatus))
{
pAdapter->MediaConnectStatus = NdisMediaStateConnected;
NdisDprReleaseSpinLock(&pAdapter->lock);
NdisMIndicateStatus(
pAdapter->MiniportAdapterHandle,
NDIS_STATUS_MEDIA_CONNECT,
(PVOID)0,
0);
// NOTE:
// have to indicate status complete every time you
// indicate status
NdisMIndicateStatusComplete(pAdapter->MiniportAdapterHandle);
NdisDprAcquireSpinLock(&pAdapter->lock);
DBGPRINT(DBG_COMP_PLC2, DBG_LEVEL_INFO, ("NDIS_STATUS_MEDIA_CONNECT\n"));
}
else if (!(LedValue & LED_LNKUP_ON_GREEN) &&
(NdisMediaStateDisconnected != pAdapter->MediaConnectStatus))
{
pAdapter->MediaConnectStatus = NdisMediaStateDisconnected;
NdisDprReleaseSpinLock(&pAdapter->lock);
NdisMIndicateStatus(
pAdapter->MiniportAdapterHandle,
NDIS_STATUS_MEDIA_DISCONNECT,
(PVOID)0,
0);
// NOTE:
// have to indicate status complete every time you
// indicate status
NdisMIndicateStatusComplete(pAdapter->MiniportAdapterHandle);
NdisDprAcquireSpinLock(&pAdapter->lock);
DBGPRINT(DBG_COMP_PLC2, DBG_LEVEL_INFO, ("NDIS_STATUS_MEDIA_DISCONNECT\n"));
}
} // end of if
NdisDprAcquireSpinLock(&pHwInfo->Lock);
pHwInfo->LedVal = LedValue; // save the current value.
NdisDprReleaseSpinLock(&pHwInfo->Lock);
//
// Was there a hardware failure?
//
if (ADAPTER_TEST_FLAG(pAdapter, fADAPTER_HARDWARE_FAILURE))
{
fReset = TRUE;
}
}
NdisDprReleaseSpinLock(&pAdapter->lock);
return(fReset);
}
VOID
tbAtm155CompletePacketQueue(
IN PPACKET_QUEUE PacketQ
)
/*++
Routine Description:
This routine will complete the packets on the given queue back to their
respective owners. This is done in the case of a reset so the status that
the packets are completed with is NDIS_STATUS_REQUEST_ABORTED.
Arguments:
PacketQ - Pointer to the queue of packets to complete.
Return Value:
None.
--*/
{
PNDIS_PACKET Packet;
PVC_BLOCK pVc;
PPACKET_RESERVED Reserved;
PXMIT_SEG_INFO pXmitSegInfo;
PXMIT_DMA_QUEUE pXmitDmaQ;
// DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
// ("==>tbAtm155CompletePacketQueue\n"));
while (!PACKET_QUEUE_EMPTY(PacketQ))
{
//
// Remove the packet from the queue.
//
RemovePacketFromHeadDpc(PacketQ, &Packet);
dbgLogSendPacket(
PACKET_RESERVED_FROM_PACKET(Packet)->pVc->DebugInfo,
PacketQ->Head,
0,
104,
'erQD');
//
// Get a local copy of the vc that this packet belongs to.
//
Reserved = PACKET_RESERVED_FROM_PACKET(Packet);
pVc = Reserved->pVc;
pXmitSegInfo = pVc->XmitSegInfo;
pXmitDmaQ = &pVc->Sar->XmitDmaQ;
//
// complete the packet back to the client.
//
dbgLogSendPacket(
pVc->DebugInfo,
Packet,
0,
0,
' tsr');
NdisMCoSendComplete(
NDIS_STATUS_REQUEST_ABORTED,
pVc->NdisVcHandle,
Packet);
DBGPRINT(DBG_COMP_TXIOC, DBG_LEVEL_ERR,
("tbAtm155CompletePacketQueue: %x (NDIS_STATUS_REQUEST_ABORTED)\n", Packet));
//
// Remove the packet reference from the VC.
//
NdisAcquireSpinLock(&pVc->lock);
tbAtm155DereferenceVc(pVc);
NdisReleaseSpinLock(&pVc->lock);
}
// DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_INFO,
// ("<==tbAtm155CompletePacketQueue\n"));
}
VOID
tbAtm155ProcessReset(
IN PADAPTER_BLOCK pAdapter
)
/*++
Routine Description:
This routine will do the actual resetting of the adapter.
All of the interrupts are disabled before getting into this routine.
Arguments:
pAdapter - Pointer to the adapter block.
Return Value:
--*/
{
PHARDWARE_INFO pHwInfo = pAdapter->HardwareInfo;
PSAR_INFO pSar = pHwInfo->SarInfo;
PXMIT_DMA_QUEUE pXmitDmaQ = &pSar->XmitDmaQ;
PRECV_DMA_QUEUE pRecvDmaQ = &pSar->RecvDmaQ;
PLIST_ENTRY Link;
PLIST_ENTRY NextLink;
PVC_BLOCK pVc;
PXMIT_SEG_INFO pXmitSegInfo;
NDIS_STATUS Status;
PRECV_BUFFER_QUEUE pSegCompleting;
TB155PCISAR_CNTRL1 regControl1;
DBGPRINT(DBG_COMP_HALT, DBG_LEVEL_INFO,
("==>tbAtm155ProcessReset\n"));
do {
//
// Don't go through complete reset if there is no hardware
// failure detected.
//
if (!ADAPTER_TEST_FLAG(pAdapter, fADAPTER_HARDWARE_FAILURE))
{
//
// Walk the VC's that are opened on this adapter and mark them as
// resetting. Also check to see if any VCs need to be deactivated.
//
Link = pAdapter->ActiveVcList.Flink;
while (Link != &pAdapter->ActiveVcList)
{
NextLink = Link->Flink;
//
// Get a pointer to the VC that this link represents.
//
pVc = CONTAINING_RECORD(Link, VC_BLOCK, Link);
//
// Get the next.
//
Link = Link->Flink;
NdisAcquireSpinLock(&pVc->lock);
VC_CLEAR_FLAG(pVc, fVC_RESET_IN_PROGRESS);
//
// Check to see if we need to deactivate the VC.
//
if ((1 == pVc->References) && VC_TEST_FLAG(pVc, fVC_DEACTIVATING))
{
NdisReleaseSpinLock(&pVc->lock);
//
// Finish VC deactivation.
//
TbAtm155DeactivateVcComplete(pVc->Adapter, pVc);
}
else
{
NdisReleaseSpinLock(&pVc->lock);
}
Link = NextLink;
}
NdisAcquireSpinLock(&pAdapter->lock);
ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_RESET_IN_PROGRESS);
ADAPTER_CLEAR_FLAG(pAdapter, fADAPTER_HARDWARE_FAILURE);
NdisReleaseSpinLock(&pAdapter->lock);
break;
}
//
// Detected hardware failure, let's reset hardware.
//
tbAtm155SoftresetNIC(pHwInfo);
//
// Complete any packets that are either waiting on the transmit
// complete for the segment or waiting for segment resources.
//
for (Link = pAdapter->ActiveVcList.Flink;
Link != &pAdapter->ActiveVcList;
Link = Link->Flink)
{
//
// Get a pointer to the VC that this link represents.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -