|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.