/****************************************************************************** * SteMiniportReset() * * NDIS Miniport エントリポイント * 以下の条件のとき NIC がハングしていると判断しドライバーのソフトステート * をリセットするために呼ばれる。 * * 1) SteMiniportCheckForHang() が TRUE を返してきた * 2) 未処理の送信パケットを検出した(シリアライズドドライバのみ) * 3) 一定時間内に完了することができなかった未処理の要求があった * * この関数の中では以下を行う * * 1) キューイングされている送信パケットの処理をやめ、NDIS_STATUS_REQUEST_ABORTED を返す。 * 2) 上位に通知した全てのパケットがリターンしてきたか確認する。 * 3) 上記2つに問題がありリセット処理をただちに完了できない場合、ResetTimer をセットし、 * NDIS_STATUS_PENDING を返す。 * * 引数: * * AddressingReset : マルチキャストや、MAC アドレス、lookahead サイズ * に変更があった場合にはここを TRUE にしなければならない。 * * MiniportAdapterContext : STE_ADAPTER 構造体のポインタ * * * 返り値: * * NDIS_STATUS * **************************************************************************/ NDIS_STATUS SteMiniportReset( OUT PBOOLEAN AddressingReset, IN NDIS_HANDLE MiniportAdapterContext ) { NDIS_STATUS Status; STE_ADAPTER *Adapter; NDIS_PACKET *Packet = NULL; DEBUG_PRINT0(3, "SteMiniportReset called\n"); Adapter = (STE_ADAPTER *)MiniportAdapterContext; // MAC アドレス、マルチキャストアドレスの変更はない!?ときめつけて FALSE を返す *AddressingReset = FALSE; Status = NDIS_STATUS_REQUEST_ABORTED; // 送信キューに入っているパケットを処理する while (SteGetQueue(&Adapter->SendQueue, &Packet) == NDIS_STATUS_SUCCESS) { NdisMSendComplete( Adapter->MiniportAdapterHandle, //IN NDIS_HANDLE Packet, //IN PNDIS_PACKET Status //IN NDIS_STATUS ); } // 受信キューに入っているパケットを処理する while (SteGetQueue(&Adapter->RecvQueue, &Packet) == NDIS_STATUS_SUCCESS) { SteFreeRecvPacket(Adapter, Packet); } // これが終われば、全ての受信パケットがフリーされているはず。 // 後は上位プロトコルに通知済みでまだ戻ってきていないパケットがあるかどうかを // 確認する。 if (Adapter->RecvIndicatedPackets > 0) { // まだ戻ってきてないパケットがあるようだ。 // リセットタイマーをセットして、後ほど SteResetTimerFunc() から // NdisMResetComplete() を呼んでリセットを完了することにする。 NdisSetTimer(&Adapter->ResetTimer, 300); Status = NDIS_STATUS_PENDING; } else { // リセット操作完了! Status = NDIS_STATUS_SUCCESS; } return(Status); }
/****************************************************** Required NDIS procedure Allocates and initializes adapter context Finally sets send and receive to Enabled state and reports connect Returns: NDIS_STATUS SUCCESS or some error code *******************************************************/ static NDIS_STATUS ParaNdis5_Initialize(OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext) { NDIS_STATUS status = NDIS_STATUS_UNSUPPORTED_MEDIA; PARANDIS_ADAPTER *pContext = NULL; UINT i; for(i = 0; i < MediumArraySize; ++i) { if(MediumArray[i] == NdisMedium802_3) { *SelectedMediumIndex = i; status = NDIS_STATUS_SUCCESS; break; } } if (status == NDIS_STATUS_SUCCESS) { pContext = (PARANDIS_ADAPTER *)ParaNdis_AllocateMemory(NULL, sizeof(PARANDIS_ADAPTER)); if (!pContext) { status = NDIS_STATUS_RESOURCES; } } if (status == NDIS_STATUS_SUCCESS) { PVOID pResourceList = &status; UINT uSize = 0; NdisZeroMemory(pContext, sizeof(PARANDIS_ADAPTER)); pContext->ulUniqueID = InterlockedIncrement(&gID); pContext->DriverHandle = DriverHandle; pContext->MiniportHandle = MiniportAdapterHandle; pContext->WrapperConfigurationHandle = WrapperConfigurationContext; NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize); if (uSize > 0) pResourceList = ParaNdis_AllocateMemory(MiniportAdapterHandle, uSize); else pResourceList = NULL; if (!pResourceList) status = uSize > 0 ? NDIS_STATUS_RESOURCES : NDIS_STATUS_FAILURE; else { ULONG attributes; attributes = NDIS_ATTRIBUTE_DESERIALIZE | NDIS_ATTRIBUTE_BUS_MASTER; // in XP SP2, if this flag is NOT set, the NDIS halts miniport // upon transition to S1..S4. // it seems that XP SP3 ignores it and always sends SET_POWER to D3 #ifndef NO_XP_POWER_MANAGEMENT attributes |= NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND; #endif #ifdef NDIS50_MINIPORT //TODO: this is wrong, I think // this API is for XP and // it should be used only if you never need virtual addresses of sent buffers // so I comment it out //attributes |= NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS; #endif NdisMSetAttributesEx( MiniportAdapterHandle, pContext, 0, attributes, NdisInterfacePci); NdisMQueryAdapterResources(&status, WrapperConfigurationContext, pResourceList, &uSize); status = ParaNdis_InitializeContext(pContext, (PNDIS_RESOURCE_LIST)pResourceList); NdisFreeMemory(pResourceList, 0, 0); } } if (status == NDIS_STATUS_SUCCESS) { status = ParaNdis_FinishInitialization(pContext); if (status == NDIS_STATUS_SUCCESS) { #ifdef NDIS50_MINIPORT NdisMRegisterAdapterShutdownHandler( MiniportAdapterHandle, pContext, (ADAPTER_SHUTDOWN_HANDLER)ParaNdis5_Shutdown); #endif //NDIS50_MINIPORT ParaNdis_DebugRegisterMiniport(pContext, TRUE); ParaNdis_IndicateConnect(pContext, FALSE, TRUE); ParaNdis5_StopSend(pContext, FALSE, NULL); ParaNdis5_StopReceive(pContext, FALSE, NULL); if (!pContext->ulMilliesToConnect) { ParaNdis_ReportLinkStatus(pContext, FALSE); } else { NdisSetTimer(&pContext->ConnectTimer, pContext->ulMilliesToConnect); } } else { ParaNdis_CleanupContext(pContext); } } if (status != NDIS_STATUS_SUCCESS && pContext) { NdisFreeMemory(pContext, 0, 0); } DEBUG_EXIT_STATUS(0, status); return status; }
NDIS_STATUS LoopSend( IN NDIS_HANDLE MacBindingHandle, IN PNDIS_PACKET Packet ) { PLOOP_ADAPTER Adapter = PLOOP_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle); PLOOP_OPEN Open = PLOOP_OPEN_FROM_BINDING_HANDLE(MacBindingHandle); UINT PacketLength; NDIS_STATUS StatusToReturn; DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, (" --> LoopSend\n")); // // Verify that the packet is correctly sized for the medium // NdisQueryPacket( Packet, NULL, NULL, NULL, &PacketLength ); if ((PacketLength < Adapter->MediumMinPacketLen) || (PacketLength > Adapter->MediumMaxPacketLen)) { return NDIS_STATUS_INVALID_PACKET; } NdisAcquireSpinLock(&Adapter->Lock); Adapter->References++; if (!Adapter->ResetInProgress) { if (!Open->BindingClosing) { PLOOP_PACKET_RESERVED Reserved = PLOOP_RESERVED_FROM_PACKET(Packet); BOOLEAN LoopIt=FALSE; PNDIS_BUFFER FirstBuffer; PVOID BufferVirtualAddress; UINT BufferLength; Open->References++; Reserved->Next = NULL; Reserved->MacBindingHandle = MacBindingHandle; Reserved->PacketLength = PacketLength; Reserved->HeaderLength = Adapter->MediumMacHeaderLen; NdisReleaseSpinLock(&Adapter->Lock); NdisQueryPacket( Packet, NULL, NULL, &FirstBuffer, NULL ); NdisQueryBuffer( FirstBuffer, &BufferVirtualAddress, &BufferLength ); NdisAcquireSpinLock(&Adapter->Lock); switch (Adapter->Medium) { case NdisMedium802_3: case NdisMediumDix: DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Ethernet Dest Addr: %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", *((PUCHAR)BufferVirtualAddress),*((PUCHAR)BufferVirtualAddress+1), *((PUCHAR)BufferVirtualAddress+2),*((PUCHAR)BufferVirtualAddress+3), *((PUCHAR)BufferVirtualAddress+4),*((PUCHAR)BufferVirtualAddress+5))); LoopIt = EthShouldAddressLoopBack( Adapter->Filter.Eth, BufferVirtualAddress ); break; case NdisMedium802_5: // check for source routing info and adjust header if (*((PUCHAR)BufferVirtualAddress+8) & 0x80) Reserved->HeaderLength += (*((PUCHAR)BufferVirtualAddress+14) & 0x1f); DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("TokenRing Dest Addr: %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n", *((PUCHAR)BufferVirtualAddress+2),*((PUCHAR)BufferVirtualAddress+3), *((PUCHAR)BufferVirtualAddress+4),*((PUCHAR)BufferVirtualAddress+5), *((PUCHAR)BufferVirtualAddress+6),*((PUCHAR)BufferVirtualAddress+7))); LoopIt = TrShouldAddressLoopBack( Adapter->Filter.Tr, (PCHAR)BufferVirtualAddress+2, Adapter->CurrentAddress ); if (!LoopIt) { // check if it's directed at ourselves TR_COMPARE_NETWORK_ADDRESSES_EQ( (PUCHAR)BufferVirtualAddress+2, (PUCHAR)(Adapter->Filter.Tr)->AdapterAddress, &BufferLength ); if (!BufferLength) LoopIt = TRUE; } break; case NdisMediumFddi: // check the address length bit and adjust the header length // if it is short. by default we assume a long address if (!(*((PUCHAR)BufferVirtualAddress) & 0x40)) { Reserved->HeaderLength = 2*FDDI_LENGTH_OF_SHORT_ADDRESS+1; BufferLength = FDDI_LENGTH_OF_SHORT_ADDRESS; } else BufferLength = FDDI_LENGTH_OF_LONG_ADDRESS; // hmmm... the DBGPRINT macro doesn't work too well to // dump out dest addr of varying lengths DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Fddi Dest Addr: L(%d) %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",BufferLength, *((PUCHAR)BufferVirtualAddress+1),*((PUCHAR)BufferVirtualAddress+2), *((PUCHAR)BufferVirtualAddress+3),*((PUCHAR)BufferVirtualAddress+4), *((PUCHAR)BufferVirtualAddress+5),*((PUCHAR)BufferVirtualAddress+6))); LoopIt = FddiShouldAddressLoopBack( Adapter->Filter.Fddi, (PCHAR)BufferVirtualAddress+1, BufferLength ); break; case NdisMediumWan: case NdisMediumLocalTalk: DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("LocalTalk Dest Addr: %.2x\n",((PUCHAR)BufferVirtualAddress)[0])); if ((((PUCHAR)BufferVirtualAddress)[1] == Adapter->CurrentAddress[0]) || LOOP_LT_IS_BROADCAST(((PUCHAR)BufferVirtualAddress)[0])) LoopIt = TRUE; else LoopIt = FALSE; break; case NdisMediumArcnet878_2: DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Arcnet Dest Addr: %.2x\n",((PUCHAR)BufferVirtualAddress)[1])); if ((((PUCHAR)BufferVirtualAddress)[1] == Adapter->CurrentAddress[0]) || LOOP_ARC_IS_BROADCAST(((PUCHAR)BufferVirtualAddress)[1])) LoopIt = TRUE; else LoopIt = FALSE; break; default: // we should never get here... ASSERT(FALSE); break; } DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_INFO, ("LoopIt = %c\n",(LoopIt)?'Y':'N')); if (LoopIt) { DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO, ("Queueing packet %lx for loopback\n",Packet)); if (Adapter->LastLoopback == NULL) Adapter->Loopback = Packet; else PLOOP_RESERVED_FROM_PACKET(Adapter->LastLoopback)->Next = Packet; Adapter->LastLoopback = Packet; StatusToReturn = NDIS_STATUS_PENDING; } else { // // Since we're not looping this packet back, there's // nothing for us to do. just return success and make // like the packet was successfully sent out // Adapter->GeneralMandatory[GM_TRANSMIT_GOOD]++; Open->References--; StatusToReturn = NDIS_STATUS_SUCCESS; } } else StatusToReturn = NDIS_STATUS_CLOSING; } else StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS; Adapter->References--; // might not queue a packet, but setting the timer anyway ensures // we don't miss any packets sitting in the queue if (!Adapter->TimerSet) { Adapter->TimerSet = TRUE; NdisReleaseSpinLock(&Adapter->Lock); NdisSetTimer( &Adapter->LoopTimer, 25 ); } else NdisReleaseSpinLock(&Adapter->Lock); return StatusToReturn; }
STATIC VOID LoopProcessLoopback( PLOOP_ADAPTER Adapter ) { PNDIS_PACKET LoopPacket; PLOOP_PACKET_RESERVED Reserved; PLOOP_OPEN Open; UINT BufferLength; UINT IndicateLen; UINT AddressType; UCHAR DestAddress[FDDI_LENGTH_OF_LONG_ADDRESS]; DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, (" --> LoopProcessLoopback\n")); while ((Adapter->Loopback != NULL) && !Adapter->ResetInProgress) { // dequeue the packet at the head of the loopback queue LoopPacket = Adapter->Loopback; Adapter->CurrentLoopback = LoopPacket; Reserved = PLOOP_RESERVED_FROM_PACKET(LoopPacket); Adapter->Loopback = Reserved->Next; if (Adapter->Loopback == NULL) Adapter->LastLoopback = NULL; DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("Dequeued packet %lx\n",LoopPacket)); IndicateLen = (Reserved->PacketLength > Adapter->MaxLookAhead) ? Adapter->MaxLookAhead : Reserved->PacketLength; Adapter->GeneralMandatory[GM_RECEIVE_GOOD]++; NdisDprReleaseSpinLock(&Adapter->Lock); LoopCopyFromPacketToBuffer( LoopPacket, 0, IndicateLen, Adapter->LoopBuffer, &BufferLength ); // indicate the packet as appropriate switch (Adapter->Medium) { case NdisMedium802_3: case NdisMediumDix: EthFilterIndicateReceive( Adapter->Filter.Eth, (NDIS_HANDLE)NULL, (PCHAR)Adapter->LoopBuffer, Adapter->LoopBuffer, Reserved->HeaderLength, (Adapter->LoopBuffer)+(Reserved->HeaderLength), IndicateLen-(Reserved->HeaderLength), (Reserved->PacketLength)-(Reserved->HeaderLength) ); break; case NdisMedium802_5: TrFilterIndicateReceive( Adapter->Filter.Tr, (NDIS_HANDLE)NULL, Adapter->LoopBuffer, Reserved->HeaderLength, (Adapter->LoopBuffer)+(Reserved->HeaderLength), IndicateLen-(Reserved->HeaderLength), (Reserved->PacketLength)-(Reserved->HeaderLength) ); break; case NdisMediumFddi: // just copy over the long address size, even though it may // be a short address NdisMoveMemory( DestAddress, Adapter->LoopBuffer+1, FDDI_LENGTH_OF_LONG_ADDRESS ); FddiFilterIndicateReceive( Adapter->Filter.Fddi, (NDIS_HANDLE)NULL, (PCHAR)DestAddress, ((*(Adapter->LoopBuffer) & 0x40) ? FDDI_LENGTH_OF_LONG_ADDRESS : FDDI_LENGTH_OF_SHORT_ADDRESS), Adapter->LoopBuffer, Reserved->HeaderLength, (Adapter->LoopBuffer)+(Reserved->HeaderLength), IndicateLen-(Reserved->HeaderLength), (Reserved->PacketLength)-(Reserved->HeaderLength) ); break; case NdisMediumLocalTalk: if (LOOP_LT_IS_BROADCAST(Adapter->LoopBuffer[0])) AddressType = NDIS_PACKET_TYPE_BROADCAST; else AddressType = NDIS_PACKET_TYPE_DIRECTED; LtIndicateReceive( Adapter, AddressType, Adapter->LoopBuffer, Reserved->HeaderLength, (Adapter->LoopBuffer)+(Reserved->HeaderLength), IndicateLen-(Reserved->HeaderLength), (Reserved->PacketLength)-(Reserved->HeaderLength) ); break; case NdisMediumArcnet878_2: if (LOOP_ARC_IS_BROADCAST(Adapter->LoopBuffer[1])) AddressType = NDIS_PACKET_TYPE_BROADCAST; else AddressType = NDIS_PACKET_TYPE_DIRECTED; LtIndicateReceive( Adapter, AddressType, Adapter->LoopBuffer, Reserved->HeaderLength, (Adapter->LoopBuffer)+(Reserved->HeaderLength), IndicateLen-(Reserved->HeaderLength), (Reserved->PacketLength)-(Reserved->HeaderLength) ); break; default: ASSERT(FALSE); // should never get here break; } // complete the send Open = PLOOP_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle); DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("Completing Send for binding %lx\n",Open)); NdisCompleteSend( Open->NdisBindingContext, LoopPacket, NDIS_STATUS_SUCCESS ); NdisDprAcquireSpinLock(&Adapter->Lock); Adapter->GeneralMandatory[GM_TRANSMIT_GOOD]++; // remove reference for send just completed Open->References--; } // rearm timer if there are still packets to loop back and the timer is // not already ticking away if (Adapter->Loopback != NULL && !Adapter->TimerSet) { DBGPRINT(DBG_COMP_DPC, DBG_LEVEL_INFO, ("More packets to loopback\n")); Adapter->TimerSet = TRUE; NdisDprReleaseSpinLock(&Adapter->Lock); NdisSetTimer( &Adapter->LoopTimer, 25 ); NdisDprAcquireSpinLock(&Adapter->Lock); } // issue indicate receive completes as necessary switch (Adapter->Medium) { case NdisMedium802_3: case NdisMediumDix: NdisDprReleaseSpinLock(&Adapter->Lock); EthFilterIndicateReceiveComplete(Adapter->Filter.Eth); NdisDprAcquireSpinLock(&Adapter->Lock); break; case NdisMedium802_5: NdisDprReleaseSpinLock(&Adapter->Lock); TrFilterIndicateReceiveComplete(Adapter->Filter.Tr); NdisDprAcquireSpinLock(&Adapter->Lock); break; case NdisMediumFddi: NdisDprReleaseSpinLock(&Adapter->Lock); FddiFilterIndicateReceiveComplete(Adapter->Filter.Fddi); NdisDprAcquireSpinLock(&Adapter->Lock); break; case NdisMediumLocalTalk: case NdisMediumArcnet878_2: NdisDprReleaseSpinLock(&Adapter->Lock); LtIndicateReceiveComplete(Adapter); NdisDprAcquireSpinLock(&Adapter->Lock); break; default: ASSERT(FALSE); break; } }
NDIS_STATUS LtInitRegisterAdapter( IN NDIS_HANDLE LtMacHandle, IN NDIS_HANDLE WrapperConfigurationContext, IN PNDIS_STRING AdapterName, IN NDIS_INTERFACE_TYPE BusType, IN UCHAR SuggestedNodeId, IN UINT IoBaseAddress, IN UINT MaxAdapters, IN NDIS_STATUS ConfigError ) /*++ Routine Description: This routine (and its interface) are not portable. They are defined by the OS, the architecture, and the particular Lt implementation. This routine is responsible for the allocation of the datastructures for the driver as well as any hardware specific details necessary to talk with the device. Arguments: LtMacHandle : The handle given back to the mac from ndis when the mac registered itself. WrapperConfigurationContext : configuration context passed in by NDIS in the AddAdapter call. AdapterName : The string containing the name to give to the device adapter. BusType : The type of bus in use. (MCA, ISA, EISA ...) IoBaseAddress : The base IO address of the card. MaxAdapters : The maximum number of opens at any one time. ConfigError : Error with the Config parameters if any. Return Value: NDIS_STATUS_SUCCESS : If successful, error otherwise. --*/ { // Pointer for the adapter root. PLT_ADAPTER Adapter; NDIS_STATUS Status, RefStatus; NDIS_ERROR_CODE LogErrorCode; // Holds information needed when registering the adapter. NDIS_ADAPTER_INFORMATION AdapterInformation; // Allocate the Adapter block. NdisAllocateMemory( (PVOID)&Adapter, sizeof(LT_ADAPTER), 0, LtNdisPhyAddr); if (Adapter == NULL) { return(NDIS_STATUS_RESOURCES); } NdisZeroMemory( Adapter, sizeof(LT_ADAPTER)); Adapter->NdisMacHandle = LtMacHandle; // Set up the AdapterInformation structure. NdisZeroMemory (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION)); AdapterInformation.DmaChannel = 0; AdapterInformation.Master = FALSE ; AdapterInformation.Dma32BitAddresses = FALSE ; AdapterInformation.AdapterType = BusType ; AdapterInformation.PhysicalMapRegistersNeeded = 0; AdapterInformation.MaximumPhysicalMapping = 0; AdapterInformation.NumberOfPortDescriptors = 1 ; AdapterInformation.PortDescriptors[0].InitialPort = IoBaseAddress; AdapterInformation.PortDescriptors[0].NumberOfPorts = 4; AdapterInformation.PortDescriptors[0].PortOffset = (PVOID *)(&(Adapter->MappedIoBaseAddr)); DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR, ("LtInitRegisterAdapter: IoBaseAddr %lx\n", IoBaseAddress)); // Register the adapter with NDIS. if ((Status = NdisRegisterAdapter( &Adapter->NdisAdapterHandle, Adapter->NdisMacHandle, Adapter, WrapperConfigurationContext, AdapterName, &AdapterInformation)) != NDIS_STATUS_SUCCESS) { // Could not register the adapter, so we cannot log any errors // either. DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_FATAL, ("LtInitRegisterAdapter: Failed %lx\n", Status)); // Free up the memory allocated. NdisFreeMemory( Adapter, sizeof(LT_ADAPTER), 0); return(Status); } DBGPRINT(DBG_COMP_INIT, DBG_LEVEL_ERR, ("LtInitRegisterAdapter: MappedIoBaseAddr %lx\n", Adapter->MappedIoBaseAddr)); do { // Ok. We are all set. Adapter->BusType = BusType; InitializeListHead(&Adapter->Request); InitializeListHead(&Adapter->OpenBindings); InitializeListHead(&Adapter->LoopBack); InitializeListHead(&Adapter->Transmit); InitializeListHead(&Adapter->Receive); NdisAllocateSpinLock(&Adapter->Lock); Adapter->OpenCount = 0; // Set refcount to 1 - creation Adapter->RefCount = 1; NdisInitializeTimer( &Adapter->PollingTimer, LtTimerPoll, (PVOID)Adapter); // If there were no configuration errors, then go ahead with the // initialize. if (ConfigError == NDIS_STATUS_SUCCESS) { // Start the card up. This writes an error // log entry if it fails. if (LtFirmInitialize(Adapter, SuggestedNodeId)) { // Ok, the firmware code has been downloaded to the card. // Start the poll timer. We should do this before we call // GetAddress. Add a reference for the timer. NdisAcquireSpinLock(&Adapter->Lock); LtReferenceAdapterNonInterlock(Adapter, &RefStatus); ASSERTMSG("LtInitRegisterAdapter: RefAdater Failed!\n", (RefStatus == NDIS_STATUS_SUCCESS)); Adapter->Flags |= ADAPTER_TIMER_QUEUED; NdisSetTimer(&Adapter->PollingTimer, LT_POLLING_TIME); NdisReleaseSpinLock(&Adapter->Lock); break; } LogErrorCode = NDIS_ERROR_CODE_HARDWARE_FAILURE; } else { LogErrorCode = NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER; } // We either could not initialize the hardware or get the node // address. OR there was a config error. Log it and deregister // the adapter. LOGERROR(Adapter->NdisAdapterHandle, LogErrorCode); // Deregister the adapter. This calls LtInitRemoveAdapter which // will do all necessary cleanup. NdisDeregisterAdapter(Adapter->NdisAdapterHandle); Status = NDIS_STATUS_FAILURE; break; } while (FALSE); return(Status); }
VOID NdisMlidStatisticTimer( IN PVOID SystemSpecific1, IN PVOID Context, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3 ) /*++ Routine Description: This DPC routine is queued to gather statistics from then NDIS MAC. Arguments: Context - Really a pointer to the MLID. Return Value: None. --*/ { PMLID_STRUCT Mlid = (PMLID_STRUCT)Context; PNDIS_REQUEST NdisMlidRequest = &(Mlid->StatsTable->NdisRequest); NDIS_STATUS NdisStatus; NdisAcquireSpinLock(&(Mlid->MlidSpinLock)); // // Loop // while (TRUE) { // // Set up NdisRequest // NdisMlidRequest->RequestType = NdisRequestQueryInformation; switch (Mlid->NdisMlidMedium) { case NdisMedium802_3: switch (Mlid->StatsTable->StatisticNumber) { case 0: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_ONE_COLLISION; break; case 1: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_MORE_COLLISIONS; break; case 2: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_DEFERRED; break; case 3: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_LATE_COLLISIONS; break; case 4: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_MAX_COLLISIONS; break; case 5: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_XMIT_TIMES_CRS_LOST; break; case 6: goto DoNextStatistic; case 7: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_3_RCV_ERROR_ALIGNMENT; break; } break; case NdisMedium802_5: switch (Mlid->StatsTable->StatisticNumber) { case 0: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_AC_ERRORS; break; case 1: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_ABORT_DELIMETERS; break; case 2: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_BURST_ERRORS; break; case 3: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_FRAME_COPIED_ERRORS; break; case 4: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_FREQUENCY_ERRORS; break; case 5: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_INTERNAL_ERRORS; break; case 6: goto DoNextStatistic; case 7: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_LINE_ERRORS; break; case 8: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_LOST_FRAMES; break; case 9: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_802_5_TOKEN_ERRORS; break; case 10: case 11: case 12: goto DoNextStatistic; } break; case NdisMediumFddi: switch (Mlid->StatsTable->StatisticNumber) { case 0: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_ATTACHMENT_TYPE; break; case 1: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_UPSTREAM_NODE_LONG; break; case 2: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_DOWNSTREAM_NODE_LONG; break; case 3: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_FRAME_ERRORS; break; case 4: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_FRAMES_LOST; break; case 5: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_RING_MGT_STATE; break; case 6: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_LCT_FAILURES; break; case 7: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_LEM_REJECTS; break; case 8: // LemCount goto DoNextStatistic; case 9: NdisMlidRequest->DATA.QUERY_INFORMATION.Oid = OID_FDDI_LCONNECTION_STATE; break; default: goto DoNextStatistic; } break; } NdisMlidRequest->DATA.QUERY_INFORMATION.InformationBuffer = (PVOID)&(Mlid->StatsTable->StatisticValue); NdisMlidRequest->DATA.QUERY_INFORMATION.InformationBufferLength = sizeof(Mlid->StatsTable->StatisticValue); NdisMlidRequest->DATA.QUERY_INFORMATION.BytesWritten = 0; NdisMlidRequest->DATA.QUERY_INFORMATION.BytesNeeded = 0; NdisReleaseSpinLock(&(Mlid->MlidSpinLock)); NdisRequest( &NdisStatus, Mlid->NdisBindingHandle, NdisMlidRequest ); // // if (pending), exit. // if (NdisStatus == NDIS_STATUS_PENDING) { return; } NdisAcquireSpinLock(&(Mlid->MlidSpinLock)); if (NdisStatus == NDIS_STATUS_SUCCESS) { // // Store Statistic // (*((PUINT32)((*(Mlid->StatsTable->StatsTable.MMediaCountsPtr)) [ Mlid->StatsTable->StatisticNumber ].StatCounter))) = Mlid->StatsTable->StatisticValue; } DoNextStatistic: Mlid->StatsTable->StatisticNumber++; switch (Mlid->NdisMlidMedium) { case NdisMedium802_3: if (Mlid->StatsTable->StatisticNumber >= NUM_ETHERNET_COUNTS) { Mlid->StatsTable->StatisticNumber = 0; } break; case NdisMedium802_5: if (Mlid->StatsTable->StatisticNumber >= NUM_TOKEN_RING_COUNTS) { Mlid->StatsTable->StatisticNumber = 0; } break; case NdisMediumFddi: if (Mlid->StatsTable->StatisticNumber >= NUM_FDDI_COUNTS) { Mlid->StatsTable->StatisticNumber = 0; } break; } if (Mlid->StatsTable->StatisticNumber == 0) { // // Set timer for 30 seconds from now. // NdisReleaseSpinLock(&(Mlid->MlidSpinLock)); NdisSetTimer(&(Mlid->StatsTable->StatisticTimer), 30000); return; } } }