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