Annotation of ntddk/src/network/lance/lance.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     lance.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This is the main file for the Advanced Micro Devices LANCE (Am 7990)
        !            12:     Ethernet controller.  This driver conforms to the NDIS 3.0 interface.
        !            13: 
        !            14:     The idea for handling loopback and sends simultaneously is largely
        !            15:     adapted from the EtherLink II NDIS driver by Adam Barr.
        !            16: 
        !            17: Author:
        !            18: 
        !            19:     Anthony V. Ercolano (Tonye) 20-Jul-1990
        !            20: 
        !            21: Environment:
        !            22: 
        !            23:     Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
        !            24: 
        !            25: Revision History:
        !            26: 
        !            27:     31-Jul-1992  R.D. Lanser:
        !            28: 
        !            29:        Changed DECST card type to DECTC for the DEC TurboChannel option
        !            30:        PMAD-AA (Lance ethernet).  This option will be available for all
        !            31:        TurboChannel systems regardless of CPU type or system.
        !            32: 
        !            33:        Removed UsedLanceBuffer conditional (always true).
        !            34: 
        !            35:        Added  InterruptRequestLevel to the _LANCE_ADAPTER structure because
        !            36:        'lance.c' was passing the InterruptVector as the IRQL to the interrupt
        !            37:        connect routine which is not correct.  This works on JAZZ because the
        !            38:        JAZZ HalGetInterruptVector is hardcoded to return a fixed IRQL for
        !            39:        EISA devices.
        !            40: 
        !            41:        Remove hardcoded configuration information and added gets from the
        !            42:        registry for the base address, interrupt vector, and interrupt
        !            43:        request level.
        !            44: 
        !            45: 
        !            46: --*/
        !            47: 
        !            48: #include <ndis.h>
        !            49: #include <efilter.h>
        !            50: #include "lancehrd.h"
        !            51: #include "lancesft.h"
        !            52: #include "dectc.h"
        !            53: 
        !            54: #if DBG
        !            55: #define STATIC
        !            56: #else
        !            57: #define STATIC static
        !            58: #endif
        !            59: 
        !            60: 
        !            61: #if DBG
        !            62: 
        !            63: UCHAR LanceSendFails[256];
        !            64: UCHAR LanceSendFailPlace = 0;
        !            65: 
        !            66: #endif
        !            67: 
        !            68: 
        !            69: NDIS_HANDLE LanceNdisWrapperHandle;
        !            70: NDIS_HANDLE LanceMacHandle;
        !            71: PDRIVER_OBJECT LanceDriverObject;
        !            72: 
        !            73: //
        !            74: // This constant is used for places where NdisAllocateMemory
        !            75: // needs to be called and the HighestAcceptableAddress does
        !            76: // not matter.
        !            77: //
        !            78: 
        !            79: NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
        !            80:     NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
        !            81: 
        !            82: 
        !            83: #if LANCELOG
        !            84: 
        !            85: NDIS_TIMER LogTimer;
        !            86: BOOLEAN LogTimerRunning = FALSE;
        !            87: 
        !            88: UCHAR Log[LOG_SIZE];
        !            89: 
        !            90: UCHAR LogPlace = 0;
        !            91: UCHAR LogWrapped = 0;
        !            92: 
        !            93: UCHAR LancePrintLog = 0;
        !            94: 
        !            95: void
        !            96: LogDpc(
        !            97:     IN PVOID SystemSpecific1,
        !            98:     PVOID Context,
        !            99:     IN PVOID SystemSpecific2,
        !           100:     IN PVOID SystemSpecific3
        !           101:    )
        !           102: {
        !           103: 
        !           104:    UNREFERENCED_PARAMETER(Context);
        !           105:    UNREFERENCED_PARAMETER(SystemSpecific1);
        !           106:    UNREFERENCED_PARAMETER(SystemSpecific2);
        !           107:    UNREFERENCED_PARAMETER(SystemSpecific3);
        !           108: 
        !           109:    LOG(TIMER);
        !           110: 
        !           111:    NdisSetTimer(&LogTimer, 1000);
        !           112: 
        !           113: }
        !           114: 
        !           115: 
        !           116: #endif
        !           117: 
        !           118: 
        !           119: 
        !           120: 
        !           121: #define MAX_MULTICAST_ADDRESS ((UINT)32)
        !           122: 
        !           123: //
        !           124: // Used for accessing the filter package multicast address list.
        !           125: //
        !           126: 
        !           127: static CHAR MulticastAddresses[MAX_MULTICAST_ADDRESS][ETH_LENGTH_OF_ADDRESS];
        !           128: 
        !           129: 
        !           130: 
        !           131: //
        !           132: // If you add to this, make sure to add the
        !           133: // a case in LanceFillInGlobalData() and in
        !           134: // LanceQueryGlobalStatistics() if global
        !           135: // information only or
        !           136: // LanceQueryProtocolStatistics() if it is
        !           137: // protocol queriable information.
        !           138: //
        !           139: UINT LanceGlobalSupportedOids[] = {
        !           140:     OID_GEN_SUPPORTED_LIST,
        !           141:     OID_GEN_HARDWARE_STATUS,
        !           142:     OID_GEN_MEDIA_SUPPORTED,
        !           143:     OID_GEN_MEDIA_IN_USE,
        !           144:     OID_GEN_MAXIMUM_LOOKAHEAD,
        !           145:     OID_GEN_MAXIMUM_FRAME_SIZE,
        !           146:     OID_GEN_MAXIMUM_TOTAL_SIZE,
        !           147:     OID_GEN_MAC_OPTIONS,
        !           148:     OID_GEN_PROTOCOL_OPTIONS,
        !           149:     OID_GEN_LINK_SPEED,
        !           150:     OID_GEN_TRANSMIT_BUFFER_SPACE,
        !           151:     OID_GEN_RECEIVE_BUFFER_SPACE,
        !           152:     OID_GEN_TRANSMIT_BLOCK_SIZE,
        !           153:     OID_GEN_RECEIVE_BLOCK_SIZE,
        !           154:     OID_GEN_VENDOR_ID,
        !           155:     OID_GEN_VENDOR_DESCRIPTION,
        !           156:     OID_GEN_DRIVER_VERSION,
        !           157:     OID_GEN_CURRENT_PACKET_FILTER,
        !           158:     OID_GEN_CURRENT_LOOKAHEAD,
        !           159:     OID_GEN_XMIT_OK,
        !           160:     OID_GEN_RCV_OK,
        !           161:     OID_GEN_XMIT_ERROR,
        !           162:     OID_GEN_RCV_ERROR,
        !           163:     OID_GEN_RCV_NO_BUFFER,
        !           164:     OID_802_3_PERMANENT_ADDRESS,
        !           165:     OID_802_3_CURRENT_ADDRESS,
        !           166:     OID_802_3_MULTICAST_LIST,
        !           167:     OID_802_3_MAXIMUM_LIST_SIZE,
        !           168:     OID_802_3_RCV_ERROR_ALIGNMENT,
        !           169:     OID_802_3_XMIT_ONE_COLLISION,
        !           170:     OID_802_3_XMIT_MORE_COLLISIONS
        !           171:     };
        !           172: 
        !           173: //
        !           174: // If you add to this, make sure to add the
        !           175: // a case in LanceQueryGlobalStatistics() and in
        !           176: // LanceQueryProtocolInformation()
        !           177: //
        !           178: UINT LanceProtocolSupportedOids[] = {
        !           179:     OID_GEN_SUPPORTED_LIST,
        !           180:     OID_GEN_HARDWARE_STATUS,
        !           181:     OID_GEN_MEDIA_SUPPORTED,
        !           182:     OID_GEN_MEDIA_IN_USE,
        !           183:     OID_GEN_MAXIMUM_LOOKAHEAD,
        !           184:     OID_GEN_MAXIMUM_FRAME_SIZE,
        !           185:     OID_GEN_MAXIMUM_TOTAL_SIZE,
        !           186:     OID_GEN_MAC_OPTIONS,
        !           187:     OID_GEN_PROTOCOL_OPTIONS,
        !           188:     OID_GEN_LINK_SPEED,
        !           189:     OID_GEN_TRANSMIT_BUFFER_SPACE,
        !           190:     OID_GEN_RECEIVE_BUFFER_SPACE,
        !           191:     OID_GEN_TRANSMIT_BLOCK_SIZE,
        !           192:     OID_GEN_RECEIVE_BLOCK_SIZE,
        !           193:     OID_GEN_VENDOR_ID,
        !           194:     OID_GEN_VENDOR_DESCRIPTION,
        !           195:     OID_GEN_DRIVER_VERSION,
        !           196:     OID_GEN_CURRENT_PACKET_FILTER,
        !           197:     OID_GEN_CURRENT_LOOKAHEAD,
        !           198:     OID_802_3_PERMANENT_ADDRESS,
        !           199:     OID_802_3_CURRENT_ADDRESS,
        !           200:     OID_802_3_MULTICAST_LIST,
        !           201:     OID_802_3_MAXIMUM_LIST_SIZE
        !           202:     };
        !           203: 
        !           204: 
        !           205: 
        !           206: //
        !           207: // This macro is to synchronize execution with interrupts.  It
        !           208: // gets the stored value of the CSR 0 and clears the old value.
        !           209: //
        !           210: #define GET_CSR0_SINCE_LAST_PROCESSED(A,V) \
        !           211: { \
        !           212:     PLANCE_ADAPTER _A = A; \
        !           213:     LANCE_SYNCH_CONTEXT _C; \
        !           214:     _C.Adapter = _A; \
        !           215:     _C.LocalRead = (V); \
        !           216:     NdisSynchronizeWithInterrupt( \
        !           217:         &(_A)->Interrupt, \
        !           218:         LanceInterruptSynch, \
        !           219:         &_C \
        !           220:         ); \
        !           221: }
        !           222: 
        !           223: //
        !           224: // We define a constant csr0 value that is useful for initializing
        !           225: // an already stopped LANCE.
        !           226: //
        !           227: // This also enables the chip for interrupts.
        !           228: //
        !           229: #define LANCE_CSR0_INIT_CHIP ((USHORT)0x41)
        !           230: 
        !           231: //
        !           232: // We define a constant csr0 value that is useful for clearing all of
        !           233: // the interesting bits that *could* be set on an interrupt.
        !           234: //
        !           235: #define LANCE_CSR0_CLEAR_INTERRUPT_BITS ((USHORT)0x7f00)
        !           236: 
        !           237: STATIC
        !           238: NDIS_STATUS
        !           239: LanceOpenAdapter(
        !           240:     OUT PNDIS_STATUS OpenErrorStatus,
        !           241:     OUT NDIS_HANDLE *MacBindingHandle,
        !           242:     OUT PUINT SelectedMediumIndex,
        !           243:     IN PNDIS_MEDIUM MediumArray,
        !           244:     IN UINT MediumArraySize,
        !           245:     IN NDIS_HANDLE NdisBindingContext,
        !           246:     IN NDIS_HANDLE MacAdapterContext,
        !           247:     IN UINT OpenOptions,
        !           248:     IN PSTRING AddressingInformation OPTIONAL
        !           249:     );
        !           250: 
        !           251: 
        !           252: VOID
        !           253: LanceUnload(
        !           254:     IN NDIS_HANDLE MacMacContext
        !           255:     );
        !           256: 
        !           257: STATIC
        !           258: NDIS_STATUS
        !           259: LanceCloseAdapter(
        !           260:     IN NDIS_HANDLE MacBindingHandle
        !           261:     );
        !           262: 
        !           263: 
        !           264: STATIC
        !           265: NDIS_STATUS
        !           266: LanceRequest(
        !           267:     IN NDIS_HANDLE MacBindingHandle,
        !           268:     IN PNDIS_REQUEST NdisRequest
        !           269:     );
        !           270: 
        !           271: NDIS_STATUS
        !           272: LanceQueryProtocolInformation(
        !           273:     IN PLANCE_ADAPTER Adapter,
        !           274:     IN PLANCE_OPEN Open,
        !           275:     IN NDIS_OID Oid,
        !           276:     IN BOOLEAN GlobalMode,
        !           277:     IN PVOID InfoBuffer,
        !           278:     IN UINT BytesLeft,
        !           279:     OUT PUINT BytesNeeded,
        !           280:     OUT PUINT BytesWritten
        !           281:     );
        !           282: 
        !           283: NDIS_STATUS
        !           284: LanceQueryInformation(
        !           285:     IN PLANCE_ADAPTER Adapter,
        !           286:     IN PLANCE_OPEN Open,
        !           287:     IN PNDIS_REQUEST NdisRequest
        !           288:     );
        !           289: 
        !           290: NDIS_STATUS
        !           291: LanceSetInformation(
        !           292:     IN PLANCE_ADAPTER Adapter,
        !           293:     IN PLANCE_OPEN Open,
        !           294:     IN PNDIS_REQUEST NdisRequest
        !           295:     );
        !           296: 
        !           297: STATIC
        !           298: NDIS_STATUS
        !           299: LanceReset(
        !           300:     IN NDIS_HANDLE MacBindingHandle
        !           301:     );
        !           302: 
        !           303: 
        !           304: STATIC
        !           305: NDIS_STATUS
        !           306: LanceSetPacketFilter(
        !           307:     IN PLANCE_ADAPTER Adapter,
        !           308:     IN PLANCE_OPEN Open,
        !           309:     IN PNDIS_REQUEST NdisRequest,
        !           310:     IN UINT PacketFilter
        !           311:     );
        !           312: 
        !           313: 
        !           314: NDIS_STATUS
        !           315: LanceFillInGlobalData(
        !           316:     IN PLANCE_ADAPTER Adapter,
        !           317:     IN PNDIS_REQUEST NdisRequest
        !           318:     );
        !           319: 
        !           320: 
        !           321: STATIC
        !           322: NDIS_STATUS
        !           323: LanceQueryGlobalStatistics(
        !           324:     IN NDIS_HANDLE MacAdapterContext,
        !           325:     IN PNDIS_REQUEST NdisRequest
        !           326:     );
        !           327: 
        !           328: NDIS_STATUS
        !           329: LanceChangeMulticastAddresses(
        !           330:     IN UINT OldFilterCount,
        !           331:     IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
        !           332:     IN UINT NewFilterCount,
        !           333:     IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
        !           334:     IN NDIS_HANDLE MacBindingHandle,
        !           335:     IN PNDIS_REQUEST NdisRequest,
        !           336:     IN BOOLEAN Set
        !           337:     );
        !           338: 
        !           339: STATIC
        !           340: NDIS_STATUS
        !           341: LanceChangeFilterClasses(
        !           342:     IN UINT OldFilterClasses,
        !           343:     IN UINT NewFilterClasses,
        !           344:     IN NDIS_HANDLE MacBindingHandle,
        !           345:     IN PNDIS_REQUEST NdisRequest,
        !           346:     IN BOOLEAN Set
        !           347:     );
        !           348: 
        !           349: STATIC
        !           350: VOID
        !           351: LanceCloseAction(
        !           352:     IN NDIS_HANDLE MacBindingHandle
        !           353:     );
        !           354: 
        !           355: STATIC
        !           356: BOOLEAN
        !           357: AllocateAdapterMemory(
        !           358:     IN PLANCE_ADAPTER Adapter
        !           359:     );
        !           360: 
        !           361: STATIC
        !           362: VOID
        !           363: DeleteAdapterMemory(
        !           364:     IN PLANCE_ADAPTER Adapter
        !           365:     );
        !           366: 
        !           367: STATIC
        !           368: VOID
        !           369: ReturnAdapterResources(
        !           370:     IN PLANCE_ADAPTER Adapter,
        !           371:     IN UINT BufferIndex
        !           372:     );
        !           373: 
        !           374: STATIC
        !           375: VOID
        !           376: RelinquishReceivePacket(
        !           377:     IN PLANCE_ADAPTER Adapter,
        !           378:     IN UINT StartingIndex,
        !           379:     IN UINT NumberOfBuffers
        !           380:     );
        !           381: 
        !           382: STATIC
        !           383: BOOLEAN
        !           384: ProcessReceiveInterrupts(
        !           385:     IN PLANCE_ADAPTER Adapter
        !           386:     );
        !           387: 
        !           388: STATIC
        !           389: BOOLEAN
        !           390: ProcessTransmitInterrupts(
        !           391:     IN PLANCE_ADAPTER Adapter
        !           392:     );
        !           393: 
        !           394: STATIC
        !           395: VOID
        !           396: LanceStandardInterruptDPC(
        !           397:     IN PVOID SystemSpecific,
        !           398:     IN PVOID Context,
        !           399:     IN PVOID SystemArgument1,
        !           400:     IN PVOID SystemArgument2
        !           401:     );
        !           402: 
        !           403: 
        !           404: extern
        !           405: BOOLEAN
        !           406: LanceISR(
        !           407:     IN PVOID Context
        !           408:     );
        !           409: 
        !           410: STATIC
        !           411: BOOLEAN
        !           412: LanceInterruptSynch(
        !           413:     IN PVOID Context
        !           414:     );
        !           415: 
        !           416: STATIC
        !           417: UINT
        !           418: CalculateCRC(
        !           419:     IN UINT NumberOfBytes,
        !           420:     IN PCHAR Input
        !           421:     );
        !           422: 
        !           423: STATIC
        !           424: VOID
        !           425: ProcessInterrupt(
        !           426:     IN PLANCE_ADAPTER Adapter
        !           427:     );
        !           428: 
        !           429: STATIC
        !           430: VOID
        !           431: LanceStartChip(
        !           432:     IN PLANCE_ADAPTER Adapter
        !           433:     );
        !           434: 
        !           435: STATIC
        !           436: VOID
        !           437: LanceSetInitializationBlock(
        !           438:     IN PLANCE_ADAPTER Adapter
        !           439:     );
        !           440: 
        !           441: STATIC
        !           442: VOID
        !           443: SetInitBlockAndInit(
        !           444:     IN PLANCE_ADAPTER Adapter
        !           445:     );
        !           446: 
        !           447: STATIC
        !           448: VOID
        !           449: StartAdapterReset(
        !           450:     IN PLANCE_ADAPTER Adapter
        !           451:     );
        !           452: 
        !           453: STATIC
        !           454: VOID
        !           455: SetupForReset(
        !           456:     IN PLANCE_ADAPTER Adapter,
        !           457:     IN PLANCE_OPEN Open,
        !           458:     IN PNDIS_REQUEST NdisRequest,
        !           459:     IN NDIS_REQUEST_TYPE RequestType
        !           460:     );
        !           461: 
        !           462: STATIC
        !           463: NDIS_STATUS
        !           464: LanceInitialInit(
        !           465:     IN PLANCE_ADAPTER Adapter
        !           466:     );
        !           467: 
        !           468: 
        !           469: STATIC
        !           470: VOID
        !           471: FinishPendOp(
        !           472:     IN PLANCE_ADAPTER Adapter,
        !           473:     IN BOOLEAN Successful
        !           474:     );
        !           475: 
        !           476: 
        !           477: //
        !           478: // Non portable interface.
        !           479: //
        !           480: 
        !           481: NTSTATUS
        !           482: DriverEntry(
        !           483:     IN PDRIVER_OBJECT DriverObject,
        !           484:     IN PUNICODE_STRING RegistryPath
        !           485:     )
        !           486: 
        !           487: /*++
        !           488: 
        !           489: Routine Description:
        !           490: 
        !           491:     This is the primary initialization routine for the lance driver.
        !           492:     It is simply responsible for the intializing the wrapper and registering
        !           493:     the MAC.  It then calls a system and architecture specific routine that
        !           494:     will initialize and register each adapter.
        !           495: 
        !           496: Arguments:
        !           497: 
        !           498:     DriverObject - Pointer to driver object created by the system.
        !           499: 
        !           500: Return Value:
        !           501: 
        !           502:     The status of the operation.
        !           503: 
        !           504: --*/
        !           505: 
        !           506: {
        !           507: 
        !           508: 
        !           509:     //
        !           510:     // Receives the status of the NdisRegisterMac operation.
        !           511:     //
        !           512:     NDIS_STATUS InitStatus;
        !           513: 
        !           514:     NDIS_HANDLE NdisMacHandle;
        !           515: 
        !           516:     NDIS_HANDLE NdisWrapperHandle;
        !           517: 
        !           518:     char Tmp[sizeof(NDIS_MAC_CHARACTERISTICS)];
        !           519:     PNDIS_MAC_CHARACTERISTICS LanceChar = (PNDIS_MAC_CHARACTERISTICS)Tmp;
        !           520: 
        !           521:     NDIS_STRING MacName = NDIS_STRING_CONST("Lance");
        !           522: 
        !           523:     //
        !           524:     // Initialize the wrapper.
        !           525:     //
        !           526: 
        !           527:     NdisInitializeWrapper(&NdisWrapperHandle,
        !           528:                           DriverObject,
        !           529:                           RegistryPath,
        !           530:                           NULL
        !           531:                           );
        !           532: 
        !           533:     //
        !           534:     // Initialize the MAC characteristics for the call to
        !           535:     // NdisRegisterMac.
        !           536:     //
        !           537: 
        !           538:     LanceChar->MajorNdisVersion = LANCE_NDIS_MAJOR_VERSION;
        !           539:     LanceChar->MinorNdisVersion = LANCE_NDIS_MINOR_VERSION;
        !           540:     LanceChar->OpenAdapterHandler = LanceOpenAdapter;
        !           541:     LanceChar->CloseAdapterHandler = LanceCloseAdapter;
        !           542:     LanceChar->SendHandler = LanceSend;
        !           543:     LanceChar->TransferDataHandler = LanceTransferData;
        !           544:     LanceChar->ResetHandler = LanceReset;
        !           545:     LanceChar->RequestHandler = LanceRequest;
        !           546:     LanceChar->AddAdapterHandler = LanceAddAdapter;
        !           547:     LanceChar->UnloadMacHandler = LanceUnload;
        !           548:     LanceChar->RemoveAdapterHandler = LanceRemoveAdapter;
        !           549:     LanceChar->QueryGlobalStatisticsHandler = LanceQueryGlobalStatistics;
        !           550: 
        !           551:     LanceChar->Name = MacName;
        !           552: 
        !           553:     LanceDriverObject = DriverObject;
        !           554:     LanceNdisWrapperHandle = NdisWrapperHandle;
        !           555: 
        !           556:     NdisRegisterMac(
        !           557:         &InitStatus,
        !           558:         &NdisMacHandle,
        !           559:         NdisWrapperHandle,
        !           560:         &NdisMacHandle,
        !           561:         LanceChar,
        !           562:         sizeof(*LanceChar)
        !           563:         );
        !           564: 
        !           565:     LanceMacHandle = NdisMacHandle;
        !           566: 
        !           567:     if (InitStatus == NDIS_STATUS_SUCCESS) {
        !           568: 
        !           569:         return NDIS_STATUS_SUCCESS;
        !           570: 
        !           571:     }
        !           572: 
        !           573:     NdisTerminateWrapper(NdisWrapperHandle, NULL);
        !           574: 
        !           575:     return NDIS_STATUS_FAILURE;
        !           576: 
        !           577: }
        !           578: 
        !           579: NDIS_STATUS
        !           580: LanceAddAdapter(
        !           581:     IN NDIS_HANDLE MacMacContext,
        !           582:     IN NDIS_HANDLE ConfigurationHandle,
        !           583:     IN PNDIS_STRING AdapterName
        !           584:     )
        !           585: /*++
        !           586: Routine Description:
        !           587: 
        !           588:     This is the Wd MacAddAdapter routine.    The system calls this routine
        !           589:     to add support for a particular WD adapter.  This routine extracts
        !           590:     configuration information from the configuration data base and registers
        !           591:     the adapter with NDIS.
        !           592: 
        !           593: Arguments:
        !           594: 
        !           595:     see NDIS 3.0 spec...
        !           596: 
        !           597: Return Value:
        !           598: 
        !           599:     NDIS_STATUS_SUCCESS - Adapter was successfully added.
        !           600:     NDIS_STATUS_FAILURE - Adapter was not added, also MAC deregistered.
        !           601: 
        !           602: --*/
        !           603: {
        !           604:     //
        !           605:     // Pointer for the adapter root.
        !           606:     //
        !           607:     PLANCE_ADAPTER Adapter;
        !           608: 
        !           609: 
        !           610:     NDIS_HANDLE ConfigHandle;
        !           611:     PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
        !           612:     NDIS_STRING IoAddressStr = NDIS_STRING_CONST("IoBaseAddress");
        !           613:     NDIS_STRING MaxMulticastListStr = NDIS_STRING_CONST("MaximumMulticastList");
        !           614:     NDIS_STRING NetworkAddressStr = NDIS_STRING_CONST("NetworkAddress");
        !           615:     NDIS_STRING InterruptStr = NDIS_STRING_CONST("InterruptNumber");
        !           616:     NDIS_STRING CardStr = NDIS_STRING_CONST("CardType");
        !           617:     NDIS_STRING MemoryBaseAddrStr = NDIS_STRING_CONST("MemoryMappedBaseAddress");
        !           618: 
        !           619:     NDIS_HANDLE NdisMacHandle = (NDIS_HANDLE)(*((PNDIS_HANDLE)MacMacContext));
        !           620: 
        !           621:     NDIS_STATUS Status;
        !           622: 
        !           623:     NDIS_ADAPTER_INFORMATION AdapterInformation;  // needed to register adapter
        !           624:     NDIS_EISA_FUNCTION_INFORMATION EisaData;
        !           625:     USHORT ConfigValue = 0;
        !           626:     UCHAR HiBaseValue = 0;
        !           627: 
        !           628:     UINT MaxMulticastList = 32;
        !           629:     PVOID NetAddress;
        !           630:     UINT Length;
        !           631: 
        !           632:     USHORT RegUshort;
        !           633:     UCHAR RegUchar;
        !           634:     UINT LanceSlot = 1;
        !           635: 
        !           636:     BOOLEAN ConfigError = FALSE;
        !           637:     NDIS_STATUS ConfigErrorCode;
        !           638: 
        !           639: 
        !           640:     //
        !           641:     // Allocate the Adapter block.
        !           642:     //
        !           643: 
        !           644:     LANCE_ALLOC_PHYS(&Adapter, sizeof(LANCE_ADAPTER));
        !           645: 
        !           646:     if (Adapter == NULL){
        !           647: 
        !           648:         return NDIS_STATUS_RESOURCES;
        !           649: 
        !           650:     }
        !           651: 
        !           652:     LANCE_ZERO_MEMORY(
        !           653:             Adapter,
        !           654:             sizeof(LANCE_ADAPTER)
        !           655:             );
        !           656: 
        !           657:     Adapter->NdisMacHandle = NdisMacHandle;
        !           658: 
        !           659: 
        !           660:     //
        !           661:     // Start with the default card
        !           662:     //
        !           663: 
        !           664:     Adapter->LanceCard = LANCE_DE201;
        !           665: 
        !           666:     Adapter->RAP = LANCE_DE201_PRI_RAP_ADDRESS;
        !           667:     Adapter->RDP = LANCE_DE201_PRI_RDP_ADDRESS;
        !           668:     Adapter->Nicsr = LANCE_DE201_PRI_NICSR_ADDRESS;
        !           669:     Adapter->NicsrDefaultValue = 0;
        !           670:     Adapter->NetworkHardwareAddress = LANCE_DE201_PRI_NETWORK_ADDRESS;
        !           671:     Adapter->HardwareBaseAddr = LANCE_DE201_BASE;
        !           672:     Adapter->AmountOfHardwareMemory = LANCE_DE201_HARDWARE_MEMORY;
        !           673:     Adapter->InterruptNumber = LANCE_DE201_INTERRUPT_VECTOR;
        !           674:     Adapter->InterruptRequestLevel = LANCE_DE201_INTERRUPT_VECTOR;
        !           675: 
        !           676:     NdisOpenConfiguration(
        !           677:                     &Status,
        !           678:                     &ConfigHandle,
        !           679:                     ConfigurationHandle
        !           680:                     );
        !           681: 
        !           682:     if (Status != NDIS_STATUS_SUCCESS) {
        !           683: 
        !           684:         return NDIS_STATUS_FAILURE;
        !           685: 
        !           686:     }
        !           687: 
        !           688:     //
        !           689:     // Read Card Type
        !           690:     //
        !           691: 
        !           692:     NdisReadConfiguration(
        !           693:                     &Status,
        !           694:                     &ReturnedValue,
        !           695:                     ConfigHandle,
        !           696:                     &CardStr,
        !           697:                     NdisParameterInteger
        !           698:                     );
        !           699: 
        !           700:     if (Status == NDIS_STATUS_SUCCESS) {
        !           701: 
        !           702:         if (ReturnedValue->ParameterData.IntegerData == 2) {
        !           703: 
        !           704:             Adapter->LanceCard = LANCE_DE201;
        !           705: 
        !           706:         } else if (ReturnedValue->ParameterData.IntegerData == 1) {
        !           707: 
        !           708:             Adapter->LanceCard = LANCE_DE100;
        !           709: 
        !           710:         } else if (ReturnedValue->ParameterData.IntegerData == 3) {
        !           711: 
        !           712:             Adapter->LanceCard = LANCE_DEPCA;
        !           713: 
        !           714: #ifndef i386
        !           715:         } else if (ReturnedValue->ParameterData.IntegerData == 4) {
        !           716: 
        !           717:             Adapter->LanceCard = LANCE_DECTC;
        !           718: 
        !           719:             ConfigErrorCode = LanceDecTcGetConfiguration(ConfigHandle, Adapter);
        !           720: 
        !           721:             if ( ConfigErrorCode != NDIS_STATUS_SUCCESS ) {
        !           722:                 ConfigError = TRUE;
        !           723:             }
        !           724: #endif // i386
        !           725: 
        !           726:         } else if (ReturnedValue->ParameterData.IntegerData == 5) {
        !           727: 
        !           728:             Adapter->LanceCard = LANCE_DE422;
        !           729: 
        !           730:         } else if (ReturnedValue->ParameterData.IntegerData == 6) {
        !           731: 
        !           732:             //
        !           733:             // This is the De200, but it operates exactly like the 201.
        !           734:             //
        !           735: 
        !           736:             Adapter->LanceCard = LANCE_DE201;
        !           737: 
        !           738:         } else if (ReturnedValue->ParameterData.IntegerData == 7) {
        !           739: 
        !           740:             //
        !           741:             // This is the De101, but it operates exactly like the 100.
        !           742:             //
        !           743: 
        !           744:             Adapter->LanceCard = LANCE_DE100;
        !           745: 
        !           746:         } else {
        !           747: 
        !           748:             ConfigError = TRUE;
        !           749:             ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !           750: 
        !           751:             goto RegisterAdapter;
        !           752:         }
        !           753: 
        !           754:     }
        !           755: 
        !           756:     //
        !           757:     // Read MaxMulticastList
        !           758:     //
        !           759: 
        !           760:     NdisReadConfiguration(
        !           761:                     &Status,
        !           762:                     &ReturnedValue,
        !           763:                     ConfigHandle,
        !           764:                     &MaxMulticastListStr,
        !           765:                     NdisParameterInteger
        !           766:                     );
        !           767: 
        !           768:     if (Status == NDIS_STATUS_SUCCESS) {
        !           769: 
        !           770:         MaxMulticastList = ReturnedValue->ParameterData.IntegerData;
        !           771: 
        !           772:     }
        !           773: 
        !           774:     //
        !           775:     // Read net address
        !           776:     //
        !           777: 
        !           778:     NdisReadNetworkAddress(
        !           779:                     &Status,
        !           780:                     &NetAddress,
        !           781:                     &Length,
        !           782:                     ConfigHandle
        !           783:                     );
        !           784: 
        !           785:     if ((Length == ETH_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS)) {
        !           786: 
        !           787:         ETH_COPY_NETWORK_ADDRESS(
        !           788:                 Adapter->CurrentNetworkAddress,
        !           789:                 NetAddress
        !           790:                 );
        !           791: 
        !           792:     }
        !           793: 
        !           794:     if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100)) {
        !           795: 
        !           796:         //
        !           797:         // Read IoAddress
        !           798:         //
        !           799: 
        !           800:         NdisReadConfiguration(
        !           801:                     &Status,
        !           802:                     &ReturnedValue,
        !           803:                     ConfigHandle,
        !           804:                     &IoAddressStr,
        !           805:                     NdisParameterInteger
        !           806:                     );
        !           807: 
        !           808:         if (Status == NDIS_STATUS_SUCCESS) {
        !           809: 
        !           810:             if (ReturnedValue->ParameterData.IntegerData == 1) {
        !           811: 
        !           812:                 Adapter->RAP = LANCE_DE201_PRI_RAP_ADDRESS;
        !           813: 
        !           814:                 Adapter->RDP = LANCE_DE201_PRI_RDP_ADDRESS;
        !           815: 
        !           816:                 Adapter->Nicsr = LANCE_DE201_PRI_NICSR_ADDRESS;
        !           817: 
        !           818:                 Adapter->NetworkHardwareAddress = LANCE_DE201_PRI_NETWORK_ADDRESS;
        !           819: 
        !           820:             } else if (ReturnedValue->ParameterData.IntegerData == 2) {
        !           821: 
        !           822:                 Adapter->RAP = LANCE_DE201_SEC_RAP_ADDRESS;
        !           823: 
        !           824:                 Adapter->RDP = LANCE_DE201_SEC_RDP_ADDRESS;
        !           825: 
        !           826:                 Adapter->Nicsr = LANCE_DE201_SEC_NICSR_ADDRESS;
        !           827: 
        !           828:                 Adapter->NetworkHardwareAddress = LANCE_DE201_SEC_NETWORK_ADDRESS;
        !           829: 
        !           830:             } else {
        !           831: 
        !           832:                 ConfigError = TRUE;
        !           833:                 ConfigErrorCode = NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS;
        !           834: 
        !           835:                 goto RegisterAdapter;
        !           836:             }
        !           837: 
        !           838:         }
        !           839: 
        !           840: 
        !           841: 
        !           842: 
        !           843:         //
        !           844:         // Read Interrupt
        !           845:         //
        !           846: 
        !           847:         NdisReadConfiguration(
        !           848:                     &Status,
        !           849:                     &ReturnedValue,
        !           850:                     ConfigHandle,
        !           851:                     &InterruptStr,
        !           852:                     NdisParameterInteger
        !           853:                     );
        !           854: 
        !           855:         if (Status == NDIS_STATUS_SUCCESS) {
        !           856: 
        !           857:             Adapter->InterruptNumber = (CCHAR)(ReturnedValue->ParameterData.IntegerData);
        !           858:             Adapter->InterruptRequestLevel = Adapter->InterruptNumber;
        !           859: 
        !           860:             if (Adapter->LanceCard == LANCE_DE201) {
        !           861: 
        !           862:                 if (!((Adapter->InterruptNumber == 5) ||
        !           863:                       (Adapter->InterruptNumber == 9) ||
        !           864:                       (Adapter->InterruptNumber == 10) ||
        !           865:                       (Adapter->InterruptNumber == 11) ||
        !           866:                       (Adapter->InterruptNumber == 15))) {
        !           867: 
        !           868:                     ConfigError = TRUE;
        !           869:                     ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !           870: 
        !           871:                     goto RegisterAdapter;
        !           872: 
        !           873:                 }
        !           874: 
        !           875:             } else {
        !           876: 
        !           877:                 if (!((Adapter->InterruptNumber == 2) ||
        !           878:                       (Adapter->InterruptNumber == 3) ||
        !           879:                       (Adapter->InterruptNumber == 4) ||
        !           880:                       (Adapter->InterruptNumber == 5) ||
        !           881:                       (Adapter->InterruptNumber == 7))) {
        !           882: 
        !           883:                     ConfigError = TRUE;
        !           884:                     ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !           885: 
        !           886:                     goto RegisterAdapter;
        !           887: 
        !           888:                 }
        !           889: 
        !           890:             }
        !           891: 
        !           892:         }
        !           893: 
        !           894: 
        !           895: 
        !           896:         //
        !           897:         // Read MemoryBaseAddress
        !           898:         //
        !           899: 
        !           900: 
        !           901:         NdisReadConfiguration(
        !           902:                     &Status,
        !           903:                     &ReturnedValue,
        !           904:                     ConfigHandle,
        !           905:                     &MemoryBaseAddrStr,
        !           906:                     NdisParameterHexInteger
        !           907:                     );
        !           908: 
        !           909:         if (Status == NDIS_STATUS_SUCCESS) {
        !           910: 
        !           911:             Adapter->HardwareBaseAddr = (PVOID)(ReturnedValue->ParameterData.IntegerData);
        !           912: 
        !           913:             if (!((Adapter->HardwareBaseAddr == (PVOID)0xC0000) ||
        !           914:                   (Adapter->HardwareBaseAddr == (PVOID)0xC8000) ||
        !           915:                   (Adapter->HardwareBaseAddr == (PVOID)0xD0000) ||
        !           916:                   (Adapter->HardwareBaseAddr == (PVOID)0xD8000) ||
        !           917:                   (Adapter->HardwareBaseAddr == (PVOID)0xE0000) ||
        !           918:                   (Adapter->HardwareBaseAddr == (PVOID)0xE8000))) {
        !           919: 
        !           920:                 ConfigError = TRUE;
        !           921:                 ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !           922: 
        !           923:                 goto RegisterAdapter;
        !           924: 
        !           925:             }
        !           926: 
        !           927:         }
        !           928: 
        !           929: 
        !           930:         if (((ULONG)Adapter->HardwareBaseAddr) & 0x8000) {
        !           931: 
        !           932:             Adapter->AmountOfHardwareMemory = 0x8000;
        !           933:             Adapter->HardwareBaseOffset = 0x8000;
        !           934: 
        !           935:         } else {
        !           936: 
        !           937:             Adapter->AmountOfHardwareMemory = 0x10000;
        !           938:             Adapter->HardwareBaseOffset = 0x0;
        !           939: 
        !           940:         }
        !           941: 
        !           942:     } else if (Adapter->LanceCard == LANCE_DEPCA) {
        !           943: 
        !           944:         Adapter->NetworkHardwareAddress = LANCE_DEPCA_EPROM_ADDRESS;
        !           945:         Adapter->InterruptNumber = LANCE_DEPCA_INTERRUPT_VECTOR;
        !           946:         Adapter->InterruptRequestLevel = LANCE_DEPCA_INTERRUPT_VECTOR;
        !           947:         Adapter->RAP = LANCE_DEPCA_RAP_ADDRESS;
        !           948:         Adapter->RDP = LANCE_DEPCA_RDP_ADDRESS;
        !           949:         Adapter->AmountOfHardwareMemory = LANCE_DEPCA_HARDWARE_MEMORY;
        !           950:         Adapter->HardwareBaseAddr = LANCE_DEPCA_BASE;
        !           951:         Adapter->Nicsr = LANCE_DEPCA_NICSR_ADDRESS;
        !           952:         Adapter->LanceCard = LANCE_DE100;
        !           953: 
        !           954:     } else if (Adapter->LanceCard == LANCE_DE422) {
        !           955: 
        !           956:         PUCHAR CurrentChar;
        !           957:         BOOLEAN LastEntry;
        !           958:         UCHAR InitType;
        !           959:         USHORT PortAddress, PortValue, Mask;
        !           960: 
        !           961:         NdisReadEisaSlotInformation(
        !           962:                                 &Status,
        !           963:                                 ConfigurationHandle,
        !           964:                                 &Adapter->SlotNumber,
        !           965:                                 &EisaData
        !           966:                                 );
        !           967: 
        !           968:         if (Status != NDIS_STATUS_SUCCESS) {
        !           969: 
        !           970:             ConfigError = TRUE;
        !           971:             ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !           972: 
        !           973:             goto RegisterAdapter;
        !           974: 
        !           975:         }
        !           976: 
        !           977:         //
        !           978:         // Setup Ports
        !           979:         //
        !           980: 
        !           981:         Adapter->RAP = (((ULONG)Adapter->SlotNumber) << 12) +
        !           982:                        LANCE_DE422_RAP_ADDRESS;
        !           983: 
        !           984:         Adapter->RDP = (((ULONG)Adapter->SlotNumber) << 12) +
        !           985:                        LANCE_DE422_RDP_ADDRESS;
        !           986: 
        !           987:         Adapter->Nicsr = (((ULONG)Adapter->SlotNumber) << 12) +
        !           988:                          LANCE_DE422_NICSR_ADDRESS;
        !           989: 
        !           990:         Adapter->NetworkHardwareAddress = (((ULONG)Adapter->SlotNumber) << 12) +
        !           991:                          LANCE_DE422_NETWORK_ADDRESS;
        !           992: 
        !           993:         CurrentChar = (PUCHAR) (EisaData.InitializationData);
        !           994:         LastEntry = FALSE;
        !           995: 
        !           996:         while (!LastEntry) {
        !           997: 
        !           998:             InitType = *(CurrentChar++);
        !           999:             PortAddress = *((USHORT UNALIGNED *) CurrentChar++);
        !          1000: 
        !          1001:             CurrentChar++;
        !          1002: 
        !          1003:             if ((InitType & 0x80) == 0) {
        !          1004:                 LastEntry = TRUE;
        !          1005:             }
        !          1006: 
        !          1007: 
        !          1008: 
        !          1009:             if (PortAddress == (USHORT)(Adapter->NetworkHardwareAddress)) {
        !          1010: 
        !          1011:                 PortValue = *((USHORT UNALIGNED *) CurrentChar++);
        !          1012: 
        !          1013:             } else if (PortAddress == ((Adapter->SlotNumber << 12) +
        !          1014:                                        LANCE_DE422_EXTENDED_MEMORY_BASE_ADDRESS)) {
        !          1015: 
        !          1016:                 PortValue = (USHORT)(*(CurrentChar++));
        !          1017: 
        !          1018:             } else {
        !          1019: 
        !          1020:                 continue;
        !          1021: 
        !          1022:             }
        !          1023: 
        !          1024: 
        !          1025: 
        !          1026:             if (InitType & 0x40) {
        !          1027: 
        !          1028:                 if (PortAddress == Adapter->NetworkHardwareAddress) {
        !          1029: 
        !          1030:                     Mask = *((USHORT UNALIGNED *) CurrentChar++);
        !          1031: 
        !          1032:                 } else {
        !          1033: 
        !          1034:                     Mask = (USHORT)(*(CurrentChar++));
        !          1035: 
        !          1036:                 }
        !          1037: 
        !          1038:             } else {
        !          1039: 
        !          1040:                 Mask = 0;
        !          1041: 
        !          1042:             }
        !          1043: 
        !          1044:             if (PortAddress == Adapter->NetworkHardwareAddress) {
        !          1045: 
        !          1046:                 ConfigValue &= Mask;
        !          1047:                 ConfigValue |= PortValue;
        !          1048: 
        !          1049:             } else {
        !          1050: 
        !          1051:                 HiBaseValue &= (UCHAR)Mask;
        !          1052:                 HiBaseValue |= (UCHAR)PortValue;
        !          1053: 
        !          1054:             }
        !          1055: 
        !          1056:         }
        !          1057: 
        !          1058:         //
        !          1059:         // Interpret values
        !          1060:         //
        !          1061: 
        !          1062:         switch (ConfigValue & 0x78) {
        !          1063: 
        !          1064:             case 0x40:
        !          1065: 
        !          1066:                 Adapter->InterruptNumber = 11;
        !          1067:                 break;
        !          1068: 
        !          1069:             case 0x20:
        !          1070: 
        !          1071:                 Adapter->InterruptNumber = 10;
        !          1072:                 break;
        !          1073: 
        !          1074:             case 0x10:
        !          1075: 
        !          1076:                 Adapter->InterruptNumber = 9;
        !          1077:                 break;
        !          1078: 
        !          1079:             case 0x08:
        !          1080: 
        !          1081:                 Adapter->InterruptNumber = 5;
        !          1082:                 break;
        !          1083: 
        !          1084:             default:
        !          1085: 
        !          1086:                 ConfigError = TRUE;
        !          1087:                 ConfigErrorCode = NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION;
        !          1088: 
        !          1089:                 goto RegisterAdapter;
        !          1090: 
        !          1091:         }
        !          1092: 
        !          1093:         Adapter->InterruptRequestLevel = Adapter->InterruptNumber;
        !          1094:         //
        !          1095:         // We postpone the rest of the processing since we have to read from
        !          1096:         // the NICSR to get the amount of hardware memory and cannot do that
        !          1097:         // until after we have called NdisRegisterAdater.
        !          1098:         //
        !          1099: 
        !          1100:     }
        !          1101: 
        !          1102: RegisterAdapter:
        !          1103: 
        !          1104:     NdisCloseConfiguration(ConfigHandle);
        !          1105: 
        !          1106:     //
        !          1107:     // The adapter is initialized, register it with NDIS.
        !          1108:     // This must occur before interrupts are enabled since the
        !          1109:     // InitializeInterrupt routine requires the NdisAdapterHandle
        !          1110:     //
        !          1111: 
        !          1112:     //
        !          1113:     // Set up the AdapterInformation structure; zero it
        !          1114:     // first in case it is extended later.
        !          1115:     //
        !          1116: 
        !          1117:     LANCE_ZERO_MEMORY(&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));
        !          1118: 
        !          1119:     if (Adapter->LanceCard & (LANCE_DE100 | LANCE_DE201)) {
        !          1120: 
        !          1121:         AdapterInformation.AdapterType = NdisInterfaceIsa;
        !          1122: 
        !          1123:     } else if (Adapter->LanceCard == LANCE_DE422) {
        !          1124: 
        !          1125:         AdapterInformation.AdapterType = NdisInterfaceEisa;
        !          1126: 
        !          1127:     }
        !          1128: 
        !          1129:     AdapterInformation.NumberOfPortDescriptors = 1;
        !          1130: 
        !          1131: #ifndef i386
        !          1132: 
        !          1133:     if (Adapter->LanceCard == LANCE_DECTC) {
        !          1134: 
        !          1135:         Status = LanceDecTcGetInformation(Adapter, &AdapterInformation);
        !          1136:         if (Status != NDIS_STATUS_SUCCESS) {
        !          1137:             return Status;
        !          1138:         }
        !          1139: 
        !          1140:     } else
        !          1141: 
        !          1142: #endif
        !          1143: 
        !          1144:     if (Adapter->LanceCard & (LANCE_DE100 | LANCE_DE201)) {
        !          1145: 
        !          1146:         AdapterInformation.PortDescriptors[0].InitialPort = (ULONG)Adapter->Nicsr;
        !          1147:         AdapterInformation.PortDescriptors[0].NumberOfPorts = 0x10;
        !          1148: 
        !          1149:     } else if (Adapter->LanceCard == LANCE_DE422) {
        !          1150: 
        !          1151:         AdapterInformation.PortDescriptors[0].InitialPort = (ULONG)(Adapter->Nicsr);
        !          1152:         AdapterInformation.PortDescriptors[0].NumberOfPorts = 0x90;
        !          1153: 
        !          1154:     }
        !          1155: 
        !          1156:     if ((Status = NdisRegisterAdapter(
        !          1157:                     &Adapter->NdisAdapterHandle,
        !          1158:                     Adapter->NdisMacHandle,
        !          1159:                     Adapter,
        !          1160:                     ConfigurationHandle,
        !          1161:                     AdapterName,
        !          1162:                     &AdapterInformation
        !          1163:                     )) != NDIS_STATUS_SUCCESS) {
        !          1164: 
        !          1165:         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1166: 
        !          1167:         return Status;
        !          1168: 
        !          1169:     }
        !          1170: 
        !          1171: 
        !          1172:     if (ConfigError) {
        !          1173: 
        !          1174:         NdisWriteErrorLogEntry(
        !          1175:             Adapter->NdisAdapterHandle,
        !          1176:             ConfigErrorCode,
        !          1177:             0
        !          1178:             );
        !          1179: 
        !          1180:         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1181: 
        !          1182:         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1183: 
        !          1184:         return NDIS_STATUS_FAILURE;
        !          1185: 
        !          1186:     }
        !          1187: 
        !          1188:     //
        !          1189:     // Now we get the rest of the information necessary for the DE422.
        !          1190:     //
        !          1191: 
        !          1192:     if (Adapter->LanceCard == LANCE_DE422) {
        !          1193: 
        !          1194:         //
        !          1195:         // Verify card is a DE422
        !          1196:         //
        !          1197: 
        !          1198:         NdisReadPortUshort(Adapter->NdisAdapterHandle,
        !          1199:                            (((ULONG)(Adapter->SlotNumber)) << 12) +
        !          1200:                                LANCE_DE422_EISA_IDENTIFICATION,
        !          1201:                            &RegUshort
        !          1202:                           );
        !          1203: 
        !          1204:         if (RegUshort != 0xA310) {
        !          1205: 
        !          1206:             //
        !          1207:             // Not a DE422 card
        !          1208:             //
        !          1209: 
        !          1210:             NdisWriteErrorLogEntry(
        !          1211:                 Adapter->NdisAdapterHandle,
        !          1212:                 NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
        !          1213:                 0
        !          1214:                 );
        !          1215: 
        !          1216:             NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1217: 
        !          1218:             LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1219: 
        !          1220:             return NDIS_STATUS_FAILURE;
        !          1221: 
        !          1222:         }
        !          1223: 
        !          1224:         NdisReadPortUshort(Adapter->NdisAdapterHandle,
        !          1225:                            (((ULONG)(Adapter->SlotNumber)) << 12) +
        !          1226:                                LANCE_DE422_EISA_IDENTIFICATION + 2,
        !          1227:                            &RegUshort
        !          1228:                           );
        !          1229: 
        !          1230:         if (RegUshort != 0x2042) {
        !          1231: 
        !          1232:             //
        !          1233:             // Not a DE422 card
        !          1234:             //
        !          1235: 
        !          1236:             NdisWriteErrorLogEntry(
        !          1237:                 Adapter->NdisAdapterHandle,
        !          1238:                 NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
        !          1239:                 0
        !          1240:                 );
        !          1241: 
        !          1242:             NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1243: 
        !          1244:             LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1245: 
        !          1246:             return NDIS_STATUS_FAILURE;
        !          1247: 
        !          1248:         }
        !          1249: 
        !          1250:         //
        !          1251:         // Check that the card is enabled.
        !          1252:         //
        !          1253: 
        !          1254:         NdisReadPortUchar(Adapter->NdisAdapterHandle,
        !          1255:                           (((ULONG)(Adapter->SlotNumber)) << 12) +
        !          1256:                               LANCE_DE422_EISA_CONTROL,
        !          1257:                           &RegUchar
        !          1258:                           );
        !          1259: 
        !          1260:         if (!(RegUchar & 0x1)) {
        !          1261: 
        !          1262:             NdisWriteErrorLogEntry(
        !          1263:                 Adapter->NdisAdapterHandle,
        !          1264:                 NDIS_ERROR_CODE_ADAPTER_DISABLED,
        !          1265:                 0
        !          1266:                 );
        !          1267: 
        !          1268:             NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1269: 
        !          1270:             LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1271: 
        !          1272:             return NDIS_STATUS_FAILURE;
        !          1273: 
        !          1274:         }
        !          1275: 
        !          1276:         //
        !          1277:         // Get Memory size
        !          1278:         //
        !          1279: 
        !          1280:         NdisReadPortUshort(Adapter->NdisAdapterHandle,
        !          1281:                            Adapter->Nicsr,
        !          1282:                            &RegUshort
        !          1283:                           );
        !          1284: 
        !          1285:         if (RegUshort & LANCE_NICSR_BUFFER_SIZE) {
        !          1286: 
        !          1287:             Adapter->AmountOfHardwareMemory = 0x8000;
        !          1288: 
        !          1289:         } else if (RegUshort & LANCE_NICSR_128K) {
        !          1290: 
        !          1291:             Adapter->AmountOfHardwareMemory = 0x20000;
        !          1292:             Adapter->NicsrDefaultValue = LANCE_NICSR_128K;
        !          1293: 
        !          1294:         } else {
        !          1295: 
        !          1296:             Adapter->AmountOfHardwareMemory = 0x10000;
        !          1297: 
        !          1298:         }
        !          1299: 
        !          1300:         //
        !          1301:         // Get Base memory address
        !          1302:         //
        !          1303: 
        !          1304:         switch (Adapter->AmountOfHardwareMemory) {
        !          1305: 
        !          1306:             case 0x8000:
        !          1307: 
        !          1308:                 switch (ConfigValue & 0x07) {
        !          1309: 
        !          1310:                     case 0x04:
        !          1311: 
        !          1312:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC8000);
        !          1313:                         Adapter->HardwareBaseOffset = 0x8000;
        !          1314:                         break;
        !          1315: 
        !          1316:                     case 0x05:
        !          1317: 
        !          1318:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xE8000);
        !          1319:                         Adapter->HardwareBaseOffset = 0x8000;
        !          1320:                         break;
        !          1321: 
        !          1322:                     case 0x06:
        !          1323: 
        !          1324:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD8000);
        !          1325:                         Adapter->HardwareBaseOffset = 0x8000;
        !          1326:                         break;
        !          1327: 
        !          1328:                     case 0x07:
        !          1329: 
        !          1330:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xF8000);
        !          1331:                         Adapter->HardwareBaseOffset = 0x8000;
        !          1332:                         break;
        !          1333: 
        !          1334:                     default:
        !          1335: 
        !          1336:                         NdisWriteErrorLogEntry(
        !          1337:                             Adapter->NdisAdapterHandle,
        !          1338:                             NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !          1339:                             0
        !          1340:                             );
        !          1341: 
        !          1342:                         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1343: 
        !          1344:                         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1345: 
        !          1346:                         return NDIS_STATUS_FAILURE;
        !          1347: 
        !          1348:                 }
        !          1349:                 break;
        !          1350: 
        !          1351:             case 0x10000:
        !          1352: 
        !          1353:                 switch (ConfigValue & 0x07) {
        !          1354: 
        !          1355:                     case 0x00:
        !          1356: 
        !          1357:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC0000);
        !          1358:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1359:                         break;
        !          1360: 
        !          1361:                     case 0x01:
        !          1362: 
        !          1363:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xE0000);
        !          1364:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1365:                         break;
        !          1366: 
        !          1367:                     case 0x02:
        !          1368: 
        !          1369:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD0000);
        !          1370:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1371:                         break;
        !          1372: 
        !          1373:                     case 0x03:
        !          1374: 
        !          1375:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xF0000);
        !          1376:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1377:                         break;
        !          1378: 
        !          1379:                     default:
        !          1380: 
        !          1381:                         NdisWriteErrorLogEntry(
        !          1382:                             Adapter->NdisAdapterHandle,
        !          1383:                             NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !          1384:                             0
        !          1385:                             );
        !          1386: 
        !          1387:                         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1388: 
        !          1389:                         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1390: 
        !          1391:                         return NDIS_STATUS_FAILURE;
        !          1392: 
        !          1393:                 }
        !          1394:                 break;
        !          1395: 
        !          1396:             case 0x20000:
        !          1397: 
        !          1398:                 switch (ConfigValue & 0x07) {
        !          1399: 
        !          1400:                     case 0x00:
        !          1401: 
        !          1402:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xC0000);
        !          1403:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1404:                         break;
        !          1405: 
        !          1406:                     case 0x01:
        !          1407: 
        !          1408:                         Adapter->HardwareBaseAddr = (PVOID)((HiBaseValue << 24) + 0xD0000);
        !          1409:                         Adapter->HardwareBaseOffset = 0x0000;
        !          1410:                         break;
        !          1411: 
        !          1412:                     default:
        !          1413: 
        !          1414:                         NdisWriteErrorLogEntry(
        !          1415:                             Adapter->NdisAdapterHandle,
        !          1416:                             NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !          1417:                             0
        !          1418:                             );
        !          1419: 
        !          1420:                         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1421: 
        !          1422:                         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1423: 
        !          1424:                         return NDIS_STATUS_FAILURE;
        !          1425: 
        !          1426:                 }
        !          1427: 
        !          1428:                 break;
        !          1429: 
        !          1430:         }
        !          1431: 
        !          1432:     }
        !          1433: 
        !          1434:     //
        !          1435:     // Set the port addresses and the network address.
        !          1436:     //
        !          1437: 
        !          1438:     Adapter->InterruptsStopped = FALSE;
        !          1439:     Adapter->MaxMulticastList = MaxMulticastList;
        !          1440: 
        !          1441:     Status = LanceRegisterAdapter(
        !          1442:                            Adapter
        !          1443:                            );
        !          1444: 
        !          1445:     if (Status != NDIS_STATUS_SUCCESS) {
        !          1446: 
        !          1447: 
        !          1448: 
        !          1449:         //
        !          1450:         // LanceRegisterAdapter failed.
        !          1451:         //
        !          1452: 
        !          1453:         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1454: 
        !          1455:         LANCE_FREE_PHYS(Adapter, sizeof(LANCE_ADAPTER));
        !          1456: 
        !          1457:         return NDIS_STATUS_FAILURE;
        !          1458: 
        !          1459:     }
        !          1460: 
        !          1461:     return NDIS_STATUS_SUCCESS;
        !          1462: }
        !          1463: 
        !          1464: 
        !          1465: VOID
        !          1466: LanceRemoveAdapter(
        !          1467:     IN PVOID MacAdapterContext
        !          1468:     )
        !          1469: /*++
        !          1470: 
        !          1471: Routine Description:
        !          1472: 
        !          1473:     LanceRemoveAdapter removes an adapter previously registered
        !          1474:     with NdisRegisterAdapter.
        !          1475: 
        !          1476: Arguments:
        !          1477: 
        !          1478:     MacAdapterContext - The context value that the MAC passed
        !          1479:         to NdisRegisterAdapter; actually as pointer to an
        !          1480:         LANCE_ADAPTER.
        !          1481: 
        !          1482: Return Value:
        !          1483: 
        !          1484:     None.
        !          1485: 
        !          1486: --*/
        !          1487: {
        !          1488: 
        !          1489:     PLANCE_ADAPTER Adapter;
        !          1490:     BOOLEAN Canceled;
        !          1491: 
        !          1492:     Adapter = PLANCE_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
        !          1493: 
        !          1494:     //
        !          1495:     // There are no opens left, so remove ourselves.
        !          1496:     //
        !          1497: 
        !          1498: #if LANCELOG
        !          1499:     if (LogTimerRunning) {
        !          1500:         NdisCancelTimer(&LogTimer, &Canceled);
        !          1501:         LogTimerRunning = FALSE;
        !          1502:     }
        !          1503: #endif
        !          1504: 
        !          1505:     NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled);
        !          1506: 
        !          1507:     if ( !Canceled ) {
        !          1508: 
        !          1509:         NdisStallExecution(500000);
        !          1510:     }
        !          1511: 
        !          1512:     NdisRemoveInterrupt(&(Adapter->Interrupt));
        !          1513: 
        !          1514:     NdisUnmapIoSpace(
        !          1515:            Adapter->NdisAdapterHandle,
        !          1516:            Adapter->MmMappedBaseAddr,
        !          1517:            Adapter->AmountOfHardwareMemory
        !          1518:            );
        !          1519: 
        !          1520:     EthDeleteFilter(Adapter->FilterDB);
        !          1521: 
        !          1522:     NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          1523: 
        !          1524:     NdisFreeSpinLock(&Adapter->Lock);
        !          1525: 
        !          1526:     NdisFreeMemory(Adapter, sizeof(LANCE_ADAPTER), 0);
        !          1527: 
        !          1528:     return;
        !          1529: }
        !          1530: 
        !          1531: VOID
        !          1532: LanceUnload(
        !          1533:     IN NDIS_HANDLE MacMacContext
        !          1534:     )
        !          1535: 
        !          1536: /*++
        !          1537: 
        !          1538: Routine Description:
        !          1539: 
        !          1540:     LanceUnload is called when the MAC is to unload itself.
        !          1541: 
        !          1542: Arguments:
        !          1543: 
        !          1544:     MacMacContext - not used.
        !          1545: 
        !          1546: Return Value:
        !          1547: 
        !          1548:     None.
        !          1549: 
        !          1550: --*/
        !          1551: 
        !          1552: {
        !          1553:     NDIS_STATUS InitStatus;
        !          1554: 
        !          1555:     UNREFERENCED_PARAMETER(MacMacContext);
        !          1556: 
        !          1557:     NdisDeregisterMac(
        !          1558:             &InitStatus,
        !          1559:             LanceMacHandle
        !          1560:             );
        !          1561: 
        !          1562:     NdisTerminateWrapper(
        !          1563:             LanceNdisWrapperHandle,
        !          1564:             NULL
        !          1565:             );
        !          1566: 
        !          1567:     return;
        !          1568: }
        !          1569: 
        !          1570: LanceRegisterAdapter(
        !          1571:     IN PLANCE_ADAPTER Adapter
        !          1572:     )
        !          1573: 
        !          1574: /*++
        !          1575: 
        !          1576: Routine Description:
        !          1577: 
        !          1578:     This routine (and its interface) are not portable.  They are
        !          1579:     defined by the OS, the architecture, and the particular LANCE
        !          1580:     implementation.
        !          1581: 
        !          1582:     This routine is responsible for the allocation of the datastructures
        !          1583:     for the driver as well as any hardware specific details necessary
        !          1584:     to talk with the device.
        !          1585: 
        !          1586: Arguments:
        !          1587: 
        !          1588:     Adapter - Pointer to the adapter block.
        !          1589: 
        !          1590: Return Value:
        !          1591: 
        !          1592:     Returns false if anything occurred that prevents the initialization
        !          1593:     of the adapter.
        !          1594: 
        !          1595: --*/
        !          1596: {
        !          1597: 
        !          1598:     //
        !          1599:     // Result of Ndis Calls.
        !          1600:     //
        !          1601:     NDIS_STATUS Status;
        !          1602: 
        !          1603: 
        !          1604:     //
        !          1605:     // We put in this assertion to make sure that ushort are 2 bytes.
        !          1606:     // if they aren't then the initialization block definition needs
        !          1607:     // to be changed.
        !          1608:     //
        !          1609:     // Also all of the logic that deals with status registers assumes
        !          1610:     // that control registers are only 2 bytes.
        !          1611:     //
        !          1612: 
        !          1613:     ASSERT(sizeof(USHORT) == 2);
        !          1614: 
        !          1615:     //
        !          1616:     // This assertion checks that the network address in the initialization
        !          1617:     // block does start on the third byte of the initalization block.
        !          1618:     //
        !          1619:     // If this is true then other fields in the initialization block
        !          1620:     // and the send and receive descriptors should be at their correct
        !          1621:     // locations.
        !          1622:     //
        !          1623: 
        !          1624:     ASSERT(FIELD_OFFSET(LANCE_INITIALIZATION_BLOCK,PhysicalAddress[0]) == 2);
        !          1625: 
        !          1626: 
        !          1627:     //
        !          1628:     // Allocate memory for all of the adapter structures.
        !          1629:     //
        !          1630: 
        !          1631:     Adapter->NumberOfTransmitRings = LANCE_NUMBER_OF_TRANSMIT_RINGS;
        !          1632:     Adapter->LogNumberTransmitRings = LANCE_LOG_TRANSMIT_RINGS;
        !          1633: 
        !          1634: #ifndef i386
        !          1635: 
        !          1636:     if (Adapter->LanceCard == LANCE_DECTC) {
        !          1637: 
        !          1638:         Status = LanceDecTcSoftwareDetails(Adapter);
        !          1639:         if (Status != NDIS_STATUS_SUCCESS) {
        !          1640:             return Status;
        !          1641:         }
        !          1642: 
        !          1643:     } else
        !          1644: 
        !          1645: 
        !          1646: #endif
        !          1647: 
        !          1648:     {
        !          1649: 
        !          1650:         if (Adapter->AmountOfHardwareMemory == 0x20000) {
        !          1651: 
        !          1652:             ASSERT(Adapter->LanceCard == LANCE_DE422);
        !          1653: 
        !          1654:             Adapter->SizeOfReceiveBuffer  = LANCE_128K_SIZE_OF_RECEIVE_BUFFERS;
        !          1655:             Adapter->NumberOfSmallBuffers = LANCE_128K_NUMBER_OF_SMALL_BUFFERS;
        !          1656:             Adapter->NumberOfMediumBuffers= LANCE_128K_NUMBER_OF_MEDIUM_BUFFERS;
        !          1657:             Adapter->NumberOfLargeBuffers = LANCE_128K_NUMBER_OF_LARGE_BUFFERS;
        !          1658: 
        !          1659:             Adapter->NumberOfReceiveRings = LANCE_128K_NUMBER_OF_RECEIVE_RINGS;
        !          1660:             Adapter->LogNumberReceiveRings = LANCE_128K_LOG_RECEIVE_RINGS;
        !          1661: 
        !          1662:         } else if (Adapter->AmountOfHardwareMemory == 0x10000) {
        !          1663: 
        !          1664:             Adapter->NumberOfReceiveRings = LANCE_64K_NUMBER_OF_RECEIVE_RINGS;
        !          1665:             Adapter->LogNumberReceiveRings = LANCE_64K_LOG_RECEIVE_RINGS;
        !          1666: 
        !          1667:             Adapter->SizeOfReceiveBuffer  = LANCE_64K_SIZE_OF_RECEIVE_BUFFERS;
        !          1668:             Adapter->NumberOfSmallBuffers = LANCE_64K_NUMBER_OF_SMALL_BUFFERS;
        !          1669:             Adapter->NumberOfMediumBuffers= LANCE_64K_NUMBER_OF_MEDIUM_BUFFERS;
        !          1670:             Adapter->NumberOfLargeBuffers = LANCE_64K_NUMBER_OF_LARGE_BUFFERS;
        !          1671: 
        !          1672:         } else {
        !          1673: 
        !          1674:             Adapter->NumberOfReceiveRings = LANCE_32K_NUMBER_OF_RECEIVE_RINGS;
        !          1675:             Adapter->LogNumberReceiveRings = LANCE_32K_LOG_RECEIVE_RINGS;
        !          1676: 
        !          1677:             Adapter->SizeOfReceiveBuffer  = LANCE_32K_SIZE_OF_RECEIVE_BUFFERS;
        !          1678:             Adapter->NumberOfSmallBuffers = LANCE_32K_NUMBER_OF_SMALL_BUFFERS;
        !          1679:             Adapter->NumberOfMediumBuffers= LANCE_32K_NUMBER_OF_MEDIUM_BUFFERS;
        !          1680:             Adapter->NumberOfLargeBuffers = LANCE_32K_NUMBER_OF_LARGE_BUFFERS;
        !          1681: 
        !          1682:         }
        !          1683: 
        !          1684:     }
        !          1685: 
        !          1686: #ifndef i386
        !          1687: 
        !          1688:     if (((Adapter->LanceCard == LANCE_DECTC) &&
        !          1689:         (LanceDecTcHardwareDetails(Adapter) == NDIS_STATUS_SUCCESS)) ||
        !          1690:         LanceHardwareDetails(Adapter)) {
        !          1691: 
        !          1692: #else
        !          1693: 
        !          1694:     if (LanceHardwareDetails(Adapter)) {
        !          1695: 
        !          1696: #endif
        !          1697: 
        !          1698:         NDIS_PHYSICAL_ADDRESS PhysicalAddress;
        !          1699: 
        !          1700:         //
        !          1701:         // Get hold of the RAP and RDP address as well
        !          1702:         // as filling in the hardware assigned network
        !          1703:         // address.
        !          1704:         //
        !          1705: 
        !          1706:         if ((Adapter->CurrentNetworkAddress[0] == 0x00) &&
        !          1707:             (Adapter->CurrentNetworkAddress[1] == 0x00) &&
        !          1708:             (Adapter->CurrentNetworkAddress[2] == 0x00) &&
        !          1709:             (Adapter->CurrentNetworkAddress[3] == 0x00) &&
        !          1710:             (Adapter->CurrentNetworkAddress[4] == 0x00) &&
        !          1711:             (Adapter->CurrentNetworkAddress[5] == 0x00)) {
        !          1712: 
        !          1713:             Adapter->CurrentNetworkAddress[0] = Adapter->NetworkAddress[0];
        !          1714:             Adapter->CurrentNetworkAddress[1] = Adapter->NetworkAddress[1];
        !          1715:             Adapter->CurrentNetworkAddress[2] = Adapter->NetworkAddress[2];
        !          1716:             Adapter->CurrentNetworkAddress[3] = Adapter->NetworkAddress[3];
        !          1717:             Adapter->CurrentNetworkAddress[4] = Adapter->NetworkAddress[4];
        !          1718:             Adapter->CurrentNetworkAddress[5] = Adapter->NetworkAddress[5];
        !          1719: 
        !          1720:         }
        !          1721: 
        !          1722:         NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
        !          1723:         NdisSetPhysicalAddressLow(PhysicalAddress, (ULONG)(Adapter->HardwareBaseAddr));
        !          1724: 
        !          1725:         NdisMapIoSpace(
        !          1726:            &Status,
        !          1727:            &(Adapter->MmMappedBaseAddr),
        !          1728:            Adapter->NdisAdapterHandle,
        !          1729:            PhysicalAddress,
        !          1730:            Adapter->AmountOfHardwareMemory
        !          1731:            );
        !          1732: 
        !          1733:         if (Status != NDIS_STATUS_SUCCESS) {
        !          1734: 
        !          1735:             NdisWriteErrorLogEntry(
        !          1736:                 Adapter->NdisAdapterHandle,
        !          1737:                 NDIS_ERROR_CODE_RESOURCE_CONFLICT,
        !          1738:                 0
        !          1739:                 );
        !          1740: 
        !          1741:             return(Status);
        !          1742: 
        !          1743:         }
        !          1744: 
        !          1745:         Adapter->CurrentMemoryFirstFree = Adapter->MmMappedBaseAddr;
        !          1746: 
        !          1747: 
        !          1748:         Adapter->MemoryFirstUnavailable =
        !          1749:                 (PUCHAR)(Adapter->CurrentMemoryFirstFree) +
        !          1750:                 Adapter->AmountOfHardwareMemory;
        !          1751: 
        !          1752:         if (!AllocateAdapterMemory(Adapter)) {
        !          1753: 
        !          1754:             NdisWriteErrorLogEntry(
        !          1755:                 Adapter->NdisAdapterHandle,
        !          1756:                 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1757:                 0
        !          1758:                 );
        !          1759: 
        !          1760:             return( NDIS_STATUS_ADAPTER_NOT_FOUND );
        !          1761: 
        !          1762:         }
        !          1763: 
        !          1764:         InitializeListHead(&Adapter->OpenBindings);
        !          1765:         InitializeListHead(&Adapter->CloseList);
        !          1766: 
        !          1767:         NdisAllocateSpinLock(&Adapter->Lock);
        !          1768: 
        !          1769:         Adapter->InterruptDPC = (PVOID)LanceStandardInterruptDPC;
        !          1770:         Adapter->LoopbackDPC  = (PVOID)LanceStandardInterruptDPC;
        !          1771: 
        !          1772: 
        !          1773:         Adapter->AllocateableRing = Adapter->TransmitRing;
        !          1774:         Adapter->TransmittingRing = Adapter->TransmitRing;
        !          1775:         Adapter->FirstUncommittedRing = Adapter->TransmitRing;
        !          1776:         Adapter->NumberOfAvailableRings = Adapter->NumberOfTransmitRings;
        !          1777:         Adapter->LastTransmitRingEntry = Adapter->TransmitRing +
        !          1778:                 (Adapter->NumberOfTransmitRings-1);
        !          1779: 
        !          1780:         Adapter->FirstLoopBack = NULL;
        !          1781:         Adapter->LastLoopBack = NULL;
        !          1782:         Adapter->FirstFinishTransmit = NULL;
        !          1783:         Adapter->LastFinishTransmit = NULL;
        !          1784:         Adapter->StageOpen = TRUE;
        !          1785:         Adapter->AlreadyProcessingStage = FALSE;
        !          1786:         Adapter->FirstStage1Packet = NULL;
        !          1787:         Adapter->LastStage1Packet = NULL;
        !          1788:         Adapter->CurrentReceiveIndex = 0;
        !          1789:         Adapter->OutOfReceiveBuffers = 0;
        !          1790:         Adapter->CRCError = 0;
        !          1791:         Adapter->FramingError = 0;
        !          1792:         Adapter->RetryFailure = 0;
        !          1793:         Adapter->LostCarrier = 0;
        !          1794:         Adapter->LateCollision = 0;
        !          1795:         Adapter->UnderFlow = 0;
        !          1796:         Adapter->Deferred = 0;
        !          1797:         Adapter->OneRetry = 0;
        !          1798:         Adapter->MoreThanOneRetry = 0;
        !          1799:         Adapter->ResetInProgress = FALSE;
        !          1800:         Adapter->ResetInitStarted = FALSE;
        !          1801:         Adapter->ResettingOpen = NULL;
        !          1802:         Adapter->FirstInitialization = TRUE;
        !          1803:         Adapter->HardwareFailure = FALSE;
        !          1804:         Adapter->PendQueue = NULL;
        !          1805:         Adapter->PendQueueTail = NULL;
        !          1806: 
        !          1807:         //
        !          1808:         // First we make sure that the device is stopped.  We call
        !          1809:         // directly since we don't have an Interrupt object yet.
        !          1810:         //
        !          1811: 
        !          1812:         LanceSyncStopChip(Adapter);
        !          1813: 
        !          1814: 
        !          1815:         //
        !          1816:         // Initialize the interrupt.
        !          1817:         //
        !          1818: 
        !          1819:         NdisInitializeInterrupt(
        !          1820:                 &Status,
        !          1821:                 &Adapter->Interrupt,
        !          1822:                 Adapter->NdisAdapterHandle,
        !          1823:                 (PNDIS_INTERRUPT_SERVICE)LanceISR,
        !          1824:                 Adapter,
        !          1825:                 (PNDIS_DEFERRED_PROCESSING)Adapter->InterruptDPC,
        !          1826:                 Adapter->InterruptNumber,
        !          1827:                 Adapter->InterruptRequestLevel,
        !          1828:                 FALSE,
        !          1829:                 NdisInterruptLatched
        !          1830:                 );
        !          1831: 
        !          1832:         if (Status != NDIS_STATUS_SUCCESS){
        !          1833: 
        !          1834:             NdisWriteErrorLogEntry(
        !          1835:                 Adapter->NdisAdapterHandle,
        !          1836:                 NDIS_ERROR_CODE_INTERRUPT_CONNECT,
        !          1837:                 0
        !          1838:                 );
        !          1839: 
        !          1840:             NdisUnmapIoSpace(
        !          1841:                 Adapter->NdisAdapterHandle,
        !          1842:                 Adapter->MmMappedBaseAddr,
        !          1843:                 Adapter->AmountOfHardwareMemory);
        !          1844: 
        !          1845:             DeleteAdapterMemory(Adapter);
        !          1846: 
        !          1847:             return Status;
        !          1848:         }
        !          1849: 
        !          1850: 
        !          1851:         if (!EthCreateFilter(
        !          1852:                          Adapter->MaxMulticastList,
        !          1853:                          LanceChangeMulticastAddresses,
        !          1854:                          LanceChangeFilterClasses,
        !          1855:                          LanceCloseAction,
        !          1856:                          Adapter->CurrentNetworkAddress,
        !          1857:                          &Adapter->Lock,
        !          1858:                          &Adapter->FilterDB
        !          1859:                          )) {
        !          1860: 
        !          1861:             NdisWriteErrorLogEntry(
        !          1862:                 Adapter->NdisAdapterHandle,
        !          1863:                 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1864:                 0
        !          1865:                 );
        !          1866: 
        !          1867:             NdisUnmapIoSpace(
        !          1868:                 Adapter->NdisAdapterHandle,
        !          1869:                 Adapter->MmMappedBaseAddr,
        !          1870:                 Adapter->AmountOfHardwareMemory);
        !          1871: 
        !          1872:             DeleteAdapterMemory(Adapter);
        !          1873: 
        !          1874:             NdisRemoveInterrupt(&Adapter->Interrupt);
        !          1875: 
        !          1876:             return NDIS_STATUS_RESOURCES;
        !          1877: 
        !          1878:         }
        !          1879: 
        !          1880:         if ((Status = LanceInitialInit(Adapter)) != NDIS_STATUS_SUCCESS) {
        !          1881: 
        !          1882: 
        !          1883:             NdisWriteErrorLogEntry(
        !          1884:                 Adapter->NdisAdapterHandle,
        !          1885:                 NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !          1886:                 0
        !          1887:                 );
        !          1888: 
        !          1889:             EthDeleteFilter(Adapter->FilterDB);
        !          1890: 
        !          1891:             NdisUnmapIoSpace(
        !          1892:                 Adapter->NdisAdapterHandle,
        !          1893:                 Adapter->MmMappedBaseAddr,
        !          1894:                 Adapter->AmountOfHardwareMemory);
        !          1895: 
        !          1896:             DeleteAdapterMemory(Adapter);
        !          1897: 
        !          1898:             NdisRemoveInterrupt(&Adapter->Interrupt);
        !          1899: 
        !          1900:             return Status;
        !          1901: 
        !          1902:         }
        !          1903: 
        !          1904:         //
        !          1905:         // Initialize the wake up timer to catch interrupts that
        !          1906:         // don't complete. It fires continuously
        !          1907:         // every 5 seconds, and we check if there are any
        !          1908:         // uncompleted operations from the previous two-second
        !          1909:         // period.
        !          1910:         //
        !          1911: 
        !          1912:         Adapter->WakeUpDpc = (PVOID)LanceWakeUpDpc;
        !          1913: 
        !          1914:         NdisInitializeTimer(&Adapter->WakeUpTimer,
        !          1915:                             (PVOID)(Adapter->WakeUpDpc),
        !          1916:                             Adapter );
        !          1917: 
        !          1918:         NdisSetTimer(
        !          1919:             &Adapter->WakeUpTimer,
        !          1920:             5000
        !          1921:             );
        !          1922: 
        !          1923:         return Status;
        !          1924: 
        !          1925:     } else {
        !          1926: 
        !          1927:         NdisWriteErrorLogEntry(
        !          1928:                 Adapter->NdisAdapterHandle,
        !          1929:                 NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
        !          1930:                 0
        !          1931:                 );
        !          1932: 
        !          1933:         return NDIS_STATUS_FAILURE;
        !          1934: 
        !          1935:     }
        !          1936: 
        !          1937: }
        !          1938: 
        !          1939: extern
        !          1940: NDIS_STATUS
        !          1941: LanceInitialInit(
        !          1942:     IN PLANCE_ADAPTER Adapter
        !          1943:     )
        !          1944: 
        !          1945: /*++
        !          1946: 
        !          1947: Routine Description:
        !          1948: 
        !          1949:     This routine sets up the initial init of the driver.
        !          1950: 
        !          1951: Arguments:
        !          1952: 
        !          1953:     Adapter - The adapter for the hardware.
        !          1954: 
        !          1955: Return Value:
        !          1956: 
        !          1957:     None.
        !          1958: 
        !          1959: --*/
        !          1960: 
        !          1961: {
        !          1962: 
        !          1963:     if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) {
        !          1964: 
        !          1965:         //
        !          1966:         // Allow interrupts
        !          1967:         //
        !          1968: 
        !          1969:         Adapter->InterruptsStopped = FALSE;
        !          1970: 
        !          1971:         LOG(UNPEND);
        !          1972: 
        !          1973:         LANCE_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON);
        !          1974: 
        !          1975:     }
        !          1976: 
        !          1977:     SetInitBlockAndInit(Adapter);
        !          1978: 
        !          1979:     //
        !          1980:     // Delay execution for 1/2 second to give the lance
        !          1981:     // time to initialize.
        !          1982:     //
        !          1983: 
        !          1984: 
        !          1985:     NdisStallExecution( 500000 );
        !          1986: 
        !          1987:     NdisAcquireSpinLock(&Adapter->Lock);
        !          1988: 
        !          1989:     //
        !          1990:     // The only way that first initialization could have
        !          1991:     // been turned off is if we actually initialized.
        !          1992:     //
        !          1993: 
        !          1994:     if (!Adapter->FirstInitialization) {
        !          1995: 
        !          1996:         //
        !          1997:         // Initialize the Deferred processing timer.
        !          1998:         //
        !          1999: 
        !          2000:         NdisInitializeTimer(&Adapter->DeferredTimer,
        !          2001:                             Adapter->LoopbackDPC,
        !          2002:                             Adapter);
        !          2003: 
        !          2004: #if LANCELOG
        !          2005: 
        !          2006:         if (!LogTimerRunning) {
        !          2007: 
        !          2008:             NdisInitializeTimer(&LogTimer,
        !          2009:                                 (PVOID)LogDpc,
        !          2010:                                 (PVOID)(&LogTimer)
        !          2011:                                );
        !          2012: 
        !          2013:             NdisSetTimer(&LogTimer,1000);
        !          2014: 
        !          2015:             LogTimerRunning = TRUE;
        !          2016: 
        !          2017:         }
        !          2018: 
        !          2019: #endif
        !          2020: 
        !          2021:         //
        !          2022:         // We actually did get the initialization.
        !          2023:         //
        !          2024: 
        !          2025:         NdisReleaseSpinLock(&Adapter->Lock);
        !          2026: 
        !          2027:         //
        !          2028:         // We can start the chip.  We may not
        !          2029:         // have any bindings to indicateto but this
        !          2030:         // is unimportant.
        !          2031:         //
        !          2032: 
        !          2033:         LanceStartChip(Adapter);
        !          2034: 
        !          2035: 
        !          2036:         return NDIS_STATUS_SUCCESS;
        !          2037: 
        !          2038: 
        !          2039:     } else {
        !          2040: 
        !          2041:         NdisReleaseSpinLock(&Adapter->Lock);
        !          2042: 
        !          2043:         return NDIS_STATUS_FAILURE;
        !          2044: 
        !          2045:     }
        !          2046: 
        !          2047: }
        !          2048: 
        !          2049: STATIC
        !          2050: VOID
        !          2051: LanceStartChip(
        !          2052:     IN PLANCE_ADAPTER Adapter
        !          2053:     )
        !          2054: 
        !          2055: /*++
        !          2056: 
        !          2057: Routine Description:
        !          2058: 
        !          2059:     This routine is used to start an already initialized lance.
        !          2060: 
        !          2061: Arguments:
        !          2062: 
        !          2063:     Adapter - The adapter for the LANCE to start.
        !          2064: 
        !          2065: Return Value:
        !          2066: 
        !          2067:     None.
        !          2068: 
        !          2069: --*/
        !          2070: 
        !          2071: {
        !          2072: 
        !          2073:     if (Adapter->ResetInProgress) {
        !          2074: 
        !          2075:         return;
        !          2076: 
        !          2077:     }
        !          2078: 
        !          2079:     //
        !          2080:     // Set the RAP to csr0.
        !          2081:     //
        !          2082: 
        !          2083:     LANCE_WRITE_RAP(
        !          2084:         Adapter,
        !          2085:         LANCE_SELECT_CSR0
        !          2086:         );
        !          2087: 
        !          2088:     //
        !          2089:     // Set the RDP to a start chip.
        !          2090:     //
        !          2091: 
        !          2092:     LANCE_WRITE_RDP(
        !          2093:         Adapter,
        !          2094:         LANCE_CSR0_START | LANCE_CSR0_INTERRUPT_ENABLE
        !          2095:         );
        !          2096: 
        !          2097: }
        !          2098: 
        !          2099: STATIC
        !          2100: BOOLEAN
        !          2101: LanceInterruptSynch(
        !          2102:     IN PVOID Context
        !          2103:     )
        !          2104: 
        !          2105: /*++
        !          2106: 
        !          2107: Routine Description:
        !          2108: 
        !          2109:     This routine is used by the normal interrupt processing routine
        !          2110:     to synchronize with interrupts from the card.  It will or
        !          2111:     the value of the stored csr 0 into the other passed address
        !          2112:     in the context and clear the stored csr 0 value.
        !          2113:     block and clear the stored csr0.
        !          2114: 
        !          2115: Arguments:
        !          2116: 
        !          2117:     Context - This is really a pointer to a record type peculiar
        !          2118:     to this routine.  The record contains a pointer to the adapter
        !          2119:     and a pointer to an address in which to place the contents
        !          2120:     of csr 0.
        !          2121: 
        !          2122: Return Value:
        !          2123: 
        !          2124:     Always returns true.
        !          2125: 
        !          2126: --*/
        !          2127: 
        !          2128: {
        !          2129: 
        !          2130:     PLANCE_SYNCH_CONTEXT C = Context;
        !          2131: 
        !          2132:     *(C->LocalRead) = *(C->LocalRead) | C->Adapter->CSR0Value;
        !          2133: 
        !          2134:     C->Adapter->CSR0Value = 0;
        !          2135: 
        !          2136:     return TRUE;
        !          2137: 
        !          2138: }
        !          2139: 
        !          2140: extern
        !          2141: BOOLEAN
        !          2142: LanceISR(
        !          2143:     IN PVOID Context
        !          2144:     )
        !          2145: 
        !          2146: /*++
        !          2147: 
        !          2148: Routine Description:
        !          2149: 
        !          2150:     Interrupt service routine for the lance.  It's main job is
        !          2151:     to get the value of CSR0 and record the changes in the
        !          2152:     adapters own list of interrupt reasons.
        !          2153: 
        !          2154: Arguments:
        !          2155: 
        !          2156:     Context - Really a pointer to the adapter.
        !          2157: 
        !          2158: Return Value:
        !          2159: 
        !          2160:     Returns true if the INTR bit of CSR0 of the lance is enabled.
        !          2161: 
        !          2162: --*/
        !          2163: 
        !          2164: {
        !          2165: 
        !          2166:     //
        !          2167:     // Will hold the value from the csr.
        !          2168:     //
        !          2169:     USHORT LocalCSR0Value;
        !          2170: 
        !          2171:     //
        !          2172:     // Holds the pointer to the adapter.
        !          2173:     //
        !          2174:     PLANCE_ADAPTER Adapter = Context;
        !          2175: 
        !          2176:     BOOLEAN StoppedInterrupts=FALSE;
        !          2177: 
        !          2178:     LOG(IN_ISR);
        !          2179: 
        !          2180:     if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) {
        !          2181: 
        !          2182:         //
        !          2183:         // If not currently pended, pend interrupts...
        !          2184:         //
        !          2185: 
        !          2186:         if (!(Adapter->InterruptsStopped)){
        !          2187: 
        !          2188:             //
        !          2189:             // Pend interrupts
        !          2190:             //
        !          2191: 
        !          2192:             StoppedInterrupts = TRUE;
        !          2193: 
        !          2194:             Adapter->InterruptsStopped = TRUE;
        !          2195: 
        !          2196:             LOG(PEND);
        !          2197: 
        !          2198:             LANCE_ISR_WRITE_NICSR(Adapter,
        !          2199:                 LANCE_NICSR_IMASK | LANCE_NICSR_LED_ON | LANCE_NICSR_INT_ON);
        !          2200: 
        !          2201:         }
        !          2202: 
        !          2203:     }
        !          2204: 
        !          2205:     //
        !          2206:     // We don't need to select csr0, as the only way we could get
        !          2207:     // an interrupt is to have already selected 0.
        !          2208:     //
        !          2209: 
        !          2210:     LANCE_ISR_READ_RDP(Adapter, &LocalCSR0Value);
        !          2211: 
        !          2212:     if (LocalCSR0Value & LANCE_CSR0_INTERRUPT_FLAG) {
        !          2213: 
        !          2214:         //
        !          2215:         // It's our interrupt. Clear only those bits that we got
        !          2216:         // in this read of csr0.  We do it this way incase any new
        !          2217:         // reasons for interrupts occur between the time that we
        !          2218:         // read csr0 and the time that we clear the bits.
        !          2219:         //
        !          2220: 
        !          2221:         LANCE_ISR_WRITE_RDP(
        !          2222:             Adapter,
        !          2223:             (USHORT)((LANCE_CSR0_CLEAR_INTERRUPT_BITS & LocalCSR0Value) |
        !          2224:                LANCE_CSR0_INTERRUPT_ENABLE)
        !          2225:             );
        !          2226: 
        !          2227: 
        !          2228:         if (Adapter->FirstInitialization &&
        !          2229:             (LocalCSR0Value & LANCE_CSR0_INITIALIZATION_DONE)) {
        !          2230: 
        !          2231:             Adapter->FirstInitialization = FALSE;
        !          2232: 
        !          2233:             if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) &&
        !          2234:                 StoppedInterrupts) {
        !          2235: 
        !          2236:                 //
        !          2237:                 // Allow interrupts
        !          2238:                 //
        !          2239: 
        !          2240:                 Adapter->InterruptsStopped = FALSE;
        !          2241: 
        !          2242:                 LOG(UNPEND);
        !          2243: 
        !          2244:                 LANCE_ISR_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON);
        !          2245: 
        !          2246:             }
        !          2247: 
        !          2248:             LOG(OUT_ISR);
        !          2249: 
        !          2250:             return FALSE;
        !          2251: 
        !          2252:         } else {
        !          2253: 
        !          2254:             //
        !          2255:             // Or the csr value into the adapter version of csr 0.
        !          2256:             //
        !          2257: 
        !          2258:             Adapter->CSR0Value |= LocalCSR0Value;
        !          2259: 
        !          2260:             LOG(OUT_ISR);
        !          2261: 
        !          2262:             return TRUE;
        !          2263: 
        !          2264:         }
        !          2265: 
        !          2266:     } else {
        !          2267: 
        !          2268:         if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) &&
        !          2269:             StoppedInterrupts) {
        !          2270: 
        !          2271:             //
        !          2272:             // Allow interrupts
        !          2273:             //
        !          2274: 
        !          2275:             Adapter->InterruptsStopped = FALSE;
        !          2276: 
        !          2277:             LOG(UNPEND);
        !          2278: 
        !          2279:             LANCE_ISR_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON);
        !          2280: 
        !          2281:         }
        !          2282: 
        !          2283:         LOG(OUT_ISR);
        !          2284: 
        !          2285:         return FALSE;
        !          2286: 
        !          2287:     }
        !          2288: 
        !          2289: }
        !          2290: 
        !          2291: STATIC
        !          2292: VOID
        !          2293: LanceStandardInterruptDPC(
        !          2294:     IN PVOID SystemSpecific,
        !          2295:     IN PVOID Context,
        !          2296:     IN PVOID SystemArgument1,
        !          2297:     IN PVOID SystemArgument2
        !          2298:     )
        !          2299: 
        !          2300: /*++
        !          2301: 
        !          2302: Routine Description:
        !          2303: 
        !          2304:     This DPC routine is queued by the interrupt service routine
        !          2305:     and other routines within the driver that notice that
        !          2306:     some deferred processing needs to be done.  It's main
        !          2307:     job is to call the interrupt processing code.
        !          2308: 
        !          2309: Arguments:
        !          2310: 
        !          2311:     SystemSpecific - not used.
        !          2312: 
        !          2313:     Context - Really a pointer to the adapter.
        !          2314: 
        !          2315: 
        !          2316:     SystemArgument1 - Flag if we should turn interrupts on when done
        !          2317:     processing.
        !          2318: 
        !          2319:     SystemArgument2 - Not used.
        !          2320: 
        !          2321: Return Value:
        !          2322: 
        !          2323:     None.
        !          2324: 
        !          2325: --*/
        !          2326: 
        !          2327: {
        !          2328:     //
        !          2329:     // Holds the pointer to the adapter.
        !          2330:     //
        !          2331:     PLANCE_ADAPTER Adapter = Context;
        !          2332: 
        !          2333:     USHORT InterruptsStopped;
        !          2334: 
        !          2335:     UNREFERENCED_PARAMETER(SystemSpecific);
        !          2336:     UNREFERENCED_PARAMETER(SystemArgument1);
        !          2337:     UNREFERENCED_PARAMETER(SystemArgument2);
        !          2338: 
        !          2339:     LOG(IN_DPC);
        !          2340: 
        !          2341:     NdisDprAcquireSpinLock(&Adapter->Lock);
        !          2342: 
        !          2343:     if (Adapter->ProcessInterruptRunning) {
        !          2344: 
        !          2345:         LOG(OUT_DPC);
        !          2346: 
        !          2347:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          2348: 
        !          2349:         return;
        !          2350: 
        !          2351:     }
        !          2352: 
        !          2353:     Adapter->ProcessInterruptRunning = TRUE;
        !          2354: 
        !          2355:     ProcessInterrupt(Adapter);
        !          2356: 
        !          2357:     InterruptsStopped = Adapter->InterruptsStopped;
        !          2358: 
        !          2359:     if ((Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) &&
        !          2360:         InterruptsStopped) {
        !          2361: 
        !          2362:         //
        !          2363:         // Allow interrupts
        !          2364:         //
        !          2365: 
        !          2366:         LOG(UNPEND);
        !          2367: 
        !          2368:         LOG(OUT_DPC);
        !          2369: 
        !          2370: 
        !          2371:         //
        !          2372:         // Safe to write here since the ISR will not fire with interrupts stopped.
        !          2373:         //
        !          2374: 
        !          2375:         Adapter->InterruptsStopped = FALSE;
        !          2376: 
        !          2377:         LANCE_WRITE_NICSR(Adapter, LANCE_NICSR_INT_ON);
        !          2378: 
        !          2379:     } else {
        !          2380: 
        !          2381:         LOG(OUT_DPC);
        !          2382: 
        !          2383:     }
        !          2384: 
        !          2385:     NdisDprReleaseSpinLock(&Adapter->Lock);
        !          2386: 
        !          2387: }
        !          2388: 
        !          2389: STATIC
        !          2390: BOOLEAN
        !          2391: AllocateAdapterMemory(
        !          2392:     IN PLANCE_ADAPTER Adapter
        !          2393:     )
        !          2394: 
        !          2395: /*++
        !          2396: 
        !          2397: Routine Description:
        !          2398: 
        !          2399:     This routine allocates memory for:
        !          2400: 
        !          2401:     - Transmit ring entries
        !          2402: 
        !          2403:     - Receive ring entries
        !          2404: 
        !          2405:     - Receive buffers
        !          2406: 
        !          2407:     - Adapter buffers for use if user transmit buffers don't meet hardware
        !          2408:       contraints
        !          2409: 
        !          2410:     - Structures to map transmit ring entries back to the packets.
        !          2411: 
        !          2412: Arguments:
        !          2413: 
        !          2414:     Adapter - The adapter to allocate memory for.
        !          2415: 
        !          2416: Return Value:
        !          2417: 
        !          2418:     Returns FALSE if some memory needed for the adapter could not
        !          2419:     be allocated.
        !          2420: 
        !          2421: --*/
        !          2422: 
        !          2423: {
        !          2424: 
        !          2425:     //
        !          2426:     // Pointer to a transmit ring entry.  Used while initializing
        !          2427:     // the ring.
        !          2428:     //
        !          2429:     PLANCE_TRANSMIT_ENTRY CurrentTransmitEntry;
        !          2430: 
        !          2431:     //
        !          2432:     // Pointer to a receive ring entry.  Used while initializing
        !          2433:     // the ring.
        !          2434:     //
        !          2435:     PLANCE_RECEIVE_ENTRY CurrentReceiveEntry;
        !          2436: 
        !          2437:     //
        !          2438:     // Simple iteration variable.
        !          2439:     //
        !          2440:     UINT i;
        !          2441: 
        !          2442:     //
        !          2443:     // These variables exist to reduce the amount of checking below.
        !          2444:     //
        !          2445: 
        !          2446:     ULONG NumberOfSmallBuffers;
        !          2447:     ULONG NumberOfMediumBuffers;
        !          2448:     ULONG NumberOfLargeBuffers;
        !          2449: 
        !          2450: 
        !          2451:     NumberOfSmallBuffers = Adapter->NumberOfSmallBuffers;
        !          2452:     NumberOfMediumBuffers = Adapter->NumberOfMediumBuffers;
        !          2453:     NumberOfLargeBuffers = Adapter->NumberOfLargeBuffers;
        !          2454: 
        !          2455: 
        !          2456: 
        !          2457:     //
        !          2458:     // Allocate memory for the initialization block.  Note that
        !          2459:     // this memory can not cross a page boundary.
        !          2460:     //
        !          2461: 
        !          2462:     LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2463:         Adapter,
        !          2464:         sizeof(LANCE_INITIALIZATION_BLOCK),
        !          2465:         &Adapter->InitBlock
        !          2466:         );
        !          2467: 
        !          2468:     if (Adapter->InitBlock == NULL) {
        !          2469:         DeleteAdapterMemory(Adapter);
        !          2470:         return FALSE;
        !          2471:     }
        !          2472: 
        !          2473:     //
        !          2474:     // Allocate the transmit ring descriptors.
        !          2475:     //
        !          2476: 
        !          2477:     LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2478:         Adapter,
        !          2479:         sizeof(LANCE_TRANSMIT_ENTRY)*Adapter->NumberOfTransmitRings,
        !          2480:         &Adapter->TransmitRing
        !          2481:         )
        !          2482: 
        !          2483:     if (Adapter->TransmitRing == NULL) {
        !          2484:         DeleteAdapterMemory(Adapter);
        !          2485:         return FALSE;
        !          2486:     }
        !          2487: 
        !          2488:     //
        !          2489:     // We have the transmit ring descriptors.  Make sure each is
        !          2490:     // in a clean state.
        !          2491:     //
        !          2492: 
        !          2493:     for (
        !          2494:         i = 0, CurrentTransmitEntry = Adapter->TransmitRing;
        !          2495:         i < Adapter->NumberOfTransmitRings;
        !          2496:         i++,CurrentTransmitEntry++
        !          2497:         ) {
        !          2498: 
        !          2499:         LANCE_ZERO_MEMORY_FOR_HARDWARE(
        !          2500:              CurrentTransmitEntry,
        !          2501:              sizeof(LANCE_TRANSMIT_ENTRY)
        !          2502:              );
        !          2503: 
        !          2504:     }
        !          2505: 
        !          2506: 
        !          2507:     //
        !          2508:     // Allocate all of the receive ring entries
        !          2509:     //
        !          2510: 
        !          2511:     LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2512:         Adapter,
        !          2513:         sizeof(LANCE_RECEIVE_ENTRY)*Adapter->NumberOfReceiveRings,
        !          2514:         &Adapter->ReceiveRing
        !          2515:         )
        !          2516: 
        !          2517:     if (Adapter->ReceiveRing == NULL) {
        !          2518:         DeleteAdapterMemory(Adapter);
        !          2519:         return FALSE;
        !          2520:     }
        !          2521: 
        !          2522:     //
        !          2523:     // We have the receive ring descriptors.  Allocate an
        !          2524:     // array to hold the virtual addresses of each receive
        !          2525:     // buffer.
        !          2526:     //
        !          2527: 
        !          2528:     LANCE_ALLOC_PHYS(
        !          2529:           &(Adapter->ReceiveVAs),
        !          2530:           sizeof(PVOID) * Adapter->NumberOfReceiveRings
        !          2531:           );
        !          2532: 
        !          2533:     if (Adapter->ReceiveVAs == NULL) {
        !          2534:         DeleteAdapterMemory(Adapter);
        !          2535:         return FALSE;
        !          2536:     }
        !          2537: 
        !          2538:     //
        !          2539:     // Clean the above memory
        !          2540:     //
        !          2541: 
        !          2542:     LANCE_ZERO_MEMORY(
        !          2543:         Adapter->ReceiveVAs,
        !          2544:         (sizeof(PVOID)*Adapter->NumberOfReceiveRings)
        !          2545:         );
        !          2546: 
        !          2547: 
        !          2548:     //
        !          2549:     // We have the receive ring descriptors.  Allocate a buffer
        !          2550:     // for each descriptor and make sure descriptor is in a clean state.
        !          2551:     //
        !          2552:     // While we're at it, relinquish ownership of the ring discriptors to
        !          2553:     // the lance.
        !          2554:     //
        !          2555: 
        !          2556:     for (
        !          2557:         i = 0, CurrentReceiveEntry = Adapter->ReceiveRing;
        !          2558:         i < Adapter->NumberOfReceiveRings;
        !          2559:         i++,CurrentReceiveEntry++
        !          2560:         ) {
        !          2561: 
        !          2562:         LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2563:             Adapter,
        !          2564:             Adapter->SizeOfReceiveBuffer,
        !          2565:             &Adapter->ReceiveVAs[i]
        !          2566:             );
        !          2567: 
        !          2568:         if (Adapter->ReceiveVAs[i] == NULL) {
        !          2569:             DeleteAdapterMemory(Adapter);
        !          2570:             return FALSE;
        !          2571:         }
        !          2572: 
        !          2573: 
        !          2574:         LANCE_SET_RECEIVE_BUFFER_ADDRESS(
        !          2575:                 Adapter,
        !          2576:                 CurrentReceiveEntry,
        !          2577:                 Adapter->ReceiveVAs[i]
        !          2578:                 );
        !          2579: 
        !          2580: 
        !          2581:         LANCE_SET_RECEIVE_BUFFER_LENGTH(
        !          2582:             CurrentReceiveEntry,
        !          2583:             Adapter->SizeOfReceiveBuffer
        !          2584:             );
        !          2585: 
        !          2586:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          2587:              CurrentReceiveEntry->ReceiveSummaryBits,
        !          2588:              LANCE_RECEIVE_OWNED_BY_CHIP
        !          2589:              );
        !          2590: 
        !          2591: 
        !          2592:     }
        !          2593: 
        !          2594:     //
        !          2595:     // Allocate the ring to packet structure.
        !          2596:     //
        !          2597: 
        !          2598:     LANCE_ALLOC_PHYS(
        !          2599:         &(Adapter->RingToPacket),
        !          2600:         sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings
        !          2601:         );
        !          2602: 
        !          2603:     if (Adapter->RingToPacket == NULL) {
        !          2604:         DeleteAdapterMemory(Adapter);
        !          2605:         return FALSE;
        !          2606:     }
        !          2607: 
        !          2608:     LANCE_ZERO_MEMORY(
        !          2609:         Adapter->RingToPacket,
        !          2610:         sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings
        !          2611:         );
        !          2612: 
        !          2613:     //
        !          2614:     // Allocate the array of buffer descriptors.
        !          2615:     //
        !          2616: 
        !          2617:     LANCE_ALLOC_PHYS(
        !          2618:        &(Adapter->LanceBuffers),
        !          2619:        sizeof(LANCE_BUFFER_DESCRIPTOR) *
        !          2620:          (NumberOfSmallBuffers +
        !          2621:           NumberOfMediumBuffers +
        !          2622:           NumberOfLargeBuffers)
        !          2623:        );
        !          2624: 
        !          2625:     if (Adapter->LanceBuffers == NULL) {
        !          2626:         DeleteAdapterMemory(Adapter);
        !          2627:         return FALSE;
        !          2628:     }
        !          2629: 
        !          2630:     //
        !          2631:     // Zero the memory of all the descriptors so that we can
        !          2632:     // know which buffers wern't allocated incase we can't allocate
        !          2633:     // them all.
        !          2634:     //
        !          2635:     LANCE_ZERO_MEMORY(
        !          2636:         Adapter->LanceBuffers,
        !          2637:         sizeof(LANCE_BUFFER_DESCRIPTOR)*
        !          2638:          (NumberOfSmallBuffers +
        !          2639:           NumberOfMediumBuffers +
        !          2640:           NumberOfLargeBuffers)
        !          2641:         );
        !          2642: 
        !          2643:     //
        !          2644:     // Allocate each of the small lance buffers and fill in the
        !          2645:     // buffer descriptor.
        !          2646:     //
        !          2647: 
        !          2648:     Adapter->LanceBufferListHeads[0] = -1;
        !          2649:     Adapter->LanceBufferListHeads[1] = 0;
        !          2650: 
        !          2651:     for (
        !          2652:         i = 0;
        !          2653:         i < NumberOfSmallBuffers;
        !          2654:         i++
        !          2655:         ) {
        !          2656: 
        !          2657:         LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2658:             Adapter,
        !          2659:             LANCE_SMALL_BUFFER_SIZE,
        !          2660:             &Adapter->LanceBuffers[i].VirtualLanceBuffer
        !          2661:             );
        !          2662: 
        !          2663:         if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) {
        !          2664:             DeleteAdapterMemory(Adapter);
        !          2665:             return FALSE;
        !          2666:         }
        !          2667: 
        !          2668:         Adapter->LanceBuffers[i].Next = i+1;
        !          2669:         Adapter->LanceBuffers[i].BufferSize = LANCE_SMALL_BUFFER_SIZE;
        !          2670: 
        !          2671:     }
        !          2672: 
        !          2673:     //
        !          2674:     // Make sure that the last buffer correctly terminates the free list.
        !          2675:     //
        !          2676: 
        !          2677:     Adapter->LanceBuffers[i-1].Next = -1;
        !          2678: 
        !          2679:     //
        !          2680:     // Do the medium buffers now.
        !          2681:     //
        !          2682: 
        !          2683:     Adapter->LanceBufferListHeads[2] = i;
        !          2684: 
        !          2685:     for (
        !          2686:         ;
        !          2687:         i < NumberOfSmallBuffers + NumberOfMediumBuffers;
        !          2688:         i++
        !          2689:         ) {
        !          2690: 
        !          2691:         LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2692:             Adapter,
        !          2693:             LANCE_MEDIUM_BUFFER_SIZE,
        !          2694:             &Adapter->LanceBuffers[i].VirtualLanceBuffer
        !          2695:             );
        !          2696: 
        !          2697:         if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) {
        !          2698:             DeleteAdapterMemory(Adapter);
        !          2699:             return FALSE;
        !          2700:         }
        !          2701: 
        !          2702: 
        !          2703:         Adapter->LanceBuffers[i].Next = i+1;
        !          2704:         Adapter->LanceBuffers[i].BufferSize = LANCE_MEDIUM_BUFFER_SIZE;
        !          2705: 
        !          2706:     }
        !          2707: 
        !          2708:     //
        !          2709:     // Make sure that the last buffer correctly terminates the free list.
        !          2710:     //
        !          2711: 
        !          2712:     Adapter->LanceBuffers[i-1].Next = -1;
        !          2713: 
        !          2714: 
        !          2715:     Adapter->LanceBufferListHeads[3] = i;
        !          2716: 
        !          2717:     for (
        !          2718:         ;
        !          2719:         i < NumberOfSmallBuffers + NumberOfMediumBuffers + NumberOfLargeBuffers;
        !          2720:         i++
        !          2721:         ) {
        !          2722: 
        !          2723: 
        !          2724:         LANCE_ALLOCATE_MEMORY_FOR_HARDWARE(
        !          2725:             Adapter,
        !          2726:             LANCE_LARGE_BUFFER_SIZE,
        !          2727:             &Adapter->LanceBuffers[i].VirtualLanceBuffer
        !          2728:             );
        !          2729: 
        !          2730:         if (Adapter->LanceBuffers[i].VirtualLanceBuffer == NULL) {
        !          2731:             DeleteAdapterMemory(Adapter);
        !          2732:             return FALSE;
        !          2733:         }
        !          2734: 
        !          2735: 
        !          2736:         Adapter->LanceBuffers[i].Next = i+1;
        !          2737:         Adapter->LanceBuffers[i].BufferSize = LANCE_LARGE_BUFFER_SIZE;
        !          2738: 
        !          2739:     }
        !          2740: 
        !          2741:     //
        !          2742:     // Make sure that the last buffer correctly terminates the free list.
        !          2743:     //
        !          2744: 
        !          2745:     Adapter->LanceBuffers[i-1].Next = -1;
        !          2746: 
        !          2747:     return TRUE;
        !          2748: 
        !          2749: }
        !          2750: 
        !          2751: STATIC
        !          2752: VOID
        !          2753: DeleteAdapterMemory(
        !          2754:     IN PLANCE_ADAPTER Adapter
        !          2755:     )
        !          2756: 
        !          2757: /*++
        !          2758: 
        !          2759: Routine Description:
        !          2760: 
        !          2761:     This routine deallocates memory for:
        !          2762: 
        !          2763:     - Transmit ring entries
        !          2764: 
        !          2765:     - Receive ring entries
        !          2766: 
        !          2767:     - Receive buffers
        !          2768: 
        !          2769:     - Adapter buffers for use if user transmit buffers don't meet hardware
        !          2770:       contraints
        !          2771: 
        !          2772:     - Structures to map transmit ring entries back to the packets.
        !          2773: 
        !          2774: Arguments:
        !          2775: 
        !          2776:     Adapter - The adapter to deallocate memory for.
        !          2777: 
        !          2778: Return Value:
        !          2779: 
        !          2780:     None.
        !          2781: 
        !          2782: --*/
        !          2783: 
        !          2784: {
        !          2785: 
        !          2786:     //
        !          2787:     // These variables exist to reduce the amount of checking below.
        !          2788:     //
        !          2789: 
        !          2790:     ULONG NumberOfSmallBuffers;
        !          2791:     ULONG NumberOfMediumBuffers;
        !          2792:     ULONG NumberOfLargeBuffers;
        !          2793: 
        !          2794:     NumberOfSmallBuffers = Adapter->NumberOfSmallBuffers;
        !          2795:     NumberOfMediumBuffers = Adapter->NumberOfMediumBuffers;
        !          2796:     NumberOfLargeBuffers = Adapter->NumberOfLargeBuffers;
        !          2797: 
        !          2798: 
        !          2799:     if (Adapter->InitBlock) {
        !          2800: 
        !          2801:         LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(
        !          2802:             Adapter,
        !          2803:             Adapter->InitBlock
        !          2804:             );
        !          2805: 
        !          2806:     }
        !          2807: 
        !          2808:     if (Adapter->TransmitRing) {
        !          2809: 
        !          2810:         LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(
        !          2811:             Adapter,
        !          2812:             Adapter->TransmitRing
        !          2813:             );
        !          2814: 
        !          2815:     }
        !          2816: 
        !          2817:     if (Adapter->ReceiveRing) {
        !          2818: 
        !          2819:         LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(
        !          2820:             Adapter,
        !          2821:             Adapter->ReceiveRing
        !          2822:             );
        !          2823: 
        !          2824:     }
        !          2825: 
        !          2826:     if (Adapter->ReceiveVAs) {
        !          2827: 
        !          2828:         UINT i;
        !          2829: 
        !          2830:         for (
        !          2831:             i = 0;
        !          2832:             i < Adapter->NumberOfReceiveRings;
        !          2833:             i++
        !          2834:             ) {
        !          2835: 
        !          2836:             if (Adapter->ReceiveVAs[i]) {
        !          2837: 
        !          2838:                 LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(
        !          2839:                     Adapter,
        !          2840:                     Adapter->ReceiveVAs[i]
        !          2841:                     );
        !          2842: 
        !          2843:             } else {
        !          2844: 
        !          2845:                 break;
        !          2846: 
        !          2847:             }
        !          2848: 
        !          2849:         }
        !          2850: 
        !          2851:         LANCE_FREE_PHYS(
        !          2852:           Adapter->ReceiveVAs,
        !          2853:           sizeof(PVOID) * Adapter->NumberOfReceiveRings
        !          2854:           );
        !          2855: 
        !          2856:     }
        !          2857: 
        !          2858:     if (Adapter->RingToPacket) {
        !          2859: 
        !          2860:         LANCE_FREE_PHYS(
        !          2861:             Adapter->RingToPacket,
        !          2862:             sizeof(LANCE_RING_TO_PACKET) * Adapter->NumberOfTransmitRings
        !          2863:             );
        !          2864: 
        !          2865:     }
        !          2866: 
        !          2867:     if (Adapter->LanceBuffers) {
        !          2868: 
        !          2869:         UINT i;
        !          2870: 
        !          2871:         for (
        !          2872:             i = 0;
        !          2873:             i < NumberOfSmallBuffers + NumberOfMediumBuffers + NumberOfLargeBuffers;
        !          2874:             i++) {
        !          2875: 
        !          2876:             if (Adapter->LanceBuffers[i].VirtualLanceBuffer) {
        !          2877: 
        !          2878:                 LANCE_DEALLOCATE_MEMORY_FOR_HARDWARE(
        !          2879:                     Adapter,
        !          2880:                     Adapter->LanceBuffers[i].VirtualLanceBuffer
        !          2881:                     );
        !          2882: 
        !          2883:             } else {
        !          2884: 
        !          2885:                 break;
        !          2886: 
        !          2887:             }
        !          2888: 
        !          2889:         }
        !          2890: 
        !          2891:         LANCE_FREE_PHYS(
        !          2892:             Adapter->LanceBuffers,
        !          2893:             sizeof(LANCE_BUFFER_DESCRIPTOR) *
        !          2894:                (NumberOfSmallBuffers +
        !          2895:                 NumberOfMediumBuffers +
        !          2896:                 NumberOfLargeBuffers)
        !          2897:             );
        !          2898: 
        !          2899:     }
        !          2900: 
        !          2901: }
        !          2902: 
        !          2903: STATIC
        !          2904: NDIS_STATUS
        !          2905: LanceOpenAdapter(
        !          2906:     OUT PNDIS_STATUS OpenErrorStatus,
        !          2907:     OUT NDIS_HANDLE *MacBindingHandle,
        !          2908:     OUT PUINT SelectedMediumIndex,
        !          2909:     IN PNDIS_MEDIUM MediumArray,
        !          2910:     IN UINT MediumArraySize,
        !          2911:     IN NDIS_HANDLE NdisBindingContext,
        !          2912:     IN NDIS_HANDLE MacAdapterContext,
        !          2913:     IN UINT OpenOptions,
        !          2914:     IN PSTRING AddressingInformation OPTIONAL
        !          2915:     )
        !          2916: 
        !          2917: /*++
        !          2918: 
        !          2919: Routine Description:
        !          2920: 
        !          2921:     This routine is used to create an open instance of an adapter, in effect
        !          2922:     creating a binding between an upper-level module and the MAC module over
        !          2923:     the adapter.
        !          2924: 
        !          2925: Arguments:
        !          2926: 
        !          2927:     MacBindingHandle - A pointer to a location in which the MAC stores
        !          2928:     a context value that it uses to represent this binding.
        !          2929: 
        !          2930:     SelectedMediumIndex - Index of MediumArray which this adapter supports.
        !          2931: 
        !          2932:     MediumArray - Array of Medium types which the protocol is requesting.
        !          2933: 
        !          2934:     MediumArraySize - Number of entries in MediumArray.
        !          2935: 
        !          2936:     NdisBindingContext - A value to be recorded by the MAC and passed as
        !          2937:     context whenever an indication is delivered by the MAC for this binding.
        !          2938: 
        !          2939:     MacAdapterContext - The value associated with the adapter that is being
        !          2940:     opened when the MAC registered the adapter with NdisRegisterAdapter.
        !          2941: 
        !          2942:     OpenOptions - A bit mask of flags.  Not used.
        !          2943: 
        !          2944:     AddressingInformation - An optional pointer to a variable length string
        !          2945:     containing hardware-specific information that can be used to program the
        !          2946:     device.  (This is not used by this MAC.)
        !          2947: 
        !          2948: Return Value:
        !          2949: 
        !          2950:     The function value is the status of the operation.  If the MAC does not
        !          2951:     complete this request synchronously, the value would be
        !          2952:     NDIS_STATUS_PENDING.
        !          2953: 
        !          2954: 
        !          2955: --*/
        !          2956: 
        !          2957: {
        !          2958: 
        !          2959:     //
        !          2960:     // The LANCE_ADAPTER that this open binding should belong too.
        !          2961:     //
        !          2962:     PLANCE_ADAPTER Adapter;
        !          2963: 
        !          2964:     //
        !          2965:     // Holds the status that should be returned to the caller.
        !          2966:     //
        !          2967:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2968: 
        !          2969:     PLANCE_OPEN NewOpen;
        !          2970: 
        !          2971: 
        !          2972:     UNREFERENCED_PARAMETER(OpenOptions);
        !          2973:     UNREFERENCED_PARAMETER(OpenErrorStatus);
        !          2974:     UNREFERENCED_PARAMETER(AddressingInformation);
        !          2975: 
        !          2976: 
        !          2977:     //
        !          2978:     // Search for correct medium.
        !          2979:     //
        !          2980: 
        !          2981:     for (; MediumArraySize > 0; MediumArraySize--){
        !          2982: 
        !          2983:         if (MediumArray[MediumArraySize - 1] == NdisMedium802_3){
        !          2984: 
        !          2985:             MediumArraySize--;
        !          2986: 
        !          2987:             break;
        !          2988: 
        !          2989:         }
        !          2990: 
        !          2991:     }
        !          2992: 
        !          2993:     if (MediumArray[MediumArraySize] != NdisMedium802_3){
        !          2994: 
        !          2995:         return(NDIS_STATUS_UNSUPPORTED_MEDIA);
        !          2996: 
        !          2997:     }
        !          2998: 
        !          2999:     *SelectedMediumIndex = MediumArraySize;
        !          3000: 
        !          3001: 
        !          3002:     Adapter = PLANCE_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
        !          3003: 
        !          3004:     NdisInterlockedAddUlong(&Adapter->References, 1, &Adapter->Lock);
        !          3005: 
        !          3006:     //
        !          3007:     // Allocate the space for the open binding.  Fill in the fields.
        !          3008:     //
        !          3009: 
        !          3010:     LANCE_ALLOC_PHYS(&NewOpen,sizeof(LANCE_OPEN));
        !          3011: 
        !          3012:     if (NewOpen != NULL){
        !          3013: 
        !          3014:         *MacBindingHandle = BINDING_HANDLE_FROM_PLANCE_OPEN(NewOpen);
        !          3015: 
        !          3016:         InitializeListHead(&NewOpen->OpenList);
        !          3017: 
        !          3018:         NewOpen->NdisBindingContext = NdisBindingContext;
        !          3019:         NewOpen->References = 0;
        !          3020:         NewOpen->BindingShuttingDown = FALSE;
        !          3021:         NewOpen->OwningLance = Adapter;
        !          3022: 
        !          3023:         NewOpen->LookAhead = LANCE_MAX_LOOKAHEAD;
        !          3024: 
        !          3025:         NdisAcquireSpinLock(&Adapter->Lock);
        !          3026: 
        !          3027:         Adapter->MaxLookAhead = LANCE_MAX_LOOKAHEAD;
        !          3028: 
        !          3029:         if (!EthNoteFilterOpenAdapter(
        !          3030:                                       NewOpen->OwningLance->FilterDB,
        !          3031:                                       NewOpen,
        !          3032:                                       NdisBindingContext,
        !          3033:                                       &NewOpen->NdisFilterHandle
        !          3034:                                       )) {
        !          3035: 
        !          3036:             NdisReleaseSpinLock(&Adapter->Lock);
        !          3037: 
        !          3038:             LANCE_FREE_PHYS(NewOpen, sizeof(LANCE_OPEN));
        !          3039: 
        !          3040:             StatusToReturn = NDIS_STATUS_FAILURE;
        !          3041: 
        !          3042:             NdisAcquireSpinLock(&Adapter->Lock);
        !          3043: 
        !          3044:         } else {
        !          3045: 
        !          3046:             //
        !          3047:             // Everything has been filled in.  Synchronize access to the
        !          3048:             // adapter block and link the new open adapter in and increment
        !          3049:             // the opens reference count to account for the fact that the
        !          3050:             // filter routines have a "reference" to the open.
        !          3051:             //
        !          3052: 
        !          3053:             InsertTailList(&Adapter->OpenBindings,&NewOpen->OpenList);
        !          3054:             NewOpen->References++;
        !          3055: 
        !          3056:         }
        !          3057: 
        !          3058:     } else {
        !          3059: 
        !          3060:         NdisWriteErrorLogEntry(
        !          3061:                 Adapter->NdisAdapterHandle,
        !          3062:                 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          3063:                 1,
        !          3064:                 (ULONG)openAdapter
        !          3065:                 );
        !          3066: 
        !          3067: 
        !          3068:         StatusToReturn = NDIS_STATUS_RESOURCES;
        !          3069: 
        !          3070:         NdisAcquireSpinLock(&Adapter->Lock);
        !          3071: 
        !          3072:     }
        !          3073: 
        !          3074:     LANCE_DO_DEFERRED(Adapter);
        !          3075: 
        !          3076:     return StatusToReturn;
        !          3077: }
        !          3078: 
        !          3079: VOID
        !          3080: LanceAdjustMaxLookAhead(
        !          3081:     IN PLANCE_ADAPTER Adapter
        !          3082:     )
        !          3083: /*++
        !          3084: 
        !          3085: Routine Description:
        !          3086: 
        !          3087:     This routine finds the open with the maximum lookahead value and
        !          3088:     stores that in the adapter block.
        !          3089: 
        !          3090: Arguments:
        !          3091: 
        !          3092:     Adapter - A pointer to the adapter block.
        !          3093: 
        !          3094: Returns:
        !          3095: 
        !          3096:     None.
        !          3097: 
        !          3098: --*/
        !          3099: {
        !          3100:     ULONG CurrentMax = 0;
        !          3101:     PLIST_ENTRY Link = &(Adapter->OpenBindings);
        !          3102: 
        !          3103:     while (Link->Flink != &(Adapter->OpenBindings)) {
        !          3104: 
        !          3105:         if (((PLANCE_OPEN)(Link->Flink))->LookAhead > CurrentMax) {
        !          3106: 
        !          3107:             CurrentMax = ((PLANCE_OPEN)(Link->Flink))->LookAhead;
        !          3108: 
        !          3109:         }
        !          3110: 
        !          3111:         Link = Link->Flink;
        !          3112: 
        !          3113:     }
        !          3114: 
        !          3115:     if (CurrentMax == 0) {
        !          3116: 
        !          3117:         CurrentMax = LANCE_MAX_LOOKAHEAD;
        !          3118: 
        !          3119:     }
        !          3120: 
        !          3121:     Adapter->MaxLookAhead = CurrentMax;
        !          3122: 
        !          3123: }
        !          3124: 
        !          3125: 
        !          3126: STATIC
        !          3127: NDIS_STATUS
        !          3128: LanceCloseAdapter(
        !          3129:     IN NDIS_HANDLE MacBindingHandle
        !          3130:     )
        !          3131: 
        !          3132: /*++
        !          3133: 
        !          3134: Routine Description:
        !          3135: 
        !          3136:     This routine causes the MAC to close an open handle (binding).
        !          3137: 
        !          3138: Arguments:
        !          3139: 
        !          3140:     MacBindingHandle - The context value returned by the MAC when the
        !          3141:     adapter was opened.  In reality it is a PLANCE_OPEN.
        !          3142: 
        !          3143: Return Value:
        !          3144: 
        !          3145:     The function value is the status of the operation.
        !          3146: 
        !          3147: 
        !          3148: --*/
        !          3149: 
        !          3150: {
        !          3151: 
        !          3152:     PLANCE_ADAPTER Adapter;
        !          3153: 
        !          3154:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3155: 
        !          3156:     PLANCE_OPEN Open;
        !          3157: 
        !          3158:     Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3159: 
        !          3160:     //
        !          3161:     // Hold the lock while we update the reference counts for the
        !          3162:     // adapter and the open.
        !          3163:     //
        !          3164: 
        !          3165:     Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3166: 
        !          3167:     NdisAcquireSpinLock(&Adapter->Lock);
        !          3168: 
        !          3169:     Adapter->References++;
        !          3170: 
        !          3171:     if (!Open->BindingShuttingDown) {
        !          3172: 
        !          3173:         Open->References++;
        !          3174: 
        !          3175:         StatusToReturn = EthDeleteFilterOpenAdapter(
        !          3176:                                  Adapter->FilterDB,
        !          3177:                                  Open->NdisFilterHandle,
        !          3178:                                  NULL
        !          3179:                                  );
        !          3180: 
        !          3181:         //
        !          3182:         // If the status is successful that merely implies that
        !          3183:         // we were able to delete the reference to the open binding
        !          3184:         // from the filtering code.  If we have a successful status
        !          3185:         // at this point we still need to check whether the reference
        !          3186:         // count to determine whether we can close.
        !          3187:         //
        !          3188:         //
        !          3189:         // The delete filter routine can return a "special" status
        !          3190:         // that indicates that there is a current NdisIndicateReceive
        !          3191:         // on this binding.  See below.
        !          3192:         //
        !          3193: 
        !          3194:         if (StatusToReturn == NDIS_STATUS_SUCCESS) {
        !          3195: 
        !          3196:             //
        !          3197:             // Check whether the reference count is two.  If
        !          3198:             // it is then we can get rid of the memory for
        !          3199:             // this open.
        !          3200:             //
        !          3201:             // A count of two indicates one for this routine
        !          3202:             // and one for the filter which we *know* we can
        !          3203:             // get rid of.
        !          3204:             //
        !          3205: 
        !          3206:             if (Open->References == 2) {
        !          3207: 
        !          3208:                 //
        !          3209:                 // We are the only reference to the open.  Remove
        !          3210:                 // it from the open list and delete the memory.
        !          3211:                 //
        !          3212: 
        !          3213:                 RemoveEntryList(&Open->OpenList);
        !          3214: 
        !          3215:                 if (Adapter->MaxLookAhead == Open->LookAhead) {
        !          3216: 
        !          3217:                     LanceAdjustMaxLookAhead(Adapter);
        !          3218: 
        !          3219:                 }
        !          3220: 
        !          3221:                 LANCE_FREE_PHYS(Open, sizeof(LANCE_OPEN));
        !          3222: 
        !          3223:             } else {
        !          3224: 
        !          3225:                 Open->BindingShuttingDown = TRUE;
        !          3226: 
        !          3227:                 //
        !          3228:                 // Remove the open from the open list and put it on
        !          3229:                 // the closing list.
        !          3230:                 //
        !          3231: 
        !          3232:                 RemoveEntryList(&Open->OpenList);
        !          3233:                 InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          3234: 
        !          3235:                 //
        !          3236:                 // Account for this routines reference to the open
        !          3237:                 // as well as reference because of the filtering.
        !          3238:                 //
        !          3239: 
        !          3240:                 Open->References -= 2;
        !          3241: 
        !          3242:                 //
        !          3243:                 // Change the status to indicate that we will
        !          3244:                 // be closing this later.
        !          3245:                 //
        !          3246: 
        !          3247:                 StatusToReturn = NDIS_STATUS_PENDING;
        !          3248: 
        !          3249:             }
        !          3250: 
        !          3251:         } else if (StatusToReturn == NDIS_STATUS_PENDING) {
        !          3252: 
        !          3253:             Open->BindingShuttingDown = TRUE;
        !          3254: 
        !          3255:             //
        !          3256:             // Remove the open from the open list and put it on
        !          3257:             // the closing list.
        !          3258:             //
        !          3259: 
        !          3260:             RemoveEntryList(&Open->OpenList);
        !          3261:             InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          3262: 
        !          3263:             //
        !          3264:             // Account for this routines reference to the open
        !          3265:             // as well as original open reference.
        !          3266:             //
        !          3267: 
        !          3268:             Open->References -= 2;
        !          3269: 
        !          3270:         } else if (StatusToReturn == NDIS_STATUS_CLOSING_INDICATING) {
        !          3271: 
        !          3272:             //
        !          3273:             // When we have this status it indicates that the filtering
        !          3274:             // code was currently doing an NdisIndicateReceive.  It
        !          3275:             // would not be wise to delete the memory for the open at
        !          3276:             // this point.  The filtering code will call our close action
        !          3277:             // routine upon return from NdisIndicateReceive and that
        !          3278:             // action routine will decrement the reference count for
        !          3279:             // the open.
        !          3280:             //
        !          3281: 
        !          3282:             Open->BindingShuttingDown = TRUE;
        !          3283: 
        !          3284:             //
        !          3285:             // This status is private to the filtering routine.  Just
        !          3286:             // tell the caller the the close is pending.
        !          3287:             //
        !          3288: 
        !          3289:             StatusToReturn = NDIS_STATUS_PENDING;
        !          3290: 
        !          3291:             //
        !          3292:             // Remove the open from the open list and put it on
        !          3293:             // the closing list.
        !          3294:             //
        !          3295: 
        !          3296:             RemoveEntryList(&Open->OpenList);
        !          3297:             InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          3298: 
        !          3299:             //
        !          3300:             // Account for this routines reference to the open. CloseAction
        !          3301:             // will remove the second reference.
        !          3302:             //
        !          3303: 
        !          3304:             Open->References--;
        !          3305: 
        !          3306:         } else {
        !          3307: 
        !          3308:             //
        !          3309:             // Account for this routines reference to the open.
        !          3310:             //
        !          3311: 
        !          3312:             Open->References--;
        !          3313: 
        !          3314:         }
        !          3315: 
        !          3316:     } else {
        !          3317: 
        !          3318:         StatusToReturn = NDIS_STATUS_CLOSING;
        !          3319: 
        !          3320:     }
        !          3321: 
        !          3322: 
        !          3323:     LANCE_DO_DEFERRED(Adapter);
        !          3324: 
        !          3325:     return StatusToReturn;
        !          3326: 
        !          3327: }
        !          3328: 
        !          3329: NDIS_STATUS
        !          3330: LanceRequest(
        !          3331:     IN NDIS_HANDLE MacBindingHandle,
        !          3332:     IN PNDIS_REQUEST NdisRequest
        !          3333:     )
        !          3334: 
        !          3335: /*++
        !          3336: 
        !          3337: Routine Description:
        !          3338: 
        !          3339:     This routine allows a protocol to query and set information
        !          3340:     about the MAC.
        !          3341: 
        !          3342: Arguments:
        !          3343: 
        !          3344:     MacBindingHandle - The context value returned by the MAC when the
        !          3345:     adapter was opened.  In reality, it is a pointer to PLANCE_OPEN.
        !          3346: 
        !          3347:     NdisRequest - A structure which contains the request type (Set or
        !          3348:     Query), an array of operations to perform, and an array for holding
        !          3349:     the results of the operations.
        !          3350: 
        !          3351: Return Value:
        !          3352: 
        !          3353:     The function value is the status of the operation.
        !          3354: 
        !          3355: --*/
        !          3356: 
        !          3357: {
        !          3358:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3359: 
        !          3360:     PLANCE_OPEN Open = (PLANCE_OPEN)(MacBindingHandle);
        !          3361:     PLANCE_ADAPTER Adapter = (Open->OwningLance);
        !          3362: 
        !          3363:     if (Adapter->HardwareFailure) {
        !          3364: 
        !          3365:         return(NDIS_STATUS_FAILURE);
        !          3366: 
        !          3367:     }
        !          3368: 
        !          3369: 
        !          3370:     //
        !          3371:     // Ensure that the open does not close while in this function.
        !          3372:     //
        !          3373: 
        !          3374:     NdisAcquireSpinLock(&Adapter->Lock);
        !          3375: 
        !          3376:     Adapter->References++;
        !          3377: 
        !          3378: #if LANCE_TRACE
        !          3379:     DbgPrint("In LanceRequest\n");
        !          3380: #endif
        !          3381: 
        !          3382:     //
        !          3383:     // Process request
        !          3384:     //
        !          3385: 
        !          3386:     if (NdisRequest->RequestType == NdisRequestQueryInformation) {
        !          3387: 
        !          3388:         StatusToReturn = LanceQueryInformation(Adapter, Open, NdisRequest);
        !          3389: 
        !          3390:     } else {
        !          3391: 
        !          3392:         if (NdisRequest->RequestType == NdisRequestSetInformation) {
        !          3393: 
        !          3394:             StatusToReturn = LanceSetInformation(Adapter,Open,NdisRequest);
        !          3395: 
        !          3396:         } else {
        !          3397: 
        !          3398:             StatusToReturn = NDIS_STATUS_NOT_RECOGNIZED;
        !          3399: 
        !          3400:         }
        !          3401: 
        !          3402:     }
        !          3403: 
        !          3404:     LANCE_DO_DEFERRED(Adapter);
        !          3405: 
        !          3406: #if LANCE_TRACE
        !          3407:     DbgPrint("Out LanceRequest %x\n",StatusToReturn);
        !          3408: #endif
        !          3409: 
        !          3410:     return(StatusToReturn);
        !          3411: 
        !          3412: }
        !          3413: 
        !          3414: NDIS_STATUS
        !          3415: LanceQueryProtocolInformation(
        !          3416:     IN PLANCE_ADAPTER Adapter,
        !          3417:     IN PLANCE_OPEN Open,
        !          3418:     IN NDIS_OID Oid,
        !          3419:     IN BOOLEAN GlobalMode,
        !          3420:     IN PVOID InfoBuffer,
        !          3421:     IN UINT BytesLeft,
        !          3422:     OUT PUINT BytesNeeded,
        !          3423:     OUT PUINT BytesWritten
        !          3424: )
        !          3425: 
        !          3426: /*++
        !          3427: 
        !          3428: Routine Description:
        !          3429: 
        !          3430:     The LanceQueryProtocolInformation process a Query request for
        !          3431:     NDIS_OIDs that are specific to a binding about the MAC.  Note that
        !          3432:     some of the OIDs that are specific to bindings are also queryable
        !          3433:     on a global basis.  Rather than recreate this code to handle the
        !          3434:     global queries, I use a flag to indicate if this is a query for the
        !          3435:     global data or the binding specific data.
        !          3436: 
        !          3437: Arguments:
        !          3438: 
        !          3439:     Adapter - a pointer to the adapter.
        !          3440: 
        !          3441:     Open - a pointer to the open instance.
        !          3442: 
        !          3443:     Oid - the NDIS_OID to process.
        !          3444: 
        !          3445:     GlobalMode - Some of the binding specific information is also used
        !          3446:     when querying global statistics.  This is a flag to specify whether
        !          3447:     to return the global value, or the binding specific value.
        !          3448: 
        !          3449:     PlaceInInfoBuffer - a pointer into the NdisRequest->InformationBuffer
        !          3450:      into which store the result of the query.
        !          3451: 
        !          3452:     BytesLeft - the number of bytes left in the InformationBuffer.
        !          3453: 
        !          3454:     BytesNeeded - If there is not enough room in the information buffer
        !          3455:     then this will contain the number of bytes needed to complete the
        !          3456:     request.
        !          3457: 
        !          3458:     BytesWritten - a pointer to the number of bytes written into the
        !          3459:     InformationBuffer.
        !          3460: 
        !          3461: Return Value:
        !          3462: 
        !          3463:     The function value is the status of the operation.
        !          3464: 
        !          3465: --*/
        !          3466: 
        !          3467: {
        !          3468:     NDIS_MEDIUM Medium = NdisMedium802_3;
        !          3469:     ULONG GenericULong;
        !          3470:     USHORT GenericUShort;
        !          3471:     UCHAR GenericArray[6];
        !          3472: 
        !          3473:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3474: 
        !          3475:     //
        !          3476:     // Common variables for pointing to result of query
        !          3477:     //
        !          3478: 
        !          3479:     PVOID MoveSource;
        !          3480:     ULONG MoveBytes;
        !          3481: 
        !          3482:     NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
        !          3483: 
        !          3484:     //
        !          3485:     // General Algorithm:
        !          3486:     //
        !          3487:     //      Switch(Request)
        !          3488:     //         Get requested information
        !          3489:     //         Store results in a common variable.
        !          3490:     //      Copy result in common variable to result buffer.
        !          3491:     //
        !          3492: 
        !          3493:     //
        !          3494:     // Make sure that ulong is 4 bytes.  Else GenericULong must change
        !          3495:     // to something of size 4.
        !          3496:     //
        !          3497:     ASSERT(sizeof(ULONG) == 4);
        !          3498: 
        !          3499: 
        !          3500: #if LANCE_TRACE
        !          3501:     DbgPrint("In LanceQueryProtocolInfo\n");
        !          3502: #endif
        !          3503: 
        !          3504:     //
        !          3505:     // Set default values
        !          3506:     //
        !          3507: 
        !          3508:     MoveSource = (PVOID)(&GenericULong);
        !          3509:     MoveBytes = sizeof(GenericULong);
        !          3510: 
        !          3511:     //
        !          3512:     // Switch on request type
        !          3513:     //
        !          3514: 
        !          3515:     switch (Oid) {
        !          3516: 
        !          3517:         case OID_GEN_MAC_OPTIONS:
        !          3518: 
        !          3519:             GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
        !          3520:                                    NDIS_MAC_OPTION_RECEIVE_SERIALIZED
        !          3521:                                   );
        !          3522: 
        !          3523:             break;
        !          3524: 
        !          3525:         case OID_GEN_SUPPORTED_LIST:
        !          3526: 
        !          3527:             if (!GlobalMode){
        !          3528: 
        !          3529:                 MoveSource = (PVOID)(LanceProtocolSupportedOids);
        !          3530:                 MoveBytes = sizeof(LanceProtocolSupportedOids);
        !          3531: 
        !          3532:             } else {
        !          3533: 
        !          3534:                 MoveSource = (PVOID)(LanceGlobalSupportedOids);
        !          3535:                 MoveBytes = sizeof(LanceGlobalSupportedOids);
        !          3536: 
        !          3537:             }
        !          3538:             break;
        !          3539: 
        !          3540:         case OID_GEN_HARDWARE_STATUS:
        !          3541: 
        !          3542: 
        !          3543:             if (Adapter->ResetInProgress){
        !          3544: 
        !          3545:                 HardwareStatus = NdisHardwareStatusReset;
        !          3546: 
        !          3547:             } else {
        !          3548: 
        !          3549:                 HardwareStatus = NdisHardwareStatusReady;
        !          3550: 
        !          3551:             }
        !          3552: 
        !          3553: 
        !          3554:             MoveSource = (PVOID)(&HardwareStatus);
        !          3555:             MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
        !          3556: 
        !          3557:             break;
        !          3558: 
        !          3559:         case OID_GEN_MEDIA_SUPPORTED:
        !          3560:         case OID_GEN_MEDIA_IN_USE:
        !          3561: 
        !          3562:             MoveSource = (PVOID) (&Medium);
        !          3563:             MoveBytes = sizeof(NDIS_MEDIUM);
        !          3564:             break;
        !          3565: 
        !          3566:         case OID_GEN_MAXIMUM_LOOKAHEAD:
        !          3567: 
        !          3568:             GenericULong = LANCE_MAX_LOOKAHEAD;
        !          3569: 
        !          3570:             break;
        !          3571: 
        !          3572: 
        !          3573:         case OID_GEN_MAXIMUM_FRAME_SIZE:
        !          3574: 
        !          3575:             GenericULong = (ULONG)(LANCE_LARGE_BUFFER_SIZE - LANCE_HEADER_SIZE);
        !          3576: 
        !          3577:             break;
        !          3578: 
        !          3579: 
        !          3580:         case OID_GEN_MAXIMUM_TOTAL_SIZE:
        !          3581: 
        !          3582:             GenericULong = (ULONG)(LANCE_LARGE_BUFFER_SIZE);
        !          3583: 
        !          3584:             break;
        !          3585: 
        !          3586: 
        !          3587:         case OID_GEN_LINK_SPEED:
        !          3588: 
        !          3589:             GenericULong = (ULONG)(100000);
        !          3590: 
        !          3591:             break;
        !          3592: 
        !          3593: 
        !          3594:         case OID_GEN_TRANSMIT_BUFFER_SPACE:
        !          3595: 
        !          3596:             GenericULong = (ULONG)((LANCE_SMALL_BUFFER_SIZE * Adapter->NumberOfSmallBuffers) +
        !          3597:                                    (LANCE_MEDIUM_BUFFER_SIZE * Adapter->NumberOfMediumBuffers) +
        !          3598:                                    (LANCE_LARGE_BUFFER_SIZE * Adapter->NumberOfLargeBuffers));
        !          3599: 
        !          3600: 
        !          3601:             break;
        !          3602: 
        !          3603:         case OID_GEN_RECEIVE_BUFFER_SPACE:
        !          3604: 
        !          3605:             GenericULong = (ULONG)(Adapter->NumberOfReceiveRings *
        !          3606:                                    Adapter->SizeOfReceiveBuffer);
        !          3607: 
        !          3608:             break;
        !          3609: 
        !          3610:         case OID_GEN_TRANSMIT_BLOCK_SIZE:
        !          3611: 
        !          3612:             GenericULong = (ULONG)(LANCE_SMALL_BUFFER_SIZE);
        !          3613: 
        !          3614:             break;
        !          3615: 
        !          3616:         case OID_GEN_RECEIVE_BLOCK_SIZE:
        !          3617: 
        !          3618:             GenericULong = (ULONG)(Adapter->SizeOfReceiveBuffer);
        !          3619: 
        !          3620:             break;
        !          3621: 
        !          3622:         case OID_GEN_VENDOR_ID:
        !          3623: 
        !          3624:             NdisMoveMemory(
        !          3625:                 (PVOID)&GenericULong,
        !          3626:                 Adapter->NetworkAddress,
        !          3627:                 3
        !          3628:                 );
        !          3629: 
        !          3630:             GenericULong &= 0xFFFFFF00;
        !          3631: 
        !          3632:             if (Adapter->LanceCard == LANCE_DE201) {
        !          3633: 
        !          3634:                 GenericULong |= 0x01;
        !          3635: 
        !          3636:             } else if (Adapter->LanceCard == LANCE_DE100) {
        !          3637: 
        !          3638:                 GenericULong |= 0x02;
        !          3639: 
        !          3640:             } else if (Adapter->LanceCard == LANCE_DE422) {
        !          3641: 
        !          3642:                 GenericULong |= 0x03;
        !          3643: 
        !          3644:             } else {
        !          3645: 
        !          3646:                 GenericULong |= 0x04;
        !          3647: 
        !          3648:             }
        !          3649: 
        !          3650:             MoveSource = (PVOID)(&GenericULong);
        !          3651:             MoveBytes = sizeof(GenericULong);
        !          3652:             break;
        !          3653: 
        !          3654:         case OID_GEN_VENDOR_DESCRIPTION:
        !          3655: 
        !          3656:             if (Adapter->LanceCard == LANCE_DE201) {
        !          3657: 
        !          3658:                 MoveSource = (PVOID)"DEC Etherworks Turbo Adapter";
        !          3659:                 MoveBytes = 29;
        !          3660: 
        !          3661:             } else if (Adapter->LanceCard == LANCE_DE100) {
        !          3662: 
        !          3663:                 MoveSource = (PVOID)"DEC Etherworks Adapter";
        !          3664:                 MoveBytes = 23;
        !          3665: 
        !          3666:             } else if (Adapter->LanceCard == LANCE_DE422) {
        !          3667: 
        !          3668:                 MoveSource = (PVOID)"DEC Etherworks Turbo EISA Adapter";
        !          3669:                 MoveBytes = 34;
        !          3670: 
        !          3671:             } else {
        !          3672: 
        !          3673:                 MoveSource = (PVOID)"Lance Adapter";
        !          3674:                 MoveBytes = 15;
        !          3675: 
        !          3676:             }
        !          3677: 
        !          3678:             break;
        !          3679: 
        !          3680:         case OID_GEN_DRIVER_VERSION:
        !          3681: 
        !          3682:             GenericUShort = (USHORT)0x0301;
        !          3683: 
        !          3684:             MoveSource = (PVOID)(&GenericUShort);
        !          3685:             MoveBytes = sizeof(GenericUShort);
        !          3686:             break;
        !          3687: 
        !          3688: 
        !          3689:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          3690: 
        !          3691:             if (GlobalMode ) {
        !          3692: 
        !          3693:                 GenericULong = ETH_QUERY_FILTER_CLASSES(
        !          3694:                                 Adapter->FilterDB
        !          3695:                                 );
        !          3696: 
        !          3697:             } else {
        !          3698: 
        !          3699:                 GenericULong = ETH_QUERY_PACKET_FILTER(
        !          3700:                                 Adapter->FilterDB,
        !          3701:                                 Open->NdisFilterHandle
        !          3702:                                 );
        !          3703: 
        !          3704:             }
        !          3705: 
        !          3706:             break;
        !          3707: 
        !          3708:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          3709: 
        !          3710:             if ( GlobalMode ) {
        !          3711: 
        !          3712:                 GenericULong = Adapter->MaxLookAhead;
        !          3713: 
        !          3714:             } else {
        !          3715: 
        !          3716:                 GenericULong = Open->LookAhead;
        !          3717: 
        !          3718:             }
        !          3719: 
        !          3720:             break;
        !          3721: 
        !          3722:         case OID_802_3_PERMANENT_ADDRESS:
        !          3723: 
        !          3724:             LANCE_MOVE_MEMORY((PCHAR)GenericArray,
        !          3725:                               Adapter->NetworkAddress,
        !          3726:                               ETH_LENGTH_OF_ADDRESS
        !          3727:                               );
        !          3728: 
        !          3729:             MoveSource = (PVOID)(GenericArray);
        !          3730:             MoveBytes = sizeof(Adapter->NetworkAddress);
        !          3731:             break;
        !          3732: 
        !          3733:         case OID_802_3_CURRENT_ADDRESS:
        !          3734: 
        !          3735: 
        !          3736:             LANCE_MOVE_MEMORY((PCHAR)GenericArray,
        !          3737:                               Adapter->CurrentNetworkAddress,
        !          3738:                               ETH_LENGTH_OF_ADDRESS
        !          3739:                               );
        !          3740: 
        !          3741:             MoveSource = (PVOID)(GenericArray);
        !          3742:             MoveBytes = sizeof(Adapter->CurrentNetworkAddress);
        !          3743:             break;
        !          3744: 
        !          3745:         case OID_802_3_MULTICAST_LIST:
        !          3746: 
        !          3747: 
        !          3748:             {
        !          3749:                 UINT NumAddresses;
        !          3750: 
        !          3751:                 if (GlobalMode) {
        !          3752: 
        !          3753:                     NumAddresses = ETH_NUMBER_OF_GLOBAL_FILTER_ADDRESSES(Adapter->FilterDB);
        !          3754: 
        !          3755:                     if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) {
        !          3756: 
        !          3757:                         *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
        !          3758: 
        !          3759:                         StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          3760: 
        !          3761:                         break;
        !          3762: 
        !          3763:                     }
        !          3764: 
        !          3765:                     EthQueryGlobalFilterAddresses(
        !          3766:                         &StatusToReturn,
        !          3767:                         Adapter->FilterDB,
        !          3768:                         BytesLeft,
        !          3769:                         &NumAddresses,
        !          3770:                         InfoBuffer
        !          3771:                         );
        !          3772: 
        !          3773:                     *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS;
        !          3774: 
        !          3775:                     //
        !          3776:                     // Should not be an error since we held the spinlock
        !          3777:                     // nothing should have changed.
        !          3778:                     //
        !          3779: 
        !          3780:                     ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
        !          3781: 
        !          3782:                 } else {
        !          3783: 
        !          3784:                     NumAddresses = EthNumberOfOpenFilterAddresses(
        !          3785:                                         Adapter->FilterDB,
        !          3786:                                         Open->NdisFilterHandle
        !          3787:                                         );
        !          3788: 
        !          3789:                     if ((NumAddresses * ETH_LENGTH_OF_ADDRESS) > BytesLeft) {
        !          3790: 
        !          3791:                         *BytesNeeded = (NumAddresses * ETH_LENGTH_OF_ADDRESS);
        !          3792: 
        !          3793:                         StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          3794: 
        !          3795:                         break;
        !          3796: 
        !          3797:                     }
        !          3798: 
        !          3799:                     EthQueryOpenFilterAddresses(
        !          3800:                         &StatusToReturn,
        !          3801:                         Adapter->FilterDB,
        !          3802:                         Open->NdisFilterHandle,
        !          3803:                         BytesLeft,
        !          3804:                         &NumAddresses,
        !          3805:                         InfoBuffer
        !          3806:                         );
        !          3807: 
        !          3808:                     //
        !          3809:                     // Should not be an error since we held the spinlock
        !          3810:                     // nothing should have changed.
        !          3811:                     //
        !          3812: 
        !          3813:                     ASSERT(StatusToReturn == NDIS_STATUS_SUCCESS);
        !          3814: 
        !          3815:                     *BytesWritten = NumAddresses * ETH_LENGTH_OF_ADDRESS;
        !          3816: 
        !          3817:                 }
        !          3818: 
        !          3819:             }
        !          3820: 
        !          3821:             MoveSource = (PVOID)NULL;
        !          3822:             MoveBytes = 0;
        !          3823: 
        !          3824:             break;
        !          3825: 
        !          3826:         case OID_802_3_MAXIMUM_LIST_SIZE:
        !          3827: 
        !          3828:             GenericULong = Adapter->MaxMulticastList;
        !          3829: 
        !          3830:             break;
        !          3831: 
        !          3832: 
        !          3833: 
        !          3834:         default:
        !          3835: 
        !          3836:             StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
        !          3837:             break;
        !          3838:     }
        !          3839: 
        !          3840:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          3841: 
        !          3842:         if (MoveBytes > BytesLeft){
        !          3843: 
        !          3844:             //
        !          3845:             // Not enough room in InformationBuffer. Punt
        !          3846:             //
        !          3847: 
        !          3848:             *BytesNeeded = MoveBytes;
        !          3849: 
        !          3850:             StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          3851: 
        !          3852:         } else {
        !          3853: 
        !          3854:             //
        !          3855:             // Store result.
        !          3856:             //
        !          3857: 
        !          3858:             LANCE_MOVE_MEMORY(InfoBuffer, MoveSource, MoveBytes);
        !          3859: 
        !          3860:             (*BytesWritten) += MoveBytes;
        !          3861: 
        !          3862:         }
        !          3863:     }
        !          3864: 
        !          3865: #if LANCE_TRACE
        !          3866:     DbgPrint("Out LanceQueryProtocolInfo\n");
        !          3867: #endif
        !          3868: 
        !          3869:     return(StatusToReturn);
        !          3870: }
        !          3871: 
        !          3872: NDIS_STATUS
        !          3873: LanceQueryInformation(
        !          3874:     IN PLANCE_ADAPTER Adapter,
        !          3875:     IN PLANCE_OPEN Open,
        !          3876:     IN PNDIS_REQUEST NdisRequest
        !          3877:     )
        !          3878: /*++
        !          3879: 
        !          3880: Routine Description:
        !          3881: 
        !          3882:     The LanceQueryInformation is used by LanceRequest to query information
        !          3883:     about the MAC.
        !          3884: 
        !          3885: Arguments:
        !          3886: 
        !          3887:     Adapter - A pointer to the adapter.
        !          3888: 
        !          3889:     Open - A pointer to a particular open instance.
        !          3890: 
        !          3891:     NdisRequest - A structure which contains the request type (Query),
        !          3892:     an array of operations to perform, and an array for holding
        !          3893:     the results of the operations.
        !          3894: 
        !          3895: Return Value:
        !          3896: 
        !          3897:     The function value is the status of the operation.
        !          3898: 
        !          3899: --*/
        !          3900: 
        !          3901: {
        !          3902: 
        !          3903:     UINT BytesWritten = 0;
        !          3904:     UINT BytesNeeded = 0;
        !          3905:     UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
        !          3906:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
        !          3907: 
        !          3908:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3909: 
        !          3910: 
        !          3911: #if LANCE_TRACE
        !          3912:     DbgPrint("In LanceQueryInfo\n");
        !          3913: #endif
        !          3914: 
        !          3915: 
        !          3916:     StatusToReturn = LanceQueryProtocolInformation(
        !          3917:                                 Adapter,
        !          3918:                                 Open,
        !          3919:                                 NdisRequest->DATA.QUERY_INFORMATION.Oid,
        !          3920:                                 FALSE,
        !          3921:                                 InfoBuffer,
        !          3922:                                 BytesLeft,
        !          3923:                                 &BytesNeeded,
        !          3924:                                 &BytesWritten
        !          3925:                                 );
        !          3926: 
        !          3927: 
        !          3928:     NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
        !          3929: 
        !          3930:     NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
        !          3931: 
        !          3932: #if LANCE_TRACE
        !          3933:     DbgPrint("Out LanceQueryInfo\n");
        !          3934: #endif
        !          3935: 
        !          3936:     return(StatusToReturn);
        !          3937: }
        !          3938: 
        !          3939: NDIS_STATUS
        !          3940: LanceSetInformation(
        !          3941:     IN PLANCE_ADAPTER Adapter,
        !          3942:     IN PLANCE_OPEN Open,
        !          3943:     IN PNDIS_REQUEST NdisRequest
        !          3944:     )
        !          3945: /*++
        !          3946: 
        !          3947: Routine Description:
        !          3948: 
        !          3949:     The LanceSetInformation is used by LanceRequest to set information
        !          3950:     about the MAC.
        !          3951: 
        !          3952:     Note: Assumes it is called with the lock held.
        !          3953: 
        !          3954: Arguments:
        !          3955: 
        !          3956:     Adapter - A pointer to the adapter.
        !          3957: 
        !          3958:     Open - A pointer to an open instance.
        !          3959: 
        !          3960:     NdisRequest - A structure which contains the request type (Set),
        !          3961:     an array of operations to perform, and an array for holding
        !          3962:     the results of the operations.
        !          3963: 
        !          3964: Return Value:
        !          3965: 
        !          3966:     The function value is the status of the operation.
        !          3967: 
        !          3968: --*/
        !          3969: 
        !          3970: {
        !          3971: 
        !          3972:     //
        !          3973:     // General Algorithm:
        !          3974:     //
        !          3975:     //  For each request
        !          3976:     //     Verify length
        !          3977:     //     Switch(Request)
        !          3978:     //        Process Request
        !          3979:     //
        !          3980: 
        !          3981:     UINT BytesRead = 0;
        !          3982:     UINT BytesNeeded = 0;
        !          3983:     UINT BytesLeft = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
        !          3984:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer);
        !          3985: 
        !          3986:     //
        !          3987:     // Variables for a particular request
        !          3988:     //
        !          3989: 
        !          3990:     NDIS_OID Oid;
        !          3991:     UINT OidLength;
        !          3992: 
        !          3993:     //
        !          3994:     // Variables for holding the new values to be used.
        !          3995:     //
        !          3996: 
        !          3997:     ULONG LookAhead;
        !          3998:     ULONG Filter;
        !          3999: 
        !          4000:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4001: 
        !          4002: 
        !          4003: #if LANCE_TRACE
        !          4004:     DbgPrint("In LanceSetInfo\n");
        !          4005: #endif
        !          4006: 
        !          4007: 
        !          4008:     //
        !          4009:     // Get Oid and Length of next request
        !          4010:     //
        !          4011: 
        !          4012:     Oid = NdisRequest->DATA.SET_INFORMATION.Oid;
        !          4013: 
        !          4014:     OidLength = BytesLeft;
        !          4015: 
        !          4016:     switch (Oid) {
        !          4017: 
        !          4018: 
        !          4019:         case OID_802_3_MULTICAST_LIST:
        !          4020: 
        !          4021:             //
        !          4022:             // Verify length
        !          4023:             //
        !          4024: 
        !          4025:             if ((OidLength % ETH_LENGTH_OF_ADDRESS) != 0){
        !          4026: 
        !          4027:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          4028: 
        !          4029:                 NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          4030:                 NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4031: 
        !          4032:                 return(StatusToReturn);
        !          4033: 
        !          4034:             }
        !          4035: 
        !          4036:             //
        !          4037:             // Call into filter package.
        !          4038:             //
        !          4039: 
        !          4040:             if (!Open->BindingShuttingDown) {
        !          4041: 
        !          4042:                 //
        !          4043:                 // Increment the open while it is going through the filtering
        !          4044:                 // routines.
        !          4045:                 //
        !          4046: 
        !          4047:                 Open->References++;
        !          4048: 
        !          4049:                 StatusToReturn = EthChangeFilterAddresses(
        !          4050:                                          Adapter->FilterDB,
        !          4051:                                          Open->NdisFilterHandle,
        !          4052:                                          NdisRequest,
        !          4053:                                          OidLength / ETH_LENGTH_OF_ADDRESS,
        !          4054:                                          (CHAR **)InfoBuffer,
        !          4055:                                          TRUE
        !          4056:                                          );
        !          4057: 
        !          4058:                 Open->References--;
        !          4059: 
        !          4060:             } else {
        !          4061: 
        !          4062:                 StatusToReturn = NDIS_STATUS_CLOSING;
        !          4063: 
        !          4064:             }
        !          4065: 
        !          4066:             break;
        !          4067: 
        !          4068: 
        !          4069:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          4070: 
        !          4071:             //
        !          4072:             // Verify length
        !          4073:             //
        !          4074: 
        !          4075:             if (OidLength != 4) {
        !          4076: 
        !          4077:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          4078: 
        !          4079:                 NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          4080:                 NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4081: 
        !          4082:                 break;
        !          4083: 
        !          4084:             }
        !          4085: 
        !          4086: 
        !          4087:             LANCE_MOVE_MEMORY(&Filter, InfoBuffer, 4);
        !          4088: 
        !          4089:             //
        !          4090:             // Verify bits
        !          4091:             //
        !          4092: 
        !          4093:             if (Filter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
        !          4094:                           NDIS_PACKET_TYPE_SMT |
        !          4095:                           NDIS_PACKET_TYPE_MAC_FRAME |
        !          4096:                           NDIS_PACKET_TYPE_FUNCTIONAL |
        !          4097:                           NDIS_PACKET_TYPE_ALL_FUNCTIONAL |
        !          4098:                           NDIS_PACKET_TYPE_GROUP
        !          4099:                          )) {
        !          4100: 
        !          4101:                 StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
        !          4102: 
        !          4103:                 NdisRequest->DATA.SET_INFORMATION.BytesRead = 4;
        !          4104:                 NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4105: 
        !          4106:                 break;
        !          4107: 
        !          4108:             }
        !          4109: 
        !          4110:             StatusToReturn = LanceSetPacketFilter(Adapter,
        !          4111:                                                   Open,
        !          4112:                                                   NdisRequest,
        !          4113:                                                   Filter);
        !          4114: 
        !          4115:             break;
        !          4116: 
        !          4117:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          4118: 
        !          4119:             //
        !          4120:             // Verify length
        !          4121:             //
        !          4122: 
        !          4123:             if (OidLength != 4) {
        !          4124: 
        !          4125:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          4126: 
        !          4127:                 NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          4128:                 NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4129: 
        !          4130:                 break;
        !          4131: 
        !          4132:             }
        !          4133: 
        !          4134:             LANCE_MOVE_MEMORY(&LookAhead, InfoBuffer, 4);
        !          4135: 
        !          4136:             if (LookAhead <= (LANCE_MAX_LOOKAHEAD)) {
        !          4137: 
        !          4138:                 if (Open->LookAhead > Adapter->MaxLookAhead) {
        !          4139: 
        !          4140:                     Open->LookAhead = LookAhead;
        !          4141: 
        !          4142:                     Adapter->MaxLookAhead = LookAhead;
        !          4143: 
        !          4144:                 } else {
        !          4145: 
        !          4146:                     if ((Open->LookAhead == Adapter->MaxLookAhead) &&
        !          4147:                         (LookAhead < Adapter->MaxLookAhead)) {
        !          4148: 
        !          4149:                         Open->LookAhead = LookAhead;
        !          4150: 
        !          4151:                         LanceAdjustMaxLookAhead(Adapter);
        !          4152: 
        !          4153:                     } else {
        !          4154: 
        !          4155:                         Open->LookAhead = LookAhead;
        !          4156: 
        !          4157:                     }
        !          4158: 
        !          4159:                 }
        !          4160: 
        !          4161:             } else {
        !          4162: 
        !          4163:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          4164: 
        !          4165:             }
        !          4166: 
        !          4167:             break;
        !          4168: 
        !          4169:         case OID_GEN_PROTOCOL_OPTIONS:
        !          4170: 
        !          4171:             StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4172:             break;
        !          4173: 
        !          4174:         default:
        !          4175: 
        !          4176:             StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          4177: 
        !          4178:             NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          4179:             NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4180: 
        !          4181:             break;
        !          4182:     }
        !          4183: 
        !          4184:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          4185: 
        !          4186:         NdisRequest->DATA.SET_INFORMATION.BytesRead = OidLength;
        !          4187:         NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          4188: 
        !          4189:     }
        !          4190: 
        !          4191: #if LANCE_TRACE
        !          4192:     DbgPrint("Out LanceSetInfo\n");
        !          4193: #endif
        !          4194: 
        !          4195:     return(StatusToReturn);
        !          4196: }
        !          4197: 
        !          4198: STATIC
        !          4199: NDIS_STATUS
        !          4200: LanceSetPacketFilter(
        !          4201:     IN PLANCE_ADAPTER Adapter,
        !          4202:     IN PLANCE_OPEN Open,
        !          4203:     IN PNDIS_REQUEST NdisRequest,
        !          4204:     IN UINT PacketFilter
        !          4205:     )
        !          4206: 
        !          4207: /*++
        !          4208: 
        !          4209: Routine Description:
        !          4210: 
        !          4211:     The LanceSetPacketFilter request allows a protocol to control the types
        !          4212:     of packets that it receives from the MAC.
        !          4213: 
        !          4214:     Note : Assumes that the lock is currently held.
        !          4215: 
        !          4216: Arguments:
        !          4217: 
        !          4218:     Adapter - Pointer to the LANCE_ADAPTER.
        !          4219: 
        !          4220:     Open - Pointer to the instance of LANCE_OPEN for Ndis.
        !          4221: 
        !          4222:     NdisRequest - Pointer to the NDIS_REQUEST which submitted the set
        !          4223:     packet filter command.
        !          4224: 
        !          4225:     PacketFilter - A bit mask that contains flags that correspond to specific
        !          4226:     classes of received packets.  If a particular bit is set in the mask,
        !          4227:     then packet reception for that class of packet is enabled.  If the
        !          4228:     bit is clear, then packets that fall into that class are not received
        !          4229:     by the client.  A single exception to this rule is that if the promiscuous
        !          4230:     bit is set, then the client receives all packets on the network, regardless
        !          4231:     of the state of the other flags.
        !          4232: 
        !          4233: Return Value:
        !          4234: 
        !          4235:     The function value is the status of the operation.
        !          4236: 
        !          4237: --*/
        !          4238: 
        !          4239: {
        !          4240: 
        !          4241:     //
        !          4242:     // Keeps track of the *MAC's* status.  The status will only be
        !          4243:     // reset if the filter change action routine is called.
        !          4244:     //
        !          4245:     NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS;
        !          4246: 
        !          4247: 
        !          4248: #if LANCE_TRACE
        !          4249:     DbgPrint("In LanceSetPacketFilter\n");
        !          4250: #endif
        !          4251: 
        !          4252:     Adapter->References++;
        !          4253: 
        !          4254:     if (!Open->BindingShuttingDown) {
        !          4255: 
        !          4256:         //
        !          4257:         // Increment the open while it is going through the filtering
        !          4258:         // routines.
        !          4259:         //
        !          4260: 
        !          4261:         Open->References++;
        !          4262: 
        !          4263:         StatusOfFilterChange = EthFilterAdjust(
        !          4264:                                        Adapter->FilterDB,
        !          4265:                                        Open->NdisFilterHandle,
        !          4266:                                        NdisRequest,
        !          4267:                                        PacketFilter,
        !          4268:                                        TRUE
        !          4269:                                        );
        !          4270: 
        !          4271:         Open->References--;
        !          4272: 
        !          4273:     } else {
        !          4274: 
        !          4275:         StatusOfFilterChange = NDIS_STATUS_CLOSING;
        !          4276: 
        !          4277:     }
        !          4278: 
        !          4279:     Adapter->References--;
        !          4280: 
        !          4281: #if LANCE_TRACE
        !          4282:     DbgPrint("Out LanceSetPacketFilter\n");
        !          4283: #endif
        !          4284: 
        !          4285:     return StatusOfFilterChange;
        !          4286: }
        !          4287: 
        !          4288: 
        !          4289: NDIS_STATUS
        !          4290: LanceFillInGlobalData(
        !          4291:     IN PLANCE_ADAPTER Adapter,
        !          4292:     IN PNDIS_REQUEST NdisRequest
        !          4293:     )
        !          4294: 
        !          4295: /*++
        !          4296: 
        !          4297: Routine Description:
        !          4298: 
        !          4299:     This routine completes a GlobalStatistics request.  It is critical that
        !          4300:     if information is needed from the Adapter->* fields, they have been
        !          4301:     updated before this routine is called.
        !          4302: 
        !          4303: Arguments:
        !          4304: 
        !          4305:     Adapter - A pointer to the Adapter.
        !          4306: 
        !          4307:     NdisRequest - A structure which contains the request type (Global
        !          4308:     Query), an array of operations to perform, and an array for holding
        !          4309:     the results of the operations.
        !          4310: 
        !          4311: Return Value:
        !          4312: 
        !          4313:     The function value is the status of the operation.
        !          4314: 
        !          4315: --*/
        !          4316: {
        !          4317:     //
        !          4318:     //   General Algorithm:
        !          4319:     //
        !          4320:     //      Switch(Request)
        !          4321:     //         Get requested information
        !          4322:     //         Store results in a common variable.
        !          4323:     //      default:
        !          4324:     //         Try protocol query information
        !          4325:     //         If that fails, fail query.
        !          4326:     //
        !          4327:     //      Copy result in common variable to result buffer.
        !          4328:     //   Finish processing
        !          4329: 
        !          4330:     UINT BytesWritten = 0;
        !          4331:     UINT BytesNeeded = 0;
        !          4332:     UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
        !          4333:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
        !          4334: 
        !          4335:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4336: 
        !          4337:     //
        !          4338:     // This variable holds result of query
        !          4339:     //
        !          4340: 
        !          4341:     ULONG GenericULong;
        !          4342:     ULONG MoveBytes = sizeof(ULONG) * 2 + sizeof(NDIS_OID);
        !          4343: 
        !          4344:     //
        !          4345:     // Make sure that int is 4 bytes.  Else GenericULong must change
        !          4346:     // to something of size 4.
        !          4347:     //
        !          4348:     ASSERT(sizeof(ULONG) == 4);
        !          4349: 
        !          4350: 
        !          4351:     StatusToReturn = LanceQueryProtocolInformation(
        !          4352:                                     Adapter,
        !          4353:                                     NULL,
        !          4354:                                     NdisRequest->DATA.QUERY_INFORMATION.Oid,
        !          4355:                                     TRUE,
        !          4356:                                     InfoBuffer,
        !          4357:                                     BytesLeft,
        !          4358:                                     &BytesNeeded,
        !          4359:                                     &BytesWritten
        !          4360:                                     );
        !          4361: 
        !          4362: 
        !          4363:     if (StatusToReturn == NDIS_STATUS_NOT_SUPPORTED){
        !          4364: 
        !          4365:         StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4366: 
        !          4367:         NdisAcquireSpinLock(&Adapter->Lock);
        !          4368: 
        !          4369:         //
        !          4370:         // Switch on request type
        !          4371:         //
        !          4372: 
        !          4373:         switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
        !          4374: 
        !          4375:             case OID_GEN_XMIT_OK:
        !          4376: 
        !          4377:                 GenericULong = (ULONG)(Adapter->Transmit +
        !          4378:                                            Adapter->LateCollision);
        !          4379: 
        !          4380:                 break;
        !          4381: 
        !          4382:             case OID_GEN_RCV_OK:
        !          4383: 
        !          4384:                 GenericULong = (ULONG)(Adapter->Receive);
        !          4385: 
        !          4386:                 break;
        !          4387: 
        !          4388:             case OID_GEN_XMIT_ERROR:
        !          4389: 
        !          4390:                 GenericULong = (ULONG)(Adapter->LostCarrier);
        !          4391: 
        !          4392:                 break;
        !          4393: 
        !          4394:             case OID_GEN_RCV_ERROR:
        !          4395: 
        !          4396:                 GenericULong = (ULONG)(Adapter->CRCError);
        !          4397: 
        !          4398:                 break;
        !          4399: 
        !          4400:             case OID_GEN_RCV_NO_BUFFER:
        !          4401: 
        !          4402:                 GenericULong = (ULONG)(Adapter->OutOfReceiveBuffers);
        !          4403: 
        !          4404:                 break;
        !          4405: 
        !          4406:             case OID_802_3_RCV_ERROR_ALIGNMENT:
        !          4407: 
        !          4408:                 GenericULong = (ULONG)(Adapter->FramingError);
        !          4409: 
        !          4410:                 break;
        !          4411: 
        !          4412:             case OID_802_3_XMIT_ONE_COLLISION:
        !          4413: 
        !          4414:                 GenericULong = (ULONG)(Adapter->OneRetry);
        !          4415: 
        !          4416:                 break;
        !          4417: 
        !          4418:             case OID_802_3_XMIT_MORE_COLLISIONS:
        !          4419: 
        !          4420:                 GenericULong = (ULONG)(Adapter->MoreThanOneRetry);
        !          4421: 
        !          4422:                 break;
        !          4423: 
        !          4424: 
        !          4425:             default:
        !          4426: 
        !          4427:                 StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          4428: 
        !          4429:                 break;
        !          4430: 
        !          4431:         }
        !          4432: 
        !          4433:         NdisReleaseSpinLock(&Adapter->Lock);
        !          4434: 
        !          4435:         if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          4436: 
        !          4437:             //
        !          4438:             // Check to make sure there is enough room in the
        !          4439:             // buffer to store the result.
        !          4440:             //
        !          4441: 
        !          4442:             if (BytesLeft >= sizeof(ULONG)){
        !          4443: 
        !          4444:                 //
        !          4445:                 // Store the result.
        !          4446:                 //
        !          4447: 
        !          4448:                 LANCE_MOVE_MEMORY(
        !          4449:                            (PVOID)InfoBuffer,
        !          4450:                            (PVOID)(&GenericULong),
        !          4451:                            sizeof(UINT)
        !          4452:                            );
        !          4453: 
        !          4454:                 BytesWritten += sizeof(ULONG);
        !          4455: 
        !          4456:             } else {
        !          4457: 
        !          4458:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          4459: 
        !          4460:             }
        !          4461: 
        !          4462:         }
        !          4463: 
        !          4464:     }
        !          4465: 
        !          4466:     NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
        !          4467: 
        !          4468:     NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
        !          4469: 
        !          4470:     return(StatusToReturn);
        !          4471: }
        !          4472: 
        !          4473: NDIS_STATUS
        !          4474: LanceQueryGlobalStatistics(
        !          4475:     IN NDIS_HANDLE MacAdapterContext,
        !          4476:     IN PNDIS_REQUEST NdisRequest
        !          4477:     )
        !          4478: 
        !          4479: /*++
        !          4480: 
        !          4481: Routine Description:
        !          4482: 
        !          4483:     The LanceQueryGlobalStatistics is used by the protocol to query
        !          4484:     global information about the MAC.
        !          4485: 
        !          4486: Arguments:
        !          4487: 
        !          4488:     MacAdapterContext - The value associated with the adapter that is being
        !          4489:     opened when the MAC registered the adapter with NdisRegisterAdapter.
        !          4490: 
        !          4491:     NdisRequest - A structure which contains the request type (Query),
        !          4492:     an array of operations to perform, and an array for holding
        !          4493:     the results of the operations.
        !          4494: 
        !          4495: Return Value:
        !          4496: 
        !          4497:     The function value is the status of the operation.
        !          4498: 
        !          4499: --*/
        !          4500: 
        !          4501: {
        !          4502: 
        !          4503:     //
        !          4504:     // General Algorithm:
        !          4505:     //
        !          4506:     //
        !          4507:     //   Check if a request is going to pend...
        !          4508:     //      If so, pend the entire operation.
        !          4509:     //
        !          4510:     //   Else
        !          4511:     //      Fill in the request block.
        !          4512:     //
        !          4513:     //
        !          4514: 
        !          4515:     PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)(MacAdapterContext);
        !          4516: 
        !          4517:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4518: 
        !          4519:     //
        !          4520:     //   Check if a request is valid and going to pend...
        !          4521:     //      If so, pend the entire operation.
        !          4522:     //
        !          4523: 
        !          4524: 
        !          4525:     //
        !          4526:     // Switch on request type
        !          4527:     //
        !          4528: 
        !          4529:     switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
        !          4530:         case OID_GEN_SUPPORTED_LIST:
        !          4531:         case OID_GEN_HARDWARE_STATUS:
        !          4532:         case OID_GEN_MEDIA_SUPPORTED:
        !          4533:         case OID_GEN_MEDIA_IN_USE:
        !          4534:         case OID_GEN_MAXIMUM_LOOKAHEAD:
        !          4535:         case OID_GEN_MAXIMUM_FRAME_SIZE:
        !          4536:         case OID_GEN_MAXIMUM_TOTAL_SIZE:
        !          4537:         case OID_GEN_MAC_OPTIONS:
        !          4538:         case OID_GEN_LINK_SPEED:
        !          4539:         case OID_GEN_TRANSMIT_BUFFER_SPACE:
        !          4540:         case OID_GEN_RECEIVE_BUFFER_SPACE:
        !          4541:         case OID_GEN_TRANSMIT_BLOCK_SIZE:
        !          4542:         case OID_GEN_RECEIVE_BLOCK_SIZE:
        !          4543:         case OID_GEN_VENDOR_ID:
        !          4544:         case OID_GEN_VENDOR_DESCRIPTION:
        !          4545:         case OID_GEN_DRIVER_VERSION:
        !          4546:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          4547:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          4548:         case OID_802_3_PERMANENT_ADDRESS:
        !          4549:         case OID_802_3_CURRENT_ADDRESS:
        !          4550:         case OID_802_5_CURRENT_FUNCTIONAL:
        !          4551:         case OID_GEN_XMIT_OK:
        !          4552:         case OID_GEN_RCV_OK:
        !          4553:         case OID_GEN_XMIT_ERROR:
        !          4554:         case OID_GEN_RCV_ERROR:
        !          4555:         case OID_GEN_RCV_NO_BUFFER:
        !          4556:         case OID_802_3_MULTICAST_LIST:
        !          4557:         case OID_802_3_MAXIMUM_LIST_SIZE:
        !          4558:         case OID_802_3_RCV_ERROR_ALIGNMENT:
        !          4559:         case OID_802_3_XMIT_ONE_COLLISION:
        !          4560:         case OID_802_3_XMIT_MORE_COLLISIONS:
        !          4561: 
        !          4562:             break;
        !          4563: 
        !          4564:         default:
        !          4565: 
        !          4566:             StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          4567: 
        !          4568:             break;
        !          4569: 
        !          4570:     }
        !          4571: 
        !          4572:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          4573: 
        !          4574:         StatusToReturn = LanceFillInGlobalData(Adapter, NdisRequest);
        !          4575: 
        !          4576:     }
        !          4577: 
        !          4578:     return(StatusToReturn);
        !          4579: }
        !          4580: 
        !          4581: 
        !          4582: 
        !          4583: STATIC
        !          4584: NDIS_STATUS
        !          4585: LanceReset(
        !          4586:     IN NDIS_HANDLE MacBindingHandle
        !          4587:     )
        !          4588: 
        !          4589: /*++
        !          4590: 
        !          4591: Routine Description:
        !          4592: 
        !          4593:     The LanceReset request instructs the MAC to issue a hardware reset
        !          4594:     to the network adapter.  The MAC also resets its software state.  See
        !          4595:     the description of NdisReset for a detailed description of this request.
        !          4596: 
        !          4597: Arguments:
        !          4598: 
        !          4599:     MacBindingHandle - The context value returned by the MAC  when the
        !          4600:     adapter was opened.  In reality, it is a pointer to LANCE_OPEN.
        !          4601: 
        !          4602: Return Value:
        !          4603: 
        !          4604:     The function value is the status of the operation.
        !          4605: 
        !          4606: 
        !          4607: --*/
        !          4608: 
        !          4609: {
        !          4610: 
        !          4611:     //
        !          4612:     // Holds the status that should be returned to the caller.
        !          4613:     //
        !          4614:     NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
        !          4615: 
        !          4616:     PLANCE_ADAPTER Adapter =
        !          4617:         PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          4618: 
        !          4619:     //
        !          4620:     // Hold the locks while we update the reference counts on the
        !          4621:     // adapter and the open.
        !          4622:     //
        !          4623: 
        !          4624:     NdisAcquireSpinLock(&Adapter->Lock);
        !          4625: 
        !          4626:     Adapter->References++;
        !          4627: 
        !          4628:     if (!Adapter->ResetInProgress) {
        !          4629: 
        !          4630:         PLANCE_OPEN Open;
        !          4631: 
        !          4632:         Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          4633: 
        !          4634:         if (!Open->BindingShuttingDown) {
        !          4635: 
        !          4636:             //
        !          4637:             // Is was a reset request
        !          4638:             //
        !          4639: 
        !          4640:             PLIST_ENTRY CurrentLink;
        !          4641: 
        !          4642:             Open->References++;
        !          4643: 
        !          4644:             CurrentLink = Adapter->OpenBindings.Flink;
        !          4645: 
        !          4646:             while (CurrentLink != &Adapter->OpenBindings) {
        !          4647: 
        !          4648:                 Open = CONTAINING_RECORD(
        !          4649:                                          CurrentLink,
        !          4650:                                          LANCE_OPEN,
        !          4651:                                          OpenList
        !          4652:                                         );
        !          4653: 
        !          4654:                 Open->References++;
        !          4655: 
        !          4656:                 NdisReleaseSpinLock(&Adapter->Lock);
        !          4657: 
        !          4658:                 NdisIndicateStatus(
        !          4659:                                    Open->NdisBindingContext,
        !          4660:                                    NDIS_STATUS_RESET_START,
        !          4661:                                    NULL,
        !          4662:                                    0
        !          4663:                                   );
        !          4664: 
        !          4665:                 NdisAcquireSpinLock(&Adapter->Lock);
        !          4666: 
        !          4667:                 Open->References--;
        !          4668: 
        !          4669:                 CurrentLink = CurrentLink->Flink;
        !          4670: 
        !          4671:             }
        !          4672: 
        !          4673:             Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          4674: 
        !          4675: #if LANCE_TRACE
        !          4676:             DbgPrint("Starting reset for 0x%x\n", Open);
        !          4677: #endif
        !          4678: 
        !          4679:             SetupForReset(
        !          4680:                 Adapter,
        !          4681:                 Open,
        !          4682:                 NULL,
        !          4683:                 NdisRequestGeneric1 // Means Reset
        !          4684:                 );
        !          4685: 
        !          4686:             Open->References--;
        !          4687: 
        !          4688:         } else {
        !          4689: 
        !          4690:             StatusToReturn = NDIS_STATUS_CLOSING;
        !          4691: 
        !          4692:         }
        !          4693: 
        !          4694:     } else {
        !          4695: 
        !          4696:         StatusToReturn = NDIS_STATUS_SUCCESS;
        !          4697: 
        !          4698:     }
        !          4699: 
        !          4700:     LANCE_DO_DEFERRED(Adapter);
        !          4701: 
        !          4702:     return StatusToReturn;
        !          4703: 
        !          4704: }
        !          4705: 
        !          4706: STATIC
        !          4707: VOID
        !          4708: LanceSetInitializationBlock(
        !          4709:     IN PLANCE_ADAPTER Adapter
        !          4710:     )
        !          4711: 
        !          4712: /*++
        !          4713: 
        !          4714: Routine Description:
        !          4715: 
        !          4716:     This routine simply fills the initialization block
        !          4717:     with the information necessary for initialization.
        !          4718: 
        !          4719:     NOTE: This routine assumes that it is called with the lock
        !          4720:     acquired OR that only a single thread of execution is accessing
        !          4721:     the particular adapter.
        !          4722: 
        !          4723: Arguments:
        !          4724: 
        !          4725:     Adapter - The adapter which holds the initialization block
        !          4726:     to initialize.
        !          4727: 
        !          4728: Return Value:
        !          4729: 
        !          4730:     None.
        !          4731: 
        !          4732: 
        !          4733: --*/
        !          4734: 
        !          4735: {
        !          4736: 
        !          4737:     PHYSICAL_ADDRESS PhysAdr;
        !          4738: 
        !          4739:     UINT PacketFilters;
        !          4740: 
        !          4741:     PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing;
        !          4742:     USHORT Mode;
        !          4743:     UCHAR RingNumber;
        !          4744:     UCHAR i;
        !          4745: 
        !          4746: #if LANCE_TRACE
        !          4747:     DbgPrint("in SetInitBlock\n");
        !          4748: #endif
        !          4749: 
        !          4750:     LANCE_ZERO_MEMORY_FOR_HARDWARE(
        !          4751:         Adapter->InitBlock,
        !          4752:         sizeof(LANCE_INITIALIZATION_BLOCK)
        !          4753:         );
        !          4754: 
        !          4755:     for (i=0; i < ETH_LENGTH_OF_ADDRESS; i++) {
        !          4756: 
        !          4757:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4758:             Adapter->InitBlock->PhysicalAddress[i],
        !          4759:             Adapter->CurrentNetworkAddress[i]
        !          4760:             );
        !          4761: 
        !          4762:     }
        !          4763: 
        !          4764:     PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter, Adapter->TransmitRing);
        !          4765: 
        !          4766: 
        !          4767:     LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS(
        !          4768:          Adapter->InitBlock->LowTransmitRingAddress,
        !          4769:          LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart)
        !          4770:          );
        !          4771:     LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS(
        !          4772:          Adapter->InitBlock->HighTransmitRingAddress,
        !          4773:          LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart)
        !          4774:          );
        !          4775: 
        !          4776:     PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter, Adapter->ReceiveRing);
        !          4777: 
        !          4778:     //
        !          4779:     // Set that the chip owns each entry in the ring
        !          4780:     //
        !          4781: 
        !          4782:     for (CurrentEntry = Adapter->ReceiveRing, RingNumber = 0;
        !          4783:          RingNumber < Adapter->NumberOfReceiveRings ;
        !          4784:          RingNumber++, CurrentEntry++) {
        !          4785: 
        !          4786:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4787:              CurrentEntry->ReceiveSummaryBits,
        !          4788:              LANCE_RECEIVE_OWNED_BY_CHIP
        !          4789:              );
        !          4790: 
        !          4791:     }
        !          4792: 
        !          4793: 
        !          4794:     LANCE_WRITE_HARDWARE_LOW_PART_ADDRESS(
        !          4795:          Adapter->InitBlock->LowReceiveRingAddress,
        !          4796:          LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart)
        !          4797:          );
        !          4798:     LANCE_WRITE_HARDWARE_HIGH_PART_ADDRESS(
        !          4799:          Adapter->InitBlock->HighReceiveRingAddress,
        !          4800:          LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart)
        !          4801:          );
        !          4802: 
        !          4803:     LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4804:         Adapter->InitBlock->TransmitLengthLow5BitsReserved,
        !          4805:         (UCHAR)(Adapter->LogNumberTransmitRings << 5)
        !          4806:         );
        !          4807: 
        !          4808:     LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4809:          Adapter->InitBlock->ReceiveLengthLow5BitsReserved,
        !          4810:          (UCHAR)(Adapter->LogNumberReceiveRings << 5)
        !          4811:          );
        !          4812: 
        !          4813:     //
        !          4814:     // Set up the address filtering.
        !          4815:     //
        !          4816:     // First get hold of the combined packet filter.
        !          4817:     //
        !          4818: 
        !          4819:     PacketFilters = ETH_QUERY_FILTER_CLASSES(Adapter->FilterDB);
        !          4820: 
        !          4821: #if LANCE_TRACE
        !          4822:     DbgPrint("Filters 0x%x\n", PacketFilters);
        !          4823: #endif
        !          4824: 
        !          4825:     if (PacketFilters & NDIS_PACKET_TYPE_PROMISCUOUS) {
        !          4826: 
        !          4827:         //
        !          4828:         // If one binding is promiscuous there is no point in
        !          4829:         // setting up any other filtering.  Every packet is
        !          4830:         // going to be accepted by the hardware.
        !          4831:         //
        !          4832: 
        !          4833:         LANCE_READ_HARDWARE_MEMORY_USHORT(
        !          4834:                  Adapter->InitBlock->ModeRegister,
        !          4835:                  &Mode
        !          4836:                  );
        !          4837: 
        !          4838:         LANCE_WRITE_HARDWARE_MEMORY_USHORT(
        !          4839:              Adapter->InitBlock->ModeRegister,
        !          4840:              Mode | LANCE_MODE_PROMISCUOUS
        !          4841:              );
        !          4842: 
        !          4843:     } else if (PacketFilters & NDIS_PACKET_TYPE_ALL_MULTICAST) {
        !          4844: 
        !          4845:         //
        !          4846:         // We turn on all the bits in the filter since one binding
        !          4847:         // wants every multicast address.
        !          4848:         //
        !          4849: 
        !          4850:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4851:              Adapter->InitBlock->LogicalAddressFilter[0],
        !          4852:              0xff
        !          4853:              );
        !          4854:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4855:              Adapter->InitBlock->LogicalAddressFilter[1],
        !          4856:              0xff
        !          4857:              );
        !          4858:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4859:              Adapter->InitBlock->LogicalAddressFilter[2],
        !          4860:              0xff
        !          4861:              );
        !          4862:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4863:              Adapter->InitBlock->LogicalAddressFilter[3],
        !          4864:              0xff
        !          4865:              );
        !          4866:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4867:              Adapter->InitBlock->LogicalAddressFilter[4],
        !          4868:              0xff
        !          4869:              );
        !          4870:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4871:              Adapter->InitBlock->LogicalAddressFilter[5],
        !          4872:              0xff
        !          4873:              );
        !          4874:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4875:              Adapter->InitBlock->LogicalAddressFilter[6],
        !          4876:              0xff
        !          4877:              );
        !          4878:         LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4879:              Adapter->InitBlock->LogicalAddressFilter[7],
        !          4880:              0xff
        !          4881:              );
        !          4882: 
        !          4883:     } else if (PacketFilters & NDIS_PACKET_TYPE_MULTICAST) {
        !          4884: 
        !          4885:         //
        !          4886:         // At least one open binding wants multicast addresses.
        !          4887:         //
        !          4888:         // We get the multicast addresses from the filter and
        !          4889:         // put each one through a CRC.  We then take the high
        !          4890:         // order 6 bits from the 32 bit CRC and set that bit
        !          4891:         // in the logical address filter.
        !          4892:         //
        !          4893: 
        !          4894:         UINT NumberOfAddresses;
        !          4895: 
        !          4896:         NDIS_STATUS Status;
        !          4897: 
        !          4898:         EthQueryGlobalFilterAddresses(
        !          4899:             &Status,
        !          4900:             Adapter->FilterDB,
        !          4901:             MAX_MULTICAST_ADDRESS * ETH_LENGTH_OF_ADDRESS,
        !          4902:             &NumberOfAddresses,
        !          4903:             MulticastAddresses
        !          4904:             );
        !          4905: 
        !          4906: 
        !          4907:         ASSERT(Status == NDIS_STATUS_SUCCESS);
        !          4908: 
        !          4909:         ASSERT(sizeof(ULONG) == 4);
        !          4910: 
        !          4911:         for (
        !          4912:             ;
        !          4913:             NumberOfAddresses;
        !          4914:             NumberOfAddresses--
        !          4915:             ) {
        !          4916: 
        !          4917:             UINT CRCValue;
        !          4918: 
        !          4919:             UINT HashValue = 0;
        !          4920: 
        !          4921:             CRCValue = CalculateCRC(
        !          4922:                            6,
        !          4923:                            MulticastAddresses[NumberOfAddresses-1]
        !          4924:                            );
        !          4925: 
        !          4926:             HashValue |= ((CRCValue & 0x00000001)?(0x00000020):(0x00000000));
        !          4927:             HashValue |= ((CRCValue & 0x00000002)?(0x00000010):(0x00000000));
        !          4928:             HashValue |= ((CRCValue & 0x00000004)?(0x00000008):(0x00000000));
        !          4929:             HashValue |= ((CRCValue & 0x00000008)?(0x00000004):(0x00000000));
        !          4930:             HashValue |= ((CRCValue & 0x00000010)?(0x00000002):(0x00000000));
        !          4931:             HashValue |= ((CRCValue & 0x00000020)?(0x00000001):(0x00000000));
        !          4932: 
        !          4933:             LANCE_READ_HARDWARE_MEMORY_UCHAR(
        !          4934:                       Adapter->InitBlock->LogicalAddressFilter[HashValue >> 3],
        !          4935:                       &RingNumber
        !          4936:                       );
        !          4937: 
        !          4938:             LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          4939:                   Adapter->InitBlock->LogicalAddressFilter[HashValue >> 3],
        !          4940:                   RingNumber | (1 << (HashValue & 0x00000007))
        !          4941:                   );
        !          4942: 
        !          4943:         }
        !          4944: 
        !          4945:     }
        !          4946: 
        !          4947: #if LANCE_TRACE
        !          4948:     DbgPrint("out SetInitBlock\n");
        !          4949: #endif
        !          4950: }
        !          4951: 
        !          4952: STATIC
        !          4953: UINT
        !          4954: CalculateCRC(
        !          4955:     IN UINT NumberOfBytes,
        !          4956:     IN PCHAR Input
        !          4957:     )
        !          4958: 
        !          4959: /*++
        !          4960: 
        !          4961: Routine Description:
        !          4962: 
        !          4963:     Calculates a 32 bit crc value over the input number of bytes.
        !          4964: 
        !          4965: Arguments:
        !          4966: 
        !          4967:     NumberOfBytes - The number of bytes in the input.
        !          4968: 
        !          4969:     Input - An input "string" to calculate a CRC over.
        !          4970: 
        !          4971: Return Value:
        !          4972: 
        !          4973:     A 32 bit crc value.
        !          4974: 
        !          4975: 
        !          4976: --*/
        !          4977: 
        !          4978: {
        !          4979: 
        !          4980:     const UINT POLY = 0x04c11db6;
        !          4981:     UINT CRCValue = 0xffffffff;
        !          4982: 
        !          4983:     ASSERT(sizeof(UINT) == 4);
        !          4984: 
        !          4985:     for (
        !          4986:         ;
        !          4987:         NumberOfBytes;
        !          4988:         NumberOfBytes--
        !          4989:         ) {
        !          4990: 
        !          4991:         UINT CurrentBit;
        !          4992:         UCHAR CurrentByte = *Input;
        !          4993:         Input++;
        !          4994: 
        !          4995:         for (
        !          4996:             CurrentBit = 8;
        !          4997:             CurrentBit;
        !          4998:             CurrentBit--
        !          4999:             ) {
        !          5000: 
        !          5001:             UINT CurrentCRCHigh = CRCValue >> 31;
        !          5002: 
        !          5003:             CRCValue <<= 1;
        !          5004: 
        !          5005:             if (CurrentCRCHigh ^ (CurrentByte & 0x01)) {
        !          5006: 
        !          5007:                 CRCValue ^= POLY;
        !          5008:                 CRCValue |= 0x00000001;
        !          5009: 
        !          5010:             }
        !          5011: 
        !          5012:             CurrentByte >>= 1;
        !          5013: 
        !          5014:         }
        !          5015: 
        !          5016:     }
        !          5017: 
        !          5018:     return CRCValue;
        !          5019: 
        !          5020: }
        !          5021: 
        !          5022: STATIC
        !          5023: NDIS_STATUS
        !          5024: LanceChangeMulticastAddresses(
        !          5025:     IN UINT OldFilterCount,
        !          5026:     IN CHAR OldAddresses[][ETH_LENGTH_OF_ADDRESS],
        !          5027:     IN UINT NewFilterCount,
        !          5028:     IN CHAR NewAddresses[][ETH_LENGTH_OF_ADDRESS],
        !          5029:     IN NDIS_HANDLE MacBindingHandle,
        !          5030:     IN PNDIS_REQUEST NdisRequest,
        !          5031:     IN BOOLEAN Set
        !          5032:     )
        !          5033: 
        !          5034: /*++
        !          5035: 
        !          5036: Routine Description:
        !          5037: 
        !          5038:     Action routine that will get called when a particular filter
        !          5039:     class is first used or last cleared.
        !          5040: 
        !          5041:     NOTE: This routine assumes that it is called with the lock
        !          5042:     acquired.
        !          5043: 
        !          5044: Arguments:
        !          5045: 
        !          5046: 
        !          5047:     OldFilterCount - Number of Addresses in the old list of multicast
        !          5048:     addresses.
        !          5049: 
        !          5050:     OldAddresses - An array of all the multicast addresses that used
        !          5051:     to be on the adapter.
        !          5052: 
        !          5053:     NewFilterCount - Number of Addresses that should be put on the adapter.
        !          5054: 
        !          5055:     NewAddresses - An array of all the multicast addresses that should
        !          5056:     now be used.
        !          5057: 
        !          5058:     MacBindingHandle - The context value returned by the MAC  when the
        !          5059:     adapter was opened.  In reality, it is a pointer to LANCE_OPEN.
        !          5060: 
        !          5061:     NdisRequest - The request which submitted the filter change.
        !          5062:     Must use when completing this request with the NdisCompleteRequest
        !          5063:     service, if the MAC completes this request asynchronously.
        !          5064: 
        !          5065:     Set - If true the change resulted from a set, otherwise the
        !          5066:     change resulted from a open closing.
        !          5067: 
        !          5068: Return Value:
        !          5069: 
        !          5070:     None.
        !          5071: 
        !          5072: 
        !          5073: --*/
        !          5074: 
        !          5075: {
        !          5076: 
        !          5077: 
        !          5078:     PLANCE_ADAPTER Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          5079: 
        !          5080:     UNREFERENCED_PARAMETER(OldFilterCount);
        !          5081:     UNREFERENCED_PARAMETER(OldAddresses);
        !          5082:     UNREFERENCED_PARAMETER(NewFilterCount);
        !          5083:     UNREFERENCED_PARAMETER(NewAddresses);
        !          5084: 
        !          5085: #if LANCE_TRACE
        !          5086:     DbgPrint("In LanceChangeMultiAdresses\n");
        !          5087: #endif
        !          5088: 
        !          5089:     if (Adapter->HardwareFailure) {
        !          5090: 
        !          5091:         return(NDIS_STATUS_SUCCESS);
        !          5092: 
        !          5093:     }
        !          5094: 
        !          5095:     if (NdisRequest == NULL) {
        !          5096: 
        !          5097:         //
        !          5098:         // It's a close request.
        !          5099:         //
        !          5100: 
        !          5101:         NdisRequest = (PNDIS_REQUEST)
        !          5102:            &(PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->CloseMulticastRequest);
        !          5103: 
        !          5104:     }
        !          5105: 
        !          5106:     //
        !          5107:     // Check to see if the device is already resetting.  If it is
        !          5108:     // then pend this add.
        !          5109:     //
        !          5110: 
        !          5111:     if (Adapter->ResetInProgress) {
        !          5112: 
        !          5113:         if (Adapter->PendQueue == NULL) {
        !          5114: 
        !          5115:             Adapter->PendQueue = Adapter->PendQueueTail = NdisRequest;
        !          5116: 
        !          5117:         } else {
        !          5118: 
        !          5119:             PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Adapter->PendQueueTail)->Next =
        !          5120:                 NdisRequest;
        !          5121: 
        !          5122:         }
        !          5123: 
        !          5124:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next = NULL;
        !          5125: 
        !          5126:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open =
        !          5127:             PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          5128: 
        !          5129:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType =
        !          5130:             Set ? NdisRequestGeneric2 : NdisRequestClose;
        !          5131: 
        !          5132:         return(NDIS_STATUS_PENDING);
        !          5133: 
        !          5134:     } else {
        !          5135: 
        !          5136:         //
        !          5137:         // We need to add this to the hardware multicast filtering.
        !          5138:         //
        !          5139: 
        !          5140:         SetupForReset(
        !          5141:                     Adapter,
        !          5142:                     PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle),
        !          5143:                     NdisRequest,
        !          5144:                     Set ? NdisRequestGeneric2 : // Means SetMulticastAddress
        !          5145:                           NdisRequestClose
        !          5146:                     );
        !          5147: 
        !          5148:     }
        !          5149: 
        !          5150: #if LANCE_TRACE
        !          5151:     DbgPrint("Out LanceChangeMultiAdresses\n");
        !          5152: #endif
        !          5153: 
        !          5154:     return NDIS_STATUS_PENDING;
        !          5155: 
        !          5156: }
        !          5157: 
        !          5158: STATIC
        !          5159: NDIS_STATUS
        !          5160: LanceChangeFilterClasses(
        !          5161:     IN UINT OldFilterClasses,
        !          5162:     IN UINT NewFilterClasses,
        !          5163:     IN NDIS_HANDLE MacBindingHandle,
        !          5164:     IN PNDIS_REQUEST NdisRequest,
        !          5165:     IN BOOLEAN Set
        !          5166:     )
        !          5167: 
        !          5168: /*++
        !          5169: 
        !          5170: Routine Description:
        !          5171: 
        !          5172:     Action routine that will get called when an address is added to
        !          5173:     the filter that wasn't referenced by any other open binding.
        !          5174: 
        !          5175:     NOTE: This routine assumes that it is called with the lock
        !          5176:     acquired.
        !          5177: 
        !          5178: Arguments:
        !          5179: 
        !          5180:     OldFilterClasses - The filter mask that used to be on the adapter.
        !          5181: 
        !          5182:     NewFilterClasses - The new filter mask to be put on the adapter.
        !          5183: 
        !          5184:     MacBindingHandle - The context value returned by the MAC  when the
        !          5185:     adapter was opened.  In reality, it is a pointer to LANCE_OPEN.
        !          5186: 
        !          5187:     NdisRequest - The request which submitted the filter change.
        !          5188:     Must use when completing this request with the NdisCompleteRequest
        !          5189:     service, if the MAC completes this request asynchronously.
        !          5190: 
        !          5191:     Set - If true the change resulted from a set, otherwise the
        !          5192:     change resulted from a open closing.
        !          5193: 
        !          5194: --*/
        !          5195: 
        !          5196: {
        !          5197: 
        !          5198:     PLANCE_ADAPTER Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          5199: 
        !          5200:     UNREFERENCED_PARAMETER(OldFilterClasses);
        !          5201:     UNREFERENCED_PARAMETER(NewFilterClasses);
        !          5202: 
        !          5203: #if LANCE_TRACE
        !          5204:     DbgPrint("In LanceChangeFilterClasses\n");
        !          5205: #endif
        !          5206: 
        !          5207: 
        !          5208:     if (Adapter->HardwareFailure) {
        !          5209: 
        !          5210:         return(NDIS_STATUS_SUCCESS);
        !          5211: 
        !          5212:     }
        !          5213: 
        !          5214: 
        !          5215:     if (NdisRequest == NULL) {
        !          5216: 
        !          5217:         //
        !          5218:         // It's a close request.
        !          5219:         //
        !          5220: 
        !          5221:         NdisRequest = (PNDIS_REQUEST)
        !          5222:            &(PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->CloseFilterRequest);
        !          5223: 
        !          5224:     }
        !          5225: 
        !          5226:     //
        !          5227:     // Check to see if the device is already resetting.  If it is
        !          5228:     // then pend this add.
        !          5229:     //
        !          5230: 
        !          5231: 
        !          5232:     if (Adapter->ResetInProgress) {
        !          5233: 
        !          5234:         if (Adapter->PendQueue == NULL) {
        !          5235: 
        !          5236:             Adapter->PendQueue = Adapter->PendQueueTail = NdisRequest;
        !          5237: 
        !          5238:         } else {
        !          5239: 
        !          5240:             PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Adapter->PendQueueTail)->Next =
        !          5241:                 NdisRequest;
        !          5242: 
        !          5243:         }
        !          5244: 
        !          5245:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next = NULL;
        !          5246: 
        !          5247:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open =
        !          5248:             PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          5249: 
        !          5250:         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType =
        !          5251:             Set ? NdisRequestGeneric2 : NdisRequestClose;
        !          5252: 
        !          5253:         return(NDIS_STATUS_PENDING);
        !          5254: 
        !          5255:     } else {
        !          5256: 
        !          5257:         //
        !          5258:         // We need to add this to the hardware multicast filtering.
        !          5259:         //
        !          5260: 
        !          5261:         SetupForReset(
        !          5262:                     Adapter,
        !          5263:                     PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle),
        !          5264:                     NdisRequest,
        !          5265:                     Set ? NdisRequestGeneric3 : // Means SetPacketFilter
        !          5266:                           NdisRequestClose
        !          5267:                     );
        !          5268: 
        !          5269:     }
        !          5270: 
        !          5271: #if LANCE_TRACE
        !          5272:     DbgPrint("Out LanceChangeFilterClasses\n");
        !          5273: #endif
        !          5274: 
        !          5275:     return NDIS_STATUS_PENDING;
        !          5276: 
        !          5277: }
        !          5278: 
        !          5279: STATIC
        !          5280: VOID
        !          5281: LanceCloseAction(
        !          5282:     IN NDIS_HANDLE MacBindingHandle
        !          5283:     )
        !          5284: 
        !          5285: /*++
        !          5286: 
        !          5287: Routine Description:
        !          5288: 
        !          5289:     Action routine that will get called when a particular binding
        !          5290:     was closed while it was indicating through NdisIndicateReceive
        !          5291: 
        !          5292:     All this routine needs to do is to decrement the reference count
        !          5293:     of the binding.
        !          5294: 
        !          5295:     NOTE: This routine assumes that it is called with the lock acquired.
        !          5296: 
        !          5297: Arguments:
        !          5298: 
        !          5299:     MacBindingHandle - The context value returned by the MAC  when the
        !          5300:     adapter was opened.  In reality, it is a pointer to LANCE_OPEN.
        !          5301: 
        !          5302: Return Value:
        !          5303: 
        !          5304:     None.
        !          5305: 
        !          5306: 
        !          5307: --*/
        !          5308: 
        !          5309: {
        !          5310: 
        !          5311:     PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->References--;
        !          5312: 
        !          5313: }
        !          5314: 
        !          5315: STATIC
        !          5316: VOID
        !          5317: ProcessInterrupt(
        !          5318:     IN PLANCE_ADAPTER Adapter
        !          5319:     )
        !          5320: 
        !          5321: /*++
        !          5322: 
        !          5323: Routine Description:
        !          5324: 
        !          5325:     Main routine for processing interrupts.
        !          5326: 
        !          5327:     NOTE: MUST BE CALLED WITH LOCK HELD!
        !          5328: 
        !          5329: Arguments:
        !          5330: 
        !          5331:     Adapter - The Adapter to process interrupts for.
        !          5332: 
        !          5333: Return Value:
        !          5334: 
        !          5335:     None.
        !          5336: 
        !          5337: --*/
        !          5338: 
        !          5339: {
        !          5340: 
        !          5341:     //
        !          5342:     // Holds a value of csr0.
        !          5343:     //
        !          5344:     USHORT Csr = 0;
        !          5345: 
        !          5346:     //
        !          5347:     // Loop until there are no more processing sources.
        !          5348:     //
        !          5349: 
        !          5350:     while (TRUE) {
        !          5351: 
        !          5352:         Adapter->WakeUpTimeout = FALSE;
        !          5353: 
        !          5354:         GET_CSR0_SINCE_LAST_PROCESSED(
        !          5355:             Adapter,
        !          5356:             &Csr
        !          5357:             );
        !          5358: 
        !          5359:         //
        !          5360:         // Check the interrupt source and other reasons
        !          5361:         // for processing.  If there are no reasons to
        !          5362:         // process then exit this loop.
        !          5363:         //
        !          5364:         // Note that when we check the for processing sources
        !          5365:         // that we "carefully" check to see if we are already
        !          5366:         // processing one of the stage queues.  We do this
        !          5367:         // by checking the "AlreadyProcessingStageX" variables
        !          5368:         // in the adapter.  If any of these are true then
        !          5369:         // we let whoever set that boolean take care of pushing
        !          5370:         // the packet through the stage queues.
        !          5371:         //
        !          5372:         // By checking the "AlreadyProcessingStageX" variables
        !          5373:         // we can prevent a possible priority inversion where
        !          5374:         // we get "stuck" behind something that is processing
        !          5375:         // at a lower priority level.
        !          5376:         //
        !          5377: 
        !          5378:         if (((!Adapter->ResetInitStarted) &&
        !          5379:              ((Csr & (LANCE_CSR0_MEMORY_ERROR |
        !          5380:                       LANCE_CSR0_MISSED_PACKET |
        !          5381:                       LANCE_CSR0_BABBLE |
        !          5382:                       LANCE_CSR0_RECEIVER_INTERRUPT |
        !          5383:                       LANCE_CSR0_TRANSMITTER_INTERRUPT)) ||
        !          5384:               (Adapter->FirstLoopBack) ||
        !          5385:               (Adapter->ResetInProgress && (!Adapter->References)) ||
        !          5386:               ((!Adapter->AlreadyProcessingStage) &&
        !          5387:                (Adapter->StageOpen && Adapter->FirstStage1Packet)))) ||
        !          5388:             (Csr & LANCE_CSR0_INITIALIZATION_DONE)) {
        !          5389: 
        !          5390:             Adapter->References++;
        !          5391: 
        !          5392:         } else {
        !          5393: 
        !          5394:             break;
        !          5395: 
        !          5396:         }
        !          5397: 
        !          5398:         //
        !          5399:         // Check for initialization.
        !          5400:         //
        !          5401:         // Note that we come out of the synchronization above holding
        !          5402:         // the spinlock.
        !          5403:         //
        !          5404: 
        !          5405:         if (Csr & LANCE_CSR0_INITIALIZATION_DONE) {
        !          5406: 
        !          5407:             //
        !          5408:             // This will point (possibly null) to the open that
        !          5409:             // initiated the reset.
        !          5410:             //
        !          5411:             PLANCE_OPEN ResettingOpen;
        !          5412: 
        !          5413:             //
        !          5414:             // Possibly undefined reason why the reset was requested.
        !          5415:             //
        !          5416:             // It is undefined if the adapter initiated the reset
        !          5417:             // request on its own.  It could do that if there
        !          5418:             // were some sort of error not associated with any particular
        !          5419:             // open.
        !          5420:             //
        !          5421:             NDIS_REQUEST_TYPE ResetRequestType;
        !          5422: 
        !          5423:             //
        !          5424:             // Possibly undefined request for the reset request.
        !          5425:             //
        !          5426:             PNDIS_REQUEST ResetNdisRequest;
        !          5427: 
        !          5428:             LOG(RESET_STEP_3);
        !          5429: 
        !          5430:             ASSERT(!Adapter->FirstInitialization);
        !          5431: 
        !          5432:             Csr &= ~LANCE_CSR0_INITIALIZATION_DONE;
        !          5433: 
        !          5434:             Adapter->ResetInProgress = FALSE;
        !          5435:             Adapter->ResetInitStarted = FALSE;
        !          5436: 
        !          5437:             //
        !          5438:             // We save off the open that caused this reset incase
        !          5439:             // we get *another* reset while we're indicating the
        !          5440:             // last reset is done.
        !          5441:             //
        !          5442: 
        !          5443:             ResettingOpen = Adapter->ResettingOpen;
        !          5444:             ResetRequestType = Adapter->ResetRequestType;
        !          5445:             ResetNdisRequest = Adapter->ResetNdisRequest;
        !          5446: 
        !          5447:             //
        !          5448:             // We need to signal every open binding that the
        !          5449:             // reset is complete.  We increment the reference
        !          5450:             // count on the open binding while we're doing indications
        !          5451:             // so that the open can't be deleted out from under
        !          5452:             // us while we're indicating (recall that we can't own
        !          5453:             // the lock during the indication).
        !          5454:             //
        !          5455: 
        !          5456:             {
        !          5457: 
        !          5458:                 PLANCE_OPEN Open;
        !          5459: 
        !          5460:                 //
        !          5461:                 // Look to see which open initiated the reset.
        !          5462:                 //
        !          5463:                 // If the reset was initiated by an open because it
        !          5464:                 // was closing we will let the closing binding loop
        !          5465:                 // further on in this routine indicate that the
        !          5466:                 // request was complete.
        !          5467:                 //
        !          5468:                 // If the reset was initiated for some obscure hardware
        !          5469:                 // reason that can't be associated with a particular
        !          5470:                 // open (e.g. memory error on receiving a packet) then
        !          5471:                 // we won't have an initiating request so we can't
        !          5472:                 // indicate.  (The ResettingOpen pointer will be
        !          5473:                 // NULL in this case.)
        !          5474:                 //
        !          5475: 
        !          5476: #if LANCE_TRACE
        !          5477:                 DbgPrint("0x%x 0x%x 0x%x %d %d\n",
        !          5478:                                           Adapter,
        !          5479:                                           ResettingOpen,
        !          5480:                                           ResetNdisRequest,
        !          5481:                                           ResetRequestType,
        !          5482:                                           NdisRequestClose
        !          5483:                                          );
        !          5484: #endif
        !          5485: 
        !          5486:                 if ((ResettingOpen != NULL) &&
        !          5487:                     (ResetRequestType != NdisRequestClose)) {
        !          5488: 
        !          5489:                     if (ResetNdisRequest != NULL) {
        !          5490: 
        !          5491:                         //
        !          5492:                         // It was a request submitted by a protocol.
        !          5493:                         //
        !          5494: 
        !          5495:                         FinishPendOp(Adapter, TRUE);
        !          5496: 
        !          5497:                     } else {
        !          5498: 
        !          5499:                         //
        !          5500:                         // It was a request submitted by the MAC or
        !          5501:                         // a reset command.
        !          5502:                         //
        !          5503: 
        !          5504:                         if (ResetRequestType == NdisRequestGeneric1) {
        !          5505: 
        !          5506:                             //
        !          5507:                             // Is was a reset request
        !          5508:                             //
        !          5509: 
        !          5510:                             PLIST_ENTRY CurrentLink;
        !          5511: 
        !          5512:                             CurrentLink = Adapter->OpenBindings.Flink;
        !          5513: 
        !          5514:                             while (CurrentLink != &Adapter->OpenBindings) {
        !          5515: 
        !          5516:                                 Open = CONTAINING_RECORD(
        !          5517:                                          CurrentLink,
        !          5518:                                          LANCE_OPEN,
        !          5519:                                          OpenList
        !          5520:                                          );
        !          5521: 
        !          5522:                                 Open->References++;
        !          5523:                                 NdisDprReleaseSpinLock(&Adapter->Lock);
        !          5524: 
        !          5525:                                 NdisIndicateStatus(
        !          5526:                                     Open->NdisBindingContext,
        !          5527:                                     NDIS_STATUS_RESET_END,
        !          5528:                                     NULL,
        !          5529:                                     0
        !          5530:                                     );
        !          5531: 
        !          5532:                                 NdisIndicateStatusComplete(
        !          5533:                                     Open->NdisBindingContext
        !          5534:                                     );
        !          5535: 
        !          5536:                                 NdisDprAcquireSpinLock(&Adapter->Lock);
        !          5537: 
        !          5538:                                 Open->References--;
        !          5539: 
        !          5540:                                 CurrentLink = CurrentLink->Flink;
        !          5541: 
        !          5542:                             }
        !          5543: 
        !          5544: #if DBG
        !          5545:                             Adapter->ResettingOpen = NULL;
        !          5546:                             Adapter->ResetNdisRequest = NULL;
        !          5547:                             Adapter->ResetRequestType = (NDIS_REQUEST_TYPE)0;
        !          5548: #endif
        !          5549: 
        !          5550: #if LANCE_TRACE
        !          5551:                             DbgPrint("Completing reset\n");
        !          5552: #endif
        !          5553: 
        !          5554:                             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          5555: 
        !          5556:                             NdisCompleteReset(
        !          5557:                                  ResettingOpen->NdisBindingContext,
        !          5558:                                  NDIS_STATUS_SUCCESS
        !          5559:                                  );
        !          5560: 
        !          5561: 
        !          5562:                             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          5563: 
        !          5564:                             ResettingOpen->References--;
        !          5565: 
        !          5566:                         }
        !          5567: 
        !          5568: 
        !          5569:                     }
        !          5570: 
        !          5571:                     //
        !          5572:                     // Restart the chip.
        !          5573:                     //
        !          5574: 
        !          5575:                     LanceStartChip(Adapter);
        !          5576: 
        !          5577:                 } else {
        !          5578: 
        !          5579:                     //
        !          5580:                     // It was a close that pended (if there is
        !          5581:                     // a ResettingOpen).  Subtract 2, one for the
        !          5582:                     // reset and one for the pended operation.
        !          5583:                     //
        !          5584: 
        !          5585:                     if (ResettingOpen) {
        !          5586: 
        !          5587:                         ResettingOpen->References--;
        !          5588: 
        !          5589: #if DBG
        !          5590:                         Adapter->ResettingOpen = NULL;
        !          5591:                         Adapter->ResetNdisRequest = NULL;
        !          5592:                         Adapter->ResetRequestType = (NDIS_REQUEST_TYPE)0;
        !          5593: #endif
        !          5594: 
        !          5595:                     }
        !          5596: 
        !          5597:                     if (!Adapter->ResetInProgress) {
        !          5598: 
        !          5599:                         LanceStartChip(Adapter);
        !          5600: 
        !          5601:                     }
        !          5602: 
        !          5603:                 }
        !          5604: 
        !          5605:             }
        !          5606: 
        !          5607:             //
        !          5608:             // Fire off any pending operations...
        !          5609:             //
        !          5610: 
        !          5611:             if (Adapter->PendQueue != NULL) {
        !          5612: 
        !          5613:                 PNDIS_REQUEST NdisRequest;
        !          5614: 
        !          5615:                 NdisRequest = Adapter->PendQueue;
        !          5616: 
        !          5617:                 Adapter->PendQueue =
        !          5618:                     PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Next;
        !          5619: 
        !          5620:                 if (NdisRequest == Adapter->PendQueueTail) {
        !          5621: 
        !          5622:                     Adapter->PendQueueTail = NULL;
        !          5623: 
        !          5624:                 }
        !          5625: 
        !          5626:                 if (PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType ==
        !          5627:                     NdisRequestClose) {
        !          5628: 
        !          5629:                     SetupForReset(
        !          5630:                         Adapter,
        !          5631:                         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open,
        !          5632:                         NULL,
        !          5633:                         NdisRequestClose
        !          5634:                         );
        !          5635: 
        !          5636:                 } else {
        !          5637: 
        !          5638:                     SetupForReset(
        !          5639:                         Adapter,
        !          5640:                         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->Open,
        !          5641:                         NdisRequest,
        !          5642:                         PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest)->RequestType
        !          5643:                         );
        !          5644: 
        !          5645:                 }
        !          5646: 
        !          5647:             }
        !          5648: 
        !          5649:             goto LoopBottom;
        !          5650: 
        !          5651:         }
        !          5652: 
        !          5653:         //
        !          5654:         // Note that the following code depends on the fact that
        !          5655:         // code above left the spinlock held.
        !          5656:         //
        !          5657: 
        !          5658:         //
        !          5659:         // If we have a reset in progress and the adapters reference
        !          5660:         // count is 1 (meaning no routine is in the interface and
        !          5661:         // we are the only "active" interrupt processing routine) then
        !          5662:         // it is safe to start the reset.
        !          5663:         //
        !          5664: 
        !          5665:         if (Adapter->ResetInProgress &&
        !          5666:             !Adapter->ResetInitStarted &&
        !          5667:             (Adapter->References == 1)) {
        !          5668: 
        !          5669: #if LANCE_TRACE
        !          5670:             DbgPrint("Starting Initialization.\n");
        !          5671: #endif
        !          5672: 
        !          5673:             StartAdapterReset(Adapter);
        !          5674: 
        !          5675:             Adapter->ResetInitStarted = TRUE;
        !          5676:             goto LoopBottom;
        !          5677: 
        !          5678:         }
        !          5679: 
        !          5680:         //
        !          5681:         // Check for non-packet related errors.
        !          5682:         //
        !          5683: 
        !          5684:         if (Csr & (LANCE_CSR0_MEMORY_ERROR |
        !          5685:                    LANCE_CSR0_MISSED_PACKET |
        !          5686:                    LANCE_CSR0_BABBLE)) {
        !          5687: 
        !          5688:             if (Csr & LANCE_CSR0_MISSED_PACKET) {
        !          5689: 
        !          5690:                 Adapter->MissedPacket++;
        !          5691: 
        !          5692:             } else if (Csr & LANCE_CSR0_BABBLE) {
        !          5693: 
        !          5694:                 //
        !          5695:                 // A babble error implies that we've sent a
        !          5696:                 // packet that is greater than the ethernet length.
        !          5697:                 // This implies that the driver is broken.
        !          5698:                 //
        !          5699: 
        !          5700:                 Adapter->Babble++;
        !          5701: 
        !          5702:                 NdisWriteErrorLogEntry(
        !          5703:                     Adapter->NdisAdapterHandle,
        !          5704:                     NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          5705:                     2,
        !          5706:                     (ULONG)processInterrupt,
        !          5707:                     (ULONG)0x1
        !          5708:                     );
        !          5709: 
        !          5710: 
        !          5711:             } else {
        !          5712: 
        !          5713:                 //
        !          5714:                 // Could only be a memory error.  This shuts down
        !          5715:                 // the receiver and the transmitter.  We have to
        !          5716:                 // reset to get the device started again.
        !          5717:                 //
        !          5718: 
        !          5719:                 Adapter->MemoryError++;
        !          5720: 
        !          5721:                 SetupForReset(
        !          5722:                     Adapter,
        !          5723:                     NULL,
        !          5724:                     NULL,
        !          5725:                     NdisRequestGeneric4 // Means MAC issued
        !          5726:                     );
        !          5727: 
        !          5728:             }
        !          5729: 
        !          5730:             Csr &= ~LANCE_CSR0_ERROR_BITS;
        !          5731: 
        !          5732:         }
        !          5733: 
        !          5734:         //
        !          5735:         // Check the interrupt vector and see if there are any
        !          5736:         // more receives to process.  After we process any
        !          5737:         // other interrupt source we always come back to the top
        !          5738:         // of the loop to check if any more receive packets have
        !          5739:         // come in.  This is to lessen the probability that we
        !          5740:         // drop a receive.
        !          5741:         //
        !          5742: 
        !          5743: 
        !          5744:         if (Csr & LANCE_CSR0_RECEIVER_INTERRUPT) {
        !          5745: 
        !          5746:             if (ProcessReceiveInterrupts(Adapter)) {
        !          5747: 
        !          5748:                 Csr &= ~LANCE_CSR0_RECEIVER_INTERRUPT;
        !          5749: 
        !          5750:             }
        !          5751: 
        !          5752:         }
        !          5753: 
        !          5754:         //
        !          5755:         // Process the transmit interrupts if there are any.
        !          5756:         //
        !          5757: 
        !          5758:         if (Csr & LANCE_CSR0_TRANSMITTER_INTERRUPT) {
        !          5759: 
        !          5760:             //
        !          5761:             // We need to check if the transmitter has
        !          5762:             // stopped as a result of an error.  If it
        !          5763:             // has then we really need to reset the adapter.
        !          5764:             //
        !          5765: 
        !          5766:             if (!(Csr & LANCE_CSR0_TRANSMITTER_ON)) {
        !          5767: 
        !          5768:                 //
        !          5769:                 // Might as well turn off the transmitter interrupt
        !          5770:                 // source since we won't ever be processing them
        !          5771:                 // and we don't want to come back here again.
        !          5772:                 //
        !          5773: 
        !          5774:                 Csr &= ~LANCE_CSR0_TRANSMITTER_INTERRUPT;
        !          5775: 
        !          5776:                 //
        !          5777:                 // Before we setup for the reset make sure that
        !          5778:                 // we aren't already resetting.
        !          5779:                 //
        !          5780: 
        !          5781:                 if (!Adapter->ResetInProgress) {
        !          5782: 
        !          5783:                     SetupForReset(
        !          5784:                         Adapter,
        !          5785:                         NULL,
        !          5786:                         0,
        !          5787:                         NdisRequestGeneric4 // means MAC issued
        !          5788:                         );
        !          5789: 
        !          5790:                 }
        !          5791: 
        !          5792:                 goto LoopBottom;
        !          5793: 
        !          5794:             } else {
        !          5795: 
        !          5796:                 if (!ProcessTransmitInterrupts(Adapter)) {
        !          5797: 
        !          5798:                     //
        !          5799:                     // Process interrupts returns false if it
        !          5800:                     // finds no more work to do.  If this so we
        !          5801:                     // turn off the transmitter interrupt source.
        !          5802:                     //
        !          5803: 
        !          5804:                     Csr &= ~LANCE_CSR0_TRANSMITTER_INTERRUPT;
        !          5805: 
        !          5806:                 }
        !          5807: 
        !          5808:             }
        !          5809: 
        !          5810:         }
        !          5811: 
        !          5812: 
        !          5813:         //
        !          5814:         // Only try to push a packet through the stage queues
        !          5815:         // if somebody else isn't already doing it and
        !          5816:         // there is some hope of moving some packets
        !          5817:         // ahead.
        !          5818:         //
        !          5819: 
        !          5820:         if ((!Adapter->AlreadyProcessingStage) &&
        !          5821:             (Adapter->StageOpen && Adapter->FirstStage1Packet)) {
        !          5822: 
        !          5823:             LanceStagedAllocation(Adapter);
        !          5824: 
        !          5825:         }
        !          5826: 
        !          5827:         //
        !          5828:         // Process the loopback queue.
        !          5829:         //
        !          5830:         //
        !          5831: 
        !          5832:         if (Adapter->FirstLoopBack != NULL) {
        !          5833: 
        !          5834:             LanceProcessLoopback(Adapter);
        !          5835: 
        !          5836:         }
        !          5837: 
        !          5838:         //
        !          5839:         // If there are any opens on the closing list and their
        !          5840:         // reference counts are zero then complete the close and
        !          5841:         // delete them from the list.
        !          5842:         //
        !          5843:         //
        !          5844: 
        !          5845: LoopBottom:;
        !          5846: 
        !          5847:         //
        !          5848:         // NOTE: This code assumes that the above code left
        !          5849:         // the spinlock acquired.
        !          5850:         //
        !          5851:         // Bottom of the interrupt processing loop.  Another dpc
        !          5852:         // could be coming in at this point to process interrupts.
        !          5853:         // We clear the flag that says we're processing interrupts
        !          5854:         // so that some invocation of the DPC can grab it and process
        !          5855:         // any further interrupts.
        !          5856:         //
        !          5857: 
        !          5858:         if (!IsListEmpty(&Adapter->CloseList)) {
        !          5859: 
        !          5860:             PLANCE_OPEN Open;
        !          5861:             PLIST_ENTRY Link = &(Adapter->CloseList);
        !          5862: 
        !          5863: 
        !          5864:             while (Link->Flink != &(Adapter->CloseList)) {
        !          5865: 
        !          5866:                 Open = CONTAINING_RECORD(
        !          5867:                      Link->Flink,
        !          5868:                      LANCE_OPEN,
        !          5869:                      OpenList
        !          5870:                      );
        !          5871: 
        !          5872: 
        !          5873:                 if (!Open->References) {
        !          5874: 
        !          5875:                     NdisDprReleaseSpinLock(&Adapter->Lock);
        !          5876: 
        !          5877:                     NdisCompleteCloseAdapter(
        !          5878:                         Open->NdisBindingContext,
        !          5879:                         NDIS_STATUS_SUCCESS
        !          5880:                         );
        !          5881: 
        !          5882:                     NdisDprAcquireSpinLock(&Adapter->Lock);
        !          5883: 
        !          5884:                     RemoveEntryList(&Open->OpenList);
        !          5885: 
        !          5886:                     if (Adapter->MaxLookAhead == Open->LookAhead) {
        !          5887: 
        !          5888:                         LanceAdjustMaxLookAhead(Adapter);
        !          5889: 
        !          5890:                     }
        !          5891: 
        !          5892:                     LANCE_FREE_PHYS(Open, sizeof(LANCE_OPEN));
        !          5893: 
        !          5894:                 }
        !          5895: 
        !          5896:                 Link = Link->Flink;
        !          5897: 
        !          5898:             }
        !          5899: 
        !          5900: 
        !          5901:         }
        !          5902: 
        !          5903:         Adapter->References--;
        !          5904: 
        !          5905:     }
        !          5906: 
        !          5907:     Adapter->ProcessInterruptRunning = FALSE;
        !          5908: 
        !          5909:     //
        !          5910:     // Check if we indicated any packets.
        !          5911:     //
        !          5912:     // Note: The only way to get out of the loop (via the break above) is
        !          5913:     // while we're still holding the spin lock.
        !          5914:     //
        !          5915: 
        !          5916:     if (Adapter->IndicatedAPacket) {
        !          5917: 
        !          5918:         Adapter->IndicatedAPacket = FALSE;
        !          5919: 
        !          5920:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          5921: 
        !          5922:         EthFilterIndicateReceiveComplete(Adapter->FilterDB);
        !          5923: 
        !          5924:         NdisDprAcquireSpinLock(&Adapter->Lock);
        !          5925: 
        !          5926:     }
        !          5927: 
        !          5928: }
        !          5929: 
        !          5930: STATIC
        !          5931: BOOLEAN
        !          5932: ProcessReceiveInterrupts(
        !          5933:     IN PLANCE_ADAPTER Adapter
        !          5934:     )
        !          5935: 
        !          5936: /*++
        !          5937: 
        !          5938: Routine Description:
        !          5939: 
        !          5940:     Process the packets that have finished receiving.
        !          5941: 
        !          5942:     NOTE: This routine assumes that no other thread of execution
        !          5943:     is processing receives!  THE LOCK MUST BE HELD
        !          5944: 
        !          5945: Arguments:
        !          5946: 
        !          5947:     Adapter - The adapter to indicate to.
        !          5948: 
        !          5949: Return Value:
        !          5950: 
        !          5951:     Whether to clear the interrupt or not.
        !          5952: 
        !          5953: --*/
        !          5954: 
        !          5955: {
        !          5956: 
        !          5957: 
        !          5958:     //
        !          5959:     // We don't get here unless there was a receive.  Loop through
        !          5960:     // the receive descriptors starting at the last known descriptor
        !          5961:     // owned by the hardware that begins a packet.
        !          5962:     //
        !          5963:     // Examine each receive ring descriptor for errors.
        !          5964:     //
        !          5965:     // We keep an array whose elements are indexed by the ring
        !          5966:     // index of the receive descriptors.  The arrays elements are
        !          5967:     // the virtual addresses of the buffers pointed to by
        !          5968:     // each ring descriptor.
        !          5969:     //
        !          5970:     // When we have the entire packet (and error processing doesn't
        !          5971:     // prevent us from indicating it), we give the routine that
        !          5972:     // processes the packet through the filter, the buffers virtual
        !          5973:     // address (which is always the lookahead size) and as the
        !          5974:     // MAC context the index to the first and last ring descriptors
        !          5975:     // comprising the packet.
        !          5976:     //
        !          5977: 
        !          5978:     //
        !          5979:     // Index of the ring descriptor in the ring.
        !          5980:     //
        !          5981:     UINT CurrentIndex = Adapter->CurrentReceiveIndex;
        !          5982: 
        !          5983:     //
        !          5984:     // Pointer to the ring descriptor being examined.
        !          5985:     //
        !          5986:     PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing + CurrentIndex;
        !          5987: 
        !          5988:     //
        !          5989:     // Hold in a local the top receive ring index so that we don't
        !          5990:     // need to get it from the adapter all the time.
        !          5991:     //
        !          5992:     const UINT TopReceiveIndex = Adapter->NumberOfReceiveRings - 1;
        !          5993: 
        !          5994:     //
        !          5995:     // Boolean to record the fact that we've finished processing
        !          5996:     // one packet and we're about to start a new one.
        !          5997:     //
        !          5998:     BOOLEAN NewPacket = FALSE;
        !          5999: 
        !          6000:     //
        !          6001:     // Count of the number of buffers in the current packet.
        !          6002:     //
        !          6003:     UINT NumberOfBuffers = 1;
        !          6004: 
        !          6005:     //
        !          6006:     // Pointer to host addressable space for the lookahead buffer
        !          6007:     //
        !          6008:     PUCHAR LookaheadBuffer;
        !          6009: 
        !          6010:     ULONG ReceivePacketCount = 0;
        !          6011: 
        !          6012:     while (TRUE) {
        !          6013: 
        !          6014:         UCHAR ReceiveSummaryBits;
        !          6015: 
        !          6016: 
        !          6017:         //
        !          6018:         // Check to see whether we own the packet.  If
        !          6019:         // we don't then simply return to the caller.
        !          6020:         //
        !          6021: 
        !          6022:         LANCE_READ_HARDWARE_MEMORY_UCHAR(
        !          6023:             CurrentEntry->ReceiveSummaryBits,
        !          6024:             &ReceiveSummaryBits
        !          6025:             );
        !          6026: 
        !          6027:         if (ReceiveSummaryBits & LANCE_RECEIVE_OWNED_BY_CHIP) {
        !          6028: 
        !          6029:             LOG(RECEIVE);
        !          6030: 
        !          6031:             return TRUE;
        !          6032: 
        !          6033:         } else if (ReceivePacketCount > 10) {
        !          6034: 
        !          6035:             LOG(RECEIVE)
        !          6036: 
        !          6037:             return FALSE;
        !          6038: 
        !          6039:         } else if (ReceiveSummaryBits & LANCE_RECEIVE_ERROR_SUMMARY) {
        !          6040: 
        !          6041: 
        !          6042:             //
        !          6043:             // We have an error in the packet.  Record
        !          6044:             // the details of the error.
        !          6045:             //
        !          6046: 
        !          6047:             //
        !          6048:             // Synch with the set/query information routines.
        !          6049:             //
        !          6050: 
        !          6051:             if (ReceiveSummaryBits & LANCE_RECEIVE_BUFFER_ERROR) {
        !          6052: 
        !          6053:                 //
        !          6054:                 // Probably ran out of descriptors.
        !          6055:                 //
        !          6056: 
        !          6057:                 Adapter->OutOfReceiveBuffers++;
        !          6058: 
        !          6059:             } else if (ReceiveSummaryBits & LANCE_RECEIVE_CRC_ERROR) {
        !          6060: 
        !          6061:                 Adapter->CRCError++;
        !          6062: 
        !          6063:             } else if (ReceiveSummaryBits & LANCE_RECEIVE_OVERFLOW_ERROR) {
        !          6064: 
        !          6065:                 Adapter->OutOfReceiveBuffers++;
        !          6066: 
        !          6067:             } else if (ReceiveSummaryBits & LANCE_RECEIVE_FRAMING_ERROR) {
        !          6068: 
        !          6069:                 Adapter->FramingError++;
        !          6070: 
        !          6071:             }
        !          6072: 
        !          6073:             ReceivePacketCount++;
        !          6074: 
        !          6075:             //
        !          6076:             // Give the packet back to the hardware.
        !          6077:             //
        !          6078: 
        !          6079:             RelinquishReceivePacket(
        !          6080:                 Adapter,
        !          6081:                 Adapter->CurrentReceiveIndex,
        !          6082:                 NumberOfBuffers
        !          6083:                 );
        !          6084: 
        !          6085:             NewPacket = TRUE;
        !          6086: 
        !          6087:         } else if (ReceiveSummaryBits & LANCE_RECEIVE_END_OF_PACKET) {
        !          6088: 
        !          6089:             //
        !          6090:             // We've reached the end of the packet.  Prepare
        !          6091:             // the parameters for indication, then indicate.
        !          6092:             //
        !          6093: 
        !          6094:             UINT PacketSize;
        !          6095:             UINT LookAheadSize;
        !          6096: 
        !          6097:             LANCE_RECEIVE_CONTEXT Context;
        !          6098: 
        !          6099:             ASSERT(sizeof(LANCE_RECEIVE_CONTEXT) == sizeof(NDIS_HANDLE));
        !          6100: 
        !          6101:             //
        !          6102:             // Check just before we do indications that we aren't
        !          6103:             // resetting.
        !          6104:             //
        !          6105: 
        !          6106:             if (Adapter->ResetInProgress) {
        !          6107: 
        !          6108:                 return TRUE;
        !          6109:             }
        !          6110: 
        !          6111:             Context.INFO.IsContext = TRUE;
        !          6112:             Context.INFO.FirstBuffer = Adapter->CurrentReceiveIndex;
        !          6113:             Context.INFO.LastBuffer = CurrentIndex;
        !          6114: 
        !          6115:             LANCE_GET_MESSAGE_SIZE(CurrentEntry, PacketSize);
        !          6116: 
        !          6117:             LookAheadSize = PacketSize;
        !          6118: 
        !          6119:             //
        !          6120:             // Find amount to indicate.
        !          6121:             //
        !          6122: 
        !          6123:             LookAheadSize = ((LookAheadSize < Adapter->SizeOfReceiveBuffer) ?
        !          6124:                              LookAheadSize :
        !          6125:                              Adapter->SizeOfReceiveBuffer);
        !          6126: 
        !          6127:             LookAheadSize -= LANCE_HEADER_SIZE;
        !          6128: 
        !          6129:             //
        !          6130:             // Increment the number of packets succesfully received.
        !          6131:             //
        !          6132: 
        !          6133:             Adapter->Receive++;
        !          6134: 
        !          6135:             LOG(INDICATE);
        !          6136: 
        !          6137:             Adapter->IndicatingMacReceiveContext = Context;
        !          6138: 
        !          6139:             Adapter->IndicatedAPacket = TRUE;
        !          6140: 
        !          6141:             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          6142: 
        !          6143:             NdisCreateLookaheadBufferFromSharedMemory(
        !          6144:                 (PVOID)(Adapter->ReceiveVAs[Adapter->CurrentReceiveIndex]),
        !          6145:                 LookAheadSize + LANCE_HEADER_SIZE,
        !          6146:                 &LookaheadBuffer
        !          6147:                 );
        !          6148: 
        !          6149:             if (LookaheadBuffer != NULL) {
        !          6150: 
        !          6151:                 if (PacketSize < LANCE_HEADER_SIZE) {
        !          6152: 
        !          6153:                     if (PacketSize >= ETH_LENGTH_OF_ADDRESS) {
        !          6154: 
        !          6155:                         //
        !          6156:                         // Runt packet
        !          6157:                         //
        !          6158: 
        !          6159:                         EthFilterIndicateReceive(
        !          6160:                             Adapter->FilterDB,
        !          6161:                             (NDIS_HANDLE)Context.WholeThing,
        !          6162:                             LookaheadBuffer,
        !          6163:                             LookaheadBuffer,
        !          6164:                             PacketSize,
        !          6165:                             NULL,
        !          6166:                             0,
        !          6167:                             0
        !          6168:                             );
        !          6169: 
        !          6170:                     }
        !          6171: 
        !          6172:                 } else {
        !          6173: 
        !          6174:                     EthFilterIndicateReceive(
        !          6175:                         Adapter->FilterDB,
        !          6176:                         (NDIS_HANDLE)Context.WholeThing,
        !          6177:                         LookaheadBuffer,
        !          6178:                         LookaheadBuffer,
        !          6179:                         LANCE_HEADER_SIZE,
        !          6180:                         LookaheadBuffer + LANCE_HEADER_SIZE,
        !          6181:                         LookAheadSize,
        !          6182:                         PacketSize - LANCE_HEADER_SIZE
        !          6183:                         );
        !          6184: 
        !          6185:                 }
        !          6186: 
        !          6187:                 NdisDestroyLookaheadBufferFromSharedMemory(
        !          6188:                     LookaheadBuffer
        !          6189:                     );
        !          6190: 
        !          6191:             }
        !          6192: 
        !          6193:             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          6194: 
        !          6195:             ReceivePacketCount++;
        !          6196: 
        !          6197:             //
        !          6198:             // Give the packet back to the hardware.
        !          6199:             //
        !          6200: 
        !          6201:             RelinquishReceivePacket(
        !          6202:                 Adapter,
        !          6203:                 Adapter->CurrentReceiveIndex,
        !          6204:                 NumberOfBuffers
        !          6205:                 );
        !          6206: 
        !          6207:             NewPacket = TRUE;
        !          6208: 
        !          6209:         }
        !          6210: 
        !          6211:         //
        !          6212:         // We're at some indermediate packet. Advance to
        !          6213:         // the next one.
        !          6214:         //
        !          6215: 
        !          6216:         if (CurrentIndex == TopReceiveIndex) {
        !          6217: 
        !          6218:             CurrentIndex = 0;
        !          6219:             CurrentEntry = Adapter->ReceiveRing;
        !          6220: 
        !          6221:         } else {
        !          6222: 
        !          6223:             CurrentIndex++;
        !          6224:             CurrentEntry++;
        !          6225: 
        !          6226:         }
        !          6227: 
        !          6228:         if (NewPacket) {
        !          6229: 
        !          6230:             Adapter->CurrentReceiveIndex = CurrentIndex;
        !          6231:             NewPacket = FALSE;
        !          6232:             NumberOfBuffers = 0;
        !          6233: 
        !          6234:         }
        !          6235: 
        !          6236:         NumberOfBuffers++;
        !          6237: 
        !          6238:         if (NumberOfBuffers > (TopReceiveIndex + 1)) {
        !          6239: 
        !          6240:             //
        !          6241:             // Error!  For some reason we wrapped without ever seeing
        !          6242:             // the end of packet.  The card is hosed.  Stop the
        !          6243:             // whole process.
        !          6244:             //
        !          6245: 
        !          6246:             //
        !          6247:             // There are opens to notify
        !          6248:             //
        !          6249: 
        !          6250:             PLIST_ENTRY CurrentLink;
        !          6251:             PLANCE_OPEN Open;
        !          6252:             BOOLEAN Cancel;
        !          6253: 
        !          6254:             Adapter->HardwareFailure = TRUE;
        !          6255: 
        !          6256:             CurrentLink = Adapter->OpenBindings.Flink;
        !          6257: 
        !          6258:             while (CurrentLink != &Adapter->OpenBindings) {
        !          6259: 
        !          6260:                 Open = CONTAINING_RECORD(
        !          6261:                                          CurrentLink,
        !          6262:                                          LANCE_OPEN,
        !          6263:                                          OpenList
        !          6264:                                         );
        !          6265: 
        !          6266:                 Open->References++;
        !          6267: 
        !          6268:                 NdisDprReleaseSpinLock(&Adapter->Lock);
        !          6269: 
        !          6270:                 NdisIndicateStatus(
        !          6271:                                    Open->NdisBindingContext,
        !          6272:                                    NDIS_STATUS_CLOSING,
        !          6273:                                    NULL,
        !          6274:                                    0
        !          6275:                                   );
        !          6276: 
        !          6277:                 NdisIndicateStatusComplete(
        !          6278:                                    Open->NdisBindingContext
        !          6279:                                    );
        !          6280: 
        !          6281:                 NdisDprAcquireSpinLock(&Adapter->Lock);
        !          6282: 
        !          6283:                 Open->References--;
        !          6284: 
        !          6285:                 CurrentLink = CurrentLink->Flink;
        !          6286: 
        !          6287:             }
        !          6288: 
        !          6289: #if LANCELOG
        !          6290: 
        !          6291:             if (LogTimerRunning) {
        !          6292: 
        !          6293:                 NdisCancelTimer(&LogTimer, &Cancel);
        !          6294:                 NdisStallExecution(500000);
        !          6295:                 LogTimerRunning = FALSE;
        !          6296: 
        !          6297:             }
        !          6298: 
        !          6299: #endif
        !          6300: 
        !          6301: 
        !          6302:             NdisRemoveInterrupt(&(Adapter->Interrupt));
        !          6303: 
        !          6304:             NdisWriteErrorLogEntry(
        !          6305:                 Adapter->NdisAdapterHandle,
        !          6306:                 NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !          6307:                 0
        !          6308:                 );
        !          6309: 
        !          6310:             NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          6311: 
        !          6312:             return TRUE;
        !          6313: 
        !          6314:         }
        !          6315: 
        !          6316:     }
        !          6317: 
        !          6318: }
        !          6319: 
        !          6320: STATIC
        !          6321: VOID
        !          6322: RelinquishReceivePacket(
        !          6323:     IN PLANCE_ADAPTER Adapter,
        !          6324:     IN UINT StartingIndex,
        !          6325:     IN UINT NumberOfBuffers
        !          6326:     )
        !          6327: 
        !          6328: /*++
        !          6329: 
        !          6330: Routine Description:
        !          6331: 
        !          6332:     Gives a range of receive descriptors back to the hardware.
        !          6333: 
        !          6334:     NOTE: MUST BE CALLED WITH THE LOCK HELD!!
        !          6335: 
        !          6336: Arguments:
        !          6337: 
        !          6338:     Adapter - The adapter that the ring works with.
        !          6339: 
        !          6340:     StartingIndex - The first ring to return.  Note that since
        !          6341:     we are dealing with a ring, this value could be greater than
        !          6342:     the EndingIndex.
        !          6343: 
        !          6344:     NumberOfBuffers - The number of buffers (or ring descriptors) in
        !          6345:     the current packet.
        !          6346: 
        !          6347: Return Value:
        !          6348: 
        !          6349:     None.
        !          6350: 
        !          6351: --*/
        !          6352: 
        !          6353: {
        !          6354: 
        !          6355:     //
        !          6356:     // Index of the ring descriptor in the ring.
        !          6357:     //
        !          6358:     UINT CurrentIndex = StartingIndex;
        !          6359: 
        !          6360:     //
        !          6361:     // Pointer to the ring descriptor being returned.
        !          6362:     //
        !          6363:     PLANCE_RECEIVE_ENTRY CurrentEntry = Adapter->ReceiveRing + CurrentIndex;
        !          6364: 
        !          6365:     //
        !          6366:     // Hold in a local so that we don't need to access via the adapter.
        !          6367:     //
        !          6368:     const UINT TopReceiveIndex = Adapter->NumberOfReceiveRings - 1;
        !          6369: 
        !          6370:     UCHAR Tmp;
        !          6371: 
        !          6372:     LANCE_READ_HARDWARE_MEMORY_UCHAR(
        !          6373:         CurrentEntry->ReceiveSummaryBits,
        !          6374:         &Tmp
        !          6375:         );
        !          6376: 
        !          6377:     ASSERT(!(Tmp & LANCE_RECEIVE_OWNED_BY_CHIP));
        !          6378:     ASSERT(Tmp & LANCE_RECEIVE_START_OF_PACKET);
        !          6379: 
        !          6380:     for (
        !          6381:         ;
        !          6382:         NumberOfBuffers;
        !          6383:         NumberOfBuffers--
        !          6384:         ) {
        !          6385: 
        !          6386:             LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          6387:                 CurrentEntry->ReceiveSummaryBits,
        !          6388:                 LANCE_RECEIVE_OWNED_BY_CHIP
        !          6389:                 );
        !          6390: 
        !          6391:         if (CurrentIndex == TopReceiveIndex) {
        !          6392: 
        !          6393:             CurrentEntry = Adapter->ReceiveRing;
        !          6394:             CurrentIndex = 0;
        !          6395: 
        !          6396:         } else {
        !          6397: 
        !          6398:             CurrentEntry++;
        !          6399:             CurrentIndex++;
        !          6400: 
        !          6401:         }
        !          6402: 
        !          6403:     }
        !          6404: 
        !          6405: }
        !          6406: 
        !          6407: STATIC
        !          6408: BOOLEAN
        !          6409: ProcessTransmitInterrupts(
        !          6410:     IN PLANCE_ADAPTER Adapter
        !          6411:     )
        !          6412: 
        !          6413: /*++
        !          6414: 
        !          6415: Routine Description:
        !          6416: 
        !          6417:     Process the packets that have finished transmitting.
        !          6418: 
        !          6419:     NOTE: This routine assumes that it is being executed in a
        !          6420:     single thread of execution.  CALLED WITH LOCK HELD!!!
        !          6421: 
        !          6422: Arguments:
        !          6423: 
        !          6424:     Adapter - The adapter that was sent from.
        !          6425: 
        !          6426: Return Value:
        !          6427: 
        !          6428:     This function will return TRUE if it finished up the
        !          6429:     send on a packet.  It will return FALSE if for some
        !          6430:     reason there was no packet to process.
        !          6431: 
        !          6432: --*/
        !          6433: 
        !          6434: {
        !          6435:     //
        !          6436:     // Index into the ring to packet structure.  This index points
        !          6437:     // to the first ring entry for the first buffer used for transmitting
        !          6438:     // the packet.
        !          6439:     //
        !          6440:     UINT FirstIndex;
        !          6441: 
        !          6442:     //
        !          6443:     // Pointer to the last ring entry for the packet to be transmitted.
        !          6444:     // This pointer might actually point to a ring entry before the first
        !          6445:     // ring entry for the packet since the ring structure is, simply, a ring.
        !          6446:     //
        !          6447:     PLANCE_TRANSMIT_ENTRY LastRingEntry;
        !          6448: 
        !          6449:     //
        !          6450:     // Pointer to the packet that started this transmission.
        !          6451:     //
        !          6452:     PNDIS_PACKET OwningPacket;
        !          6453: 
        !          6454:     //
        !          6455:     // First Buffer
        !          6456:     //
        !          6457:     PNDIS_BUFFER FirstBuffer;
        !          6458: 
        !          6459:     //
        !          6460:     // Virtual address of first buffer
        !          6461:     //
        !          6462:     PVOID BufferVA;
        !          6463: 
        !          6464:     //
        !          6465:     // Length of the first buffer
        !          6466:     //
        !          6467:     UINT Length;
        !          6468: 
        !          6469:     //
        !          6470:     // Points to the reserved part of the OwningPacket.
        !          6471:     //
        !          6472:     PLANCE_RESERVED Reserved;
        !          6473: 
        !          6474:     UCHAR TransmitSummaryBits;
        !          6475:     USHORT ErrorSummaryInfo;
        !          6476: 
        !          6477:     //
        !          6478:     // Used to hold the ring to packet mapping information so that
        !          6479:     // we can release the ring entries as quickly as possible.
        !          6480:     //
        !          6481:     LANCE_RING_TO_PACKET SavedRingMapping;
        !          6482: 
        !          6483: 
        !          6484:     //
        !          6485:     // Get hold of the first transmitted packet.
        !          6486:     //
        !          6487: 
        !          6488:     //
        !          6489:     // First we check that this is a packet that was transmitted
        !          6490:     // but not already processed.  Recall that this routine
        !          6491:     // will be called repeatedly until this tests false, Or we
        !          6492:     // hit a packet that we don't completely own.
        !          6493:     //
        !          6494: 
        !          6495:     //
        !          6496:     // NOTE: I found a problem where FirstUncommitedRing wraps around
        !          6497:     // and becomes equal to TransmittingRing.  This only happens when
        !          6498:     // NumberOfAvailableRings is 0 (JohnsonA)
        !          6499:     //
        !          6500: 
        !          6501:     if ((Adapter->TransmittingRing == Adapter->FirstUncommittedRing) &&
        !          6502:         (Adapter->NumberOfAvailableRings > 0)) {
        !          6503: 
        !          6504:         return FALSE;
        !          6505: 
        !          6506:     } else {
        !          6507: 
        !          6508:         FirstIndex = Adapter->TransmittingRing - Adapter->TransmitRing;
        !          6509: 
        !          6510:     }
        !          6511: 
        !          6512: 
        !          6513:     //
        !          6514:     // We put the mapping into a local variable so that we
        !          6515:     // can return the mapping as soon as possible.
        !          6516:     //
        !          6517: 
        !          6518:     SavedRingMapping = Adapter->RingToPacket[FirstIndex];
        !          6519: 
        !          6520:     //
        !          6521:     // Get a pointer to the last ring entry for this packet.
        !          6522:     //
        !          6523: 
        !          6524:     LastRingEntry = Adapter->TransmitRing +
        !          6525:                      SavedRingMapping.RingIndex;
        !          6526: 
        !          6527:     //
        !          6528:     // Get a pointer to the owning packet and the reserved part of
        !          6529:     // the packet.
        !          6530:     //
        !          6531: 
        !          6532:     OwningPacket = SavedRingMapping.OwningPacket;
        !          6533: 
        !          6534:     SavedRingMapping.OwningPacket = NULL;
        !          6535: 
        !          6536:     if (OwningPacket == NULL) {
        !          6537: 
        !          6538:         //
        !          6539:         // We seem to be in a messed up state.  Ignore this interrupt and
        !          6540:         // the wake up dpc will reset the card if necessary.
        !          6541:         //
        !          6542: 
        !          6543:         ASSERT(OwningPacket != NULL);
        !          6544:         return(FALSE);
        !          6545: 
        !          6546:     }
        !          6547: 
        !          6548:     if (Adapter->FirstFinishTransmit == NULL) {
        !          6549: 
        !          6550:         //
        !          6551:         // We seem to be in a messed up state.  Ignore this interrupt and
        !          6552:         // the wake up dpc will reset the card if necessary.
        !          6553:         //
        !          6554: 
        !          6555:         ASSERT(Adapter->FirstFinishTransmit != NULL);
        !          6556:         return(FALSE);
        !          6557: 
        !          6558:     }
        !          6559: 
        !          6560:     Reserved = PLANCE_RESERVED_FROM_PACKET(OwningPacket);
        !          6561: 
        !          6562:     //
        !          6563:     // Check that the host does indeed own this entire packet.
        !          6564:     //
        !          6565: 
        !          6566:     LANCE_READ_HARDWARE_MEMORY_UCHAR(
        !          6567:         LastRingEntry->TransmitSummaryBits,
        !          6568:         &TransmitSummaryBits
        !          6569:         );
        !          6570: 
        !          6571:     if (TransmitSummaryBits & LANCE_TRANSMIT_OWNED_BY_CHIP) {
        !          6572: 
        !          6573:         //
        !          6574:         // We don't own this last packet.  We return FALSE to indicate
        !          6575:         // that we don't have any more packets to work on.
        !          6576:         //
        !          6577: 
        !          6578:         return FALSE;
        !          6579: 
        !          6580:     } else {
        !          6581: 
        !          6582:         //
        !          6583:         // Pointer to the current ring descriptor being examine for errors
        !          6584:         // and the statistics accumulated during its transmission.
        !          6585:         //
        !          6586:         PLANCE_TRANSMIT_ENTRY CurrentRingEntry;
        !          6587: 
        !          6588:         //
        !          6589:         // The binding that is submitting this packet.
        !          6590:         //
        !          6591:         PLANCE_OPEN Open;
        !          6592: 
        !          6593:         //
        !          6594:         // Holds whether the packet successfully transmitted or not.
        !          6595:         //
        !          6596:         BOOLEAN Successful = TRUE;
        !          6597: 
        !          6598:         LOG(TRANSMIT_COMPLETE);
        !          6599: 
        !          6600:         CurrentRingEntry = Adapter->TransmitRing + FirstIndex;
        !          6601: 
        !          6602:         //
        !          6603:         // now return these buffers to the adapter.
        !          6604:         //
        !          6605: 
        !          6606:         ReturnAdapterResources(
        !          6607:             Adapter,
        !          6608:             SavedRingMapping.LanceBuffersIndex
        !          6609:             );
        !          6610: 
        !          6611:         //
        !          6612:         // Since the host owns the entire packet check the ring
        !          6613:         // entries from first to last for any errors in transmission.
        !          6614:         // Any errors found or multiple tries should be recorded in
        !          6615:         // the information structure for the adapter.
        !          6616:         //
        !          6617:         // We treat Late Collisions as success since the packet was
        !          6618:         // fully transmitted and may have been received.
        !          6619:         //
        !          6620: 
        !          6621:         while (TRUE) {
        !          6622: 
        !          6623:             LANCE_READ_HARDWARE_MEMORY_UCHAR(
        !          6624:                     CurrentRingEntry->TransmitSummaryBits,
        !          6625:                     &TransmitSummaryBits
        !          6626:                     );
        !          6627: 
        !          6628:             LANCE_READ_HARDWARE_MEMORY_USHORT(
        !          6629:                     CurrentRingEntry->ErrorSummaryInfo,
        !          6630:                     &ErrorSummaryInfo
        !          6631:                     );
        !          6632: 
        !          6633:             if ((TransmitSummaryBits & LANCE_TRANSMIT_ANY_ERRORS) &&
        !          6634:                 !(ErrorSummaryInfo & LANCE_TRANSMIT_LATE_COLLISION)) {
        !          6635: 
        !          6636:                 if (ErrorSummaryInfo & LANCE_TRANSMIT_RETRY) {
        !          6637: 
        !          6638:                     Adapter->RetryFailure++;
        !          6639: 
        !          6640:                 } else if (ErrorSummaryInfo & LANCE_TRANSMIT_LOST_CARRIER) {
        !          6641: 
        !          6642:                     Adapter->LostCarrier++;
        !          6643: 
        !          6644:                 } else if (ErrorSummaryInfo & LANCE_TRANSMIT_UNDERFLOW) {
        !          6645: 
        !          6646:                     Adapter->UnderFlow++;
        !          6647: 
        !          6648:                 }
        !          6649: 
        !          6650: #if DBG
        !          6651:                 LanceSendFails[LanceSendFailPlace] =
        !          6652:                          (UCHAR)(ErrorSummaryInfo);
        !          6653:                 LanceSendFailPlace++;
        !          6654: 
        !          6655: 
        !          6656: #endif
        !          6657: 
        !          6658: #if LANCE_TRACE
        !          6659:                 DbgPrint("Unsuccessful Transmit 0x%x\n",
        !          6660:                          ErrorSummaryInfo);
        !          6661: #endif
        !          6662: 
        !          6663:                 Successful = FALSE;
        !          6664: 
        !          6665:                 //
        !          6666:                 // Move the pointer to transmitting but unprocessed
        !          6667:                 // ring entries to after this packet, and recover
        !          6668:                 // the remaining now available ring entries.
        !          6669:                 //
        !          6670: 
        !          6671:                 Adapter->NumberOfAvailableRings +=
        !          6672:                 (CurrentRingEntry <= LastRingEntry)?
        !          6673:                  ((LastRingEntry - CurrentRingEntry)+1):
        !          6674:                  ((Adapter->LastTransmitRingEntry - CurrentRingEntry) +
        !          6675:                   (LastRingEntry-Adapter->TransmitRing) + 2);
        !          6676: 
        !          6677:                 if (LastRingEntry == Adapter->LastTransmitRingEntry) {
        !          6678: 
        !          6679:                     Adapter->TransmittingRing = Adapter->TransmitRing;
        !          6680: 
        !          6681:                 } else {
        !          6682: 
        !          6683:                     Adapter->TransmittingRing = LastRingEntry + 1;
        !          6684: 
        !          6685:                 }
        !          6686: 
        !          6687:                 break;
        !          6688: 
        !          6689:             } else {
        !          6690: 
        !          6691:                 //
        !          6692:                 // Logical variable that records whether this
        !          6693:                 // is the last packet.
        !          6694:                 //
        !          6695:                 BOOLEAN DoneWithPacket =
        !          6696:                     TransmitSummaryBits &
        !          6697:                     LANCE_TRANSMIT_END_OF_PACKET;
        !          6698: 
        !          6699:                 if (ErrorSummaryInfo &
        !          6700:                            LANCE_TRANSMIT_LATE_COLLISION) {
        !          6701: 
        !          6702:                     Adapter->LateCollision++;
        !          6703: 
        !          6704:                 }
        !          6705: 
        !          6706:                 if (TransmitSummaryBits &
        !          6707:                     LANCE_TRANSMIT_START_OF_PACKET) {
        !          6708: 
        !          6709:                     //
        !          6710:                     // Collect some statistics on how many tries were needed.
        !          6711:                     //
        !          6712: 
        !          6713:                     if (TransmitSummaryBits & LANCE_TRANSMIT_DEFERRED) {
        !          6714: 
        !          6715:                         Adapter->Deferred++;
        !          6716: 
        !          6717:                     } else if (TransmitSummaryBits & LANCE_TRANSMIT_ONE_RETRY) {
        !          6718: 
        !          6719:                         Adapter->OneRetry++;
        !          6720: 
        !          6721:                     } else if (TransmitSummaryBits & LANCE_TRANSMIT_MORE_THAN_ONE_RETRY) {
        !          6722: 
        !          6723:                         Adapter->MoreThanOneRetry++;
        !          6724: 
        !          6725: 
        !          6726:                     }
        !          6727: 
        !          6728:                 }
        !          6729: 
        !          6730:                 if (CurrentRingEntry == Adapter->LastTransmitRingEntry) {
        !          6731: 
        !          6732:                     CurrentRingEntry = Adapter->TransmitRing;
        !          6733: 
        !          6734:                 } else {
        !          6735: 
        !          6736:                     CurrentRingEntry++;
        !          6737: 
        !          6738:                 }
        !          6739: 
        !          6740:                 Adapter->TransmittingRing = CurrentRingEntry;
        !          6741:                 Adapter->NumberOfAvailableRings++;
        !          6742: 
        !          6743:                 if (DoneWithPacket) {
        !          6744: 
        !          6745:                     break;
        !          6746: 
        !          6747:                 }
        !          6748: 
        !          6749:             }
        !          6750: 
        !          6751:         }
        !          6752: 
        !          6753:         //
        !          6754:         // Store result
        !          6755:         //
        !          6756: 
        !          6757:         if (Successful) {
        !          6758: 
        !          6759:             //
        !          6760:             // Increment number of packets successfully sent.
        !          6761:             //
        !          6762: 
        !          6763:             Adapter->Transmit++;
        !          6764: 
        !          6765:         }
        !          6766: 
        !          6767:         //
        !          6768:         // Remove packet from sending queue
        !          6769:         //
        !          6770: 
        !          6771:         Adapter->FirstFinishTransmit = Reserved->Next;
        !          6772: 
        !          6773:         if (Adapter->FirstFinishTransmit == NULL) {
        !          6774: 
        !          6775:             Adapter->LastFinishTransmit = NULL;
        !          6776: 
        !          6777:         }
        !          6778: 
        !          6779:         //
        !          6780:         // Do a quick check to see if the packet has a high likelyhood
        !          6781:         // of needing to loopback.  (NOTE: This means that if the packet
        !          6782:         // must be loopbacked then this function will return true.  If
        !          6783:         // the packet doesn't need to be loopbacked then the function
        !          6784:         // will probably return false.)
        !          6785:         //
        !          6786: 
        !          6787:         //
        !          6788:         // Get first buffer
        !          6789:         //
        !          6790: 
        !          6791:         NdisQueryPacket(
        !          6792:             OwningPacket,
        !          6793:             NULL,
        !          6794:             NULL,
        !          6795:             &FirstBuffer,
        !          6796:             NULL
        !          6797:             );
        !          6798: 
        !          6799:         //
        !          6800:         // Get VA of first buffer
        !          6801:         //
        !          6802: 
        !          6803:         NdisQueryBuffer(
        !          6804:             FirstBuffer,
        !          6805:             &BufferVA,
        !          6806:             &Length
        !          6807:             );
        !          6808: 
        !          6809:         if (EthShouldAddressLoopBack(
        !          6810:                 Adapter->FilterDB,
        !          6811:                 BufferVA
        !          6812:                 )) {
        !          6813: 
        !          6814:             Reserved->SuccessfulTransmit = Successful;
        !          6815: 
        !          6816:             if (!Adapter->FirstLoopBack) {
        !          6817: 
        !          6818:                 Adapter->FirstLoopBack = OwningPacket;
        !          6819: 
        !          6820:             } else {
        !          6821: 
        !          6822:                 PLANCE_RESERVED_FROM_PACKET(Adapter->LastLoopBack)->Next = OwningPacket;
        !          6823: 
        !          6824:             }
        !          6825: 
        !          6826:             Reserved->Next = NULL;
        !          6827:             Adapter->LastLoopBack = OwningPacket;
        !          6828: 
        !          6829:         } else {
        !          6830: 
        !          6831: 
        !          6832:             Open = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          6833: 
        !          6834:             //
        !          6835:             // Along with at least one reference because of the coming
        !          6836:             // indication there should be a reference because of the
        !          6837:             // packet to indicate.
        !          6838:             //
        !          6839: 
        !          6840:             ASSERT(Open->References > 0);
        !          6841: 
        !          6842:             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          6843: 
        !          6844:             NdisCompleteSend(
        !          6845:                 Open->NdisBindingContext,
        !          6846:                 OwningPacket,
        !          6847:                 ((Successful)?(NDIS_STATUS_SUCCESS):(NDIS_STATUS_FAILURE))
        !          6848:                 );
        !          6849: 
        !          6850:             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          6851: 
        !          6852:             //
        !          6853:             // Remove reference for packet
        !          6854:             //
        !          6855: 
        !          6856:             Open->References--;
        !          6857: 
        !          6858:         }
        !          6859: 
        !          6860:         //
        !          6861:         // Since we've given back some ring entries we should
        !          6862:         // open of the stage if it was closed and we are not resetting.
        !          6863:         //
        !          6864: 
        !          6865:         if ((!Adapter->StageOpen) && (!Adapter->ResetInProgress)) {
        !          6866: 
        !          6867:             Adapter->StageOpen = TRUE;
        !          6868: 
        !          6869:         }
        !          6870: 
        !          6871:         return TRUE;
        !          6872:     }
        !          6873: 
        !          6874: }
        !          6875: 
        !          6876: STATIC
        !          6877: VOID
        !          6878: ReturnAdapterResources(
        !          6879:     IN PLANCE_ADAPTER Adapter,
        !          6880:     IN UINT BufferIndex
        !          6881:     )
        !          6882: 
        !          6883: /*++
        !          6884: 
        !          6885: Routine Description:
        !          6886: 
        !          6887:     Given that a packet has used adapter resources (which the routine
        !          6888:     asserts), return those resources to the adapter.
        !          6889: 
        !          6890:     NOTE: CALLED WITH LOCK HELD!!!
        !          6891: 
        !          6892: Arguments:
        !          6893: 
        !          6894:     Adapter - The adapter that the packet came through.
        !          6895: 
        !          6896:     BufferIndex - The adapter buffer descriptor index to put back on the
        !          6897:     free list.
        !          6898: 
        !          6899: 
        !          6900: Return Value:
        !          6901: 
        !          6902:     None.
        !          6903: 
        !          6904: --*/
        !          6905: {
        !          6906: 
        !          6907:     //
        !          6908:     // The adapter buffer descriptor that was allocated to this packet.
        !          6909:     //
        !          6910:     PLANCE_BUFFER_DESCRIPTOR BufferDescriptor = Adapter->LanceBuffers +
        !          6911:                                                   BufferIndex;
        !          6912: 
        !          6913:     //
        !          6914:     // Index of the listhead that heads the list that the adapter
        !          6915:     // buffer descriptor belongs too.
        !          6916:     //
        !          6917:     INT ListHeadIndex = BufferDescriptor->Next;
        !          6918: 
        !          6919:     //
        !          6920:     // Put the adapter buffer back on the free list.
        !          6921:     //
        !          6922: 
        !          6923:     BufferDescriptor->Next = Adapter->LanceBufferListHeads[ListHeadIndex];
        !          6924:     Adapter->LanceBufferListHeads[ListHeadIndex] = BufferIndex;
        !          6925: 
        !          6926:     //
        !          6927:     // If the stage was closed and we aren't resetting then open
        !          6928:     // it back up.
        !          6929:     //
        !          6930: 
        !          6931:     if ((!Adapter->StageOpen) && (!Adapter->ResetInProgress)) {
        !          6932: 
        !          6933:         Adapter->StageOpen = TRUE;
        !          6934: 
        !          6935:     }
        !          6936: 
        !          6937: }
        !          6938: 
        !          6939: STATIC
        !          6940: VOID
        !          6941: StartAdapterReset(
        !          6942:     IN PLANCE_ADAPTER Adapter
        !          6943:     )
        !          6944: 
        !          6945: /*++
        !          6946: 
        !          6947: Routine Description:
        !          6948: 
        !          6949:     This is the first phase of resetting the adapter hardware.
        !          6950: 
        !          6951:     It makes the following assumptions:
        !          6952: 
        !          6953:     1) That the hardware has been stopped.
        !          6954: 
        !          6955:     2) That it can not be preempted.
        !          6956: 
        !          6957:     3) That no other adapter activity can occur.
        !          6958: 
        !          6959:     When this routine is finished all of the adapter information
        !          6960:     will be as if the driver was just initialized.
        !          6961: 
        !          6962: Arguments:
        !          6963: 
        !          6964:     Adapter - The adapter whose hardware is to be reset.
        !          6965: 
        !          6966: Return Value:
        !          6967: 
        !          6968:     None.
        !          6969: 
        !          6970: --*/
        !          6971: 
        !          6972: {
        !          6973:     UINT i;
        !          6974:     PNDIS_PACKET Packet;
        !          6975:     PLANCE_RESERVED Reserved;
        !          6976:     PLANCE_OPEN Open;
        !          6977:     PNDIS_PACKET Next;
        !          6978: 
        !          6979: 
        !          6980: #if LANCE_TRACE
        !          6981:     DbgPrint("In StartAdapterReset\n");
        !          6982: #endif
        !          6983: 
        !          6984:     LOG(RESET_STEP_2);
        !          6985: 
        !          6986:     //
        !          6987:     // Go through the various transmit lists and....
        !          6988:     //
        !          6989: 
        !          6990: 
        !          6991:     for (
        !          6992:         i = 3;
        !          6993:         i > 0;
        !          6994:         i--
        !          6995:         ) {
        !          6996: 
        !          6997:         switch (i) {
        !          6998: 
        !          6999:             case 1:
        !          7000:                 Next = Adapter->FirstFinishTransmit;
        !          7001:                 break;
        !          7002:             case 2:
        !          7003:                 Next = Adapter->FirstStage1Packet;
        !          7004:                 break;
        !          7005:             case 3:
        !          7006:                 Next = Adapter->FirstLoopBack;
        !          7007:                 break;
        !          7008: 
        !          7009:         }
        !          7010: 
        !          7011: 
        !          7012:         while (Next) {
        !          7013: 
        !          7014:             Packet = Next;
        !          7015:             Reserved = PLANCE_RESERVED_FROM_PACKET(Packet);
        !          7016:             Next = Reserved->Next;
        !          7017:             Open =
        !          7018:               PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          7019: 
        !          7020: 
        !          7021:             if (Adapter->ResetRequestType == NdisRequestGeneric1) {
        !          7022: 
        !          7023:                 //
        !          7024:                 // Abort the packet
        !          7025:                 //
        !          7026:                 // The completion of the packet is one less reason
        !          7027:                 // to keep the open around.
        !          7028:                 //
        !          7029: 
        !          7030:                 ASSERT(Open->References);
        !          7031: 
        !          7032:                 Open->References--;
        !          7033: 
        !          7034:                 NdisReleaseSpinLock(&Adapter->Lock);
        !          7035: 
        !          7036:                 NdisCompleteSend(
        !          7037:                     Open->NdisBindingContext,
        !          7038:                     Packet,
        !          7039:                     NDIS_STATUS_REQUEST_ABORTED
        !          7040:                     );
        !          7041: 
        !          7042:                 NdisAcquireSpinLock(&Adapter->Lock);
        !          7043: 
        !          7044:             } else if ((i == 1) || (i ==3)) {
        !          7045: 
        !          7046:                 //
        !          7047:                 // Complete these sends
        !          7048:                 //
        !          7049:                 // The completion of the packet is one less reason
        !          7050:                 // to keep the open around.
        !          7051:                 //
        !          7052: 
        !          7053:                 ASSERT(Open->References);
        !          7054: 
        !          7055:                 Adapter->Transmit++;
        !          7056: 
        !          7057:                 LOG(RESET_COMPLETE_PACKET);
        !          7058: 
        !          7059:                 NdisReleaseSpinLock(&Adapter->Lock);
        !          7060: 
        !          7061:                 NdisCompleteSend(
        !          7062:                     Open->NdisBindingContext,
        !          7063:                     Packet,
        !          7064:                     NDIS_STATUS_SUCCESS
        !          7065:                     );
        !          7066: 
        !          7067:                 NdisAcquireSpinLock(&Adapter->Lock);
        !          7068: 
        !          7069:                 Open->References--;
        !          7070: 
        !          7071:             }
        !          7072: 
        !          7073:         }
        !          7074: 
        !          7075:     }
        !          7076: 
        !          7077: 
        !          7078: 
        !          7079:     Adapter->CSR0Value = 0;
        !          7080:     Adapter->NumberOfAvailableRings = Adapter->NumberOfTransmitRings;
        !          7081:     Adapter->AllocateableRing = Adapter->TransmitRing;
        !          7082:     Adapter->TransmittingRing = Adapter->TransmitRing;
        !          7083:     Adapter->FirstUncommittedRing = Adapter->TransmitRing;
        !          7084: 
        !          7085: 
        !          7086:     Adapter->StageOpen = TRUE;
        !          7087: 
        !          7088:     Adapter->AlreadyProcessingStage = FALSE;
        !          7089: 
        !          7090:     Adapter->CurrentReceiveIndex = 0;
        !          7091: 
        !          7092:     //
        !          7093:     // Clean all of the receive ring entries.
        !          7094:     //
        !          7095: 
        !          7096:     {
        !          7097: 
        !          7098:         PLANCE_RECEIVE_ENTRY CurrentReceive = Adapter->ReceiveRing;
        !          7099:         const PLANCE_RECEIVE_ENTRY After = Adapter->ReceiveRing+
        !          7100:                                            Adapter->NumberOfReceiveRings;
        !          7101: 
        !          7102:         do {
        !          7103: 
        !          7104:             LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          7105:                 CurrentReceive->ReceiveSummaryBits,
        !          7106:                 LANCE_RECEIVE_OWNED_BY_CHIP
        !          7107:                 );
        !          7108:             CurrentReceive++;
        !          7109: 
        !          7110: 
        !          7111:         } while (CurrentReceive != After);
        !          7112: 
        !          7113:     }
        !          7114: 
        !          7115: 
        !          7116:     //
        !          7117:     // Clean all of the transmit ring entries.
        !          7118:     //
        !          7119: 
        !          7120:     {
        !          7121: 
        !          7122:         PLANCE_TRANSMIT_ENTRY CurrentTransmit = Adapter->TransmitRing;
        !          7123:         const PLANCE_TRANSMIT_ENTRY After = Adapter->TransmitRing+
        !          7124:                                             Adapter->NumberOfTransmitRings;
        !          7125: 
        !          7126:         do {
        !          7127: 
        !          7128:             LANCE_WRITE_HARDWARE_MEMORY_UCHAR(
        !          7129:                 CurrentTransmit->TransmitSummaryBits,
        !          7130:                 0x00
        !          7131:                 );
        !          7132:             CurrentTransmit++;
        !          7133: 
        !          7134: 
        !          7135:         } while (CurrentTransmit != After);
        !          7136: 
        !          7137:     }
        !          7138: 
        !          7139:     //
        !          7140:     // Recover all of the adapter buffers.
        !          7141:     //
        !          7142: 
        !          7143:     for (
        !          7144:         i = 0;
        !          7145:         i < (Adapter->NumberOfSmallBuffers +
        !          7146:              Adapter->NumberOfMediumBuffers +
        !          7147:              Adapter->NumberOfLargeBuffers);
        !          7148:         i++
        !          7149:         ) {
        !          7150: 
        !          7151:         Adapter->LanceBuffers[i].Next = i+1;
        !          7152: 
        !          7153:     }
        !          7154: 
        !          7155:     Adapter->LanceBufferListHeads[0] = -1;
        !          7156:     Adapter->LanceBufferListHeads[1] = 0;
        !          7157:     Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers)-1].Next = -1;
        !          7158:     Adapter->LanceBufferListHeads[2] = Adapter->NumberOfSmallBuffers;
        !          7159:     Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers +
        !          7160:                            Adapter->NumberOfMediumBuffers)-1].Next = -1;
        !          7161:     Adapter->LanceBufferListHeads[3] = Adapter->NumberOfSmallBuffers +
        !          7162:                                        Adapter->NumberOfMediumBuffers;
        !          7163:     Adapter->LanceBuffers[(Adapter->NumberOfSmallBuffers+
        !          7164:                            Adapter->NumberOfMediumBuffers+
        !          7165:                            Adapter->NumberOfLargeBuffers)-1].Next = -1;
        !          7166: 
        !          7167:     //
        !          7168:     // If it was a Reset from LanceReset(), clear out all queues.
        !          7169:     //
        !          7170: 
        !          7171:     if (Adapter->ResetRequestType == NdisRequestGeneric1) {
        !          7172: 
        !          7173:         Adapter->FirstLoopBack = NULL;
        !          7174:         Adapter->LastLoopBack = NULL;
        !          7175:         Adapter->FirstFinishTransmit = NULL;
        !          7176:         Adapter->LastFinishTransmit = NULL;
        !          7177:         Adapter->FirstStage1Packet = NULL;
        !          7178:         Adapter->LastStage1Packet = NULL;
        !          7179: 
        !          7180:     } else  {
        !          7181: 
        !          7182:         //
        !          7183:         // It was a reset from a SetInfo,
        !          7184:         // Clear out only the intermediate queues - the
        !          7185:         // packets were moved out and back to stage1. (sigh)
        !          7186:         //
        !          7187: 
        !          7188:         Adapter->FirstFinishTransmit = NULL;
        !          7189:         Adapter->LastFinishTransmit = NULL;
        !          7190: 
        !          7191:         //
        !          7192:         // Re-allocate all the stage 1 packets.
        !          7193:         //
        !          7194: 
        !          7195:         Next = Adapter->FirstStage1Packet;
        !          7196: 
        !          7197:         Adapter->FirstStage1Packet = NULL;
        !          7198:         Adapter->LastStage1Packet = NULL;
        !          7199: 
        !          7200:         while (Next != NULL) {
        !          7201: 
        !          7202:             LOG(RESET_RECOVER_PACKET);
        !          7203: 
        !          7204:             Packet = Next,
        !          7205:             Reserved = PLANCE_RESERVED_FROM_PACKET(Packet);
        !          7206:             Next = Reserved->Next;
        !          7207: 
        !          7208:             SetupAllocate(Adapter, Reserved->MacBindingHandle, Packet);
        !          7209: 
        !          7210:         }
        !          7211: 
        !          7212:     }
        !          7213: 
        !          7214: 
        !          7215:     SetInitBlockAndInit(Adapter);
        !          7216: 
        !          7217: #if LANCE_TRACE
        !          7218:     DbgPrint("Out StartAdapterReset\n");
        !          7219: #endif
        !          7220: 
        !          7221: }
        !          7222: 
        !          7223: STATIC
        !          7224: VOID
        !          7225: SetInitBlockAndInit(
        !          7226:     IN PLANCE_ADAPTER Adapter
        !          7227:     )
        !          7228: 
        !          7229: /*++
        !          7230: 
        !          7231: Routine Description:
        !          7232: 
        !          7233:     It is this routines responsibility to make sure that the
        !          7234:     initialization block is filled and the chip is initialized
        !          7235:     *but not* started.
        !          7236: 
        !          7237:     NOTE: This routine assumes that it is called with the lock
        !          7238:     acquired OR that only a single thread of execution is working
        !          7239:     with this particular adapter.
        !          7240: 
        !          7241: Arguments:
        !          7242: 
        !          7243:     Adapter - The adapter whose hardware is to be initialized.
        !          7244: 
        !          7245: Return Value:
        !          7246: 
        !          7247:     None.
        !          7248: 
        !          7249: --*/
        !          7250: {
        !          7251: 
        !          7252:     PHYSICAL_ADDRESS PhysAdr;
        !          7253: 
        !          7254:     //
        !          7255:     // Fill in the adapters initialization block.
        !          7256:     //
        !          7257: 
        !          7258:     LanceSetInitializationBlock(Adapter);
        !          7259: 
        !          7260:     PhysAdr = LANCE_GET_HARDWARE_PHYSICAL_ADDRESS(Adapter,Adapter->InitBlock);
        !          7261: 
        !          7262:     //
        !          7263:     // Make sure that it does have even byte alignment.
        !          7264:     //
        !          7265: 
        !          7266:     ASSERT(!(PhysAdr.LowPart & 0x01));
        !          7267: 
        !          7268:     //
        !          7269:     // Write the address of the initialization block to csr1 and csr2.
        !          7270:     //
        !          7271: 
        !          7272:     LANCE_WRITE_RAP(
        !          7273:         Adapter,
        !          7274:         LANCE_SELECT_CSR1
        !          7275:         );
        !          7276: 
        !          7277:     LANCE_WRITE_RDP(
        !          7278:         Adapter,
        !          7279:         LANCE_GET_LOW_PART_ADDRESS(PhysAdr.LowPart)
        !          7280:         );
        !          7281: 
        !          7282:     LANCE_WRITE_RAP(
        !          7283:         Adapter,
        !          7284:         LANCE_SELECT_CSR2
        !          7285:         );
        !          7286: 
        !          7287:     LANCE_WRITE_RDP(
        !          7288:         Adapter,
        !          7289:         LANCE_GET_HIGH_PART_ADDRESS(PhysAdr.LowPart)
        !          7290:         );
        !          7291: 
        !          7292:     //
        !          7293:     // Write to csr0 to initialize the chip.
        !          7294:     //
        !          7295: 
        !          7296:     LANCE_WRITE_RAP(
        !          7297:         Adapter,
        !          7298:         LANCE_SELECT_CSR0
        !          7299:         );
        !          7300: 
        !          7301:     LANCE_WRITE_RDP(
        !          7302:         Adapter,
        !          7303:         LANCE_CSR0_INIT_CHIP
        !          7304:         );
        !          7305: 
        !          7306: }
        !          7307: 
        !          7308: STATIC
        !          7309: VOID
        !          7310: SetupForReset(
        !          7311:     IN PLANCE_ADAPTER Adapter,
        !          7312:     IN PLANCE_OPEN Open,
        !          7313:     IN PNDIS_REQUEST NdisRequest,
        !          7314:     IN NDIS_REQUEST_TYPE RequestType
        !          7315:     )
        !          7316: 
        !          7317: /*++
        !          7318: 
        !          7319: Routine Description:
        !          7320: 
        !          7321:     This routine is used to fill in the who and why a reset is
        !          7322:     being set up as well as setting the appropriate fields in the
        !          7323:     adapter.
        !          7324: 
        !          7325:     NOTE: This routine must be called with the lock acquired.
        !          7326: 
        !          7327: Arguments:
        !          7328: 
        !          7329:     Adapter - The adapter whose hardware is to be initialized.
        !          7330: 
        !          7331:     Open - A (possibly NULL) pointer to an lance open structure.
        !          7332:     The reason it could be null is if the adapter is initiating the
        !          7333:     reset on its own.
        !          7334: 
        !          7335:     NdisRequest - A pointer to the NDIS_REQUEST which requested the reset.
        !          7336: 
        !          7337:     RequestType - If the open is not null then the request type that
        !          7338:     is causing the reset.
        !          7339: 
        !          7340: Return Value:
        !          7341: 
        !          7342:     None.
        !          7343: 
        !          7344: --*/
        !          7345: {
        !          7346: 
        !          7347: #if LANCE_TRACE
        !          7348:     DbgPrint("In SetupForReset\n");
        !          7349: #endif
        !          7350: 
        !          7351:     LOG(RESET_STEP_1);
        !          7352: 
        !          7353:     //
        !          7354:     // Shut down the chip.  We won't be doing any more work until
        !          7355:     // the reset is complete.
        !          7356:     //
        !          7357: 
        !          7358:     NdisSynchronizeWithInterrupt(
        !          7359:         &Adapter->Interrupt,
        !          7360:         LanceSyncStopChip,
        !          7361:         (PVOID)Adapter
        !          7362:         );
        !          7363: 
        !          7364:     //
        !          7365:     // Once the chip is stopped we can't get any more interrupts.
        !          7366:     // Any interrupts that are "queued" for processing could
        !          7367:     // only possibly service this reset.  It is therefore safe for
        !          7368:     // us to clear the adapter global csr value.
        !          7369:     //
        !          7370: 
        !          7371:     Adapter->CSR0Value = 0;
        !          7372: 
        !          7373:     Adapter->ResetInProgress = TRUE;
        !          7374:     Adapter->ResetInitStarted = FALSE;
        !          7375: 
        !          7376:     //
        !          7377:     // Shut down all of the transmit queues so that the
        !          7378:     // transmit portion of the chip will eventually calm down.
        !          7379:     //
        !          7380: 
        !          7381:     Adapter->StageOpen = FALSE;
        !          7382: 
        !          7383:     Adapter->ResetNdisRequest = NdisRequest;
        !          7384:     Adapter->ResettingOpen = Open;
        !          7385:     Adapter->ResetRequestType = RequestType;
        !          7386: 
        !          7387:     //
        !          7388:     // If there is a valid open we should up the reference count
        !          7389:     // so that the open can't be deleted before we indicate that
        !          7390:     // their request is finished.
        !          7391:     //
        !          7392: 
        !          7393:     if (Open) {
        !          7394: 
        !          7395:         Open->References++;
        !          7396: 
        !          7397:     }
        !          7398: 
        !          7399: #if LANCE_TRACE
        !          7400:     DbgPrint("Out SetupForReset\n");
        !          7401: #endif
        !          7402: 
        !          7403: }
        !          7404: 
        !          7405: 
        !          7406: STATIC
        !          7407: VOID
        !          7408: FinishPendOp(
        !          7409:     IN PLANCE_ADAPTER Adapter,
        !          7410:     IN BOOLEAN Successful
        !          7411:     )
        !          7412: 
        !          7413: /*++
        !          7414: 
        !          7415: Routine Description:
        !          7416: 
        !          7417:     This routine is called when a pended operation completes.
        !          7418:     It calles CompleteRequest if needed and does any other
        !          7419:     cleanup required.
        !          7420: 
        !          7421:     NOTE: This routine is called with the lock held and
        !          7422:     returns with it held.
        !          7423: 
        !          7424:     NOTE: This routine assumes that the pended operation to
        !          7425:     be completed was specifically requested by the protocol.
        !          7426: 
        !          7427: 
        !          7428: Arguments:
        !          7429: 
        !          7430:     Adapter - The adapter.
        !          7431: 
        !          7432:     Successful - Was the pended operation completed successfully.
        !          7433: 
        !          7434: Return Value:
        !          7435: 
        !          7436:     None.
        !          7437: 
        !          7438: --*/
        !          7439: 
        !          7440: {
        !          7441:     ASSERT(Adapter->ResetNdisRequest != NULL);
        !          7442: 
        !          7443: 
        !          7444:     //
        !          7445:     // It was a request for filter change or multicastlist change.
        !          7446:     //
        !          7447: 
        !          7448:     if (Successful) {
        !          7449: 
        !          7450:         //
        !          7451:         // complete the operation.
        !          7452:         //
        !          7453: 
        !          7454: 
        !          7455:         NdisReleaseSpinLock(&(Adapter->Lock));
        !          7456: 
        !          7457:         NdisCompleteRequest(
        !          7458:                             Adapter->ResettingOpen->NdisBindingContext,
        !          7459:                             Adapter->ResetNdisRequest,
        !          7460:                             NDIS_STATUS_SUCCESS
        !          7461:                             );
        !          7462: 
        !          7463:         NdisAcquireSpinLock(&(Adapter->Lock));
        !          7464: 
        !          7465:         Adapter->ResetNdisRequest = NULL;
        !          7466: 
        !          7467:         Adapter->ResettingOpen->References--;
        !          7468: 
        !          7469:     } else {
        !          7470: 
        !          7471: 
        !          7472:         //
        !          7473:         // complete the operation.
        !          7474:         //
        !          7475: 
        !          7476: 
        !          7477:         NdisReleaseSpinLock(&(Adapter->Lock));
        !          7478: 
        !          7479:         NdisCompleteRequest(
        !          7480:                             Adapter->ResettingOpen->NdisBindingContext,
        !          7481:                             Adapter->ResetNdisRequest,
        !          7482:                             NDIS_STATUS_FAILURE
        !          7483:                             );
        !          7484: 
        !          7485:         NdisAcquireSpinLock(&(Adapter->Lock));
        !          7486: 
        !          7487:         Adapter->ResetNdisRequest = NULL;
        !          7488: 
        !          7489:         Adapter->ResettingOpen->References--;
        !          7490: 
        !          7491:     }
        !          7492: 
        !          7493:     return;
        !          7494: 
        !          7495: }
        !          7496: 
        !          7497: 
        !          7498: 
        !          7499: STATIC
        !          7500: BOOLEAN
        !          7501: LanceSyncWriteRAP(
        !          7502:     IN PVOID Context
        !          7503:     )
        !          7504: /*++
        !          7505: 
        !          7506: Routine Description:
        !          7507: 
        !          7508:     This routine is used by the normal interrupt processing routine
        !          7509:     to synchronize with interrupts from the card.  It will write
        !          7510:     to the RAP
        !          7511: 
        !          7512: 
        !          7513: Arguments:
        !          7514: 
        !          7515:     Context - This is really a pointer to a record type peculiar
        !          7516:     to this routine.  The record contains a pointer to the adapter
        !          7517:     and a pointer to the value to write.
        !          7518: 
        !          7519: 
        !          7520: Return Value:
        !          7521: 
        !          7522:     Always returns true.
        !          7523: 
        !          7524: --*/
        !          7525: 
        !          7526: {
        !          7527: 
        !          7528: 
        !          7529:     PLANCE_SYNCH_CONTEXT C = Context;
        !          7530: 
        !          7531:     LANCE_ISR_WRITE_RAP(C->Adapter, C->LocalWrite);
        !          7532: 
        !          7533:     return FALSE;
        !          7534: 
        !          7535: }
        !          7536: 
        !          7537: BOOLEAN
        !          7538: LanceSyncWriteRDP(
        !          7539:     IN PVOID Context
        !          7540:     )
        !          7541: /*++
        !          7542: 
        !          7543: Routine Description:
        !          7544: 
        !          7545:     This routine is used by the normal interrupt processing routine
        !          7546:     to synchronize with interrupts from the card.  It will write
        !          7547:     into the RDP register
        !          7548: 
        !          7549: 
        !          7550: Arguments:
        !          7551: 
        !          7552:     Context - This is really a pointer to a record type peculiar
        !          7553:     to this routine.  The record contains a pointer to the adapter
        !          7554:     and a pointer to the value to write.
        !          7555: 
        !          7556: Return Value:
        !          7557: 
        !          7558:     Always returns true.
        !          7559: 
        !          7560: --*/
        !          7561: 
        !          7562: {
        !          7563: 
        !          7564: 
        !          7565:     PLANCE_SYNCH_CONTEXT C = Context;
        !          7566: 
        !          7567:     LANCE_ISR_WRITE_RDP(C->Adapter, C->LocalWrite);
        !          7568: 
        !          7569:     return FALSE;
        !          7570: 
        !          7571: 
        !          7572: }
        !          7573: 
        !          7574: STATIC
        !          7575: BOOLEAN
        !          7576: LanceSyncReadRDP(
        !          7577:     IN PVOID Context
        !          7578:     )
        !          7579: /*++
        !          7580: 
        !          7581: Routine Description:
        !          7582: 
        !          7583:     This routine is used by the normal interrupt processing routine
        !          7584:     to synchronize with interrupts from the card.  It will read
        !          7585:     from the RDP.
        !          7586: 
        !          7587: Arguments:
        !          7588: 
        !          7589:     Context - This is really a pointer to a record type peculiar
        !          7590:     to this routine.  The record contains a pointer to the adapter
        !          7591:     and a pointer to a USHORT to store the value into.
        !          7592: 
        !          7593: Return Value:
        !          7594: 
        !          7595:     Always returns true.
        !          7596: 
        !          7597: --*/
        !          7598: 
        !          7599: {
        !          7600: 
        !          7601: 
        !          7602:     PLANCE_SYNCH_CONTEXT C = Context;
        !          7603: 
        !          7604:     LANCE_ISR_READ_RDP(C->Adapter, C->LocalRead);
        !          7605: 
        !          7606:     return FALSE;
        !          7607: 
        !          7608: }
        !          7609: 
        !          7610: STATIC
        !          7611: BOOLEAN
        !          7612: LanceSyncWriteNicsr(
        !          7613:     IN PVOID Context
        !          7614:     )
        !          7615: /*++
        !          7616: 
        !          7617: Routine Description:
        !          7618: 
        !          7619:     This routine is used by the normal interrupt processing routine
        !          7620:     to synchronize with interrupts from the card.  It will
        !          7621:     Write to the NIC Status Register.
        !          7622: 
        !          7623: Arguments:
        !          7624: 
        !          7625:     Context - This is really a pointer to a record type peculiar
        !          7626:     to this routine.  The record contains a pointer to the adapter
        !          7627:     and a pointer to an address which holds the value to write.
        !          7628: 
        !          7629: Return Value:
        !          7630: 
        !          7631:     Always returns false.
        !          7632: 
        !          7633: --*/
        !          7634: 
        !          7635: {
        !          7636: 
        !          7637:     PLANCE_SYNCH_CONTEXT C = Context;
        !          7638: 
        !          7639:     LANCE_ISR_WRITE_NICSR(C->Adapter, C->LocalWrite);
        !          7640: 
        !          7641:     return FALSE;
        !          7642: 
        !          7643: }
        !          7644: 
        !          7645: STATIC
        !          7646: BOOLEAN
        !          7647: LanceSyncStopChip(
        !          7648:     IN PVOID Context
        !          7649:     )
        !          7650: 
        !          7651: /*++
        !          7652: 
        !          7653: Routine Description:
        !          7654: 
        !          7655:     This routine is used to stop a lance.
        !          7656: 
        !          7657: 
        !          7658: 
        !          7659: Arguments:
        !          7660: 
        !          7661:     Adapter - The adapter for the LANCE to stop.
        !          7662: 
        !          7663: Return Value:
        !          7664: 
        !          7665:     FALSE
        !          7666: 
        !          7667: --*/
        !          7668: 
        !          7669: {
        !          7670: 
        !          7671:     PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)Context;
        !          7672: 
        !          7673:     //
        !          7674:     // Set the RAP to csr0.
        !          7675:     //
        !          7676: 
        !          7677:     LANCE_ISR_WRITE_RAP(
        !          7678:         Adapter,
        !          7679:         LANCE_SELECT_CSR0
        !          7680:         );
        !          7681: 
        !          7682:     //
        !          7683:     // Set the RDP to stop chip.
        !          7684:     //
        !          7685: 
        !          7686:     LANCE_ISR_WRITE_RDP(
        !          7687:         Adapter,
        !          7688:         LANCE_CSR0_STOP
        !          7689:         );
        !          7690: 
        !          7691:     if (Adapter->LanceCard & (LANCE_DE201 | LANCE_DE100 | LANCE_DE422)) {
        !          7692: 
        !          7693:         //
        !          7694:         // Always reset the ACON bit after a stop.
        !          7695:         //
        !          7696: 
        !          7697:         LANCE_ISR_WRITE_RAP(
        !          7698:             Adapter,
        !          7699:             LANCE_SELECT_CSR3
        !          7700:             );
        !          7701: 
        !          7702:         LANCE_ISR_WRITE_RDP(
        !          7703:             Adapter,
        !          7704:             LANCE_CSR3_ACON
        !          7705:             );
        !          7706: 
        !          7707:     }
        !          7708: 
        !          7709:     //
        !          7710:     // Select CSR0 again.
        !          7711:     //
        !          7712: 
        !          7713:     LANCE_ISR_WRITE_RAP(
        !          7714:         Adapter,
        !          7715:         LANCE_SELECT_CSR0
        !          7716:         );
        !          7717: 
        !          7718:     return(FALSE);
        !          7719: }
        !          7720: 
        !          7721: 
        !          7722: VOID
        !          7723: LanceWakeUpDpc(
        !          7724:     IN PVOID SystemSpecific1,
        !          7725:     IN PVOID Context,
        !          7726:     IN PVOID SystemSpecific2,
        !          7727:     IN PVOID SystemSpecific3
        !          7728:     )
        !          7729: 
        !          7730: /*++
        !          7731: 
        !          7732: Routine Description:
        !          7733: 
        !          7734:     This DPC routine is queued every 5 seconds to check on the
        !          7735:     queues. If an interrupt was not received
        !          7736:     in the last 5 seconds and there should have been one,
        !          7737:     then we abort all operations.
        !          7738: 
        !          7739: Arguments:
        !          7740: 
        !          7741:     Context - Really a pointer to the adapter.
        !          7742: 
        !          7743: Return Value:
        !          7744: 
        !          7745:     None.
        !          7746: 
        !          7747: --*/
        !          7748: {
        !          7749:     PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)Context;
        !          7750:     PLANCE_OPEN TmpOpen;
        !          7751:     PNDIS_PACKET TransmitPacket;
        !          7752:     PLANCE_PEND_DATA PendOp;
        !          7753:     PNDIS_REQUEST Request;
        !          7754:     PLANCE_RESERVED Reserved;
        !          7755: 
        !          7756:     UNREFERENCED_PARAMETER(SystemSpecific1);
        !          7757:     UNREFERENCED_PARAMETER(SystemSpecific2);
        !          7758:     UNREFERENCED_PARAMETER(SystemSpecific3);
        !          7759: 
        !          7760:     NdisDprAcquireSpinLock(&Adapter->Lock);
        !          7761: 
        !          7762:     if ((Adapter->WakeUpTimeout) &&
        !          7763:         ((Adapter->FirstFinishTransmit != NULL) ||
        !          7764:          (Adapter->FirstStage1Packet != NULL) ||
        !          7765:          (Adapter->PendQueue != NULL) ||
        !          7766:          (Adapter->ResetNdisRequest != NULL))) {
        !          7767: 
        !          7768:         //
        !          7769:         // We had a pending operation the last time we ran,
        !          7770:         // and it has not been completed...we need to complete
        !          7771:         // it now.
        !          7772: 
        !          7773:         Adapter->WakeUpTimeout = FALSE;
        !          7774: 
        !          7775:         Adapter->TimeoutCount++;
        !          7776: 
        !          7777:         if (Adapter->TimeoutCount < 10) {
        !          7778: 
        !          7779:             //
        !          7780:             // Limit the number of error log entries
        !          7781:             //
        !          7782: 
        !          7783:             NdisWriteErrorLogEntry(
        !          7784:                 Adapter->NdisAdapterHandle,
        !          7785:                 NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !          7786:                 0
        !          7787:                 );
        !          7788: 
        !          7789: 
        !          7790:         }
        !          7791: 
        !          7792:         if ((Adapter->ResettingOpen != NULL) &&
        !          7793:             (Adapter->ResetRequestType != NdisRequestClose)) {
        !          7794: 
        !          7795:             if (Adapter->ResetNdisRequest != NULL) {
        !          7796: 
        !          7797:                 //
        !          7798:                 // It was a request submitted by a protocol.
        !          7799:                 //
        !          7800: 
        !          7801:                 TmpOpen = Adapter->ResettingOpen;
        !          7802: 
        !          7803:                 NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          7804: 
        !          7805:                 NdisCompleteRequest(
        !          7806:                             Adapter->ResettingOpen->NdisBindingContext,
        !          7807:                             Adapter->ResetNdisRequest,
        !          7808:                             NDIS_STATUS_SUCCESS
        !          7809:                             );
        !          7810: 
        !          7811:                 NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          7812: 
        !          7813:                 TmpOpen->References--;
        !          7814: 
        !          7815:             }
        !          7816: 
        !          7817:         }
        !          7818: 
        !          7819:         while (Adapter->PendQueue) {
        !          7820: 
        !          7821:             Request = Adapter->PendQueue;
        !          7822:             PendOp = PLANCE_PEND_DATA_FROM_PNDIS_REQUEST(Request);
        !          7823: 
        !          7824:             Adapter->PendQueue = PendOp->Next;
        !          7825: 
        !          7826:             if (Adapter->PendQueue == NULL){
        !          7827: 
        !          7828:                 //
        !          7829:                 // We have just emptied the list.
        !          7830:                 //
        !          7831: 
        !          7832:                 Adapter->PendQueueTail = NULL;
        !          7833: 
        !          7834:             }
        !          7835: 
        !          7836: 
        !          7837:             if ((PendOp->Open != NULL) &&
        !          7838:                 (PendOp->RequestType != NdisRequestClose)) {
        !          7839: 
        !          7840:                 //
        !          7841:                 // It was a request submitted by a protocol.
        !          7842:                 //
        !          7843: 
        !          7844:                 TmpOpen = PendOp->Open;
        !          7845: 
        !          7846:                 NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          7847: 
        !          7848:                 NdisCompleteRequest(
        !          7849:                             PendOp->Open->NdisBindingContext,
        !          7850:                             Request,
        !          7851:                             NDIS_STATUS_SUCCESS
        !          7852:                             );
        !          7853: 
        !          7854:                 NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          7855: 
        !          7856:                 TmpOpen->References--;
        !          7857: 
        !          7858:             }
        !          7859: 
        !          7860:         }
        !          7861: 
        !          7862:         while (Adapter->FirstFinishTransmit != NULL) {
        !          7863: 
        !          7864:             TransmitPacket = Adapter->FirstFinishTransmit;
        !          7865: 
        !          7866:             Reserved = PLANCE_RESERVED_FROM_PACKET(TransmitPacket);
        !          7867: 
        !          7868:             Adapter->FirstFinishTransmit = Reserved->Next;
        !          7869: 
        !          7870:             if (Adapter->FirstFinishTransmit == NULL) {
        !          7871: 
        !          7872:                 Adapter->LastFinishTransmit = NULL;
        !          7873: 
        !          7874:             }
        !          7875: 
        !          7876:             TmpOpen = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          7877: 
        !          7878:             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          7879: 
        !          7880:             NdisCompleteSend(
        !          7881:                     TmpOpen->NdisBindingContext,
        !          7882:                     TransmitPacket,
        !          7883:                     NDIS_STATUS_SUCCESS
        !          7884:                     );
        !          7885: 
        !          7886:             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          7887: 
        !          7888:             TmpOpen->References--;
        !          7889: 
        !          7890:         }
        !          7891: 
        !          7892:         while (Adapter->FirstStage1Packet != NULL) {
        !          7893: 
        !          7894:             TransmitPacket = Adapter->FirstStage1Packet;
        !          7895: 
        !          7896:             Reserved = PLANCE_RESERVED_FROM_PACKET(TransmitPacket);
        !          7897: 
        !          7898:             //
        !          7899:             // Remove the packet from the queue.
        !          7900:             //
        !          7901: 
        !          7902:             Adapter->FirstStage1Packet = Reserved->Next;
        !          7903: 
        !          7904:             if (Adapter->FirstStage1Packet == NULL) {
        !          7905: 
        !          7906:                 Adapter->LastStage1Packet = NULL;
        !          7907: 
        !          7908:             }
        !          7909: 
        !          7910:             TmpOpen = PLANCE_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          7911: 
        !          7912:             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          7913: 
        !          7914:             NdisCompleteSend(
        !          7915:                     TmpOpen->NdisBindingContext,
        !          7916:                     TransmitPacket,
        !          7917:                     NDIS_STATUS_SUCCESS
        !          7918:                     );
        !          7919: 
        !          7920:             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          7921: 
        !          7922:             TmpOpen->References--;
        !          7923: 
        !          7924:         }
        !          7925: 
        !          7926:         Adapter->WakeUpTimeout = FALSE;
        !          7927: 
        !          7928:         SetupForReset(
        !          7929:             Adapter,
        !          7930:             NULL,
        !          7931:             NULL,
        !          7932:             NdisRequestGeneric4 // Means MAC issued
        !          7933:             );
        !          7934: 
        !          7935:         NdisSetTimer(&Adapter->DeferredTimer, 0);
        !          7936: 
        !          7937:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          7938: 
        !          7939:     } else {
        !          7940: 
        !          7941:         if ((Adapter->FirstFinishTransmit != NULL) ||
        !          7942:             (Adapter->FirstStage1Packet != NULL) ||
        !          7943:             (Adapter->PendQueue != NULL) ||
        !          7944:             (Adapter->ResetNdisRequest != NULL)) {
        !          7945: 
        !          7946:             Adapter->WakeUpTimeout = TRUE;
        !          7947: 
        !          7948:         }
        !          7949: 
        !          7950:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          7951: 
        !          7952: 
        !          7953:     }
        !          7954: 
        !          7955:     //
        !          7956:     // Fire off another Dpc to execute after 5 seconds
        !          7957:     //
        !          7958: 
        !          7959:     NdisSetTimer(
        !          7960:         &Adapter->WakeUpTimer,
        !          7961:         5000
        !          7962:         );
        !          7963: 
        !          7964: }
        !          7965: 
        !          7966: 
        !          7967: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.