Annotation of ntddk/src/network/sonic/sonic.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1990-1992  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     sonic.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This is the main file for the National Semiconductor SONIC
                     12:     Ethernet controller.  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) 14-Nov-1990
                     21: 
                     22: Environment:
                     23: 
                     24:     Kernel Mode - Or whatever is the equivalent.
                     25: 
                     26: Revision History:
                     27: 
                     28: 
                     29: --*/
                     30: 
                     31: #include <ndis.h>
                     32: 
                     33: 
                     34: #include <efilter.h>
                     35: #include <sonichrd.h>
                     36: #include <sonicsft.h>
                     37: 
                     38: 
                     39: 
                     40: //
                     41: // This variable is used to control debug output.
                     42: //
                     43: 
                     44: #if DBG
                     45: INT SonicDbg = 0;
                     46: #endif
                     47: 
                     48: 
                     49: STATIC
                     50: VOID
                     51: SonicShutdown(
                     52:     IN PVOID ShutdownContext
                     53:     );
                     54: 
                     55: STATIC
                     56: NDIS_STATUS
                     57: SonicOpenAdapter(
                     58:     OUT PNDIS_STATUS OpenErrorStatus,
                     59:     OUT NDIS_HANDLE *MacBindingHandle,
                     60:     OUT PUINT SelectedMediumIndex,
                     61:     IN PNDIS_MEDIUM MediumArray,
                     62:     IN UINT MediumArraySize,
                     63:     IN NDIS_HANDLE NdisBindingContext,
                     64:     IN NDIS_HANDLE MacAdapterContext,
                     65:     IN UINT OpenOptions,
                     66:     IN PSTRING AddressingInformation OPTIONAL
                     67:     );
                     68: 
                     69: STATIC
                     70: NDIS_STATUS
                     71: SonicCloseAdapter(
                     72:     IN NDIS_HANDLE MacBindingHandle
                     73:     );
                     74: 
                     75: 
                     76: STATIC
                     77: VOID
                     78: SonicUnload(
                     79:     IN NDIS_HANDLE MacMacContext
                     80:     );
                     81: 
                     82: STATIC
                     83: NDIS_STATUS
                     84: SonicAddAdapter(
                     85:     IN NDIS_HANDLE MacMacContext,
                     86:     IN NDIS_HANDLE ConfigurationHandle,
                     87:     IN PNDIS_STRING AdapterName
                     88:     );
                     89: 
                     90: STATIC
                     91: VOID
                     92: SonicRemoveAdapter(
                     93:     IN NDIS_HANDLE MacAdapterContext
                     94:     );
                     95: 
                     96: STATIC
                     97: NDIS_STATUS
                     98: SonicReset(
                     99:     IN NDIS_HANDLE MacBindingHandle
                    100:     );
                    101: 
                    102: #if 0
                    103: STATIC
                    104: UINT
                    105: CalculateCRC(
                    106:     IN UINT NumberOfBytes,
                    107:     IN PCHAR Input
                    108:     );
                    109: #endif
                    110: 
                    111: STATIC
                    112: BOOLEAN
                    113: SonicSynchClearIsr(
                    114:     IN PVOID Context
                    115:     );
                    116: 
                    117: STATIC
                    118: VOID
                    119: SonicStopChip(
                    120:     IN PSONIC_ADAPTER Adapter
                    121:     );
                    122: 
                    123: STATIC
                    124: BOOLEAN
                    125: SetupRegistersAndInit(
                    126:     IN PSONIC_ADAPTER Adapter
                    127:     );
                    128: 
                    129: STATIC
                    130: BOOLEAN
                    131: SonicInitialInit(
                    132:     IN PSONIC_ADAPTER Adapter
                    133:     );
                    134: 
                    135: #ifdef NDIS_NT
                    136: 
                    137: NTSTATUS
                    138: DriverEntry(
                    139:     IN PDRIVER_OBJECT DriverObject,
                    140:     IN PUNICODE_STRING RegistryPath
                    141:     );
                    142: 
                    143: #else
                    144: 
                    145: NDIS_STATUS
                    146: DriverEntry(
                    147:     VOID
                    148:     );
                    149: 
                    150: #endif
                    151: 
                    152: STATIC
                    153: NDIS_STATUS
                    154: SonicRegisterAdapter(
                    155:     IN NDIS_HANDLE NdisMacHandle,
                    156:     IN NDIS_HANDLE ConfigurationHandle,
                    157:     IN PNDIS_STRING DeviceName,
                    158:     IN PUCHAR NetworkAddress,
                    159:     IN UCHAR AdapterType,
                    160:     IN UINT SlotNumber,
                    161:     IN UINT Controller,
                    162:     IN UINT MultifunctionAdapter,
                    163:     IN UINT SonicInterruptVector,
                    164:     IN UINT SonicInterruptLevel,
                    165:     IN NDIS_INTERRUPT_MODE SonicInterruptMode,
                    166:     IN UINT MaximumOpenAdapters
                    167:     );
                    168: 
                    169: typedef enum {
                    170:     SonicHardwareOk,
                    171:     SonicHardwareChecksum,
                    172:     SonicHardwareConfig
                    173: } SONIC_HARDWARE_STATUS;
                    174: 
                    175: STATIC
                    176: SONIC_HARDWARE_STATUS
                    177: SonicHardwareGetDetails(
                    178:     IN PSONIC_ADAPTER Adapter,
                    179:     IN UINT SlotNumber,
                    180:     IN UINT Controller,
                    181:     IN UINT MultifunctionAdapter,
                    182:     OUT PULONG InitialPort,
                    183:     OUT PULONG NumberOfPorts,
                    184:     IN OUT PUINT InterruptVector,
                    185:     IN OUT PUINT InterruptLevel,
                    186:     OUT ULONG ErrorLogData[3]
                    187:     );
                    188: 
                    189: STATIC
                    190: BOOLEAN
                    191: SonicHardwareGetAddress(
                    192:     IN PSONIC_ADAPTER Adapter,
                    193:     OUT ULONG ErrorLogData[3]
                    194:     );
                    195: 
                    196: #ifdef SONIC_INTERNAL
                    197: 
                    198: //
                    199: // These routines are support reading the address for the
                    200: // sonic internal implementation on the R4000 motherboards.
                    201: //
                    202: 
                    203: STATIC
                    204: NTSTATUS
                    205: SonicHardwareSaveInformation(
                    206:     IN PWSTR ValueName,
                    207:     IN ULONG ValueType,
                    208:     IN PVOID ValueData,
                    209:     IN ULONG ValueLength,
                    210:     IN PVOID Context,
                    211:     IN PVOID EntryContext
                    212:     );
                    213: 
                    214: STATIC
                    215: BOOLEAN
                    216: SonicHardwareVerifyChecksum(
                    217:     IN PSONIC_ADAPTER Adapter,
                    218:     IN PUCHAR EthernetAddress,
                    219:     OUT ULONG ErrorLogData[3]
                    220:     );
                    221: 
                    222: #endif
                    223: 
                    224: 
                    225: //
                    226: // Use the alloc_text pragma to specify the driver initialization routines
                    227: // (they can be paged out).
                    228: //
                    229: 
                    230: #ifdef ALLOC_PRAGMA
                    231: #pragma alloc_text(init,DriverEntry)
                    232: #pragma alloc_text(init,SonicRegisterAdapter)
                    233: #pragma alloc_text(init,SonicInitialInit)
                    234: #pragma alloc_text(init,SonicAddAdapter)
                    235: #pragma alloc_text(init,SonicHardwareGetDetails)
                    236: #pragma alloc_text(init,SonicHardwareGetAddress)
                    237: #ifdef SONIC_INTERNAL
                    238: #pragma alloc_text(init,SonicHardwareSaveInformation)
                    239: #pragma alloc_text(init,SonicHardwareVerifyChecksum)
                    240: #endif
                    241: #endif
                    242: 
                    243: 
                    244: 
                    245: NTSTATUS
                    246: DriverEntry(
                    247:     IN PDRIVER_OBJECT DriverObject,
                    248:     IN PUNICODE_STRING RegistryPath
                    249:     )
                    250: 
                    251: /*++
                    252: 
                    253: Routine Description:
                    254: 
                    255:     This is the primary initialization routine for the sonic driver.
                    256:     It is simply responsible for the intializing the wrapper and registering
                    257:     the MAC.  It then calls a system and architecture specific routine that
                    258:     will initialize and register each adapter.
                    259: 
                    260: Arguments:
                    261: 
                    262:     DriverObject - Pointer to driver object created by the system.
                    263: 
                    264: Return Value:
                    265: 
                    266:     The status of the operation.
                    267: 
                    268: --*/
                    269: 
                    270: {
                    271: 
                    272:     //
                    273:     // Receives the status of the NdisRegisterMac operation.
                    274:     //
                    275:     NDIS_STATUS Status;
                    276: 
                    277:     PSONIC_MAC SonicMac;
                    278: 
                    279:     NDIS_HANDLE SonicWrapperHandle;
                    280: 
                    281:     static const NDIS_STRING MacName = NDIS_STRING_CONST("SONIC");
                    282:     NDIS_MAC_CHARACTERISTICS SonicChar;
                    283: 
                    284: 
                    285:     //
                    286:     // Initialize the wrapper.
                    287:     //
                    288: 
                    289:     NdisInitializeWrapper(
                    290:                 &SonicWrapperHandle,
                    291:                 DriverObject,
                    292:                 RegistryPath,
                    293:                 NULL
                    294:                 );
                    295: 
                    296:     //
                    297:     // Now allocate memory for our global structure.
                    298:     //
                    299: 
                    300:     SONIC_ALLOC_MEMORY(&Status, &SonicMac, sizeof(SONIC_MAC));
                    301: 
                    302:     if (Status != NDIS_STATUS_SUCCESS) {
                    303: 
                    304:          return NDIS_STATUS_RESOURCES;
                    305: 
                    306:     }
                    307: 
                    308:     SonicMac->WrapperHandle = SonicWrapperHandle;
                    309: 
                    310:     //
                    311:     // Initialize the MAC characteristics for the call to
                    312:     // NdisRegisterMac.
                    313:     //
                    314: 
                    315:     SonicChar.MajorNdisVersion = SONIC_NDIS_MAJOR_VERSION;
                    316:     SonicChar.MinorNdisVersion = SONIC_NDIS_MINOR_VERSION;
                    317:     SonicChar.OpenAdapterHandler = SonicOpenAdapter;
                    318:     SonicChar.CloseAdapterHandler = SonicCloseAdapter;
                    319:     SonicChar.SendHandler = SonicSend;
                    320:     SonicChar.TransferDataHandler = SonicTransferData;
                    321:     SonicChar.ResetHandler = SonicReset;
                    322:     SonicChar.RequestHandler = SonicRequest;
                    323:     SonicChar.QueryGlobalStatisticsHandler = SonicQueryGlobalStatistics;
                    324:     SonicChar.UnloadMacHandler = SonicUnload;
                    325:     SonicChar.AddAdapterHandler = SonicAddAdapter;
                    326:     SonicChar.RemoveAdapterHandler = SonicRemoveAdapter;
                    327:     SonicChar.Name = MacName;
                    328: 
                    329: 
                    330:     NdisRegisterMac(
                    331:         &Status,
                    332:         &SonicMac->MacHandle,
                    333:         SonicWrapperHandle,
                    334:         (NDIS_HANDLE)SonicMac,                   // MacMacContext
                    335:         &SonicChar,
                    336:         sizeof(SonicChar)
                    337:         );
                    338: 
                    339:     if (Status == NDIS_STATUS_SUCCESS) {
                    340: 
                    341:         return NDIS_STATUS_SUCCESS;
                    342: 
                    343:     }
                    344: 
                    345: 
                    346:     //
                    347:     // We can only get here if something went wrong with registering
                    348:     // the mac or *all* of the adapters.
                    349:     //
                    350: 
                    351:     NdisTerminateWrapper(SonicWrapperHandle, NULL);
                    352: 
                    353:     return NDIS_STATUS_FAILURE;
                    354: 
                    355: }
                    356: 
                    357: #if DBG
                    358: //
                    359: // Save this to retrieve it in the debugger.
                    360: //
                    361: 
                    362: PVOID SonicAdapterAddress;
                    363: #endif
                    364: 
                    365: 
                    366: STATIC
                    367: NDIS_STATUS
                    368: SonicRegisterAdapter(
                    369:     IN NDIS_HANDLE NdisMacHandle,
                    370:     IN NDIS_HANDLE ConfigurationHandle,
                    371:     IN PNDIS_STRING DeviceName,
                    372:     IN PUCHAR NetworkAddress,
                    373:     IN UCHAR AdapterType,
                    374:     IN UINT SlotNumber,
                    375:     IN UINT Controller,
                    376:     IN UINT MultifunctionAdapter,
                    377:     IN UINT SonicInterruptVector,
                    378:     IN UINT SonicInterruptLevel,
                    379:     IN NDIS_INTERRUPT_MODE SonicInterruptMode,
                    380:     IN UINT MaximumOpenAdapters
                    381:     )
                    382: 
                    383: /*++
                    384: 
                    385: Routine Description:
                    386: 
                    387:     This routine (and its interface) are not portable.  They are
                    388:     defined by the OS, the architecture, and the particular SONIC
                    389:     implementation.
                    390: 
                    391:     This routine is responsible for the allocation of the datastructures
                    392:     for the driver as well as any hardware specific details necessary
                    393:     to talk with the device.
                    394: 
                    395: Arguments:
                    396: 
                    397:     NdisMacHandle - The handle given back to the mac from ndis when
                    398:     the mac registered itself.
                    399: 
                    400:     ConfigurationHandle - Config handle passed to MacAddAdapter.
                    401: 
                    402:     DeviceName - The string containing the name to give to the
                    403:     device adapter.
                    404: 
                    405:     NetworkAddress - The network address, or NULL if the default
                    406:     should be used.
                    407: 
                    408:     AdapterType - The type of the adapter; currently SONIC_ADAPTER_TYPE_EISA
                    409:     and SONIC_ADAPTER_TYPE_INTERNAL are supported,
                    410: 
                    411:     SlotNumber - The slot number for the EISA card.
                    412: 
                    413:     Controller - The controller number for INTERNAL chips.
                    414: 
                    415:     MultifunctionAdapter - The INTERNAL bus number for INTERNAL chips.
                    416: 
                    417:     SonicInterruptVector - The interrupt vector to use for the adapter.
                    418: 
                    419:     SonicInterruptLevel - The interrupt request level to use for this
                    420:     adapter.
                    421: 
                    422:     SonicInterruptMode - The interrupt mode to be use for this adapter.
                    423: 
                    424:     MaximumOpenAdapters - The maximum number of opens at any one time.
                    425: 
                    426: Return Value:
                    427: 
                    428:     Returns a failure status if anything occurred that prevents the
                    429:     initialization of the adapter.
                    430: 
                    431: --*/
                    432: 
                    433: {
                    434: 
                    435:     //
                    436:     // Pointer for the adapter root.
                    437:     //
                    438:     PSONIC_ADAPTER Adapter;
                    439: 
                    440:     //
                    441:     // Status of various NDIS calls.
                    442:     //
                    443:     NDIS_STATUS Status;
                    444: 
                    445:     //
                    446:     // Holds information needed when registering the adapter.
                    447:     //
                    448:     NDIS_ADAPTER_INFORMATION AdapterInformation;
                    449: 
                    450:     //
                    451:     // Number of ports needed
                    452:     //
                    453:     ULONG InitialPort;
                    454:     ULONG NumberOfPorts;
                    455: 
                    456:     //
                    457:     // Returned from SonicHardwareGetDetails; if it failed,
                    458:     // we log an error and exit.
                    459:     //
                    460:     SONIC_HARDWARE_STATUS HardwareDetailsStatus;
                    461: 
                    462:     //
                    463:     // Used to store error log data from SonicHardwareGetDetails.
                    464:     //
                    465:     ULONG ErrorLogData[3];
                    466: 
                    467:     //
                    468:     // We put in this assertion to make sure that ushort are 2 bytes.
                    469:     // if they aren't then the initialization block definition needs
                    470:     // to be changed.
                    471:     //
                    472:     // Also all of the logic that deals with status registers assumes
                    473:     // that control registers are only 2 bytes.
                    474:     //
                    475: 
                    476:     ASSERT(sizeof(USHORT) == 2);
                    477: 
                    478:     //
                    479:     // The Sonic uses four bytes four physical addresses, so we
                    480:     // must ensure that this is the case (SONIC_PHYSICAL_ADDRESS)
                    481:     // is defined as a ULONG).
                    482:     //
                    483: 
                    484:     ASSERT(sizeof(SONIC_PHYSICAL_ADDRESS) == 4);
                    485: 
                    486:     //
                    487:     // Allocate the Adapter block.
                    488:     //
                    489: 
                    490:     SONIC_ALLOC_MEMORY(&Status, &Adapter, sizeof(SONIC_ADAPTER));
                    491: 
                    492:     if (Status == NDIS_STATUS_SUCCESS) {
                    493: #if DBG
                    494:         SonicAdapterAddress = Adapter;
                    495: #endif
                    496: 
                    497:         SONIC_ZERO_MEMORY(
                    498:             Adapter,
                    499:             sizeof(SONIC_ADAPTER)
                    500:             );
                    501: 
                    502: 
                    503:         Adapter->AdapterType = AdapterType;
                    504:         if (SonicInterruptMode == NdisInterruptLatched) {
                    505:             Adapter->InterruptLatched = TRUE;
                    506:         }
                    507:         Adapter->PermanentAddressValid = FALSE;
                    508: 
                    509:         //
                    510:         // Set up the AdapterInformation structure; zero it out
                    511:         // first using sizeof (in case any fields are added).
                    512:         //
                    513: 
                    514:         SONIC_ZERO_MEMORY (&AdapterInformation, sizeof(NDIS_ADAPTER_INFORMATION));
                    515:         AdapterInformation.DmaChannel = 0;
                    516:         AdapterInformation.Master = TRUE;
                    517:         AdapterInformation.PhysicalMapRegistersNeeded =
                    518:             SONIC_MAX_FRAGMENTS * SONIC_NUMBER_OF_TRANSMIT_DESCRIPTORS;
                    519:         AdapterInformation.MaximumPhysicalMapping =
                    520:                              SONIC_LARGE_BUFFER_SIZE;
                    521: 
                    522:         //
                    523:         // This returns the I/O ports used by the Sonic and may
                    524:         // modify SonicInterruptVector and SonicInterruptLevel,
                    525:         // as well as modiying some fields in Adapter.
                    526:         //
                    527: 
                    528:         if ((HardwareDetailsStatus =
                    529:               SonicHardwareGetDetails(
                    530:                  Adapter,
                    531:                  SlotNumber,
                    532:                  Controller,
                    533:                  MultifunctionAdapter,
                    534:                  &InitialPort,
                    535:                  &NumberOfPorts,
                    536:                  &SonicInterruptVector,
                    537:                  &SonicInterruptLevel,
                    538:                  ErrorLogData)) != SonicHardwareOk) {
                    539: 
                    540:             //
                    541:             // If it fails, we call NdisRegisterAdapter anyway
                    542:             // (so we can log an error using the NdisAdapterHandle),
                    543:             // then return failure.
                    544:             //
                    545: 
                    546:             AdapterInformation.NumberOfPortDescriptors = 0;
                    547: 
                    548:         } else {
                    549: 
                    550:             AdapterInformation.NumberOfPortDescriptors = 1;
                    551:             AdapterInformation.PortDescriptors[0].InitialPort = InitialPort;
                    552:             AdapterInformation.PortDescriptors[0].NumberOfPorts = NumberOfPorts;
                    553:             AdapterInformation.PortDescriptors[0].PortOffset = (PVOID *)(&(Adapter->SonicPortAddress));
                    554: 
                    555:         }
                    556: 
                    557:         if (AdapterType == SONIC_ADAPTER_TYPE_EISA) {
                    558:             AdapterInformation.AdapterType = NdisInterfaceEisa;
                    559:         } else {
                    560:             AdapterInformation.AdapterType = NdisInterfaceInternal;
                    561:         }
                    562: 
                    563:         //
                    564:         // Register the adapter with NDIS.
                    565:         //
                    566: 
                    567:         if ((Status = NdisRegisterAdapter(
                    568:                 &Adapter->NdisAdapterHandle,
                    569:                 NdisMacHandle,
                    570:                 Adapter,
                    571:                 ConfigurationHandle,
                    572:                 DeviceName,
                    573:                 &AdapterInformation
                    574:                 )) == NDIS_STATUS_SUCCESS) {
                    575: 
                    576:             if (HardwareDetailsStatus != SonicHardwareOk) {
                    577: 
                    578:                 //
                    579:                 // Log an error and exit.
                    580:                 //
                    581: 
                    582:                 if (HardwareDetailsStatus == SonicHardwareChecksum) {
                    583: 
                    584:                     NdisWriteErrorLogEntry(
                    585:                         Adapter->NdisAdapterHandle,
                    586:                         NDIS_ERROR_CODE_NETWORK_ADDRESS,
                    587:                         6,
                    588:                         hardwareDetails,
                    589:                         SONIC_ERRMSG_HARDWARE_ADDRESS,
                    590:                         NDIS_STATUS_FAILURE,
                    591:                         ErrorLogData[0],
                    592:                         ErrorLogData[1],
                    593:                         ErrorLogData[2]
                    594:                         );
                    595: 
                    596:                 } else {
                    597: 
                    598:                     NdisWriteErrorLogEntry(
                    599:                         Adapter->NdisAdapterHandle,
                    600:                         NDIS_ERROR_CODE_MISSING_CONFIGURATION_PARAMETER,
                    601:                         0
                    602:                         );
                    603: 
                    604:                 }
                    605: 
                    606:                 NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    607:                 SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    608:                 return NDIS_STATUS_FAILURE;
                    609: 
                    610:             }
                    611: 
                    612: 
                    613:             //
                    614:             // Allocate memory for all of the adapter structures.
                    615:             //
                    616: 
                    617:             Adapter->NumberOfTransmitDescriptors =
                    618:                                 SONIC_NUMBER_OF_TRANSMIT_DESCRIPTORS;
                    619:             Adapter->NumberOfReceiveBuffers =
                    620:                                 SONIC_NUMBER_OF_RECEIVE_BUFFERS;
                    621:             Adapter->NumberOfReceiveDescriptors =
                    622:                                 SONIC_NUMBER_OF_RECEIVE_DESCRIPTORS;
                    623: 
                    624: 
                    625:             if (AllocateAdapterMemory(Adapter)) {
                    626: 
                    627:                 //
                    628:                 // Get the network address. This writes
                    629:                 // an error log entry if it fails. This routine
                    630:                 // may do nothing on some systems, if
                    631:                 // SonicHardwareGetDetails has already determined
                    632:                 // the network address.
                    633:                 //
                    634: 
                    635:                 if (!SonicHardwareGetAddress(Adapter, ErrorLogData)) {
                    636: 
                    637:                     NdisWriteErrorLogEntry(
                    638:                         Adapter->NdisAdapterHandle,
                    639:                         NDIS_ERROR_CODE_NETWORK_ADDRESS,
                    640:                         6,
                    641:                         hardwareDetails,
                    642:                         SONIC_ERRMSG_HARDWARE_ADDRESS,
                    643:                         NDIS_STATUS_FAILURE,
                    644:                         ErrorLogData[0],
                    645:                         ErrorLogData[1],
                    646:                         ErrorLogData[2]
                    647:                         );
                    648: 
                    649:                     DeleteAdapterMemory(Adapter);
                    650:                     NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    651:                     SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    652:                     return NDIS_STATUS_FAILURE;
                    653: 
                    654:                 }
                    655: 
                    656:                 //
                    657:                 // Initialize the current hardware address.
                    658:                 //
                    659: 
                    660:                 SONIC_MOVE_MEMORY(
                    661:                     Adapter->CurrentNetworkAddress,
                    662:                     (NetworkAddress != NULL) ?
                    663:                         NetworkAddress :
                    664:                         Adapter->PermanentNetworkAddress,
                    665:                     ETH_LENGTH_OF_ADDRESS);
                    666: 
                    667: 
                    668:                 InitializeListHead(&Adapter->OpenBindings);
                    669:                 Adapter->OpenCount = 0;
                    670:                 Adapter->Removed = FALSE;
                    671:                 InitializeListHead(&Adapter->CloseList);
                    672:                 NdisAllocateSpinLock(&Adapter->Lock);
                    673: 
                    674: 
                    675:                 Adapter->LastTransmitDescriptor =
                    676:                             Adapter->TransmitDescriptorArea +
                    677:                             (Adapter->NumberOfTransmitDescriptors-1);
                    678:                 Adapter->NumberOfAvailableDescriptors =
                    679:                             Adapter->NumberOfTransmitDescriptors;
                    680:                 Adapter->AllocateableDescriptor =
                    681:                             Adapter->TransmitDescriptorArea;
                    682:                 Adapter->TransmittingDescriptor =
                    683:                             Adapter->TransmitDescriptorArea;
                    684:                 Adapter->FirstUncommittedDescriptor =
                    685:                             Adapter->TransmitDescriptorArea;
                    686:                 Adapter->PacketsSinceLastInterrupt = 0;
                    687: 
                    688:                 Adapter->CurrentReceiveBufferIndex = 0;
                    689:                 Adapter->CurrentReceiveDescriptorIndex = 0;
                    690:                 Adapter->LastReceiveDescriptor =
                    691:                             &Adapter->ReceiveDescriptorArea[
                    692:                                 Adapter->NumberOfReceiveDescriptors-1];
                    693: 
                    694:                 Adapter->InterruptMaskRegister = SONIC_INT_DEFAULT_VALUE;
                    695:                 Adapter->ReceiveDescriptorsExhausted = FALSE;
                    696:                 Adapter->ReceiveBuffersExhausted = FALSE;
                    697:                 Adapter->ReceiveControlRegister = SONIC_RCR_DEFAULT_VALUE;
                    698: 
                    699:                 Adapter->ProcessingReceiveInterrupt = FALSE;
                    700:                 Adapter->ProcessingGeneralInterrupt = FALSE;
                    701:                 Adapter->ProcessingDeferredOperations = FALSE;
                    702:                 Adapter->FirstLoopBack = NULL;
                    703:                 Adapter->LastLoopBack = NULL;
                    704:                 Adapter->FirstFinishTransmit = NULL;
                    705:                 Adapter->LastFinishTransmit = NULL;
                    706:                 Adapter->SendStageOpen = TRUE;
                    707:                 Adapter->AlreadyProcessingSendStage = FALSE;
                    708:                 Adapter->FirstSendStagePacket = NULL;
                    709:                 Adapter->LastSendStagePacket = NULL;
                    710: 
                    711:                 Adapter->References = 1;
                    712: 
                    713:                 Adapter->ResetInProgress = FALSE;
                    714:                 Adapter->IndicatingResetStart = FALSE;
                    715:                 Adapter->IndicatingResetEnd = FALSE;
                    716:                 Adapter->ResettingOpen = NULL;
                    717:                 Adapter->FirstInitialization = TRUE;
                    718: 
                    719:                 SONIC_ZERO_MEMORY (&Adapter->GeneralMandatory, GM_ARRAY_SIZE * sizeof(ULONG));
                    720:                 SONIC_ZERO_MEMORY (&Adapter->GeneralOptionalByteCount, GO_COUNT_ARRAY_SIZE * sizeof(SONIC_LARGE_INTEGER));
                    721:                 SONIC_ZERO_MEMORY (&Adapter->GeneralOptionalFrameCount, GO_COUNT_ARRAY_SIZE * sizeof(ULONG));
                    722:                 SONIC_ZERO_MEMORY (&Adapter->GeneralOptional, (GO_ARRAY_SIZE - GO_ARRAY_START) * sizeof(ULONG));
                    723:                 SONIC_ZERO_MEMORY (&Adapter->MediaMandatory, MM_ARRAY_SIZE * sizeof(ULONG));
                    724:                 SONIC_ZERO_MEMORY (&Adapter->MediaOptional, MO_ARRAY_SIZE * sizeof(ULONG));
                    725: 
                    726:                 //
                    727:                 // Initialize the CAM and associated things.
                    728:                 // At the beginning nothing is enabled since
                    729:                 // our filter is 0, although we do store
                    730:                 // our network address in the first slot.
                    731:                 //
                    732: 
                    733:                 Adapter->MulticastCamEnableBits = 0x0000;
                    734:                 Adapter->CurrentPacketFilter = 0;
                    735:                 Adapter->CamDescriptorArea->CamEnable = 0x0000;
                    736:                 Adapter->CamDescriptorsUsed = 0x0001;
                    737:                 Adapter->CamDescriptorAreaSize = 1;
                    738: 
                    739:                 NdisInitializeTimer(
                    740:                     &Adapter->DeferredTimer,
                    741:                     SonicTimerProcess,
                    742:                     (PVOID)Adapter);
                    743: 
                    744:                 SONIC_LOAD_CAM_FRAGMENT(
                    745:                     &Adapter->CamDescriptorArea->CamFragments[0],
                    746:                     0,
                    747:                     Adapter->CurrentNetworkAddress
                    748:                     );
                    749: 
                    750: 
                    751:                 if (!EthCreateFilter(
                    752:                          SONIC_CAM_ENTRIES-1,    // maximum MC addresses
                    753:                          SonicChangeAddresses,
                    754:                          SonicChangeClass,
                    755:                          SonicCloseAction,
                    756:                          Adapter->CurrentNetworkAddress,
                    757:                          &Adapter->Lock,
                    758:                          &Adapter->FilterDB
                    759:                          )) {
                    760: 
                    761:                     NdisWriteErrorLogEntry(
                    762:                         Adapter->NdisAdapterHandle,
                    763:                         NDIS_ERROR_CODE_OUT_OF_RESOURCES,
                    764:                         2,
                    765:                         registerAdapter,
                    766:                         SONIC_ERRMSG_CREATE_FILTER
                    767:                         );
                    768: 
                    769:                     DeleteAdapterMemory(Adapter);
                    770:                     NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    771:                     NdisFreeSpinLock(&Adapter->Lock);
                    772:                     SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    773:                     return NDIS_STATUS_RESOURCES;
                    774: 
                    775:                 } else {
                    776: 
                    777:                     //
                    778:                     // Initialize the interrupt.
                    779:                     //
                    780: 
                    781:                     NdisInitializeInterrupt(
                    782:                         &Status,
                    783:                         &Adapter->Interrupt,
                    784:                         Adapter->NdisAdapterHandle,
                    785:                         SonicInterruptService,
                    786:                         Adapter,
                    787:                         SonicDeferredProcessing,
                    788:                         SonicInterruptVector,
                    789:                         SonicInterruptLevel,
                    790:                         TRUE,
                    791:                         SonicInterruptMode
                    792:                         );
                    793: 
                    794: 
                    795:                     if (Status != NDIS_STATUS_SUCCESS) {
                    796: 
                    797:                         NdisWriteErrorLogEntry(
                    798:                             Adapter->NdisAdapterHandle,
                    799:                             NDIS_ERROR_CODE_INTERRUPT_CONNECT,
                    800:                             2,
                    801:                             registerAdapter,
                    802:                             SONIC_ERRMSG_INIT_INTERRUPT
                    803:                             );
                    804: 
                    805:                         EthDeleteFilter(Adapter->FilterDB);
                    806:                         DeleteAdapterMemory(Adapter);
                    807:                         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    808:                         NdisFreeSpinLock(&Adapter->Lock);
                    809:                         SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    810:                         return Status;
                    811: 
                    812:                     }
                    813: 
                    814:                     //
                    815:                     // Start the card up. This writes an error
                    816:                     // log entry if it fails.
                    817:                     //
                    818: 
                    819:                     if (!SonicInitialInit(Adapter)) {
                    820: 
                    821:                         NdisRemoveInterrupt(&Adapter->Interrupt);
                    822:                         EthDeleteFilter(Adapter->FilterDB);
                    823:                         DeleteAdapterMemory(Adapter);
                    824:                         NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    825:                         NdisFreeSpinLock(&Adapter->Lock);
                    826:                         SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    827:                         return NDIS_STATUS_FAILURE;
                    828: 
                    829:                     } else {
                    830: 
                    831:                         //
                    832:                         // Initialize the wake up timer to catch interrupts that
                    833:                         // don't complete. It fires continuously
                    834:                         // every 5 seconds, and we check if there are any
                    835:                         // uncompleted operations from the previous 5 second
                    836:                         // period.
                    837:                         //
                    838: 
                    839:                         Adapter->WakeUpDpc = (PVOID)SonicWakeUpDpc;
                    840: 
                    841:                         NdisInitializeTimer(&Adapter->WakeUpTimer,
                    842:                                             (PVOID)(Adapter->WakeUpDpc),
                    843:                                             Adapter );
                    844: 
                    845:                         NdisSetTimer(
                    846:                             &Adapter->WakeUpTimer,
                    847:                             5000
                    848:                             );
                    849: 
                    850:                         NdisRegisterAdapterShutdownHandler(
                    851:                             Adapter->NdisAdapterHandle,
                    852:                             (PVOID)Adapter,
                    853:                             SonicShutdown
                    854:                             );
                    855: 
                    856:                         return NDIS_STATUS_SUCCESS;
                    857: 
                    858:                     }
                    859: 
                    860:                 }
                    861: 
                    862: 
                    863:             } else {
                    864: 
                    865:                 //
                    866:                 // Call to AllocateAdapterMemory failed.
                    867:                 //
                    868: 
                    869:                 NdisWriteErrorLogEntry(
                    870:                     Adapter->NdisAdapterHandle,
                    871:                     NDIS_ERROR_CODE_OUT_OF_RESOURCES,
                    872:                     2,
                    873:                     registerAdapter,
                    874:                     SONIC_ERRMSG_ALLOC_MEMORY
                    875:                     );
                    876: 
                    877:                 DeleteAdapterMemory(Adapter);
                    878:                 NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                    879:                 SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    880:                 return NDIS_STATUS_RESOURCES;
                    881: 
                    882:             }
                    883: 
                    884:         } else {
                    885: 
                    886:             //
                    887:             // Call to NdisRegisterAdapter failed.
                    888:             //
                    889: 
                    890:             SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                    891:             return Status;
                    892: 
                    893:         }
                    894: 
                    895:     } else {
                    896: 
                    897:         //
                    898:         // Couldn't allocate adapter object.
                    899:         //
                    900: 
                    901:         return Status;
                    902: 
                    903:     }
                    904: 
                    905: }
                    906: 
                    907: extern
                    908: BOOLEAN
                    909: SonicInitialInit(
                    910:     IN PSONIC_ADAPTER Adapter
                    911:     )
                    912: 
                    913: /*++
                    914: 
                    915: Routine Description:
                    916: 
                    917:     This routine sets up the initial init of the driver.
                    918: 
                    919: Arguments:
                    920: 
                    921:     Adapter - The adapter for the hardware.
                    922: 
                    923: Return Value:
                    924: 
                    925:     None.
                    926: 
                    927: --*/
                    928: 
                    929: {
                    930: 
                    931:     UINT Time = 50;
                    932: 
                    933:     //
                    934:     // First we make sure that the device is stopped.
                    935:     //
                    936: 
                    937:     SonicStopChip(Adapter);
                    938: 
                    939:     //
                    940:     // Set up the registers.
                    941:     //
                    942: 
                    943:     if (!SetupRegistersAndInit(Adapter)) {
                    944: 
                    945:         NdisWriteErrorLogEntry(
                    946:             Adapter->NdisAdapterHandle,
                    947:             NDIS_ERROR_CODE_ADAPTER_NOT_FOUND,
                    948:             3,
                    949:             registerAdapter,
                    950:             SONIC_ERRMSG_INITIAL_INIT
                    951:             );
                    952: 
                    953:         return FALSE;
                    954: 
                    955:     }
                    956: 
                    957: 
                    958:     //
                    959:     // Delay execution for 1/2 second to give the sonic
                    960:     // time to initialize.
                    961:     //
                    962: 
                    963:     while (Time > 0) {
                    964: 
                    965:         if (!Adapter->FirstInitialization) {
                    966:             break;
                    967:         }
                    968: 
                    969:         NdisStallExecution(10000);
                    970:         Time--;
                    971: 
                    972:     }
                    973: 
                    974: 
                    975:     //
                    976:     // The only way that first initialization could have
                    977:     // been turned off is if we actually initialized.
                    978:     //
                    979: 
                    980:     if (!Adapter->FirstInitialization) {
                    981: 
                    982:         //
                    983:         // We actually did get the initialization.
                    984:         //
                    985:         // We can start the chip.  We may not
                    986:         // have any bindings to indicate to but this
                    987:         // is unimportant.
                    988:         //
                    989: 
                    990:         SonicStartChip(Adapter);
                    991: 
                    992:         return TRUE;
                    993: 
                    994: 
                    995:     } else {
                    996: 
                    997:         NdisWriteErrorLogEntry(
                    998:             Adapter->NdisAdapterHandle,
                    999:             NDIS_ERROR_CODE_TIMEOUT,
                   1000:             2,
                   1001:             registerAdapter,
                   1002:             SONIC_ERRMSG_INITIAL_INIT
                   1003:             );
                   1004: 
                   1005:         return FALSE;
                   1006: 
                   1007:     }
                   1008: 
                   1009: }
                   1010: 
                   1011: STATIC
                   1012: BOOLEAN
                   1013: SonicSynchClearIsr(
                   1014:     IN PVOID Context
                   1015:     )
                   1016: 
                   1017: /*++
                   1018: 
                   1019: Routine Description:
                   1020: 
                   1021:     This routine is used during a reset. It ensures that no
                   1022:     interrupts will come through, and that any DPRs that run
                   1023:     will find no interrupts to process.
                   1024: 
                   1025: Arguments:
                   1026: 
                   1027:     Context - A pointer to a SONIC_ADAPTER structure.
                   1028: 
                   1029: Return Value:
                   1030: 
                   1031:     Always returns true.
                   1032: 
                   1033: --*/
                   1034: 
                   1035: {
                   1036: 
                   1037:     PSONIC_ADAPTER Adapter = (PSONIC_ADAPTER)Context;
                   1038: 
                   1039:     SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_STATUS, 0xffff);
                   1040:     Adapter->IsrValue = 0;
                   1041: 
                   1042:     return TRUE;
                   1043: 
                   1044: }
                   1045: 
                   1046: extern
                   1047: VOID
                   1048: SonicStartChip(
                   1049:     IN PSONIC_ADAPTER Adapter
                   1050:     )
                   1051: 
                   1052: /*++
                   1053: 
                   1054: Routine Description:
                   1055: 
                   1056:     This routine is used to start an already initialized sonic.
                   1057: 
                   1058: Arguments:
                   1059: 
                   1060:     Adapter - The adapter for the SONIC to start.
                   1061: 
                   1062: Return Value:
                   1063: 
                   1064:     None.
                   1065: 
                   1066: --*/
                   1067: 
                   1068: {
                   1069: 
                   1070:     //
                   1071:     // Take us out of reset mode if we are in it.
                   1072:     //
                   1073: 
                   1074:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   1075:         0x0000
                   1076:         );
                   1077: 
                   1078:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   1079:         SONIC_CR_RECEIVER_ENABLE
                   1080:         );
                   1081: 
                   1082: }
                   1083: 
                   1084: STATIC
                   1085: VOID
                   1086: SonicStopChip(
                   1087:     IN PSONIC_ADAPTER Adapter
                   1088:     )
                   1089: 
                   1090: /*++
                   1091: 
                   1092: Routine Description:
                   1093: 
                   1094:     This routine is used to stop a sonic.
                   1095: 
                   1096:     This routine is *not* portable.  It is specific to the 386
                   1097:     implementation of the sonic.  On the bus master card the ACON bit
                   1098:     must be set in csr3, whereas on the decstation, csr3 remains clear.
                   1099: 
                   1100: Arguments:
                   1101: 
                   1102:     Adapter - The adapter for the SONIC to stop.
                   1103: 
                   1104: Return Value:
                   1105: 
                   1106:     None.
                   1107: 
                   1108: --*/
                   1109: 
                   1110: {
                   1111: 
                   1112:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   1113:         SONIC_CR_RECEIVER_DISABLE |
                   1114:         SONIC_CR_SOFTWARE_RESET
                   1115:         );
                   1116: 
                   1117: }
                   1118: 
                   1119: extern
                   1120: VOID
                   1121: SonicStartCamReload(
                   1122:     IN PSONIC_ADAPTER Adapter
                   1123:     )
                   1124: 
                   1125: /*++
                   1126: 
                   1127: Routine Description:
                   1128: 
                   1129:     This routine starts a CAM reload, which will cause an
                   1130:     interrupt when it is done.
                   1131: 
                   1132: Arguments:
                   1133: 
                   1134:     Adapter - The adapter for the SONIC to reload.
                   1135: 
                   1136: Return Value:
                   1137: 
                   1138:     None.
                   1139: 
                   1140: --*/
                   1141: 
                   1142: {
                   1143: 
                   1144:     //
                   1145:     // Move CAM Enable into the appropriate spot.
                   1146:     //
                   1147: 
                   1148:     SONIC_LOAD_CAM_ENABLE(
                   1149:         &Adapter->CamDescriptorArea->CamFragments[
                   1150:                                         Adapter->CamDescriptorAreaSize],
                   1151:         Adapter->CamDescriptorArea->CamEnable
                   1152:         );
                   1153: 
                   1154: 
                   1155:     //
                   1156:     // Flush the CAM before we start the reload.
                   1157:     //
                   1158: 
                   1159:     SONIC_FLUSH_WRITE_BUFFER(Adapter->CamDescriptorAreaFlushBuffer);
                   1160: 
                   1161: 
                   1162:     SONIC_WRITE_PORT(Adapter, SONIC_CAM_DESCRIPTOR,
                   1163:         SONIC_GET_LOW_PART_ADDRESS(Adapter->CamDescriptorAreaPhysical)
                   1164:         );
                   1165: 
                   1166:     SONIC_WRITE_PORT(Adapter, SONIC_CAM_DESCRIPTOR_COUNT,
                   1167:         (USHORT)Adapter->CamDescriptorAreaSize
                   1168:         );
                   1169: 
                   1170: 
                   1171:     //
                   1172:     // Start the Load CAM, which will cause an interrupt
                   1173:     // when it is done.
                   1174:     //
                   1175: 
                   1176:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   1177:         SONIC_CR_LOAD_CAM
                   1178:         );
                   1179: 
                   1180: }
                   1181: 
                   1182: STATIC
                   1183: NDIS_STATUS
                   1184: SonicOpenAdapter(
                   1185:     OUT PNDIS_STATUS OpenErrorStatus,
                   1186:     OUT NDIS_HANDLE *MacBindingHandle,
                   1187:     OUT PUINT SelectedMediumIndex,
                   1188:     IN PNDIS_MEDIUM MediumArray,
                   1189:     IN UINT MediumArraySize,
                   1190:     IN NDIS_HANDLE NdisBindingContext,
                   1191:     IN NDIS_HANDLE MacAdapterContext,
                   1192:     IN UINT OpenOptions,
                   1193:     IN PSTRING AddressingInformation OPTIONAL
                   1194:     )
                   1195: 
                   1196: /*++
                   1197: 
                   1198: Routine Description:
                   1199: 
                   1200:     This routine is used to create an open instance of an adapter, in effect
                   1201:     creating a binding between an upper-level module and the MAC module over
                   1202:     the adapter.
                   1203: 
                   1204: Arguments:
                   1205: 
                   1206:     OpenErrorStatus - Returns more information in some cases.
                   1207: 
                   1208:     MacBindingHandle - A pointer to a location in which the MAC stores
                   1209:     a context value that it uses to represent this binding.
                   1210: 
                   1211:     SelectedMediumIndex - A pointer to a location in which the MAC stores
                   1212:     the medium selected out of MediumArray.
                   1213: 
                   1214:     MediumArray - An array of media that the protocol can support.
                   1215: 
                   1216:     MediumArraySize - The number of elements in MediumArray.
                   1217: 
                   1218:     NdisBindingContext - A value to be recorded by the MAC and passed as
                   1219:     context whenever an indication is delivered by the MAC for this binding.
                   1220: 
                   1221:     MacAdapterContext - The value associated with the adapter that is being
                   1222:     opened when the MAC registered the adapter with NdisRegisterAdapter.
                   1223: 
                   1224:     OpenOptions - A bit mask containing flags with information about this
                   1225:     binding.
                   1226: 
                   1227:     AddressingInformation - An optional pointer to a variable length string
                   1228:     containing hardware-specific information that can be used to program the
                   1229:     device.  (This is not used by this MAC.)
                   1230: 
                   1231: Return Value:
                   1232: 
                   1233:     The function value is the status of the operation.  If the MAC does not
                   1234:     complete this request synchronously, the value would be
                   1235:     NDIS_STATUS_PENDING.
                   1236: 
                   1237: 
                   1238: --*/
                   1239: 
                   1240: {
                   1241: 
                   1242:     //
                   1243:     // The SONIC_ADAPTER that this open binding should belong too.
                   1244:     //
                   1245:     PSONIC_ADAPTER Adapter;
                   1246: 
                   1247:     //
                   1248:     // Holds the status that should be returned to the caller.
                   1249:     //
                   1250:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
                   1251: 
                   1252:     //
                   1253:     // Simple iteration variable, for scanning the medium array.
                   1254:     //
                   1255:     UINT i;
                   1256: 
                   1257:     //
                   1258:     // Pointer to the space allocated for the binding.
                   1259:     //
                   1260:     PSONIC_OPEN NewOpen;
                   1261: 
                   1262:     //
                   1263:     // Points to the MacReserved section of NewOpen->OpenCloseRequest.
                   1264:     //
                   1265:     PSONIC_REQUEST_RESERVED Reserved;
                   1266: 
                   1267: 
                   1268:     //
                   1269:     // If we are being removed, don't allow new opens.
                   1270:     //
                   1271: 
                   1272:     Adapter = PSONIC_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
                   1273: 
                   1274:     if (Adapter->Removed) {
                   1275:         return NDIS_STATUS_FAILURE;
                   1276:     }
                   1277: 
                   1278: 
                   1279:     //
                   1280:     // Search for the 802.3 media type
                   1281:     //
                   1282: 
                   1283:     for (i=0; i<MediumArraySize; i++) {
                   1284: 
                   1285:         if (MediumArray[i] == NdisMedium802_3) {
                   1286:             break;
                   1287:         }
                   1288: 
                   1289:     }
                   1290: 
                   1291:     if (i == MediumArraySize) {
                   1292: 
                   1293:         return NDIS_STATUS_UNSUPPORTED_MEDIA;
                   1294: 
                   1295:     }
                   1296: 
                   1297:     *SelectedMediumIndex = i;
                   1298: 
                   1299: 
                   1300:     NdisAcquireSpinLock(&Adapter->Lock);
                   1301:     Adapter->References++;
                   1302: 
                   1303:     NdisReleaseSpinLock(&Adapter->Lock);
                   1304: 
                   1305:     //
                   1306:     // Allocate the space for the open binding.  Fill in the fields.
                   1307:     //
                   1308: 
                   1309:     SONIC_ALLOC_MEMORY(&StatusToReturn, &NewOpen, sizeof(SONIC_OPEN));
                   1310: 
                   1311:     if (StatusToReturn == NDIS_STATUS_SUCCESS) {
                   1312: 
                   1313:         *MacBindingHandle = BINDING_HANDLE_FROM_PSONIC_OPEN(NewOpen);
                   1314:         InitializeListHead(&NewOpen->OpenList);
                   1315:         NewOpen->NdisBindingContext = NdisBindingContext;
                   1316:         NewOpen->References = 1;
                   1317:         NewOpen->BindingShuttingDown = FALSE;
                   1318:         NewOpen->OwningSonic = Adapter;
                   1319: 
                   1320:         NewOpen->OpenCloseRequest.RequestType = NdisRequestOpen;
                   1321:         Reserved = PSONIC_RESERVED_FROM_REQUEST(&NewOpen->OpenCloseRequest);
                   1322:         Reserved->OpenBlock = NewOpen;
                   1323:         Reserved->Next = (PNDIS_REQUEST)NULL;
                   1324: 
                   1325:         NdisAcquireSpinLock(&Adapter->Lock);
                   1326: 
                   1327:         SonicQueueRequest(Adapter, &NewOpen->OpenCloseRequest);
                   1328: 
                   1329:         StatusToReturn = NDIS_STATUS_PENDING;
                   1330: 
                   1331:     } else {
                   1332: 
                   1333:         NdisWriteErrorLogEntry(
                   1334:             Adapter->NdisAdapterHandle,
                   1335:             NDIS_ERROR_CODE_OUT_OF_RESOURCES,
                   1336:             2,
                   1337:             openAdapter,
                   1338:             SONIC_ERRMSG_ALLOC_OPEN
                   1339:             );
                   1340: 
                   1341: 
                   1342:         NdisAcquireSpinLock(&Adapter->Lock);
                   1343: 
                   1344:     }
                   1345: 
                   1346: 
                   1347:     //
                   1348:     // This macro assumes it is called with the lock held,
                   1349:     // and releases it.
                   1350:     //
                   1351: 
                   1352:     SONIC_DO_DEFERRED(Adapter);
                   1353:     return StatusToReturn;
                   1354: }
                   1355: 
                   1356: STATIC
                   1357: NDIS_STATUS
                   1358: SonicCloseAdapter(
                   1359:     IN NDIS_HANDLE MacBindingHandle
                   1360:     )
                   1361: 
                   1362: /*++
                   1363: 
                   1364: Routine Description:
                   1365: 
                   1366:     This routine causes the MAC to close an open handle (binding).
                   1367: 
                   1368: Arguments:
                   1369: 
                   1370:     MacBindingHandle - The context value returned by the MAC when the
                   1371:     adapter was opened.  In reality it is a PSONIC_OPEN.
                   1372: 
                   1373: Return Value:
                   1374: 
                   1375:     The function value is the status of the operation.
                   1376: 
                   1377: 
                   1378: --*/
                   1379: 
                   1380: {
                   1381: 
                   1382:     //
                   1383:     // The SONIC_ADAPTER that this open binding should belong too.
                   1384:     //
                   1385:     PSONIC_ADAPTER Adapter;
                   1386: 
                   1387:     //
                   1388:     // Holds the status that should be returned to the caller.
                   1389:     //
                   1390:     NDIS_STATUS StatusToReturn = NDIS_STATUS_SUCCESS;
                   1391: 
                   1392:     //
                   1393:     // Pointer to the space allocated for the binding.
                   1394:     //
                   1395:     PSONIC_OPEN Open;
                   1396: 
                   1397: 
                   1398:     Adapter = PSONIC_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
                   1399: 
                   1400:     //
                   1401:     // Hold the lock while we update the reference counts for the
                   1402:     // adapter and the open.
                   1403:     //
                   1404: 
                   1405:     NdisAcquireSpinLock(&Adapter->Lock);
                   1406:     Adapter->References++;
                   1407: 
                   1408:     Open = PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
                   1409: 
                   1410:     //
                   1411:     // Don't do anything if this binding is already closing.
                   1412:     //
                   1413: 
                   1414:     if (!Open->BindingShuttingDown) {
                   1415: 
                   1416:         PSONIC_REQUEST_RESERVED Reserved = PSONIC_RESERVED_FROM_REQUEST(&Open->OpenCloseRequest);
                   1417: 
                   1418:         Open->OpenCloseRequest.RequestType = NdisRequestClose;
                   1419:         Reserved->OpenBlock = Open;
                   1420:         Reserved->Next = (PNDIS_REQUEST)NULL;
                   1421: 
                   1422:         ++Open->References;
                   1423: 
                   1424:         SonicQueueRequest(Adapter, &Open->OpenCloseRequest);
                   1425: 
                   1426:         //
                   1427:         // Remove the creation reference.
                   1428:         //
                   1429: 
                   1430:         --Open->References;
                   1431: 
                   1432:         StatusToReturn = NDIS_STATUS_PENDING;
                   1433: 
                   1434:     } else {
                   1435: 
                   1436:         StatusToReturn = NDIS_STATUS_CLOSING;
                   1437: 
                   1438:     }
                   1439: 
                   1440:     //
                   1441:     // This macro assumes it is called with the lock held,
                   1442:     // and releases it.
                   1443:     //
                   1444: 
                   1445:     SONIC_DO_DEFERRED(Adapter);
                   1446:     return StatusToReturn;
                   1447: 
                   1448: }
                   1449: 
                   1450: STATIC
                   1451: VOID
                   1452: SonicUnload(
                   1453:     IN NDIS_HANDLE MacMacContext
                   1454:     )
                   1455: 
                   1456: /*++
                   1457: 
                   1458: Routine Description:
                   1459: 
                   1460:     SonicUnload is called when the MAC is to unload itself.
                   1461: 
                   1462: Arguments:
                   1463: 
                   1464:     None.
                   1465: 
                   1466: Return Value:
                   1467: 
                   1468:     None.
                   1469: 
                   1470: --*/
                   1471: 
                   1472: {
                   1473: 
                   1474:     NDIS_STATUS Status;
                   1475: 
                   1476:     PSONIC_MAC SonicMac = (PSONIC_MAC)MacMacContext;
                   1477: 
                   1478: 
                   1479:     NdisDeregisterMac(
                   1480:         &Status,
                   1481:         SonicMac->MacHandle
                   1482:         );
                   1483: 
                   1484:     NdisTerminateWrapper(
                   1485:         SonicMac->WrapperHandle,
                   1486:         NULL
                   1487:         );
                   1488: 
                   1489:     return;
                   1490: 
                   1491: }
                   1492: 
                   1493: 
                   1494: STATIC
                   1495: NDIS_STATUS
                   1496: SonicAddAdapter(
                   1497:     IN NDIS_HANDLE MacMacContext,
                   1498:     IN NDIS_HANDLE ConfigurationHandle,
                   1499:     IN PNDIS_STRING AdapterName
                   1500:     )
                   1501: 
                   1502: /*++
                   1503: 
                   1504: Routine Description:
                   1505: 
                   1506:     SonicAddAdapter adds an adapter to the list supported
                   1507:     by this MAC.
                   1508: 
                   1509: Arguments:
                   1510: 
                   1511:     MacMacContext - The context passed to NdisRegisterMac (will be NULL).
                   1512: 
                   1513:     ConfigurationHandle - A handle to pass to NdisOpenConfiguration.
                   1514: 
                   1515:     AdapterName - The name to register with via NdisRegisterAdapter.
                   1516: 
                   1517: Return Value:
                   1518: 
                   1519:     NDIS_STATUS_SUCCESS
                   1520:     NDIS_STATUS_PENDING
                   1521: 
                   1522: --*/
                   1523: 
                   1524: {
                   1525: 
                   1526:     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
                   1527:     PSONIC_MAC SonicMac = (PSONIC_MAC)MacMacContext;
                   1528:     NDIS_HANDLE ConfigHandle;
                   1529:     NDIS_STRING AdapterTypeString = NDIS_STRING_CONST("AdapterType");
                   1530: #ifdef SONIC_INTERNAL
                   1531:     NDIS_STRING MultifunctionAdapterString = NDIS_STRING_CONST("MultifunctionAdapter");
                   1532:     NDIS_STRING NetworkControllerString = NDIS_STRING_CONST("NetworkController");
                   1533: #endif
                   1534:     PNDIS_CONFIGURATION_PARAMETER ReturnedValue;
                   1535:     PUCHAR NetworkAddress;
                   1536:     UINT NetworkAddressLength;
                   1537:     UCHAR AdapterType;
                   1538:     UINT InterruptVector;
                   1539:     UINT InterruptLevel;
                   1540:     NDIS_INTERRUPT_MODE InterruptMode;
                   1541:     UINT SlotNumber;
                   1542:     UINT Controller = 0;
                   1543:     UINT MultifunctionAdapter = 0;
                   1544: 
                   1545:     //
                   1546:     // Open the configuration info.
                   1547:     //
                   1548: 
                   1549:     NdisOpenConfiguration(
                   1550:                     &Status,
                   1551:                     &ConfigHandle,
                   1552:                     ConfigurationHandle
                   1553:                     );
                   1554: 
                   1555:     if (Status != NDIS_STATUS_SUCCESS) {
                   1556:         return Status;
                   1557:     }
                   1558: 
                   1559: 
                   1560:     //
                   1561:     // Check that adapter type is supported.
                   1562:     // The default depends on the processor type.
                   1563:     //
                   1564: 
                   1565:     AdapterType = SONIC_ADAPTER_TYPE_DEFAULT;
                   1566: 
                   1567:     NdisReadConfiguration(
                   1568:                     &Status,
                   1569:                     &ReturnedValue,
                   1570:                     ConfigHandle,
                   1571:                     &AdapterTypeString,
                   1572:                     NdisParameterInteger
                   1573:                     );
                   1574: 
                   1575:     if (Status == NDIS_STATUS_SUCCESS) {
                   1576: 
                   1577:         //
                   1578:         // See if the adapter type is valid. We skip to AdapterTypeRecognized
                   1579:         // if the AdapterType is known to this driver.
                   1580:         //
                   1581: 
                   1582: #ifdef SONIC_EISA
                   1583:         if (ReturnedValue->ParameterData.IntegerData == SONIC_ADAPTER_TYPE_EISA) {
                   1584:             goto AdapterTypeRecognized;
                   1585:         }
                   1586: #endif
                   1587: 
                   1588: #ifdef SONIC_INTERNAL
                   1589:         if (ReturnedValue->ParameterData.IntegerData == SONIC_ADAPTER_TYPE_INTERNAL) {
                   1590:             goto AdapterTypeRecognized;
                   1591:         }
                   1592: #endif
                   1593: 
                   1594:         //
                   1595:         // Card type not supported by this driver
                   1596:         //
                   1597: 
                   1598: #if DBG
                   1599:         DbgPrint("SONIC: Error in adapter type: %lx\n", ReturnedValue->ParameterData.IntegerData);
                   1600: #endif
                   1601:         NdisCloseConfiguration(ConfigHandle);
                   1602:         return NDIS_STATUS_FAILURE;
                   1603: 
                   1604: 
                   1605: AdapterTypeRecognized:
                   1606: 
                   1607:         AdapterType = (UCHAR)ReturnedValue->ParameterData.IntegerData;
                   1608:     }
                   1609: 
                   1610:     switch (AdapterType) {
                   1611: 
                   1612: #ifdef SONIC_EISA
                   1613: 
                   1614:     case SONIC_ADAPTER_TYPE_EISA:
                   1615:     {
                   1616: 
                   1617:         NDIS_EISA_FUNCTION_INFORMATION EisaData;
                   1618:         USHORT Portzc88;
                   1619:         UCHAR zc88Value;
                   1620:         UCHAR Mask;
                   1621:         UCHAR InitType;
                   1622:         UCHAR PortValue;
                   1623:         USHORT PortAddress;
                   1624:         PUCHAR CurrentChar;
                   1625:         BOOLEAN LastEntry;
                   1626: 
                   1627:         NdisReadEisaSlotInformation(
                   1628:                                 &Status,
                   1629:                                 ConfigurationHandle,
                   1630:                                 &SlotNumber,
                   1631:                                 &EisaData
                   1632:                                 );
                   1633: 
                   1634:         if (Status != NDIS_STATUS_SUCCESS) {
                   1635: 
                   1636: #if DBG
                   1637:             DbgPrint("SONIC: Could not read EISA data\n");
                   1638: #endif
                   1639:             NdisCloseConfiguration(ConfigHandle);
                   1640:             return NDIS_STATUS_FAILURE;
                   1641: 
                   1642:         }
                   1643: 
                   1644:         CurrentChar = EisaData.InitializationData;
                   1645: 
                   1646:         Portzc88 = (SlotNumber << 12) + 0xc88;
                   1647: 
                   1648:         LastEntry = FALSE;
                   1649:         while (!LastEntry) {
                   1650:             InitType = *(CurrentChar++);
                   1651:             PortAddress = *((USHORT UNALIGNED *)CurrentChar);
                   1652:             CurrentChar += sizeof(USHORT);
                   1653: 
                   1654:             if ((InitType & 0x80) == 0) {
                   1655:                 LastEntry = TRUE;
                   1656:             }
                   1657: 
                   1658:             PortValue = *(CurrentChar++);
                   1659: 
                   1660:             if (InitType & 0x40) {
                   1661:                 Mask = *(CurrentChar++);
                   1662:             } else {
                   1663:                 Mask = 0;
                   1664:             }
                   1665: 
                   1666:             //
                   1667:             // The only port we care about is zc88 (z is the
                   1668:             // slot number) since it has the interrupt in it.
                   1669:             //
                   1670: 
                   1671:             if (PortAddress != Portzc88) {
                   1672:                 continue;
                   1673:             }
                   1674: 
                   1675:             zc88Value &= Mask;
                   1676:             zc88Value |= PortValue;
                   1677: 
                   1678:         }
                   1679: 
                   1680:         switch ((zc88Value & 0x06) >> 1) {
                   1681:         case 0:
                   1682:             InterruptVector = 5; break;
                   1683:         case 1:
                   1684:             InterruptVector = 9; break;
                   1685:         case 2:
                   1686:             InterruptVector = 10; break;
                   1687:         case 3:
                   1688:             InterruptVector = 11; break;
                   1689:         }
                   1690: 
                   1691:         InterruptLevel = InterruptVector;
                   1692: 
                   1693:         if ((zc88Value & 0x01) != 0) {
                   1694:             InterruptMode = NdisInterruptLatched;
                   1695:         } else {
                   1696:             InterruptMode = NdisInterruptLevelSensitive;
                   1697:         }
                   1698: 
                   1699:         break;
                   1700: 
                   1701:     }
                   1702: 
                   1703: #endif  // SONIC_EISA
                   1704: 
                   1705: #ifdef SONIC_INTERNAL
                   1706: 
                   1707:     case SONIC_ADAPTER_TYPE_INTERNAL:
                   1708:     {
                   1709: 
                   1710:         //
                   1711:         // For the internal adapter, we read the MultifunctionAdapter number
                   1712:         // and NetworkController number, which are both optional. For
                   1713:         // passing to SonicRegisterAdapter.
                   1714:         //
                   1715: 
                   1716:         NdisReadConfiguration(
                   1717:                         &Status,
                   1718:                         &ReturnedValue,
                   1719:                         ConfigHandle,
                   1720:                         &MultifunctionAdapterString,
                   1721:                         NdisParameterInteger
                   1722:                         );
                   1723: 
                   1724:         if (Status == NDIS_STATUS_SUCCESS) {
                   1725: 
                   1726:             MultifunctionAdapter =  ReturnedValue->ParameterData.IntegerData;
                   1727: 
                   1728:         }
                   1729: 
                   1730:         NdisReadConfiguration(
                   1731:                         &Status,
                   1732:                         &ReturnedValue,
                   1733:                         ConfigHandle,
                   1734:                         &NetworkControllerString,
                   1735:                         NdisParameterInteger
                   1736:                         );
                   1737: 
                   1738:         if (Status == NDIS_STATUS_SUCCESS) {
                   1739: 
                   1740:             Controller =  ReturnedValue->ParameterData.IntegerData;
                   1741: 
                   1742:         }
                   1743: 
                   1744:         //
                   1745:         // These are filled in by SonicHardwareGetDetails.
                   1746:         //
                   1747: 
                   1748:         InterruptVector = 0;
                   1749:         InterruptLevel = 0;
                   1750: 
                   1751:         //
                   1752:         // The internal adapter is level-sensitive.
                   1753:         //
                   1754: 
                   1755:         InterruptMode = NdisInterruptLevelSensitive;
                   1756: 
                   1757:         break;
                   1758: 
                   1759:     }
                   1760: 
                   1761: #endif  // SONIC_INTERNAL
                   1762: 
                   1763:     default:
                   1764: 
                   1765:         ASSERT(FALSE);
                   1766:         break;
                   1767: 
                   1768:     }
                   1769: 
                   1770: 
                   1771:     //
                   1772:     // Read network address
                   1773:     //
                   1774: 
                   1775:     NdisReadNetworkAddress(
                   1776:         &Status,
                   1777:         (PVOID *)&NetworkAddress,
                   1778:         &NetworkAddressLength,
                   1779:         ConfigHandle);
                   1780: 
                   1781: 
                   1782:     //
                   1783:     // Make sure that the address is the right length asnd
                   1784:     // at least one of the bytes is non-zero.
                   1785:     //
                   1786: 
                   1787:     if ((Status == NDIS_STATUS_SUCCESS) &&
                   1788:         (NetworkAddressLength == ETH_LENGTH_OF_ADDRESS) &&
                   1789:         ((NetworkAddress[0] |
                   1790:           NetworkAddress[1] |
                   1791:           NetworkAddress[2] |
                   1792:           NetworkAddress[3] |
                   1793:           NetworkAddress[4] |
                   1794:           NetworkAddress[5]) != 0)) {
                   1795: 
                   1796: #if DBG
                   1797:         if (SonicDbg) {
                   1798:             DbgPrint("SONIC: New Address = %.2x-%.2x-%.2x-%.2x-%.2x-%.2x\n",
                   1799:                                     NetworkAddress[0],
                   1800:                                     NetworkAddress[1],
                   1801:                                     NetworkAddress[2],
                   1802:                                     NetworkAddress[3],
                   1803:                                     NetworkAddress[4],
                   1804:                                     NetworkAddress[5]);
                   1805:         }
                   1806: #endif
                   1807: 
                   1808:     } else {
                   1809: 
                   1810:         //
                   1811:         // Tells SonicRegisterAdapter to use the
                   1812:         // burned-in address.
                   1813:         //
                   1814: 
                   1815:         NetworkAddress = NULL;
                   1816: 
                   1817:     }
                   1818: 
                   1819:     //
                   1820:     // Used passed-in adapter name to register.
                   1821:     //
                   1822: 
                   1823:     Status = SonicRegisterAdapter(
                   1824:                  SonicMac->MacHandle,
                   1825:                  ConfigurationHandle,
                   1826:                  AdapterName,
                   1827:                  NetworkAddress,
                   1828:                  AdapterType,
                   1829:                  SlotNumber,
                   1830:                  Controller,
                   1831:                  MultifunctionAdapter,
                   1832:                  InterruptVector,
                   1833:                  InterruptLevel,
                   1834:                  InterruptMode,
                   1835:                  32);
                   1836: 
                   1837: 
                   1838:     NdisCloseConfiguration(ConfigHandle);
                   1839: 
                   1840: 
                   1841:     return Status;           // should be NDIS_STATUS_SUCCESS
                   1842: 
                   1843: }
                   1844: 
                   1845: STATIC
                   1846: VOID
                   1847: SonicRemoveAdapter(
                   1848:     IN NDIS_HANDLE MacAdapterContext
                   1849:     )
                   1850: 
                   1851: /*++
                   1852: 
                   1853: Routine Description:
                   1854: 
                   1855:     SonicRemoveAdapter removes an adapter previously registered
                   1856:     with NdisRegisterAdapter.
                   1857: 
                   1858: Arguments:
                   1859: 
                   1860:     MacAdapterContext - The context value that the MAC passed
                   1861:         to NdisRegisterAdapter; actually as pointer to a
                   1862:         SONIC_ADAPTER.
                   1863: 
                   1864: Return Value:
                   1865: 
                   1866:     None.
                   1867: 
                   1868: --*/
                   1869: 
                   1870: {
                   1871:     PSONIC_ADAPTER Adapter;
                   1872:     BOOLEAN Canceled;
                   1873: 
                   1874:     Adapter = PSONIC_ADAPTER_FROM_CONTEXT_HANDLE(MacAdapterContext);
                   1875: 
                   1876:     Adapter->Removed = TRUE;
                   1877: 
                   1878:     //
                   1879:     // Stop the chip.
                   1880:     //
                   1881: 
                   1882:     SonicStopChip (Adapter);
                   1883: 
                   1884:     NdisDeregisterAdapterShutdownHandler(Adapter->NdisAdapterHandle);
                   1885: 
                   1886:     ASSERT (Adapter->OpenCount == 0);
                   1887: 
                   1888:     //
                   1889:     // There are no opens left, so remove ourselves.
                   1890:     //
                   1891: 
                   1892:     //
                   1893:     // Stop the deadman timer
                   1894:     //
                   1895: 
                   1896:     NdisCancelTimer(&Adapter->WakeUpTimer, &Canceled);
                   1897: 
                   1898:     if ( !Canceled ) {
                   1899:         NdisStallExecution(500000);
                   1900:     }
                   1901: 
                   1902:     NdisRemoveInterrupt(&Adapter->Interrupt);
                   1903: 
                   1904:     EthDeleteFilter(Adapter->FilterDB);
                   1905: 
                   1906:     DeleteAdapterMemory(Adapter);
                   1907:     NdisDeregisterAdapter(Adapter->NdisAdapterHandle);
                   1908: 
                   1909:     NdisFreeSpinLock(&Adapter->Lock);
                   1910:     SONIC_FREE_MEMORY(Adapter, sizeof(SONIC_ADAPTER));
                   1911: 
                   1912: }
                   1913: 
                   1914: STATIC
                   1915: NDIS_STATUS
                   1916: SonicReset(
                   1917:     IN NDIS_HANDLE MacBindingHandle
                   1918:     )
                   1919: 
                   1920: /*++
                   1921: 
                   1922: Routine Description:
                   1923: 
                   1924:     The SonicReset request instructs the MAC to issue a hardware reset
                   1925:     to the network adapter.  The MAC also resets its software state.  See
                   1926:     the description of NdisReset for a detailed description of this request.
                   1927: 
                   1928: Arguments:
                   1929: 
                   1930:     MacBindingHandle - The context value returned by the MAC  when the
                   1931:     adapter was opened.  In reality, it is a pointer to SONIC_OPEN.
                   1932: 
                   1933: Return Value:
                   1934: 
                   1935:     The function value is the status of the operation.
                   1936: 
                   1937: 
                   1938: --*/
                   1939: 
                   1940: {
                   1941: 
                   1942:     //
                   1943:     // Holds the status that should be returned to the caller.
                   1944:     //
                   1945:     NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
                   1946: 
                   1947:     PSONIC_ADAPTER Adapter =
                   1948:         PSONIC_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
                   1949: 
                   1950:     //
                   1951:     // Hold the locks while we update the reference counts on the
                   1952:     // adapter and the open.
                   1953:     //
                   1954: 
                   1955:     if (Adapter->Removed) {
                   1956: 
                   1957:         return(NDIS_STATUS_FAILURE);
                   1958: 
                   1959:     }
                   1960: 
                   1961:     NdisAcquireSpinLock(&Adapter->Lock);
                   1962: 
                   1963:     Adapter->References++;
                   1964: 
                   1965:     if (!Adapter->ResetInProgress && !Adapter->IndicatingResetStart) {
                   1966: 
                   1967:         PSONIC_OPEN Open;
                   1968: 
                   1969:         Open = PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
                   1970: 
                   1971:         if (!Open->BindingShuttingDown) {
                   1972: 
                   1973:             Adapter->IndicatingResetStart = TRUE;
                   1974: 
                   1975:             if (!Adapter->IndicatingResetEnd) {
                   1976: 
                   1977:                 //
                   1978:                 // Loop through, indicating RESET_START; we
                   1979:                 // don't bother with the StatusComplete
                   1980:                 // indication until RESET_END is indicated.
                   1981:                 //
                   1982: 
                   1983:                 PSONIC_OPEN Open;
                   1984:                 PLIST_ENTRY CurrentLink;
                   1985: 
                   1986:                 CurrentLink = Adapter->OpenBindings.Flink;
                   1987: 
                   1988:                 while (CurrentLink != &Adapter->OpenBindings) {
                   1989: 
                   1990:                     Open = CONTAINING_RECORD(
                   1991:                              CurrentLink,
                   1992:                              SONIC_OPEN,
                   1993:                              OpenList
                   1994:                              );
                   1995: 
                   1996:                     Open->References++;
                   1997:                     NdisReleaseSpinLock(&Adapter->Lock);
                   1998: 
                   1999:                     NdisIndicateStatus(
                   2000:                         Open->NdisBindingContext,
                   2001:                         NDIS_STATUS_RESET_START,
                   2002:                         NULL,
                   2003:                         0
                   2004:                         );
                   2005: 
                   2006:                     NdisAcquireSpinLock(&Adapter->Lock);
                   2007:                     Open->References--;
                   2008: 
                   2009:                     CurrentLink = CurrentLink->Flink;
                   2010: 
                   2011:                 }
                   2012: 
                   2013: 
                   2014:                 Adapter->IndicatingResetStart = FALSE;
                   2015: 
                   2016:                 SetupForReset(
                   2017:                     Adapter,
                   2018:                     PSONIC_OPEN_FROM_BINDING_HANDLE(MacBindingHandle)
                   2019:                     );
                   2020:             }
                   2021: 
                   2022:             Open->References++;
                   2023:             Adapter->ResettingOpen = Open;
                   2024: 
                   2025:             StatusToReturn = NDIS_STATUS_PENDING;
                   2026: 
                   2027:         } else {
                   2028: 
                   2029:             StatusToReturn = NDIS_STATUS_CLOSING;
                   2030: 
                   2031:         }
                   2032: 
                   2033:     } else {
                   2034: 
                   2035:         StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
                   2036: 
                   2037:     }
                   2038: 
                   2039: 
                   2040:     //
                   2041:     // This macro assumes it is called with the lock held,
                   2042:     // and releases it.
                   2043:     //
                   2044: 
                   2045:     SONIC_DO_DEFERRED(Adapter);
                   2046:     return StatusToReturn;
                   2047: 
                   2048: }
                   2049: 
                   2050: #if 0
                   2051: STATIC
                   2052: UINT
                   2053: CalculateCRC(
                   2054:     IN UINT NumberOfBytes,
                   2055:     IN PCHAR Input
                   2056:     )
                   2057: 
                   2058: /*++
                   2059: 
                   2060: Routine Description:
                   2061: 
                   2062:     Calculates a 32 bit crc value over the input number of bytes.
                   2063: 
                   2064:     NOTE: This routine assumes UINTs are 32 bits.
                   2065: 
                   2066: Arguments:
                   2067: 
                   2068:     NumberOfBytes - The number of bytes in the input.
                   2069: 
                   2070:     Input - An input "string" to calculate a CRC over.
                   2071: 
                   2072: Return Value:
                   2073: 
                   2074:     A 32 bit crc value.
                   2075: 
                   2076: 
                   2077: --*/
                   2078: 
                   2079: {
                   2080: 
                   2081:     const UINT POLY = 0x04c11db6;
                   2082:     UINT CRCValue = 0xffffffff;
                   2083: 
                   2084:     ASSERT(sizeof(UINT) == 4);
                   2085: 
                   2086:     for (
                   2087:         ;
                   2088:         NumberOfBytes;
                   2089:         NumberOfBytes--
                   2090:         ) {
                   2091: 
                   2092:         UINT CurrentBit;
                   2093:         UCHAR CurrentByte = *Input;
                   2094:         Input++;
                   2095: 
                   2096:         for (
                   2097:             CurrentBit = 8;
                   2098:             CurrentBit;
                   2099:             CurrentBit--
                   2100:             ) {
                   2101: 
                   2102:             UINT CurrentCRCHigh = CRCValue >> 31;
                   2103: 
                   2104:             CRCValue <<= 1;
                   2105: 
                   2106:             if (CurrentCRCHigh ^ (CurrentByte & 0x01)) {
                   2107: 
                   2108:                 CRCValue ^= POLY;
                   2109:                 CRCValue |= 0x00000001;
                   2110: 
                   2111:             }
                   2112: 
                   2113:             CurrentByte >>= 1;
                   2114: 
                   2115:         }
                   2116: 
                   2117:     }
                   2118: 
                   2119:     return CRCValue;
                   2120: 
                   2121: }
                   2122: #endif
                   2123: 
                   2124: extern
                   2125: VOID
                   2126: StartAdapterReset(
                   2127:     IN PSONIC_ADAPTER Adapter
                   2128:     )
                   2129: 
                   2130: /*++
                   2131: 
                   2132: Routine Description:
                   2133: 
                   2134:     This is the first phase of resetting the adapter hardware.
                   2135: 
                   2136:     It makes the following assumptions:
                   2137: 
                   2138:     1) That the hardware has been stopped.
                   2139: 
                   2140:     2) That it can not be preempted.
                   2141: 
                   2142:     3) That no other adapter activity can occur.
                   2143: 
                   2144:     When this routine is finished all of the adapter information
                   2145:     will be as if the driver was just initialized.
                   2146: 
                   2147: Arguments:
                   2148: 
                   2149:     Adapter - The adapter whose hardware is to be reset.
                   2150: 
                   2151: Return Value:
                   2152: 
                   2153:     None.
                   2154: 
                   2155: --*/
                   2156: {
                   2157: 
                   2158:     //
                   2159:     // These are used for cleaning the rings.
                   2160:     //
                   2161: 
                   2162:     PSONIC_RECEIVE_DESCRIPTOR CurrentReceiveDescriptor;
                   2163:     PSONIC_TRANSMIT_DESCRIPTOR CurrentTransmitDescriptor;
                   2164:     UINT i;
                   2165:     SONIC_PHYSICAL_ADDRESS SonicPhysicalAdr;
                   2166: 
                   2167: 
                   2168:     //
                   2169:     // Shut down the chip.  We won't be doing any more work until
                   2170:     // the reset is complete.
                   2171:     //
                   2172: 
                   2173:     SonicStopChip(Adapter);
                   2174: 
                   2175:     //
                   2176:     // Once the chip is stopped we can't get any more interrupts.
                   2177:     // Any interrupts that are "queued" for processing could
                   2178:     // only possibly service this reset.  It is therefore safe for
                   2179:     // us to clear the adapter global csr value.
                   2180:     //
                   2181:     Adapter->IsrValue = 0;
                   2182: 
                   2183: 
                   2184:     Adapter->LastTransmitDescriptor =
                   2185:                 Adapter->TransmitDescriptorArea +
                   2186:                 (Adapter->NumberOfTransmitDescriptors-1);
                   2187:     Adapter->NumberOfAvailableDescriptors =
                   2188:                 Adapter->NumberOfTransmitDescriptors;
                   2189:     Adapter->AllocateableDescriptor =
                   2190:                 Adapter->TransmitDescriptorArea;
                   2191:     Adapter->TransmittingDescriptor =
                   2192:                 Adapter->TransmitDescriptorArea;
                   2193:     Adapter->FirstUncommittedDescriptor =
                   2194:                 Adapter->TransmitDescriptorArea;
                   2195:     Adapter->PacketsSinceLastInterrupt = 0;
                   2196: 
                   2197:     Adapter->CurrentReceiveBufferIndex = 0;
                   2198:     Adapter->CurrentReceiveDescriptorIndex = 0;
                   2199:     Adapter->LastReceiveDescriptor =
                   2200:                 &Adapter->ReceiveDescriptorArea[
                   2201:                     Adapter->NumberOfReceiveDescriptors-1];
                   2202: 
                   2203:     Adapter->InterruptMaskRegister = SONIC_INT_DEFAULT_VALUE;
                   2204:     Adapter->ReceiveDescriptorsExhausted = FALSE;
                   2205:     Adapter->ReceiveBuffersExhausted = FALSE;
                   2206:     Adapter->ReceiveControlRegister = SONIC_RCR_DEFAULT_VALUE;
                   2207: 
                   2208:     Adapter->SendStageOpen = TRUE;
                   2209: 
                   2210:     Adapter->AlreadyProcessingSendStage = FALSE;
                   2211: 
                   2212:     //
                   2213:     // Clean the receive descriptors and initialize the link
                   2214:     // fields.
                   2215:     //
                   2216: 
                   2217:     SONIC_ZERO_MEMORY(
                   2218:         Adapter->ReceiveDescriptorArea,
                   2219:         (sizeof(SONIC_RECEIVE_DESCRIPTOR)*Adapter->NumberOfReceiveDescriptors)
                   2220:         );
                   2221: 
                   2222:     for (
                   2223:         i = 0, CurrentReceiveDescriptor = Adapter->ReceiveDescriptorArea;
                   2224:         i < Adapter->NumberOfReceiveDescriptors;
                   2225:         i++,CurrentReceiveDescriptor++
                   2226:         ) {
                   2227: 
                   2228:         CurrentReceiveDescriptor->InUse = SONIC_OWNED_BY_SONIC;
                   2229: 
                   2230:         SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical) +
                   2231:                         (i * sizeof(SONIC_RECEIVE_DESCRIPTOR));
                   2232: 
                   2233:         if (i == 0) {
                   2234: 
                   2235:             Adapter->ReceiveDescriptorArea[
                   2236:                 Adapter->NumberOfReceiveDescriptors-1].Link =
                   2237:                         SonicPhysicalAdr | SONIC_END_OF_LIST;
                   2238: 
                   2239:         } else {
                   2240: 
                   2241:             Adapter->ReceiveDescriptorArea[i-1].Link = SonicPhysicalAdr;
                   2242: 
                   2243:         }
                   2244: 
                   2245:     }
                   2246: 
                   2247: 
                   2248:     //
                   2249:     // Clean the transmit descriptors and initialize the link
                   2250:     // fields.
                   2251:     //
                   2252: 
                   2253:     SONIC_ZERO_MEMORY(
                   2254:         Adapter->TransmitDescriptorArea,
                   2255:         (sizeof(SONIC_TRANSMIT_DESCRIPTOR)*Adapter->NumberOfTransmitDescriptors)
                   2256:         );
                   2257: 
                   2258:     for (
                   2259:         i = 0, CurrentTransmitDescriptor = Adapter->TransmitDescriptorArea;
                   2260:         i < Adapter->NumberOfTransmitDescriptors;
                   2261:         i++,CurrentTransmitDescriptor++
                   2262:         ) {
                   2263: 
                   2264:         SonicPhysicalAdr = NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical) +
                   2265:                         (i * sizeof(SONIC_TRANSMIT_DESCRIPTOR));
                   2266: 
                   2267:         if (i == 0) {
                   2268: 
                   2269:             Adapter->TransmitDescriptorArea[Adapter->NumberOfTransmitDescriptors-1].Link = SonicPhysicalAdr;
                   2270: 
                   2271:         } else {
                   2272: 
                   2273:             (CurrentTransmitDescriptor-1)->Link = SonicPhysicalAdr;
                   2274: 
                   2275:         }
                   2276: 
                   2277:     }
                   2278: 
                   2279: 
                   2280:     //
                   2281:     // Recover all of the adapter buffers.
                   2282:     //
                   2283: 
                   2284:     {
                   2285: 
                   2286:         UINT i;
                   2287: 
                   2288:         for (
                   2289:             i = 0;
                   2290:             i < (SONIC_NUMBER_OF_SMALL_BUFFERS +
                   2291:                  SONIC_NUMBER_OF_MEDIUM_BUFFERS +
                   2292:                  SONIC_NUMBER_OF_LARGE_BUFFERS);
                   2293:             i++
                   2294:             ) {
                   2295: 
                   2296:             Adapter->SonicBuffers[i].Next = i+1;
                   2297: 
                   2298:         }
                   2299: 
                   2300:         Adapter->SonicBufferListHeads[0] = -1;
                   2301:         Adapter->SonicBufferListHeads[1] = 0;
                   2302:         Adapter->SonicBuffers[SONIC_NUMBER_OF_SMALL_BUFFERS-1].Next = -1;
                   2303:         Adapter->SonicBufferListHeads[2] = SONIC_NUMBER_OF_SMALL_BUFFERS;
                   2304:         Adapter->SonicBuffers[(SONIC_NUMBER_OF_SMALL_BUFFERS+
                   2305:                                SONIC_NUMBER_OF_MEDIUM_BUFFERS)-1].Next = -1;
                   2306:         Adapter->SonicBufferListHeads[3] = SONIC_NUMBER_OF_SMALL_BUFFERS +
                   2307:                                            SONIC_NUMBER_OF_MEDIUM_BUFFERS;
                   2308:         Adapter->SonicBuffers[(SONIC_NUMBER_OF_SMALL_BUFFERS+
                   2309:                                SONIC_NUMBER_OF_MEDIUM_BUFFERS+
                   2310:                                SONIC_NUMBER_OF_LARGE_BUFFERS)-1].Next = -1;
                   2311: 
                   2312:     }
                   2313: 
                   2314:     //
                   2315:     // Go through the various transmit lists and abort every packet.
                   2316:     //
                   2317: 
                   2318:     {
                   2319: 
                   2320:         UINT i;
                   2321:         PNDIS_PACKET Packet;
                   2322:         PSONIC_PACKET_RESERVED Reserved;
                   2323:         PSONIC_OPEN Open;
                   2324:         PNDIS_PACKET Next;
                   2325: 
                   2326:         for (
                   2327:             i = 0;
                   2328:             i < 3;
                   2329:             i++
                   2330:             ) {
                   2331: 
                   2332:             switch (i) {
                   2333: 
                   2334:                 case 0:
                   2335:                     Next = Adapter->FirstLoopBack;
                   2336:                     break;
                   2337:                 case 1:
                   2338:                     Next = Adapter->FirstFinishTransmit;
                   2339:                     break;
                   2340:                 case 2:
                   2341:                     Next = Adapter->FirstSendStagePacket;
                   2342:                     break;
                   2343: 
                   2344:             }
                   2345: 
                   2346: 
                   2347:             while (Next) {
                   2348: 
                   2349:                 Packet = Next;
                   2350:                 Reserved = PSONIC_RESERVED_FROM_PACKET(Packet);
                   2351:                 Next = Reserved->Next;
                   2352:                 Open =
                   2353:                   PSONIC_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
                   2354: 
                   2355:                 //
                   2356:                 // The completion of the packet is one less reason
                   2357:                 // to keep the open around.
                   2358:                 //
                   2359: 
                   2360:                 ASSERT(Open->References);
                   2361: 
                   2362:                 NdisCompleteSend(
                   2363:                     Open->NdisBindingContext,
                   2364:                     Packet,
                   2365:                     NDIS_STATUS_REQUEST_ABORTED
                   2366:                     );
                   2367: 
                   2368:                 Open->References--;
                   2369: 
                   2370:             }
                   2371: 
                   2372:         }
                   2373: 
                   2374:         Adapter->FirstLoopBack = NULL;
                   2375:         Adapter->LastLoopBack = NULL;
                   2376:         Adapter->FirstFinishTransmit = NULL;
                   2377:         Adapter->LastFinishTransmit = NULL;
                   2378:         Adapter->FirstSendStagePacket = NULL;
                   2379:         Adapter->LastSendStagePacket = NULL;
                   2380:         Adapter->GeneralOptional[GO_TRANSMIT_QUEUE_LENGTH - GO_ARRAY_START] = 0;
                   2381: 
                   2382:     }
                   2383: 
                   2384:     (VOID)SetupRegistersAndInit(Adapter);
                   2385: 
                   2386: }
                   2387: 
                   2388: STATIC
                   2389: BOOLEAN
                   2390: SetupRegistersAndInit(
                   2391:     IN PSONIC_ADAPTER Adapter
                   2392:     )
                   2393: 
                   2394: /*++
                   2395: 
                   2396: Routine Description:
                   2397: 
                   2398:     It is this routines responsibility to make sure that the
                   2399:     initialization block is filled and the chip is initialized
                   2400:     *but not* started.
                   2401: 
                   2402:     NOTE: This routine assumes that it is called with the lock
                   2403:     acquired OR that only a single thread of execution is working
                   2404:     with this particular adapter.
                   2405: 
                   2406: Arguments:
                   2407: 
                   2408:     Adapter - The adapter whose hardware is to be initialized.
                   2409: 
                   2410: Return Value:
                   2411: 
                   2412:     TRUE if the registers are initialized successfully.
                   2413: 
                   2414: --*/
                   2415: {
                   2416: 
                   2417:     USHORT CommandRegister;
                   2418:     UINT Time;
                   2419: 
                   2420: 
                   2421:     SONIC_WRITE_PORT(Adapter, SONIC_DATA_CONFIGURATION,
                   2422:             Adapter->DataConfigurationRegister
                   2423:             );
                   2424: 
                   2425:     SONIC_WRITE_PORT(Adapter, SONIC_RECEIVE_CONTROL,
                   2426:             Adapter->ReceiveControlRegister
                   2427:             );
                   2428: 
                   2429:     SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_MASK,
                   2430:             Adapter->InterruptMaskRegister
                   2431:             );
                   2432: 
                   2433:     SONIC_WRITE_PORT(Adapter, SONIC_INTERRUPT_STATUS,
                   2434:             (USHORT)0xffff
                   2435:             );
                   2436: 
                   2437: 
                   2438: 
                   2439:     SONIC_WRITE_PORT(Adapter, SONIC_UPPER_TRANSMIT_DESCRIPTOR,
                   2440:             SONIC_GET_HIGH_PART_ADDRESS(
                   2441:                 NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical))
                   2442:             );
                   2443: 
                   2444:     SONIC_WRITE_PORT(Adapter, SONIC_CURR_TRANSMIT_DESCRIPTOR,
                   2445:             SONIC_GET_LOW_PART_ADDRESS(
                   2446:                 NdisGetPhysicalAddressLow(Adapter->TransmitDescriptorAreaPhysical))
                   2447:             );
                   2448: 
                   2449: 
                   2450:     SONIC_WRITE_PORT(Adapter, SONIC_UPPER_RECEIVE_DESCRIPTOR,
                   2451:             SONIC_GET_HIGH_PART_ADDRESS(
                   2452:                 NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical))
                   2453:             );
                   2454: 
                   2455:     SONIC_WRITE_PORT(Adapter, SONIC_CURR_RECEIVE_DESCRIPTOR,
                   2456:             SONIC_GET_LOW_PART_ADDRESS(
                   2457:                 NdisGetPhysicalAddressLow(Adapter->ReceiveDescriptorAreaPhysical))
                   2458:             );
                   2459: 
                   2460: 
                   2461:     //
                   2462:     // The EOBC value cannot be odd (since the card register
                   2463:     // wants it in words); in addition it appears that the
                   2464:     // value in the register must be even, so this number
                   2465:     // has to be a multiple of 4.
                   2466:     //
                   2467:     ASSERT((SONIC_END_OF_BUFFER_COUNT & 0x3) == 0);
                   2468: 
                   2469:     switch (Adapter->AdapterType) {
                   2470: 
                   2471: #ifdef SONIC_EISA
                   2472: 
                   2473:     case SONIC_ADAPTER_TYPE_EISA:
                   2474: 
                   2475:         //
                   2476:         // For the EISA card, set EOBC to 2 words more than real
                   2477:         // size.
                   2478:         //
                   2479: 
                   2480:         SONIC_WRITE_PORT(Adapter, SONIC_END_OF_BUFFER_WORD_COUNT,
                   2481:                 (SONIC_END_OF_BUFFER_COUNT / 2) + 2
                   2482:                 );
                   2483:         break;
                   2484: 
                   2485: #endif  // SONIC_EISA
                   2486: 
                   2487: #ifdef SONIC_INTERNAL
                   2488: 
                   2489:     case SONIC_ADAPTER_TYPE_INTERNAL:
                   2490: 
                   2491:         SONIC_WRITE_PORT(Adapter, SONIC_END_OF_BUFFER_WORD_COUNT,
                   2492:                 SONIC_END_OF_BUFFER_COUNT / 2
                   2493:                 );
                   2494:         break;
                   2495: 
                   2496: #endif  // SONIC_INTERNAL
                   2497: 
                   2498:     default:
                   2499: 
                   2500:         ASSERT(FALSE);
                   2501:         break;
                   2502: 
                   2503:     }
                   2504: 
                   2505: 
                   2506:     SONIC_WRITE_PORT(Adapter, SONIC_UPPER_RECEIVE_RESOURCE,
                   2507:             SONIC_GET_HIGH_PART_ADDRESS(
                   2508:                 NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical))
                   2509:             );
                   2510: 
                   2511:     SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_START,
                   2512:             SONIC_GET_LOW_PART_ADDRESS(
                   2513:                 NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical))
                   2514:             );
                   2515: 
                   2516:     SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_END,
                   2517:             (USHORT)(SONIC_GET_LOW_PART_ADDRESS(
                   2518:                 NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical)) +
                   2519:                 sizeof(SONIC_RECEIVE_RESOURCE) *
                   2520:                 Adapter->NumberOfReceiveBuffers)
                   2521:             );
                   2522: 
                   2523:     SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_READ,
                   2524:             SONIC_GET_LOW_PART_ADDRESS(
                   2525:                 NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical))
                   2526:             );
                   2527: 
                   2528:     SONIC_WRITE_PORT(Adapter, SONIC_RESOURCE_WRITE,
                   2529:             SONIC_GET_LOW_PART_ADDRESS(
                   2530:                 NdisGetPhysicalAddressLow(Adapter->ReceiveResourceAreaPhysical))
                   2531:             );
                   2532: 
                   2533: 
                   2534:     //
                   2535:     // Now take us out of reset mode...
                   2536:     //
                   2537: 
                   2538:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   2539:         0x0000
                   2540:         );
                   2541: 
                   2542:     //
                   2543:     // ...and issue the Read RRA command.
                   2544:     //
                   2545: 
                   2546:     SONIC_WRITE_PORT(Adapter, SONIC_COMMAND,
                   2547:         SONIC_CR_READ_RRA
                   2548:         );
                   2549: 
                   2550: 
                   2551: 
                   2552:     //
                   2553:     // Wait for 1/5 second for Read RRA to finish.
                   2554:     //
                   2555: 
                   2556:     Time = 20;
                   2557: 
                   2558:     while (Time > 0) {
                   2559: 
                   2560:         NdisStallExecution(10000);
                   2561: 
                   2562:         SONIC_READ_PORT(Adapter, SONIC_COMMAND, &CommandRegister);
                   2563:         if ((CommandRegister & SONIC_CR_READ_RRA) == 0) {
                   2564:             break;
                   2565:         }
                   2566: 
                   2567:         Time--;
                   2568: 
                   2569:     }
                   2570: 
                   2571:     if (Time == 0) {
                   2572: 
                   2573: #if DBG
                   2574:         DbgPrint("SONIC: Could not read RRA\n");
                   2575: #endif
                   2576:         return FALSE;
                   2577: 
                   2578:     }
                   2579: 
                   2580: 
                   2581:     //
                   2582:     // This will cause a LOAD_CAM interrupt when it is done.
                   2583:     //
                   2584: 
                   2585:     SonicStartCamReload(Adapter);
                   2586: 
                   2587:     return TRUE;
                   2588: 
                   2589: }
                   2590: 
                   2591: extern
                   2592: VOID
                   2593: SetupForReset(
                   2594:     IN PSONIC_ADAPTER Adapter,
                   2595:     IN PSONIC_OPEN Open
                   2596:     )
                   2597: 
                   2598: /*++
                   2599: 
                   2600: Routine Description:
                   2601: 
                   2602:     This routine is used to fill in the who and why a reset is
                   2603:     being set up as well as setting the appropriate fields in the
                   2604:     adapter.
                   2605: 
                   2606:     NOTE: This routine must be called with the lock acquired.
                   2607: 
                   2608: Arguments:
                   2609: 
                   2610:     Adapter - The adapter whose hardware is to be initialized.
                   2611: 
                   2612:     Open - A pointer to an sonic open structure.
                   2613: 
                   2614: Return Value:
                   2615: 
                   2616:     None.
                   2617: 
                   2618: --*/
                   2619: {
                   2620: 
                   2621:     PNDIS_REQUEST CurrentRequest;
                   2622:     PNDIS_REQUEST * CurrentNextLocation;
                   2623:     PSONIC_OPEN TmpOpen;
                   2624: 
                   2625:     PSONIC_REQUEST_RESERVED Reserved;
                   2626: 
                   2627:     //
                   2628:     // Shut down the chip.  We won't be doing any more work until
                   2629:     // the reset is complete. We take it out of reset mode, however.
                   2630:     //
                   2631: 
                   2632:     SonicStopChip(Adapter);
                   2633: 
                   2634: 
                   2635:     //
                   2636:     // Once the chip is stopped we can't get any more interrupts.
                   2637:     // This call ensures that any ISR which is just about to run
                   2638:     // will find no bits in the ISR, and any DPR which fires will
                   2639:     // find nothing queued to do.
                   2640:     //
                   2641: 
                   2642:     NdisSynchronizeWithInterrupt(
                   2643:         &Adapter->Interrupt,
                   2644:         SonicSynchClearIsr,
                   2645:         (PVOID)Adapter);
                   2646: 
                   2647: 
                   2648:     Adapter->ResetInProgress = TRUE;
                   2649: 
                   2650:     //
                   2651:     // Shut down all of the transmit queues so that the
                   2652:     // transmit portion of the chip will eventually calm down.
                   2653:     //
                   2654: 
                   2655:     Adapter->SendStageOpen = FALSE;
                   2656: 
                   2657:     //
                   2658:     // If there is a close at the top of the queue, then
                   2659:     // it may be in two states:
                   2660:     //
                   2661:     // 1- Has interrupted, and the InterruptDpc got the
                   2662:     // interrupt out of Adapter->IsrValue before we zeroed it.
                   2663:     //
                   2664:     // 2- Has interrupted, but we zeroed Adapter->IsrValue
                   2665:     // before it read it, OR has not yet interrupted.
                   2666:     //
                   2667:     // In case 1, the interrupt will be processed and the
                   2668:     // close will complete without our intervention. In
                   2669:     // case 2, the open will not complete. In that case
                   2670:     // the CAM will have been updated for that open, so
                   2671:     // all that remains is for us to dereference the open
                   2672:     // as would have been done in the interrupt handler.
                   2673:     //
                   2674:     // Closes that are not at the top of the queue we
                   2675:     // leave in place; when we restart the queue after
                   2676:     // the reset, they will get processed.
                   2677:     //
                   2678: 
                   2679:     CurrentRequest = Adapter->FirstRequest;
                   2680: 
                   2681:     if (CurrentRequest) {
                   2682: 
                   2683:         Reserved = PSONIC_RESERVED_FROM_REQUEST(CurrentRequest);
                   2684: 
                   2685:         //
                   2686:         // If the first request is a close, take it off the
                   2687:         // queue, and "complete" it.
                   2688:         //
                   2689: 
                   2690:         if (CurrentRequest->RequestType == NdisRequestClose) {
                   2691:             Adapter->FirstRequest = Reserved->Next;
                   2692:             --(Reserved->OpenBlock)->References;
                   2693:             CurrentRequest = Adapter->FirstRequest;
                   2694:         }
                   2695: 
                   2696:         CurrentNextLocation = &(Adapter->FirstRequest);
                   2697: 
                   2698:         while (CurrentRequest) {
                   2699: 
                   2700:             Reserved = PSONIC_RESERVED_FROM_REQUEST(CurrentRequest);
                   2701: 
                   2702:             if ((CurrentRequest->RequestType == NdisRequestClose) ||
                   2703:                 (CurrentRequest->RequestType == NdisRequestOpen)) {
                   2704: 
                   2705:                 //
                   2706:                 // Opens are inoffensive, we just leave them
                   2707:                 // on the list. Closes that were not at the
                   2708:                 // head of the list were not processing and
                   2709:                 // can be left on also.
                   2710:                 //
                   2711: 
                   2712:                 CurrentNextLocation = &(Reserved->Next);
                   2713: 
                   2714:             } else {
                   2715: 
                   2716:                 //
                   2717:                 // Not a close, remove it from the list and
                   2718:                 // fail it.
                   2719:                 //
                   2720: 
                   2721:                 *CurrentNextLocation = Reserved->Next;
                   2722:                 TmpOpen = Reserved->OpenBlock;
                   2723: 
                   2724:                 NdisReleaseSpinLock(&Adapter->Lock);
                   2725: 
                   2726:                 NdisCompleteRequest(
                   2727:                     TmpOpen->NdisBindingContext,
                   2728:                     CurrentRequest,
                   2729:                     NDIS_STATUS_RESET_IN_PROGRESS
                   2730:                     );
                   2731: 
                   2732:                 NdisAcquireSpinLock(&Adapter->Lock);
                   2733: 
                   2734:                 --TmpOpen->References;
                   2735: 
                   2736:             }
                   2737: 
                   2738:             CurrentRequest = *CurrentNextLocation;
                   2739: 
                   2740:         }
                   2741: 
                   2742:         Adapter->RequestInProgress = FALSE;
                   2743: 
                   2744:     }
                   2745: 
                   2746: }
                   2747: 
                   2748: #ifdef SONIC_INTERNAL
                   2749: 
                   2750: //
                   2751: // The next routines are to support reading the registry to
                   2752: // obtain information about the internal sonic on the
                   2753: // MIPS R4000 motherboards.
                   2754: //
                   2755: 
                   2756: //
                   2757: // This structure is used as the Context in the callbacks
                   2758: // to SonicHardwareSaveInformation.
                   2759: //
                   2760: 
                   2761: typedef struct _SONIC_HARDWARE_INFO {
                   2762: 
                   2763:     //
                   2764:     // These are read out of the "Configuration Data"
                   2765:     // data.
                   2766:     //
                   2767: 
                   2768:     CCHAR InterruptVector;
                   2769:     KIRQL InterruptLevel;
                   2770:     USHORT DataConfigurationRegister;
                   2771:     LARGE_INTEGER PortAddress;
                   2772:     BOOLEAN DataValid;
                   2773:     UCHAR EthernetAddress[8];
                   2774:     BOOLEAN AddressValid;
                   2775: 
                   2776:     //
                   2777:     // This is set to TRUE if "Identifier" is equal to
                   2778:     // "SONIC".
                   2779:     //
                   2780: 
                   2781:     BOOLEAN SonicIdentifier;
                   2782: 
                   2783: } SONIC_HARDWARE_INFO, *PSONIC_HARDWARE_INFO;
                   2784: 
                   2785: 
                   2786: STATIC
                   2787: NTSTATUS
                   2788: SonicHardwareSaveInformation(
                   2789:     IN PWSTR ValueName,
                   2790:     IN ULONG ValueType,
                   2791:     IN PVOID ValueData,
                   2792:     IN ULONG ValueLength,
                   2793:     IN PVOID Context,
                   2794:     IN PVOID EntryContext
                   2795:     )
                   2796: 
                   2797: /*++
                   2798: 
                   2799: Routine Description:
                   2800: 
                   2801:     This routine is a callback routine for RtlQueryRegistryValues.
                   2802:     It is called back with the data for the "Identifier" value
                   2803:     and verifies that it is "SONIC", then is called back with
                   2804:     the resource list and records the ports, interrupt number,
                   2805:     and DCR value.
                   2806: 
                   2807: Arguments:
                   2808: 
                   2809:     ValueName - The name of the value ("Identifier" or "Configuration
                   2810:         Data").
                   2811: 
                   2812:     ValueType - The type of the value (REG_SZ or REG_BINARY).
                   2813: 
                   2814:     ValueData - The null-terminated data for the value.
                   2815: 
                   2816:     ValueLength - The length of ValueData (ignored).
                   2817: 
                   2818:     Context - A pointer to the SONIC_HARDWARE_INFO structure.
                   2819: 
                   2820:     EntryContext - FALSE for "Identifier", TRUE for "Configuration Data".
                   2821: 
                   2822: Return Value:
                   2823: 
                   2824:     STATUS_SUCCESS
                   2825: 
                   2826: --*/
                   2827: 
                   2828: {
                   2829:     PSONIC_HARDWARE_INFO HardwareInfo = (PSONIC_HARDWARE_INFO)Context;
                   2830: 
                   2831:     if ((BOOLEAN)EntryContext) {
                   2832: 
                   2833:         //
                   2834:         // This is the "Configuration Data" callback.
                   2835:         //
                   2836: 
                   2837:         if ((ValueType == REG_BINARY || ValueType == REG_FULL_RESOURCE_DESCRIPTOR) &&
                   2838:             (ValueLength >= sizeof(CM_FULL_RESOURCE_DESCRIPTOR))) {
                   2839: 
                   2840:             BOOLEAN InterruptRead = FALSE;
                   2841:             BOOLEAN PortAddressRead = FALSE;
                   2842:             BOOLEAN DeviceSpecificRead = FALSE;
                   2843:             UINT i;
                   2844: 
                   2845:             PCM_PARTIAL_RESOURCE_LIST ResourceList;
                   2846:             PCM_PARTIAL_RESOURCE_DESCRIPTOR ResourceDescriptor;
                   2847:             PCM_SONIC_DEVICE_DATA SonicDeviceData;
                   2848: 
                   2849:             ResourceList =
                   2850:                &((PCM_FULL_RESOURCE_DESCRIPTOR)ValueData)->PartialResourceList;
                   2851: 
                   2852:             for (i = 0; i < ResourceList->Count; i++) {
                   2853: 
                   2854:                 ResourceDescriptor = &(ResourceList->PartialDescriptors[i]);
                   2855: 
                   2856:                 switch (ResourceDescriptor->Type) {
                   2857: 
                   2858:                 case CmResourceTypePort:
                   2859: 
                   2860:                     HardwareInfo->PortAddress = ResourceDescriptor->u.Port.Start;
                   2861:                     PortAddressRead = TRUE;
                   2862:                     break;
                   2863: 
                   2864:                 case CmResourceTypeInterrupt:
                   2865: 
                   2866:                     HardwareInfo->InterruptVector = (CCHAR)ResourceDescriptor->u.Interrupt.Vector;
                   2867:                     HardwareInfo->InterruptLevel = (KIRQL)ResourceDescriptor->u.Interrupt.Level;
                   2868:                     InterruptRead = TRUE;
                   2869:                     break;
                   2870: 
                   2871:                 case CmResourceTypeDeviceSpecific:
                   2872: 
                   2873:                     if (i == ResourceList->Count-1) {
                   2874: 
                   2875:                         SonicDeviceData = (PCM_SONIC_DEVICE_DATA)
                   2876:                             &(ResourceList->PartialDescriptors[ResourceList->Count]);
                   2877: 
                   2878:                         //
                   2879:                         // Make sure we have enough room for each element we read.
                   2880:                         //
                   2881: 
                   2882:                         if (ResourceDescriptor->u.DeviceSpecificData.DataSize >=
                   2883:                             (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]))) {
                   2884: 
                   2885:                             HardwareInfo->DataConfigurationRegister =
                   2886:                                 SonicDeviceData->DataConfigurationRegister;
                   2887:                             DeviceSpecificRead = TRUE;
                   2888: 
                   2889:                             //
                   2890:                             // Version.Revision later than 0.0 means that
                   2891:                             // the ethernet address is there too.
                   2892:                             //
                   2893: 
                   2894:                             if ((SonicDeviceData->Version != 0) ||
                   2895:                                 (SonicDeviceData->Revision != 0)) {
                   2896: 
                   2897:                                 if (ResourceDescriptor->u.DeviceSpecificData.DataSize >=
                   2898:                                     (ULONG)(FIELD_OFFSET (CM_SONIC_DEVICE_DATA, EthernetAddress[0]) + 8)) {
                   2899: 
                   2900:                                     SONIC_MOVE_MEMORY(
                   2901:                                         HardwareInfo->EthernetAddress,
                   2902:                                         SonicDeviceData->EthernetAddress,
                   2903:                                         8);
                   2904: 
                   2905:                                     HardwareInfo->AddressValid = TRUE;
                   2906: 
                   2907:                                 }
                   2908: 
                   2909:                             }
                   2910: 
                   2911:                         }
                   2912: 
                   2913:                     }
                   2914: 
                   2915:                     break;
                   2916: 
                   2917:                 }
                   2918: 
                   2919:             }
                   2920: 
                   2921:             //
                   2922:             // Make sure we got all we wanted.
                   2923:             //
                   2924: 
                   2925:             if (PortAddressRead && InterruptRead && DeviceSpecificRead) {
                   2926:                 HardwareInfo->DataValid = TRUE;
                   2927:             }
                   2928: 
                   2929:         }
                   2930: 
                   2931:     } else {
                   2932: 
                   2933:         static const WCHAR SonicString[] = L"SONIC";
                   2934: 
                   2935:         //
                   2936:         // This is the "Identifier" callback.
                   2937:         //
                   2938: 
                   2939:         if ((ValueType == REG_SZ) &&
                   2940:             (ValueLength >= sizeof(SonicString)) &&
                   2941:             (RtlCompareMemory (ValueData, (PVOID)&SonicString, sizeof(SonicString)) == sizeof(SonicString))) {
                   2942: 
                   2943:             HardwareInfo->SonicIdentifier = TRUE;
                   2944: 
                   2945:         }
                   2946: 
                   2947:     }
                   2948: 
                   2949:     return STATUS_SUCCESS;
                   2950: 
                   2951: }
                   2952: 
                   2953: 
                   2954: STATIC
                   2955: BOOLEAN
                   2956: SonicHardwareVerifyChecksum(
                   2957:     IN PSONIC_ADAPTER Adapter,
                   2958:     IN PUCHAR EthernetAddress,
                   2959:     OUT ULONG ErrorLogData[3]
                   2960:     )
                   2961: 
                   2962: /*++
                   2963: 
                   2964: Routine Description:
                   2965: 
                   2966:     This routine verifies that the checksum on the address
                   2967:     for an internal sonic on a MIPS R4000 system is correct.
                   2968: 
                   2969: Arguments:
                   2970: 
                   2971:     Adapter - The adapter which is being verified.
                   2972: 
                   2973:     EthernetAddress - A pointer to the address, with the checksum
                   2974:         following it.
                   2975: 
                   2976:     ErrorLogData - If the checksum is bad, returns the address
                   2977:         and the checksum we expected.
                   2978: 
                   2979: Return Value:
                   2980: 
                   2981:     TRUE if the checksum is correct.
                   2982: 
                   2983: --*/
                   2984: 
                   2985: {
                   2986: 
                   2987:     //
                   2988:     // Iteration variable.
                   2989:     //
                   2990:     UINT i;
                   2991: 
                   2992:     //
                   2993:     // Holds the checksum value.
                   2994:     //
                   2995:     USHORT CheckSum = 0;
                   2996: 
                   2997: 
                   2998:     //
                   2999:     // The network address is stored in the first 6 bytes of
                   3000:     // EthernetAddress. Following that is a zero byte followed
                   3001:     // by a value such that the sum of a checksum on the six
                   3002:     // bytes and this value is 0xff. The checksum is computed
                   3003:     // by adding together the six bytes, with the carry being
                   3004:     // wrapped back to the first byte.
                   3005:     //
                   3006: 
                   3007:     for (i=0; i<6; i++) {
                   3008: 
                   3009:         CheckSum += EthernetAddress[i];
                   3010:         if (CheckSum > 0xff) {
                   3011:             CheckSum -= 0xff;
                   3012:         }
                   3013: 
                   3014:     }
                   3015: 
                   3016: 
                   3017:     if ((EthernetAddress[6] != 0x00)  ||
                   3018:         ((EthernetAddress[7] + CheckSum) != 0xff)) {
                   3019: 
                   3020:         ErrorLogData[0] = ((ULONG)(EthernetAddress[3]) << 24) +
                   3021:                           ((ULONG)(EthernetAddress[2]) << 16) +
                   3022:                           ((ULONG)(EthernetAddress[1]) << 8) +
                   3023:                           ((ULONG)(EthernetAddress[0]));
                   3024:         ErrorLogData[1] = ((ULONG)(EthernetAddress[7]) << 24) +
                   3025:                           ((ULONG)(EthernetAddress[6]) << 16) +
                   3026:                           ((ULONG)(EthernetAddress[5]) << 8) +
                   3027:                           ((ULONG)(EthernetAddress[4]));
                   3028:         ErrorLogData[2] = 0xff - CheckSum;
                   3029: 
                   3030:         return FALSE;
                   3031: 
                   3032:     }
                   3033: 
                   3034:     return TRUE;
                   3035: 
                   3036: }
                   3037: 
                   3038: #endif  // SONIC_INTERNAL
                   3039: 
                   3040: 
                   3041: STATIC
                   3042: SONIC_HARDWARE_STATUS
                   3043: SonicHardwareGetDetails(
                   3044:     IN PSONIC_ADAPTER Adapter,
                   3045:     IN UINT SlotNumber,
                   3046:     IN UINT Controller,
                   3047:     IN UINT MultifunctionAdapter,
                   3048:     OUT PULONG InitialPort,
                   3049:     OUT PULONG NumberOfPorts,
                   3050:     IN OUT PUINT InterruptVector,
                   3051:     IN OUT PUINT InterruptLevel,
                   3052:     OUT ULONG ErrorLogData[3]
                   3053:     )
                   3054: 
                   3055: /*++
                   3056: 
                   3057: Routine Description:
                   3058: 
                   3059:     This routine gets the initial port and number of ports for
                   3060:     the Sonic. It also sets Adapter->PortShift. The ports are
                   3061:     numbered 0, 1, 2, etc. but may appear as 16- or 32-bit
                   3062:     ports, so PortShift will be 1 or 2 depending on how wide
                   3063:     the ports are.
                   3064: 
                   3065:     It also sets the value of Adapter->DataConfigurationRegister,
                   3066:     and may modify InterruptVector, InterruptLevel, and
                   3067:     Adapter->PermanentNetworkAddress.
                   3068: 
                   3069: Arguments:
                   3070: 
                   3071:     Adapter - The adapter in question.
                   3072: 
                   3073:     SlotNumber - For the EISA card this is the slot number that the
                   3074:         card is in.
                   3075: 
                   3076:     Controller - For the internal version, it is the
                   3077:         NetworkController number.
                   3078: 
                   3079:     MultifunctionAdapter - For the internal version, it is the adapter number.
                   3080: 
                   3081:     InitialPort - The base of the Sonic ports.
                   3082: 
                   3083:     NumberOfPorts - The number of bytes of ports to map.
                   3084: 
                   3085:     InterruptVector - A pointer to the interrupt vector. Depending
                   3086:         on the card type, this may be passed in or returned by
                   3087:         this function.
                   3088: 
                   3089:     InterruptLevel - A pointer to the interrupt level. Depending
                   3090:         on the card type, this may be passed in or returned by
                   3091:         this function.
                   3092: 
                   3093:     ErrorLogData - If the return status is SonicHardwareChecksum,
                   3094:         this returns 3 longwords to be included in the error log.
                   3095: 
                   3096: Return Value:
                   3097: 
                   3098:     SonicHardwareOk if successful, SonicHardwareChecksum if the
                   3099:     checksum is bad, SonicHardwareConfig for other problems.
                   3100: 
                   3101: --*/
                   3102: 
                   3103: {
                   3104: 
                   3105:     switch (Adapter->AdapterType) {
                   3106: 
                   3107: #ifdef SONIC_EISA
                   3108: 
                   3109:     case SONIC_ADAPTER_TYPE_EISA:
                   3110: 
                   3111:         *InitialPort = (SlotNumber << 12);
                   3112:         *NumberOfPorts = 0xD00;
                   3113:         Adapter->PortShift = 1;
                   3114:         Adapter->DataConfigurationRegister =
                   3115:             SONIC_DCR_PROGRAMMABLE_OUTPUT_1 |
                   3116:             SONIC_DCR_USER_DEFINABLE_1 |
                   3117:             SONIC_DCR_3_WAIT_STATE |
                   3118:             SONIC_DCR_BLOCK_MODE_DMA |
                   3119:             SONIC_DCR_32_BIT_DATA_WIDTH |
                   3120:             SONIC_DCR_8_WORD_RECEIVE_FIFO |
                   3121:             SONIC_DCR_8_WORD_TRANSMIT_FIFO;
                   3122: 
                   3123:         return SonicHardwareOk;
                   3124:         break;
                   3125: 
                   3126: #endif  // SONIC_EISA
                   3127: 
                   3128: #ifdef SONIC_INTERNAL
                   3129: 
                   3130:     case SONIC_ADAPTER_TYPE_INTERNAL:
                   3131:     {
                   3132: 
                   3133:         //
                   3134:         // For MIPS R4000 systems, we have to query the registry to obtain
                   3135:         // information about ports, interrupts, and the value to be
                   3136:         // stored in the DCR register.
                   3137:         //
                   3138: 
                   3139:         //
                   3140:         // NOTE: The following code is NT-specific, since that is
                   3141:         // currently the only system that runs on the MIPS R4000 hardware.
                   3142:         //
                   3143:         // We initialize an RTL_QUERY_TABLE to retrieve the Identifer
                   3144:         // and ConfigurationData strings from the registry.
                   3145:         //
                   3146: 
                   3147:         PWSTR ConfigDataPath = L"\\Registry\\Machine\\Hardware\\Description\\System\\MultifunctionAdapter\\#\\NetworkController\\#";
                   3148:         PWSTR IdentifierString = L"Identifier";
                   3149:         PWSTR ConfigDataString = L"Configuration Data";
                   3150:         RTL_QUERY_REGISTRY_TABLE QueryTable[4];
                   3151:         SONIC_HARDWARE_INFO SonicHardwareInfo;
                   3152:         NTSTATUS Status;
                   3153: 
                   3154: 
                   3155:         //
                   3156:         // Set up QueryTable to do the following:
                   3157:         //
                   3158: 
                   3159:         //
                   3160:         // 1) Call SonicSaveHardwareInformation for the "Identifier"
                   3161:         // value.
                   3162:         //
                   3163: 
                   3164:         QueryTable[0].QueryRoutine = SonicHardwareSaveInformation;
                   3165:         QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED;
                   3166:         QueryTable[0].Name = IdentifierString;
                   3167:         QueryTable[0].EntryContext = (PVOID)FALSE;
                   3168:         QueryTable[0].DefaultType = REG_NONE;
                   3169: 
                   3170:         //
                   3171:         // 2) Call SonicSaveHardwareInformation for the "Configuration Data"
                   3172:         // value.
                   3173:         //
                   3174: 
                   3175:         QueryTable[1].QueryRoutine = SonicHardwareSaveInformation;
                   3176:         QueryTable[1].Flags = RTL_QUERY_REGISTRY_REQUIRED;
                   3177:         QueryTable[1].Name = ConfigDataString;
                   3178:         QueryTable[1].EntryContext = (PVOID)TRUE;
                   3179:         QueryTable[1].DefaultType = REG_NONE;
                   3180: 
                   3181:         //
                   3182:         // 3) Stop
                   3183:         //
                   3184: 
                   3185:         QueryTable[2].QueryRoutine = NULL;
                   3186:         QueryTable[2].Flags = 0;
                   3187:         QueryTable[2].Name = NULL;
                   3188: 
                   3189: 
                   3190:         //
                   3191:         // Modify ConfigDataPath to replace the two # symbols with
                   3192:         // the MultifunctionAdapter number and NetworkController number.
                   3193:         //
                   3194: 
                   3195:         ConfigDataPath[67] = (WCHAR)('0' + MultifunctionAdapter);
                   3196:         ConfigDataPath[87] = (WCHAR)('0' + Controller);
                   3197: 
                   3198:         SonicHardwareInfo.DataValid = FALSE;
                   3199:         SonicHardwareInfo.AddressValid = FALSE;
                   3200:         SonicHardwareInfo.SonicIdentifier = FALSE;
                   3201: 
                   3202:         Status = RtlQueryRegistryValues(
                   3203:                      RTL_REGISTRY_ABSOLUTE,
                   3204:                      ConfigDataPath,
                   3205:                      QueryTable,
                   3206:                      (PVOID)&SonicHardwareInfo,
                   3207:                      NULL);
                   3208: 
                   3209:         if (!NT_SUCCESS(Status)) {
                   3210: #if DBG
                   3211:             DbgPrint ("SONIC: Could not read hardware information\n");
                   3212: #endif
                   3213:             return SonicHardwareConfig;
                   3214:         }
                   3215: 
                   3216:         if (SonicHardwareInfo.DataValid && SonicHardwareInfo.SonicIdentifier) {
                   3217: 
                   3218:             *InterruptVector = (UINT)SonicHardwareInfo.InterruptVector;
                   3219:             *InterruptLevel = (UINT)SonicHardwareInfo.InterruptLevel;
                   3220:             *InitialPort = SonicHardwareInfo.PortAddress.LowPart;
                   3221:             *NumberOfPorts = 192;
                   3222:             Adapter->PortShift = 2;
                   3223:             Adapter->DataConfigurationRegister =
                   3224:                 SonicHardwareInfo.DataConfigurationRegister;
                   3225: 
                   3226:             if (SonicHardwareInfo.AddressValid) {
                   3227: 
                   3228:                 if (!SonicHardwareVerifyChecksum(Adapter, SonicHardwareInfo.EthernetAddress, ErrorLogData)) {
                   3229: #if DBG
                   3230:                     DbgPrint("SONIC: Invalid registry network address checksum!!\n");
                   3231: #endif
                   3232:                     return SonicHardwareChecksum;
                   3233:                 }
                   3234: 
                   3235:                 SONIC_MOVE_MEMORY(
                   3236:                     Adapter->PermanentNetworkAddress,
                   3237:                     SonicHardwareInfo.EthernetAddress,
                   3238:                     8);
                   3239:                 Adapter->PermanentAddressValid = TRUE;
                   3240: 
                   3241:             }
                   3242: 
                   3243:             return SonicHardwareOk;
                   3244: 
                   3245:         } else {
                   3246: 
                   3247: #if DBG
                   3248:             DbgPrint ("SONIC: Incorrect registry hardware information\n");
                   3249: #endif
                   3250:             return SonicHardwareConfig;
                   3251: 
                   3252:         }
                   3253: 
                   3254:         break;
                   3255: 
                   3256:     }
                   3257: 
                   3258: #endif  // SONIC_INTERNAL
                   3259: 
                   3260:     default:
                   3261: 
                   3262:         ASSERT(FALSE);
                   3263:         break;
                   3264: 
                   3265:     }
                   3266: 
                   3267:     return SonicHardwareConfig;
                   3268: 
                   3269: }
                   3270: 
                   3271: 
                   3272: STATIC
                   3273: BOOLEAN
                   3274: SonicHardwareGetAddress(
                   3275:     IN PSONIC_ADAPTER Adapter,
                   3276:     IN ULONG ErrorLogData[3]
                   3277:     )
                   3278: 
                   3279: /*++
                   3280: 
                   3281: Routine Description:
                   3282: 
                   3283:     This routine gets the network address from the hardware.
                   3284: 
                   3285: Arguments:
                   3286: 
                   3287:     Adapter - Where to store the network address.
                   3288: 
                   3289:     ErrorLogData - If the checksum is bad, returns the address
                   3290:         and the checksum we expected.
                   3291: 
                   3292: Return Value:
                   3293: 
                   3294:     TRUE if successful.
                   3295: 
                   3296: --*/
                   3297: 
                   3298: {
                   3299: #define NVRAM_READ_ONLY_BASE 0x8000b000
                   3300: 
                   3301:     //
                   3302:     // Iteration variable.
                   3303:     //
                   3304:     UINT i;
                   3305: 
                   3306: 
                   3307:     switch (Adapter->AdapterType) {
                   3308: 
                   3309: #ifdef SONIC_EISA
                   3310: 
                   3311:     case SONIC_ADAPTER_TYPE_EISA:
                   3312: 
                   3313:         //
                   3314:         // The EISA card has the address stored at ports xC90 to xC95,
                   3315:         // where x is the slot number.
                   3316:         //
                   3317: 
                   3318:         for (i = 0; i < 6; i++) {
                   3319: 
                   3320:             NdisRawReadPortUchar(
                   3321:                 Adapter->SonicPortAddress + 0xc90 + i,
                   3322:                 &Adapter->PermanentNetworkAddress[i]);
                   3323: 
                   3324:         }
                   3325: 
                   3326:         break;
                   3327: 
                   3328: #endif  // SONIC_EISA
                   3329: 
                   3330: #ifdef SONIC_INTERNAL
                   3331: 
                   3332:     case SONIC_ADAPTER_TYPE_INTERNAL:
                   3333:     {
                   3334: 
                   3335:         NDIS_STATUS Status;
                   3336:         USHORT SiliconRevision;
                   3337: 
                   3338:         if (!Adapter->PermanentAddressValid) {
                   3339: 
                   3340:             //
                   3341:             // Physical addresses for call to NdisMapIoSpace.
                   3342:             //
                   3343: 
                   3344:             NDIS_PHYSICAL_ADDRESS NvRamPhysical =
                   3345:                                 NDIS_PHYSICAL_ADDRESS_CONST(NVRAM_READ_ONLY_BASE, 0);
                   3346: 
                   3347:             //
                   3348:             // Temporarily maps the NVRAM into our address space.
                   3349:             //
                   3350:             PVOID NvRamMapping;
                   3351: 
                   3352: 
                   3353: 
                   3354:             //
                   3355:             // If PermanentAddressValid is still FALSE then the address
                   3356:             // was not read by SonicHardwareGetDetails, so we must do it
                   3357:             // here.
                   3358:             //
                   3359: 
                   3360:             NdisMapIoSpace (
                   3361:                   &Status,
                   3362:                   &NvRamMapping,
                   3363:                   Adapter->NdisAdapterHandle,
                   3364:                   NvRamPhysical,
                   3365:                   8
                   3366:                   );
                   3367: 
                   3368:             if (Status != NDIS_STATUS_SUCCESS) {
                   3369: 
                   3370:                 NdisWriteErrorLogEntry(
                   3371:                     Adapter->NdisAdapterHandle,
                   3372:                     NDIS_ERROR_CODE_RESOURCE_CONFLICT,
                   3373:                     0
                   3374:                     );
                   3375: 
                   3376:                 return(FALSE);
                   3377: 
                   3378:             }
                   3379: 
                   3380:             //
                   3381:             // Verify that the checksum matches.
                   3382:             //
                   3383: 
                   3384:             if (!SonicHardwareVerifyChecksum(Adapter, (PUCHAR)NvRamMapping, ErrorLogData)) {
                   3385: 
                   3386: #if DBG
                   3387:                 DbgPrint("SONIC: Invalid NVRAM network address checksum!!\n");
                   3388: #endif
                   3389:                 NdisUnmapIoSpace(Adapter->NdisAdapterHandle, NvRamMapping, 8);
                   3390:                 return FALSE;
                   3391: 
                   3392:             }
                   3393: 
                   3394:             //
                   3395:             // Checksum is OK, save the address.
                   3396:             //
                   3397: 
                   3398:             for (i=0; i<6; i++) {
                   3399:                 Adapter->PermanentNetworkAddress[i] = *((PUCHAR)NvRamMapping+i);
                   3400:             }
                   3401:             Adapter->PermanentAddressValid = TRUE;
                   3402: 
                   3403:             NdisUnmapIoSpace(Adapter->NdisAdapterHandle, NvRamMapping, 8);
                   3404: 
                   3405:         }
                   3406: 
                   3407:         //
                   3408:         // The Data Configuration Register is already set up, but we
                   3409:         // change the FIFO initialization for old revisions.
                   3410:         //
                   3411: 
                   3412:         SONIC_READ_PORT(Adapter, SONIC_SILICON_REVISION, &SiliconRevision);
                   3413: 
                   3414:         if (SiliconRevision < 4) {
                   3415: 
                   3416:             Adapter->DataConfigurationRegister =
                   3417:                 (Adapter->DataConfigurationRegister & SONIC_DCR_FIFO_MASK) |
                   3418:                 SONIC_DCR_8_WORD_RECEIVE_FIFO |
                   3419:                 SONIC_DCR_8_WORD_TRANSMIT_FIFO;
                   3420: 
                   3421:         }
                   3422: 
                   3423:         break;
                   3424: 
                   3425:     }
                   3426: 
                   3427: #endif  // SONIC_INTERNAL
                   3428: 
                   3429:     default:
                   3430: 
                   3431:         ASSERT(FALSE);
                   3432:         break;
                   3433: 
                   3434:     }
                   3435: 
                   3436: 
                   3437: #if DBG
                   3438:     if (SonicDbg) {
                   3439:         DbgPrint("SONIC: ");
                   3440:         DbgPrint("[ %x-%x-%x-%x-%x-%x ]\n",
                   3441:             (UCHAR)Adapter->PermanentNetworkAddress[0],
                   3442:             (UCHAR)Adapter->PermanentNetworkAddress[1],
                   3443:             (UCHAR)Adapter->PermanentNetworkAddress[2],
                   3444:             (UCHAR)Adapter->PermanentNetworkAddress[3],
                   3445:             (UCHAR)Adapter->PermanentNetworkAddress[4],
                   3446:             (UCHAR)Adapter->PermanentNetworkAddress[5]);
                   3447:         DbgPrint("\n");
                   3448:     }
                   3449: #endif
                   3450: 
                   3451:     return TRUE;
                   3452: 
                   3453: }
                   3454: 
                   3455: 
                   3456: VOID
                   3457: SonicShutdown(
                   3458:     IN PVOID ShutdownContext
                   3459:     )
                   3460: 
                   3461: /*++
                   3462: 
                   3463: Routine Description:
                   3464: 
                   3465:     Turns off the card during a powerdown of the system.
                   3466: 
                   3467: Arguments:
                   3468: 
                   3469:     ShutdownContext - Really a pointer to the adapter structure.
                   3470: 
                   3471: Return Value:
                   3472: 
                   3473:     None.
                   3474: 
                   3475: --*/
                   3476: 
                   3477: {
                   3478:     PSONIC_ADAPTER Adapter = (PSONIC_ADAPTER)(ShutdownContext);
                   3479: 
                   3480:     NdisAcquireSpinLock(&Adapter->Lock);
                   3481: 
                   3482:     //
                   3483:     // Set the flag
                   3484:     //
                   3485: 
                   3486:     Adapter->Removed = TRUE;
                   3487: 
                   3488:     //
                   3489:     // Shut down the chip.  We won't be doing any more work until
                   3490:     // the reset is complete.
                   3491:     //
                   3492: 
                   3493:     SonicStopChip(Adapter);
                   3494: 
                   3495:     NdisStallExecution(250000);
                   3496: 
                   3497:     NdisReleaseSpinLock(&Adapter->Lock);
                   3498: 
                   3499: }

unix.superglobalmegacorp.com

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