Annotation of ntddk/src/network/ibmtok/interrup.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     interrup.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This is a part of the driver for the National Semiconductor IBMTOK
        !            12:     Ethernet controller.  It contains the interrupt-handling routines.
        !            13:     This driver conforms to the NDIS 3.0 interface.
        !            14: 
        !            15:     The overall structure and much of the code is taken from
        !            16:     the Lance NDIS driver by Tony Ercolano.
        !            17: 
        !            18: Author:
        !            19: 
        !            20:     Adam Barr (adamba) 16-Jan-1991
        !            21: 
        !            22: Environment:
        !            23: 
        !            24:     Kernel Mode - Or whatever is the equivalent.
        !            25: 
        !            26: Revision History:
        !            27: 
        !            28:     Sean Selitrennikoff - 10/91
        !            29:         Fixed synchronization bugs.
        !            30: 
        !            31:     Sean Selitrennikoff - 10/15/91
        !            32:         Converted to Ndis 3.0
        !            33: 
        !            34:     Sean Selitrennikoff - 1/8/92
        !            35:         Added error logging
        !            36: 
        !            37: --*/
        !            38: 
        !            39: #pragma optimize("",off)
        !            40: 
        !            41: #include <ndis.h>
        !            42: 
        !            43: 
        !            44: #include <tfilter.h>
        !            45: #include <tokhrd.h>
        !            46: #include <toksft.h>
        !            47: 
        !            48: 
        !            49: #if DEVL
        !            50: #define STATIC
        !            51: #else
        !            52: #define STATIC static
        !            53: #endif
        !            54: 
        !            55: #if DBG
        !            56: extern INT IbmtokDbg;
        !            57: #endif
        !            58: 
        !            59: //
        !            60: // This section contains all the functions and definitions for
        !            61: // doing logging of input and output to/from the card.
        !            62: //
        !            63: 
        !            64: #if LOG
        !            65: 
        !            66: //
        !            67: // Place in the circular buffer.
        !            68: //
        !            69: UCHAR IbmtokLogPlace;
        !            70: 
        !            71: //
        !            72: // Circular buffer for storing log information.
        !            73: //
        !            74: UCHAR IbmtokLog[256];
        !            75: 
        !            76: #define IF_LOG(A) {IbmtokLog[IbmtokLogPlace++ % 256] = (A); IbmtokLog[IbmtokLogPlace+2 % 256] = '.';}
        !            77: 
        !            78: #else
        !            79: 
        !            80: #define IF_LOG(A)
        !            81: 
        !            82: #endif
        !            83: 
        !            84: VOID
        !            85: SetResetVariables(
        !            86:     IN PIBMTOK_ADAPTER Adapter
        !            87:     );
        !            88: 
        !            89: STATIC
        !            90: VOID
        !            91: IbmtokHandleSrbSsb(
        !            92:     IN PIBMTOK_ADAPTER Adapter
        !            93:     );
        !            94: 
        !            95: STATIC
        !            96: VOID
        !            97: IbmtokHandleArbAsb(
        !            98:     IN PIBMTOK_ADAPTER Adapter
        !            99:     );
        !           100: 
        !           101: 
        !           102: STATIC
        !           103: VOID
        !           104: HandleResetStaging(
        !           105:     IN PIBMTOK_ADAPTER Adapter
        !           106:     );
        !           107: 
        !           108: STATIC
        !           109: BOOLEAN
        !           110: IbmtokSynchGetSrbSsbBits(
        !           111:     IN PVOID Context
        !           112:     );
        !           113: 
        !           114: STATIC
        !           115: BOOLEAN
        !           116: IbmtokSynchGetArbAsbBits(
        !           117:     IN PVOID Context
        !           118:     );
        !           119: 
        !           120: STATIC
        !           121: VOID
        !           122: PutPacketOnWaitingForAsb(
        !           123:     IN PIBMTOK_ADAPTER Adapter,
        !           124:     IN PNDIS_PACKET Packet
        !           125:     );
        !           126: 
        !           127: STATIC
        !           128: PNDIS_PACKET
        !           129: RemoveTransmitFromSrb(
        !           130:     IN PIBMTOK_ADAPTER Adapter,
        !           131:     OUT PBOOLEAN PacketRemoved
        !           132:     );
        !           133: 
        !           134: STATIC
        !           135: VOID
        !           136: SetupTransmitFrameSrb(
        !           137:     IN PIBMTOK_ADAPTER Adapter,
        !           138:     IN PNDIS_PACKET Packet
        !           139:     );
        !           140: 
        !           141: STATIC
        !           142: VOID
        !           143: SetupTransmitStatusAsb(
        !           144:     IN PIBMTOK_ADAPTER Adapter,
        !           145:     IN PNDIS_PACKET Packet
        !           146:     );
        !           147: 
        !           148: STATIC
        !           149: VOID
        !           150: GetAdapterStatisticsFromSrb(
        !           151:     PIBMTOK_ADAPTER Adapter
        !           152:     );
        !           153: 
        !           154: STATIC
        !           155: VOID
        !           156: GetAdapterErrorsFromSrb(
        !           157:     PIBMTOK_ADAPTER Adapter
        !           158:     );
        !           159: 
        !           160: 
        !           161: STATIC
        !           162: NDIS_STATUS
        !           163: StartPendQueueOp(
        !           164:     IN PIBMTOK_ADAPTER Adapter
        !           165:     );
        !           166: 
        !           167: STATIC
        !           168: NDIS_STATUS
        !           169: FinishSetOperation(
        !           170:     IN PIBMTOK_ADAPTER Adapter,
        !           171:     IN PIBMTOK_PEND_DATA PendOp
        !           172:     );
        !           173: 
        !           174: 
        !           175: STATIC
        !           176: BOOLEAN
        !           177: FinishPendQueueOp(
        !           178:     IN PIBMTOK_ADAPTER Adapter,
        !           179:     IN BOOLEAN Successful
        !           180:     );
        !           181: 
        !           182: STATIC
        !           183: NDIS_STATUS
        !           184: SetAdapterFunctionalAddress(
        !           185:     IN PIBMTOK_ADAPTER Adapter
        !           186:     );
        !           187: 
        !           188: STATIC
        !           189: VOID
        !           190: SetupFunctionalSrb(
        !           191:     IN PIBMTOK_ADAPTER Adapter,
        !           192:     IN TR_FUNCTIONAL_ADDRESS FunctionalAddress
        !           193:     );
        !           194: 
        !           195: STATIC
        !           196: NDIS_STATUS
        !           197: SetAdapterGroupAddress(
        !           198:     IN PIBMTOK_ADAPTER Adapter
        !           199:     );
        !           200: 
        !           201: STATIC
        !           202: VOID
        !           203: SetupGroupSrb(
        !           204:     IN PIBMTOK_ADAPTER Adapter,
        !           205:     IN TR_FUNCTIONAL_ADDRESS FunctionalAddress
        !           206:     );
        !           207: 
        !           208: STATIC
        !           209: VOID
        !           210: SetupReceivedDataAsb(
        !           211:     IN PIBMTOK_ADAPTER Adapter,
        !           212:     IN SRAM_PTR ReceiveBuffer
        !           213:     );
        !           214: 
        !           215: 
        !           216: //
        !           217: // These macros are used to set the SRPR correctly.
        !           218: //
        !           219: #define SET_SRB_SRPR(Adapter) \
        !           220:     if (Adapter->SharedRamPaging) { \
        !           221:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, Adapter->SrbSrprLow) \
        !           222:     }
        !           223: 
        !           224: #define SET_SSB_SRPR(Adapter) \
        !           225:     if (Adapter->SharedRamPaging) { \
        !           226:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, Adapter->SsbSrprLow) \
        !           227:     }
        !           228: 
        !           229: #define SET_ARB_SRPR(Adapter) \
        !           230:     if (Adapter->SharedRamPaging) { \
        !           231:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, Adapter->ArbSrprLow) \
        !           232:     }
        !           233: 
        !           234: #define SET_ASB_SRPR(Adapter) \
        !           235:     if (Adapter->SharedRamPaging) { \
        !           236:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, Adapter->AsbSrprLow) \
        !           237:     }
        !           238: 
        !           239: 
        !           240: 
        !           241: typedef struct _IBMTOK_SYNCH_CONTEXT {
        !           242: 
        !           243:     //
        !           244:     // Pointer to the ibmtok adapter for which interrupts are
        !           245:     // being synchronized.
        !           246:     //
        !           247:     PIBMTOK_ADAPTER Adapter;
        !           248: 
        !           249:     //
        !           250:     // Points to the variable on to which the relevant
        !           251:     // interrupt bits should be ORed.
        !           252:     //
        !           253:     PVOID Local;
        !           254: 
        !           255: } IBMTOK_SYNCH_CONTEXT, * PIBMTOK_SYNCH_CONTEXT;
        !           256: 
        !           257: //
        !           258: // This macro is to synchronize execution with interrupts.  It
        !           259: // gets the stored value of the SRB/SSB bits and clears the
        !           260: // old value.
        !           261: //
        !           262: #define GET_SRB_SSB_BITS(A,L) \
        !           263: { \
        !           264:     PIBMTOK_ADAPTER _A = A; \
        !           265:     IBMTOK_SYNCH_CONTEXT _C; \
        !           266:     _C.Adapter = _A; \
        !           267:     _C.Local = (PVOID)(L); \
        !           268:     NdisSynchronizeWithInterrupt( \
        !           269:         &(_A->Interrupt), \
        !           270:         (PVOID) IbmtokSynchGetSrbSsbBits, \
        !           271:         &_C \
        !           272:         ); \
        !           273: }
        !           274: 
        !           275: //
        !           276: // This macro is to synchronize execution with interrupts.  It
        !           277: // gets the stored value of the ARB/ASB bits and clears the
        !           278: // old value.
        !           279: //
        !           280: #define GET_ARB_ASB_BITS(A,L) \
        !           281: { \
        !           282:     PIBMTOK_ADAPTER _A = A; \
        !           283:     IBMTOK_SYNCH_CONTEXT _C; \
        !           284:     _C.Adapter = _A; \
        !           285:     _C.Local = (PVOID)(L); \
        !           286:     NdisSynchronizeWithInterrupt( \
        !           287:         &(_A->Interrupt), \
        !           288:         (PVOID) IbmtokSynchGetArbAsbBits, \
        !           289:         &_C \
        !           290:         ); \
        !           291: }
        !           292: 
        !           293: 
        !           294: //++
        !           295: //
        !           296: // PNDIS_PACKET
        !           297: // FindPacketGivenCorrelator(
        !           298: //     IN PIBMTOK_ADAPTER Adapter,
        !           299: //     IN UCHAR CommandCorrelator
        !           300: //     )
        !           301: //
        !           302: //
        !           303: // Routine Description:
        !           304: //
        !           305: //     This looks a packet up on the command correlator array.
        !           306: //
        !           307: //     This routine should be called with the spinlock held.
        !           308: //
        !           309: // Arguments:
        !           310: //
        !           311: //     Adapter - The adapter that this packet is coming through.
        !           312: //
        !           313: //     CommandCorrelator - The command correlator to search based on.
        !           314: //
        !           315: // Return Value:
        !           316: //
        !           317: //     The packet if found, NULL otherwise.
        !           318: //
        !           319: //--
        !           320: 
        !           321: #define FindPacketGivenCorrelator(_Adapter, _CommandCorrelator) \
        !           322:     ((_Adapter)->CorrelatorArray[_CommandCorrelator])
        !           323: 
        !           324: 
        !           325: STATIC
        !           326: BOOLEAN
        !           327: IbmtokSynchGetSrbSsbBits(
        !           328:     IN PVOID Context
        !           329:     )
        !           330: 
        !           331: /*++
        !           332: 
        !           333: Routine Description:
        !           334: 
        !           335:     This routine is used by the normal interrupt processing routine
        !           336:     to synchronize with interrupts from the card.  It will or
        !           337:     the value of the stored SRB/SSB bits into the other passed address
        !           338:     in the context and clear the stored value.
        !           339: 
        !           340: Arguments:
        !           341: 
        !           342:     Context - This is really a pointer to a record type peculiar
        !           343:     to this routine.  The record contains a pointer to the adapter
        !           344:     and a pointer to an address in which to place the contents
        !           345:     of the ISRP.
        !           346: 
        !           347: Return Value:
        !           348: 
        !           349:     Always returns true.
        !           350: 
        !           351: --*/
        !           352: 
        !           353: {
        !           354: 
        !           355:     PIBMTOK_SYNCH_CONTEXT C = (PIBMTOK_SYNCH_CONTEXT)Context;
        !           356: 
        !           357:     *((PUCHAR)C->Local) = (C->Adapter->IsrpBits) &
        !           358:                          (ISRP_HIGH_SRB_RESPONSE | ISRP_HIGH_SSB_RESPONSE);
        !           359: 
        !           360:     C->Adapter->IsrpBits = (C->Adapter->IsrpBits) &
        !           361:                          (~(ISRP_HIGH_SRB_RESPONSE | ISRP_HIGH_SSB_RESPONSE));
        !           362: 
        !           363:     return TRUE;
        !           364: 
        !           365: }
        !           366: 
        !           367: STATIC
        !           368: BOOLEAN
        !           369: IbmtokSynchGetArbAsbBits(
        !           370:     IN PVOID Context
        !           371:     )
        !           372: 
        !           373: /*++
        !           374: 
        !           375: Routine Description:
        !           376: 
        !           377:     This routine is used by the normal interrupt processing routine
        !           378:     to synchronize with interrupts from the card.  It will or
        !           379:     the value of the stored ARB/ASB bits into the other passed address
        !           380:     in the context and clear the stored value.
        !           381: 
        !           382: Arguments:
        !           383: 
        !           384:     Context - This is really a pointer to a record type peculiar
        !           385:     to this routine.  The record contains a pointer to the adapter
        !           386:     and a pointer to an address in which to place the contents
        !           387:     of the ISRP.
        !           388: Return Value:
        !           389: 
        !           390:     Always returns true.
        !           391: 
        !           392: --*/
        !           393: 
        !           394: {
        !           395: 
        !           396:     PIBMTOK_SYNCH_CONTEXT C = (PIBMTOK_SYNCH_CONTEXT)Context;
        !           397: 
        !           398:     *((PUCHAR)C->Local) = (C->Adapter->IsrpBits) &
        !           399:                          (ISRP_HIGH_ARB_COMMAND | ISRP_HIGH_ASB_FREE);
        !           400: 
        !           401:     C->Adapter->IsrpBits = (C->Adapter->IsrpBits) &
        !           402:                          (~(ISRP_HIGH_ARB_COMMAND | ISRP_HIGH_ASB_FREE));
        !           403: 
        !           404:     return TRUE;
        !           405: 
        !           406: }
        !           407: 
        !           408: extern
        !           409: BOOLEAN
        !           410: IbmtokSynchSetReset(
        !           411:     IN PVOID Context
        !           412:     )
        !           413: 
        !           414: /*++
        !           415: 
        !           416: Routine Description:
        !           417: 
        !           418:     This routine is called by the SET_INTERRUPT_RESET_FLAG macro.
        !           419:     It sets the ResetInterruptAllowed flag to TRUE.
        !           420: 
        !           421: Arguments:
        !           422: 
        !           423:     Context - A pointer to the Adapter structure.
        !           424: 
        !           425: Return Value:
        !           426: 
        !           427:     Always returns true.
        !           428: 
        !           429: --*/
        !           430: 
        !           431: {
        !           432: 
        !           433:     PIBMTOK_ADAPTER Adapter = (PIBMTOK_ADAPTER)Context;
        !           434: 
        !           435:     Adapter->ResetInterruptAllowed = TRUE;
        !           436: 
        !           437:     return TRUE;
        !           438: 
        !           439: }
        !           440: 
        !           441: extern
        !           442: BOOLEAN
        !           443: IbmtokSynchClearIsrpBits(
        !           444:     IN PVOID Context
        !           445:     )
        !           446: 
        !           447: /*++
        !           448: 
        !           449: Routine Description:
        !           450: 
        !           451:     This routine is called by the CLEAR_ISRP_BITS macro.
        !           452:     It clears the SRB/SSB and ARB/ASB bits. This is used
        !           453:     when a reset has started to prevent a previously
        !           454:     queued interrupt handler to come in and start
        !           455:     playing with an adapter that is being reset.
        !           456: 
        !           457: Arguments:
        !           458: 
        !           459:     Context - A pointer to the Adapter structure.
        !           460: 
        !           461: Return Value:
        !           462: 
        !           463:     Always returns true.
        !           464: 
        !           465: --*/
        !           466: 
        !           467: {
        !           468: 
        !           469:     PIBMTOK_ADAPTER Adapter = (PIBMTOK_ADAPTER)Context;
        !           470: 
        !           471:     Adapter->IsrpBits = 0;
        !           472: 
        !           473:     return TRUE;
        !           474: 
        !           475: }
        !           476: 
        !           477: extern
        !           478: BOOLEAN
        !           479: IbmtokISR(
        !           480:     IN PVOID Context
        !           481:     )
        !           482: 
        !           483: /*++
        !           484: 
        !           485: Routine Description:
        !           486: 
        !           487:     Interrupt service routine for the sonic.  It's main job is
        !           488:     to get the value of ISR and record the changes in the
        !           489:     adapters own list of interrupt reasons.
        !           490: 
        !           491: Arguments:
        !           492: 
        !           493:     Context - Really a pointer to the adapter.
        !           494: 
        !           495: Return Value:
        !           496: 
        !           497:     Returns true if the card ISR is non-zero.
        !           498: 
        !           499: --*/
        !           500: 
        !           501: {
        !           502: 
        !           503:     //
        !           504:     // Holds the pointer to the adapter.
        !           505:     //
        !           506:     PIBMTOK_ADAPTER Adapter = Context;
        !           507: 
        !           508:     //
        !           509:     // Holds the value of the ISRP High
        !           510:     //
        !           511:     UCHAR IsrpHigh;
        !           512: 
        !           513:     READ_ADAPTER_REGISTER(Adapter, ISRP_HIGH, &IsrpHigh);
        !           514: 
        !           515: 
        !           516:     if (!Adapter->BringUp) {
        !           517: 
        !           518:         Adapter->ContinuousIsrs++;
        !           519: 
        !           520:         if (Adapter->ContinuousIsrs == 0xFF) {
        !           521: 
        !           522:             //
        !           523:             // We seemed to be confused since the DPCs aren't getting in.
        !           524:             // Shutdown and exit.
        !           525:             //
        !           526: 
        !           527: #if DBG
        !           528:             if (IbmtokDbg) DbgPrint("IBMTOK: Continuous ISRs received\n");
        !           529: #endif
        !           530: 
        !           531:             WRITE_ADAPTER_PORT(Adapter, RESET_LATCH, 0);
        !           532: 
        !           533:             return(FALSE);
        !           534: 
        !           535:         }
        !           536: 
        !           537:     }
        !           538: 
        !           539: 
        !           540: #if DBG
        !           541:     if (IbmtokDbg) DbgPrint("ISRP High: %x\n", IsrpHigh);
        !           542: #endif
        !           543: 
        !           544:     IF_LOG('i');
        !           545: 
        !           546:     //
        !           547:     // Acknowledge all the interrupts we got in IsrpHigh.
        !           548:     //
        !           549: 
        !           550:     WRITE_ADAPTER_REGISTER(Adapter, ISRP_HIGH_RESET, (UCHAR)(~IsrpHigh));
        !           551: 
        !           552:     //
        !           553:     // If the adapter is not accepting requests, ignore everything
        !           554:     // but SRB_RESPONSE interrupts, saving any others until
        !           555:     // NotAcceptingRequests goes to FALSE (note that we have
        !           556:     // already turned off ALL bits in ISRP_HIGH).
        !           557:     //
        !           558:     if (Adapter->NotAcceptingRequests) {
        !           559: 
        !           560:         Adapter->IsrpDeferredBits |= (IsrpHigh & (~ISRP_HIGH_SRB_RESPONSE));
        !           561: 
        !           562:         IsrpHigh &= ISRP_HIGH_SRB_RESPONSE;
        !           563: 
        !           564:     } else {
        !           565: 
        !           566:         //
        !           567:         // Put the deferred bits back on (after the first time
        !           568:         // through they will be 0).
        !           569:         //
        !           570: 
        !           571:         IsrpHigh |= Adapter->IsrpDeferredBits;
        !           572: 
        !           573:         Adapter->IsrpDeferredBits = 0;
        !           574: 
        !           575:     }
        !           576: 
        !           577: 
        !           578:     //
        !           579:     // Now store the bits for the DPC.
        !           580:     //
        !           581: 
        !           582:     Adapter->IsrpBits |= IsrpHigh;
        !           583: 
        !           584:     //
        !           585:     // If this is the reset interrupt, set the flag.
        !           586:     //
        !           587: 
        !           588:     if (Adapter->ResetInterruptAllowed){
        !           589:         Adapter->ResetInterruptHasArrived = TRUE;
        !           590:     }
        !           591: 
        !           592:     if (Adapter->FirstInitialization) {
        !           593: 
        !           594:         USHORT WrbOffset;
        !           595:         PSRB_BRING_UP_RESULT BringUpSrb;
        !           596:         UCHAR Value1, Value2;
        !           597:         USHORT RegValue;
        !           598: 
        !           599:         READ_ADAPTER_REGISTER(Adapter, WRBR_LOW,  &Value1);
        !           600:         READ_ADAPTER_REGISTER(Adapter, WRBR_HIGH, &Value2);
        !           601: 
        !           602:         WrbOffset = (((USHORT)Value1) << 8) + (USHORT)Value2;
        !           603: 
        !           604:         Adapter->InitialWrbOffset = WrbOffset;
        !           605: 
        !           606:         BringUpSrb = (PSRB_BRING_UP_RESULT)(Adapter->SharedRam + WrbOffset);
        !           607: 
        !           608:         NdisReadRegisterUshort(&(BringUpSrb->ReturnCode), &RegValue);
        !           609: 
        !           610:         if (RegValue == 0x0000) {
        !           611: 
        !           612:             Adapter->BringUp = TRUE;
        !           613: 
        !           614:         }
        !           615: 
        !           616:         //
        !           617:         // If we are using the PC I/O Bus then we have to re-enable
        !           618:         // interrupts because the card is blocking all other interrupts
        !           619:         //
        !           620: 
        !           621:         if (Adapter->UsingPcIoBus) {
        !           622:             WRITE_ADAPTER_PORT(Adapter, INTERRUPT_RELEASE_ISA_ONLY, 0);
        !           623:         }
        !           624: 
        !           625:         IF_LOG('I');
        !           626: 
        !           627:         //
        !           628:         // no DPC for the first init.
        !           629:         //
        !           630: 
        !           631:         return(FALSE);
        !           632:     }
        !           633: 
        !           634:     //
        !           635:     // If we are using the PC I/O Bus then we have to re-enable
        !           636:     // interrupts because the card is blocking all other interrupts
        !           637:     //
        !           638: 
        !           639:     if (Adapter->UsingPcIoBus) {
        !           640:         WRITE_ADAPTER_PORT(Adapter, INTERRUPT_RELEASE_ISA_ONLY, 0);
        !           641:     }
        !           642: 
        !           643:     if (IsrpHigh == 0x0) {
        !           644: 
        !           645:         //
        !           646:         // This means that the interrupt was generated from the IsrpLow
        !           647:         // and needs to be cleared.
        !           648:         //
        !           649: 
        !           650:         READ_ADAPTER_REGISTER(Adapter, ISRP_LOW, &IsrpHigh);
        !           651: 
        !           652:         //
        !           653:         // Mask off the bits we need.
        !           654:         //
        !           655: 
        !           656:         IsrpHigh &= 0x1C;
        !           657: 
        !           658:         Adapter->IsrpLowBits = IsrpHigh;
        !           659: 
        !           660:         //
        !           661:         // Acknowledge all the interrupts we got in IsrpLow.
        !           662:         //
        !           663: 
        !           664:         WRITE_ADAPTER_REGISTER(Adapter, ISRP_LOW_RESET, (UCHAR)(~IsrpHigh));
        !           665: 
        !           666:     }
        !           667: 
        !           668:     IF_LOG('I');
        !           669: 
        !           670:     if (Adapter->IsrpBits != 0) {
        !           671: 
        !           672:         return TRUE;
        !           673: 
        !           674:     } else {
        !           675: 
        !           676:         return FALSE;
        !           677: 
        !           678:     }
        !           679: 
        !           680: }
        !           681: 
        !           682: extern
        !           683: VOID
        !           684: IbmtokDPC(
        !           685:     IN PVOID SystemSpecific1,
        !           686:     IN PVOID Context,
        !           687:     IN PVOID SystemArgument1,
        !           688:     IN PVOID SystemArgument2
        !           689:     )
        !           690: 
        !           691: /*++
        !           692: 
        !           693: Routine Description:
        !           694: 
        !           695:     This DPC routine is queued by Ndis after interrupt service routine
        !           696:     has run. It's main job is to call the interrupt processing code.
        !           697: 
        !           698: Arguments:
        !           699: 
        !           700:     SystemSpecific1 - Not used.
        !           701: 
        !           702:     Context - Really a pointer to the adapter.
        !           703: 
        !           704:     SystemArgument1(2) - Neither of these arguments used.
        !           705: 
        !           706: Return Value:
        !           707: 
        !           708:     None.
        !           709: 
        !           710: --*/
        !           711: 
        !           712: {
        !           713:     PIBMTOK_ADAPTER Adapter = (PIBMTOK_ADAPTER)Context;
        !           714: 
        !           715:     NdisDprAcquireSpinLock(&Adapter->Lock);
        !           716: 
        !           717:     Adapter->ContinuousIsrs = 0;
        !           718: 
        !           719:     IF_LOG('d');
        !           720: 
        !           721:     Adapter->WakeUpTimeout = FALSE;
        !           722: 
        !           723:     if (Adapter->IsrpLowBits) {
        !           724: 
        !           725:         NdisWriteErrorLogEntry(
        !           726:             Adapter->NdisAdapterHandle,
        !           727:             NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !           728:             3,
        !           729:             ibmtokDpc,
        !           730:             IBMTOK_ERRMSG_ISRP_LOW_ERROR,
        !           731:             (ULONG)(Adapter->IsrpLowBits)
        !           732:             );
        !           733: 
        !           734:         Adapter->IsrpLowBits = 0;
        !           735: 
        !           736:     }
        !           737: 
        !           738:     if ((Adapter->IsrpBits & (ISRP_HIGH_SRB_RESPONSE | ISRP_HIGH_SSB_RESPONSE)) &&
        !           739:         (!Adapter->HandleSrbRunning)) {
        !           740: 
        !           741:         IbmtokHandleSrbSsb(Adapter);
        !           742: 
        !           743:         NdisDprAcquireSpinLock(&(Adapter->Lock));
        !           744: 
        !           745:     }
        !           746: 
        !           747:     if ((Adapter->IsrpBits & (ISRP_HIGH_ARB_COMMAND | ISRP_HIGH_ASB_FREE)) &&
        !           748:         (!Adapter->HandleArbRunning)) {
        !           749: 
        !           750:         IbmtokHandleArbAsb(Adapter);
        !           751: 
        !           752:     } else {
        !           753: 
        !           754:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !           755:     }
        !           756: 
        !           757: #if DBG
        !           758:     NdisDprAcquireSpinLock(&Adapter->Lock);
        !           759:     IF_LOG('D');
        !           760:     NdisDprReleaseSpinLock(&Adapter->Lock);
        !           761: #endif
        !           762: 
        !           763: }
        !           764: 
        !           765: extern
        !           766: VOID
        !           767: IbmtokHandleSrbSsb(
        !           768:     IN PIBMTOK_ADAPTER Adapter
        !           769:     )
        !           770: 
        !           771: /*++
        !           772: 
        !           773: Routine Description:
        !           774: 
        !           775:     This routine is called by the DPC routine
        !           776:     and other routines within the driver that notice that
        !           777:     some deferred processing needs to be done.  It's main
        !           778:     job is to call the interrupt processing code.
        !           779: 
        !           780:     NOTE: THIS ROUTINE IS CALLED WITH THE LOCK HELD!!  AND RETURNS
        !           781:     WITH IT RELEASED!!
        !           782: 
        !           783: Arguments:
        !           784: 
        !           785:    Adapter - A pointer to the adapter.
        !           786: 
        !           787: Return Value:
        !           788: 
        !           789:     None.
        !           790: 
        !           791: --*/
        !           792: 
        !           793: {
        !           794:     UCHAR IsrpHigh;
        !           795:     UCHAR TmpUchar;
        !           796:     USHORT TmpUshort;
        !           797: 
        !           798:     IF_LOG('h');
        !           799: 
        !           800:     Adapter->References++;
        !           801: 
        !           802:     if (Adapter->ResetInProgress) {
        !           803: 
        !           804:         if (Adapter->ResetInterruptHasArrived) {
        !           805: 
        !           806:             //
        !           807:             // This is the interrupt after a reset,
        !           808:             // continue things along.
        !           809:             //
        !           810: 
        !           811:             HandleResetStaging(Adapter);
        !           812: 
        !           813:             IBMTOK_DO_DEFERRED(Adapter);
        !           814: 
        !           815:             return;
        !           816: 
        !           817:         }
        !           818: 
        !           819:     }
        !           820: 
        !           821:     //
        !           822:     // If ResetInProgress is TRUE but this is an old
        !           823:     // interrupt, proceed as usual (once the reset
        !           824:     // actually starts, GET_SRB_SSB_BITS will return
        !           825:     // nothing so no work will get done).
        !           826:     //
        !           827: 
        !           828:     Adapter->HandleSrbRunning = TRUE;
        !           829: 
        !           830:     GET_SRB_SSB_BITS(Adapter, &IsrpHigh);
        !           831: 
        !           832:     while (IsrpHigh & (ISRP_HIGH_SRB_RESPONSE | ISRP_HIGH_SSB_RESPONSE)) {
        !           833: 
        !           834:         IF_LOG((UCHAR)(Adapter->OpenInProgress));
        !           835: 
        !           836:         if (Adapter->Unplugged && !Adapter->UnpluggedResetInProgress) {
        !           837: 
        !           838:             //
        !           839:             // Do, nothing.  This is most likely a stale interrupt.  We
        !           840:             // wait until we get a ring status interrupt telling us that
        !           841:             // the cable is plugged in.
        !           842:             //
        !           843: 
        !           844:             break;
        !           845: 
        !           846:         }
        !           847: 
        !           848:         if (IsrpHigh & ISRP_HIGH_SRB_RESPONSE) {
        !           849: 
        !           850:             if (Adapter->OpenInProgress) {
        !           851: 
        !           852:                 //
        !           853:                 // Handle the result of the DIR.OPEN.ADAPTER command.
        !           854:                 //
        !           855: 
        !           856:                 PSRB_OPEN_RESPONSE OpenResponseSrb;
        !           857:                 PIBMTOK_OPEN Open;
        !           858:                 PLIST_ENTRY CurrentLink;
        !           859:                 UCHAR ReturnCode;
        !           860: 
        !           861:                 OpenResponseSrb = (PSRB_OPEN_RESPONSE)
        !           862:                         (Adapter->SharedRam + Adapter->InitialWrbOffset);
        !           863: 
        !           864:                 NdisReadRegisterUchar(&(OpenResponseSrb->ReturnCode), &ReturnCode);
        !           865: 
        !           866: #if DBG
        !           867:     if (IbmtokDbg)
        !           868:                 DbgPrint("IBMTOK: OPEN, Return code = %x, at %lx\n",
        !           869:                                 ReturnCode,
        !           870:                                 OpenResponseSrb);
        !           871: #endif
        !           872: 
        !           873:                 if (ReturnCode == 0x0) {
        !           874: 
        !           875:                     NdisDprReleaseSpinLock(&(Adapter->Lock));
        !           876: 
        !           877:                     if (Adapter->SharedRamPaging) {
        !           878: 
        !           879:                         NdisReadRegisterUshort(&(OpenResponseSrb->SrbPointer), &TmpUshort);
        !           880: 
        !           881:                         TmpUshort = IBMSHORT_TO_USHORT(TmpUshort);
        !           882: 
        !           883:                         Adapter->SrbAddress = SHARED_RAM_ADDRESS(Adapter,
        !           884:                                                     SHARED_RAM_LOW_BITS(TmpUshort));
        !           885:                         Adapter->SrbSrprLow = (UCHAR)(TmpUshort >> 14);
        !           886: 
        !           887: 
        !           888:                         NdisReadRegisterUshort(&(OpenResponseSrb->SsbPointer), &TmpUshort);
        !           889: 
        !           890:                         TmpUshort = IBMSHORT_TO_USHORT(TmpUshort);
        !           891: 
        !           892:                         Adapter->SsbAddress = SHARED_RAM_ADDRESS(Adapter,
        !           893:                                                     SHARED_RAM_LOW_BITS(TmpUshort));
        !           894:                         Adapter->SsbSrprLow = (UCHAR)(TmpUshort >> 14);
        !           895: 
        !           896: 
        !           897:                         NdisReadRegisterUshort(&(OpenResponseSrb->ArbPointer), &TmpUshort);
        !           898: 
        !           899:                         TmpUshort = IBMSHORT_TO_USHORT(TmpUshort);
        !           900: 
        !           901:                         Adapter->ArbAddress = SHARED_RAM_ADDRESS(Adapter,
        !           902:                                                     SHARED_RAM_LOW_BITS(TmpUshort));
        !           903:                         Adapter->ArbSrprLow = (UCHAR)(TmpUshort >> 14);
        !           904: 
        !           905: 
        !           906:                         NdisReadRegisterUshort(&(OpenResponseSrb->AsbPointer), &TmpUshort);
        !           907: 
        !           908:                         TmpUshort = IBMSHORT_TO_USHORT(TmpUshort);
        !           909: 
        !           910:                         Adapter->AsbAddress = SHARED_RAM_ADDRESS(Adapter,
        !           911:                                                     SHARED_RAM_LOW_BITS(TmpUshort));
        !           912:                         Adapter->AsbSrprLow = (UCHAR)(TmpUshort >> 14);
        !           913: 
        !           914:                     } else {
        !           915: 
        !           916:                         NdisReadRegisterUshort(&(OpenResponseSrb->SrbPointer), &TmpUshort);
        !           917:                         Adapter->SrbAddress = SRAM_PTR_TO_PVOID(Adapter, TmpUshort);
        !           918: 
        !           919:                         NdisReadRegisterUshort(&(OpenResponseSrb->SsbPointer), &TmpUshort);
        !           920:                         Adapter->SsbAddress = SRAM_PTR_TO_PVOID(Adapter, TmpUshort);
        !           921: 
        !           922:                         NdisReadRegisterUshort(&(OpenResponseSrb->ArbPointer), &TmpUshort);
        !           923:                         Adapter->ArbAddress = SRAM_PTR_TO_PVOID(Adapter, TmpUshort);
        !           924: 
        !           925:                         NdisReadRegisterUshort(&(OpenResponseSrb->AsbPointer), &TmpUshort);
        !           926:                         Adapter->AsbAddress = SRAM_PTR_TO_PVOID(Adapter, TmpUshort);
        !           927: 
        !           928:                     }
        !           929: 
        !           930: #if DBG
        !           931:                     if (IbmtokDbg) {
        !           932:                         USHORT TmpUshort1;
        !           933:                         USHORT TmpUshort2;
        !           934:                         USHORT TmpUshort3;
        !           935:                         USHORT TmpUshort4;
        !           936:                         NdisReadRegisterUshort(&(OpenResponseSrb->SrbPointer), &TmpUshort1);
        !           937:                         NdisReadRegisterUshort(&(OpenResponseSrb->SsbPointer), &TmpUshort2);
        !           938:                         NdisReadRegisterUshort(&(OpenResponseSrb->ArbPointer), &TmpUshort3);
        !           939:                         NdisReadRegisterUshort(&(OpenResponseSrb->AsbPointer), &TmpUshort4);
        !           940:                         DbgPrint("IBMTOK: Offsets: SRB %x  SSB %x  ARB %x  ASB %x\n",
        !           941:                                 IBMSHORT_TO_USHORT(TmpUshort1),
        !           942:                                 IBMSHORT_TO_USHORT(TmpUshort2),
        !           943:                                 IBMSHORT_TO_USHORT(TmpUshort3),
        !           944:                                 IBMSHORT_TO_USHORT(TmpUshort4));
        !           945:                     }
        !           946: #endif
        !           947: 
        !           948:                     //
        !           949:                     // Now we have to start worrying about synchronization.
        !           950:                     //
        !           951: 
        !           952:                     NdisDprAcquireSpinLock(&(Adapter->Lock));
        !           953: 
        !           954:                     Adapter->CurrentRingState = NdisRingStateOpened;
        !           955:                     Adapter->OpenInProgress = FALSE;
        !           956:                     Adapter->OpenErrorCode = 0;
        !           957:                     Adapter->AdapterNotOpen = FALSE;
        !           958:                     Adapter->NotAcceptingRequests = FALSE;
        !           959: 
        !           960:                     //
        !           961:                     // Complete all opens that pended during this operation.
        !           962:                     //
        !           963: 
        !           964:                     CurrentLink = Adapter->OpenBindings.Flink;
        !           965: 
        !           966:                     while (CurrentLink != &(Adapter->OpenBindings)){
        !           967: 
        !           968:                         Open = CONTAINING_RECORD(
        !           969:                                  CurrentLink,
        !           970:                                  IBMTOK_OPEN,
        !           971:                                  OpenList
        !           972:                                  );
        !           973: 
        !           974:                         if (Open->OpenPending) {
        !           975: 
        !           976:                             Open->OpenPending = FALSE;
        !           977:                             NdisDprReleaseSpinLock(&(Adapter->Lock));
        !           978: 
        !           979:                             NdisCompleteOpenAdapter(
        !           980:                                 Open->NdisBindingContext,
        !           981:                                 NDIS_STATUS_SUCCESS,
        !           982:                                 0
        !           983:                                 );
        !           984: 
        !           985:                             NdisDprAcquireSpinLock(&(Adapter->Lock));
        !           986: 
        !           987:                         }
        !           988: 
        !           989:                         CurrentLink = CurrentLink->Flink;
        !           990: 
        !           991:                     }
        !           992: 
        !           993:                     //
        !           994:                     // Get any interrupts that have been deferred
        !           995:                     // while NotAcceptingRequests was TRUE.
        !           996:                     //
        !           997:                     IbmtokForceAdapterInterrupt(Adapter);
        !           998: 
        !           999:                 } else {
        !          1000: 
        !          1001:                     //
        !          1002:                     // Open Failed!
        !          1003:                     //
        !          1004: 
        !          1005:                     //
        !          1006:                     // Now we have to start worrying about synchronization.
        !          1007:                     //
        !          1008: 
        !          1009:                     Adapter->CurrentRingState = NdisRingStateOpenFailure;
        !          1010:                     Adapter->OpenInProgress = FALSE;
        !          1011:                     NdisReadRegisterUshort(&(OpenResponseSrb->ErrorCode),
        !          1012:                                            &(Adapter->OpenErrorCode)
        !          1013:                                           );
        !          1014:                     Adapter->OpenErrorCode = IBMSHORT_TO_USHORT(Adapter->OpenErrorCode);
        !          1015:                     Adapter->AdapterNotOpen = TRUE;
        !          1016:                     Adapter->NotAcceptingRequests = TRUE;
        !          1017: 
        !          1018:                     //
        !          1019:                     // Fail all opens that pended during this operation.
        !          1020:                     //
        !          1021: 
        !          1022:                     CurrentLink = Adapter->OpenBindings.Flink;
        !          1023: 
        !          1024:                     while (CurrentLink != &(Adapter->OpenBindings)){
        !          1025: 
        !          1026:                         Open = CONTAINING_RECORD(
        !          1027:                                  CurrentLink,
        !          1028:                                  IBMTOK_OPEN,
        !          1029:                                  OpenList
        !          1030:                                  );
        !          1031: 
        !          1032: 
        !          1033:                         if (Open->OpenPending) {
        !          1034: 
        !          1035:                             Open->OpenPending = FALSE;
        !          1036: 
        !          1037:                             NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          1038: 
        !          1039:                             NdisCompleteOpenAdapter(
        !          1040:                                 Open->NdisBindingContext,
        !          1041:                                 NDIS_STATUS_OPEN_FAILED,
        !          1042:                                 NDIS_STATUS_TOKEN_RING_OPEN_ERROR |
        !          1043:                                 (NDIS_STATUS)(Adapter->OpenErrorCode)
        !          1044:                                 );
        !          1045: 
        !          1046:                             NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          1047: 
        !          1048:                             CurrentLink = CurrentLink->Flink;
        !          1049: 
        !          1050:                             RemoveEntryList(&(Open->OpenList));
        !          1051: 
        !          1052:                             IBMTOK_FREE_PHYS(Open, sizeof(IBMTOK_OPEN));
        !          1053: 
        !          1054:                             Adapter->References--;
        !          1055: 
        !          1056:                         } else {
        !          1057: 
        !          1058:                             //
        !          1059:                             // Note: All opens are pending, otherwise the
        !          1060:                             //   adapter would have already been open.
        !          1061:                             //
        !          1062: 
        !          1063:                         }
        !          1064: 
        !          1065:                     }
        !          1066: 
        !          1067:                 }
        !          1068: 
        !          1069:             } else {
        !          1070: 
        !          1071: #if DBG
        !          1072:                 if (IbmtokDbg) DbgPrint("IBMTOK: SRB Response\n");
        !          1073: #endif
        !          1074: 
        !          1075:                 IF_LOG('>');
        !          1076: 
        !          1077:                 if (Adapter->TransmittingPacket != (PNDIS_PACKET)NULL) {
        !          1078: 
        !          1079:                     BOOLEAN PacketRemoved;
        !          1080: 
        !          1081:                     //
        !          1082:                     // Happens if the transmit failed.
        !          1083:                     //
        !          1084: 
        !          1085:                     (PVOID)RemoveTransmitFromSrb(Adapter, &PacketRemoved);
        !          1086: 
        !          1087:                     //
        !          1088:                     // If the packet was successfully removed, then
        !          1089:                     // start the next command.
        !          1090:                     //
        !          1091:                     // This will release the spin lock.
        !          1092:                     //
        !          1093: 
        !          1094:                     if (PacketRemoved) {
        !          1095: 
        !          1096:                         //
        !          1097:                         // SrbAvailable will still be FALSE here,
        !          1098:                         // as required.
        !          1099:                         //
        !          1100: 
        !          1101:                         SetupSrbCommand(Adapter);
        !          1102: 
        !          1103:                     }
        !          1104: 
        !          1105:                 } else if (!Adapter->SrbAvailable) {
        !          1106: 
        !          1107:                     PSRB_GENERIC GenericSrb = (PSRB_GENERIC)Adapter->SrbAddress;
        !          1108:                     UCHAR ReturnCode;
        !          1109: 
        !          1110:                     //
        !          1111:                     // Another command in progress, complete it unless
        !          1112:                     // it was an INTERRUPT command.
        !          1113:                     //
        !          1114: 
        !          1115:                     NdisReadRegisterUchar(&(GenericSrb->ReturnCode), &ReturnCode);
        !          1116: 
        !          1117:                     IF_LOG('N');
        !          1118: 
        !          1119:                     NdisReadRegisterUchar(&(GenericSrb->Command), &TmpUchar);
        !          1120: 
        !          1121:                     if (TmpUchar != SRB_CMD_INTERRUPT) {
        !          1122: 
        !          1123:                         if ((TmpUchar != SRB_CMD_READ_LOG) &&
        !          1124:                             (TmpUchar != SRB_CMD_SET_FUNCTIONAL_ADDRESS) &&
        !          1125:                             (TmpUchar != SRB_CMD_SET_GROUP_ADDRESS) &&
        !          1126:                             (TmpUchar != SRB_CMD_DLC_STATISTICS)) {
        !          1127: 
        !          1128:                             //
        !          1129:                             // We have an invalid response.  Log an error an exit.
        !          1130:                             //
        !          1131: 
        !          1132:                             NdisWriteErrorLogEntry(
        !          1133:                                 Adapter->NdisAdapterHandle,
        !          1134:                                 NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER,
        !          1135:                                 3,
        !          1136:                                 handleSrbSsb,
        !          1137:                                 IBMTOK_ERRMSG_INVALID_CMD,
        !          1138:                                 (ULONG)TmpUchar
        !          1139:                                 );
        !          1140: 
        !          1141:                         } else {
        !          1142: 
        !          1143:                             //
        !          1144:                             // This interrupt had to come from a pended op.
        !          1145:                             //
        !          1146: 
        !          1147:                             ASSERT(Adapter->PendData != NULL);
        !          1148: 
        !          1149:                             if (Adapter->PendData->RequestType == NdisRequestGeneric1){
        !          1150: 
        !          1151:                                 //
        !          1152:                                 // If no request, it came as a result of the
        !          1153:                                 // card overflowing a counter and then we
        !          1154:                                 // submitted the correcting operation.
        !          1155:                                 //
        !          1156: 
        !          1157:                                 if (ReturnCode == 0x00) {
        !          1158: 
        !          1159:                                     if (Adapter->PendData->COMMAND.MAC.ReadLogPending){
        !          1160: 
        !          1161:                                         //
        !          1162:                                         // We are getting an SRB_CMD_READ_LOG from
        !          1163:                                         // we sent as a result to a RING_STATUS_CHANGE.
        !          1164:                                         //
        !          1165: 
        !          1166:                                         GetAdapterErrorsFromSrb(Adapter);
        !          1167: 
        !          1168:                                     } else {
        !          1169: 
        !          1170:                                         //
        !          1171:                                         // We are getting an SRB_CMD_DLC_STATISTICS from
        !          1172:                                         // we sent as a result to a DLC_STATUS.
        !          1173:                                         //
        !          1174: 
        !          1175:                                         GetAdapterStatisticsFromSrb(Adapter);
        !          1176: 
        !          1177:                                     }
        !          1178: 
        !          1179:                                 }
        !          1180: 
        !          1181:                                 //
        !          1182:                                 // Free up pend operation.
        !          1183:                                 //
        !          1184: 
        !          1185:                                 IBMTOK_FREE_PHYS(Adapter->PendData, sizeof(IBMTOK_PEND_DATA));
        !          1186: 
        !          1187:                                 Adapter->PendData = NULL;
        !          1188: 
        !          1189:                                 //
        !          1190:                                 // Fire off next command.
        !          1191:                                 //
        !          1192: 
        !          1193:                                 SetupSrbCommand(Adapter);
        !          1194: 
        !          1195:                             } else {
        !          1196: 
        !          1197:                                 //
        !          1198:                                 // This is the result of a pending op from Ndis.
        !          1199:                                 //
        !          1200: 
        !          1201:                                 if (FinishPendQueueOp(
        !          1202:                                    Adapter,
        !          1203:                                    (BOOLEAN)(ReturnCode == 0x00 ? TRUE : FALSE)
        !          1204:                                    )){
        !          1205: 
        !          1206:                                     //
        !          1207:                                     // Fire off next command.
        !          1208:                                     //
        !          1209: 
        !          1210:                                     SetupSrbCommand(Adapter);
        !          1211: 
        !          1212:                                 }
        !          1213: 
        !          1214:                             }
        !          1215: 
        !          1216:                         }
        !          1217:                     } else {
        !          1218: 
        !          1219:                         SetupSrbCommand(Adapter);
        !          1220: 
        !          1221:                     }
        !          1222: 
        !          1223:                 } else {
        !          1224: 
        !          1225:                     //
        !          1226:                     // Nothing to do -- we get here when an SRB_FREE_REQUEST
        !          1227:                     // comes through after the ARB to transfer the data has
        !          1228:                     // already come through.
        !          1229:                     //
        !          1230: 
        !          1231:                 }
        !          1232: 
        !          1233:             }
        !          1234: 
        !          1235:         }
        !          1236: 
        !          1237:         if (IsrpHigh & ISRP_HIGH_SSB_RESPONSE) {
        !          1238: 
        !          1239:             //
        !          1240:             // This has to be a transmit completing since
        !          1241:             // that is the only operation we do that pends.
        !          1242:             //
        !          1243:             PSSB_TRANSMIT_COMPLETE ResponseSsb =
        !          1244:                         (PSSB_TRANSMIT_COMPLETE)Adapter->SsbAddress;
        !          1245: 
        !          1246:             NdisReadRegisterUchar(&(ResponseSsb->Command), &TmpUchar);
        !          1247: 
        !          1248:             if (TmpUchar == SRB_CMD_TRANSMIT_DIR_FRAME) {
        !          1249: 
        !          1250:                 UCHAR CorrelatorInSrb;
        !          1251:                 NDIS_STATUS SendStatus;
        !          1252:                 UCHAR SrbReturnCode;
        !          1253: 
        !          1254:                 //
        !          1255:                 // Initialize this to one less since the loop starts by
        !          1256:                 // incrementing it.
        !          1257:                 //
        !          1258: 
        !          1259:                 UCHAR CurrentCorrelator = (UCHAR)
        !          1260:                             ((Adapter->NextCorrelatorToComplete +
        !          1261:                             (MAX_COMMAND_CORRELATOR-1)) %
        !          1262:                                 MAX_COMMAND_CORRELATOR);
        !          1263: 
        !          1264:                 NdisReadRegisterUchar(&(ResponseSsb->CommandCorrelator), &CorrelatorInSrb);
        !          1265: 
        !          1266:                 //
        !          1267:                 // Have to loop to complete since supposedly one
        !          1268:                 // of these can indicate multiple completing sends.
        !          1269:                 //
        !          1270: 
        !          1271:                 //
        !          1272:                 // Figure out what the return code should be.
        !          1273:                 //
        !          1274: 
        !          1275:                 NdisReadRegisterUchar(&(ResponseSsb->ReturnCode), &SrbReturnCode);
        !          1276: 
        !          1277:                 if (SrbReturnCode == 0x00) {
        !          1278: 
        !          1279:                     SendStatus = NDIS_STATUS_SUCCESS;
        !          1280: 
        !          1281:                 } else if (SrbReturnCode == 0x22) {
        !          1282: 
        !          1283:                     //
        !          1284:                     // Check the frame status.
        !          1285:                     //
        !          1286:                     UCHAR FrameStatus;
        !          1287:                     UCHAR HighAc;
        !          1288:                     UCHAR LowAc;
        !          1289: 
        !          1290:                     NdisReadRegisterUchar(&(ResponseSsb->ErrorFrameStatus), &FrameStatus);
        !          1291:                     HighAc = GET_FRAME_STATUS_HIGH_AC(FrameStatus);
        !          1292:                     LowAc = GET_FRAME_STATUS_LOW_AC(FrameStatus);
        !          1293: 
        !          1294:                     if (HighAc != LowAc  ||
        !          1295:                             (HighAc != AC_NOT_RECOGNIZED)) {
        !          1296: 
        !          1297:                         SendStatus = NDIS_STATUS_NOT_RECOGNIZED;
        !          1298: 
        !          1299:                     } else {
        !          1300: 
        !          1301:                         SendStatus = NDIS_STATUS_SUCCESS;
        !          1302: 
        !          1303:                     }
        !          1304: 
        !          1305: #if DBG
        !          1306:     if (IbmtokDbg) DbgPrint("IBMTOK: Send failed, code %x  err %x\n",
        !          1307:                         SrbReturnCode,
        !          1308:                         FrameStatus);
        !          1309: #endif
        !          1310: 
        !          1311:                 } else {
        !          1312: 
        !          1313:                     SendStatus = NDIS_STATUS_FAILURE;
        !          1314: 
        !          1315: #if DBG
        !          1316:     if (IbmtokDbg) DbgPrint("IBMTOK: Send failed, code %x\n",
        !          1317:                         SrbReturnCode);
        !          1318: #endif
        !          1319: 
        !          1320:                 }
        !          1321: 
        !          1322:                 NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          1323: 
        !          1324:                 do {
        !          1325: 
        !          1326:                     PNDIS_PACKET TransmitPacket;
        !          1327:                     PIBMTOK_RESERVED Reserved;
        !          1328:                     PIBMTOK_OPEN Open;
        !          1329: 
        !          1330:                     CurrentCorrelator = (UCHAR)((CurrentCorrelator + 1) %
        !          1331:                                             MAX_COMMAND_CORRELATOR);
        !          1332: 
        !          1333:                     //
        !          1334:                     // Complete the transmit.
        !          1335:                     //
        !          1336: 
        !          1337:                     TransmitPacket =
        !          1338:                             FindPacketGivenCorrelator(Adapter, CurrentCorrelator);
        !          1339: 
        !          1340:                     if (TransmitPacket == (PNDIS_PACKET)NULL) {
        !          1341: 
        !          1342: #if DBG
        !          1343:     if (IbmtokDbg)       DbgPrint("IBMTOK: Missing %d to complete, %d to %d\n",
        !          1344:                                     CurrentCorrelator,
        !          1345:                                     Adapter->NextCorrelatorToComplete,
        !          1346:                                     CorrelatorInSrb);
        !          1347: #endif
        !          1348: 
        !          1349:                         continue;
        !          1350: 
        !          1351:                     }
        !          1352: 
        !          1353:                     RemovePacketFromCorrelatorArray(Adapter, TransmitPacket);
        !          1354: 
        !          1355:                     Reserved = PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          1356: 
        !          1357:                     Open =
        !          1358:                         PIBMTOK_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          1359: 
        !          1360:                     //
        !          1361:                     // If doing LOOPBACK, this should really be a check
        !          1362:                     // of ReadyToComplete etc.
        !          1363:                     //
        !          1364: 
        !          1365: #ifdef CHECK_DUP_SENDS
        !          1366:                     {
        !          1367:                     VOID IbmtokRemovePacketFromList(PIBMTOK_ADAPTER, PNDIS_PACKET);
        !          1368:                     IbmtokRemovePacketFromList(Adapter, TransmitPacket);
        !          1369:                     }
        !          1370: #endif
        !          1371: 
        !          1372:                     if (SendStatus == NDIS_STATUS_SUCCESS) {
        !          1373:                         Adapter->FramesTransmitted++;
        !          1374:                     } else {
        !          1375:                         Adapter->FrameTransmitErrors++;
        !          1376:                     }
        !          1377: 
        !          1378:                     NdisCompleteSend(
        !          1379:                         Open->NdisBindingContext,
        !          1380:                         Reserved->Packet,
        !          1381:                         SendStatus
        !          1382:                         );
        !          1383: 
        !          1384: 
        !          1385:                     //
        !          1386:                     // Decrement the reference count for the open.
        !          1387:                     //
        !          1388: 
        !          1389: #if DBG
        !          1390:                     NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          1391:                     IF_LOG('C');
        !          1392:                     NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          1393: #endif
        !          1394: 
        !          1395:                     NdisInterlockedAddUlong((PULONG)&Open->References, (UINT)-1, &Adapter->Lock);
        !          1396: 
        !          1397: 
        !          1398: 
        !          1399:                 } while (CurrentCorrelator != CorrelatorInSrb);
        !          1400: 
        !          1401:                 NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          1402: 
        !          1403:                 Adapter->NextCorrelatorToComplete =
        !          1404:                         (UCHAR)((CurrentCorrelator + 1) % MAX_COMMAND_CORRELATOR);
        !          1405: 
        !          1406: 
        !          1407:                 //
        !          1408:                 // We know that SrbAvailable is FALSE...
        !          1409:                 //
        !          1410: 
        !          1411:                 IF_LOG('<');
        !          1412: 
        !          1413:                 SetupSrbCommand(Adapter);
        !          1414: 
        !          1415:             } else {
        !          1416: 
        !          1417:                 //
        !          1418:                 // Nothing else should pend!!
        !          1419:                 //
        !          1420: 
        !          1421:                 NdisWriteErrorLogEntry(
        !          1422:                     Adapter->NdisAdapterHandle,
        !          1423:                     NDIS_ERROR_CODE_INVALID_VALUE_FROM_ADAPTER,
        !          1424:                     3,
        !          1425:                     handleSrbSsb,
        !          1426:                     IBMTOK_ERRMSG_INVALID_CMD,
        !          1427:                     (ULONG)TmpUchar
        !          1428:                     );
        !          1429: 
        !          1430: #if DBG
        !          1431:     if (IbmtokDbg) DbgPrint("IBMTOK: Error! Got Cmd %x\n",TmpUchar);
        !          1432: #endif
        !          1433: 
        !          1434:             }
        !          1435: 
        !          1436:             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1437:                         ISRA_HIGH_SSB_FREE);
        !          1438: 
        !          1439:         }
        !          1440: 
        !          1441:         GET_SRB_SSB_BITS(Adapter, &IsrpHigh);
        !          1442: 
        !          1443:     }
        !          1444: 
        !          1445:     Adapter->HandleSrbRunning = FALSE;
        !          1446: 
        !          1447:     IF_LOG('H');
        !          1448: 
        !          1449:     //
        !          1450:     // This macro assumes it is called with the lock held,
        !          1451:     // and releases it.
        !          1452:     //
        !          1453:     IBMTOK_DO_DEFERRED(Adapter);
        !          1454: 
        !          1455: }
        !          1456: 
        !          1457: extern
        !          1458: VOID
        !          1459: IbmtokHandleArbAsb(
        !          1460:     IN PIBMTOK_ADAPTER Adapter
        !          1461:     )
        !          1462: 
        !          1463: /*++
        !          1464: 
        !          1465: Routine Description:
        !          1466: 
        !          1467:     This routine is called by the DPC
        !          1468:     and other routines within the driver that notice that
        !          1469:     some deferred processing needs to be done.  It's main
        !          1470:     job is to call the interrupt processing code.
        !          1471: 
        !          1472:     NOTE: THIS ROUTINE IS CALLED WITH THE LOCK HELD!!  AND RETURNS WITH
        !          1473:     THE LOCK REALEASED!!
        !          1474: 
        !          1475: Arguments:
        !          1476: 
        !          1477:     Adapter - A pointer to the adapter.
        !          1478: 
        !          1479: Return Value:
        !          1480: 
        !          1481:     None.
        !          1482: 
        !          1483: --*/
        !          1484: 
        !          1485: {
        !          1486:     UCHAR IsrpHigh;
        !          1487: 
        !          1488:     PARB_TRANSMIT_DATA_REQUEST TransmitDataArb;
        !          1489: 
        !          1490:     PARB_RECEIVED_DATA ReceivedDataArb;
        !          1491: 
        !          1492:     PNDIS_PACKET TransmitPacket;
        !          1493: 
        !          1494:     SRAM_PTR ReceiveBufferPointer;
        !          1495: 
        !          1496:     PRECEIVE_BUFFER ReceiveBuffer;
        !          1497: 
        !          1498:     UINT PacketLength, DummyBytesCopied;
        !          1499: 
        !          1500:     BOOLEAN FreedSrb;
        !          1501: 
        !          1502:     PIBMTOK_RESERVED Reserved;
        !          1503: 
        !          1504:     PUCHAR DhbAddress;
        !          1505: 
        !          1506:     UINT PacketSize, LookaheadSize;
        !          1507: 
        !          1508:     PUCHAR FrameData;
        !          1509: 
        !          1510:     ULONG HeaderLength;
        !          1511: 
        !          1512:     UCHAR TmpUchar;
        !          1513: 
        !          1514:     USHORT TmpUshort;
        !          1515: 
        !          1516:     PUCHAR LookaheadBuffer;
        !          1517: 
        !          1518:     Adapter->References++;
        !          1519: 
        !          1520:     Adapter->HandleArbRunning = TRUE;
        !          1521: 
        !          1522:     IF_LOG('j');
        !          1523: 
        !          1524:     GET_ARB_ASB_BITS(Adapter, &IsrpHigh);
        !          1525: 
        !          1526:     while (IsrpHigh & (ISRP_HIGH_ARB_COMMAND | ISRP_HIGH_ASB_FREE)) {
        !          1527: 
        !          1528:         if (IsrpHigh & ISRP_HIGH_ARB_COMMAND) {
        !          1529: 
        !          1530:             NdisReadRegisterUchar(&((PARB_GENERIC)Adapter->ArbAddress)->Command, &TmpUchar);
        !          1531: 
        !          1532:             switch (TmpUchar) {
        !          1533: 
        !          1534:                 case ARB_CMD_DLC_STATUS:
        !          1535: 
        !          1536: #if DBG
        !          1537:     if (IbmtokDbg) {
        !          1538:                     NdisReadRegisterUshort(&
        !          1539:                             ((PARB_DLC_STATUS)Adapter->ArbAddress)->Status, &TmpUshort);
        !          1540:                     DbgPrint("IBMTOK: DLC Status %x\n",
        !          1541:                             IBMSHORT_TO_USHORT(TmpUshort));
        !          1542:     }
        !          1543: #endif
        !          1544: 
        !          1545: 
        !          1546: 
        !          1547:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1548:                                 ISRA_HIGH_ARB_FREE);
        !          1549: 
        !          1550:                     IF_LOG('#');
        !          1551: 
        !          1552:                     //
        !          1553:                     // If it is a counter overflow, we need to queue a
        !          1554:                     // DLC.STATISTICS command.
        !          1555:                     //
        !          1556: 
        !          1557:                     NdisReadRegisterUshort(&
        !          1558:                             ((PARB_RING_STATUS_CHANGE)Adapter->ArbAddress)->
        !          1559:                             NetworkStatus, &TmpUshort);
        !          1560: 
        !          1561:                     if (IBMSHORT_TO_USHORT(TmpUshort) & 0x0040 ) {
        !          1562:                         //
        !          1563:                         // Build a pending operation.  It will get run ASAP
        !          1564:                         // by ProcessSrbCommand.
        !          1565:                         //
        !          1566: 
        !          1567:                         PIBMTOK_PEND_DATA PendOp;
        !          1568: 
        !          1569:                         if (IBMTOK_ALLOC_PHYS(&PendOp,sizeof(IBMTOK_PEND_DATA)) !=
        !          1570:                             NDIS_STATUS_SUCCESS){
        !          1571: 
        !          1572:                             NdisWriteErrorLogEntry(
        !          1573:                                 Adapter->NdisAdapterHandle,
        !          1574:                                 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1575:                                 2,
        !          1576:                                 handleSrbSsb,
        !          1577:                                 IBMTOK_ERRMSG_ALLOC_MEM
        !          1578:                                 );
        !          1579: 
        !          1580:                             break;
        !          1581: 
        !          1582:                         }
        !          1583: 
        !          1584:                         PendOp->Next = NULL;
        !          1585:                         PendOp->RequestType = NdisRequestGeneric1;
        !          1586:                         PendOp->COMMAND.MAC.ReadLogPending = FALSE;
        !          1587: 
        !          1588:                         if (Adapter->PendQueue == NULL){
        !          1589: 
        !          1590:                             Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          1591: 
        !          1592:                         } else {
        !          1593: 
        !          1594:                             //
        !          1595:                             // Put this operation on the front, so it can
        !          1596:                             // correct the error quickly.
        !          1597:                             //
        !          1598: 
        !          1599:                             PendOp->Next = Adapter->PendQueue;
        !          1600:                             Adapter->PendQueue = PendOp;
        !          1601: 
        !          1602:                         }
        !          1603: 
        !          1604:                         //
        !          1605:                         // It is now in the pend
        !          1606:                         // queue so we should start that up.
        !          1607:                         //
        !          1608: 
        !          1609:                         IbmtokProcessSrbRequests(Adapter);
        !          1610: 
        !          1611:                     }
        !          1612: 
        !          1613:                     break;
        !          1614: 
        !          1615:                 case ARB_CMD_RECEIVED_DATA:
        !          1616: 
        !          1617: #if DBG
        !          1618:                     if (IbmtokDbg) DbgPrint("IBMTOK: Received data\n");
        !          1619: #endif
        !          1620:                     IF_LOG('r');
        !          1621: 
        !          1622:                     if (Adapter->Unplugged && !Adapter->UnpluggedResetInProgress) {
        !          1623: 
        !          1624:                         //
        !          1625:                         // Do, nothing.  This is most likely a stale interrupt.  We
        !          1626:                         // wait until we get a ring status interrupt telling us that
        !          1627:                         // the cable is plugged in.
        !          1628:                         //
        !          1629: 
        !          1630:                         break;
        !          1631: 
        !          1632:                     }
        !          1633: 
        !          1634:                     ReceivedDataArb =
        !          1635:                             (PARB_RECEIVED_DATA)Adapter->ArbAddress;
        !          1636: 
        !          1637:                     NdisReadRegisterUshort(&(ReceivedDataArb->ReceiveBuffer), &ReceiveBufferPointer);
        !          1638: 
        !          1639:                     //
        !          1640:                     // Prepare for indication.
        !          1641:                     //
        !          1642: 
        !          1643:                     Adapter->IndicatedReceiveBuffer = ReceiveBufferPointer;
        !          1644: 
        !          1645:                     ReceiveBuffer = (PRECEIVE_BUFFER)
        !          1646:                      ((PUCHAR)SRAM_PTR_TO_PVOID(Adapter, ReceiveBufferPointer) + 2);
        !          1647: 
        !          1648:                     NdisReadRegisterUshort(&(ReceivedDataArb->FrameLength), &PacketSize);
        !          1649: 
        !          1650:                     PacketSize = IBMSHORT_TO_USHORT(PacketSize);
        !          1651: 
        !          1652: 
        !          1653:                     NdisReadRegisterUshort(&(ReceiveBuffer->BufferLength), &LookaheadSize);
        !          1654: 
        !          1655:                     LookaheadSize = IBMSHORT_TO_USHORT(LookaheadSize);
        !          1656: 
        !          1657: 
        !          1658:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1659:                                 ISRA_HIGH_ARB_FREE);
        !          1660: 
        !          1661: #if DBG
        !          1662:                     if (IbmtokDbg) DbgPrint("IBMTOK: indicate len %d, lookahead %d\n",
        !          1663:                                 PacketSize, LookaheadSize);
        !          1664: #endif
        !          1665: 
        !          1666:                     //
        !          1667:                     // Calculate how big the header is for this
        !          1668:                     // packet.
        !          1669:                     //
        !          1670: 
        !          1671:                     FrameData = ReceiveBuffer->FrameData;
        !          1672: 
        !          1673:                     NdisReadRegisterUchar(&FrameData[8], &TmpUchar);
        !          1674: 
        !          1675:                     if (TmpUchar & 0x80) {
        !          1676: 
        !          1677:                         //
        !          1678:                         // Source routing bit is on in source address.
        !          1679:                         //
        !          1680: 
        !          1681:                         NdisReadRegisterUchar(&FrameData[14], &TmpUchar);
        !          1682:                         HeaderLength = (TmpUchar & 0x1f) + 14;
        !          1683: 
        !          1684:                     } else {
        !          1685: 
        !          1686:                         HeaderLength = 14;
        !          1687: 
        !          1688:                     }
        !          1689: 
        !          1690:                     Adapter->IndicatedHeaderLength = (USHORT)HeaderLength;
        !          1691: 
        !          1692:                     Adapter->FramesReceived++;
        !          1693: 
        !          1694:                     NdisDprReleaseSpinLock(&Adapter->Lock);
        !          1695: 
        !          1696:                     //
        !          1697:                     // Call into the filter package to do the
        !          1698:                     // indication.
        !          1699:                     //
        !          1700: 
        !          1701:                     if (LookaheadSize < HeaderLength) {
        !          1702: 
        !          1703:                         //
        !          1704:                         // Must at least have an address
        !          1705:                         //
        !          1706: 
        !          1707:                         if (LookaheadSize >=  TR_LENGTH_OF_ADDRESS) {
        !          1708: 
        !          1709:                             NdisCreateLookaheadBufferFromSharedMemory(
        !          1710:                                 (PVOID)FrameData,
        !          1711:                                 LookaheadSize,
        !          1712:                                 &LookaheadBuffer
        !          1713:                             );
        !          1714: 
        !          1715:                             if (LookaheadBuffer != NULL) {
        !          1716: 
        !          1717:                                 //
        !          1718:                                 // Runt Packet
        !          1719:                                 //
        !          1720: 
        !          1721:                                 TrFilterIndicateReceive(
        !          1722:                                     Adapter->FilterDB,
        !          1723:                                     (NDIS_HANDLE)ReceiveBuffer,         // context
        !          1724:                                     LookaheadBuffer,                    // header
        !          1725:                                     LookaheadSize,                      // header length
        !          1726:                                     NULL,                               // lookahead
        !          1727:                                     0,                                  // lookahead length
        !          1728:                                     0
        !          1729:                                     );
        !          1730: 
        !          1731:                                 NdisDestroyLookaheadBufferFromSharedMemory(
        !          1732:                                     LookaheadBuffer
        !          1733:                                     );
        !          1734: 
        !          1735:                             }
        !          1736: 
        !          1737:                         }
        !          1738: 
        !          1739:                     } else {
        !          1740: 
        !          1741:                         NdisCreateLookaheadBufferFromSharedMemory(
        !          1742:                             (PVOID)FrameData,
        !          1743:                             LookaheadSize,
        !          1744:                             &LookaheadBuffer
        !          1745:                         );
        !          1746: 
        !          1747:                         if (LookaheadBuffer != NULL) {
        !          1748: 
        !          1749:                             TrFilterIndicateReceive(
        !          1750:                                 Adapter->FilterDB,
        !          1751:                                 (NDIS_HANDLE)ReceiveBuffer,         // context
        !          1752:                                 LookaheadBuffer,                    // header
        !          1753:                                 HeaderLength,                       // header length
        !          1754:                                 LookaheadBuffer + HeaderLength,     // lookahead
        !          1755:                                 LookaheadSize - HeaderLength,       // lookahead length
        !          1756:                                 PacketSize - HeaderLength
        !          1757:                                 );
        !          1758: 
        !          1759:                             NdisDestroyLookaheadBufferFromSharedMemory(
        !          1760:                                 LookaheadBuffer
        !          1761:                                 );
        !          1762: 
        !          1763:                         }
        !          1764: 
        !          1765:                     }
        !          1766: 
        !          1767:                     TrFilterIndicateReceiveComplete( Adapter->FilterDB );
        !          1768: 
        !          1769:                     //
        !          1770:                     // Now worry about the ASB.
        !          1771:                     //
        !          1772: 
        !          1773:                     NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          1774: 
        !          1775:                     //
        !          1776:                     // Set response in ASB, if possible, else queue the response
        !          1777:                     //
        !          1778: 
        !          1779:                     if (Adapter->AsbAvailable){
        !          1780: 
        !          1781:                         Adapter->AsbAvailable = FALSE;
        !          1782: 
        !          1783:                         Adapter->UseNextAsbForReceive = FALSE;
        !          1784: 
        !          1785:                         SetupReceivedDataAsb(Adapter, ReceiveBufferPointer);
        !          1786:                         WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1787:                            ISRA_HIGH_RESPONSE_IN_ASB);
        !          1788: 
        !          1789:                         //
        !          1790:                         // LOOPBACK HERE!!
        !          1791:                         //
        !          1792: 
        !          1793:                     } else {
        !          1794: 
        !          1795: #if DBG
        !          1796:     if (IbmtokDbg)   DbgPrint("W_ASB R\n");
        !          1797: #endif
        !          1798: 
        !          1799:                         if (Adapter->ReceiveWaitingForAsbEnd == (USHORT)(-1)){
        !          1800: 
        !          1801:                             Adapter->ReceiveWaitingForAsbList = ReceiveBufferPointer;
        !          1802: 
        !          1803:                         } else {
        !          1804: 
        !          1805:                             PVOID PEnd;
        !          1806: 
        !          1807:                             PEnd = SRAM_PTR_TO_PVOID(
        !          1808:                                        Adapter,
        !          1809:                                        Adapter->ReceiveWaitingForAsbEnd
        !          1810:                                        );
        !          1811: 
        !          1812:                             NdisWriteRegisterUshort(PEnd, ReceiveBufferPointer);
        !          1813: 
        !          1814:                         }
        !          1815: 
        !          1816:                         Adapter->ReceiveWaitingForAsbEnd = ReceiveBufferPointer;
        !          1817: 
        !          1818:                         if (!(Adapter->OutstandingAsbFreeRequest)){
        !          1819: 
        !          1820:                             Adapter->OutstandingAsbFreeRequest = TRUE;
        !          1821: 
        !          1822:                             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1823:                                                    ISRA_HIGH_ASB_FREE_REQUEST);
        !          1824: 
        !          1825:                             IF_LOG('a');
        !          1826: 
        !          1827:                         }
        !          1828: 
        !          1829:                     }
        !          1830: 
        !          1831:                     break;
        !          1832: 
        !          1833:                 case ARB_CMD_RING_STATUS_CHANGE:
        !          1834: 
        !          1835:                     {
        !          1836:                         USHORT RingStatus;
        !          1837:                         NDIS_STATUS NotifyStatus = 0;
        !          1838: 
        !          1839:                         NdisReadRegisterUshort(&
        !          1840:                   ((PARB_RING_STATUS_CHANGE)Adapter->ArbAddress)->NetworkStatus,
        !          1841:                                                 &RingStatus);
        !          1842: 
        !          1843:                         RingStatus = IBMSHORT_TO_USHORT(RingStatus);
        !          1844: 
        !          1845: #if DBG
        !          1846:                         if (IbmtokDbg)
        !          1847:                         DbgPrint("IBMTOK: Ring Status %x\n", RingStatus);
        !          1848: #endif
        !          1849: 
        !          1850: 
        !          1851:                         WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1852:                                     ISRA_HIGH_ARB_FREE);
        !          1853: 
        !          1854:                         //
        !          1855:                         // If it is a counter overflow, we need to queue a
        !          1856:                         // DIR.READ.LOG command.
        !          1857:                         //
        !          1858: 
        !          1859:                         if (RingStatus & 0x0080) {
        !          1860: 
        !          1861:                             //
        !          1862:                             // Build a pending operation.  It will get run ASAP
        !          1863:                             // by ProcessSrbCommand.
        !          1864:                             //
        !          1865: 
        !          1866:                             PIBMTOK_PEND_DATA PendOp;
        !          1867: 
        !          1868:                             if (IBMTOK_ALLOC_PHYS(&PendOp,sizeof(IBMTOK_PEND_DATA)) !=
        !          1869:                                 NDIS_STATUS_SUCCESS){
        !          1870: 
        !          1871:                                 NdisWriteErrorLogEntry(
        !          1872:                                     Adapter->NdisAdapterHandle,
        !          1873:                                     NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1874:                                     2,
        !          1875:                                     handleSrbSsb,
        !          1876:                                     IBMTOK_ERRMSG_ALLOC_MEM
        !          1877:                                     );
        !          1878: 
        !          1879:                                 break;
        !          1880: 
        !          1881:                             }
        !          1882: 
        !          1883:                             PendOp->Next = NULL;
        !          1884:                             PendOp->RequestType = NdisRequestGeneric1;
        !          1885:                             PendOp->COMMAND.MAC.ReadLogPending = TRUE;
        !          1886: 
        !          1887:                             if (Adapter->PendQueue == NULL){
        !          1888: 
        !          1889:                                 Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          1890: 
        !          1891:                             } else {
        !          1892: 
        !          1893:                                 //
        !          1894:                                 // Put this operation on the front, so it can
        !          1895:                                 // correct the error quickly.
        !          1896:                                 //
        !          1897: 
        !          1898:                                 PendOp->Next = Adapter->PendQueue;
        !          1899:                                 Adapter->PendQueue = PendOp;
        !          1900: 
        !          1901:                             }
        !          1902: 
        !          1903:                             //
        !          1904:                             // It is now in the pend
        !          1905:                             // queue so we should start that up.
        !          1906:                             // Returns with lock released
        !          1907:                             //
        !          1908: 
        !          1909:                             IbmtokProcessSrbRequests(Adapter);
        !          1910: 
        !          1911:                         }
        !          1912: 
        !          1913:                         if (RingStatus & 0x0020) { // Ring Recovery
        !          1914:                             NotifyStatus |= NDIS_RING_RING_RECOVERY;
        !          1915:                         }
        !          1916: 
        !          1917:                         if (RingStatus & 0x0040) { // Single Station
        !          1918:                             NotifyStatus |= NDIS_RING_SINGLE_STATION;
        !          1919:                         }
        !          1920: 
        !          1921:                         if (RingStatus & 0x0080) { // Counter Overflow
        !          1922:                             NotifyStatus |= NDIS_RING_COUNTER_OVERFLOW;
        !          1923:                         }
        !          1924: 
        !          1925:                         if (RingStatus & 0x0100) { // Remove received
        !          1926:                             NotifyStatus |= NDIS_RING_REMOVE_RECEIVED;
        !          1927:                         }
        !          1928: 
        !          1929:                         if (RingStatus & 0x0400) { // Auto-removal
        !          1930:                             NotifyStatus |= NDIS_RING_AUTO_REMOVAL_ERROR;
        !          1931:                         }
        !          1932: 
        !          1933:                         if (RingStatus & 0x0800) { // Lobe wire fault
        !          1934:                             NotifyStatus |= NDIS_RING_LOBE_WIRE_FAULT;
        !          1935:                         }
        !          1936: 
        !          1937:                         if (RingStatus & 0x1000) { // Transmit Beacon
        !          1938:                             NotifyStatus |= NDIS_RING_TRANSMIT_BEACON;
        !          1939:                         }
        !          1940: 
        !          1941:                         if (RingStatus & 0x2000) { // Soft error
        !          1942:                             NotifyStatus |= NDIS_RING_SOFT_ERROR;
        !          1943:                         }
        !          1944: 
        !          1945:                         if (RingStatus & 0x4000) { // Hard error
        !          1946:                             NotifyStatus |= NDIS_RING_HARD_ERROR;
        !          1947:                         }
        !          1948: 
        !          1949:                         if (RingStatus & 0x8000) { // Signal loss
        !          1950:                             NotifyStatus |= NDIS_RING_SIGNAL_LOSS;
        !          1951:                         }
        !          1952: 
        !          1953:                         if (NotifyStatus != 0) {
        !          1954: 
        !          1955:                             PLIST_ENTRY CurrentLink;
        !          1956:                             PIBMTOK_OPEN TempOpen;
        !          1957: 
        !          1958:                             //
        !          1959:                             // Indicate Status to all opens
        !          1960:                             //
        !          1961: 
        !          1962:                             CurrentLink = Adapter->OpenBindings.Flink;
        !          1963: 
        !          1964:                             while (CurrentLink != &(Adapter->OpenBindings)){
        !          1965: 
        !          1966:                                 TempOpen = CONTAINING_RECORD(
        !          1967:                                                      CurrentLink,
        !          1968:                                                      IBMTOK_OPEN,
        !          1969:                                                      OpenList
        !          1970:                                                      );
        !          1971: 
        !          1972:                                 TempOpen->References++;
        !          1973: 
        !          1974:                                 NdisDprReleaseSpinLock(&Adapter->Lock);
        !          1975: 
        !          1976:                                 NdisIndicateStatus(TempOpen->NdisBindingContext,
        !          1977:                                                    NDIS_STATUS_RING_STATUS,
        !          1978:                                                    (PVOID)&NotifyStatus,
        !          1979:                                                    sizeof(NotifyStatus)
        !          1980:                                                   );
        !          1981: 
        !          1982:                                 NdisIndicateStatusComplete(TempOpen->NdisBindingContext);
        !          1983: 
        !          1984:                                 NdisDprAcquireSpinLock(&Adapter->Lock);
        !          1985: 
        !          1986:                                 CurrentLink = CurrentLink->Flink;
        !          1987: 
        !          1988:                                 TempOpen->References--;
        !          1989: 
        !          1990:                             }
        !          1991: 
        !          1992:                             Adapter->LastNotifyStatus = NotifyStatus;
        !          1993: 
        !          1994:                         }
        !          1995: 
        !          1996:                         //
        !          1997:                         // Handle a cable being unplugged
        !          1998:                         //
        !          1999: 
        !          2000:                         if ((RingStatus & 0x5000) == 0x5000) {  // receive and transmit beacon
        !          2001: 
        !          2002:                             //
        !          2003:                             // Ok, the cable has been unplugged.  We now abort all
        !          2004:                             // outstanding sends, etc.
        !          2005:                             //
        !          2006: 
        !          2007:                             Adapter->Unplugged = TRUE;
        !          2008: 
        !          2009:                             IbmtokAbortPending(Adapter, NDIS_STATUS_DEVICE_FAILED);
        !          2010: 
        !          2011:                             if ((RingStatus & 0x800) == 0x800) {
        !          2012:                                 Adapter->LobeWireFaultIndicated = TRUE;
        !          2013:                             }
        !          2014: 
        !          2015:                         } else if ((RingStatus & 0x0020)  &&
        !          2016:                                    !(RingStatus & 0x4000) &&
        !          2017:                                    (Adapter->Unplugged) &&
        !          2018:                                    (!Adapter->UnpluggedResetInProgress)) {
        !          2019: 
        !          2020:                             //
        !          2021:                             // Reset the adapter to remove all stale information
        !          2022:                             //
        !          2023: 
        !          2024:                             Adapter->UnpluggedResetInProgress = TRUE;
        !          2025: 
        !          2026:                             IbmtokSetupForReset(Adapter, NULL);
        !          2027: 
        !          2028:                             IbmtokHandleDeferred(Adapter);
        !          2029: 
        !          2030:                         }
        !          2031: 
        !          2032:                     }
        !          2033: 
        !          2034:                     break;
        !          2035: 
        !          2036:                 case ARB_CMD_TRANSMIT_DATA_REQUEST:
        !          2037: 
        !          2038: #if DBG
        !          2039:                     if (IbmtokDbg) DbgPrint("IBMTOK: Transmit data\n");
        !          2040: #endif
        !          2041: 
        !          2042:                     if (Adapter->Unplugged && !Adapter->UnpluggedResetInProgress) {
        !          2043: 
        !          2044:                         //
        !          2045:                         // Do, nothing.  This is most likely a stale interrupt.  We
        !          2046:                         // wait until we get a ring status interrupt telling us that
        !          2047:                         // the cable is plugged in.
        !          2048:                         //
        !          2049: 
        !          2050:                         break;
        !          2051: 
        !          2052:                     }
        !          2053: 
        !          2054:                     TransmitDataArb =
        !          2055:                             (PARB_TRANSMIT_DATA_REQUEST)Adapter->ArbAddress;
        !          2056: 
        !          2057:                     //
        !          2058:                     // First see if we have to assign the command correlator.
        !          2059:                     //
        !          2060: 
        !          2061:                     NdisReadRegisterUchar(&(TransmitDataArb->CommandCorrelator), &TmpUchar);
        !          2062: 
        !          2063:                     TransmitPacket = FindPacketGivenCorrelator(Adapter, TmpUchar);
        !          2064: 
        !          2065:                     if (TransmitPacket == NULL) {
        !          2066: 
        !          2067:                         BOOLEAN PacketRemoved;
        !          2068: 
        !          2069:                         //
        !          2070:                         // Have to take the correlator out of the SRB
        !          2071:                         // ourselves. This means that the SRB must still
        !          2072:                         // be occupied by the request for this transmit.
        !          2073:                         //
        !          2074: 
        !          2075:                         ASSERT((!Adapter->SrbAvailable) &&
        !          2076:                             (Adapter->TransmittingPacket != (PNDIS_PACKET)NULL));
        !          2077: 
        !          2078:                         FreedSrb = FALSE;
        !          2079: 
        !          2080:                         //
        !          2081:                         // This call will remove the packet from the SRB.
        !          2082:                         //
        !          2083: 
        !          2084:                         TransmitPacket =
        !          2085:                                 RemoveTransmitFromSrb(Adapter, &PacketRemoved);
        !          2086: 
        !          2087:                         //
        !          2088:                         // This will be NULL if there was an error in
        !          2089:                         // the transmit command, but in that case why
        !          2090:                         // are we getting this ARB request??  Just exit.
        !          2091:                         // The WakeUpDpc will reset the card if it is hosed.
        !          2092:                         //
        !          2093: 
        !          2094:                         if ((TransmitPacket == (PNDIS_PACKET)NULL) || !PacketRemoved) {
        !          2095: 
        !          2096:                             break;
        !          2097: 
        !          2098:                         }
        !          2099: 
        !          2100:                     } else {
        !          2101: 
        !          2102:                         FreedSrb = FALSE;
        !          2103: 
        !          2104:                         Reserved =
        !          2105:                             PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          2106: 
        !          2107:                     }
        !          2108: 
        !          2109:                     NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          2110: 
        !          2111:                     //
        !          2112:                     // Fill in the AC and FC bytes.
        !          2113:                     //
        !          2114: 
        !          2115:                     NdisReadRegisterUshort(&(TransmitDataArb->DhbPointer), &TmpUshort);
        !          2116: 
        !          2117:                     DhbAddress = (PUCHAR)SRAM_PTR_TO_PVOID(Adapter,TmpUshort);
        !          2118: 
        !          2119:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2120:                                 ISRA_HIGH_ARB_FREE);
        !          2121: 
        !          2122: 
        !          2123:                     //
        !          2124:                     // Now copy the data down from TransmitPacket.
        !          2125:                     //
        !          2126: 
        !          2127:                     NdisQueryPacket(
        !          2128:                         TransmitPacket,
        !          2129:                         NULL,
        !          2130:                         NULL,
        !          2131:                         NULL,
        !          2132:                         &PacketLength
        !          2133:                         );
        !          2134: 
        !          2135:                     IbmtokCopyFromPacketToBuffer(
        !          2136:                         TransmitPacket,
        !          2137:                         0,
        !          2138:                         PacketLength,
        !          2139:                         (PCHAR)DhbAddress,
        !          2140:                         &DummyBytesCopied
        !          2141:                         );
        !          2142: 
        !          2143: 
        !          2144:                     //
        !          2145:                     // Now worry about the ASB.
        !          2146:                     //
        !          2147: 
        !          2148:                     NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          2149: 
        !          2150:                     IF_LOG('c');
        !          2151: 
        !          2152:                     //
        !          2153:                     // Set response in ASB, if available, else queue response
        !          2154:                     //
        !          2155: 
        !          2156:                     if (Adapter->AsbAvailable){
        !          2157: 
        !          2158:                         Adapter->AsbAvailable = FALSE;
        !          2159: 
        !          2160:                         Adapter->UseNextAsbForReceive = TRUE;
        !          2161: 
        !          2162:                         SetupTransmitStatusAsb(Adapter, TransmitPacket);
        !          2163:                         WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2164:                            ISRA_HIGH_RESPONSE_IN_ASB);
        !          2165: 
        !          2166:                         //
        !          2167:                         // LOOPBACK HERE!!
        !          2168:                         //
        !          2169: 
        !          2170:                     } else {
        !          2171: 
        !          2172: #if DBG
        !          2173:     if (IbmtokDbg)  DbgPrint("W_ASB T\n");
        !          2174: #endif
        !          2175: 
        !          2176:                         PutPacketOnWaitingForAsb(Adapter, TransmitPacket);
        !          2177: 
        !          2178:                         if (!(Adapter->OutstandingAsbFreeRequest)){
        !          2179: 
        !          2180:                             Adapter->OutstandingAsbFreeRequest = TRUE;
        !          2181: 
        !          2182:                             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2183:                                                    ISRA_HIGH_ASB_FREE_REQUEST);
        !          2184: 
        !          2185:                             IF_LOG('a');
        !          2186:                         }
        !          2187: 
        !          2188:                         //
        !          2189:                         // FINAL RETURNCODE CHECK HERE!
        !          2190:                         //
        !          2191: 
        !          2192:                     }
        !          2193: 
        !          2194: 
        !          2195:                     //
        !          2196:                     // If we freed up the SRB, queue the next command
        !          2197:                     // if there is one.
        !          2198:                     // Returns with lock released
        !          2199:                     //
        !          2200: 
        !          2201:                     if (FreedSrb) {
        !          2202: 
        !          2203:                         IbmtokProcessSrbRequests(Adapter);
        !          2204: 
        !          2205:                     }
        !          2206: 
        !          2207:                     break;
        !          2208: 
        !          2209:                 default:
        !          2210: 
        !          2211:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2212:                                 ISRA_HIGH_ARB_FREE);
        !          2213:                     break;
        !          2214: 
        !          2215:             }
        !          2216: 
        !          2217:         }
        !          2218: 
        !          2219:         if (IsrpHigh & ISRP_HIGH_ASB_FREE) {
        !          2220:             BOOLEAN ReceiveNeedsAsb = FALSE;
        !          2221:             BOOLEAN TransmitNeedsAsb = FALSE;
        !          2222: 
        !          2223:             //
        !          2224:             // Check whether we have stuff to do.
        !          2225:             //
        !          2226: 
        !          2227:             IF_LOG('A');
        !          2228: 
        !          2229:             if (Adapter->Unplugged && !Adapter->UnpluggedResetInProgress) {
        !          2230: 
        !          2231:                 //
        !          2232:                 // Do, nothing.  This is most likely a stale interrupt.  We
        !          2233:                 // wait until we get a ring status interrupt telling us that
        !          2234:                 // the cable is plugged in.
        !          2235:                 //
        !          2236: 
        !          2237:                 break;
        !          2238: 
        !          2239:             }
        !          2240: 
        !          2241:             ASSERT(Adapter->AsbAvailable == FALSE);
        !          2242: 
        !          2243:             ASSERT(Adapter->OutstandingAsbFreeRequest == TRUE);
        !          2244: 
        !          2245:             if (Adapter->ReceiveWaitingForAsbList != (USHORT)-1) {
        !          2246: 
        !          2247:                 ReceiveNeedsAsb = TRUE;
        !          2248: 
        !          2249:             }
        !          2250: 
        !          2251:             if (Adapter->FirstWaitingForAsb != NULL) {
        !          2252: 
        !          2253:                 TransmitNeedsAsb = TRUE;
        !          2254: 
        !          2255:             }
        !          2256: 
        !          2257:             if (ReceiveNeedsAsb &&
        !          2258:                     (!TransmitNeedsAsb || Adapter->UseNextAsbForReceive)) {
        !          2259: 
        !          2260:                 SRAM_PTR ReceiveBufferPointer;
        !          2261:                 PVOID PFront;
        !          2262: 
        !          2263: #if DBG
        !          2264:     if (IbmtokDbg) DbgPrint("ASB R\n");
        !          2265: #endif
        !          2266:                 IF_LOG('R');
        !          2267: 
        !          2268:                 //
        !          2269:                 // Save ReceiveWaitingForAsb so we can release
        !          2270:                 // the spinlock.
        !          2271:                 //
        !          2272: 
        !          2273:                 ReceiveBufferPointer = Adapter->ReceiveWaitingForAsbList;
        !          2274: 
        !          2275: 
        !          2276:                 if (Adapter->ReceiveWaitingForAsbList == Adapter->ReceiveWaitingForAsbEnd){
        !          2277: 
        !          2278:                     Adapter->ReceiveWaitingForAsbList = (USHORT)-1;
        !          2279: 
        !          2280:                     Adapter->ReceiveWaitingForAsbEnd = (USHORT)-1;
        !          2281: 
        !          2282:                 } else {
        !          2283: 
        !          2284:                     PFront = SRAM_PTR_TO_PVOID(Adapter,ReceiveBufferPointer);
        !          2285: 
        !          2286:                     NdisReadRegisterUshort(((PUSHORT)PFront),
        !          2287:                                            &(Adapter->ReceiveWaitingForAsbList)
        !          2288:                                           );
        !          2289: 
        !          2290:                 }
        !          2291: 
        !          2292:                 Adapter->AsbAvailable = FALSE;
        !          2293: 
        !          2294:                 Adapter->UseNextAsbForReceive = FALSE;
        !          2295: 
        !          2296:                 //
        !          2297:                 // Fill in the ASB and submit it.
        !          2298:                 //
        !          2299: 
        !          2300:                 SetupReceivedDataAsb(Adapter, ReceiveBufferPointer);
        !          2301: 
        !          2302:                 if (TransmitNeedsAsb){
        !          2303:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2304:                            ISRA_HIGH_RESPONSE_IN_ASB | ISRA_HIGH_ASB_FREE_REQUEST);
        !          2305:                 } else {
        !          2306:                     Adapter->OutstandingAsbFreeRequest = FALSE;
        !          2307:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2308:                                            ISRA_HIGH_RESPONSE_IN_ASB);
        !          2309:                 }
        !          2310: 
        !          2311:             } else if (TransmitNeedsAsb) {
        !          2312: 
        !          2313:                 PNDIS_PACKET AsbPacket = Adapter->FirstWaitingForAsb;
        !          2314:                 PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(AsbPacket);
        !          2315: 
        !          2316: #if DBG
        !          2317:     if (IbmtokDbg) DbgPrint("ASB T\n");
        !          2318: #endif
        !          2319:                 IF_LOG('T');
        !          2320: 
        !          2321:                 //
        !          2322:                 // Take the packet off of WaitingForAsb;
        !          2323:                 //
        !          2324: 
        !          2325:                 Adapter->FirstWaitingForAsb = Reserved->Next;
        !          2326: 
        !          2327:                 Adapter->AsbAvailable = FALSE;
        !          2328: 
        !          2329:                 Adapter->UseNextAsbForReceive = TRUE;
        !          2330: 
        !          2331:                 //
        !          2332:                 // Now fill in the ASB and fire it off.
        !          2333:                 //
        !          2334: 
        !          2335: 
        !          2336:                 SetupTransmitStatusAsb(Adapter, AsbPacket);
        !          2337: 
        !          2338:                 if (ReceiveNeedsAsb || (Adapter->FirstWaitingForAsb != NULL)){
        !          2339:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2340:                            ISRA_HIGH_RESPONSE_IN_ASB | ISRA_HIGH_ASB_FREE_REQUEST);
        !          2341:                 } else {
        !          2342:                     Adapter->OutstandingAsbFreeRequest = FALSE;
        !          2343:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2344:                                            ISRA_HIGH_RESPONSE_IN_ASB);
        !          2345:                 }
        !          2346: 
        !          2347:                 //
        !          2348:                 // LOOPBACK HERE!!
        !          2349:                 //
        !          2350: 
        !          2351:             } else {
        !          2352: 
        !          2353: #if DBG
        !          2354:     if (IbmtokDbg) DbgPrint("ASB -\n");
        !          2355: #endif
        !          2356: 
        !          2357:                 Adapter->AsbAvailable = TRUE;
        !          2358: 
        !          2359:             }
        !          2360: 
        !          2361:         }
        !          2362: 
        !          2363:         GET_ARB_ASB_BITS(Adapter, &IsrpHigh);
        !          2364: 
        !          2365:     }
        !          2366: 
        !          2367:     Adapter->HandleArbRunning = FALSE;
        !          2368: 
        !          2369:     IF_LOG('J');
        !          2370: 
        !          2371:     //
        !          2372:     // This macro assumes it is called with the lock held,
        !          2373:     // and releases it.
        !          2374:     //
        !          2375:     IBMTOK_DO_DEFERRED(Adapter);
        !          2376: 
        !          2377: }
        !          2378: 
        !          2379: STATIC
        !          2380: VOID
        !          2381: CleanupResetFailure(
        !          2382:     IN PIBMTOK_ADAPTER Adapter,
        !          2383:     PNDIS_STATUS IndicateStatus,
        !          2384:     IN ULONG FailureCode,
        !          2385:     IN ULONG ResetStage
        !          2386:     )
        !          2387: 
        !          2388: /*++
        !          2389: 
        !          2390: Routine Description:
        !          2391: 
        !          2392:     Clean up if a reset fails partway through. Called
        !          2393:     from HandleResetStaging.
        !          2394: 
        !          2395:     Called with the lock held and returns with it held.
        !          2396: 
        !          2397: Arguments:
        !          2398: 
        !          2399:     Adapter - The adapter that the reset is for.
        !          2400: 
        !          2401:     IndicateStatus - Status to indicate to the protocols, or NULL.
        !          2402: 
        !          2403:     FailureCode - A code to include in the error log.
        !          2404: 
        !          2405:     ResetStage - The stage of the reset where the failure occured.
        !          2406: 
        !          2407: Return Value:
        !          2408: 
        !          2409:     None.
        !          2410: 
        !          2411: --*/
        !          2412: 
        !          2413: {
        !          2414: 
        !          2415:     PLIST_ENTRY CurrentLink;
        !          2416:     PIBMTOK_OPEN TempOpen;
        !          2417: 
        !          2418:     if (!Adapter->UnpluggedResetInProgress) {
        !          2419: 
        !          2420:         //
        !          2421:         // signal failure....
        !          2422:         //
        !          2423:         Adapter->CurrentRingState = NdisRingStateRingFailure;
        !          2424: 
        !          2425:         //
        !          2426:         // Indicate Status to all opens
        !          2427:         //
        !          2428: 
        !          2429:         CurrentLink = Adapter->OpenBindings.Flink;
        !          2430: 
        !          2431:         while (CurrentLink != &(Adapter->OpenBindings)){
        !          2432: 
        !          2433:             TempOpen = CONTAINING_RECORD(
        !          2434:                                  CurrentLink,
        !          2435:                                  IBMTOK_OPEN,
        !          2436:                                  OpenList
        !          2437:                                  );
        !          2438: 
        !          2439:             TempOpen->References++;
        !          2440: 
        !          2441:             NdisReleaseSpinLock(&Adapter->Lock);
        !          2442: 
        !          2443:             if (IndicateStatus) {
        !          2444:                 NdisIndicateStatus(TempOpen->NdisBindingContext,
        !          2445:                                    NDIS_STATUS_CLOSED,
        !          2446:                                    IndicateStatus,
        !          2447:                                    sizeof(NDIS_STATUS)
        !          2448:                                   );
        !          2449:             } else {
        !          2450:                 NdisIndicateStatus(TempOpen->NdisBindingContext,
        !          2451:                                    NDIS_STATUS_CLOSED,
        !          2452:                                    NULL,
        !          2453:                                    0
        !          2454:                                   );
        !          2455:             }
        !          2456: 
        !          2457:             NdisIndicateStatusComplete(TempOpen->NdisBindingContext);
        !          2458: 
        !          2459:             NdisAcquireSpinLock(&Adapter->Lock);
        !          2460: 
        !          2461:             CurrentLink = CurrentLink->Flink;
        !          2462: 
        !          2463:             TempOpen->References--;
        !          2464: 
        !          2465:         }
        !          2466: 
        !          2467:         NdisWriteErrorLogEntry(
        !          2468:             Adapter->NdisAdapterHandle,
        !          2469:             NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !          2470:             4,
        !          2471:             handleResetStaging,
        !          2472:             IBMTOK_ERRMSG_BRINGUP_FAILURE,
        !          2473:             FailureCode,
        !          2474:             ResetStage
        !          2475:             );
        !          2476: 
        !          2477:     } else {
        !          2478: 
        !          2479:         //
        !          2480:         // Set this to false, we will try again later.
        !          2481:         //
        !          2482: 
        !          2483:         Adapter->LobeWireFaultIndicated = TRUE;
        !          2484:         Adapter->UnpluggedResetInProgress = FALSE;
        !          2485: 
        !          2486:     }
        !          2487: 
        !          2488:     //
        !          2489:     // Set Abort
        !          2490:     //
        !          2491: 
        !          2492:     Adapter->CurrentResetStage = 4;
        !          2493: 
        !          2494:     SetResetVariables(Adapter);
        !          2495: 
        !          2496:     Adapter->OpenInProgress = FALSE;
        !          2497:     Adapter->NotAcceptingRequests = TRUE;
        !          2498: 
        !          2499:     Adapter->ResetInProgress = FALSE;
        !          2500:     Adapter->ResetInterruptAllowed = FALSE;
        !          2501:     Adapter->ResetInterruptHasArrived = FALSE;
        !          2502: 
        !          2503:     if (Adapter->ResettingOpen != NULL) {
        !          2504: 
        !          2505:         PIBMTOK_OPEN Open = Adapter->ResettingOpen;
        !          2506: 
        !          2507:         //
        !          2508:         // Decrement the reference count that was incremented
        !          2509:         // in SetupForReset.
        !          2510:         //
        !          2511: 
        !          2512:         Open->References--;
        !          2513: 
        !          2514:         NdisReleaseSpinLock(&Adapter->Lock);
        !          2515: 
        !          2516:         NdisCompleteReset(
        !          2517:           Open->NdisBindingContext,
        !          2518:           NDIS_STATUS_FAILURE
        !          2519:           );
        !          2520: 
        !          2521:         NdisAcquireSpinLock(&Adapter->Lock);
        !          2522: 
        !          2523:     }
        !          2524: 
        !          2525: }
        !          2526: 
        !          2527: STATIC
        !          2528: VOID
        !          2529: HandleResetStaging(
        !          2530:     IN PIBMTOK_ADAPTER Adapter
        !          2531:     )
        !          2532: 
        !          2533: /*++
        !          2534: 
        !          2535: Routine Description:
        !          2536: 
        !          2537:     Handles the next stage of the transmit interrupt,
        !          2538:     knowing that an SRB interrupt just came through.
        !          2539: 
        !          2540:     Called with the lock held and returns with it held.
        !          2541: 
        !          2542: Arguments:
        !          2543: 
        !          2544:     Adapter - The adapter that the reset is for.
        !          2545: 
        !          2546: Return Value:
        !          2547: 
        !          2548:     None.
        !          2549: 
        !          2550: --*/
        !          2551: 
        !          2552: {
        !          2553:     USHORT TmpUshort;
        !          2554: #if DBG
        !          2555:     UCHAR TmpUchar;
        !          2556: #endif
        !          2557: 
        !          2558:     switch (Adapter->CurrentResetStage) {
        !          2559: 
        !          2560:         case 1: {
        !          2561: 
        !          2562:             //
        !          2563:             // The adapter just finished being reset.
        !          2564:             //
        !          2565: 
        !          2566:             USHORT WrbOffset;
        !          2567:             PSRB_BRING_UP_RESULT BringUpSrb;
        !          2568:             PSRB_OPEN_ADAPTER OpenSrb;
        !          2569:             UCHAR Value1, Value2;
        !          2570: 
        !          2571: #if DBG
        !          2572: if (IbmtokDbg) DbgPrint("IBMTOK: RESET done\n");
        !          2573: #endif
        !          2574: 
        !          2575:             READ_ADAPTER_REGISTER(Adapter, WRBR_LOW, &Value1);
        !          2576:             READ_ADAPTER_REGISTER(Adapter, WRBR_HIGH, &Value2);
        !          2577: 
        !          2578:             WrbOffset = (USHORT)
        !          2579:                         (((USHORT)Value1) << 8) +
        !          2580:                         (USHORT)Value2;
        !          2581: 
        !          2582:             Adapter->InitialWrbOffset = WrbOffset;
        !          2583: 
        !          2584:             BringUpSrb = (PSRB_BRING_UP_RESULT)
        !          2585:                                     (Adapter->SharedRam + WrbOffset);
        !          2586: 
        !          2587:             NdisReadRegisterUshort(&(BringUpSrb->ReturnCode), &TmpUshort);
        !          2588: 
        !          2589:             if (TmpUshort != 0x0000) {
        !          2590: 
        !          2591:                 CleanupResetFailure (Adapter, NULL, TmpUshort, 1);
        !          2592:                 break;
        !          2593: 
        !          2594:             }
        !          2595: 
        !          2596:             //
        !          2597:             // Now set up the open SRB request.
        !          2598:             //
        !          2599: 
        !          2600:             OpenSrb = (PSRB_OPEN_ADAPTER)
        !          2601:                 (Adapter->SharedRam + Adapter->InitialWrbOffset);
        !          2602: 
        !          2603:             IBMTOK_ZERO_MAPPED_MEMORY(OpenSrb, sizeof(SRB_OPEN_ADAPTER));
        !          2604: 
        !          2605:             NdisWriteRegisterUchar(&(OpenSrb->Command), SRB_CMD_OPEN_ADAPTER);
        !          2606:             NdisWriteRegisterUshort(&(OpenSrb->OpenOptions), OPEN_CONTENDER);
        !          2607: 
        !          2608:             NdisMoveToMappedMemory((PCHAR)OpenSrb->NodeAddress,
        !          2609:                                    Adapter->NetworkAddress,
        !          2610:                                    TR_LENGTH_OF_ADDRESS
        !          2611:                                    );
        !          2612: 
        !          2613:             WRITE_IBMSHORT(OpenSrb->ReceiveBufferNum,
        !          2614:                                         Adapter->NumberOfReceiveBuffers);
        !          2615:             WRITE_IBMSHORT(OpenSrb->ReceiveBufferLen,
        !          2616:                                         Adapter->ReceiveBufferLength);
        !          2617: 
        !          2618:             WRITE_IBMSHORT(OpenSrb->TransmitBufferLen,
        !          2619:                                         Adapter->TransmitBufferLength);
        !          2620: 
        !          2621:             NdisWriteRegisterUchar(&(OpenSrb->TransmitBufferNum),
        !          2622:                                    (UCHAR)Adapter->NumberOfTransmitBuffers
        !          2623:                                   );
        !          2624: 
        !          2625:             Adapter->CurrentResetStage = 2;
        !          2626: 
        !          2627:             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2628:                         ISRA_HIGH_COMMAND_IN_SRB | ISRA_HIGH_SRB_FREE_REQUEST);
        !          2629: 
        !          2630:             IF_LOG('1');
        !          2631: 
        !          2632:             break;
        !          2633: 
        !          2634:         }
        !          2635: 
        !          2636:         case 2: {
        !          2637: 
        !          2638:             //
        !          2639:             // Handle the result of the DIR.OPEN.ADAPTER command.
        !          2640:             //
        !          2641: 
        !          2642:             PSRB_OPEN_RESPONSE OpenResponseSrb;
        !          2643:             UCHAR TmpUchar;
        !          2644: 
        !          2645: #if DBG
        !          2646: if (IbmtokDbg) DbgPrint("IBMTOK: OPEN done\n");
        !          2647: #endif
        !          2648: 
        !          2649:             OpenResponseSrb = (PSRB_OPEN_RESPONSE)
        !          2650:                     (Adapter->SharedRam + Adapter->InitialWrbOffset);
        !          2651: 
        !          2652:             NdisReadRegisterUchar(&(OpenResponseSrb->ReturnCode), &TmpUchar);
        !          2653: 
        !          2654:             if (TmpUchar != 0) {
        !          2655: 
        !          2656:                 NDIS_STATUS IndicateStatus;
        !          2657: 
        !          2658:                 NdisReadRegisterUshort(&(OpenResponseSrb->ErrorCode),
        !          2659:                                        &(Adapter->OpenErrorCode));
        !          2660:                 Adapter->OpenErrorCode = IBMSHORT_TO_USHORT(Adapter->OpenErrorCode);
        !          2661:                 IndicateStatus =
        !          2662:                     NDIS_STATUS_TOKEN_RING_OPEN_ERROR |
        !          2663:                     (NDIS_STATUS)(Adapter->OpenErrorCode);
        !          2664: 
        !          2665:                 CleanupResetFailure (Adapter, &IndicateStatus, Adapter->OpenErrorCode, 2);
        !          2666:                 break;
        !          2667: 
        !          2668:             }
        !          2669: 
        !          2670:             IF_LOG('2');
        !          2671: 
        !          2672: #if DBG
        !          2673:             NdisReadRegisterUchar(&(OpenResponseSrb->ReturnCode),&TmpUchar);
        !          2674:             if (IbmtokDbg) DbgPrint("IBMTOK: RESET OPEN, Return code = %x, at %lx\n",
        !          2675:                             TmpUchar,
        !          2676:                             OpenResponseSrb);
        !          2677: #endif
        !          2678: 
        !          2679:             NdisReadRegisterUshort(&(OpenResponseSrb->SrbPointer), &TmpUshort);
        !          2680:             Adapter->SrbAddress = SRAM_PTR_TO_PVOID(Adapter,TmpUshort);
        !          2681: 
        !          2682:             NdisReadRegisterUshort(&(OpenResponseSrb->SsbPointer), &TmpUshort);
        !          2683:             Adapter->SsbAddress = SRAM_PTR_TO_PVOID(Adapter,TmpUshort);
        !          2684: 
        !          2685:             NdisReadRegisterUshort(&(OpenResponseSrb->ArbPointer), &TmpUshort);
        !          2686:             Adapter->ArbAddress = SRAM_PTR_TO_PVOID(Adapter,TmpUshort);
        !          2687: 
        !          2688:             NdisReadRegisterUshort(&(OpenResponseSrb->AsbPointer), &TmpUshort);
        !          2689:             Adapter->AsbAddress = SRAM_PTR_TO_PVOID(Adapter,TmpUshort);
        !          2690: 
        !          2691: #if DBG
        !          2692: if (IbmtokDbg) {
        !          2693:             USHORT TmpUshort1;
        !          2694:             USHORT TmpUshort2;
        !          2695:             USHORT TmpUshort3;
        !          2696:             USHORT TmpUshort4;
        !          2697:                     NdisReadRegisterUshort(&(OpenResponseSrb->SrbPointer), &TmpUshort1);
        !          2698:                     NdisReadRegisterUshort(&(OpenResponseSrb->SsbPointer), &TmpUshort2);
        !          2699:                     NdisReadRegisterUshort(&(OpenResponseSrb->ArbPointer), &TmpUshort3);
        !          2700:                     NdisReadRegisterUshort(&(OpenResponseSrb->AsbPointer), &TmpUshort4);
        !          2701:                     DbgPrint("IBMTOK: Offsets: SRB %x  SSB %x  ARB %x  ASB %x\n",
        !          2702:                                 IBMSHORT_TO_USHORT(TmpUshort1),
        !          2703:                                 IBMSHORT_TO_USHORT(TmpUshort2),
        !          2704:                                 IBMSHORT_TO_USHORT(TmpUshort3),
        !          2705:                                 IBMSHORT_TO_USHORT(TmpUshort4));
        !          2706:     }
        !          2707: #endif
        !          2708: 
        !          2709:             //
        !          2710:             // Now queue a SET.FUNCT.ADDRESS command if needed.
        !          2711:             //
        !          2712: 
        !          2713:             Adapter->CurrentCardFunctional = (TR_FUNCTIONAL_ADDRESS)0;
        !          2714: 
        !          2715:             if (SetAdapterFunctionalAddress(Adapter) == NDIS_STATUS_SUCCESS) {
        !          2716: 
        !          2717:                 //
        !          2718:                 // This means that the command did not have to be
        !          2719:                 // queued, so we are done with this step.
        !          2720:                 //
        !          2721: 
        !          2722:                 if (SetAdapterGroupAddress(Adapter) == NDIS_STATUS_SUCCESS) {
        !          2723: 
        !          2724:                     //
        !          2725:                     // This one did not pend either, we are done.
        !          2726:                     //
        !          2727: 
        !          2728:                     IbmtokFinishAdapterReset(Adapter);
        !          2729: 
        !          2730:                 } else {
        !          2731: 
        !          2732:                     Adapter->CurrentResetStage = 4;
        !          2733: 
        !          2734:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2735:                         ISRA_HIGH_COMMAND_IN_SRB | ISRA_HIGH_SRB_FREE_REQUEST);
        !          2736: 
        !          2737:                 }
        !          2738: 
        !          2739:             } else {
        !          2740: 
        !          2741:                 Adapter->CurrentResetStage = 3;
        !          2742: 
        !          2743:                 WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2744:                         ISRA_HIGH_COMMAND_IN_SRB | ISRA_HIGH_SRB_FREE_REQUEST);
        !          2745: 
        !          2746:             }
        !          2747: 
        !          2748:             break;
        !          2749: 
        !          2750:         }
        !          2751: 
        !          2752:         case 3: {
        !          2753: 
        !          2754:             //
        !          2755:             // The SET.FUNCT.ADDRESS command finished.
        !          2756:             //
        !          2757: 
        !          2758:             PSRB_GENERIC GenericSrb = (PSRB_GENERIC)Adapter->SrbAddress;
        !          2759:             UCHAR ReturnCode;
        !          2760: 
        !          2761:             NdisReadRegisterUchar(&(GenericSrb->ReturnCode), &ReturnCode);
        !          2762: 
        !          2763:             IF_LOG('3');
        !          2764: 
        !          2765: #if DBG
        !          2766: if (IbmtokDbg) DbgPrint("IBMTOK: SET FUNCT done\n");
        !          2767: #endif
        !          2768:             if (ReturnCode == 0x00) {
        !          2769: 
        !          2770:                 if (SetAdapterGroupAddress(Adapter) == NDIS_STATUS_SUCCESS) {
        !          2771: 
        !          2772:                     //
        !          2773:                     // This one did not pend, the dishes are done.
        !          2774:                     //
        !          2775: 
        !          2776:                     IbmtokFinishAdapterReset(Adapter);
        !          2777: 
        !          2778:                 } else {
        !          2779: 
        !          2780:                     Adapter->CurrentResetStage = 4;
        !          2781: 
        !          2782:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          2783:                         ISRA_HIGH_COMMAND_IN_SRB | ISRA_HIGH_SRB_FREE_REQUEST);
        !          2784: 
        !          2785:                 }
        !          2786: 
        !          2787:             } else if (ReturnCode != 0xfe) {
        !          2788: 
        !          2789:                 CleanupResetFailure (Adapter, NULL, (ULONG)ReturnCode, 3);
        !          2790: 
        !          2791:             }
        !          2792: 
        !          2793:             break;
        !          2794: 
        !          2795:         }
        !          2796: 
        !          2797:         case 4: {
        !          2798: 
        !          2799:             //
        !          2800:             // The SET.GROUP.ADDRESS command finished.
        !          2801:             //
        !          2802: 
        !          2803:             PSRB_GENERIC GenericSrb = (PSRB_GENERIC)Adapter->SrbAddress;
        !          2804:             UCHAR ReturnCode;
        !          2805: 
        !          2806:             NdisReadRegisterUchar(&(GenericSrb->ReturnCode), &ReturnCode);
        !          2807: 
        !          2808:             IF_LOG('4');
        !          2809: 
        !          2810: #if DBG
        !          2811: if (IbmtokDbg) DbgPrint("IBMTOK: SET GROUP done\n");
        !          2812: #endif
        !          2813:             if (ReturnCode == 0x00) {
        !          2814: 
        !          2815:                 IbmtokFinishAdapterReset(Adapter);
        !          2816: 
        !          2817:             } else if (ReturnCode != 0xfe) {
        !          2818: 
        !          2819:                 CleanupResetFailure (Adapter, NULL, (ULONG)ReturnCode, 4);
        !          2820: 
        !          2821:             }
        !          2822: 
        !          2823:             break;
        !          2824: 
        !          2825:         }
        !          2826: 
        !          2827:     }
        !          2828: 
        !          2829: }
        !          2830: 
        !          2831: STATIC
        !          2832: PNDIS_PACKET
        !          2833: RemoveTransmitFromSrb(
        !          2834:     IN PIBMTOK_ADAPTER Adapter,
        !          2835:     OUT PBOOLEAN PacketRemoved
        !          2836:     )
        !          2837: 
        !          2838: /*++
        !          2839: 
        !          2840: Routine Description:
        !          2841: 
        !          2842:     Cleans a transmit out of the SRB if one was there.
        !          2843: 
        !          2844:     NOTE : Should be called with the spinlock held!!!
        !          2845: 
        !          2846: Arguments:
        !          2847: 
        !          2848:     Adapter - The adapter that this packet is coming through.
        !          2849: 
        !          2850:     PacketRemoved - TRUE if the packet was removed from the SRB.
        !          2851: 
        !          2852: Return Value:
        !          2853: 
        !          2854:     The packet removed.
        !          2855: 
        !          2856: --*/
        !          2857: 
        !          2858: {
        !          2859:     PNDIS_PACKET TransmitPacket;
        !          2860:     PIBMTOK_RESERVED Reserved;
        !          2861:     UCHAR TmpUchar;
        !          2862:     PSRB_TRANSMIT_DIR_FRAME TransmitSrb =
        !          2863:             (PSRB_TRANSMIT_DIR_FRAME)Adapter->SrbAddress;
        !          2864: 
        !          2865: 
        !          2866:     NdisReadRegisterUchar(&(TransmitSrb->ReturnCode), &TmpUchar);
        !          2867: 
        !          2868:     if (TmpUchar == 0xfe) {
        !          2869: 
        !          2870:         //
        !          2871:         // The TRANSMIT command was just put in the SRB, and
        !          2872:         // the adapter has not yet had time to process it.
        !          2873:         // We return now before setting SrbAvailable to TRUE,
        !          2874:         // so the command is left to be processed.
        !          2875:         //
        !          2876:         // NOTE: If this happens on a call from inside the
        !          2877:         // ARB_TRANSMIT_DATA interrupt handler, we will fail
        !          2878:         // on an assertion when we return NULL.
        !          2879:         //
        !          2880:         *PacketRemoved = FALSE;
        !          2881: 
        !          2882:         return (PNDIS_PACKET)NULL;
        !          2883: 
        !          2884:     }
        !          2885: 
        !          2886: 
        !          2887:     //
        !          2888:     // if there was a packet in there, put it in
        !          2889:     // the correlator array.
        !          2890:     //
        !          2891: 
        !          2892:     TransmitPacket = Adapter->TransmittingPacket;
        !          2893: 
        !          2894:     Adapter->TransmittingPacket = (PNDIS_PACKET)NULL;
        !          2895: 
        !          2896:     //
        !          2897:     // This will be TRUE whatever happens next.
        !          2898:     //
        !          2899:     *PacketRemoved = TRUE;
        !          2900: 
        !          2901:     Reserved =
        !          2902:         PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          2903: 
        !          2904:     //
        !          2905:     // Check that the return code is OK.
        !          2906:     //
        !          2907: 
        !          2908:     if (TmpUchar != 0xff) {
        !          2909: 
        !          2910:         PIBMTOK_OPEN Open =
        !          2911:             PIBMTOK_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          2912:         //
        !          2913:         // Fail the transmit.
        !          2914:         //
        !          2915: 
        !          2916:         //
        !          2917:         // If doing LOOPBACK, this should really be a check
        !          2918:         // of ReadyToComplete etc.
        !          2919:         //
        !          2920: 
        !          2921: #if DBG
        !          2922: if (IbmtokDbg) {
        !          2923:     UCHAR TmpUchar1, TmpUchar2;
        !          2924:     NdisReadRegisterUchar(&TransmitSrb->ReturnCode, &TmpUchar1);
        !          2925:     NdisReadRegisterUchar(&TransmitSrb->Command, &TmpUchar2);
        !          2926:     DbgPrint("IBMTOK: Transmit failed in SRB: %x for %x\n", TmpUchar1, TmpUchar2);
        !          2927: }
        !          2928: #endif
        !          2929: 
        !          2930: #ifdef CHECK_DUP_SENDS
        !          2931:         {
        !          2932:         VOID IbmtokRemovePacketFromList(PIBMTOK_ADAPTER, PNDIS_PACKET);
        !          2933:         IbmtokRemovePacketFromList(Adapter, TransmitPacket);
        !          2934:         }
        !          2935: #endif
        !          2936: 
        !          2937:         Adapter->FrameTransmitErrors++;
        !          2938: 
        !          2939:         NdisReleaseSpinLock(&(Adapter->Lock));
        !          2940: 
        !          2941:         NdisCompleteSend(
        !          2942:             Open->NdisBindingContext,
        !          2943:             Reserved->Packet,
        !          2944:             NDIS_STATUS_FAILURE
        !          2945:             );
        !          2946: 
        !          2947:         NdisAcquireSpinLock(&(Adapter->Lock));
        !          2948: 
        !          2949:         //
        !          2950:         // Decrement the reference count for the open.
        !          2951:         //
        !          2952:         Open->References--;
        !          2953: 
        !          2954:         //
        !          2955:         // This will cause an assertion failure if we were
        !          2956:         // called from the ARB_TRANSMIT_DATA handler.
        !          2957:         //
        !          2958:         return (PNDIS_PACKET)NULL;
        !          2959: 
        !          2960:     }
        !          2961: 
        !          2962:     //
        !          2963:     // Put the packet in the correlator array.
        !          2964:     //
        !          2965: 
        !          2966:     Reserved->CorrelatorAssigned = TRUE;
        !          2967:     NdisReadRegisterUchar(&(TransmitSrb->CommandCorrelator), &(Reserved->CommandCorrelator));
        !          2968: 
        !          2969:     PutPacketInCorrelatorArray(Adapter, TransmitPacket);
        !          2970: 
        !          2971:     return TransmitPacket;
        !          2972: }
        !          2973: 
        !          2974: VOID
        !          2975: SetupSrbCommand(
        !          2976:     IN PIBMTOK_ADAPTER Adapter
        !          2977:     )
        !          2978: 
        !          2979: /*++
        !          2980: 
        !          2981: Routine Description:
        !          2982: 
        !          2983:     Fills in the SRB with the next request. It first checks
        !          2984:     if there is a pended request outstanding, then
        !          2985:     handles any queued transmits.
        !          2986: 
        !          2987:     Called with the spinlock held.
        !          2988: 
        !          2989:     NOTE: Should be called with Adapter->SrbAvailable == FALSE.
        !          2990: 
        !          2991: Arguments:
        !          2992: 
        !          2993:     Adapter - The Adapter to process interrupts for.
        !          2994: 
        !          2995: Return Value:
        !          2996: 
        !          2997:     None.
        !          2998: 
        !          2999: --*/
        !          3000: 
        !          3001: {
        !          3002: 
        !          3003:     if (Adapter->PendQueue != NULL) {
        !          3004: 
        !          3005:         //
        !          3006:         // This will copy the appropriate info out of the
        !          3007:         // pend queue.
        !          3008:         //
        !          3009: 
        !          3010:         if (StartPendQueueOp(Adapter) == NDIS_STATUS_PENDING) {
        !          3011: 
        !          3012:             //
        !          3013:             // Indicate the SRB command.
        !          3014:             //
        !          3015: 
        !          3016:             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          3017:                                     ISRA_HIGH_COMMAND_IN_SRB);
        !          3018: 
        !          3019:             return;
        !          3020: 
        !          3021:         }
        !          3022: 
        !          3023:     }
        !          3024: 
        !          3025:     //
        !          3026:     // If we reach here, the pend queue was empty or
        !          3027:     // else StartPendQueueOp drained the entire queue
        !          3028:     // without an operation needing the SRB.
        !          3029:     //
        !          3030: 
        !          3031:     if (Adapter->FirstTransmit != NULL) {
        !          3032: 
        !          3033:         //
        !          3034:         // Remove the packet from the queue.
        !          3035:         //
        !          3036: 
        !          3037:         PNDIS_PACKET TransmitPacket = Adapter->FirstTransmit;
        !          3038: 
        !          3039:         PIBMTOK_RESERVED Reserved =
        !          3040:             PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          3041: 
        !          3042:         Adapter->FirstTransmit = Reserved->Next;
        !          3043: 
        !          3044:         Adapter->TransmittingPacket = TransmitPacket;
        !          3045: 
        !          3046:         //
        !          3047:         // set up the send - this sets the packet equal
        !          3048:         // to Adapter->TransmittingPacket;
        !          3049:         //
        !          3050:         SetupTransmitFrameSrb(Adapter, TransmitPacket);
        !          3051: 
        !          3052:         //
        !          3053:         // Indicate the SRB command.
        !          3054:         //
        !          3055: 
        !          3056:         WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          3057:                                     ISRA_HIGH_COMMAND_IN_SRB);
        !          3058: 
        !          3059:     } else {
        !          3060: 
        !          3061:         Adapter->SrbAvailable = TRUE;
        !          3062: 
        !          3063:     }
        !          3064: }
        !          3065: 
        !          3066: extern
        !          3067: VOID
        !          3068: IbmtokForceAdapterInterrupt(
        !          3069:     IN PIBMTOK_ADAPTER Adapter
        !          3070:     )
        !          3071: 
        !          3072: /*++
        !          3073: 
        !          3074: Routine Description:
        !          3075: 
        !          3076:     This forces an adapter interrupt by queueing an
        !          3077:     INTERRUPT SRB.
        !          3078: 
        !          3079:     This is called with the spinlock held, and also
        !          3080:     Adapter->SrbAvailable must be TRUE.
        !          3081: 
        !          3082: Arguments:
        !          3083: 
        !          3084:     Adapter - The Adapter to force the interrupt on.
        !          3085: 
        !          3086: Return Value:
        !          3087: 
        !          3088:     None.
        !          3089: 
        !          3090: --*/
        !          3091: 
        !          3092: {
        !          3093: 
        !          3094:     PSRB_INTERRUPT InterruptSrb =
        !          3095:                 (PSRB_INTERRUPT)Adapter->SrbAddress;
        !          3096: 
        !          3097:     ASSERT(Adapter->SrbAvailable);
        !          3098: 
        !          3099:     Adapter->SrbAvailable = FALSE;
        !          3100: 
        !          3101:     NdisWriteRegisterUchar(&(InterruptSrb->Command), SRB_CMD_INTERRUPT);
        !          3102:     NdisWriteRegisterUchar(&(InterruptSrb->ReturnCode), 0xfe);
        !          3103: 
        !          3104:     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          3105:                                         ISRA_HIGH_COMMAND_IN_SRB);
        !          3106: 
        !          3107:     IF_LOG('O');
        !          3108: 
        !          3109: }
        !          3110: 
        !          3111: STATIC
        !          3112: VOID
        !          3113: SetupTransmitFrameSrb(
        !          3114:     IN PIBMTOK_ADAPTER Adapter,
        !          3115:     IN PNDIS_PACKET Packet
        !          3116:     )
        !          3117: 
        !          3118: /*++
        !          3119: 
        !          3120: Routine Description:
        !          3121: 
        !          3122:     This routine sets up the SRB for a TRANSMIT.DIR.FRAME.
        !          3123: 
        !          3124: Arguments:
        !          3125: 
        !          3126:     Adapter - The adapter that this packet is coming through.
        !          3127: 
        !          3128:     Packet - The packet that is being sent.
        !          3129: 
        !          3130: Return Value:
        !          3131: 
        !          3132:     None.
        !          3133: 
        !          3134: --*/
        !          3135: 
        !          3136: {
        !          3137:     PSRB_TRANSMIT_DIR_FRAME TransmitSrb =
        !          3138:                 (PSRB_TRANSMIT_DIR_FRAME)Adapter->SrbAddress;
        !          3139: 
        !          3140:     UNREFERENCED_PARAMETER(Packet);
        !          3141: 
        !          3142:     NdisWriteRegisterUchar(&(TransmitSrb->Command), SRB_CMD_TRANSMIT_DIR_FRAME);
        !          3143:     NdisWriteRegisterUchar(&(TransmitSrb->CommandCorrelator), 0x00);
        !          3144:     NdisWriteRegisterUchar(&(TransmitSrb->ReturnCode), 0xfe);   // will change to 0xff or error
        !          3145:     NdisWriteRegisterUshort(&(TransmitSrb->StationId), USHORT_TO_IBMSHORT(0x00));
        !          3146: 
        !          3147:     IF_LOG('x');
        !          3148: }
        !          3149: 
        !          3150: STATIC
        !          3151: VOID
        !          3152: SetupTransmitStatusAsb(
        !          3153:     IN PIBMTOK_ADAPTER Adapter,
        !          3154:     IN PNDIS_PACKET Packet
        !          3155:     )
        !          3156: 
        !          3157: /*++
        !          3158: 
        !          3159: Routine Description:
        !          3160: 
        !          3161:     This routine sets up the ASB for a response from
        !          3162:     a TRANSMIT.DATA.REQUEST.
        !          3163: 
        !          3164: Arguments:
        !          3165: 
        !          3166:     Adapter - The adapter that this packet is coming through.
        !          3167: 
        !          3168:     Packet - The packet that has been copied down.
        !          3169: 
        !          3170: Return Value:
        !          3171: 
        !          3172:     None.
        !          3173: 
        !          3174: --*/
        !          3175: 
        !          3176: {
        !          3177: 
        !          3178:     PASB_TRANSMIT_DATA_STATUS TransmitDataAsb;
        !          3179:     UINT PacketLength;
        !          3180:     PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(Packet);
        !          3181: 
        !          3182:     NdisQueryPacket(
        !          3183:         Packet,
        !          3184:         NULL,
        !          3185:         NULL,
        !          3186:         NULL,
        !          3187:         &PacketLength
        !          3188:         );
        !          3189: 
        !          3190:     TransmitDataAsb = (PASB_TRANSMIT_DATA_STATUS)
        !          3191:                         Adapter->AsbAddress;
        !          3192: 
        !          3193:     NdisWriteRegisterUchar(&(TransmitDataAsb->Command), SRB_CMD_TRANSMIT_DIR_FRAME);
        !          3194:     NdisWriteRegisterUchar(&(TransmitDataAsb->CommandCorrelator),
        !          3195:             Reserved->CommandCorrelator);
        !          3196:     NdisWriteRegisterUchar(&(TransmitDataAsb->ReturnCode), 0x00);
        !          3197:     NdisWriteRegisterUshort(&(TransmitDataAsb->FrameLength),
        !          3198:             USHORT_TO_IBMSHORT(PacketLength));
        !          3199: 
        !          3200:     IF_LOG('X');
        !          3201: 
        !          3202: }
        !          3203: 
        !          3204: STATIC
        !          3205: VOID
        !          3206: SetupAdapterStatisticsSrb(
        !          3207:     IN PIBMTOK_ADAPTER Adapter
        !          3208:     )
        !          3209: 
        !          3210: /*++
        !          3211: 
        !          3212: Routine Description:
        !          3213: 
        !          3214:     This routine sets up the SRB for a DLC.STATISTICS.
        !          3215: 
        !          3216: Arguments:
        !          3217: 
        !          3218:     Adapter - A pointer to the adapter.
        !          3219: 
        !          3220: Return Value:
        !          3221: 
        !          3222:     None.
        !          3223: 
        !          3224: --*/
        !          3225: {
        !          3226:     PSRB_DLC_STATS StatsSrb = (PSRB_DLC_STATS)(Adapter->SrbAddress);
        !          3227: 
        !          3228:     NdisWriteRegisterUchar(&(StatsSrb->Command), SRB_CMD_DLC_STATISTICS);
        !          3229:     NdisWriteRegisterUchar(&(StatsSrb->StationId), USHORT_TO_IBMSHORT(0x00));
        !          3230:     NdisWriteRegisterUchar(&(StatsSrb->ReturnCode), 0x80);                      // Resets counters
        !          3231: 
        !          3232: }
        !          3233: 
        !          3234: STATIC
        !          3235: VOID
        !          3236: GetAdapterStatisticsFromSrb(
        !          3237:     PIBMTOK_ADAPTER Adapter
        !          3238:     )
        !          3239: 
        !          3240: /*++
        !          3241: 
        !          3242: Routine Description:
        !          3243: 
        !          3244:     This routine reads the statistics after a DLC.STATISTICS has completed
        !          3245:     and stores the results in the adapter structure.
        !          3246: 
        !          3247: Arguments:
        !          3248: 
        !          3249:     Adapter - A pointer to the adapter.
        !          3250: 
        !          3251: Return Value:
        !          3252: 
        !          3253:     None.
        !          3254: 
        !          3255: --*/
        !          3256: 
        !          3257: {
        !          3258:     PSRB_DLC_STATS StatsSrb = (PSRB_DLC_STATS)(Adapter->SrbAddress);
        !          3259:     PDLC_COUNTERS Counters;
        !          3260:     USHORT TmpUshort;
        !          3261:     UCHAR TmpUchar;
        !          3262: 
        !          3263:     NdisReadRegisterUshort(&StatsSrb->CountersOffset, &TmpUshort);
        !          3264:     Counters = (PDLC_COUNTERS) (((PUCHAR)(Adapter->SrbAddress)) +
        !          3265:                                 IBMSHORT_TO_USHORT(TmpUshort));
        !          3266: 
        !          3267:     NdisReadRegisterUshort(&Counters->TransmitCount, &TmpUshort);
        !          3268:     Adapter->FramesTransmitted += IBMSHORT_TO_USHORT(TmpUshort);
        !          3269:     NdisReadRegisterUshort(&Counters->ReceiveCount, &TmpUshort);
        !          3270:     Adapter->FramesReceived += IBMSHORT_TO_USHORT(TmpUshort);
        !          3271:     NdisReadRegisterUchar(&Counters->TransmitErrors, &TmpUchar);
        !          3272:     Adapter->FrameTransmitErrors += TmpUchar;
        !          3273:     NdisReadRegisterUchar(&Counters->ReceiveErrors, &TmpUchar);
        !          3274:     Adapter->FrameReceiveErrors += TmpUchar;
        !          3275: 
        !          3276: }
        !          3277: 
        !          3278: STATIC
        !          3279: VOID
        !          3280: GetAdapterErrorsFromSrb(
        !          3281:     PIBMTOK_ADAPTER Adapter
        !          3282:     )
        !          3283: 
        !          3284: /*++
        !          3285: 
        !          3286: Routine Description:
        !          3287: 
        !          3288:     This routine reads the statistics after a DIR.READ.LOG has completed
        !          3289:     and stores the results in the adapter structure.
        !          3290: 
        !          3291: Arguments:
        !          3292: 
        !          3293:     Adapter - A pointer to the adapter.
        !          3294: 
        !          3295: Return Value:
        !          3296: 
        !          3297:     None.
        !          3298: 
        !          3299: --*/
        !          3300: 
        !          3301: {
        !          3302:     PSRB_READ_LOG ReadLogSrb = (PSRB_READ_LOG)(Adapter->SrbAddress);
        !          3303:     ULONG TmpUchar;
        !          3304: 
        !          3305:     NdisReadRegisterUchar(&ReadLogSrb->LineErrors, &TmpUchar);
        !          3306:     Adapter->LineErrors += TmpUchar;
        !          3307:     NdisReadRegisterUchar(&ReadLogSrb->InternalErrors, &TmpUchar);
        !          3308:     Adapter->InternalErrors += TmpUchar;
        !          3309:     NdisReadRegisterUchar(&ReadLogSrb->BurstErrors, &TmpUchar);
        !          3310:     Adapter->BurstErrors += TmpUchar;
        !          3311:     NdisReadRegisterUchar(&ReadLogSrb->AcErrors, &TmpUchar);
        !          3312:     Adapter->AcErrors += TmpUchar;
        !          3313:     NdisReadRegisterUchar(&ReadLogSrb->AbortDelimeters, &TmpUchar);
        !          3314:     Adapter->AbortDelimeters += TmpUchar;
        !          3315:     NdisReadRegisterUchar(&ReadLogSrb->LostFrames, &TmpUchar);
        !          3316:     Adapter->LostFrames += TmpUchar;
        !          3317:     NdisReadRegisterUchar(&ReadLogSrb->ReceiveCongestionCount, &TmpUchar);
        !          3318:     Adapter->ReceiveCongestionCount += TmpUchar;
        !          3319:     NdisReadRegisterUchar(&ReadLogSrb->FrameCopiedErrors, &TmpUchar);
        !          3320:     Adapter->FrameCopiedErrors += TmpUchar;
        !          3321:     NdisReadRegisterUchar(&ReadLogSrb->FrequencyErrors, &TmpUchar);
        !          3322:     Adapter->FrequencyErrors += TmpUchar;
        !          3323:     NdisReadRegisterUchar(&ReadLogSrb->TokenErrors, &TmpUchar);
        !          3324:     Adapter->TokenErrors += TmpUchar;
        !          3325: }
        !          3326: 
        !          3327: STATIC
        !          3328: VOID
        !          3329: SetupAdapterErrorsSrb(
        !          3330:     PIBMTOK_ADAPTER Adapter
        !          3331:     )
        !          3332: 
        !          3333: /*++
        !          3334: 
        !          3335: Routine Description:
        !          3336: 
        !          3337:     This routine sets up the SRB for a DIR.READ.LOG command.
        !          3338: 
        !          3339: Arguments:
        !          3340: 
        !          3341:     Adapter - A pointer to the adapter.
        !          3342: 
        !          3343: Return Value:
        !          3344: 
        !          3345:     None.
        !          3346: 
        !          3347: --*/
        !          3348: {
        !          3349:     PSRB_READ_LOG ReadLogSrb = (PSRB_READ_LOG)(Adapter->SrbAddress);
        !          3350: 
        !          3351:     NdisWriteRegisterUchar(&(ReadLogSrb->Command), SRB_CMD_READ_LOG);
        !          3352: }
        !          3353: 
        !          3354: STATIC
        !          3355: NDIS_STATUS
        !          3356: StartPendQueueOp(
        !          3357:     IN PIBMTOK_ADAPTER Adapter
        !          3358:     )
        !          3359: 
        !          3360: /*++
        !          3361: 
        !          3362: Routine Description:
        !          3363: 
        !          3364:     This routine goes through the pending queue until it
        !          3365:     is empty or it finds a request that requires an SRB
        !          3366:     command and hence pends.
        !          3367: 
        !          3368:     NOTE: This routine is called with the lock held and
        !          3369:     returns with it held.
        !          3370: 
        !          3371: Arguments:
        !          3372: 
        !          3373:     Adapter - The adapter that the queue should be checked for.
        !          3374: 
        !          3375: Return Value:
        !          3376: 
        !          3377:     NDIS_STATUS_SUCCESS - If the queue was drained completely.
        !          3378:     NDIS_STATUS_PENDING - If a request required the SRB.
        !          3379: 
        !          3380: --*/
        !          3381: 
        !          3382: {
        !          3383:     //
        !          3384:     // Holds the operation on the head of the queue
        !          3385:     // (we know it is not empty).
        !          3386:     //
        !          3387:     PIBMTOK_PEND_DATA PendOp;
        !          3388: 
        !          3389:     //
        !          3390:     // Holds status temporarily.
        !          3391:     //
        !          3392:     NDIS_STATUS RequestStatus;
        !          3393: 
        !          3394: 
        !          3395:     while (Adapter->PendQueue != NULL) {
        !          3396: 
        !          3397:         //
        !          3398:         // First take the head operation off the queue.
        !          3399:         //
        !          3400: 
        !          3401:         PendOp = Adapter->PendQueue;
        !          3402: 
        !          3403:         Adapter->PendQueue = Adapter->PendQueue->Next;
        !          3404: 
        !          3405:         if (Adapter->PendQueue == NULL){
        !          3406: 
        !          3407:             //
        !          3408:             // We have just emptied the list.
        !          3409:             //
        !          3410: 
        !          3411:             Adapter->EndOfPendQueue = NULL;
        !          3412: 
        !          3413:         }
        !          3414: 
        !          3415: 
        !          3416:         if (PendOp->RequestType == NdisRequestGeneric1){
        !          3417: 
        !          3418:             //
        !          3419:             // The pended operation is a result of the card having
        !          3420:             // a counter overflow, and now we need to send the command.
        !          3421:             //
        !          3422: 
        !          3423:             if (PendOp->COMMAND.MAC.ReadLogPending){
        !          3424: 
        !          3425:                 //
        !          3426:                 // A DIR.READ.LOG command is needed.
        !          3427:                 //
        !          3428: 
        !          3429:                 SetupAdapterErrorsSrb(Adapter);
        !          3430: 
        !          3431:             } else {
        !          3432: 
        !          3433:                 //
        !          3434:                 // A DLC.STATISTICS command is needed.
        !          3435:                 //
        !          3436: 
        !          3437:                 SetupAdapterStatisticsSrb(Adapter);
        !          3438: 
        !          3439:             }
        !          3440: 
        !          3441:             //
        !          3442:             // Issue adapter command.
        !          3443:             //
        !          3444: 
        !          3445:             WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          3446:                                         ISRA_HIGH_COMMAND_IN_SRB);
        !          3447: 
        !          3448:             RequestStatus = NDIS_STATUS_PENDING;
        !          3449: 
        !          3450:         } else {
        !          3451: 
        !          3452:             switch (PendOp->RequestType) {
        !          3453: 
        !          3454: 
        !          3455:                 case NdisRequestSetInformation:
        !          3456: 
        !          3457:                     //
        !          3458:                     // It's a set filter or set address command.
        !          3459:                     //
        !          3460: 
        !          3461:                     if ((PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp))->DATA.SET_INFORMATION.Oid ==
        !          3462:                        OID_GEN_CURRENT_PACKET_FILTER){
        !          3463: 
        !          3464:                         //
        !          3465:                         // It's a set filter command.
        !          3466:                         //
        !          3467: 
        !          3468: 
        !          3469:                         Adapter->OldPacketFilter = Adapter->CurrentPacketFilter;
        !          3470: 
        !          3471:                         Adapter->CurrentPacketFilter =
        !          3472:                               PendOp->COMMAND.NDIS.SET_FILTER.NewFilterValue;
        !          3473: 
        !          3474:                         RequestStatus = SetAdapterFunctionalAddress(Adapter);
        !          3475: 
        !          3476:                     } else {
        !          3477: 
        !          3478:                         //
        !          3479:                         // It's a set address command.
        !          3480:                         //
        !          3481: #if DBG
        !          3482:                         if (IbmtokDbg) {
        !          3483:                             DbgPrint("IBMTOK: Starting Command\n");
        !          3484:                         }
        !          3485: #endif
        !          3486: 
        !          3487:                         if ((PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp))->DATA.SET_INFORMATION.Oid ==
        !          3488:                             OID_802_5_CURRENT_FUNCTIONAL) {
        !          3489: 
        !          3490:                             Adapter->CurrentFunctionalAddress =
        !          3491:                                PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue;
        !          3492: 
        !          3493:                             RequestStatus = SetAdapterFunctionalAddress(Adapter);
        !          3494: 
        !          3495:                         } else {
        !          3496: 
        !          3497:                             Adapter->CurrentGroupAddress =
        !          3498:                                PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue;
        !          3499: 
        !          3500:                             RequestStatus = SetAdapterGroupAddress(Adapter);
        !          3501: 
        !          3502:                         }
        !          3503: 
        !          3504:                     }
        !          3505: 
        !          3506: 
        !          3507:                     break;
        !          3508: 
        !          3509:                 case NdisRequestClose:
        !          3510: 
        !          3511:                     //
        !          3512:                     // It's a set filter command.
        !          3513:                     //
        !          3514: 
        !          3515:                     Adapter->OldPacketFilter = Adapter->CurrentPacketFilter;
        !          3516: 
        !          3517:                     Adapter->CurrentPacketFilter =
        !          3518:                          PendOp->COMMAND.NDIS.CLOSE.NewFilterValue;
        !          3519: 
        !          3520:                     RequestStatus = SetAdapterFunctionalAddress(Adapter);
        !          3521: 
        !          3522:                     break;
        !          3523: 
        !          3524:                 case NdisRequestGeneric2:
        !          3525: 
        !          3526:                     //
        !          3527:                     // It's a set address command.
        !          3528:                     //
        !          3529: 
        !          3530:                     Adapter->CurrentFunctionalAddress =
        !          3531:                               PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue;
        !          3532: 
        !          3533: 
        !          3534:                     RequestStatus = SetAdapterFunctionalAddress(Adapter);
        !          3535: 
        !          3536:                     break;
        !          3537: 
        !          3538: 
        !          3539:                 case NdisRequestGeneric3:
        !          3540: 
        !          3541:                     //
        !          3542:                     // It's a set address command.
        !          3543:                     //
        !          3544: 
        !          3545:                     Adapter->CurrentGroupAddress =
        !          3546:                               PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue;
        !          3547: 
        !          3548: 
        !          3549:                     RequestStatus = SetAdapterGroupAddress(Adapter);
        !          3550: 
        !          3551:                     break;
        !          3552: 
        !          3553: 
        !          3554:                 case NdisRequestQueryStatistics:
        !          3555: 
        !          3556:                     //
        !          3557:                     // We know it's a request for statistics.
        !          3558:                     //
        !          3559: 
        !          3560:                     RequestStatus = NDIS_STATUS_PENDING;
        !          3561: 
        !          3562:                     SetupAdapterErrorsSrb(Adapter);
        !          3563: 
        !          3564:                     PendOp->COMMAND.NDIS.STATISTICS.ReadLogPending = TRUE;
        !          3565: 
        !          3566:                     //
        !          3567:                     // Issue adapter command.
        !          3568:                     //
        !          3569: 
        !          3570:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          3571:                                             ISRA_HIGH_COMMAND_IN_SRB);
        !          3572: 
        !          3573:                     break;
        !          3574: 
        !          3575:                 default:
        !          3576: 
        !          3577:                     NdisWriteErrorLogEntry(
        !          3578:                         Adapter->NdisAdapterHandle,
        !          3579:                         NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          3580:                         3,
        !          3581:                         IBMTOK_ERRMSG_BAD_OP,
        !          3582:                         1,
        !          3583:                         PendOp->RequestType
        !          3584:                         );
        !          3585: 
        !          3586: 
        !          3587:             }
        !          3588:         }
        !          3589: 
        !          3590: 
        !          3591: 
        !          3592: 
        !          3593:         if (RequestStatus == NDIS_STATUS_PENDING) {
        !          3594: 
        !          3595:             //
        !          3596:             // Set this up for when the request completes.
        !          3597:             //
        !          3598: 
        !          3599:             Adapter->PendData = PendOp;
        !          3600: 
        !          3601:             return NDIS_STATUS_PENDING;
        !          3602: 
        !          3603:         } else if (RequestStatus == NDIS_STATUS_SUCCESS) {
        !          3604: 
        !          3605:             PIBMTOK_OPEN TmpOpen;
        !          3606: 
        !          3607: 
        !          3608:             switch (PendOp->RequestType) {
        !          3609: 
        !          3610:                 case NdisRequestSetInformation:
        !          3611: 
        !          3612:                     //
        !          3613:                     // Complete the request.
        !          3614:                     //
        !          3615: 
        !          3616:                     TmpOpen = PendOp->COMMAND.NDIS.SET_FILTER.Open;
        !          3617: 
        !          3618: 
        !          3619:                     NdisReleaseSpinLock(&(Adapter->Lock));
        !          3620: 
        !          3621:                     NdisCompleteRequest(
        !          3622:                                 PendOp->COMMAND.NDIS.SET_FILTER.Open->NdisBindingContext,
        !          3623:                                 PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3624:                                 NDIS_STATUS_SUCCESS
        !          3625:                                 );
        !          3626: 
        !          3627:                     NdisAcquireSpinLock(&(Adapter->Lock));
        !          3628: 
        !          3629:                     TmpOpen->References--;
        !          3630: 
        !          3631:                     break;
        !          3632: 
        !          3633: 
        !          3634:                 case NdisRequestClose:
        !          3635: 
        !          3636:                     PendOp->COMMAND.NDIS.CLOSE.Open->References--;
        !          3637:                     break;
        !          3638: 
        !          3639:                 case NdisRequestGeneric2:
        !          3640:                 case NdisRequestGeneric3:
        !          3641: 
        !          3642:                     PendOp->COMMAND.NDIS.SET_ADDRESS.Open->References--;
        !          3643:                     break;
        !          3644: 
        !          3645: 
        !          3646:                 case NdisRequestQueryStatistics:
        !          3647: 
        !          3648:                     NdisReleaseSpinLock(&(Adapter->Lock));
        !          3649: 
        !          3650:                     NdisCompleteQueryStatistics(
        !          3651:                             Adapter->NdisMacHandle,
        !          3652:                             PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3653:                             NDIS_STATUS_SUCCESS
        !          3654:                             );
        !          3655: 
        !          3656:                     NdisAcquireSpinLock(&(Adapter->Lock));
        !          3657: 
        !          3658:                     Adapter->References--;
        !          3659: 
        !          3660:                     break;
        !          3661: 
        !          3662:                 default:
        !          3663: 
        !          3664:                     NdisWriteErrorLogEntry(
        !          3665:                         Adapter->NdisAdapterHandle,
        !          3666:                         NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          3667:                         3,
        !          3668:                         startPendQueueOp,
        !          3669:                         IBMTOK_ERRMSG_BAD_OP,
        !          3670:                         PendOp->RequestType
        !          3671:                         );
        !          3672: 
        !          3673: 
        !          3674:             }
        !          3675: 
        !          3676:         } else {
        !          3677: 
        !          3678:             NdisWriteErrorLogEntry(
        !          3679:                 Adapter->NdisAdapterHandle,
        !          3680:                 NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          3681:                 3,
        !          3682:                 startPendQueueOp,
        !          3683:                 IBMTOK_ERRMSG_INVALID_STATUS,
        !          3684:                 RequestStatus
        !          3685:                 );
        !          3686: 
        !          3687:         }
        !          3688: 
        !          3689:     }
        !          3690: 
        !          3691:     //
        !          3692:     // We drained the entire queue without pending.
        !          3693:     //
        !          3694: 
        !          3695:     return NDIS_STATUS_SUCCESS;
        !          3696: }
        !          3697: 
        !          3698: STATIC
        !          3699: BOOLEAN
        !          3700: FinishPendQueueOp(
        !          3701:     IN PIBMTOK_ADAPTER Adapter,
        !          3702:     IN BOOLEAN Successful
        !          3703:     )
        !          3704: 
        !          3705: /*++
        !          3706: 
        !          3707: Routine Description:
        !          3708: 
        !          3709:     This routine is called when an SRB command completes.
        !          3710:     It calles CompleteRequest if needed and does any other
        !          3711:     cleanup required.
        !          3712: 
        !          3713:     NOTE: This routine is called with the lock held and
        !          3714:     returns with it held.
        !          3715: 
        !          3716:     NOTE: This routine assumes that the pended operation to
        !          3717:     be completed was specifically requested by the protocol
        !          3718:     and, thus, that PendData->Request != NULL.
        !          3719: 
        !          3720: Arguments:
        !          3721: 
        !          3722:     Adapter - The adapter that the queue should be checked for.
        !          3723: 
        !          3724:     Successful - Was the SRB command completed successfully.
        !          3725: 
        !          3726: Return Value:
        !          3727: 
        !          3728:     TRUE if the operation was completed, FALSE if another command
        !          3729:     was submitted to the card to complete the operation.
        !          3730: 
        !          3731: --*/
        !          3732: 
        !          3733: {
        !          3734:     PIBMTOK_PEND_DATA PendOp = Adapter->PendData;
        !          3735: 
        !          3736:     ASSERT(PendOp != NULL);
        !          3737: 
        !          3738: 
        !          3739:     switch (PendOp->RequestType) {
        !          3740: 
        !          3741:         case NdisRequestQueryStatistics:
        !          3742: 
        !          3743:             //
        !          3744:             // It was a request for global statistics.
        !          3745:             //
        !          3746: 
        !          3747:             if (Successful){
        !          3748: 
        !          3749:                 NDIS_STATUS StatusToReturn;
        !          3750: 
        !          3751:                 //
        !          3752:                 // Grab the data
        !          3753:                 //
        !          3754: 
        !          3755:                 GetAdapterErrorsFromSrb(Adapter);
        !          3756: 
        !          3757:                 //
        !          3758:                 // Fill in NdisRequest InformationBuffer
        !          3759:                 //
        !          3760: 
        !          3761:                 StatusToReturn = IbmtokFillInGlobalData(
        !          3762:                                       Adapter,
        !          3763:                                       PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp)
        !          3764:                                       );
        !          3765: 
        !          3766:                 //
        !          3767:                 // Complete statistics call
        !          3768:                 //
        !          3769: 
        !          3770:                 Adapter->PendData = NULL;
        !          3771: 
        !          3772:                 NdisReleaseSpinLock(&(Adapter->Lock));
        !          3773: 
        !          3774:                 NdisCompleteQueryStatistics(
        !          3775:                     Adapter->NdisMacHandle,
        !          3776:                     PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3777:                     StatusToReturn
        !          3778:                     );
        !          3779: 
        !          3780:                 NdisAcquireSpinLock(&(Adapter->Lock));
        !          3781: 
        !          3782:                 Adapter->References--;
        !          3783: 
        !          3784:             } else {
        !          3785: 
        !          3786:                 //
        !          3787:                 // Complete statistics call
        !          3788:                 //
        !          3789: 
        !          3790:                 Adapter->PendData = NULL;
        !          3791: 
        !          3792:                 NdisReleaseSpinLock(&(Adapter->Lock));
        !          3793: 
        !          3794:                 NdisCompleteQueryStatistics(
        !          3795:                         Adapter->NdisMacHandle,
        !          3796:                         PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3797:                         NDIS_STATUS_FAILURE
        !          3798:                         );
        !          3799: 
        !          3800:                 NdisAcquireSpinLock(&(Adapter->Lock));
        !          3801: 
        !          3802:                 Adapter->References--;
        !          3803: 
        !          3804:             }
        !          3805: 
        !          3806:             break;
        !          3807: 
        !          3808: 
        !          3809:         case NdisRequestSetInformation:
        !          3810: 
        !          3811: 
        !          3812:             //
        !          3813:             // It was a request for address change.
        !          3814:             //
        !          3815: #if DBG
        !          3816:             if (IbmtokDbg) {
        !          3817:                 if (Successful) {
        !          3818:                     DbgPrint("IBMTOK: SUCCESS\n\n");
        !          3819:                 } else {
        !          3820:                     DbgPrint("IBMTOK: FAILURE\n\n");
        !          3821:                 }
        !          3822:             }
        !          3823: #endif
        !          3824: 
        !          3825:             if (Successful){
        !          3826: 
        !          3827:                 PIBMTOK_OPEN TmpOpen;
        !          3828: 
        !          3829:                 //
        !          3830:                 // complete the operation.
        !          3831:                 //
        !          3832: 
        !          3833: 
        !          3834:                 if (PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(Adapter->PendData)->DATA.SET_INFORMATION.Oid ==
        !          3835:                     OID_802_5_CURRENT_GROUP) {
        !          3836: 
        !          3837:                     //
        !          3838:                     // Store new group address
        !          3839:                     //
        !          3840: 
        !          3841:                     Adapter->CurrentCardGroup = Adapter->CurrentGroupAddress;
        !          3842: 
        !          3843:                 }
        !          3844: 
        !          3845:                 Adapter->PendData = NULL;
        !          3846: 
        !          3847:                 TmpOpen = PendOp->COMMAND.NDIS.SET_FILTER.Open;
        !          3848: 
        !          3849:                 NdisReleaseSpinLock(&(Adapter->Lock));
        !          3850: 
        !          3851:                 NdisCompleteRequest(
        !          3852:                             PendOp->COMMAND.NDIS.SET_FILTER.Open->NdisBindingContext,
        !          3853:                             PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3854:                             NDIS_STATUS_SUCCESS
        !          3855:                             );
        !          3856: 
        !          3857:                 NdisAcquireSpinLock(&(Adapter->Lock));
        !          3858: 
        !          3859: 
        !          3860:                 TmpOpen->References--;
        !          3861: 
        !          3862:             } else {
        !          3863: 
        !          3864: 
        !          3865:                 //
        !          3866:                 // complete the operation.
        !          3867:                 //
        !          3868: 
        !          3869:                 PIBMTOK_OPEN TmpOpen;
        !          3870: 
        !          3871:                 Adapter->PendData = NULL;
        !          3872: 
        !          3873:                 TmpOpen = PendOp->COMMAND.NDIS.SET_FILTER.Open;
        !          3874: 
        !          3875:                 NdisReleaseSpinLock(&(Adapter->Lock));
        !          3876: 
        !          3877:                 NdisCompleteRequest(
        !          3878:                             PendOp->COMMAND.NDIS.SET_FILTER.Open->NdisBindingContext,
        !          3879:                             PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          3880:                             NDIS_STATUS_FAILURE
        !          3881:                             );
        !          3882: 
        !          3883:                 NdisAcquireSpinLock(&(Adapter->Lock));
        !          3884: 
        !          3885: 
        !          3886:                 TmpOpen->References--;
        !          3887: 
        !          3888:             }
        !          3889: 
        !          3890:             break;
        !          3891: 
        !          3892: 
        !          3893:         case NdisRequestClose:
        !          3894:         case NdisRequestGeneric2:
        !          3895:         case NdisRequestGeneric3:
        !          3896: 
        !          3897:             PendOp->COMMAND.NDIS.CLOSE.Open->References--;
        !          3898: 
        !          3899:             break;
        !          3900: 
        !          3901:     }
        !          3902: 
        !          3903:     //
        !          3904:     // Now finish up unsuccessful operations based on the type.
        !          3905:     //
        !          3906:     // NOTE: If we ever have cleanup for successful operations,
        !          3907:     // we probably have to copy that code into the
        !          3908:     // 'RequestStatus == NDIS_STATUS_SUCCESS' section
        !          3909:     // in the function above.
        !          3910:     //
        !          3911: 
        !          3912:     if (!Successful) {
        !          3913: 
        !          3914:         switch (PendOp->RequestType) {
        !          3915: 
        !          3916:             case NdisRequestSetInformation:
        !          3917: 
        !          3918:                 //
        !          3919:                 // We know it was a set filter or set address.
        !          3920:                 //
        !          3921: 
        !          3922:                 if ((PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp))->DATA.SET_INFORMATION.Oid ==
        !          3923:                    OID_GEN_CURRENT_PACKET_FILTER){
        !          3924: 
        !          3925:                     //
        !          3926:                     // It was a set filter.
        !          3927:                     //
        !          3928: 
        !          3929: 
        !          3930:                     Adapter->CurrentPacketFilter = Adapter->OldPacketFilter;
        !          3931: 
        !          3932:                     Adapter->CurrentCardFunctional = (TR_FUNCTIONAL_ADDRESS)0;
        !          3933: 
        !          3934:                 } else {
        !          3935: 
        !          3936:                     //
        !          3937:                     // It was a set address.
        !          3938:                     //
        !          3939: 
        !          3940:                     Adapter->CurrentFunctionalAddress = (TR_FUNCTIONAL_ADDRESS)0;
        !          3941: 
        !          3942:                 }
        !          3943: 
        !          3944:                 break;
        !          3945: 
        !          3946:             case NdisRequestQueryStatistics:
        !          3947: 
        !          3948:                 break;
        !          3949: 
        !          3950:             case NdisRequestClose:
        !          3951:             case NdisRequestGeneric2:
        !          3952:             case NdisRequestGeneric3:
        !          3953: 
        !          3954:                 break;
        !          3955: 
        !          3956:             default:
        !          3957: 
        !          3958:                 NdisWriteErrorLogEntry(
        !          3959:                     Adapter->NdisAdapterHandle,
        !          3960:                     NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          3961:                     3,
        !          3962:                     finishPendQueueOp,
        !          3963:                     IBMTOK_ERRMSG_BAD_OP,
        !          3964:                     PendOp->RequestType
        !          3965:                     );
        !          3966: 
        !          3967:                 break;
        !          3968: 
        !          3969:         }
        !          3970:     }
        !          3971: 
        !          3972: 
        !          3973:     return(TRUE);
        !          3974: 
        !          3975: }
        !          3976: 
        !          3977: STATIC
        !          3978: NDIS_STATUS
        !          3979: SetAdapterFunctionalAddress(
        !          3980:     IN PIBMTOK_ADAPTER Adapter
        !          3981:     )
        !          3982: 
        !          3983: 
        !          3984: /*++
        !          3985: 
        !          3986: Routine Description:
        !          3987: 
        !          3988:     This routine checks the functional address on the adapter
        !          3989:     against what it should be given the current packet filter
        !          3990:     and functional address specified, and queues an update
        !          3991:     if necessary.
        !          3992: 
        !          3993:     NOTE: This routine assumes that it is called with the lock
        !          3994:     acquired.
        !          3995: 
        !          3996: Arguments:
        !          3997: 
        !          3998:     Adapter - The adapter to check.
        !          3999: 
        !          4000: Return Value:
        !          4001: 
        !          4002:     NDIS_STATUS_SUCCESS - If no change is necessary.
        !          4003:     NDIS_STATUS_PENDING - If the change was queued.
        !          4004: 
        !          4005: 
        !          4006: --*/
        !          4007: {
        !          4008:     //
        !          4009:     // The new value we compute for the functional address that
        !          4010:     // should be on the card.
        !          4011:     //
        !          4012:     TR_FUNCTIONAL_ADDRESS NewCardFunctional;
        !          4013: 
        !          4014:     //
        !          4015:     // Holds the value to be returned.
        !          4016:     //
        !          4017:     NDIS_STATUS StatusOfSet;
        !          4018: 
        !          4019:     //
        !          4020:     // Used if ALL_MULTICAST is selected.
        !          4021:     //
        !          4022:     ULONG AllFunctionalAddress = 0x7fffffff;
        !          4023: 
        !          4024:     //
        !          4025:     // First calculate what the new functional address
        !          4026:     // should be.
        !          4027:     //
        !          4028: 
        !          4029: #if DBG
        !          4030:     if (IbmtokDbg) {
        !          4031:         DbgPrint("IBMTOK: Current packet filter : 0x%x\n", Adapter->CurrentPacketFilter);
        !          4032:     }
        !          4033: #endif
        !          4034: 
        !          4035:     if (Adapter->CurrentPacketFilter &
        !          4036:                     NDIS_PACKET_TYPE_ALL_FUNCTIONAL) {
        !          4037: 
        !          4038:         //
        !          4039:         // We have to set all the bits in the address.
        !          4040:         //
        !          4041: 
        !          4042:         NewCardFunctional = AllFunctionalAddress;
        !          4043: 
        !          4044:     } else if (Adapter->CurrentPacketFilter &
        !          4045:                     NDIS_PACKET_TYPE_FUNCTIONAL) {
        !          4046: 
        !          4047:         NewCardFunctional = Adapter->CurrentFunctionalAddress;
        !          4048: 
        !          4049:     } else {
        !          4050: 
        !          4051:         NewCardFunctional = (TR_FUNCTIONAL_ADDRESS)0;
        !          4052: 
        !          4053:     }
        !          4054: 
        !          4055: #if DBG
        !          4056:     if (IbmtokDbg) {
        !          4057:         DbgPrint("IBMTOK: NewFunc is 0x%x\n", NewCardFunctional);
        !          4058:     }
        !          4059: #endif
        !          4060: 
        !          4061: 
        !          4062:     //
        !          4063:     // Now queue it up if needed.
        !          4064:     //
        !          4065: 
        !          4066:     if (NewCardFunctional == Adapter->CurrentCardFunctional) {
        !          4067: 
        !          4068: #if DBG
        !          4069:         if (IbmtokDbg) {
        !          4070:             DbgPrint("IBMTOK: SUCCESS\n\n");
        !          4071:         }
        !          4072: #endif
        !          4073: 
        !          4074:         StatusOfSet = NDIS_STATUS_SUCCESS;
        !          4075: 
        !          4076:     } else {
        !          4077: 
        !          4078:         SetupFunctionalSrb(
        !          4079:             Adapter,
        !          4080:             NewCardFunctional
        !          4081:         );
        !          4082:         Adapter->CurrentCardFunctional = NewCardFunctional;
        !          4083: 
        !          4084:         StatusOfSet = NDIS_STATUS_PENDING;
        !          4085: 
        !          4086:     }
        !          4087: 
        !          4088:     return StatusOfSet;
        !          4089: 
        !          4090: }
        !          4091: 
        !          4092: STATIC
        !          4093: VOID
        !          4094: SetupFunctionalSrb(
        !          4095:     IN PIBMTOK_ADAPTER Adapter,
        !          4096:     IN TR_FUNCTIONAL_ADDRESS FunctionalAddress
        !          4097:     )
        !          4098: 
        !          4099: /*++
        !          4100: 
        !          4101: Routine Description:
        !          4102: 
        !          4103:     This routine sets up the SRB for a DIR.SET.FUNCT.Address.
        !          4104: 
        !          4105: Arguments:
        !          4106: 
        !          4107:     Adapter - The adapter that this packet is coming through.
        !          4108: 
        !          4109:     FunctionalAddress - The address to set up.
        !          4110: 
        !          4111: Return Value:
        !          4112: 
        !          4113:     None.
        !          4114: 
        !          4115: --*/
        !          4116: 
        !          4117: {
        !          4118:     //
        !          4119:     // Used to set up the SRB request.
        !          4120:     //
        !          4121:     PSRB_SET_FUNCT_ADDRESS FunctSrb =
        !          4122:                 (PSRB_SET_FUNCT_ADDRESS)Adapter->SrbAddress;
        !          4123: 
        !          4124:     //
        !          4125:     // Used to hold the functional address temporarily.
        !          4126:     //
        !          4127:     UCHAR TempAddress[4];
        !          4128: 
        !          4129:     //
        !          4130:     // Used to copy down the functional address.
        !          4131:     //
        !          4132:     UINT i;
        !          4133: 
        !          4134: 
        !          4135: 
        !          4136:     NdisWriteRegisterUchar(&(FunctSrb->Command), SRB_CMD_SET_FUNCTIONAL_ADDRESS);
        !          4137:     NdisWriteRegisterUchar(&(FunctSrb->ReturnCode), 0xfe);
        !          4138: 
        !          4139:     //
        !          4140:     // Have to worry about setting the functional address
        !          4141:     // since it is not aligned correctly.
        !          4142:     //
        !          4143:     IBMTOK_STORE_ULONG(TempAddress, FunctionalAddress);
        !          4144: 
        !          4145:     for (i=0; i<4; i++) {
        !          4146: 
        !          4147:         NdisWriteRegisterUchar(&(FunctSrb->FunctionalAddress[i]), TempAddress[i]);
        !          4148: 
        !          4149:     }
        !          4150: 
        !          4151: }
        !          4152: 
        !          4153: STATIC
        !          4154: NDIS_STATUS
        !          4155: SetAdapterGroupAddress(
        !          4156:     IN PIBMTOK_ADAPTER Adapter
        !          4157:     )
        !          4158: 
        !          4159: 
        !          4160: /*++
        !          4161: 
        !          4162: Routine Description:
        !          4163: 
        !          4164:     This routine takes the value in Adapter->CurrentGroupAddress and
        !          4165:     puts it out to the card.
        !          4166: 
        !          4167:     NOTE: This routine assumes that it is called with the lock
        !          4168:     acquired.
        !          4169: 
        !          4170: Arguments:
        !          4171: 
        !          4172:     Adapter - The adapter to check.
        !          4173: 
        !          4174: Return Value:
        !          4175: 
        !          4176:     NDIS_STATUS_PENDING - If the change was queued.
        !          4177: 
        !          4178: 
        !          4179: --*/
        !          4180: {
        !          4181:     //
        !          4182:     // Holds the value to be returned.
        !          4183:     //
        !          4184: 
        !          4185:     SetupGroupSrb(
        !          4186:             Adapter,
        !          4187:             Adapter->CurrentGroupAddress
        !          4188:             );
        !          4189: 
        !          4190:     return NDIS_STATUS_PENDING;
        !          4191: 
        !          4192: }
        !          4193: 
        !          4194: STATIC
        !          4195: VOID
        !          4196: SetupGroupSrb(
        !          4197:     IN PIBMTOK_ADAPTER Adapter,
        !          4198:     IN TR_FUNCTIONAL_ADDRESS GroupAddress
        !          4199:     )
        !          4200: 
        !          4201: /*++
        !          4202: 
        !          4203: Routine Description:
        !          4204: 
        !          4205:     This routine sets up the SRB for a DIR.SET.GROUP.ADDRESS.
        !          4206: 
        !          4207: Arguments:
        !          4208: 
        !          4209:     Adapter - The adapter that this packet is coming through.
        !          4210: 
        !          4211:     GroupAddress - The address to set up.
        !          4212: 
        !          4213: Return Value:
        !          4214: 
        !          4215:     None.
        !          4216: 
        !          4217: --*/
        !          4218: 
        !          4219: {
        !          4220:     //
        !          4221:     // Used to set up the SRB request.
        !          4222:     //
        !          4223:     PSRB_SET_GROUP_ADDRESS GroupSrb =
        !          4224:                 (PSRB_SET_GROUP_ADDRESS)Adapter->SrbAddress;
        !          4225: 
        !          4226:     //
        !          4227:     // Used to hold the group address temporarily.
        !          4228:     //
        !          4229:     UCHAR TempAddress[4];
        !          4230: 
        !          4231:     //
        !          4232:     // Used to copy down the group address.
        !          4233:     //
        !          4234:     UINT i;
        !          4235: 
        !          4236: 
        !          4237: 
        !          4238:     NdisWriteRegisterUchar(&(GroupSrb->Command), SRB_CMD_SET_GROUP_ADDRESS);
        !          4239:     NdisWriteRegisterUchar(&(GroupSrb->ReturnCode), 0xfe);
        !          4240: 
        !          4241:     //
        !          4242:     // Have to worry about setting the group address
        !          4243:     // since it is not aligned correctly.
        !          4244:     //
        !          4245:     IBMTOK_STORE_ULONG(TempAddress, GroupAddress);
        !          4246: 
        !          4247:     for (i=0; i<4; i++) {
        !          4248: 
        !          4249:         NdisWriteRegisterUchar(&(GroupSrb->GroupAddress[i]), TempAddress[i]);
        !          4250: 
        !          4251:     }
        !          4252: 
        !          4253: }
        !          4254: 
        !          4255: STATIC
        !          4256: VOID
        !          4257: SetupReceivedDataAsb(
        !          4258:     IN PIBMTOK_ADAPTER Adapter,
        !          4259:     IN SRAM_PTR ReceiveBuffer
        !          4260:     )
        !          4261: 
        !          4262: /*++
        !          4263: 
        !          4264: Routine Description:
        !          4265: 
        !          4266:     This routine sets up the ASB for a response from
        !          4267:     a RECEIVED.DATA ARB.
        !          4268: 
        !          4269: Arguments:
        !          4270: 
        !          4271:     Adapter - The adapter that this packet is coming through.
        !          4272: 
        !          4273:     ReceiveBuffer - The first receive buffer in the frame.
        !          4274: 
        !          4275: Return Value:
        !          4276: 
        !          4277:     None.
        !          4278: 
        !          4279: --*/
        !          4280: 
        !          4281: {
        !          4282: 
        !          4283:     PASB_RECEIVED_DATA_STATUS ReceivedDataAsb;
        !          4284: 
        !          4285:     ReceivedDataAsb = (PASB_RECEIVED_DATA_STATUS)
        !          4286:                         Adapter->AsbAddress;
        !          4287: 
        !          4288:     NdisWriteRegisterUchar(&(ReceivedDataAsb->Command), ARB_CMD_RECEIVED_DATA);
        !          4289:     NdisWriteRegisterUchar(&(ReceivedDataAsb->ReturnCode), 0x00);
        !          4290:     NdisWriteRegisterUshort(&(ReceivedDataAsb->StationId), 0x0000);
        !          4291:     NdisWriteRegisterUshort(&(ReceivedDataAsb->ReceiveBuffer), ReceiveBuffer);
        !          4292: 
        !          4293: }
        !          4294: 
        !          4295: STATIC
        !          4296: VOID
        !          4297: PutPacketOnWaitingForAsb(
        !          4298:     IN PIBMTOK_ADAPTER Adapter,
        !          4299:     IN PNDIS_PACKET Packet
        !          4300:     )
        !          4301: 
        !          4302: /*++
        !          4303: 
        !          4304: Routine Description:
        !          4305: 
        !          4306:     This queues a packet on the Waiting To Copy queue.
        !          4307:     It is called and returns with the spinlock held.
        !          4308: 
        !          4309: Arguments:
        !          4310: 
        !          4311:     Adapter - The adapter that this packet is coming through.
        !          4312: 
        !          4313:     Packet - The packet that is to be transmitted.
        !          4314: 
        !          4315: Return Value:
        !          4316: 
        !          4317:     None.
        !          4318: 
        !          4319: --*/
        !          4320: 
        !          4321: {
        !          4322: 
        !          4323:     //
        !          4324:     // Points to the MAC reserved portion of this packet.  This
        !          4325:     // interpretation of the reserved section is only valid during
        !          4326:     // the allocation phase of the packet.
        !          4327:     //
        !          4328:     PIBMTOK_RESERVED Reserved = PIBMTOK_RESERVED_FROM_PACKET(Packet);
        !          4329: 
        !          4330: 
        !          4331:     ASSERT(sizeof(IBMTOK_RESERVED) <=
        !          4332:            sizeof(Packet->MacReserved));
        !          4333: 
        !          4334: 
        !          4335:     if (Adapter->FirstWaitingForAsb == NULL) {
        !          4336: 
        !          4337:         Adapter->FirstWaitingForAsb = Packet;
        !          4338: 
        !          4339:     } else {
        !          4340: 
        !          4341:         PIBMTOK_RESERVED_FROM_PACKET(Adapter->FirstWaitingForAsb)->Next = Packet;
        !          4342: 
        !          4343:     }
        !          4344: 
        !          4345:     Adapter->LastWaitingForAsb = Packet;
        !          4346: 
        !          4347:     Reserved->Next = NULL;
        !          4348: 
        !          4349: }
        !          4350: extern
        !          4351: VOID
        !          4352: IbmtokHandleDeferred(
        !          4353:     IN PIBMTOK_ADAPTER Adapter
        !          4354:     )
        !          4355: 
        !          4356: /*++
        !          4357: 
        !          4358: Routine Description:
        !          4359: 
        !          4360:     This routine handles any pending resets and closes.
        !          4361:     It is called during interrupt processing and also at
        !          4362:     the end of every routine if needed.
        !          4363: 
        !          4364:     NOTE: This routine is called with the spinlock held
        !          4365:     and returns with it held.
        !          4366: 
        !          4367: Arguments:
        !          4368: 
        !          4369:     Adapter - The adapter to check deferred processing on.
        !          4370: 
        !          4371: Return Value:
        !          4372: 
        !          4373:     None.
        !          4374: 
        !          4375: --*/
        !          4376: 
        !          4377: {
        !          4378:     PIBMTOK_OPEN Open;
        !          4379: 
        !          4380:     //
        !          4381:     // Note that the following code depends on the fact that
        !          4382:     // code above left the spinlock held.
        !          4383:     //
        !          4384: 
        !          4385:     //
        !          4386:     // We will only come in here if the adapter's reference
        !          4387:     // count is zero, so if a reset is in progress then we
        !          4388:     // can start the reset.
        !          4389:     //
        !          4390: 
        !          4391: 
        !          4392: 
        !          4393:     //
        !          4394:     // Make sure we don't start it twice!!
        !          4395:     //
        !          4396: 
        !          4397:     Adapter->References++;
        !          4398: 
        !          4399:     if (Adapter->ResetInProgress && Adapter->CurrentResetStage == 0) {
        !          4400: 
        !          4401:         Adapter->CurrentResetStage = 1;
        !          4402: 
        !          4403:         NdisReleaseSpinLock(&(Adapter->Lock));
        !          4404: 
        !          4405:         IbmtokStartAdapterReset(Adapter);
        !          4406: 
        !          4407:         NdisAcquireSpinLock(&(Adapter->Lock));
        !          4408: 
        !          4409:     }
        !          4410: 
        !          4411: 
        !          4412:     if (!Adapter->ResetInProgress && !IsListEmpty(&(Adapter->CloseDuringResetList))) {
        !          4413: 
        !          4414: 
        !          4415:         //
        !          4416:         // Status of the Filter delete call.
        !          4417:         //
        !          4418: 
        !          4419:         NDIS_STATUS Status;
        !          4420: 
        !          4421:         Open = CONTAINING_RECORD(
        !          4422:                  Adapter->CloseDuringResetList.Flink,
        !          4423:                  IBMTOK_OPEN,
        !          4424:                  OpenList
        !          4425:                  );
        !          4426: 
        !          4427:         Open->References++;
        !          4428: #if DBG
        !          4429:         if (IbmtokDbg) DbgPrint("IBMTOK: Calling TrDelete\n");
        !          4430: #endif
        !          4431: 
        !          4432:         Status = TrDeleteFilterOpenAdapter(
        !          4433:                                  Adapter->FilterDB,
        !          4434:                                  Open->NdisFilterHandle,
        !          4435:                                  NULL
        !          4436:                                  );
        !          4437: 
        !          4438: #if DBG
        !          4439:         if (IbmtokDbg) DbgPrint("IBMTOK: TrDelete returned\n");
        !          4440: #endif
        !          4441: 
        !          4442:         //
        !          4443:         // If the status is successful that merely implies that
        !          4444:         // we were able to delete the reference to the open binding
        !          4445:         // from the filtering code.  If we have a successful status
        !          4446:         // at this point we still need to check whether the reference
        !          4447:         // count to determine whether we can close.
        !          4448:         //
        !          4449:         //
        !          4450:         // The delete filter routine can return a "special" status
        !          4451:         // that indicates that there is a current NdisIndicateReceive
        !          4452:         // on this binding.
        !          4453:         //
        !          4454: 
        !          4455: 
        !          4456:         if (Status == NDIS_STATUS_SUCCESS) {
        !          4457: 
        !          4458:             //
        !          4459:             // Check whether the reference count is two.  If
        !          4460:             // it is then we can get rid of the memory for
        !          4461:             // this open.
        !          4462:             //
        !          4463:             // A count of two indicates one for this routine
        !          4464:             // and one for the filter which we *know* we can
        !          4465:             // get rid of.
        !          4466:             //
        !          4467: 
        !          4468:             if (Open->References == 2) {
        !          4469: 
        !          4470:                 //
        !          4471:                 // We are the only reference to the open.  Remove
        !          4472:                 // it from the list and delete the memory.
        !          4473:                 //
        !          4474: 
        !          4475:                 RemoveEntryList(&Open->OpenList);
        !          4476: 
        !          4477:                 //
        !          4478:                 // Complete the close here.
        !          4479:                 //
        !          4480: 
        !          4481:                 if (Adapter->LookAhead == Open->LookAhead) {
        !          4482: 
        !          4483:                     IbmtokAdjustMaxLookAhead(Adapter);
        !          4484: 
        !          4485:                 }
        !          4486: 
        !          4487:                 NdisReleaseSpinLock(&Adapter->Lock);
        !          4488: 
        !          4489:                 NdisCompleteCloseAdapter(
        !          4490:                             Open->NdisBindingContext,
        !          4491:                             NDIS_STATUS_SUCCESS
        !          4492:                             );
        !          4493: 
        !          4494:                 IBMTOK_FREE_PHYS(Open,sizeof(IBMTOK_OPEN));
        !          4495: 
        !          4496:                 NdisAcquireSpinLock(&Adapter->Lock);
        !          4497: 
        !          4498: 
        !          4499:             } else {
        !          4500: 
        !          4501:                 //
        !          4502:                 // Remove the open from the list and put it on
        !          4503:                 // the closing list.
        !          4504:                 //
        !          4505: 
        !          4506:                 RemoveEntryList(&Open->OpenList);
        !          4507: 
        !          4508:                 InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          4509: 
        !          4510:                 //
        !          4511:                 // Account for this routines reference to the open
        !          4512:                 // as well as reference because of the filtering.
        !          4513:                 //
        !          4514: 
        !          4515:                 Open->References -= 2;
        !          4516: 
        !          4517: 
        !          4518:             }
        !          4519: 
        !          4520:         } else if (Status == NDIS_STATUS_PENDING) {
        !          4521: 
        !          4522: 
        !          4523:             //
        !          4524:             // If it pended, there may be
        !          4525:             // operations queued.
        !          4526:             // Returns with lock released
        !          4527:             //
        !          4528: 
        !          4529:             IbmtokProcessSrbRequests(Adapter);
        !          4530: 
        !          4531:             //
        !          4532:             // Now start closing down this open.
        !          4533:             //
        !          4534: 
        !          4535:             Open->BindingShuttingDown = TRUE;
        !          4536: 
        !          4537:             //
        !          4538:             // Remove the open from the open list and put it on
        !          4539:             // the closing list.
        !          4540:             //
        !          4541: 
        !          4542:             RemoveEntryList(&Open->OpenList);
        !          4543:             InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          4544: 
        !          4545:             //
        !          4546:             // Account for this routines reference to the open
        !          4547:             // as well as reference because of the filtering.
        !          4548:             //
        !          4549: 
        !          4550:             Open->References -= 2;
        !          4551: 
        !          4552:         } else {
        !          4553: 
        !          4554:             //
        !          4555:             // We should not get RESET_IN_PROGRESS or any other types.
        !          4556:             //
        !          4557: 
        !          4558:             NdisWriteErrorLogEntry(
        !          4559:                 Adapter->NdisAdapterHandle,
        !          4560:                 NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          4561:                 3,
        !          4562:                 handleDeferred,
        !          4563:                 IBMTOK_ERRMSG_INVALID_STATUS,
        !          4564:                 Status
        !          4565:                 );
        !          4566: 
        !          4567:         }
        !          4568: 
        !          4569:     }
        !          4570: 
        !          4571:     //
        !          4572:     // If there are any opens on the closing list and their
        !          4573:     // reference counts are zero then complete the close and
        !          4574:     // delete them from the list.
        !          4575:     //
        !          4576:     //
        !          4577: 
        !          4578:     if (!IsListEmpty(&(Adapter->CloseList))){
        !          4579: 
        !          4580:         Open = CONTAINING_RECORD(
        !          4581:                  Adapter->CloseList.Flink,
        !          4582:                  IBMTOK_OPEN,
        !          4583:                  OpenList
        !          4584:                  );
        !          4585: 
        !          4586:         if (!Open->References) {
        !          4587: 
        !          4588:             if (Adapter->LookAhead == Open->LookAhead) {
        !          4589: 
        !          4590:                 IbmtokAdjustMaxLookAhead(Adapter);
        !          4591: 
        !          4592:             }
        !          4593: 
        !          4594:             NdisReleaseSpinLock(&(Adapter->Lock));
        !          4595: 
        !          4596:             NdisCompleteCloseAdapter(
        !          4597:                 Open->NdisBindingContext,
        !          4598:                 NDIS_STATUS_SUCCESS
        !          4599:                 );
        !          4600: 
        !          4601:             NdisAcquireSpinLock(&(Adapter->Lock));
        !          4602:             RemoveEntryList(&(Open->OpenList));
        !          4603:             IBMTOK_FREE_PHYS(Open, sizeof(IBMTOK_OPEN));
        !          4604: 
        !          4605:         }
        !          4606: 
        !          4607:     }
        !          4608: 
        !          4609:     Adapter->References--;
        !          4610: 
        !          4611: }
        !          4612: 
        !          4613: extern
        !          4614: VOID
        !          4615: IbmtokAbortPending(
        !          4616:     IN PIBMTOK_ADAPTER Adapter,
        !          4617:     IN NDIS_STATUS AbortStatus
        !          4618:     )
        !          4619: 
        !          4620: /*++
        !          4621: 
        !          4622: Routine Description:
        !          4623: 
        !          4624:     This routine aborts any pending requests, and calls
        !          4625:     IbmtokAbortSends to abort any pending sends.
        !          4626: 
        !          4627:     NOTE: This routine is called with the spinlock held
        !          4628:     and returns with it held.
        !          4629: 
        !          4630: Arguments:
        !          4631: 
        !          4632:     Adapter - The adapter to abort.
        !          4633: 
        !          4634:     AbortStatus - The status to complete requests with.
        !          4635: 
        !          4636: Return Value:
        !          4637: 
        !          4638:     None.
        !          4639: 
        !          4640: --*/
        !          4641: 
        !          4642: {
        !          4643:     PIBMTOK_OPEN Open;
        !          4644:     PIBMTOK_PEND_DATA PendOp;
        !          4645: 
        !          4646:     while (Adapter->PendQueue) {
        !          4647: 
        !          4648:         //
        !          4649:         // Holds the operation on the head of the queue
        !          4650:         //
        !          4651: 
        !          4652:         PendOp = Adapter->PendQueue;
        !          4653: 
        !          4654:         Adapter->PendQueue = Adapter->PendQueue->Next;
        !          4655: 
        !          4656:         if (Adapter->PendQueue == NULL){
        !          4657: 
        !          4658:             //
        !          4659:             // We have just emptied the list.
        !          4660:             //
        !          4661: 
        !          4662:             Adapter->EndOfPendQueue = NULL;
        !          4663: 
        !          4664:         }
        !          4665: 
        !          4666:         switch (PendOp->RequestType) {
        !          4667: 
        !          4668:             case NdisRequestSetInformation:
        !          4669: 
        !          4670:                 //
        !          4671:                 // Complete the request.
        !          4672:                 //
        !          4673: 
        !          4674:                 Open = PendOp->COMMAND.NDIS.SET_FILTER.Open;
        !          4675: 
        !          4676:                 NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          4677: 
        !          4678:                 NdisCompleteRequest(
        !          4679:                             Open->NdisBindingContext,
        !          4680:                             PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          4681:                             AbortStatus
        !          4682:                             );
        !          4683: 
        !          4684:                 NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          4685: 
        !          4686:                 Open->References--;
        !          4687: 
        !          4688:                 break;
        !          4689: 
        !          4690: 
        !          4691:             case NdisRequestClose:
        !          4692: 
        !          4693:                 PendOp->COMMAND.NDIS.CLOSE.Open->References--;
        !          4694:                 break;
        !          4695: 
        !          4696:             case NdisRequestGeneric1:
        !          4697: 
        !          4698:                 //
        !          4699:                 // Submitted by the driver
        !          4700:                 //
        !          4701: 
        !          4702:                 IBMTOK_FREE_PHYS(PendOp, sizeof(IBMTOK_PEND_DATA));
        !          4703:                 Adapter->PendData = NULL;
        !          4704:                 break;
        !          4705: 
        !          4706:             case NdisRequestGeneric2:
        !          4707:             case NdisRequestGeneric3:
        !          4708: 
        !          4709:                 //
        !          4710:                 // Changes in address and filters due to a close
        !          4711:                 //
        !          4712: 
        !          4713:                 PendOp->COMMAND.NDIS.SET_ADDRESS.Open->References--;
        !          4714:                 break;
        !          4715: 
        !          4716: 
        !          4717:             case NdisRequestQueryStatistics:
        !          4718: 
        !          4719:                 NdisDprReleaseSpinLock(&(Adapter->Lock));
        !          4720: 
        !          4721:                 NdisCompleteQueryStatistics(
        !          4722:                         Adapter->NdisMacHandle,
        !          4723:                         PNDIS_REQUEST_FROM_PIBMTOK_PEND_DATA(PendOp),
        !          4724:                         AbortStatus
        !          4725:                         );
        !          4726: 
        !          4727:                 NdisDprAcquireSpinLock(&(Adapter->Lock));
        !          4728: 
        !          4729:                 Adapter->References--;
        !          4730: 
        !          4731:                 break;
        !          4732: 
        !          4733:         }
        !          4734: 
        !          4735:     }
        !          4736: 
        !          4737:     IbmtokAbortSends (Adapter, AbortStatus);
        !          4738: 
        !          4739: }
        !          4740: 
        !          4741: extern
        !          4742: VOID
        !          4743: IbmtokAbortSends(
        !          4744:     IN PIBMTOK_ADAPTER Adapter,
        !          4745:     IN NDIS_STATUS AbortStatus
        !          4746:     )
        !          4747: 
        !          4748: /*++
        !          4749: 
        !          4750: Routine Description:
        !          4751: 
        !          4752:     This routine aborts any pending sends.
        !          4753: 
        !          4754:     NOTE: This routine is called with the spinlock held
        !          4755:     and returns with it held.
        !          4756: 
        !          4757: Arguments:
        !          4758: 
        !          4759:     Adapter - The adapter to abort.
        !          4760: 
        !          4761:     AbortStatus - The status to complete requests with.
        !          4762: 
        !          4763: Return Value:
        !          4764: 
        !          4765:     None.
        !          4766: 
        !          4767: --*/
        !          4768: 
        !          4769: {
        !          4770:     PIBMTOK_OPEN Open;
        !          4771:     PNDIS_PACKET TransmitPacket;
        !          4772:     PIBMTOK_RESERVED Reserved;
        !          4773:     UINT i;
        !          4774: 
        !          4775:     //
        !          4776:     // First the packet in the SRB.
        !          4777:     //
        !          4778: 
        !          4779:     if (Adapter->TransmittingPacket != NULL) {
        !          4780: 
        !          4781:         TransmitPacket = Adapter->TransmittingPacket;
        !          4782:         Adapter->TransmittingPacket = NULL;
        !          4783: 
        !          4784:         Reserved = PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          4785:         Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          4786: 
        !          4787:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          4788: 
        !          4789:         NdisCompleteSend(
        !          4790:                 Open->NdisBindingContext,
        !          4791:                 TransmitPacket,
        !          4792:                 AbortStatus
        !          4793:                 );
        !          4794: 
        !          4795:         NdisDprAcquireSpinLock(&Adapter->Lock);
        !          4796:         Open->References--;
        !          4797:     }
        !          4798: 
        !          4799:     //
        !          4800:     // Then any that are queued up waiting to be given to the card.
        !          4801:     //
        !          4802: 
        !          4803:     while (Adapter->FirstTransmit) {
        !          4804: 
        !          4805:         TransmitPacket = Adapter->FirstTransmit;
        !          4806: 
        !          4807:         Reserved = PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          4808:         Adapter->FirstTransmit = Reserved->Next;
        !          4809: 
        !          4810:         Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          4811: 
        !          4812:         NdisDprReleaseSpinLock(&Adapter->Lock);
        !          4813: 
        !          4814:         NdisCompleteSend(
        !          4815:                 Open->NdisBindingContext,
        !          4816:                 TransmitPacket,
        !          4817:                 AbortStatus
        !          4818:                 );
        !          4819: 
        !          4820:         NdisDprAcquireSpinLock(&Adapter->Lock);
        !          4821:         Open->References--;
        !          4822: 
        !          4823:     }
        !          4824: 
        !          4825:     //
        !          4826:     // Finally, the Correlator array (this will include any
        !          4827:     // packets on WaitingForAsb).
        !          4828:     //
        !          4829: 
        !          4830:     for (i=0; i<MAX_COMMAND_CORRELATOR; i++) {
        !          4831: 
        !          4832:         TransmitPacket = Adapter->CorrelatorArray[i];
        !          4833: 
        !          4834:         if (TransmitPacket != NULL) {
        !          4835: 
        !          4836:             RemovePacketFromCorrelatorArray (Adapter, TransmitPacket);
        !          4837: 
        !          4838:             Reserved = PIBMTOK_RESERVED_FROM_PACKET(TransmitPacket);
        !          4839:             Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !          4840: 
        !          4841:             NdisDprReleaseSpinLock(&Adapter->Lock);
        !          4842: 
        !          4843:             NdisCompleteSend(
        !          4844:                 Open->NdisBindingContext,
        !          4845:                 Reserved->Packet,
        !          4846:                 AbortStatus
        !          4847:                 );
        !          4848: 
        !          4849:             NdisDprAcquireSpinLock(&Adapter->Lock);
        !          4850:             Open->References--;
        !          4851:         }
        !          4852: 
        !          4853:     }
        !          4854: 
        !          4855:     Adapter->FirstWaitingForAsb = NULL;
        !          4856: 
        !          4857: }
        !          4858: 
        !          4859: VOID
        !          4860: IbmtokWakeUpDpc(
        !          4861:     IN PVOID SystemSpecific1,
        !          4862:     IN PVOID Context,
        !          4863:     IN PVOID SystemSpecific2,
        !          4864:     IN PVOID SystemSpecific3
        !          4865:     )
        !          4866: 
        !          4867: /*++
        !          4868: 
        !          4869: Routine Description:
        !          4870: 
        !          4871:     This DPC routine is queued every 2 seconds to check on the
        !          4872:     queues. If an interrupt was not received
        !          4873:     in the last two seconds and there should have been one,
        !          4874:     then we abort all operations.
        !          4875: 
        !          4876: Arguments:
        !          4877: 
        !          4878:     Context - Really a pointer to the adapter.
        !          4879: 
        !          4880: Return Value:
        !          4881: 
        !          4882:     None.
        !          4883: 
        !          4884: --*/
        !          4885: {
        !          4886:     PIBMTOK_ADAPTER Adapter = (PIBMTOK_ADAPTER)Context;
        !          4887: 
        !          4888:     UNREFERENCED_PARAMETER(SystemSpecific1);
        !          4889:     UNREFERENCED_PARAMETER(SystemSpecific2);
        !          4890:     UNREFERENCED_PARAMETER(SystemSpecific3);
        !          4891: 
        !          4892:     NdisDprAcquireSpinLock(&Adapter->Lock);
        !          4893: 
        !          4894:     if ((Adapter->WakeUpTimeout) &&
        !          4895:         ((Adapter->TransmittingPacket != NULL) ||
        !          4896:          (Adapter->FirstTransmit != NULL) ||
        !          4897:          (Adapter->PendQueue != NULL))) {
        !          4898: 
        !          4899:         //
        !          4900:         // We had a pending operation the last time we ran,
        !          4901:         // and it has not been completed...we need to complete
        !          4902:         // it now.
        !          4903: 
        !          4904:         Adapter->NotAcceptingRequests = TRUE;
        !          4905: 
        !          4906:         Adapter->WakeUpTimeout = FALSE;
        !          4907: 
        !          4908:         NdisWriteErrorLogEntry(
        !          4909:             Adapter->NdisAdapterHandle,
        !          4910:             NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !          4911:             0
        !          4912:             );
        !          4913: 
        !          4914:         //
        !          4915:         // Complete any pending requests or sends.
        !          4916:         //
        !          4917: 
        !          4918:         IbmtokAbortPending (Adapter, STATUS_SUCCESS);
        !          4919: 
        !          4920:         Adapter->WakeUpTimeout = FALSE;
        !          4921: 
        !          4922:     } else {
        !          4923: 
        !          4924:         if ((Adapter->TransmittingPacket != NULL) ||
        !          4925:             (Adapter->FirstTransmit != NULL) ||
        !          4926:             (Adapter->PendQueue != NULL)) {
        !          4927: 
        !          4928:             Adapter->WakeUpTimeout = TRUE;
        !          4929: 
        !          4930:         }
        !          4931: 
        !          4932:     }
        !          4933: 
        !          4934:     //
        !          4935:     // If we've been unplugged, and there is not a reset in
        !          4936:     // progress, try one.
        !          4937:     //
        !          4938: 
        !          4939:     if ((Adapter->LobeWireFaultIndicated) & (!Adapter->UnpluggedResetInProgress)) {
        !          4940: 
        !          4941:         Adapter->UnpluggedResetInProgress = TRUE;
        !          4942: 
        !          4943:         IbmtokSetupForReset(Adapter, NULL);
        !          4944: 
        !          4945:         IbmtokHandleDeferred(Adapter);
        !          4946:     }
        !          4947: 
        !          4948:     NdisDprReleaseSpinLock(&Adapter->Lock);
        !          4949: 
        !          4950:     //
        !          4951:     // Fire off another Dpc to execute after 30 seconds
        !          4952:     //
        !          4953: 
        !          4954:     NdisSetTimer(
        !          4955:         &Adapter->WakeUpTimer,
        !          4956:         30000
        !          4957:         );
        !          4958: 
        !          4959: }
        !          4960: 

unix.superglobalmegacorp.com

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