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

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     ibmtok.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This is the main file for the IBM Token-Ring 16/4 Adapter.
        !            12:     This driver conforms to the NDIS 3.0 interface.
        !            13: 
        !            14:     The overall structure and much of the code is taken from
        !            15:     the Lance NDIS driver by Tony Ercolano.
        !            16: 
        !            17: Author:
        !            18: 
        !            19:     Anthony V. Ercolano (Tonye) 20-Jul-1990
        !            20:     Adam Barr (adamba) 15-Feb-1990
        !            21: 
        !            22: Environment:
        !            23: 
        !            24:     Kernel Mode - Or whatever is the equivalent.
        !            25: 
        !            26: Revision History:
        !            27: 
        !            28:     Sean Selitrennikoff -- 9/15/91:
        !            29:       Added code to handle Microchannel with PC I/O bus handling.
        !            30:       Fixed bugs.
        !            31:     Sean Selitrennikoff -- 10/15/91:
        !            32:       Converted to Ndis 3.0 spec.
        !            33:     George Joy -- 12/1/91
        !            34:       Changed for compilation under DOS as well as NT
        !            35:     Sean Selitrennikoff -- 1/8/92:
        !            36:       Added error logging
        !            37: 
        !            38: --*/
        !            39: 
        !            40: #pragma optimize("",off)
        !            41: 
        !            42: #include <ndis.h>
        !            43: 
        !            44: 
        !            45: #include <tfilter.h>
        !            46: #include <tokhrd.h>
        !            47: #include <toksft.h>
        !            48: 
        !            49: 
        !            50: #if LOG
        !            51: 
        !            52: //
        !            53: // Place in the circular buffer.
        !            54: //
        !            55: extern UCHAR IbmtokLogPlace;
        !            56: 
        !            57: //
        !            58: // Circular buffer for storing log information.
        !            59: //
        !            60: extern UCHAR IbmtokLog[];
        !            61: 
        !            62: #define IF_LOG(A) {IbmtokLog[IbmtokLogPlace++] = (A); IbmtokLog[IbmtokLogPlace+2] = '.';}
        !            63: 
        !            64: #else
        !            65: 
        !            66: #define IF_LOG(A)
        !            67: 
        !            68: #endif
        !            69: 
        !            70: //
        !            71: // This constant is used for places where NdisAllocateMemory
        !            72: // needs to be called and the HighestAcceptableAddress does
        !            73: // not matter.
        !            74: //
        !            75: 
        !            76: const NDIS_PHYSICAL_ADDRESS HighestAcceptableMax =
        !            77:     NDIS_PHYSICAL_ADDRESS_CONST(-1,-1);
        !            78: 
        !            79: 
        !            80: //
        !            81: // If you add to this, make sure to add the
        !            82: // a case in IbmtokFillInGlobalData() and in
        !            83: // IbmtokQueryGlobalStatistics()
        !            84: //
        !            85: static const UINT IbmtokGlobalSupportedOids[] = {
        !            86:     OID_GEN_SUPPORTED_LIST,
        !            87:     OID_GEN_HARDWARE_STATUS,
        !            88:     OID_GEN_MEDIA_SUPPORTED,
        !            89:     OID_GEN_MEDIA_IN_USE,
        !            90:     OID_GEN_MAXIMUM_LOOKAHEAD,
        !            91:     OID_GEN_MAXIMUM_FRAME_SIZE,
        !            92:     OID_GEN_MAXIMUM_TOTAL_SIZE,
        !            93:     OID_GEN_MAC_OPTIONS,
        !            94:     OID_GEN_PROTOCOL_OPTIONS,
        !            95:     OID_GEN_LINK_SPEED,
        !            96:     OID_GEN_TRANSMIT_BUFFER_SPACE,
        !            97:     OID_GEN_RECEIVE_BUFFER_SPACE,
        !            98:     OID_GEN_TRANSMIT_BLOCK_SIZE,
        !            99:     OID_GEN_RECEIVE_BLOCK_SIZE,
        !           100:     OID_GEN_VENDOR_ID,
        !           101:     OID_GEN_VENDOR_DESCRIPTION,
        !           102:     OID_GEN_DRIVER_VERSION,
        !           103:     OID_GEN_CURRENT_PACKET_FILTER,
        !           104:     OID_GEN_CURRENT_LOOKAHEAD,
        !           105:     OID_GEN_XMIT_OK,
        !           106:     OID_GEN_RCV_OK,
        !           107:     OID_GEN_XMIT_ERROR,
        !           108:     OID_GEN_RCV_ERROR,
        !           109:     OID_GEN_RCV_NO_BUFFER,
        !           110:     OID_802_5_PERMANENT_ADDRESS,
        !           111:     OID_802_5_CURRENT_ADDRESS,
        !           112:     OID_802_5_CURRENT_FUNCTIONAL,
        !           113:     OID_802_5_CURRENT_GROUP,
        !           114:     OID_802_5_LAST_OPEN_STATUS,
        !           115:     OID_802_5_CURRENT_RING_STATUS,
        !           116:     OID_802_5_CURRENT_RING_STATE,
        !           117:     OID_802_5_LINE_ERRORS,
        !           118:     OID_802_5_LOST_FRAMES
        !           119:     };
        !           120: 
        !           121: //
        !           122: // If you add to this, make sure to add the
        !           123: // a case in IbmtokQueryGlobalStatistics() and in
        !           124: // IbmtokQueryProtocolInformation()
        !           125: //
        !           126: static const UINT IbmtokProtocolSupportedOids[] = {
        !           127:     OID_GEN_SUPPORTED_LIST,
        !           128:     OID_GEN_HARDWARE_STATUS,
        !           129:     OID_GEN_MEDIA_SUPPORTED,
        !           130:     OID_GEN_MEDIA_IN_USE,
        !           131:     OID_GEN_MAXIMUM_LOOKAHEAD,
        !           132:     OID_GEN_MAXIMUM_FRAME_SIZE,
        !           133:     OID_GEN_MAXIMUM_TOTAL_SIZE,
        !           134:     OID_GEN_MAC_OPTIONS,
        !           135:     OID_GEN_PROTOCOL_OPTIONS,
        !           136:     OID_GEN_LINK_SPEED,
        !           137:     OID_GEN_TRANSMIT_BUFFER_SPACE,
        !           138:     OID_GEN_RECEIVE_BUFFER_SPACE,
        !           139:     OID_GEN_TRANSMIT_BLOCK_SIZE,
        !           140:     OID_GEN_RECEIVE_BLOCK_SIZE,
        !           141:     OID_GEN_VENDOR_ID,
        !           142:     OID_GEN_VENDOR_DESCRIPTION,
        !           143:     OID_GEN_DRIVER_VERSION,
        !           144:     OID_GEN_CURRENT_PACKET_FILTER,
        !           145:     OID_GEN_CURRENT_LOOKAHEAD,
        !           146:     OID_802_5_PERMANENT_ADDRESS,
        !           147:     OID_802_5_CURRENT_ADDRESS,
        !           148:     OID_802_5_CURRENT_FUNCTIONAL,
        !           149:     OID_802_5_CURRENT_GROUP
        !           150:     };
        !           151: 
        !           152: 
        !           153: //
        !           154: // On a development build, don't define functions as static
        !           155: // so we can set breakpoints on them.
        !           156: //
        !           157: 
        !           158: #if DEVL
        !           159: #define STATIC
        !           160: #else
        !           161: #define STATIC static
        !           162: #endif
        !           163: 
        !           164: #if DBG
        !           165: INT IbmtokDbg = 0;
        !           166: #define LOG 1
        !           167: #else
        !           168: #define LOG 0
        !           169: #endif
        !           170: 
        !           171: 
        !           172: //
        !           173: // Get from configuration file.
        !           174: //
        !           175: 
        !           176: #define MAX_MULTICAST_ADDRESS ((UINT)16)
        !           177: #define MAX_ADAPTERS ((UINT)4)
        !           178: 
        !           179: 
        !           180: //
        !           181: // This macro determines if the directed address
        !           182: // filtering in the CAM is actually necessary given
        !           183: // the current filter.
        !           184: //
        !           185: #define CAM_DIRECTED_SIGNIFICANT(_Filter) \
        !           186:     ((((_Filter) & NDIS_PACKET_TYPE_DIRECTED) && \
        !           187:     (!((_Filter) & NDIS_PACKET_TYPE_PROMISCUOUS))) ? 1 : 0)
        !           188: 
        !           189: 
        !           190: //
        !           191: // This macro determines if the multicast filtering in
        !           192: // the CAM are actually necessary given the current filter.
        !           193: //
        !           194: #define CAM_MULTICAST_SIGNIFICANT(_Filter) \
        !           195:     ((((_Filter) & NDIS_PACKET_TYPE_MULTICAST) && \
        !           196:     (!((_Filter) & (NDIS_PACKET_TYPE_ALL_MULTICAST | \
        !           197:                     NDIS_PACKET_TYPE_PROMISCUOUS)))) ? 1 : 0)
        !           198: 
        !           199: 
        !           200: STATIC
        !           201: NDIS_STATUS
        !           202: IbmtokOpenAdapter(
        !           203:     OUT PNDIS_STATUS OpenErrorStatus,
        !           204:     OUT NDIS_HANDLE *MacBindingHandle,
        !           205:     OUT PUINT SelectedMediumIndex,
        !           206:     IN PNDIS_MEDIUM MediumArray,
        !           207:     IN UINT MediumArraySize,
        !           208:     IN NDIS_HANDLE NdisBindingContext,
        !           209:     IN NDIS_HANDLE MacAdapterContext,
        !           210:     IN UINT OpenOptions,
        !           211:     IN PSTRING AddressingInformation OPTIONAL
        !           212:     );
        !           213: 
        !           214: STATIC
        !           215: NDIS_STATUS
        !           216: IbmtokCloseAdapter(
        !           217:     IN NDIS_HANDLE MacBindingHandle
        !           218:     );
        !           219: 
        !           220: 
        !           221: STATIC
        !           222: NDIS_STATUS
        !           223: IbmtokRequest(
        !           224:     IN NDIS_HANDLE MacBindingHandle,
        !           225:     IN PNDIS_REQUEST NdisRequest
        !           226:     );
        !           227: 
        !           228: STATIC
        !           229: NDIS_STATUS
        !           230: IbmtokQueryInformation(
        !           231:     IN PIBMTOK_ADAPTER Adapter,
        !           232:     IN PIBMTOK_OPEN Open,
        !           233:     IN PNDIS_REQUEST NdisRequest
        !           234:     );
        !           235: 
        !           236: 
        !           237: STATIC
        !           238: NDIS_STATUS
        !           239: IbmtokSetInformation(
        !           240:     IN PIBMTOK_ADAPTER Adapter,
        !           241:     IN PIBMTOK_OPEN Open,
        !           242:     IN PNDIS_REQUEST NdisRequest
        !           243:     );
        !           244: 
        !           245: STATIC
        !           246: NDIS_STATUS
        !           247: IbmtokQueryGlobalStatistics(
        !           248:     IN NDIS_HANDLE MacAdapterContext,
        !           249:     IN PNDIS_REQUEST NdisRequest
        !           250:     );
        !           251: 
        !           252: NDIS_STATUS
        !           253: IbmtokAddAdapter(
        !           254:     IN NDIS_HANDLE MacMacContext,
        !           255:     IN NDIS_HANDLE ConfigurationHandle,
        !           256:     IN PNDIS_STRING AdaptName
        !           257:     );
        !           258: 
        !           259: VOID
        !           260: IbmtokRemoveAdapter(
        !           261:     IN PVOID MacAdapterContext
        !           262:     );
        !           263: 
        !           264: STATIC
        !           265: NDIS_STATUS
        !           266: IbmtokSetPacketFilter(
        !           267:     IN PIBMTOK_ADAPTER Adapter,
        !           268:     IN PIBMTOK_OPEN Open,
        !           269:     IN PNDIS_REQUEST NdisRequest,
        !           270:     IN UINT PacketFilter
        !           271:     );
        !           272: 
        !           273: STATIC
        !           274: NDIS_STATUS
        !           275: IbmtokSetGroupAddress(
        !           276:     IN PIBMTOK_ADAPTER Adapter,
        !           277:     IN PIBMTOK_OPEN Open,
        !           278:     IN PNDIS_REQUEST NdisRequest,
        !           279:     IN PUCHAR Address
        !           280:     );
        !           281: 
        !           282: STATIC
        !           283: NDIS_STATUS
        !           284: IbmtokChangeFunctionalAddress(
        !           285:     IN PIBMTOK_ADAPTER Adapter,
        !           286:     IN PIBMTOK_OPEN Open,
        !           287:     IN PNDIS_REQUEST NdisRequest,
        !           288:     IN PUCHAR Address
        !           289:     );
        !           290: 
        !           291: STATIC
        !           292: NDIS_STATUS
        !           293: IbmtokReset(
        !           294:     IN NDIS_HANDLE MacBindingHandle
        !           295:     );
        !           296: 
        !           297: STATIC
        !           298: NDIS_STATUS
        !           299: IbmtokTest(
        !           300:     IN NDIS_HANDLE MacBindingHandle
        !           301:     );
        !           302: 
        !           303: STATIC
        !           304: NDIS_STATUS
        !           305: IbmtokChangeFilter(
        !           306:     IN UINT OldFilterClasses,
        !           307:     IN UINT NewFilterClasses,
        !           308:     IN NDIS_HANDLE MacBindingHandle,
        !           309:     IN PNDIS_REQUEST NdisRequest,
        !           310:     IN BOOLEAN Set
        !           311:     );
        !           312: 
        !           313: STATIC
        !           314: NDIS_STATUS
        !           315: IbmtokChangeAddress(
        !           316:     IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddress,
        !           317:     IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddress,
        !           318:     IN NDIS_HANDLE MacBindingHandle,
        !           319:     IN PNDIS_REQUEST NdisRequest,
        !           320:     IN BOOLEAN Set
        !           321:     );
        !           322: 
        !           323: STATIC
        !           324: NDIS_STATUS
        !           325: IbmtokChangeGroupAddress(
        !           326:     IN TR_FUNCTIONAL_ADDRESS OldGroupAddress,
        !           327:     IN TR_FUNCTIONAL_ADDRESS NewGroupAddress,
        !           328:     IN NDIS_HANDLE MacBindingHandle,
        !           329:     IN PNDIS_REQUEST NdisRequest,
        !           330:     IN BOOLEAN Set
        !           331:     );
        !           332: 
        !           333: STATIC
        !           334: BOOLEAN
        !           335: IbmtokHardwareDetails(
        !           336:     IN PIBMTOK_ADAPTER Adapter
        !           337:     );
        !           338: 
        !           339: STATIC
        !           340: NDIS_STATUS
        !           341: IbmtokRegisterAdapter(
        !           342:     IN PIBMTOK_ADAPTER Adapter,
        !           343:     IN NDIS_HANDLE ConfigurationHandle,
        !           344:     IN PNDIS_STRING DeviceName,
        !           345:     IN BOOLEAN McaCard,
        !           346:     IN BOOLEAN ConfigError
        !           347:     );
        !           348: 
        !           349: STATIC
        !           350: VOID
        !           351: SetInitializeVariables(
        !           352:     IN PIBMTOK_ADAPTER Adapter
        !           353:     );
        !           354: 
        !           355: VOID
        !           356: SetResetVariables(
        !           357:     IN PIBMTOK_ADAPTER Adapter
        !           358:     );
        !           359: 
        !           360: extern
        !           361: VOID
        !           362: IbmtokStartAdapterReset(
        !           363:     IN PIBMTOK_ADAPTER Adapter
        !           364:     );
        !           365: 
        !           366: STATIC
        !           367: VOID
        !           368: IbmtokCloseAction(
        !           369:     IN NDIS_HANDLE MacBindingHandle
        !           370:     );
        !           371: 
        !           372: STATIC
        !           373: VOID
        !           374: IbmtokSetupRegistersAndInit(
        !           375:     IN PIBMTOK_ADAPTER Adapter
        !           376:     );
        !           377: 
        !           378: STATIC
        !           379: NDIS_STATUS
        !           380: IbmtokInitialInit(
        !           381:     IN PIBMTOK_ADAPTER Adapter
        !           382:     );
        !           383: 
        !           384: VOID
        !           385: IbmtokUnload(
        !           386:     IN NDIS_HANDLE MacMacContext
        !           387:     );
        !           388: 
        !           389: 
        !           390: NTSTATUS
        !           391: DriverEntry(
        !           392:     IN PDRIVER_OBJECT DriverObject,
        !           393:     IN PUNICODE_STRING RegistryPath
        !           394:     )
        !           395: /*++
        !           396: 
        !           397: Routine Description:
        !           398: 
        !           399:     This is the primary initialization routine for the ibmtok driver.
        !           400:     It is simply responsible for the intializing the wrapper and registering
        !           401:     the MAC.  It then calls a system and architecture specific routine that
        !           402:     will initialize and register each adapter.
        !           403: 
        !           404: Arguments:
        !           405: 
        !           406:     DriverObject - Pointer to driver object created by the system.
        !           407: 
        !           408: Return Value:
        !           409: 
        !           410:     The status of the operation.
        !           411: 
        !           412: --*/
        !           413: 
        !           414: {
        !           415: 
        !           416: 
        !           417:     //
        !           418:     // Receives the status of the NdisRegisterMac operation.
        !           419:     //
        !           420:     NDIS_STATUS InitStatus;
        !           421:     PIBMTOK_MAC IbmtokMac;
        !           422:     NDIS_HANDLE NdisWrapperHandle;
        !           423:     char Tmp[sizeof(NDIS_MAC_CHARACTERISTICS)];
        !           424:     PNDIS_MAC_CHARACTERISTICS IbmtokChar = (PNDIS_MAC_CHARACTERISTICS)(PVOID)Tmp;
        !           425:     NDIS_STRING MacName = NDIS_STRING_CONST("IbmTok");
        !           426: 
        !           427:     //
        !           428:     // Initialize the wrapper.
        !           429:     //
        !           430: 
        !           431:     NdisInitializeWrapper(
        !           432:                 &NdisWrapperHandle,
        !           433:                 DriverObject,
        !           434:                 RegistryPath,
        !           435:                 NULL
        !           436:                 );
        !           437: 
        !           438:     //
        !           439:     // Now allocate memory for our global structure.
        !           440:     //
        !           441: 
        !           442:     InitStatus = IBMTOK_ALLOC_PHYS(&IbmtokMac, sizeof(IBMTOK_MAC));
        !           443: 
        !           444:     if (InitStatus != NDIS_STATUS_SUCCESS) {
        !           445: 
        !           446:          return NDIS_STATUS_RESOURCES;
        !           447: 
        !           448:     }
        !           449: 
        !           450:     IbmtokMac->NdisWrapperHandle = NdisWrapperHandle;
        !           451: 
        !           452:     //
        !           453:     // Initialize the MAC characteristics for the call to
        !           454:     // NdisRegisterMac.
        !           455:     //
        !           456: 
        !           457: 
        !           458:     IbmtokChar->MajorNdisVersion = IBMTOK_NDIS_MAJOR_VERSION;
        !           459:     IbmtokChar->MinorNdisVersion = IBMTOK_NDIS_MINOR_VERSION;
        !           460:     IbmtokChar->OpenAdapterHandler = (OPEN_ADAPTER_HANDLER) IbmtokOpenAdapter;
        !           461:     IbmtokChar->CloseAdapterHandler = (CLOSE_ADAPTER_HANDLER) IbmtokCloseAdapter;
        !           462:     IbmtokChar->RequestHandler = IbmtokRequest;
        !           463:     IbmtokChar->SendHandler = IbmtokSend;
        !           464:     IbmtokChar->TransferDataHandler = IbmtokTransferData;
        !           465:     IbmtokChar->ResetHandler = IbmtokReset;
        !           466:     IbmtokChar->UnloadMacHandler = IbmtokUnload;
        !           467:     IbmtokChar->QueryGlobalStatisticsHandler = IbmtokQueryGlobalStatistics;
        !           468:     IbmtokChar->AddAdapterHandler      = IbmtokAddAdapter;
        !           469:     IbmtokChar->RemoveAdapterHandler   = IbmtokRemoveAdapter;
        !           470: 
        !           471:     IbmtokChar->Name = MacName;
        !           472: 
        !           473:     NdisRegisterMac(
        !           474:         &InitStatus,
        !           475:         &IbmtokMac->NdisMacHandle,
        !           476:         NdisWrapperHandle,
        !           477:         (PVOID)IbmtokMac,
        !           478:         IbmtokChar,
        !           479:         sizeof(*IbmtokChar)
        !           480:         );
        !           481: 
        !           482:     if (InitStatus != NDIS_STATUS_SUCCESS) {
        !           483: 
        !           484:         NdisTerminateWrapper(NdisWrapperHandle, NULL);
        !           485: 
        !           486:         return NDIS_STATUS_FAILURE;
        !           487: 
        !           488:     }
        !           489: 
        !           490:     return NDIS_STATUS_SUCCESS;
        !           491: 
        !           492: }
        !           493: 
        !           494: 
        !           495: STATIC
        !           496: NDIS_STATUS
        !           497: IbmtokRegisterAdapter(
        !           498:     IN PIBMTOK_ADAPTER Adapter,
        !           499:     IN NDIS_HANDLE ConfigurationHandle,
        !           500:     IN PNDIS_STRING DeviceName,
        !           501:     IN BOOLEAN McaCard,
        !           502:     IN BOOLEAN ConfigError
        !           503:     )
        !           504: 
        !           505: /*++
        !           506: 
        !           507: Routine Description:
        !           508: 
        !           509:     This routine (and its interface) are not portable.  They are
        !           510:     defined by the OS, the architecture, and the particular IBMTOK
        !           511:     implementation.
        !           512: 
        !           513:     This routine is responsible for the allocation of the datastructures
        !           514:     for the driver as well as any hardware specific details necessary
        !           515:     to talk with the device.
        !           516: 
        !           517: Arguments:
        !           518: 
        !           519:     Adapter - Pointer to the adapter block.
        !           520: 
        !           521:     ConfigurationHandle - Handle passed to MacAddAdapter, to be passed to
        !           522:     NdisRegisterAdapter.
        !           523: 
        !           524:     DeviceName - Name of this adapter.
        !           525: 
        !           526:     McaCard - This is an MCA bus.
        !           527: 
        !           528:     ConfigError - TRUE if a configuration error was found earlier.
        !           529: 
        !           530: Return Value:
        !           531: 
        !           532:     Returns NDIS_STATUS_SUCCESS if everything goes ok, else
        !           533:     if anything occurred that prevents the initialization
        !           534:     of the adapter it returns an appropriate NDIS error.
        !           535: 
        !           536: --*/
        !           537: 
        !           538: {
        !           539: 
        !           540:     NDIS_STATUS Status;
        !           541: 
        !           542:     //
        !           543:     // Holds information needed when registering the adapter.
        !           544:     //
        !           545: 
        !           546:     NDIS_ADAPTER_INFORMATION AdapterInformation;
        !           547: 
        !           548:     // We put in this assertion to make sure that ushort are 2 bytes.
        !           549:     // if they aren't then the initialization block definition needs
        !           550:     // to be changed.
        !           551:     //
        !           552:     // Also all of the logic that deals with status registers assumes
        !           553:     // that control registers are only 2 bytes.
        !           554:     //
        !           555: 
        !           556:     ASSERT(sizeof(USHORT) == 2);
        !           557: 
        !           558:     //
        !           559:     // Get the interrupt number and MMIO address.
        !           560:     //
        !           561: 
        !           562:     //
        !           563:     // Set the adapter state.
        !           564:     //
        !           565: 
        !           566:     SetInitializeVariables(Adapter);
        !           567: 
        !           568:     SetResetVariables(Adapter);
        !           569: 
        !           570:     //
        !           571:     // Set up the AdapterInformation structure; zero it
        !           572:     // first in case it is extended later.
        !           573:     //
        !           574: 
        !           575:     IBMTOK_ZERO_MEMORY (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));
        !           576:     AdapterInformation.AdapterType = (McaCard ? NdisInterfaceMca : NdisInterfaceIsa);
        !           577:     AdapterInformation.NumberOfPortDescriptors = 1;
        !           578:     AdapterInformation.PortDescriptors[0].InitialPort = Adapter->IbmtokPortAddress;
        !           579:     AdapterInformation.PortDescriptors[0].NumberOfPorts = 4;
        !           580: 
        !           581:     //
        !           582:     // Register the adapter with Ndis.
        !           583:     //
        !           584: 
        !           585:     Status = NdisRegisterAdapter(
        !           586:                                 &Adapter->NdisAdapterHandle,
        !           587:                                 Adapter->NdisMacHandle,
        !           588:                                 Adapter,
        !           589:                                 ConfigurationHandle,
        !           590:                                 DeviceName,
        !           591:                                 &AdapterInformation
        !           592:                                 );
        !           593: 
        !           594:     if (Status != NDIS_STATUS_SUCCESS) {
        !           595: 
        !           596:         return(Status);
        !           597: 
        !           598:     }
        !           599: 
        !           600:     if (ConfigError) {
        !           601: 
        !           602:         //
        !           603:         // Error and quit
        !           604:         //
        !           605: 
        !           606:         NdisWriteErrorLogEntry(
        !           607:             Adapter->NdisAdapterHandle,
        !           608:             NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !           609:             0
        !           610:             );
        !           611: 
        !           612:         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !           613: 
        !           614:         return(NDIS_STATUS_FAILURE);
        !           615: 
        !           616:     }
        !           617: 
        !           618: 
        !           619: 
        !           620:     if (!IbmtokHardwareDetails(Adapter)) {
        !           621: 
        !           622:         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !           623:         return NDIS_STATUS_ADAPTER_NOT_FOUND;
        !           624: 
        !           625:     }
        !           626: 
        !           627: 
        !           628:     //
        !           629:     // Reset the card to put it in a valid state.
        !           630:     //
        !           631: 
        !           632:     if (Adapter->SharedRamPaging) {
        !           633: 
        !           634:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, 0xc0);
        !           635: 
        !           636:     }
        !           637: 
        !           638:     //
        !           639:     // OK, do the reset as detailed in the Tech Ref...
        !           640:     //
        !           641: 
        !           642:     WRITE_ADAPTER_PORT(Adapter, RESET_LATCH, 0);
        !           643: 
        !           644:     NdisStallExecution(50000);
        !           645: 
        !           646:     WRITE_ADAPTER_PORT(Adapter, RESET_RELEASE, 0);
        !           647: 
        !           648:     //
        !           649:     // Initialize the interrupt.
        !           650:     //
        !           651: 
        !           652:     NdisAllocateSpinLock(&Adapter->InterruptLock);
        !           653: 
        !           654:     NdisInitializeInterrupt(
        !           655:             &Status,
        !           656:             &Adapter->Interrupt,
        !           657:             Adapter->NdisAdapterHandle,
        !           658:             IbmtokISR,
        !           659:             Adapter,
        !           660:             IbmtokDPC,
        !           661:             Adapter->InterruptLevel,
        !           662:             Adapter->InterruptLevel,
        !           663:             FALSE,
        !           664:             (Adapter->UsingPcIoBus)?NdisInterruptLatched:
        !           665:                                     NdisInterruptLevelSensitive
        !           666:             );
        !           667: 
        !           668:     if (Status == NDIS_STATUS_SUCCESS){
        !           669: 
        !           670:         //
        !           671:         // Set up the Adapter variables. (We have to do the
        !           672:         // initial init to get the network address before we
        !           673:         // create the filter DB.)
        !           674:         //
        !           675:         if (IbmtokInitialInit(Adapter) != NDIS_STATUS_SUCCESS) {
        !           676: 
        !           677:             NdisWriteErrorLogEntry(
        !           678:                 Adapter->NdisAdapterHandle,
        !           679:                 NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
        !           680:                 2,
        !           681:                 registerAdapter,
        !           682:                 IBMTOK_ERRMSG_NOT_FOUND
        !           683:                 );
        !           684: 
        !           685:             NdisRemoveInterrupt(&Adapter->Interrupt);
        !           686: 
        !           687:             NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !           688:             NdisFreeSpinLock(&(Adapter->Lock));
        !           689:             return NDIS_STATUS_ADAPTER_NOT_FOUND;
        !           690: 
        !           691:         } else {
        !           692: 
        !           693:             if (!TrCreateFilter(
        !           694:                  IbmtokChangeAddress,
        !           695:                  IbmtokChangeGroupAddress,
        !           696:                  IbmtokChangeFilter,
        !           697:                  IbmtokCloseAction,
        !           698:                  Adapter->NetworkAddress,
        !           699:                  &Adapter->Lock,
        !           700:                  &Adapter->FilterDB
        !           701:                  )) {
        !           702: 
        !           703:                 NdisWriteErrorLogEntry(
        !           704:                     Adapter->NdisAdapterHandle,
        !           705:                     NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !           706:                     2,
        !           707:                     registerAdapter,
        !           708:                     IBMTOK_ERRMSG_CREATE_DB
        !           709:                     );
        !           710: 
        !           711:                 NdisRemoveInterrupt(&Adapter->Interrupt);
        !           712:                 NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !           713:                 NdisFreeSpinLock(&(Adapter->Lock));
        !           714:                 return NDIS_STATUS_RESOURCES;
        !           715: 
        !           716:             } else {
        !           717: 
        !           718:                 //
        !           719:                 // Initialize the wake up timer to catch interrupts that
        !           720:                 // don't complete. It fires continuously
        !           721:                 // every thirty seconds, and we check if there are any
        !           722:                 // uncompleted operations from the previous two-second
        !           723:                 // period.
        !           724:                 //
        !           725: 
        !           726:                 Adapter->WakeUpDpc = (PVOID)IbmtokWakeUpDpc;
        !           727: 
        !           728:                 NdisInitializeTimer(&Adapter->WakeUpTimer,
        !           729:                                     (PVOID)(Adapter->WakeUpDpc),
        !           730:                                     Adapter );
        !           731: 
        !           732:                 NdisSetTimer(
        !           733:                     &Adapter->WakeUpTimer,
        !           734:                     30000
        !           735:                     );
        !           736: 
        !           737:                 return(NDIS_STATUS_SUCCESS);
        !           738: 
        !           739:             }
        !           740: 
        !           741:         }
        !           742: 
        !           743:     } else {
        !           744: 
        !           745:         NdisWriteErrorLogEntry(
        !           746:             Adapter->NdisAdapterHandle,
        !           747:             NDIS_ERROR_CODE_INTERRUPT_CONNECT,
        !           748:             2,
        !           749:             registerAdapter,
        !           750:             IBMTOK_ERRMSG_INIT_INTERRUPT
        !           751:             );
        !           752: 
        !           753:         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !           754:         NdisFreeSpinLock(&(Adapter->Lock));
        !           755:         return(Status);
        !           756:     }
        !           757: 
        !           758: }
        !           759: 
        !           760: STATIC
        !           761: VOID
        !           762: SetInitializeVariables(
        !           763:     IN PIBMTOK_ADAPTER Adapter
        !           764:     )
        !           765: 
        !           766: /*++
        !           767: 
        !           768: Routine Description:
        !           769: 
        !           770:     This routine initializes all the variables in the Adapter
        !           771:     structure that should only be set during adapter initialization
        !           772:     (i.e. not during a reset).
        !           773: 
        !           774: Arguments:
        !           775: 
        !           776:     Adapter - The adapter for the hardware.
        !           777: 
        !           778: Return Value:
        !           779: 
        !           780:     None.
        !           781: 
        !           782: --*/
        !           783: 
        !           784: {
        !           785:     InitializeListHead(&Adapter->OpenBindings);
        !           786:     InitializeListHead(&Adapter->CloseList);
        !           787:     InitializeListHead(&Adapter->CloseDuringResetList);
        !           788: 
        !           789:     NdisAllocateSpinLock(&Adapter->Lock);
        !           790: 
        !           791:     //
        !           792:     // If this is not true, then uncomment below
        !           793:     //
        !           794: 
        !           795:     ASSERT(FALSE == (BOOLEAN)0);
        !           796: 
        !           797:     // Adapter->HandleSrbRunning = FALSE;
        !           798:     // Adapter->HandleArbRunning = FALSE;
        !           799: 
        !           800:     // Adapter->OpenInProgress = FALSE;
        !           801: 
        !           802:     Adapter->AdapterNotOpen = TRUE;
        !           803:     Adapter->NotAcceptingRequests = TRUE;
        !           804: 
        !           805:     // Adapter->ResetInProgress = FALSE;
        !           806:     // Adapter->ResettingOpen = NULL;
        !           807:     // Adapter->ResetInterruptAllowed = FALSE;
        !           808:     // Adapter->ResetInterruptHasArrived = FALSE;
        !           809: 
        !           810:     // Adapter->BringUp = FALSE;
        !           811: 
        !           812:     //
        !           813:     // Note: These assume that the SAP info will not
        !           814:     // take up more than 218 bytes.  This is ok, for now, since
        !           815:     // we open the card with 0 SAPs allowed.
        !           816:     //
        !           817: 
        !           818:     Adapter->ReceiveBufferLength = 256;
        !           819:     Adapter->NumberOfTransmitBuffers = 1;
        !           820: 
        !           821:     //
        !           822:     // Note: The following fields are set in the interrupt handler after
        !           823:     // the card tells us if the ring is 16 or 4 Mbps.
        !           824:     //
        !           825:     //
        !           826:     // TransmitBufferLength
        !           827:     // NumberOfReceiveBuffers
        !           828:     // MaximumTransmittablePacket
        !           829:     //
        !           830: 
        !           831:     // Adapter->IsrpDeferredBits = 0;
        !           832: 
        !           833:     Adapter->FirstInitialization = TRUE;
        !           834: 
        !           835:     // Adapter->OutstandingAsbFreeRequest = FALSE;
        !           836: }
        !           837: 
        !           838: VOID
        !           839: SetResetVariables(
        !           840:     IN PIBMTOK_ADAPTER Adapter
        !           841:     )
        !           842: 
        !           843: /*++
        !           844: 
        !           845: Routine Description:
        !           846: 
        !           847:     This routine initializes all the variables in the Adapter
        !           848:     structure that are set both during an initialization and
        !           849:     after a reset.
        !           850: 
        !           851: Arguments:
        !           852: 
        !           853:     Adapter - The adapter for the hardware.
        !           854: 
        !           855: Return Value:
        !           856: 
        !           857:     None.
        !           858: 
        !           859: --*/
        !           860: 
        !           861: {
        !           862:     Adapter->FirstTransmit = NULL;
        !           863:     Adapter->LastTransmit = NULL;
        !           864:     Adapter->FirstWaitingForAsb = NULL;
        !           865:     Adapter->LastWaitingForAsb = NULL;
        !           866:     Adapter->TransmittingPacket = NULL;
        !           867: 
        !           868:     IBMTOK_ZERO_MEMORY(Adapter->CorrelatorArray,
        !           869:                     sizeof(PNDIS_PACKET) * MAX_COMMAND_CORRELATOR);
        !           870: 
        !           871:     Adapter->PendQueue = NULL;
        !           872:     Adapter->EndOfPendQueue = NULL;
        !           873: 
        !           874:     Adapter->SrbAvailable = TRUE;
        !           875:     Adapter->AsbAvailable = TRUE;
        !           876: 
        !           877:     Adapter->IsrpBits = 0;
        !           878:     Adapter->IsrpLowBits = 0;
        !           879: 
        !           880:     Adapter->NextCorrelatorToComplete = 0;
        !           881:     Adapter->ReceiveWaitingForAsbList = (USHORT)-1;
        !           882:     Adapter->ReceiveWaitingForAsbEnd  = (USHORT)-1;
        !           883:     Adapter->UseNextAsbForReceive = TRUE;
        !           884: }
        !           885: 
        !           886: extern
        !           887: NDIS_STATUS
        !           888: IbmtokInitialInit(
        !           889:     IN PIBMTOK_ADAPTER Adapter
        !           890:     )
        !           891: 
        !           892: /*++
        !           893: 
        !           894: Routine Description:
        !           895: 
        !           896:     This routine sets up the initial init of the driver.
        !           897: 
        !           898: Arguments:
        !           899: 
        !           900:     Adapter - The adapter for the hardware.
        !           901: 
        !           902: Return Value:
        !           903: 
        !           904:     None.
        !           905: 
        !           906: --*/
        !           907: 
        !           908: {
        !           909:     USHORT RegValue;
        !           910:     UINT Time = 50; // Number of 100 milliseconds to delay while waiting
        !           911:                     // for the card to initialize.
        !           912: 
        !           913:     IbmtokSetupRegistersAndInit(Adapter);
        !           914: 
        !           915:     //
        !           916:     // Delay execution for 5 seconds to give the ring
        !           917:     // time to initialize.
        !           918:     //
        !           919: 
        !           920:     while((!Adapter->BringUp) && (Time != 0)){
        !           921: 
        !           922:         NdisStallExecution(100000);
        !           923: 
        !           924:         Time--;
        !           925: 
        !           926:     }
        !           927: 
        !           928:     if (!Adapter->BringUp){
        !           929: 
        !           930:         return(NDIS_STATUS_ADAPTER_NOT_FOUND);
        !           931: 
        !           932:     } else {
        !           933: 
        !           934:         //
        !           935:         // Do remaining initialization.
        !           936:         //
        !           937: 
        !           938:         USHORT WrbOffset;
        !           939:         PSRB_BRING_UP_RESULT BringUpSrb;
        !           940:         PUCHAR EncodedAddress;
        !           941:         UCHAR Value1, Value2;
        !           942: 
        !           943:         READ_ADAPTER_REGISTER(Adapter, WRBR_LOW,  &Value1);
        !           944:         READ_ADAPTER_REGISTER(Adapter, WRBR_HIGH, &Value2);
        !           945: 
        !           946:         WrbOffset = (((USHORT)Value1) << 8) + (USHORT)Value2;
        !           947: 
        !           948:         Adapter->InitialWrbOffset = WrbOffset;
        !           949: 
        !           950: #if DBG
        !           951:         if (IbmtokDbg) {
        !           952: 
        !           953:             DbgPrint("IBMTOK: Initial Offset = 0x%x\n", WrbOffset);
        !           954: 
        !           955:         }
        !           956: #endif
        !           957: 
        !           958:         BringUpSrb = (PSRB_BRING_UP_RESULT)
        !           959:                                 (Adapter->SharedRam + WrbOffset);
        !           960: 
        !           961:         NdisReadRegisterUshort(&(BringUpSrb->ReturnCode), &RegValue);
        !           962: 
        !           963:         if (RegValue != 0x0000) {
        !           964: 
        !           965:             if (RegValue == 0x30){
        !           966: 
        !           967:                 NdisWriteErrorLogEntry(
        !           968:                     Adapter->NdisAdapterHandle,
        !           969:                     NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !           970:                     0x32,
        !           971:                     handleSrbSsb,
        !           972:                     IBMTOK_ERRMSG_BRINGUP_FAILURE
        !           973:                     );
        !           974: 
        !           975: 
        !           976:                 return(NDIS_STATUS_ADAPTER_NOT_FOUND);
        !           977: 
        !           978:             } else {
        !           979: 
        !           980:                 NdisWriteErrorLogEntry(
        !           981:                     Adapter->NdisAdapterHandle,
        !           982:                     NDIS_ERROR_CODE_HARDWARE_FAILURE,
        !           983:                     3,
        !           984:                     handleSrbSsb,
        !           985:                     IBMTOK_ERRMSG_BRINGUP_FAILURE,
        !           986:                     (ULONG)RegValue
        !           987:                     );
        !           988: 
        !           989:                 return(NDIS_STATUS_ADAPTER_NOT_FOUND);
        !           990: 
        !           991: 
        !           992:             }
        !           993: 
        !           994:         } else {
        !           995: 
        !           996:             Adapter->FirstInitialization = FALSE;
        !           997:             Adapter->BringUp = TRUE;
        !           998: 
        !           999:         }
        !          1000: 
        !          1001:         NdisReadRegisterUchar(&(BringUpSrb->InitStatus), &RegValue);
        !          1002: 
        !          1003:         if (RegValue & 0x01) {
        !          1004: 
        !          1005: #if DBG
        !          1006:             if (IbmtokDbg) DbgPrint("IBMTOK: 16 Mbps\n");
        !          1007: #endif
        !          1008: 
        !          1009:             Adapter->Running16Mbps = TRUE;
        !          1010: 
        !          1011:         } else {
        !          1012: 
        !          1013:             Adapter->Running16Mbps = FALSE;
        !          1014: 
        !          1015:         }
        !          1016: 
        !          1017:         //
        !          1018:         // ZZZ: This code assumes that there is no shared ram paging and
        !          1019:         // that the MappedSharedRam is all that is available.
        !          1020:         //
        !          1021: 
        !          1022: 
        !          1023: #if DBG
        !          1024:         if (IbmtokDbg) DbgPrint( "IBMTOK: shared RAM size is %x (%d)\n", Adapter->MappedSharedRam, Adapter->MappedSharedRam );
        !          1025: #endif
        !          1026:         if (Adapter->MappedSharedRam > 0x2000){
        !          1027: 
        !          1028:             ULONG RamAvailable;
        !          1029:             UCHAR NumTransmitBuffers = (UCHAR)Adapter->NumberOfTransmitBuffers;
        !          1030: 
        !          1031:             //
        !          1032:             // 2096 is the amount of shared ram that is current sucked
        !          1033:             // up by the areas found on page 7-27 of the Tech. Ref.
        !          1034:             //
        !          1035:             //
        !          1036: 
        !          1037:             RamAvailable = Adapter->MappedSharedRam;
        !          1038: 
        !          1039:             if (Adapter->MappedSharedRam == 0x10000){
        !          1040: 
        !          1041:                 //
        !          1042:                 // Subtract an extra 8K to account for when we map
        !          1043:                 // MMIO space to the top 8K of RAM.
        !          1044:                 //
        !          1045: 
        !          1046:                 RamAvailable = RamAvailable - 2096 - 0x2000;
        !          1047: 
        !          1048:             } else {
        !          1049: 
        !          1050:                 RamAvailable = RamAvailable - 1584;
        !          1051: 
        !          1052:             }
        !          1053: #if DBG
        !          1054:             if (IbmtokDbg) DbgPrint( "IBMTOK: RAM available is %x (%d)\n", RamAvailable, RamAvailable );
        !          1055: #endif
        !          1056: 
        !          1057:             //
        !          1058:             // The card has more than 8K of ram, so adjust
        !          1059:             // transmit buffer size to abuse this.
        !          1060:             //
        !          1061: 
        !          1062:             if (Adapter->Running16Mbps) {
        !          1063: 
        !          1064:                 //
        !          1065:                 // Use the maximum allowed
        !          1066:                 //
        !          1067: 
        !          1068:                 Adapter->TransmitBufferLength = Adapter->Max16MbpsDhb;
        !          1069: #if DBG
        !          1070:                 if (IbmtokDbg) DbgPrint( "IBMTOK: 16 MB ring. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1071: #endif
        !          1072: 
        !          1073:             } else {
        !          1074: 
        !          1075:                 //
        !          1076:                 // Use the maximum allowed
        !          1077:                 //
        !          1078:                 Adapter->TransmitBufferLength = Adapter->Max4MbpsDhb;
        !          1079: #if DBG
        !          1080:                 if (IbmtokDbg) DbgPrint( "IBMTOK: 4 MB ring. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1081: #endif
        !          1082: 
        !          1083:             }
        !          1084: 
        !          1085:             //
        !          1086:             // First we subtract off buffer space for receiving the
        !          1087:             // maximum sized packet that can be on the wire.  This is
        !          1088:             // the *minimum* number of receive buffers and may be
        !          1089:             // modified below if the transmit space does not take up
        !          1090:             // the rest.
        !          1091:             //
        !          1092: 
        !          1093: #if DBG
        !          1094:             if (IbmtokDbg) DbgPrint( "IBMTOK: Receive buffer length is %x (%d)\n", Adapter->ReceiveBufferLength, Adapter->ReceiveBufferLength );
        !          1095: #endif
        !          1096:             if (RamAvailable < Adapter->TransmitBufferLength) {
        !          1097: 
        !          1098:                 //
        !          1099:                 // There is not enough buffer space for even a single maximum
        !          1100:                 // sized frame.  So, just divide the buffer space into two
        !          1101:                 // equally sized areas -- receive and transmit.
        !          1102:                 //
        !          1103: 
        !          1104:                 Adapter->NumberOfReceiveBuffers = (USHORT)((RamAvailable / 2) /
        !          1105:                                                            Adapter->ReceiveBufferLength)
        !          1106:                                                            + 1;
        !          1107: #if DBG
        !          1108:                 if (IbmtokDbg) DbgPrint( "IBMTOK: RAM too small. # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers );
        !          1109: #endif
        !          1110: 
        !          1111:             } else {
        !          1112: 
        !          1113:                 Adapter->NumberOfReceiveBuffers = (USHORT)(Adapter->TransmitBufferLength /
        !          1114:                                          Adapter->ReceiveBufferLength) + 1;
        !          1115: #if DBG
        !          1116:                 if (IbmtokDbg) DbgPrint( "IBMTOK: RAM large enough. # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers );
        !          1117: #endif
        !          1118: 
        !          1119:             }
        !          1120: 
        !          1121:             RamAvailable = RamAvailable -
        !          1122:                               (Adapter->NumberOfReceiveBuffers * Adapter->ReceiveBufferLength);
        !          1123: #if DBG
        !          1124:             if (IbmtokDbg) {
        !          1125:                 DbgPrint( "IBMTOK: RAM available for transmit is %x (%d)\n", RamAvailable, RamAvailable );
        !          1126:                 DbgPrint( "IBMTOK: # transmit buffers is %x (%d)\n", NumTransmitBuffers, NumTransmitBuffers );
        !          1127:             }
        !          1128: #endif
        !          1129: 
        !          1130:             if (Adapter->TransmitBufferLength > (RamAvailable / NumTransmitBuffers)) {
        !          1131: 
        !          1132:                 if ((RamAvailable / NumTransmitBuffers) < 0x1000) {
        !          1133: 
        !          1134:                     Adapter->TransmitBufferLength = 0x800;
        !          1135: 
        !          1136:                 } else if ((RamAvailable / NumTransmitBuffers) < 0x2000) {
        !          1137: 
        !          1138:                     Adapter->TransmitBufferLength = 0x1000;
        !          1139: 
        !          1140:                 } else if ((RamAvailable / NumTransmitBuffers) < 0x4000) {
        !          1141: 
        !          1142:                     Adapter->TransmitBufferLength = 0x2000;
        !          1143: 
        !          1144:                 } else {
        !          1145: 
        !          1146:                     Adapter->TransmitBufferLength = 0x4000;
        !          1147: 
        !          1148:                 }
        !          1149: 
        !          1150: #if DBG
        !          1151:                 if (IbmtokDbg) DbgPrint( "IBMTOK: RAM too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1152: #endif
        !          1153:             }
        !          1154: 
        !          1155: 
        !          1156:             //
        !          1157:             // If computed value is greater than the value that the
        !          1158:             // registry allows, then use the registry value.
        !          1159:             //
        !          1160: 
        !          1161: #if DBG
        !          1162:             if (IbmtokDbg) DbgPrint( "IBMTOK: Original max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket );
        !          1163: #endif
        !          1164:             if (Adapter->TransmitBufferLength > Adapter->MaxTransmittablePacket) {
        !          1165: 
        !          1166:                 Adapter->TransmitBufferLength = Adapter->MaxTransmittablePacket;
        !          1167: #if DBG
        !          1168:                 if (IbmtokDbg) DbgPrint( "IBMTOK: Max too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1169: #endif
        !          1170: 
        !          1171:             }
        !          1172: 
        !          1173:             Adapter->MaxTransmittablePacket = Adapter->TransmitBufferLength - 6;
        !          1174: #if DBG
        !          1175:             if (IbmtokDbg) DbgPrint( "IBMTOK: New max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket );
        !          1176: #endif
        !          1177: 
        !          1178:             //
        !          1179:             // Remove space taken up by transmit buffers.
        !          1180:             //
        !          1181: 
        !          1182:             RamAvailable = RamAvailable - ((ULONG)NumTransmitBuffers *
        !          1183:                                    (ULONG)Adapter->TransmitBufferLength);
        !          1184: 
        !          1185:             //
        !          1186:             // Add in any left over space for receive buffers.
        !          1187:             //
        !          1188: 
        !          1189:             Adapter->NumberOfReceiveBuffers += (USHORT)(RamAvailable /
        !          1190:                                          Adapter->ReceiveBufferLength);
        !          1191: #if DBG
        !          1192:             if (IbmtokDbg) DbgPrint( "IBMTOK: New # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers );
        !          1193: #endif
        !          1194: 
        !          1195:         } else {
        !          1196: 
        !          1197:             Adapter->TransmitBufferLength = 0x800;
        !          1198:             Adapter->NumberOfTransmitBuffers = 1;
        !          1199: #if DBG
        !          1200:             if (IbmtokDbg) {
        !          1201:                 DbgPrint( "IBMTOK: Only 8K shared RAM. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1202:                 DbgPrint( "IBMTOK: Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1203:             }
        !          1204: #endif
        !          1205: 
        !          1206:             //
        !          1207:             // There is only 8K of buffer space, which is not enough space for
        !          1208:             // receiving and transmitting packets on even a 4Mbit ring.  So,
        !          1209:             // use some reasonable values for transmit and receive space.
        !          1210:             //
        !          1211: 
        !          1212:             // If computed value is greater than the value that the
        !          1213:             // registry allows, then use the registry value.
        !          1214:             //
        !          1215: 
        !          1216: #if DBG
        !          1217:             if (IbmtokDbg) DbgPrint( "IBMTOK: Original max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket );
        !          1218: #endif
        !          1219:             if (Adapter->TransmitBufferLength > Adapter->MaxTransmittablePacket) {
        !          1220: 
        !          1221:                 Adapter->TransmitBufferLength = Adapter->MaxTransmittablePacket;
        !          1222: #if DBG
        !          1223:                 if (IbmtokDbg) DbgPrint( "IBMTOK: Max too small. Transmit buffer length is %x (%d)\n", Adapter->TransmitBufferLength, Adapter->TransmitBufferLength );
        !          1224: #endif
        !          1225: 
        !          1226:             }
        !          1227: 
        !          1228:             Adapter->MaxTransmittablePacket = Adapter->TransmitBufferLength - 6;
        !          1229: 
        !          1230:             Adapter->NumberOfReceiveBuffers = 15;
        !          1231: #if DBG
        !          1232:             if (IbmtokDbg) {
        !          1233:                 DbgPrint( "IBMTOK: New max transmit length is %x (%d)\n", Adapter->MaxTransmittablePacket, Adapter->MaxTransmittablePacket );
        !          1234:                 DbgPrint( "IBMTOK: # receive buffers is %x (%d)\n", Adapter->NumberOfReceiveBuffers, Adapter->NumberOfReceiveBuffers );
        !          1235:             }
        !          1236: #endif
        !          1237: 
        !          1238:         }
        !          1239: 
        !          1240: #if DBG
        !          1241:         if (IbmtokDbg) {
        !          1242:             DbgPrint("IBMTOK: Space: 0x%x, # Rcv: 0x%x, TransmitSize: 0x%x\n",
        !          1243:                  Adapter->RrrLowValue,
        !          1244:                  Adapter->NumberOfReceiveBuffers,
        !          1245:                  Adapter->MaxTransmittablePacket
        !          1246:                 );
        !          1247:         }
        !          1248: #endif
        !          1249: 
        !          1250:         NdisReadRegisterUshort(&(BringUpSrb->EncodedAddressPointer), &RegValue);
        !          1251: 
        !          1252:         EncodedAddress = (PUCHAR)
        !          1253:             SRAM_PTR_TO_PVOID(Adapter,RegValue);
        !          1254: 
        !          1255:         IBMTOK_MOVE_FROM_MAPPED_MEMORY(Adapter->PermanentNetworkAddress, EncodedAddress,
        !          1256:                                     TR_LENGTH_OF_ADDRESS);
        !          1257: 
        !          1258: 
        !          1259:         if ((Adapter->NetworkAddress[0] == 0x00) &&
        !          1260:             (Adapter->NetworkAddress[1] == 0x00) &&
        !          1261:             (Adapter->NetworkAddress[2] == 0x00) &&
        !          1262:             (Adapter->NetworkAddress[3] == 0x00) &&
        !          1263:             (Adapter->NetworkAddress[4] == 0x00) &&
        !          1264:             (Adapter->NetworkAddress[5] == 0x00)) {
        !          1265: 
        !          1266: 
        !          1267:             IBMTOK_MOVE_FROM_MAPPED_MEMORY(Adapter->NetworkAddress, EncodedAddress,
        !          1268:                                     TR_LENGTH_OF_ADDRESS);
        !          1269:         }
        !          1270: 
        !          1271:         //
        !          1272:         // If required, we have to zero the upper section
        !          1273:         // of the Shared RAM now.
        !          1274:         //
        !          1275:         //
        !          1276:         // THIS DOESN'T WORK! It hangs the system while
        !          1277:         // zeroing the first address. (One gets an infinite number of
        !          1278:         // hardware interrupts w/o any reason)
        !          1279:         //
        !          1280: 
        !          1281: #if 0
        !          1282:         if (Adapter->UpperSharedRamZero) {
        !          1283: 
        !          1284:             PUCHAR ZeroPointer;
        !          1285:             UINT i;
        !          1286:             PUCHAR OldSharedRam;
        !          1287:             NDIS_PHYSICAL_ADDRESS PhysicalAddress;
        !          1288: 
        !          1289: #if DBG
        !          1290:             if (IbmtokDbg) DbgPrint("IBMTOK: Zeroing Memory\n");
        !          1291: #endif
        !          1292: 
        !          1293: 
        !          1294:             if (Adapter->MappedSharedRam < 0x10000) {
        !          1295: 
        !          1296:                 //
        !          1297:                 // This portion of memory is not currently mapped, so do it.
        !          1298:                 //
        !          1299: 
        !          1300:                 OldSharedRam = Adapter->SharedRam;
        !          1301: 
        !          1302:                 NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
        !          1303:                 NdisSetPhysicalAddressLow(PhysicalAddress, (Adapter->RrrLowValue << 12) + (0x10000 - 512));
        !          1304: 
        !          1305:                 NdisMapIoSpace(
        !          1306:                    &Status,
        !          1307:                    &(Adapter->SharedRam),
        !          1308:                    Adapter->NdisAdapterHandle,
        !          1309:                    PhysicalAddress,
        !          1310:                    512);
        !          1311: 
        !          1312:                 if (Status != NDIS_STATUS_SUCCESS) {
        !          1313: 
        !          1314:                     NdisWriteErrorLogEntry(
        !          1315:                         Adapter->NdisAdapterHandle,
        !          1316:                         NDIS_ERROR_CODE_RESOURCE_CONFLICT,
        !          1317:                         0
        !          1318:                         );
        !          1319: 
        !          1320:                     return(Status);
        !          1321: 
        !          1322:                 }
        !          1323: 
        !          1324:             }
        !          1325: 
        !          1326:             if (Adapter->SharedRamPaging){
        !          1327: 
        !          1328:                 SETUP_SRPR(Adapter, SHARED_RAM_ZERO_OFFSET);
        !          1329: 
        !          1330: #if DBG
        !          1331:                 if (IbmtokDbg) DbgPrint("IBMTOK: Shared RAM paging enabled\n");
        !          1332: #endif
        !          1333: 
        !          1334:                 ZeroPointer =
        !          1335:                     SHARED_RAM_ADDRESS(Adapter,
        !          1336:                         SHARED_RAM_LOW_BITS(SHARED_RAM_ZERO_OFFSET));
        !          1337: 
        !          1338:             } else {
        !          1339: 
        !          1340:                 if (Adapter->MappedSharedRam < 0x10000) {
        !          1341: 
        !          1342:                     //
        !          1343:                     // No offset for this portion, since we just mapped it.
        !          1344:                     //
        !          1345:                     //
        !          1346: 
        !          1347:                     ZeroPointer = SHARED_RAM_ADDRESS(Adapter, 0);
        !          1348: 
        !          1349:                 } else {
        !          1350: 
        !          1351:                     ZeroPointer =
        !          1352:                       SHARED_RAM_ADDRESS(Adapter, SHARED_RAM_ZERO_OFFSET);
        !          1353: 
        !          1354:                 }
        !          1355: 
        !          1356:             }
        !          1357: 
        !          1358:             for (i=0; i<SHARED_RAM_ZERO_LENGTH; i++) {
        !          1359: 
        !          1360:                 NdisWriteRegisterUchar(&(ZeroPointer[i]), 0x00);
        !          1361: 
        !          1362:             }
        !          1363: 
        !          1364:             if (Adapter->MappedSharedRam < 0x10000) {
        !          1365: 
        !          1366:                 //
        !          1367:                 // Unmap it
        !          1368:                 //
        !          1369: 
        !          1370:                 NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          1371:                              Adapter->SharedRam,
        !          1372:                              512);
        !          1373: 
        !          1374:                 Adapter->SharedRam = OldSharedRam;
        !          1375: 
        !          1376:             }
        !          1377: 
        !          1378:         }
        !          1379: #endif
        !          1380: 
        !          1381: 
        !          1382:         //
        !          1383:         // Now set the timer to the maximum...we still need it
        !          1384:         // as a card heartbeat.
        !          1385:         //
        !          1386: 
        !          1387:         WRITE_ADAPTER_REGISTER(Adapter, TVR_HIGH, 0xff);
        !          1388: 
        !          1389:         return NDIS_STATUS_SUCCESS;
        !          1390: 
        !          1391:     }
        !          1392: 
        !          1393: }
        !          1394: 
        !          1395: STATIC
        !          1396: NDIS_STATUS
        !          1397: IbmtokOpenAdapter(
        !          1398:     OUT PNDIS_STATUS OpenErrorStatus,
        !          1399:     OUT NDIS_HANDLE *MacBindingHandle,
        !          1400:     OUT PUINT SelectedMediumIndex,
        !          1401:     IN PNDIS_MEDIUM MediumArray,
        !          1402:     IN UINT MediumArraySize,
        !          1403:     IN NDIS_HANDLE NdisBindingContext,
        !          1404:     IN NDIS_HANDLE MacAdapterContext,
        !          1405:     IN UINT OpenOptions,
        !          1406:     IN PSTRING AddressingInformation OPTIONAL
        !          1407:     )
        !          1408: 
        !          1409: /*++
        !          1410: 
        !          1411: Routine Description:
        !          1412: 
        !          1413:     OpenErrorStatus - Returns more information about the error status.  In
        !          1414:     this card it is not used, since this code returns either success or
        !          1415:     pending, no failure is possible.
        !          1416: 
        !          1417:     This routine is used to create an open instance of an adapter, in effect
        !          1418:     creating a binding between an upper-level module and the MAC module over
        !          1419:     the adapter.
        !          1420: 
        !          1421: Arguments:
        !          1422: 
        !          1423:     OpenErrorStatus - Returns more information about the error status.  In
        !          1424:     this card it is not used, since this code returns either success or
        !          1425:     pending, no failure is possible.
        !          1426: 
        !          1427:     MacBindingHandle - A pointer to a location in which the MAC stores
        !          1428:     a context value that it uses to represent this binding.
        !          1429: 
        !          1430: 
        !          1431:     SelectedMediumIndex - An index into the MediumArray of the medium
        !          1432:     typedef that the MAC wishes to viewed as.
        !          1433: 
        !          1434:     MediumArray - An array of medium types which the protocol supports.
        !          1435: 
        !          1436:     MediumArraySize - The number of elements in MediumArray.
        !          1437: 
        !          1438:     NdisBindingContext - A value to be recorded by the MAC and passed as
        !          1439:     context whenever an indication is delivered by the MAC for this binding.
        !          1440: 
        !          1441:     MacAdapterContext - The value associated with the adapter that is being
        !          1442:     opened when the MAC registered the adapter with NdisRegisterAdapter.
        !          1443: 
        !          1444:     IN UINT OpenOptions,
        !          1445: 
        !          1446:     AddressingInformation - An optional pointer to a variable length string
        !          1447:     containing hardware-specific information that can be used to program the
        !          1448:     device.  (This is not used by this MAC.)
        !          1449: 
        !          1450: Return Value:
        !          1451: 
        !          1452:     The function value is the status of the operation.  If the MAC does not
        !          1453:     complete this request synchronously, the value would be
        !          1454:     NDIS_STATUS_PENDING.
        !          1455: 
        !          1456: 
        !          1457: --*/
        !          1458: 
        !          1459: {
        !          1460: 
        !          1461:     //
        !          1462:     // The IBMTOK_ADAPTER that this open binding should belong too.
        !          1463:     //
        !          1464:     PIBMTOK_ADAPTER Adapter;
        !          1465: 
        !          1466:     //
        !          1467:     // Holds the status that should be returned to the caller.
        !          1468:     //
        !          1469:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          1470: 
        !          1471:     //
        !          1472:     // Pointer to the space allocated for the binding.
        !          1473:     //
        !          1474:     PIBMTOK_OPEN NewOpen;
        !          1475: 
        !          1476:     //
        !          1477:     // Generic loop variable
        !          1478:     //
        !          1479:     UINT i;
        !          1480: 
        !          1481: 
        !          1482:     UNREFERENCED_PARAMETER(AddressingInformation);
        !          1483: 
        !          1484:     *OpenErrorStatus = (NDIS_STATUS)0;
        !          1485: 
        !          1486:     //
        !          1487:     // Search for the medium type (token ring)
        !          1488:     //
        !          1489: 
        !          1490:     for(i=0; i < MediumArraySize; i++){
        !          1491: 
        !          1492:         if (MediumArray[i] == NdisMedium802_5){
        !          1493: 
        !          1494:             break;
        !          1495: 
        !          1496:         }
        !          1497: 
        !          1498:     }
        !          1499: 
        !          1500:     if (i == MediumArraySize){
        !          1501: 
        !          1502:         return(NDIS_STATUS_UNSUPPORTED_MEDIA);
        !          1503: 
        !          1504:     }
        !          1505: 
        !          1506:     *SelectedMediumIndex = i;
        !          1507: 
        !          1508:     Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
        !          1509: 
        !          1510:     NdisInterlockedAddUlong((PULONG)&Adapter->References, 1, &Adapter->Lock);
        !          1511: 
        !          1512:     //
        !          1513:     // Allocate the space for the open binding.  Fill in the fields.
        !          1514:     //
        !          1515: 
        !          1516:     if (IBMTOK_ALLOC_PHYS(&NewOpen, sizeof(IBMTOK_OPEN)) ==
        !          1517:         NDIS_STATUS_SUCCESS){
        !          1518: 
        !          1519:         *MacBindingHandle = BINDING_HANDLE_FROM_PIBMTOK_OPEN(NewOpen);
        !          1520:         InitializeListHead(&NewOpen->OpenList);
        !          1521:         NewOpen->NdisBindingContext = NdisBindingContext;
        !          1522:         NewOpen->References = 0;
        !          1523:         NewOpen->BindingShuttingDown = FALSE;
        !          1524:         NewOpen->OwningIbmtok = Adapter;
        !          1525:         NewOpen->OpenPending = FALSE;
        !          1526: 
        !          1527:         NdisAcquireSpinLock(&Adapter->Lock);
        !          1528:         if (!TrNoteFilterOpenAdapter(
        !          1529:                                      NewOpen->OwningIbmtok->FilterDB,
        !          1530:                                      NewOpen,
        !          1531:                                      NdisBindingContext,
        !          1532:                                      &NewOpen->NdisFilterHandle
        !          1533:                                      )) {
        !          1534: 
        !          1535:             NdisReleaseSpinLock(&Adapter->Lock);
        !          1536: 
        !          1537:             NdisWriteErrorLogEntry(
        !          1538:                 Adapter->NdisAdapterHandle,
        !          1539:                 NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1540:                 2,
        !          1541:                 openAdapter,
        !          1542:                 IBMTOK_ERRMSG_OPEN_DB
        !          1543:                 );
        !          1544: 
        !          1545:             IBMTOK_FREE_PHYS(NewOpen, sizeof(IBMTOK_OPEN));
        !          1546: 
        !          1547:             StatusToReturn = NDIS_STATUS_FAILURE;
        !          1548:             NdisAcquireSpinLock(&Adapter->Lock);
        !          1549: 
        !          1550:         } else {
        !          1551: 
        !          1552:             //
        !          1553:             // Everything has been filled in.  Synchronize access to the
        !          1554:             // adapter block and link the new open adapter in and increment
        !          1555:             // the opens reference count to account for the fact that the
        !          1556:             // filter routines have a "reference" to the open.
        !          1557:             //
        !          1558: 
        !          1559:             NewOpen->LookAhead = IBMTOK_MAX_LOOKAHEAD;
        !          1560: 
        !          1561:             Adapter->LookAhead = IBMTOK_MAX_LOOKAHEAD;
        !          1562: 
        !          1563:             InsertTailList(&Adapter->OpenBindings,&NewOpen->OpenList);
        !          1564:             NewOpen->References++;
        !          1565: 
        !          1566:             //
        !          1567:             // Now see if the adapter is currently open.
        !          1568:             //
        !          1569: 
        !          1570:             if (Adapter->AdapterNotOpen) {
        !          1571: 
        !          1572:                 //
        !          1573:                 // The adapter is not open, so this has to pend.
        !          1574:                 //
        !          1575:                 NewOpen->OpenPending = TRUE;
        !          1576: 
        !          1577:                 StatusToReturn = NDIS_STATUS_PENDING;
        !          1578: 
        !          1579:                 if (!Adapter->OpenInProgress) {
        !          1580: 
        !          1581:                     //
        !          1582:                     // Fill in the SRB for the open if this is the first
        !          1583:                     // one for the card.
        !          1584:                     //
        !          1585: 
        !          1586:                     PSRB_OPEN_ADAPTER OpenSrb;
        !          1587: 
        !          1588:                     IF_LOG('o');
        !          1589: 
        !          1590:                     Adapter->OpenInProgress = TRUE;
        !          1591:                     Adapter->CurrentRingState = NdisRingStateOpening;
        !          1592: 
        !          1593:                     NdisReleaseSpinLock(&Adapter->Lock);
        !          1594: 
        !          1595:                     OpenSrb = (PSRB_OPEN_ADAPTER)
        !          1596:                              (Adapter->SharedRam + Adapter->InitialWrbOffset);
        !          1597: 
        !          1598:                     IBMTOK_ZERO_MAPPED_MEMORY(OpenSrb, sizeof(SRB_OPEN_ADAPTER));
        !          1599: 
        !          1600:                     NdisWriteRegisterUchar(
        !          1601:                                 (PUCHAR)&OpenSrb->Command,
        !          1602:                                 SRB_CMD_OPEN_ADAPTER);
        !          1603:                     NdisWriteRegisterUshort(
        !          1604:                                 (PUSHORT)&OpenSrb->OpenOptions,
        !          1605:                                 OPEN_CONTENDER);
        !          1606: 
        !          1607:                     for (i=0; i < TR_LENGTH_OF_ADDRESS; i++) {
        !          1608:                         NdisWriteRegisterUchar((PCHAR)&OpenSrb->NodeAddress[i],
        !          1609:                                                 Adapter->NetworkAddress[i]
        !          1610:                                                 );
        !          1611:                     }
        !          1612: 
        !          1613:                     WRITE_IBMSHORT(OpenSrb->ReceiveBufferNum,
        !          1614:                                             Adapter->NumberOfReceiveBuffers);
        !          1615:                     WRITE_IBMSHORT(OpenSrb->ReceiveBufferLen,
        !          1616:                                             Adapter->ReceiveBufferLength);
        !          1617: 
        !          1618:                     WRITE_IBMSHORT(OpenSrb->TransmitBufferLen,
        !          1619:                                             Adapter->TransmitBufferLength);
        !          1620:                     NdisWriteRegisterUchar(
        !          1621:                                 (PUCHAR)&OpenSrb->TransmitBufferNum,
        !          1622:                                 (UCHAR)Adapter->NumberOfTransmitBuffers);
        !          1623: 
        !          1624:                     WRITE_ADAPTER_REGISTER(Adapter, ISRA_HIGH_SET,
        !          1625:                                         ISRA_HIGH_COMMAND_IN_SRB);
        !          1626: 
        !          1627:                     NdisAcquireSpinLock(&Adapter->Lock);
        !          1628: 
        !          1629:                 }
        !          1630: 
        !          1631:             }
        !          1632: 
        !          1633:         }
        !          1634: 
        !          1635:     } else {
        !          1636: 
        !          1637:         NdisWriteErrorLogEntry(
        !          1638:             Adapter->NdisAdapterHandle,
        !          1639:             NDIS_ERROR_CODE_OUT_OF_RESOURCES,
        !          1640:             2,
        !          1641:             openAdapter,
        !          1642:             IBMTOK_ERRMSG_ALLOC_MEM
        !          1643:             );
        !          1644: 
        !          1645:         return(NDIS_STATUS_RESOURCES);
        !          1646: 
        !          1647:     }
        !          1648: 
        !          1649: 
        !          1650: 
        !          1651: 
        !          1652:     //
        !          1653:     // This macro assumes it is called with the lock held,
        !          1654:     // and releases it.
        !          1655:     //
        !          1656: 
        !          1657:     IBMTOK_DO_DEFERRED(Adapter);
        !          1658:     return StatusToReturn;
        !          1659: }
        !          1660: 
        !          1661: VOID
        !          1662: IbmtokAdjustMaxLookAhead(
        !          1663:     IN PIBMTOK_ADAPTER Adapter
        !          1664:     )
        !          1665: /*++
        !          1666: 
        !          1667: Routine Description:
        !          1668: 
        !          1669:     This routine finds the open with the maximum lookahead value and
        !          1670:     stores that in the adapter block.
        !          1671: 
        !          1672: Arguments:
        !          1673: 
        !          1674:     Adapter - A pointer to the adapter block.
        !          1675: 
        !          1676: Returns:
        !          1677: 
        !          1678:     None.
        !          1679: 
        !          1680: --*/
        !          1681: {
        !          1682:     ULONG CurrentMax = 0;
        !          1683:     PLIST_ENTRY CurrentLink;
        !          1684:     PIBMTOK_OPEN TempOpen;
        !          1685: 
        !          1686:     CurrentLink = Adapter->OpenBindings.Flink;
        !          1687: 
        !          1688:     while (CurrentLink != &(Adapter->OpenBindings)){
        !          1689: 
        !          1690:         TempOpen = CONTAINING_RECORD(
        !          1691:                              CurrentLink,
        !          1692:                              IBMTOK_OPEN,
        !          1693:                              OpenList
        !          1694:                              );
        !          1695: 
        !          1696:         if (TempOpen->LookAhead > CurrentMax) {
        !          1697: 
        !          1698:             CurrentMax = TempOpen->LookAhead;
        !          1699: 
        !          1700:         }
        !          1701: 
        !          1702:         CurrentLink = CurrentLink->Flink;
        !          1703: 
        !          1704:     }
        !          1705: 
        !          1706:     if (CurrentMax == 0) {
        !          1707: 
        !          1708:         CurrentMax = IBMTOK_MAX_LOOKAHEAD;
        !          1709: 
        !          1710:     }
        !          1711: 
        !          1712:     Adapter->LookAhead = CurrentMax;
        !          1713: 
        !          1714: }
        !          1715: 
        !          1716: STATIC
        !          1717: NDIS_STATUS
        !          1718: IbmtokCloseAdapter(
        !          1719:     IN NDIS_HANDLE MacBindingHandle
        !          1720:     )
        !          1721: 
        !          1722: /*++
        !          1723: 
        !          1724: Routine Description:
        !          1725: 
        !          1726:     This routine causes the MAC to close an open handle (binding).
        !          1727: 
        !          1728: Arguments:
        !          1729: 
        !          1730:     MacBindingHandle - The context value returned by the MAC when the
        !          1731:     adapter was opened.  In reality it is a PIBMTOK_OPEN.
        !          1732: 
        !          1733: Return Value:
        !          1734: 
        !          1735:     The function value is the status of the operation.
        !          1736: 
        !          1737: 
        !          1738: --*/
        !          1739: 
        !          1740: {
        !          1741: 
        !          1742:     PIBMTOK_ADAPTER Adapter;
        !          1743:     PIBMTOK_OPEN Open;
        !          1744: 
        !          1745:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          1746: 
        !          1747:     Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          1748:     Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          1749: 
        !          1750:     //
        !          1751:     // Hold the lock while we update the reference counts for the
        !          1752:     // adapter and the open.
        !          1753:     //
        !          1754: 
        !          1755:     NdisAcquireSpinLock(&Adapter->Lock);
        !          1756:     Adapter->References++;
        !          1757: 
        !          1758:     if (!Open->BindingShuttingDown) {
        !          1759: 
        !          1760:         Open->References++;
        !          1761: 
        !          1762:         StatusToReturn = TrDeleteFilterOpenAdapter(
        !          1763:                              Adapter->FilterDB,
        !          1764:                              Open->NdisFilterHandle,
        !          1765:                              NULL
        !          1766:                              );
        !          1767: 
        !          1768:         //
        !          1769:         // If the status is successful that merely implies that
        !          1770:         // we were able to delete the reference to the open binding
        !          1771:         // from the filtering code.  If we have a successful status
        !          1772:         // at this point we still need to check whether the reference
        !          1773:         // count to determine whether we can close.
        !          1774:         //
        !          1775:         //
        !          1776:         // The delete filter routine can return a "special" status
        !          1777:         // that indicates that there is a current NdisIndicateReceive
        !          1778:         // on this binding.
        !          1779:         //
        !          1780: 
        !          1781: 
        !          1782:         if (StatusToReturn == NDIS_STATUS_SUCCESS) {
        !          1783: 
        !          1784:             //
        !          1785:             // Check whether the reference count is two.  If
        !          1786:             // it is then we can get rid of the memory for
        !          1787:             // this open.
        !          1788:             //
        !          1789:             // A count of two indicates one for this routine
        !          1790:             // and one for the filter which we *know* we can
        !          1791:             // get rid of.
        !          1792:             //
        !          1793: 
        !          1794:             if (Open->References == 2) {
        !          1795: 
        !          1796:                 RemoveEntryList(&Open->OpenList);
        !          1797: 
        !          1798:                 //
        !          1799:                 // We are the only reference to the open.  Remove
        !          1800:                 // it from the open list and delete the memory.
        !          1801:                 //
        !          1802: 
        !          1803:                 RemoveEntryList(&Open->OpenList);
        !          1804: 
        !          1805:                 if (Open->LookAhead == Adapter->LookAhead) {
        !          1806: 
        !          1807:                     IbmtokAdjustMaxLookAhead(Adapter);
        !          1808: 
        !          1809:                 }
        !          1810: 
        !          1811:                 IBMTOK_FREE_PHYS(Open,sizeof(IBMTOK_OPEN));
        !          1812: 
        !          1813:             } else {
        !          1814: 
        !          1815:                 Open->BindingShuttingDown = TRUE;
        !          1816: 
        !          1817:                 //
        !          1818:                 // Remove the open from the open list and put it on
        !          1819:                 // the closing list.
        !          1820:                 //
        !          1821: 
        !          1822:                 RemoveEntryList(&Open->OpenList);
        !          1823:                 InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          1824: 
        !          1825:                 //
        !          1826:                 // Account for this routines reference to the open
        !          1827:                 // as well as reference because of the filtering.
        !          1828:                 //
        !          1829: 
        !          1830:                 Open->References -= 2;
        !          1831: 
        !          1832:                 //
        !          1833:                 // Change the status to indicate that we will
        !          1834:                 // be closing this later.
        !          1835:                 //
        !          1836: 
        !          1837:                 StatusToReturn = NDIS_STATUS_PENDING;
        !          1838: 
        !          1839:             }
        !          1840: 
        !          1841:         } else if (StatusToReturn == NDIS_STATUS_PENDING) {
        !          1842: 
        !          1843: 
        !          1844:             //
        !          1845:             // If it pended, there may be
        !          1846:             // operations queued.
        !          1847:             //
        !          1848: 
        !          1849:             IbmtokProcessSrbRequests(Adapter);
        !          1850: 
        !          1851:             //
        !          1852:             // Now start closing down this open.
        !          1853:             //
        !          1854: 
        !          1855:             Open->BindingShuttingDown = TRUE;
        !          1856: 
        !          1857:             //
        !          1858:             // Remove the open from the open list and put it on
        !          1859:             // the closing list.
        !          1860:             //
        !          1861: 
        !          1862:             RemoveEntryList(&Open->OpenList);
        !          1863:             InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          1864: 
        !          1865:             //
        !          1866:             // Account for this routines reference to the open
        !          1867:             // as well as reference because of the filtering.
        !          1868:             //
        !          1869: 
        !          1870:             Open->References -= 2;
        !          1871: 
        !          1872:         } else if (StatusToReturn == NDIS_STATUS_CLOSING_INDICATING) {
        !          1873: 
        !          1874:             //
        !          1875:             // When we have this status it indicates that the filtering
        !          1876:             // code was currently doing an NdisIndicateReceive.  It
        !          1877:             // would not be wise to delete the memory for the open at
        !          1878:             // this point.  The filtering code will call our close action
        !          1879:             // routine upon return from NdisIndicateReceive and that
        !          1880:             // action routine will decrement the reference count for
        !          1881:             // the open.
        !          1882:             //
        !          1883: 
        !          1884:             Open->BindingShuttingDown = TRUE;
        !          1885: 
        !          1886:             //
        !          1887:             // This status is private to the filtering routine.  Just
        !          1888:             // tell the caller the the close is pending.
        !          1889:             //
        !          1890: 
        !          1891:             StatusToReturn = NDIS_STATUS_PENDING;
        !          1892: 
        !          1893:             //
        !          1894:             // Remove the open from the open list and put it on
        !          1895:             // the closing list.
        !          1896:             //
        !          1897: 
        !          1898:             RemoveEntryList(&Open->OpenList);
        !          1899:             InsertTailList(&Adapter->CloseList,&Open->OpenList);
        !          1900: 
        !          1901:             //
        !          1902:             // Account for this routines reference to the open.
        !          1903:             //
        !          1904: 
        !          1905:             Open->References--;
        !          1906: 
        !          1907:         } else if (StatusToReturn == NDIS_STATUS_RESET_IN_PROGRESS) {
        !          1908: 
        !          1909:             Open->BindingShuttingDown = TRUE;
        !          1910: 
        !          1911:             //
        !          1912:             // Remove the open from the open list and put it on
        !          1913:             // the closing list.
        !          1914:             //
        !          1915: 
        !          1916:             RemoveEntryList(&Open->OpenList);
        !          1917:             InsertTailList(&Adapter->CloseDuringResetList,&Open->OpenList);
        !          1918: 
        !          1919: 
        !          1920:             //
        !          1921:             // Account for this routines reference to the open.
        !          1922:             //
        !          1923: 
        !          1924:             Open->References--;
        !          1925: 
        !          1926:             StatusToReturn = NDIS_STATUS_PENDING;
        !          1927: 
        !          1928:         } else {
        !          1929: 
        !          1930:             NdisWriteErrorLogEntry(
        !          1931:                 Adapter->NdisAdapterHandle,
        !          1932:                 NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          1933:                 2,
        !          1934:                 IBMTOK_ERRMSG_INVALID_STATUS,
        !          1935:                 1
        !          1936:                 );
        !          1937: 
        !          1938:         }
        !          1939: 
        !          1940:     } else {
        !          1941: 
        !          1942:         StatusToReturn = NDIS_STATUS_CLOSING;
        !          1943: 
        !          1944:     }
        !          1945: 
        !          1946: 
        !          1947:     //
        !          1948:     // This macro assumes it is called with the lock held,
        !          1949:     // and releases it.
        !          1950:     //
        !          1951: 
        !          1952:     IBMTOK_DO_DEFERRED(Adapter);
        !          1953:     return StatusToReturn;
        !          1954: 
        !          1955: }
        !          1956: 
        !          1957: STATIC
        !          1958: NDIS_STATUS
        !          1959: IbmtokRequest(
        !          1960:     IN NDIS_HANDLE MacBindingHandle,
        !          1961:     IN PNDIS_REQUEST NdisRequest
        !          1962:     )
        !          1963: 
        !          1964: /*++
        !          1965: 
        !          1966: Routine Description:
        !          1967: 
        !          1968:     The IbmtokRequest allows a protocol to query and set information
        !          1969:     about the MAC.
        !          1970: 
        !          1971: Arguments:
        !          1972: 
        !          1973:     MacBindingHandle - The context value returned by the MAC when the
        !          1974:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          1975: 
        !          1976:     NdisRequest - A structure which contains the request type (Set or
        !          1977:     Query), an array of operations to perform, and an array for holding
        !          1978:     the results of the operations.
        !          1979: 
        !          1980: Return Value:
        !          1981: 
        !          1982:     The function value is the status of the operation.
        !          1983: 
        !          1984: --*/
        !          1985: 
        !          1986: {
        !          1987:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          1988: 
        !          1989:     PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          1990:     PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          1991: 
        !          1992:     NdisAcquireSpinLock(&(Adapter->Lock));
        !          1993: 
        !          1994:     Adapter->References++;
        !          1995: 
        !          1996:     //
        !          1997:     // Process request
        !          1998:     //
        !          1999: 
        !          2000:     if (NdisRequest->RequestType == NdisRequestQueryInformation) {
        !          2001: 
        !          2002:         StatusToReturn = IbmtokQueryInformation(Adapter, Open, NdisRequest);
        !          2003: 
        !          2004:     } else if (NdisRequest->RequestType == NdisRequestSetInformation) {
        !          2005: 
        !          2006: 
        !          2007:         //
        !          2008:         // Make sure Adapter is in a valid state.
        !          2009:         //
        !          2010: 
        !          2011:         if (Adapter->Unplugged) {
        !          2012: 
        !          2013:             StatusToReturn = NDIS_STATUS_DEVICE_FAILED;
        !          2014: 
        !          2015:         } else if (!Adapter->NotAcceptingRequests) {
        !          2016: 
        !          2017:             //
        !          2018:             // Make sure the open instance is valid
        !          2019:             //
        !          2020: 
        !          2021:             if (!Open->BindingShuttingDown) {
        !          2022: 
        !          2023:                 StatusToReturn = IbmtokSetInformation(Adapter,Open,NdisRequest);
        !          2024: 
        !          2025:             } else {
        !          2026: 
        !          2027:                 StatusToReturn = NDIS_STATUS_CLOSING;
        !          2028: 
        !          2029:             }
        !          2030: 
        !          2031:         } else {
        !          2032: 
        !          2033:             if (Adapter->ResetInProgress) {
        !          2034: 
        !          2035:                 StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
        !          2036: 
        !          2037:             } else if (Adapter->AdapterNotOpen) {
        !          2038: 
        !          2039:                 StatusToReturn = NDIS_STATUS_FAILURE;
        !          2040: 
        !          2041:             } else {
        !          2042: 
        !          2043:                 NdisWriteErrorLogEntry(
        !          2044:                     Adapter->NdisAdapterHandle,
        !          2045:                     NDIS_ERROR_CODE_DRIVER_FAILURE,
        !          2046:                     2,
        !          2047:                     IBMTOK_ERRMSG_INVALID_STATE,
        !          2048:                     3
        !          2049:                     );
        !          2050: 
        !          2051:             }
        !          2052:         }
        !          2053:     } else {
        !          2054: 
        !          2055:         StatusToReturn = NDIS_STATUS_NOT_RECOGNIZED;
        !          2056: 
        !          2057:     }
        !          2058: 
        !          2059:     IBMTOK_DO_DEFERRED(Adapter);
        !          2060: 
        !          2061:     return(StatusToReturn);
        !          2062: 
        !          2063: }
        !          2064: 
        !          2065: STATIC
        !          2066: NDIS_STATUS
        !          2067: IbmtokQueryProtocolInformation(
        !          2068:     IN PIBMTOK_ADAPTER Adapter,
        !          2069:     IN PIBMTOK_OPEN Open,
        !          2070:     IN NDIS_OID Oid,
        !          2071:     IN BOOLEAN GlobalMode,
        !          2072:     IN PVOID  InfoBuffer,
        !          2073:     IN UINT   BytesLeft,
        !          2074:     OUT PUINT BytesNeeded,
        !          2075:     OUT PUINT BytesWritten
        !          2076: )
        !          2077: 
        !          2078: /*++
        !          2079: 
        !          2080: Routine Description:
        !          2081: 
        !          2082:     The IbmtokQueryProtocolInformation process a Query request for
        !          2083:     NDIS_OIDs that are specific to a binding about the MAC.  Note that
        !          2084:     some of the OIDs that are specific to bindings are also queryable
        !          2085:     on a global basis.  Rather than recreate this code to handle the
        !          2086:     global queries, I use a flag to indicate if this is a query for the
        !          2087:     global data or the binding specific data.
        !          2088: 
        !          2089: Arguments:
        !          2090: 
        !          2091:     Adapter - a pointer to the adapter.
        !          2092: 
        !          2093:     Open - a pointer to the open instance.
        !          2094: 
        !          2095:     Oid - the NDIS_OID to process.
        !          2096: 
        !          2097:     GlobalMode - Some of the binding specific information is also used
        !          2098:     when querying global statistics.  This is a flag to specify whether
        !          2099:     to return the global value, or the binding specific value.
        !          2100: 
        !          2101:     InfoBuffer - a pointer into the NdisRequest->InformationBuffer
        !          2102:      into which store the result of the query.
        !          2103: 
        !          2104:     BytesLeft - the number of bytes left in the InformationBuffer.
        !          2105: 
        !          2106:     BytesNeeded - If there is not enough room in the information buffer
        !          2107:     then this will contain the number of bytes needed to complete the
        !          2108:     request.
        !          2109: 
        !          2110:     BytesWritten - a pointer to the number of bytes written into the
        !          2111:     InformationBuffer.
        !          2112: 
        !          2113: Return Value:
        !          2114: 
        !          2115:     The function value is the status of the operation.
        !          2116: 
        !          2117: --*/
        !          2118: 
        !          2119: {
        !          2120:     NDIS_MEDIUM Medium = NdisMedium802_5;
        !          2121:     ULONG GenericULong;
        !          2122:     USHORT GenericUShort;
        !          2123:     UCHAR GenericArray[6];
        !          2124: 
        !          2125:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2126: 
        !          2127:     //
        !          2128:     // Common variables for pointing to result of query
        !          2129:     //
        !          2130: 
        !          2131:     PVOID MoveSource = (PVOID)(&GenericULong);
        !          2132:     ULONG MoveBytes = sizeof(GenericULong);
        !          2133: 
        !          2134:     NDIS_HARDWARE_STATUS HardwareStatus = NdisHardwareStatusReady;
        !          2135: 
        !          2136:     //
        !          2137:     // General Algorithm:
        !          2138:     //
        !          2139:     //      Switch(Request)
        !          2140:     //         Get requested information
        !          2141:     //         Store results in a common variable.
        !          2142:     //      Copy result in common variable to result buffer.
        !          2143:     //
        !          2144: 
        !          2145:     //
        !          2146:     // Switch on request type
        !          2147:     //
        !          2148: 
        !          2149:     switch (Oid) {
        !          2150: 
        !          2151:         case OID_GEN_MAC_OPTIONS:
        !          2152: 
        !          2153:             GenericULong = (ULONG)(NDIS_MAC_OPTION_TRANSFERS_NOT_PEND  |
        !          2154:                                    NDIS_MAC_OPTION_RECEIVE_SERIALIZED
        !          2155:                                   );
        !          2156: 
        !          2157:             break;
        !          2158: 
        !          2159:         case OID_GEN_SUPPORTED_LIST:
        !          2160: 
        !          2161:             if (!GlobalMode){
        !          2162:                 MoveSource = (PVOID)(IbmtokProtocolSupportedOids);
        !          2163:                 MoveBytes = sizeof(IbmtokProtocolSupportedOids);
        !          2164:             } else {
        !          2165:                 MoveSource = (PVOID)(IbmtokGlobalSupportedOids);
        !          2166:                 MoveBytes = sizeof(IbmtokGlobalSupportedOids);
        !          2167:             }
        !          2168:             break;
        !          2169: 
        !          2170:         case OID_GEN_HARDWARE_STATUS:
        !          2171: 
        !          2172: 
        !          2173:             if (Adapter->ResetInProgress){
        !          2174: 
        !          2175:                 HardwareStatus = NdisHardwareStatusReset;
        !          2176: 
        !          2177:             } else if ((Adapter->FirstInitialization) ||
        !          2178:                      (Adapter->OpenInProgress)){
        !          2179: 
        !          2180:                  HardwareStatus = NdisHardwareStatusInitializing;
        !          2181: 
        !          2182:             } else if (Adapter->NotAcceptingRequests){
        !          2183: 
        !          2184:                 HardwareStatus = NdisHardwareStatusNotReady;
        !          2185: 
        !          2186:             } else
        !          2187:                 HardwareStatus = NdisHardwareStatusReady;
        !          2188: 
        !          2189: 
        !          2190:             MoveSource = (PVOID)(&HardwareStatus);
        !          2191:             MoveBytes = sizeof(NDIS_HARDWARE_STATUS);
        !          2192: 
        !          2193:             break;
        !          2194: 
        !          2195:         case OID_GEN_MEDIA_SUPPORTED:
        !          2196:         case OID_GEN_MEDIA_IN_USE:
        !          2197: 
        !          2198:             MoveSource = (PVOID) (&Medium);
        !          2199:             MoveBytes = sizeof(NDIS_MEDIUM);
        !          2200:             break;
        !          2201: 
        !          2202:         case OID_GEN_MAXIMUM_LOOKAHEAD:
        !          2203: 
        !          2204:             GenericULong = IBMTOK_MAX_LOOKAHEAD;
        !          2205: 
        !          2206:             break;
        !          2207: 
        !          2208: 
        !          2209:         case OID_GEN_MAXIMUM_FRAME_SIZE:
        !          2210:         case OID_GEN_MAXIMUM_TOTAL_SIZE:
        !          2211: 
        !          2212:             GenericULong = (ULONG)(Adapter->MaxTransmittablePacket);
        !          2213: 
        !          2214:             if (Oid == OID_GEN_MAXIMUM_FRAME_SIZE) {
        !          2215: 
        !          2216:                 //
        !          2217:                 // For the receive frame size, we subtract the minimum
        !          2218:                 // header size from the number.
        !          2219:                 //
        !          2220: 
        !          2221:                 GenericULong -= 14;
        !          2222:             }
        !          2223: 
        !          2224:             break;
        !          2225: 
        !          2226: 
        !          2227:         case OID_GEN_LINK_SPEED:
        !          2228: 
        !          2229:             GenericULong = (ULONG)(Adapter->Running16Mbps? 160000 : 40000);
        !          2230: 
        !          2231:             break;
        !          2232: 
        !          2233: 
        !          2234:         case OID_GEN_TRANSMIT_BUFFER_SPACE:
        !          2235: 
        !          2236:             GenericULong = (ULONG)(Adapter->NumberOfTransmitBuffers *
        !          2237:                             Adapter->TransmitBufferLength);
        !          2238: 
        !          2239:             break;
        !          2240: 
        !          2241:         case OID_GEN_RECEIVE_BUFFER_SPACE:
        !          2242: 
        !          2243:             GenericULong = (ULONG)(Adapter->NumberOfReceiveBuffers *
        !          2244:                              Adapter->ReceiveBufferLength);
        !          2245: 
        !          2246:             break;
        !          2247: 
        !          2248:         case OID_GEN_TRANSMIT_BLOCK_SIZE:
        !          2249: 
        !          2250:             GenericULong = (ULONG)(Adapter->TransmitBufferLength);
        !          2251: 
        !          2252:             break;
        !          2253: 
        !          2254:         case OID_GEN_RECEIVE_BLOCK_SIZE:
        !          2255: 
        !          2256:             GenericULong = (ULONG)(Adapter->ReceiveBufferLength);
        !          2257: 
        !          2258:             break;
        !          2259: 
        !          2260:         case OID_GEN_VENDOR_ID:
        !          2261: 
        !          2262:             NdisMoveMemory(
        !          2263:                 (PVOID)&GenericULong,
        !          2264:                 Adapter->PermanentNetworkAddress,
        !          2265:                 3
        !          2266:                 );
        !          2267:             GenericULong &= 0xFFFFFF00;
        !          2268: 
        !          2269:             if (Adapter->UsingPcIoBus) {
        !          2270: 
        !          2271:                 GenericULong |= 0x01;
        !          2272: 
        !          2273:             }
        !          2274: 
        !          2275:             MoveSource = (PVOID)(&GenericULong);
        !          2276:             MoveBytes = sizeof(GenericULong);
        !          2277:             break;
        !          2278: 
        !          2279:         case OID_GEN_VENDOR_DESCRIPTION:
        !          2280: 
        !          2281:             if (Adapter->UsingPcIoBus){
        !          2282:                 MoveSource = (PVOID)"Ibm Token Ring Network Card for PC I/O bus.";
        !          2283:                 MoveBytes = 44;
        !          2284:             } else {
        !          2285:                 MoveSource = (PVOID)"Ibm Token Ring Network Card for MCA bus.";
        !          2286:                 MoveBytes = 41;
        !          2287:             }
        !          2288:             break;
        !          2289: 
        !          2290:         case OID_GEN_DRIVER_VERSION:
        !          2291: 
        !          2292:             GenericUShort = (USHORT)((IBMTOK_NDIS_MAJOR_VERSION << 8) | IBMTOK_NDIS_MINOR_VERSION);
        !          2293: 
        !          2294:             MoveSource = (PVOID)(&GenericUShort);
        !          2295:             MoveBytes = sizeof(GenericUShort);
        !          2296:             break;
        !          2297: 
        !          2298: 
        !          2299:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          2300: 
        !          2301:             if (GlobalMode) {
        !          2302: 
        !          2303:                 GenericULong = (ULONG)(Adapter->CurrentPacketFilter);
        !          2304: 
        !          2305:             } else {
        !          2306: 
        !          2307:                 GenericULong = (ULONG)(TR_QUERY_PACKET_FILTER(
        !          2308:                                                  Adapter->FilterDB,
        !          2309:                                                  Open->NdisFilterHandle));
        !          2310: 
        !          2311:             }
        !          2312: 
        !          2313:             break;
        !          2314: 
        !          2315:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          2316: 
        !          2317:             if (!GlobalMode){
        !          2318: 
        !          2319:                 GenericULong = Open->LookAhead;
        !          2320: 
        !          2321:             } else {
        !          2322: 
        !          2323:                 PLIST_ENTRY CurrentLink;
        !          2324:                 PIBMTOK_OPEN TempOpen;
        !          2325: 
        !          2326:                 CurrentLink = Adapter->OpenBindings.Flink;
        !          2327: 
        !          2328:                 GenericULong = 0;
        !          2329: 
        !          2330:                 while (CurrentLink != &(Adapter->OpenBindings)){
        !          2331: 
        !          2332:                     TempOpen = CONTAINING_RECORD(
        !          2333:                              CurrentLink,
        !          2334:                              IBMTOK_OPEN,
        !          2335:                              OpenList
        !          2336:                              );
        !          2337: 
        !          2338:                     if (TempOpen->LookAhead > GenericULong) {
        !          2339: 
        !          2340:                         GenericULong = TempOpen->LookAhead;
        !          2341: 
        !          2342:                         if (GenericULong == IBMTOK_MAX_LOOKAHEAD) {
        !          2343: 
        !          2344:                             break;
        !          2345: 
        !          2346:                         }
        !          2347:                     }
        !          2348: 
        !          2349:                     CurrentLink = CurrentLink->Flink;
        !          2350: 
        !          2351:                 }
        !          2352: 
        !          2353:             }
        !          2354: 
        !          2355:             break;
        !          2356: 
        !          2357:         case OID_802_5_PERMANENT_ADDRESS:
        !          2358: 
        !          2359:             TR_COPY_NETWORK_ADDRESS((PCHAR)GenericArray,
        !          2360:                                     Adapter->PermanentNetworkAddress);
        !          2361: 
        !          2362:             MoveSource = (PVOID)(GenericArray);
        !          2363:             MoveBytes = sizeof(Adapter->PermanentNetworkAddress);
        !          2364: 
        !          2365:             break;
        !          2366: 
        !          2367:         case OID_802_5_CURRENT_ADDRESS:
        !          2368: 
        !          2369:             TR_COPY_NETWORK_ADDRESS((PCHAR)GenericArray,
        !          2370:                                     Adapter->NetworkAddress);
        !          2371: 
        !          2372:             MoveSource = (PVOID)(GenericArray);
        !          2373:             MoveBytes = sizeof(Adapter->NetworkAddress);
        !          2374: 
        !          2375:             break;
        !          2376: 
        !          2377:         case OID_802_5_CURRENT_FUNCTIONAL:
        !          2378: 
        !          2379:             if (!GlobalMode){
        !          2380: 
        !          2381:                 GenericULong = TR_QUERY_FILTER_BINDING_ADDRESS(
        !          2382:                                    Adapter->FilterDB,
        !          2383:                                    Open->NdisFilterHandle);
        !          2384: 
        !          2385:             } else {
        !          2386: 
        !          2387:                 GenericULong = Adapter->CurrentCardFunctional & 0xffffffff;
        !          2388: 
        !          2389:             }
        !          2390: 
        !          2391:             //
        !          2392:             // Now we need to reverse the crazy thing.
        !          2393:             //
        !          2394: 
        !          2395:             GenericULong = (ULONG)(
        !          2396:                                 ((GenericULong >> 24) & 0xFF) |
        !          2397:                                 ((GenericULong >> 8)  & 0xFF00) |
        !          2398:                                 ((GenericULong << 8)  & 0xFF0000) |
        !          2399:                                 ((GenericULong << 24) & 0xFF000000)
        !          2400:                                 );
        !          2401: 
        !          2402:             break;
        !          2403: 
        !          2404:         case OID_802_5_CURRENT_GROUP:
        !          2405: 
        !          2406:             GenericULong = Adapter->CurrentCardGroup & 0xffffffff;
        !          2407: 
        !          2408:             //
        !          2409:             // Now we need to reverse the crazy thing.
        !          2410:             //
        !          2411: 
        !          2412:             GenericULong = (ULONG)(
        !          2413:                                 ((GenericULong >> 24) & 0xFF) |
        !          2414:                                 ((GenericULong >> 8)  & 0xFF00) |
        !          2415:                                 ((GenericULong << 8)  & 0xFF0000) |
        !          2416:                                 ((GenericULong << 24) & 0xFF000000)
        !          2417:                                 );
        !          2418: 
        !          2419:             break;
        !          2420: 
        !          2421:         default:
        !          2422: 
        !          2423:             StatusToReturn = NDIS_STATUS_NOT_SUPPORTED;
        !          2424:             break;
        !          2425:     }
        !          2426: 
        !          2427:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          2428: 
        !          2429:         if (MoveBytes > BytesLeft){
        !          2430: 
        !          2431:             //
        !          2432:             // Not enough room in InformationBuffer. Punt
        !          2433:             //
        !          2434: 
        !          2435:             *BytesNeeded = MoveBytes;
        !          2436: 
        !          2437:             StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          2438: 
        !          2439:         } else {
        !          2440: 
        !          2441:             //
        !          2442:             // Store result.
        !          2443:             //
        !          2444: 
        !          2445:             IBMTOK_MOVE_MEMORY(InfoBuffer, MoveSource, MoveBytes);
        !          2446: 
        !          2447:             (*BytesWritten) += MoveBytes;
        !          2448: 
        !          2449:         }
        !          2450:     }
        !          2451: 
        !          2452:     return(StatusToReturn);
        !          2453: }
        !          2454: 
        !          2455: STATIC
        !          2456: NDIS_STATUS
        !          2457: IbmtokQueryInformation(
        !          2458:     IN PIBMTOK_ADAPTER Adapter,
        !          2459:     IN PIBMTOK_OPEN Open,
        !          2460:     IN PNDIS_REQUEST NdisRequest
        !          2461:     )
        !          2462: /*++
        !          2463: 
        !          2464: Routine Description:
        !          2465: 
        !          2466:     The IbmtokQueryInformation is used by IbmtokRequest to query information
        !          2467:     about the MAC.
        !          2468: 
        !          2469: Arguments:
        !          2470: 
        !          2471:     Adapter - A pointer to the adapter.
        !          2472: 
        !          2473:     Open - A pointer to a particular open instance.
        !          2474: 
        !          2475:     NdisRequest - A structure which contains the request type (Query),
        !          2476:     an array of operations to perform, and an array for holding
        !          2477:     the results of the operations.
        !          2478: 
        !          2479: Return Value:
        !          2480: 
        !          2481:     The function value is the status of the operation.
        !          2482: 
        !          2483: --*/
        !          2484: 
        !          2485: {
        !          2486: 
        !          2487:     UINT BytesWritten = 0;
        !          2488:     UINT BytesNeeded = 0;
        !          2489:     UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
        !          2490:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
        !          2491: 
        !          2492:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2493: 
        !          2494: 
        !          2495:     StatusToReturn = IbmtokQueryProtocolInformation(
        !          2496:                                 Adapter,
        !          2497:                                 Open,
        !          2498:                                 NdisRequest->DATA.QUERY_INFORMATION.Oid,
        !          2499:                                 FALSE,
        !          2500:                                 InfoBuffer,
        !          2501:                                 BytesLeft,
        !          2502:                                 &BytesNeeded,
        !          2503:                                 &BytesWritten
        !          2504:                                 );
        !          2505: 
        !          2506:     NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
        !          2507: 
        !          2508:     NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
        !          2509: 
        !          2510:     return(StatusToReturn);
        !          2511: }
        !          2512: 
        !          2513: STATIC
        !          2514: NDIS_STATUS
        !          2515: IbmtokSetInformation(
        !          2516:     IN PIBMTOK_ADAPTER Adapter,
        !          2517:     IN PIBMTOK_OPEN Open,
        !          2518:     IN PNDIS_REQUEST NdisRequest
        !          2519:     )
        !          2520: /*++
        !          2521: 
        !          2522: Routine Description:
        !          2523: 
        !          2524:     The IbmtokSetInformation is used by IbmtokRequest to set information
        !          2525:     about the MAC.
        !          2526: 
        !          2527: Arguments:
        !          2528: 
        !          2529:     Adapter - A pointer to the adapter.
        !          2530: 
        !          2531:     Open - A pointer to an open instance.
        !          2532: 
        !          2533:     NdisRequest - A structure which contains the request type (Set),
        !          2534:     an array of operations to perform, and an array for holding
        !          2535:     the results of the operations.
        !          2536: 
        !          2537: Return Value:
        !          2538: 
        !          2539:     The function value is the status of the operation.
        !          2540: 
        !          2541: --*/
        !          2542: 
        !          2543: {
        !          2544: 
        !          2545:     //
        !          2546:     // General Algorithm:
        !          2547:     //
        !          2548:     //     Verify length
        !          2549:     //     Switch(Request)
        !          2550:     //        Process Request
        !          2551:     //
        !          2552: 
        !          2553:     UINT BytesNeeded = 0;
        !          2554:     UINT BytesLeft = NdisRequest->DATA.SET_INFORMATION.InformationBufferLength;
        !          2555:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.SET_INFORMATION.InformationBuffer);
        !          2556: 
        !          2557:     //
        !          2558:     // Variables for the request
        !          2559:     //
        !          2560: 
        !          2561:     NDIS_OID Oid;
        !          2562:     UINT OidLength;
        !          2563: 
        !          2564:     //
        !          2565:     // Variables for holding the new values to be used.
        !          2566:     //
        !          2567: 
        !          2568:     ULONG LookAhead;
        !          2569:     ULONG Filter;
        !          2570: 
        !          2571:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2572: 
        !          2573: 
        !          2574:     //
        !          2575:     // Get Oid and Length of request
        !          2576:     //
        !          2577: 
        !          2578:     Oid = NdisRequest->DATA.SET_INFORMATION.Oid;
        !          2579: 
        !          2580:     OidLength = BytesLeft;
        !          2581: 
        !          2582:     //
        !          2583:     // Verify length
        !          2584:     //
        !          2585: 
        !          2586:     if (OidLength != 4){
        !          2587: 
        !          2588:         StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          2589: 
        !          2590:         NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          2591:         NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          2592: 
        !          2593:         return(StatusToReturn);
        !          2594:     }
        !          2595: 
        !          2596:     switch (Oid) {
        !          2597: 
        !          2598:         case OID_802_5_CURRENT_FUNCTIONAL:
        !          2599: 
        !          2600:             StatusToReturn = IbmtokChangeFunctionalAddress(
        !          2601:                                         Adapter,
        !          2602:                                         Open,
        !          2603:                                         NdisRequest,
        !          2604:                                         InfoBuffer
        !          2605:                                         );
        !          2606: 
        !          2607:             break;
        !          2608: 
        !          2609:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          2610: 
        !          2611:             IBMTOK_MOVE_MEMORY(&Filter, InfoBuffer, 4);
        !          2612: 
        !          2613:             StatusToReturn = IbmtokSetPacketFilter(Adapter,
        !          2614:                                                    Open,
        !          2615:                                                    NdisRequest,
        !          2616:                                                    Filter);
        !          2617: 
        !          2618:             break;
        !          2619: 
        !          2620:         case OID_802_5_CURRENT_GROUP:
        !          2621: 
        !          2622:             StatusToReturn = IbmtokSetGroupAddress(
        !          2623:                                         Adapter,
        !          2624:                                         Open,
        !          2625:                                         NdisRequest,
        !          2626:                                         InfoBuffer
        !          2627:                                         );
        !          2628: 
        !          2629:             break;
        !          2630: 
        !          2631: 
        !          2632:         case OID_GEN_PROTOCOL_OPTIONS:
        !          2633: 
        !          2634:             StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2635: 
        !          2636:             break;
        !          2637: 
        !          2638:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          2639: 
        !          2640:             IBMTOK_MOVE_MEMORY(&LookAhead, InfoBuffer, 4);
        !          2641: 
        !          2642:             if (LookAhead > IBMTOK_MAX_LOOKAHEAD) {
        !          2643: 
        !          2644:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          2645: 
        !          2646:             } else {
        !          2647: 
        !          2648:                 if (LookAhead > Adapter->LookAhead) {
        !          2649: 
        !          2650:                     Open->LookAhead = LookAhead;
        !          2651: 
        !          2652:                     Adapter->LookAhead = LookAhead;
        !          2653: 
        !          2654:                 } else {
        !          2655: 
        !          2656:                     if ((Open->LookAhead == Adapter->LookAhead) &&
        !          2657:                         (LookAhead < Open->LookAhead)) {
        !          2658: 
        !          2659:                         Open->LookAhead = LookAhead;
        !          2660: 
        !          2661:                         IbmtokAdjustMaxLookAhead(Adapter);
        !          2662: 
        !          2663:                     } else {
        !          2664: 
        !          2665:                         Open->LookAhead = LookAhead;
        !          2666: 
        !          2667:                     }
        !          2668: 
        !          2669:                 }
        !          2670: 
        !          2671:             }
        !          2672: 
        !          2673:             break;
        !          2674: 
        !          2675:         default:
        !          2676: 
        !          2677:             StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          2678: 
        !          2679:             NdisRequest->DATA.SET_INFORMATION.BytesRead = 0;
        !          2680:             NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          2681: 
        !          2682:             break;
        !          2683:     }
        !          2684: 
        !          2685:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          2686: 
        !          2687:         NdisRequest->DATA.SET_INFORMATION.BytesRead = OidLength;
        !          2688:         NdisRequest->DATA.SET_INFORMATION.BytesNeeded = 0;
        !          2689: 
        !          2690:     }
        !          2691: 
        !          2692: 
        !          2693: 
        !          2694:     return(StatusToReturn);
        !          2695: }
        !          2696: 
        !          2697: STATIC
        !          2698: NDIS_STATUS
        !          2699: IbmtokSetPacketFilter(
        !          2700:     IN PIBMTOK_ADAPTER Adapter,
        !          2701:     IN PIBMTOK_OPEN Open,
        !          2702:     IN PNDIS_REQUEST NdisRequest,
        !          2703:     IN UINT PacketFilter
        !          2704:     )
        !          2705: 
        !          2706: /*++
        !          2707: 
        !          2708: Routine Description:
        !          2709: 
        !          2710:     This routine processes the stages necessary to implement changing
        !          2711:     the packets that a protocol receives from the MAC.
        !          2712: 
        !          2713: Arguments:
        !          2714: 
        !          2715:     Adapter - A pointer to the Adapter.
        !          2716: 
        !          2717:     Open - A pointer to the open instance.
        !          2718: 
        !          2719:     NdisRequest - A pointer to the request submitting the set command.
        !          2720: 
        !          2721:     PacketFilter - A bit mask that contains flags that correspond to specific
        !          2722:     classes of received packets.  If a particular bit is set in the mask,
        !          2723:     then packet reception for that class of packet is enabled.  If the
        !          2724:     bit is clear, then packets that fall into that class are not received
        !          2725:     by the client.  A single exception to this rule is that if the promiscuous
        !          2726:     bit is set, then the client receives all packets on the network, regardless
        !          2727:     of the state of the other flags.
        !          2728: 
        !          2729: Return Value:
        !          2730: 
        !          2731:     The function value is the status of the operation.
        !          2732: 
        !          2733: --*/
        !          2734: 
        !          2735: {
        !          2736: 
        !          2737:     //
        !          2738:     // Keeps track of the *MAC's* status.  The status will only be
        !          2739:     // reset if the filter change action routine is called.
        !          2740:     //
        !          2741:     NDIS_STATUS StatusOfFilterChange = NDIS_STATUS_SUCCESS;
        !          2742: 
        !          2743:     //
        !          2744:     // Verify bits
        !          2745:     //
        !          2746: 
        !          2747:     if (PacketFilter & (NDIS_PACKET_TYPE_SOURCE_ROUTING |
        !          2748:                         NDIS_PACKET_TYPE_MULTICAST |
        !          2749:                         NDIS_PACKET_TYPE_PROMISCUOUS |
        !          2750:                         NDIS_PACKET_TYPE_ALL_MULTICAST |
        !          2751:                         NDIS_PACKET_TYPE_SMT |
        !          2752:                         NDIS_PACKET_TYPE_MAC_FRAME
        !          2753:                        )) {
        !          2754: 
        !          2755:         return(NDIS_STATUS_NOT_SUPPORTED);
        !          2756: 
        !          2757:     }
        !          2758: 
        !          2759:     //
        !          2760:     // Increment the open while it is going through the filtering
        !          2761:     // routines.
        !          2762:     //
        !          2763: 
        !          2764:     Open->References++;
        !          2765: 
        !          2766:     StatusOfFilterChange = TrFilterAdjust(
        !          2767:                                Adapter->FilterDB,
        !          2768:                                Open->NdisFilterHandle,
        !          2769:                                NdisRequest,
        !          2770:                                PacketFilter,
        !          2771:                                TRUE
        !          2772:                                );
        !          2773:     Open->References--;
        !          2774: 
        !          2775:     if (StatusOfFilterChange == NDIS_STATUS_PENDING) {
        !          2776: 
        !          2777:         //
        !          2778:         // If it pended, it will be in the pend
        !          2779:         // queue so we should start that up.
        !          2780:         //
        !          2781: 
        !          2782:         IbmtokProcessSrbRequests(Adapter);
        !          2783: 
        !          2784:     }
        !          2785: 
        !          2786:     return StatusOfFilterChange;
        !          2787: }
        !          2788: 
        !          2789: STATIC
        !          2790: NDIS_STATUS
        !          2791: IbmtokChangeFunctionalAddress(
        !          2792:     IN PIBMTOK_ADAPTER Adapter,
        !          2793:     IN PIBMTOK_OPEN Open,
        !          2794:     IN PNDIS_REQUEST NdisRequest,
        !          2795:     IN PUCHAR Address
        !          2796:     )
        !          2797: 
        !          2798: /*++
        !          2799: 
        !          2800: Routine Description:
        !          2801: 
        !          2802:     This routine processes the stages necessary to implement changing
        !          2803:     the packets that a protocol receives from the MAC.
        !          2804: 
        !          2805: 
        !          2806:     Note: The spin lock must be held before entering this routine.
        !          2807: 
        !          2808: Arguments:
        !          2809: 
        !          2810:     Adapter - A pointer to the Adapter.
        !          2811: 
        !          2812:     Open - A pointer to the open instance.
        !          2813: 
        !          2814:     NdisRequest - A pointer to the request submitting the set command.
        !          2815: 
        !          2816:     Address - The new functional address.
        !          2817: 
        !          2818: Return Value:
        !          2819: 
        !          2820:     The function value is the status of the operation.
        !          2821: 
        !          2822: --*/
        !          2823: 
        !          2824: {
        !          2825: 
        !          2826:     //
        !          2827:     // Keeps track of the *MAC's* status.  The status will only be
        !          2828:     // reset if the address change action routine is called.
        !          2829:     //
        !          2830:     NDIS_STATUS StatusOfChange = NDIS_STATUS_SUCCESS;
        !          2831: 
        !          2832:     //
        !          2833:     // Increment the open while it is going through the filtering
        !          2834:     // routines.
        !          2835:     //
        !          2836: 
        !          2837:     Open->References++;
        !          2838: 
        !          2839:     StatusOfChange = TrChangeFunctionalAddress(
        !          2840:                               Open->OwningIbmtok->FilterDB,
        !          2841:                               Open->NdisFilterHandle,
        !          2842:                               NdisRequest,
        !          2843:                               Address,
        !          2844:                               TRUE
        !          2845:                               );
        !          2846: 
        !          2847:     Open->References--;
        !          2848: 
        !          2849:     if (StatusOfChange == NDIS_STATUS_PENDING) {
        !          2850: 
        !          2851:         //
        !          2852:         // If it pended, it will be in the pend
        !          2853:         // queue so we should start that up.
        !          2854:         //
        !          2855: 
        !          2856:         IbmtokProcessSrbRequests(Adapter);
        !          2857: 
        !          2858:     }
        !          2859: 
        !          2860:     return StatusOfChange;
        !          2861: }
        !          2862: 
        !          2863: STATIC
        !          2864: NDIS_STATUS
        !          2865: IbmtokSetGroupAddress(
        !          2866:     IN PIBMTOK_ADAPTER Adapter,
        !          2867:     IN PIBMTOK_OPEN Open,
        !          2868:     IN PNDIS_REQUEST NdisRequest,
        !          2869:     IN PUCHAR Address
        !          2870:     )
        !          2871: 
        !          2872: /*++
        !          2873: 
        !          2874: Routine Description:
        !          2875: 
        !          2876:     This routine processes the stages necessary to implement changing
        !          2877:     the packets that a protocol receives from the MAC.
        !          2878: 
        !          2879: 
        !          2880:     Note: The spin lock must be held before entering this routine.
        !          2881: 
        !          2882: Arguments:
        !          2883: 
        !          2884:     Adapter - A pointer to the Adapter.
        !          2885: 
        !          2886:     Open - A pointer to the open instance.
        !          2887: 
        !          2888:     NdisRequest - A pointer to the request submitting the set command.
        !          2889: 
        !          2890:     Address - The new group address.
        !          2891: 
        !          2892: Return Value:
        !          2893: 
        !          2894:     The function value is the status of the operation.
        !          2895: 
        !          2896: --*/
        !          2897: 
        !          2898: {
        !          2899: 
        !          2900:     //
        !          2901:     // Keeps track of the *MAC's* status.  The status will only be
        !          2902:     // reset if the address change action routine is called.
        !          2903:     //
        !          2904:     NDIS_STATUS StatusOfChange = NDIS_STATUS_SUCCESS;
        !          2905: 
        !          2906:     //
        !          2907:     // Increment the open while it is going through the filtering
        !          2908:     // routines.
        !          2909:     //
        !          2910: 
        !          2911:     Open->References++;
        !          2912: 
        !          2913:     StatusOfChange = TrChangeGroupAddress(
        !          2914:                               Open->OwningIbmtok->FilterDB,
        !          2915:                               Open->NdisFilterHandle,
        !          2916:                               NdisRequest,
        !          2917:                               Address,
        !          2918:                               TRUE
        !          2919:                               );
        !          2920: 
        !          2921:     Open->References--;
        !          2922: 
        !          2923:     if (StatusOfChange == NDIS_STATUS_PENDING) {
        !          2924: 
        !          2925:         //
        !          2926:         // If it pended, it will be in the pend
        !          2927:         // queue so we should start that up.
        !          2928:         //
        !          2929: 
        !          2930:         IbmtokProcessSrbRequests(Adapter);
        !          2931: 
        !          2932:     }
        !          2933: 
        !          2934:     return StatusOfChange;
        !          2935: }
        !          2936: 
        !          2937: NDIS_STATUS
        !          2938: IbmtokFillInGlobalData(
        !          2939:     IN PIBMTOK_ADAPTER Adapter,
        !          2940:     IN PNDIS_REQUEST NdisRequest
        !          2941:     )
        !          2942: 
        !          2943: /*++
        !          2944: 
        !          2945: Routine Description:
        !          2946: 
        !          2947:     This routine completes a GlobalStatistics request.  It is critical that
        !          2948:     if information is needed from the Adapter->* fields, they have been
        !          2949:     updated before this routine is called.
        !          2950: 
        !          2951: Arguments:
        !          2952: 
        !          2953:     Adapter - A pointer to the Adapter.
        !          2954: 
        !          2955:     NdisRequest - A structure which contains the request type (Global
        !          2956:     Query), an array of operations to perform, and an array for holding
        !          2957:     the results of the operations.
        !          2958: 
        !          2959: Return Value:
        !          2960: 
        !          2961:     The function value is the status of the operation.
        !          2962: 
        !          2963: --*/
        !          2964: {
        !          2965:     //
        !          2966:     //   General Algorithm:
        !          2967:     //
        !          2968:     //      Switch(Request)
        !          2969:     //         Get requested information
        !          2970:     //         Store results in a common variable.
        !          2971:     //      default:
        !          2972:     //         Try protocol query information
        !          2973:     //         If that fails, fail query.
        !          2974:     //
        !          2975:     //      Copy result in common variable to result buffer.
        !          2976:     //   Finish processing
        !          2977: 
        !          2978:     UINT BytesWritten = 0;
        !          2979:     UINT BytesNeeded = 0;
        !          2980:     UINT BytesLeft = NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength;
        !          2981:     PUCHAR InfoBuffer = (PUCHAR)(NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer);
        !          2982: 
        !          2983:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          2984: 
        !          2985:     //
        !          2986:     // This variable holds result of query
        !          2987:     //
        !          2988: 
        !          2989:     ULONG GenericULong;
        !          2990:     ULONG MoveBytes = sizeof(ULONG) * 2 + sizeof(NDIS_OID);
        !          2991: 
        !          2992: 
        !          2993:     StatusToReturn = IbmtokQueryProtocolInformation(
        !          2994:                                     Adapter,
        !          2995:                                     NULL,
        !          2996:                                     NdisRequest->DATA.QUERY_INFORMATION.Oid,
        !          2997:                                     TRUE,
        !          2998:                                     InfoBuffer,
        !          2999:                                     BytesLeft,
        !          3000:                                     &BytesNeeded,
        !          3001:                                     &BytesWritten
        !          3002:                                     );
        !          3003: 
        !          3004: 
        !          3005:     if (StatusToReturn == NDIS_STATUS_NOT_SUPPORTED){
        !          3006: 
        !          3007:         StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3008: 
        !          3009:         //
        !          3010:         // Switch on request type
        !          3011:         //
        !          3012: 
        !          3013:         switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
        !          3014: 
        !          3015:             case OID_GEN_XMIT_OK:
        !          3016: 
        !          3017:                 GenericULong = (ULONG)(Adapter->FramesTransmitted);
        !          3018: 
        !          3019:                 break;
        !          3020: 
        !          3021:             case OID_GEN_RCV_OK:
        !          3022: 
        !          3023:                 GenericULong = (ULONG)(Adapter->FramesReceived);
        !          3024: 
        !          3025:                 break;
        !          3026: 
        !          3027:             case OID_GEN_XMIT_ERROR:
        !          3028: 
        !          3029:                 GenericULong = (ULONG)(Adapter->FrameTransmitErrors);
        !          3030: 
        !          3031:                 break;
        !          3032: 
        !          3033:             case OID_GEN_RCV_ERROR:
        !          3034: 
        !          3035:                 GenericULong = (ULONG)(Adapter->FrameReceiveErrors);
        !          3036: 
        !          3037:                 break;
        !          3038: 
        !          3039:             case OID_GEN_RCV_NO_BUFFER:
        !          3040: 
        !          3041:                 GenericULong = (ULONG)(Adapter->ReceiveCongestionCount);
        !          3042: 
        !          3043:                 break;
        !          3044: 
        !          3045:             case OID_802_5_LINE_ERRORS:
        !          3046: 
        !          3047:                 GenericULong = (ULONG)(Adapter->LineErrors);
        !          3048: 
        !          3049:                 break;
        !          3050: 
        !          3051:             case OID_802_5_LOST_FRAMES:
        !          3052: 
        !          3053:                 GenericULong = (ULONG)(Adapter->LostFrames);
        !          3054: 
        !          3055:                 break;
        !          3056: 
        !          3057:             case OID_802_5_LAST_OPEN_STATUS:
        !          3058: 
        !          3059:                 GenericULong = (ULONG)(NDIS_STATUS_TOKEN_RING_OPEN_ERROR |
        !          3060:                                        (NDIS_STATUS)(Adapter->OpenErrorCode));
        !          3061: 
        !          3062:                 break;
        !          3063: 
        !          3064:             case OID_802_5_CURRENT_RING_STATUS:
        !          3065: 
        !          3066:                 GenericULong = (ULONG)(Adapter->LastNotifyStatus);
        !          3067: 
        !          3068:                 break;
        !          3069: 
        !          3070:             case OID_802_5_CURRENT_RING_STATE:
        !          3071: 
        !          3072:                 GenericULong = (ULONG)(Adapter->CurrentRingState);
        !          3073: 
        !          3074:                 break;
        !          3075: 
        !          3076:             default:
        !          3077: 
        !          3078:                 StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          3079: 
        !          3080:                 break;
        !          3081: 
        !          3082:         }
        !          3083: 
        !          3084:         if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          3085: 
        !          3086:             //
        !          3087:             // Check to make sure there is enough room in the
        !          3088:             // buffer to store the result.
        !          3089:             //
        !          3090: 
        !          3091:             if (BytesLeft >= sizeof(ULONG)) {
        !          3092: 
        !          3093:                 //
        !          3094:                 // Store the result.
        !          3095:                 //
        !          3096: 
        !          3097:                 IBMTOK_MOVE_MEMORY(
        !          3098:                            (PVOID)InfoBuffer,
        !          3099:                            (PVOID)(&GenericULong),
        !          3100:                            sizeof(ULONG)
        !          3101:                            );
        !          3102: 
        !          3103:                 BytesWritten += sizeof(ULONG);
        !          3104: 
        !          3105:             } else {
        !          3106: 
        !          3107:                 BytesNeeded = sizeof(ULONG) - BytesLeft;
        !          3108: 
        !          3109:                 StatusToReturn = NDIS_STATUS_INVALID_LENGTH;
        !          3110: 
        !          3111:             }
        !          3112: 
        !          3113:         }
        !          3114: 
        !          3115:     }
        !          3116: 
        !          3117:     NdisRequest->DATA.QUERY_INFORMATION.BytesWritten = BytesWritten;
        !          3118: 
        !          3119:     NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded = BytesNeeded;
        !          3120: 
        !          3121:     return(StatusToReturn);
        !          3122: }
        !          3123: 
        !          3124: STATIC
        !          3125: NDIS_STATUS
        !          3126: IbmtokQueryGlobalStatistics(
        !          3127:     IN NDIS_HANDLE MacAdapterContext,
        !          3128:     IN PNDIS_REQUEST NdisRequest
        !          3129:     )
        !          3130: 
        !          3131: /*++
        !          3132: 
        !          3133: Routine Description:
        !          3134: 
        !          3135:     The IbmtokQueryGlobalStatistics is used by the protocol to query
        !          3136:     global information about the MAC.
        !          3137: 
        !          3138: Arguments:
        !          3139: 
        !          3140:     MacAdapterContext - The value associated with the adapter that is being
        !          3141:     opened when the MAC registered the adapter with NdisRegisterAdapter.
        !          3142: 
        !          3143:     NdisRequest - A structure which contains the request type (Query),
        !          3144:     an array of operations to perform, and an array for holding
        !          3145:     the results of the operations.
        !          3146: 
        !          3147: Return Value:
        !          3148: 
        !          3149:     The function value is the status of the operation.
        !          3150: 
        !          3151: --*/
        !          3152: 
        !          3153: {
        !          3154: 
        !          3155:     //
        !          3156:     // General Algorithm:
        !          3157:     //
        !          3158:     //
        !          3159:     //   Check if a request is going to pend...
        !          3160:     //      If so, pend the entire operation.
        !          3161:     //
        !          3162:     //   Else
        !          3163:     //      Fill in the request block.
        !          3164:     //
        !          3165:     //
        !          3166: 
        !          3167:     PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
        !          3168: 
        !          3169:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
        !          3170: 
        !          3171:     //
        !          3172:     //   Check if a request is valid and going to pend...
        !          3173:     //      If so, pend the entire operation.
        !          3174:     //
        !          3175: 
        !          3176:     NdisInterlockedAddUlong((PULONG)&Adapter->References, 1 ,&(Adapter->Lock));
        !          3177: 
        !          3178:     //
        !          3179:     // Switch on request type
        !          3180:     //
        !          3181: 
        !          3182:     switch (NdisRequest->DATA.QUERY_INFORMATION.Oid) {
        !          3183:         case OID_GEN_SUPPORTED_LIST:
        !          3184:         case OID_GEN_HARDWARE_STATUS:
        !          3185:         case OID_GEN_MEDIA_SUPPORTED:
        !          3186:         case OID_GEN_MEDIA_IN_USE:
        !          3187:         case OID_GEN_MAXIMUM_LOOKAHEAD:
        !          3188:         case OID_GEN_MAXIMUM_FRAME_SIZE:
        !          3189:         case OID_GEN_MAXIMUM_TOTAL_SIZE:
        !          3190:         case OID_GEN_MAC_OPTIONS:
        !          3191:         case OID_GEN_LINK_SPEED:
        !          3192:         case OID_GEN_TRANSMIT_BUFFER_SPACE:
        !          3193:         case OID_GEN_RECEIVE_BUFFER_SPACE:
        !          3194:         case OID_GEN_TRANSMIT_BLOCK_SIZE:
        !          3195:         case OID_GEN_RECEIVE_BLOCK_SIZE:
        !          3196:         case OID_GEN_VENDOR_ID:
        !          3197:         case OID_GEN_DRIVER_VERSION:
        !          3198:         case OID_GEN_CURRENT_PACKET_FILTER:
        !          3199:         case OID_GEN_CURRENT_LOOKAHEAD:
        !          3200:         case OID_802_5_CURRENT_GROUP:
        !          3201:         case OID_802_5_LAST_OPEN_STATUS:
        !          3202:         case OID_802_5_CURRENT_RING_STATUS:
        !          3203:         case OID_802_5_CURRENT_RING_STATE:
        !          3204:         case OID_802_5_PERMANENT_ADDRESS:
        !          3205:         case OID_802_5_CURRENT_ADDRESS:
        !          3206:         case OID_802_5_CURRENT_FUNCTIONAL:
        !          3207:             break;
        !          3208: 
        !          3209:         case OID_GEN_XMIT_OK:
        !          3210:         case OID_GEN_RCV_OK:
        !          3211:         case OID_GEN_XMIT_ERROR:
        !          3212:         case OID_GEN_RCV_ERROR:
        !          3213:         case OID_GEN_RCV_NO_BUFFER:
        !          3214:         case OID_802_5_LINE_ERRORS:
        !          3215:         case OID_802_5_LOST_FRAMES:
        !          3216: 
        !          3217:             StatusToReturn = NDIS_STATUS_PENDING;
        !          3218: 
        !          3219:             break;
        !          3220: 
        !          3221:         default:
        !          3222: 
        !          3223:             StatusToReturn = NDIS_STATUS_INVALID_OID;
        !          3224: 
        !          3225:             break;
        !          3226:     }
        !          3227: 
        !          3228:     if (StatusToReturn == NDIS_STATUS_PENDING) {
        !          3229: 
        !          3230:         //
        !          3231:         // Build a pending operation
        !          3232:         //
        !          3233: 
        !          3234:         PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest);
        !          3235: 
        !          3236:         PendOp->Next = NULL;
        !          3237:         PendOp->COMMAND.NDIS.STATISTICS.ReadLogPending = FALSE;
        !          3238: 
        !          3239:         NdisAcquireSpinLock(&Adapter->Lock);
        !          3240: 
        !          3241:         if (Adapter->PendQueue == NULL){
        !          3242: 
        !          3243:             Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          3244: 
        !          3245:         } else {
        !          3246: 
        !          3247:             Adapter->EndOfPendQueue->Next = PendOp;
        !          3248: 
        !          3249:         }
        !          3250: 
        !          3251: 
        !          3252:         //
        !          3253:         // It is now in the pend
        !          3254:         // queue so we should start that up.
        !          3255:         //
        !          3256: 
        !          3257:         IbmtokProcessSrbRequests(Adapter);
        !          3258: 
        !          3259:         NdisReleaseSpinLock(&Adapter->Lock);
        !          3260: 
        !          3261:         //
        !          3262:         // Defer subtracting from Adapter->Reference until the
        !          3263:         // request completes (see IbmtokFinishPendQueueOp()).
        !          3264:         //
        !          3265: 
        !          3266:         return(StatusToReturn);
        !          3267: 
        !          3268:     }
        !          3269: 
        !          3270:     if (StatusToReturn == NDIS_STATUS_SUCCESS){
        !          3271: 
        !          3272:         StatusToReturn = IbmtokFillInGlobalData(Adapter, NdisRequest);
        !          3273: 
        !          3274:     }
        !          3275: 
        !          3276:     NdisAcquireSpinLock(&Adapter->Lock);
        !          3277: 
        !          3278:     IBMTOK_DO_DEFERRED(Adapter);
        !          3279: 
        !          3280:     return(StatusToReturn);
        !          3281: }
        !          3282: 
        !          3283: STATIC
        !          3284: NDIS_STATUS
        !          3285: IbmtokReset(
        !          3286:     IN NDIS_HANDLE MacBindingHandle
        !          3287:     )
        !          3288: 
        !          3289: /*++
        !          3290: 
        !          3291: Routine Description:
        !          3292: 
        !          3293:     The IbmtokReset request instructs the MAC to issue a hardware reset
        !          3294:     to the network adapter.  The MAC also resets its software state.  See
        !          3295:     the description of NdisReset for a detailed description of this request.
        !          3296: 
        !          3297: Arguments:
        !          3298: 
        !          3299:     MacBindingHandle - The context value returned by the MAC  when the
        !          3300:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          3301: 
        !          3302: Return Value:
        !          3303: 
        !          3304:     The function value is the status of the operation.
        !          3305: 
        !          3306: 
        !          3307: --*/
        !          3308: 
        !          3309: {
        !          3310: 
        !          3311:     //
        !          3312:     // Holds the status that should be returned to the caller.
        !          3313:     //
        !          3314:     NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
        !          3315: 
        !          3316:     PIBMTOK_ADAPTER Adapter =
        !          3317:         PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3318: 
        !          3319:     PIBMTOK_OPEN Open;
        !          3320: 
        !          3321:     //
        !          3322:     // Hold the locks while we update the reference counts on the
        !          3323:     // adapter and the open.
        !          3324:     //
        !          3325: 
        !          3326:     NdisAcquireSpinLock(&Adapter->Lock);
        !          3327:     Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3328: 
        !          3329:     Adapter->References++;
        !          3330: 
        !          3331:     if (Adapter->ResetInProgress) {
        !          3332: 
        !          3333:         StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
        !          3334: 
        !          3335:     } else if (Adapter->AdapterNotOpen) {
        !          3336: 
        !          3337:         StatusToReturn = NDIS_STATUS_FAILURE;
        !          3338: 
        !          3339:     } else {
        !          3340: 
        !          3341:         if (!Open->BindingShuttingDown) {
        !          3342: 
        !          3343:             Open->References++;
        !          3344:             IbmtokSetupForReset(
        !          3345:                 Adapter,
        !          3346:                 PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)
        !          3347:                 );
        !          3348:             Open->References--;
        !          3349: 
        !          3350:         } else {
        !          3351: 
        !          3352:             StatusToReturn = NDIS_STATUS_CLOSING;
        !          3353: 
        !          3354:         }
        !          3355: 
        !          3356:     }
        !          3357: 
        !          3358:     //
        !          3359:     // This macro assumes it is called with the lock held,
        !          3360:     // and releases it.
        !          3361:     //
        !          3362: 
        !          3363:     IBMTOK_DO_DEFERRED(Adapter);
        !          3364:     return StatusToReturn;
        !          3365: 
        !          3366: }
        !          3367: 
        !          3368: STATIC
        !          3369: NDIS_STATUS
        !          3370: IbmtokChangeFilter(
        !          3371:     IN UINT OldFilterClasses,
        !          3372:     IN UINT NewFilterClasses,
        !          3373:     IN NDIS_HANDLE MacBindingHandle,
        !          3374:     IN PNDIS_REQUEST NdisRequest,
        !          3375:     IN BOOLEAN Set
        !          3376:     )
        !          3377: 
        !          3378: /*++
        !          3379: 
        !          3380: Routine Description:
        !          3381: 
        !          3382:     Action routine that will get called when a particular filter
        !          3383:     class is first used or last cleared.
        !          3384: 
        !          3385:     NOTE: This routine assumes that it is called with the lock
        !          3386:     acquired.
        !          3387: 
        !          3388: Arguments:
        !          3389: 
        !          3390:     OldFilterClasses - The values of the class filter before it
        !          3391:     was changed.
        !          3392: 
        !          3393:     NewFilterClasses - The current value of the class filter
        !          3394: 
        !          3395:     MacBindingHandle - The context value returned by the MAC  when the
        !          3396:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          3397: 
        !          3398:     Set - If true the change resulted from a set, otherwise the
        !          3399:     change resulted from a open closing.
        !          3400: 
        !          3401: Return Value:
        !          3402: 
        !          3403:     None.
        !          3404: 
        !          3405: --*/
        !          3406: 
        !          3407: {
        !          3408: 
        !          3409: 
        !          3410:     PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3411: 
        !          3412:     //
        !          3413:     // The open that made this request.
        !          3414:     //
        !          3415:     PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3416: 
        !          3417:     //
        !          3418:     // Holds the change that should be returned to the filtering package.
        !          3419:     //
        !          3420:     NDIS_STATUS StatusOfChange;
        !          3421: 
        !          3422:     if (NdisRequest == NULL) {
        !          3423: 
        !          3424:         NdisRequest = &(Open->CloseRequestChangeFilter);
        !          3425: 
        !          3426:         NdisRequest->RequestType = NdisRequestClose;
        !          3427: 
        !          3428: 
        !          3429:     }
        !          3430: 
        !          3431: 
        !          3432:     if (Adapter->ResetInProgress) {
        !          3433: 
        !          3434:         StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS;
        !          3435: 
        !          3436:     } else {
        !          3437: 
        !          3438:         //
        !          3439:         // The whole purpose of this routine is to determine whether
        !          3440:         // the filtering changes need to result in the hardware being
        !          3441:         // reset.
        !          3442:         //
        !          3443: 
        !          3444:         ASSERT(OldFilterClasses != NewFilterClasses);
        !          3445: 
        !          3446: #if DBG
        !          3447:         if (IbmtokDbg) DbgPrint("IBMTOK: Change filter\n");
        !          3448: #endif
        !          3449: 
        !          3450:         if (NewFilterClasses &
        !          3451:             (NDIS_PACKET_TYPE_PROMISCUOUS | NDIS_PACKET_TYPE_SOURCE_ROUTING)) {
        !          3452: 
        !          3453:             //
        !          3454:             // The adapter cannot support promiscuous mode, or
        !          3455:             // source routing which implies promiscuous.
        !          3456:             //
        !          3457: 
        !          3458:             StatusOfChange = NDIS_STATUS_FAILURE;
        !          3459: 
        !          3460:         } else {
        !          3461: 
        !          3462:             //
        !          3463:             // Queue this request.
        !          3464:             //
        !          3465: 
        !          3466:             PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest);
        !          3467: 
        !          3468:             //
        !          3469:             // Store open block.
        !          3470:             //
        !          3471: 
        !          3472:             PendOp->COMMAND.NDIS.SET_FILTER.Open = Open;
        !          3473: 
        !          3474:             //
        !          3475:             // Hold new Filter value
        !          3476:             //
        !          3477: 
        !          3478:             if (PendOp->RequestType == NdisRequestClose){
        !          3479: 
        !          3480:                 PendOp->COMMAND.NDIS.CLOSE.NewFilterValue = NewFilterClasses;
        !          3481: 
        !          3482:             } else {
        !          3483: 
        !          3484:                 PendOp->COMMAND.NDIS.SET_FILTER.NewFilterValue = NewFilterClasses;
        !          3485: 
        !          3486:             }
        !          3487: 
        !          3488: 
        !          3489:             //
        !          3490:             // Insert into queue.
        !          3491:             //
        !          3492: 
        !          3493:             PendOp->Next = NULL;
        !          3494: 
        !          3495:             if (Adapter->PendQueue == NULL) {
        !          3496: 
        !          3497:                 Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          3498: 
        !          3499:             } else {
        !          3500: 
        !          3501:                 Adapter->EndOfPendQueue->Next = PendOp;
        !          3502: 
        !          3503:             }
        !          3504: 
        !          3505:             Open->References++;
        !          3506: 
        !          3507:             StatusOfChange = NDIS_STATUS_PENDING;
        !          3508: 
        !          3509: 
        !          3510:         }
        !          3511: 
        !          3512:     }
        !          3513: 
        !          3514:     return StatusOfChange;
        !          3515: 
        !          3516: }
        !          3517: 
        !          3518: STATIC
        !          3519: NDIS_STATUS
        !          3520: IbmtokChangeAddress(
        !          3521:     IN TR_FUNCTIONAL_ADDRESS OldFunctionalAddress,
        !          3522:     IN TR_FUNCTIONAL_ADDRESS NewFunctionalAddress,
        !          3523:     IN NDIS_HANDLE MacBindingHandle,
        !          3524:     IN PNDIS_REQUEST NdisRequest,
        !          3525:     IN BOOLEAN Set
        !          3526:     )
        !          3527: 
        !          3528: 
        !          3529: /*++
        !          3530: 
        !          3531: Routine Description:
        !          3532: 
        !          3533:     Action routine that will get called when an address is added to
        !          3534:     the filter that wasn't referenced by any other open binding.
        !          3535: 
        !          3536:     NOTE: This routine assumes that it is called with the lock
        !          3537:     acquired.
        !          3538: 
        !          3539: Arguments:
        !          3540: 
        !          3541:     OldFunctionalAddress - The previous functional address.
        !          3542: 
        !          3543:     NewFunctionalAddress - The new functional address.
        !          3544: 
        !          3545:     MacBindingHandle - The context value returned by the MAC  when the
        !          3546:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          3547: 
        !          3548:     NdisRequest - A pointer to the Request that submitted the set command.
        !          3549: 
        !          3550:     Set - If true the change resulted from a set, otherwise the
        !          3551:     change resulted from a open closing.
        !          3552: 
        !          3553: Return Value:
        !          3554: 
        !          3555:     None.
        !          3556: 
        !          3557: 
        !          3558: --*/
        !          3559: 
        !          3560: {
        !          3561: 
        !          3562:     PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3563: 
        !          3564:     //
        !          3565:     // Holds the status that should be returned to the filtering package.
        !          3566:     //
        !          3567:     NDIS_STATUS StatusOfChange;
        !          3568: 
        !          3569:     //
        !          3570:     // The open that made this request.
        !          3571:     //
        !          3572:     PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3573: 
        !          3574: #if DBG
        !          3575:     if (IbmtokDbg) {
        !          3576:         DbgPrint("IBMTOK: Queueing:\n");
        !          3577:         DbgPrint("   Req  : 0x%x\n", NdisRequest);
        !          3578:         DbgPrint("   Old  : 0x%x\n", OldFunctionalAddress);
        !          3579:         DbgPrint("   New  : 0x%x\n", NewFunctionalAddress);
        !          3580:     }
        !          3581: #endif
        !          3582: 
        !          3583:     // Check to see if the device is already resetting.  If it is
        !          3584:     // then reject this change.
        !          3585:     //
        !          3586: 
        !          3587:     if (NdisRequest == NULL) {
        !          3588: 
        !          3589:         NdisRequest = &(Open->CloseRequestChangeAddress);
        !          3590: 
        !          3591:         NdisRequest->RequestType = NdisRequestGeneric2;  // Close, set address
        !          3592: 
        !          3593:     }
        !          3594: 
        !          3595: 
        !          3596:     if (Adapter->ResetInProgress) {
        !          3597: 
        !          3598: #if DBG
        !          3599:         if (IbmtokDbg) {
        !          3600:             DbgPrint("IBMTOK: ResetInProgress\n\n");
        !          3601:         }
        !          3602: #endif
        !          3603: 
        !          3604:         StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS;
        !          3605: 
        !          3606:     } else {
        !          3607: 
        !          3608:         //
        !          3609:         // Queue this request.
        !          3610:         //
        !          3611: 
        !          3612:         PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest);
        !          3613: 
        !          3614: 
        !          3615:         //
        !          3616:         // Store open block.
        !          3617:         //
        !          3618: 
        !          3619:         PendOp->COMMAND.NDIS.SET_ADDRESS.Open = Open;
        !          3620: 
        !          3621:         //
        !          3622:         // Hold new Address value
        !          3623:         //
        !          3624: 
        !          3625:         PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue = NewFunctionalAddress;
        !          3626: 
        !          3627: 
        !          3628:         //
        !          3629:         // Insert into queue.
        !          3630:         //
        !          3631: 
        !          3632:         PendOp->Next = NULL;
        !          3633: 
        !          3634:         if (Adapter->PendQueue == NULL) {
        !          3635: 
        !          3636:             Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          3637: 
        !          3638:         } else {
        !          3639: 
        !          3640:             Adapter->EndOfPendQueue->Next = PendOp;
        !          3641: 
        !          3642:         }
        !          3643: 
        !          3644:         Open->References++;
        !          3645: 
        !          3646:         StatusOfChange = NDIS_STATUS_PENDING;
        !          3647: 
        !          3648:     }
        !          3649: 
        !          3650:     return StatusOfChange;
        !          3651: 
        !          3652: }
        !          3653: 
        !          3654: STATIC
        !          3655: NDIS_STATUS
        !          3656: IbmtokChangeGroupAddress(
        !          3657:     IN TR_FUNCTIONAL_ADDRESS OldGroupAddress,
        !          3658:     IN TR_FUNCTIONAL_ADDRESS NewGroupAddress,
        !          3659:     IN NDIS_HANDLE MacBindingHandle,
        !          3660:     IN PNDIS_REQUEST NdisRequest,
        !          3661:     IN BOOLEAN Set
        !          3662:     )
        !          3663: 
        !          3664: /*++
        !          3665: 
        !          3666: Routine Description:
        !          3667: 
        !          3668:     Action routine that will get called when a group address is to
        !          3669:     be changed.
        !          3670: 
        !          3671:     NOTE: This routine assumes that it is called with the lock
        !          3672:     acquired.
        !          3673: 
        !          3674: Arguments:
        !          3675: 
        !          3676:     OldGroupAddress - The previous group address.
        !          3677: 
        !          3678:     NewGroupAddress - The new group address.
        !          3679: 
        !          3680:     MacBindingHandle - The context value returned by the MAC  when the
        !          3681:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          3682: 
        !          3683:     NdisRequest - A pointer to the Request that submitted the set command.
        !          3684: 
        !          3685:     Set - If true the change resulted from a set, otherwise the
        !          3686:     change resulted from a open closing.
        !          3687: 
        !          3688: Return Value:
        !          3689: 
        !          3690:     None.
        !          3691: 
        !          3692: 
        !          3693: --*/
        !          3694: 
        !          3695: {
        !          3696: 
        !          3697:     PIBMTOK_ADAPTER Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3698: 
        !          3699:     //
        !          3700:     // Holds the status that should be returned to the filtering package.
        !          3701:     //
        !          3702:     NDIS_STATUS StatusOfChange;
        !          3703: 
        !          3704:     //
        !          3705:     // The open that made this request.
        !          3706:     //
        !          3707:     PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !          3708: 
        !          3709: 
        !          3710:     if (NdisRequest == NULL) {
        !          3711: 
        !          3712:         NdisRequest = &(Open->CloseRequestChangeGroupAddress);
        !          3713: 
        !          3714:         NdisRequest->RequestType = NdisRequestGeneric3;  // Close, set group address
        !          3715: 
        !          3716:     }
        !          3717: 
        !          3718: 
        !          3719:     //
        !          3720:     // Check to see if the device is already resetting.  If it is
        !          3721:     // then reject this change.
        !          3722:     //
        !          3723: 
        !          3724:     if (Adapter->ResetInProgress) {
        !          3725: 
        !          3726:         StatusOfChange = NDIS_STATUS_RESET_IN_PROGRESS;
        !          3727: 
        !          3728:     } else {
        !          3729: 
        !          3730:         //
        !          3731:         // Queue this request.
        !          3732:         //
        !          3733: 
        !          3734:         PIBMTOK_PEND_DATA PendOp = PIBMTOK_PEND_DATA_FROM_PNDIS_REQUEST(NdisRequest);
        !          3735: 
        !          3736: 
        !          3737:         //
        !          3738:         // Store open block.
        !          3739:         //
        !          3740: 
        !          3741:         PendOp->COMMAND.NDIS.SET_ADDRESS.Open = Open;
        !          3742: 
        !          3743:         //
        !          3744:         // Hold new Address value
        !          3745:         //
        !          3746: 
        !          3747:         PendOp->COMMAND.NDIS.SET_ADDRESS.NewAddressValue = NewGroupAddress;
        !          3748: 
        !          3749: 
        !          3750:         //
        !          3751:         // Insert into queue.
        !          3752:         //
        !          3753: 
        !          3754:         PendOp->Next = NULL;
        !          3755: 
        !          3756:         if (Adapter->PendQueue == NULL) {
        !          3757: 
        !          3758:             Adapter->PendQueue = Adapter->EndOfPendQueue = PendOp;
        !          3759: 
        !          3760:         } else {
        !          3761: 
        !          3762:             Adapter->EndOfPendQueue->Next = PendOp;
        !          3763: 
        !          3764:         }
        !          3765: 
        !          3766:         Open->References++;
        !          3767: 
        !          3768:         StatusOfChange = NDIS_STATUS_PENDING;
        !          3769: 
        !          3770:     }
        !          3771: 
        !          3772:     return StatusOfChange;
        !          3773: 
        !          3774: }
        !          3775: 
        !          3776: STATIC
        !          3777: VOID
        !          3778: IbmtokCloseAction(
        !          3779:     IN NDIS_HANDLE MacBindingHandle
        !          3780:     )
        !          3781: 
        !          3782: /*++
        !          3783: 
        !          3784: Routine Description:
        !          3785: 
        !          3786:     Action routine that will get called when a particular binding
        !          3787:     was closed while it was indicating through NdisIndicateReceive
        !          3788: 
        !          3789:     All this routine needs to do is to decrement the reference count
        !          3790:     of the binding.
        !          3791: 
        !          3792:     NOTE: This routine assumes that it is called with the lock acquired.
        !          3793: 
        !          3794: Arguments:
        !          3795: 
        !          3796:     MacBindingHandle - The context value returned by the MAC  when the
        !          3797:     adapter was opened.  In reality, it is a pointer to IBMTOK_OPEN.
        !          3798: 
        !          3799: Return Value:
        !          3800: 
        !          3801:     None.
        !          3802: 
        !          3803: 
        !          3804: --*/
        !          3805: 
        !          3806: {
        !          3807: 
        !          3808:     PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)->References--;
        !          3809: 
        !          3810: }
        !          3811: 
        !          3812: extern
        !          3813: VOID
        !          3814: IbmtokStartAdapterReset(
        !          3815:     IN PIBMTOK_ADAPTER Adapter
        !          3816:     )
        !          3817: 
        !          3818: /*++
        !          3819: 
        !          3820: Routine Description:
        !          3821: 
        !          3822:     This is the first phase of resetting the adapter hardware.
        !          3823: 
        !          3824:     It makes the following assumptions:
        !          3825: 
        !          3826:     1) That the hardware has been stopped.
        !          3827: 
        !          3828:     2) That it can not be preempted.
        !          3829: 
        !          3830:     3) That no other adapter activity can occur.
        !          3831: 
        !          3832:     When this routine is finished all of the adapter information
        !          3833:     will be as if the driver was just initialized.
        !          3834: 
        !          3835: Arguments:
        !          3836: 
        !          3837:     Adapter - The adapter whose hardware is to be reset.
        !          3838: 
        !          3839: Return Value:
        !          3840: 
        !          3841:     None.
        !          3842: 
        !          3843: --*/
        !          3844: {
        !          3845: 
        !          3846:     //
        !          3847:     // Disable these so no pending interrupts
        !          3848:     // will fire.
        !          3849:     //
        !          3850:     CLEAR_ISRP_BITS(Adapter);
        !          3851: 
        !          3852:     //
        !          3853:     // OK, do the reset as detailed in the Tech Ref...
        !          3854:     //
        !          3855: 
        !          3856:     WRITE_ADAPTER_PORT(Adapter, RESET_LATCH, 0);
        !          3857: 
        !          3858:     NdisStallExecution(50000);
        !          3859: 
        !          3860:     WRITE_ADAPTER_PORT(Adapter, RESET_RELEASE, 0);
        !          3861: 
        !          3862:     //
        !          3863:     // Have to write this now to enable Shared RAM paging.
        !          3864:     //
        !          3865:     if (Adapter->SharedRamPaging) {
        !          3866: 
        !          3867:         WRITE_ADAPTER_REGISTER(Adapter, SRPR_LOW, 0xc0);
        !          3868: 
        !          3869:     }
        !          3870: 
        !          3871: 
        !          3872: 
        !          3873:     //
        !          3874:     // If this is a PC I/O Bus....
        !          3875:     // Set up the shared RAM to be right after the MMIO.
        !          3876:     //
        !          3877: 
        !          3878:     if (Adapter->UsingPcIoBus){
        !          3879:         WRITE_ADAPTER_REGISTER(Adapter, RRR_LOW, Adapter->RrrLowValue);
        !          3880:     }
        !          3881: 
        !          3882: 
        !          3883: 
        !          3884:     //
        !          3885:     // Allow the reset complete interrupt to be
        !          3886:     // serviced correctly.
        !          3887:     //
        !          3888:     SET_INTERRUPT_RESET_FLAG(Adapter);
        !          3889: 
        !          3890:     //
        !          3891:     // Enable card interrupts to get the reset interrupt.
        !          3892:     //
        !          3893: 
        !          3894:     WRITE_ADAPTER_REGISTER(Adapter, ISRP_LOW,
        !          3895:                 ISRP_LOW_NO_CHANNEL_CHECK | ISRP_LOW_INTERRUPT_ENABLE);
        !          3896: 
        !          3897: 
        !          3898:     //
        !          3899:     // The remaining processing is done in the
        !          3900:     // interrupt handler.
        !          3901:     //
        !          3902: 
        !          3903: 
        !          3904: 
        !          3905:     //
        !          3906:     // OK, now abort pending requests before we nuke
        !          3907:     // everything.
        !          3908:     //
        !          3909: 
        !          3910:     NdisDprAcquireSpinLock (&Adapter->Lock);
        !          3911: 
        !          3912:     IbmtokAbortSends (Adapter, NDIS_STATUS_REQUEST_ABORTED);
        !          3913: 
        !          3914:     NdisDprReleaseSpinLock (&Adapter->Lock);
        !          3915: 
        !          3916: }
        !          3917: 
        !          3918: extern
        !          3919: VOID
        !          3920: IbmtokFinishAdapterReset(
        !          3921:     IN PIBMTOK_ADAPTER Adapter
        !          3922:     )
        !          3923: 
        !          3924: /*++
        !          3925: 
        !          3926: Routine Description:
        !          3927: 
        !          3928:     Called by HandleResetStaging when the last piece
        !          3929:     of the adapter reset is complete and normal
        !          3930:     operation can resume.
        !          3931: 
        !          3932:     Called with the lock held and returns with it held.
        !          3933: 
        !          3934: Arguments:
        !          3935: 
        !          3936:     Adapter - The adapter that the reset is for.
        !          3937: 
        !          3938: Return Value:
        !          3939: 
        !          3940:     None.
        !          3941: 
        !          3942: --*/
        !          3943: 
        !          3944: {
        !          3945:     PLIST_ENTRY CurrentLink;
        !          3946:     PIBMTOK_OPEN TempOpen;
        !          3947: 
        !          3948: 
        !          3949:     SetResetVariables(Adapter);
        !          3950: 
        !          3951:     if (Adapter->UnpluggedResetInProgress) {
        !          3952:         Adapter->UnpluggedResetInProgress = FALSE;
        !          3953:         Adapter->Unplugged = FALSE;
        !          3954:         Adapter->LobeWireFaultIndicated = FALSE;
        !          3955:     }
        !          3956: 
        !          3957:     Adapter->ResetInProgress = FALSE;
        !          3958:     Adapter->ResetInterruptAllowed = FALSE;
        !          3959:     Adapter->ResetInterruptHasArrived = FALSE;
        !          3960:     Adapter->NotAcceptingRequests = FALSE;
        !          3961: 
        !          3962:     //
        !          3963:     // Get any interrupts that have been deferred
        !          3964:     // while NotAcceptingRequests was TRUE.
        !          3965:     //
        !          3966:     IbmtokForceAdapterInterrupt(Adapter);
        !          3967: 
        !          3968:     if (Adapter->ResettingOpen != NULL) {
        !          3969: 
        !          3970:         PIBMTOK_OPEN ResettingOpen = Adapter->ResettingOpen;
        !          3971: 
        !          3972:         //
        !          3973:         // Indicate reset complete to everybody
        !          3974:         //
        !          3975: 
        !          3976:         CurrentLink = Adapter->OpenBindings.Flink;
        !          3977: 
        !          3978:         while (CurrentLink != &(Adapter->OpenBindings)){
        !          3979: 
        !          3980:             TempOpen = CONTAINING_RECORD(
        !          3981:                                  CurrentLink,
        !          3982:                                  IBMTOK_OPEN,
        !          3983:                                  OpenList
        !          3984:                                  );
        !          3985: 
        !          3986:             NdisReleaseSpinLock(&Adapter->Lock);
        !          3987: 
        !          3988:             NdisIndicateStatus(TempOpen->NdisBindingContext,
        !          3989:                                NDIS_STATUS_RESET_END,
        !          3990:                                NULL,
        !          3991:                                0
        !          3992:                               );
        !          3993: 
        !          3994:             NdisIndicateStatusComplete(TempOpen->NdisBindingContext);
        !          3995: 
        !          3996:             NdisAcquireSpinLock(&Adapter->Lock);
        !          3997: 
        !          3998:             CurrentLink = CurrentLink->Flink;
        !          3999: 
        !          4000:         }
        !          4001: 
        !          4002:         //
        !          4003:         // Decrement the reference count that was incremented
        !          4004:         // in SetupForReset.
        !          4005:         //
        !          4006:         ResettingOpen->References--;
        !          4007: 
        !          4008:         NdisReleaseSpinLock(&Adapter->Lock);
        !          4009: 
        !          4010:         NdisCompleteReset(
        !          4011:             ResettingOpen->NdisBindingContext,
        !          4012:             NDIS_STATUS_SUCCESS
        !          4013:             );
        !          4014: 
        !          4015:         NdisAcquireSpinLock(&Adapter->Lock);
        !          4016: 
        !          4017:     }
        !          4018: 
        !          4019: }
        !          4020: 
        !          4021: STATIC
        !          4022: VOID
        !          4023: IbmtokSetupRegistersAndInit(
        !          4024:     IN PIBMTOK_ADAPTER Adapter
        !          4025:     )
        !          4026: 
        !          4027: /*++
        !          4028: 
        !          4029: Routine Description:
        !          4030: 
        !          4031:     It is this routines responsibility to make sure that the
        !          4032:     initialization block is filled and the chip is initialized
        !          4033:     *but not* started.
        !          4034: 
        !          4035:     NOTE: This routine assumes that it is called with the lock
        !          4036:     acquired OR that only a single thread of execution is working
        !          4037:     with this particular adapter.
        !          4038: 
        !          4039: Arguments:
        !          4040: 
        !          4041:     Adapter - The adapter whose hardware is to be initialized.
        !          4042: 
        !          4043: Return Value:
        !          4044: 
        !          4045:     None.
        !          4046: 
        !          4047: --*/
        !          4048: {
        !          4049: 
        !          4050:     //
        !          4051:     // Enable card interrupts to get the reset interrupt.
        !          4052:     //
        !          4053: 
        !          4054:     WRITE_ADAPTER_REGISTER(Adapter, ISRP_LOW,
        !          4055:                 ISRP_LOW_NO_CHANNEL_CHECK | ISRP_LOW_INTERRUPT_ENABLE);
        !          4056: 
        !          4057:     //
        !          4058:     // Set the timer to 10 milliseconds...this seems to
        !          4059:     // be necessary for proper operation (according to
        !          4060:     // ChandanC).
        !          4061:     //
        !          4062: 
        !          4063:     WRITE_ADAPTER_REGISTER(Adapter, TVR_HIGH, 0x01);
        !          4064: 
        !          4065: 
        !          4066:     //
        !          4067:     // Start the timer and set it to reload, but not to
        !          4068:     // interrupt us (TCR_LOW_INTERRUPT_MASK is off). This
        !          4069:     // will still cause bit 4 in the ISRP Low to go on,
        !          4070:     // but it won't cause an interrupt.
        !          4071:     //
        !          4072: 
        !          4073: #if 0
        !          4074:     WRITE_ADAPTER_REGISTER(Adapter, TCR_LOW,
        !          4075: //              TCR_LOW_INTERRUPT_MASK |
        !          4076:                 TCR_LOW_RELOAD_TIMER | TCR_LOW_COUNTER_ENABLE);
        !          4077: #endif
        !          4078:     WRITE_ADAPTER_REGISTER(Adapter, TCR_LOW, 0);
        !          4079: 
        !          4080: 
        !          4081: 
        !          4082:     //
        !          4083:     // If this is a PC I/O Bus...
        !          4084:     // Set up the shared RAM to be right after the MMIO.
        !          4085:     //
        !          4086: 
        !          4087:     if (Adapter->UsingPcIoBus) {
        !          4088:         WRITE_ADAPTER_REGISTER(Adapter, RRR_LOW, Adapter->RrrLowValue);
        !          4089:     }
        !          4090: 
        !          4091: 
        !          4092:     //
        !          4093:     // The remaining initialization processing is done in
        !          4094:     // the interrupt handler.
        !          4095:     //
        !          4096: 
        !          4097: }
        !          4098: 
        !          4099: VOID
        !          4100: IbmtokSetupForReset(
        !          4101:     IN PIBMTOK_ADAPTER Adapter,
        !          4102:     IN PIBMTOK_OPEN Open
        !          4103:     )
        !          4104: 
        !          4105: /*++
        !          4106: 
        !          4107: Routine Description:
        !          4108: 
        !          4109:     This routine is used to fill in the who and why a reset is
        !          4110:     being set up as well as setting the appropriate fields in the
        !          4111:     adapter.
        !          4112: 
        !          4113:     NOTE: This routine must be called with the lock acquired.
        !          4114: 
        !          4115: Arguments:
        !          4116: 
        !          4117:     Adapter - The adapter whose hardware is to be initialized.
        !          4118: 
        !          4119:     Open - A (possibly NULL) pointer to an sonic open structure.
        !          4120:     The reason it could be null is if the adapter is initiating the
        !          4121:     reset on its own.
        !          4122: 
        !          4123: Return Value:
        !          4124: 
        !          4125:     None.
        !          4126: 
        !          4127: --*/
        !          4128: {
        !          4129:     //
        !          4130:     // Notify of reset start
        !          4131:     //
        !          4132: 
        !          4133:     PLIST_ENTRY CurrentLink;
        !          4134:     PIBMTOK_OPEN TempOpen;
        !          4135: 
        !          4136:     if (Open != NULL) {
        !          4137: 
        !          4138:         CurrentLink = Adapter->OpenBindings.Flink;
        !          4139: 
        !          4140:         while (CurrentLink != &(Adapter->OpenBindings)){
        !          4141: 
        !          4142:             TempOpen = CONTAINING_RECORD(
        !          4143:                                  CurrentLink,
        !          4144:                                  IBMTOK_OPEN,
        !          4145:                                  OpenList
        !          4146:                                  );
        !          4147: 
        !          4148:             NdisReleaseSpinLock(&Adapter->Lock);
        !          4149: 
        !          4150:             NdisIndicateStatus(TempOpen->NdisBindingContext,
        !          4151:                                NDIS_STATUS_RESET_START,
        !          4152:                                NULL,
        !          4153:                                0
        !          4154:                               );
        !          4155: 
        !          4156:             NdisAcquireSpinLock(&Adapter->Lock);
        !          4157: 
        !          4158:             CurrentLink = CurrentLink->Flink;
        !          4159: 
        !          4160:         }
        !          4161:     }
        !          4162: 
        !          4163: 
        !          4164:     Adapter->ResetInProgress = TRUE;
        !          4165:     Adapter->NotAcceptingRequests = TRUE;
        !          4166: 
        !          4167:     Adapter->ResettingOpen = Open;
        !          4168: 
        !          4169:     //
        !          4170:     // This will go to 1 when StartAdapterReset is called.
        !          4171:     //
        !          4172:     Adapter->CurrentResetStage = 0;
        !          4173: 
        !          4174:     //
        !          4175:     // If there is a valid open we should up the reference count
        !          4176:     // so that the open can't be deleted before we indicate that
        !          4177:     // their request is finished.
        !          4178:     //
        !          4179: 
        !          4180:     if (Open != NULL) {
        !          4181: 
        !          4182:         Open->References++;
        !          4183: 
        !          4184:     }
        !          4185: 
        !          4186: }
        !          4187: 
        !          4188: NDIS_STATUS
        !          4189: IbmtokAddAdapter(
        !          4190:     IN NDIS_HANDLE MacMacContext,
        !          4191:     IN NDIS_HANDLE ConfigurationHandle,
        !          4192:     IN PNDIS_STRING AdapterName
        !          4193:     )
        !          4194: 
        !          4195: /*++
        !          4196: 
        !          4197: Routine Description:
        !          4198: 
        !          4199:     This routine is used to initialize each adapter card/chip.
        !          4200: 
        !          4201: Arguments:
        !          4202: 
        !          4203:     see NDIS 3.0 spec...
        !          4204: 
        !          4205: Return Value:
        !          4206: 
        !          4207: 
        !          4208:     NDIS_STATUS_SUCCESS - Adapter was successfully added.
        !          4209:     NDIS_STATUS_FAILURE - Adapter was not added, also MAC deregistered.
        !          4210: 
        !          4211: --*/
        !          4212: 
        !          4213: {
        !          4214:     PIBMTOK_ADAPTER Adapter;
        !          4215: 
        !          4216:     NDIS_HANDLE ConfigHandle;
        !          4217:     PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
        !          4218:     NDIS_STRING BusTypeStr = NDIS_STRING_CONST("BusType");
        !          4219:     NDIS_STRING IOAddressStr = NDIS_STRING_CONST("IoBaseAddress");
        !          4220:     NDIS_STRING NetworkAddressStr = NDIS_STRING_CONST("NetworkAddress");
        !          4221:     NDIS_STRING PacketSizeStr = NDIS_STRING_CONST("MaximumPacketSize");
        !          4222: 
        !          4223:     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
        !          4224: 
        !          4225:     BOOLEAN PrimaryAdapter = TRUE;
        !          4226:     BOOLEAN ConfigError = FALSE;
        !          4227:     BOOLEAN McaCard = FALSE;
        !          4228: 
        !          4229:     UINT SlotNumber;
        !          4230:     NDIS_MCA_POS_DATA McaData;
        !          4231: 
        !          4232:     PVOID NetAddress;
        !          4233:     ULONG Length;
        !          4234: 
        !          4235:     //
        !          4236:     // Allocate the Adapter block.
        !          4237:     //
        !          4238: 
        !          4239:     if (IBMTOK_ALLOC_PHYS(&Adapter, sizeof(IBMTOK_ADAPTER)) !=
        !          4240:         NDIS_STATUS_SUCCESS) {
        !          4241: 
        !          4242:         return(NDIS_STATUS_RESOURCES);
        !          4243: 
        !          4244:     }
        !          4245: 
        !          4246: 
        !          4247:     IBMTOK_ZERO_MEMORY(
        !          4248:             Adapter,
        !          4249:             sizeof(IBMTOK_ADAPTER)
        !          4250:             );
        !          4251: 
        !          4252:     Adapter->MaxTransmittablePacket = 17960;
        !          4253:     Adapter->CurrentRingState = NdisRingStateClosed;
        !          4254: 
        !          4255:     Adapter->NdisMacHandle = ((PIBMTOK_MAC)MacMacContext)->NdisMacHandle;
        !          4256: 
        !          4257: 
        !          4258:     NdisOpenConfiguration(
        !          4259:                     &Status,
        !          4260:                     &ConfigHandle,
        !          4261:                     ConfigurationHandle
        !          4262:                     );
        !          4263: 
        !          4264:     if (Status != NDIS_STATUS_SUCCESS) {
        !          4265: 
        !          4266:         IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER));
        !          4267: 
        !          4268:         return NDIS_STATUS_FAILURE;
        !          4269: 
        !          4270:     }
        !          4271: 
        !          4272:     //
        !          4273:     // Read Bus Type
        !          4274:     //
        !          4275: 
        !          4276:     NdisReadConfiguration(
        !          4277:                     &Status,
        !          4278:                     &ReturnedValue,
        !          4279:                     ConfigHandle,
        !          4280:                     &BusTypeStr,
        !          4281:                     NdisParameterHexInteger
        !          4282:                     );
        !          4283: 
        !          4284:     if (Status == NDIS_STATUS_SUCCESS) {
        !          4285: 
        !          4286:         if (ReturnedValue->ParameterData.IntegerData == (ULONG)NdisInterfaceMca) {
        !          4287: 
        !          4288:             McaCard = TRUE;
        !          4289: 
        !          4290:         }
        !          4291: 
        !          4292:     }
        !          4293: 
        !          4294:     //
        !          4295:     // Get I/O Address
        !          4296:     //
        !          4297: 
        !          4298:     if (McaCard) {
        !          4299: 
        !          4300:         //
        !          4301:         // Get I/O Address from Mca Pos info.
        !          4302:         //
        !          4303: 
        !          4304:         NdisReadMcaPosInformation(
        !          4305:                     &Status,
        !          4306:                     ConfigurationHandle,
        !          4307:                     &SlotNumber,
        !          4308:                     &McaData
        !          4309:                     );
        !          4310: 
        !          4311:         if (Status != NDIS_STATUS_SUCCESS) {
        !          4312: 
        !          4313:             ConfigError = TRUE;
        !          4314:             goto RegisterAdapter;
        !          4315: 
        !          4316:         }
        !          4317: 
        !          4318:         //
        !          4319:         // Now interperet the data
        !          4320:         //
        !          4321: 
        !          4322:         switch (McaData.PosData2 & 0x1) {
        !          4323:             case 0x00:
        !          4324:                 Adapter->IbmtokPortAddress = PRIMARY_ADAPTER_OFFSET;
        !          4325:                 break;
        !          4326: 
        !          4327:             case 0x01:
        !          4328:                 Adapter->IbmtokPortAddress = ALTERNATE_ADAPTER_OFFSET;
        !          4329:                 break;
        !          4330: 
        !          4331:         }
        !          4332: 
        !          4333:     } else {
        !          4334: 
        !          4335:         //
        !          4336:         // Read I/O Address
        !          4337:         //
        !          4338: 
        !          4339:         NdisReadConfiguration(
        !          4340:                         &Status,
        !          4341:                         &ReturnedValue,
        !          4342:                         ConfigHandle,
        !          4343:                         &IOAddressStr,
        !          4344:                         NdisParameterInteger
        !          4345:                         );
        !          4346: 
        !          4347:         if (Status == NDIS_STATUS_SUCCESS) {
        !          4348: 
        !          4349:             PrimaryAdapter = (ReturnedValue->ParameterData.IntegerData == 1)?TRUE:FALSE;
        !          4350: 
        !          4351:         }
        !          4352: 
        !          4353:         if (PrimaryAdapter) {
        !          4354: 
        !          4355:             Adapter->IbmtokPortAddress = PRIMARY_ADAPTER_OFFSET;
        !          4356: 
        !          4357:         } else {
        !          4358: 
        !          4359:             Adapter->IbmtokPortAddress = ALTERNATE_ADAPTER_OFFSET;
        !          4360: 
        !          4361:         }
        !          4362: 
        !          4363:     }
        !          4364: 
        !          4365:     //
        !          4366:     // Read PacketSize
        !          4367:     //
        !          4368: 
        !          4369:     NdisReadConfiguration(
        !          4370:                     &Status,
        !          4371:                     &ReturnedValue,
        !          4372:                     ConfigHandle,
        !          4373:                     &PacketSizeStr,
        !          4374:                     NdisParameterInteger
        !          4375:                     );
        !          4376: 
        !          4377:     if (Status == NDIS_STATUS_SUCCESS) {
        !          4378: 
        !          4379:         Adapter->MaxTransmittablePacket = ReturnedValue->ParameterData.IntegerData;
        !          4380: 
        !          4381:     }
        !          4382: 
        !          4383: 
        !          4384:     //
        !          4385:     // Read net address
        !          4386:     //
        !          4387: 
        !          4388:     NdisReadNetworkAddress(
        !          4389:                     &Status,
        !          4390:                     &NetAddress,
        !          4391:                     &Length,
        !          4392:                     ConfigHandle
        !          4393:                     );
        !          4394: 
        !          4395:     if ((Length == TR_LENGTH_OF_ADDRESS) && (Status == NDIS_STATUS_SUCCESS)) {
        !          4396: 
        !          4397:         TR_COPY_NETWORK_ADDRESS(
        !          4398:                 Adapter->NetworkAddress,
        !          4399:                 NetAddress
        !          4400:                 );
        !          4401: 
        !          4402:     }
        !          4403: 
        !          4404: RegisterAdapter:
        !          4405: 
        !          4406:     NdisCloseConfiguration(ConfigHandle);
        !          4407: 
        !          4408:     Status = IbmtokRegisterAdapter(
        !          4409:                      Adapter,
        !          4410:                      ConfigurationHandle,
        !          4411:                      AdapterName,
        !          4412:                      McaCard,
        !          4413:                      ConfigError
        !          4414:                      );
        !          4415: 
        !          4416:     if (Status != NDIS_STATUS_SUCCESS) {
        !          4417: 
        !          4418:         IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER));
        !          4419: 
        !          4420:     }
        !          4421: 
        !          4422:     return Status;
        !          4423: 
        !          4424: }
        !          4425: 
        !          4426: VOID
        !          4427: IbmtokRemoveAdapter(
        !          4428:     IN PVOID MacAdapterContext
        !          4429:     )
        !          4430: 
        !          4431: 
        !          4432: /*++
        !          4433: 
        !          4434: Routine Description:
        !          4435: 
        !          4436:     This routine is called when an adapter is to be removed.
        !          4437: 
        !          4438: Arguments:
        !          4439: 
        !          4440:     MacAdapterContext - Pointer to global list of adapter blocks.
        !          4441: 
        !          4442: Return Value:
        !          4443: 
        !          4444:     None
        !          4445: 
        !          4446: --*/
        !          4447: 
        !          4448: {
        !          4449:     PIBMTOK_ADAPTER Adapter;
        !          4450:     BOOLEAN Canceled;
        !          4451: 
        !          4452:     Adapter = PIBMTOK_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
        !          4453: 
        !          4454:     //
        !          4455:     // There are no opens left, so remove ourselves.
        !          4456:     //
        !          4457: 
        !          4458:     NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled);
        !          4459: 
        !          4460:     if ( !Canceled ) {
        !          4461: 
        !          4462:         NdisStallExecution(500000);
        !          4463:     }
        !          4464: 
        !          4465:     NdisRemoveInterrupt(&(Adapter->Interrupt));
        !          4466: 
        !          4467:     NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          4468:                      Adapter->SharedRam,
        !          4469:                      (Adapter->MappedSharedRam == 0x10000) ?
        !          4470:                        0x8000 :
        !          4471:                        Adapter->MappedSharedRam
        !          4472:                     );
        !          4473: 
        !          4474:     TrDeleteFilter(Adapter->FilterDB);
        !          4475: 
        !          4476:     NdisFreeSpinLock(&Adapter->Lock);
        !          4477: 
        !          4478:     NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
        !          4479: 
        !          4480:     IBMTOK_FREE_PHYS(Adapter, sizeof(IBMTOK_ADAPTER));
        !          4481: 
        !          4482:     return;
        !          4483: 
        !          4484: }
        !          4485: 
        !          4486: VOID
        !          4487: IbmtokUnload(
        !          4488:     IN NDIS_HANDLE MacMacContext
        !          4489:     )
        !          4490: 
        !          4491: /*++
        !          4492: 
        !          4493: Routine Description:
        !          4494: 
        !          4495:     IbmtokUnload is called when the MAC is to unload itself.
        !          4496: 
        !          4497: Arguments:
        !          4498: 
        !          4499:     MacMacContext - nothing.
        !          4500: 
        !          4501: Return Value:
        !          4502: 
        !          4503:     None.
        !          4504: 
        !          4505: --*/
        !          4506: 
        !          4507: {
        !          4508:     NDIS_STATUS InitStatus;
        !          4509: 
        !          4510:     UNREFERENCED_PARAMETER(MacMacContext);
        !          4511: 
        !          4512:     NdisDeregisterMac(
        !          4513:             &InitStatus,
        !          4514:             ((PIBMTOK_MAC)MacMacContext)->NdisMacHandle
        !          4515:             );
        !          4516: 
        !          4517:     NdisTerminateWrapper(
        !          4518:             ((PIBMTOK_MAC)MacMacContext)->NdisWrapperHandle,
        !          4519:             NULL
        !          4520:             );
        !          4521: 
        !          4522:     return;
        !          4523: }
        !          4524: 
        !          4525: STATIC
        !          4526: BOOLEAN
        !          4527: IbmtokHardwareDetails(
        !          4528:     IN PIBMTOK_ADAPTER Adapter
        !          4529:     )
        !          4530: 
        !          4531: /*++
        !          4532: 
        !          4533: Routine Description:
        !          4534: 
        !          4535:     This routine gets the MMIO address and interrupt level.
        !          4536:     It also maps the MMIO and Shared RAM.
        !          4537: 
        !          4538: Arguments:
        !          4539: 
        !          4540:     Adapter - Where to store the network address.
        !          4541: 
        !          4542: Return Value:
        !          4543: 
        !          4544:     TRUE if successful.
        !          4545: 
        !          4546: --*/
        !          4547: 
        !          4548: {
        !          4549: 
        !          4550:     NDIS_STATUS Status;
        !          4551: 
        !          4552:     //
        !          4553:     // Holds the value read from the SWITCH_READ_1 port.
        !          4554:     //
        !          4555:     UCHAR SwitchRead1;
        !          4556: 
        !          4557:     //
        !          4558:     // Holds the value read from the SWITCH_READ_2 port in
        !          4559:     // the Microchannel Bus.
        !          4560:     //
        !          4561:     UCHAR SwitchRead2;
        !          4562: 
        !          4563:     //
        !          4564:     // Holds the physical address of the MMIO region.
        !          4565:     //
        !          4566:     ULONG MmioAddress;
        !          4567: 
        !          4568:     NDIS_PHYSICAL_ADDRESS PhysicalAddress;
        !          4569: 
        !          4570:     //
        !          4571:     // The interrupt level;
        !          4572:     //
        !          4573:     UINT InterruptLevel;
        !          4574: 
        !          4575:     //
        !          4576:     // The RRR bits indicating the Shared RAM size:
        !          4577:     // 0 = 8K, 1 = 16K, 2 = 32K, 3 = 64K.
        !          4578:     //
        !          4579:     UCHAR SharedRamBits;
        !          4580: 
        !          4581:     //
        !          4582:     // The actual size of Shared RAM from RRR bits 2,3 in
        !          4583:     // the PC I/O Bus adapter.
        !          4584:     //
        !          4585:     UINT RrrSharedRamSize;
        !          4586: 
        !          4587:     //
        !          4588:     // Common variable for storing total Shared RAM Size.
        !          4589:     //
        !          4590:     UINT SharedRamSize;
        !          4591: 
        !          4592:     //
        !          4593:     // The actual address of Shared RAM from the SWITCH_READ_2
        !          4594:     // port in the Microchannel adapter.
        !          4595:     //
        !          4596:     UINT McaSharedRam;
        !          4597: 
        !          4598:     //
        !          4599:     // The boundary needed for the Shared RAM mapping.
        !          4600:     //
        !          4601:     UCHAR BoundaryNeeded;
        !          4602: 
        !          4603:     //
        !          4604:     // The value read from the Shared RAM paging byte of
        !          4605:     // the AIP.
        !          4606:     //
        !          4607:     UCHAR AipSharedRamPaging;
        !          4608: 
        !          4609:     UCHAR RegValue;
        !          4610: 
        !          4611:     //
        !          4612:     // SwitchRead1 contains the interrupt code in the low 2 bits,
        !          4613:     // and bits 18 through 13 of the MMIO address in the high
        !          4614:     // 6 bits.
        !          4615:     //
        !          4616: 
        !          4617:     READ_ADAPTER_PORT(Adapter, SWITCH_READ_1, &SwitchRead1);
        !          4618: 
        !          4619:     //
        !          4620:     // SwitchRead2 contains Bit 19 of the MMIO address in the
        !          4621:     // low bit.  It is always 1 for PC I/O Bus and possibly 0
        !          4622:     // for the Microchannel bus
        !          4623:     //
        !          4624: 
        !          4625:     READ_ADAPTER_PORT(Adapter, SWITCH_READ_2, &SwitchRead2);
        !          4626: 
        !          4627:     //
        !          4628:     // To compute MmioAddress, we mask off the low 2 bits of
        !          4629:     // SwitchRead1, shift it out by 11 (so that the high 6 bits
        !          4630:     // are moved to the right place), and add in the 19th bit value.
        !          4631:     //
        !          4632: 
        !          4633:     MmioAddress = ((SwitchRead1 & 0xfc) << 11) | ((SwitchRead2 & 1) << 19);
        !          4634: 
        !          4635:     NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
        !          4636:     NdisSetPhysicalAddressLow(PhysicalAddress, MmioAddress);
        !          4637: 
        !          4638:     NdisMapIoSpace(
        !          4639:                    &Status,
        !          4640:                    (PVOID *)&(Adapter->MmioRegion),
        !          4641:                    Adapter->NdisAdapterHandle,
        !          4642:                    PhysicalAddress,
        !          4643:                    0x2000);
        !          4644: 
        !          4645:     if (Status != NDIS_STATUS_SUCCESS) {
        !          4646: 
        !          4647:         NdisWriteErrorLogEntry(
        !          4648:            Adapter->NdisAdapterHandle,
        !          4649:            NDIS_ERROR_CODE_RESOURCE_CONFLICT,
        !          4650:            0
        !          4651:            );
        !          4652: 
        !          4653:         return(FALSE);
        !          4654: 
        !          4655:     }
        !          4656: 
        !          4657: 
        !          4658:     //
        !          4659:     // Now we have mapped the MMIO, look at the AIP. First
        !          4660:     // determine the channel identifier.
        !          4661:     //
        !          4662: 
        !          4663:     {
        !          4664:         //
        !          4665:         // Will hold the Adapter ID as read from the card.
        !          4666:         //
        !          4667:         ULONG AdapterId[3];
        !          4668: 
        !          4669:         //
        !          4670:         // What AdapterId should contain for a PC I/O bus card.
        !          4671:         //
        !          4672:         static ULONG PcIoBusId[3] = { 0x5049434f, 0x36313130, 0x39393020 };
        !          4673: 
        !          4674:         //
        !          4675:         // What AdapterId should contain for a Micro Channel card.
        !          4676:         //
        !          4677:         static ULONG MicroChannelId[3] = { 0x4d415253, 0x36335834, 0x35313820 };
        !          4678: 
        !          4679:         //
        !          4680:         // Loop counters.
        !          4681:         //
        !          4682:         UINT i, j;
        !          4683: 
        !          4684:         UCHAR TmpUchar;
        !          4685: 
        !          4686:         //
        !          4687:         // Read in AdapterId.
        !          4688:         //
        !          4689:         // Turns out that the bytes which identify the card are stored
        !          4690:         // in a very odd manner.  There are 48 bytes on the card.  The
        !          4691:         // even numbered bytes contain 4 bits of the card signature.
        !          4692:         //
        !          4693: 
        !          4694:         for (i=0; i<3; i++) {
        !          4695: 
        !          4696:             AdapterId[i] = 0;
        !          4697: 
        !          4698:             for (j=0; j<16; j+=2) {
        !          4699: 
        !          4700:                 READ_ADAPTER_REGISTER(Adapter,
        !          4701:                                       CHANNEL_IDENTIFIER + (i*16 + j),
        !          4702:                                       &TmpUchar
        !          4703:                                      );
        !          4704: 
        !          4705:                 AdapterId[i] = (AdapterId[i] << 4) + TmpUchar;
        !          4706: 
        !          4707: 
        !          4708:             }
        !          4709: 
        !          4710:         }
        !          4711: 
        !          4712:         if ((AdapterId[0] == PcIoBusId[0]) &&
        !          4713:             (AdapterId[1] == PcIoBusId[1]) &&
        !          4714:             (AdapterId[2] == PcIoBusId[2])) {
        !          4715: 
        !          4716:             Adapter->UsingPcIoBus = TRUE;
        !          4717: 
        !          4718:         } else if ((AdapterId[0] == MicroChannelId[0]) &&
        !          4719:                    (AdapterId[1] == MicroChannelId[1]) &&
        !          4720:                    (AdapterId[2] == MicroChannelId[2])) {
        !          4721: 
        !          4722:             Adapter->UsingPcIoBus = FALSE;
        !          4723: 
        !          4724:         } else {
        !          4725: 
        !          4726:             //
        !          4727:             // Unknown channel type.
        !          4728:             //
        !          4729: 
        !          4730: 
        !          4731:             NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          4732:                              Adapter->MmioRegion,
        !          4733:                              0x2000);
        !          4734: 
        !          4735:             NdisWriteErrorLogEntry(
        !          4736:                 Adapter->NdisAdapterHandle,
        !          4737:                 NDIS_ERROR_CODE_BAD_IO_BASE_ADDRESS,
        !          4738:                 0
        !          4739:                 );
        !          4740: 
        !          4741:             return FALSE;
        !          4742: 
        !          4743:         }
        !          4744: 
        !          4745:     }
        !          4746: 
        !          4747:     //
        !          4748:     // We can read the network address from the AIP but we won't,
        !          4749:     // we read it from the bring-up SRB instead.
        !          4750:     //
        !          4751: 
        !          4752:     //
        !          4753:     // Read the RRR High to get the Shared RAM size (we are
        !          4754:     // only interested in bits 2 and 3).
        !          4755:     //
        !          4756: 
        !          4757:     READ_ADAPTER_REGISTER(Adapter, RRR_HIGH, &SharedRamBits);
        !          4758: 
        !          4759:     SharedRamBits = ((SharedRamBits & 0x0c) >> 2);
        !          4760: 
        !          4761:     if (Adapter->UsingPcIoBus) {
        !          4762: 
        !          4763:         //
        !          4764:         // Here we have to tell the Adapter where Shared RAM is
        !          4765:         // going to be.  To do this we first find the lowest
        !          4766:         // address it could be at, and then advance the address
        !          4767:         // such that it falls on a correct page boudary.
        !          4768:         //
        !          4769: 
        !          4770: 
        !          4771:         //
        !          4772:         // To get value to put in RRR Low, which indicates where
        !          4773:         // the Shared RAM is mapped, we first compute the lowest
        !          4774:         // possible value, which is right after the MMIO region.
        !          4775:         // We take the high six bits of SwitchRead and shift
        !          4776:         // them right one (so bits 18-13 of the address are in
        !          4777:         // bits 6-1), then we turn on bit 7 to indicate that bit
        !          4778:         // 19 of the address is on, and leave bit 0 zero since
        !          4779:         // it must be.
        !          4780:         //
        !          4781: 
        !          4782:         Adapter->RrrLowValue = (UCHAR)
        !          4783:                               ((((SwitchRead1 & 0xfc) >> 1) | 0x80) + 0x02);
        !          4784: 
        !          4785:         //
        !          4786:         // We now have to move up to a memory boundary
        !          4787:         // based on the value of SharedRamBits; 0 (8K) = 16K boundary,
        !          4788:         // 1 (16K) = 16K boundary, 2 (32K) = 32K boundary, and
        !          4789:         // 3 (64K) = 64K Boundary. Remember that the way the
        !          4790:         // address bits are shifted over in RrrLowValue, bit 1
        !          4791:         // is really bit 13 of the final address (turning it on
        !          4792:         // adds 8K), bit 2 if bit 14, etc. We compute Boundary
        !          4793:         // Needed in this frame of reference.
        !          4794:         //
        !          4795: 
        !          4796:         switch (SharedRamBits) {
        !          4797: 
        !          4798:             case 0:
        !          4799:             case 1:
        !          4800: 
        !          4801:                 //
        !          4802:                 // 8K or 16K needs a 16K boundary.
        !          4803:                 //
        !          4804: 
        !          4805:                 RrrSharedRamSize = (SharedRamBits == 0) ? 0x2000 : 0x4000;
        !          4806:                 BoundaryNeeded = 0x04;
        !          4807:                 break;
        !          4808: 
        !          4809:             case 2:
        !          4810: 
        !          4811:                 //
        !          4812:                 // 32K needs a 32K boundary.
        !          4813:                 //
        !          4814: 
        !          4815:                 RrrSharedRamSize = 0x8000;
        !          4816:                 BoundaryNeeded = 0x08;
        !          4817:                 break;
        !          4818: 
        !          4819:             case 3:
        !          4820: 
        !          4821:                 //
        !          4822:                 // 64K needs a 64K boundary.
        !          4823:                 //
        !          4824: 
        !          4825:                 RrrSharedRamSize = 0x10000;
        !          4826:                 BoundaryNeeded = 0x10;
        !          4827:                 break;
        !          4828: 
        !          4829:         }
        !          4830: 
        !          4831: 
        !          4832:         //
        !          4833:         // If RrrLowValue is not on the proper boundary, move it
        !          4834:         // forward until it is.
        !          4835:         //
        !          4836: 
        !          4837:         if (Adapter->RrrLowValue & (BoundaryNeeded-1)) {
        !          4838: 
        !          4839:             Adapter->RrrLowValue = (UCHAR)
        !          4840:               ((Adapter->RrrLowValue & ~(BoundaryNeeded-1)) + BoundaryNeeded);
        !          4841: 
        !          4842:         }
        !          4843: 
        !          4844:         Adapter->MappedSharedRam = SharedRamSize = RrrSharedRamSize;
        !          4845: 
        !          4846:         NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
        !          4847:         NdisSetPhysicalAddressLow(PhysicalAddress, Adapter->RrrLowValue << 12);
        !          4848: 
        !          4849:         NdisMapIoSpace(&Status,
        !          4850:                        (PVOID *)&(Adapter->SharedRam),
        !          4851:                        Adapter->NdisAdapterHandle,
        !          4852:                        PhysicalAddress,
        !          4853:                        RrrSharedRamSize
        !          4854:                       );
        !          4855: 
        !          4856:         if (Status != NDIS_STATUS_SUCCESS) {
        !          4857: 
        !          4858:             NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          4859:                              Adapter->MmioRegion,
        !          4860:                              0x2000);
        !          4861: 
        !          4862:             NdisWriteErrorLogEntry(
        !          4863:                 Adapter->NdisAdapterHandle,
        !          4864:                 NDIS_ERROR_CODE_RESOURCE_CONFLICT,
        !          4865:                 0
        !          4866:                 );
        !          4867: 
        !          4868:             return(FALSE);
        !          4869: 
        !          4870:         }
        !          4871: 
        !          4872:     } else {
        !          4873: 
        !          4874:         //
        !          4875:         // Using Microchannel
        !          4876:         //
        !          4877:         // No need to set Adapter->RrrLowValue since it is not
        !          4878:         // used in the Microchannel adapter.
        !          4879:         //
        !          4880: 
        !          4881:         switch (SharedRamBits){
        !          4882:             case 0:
        !          4883:                 SharedRamSize = 0x2000;
        !          4884:                 break;
        !          4885:             case 1:
        !          4886:                 SharedRamSize = 0x4000;
        !          4887:                 break;
        !          4888:             case 2:
        !          4889:                 SharedRamSize = 0x8000;
        !          4890:                 break;
        !          4891:             case 3:
        !          4892:                 SharedRamSize = 0x10000;
        !          4893:                 break;
        !          4894:         }
        !          4895: 
        !          4896:         McaSharedRam = ((SwitchRead2 & 0xfe) << 12);
        !          4897: 
        !          4898:         NdisSetPhysicalAddressHigh(PhysicalAddress, 0);
        !          4899:         NdisSetPhysicalAddressLow(PhysicalAddress, McaSharedRam);
        !          4900: 
        !          4901:         NdisMapIoSpace(&Status,
        !          4902:                        (PVOID *)&(Adapter->SharedRam),
        !          4903:                        Adapter->NdisAdapterHandle,
        !          4904:                        PhysicalAddress,
        !          4905:                        SharedRamSize);
        !          4906: 
        !          4907:         if (Status != NDIS_STATUS_SUCCESS) {
        !          4908: 
        !          4909:             NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          4910:                              Adapter->MmioRegion,
        !          4911:                              0x2000);
        !          4912: 
        !          4913:             NdisWriteErrorLogEntry(
        !          4914:                 Adapter->NdisAdapterHandle,
        !          4915:                 NDIS_ERROR_CODE_RESOURCE_CONFLICT,
        !          4916:                 0
        !          4917:                 );
        !          4918: 
        !          4919:             return(FALSE);
        !          4920: 
        !          4921:         }
        !          4922: 
        !          4923:         Adapter->MappedSharedRam = SharedRamSize;
        !          4924: 
        !          4925:     }
        !          4926: 
        !          4927: 
        !          4928: 
        !          4929:     //
        !          4930:     // Get the interrupt level...note that a switch being
        !          4931:     // "off" shows up as a 1, "on" is 0.
        !          4932:     //
        !          4933: 
        !          4934:     switch (SwitchRead1 & 0x03) {
        !          4935: 
        !          4936:         case 0: InterruptLevel = 2; break;
        !          4937:         case 1: InterruptLevel = 3; break;
        !          4938:         case 2: InterruptLevel = (Adapter->UsingPcIoBus)?6:10; break;
        !          4939:         case 3: InterruptLevel = (Adapter->UsingPcIoBus)?7:11; break;
        !          4940: 
        !          4941:     }
        !          4942: 
        !          4943:     Adapter->InterruptLevel = InterruptLevel;
        !          4944: 
        !          4945:     //
        !          4946:     // Now determine how much memory the adapter has, and
        !          4947:     // whether to use Shared RAM paging.
        !          4948:     //
        !          4949: 
        !          4950:     Adapter->UpperSharedRamZero = FALSE;
        !          4951: 
        !          4952:     READ_ADAPTER_REGISTER(Adapter, TOTAL_ADAPTER_RAM, &RegValue);
        !          4953: 
        !          4954:     switch (RegValue) {
        !          4955: 
        !          4956:         //
        !          4957:         // These values are described on page 7-26 of the
        !          4958:         // Technical Reference.
        !          4959:         //
        !          4960: 
        !          4961:         case 0xf:
        !          4962: 
        !          4963:             Adapter->TotalSharedRam = SharedRamSize;
        !          4964:             break;
        !          4965: 
        !          4966:         case 0xe:
        !          4967: 
        !          4968:             Adapter->TotalSharedRam = 0x2000;
        !          4969:             break;
        !          4970: 
        !          4971:         case 0xd:
        !          4972: 
        !          4973:             Adapter->TotalSharedRam = 0x4000;
        !          4974:             break;
        !          4975: 
        !          4976:         case 0xc:
        !          4977: 
        !          4978:             Adapter->TotalSharedRam = 0x8000;
        !          4979:             break;
        !          4980: 
        !          4981:         case 0xb:
        !          4982: 
        !          4983:             Adapter->TotalSharedRam = 0x10000;
        !          4984: 
        !          4985:             Adapter->UpperSharedRamZero = TRUE;
        !          4986:             break;
        !          4987: 
        !          4988:         case 0xa:
        !          4989: 
        !          4990:             Adapter->TotalSharedRam = 0x10000;
        !          4991:             break;
        !          4992: 
        !          4993:         default:
        !          4994: 
        !          4995:             NdisWriteErrorLogEntry(
        !          4996:                 Adapter->NdisAdapterHandle,
        !          4997:                 NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION,
        !          4998:                 3,
        !          4999:                 hardwareDetails,
        !          5000:                 IBMTOK_ERRMSG_UNSUPPORTED_RAM,
        !          5001:                 (ULONG)RegValue
        !          5002:                 );
        !          5003: 
        !          5004:             NdisUnmapIoSpace(Adapter->NdisAdapterHandle,
        !          5005:                              Adapter->MmioRegion,
        !          5006:                              0x2000);
        !          5007: 
        !          5008:             if (Adapter->UsingPcIoBus) {
        !          5009:                 NdisUnmapIoSpace(
        !          5010:                     Adapter->NdisAdapterHandle,
        !          5011:                     Adapter->SharedRam,
        !          5012:                     SharedRamSize);
        !          5013:             } else {
        !          5014:                 NdisUnmapIoSpace(
        !          5015:                     Adapter->NdisAdapterHandle,
        !          5016:                     Adapter->SharedRam,
        !          5017:                     SharedRamSize);
        !          5018:             }
        !          5019: 
        !          5020:             return FALSE;
        !          5021: 
        !          5022:     }
        !          5023: 
        !          5024:     //
        !          5025:     // Only allow Shared RAM paging if we have 16K selected
        !          5026:     // on SharedRamSize, 64K of total adapter memory, and it is allowed
        !          5027:     // as specified on p. 7-26 of the Technical Reference.
        !          5028:     //
        !          5029: 
        !          5030:     READ_ADAPTER_REGISTER(Adapter, SHARED_RAM_PAGING, &AipSharedRamPaging);
        !          5031: 
        !          5032: #if 0
        !          5033:     if (SharedRamSize == 0x4000 &&
        !          5034:         Adapter->TotalSharedRam == 0x10000 &&
        !          5035:         (AipSharedRamPaging == 0xe || AipSharedRamPaging == 0xc)) {
        !          5036: 
        !          5037:         Adapter->SharedRamPaging = TRUE;
        !          5038: 
        !          5039:     } else {
        !          5040: 
        !          5041:         Adapter->SharedRamPaging = FALSE;
        !          5042: 
        !          5043:     }
        !          5044: #else
        !          5045:     Adapter->SharedRamPaging = FALSE;
        !          5046: #endif
        !          5047: 
        !          5048: 
        !          5049:     //
        !          5050:     // Read in the maximum sizes allowed for DHBs based on
        !          5051:     // the speed of the adapter (which we don't know yet).
        !          5052:     //
        !          5053: 
        !          5054:     READ_ADAPTER_REGISTER(Adapter, MAX_4_MBPS_DHB, &RegValue);
        !          5055: 
        !          5056:     switch (RegValue) {
        !          5057: 
        !          5058:         case 0xf:
        !          5059:         default:
        !          5060: 
        !          5061:             Adapter->Max4MbpsDhb = 2048;
        !          5062:             break;
        !          5063: 
        !          5064:         case 0xe:
        !          5065: 
        !          5066:             Adapter->Max4MbpsDhb = 4096;
        !          5067:             break;
        !          5068: 
        !          5069:         case 0xd:
        !          5070: 
        !          5071:             Adapter->Max4MbpsDhb = 4464;
        !          5072:             break;
        !          5073: 
        !          5074:     }
        !          5075: 
        !          5076:     READ_ADAPTER_REGISTER(Adapter, MAX_16_MBPS_DHB, &RegValue);
        !          5077: 
        !          5078:     switch (RegValue) {
        !          5079: 
        !          5080:         case 0xf:
        !          5081:         default:
        !          5082: 
        !          5083:             Adapter->Max16MbpsDhb = 2048;
        !          5084:             break;
        !          5085: 
        !          5086:         case 0xe:
        !          5087: 
        !          5088:             Adapter->Max16MbpsDhb = 4096;
        !          5089:             break;
        !          5090: 
        !          5091:         case 0xd:
        !          5092: 
        !          5093:             Adapter->Max16MbpsDhb = 8192;
        !          5094:             break;
        !          5095: 
        !          5096:         case 0xc:
        !          5097: 
        !          5098:             Adapter->Max16MbpsDhb = 16384;
        !          5099:             break;
        !          5100: 
        !          5101:         case 0xb:
        !          5102: 
        !          5103:             Adapter->Max16MbpsDhb = 17960;
        !          5104:             break;
        !          5105: 
        !          5106:     }
        !          5107: 
        !          5108: 
        !          5109:     return TRUE;
        !          5110: 
        !          5111: }

unix.superglobalmegacorp.com

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