|
|
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.