Annotation of ntddk/src/network/ibmtok/interrup.c, revision 1.1.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.