⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reset.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

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 + -