Annotation of q_a/samples/ddk/detect/detlance.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1992  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     detlance.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This is the main file for the autodetection DLL for all the lance.sys
                     12:     which MS is shipping with Windows NT.
                     13: 
                     14: 
                     15: --*/
                     16: 
                     17: #include <ntddk.h>
                     18: #include <ntddnetd.h>
                     19: 
                     20: #include <windef.h>
                     21: #include <winerror.h>
                     22: 
                     23: #include <stdio.h>
                     24: #include <stdlib.h>
                     25: #include <string.h>
                     26: #include "detect.h"
                     27: 
                     28: //  Prototype "borrowed" from WINUSER.H
                     29: extern int WINAPIV wsprintfW(LPWSTR, LPCWSTR, ...);
                     30: //  Prototype "borrowed" from WINBASE.H
                     31: VOID WINAPI Sleep( DWORD dwMilliseconds );
                     32: 
                     33: 
                     34: //
                     35: // Individual card detection routines
                     36: //
                     37: 
                     38: LONG
                     39: De100FirstNext(
                     40:     IN  LONG NetcardId,
                     41:     IN  INTERFACE_TYPE InterfaceType,
                     42:     IN  ULONG BusNumber,
                     43:     IN  BOOL First,
                     44:     OUT PVOID *Token,
                     45:     OUT LONG *Confidence
                     46:     );
                     47: 
                     48: 
                     49: LONG
                     50: De200FirstNext(
                     51:     IN  LONG NetcardId,
                     52:     IN  INTERFACE_TYPE InterfaceType,
                     53:     IN  ULONG BusNumber,
                     54:     IN  BOOL First,
                     55:     OUT PVOID *Token,
                     56:     OUT LONG *Confidence
                     57:     );
                     58: 
                     59: LONG
                     60: De201FirstNext(
                     61:     IN  LONG NetcardId,
                     62:     IN  INTERFACE_TYPE InterfaceType,
                     63:     IN  ULONG BusNumber,
                     64:     IN  BOOL First,
                     65:     OUT PVOID *Token,
                     66:     OUT LONG *Confidence
                     67:     );
                     68: 
                     69: LONG
                     70: De101FirstNext(
                     71:     IN  LONG NetcardId,
                     72:     IN  INTERFACE_TYPE InterfaceType,
                     73:     IN  ULONG BusNumber,
                     74:     IN  BOOL First,
                     75:     OUT PVOID *Token,
                     76:     OUT LONG *Confidence
                     77:     );
                     78: 
                     79: LONG
                     80: DePCAFirstNext(
                     81:     IN  LONG NetcardId,
                     82:     IN  INTERFACE_TYPE InterfaceType,
                     83:     IN  ULONG BusNumber,
                     84:     IN  BOOL First,
                     85:     OUT PVOID *Token,
                     86:     OUT LONG *Confidence
                     87:     );
                     88: 
                     89: 
                     90: #ifdef WORKAROUND
                     91: 
                     92: UCHAR LanceFirstTime = 1;
                     93: 
                     94: //
                     95: // List of all the adapters supported in this file, this cannot be > 256
                     96: // because of the way tokens are generated.
                     97: //
                     98: //
                     99: // NOTE : If you change the index of an adapter, be sure the change it in
                    100: // LanceQueryCfgHandler() and LanceVerifyCfgHandler() as well!
                    101: //
                    102: 
                    103: static ADAPTER_INFO Adapters[] = {
                    104: 
                    105:     {
                    106:         1000,
                    107:         L"DEC100",
                    108:         L"IRQ 1 90 IRQTYPE 2 100 IOADDR 1 100 IOADDRLENGTH 2 100 MEMADDR 1 75 MEMADDRLENGTH 2 0 100 ",
                    109:         De100FirstNext,
                    110:         700
                    111: 
                    112:     },
                    113: 
                    114:     {
                    115:         1100,
                    116:         L"DEC200",
                    117:         L"IRQ 1 90 IRQTYPE 2 100 IOADDR 1 100 IOADDRLENGTH 2 100 MEMADDR 1 75 MEMADDRLENGTH 2 0 100 ",
                    118:         De200FirstNext,
                    119:         700
                    120: 
                    121:     },
                    122: 
                    123:     {
                    124:         1200,
                    125:         L"DEC201",
                    126:         L"IRQ 1 90 IRQTYPE 2 100 IOADDR 1 100 IOADDRLENGTH 2 100 MEMADDR 1 75 MEMADDRLENGTH 2 0 100 ",
                    127:         De201FirstNext,
                    128:         700
                    129: 
                    130:     },
                    131: 
                    132:     {
                    133:         1300,
                    134:         L"DEC101",
                    135:         L"IRQ 1 90 IRQTYPE 2 100 IOADDR 1 100 IOADDRLENGTH 2 100 MEMADDR 1 75 MEMADDRLENGTH 2 0 100 ",
                    136:         De101FirstNext,
                    137:         700
                    138: 
                    139:     },
                    140: 
                    141:     {
                    142:         1400,
                    143:         L"DECPC",
                    144:         L"\0",
                    145:         DePCAFirstNext,
                    146:         701
                    147: 
                    148:     }
                    149: 
                    150: };
                    151: 
                    152: #else
                    153: 
                    154: 
                    155: //
                    156: // List of all the adapters supported in this file, this cannot be > 256
                    157: // because of the way tokens are generated.
                    158: //
                    159: //
                    160: // NOTE : If you change the index of an adapter, be sure the change it in
                    161: // LanceQueryCfgHandler() and LanceVerifyCfgHandler() as well!
                    162: //
                    163: 
                    164: static ADAPTER_INFO Adapters[] = {
                    165: 
                    166:     {
                    167:         1000,
                    168:         L"DEC100",
                    169:         L"IRQ\0001\00090\0IRQTYPE\0002\000100\0IOADDR\0001\000100\0IOADDRLENGTH\0002\000100\0MEMADDR\0001\00075\0MEMADDRLENGTH\0002\000100",
                    170:         De100FirstNext,
                    171:         700
                    172: 
                    173:     },
                    174: 
                    175:     {
                    176:         1100,
                    177:         L"DEC200",
                    178:         L"IRQ\0001\00090\0IRQTYPE\0002\000100\0IOADDR\0001\000100\0IOADDRLENGTH\0002\000100\0MEMADDR\0001\00075\0MEMADDRLENGTH\0002\000100",
                    179:         De200FirstNext,
                    180:         700
                    181: 
                    182:     },
                    183: 
                    184:     {
                    185:         1200,
                    186:         L"DEC201",
                    187:         L"IRQ\0001\00090\0IRQTYPE\0002\000100\0IOADDR\0001\000100\0IOADDRLENGTH\0002\000100\0MEMADDR\0001\00075\0MEMADDRLENGTH\0002\000100",
                    188:         De201FirstNext,
                    189:         700
                    190: 
                    191:     },
                    192: 
                    193:     {
                    194:         1300,
                    195:         L"DEC101",
                    196:         L"IRQ\0001\00090\0IRQTYPE\0002\000100\0IOADDR\0001\000100\0IOADDRLENGTH\0002\000100\0MEMADDR\0001\00075\0MEMADDRLENGTH\0002\000100",
                    197:         De101FirstNext,
                    198:         700
                    199: 
                    200:     },
                    201: 
                    202:     {
                    203:         1400,
                    204:         L"DECPC",
                    205:         L"\0",
                    206:         DePCAFirstNext,
                    207:         701
                    208: 
                    209:     }
                    210: 
                    211: };
                    212: 
                    213: #endif
                    214: 
                    215: //
                    216: // Structure for holding state of a search
                    217: //
                    218: 
                    219: typedef struct _SEARCH_STATE {
                    220: 
                    221:     PUCHAR MemoryAddress;
                    222: 
                    223: } SEARCH_STATE, *PSEARCH_STATE;
                    224: 
                    225: 
                    226: //
                    227: // This is an array of search states.  We need one state for each type
                    228: // of adapter supported.
                    229: //
                    230: 
                    231: static SEARCH_STATE SearchStates[sizeof(Adapters) / sizeof(ADAPTER_INFO)] = {0};
                    232: 
                    233: static UCHAR CopyrightString[] = "COPYRIGHT DIGITAL EQUIPMENT";
                    234: #define LENGTH_OF_COPYRIGHT 30
                    235: 
                    236: 
                    237: //
                    238: // Structure for holding a particular adapter's complete information
                    239: //
                    240: typedef struct _LANCE_ADAPTER {
                    241: 
                    242:     LONG CardType;
                    243:     INTERFACE_TYPE InterfaceType;
                    244:     ULONG BusNumber;
                    245:     PUCHAR MemoryMappedBaseAddress;
                    246: 
                    247: } LANCE_ADAPTER, *PLANCE_ADAPTER;
                    248: 
                    249: 
                    250: //
                    251: // Constant strings for parameters
                    252: //
                    253: 
                    254: static CHAR De100String[] = "DE100";
                    255: static CHAR De200String[] = "DE200";
                    256: static CHAR De201String[] = "DE201";
                    257: static CHAR De101String[] = "DE101";
                    258: 
                    259: 
                    260: 
                    261: BOOLEAN
                    262: LanceHardwareDetails(
                    263:     IN INTERFACE_TYPE InterfaceType,
                    264:     IN ULONG BusNumber,
                    265:     IN ULONG IoBaseAddress
                    266:     );
                    267: 
                    268: BOOLEAN
                    269: DecCardAt(
                    270:     IN INTERFACE_TYPE InterfaceType,
                    271:     IN ULONG BusNumber,
                    272:     IN ULONG MemoryAddress,
                    273:     IN CHAR *DectectString
                    274:     );
                    275: 
                    276: 
                    277: 
                    278: 
                    279: extern
                    280: LONG
                    281: LanceIdentifyHandler(
                    282:     IN LONG Index,
                    283:     IN WCHAR * Buffer,
                    284:     IN LONG BuffSize
                    285:     )
                    286: 
                    287: /*++
                    288: 
                    289: Routine Description:
                    290: 
                    291:     This routine returns information about the netcards supported by
                    292:     this file.
                    293: 
                    294: Arguments:
                    295: 
                    296:     Index -  The index of the netcard being address.  The first
                    297:     cards information is at index 1000, the second at 1100, etc.
                    298: 
                    299:     Buffer - Buffer to store the result into.
                    300: 
                    301:     BuffSize - Number of bytes in Buffer
                    302: 
                    303: Return Value:
                    304: 
                    305:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    306: 
                    307: --*/
                    308: 
                    309: 
                    310: {
                    311:     LONG NumberOfAdapters;
                    312:     LONG Code = Index % 100;
                    313:     LONG Length;
                    314:     LONG i;
                    315: 
                    316: 
                    317:     NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
                    318: 
                    319: #ifdef WORKAROUND
                    320: 
                    321:     if (LanceFirstTime) {
                    322: 
                    323:         LanceFirstTime = 0;
                    324: 
                    325:         for (i = 0; i < NumberOfAdapters; i++) {
                    326: 
                    327:             Length = UnicodeStrLen(Adapters[i].Parameters);
                    328: 
                    329:             for (; Length > 0; Length--) {
                    330: 
                    331:                 if (Adapters[i].Parameters[Length] == L' ') {
                    332: 
                    333:                     Adapters[i].Parameters[Length] = UNICODE_NULL;
                    334: 
                    335:                 }
                    336: 
                    337:             }
                    338: 
                    339:         }
                    340: 
                    341:     }
                    342: #endif
                    343: 
                    344:     Index = Index - Code;
                    345: 
                    346:     if (((Index / 100) - 10) < NumberOfAdapters) {
                    347: 
                    348:         //
                    349:         // Find the adapter
                    350:         //
                    351: 
                    352:         for (i=0; i < NumberOfAdapters; i++) {
                    353: 
                    354:             if (Adapters[i].Index == Index) {
                    355: 
                    356:                 switch (Code) {
                    357: 
                    358:                     case 0:
                    359: 
                    360:                         //
                    361:                         // Find the string length
                    362:                         //
                    363: 
                    364:                         Length = UnicodeStrLen(Adapters[i].InfId);
                    365: 
                    366:                         Length ++;
                    367: 
                    368:                         if (BuffSize < Length) {
                    369: 
                    370:                             return(ERROR_INSUFFICIENT_BUFFER);
                    371: 
                    372:                         }
                    373: 
                    374:                         memcpy((PVOID)Buffer, Adapters[i].InfId, Length * sizeof(WCHAR));
                    375:                         break;
                    376: 
                    377:                     case 3:
                    378: 
                    379:                         //
                    380:                         // Maximum value is 1000
                    381:                         //
                    382: 
                    383:                         if (BuffSize < 5) {
                    384: 
                    385:                             return(ERROR_INSUFFICIENT_BUFFER);
                    386: 
                    387:                         }
                    388: 
                    389:                         wsprintfW((PVOID)Buffer, L"%d", Adapters[i].SearchOrder);
                    390: 
                    391:                         break;
                    392: 
                    393:                     default:
                    394: 
                    395:                         return(ERROR_INVALID_PARAMETER);
                    396: 
                    397:                 }
                    398: 
                    399:                 return(0);
                    400: 
                    401:             }
                    402: 
                    403:         }
                    404: 
                    405:         return(ERROR_INVALID_PARAMETER);
                    406: 
                    407:     }
                    408: 
                    409:     return(ERROR_NO_MORE_ITEMS);
                    410: 
                    411: }
                    412: 
                    413: 
                    414: extern
                    415: LONG LanceFirstNextHandler(
                    416:     IN  LONG NetcardId,
                    417:     IN  INTERFACE_TYPE InterfaceType,
                    418:     IN  ULONG BusNumber,
                    419:     IN  BOOL First,
                    420:     OUT PVOID *Token,
                    421:     OUT LONG *Confidence
                    422:     )
                    423: 
                    424: /*++
                    425: 
                    426: Routine Description:
                    427: 
                    428:     This routine finds the instances of a physical adapter identified
                    429:     by the NetcardId.
                    430: 
                    431: Arguments:
                    432: 
                    433:     NetcardId -  The index of the netcard being address.  The first
                    434:     cards information is id 1000, the second id 1100, etc.
                    435: 
                    436:     InterfaceType - Either Isa, or Eisa.
                    437: 
                    438:     BusNumber - The bus number of the bus to search.
                    439: 
                    440:     First - TRUE is we are to search for the first instance of an
                    441:     adapter, FALSE if we are to continue search from a previous stopping
                    442:     point.
                    443: 
                    444:     Token - A pointer to a handle to return to identify the found
                    445:     instance
                    446: 
                    447:     Confidence - A pointer to a long for storing the confidence factor
                    448:     that the card exists.
                    449: 
                    450: Return Value:
                    451: 
                    452:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    453: 
                    454: --*/
                    455: 
                    456: {
                    457:     LONG ReturnValue;
                    458:     LONG NumberOfAdapters;
                    459:     LONG i;
                    460: 
                    461:     if ((InterfaceType != Isa) &&
                    462:         (InterfaceType != Eisa)) {
                    463: 
                    464:         *Confidence = 0;
                    465: 
                    466:         return(0);
                    467: 
                    468:     }
                    469: 
                    470:     NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
                    471: 
                    472:     for (i=0; i < NumberOfAdapters; i++) {
                    473: 
                    474:         if (Adapters[i].Index == NetcardId) {
                    475: 
                    476:             //
                    477:             // Call FindFirst Routine
                    478:             //
                    479: 
                    480:             ReturnValue = (*(Adapters[i].FirstNext))(
                    481:                                 i,
                    482:                                 InterfaceType,
                    483:                                 BusNumber,
                    484:                                 First,
                    485:                                 0,
                    486:                                 Confidence
                    487:                                 );
                    488: 
                    489:             if (ReturnValue == 0) {
                    490: 
                    491:                 //
                    492:                 // In this module I use the token as follows: Remember that
                    493:                 // the token can only be 2 bytes long (the low 2) because of
                    494:                 // the interface to the upper part of this DLL.
                    495:                 //
                    496:                 //  The high bit of the short is boolean for ISA (else, EISA).
                    497:                 //  The rest of the high byte is the the bus number.
                    498:                 //  The low byte is the driver index number into Adapters.
                    499:                 //
                    500:                 // NOTE: This presumes that there are < 129 buses in the
                    501:                 // system. Is this reasonable?
                    502:                 //
                    503: 
                    504:                 if (InterfaceType == Isa) {
                    505: 
                    506:                     *Token = (PVOID)0x8000;
                    507: 
                    508:                 } else {
                    509: 
                    510:                     *Token = (PVOID)0x0;
                    511:                 }
                    512: 
                    513:                 *Token = (PVOID)(((ULONG)*Token) | ((BusNumber & 0x7F) << 8));
                    514: 
                    515:                 *Token = (PVOID)(((ULONG)*Token) | i);
                    516: 
                    517:             }
                    518: 
                    519:             return(ReturnValue);
                    520: 
                    521:         }
                    522: 
                    523:     }
                    524: 
                    525:     return(ERROR_INVALID_PARAMETER);
                    526: }
                    527: 
                    528: extern
                    529: LONG
                    530: LanceOpenHandleHandler(
                    531:     IN  PVOID Token,
                    532:     OUT PVOID *Handle
                    533:     )
                    534: 
                    535: /*++
                    536: 
                    537: Routine Description:
                    538: 
                    539:     This routine takes a token returned by FirstNext and converts it
                    540:     into a permanent handle.
                    541: 
                    542: Arguments:
                    543: 
                    544:     Token - The token.
                    545: 
                    546:     Handle - A pointer to the handle, so we can store the resulting
                    547:     handle.
                    548: 
                    549: Return Value:
                    550: 
                    551:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    552: 
                    553: --*/
                    554: 
                    555: {
                    556:     PLANCE_ADAPTER Adapter;
                    557:     LONG AdapterNumber;
                    558:     ULONG BusNumber;
                    559:     INTERFACE_TYPE InterfaceType;
                    560: 
                    561:     //
                    562:     // Get info from the token
                    563:     //
                    564: 
                    565:     if (((ULONG)Token) & 0x8000) {
                    566: 
                    567:         InterfaceType = Isa;
                    568: 
                    569:     } else {
                    570: 
                    571:         InterfaceType = Eisa;
                    572: 
                    573:     }
                    574: 
                    575:     BusNumber = (ULONG)(((ULONG)Token >> 8) & 0x7F);
                    576: 
                    577:     AdapterNumber = ((ULONG)Token) & 0xFF;
                    578: 
                    579:     //
                    580:     // Store information
                    581:     //
                    582: 
                    583:     Adapter = (PLANCE_ADAPTER)DetectAllocateHeap(
                    584:                                  sizeof(LANCE_ADAPTER)
                    585:                                  );
                    586: 
                    587:     if (Adapter == NULL) {
                    588: 
                    589:         return(ERROR_NOT_ENOUGH_MEMORY);
                    590: 
                    591:     }
                    592: 
                    593:     //
                    594:     // Copy across memory address
                    595:     //
                    596: 
                    597:     Adapter->MemoryMappedBaseAddress = SearchStates[(ULONG)AdapterNumber].MemoryAddress -
                    598:                                       0x10000;
                    599:     Adapter->CardType = Adapters[AdapterNumber].Index;
                    600:     Adapter->InterfaceType = InterfaceType;
                    601:     Adapter->BusNumber = BusNumber;
                    602: 
                    603:     *Handle = (PVOID)Adapter;
                    604: 
                    605:     return(0);
                    606: }
                    607: 
                    608: extern
                    609: LONG LanceCreateHandleHandler(
                    610:     IN  LONG NetcardId,
                    611:     IN  INTERFACE_TYPE InterfaceType,
                    612:     IN  ULONG BusNumber,
                    613:     OUT PVOID *Handle
                    614:     )
                    615: 
                    616: /*++
                    617: 
                    618: Routine Description:
                    619: 
                    620:     This routine is used to force the creation of a handle for cases
                    621:     where a card is not found via FirstNext, but the user says it does
                    622:     exist.
                    623: 
                    624: Arguments:
                    625: 
                    626:     NetcardId - The id of the card to create the handle for.
                    627: 
                    628:     InterfaceType - Isa or Eisa.
                    629: 
                    630:     BusNumber - The bus number of the bus in the system.
                    631: 
                    632:     Handle - A pointer to the handle, for storing the resulting handle.
                    633: 
                    634: Return Value:
                    635: 
                    636:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    637: 
                    638: --*/
                    639: 
                    640: {
                    641:     PLANCE_ADAPTER Adapter;
                    642:     LONG NumberOfAdapters;
                    643:     LONG i;
                    644: 
                    645:     if ((InterfaceType != Isa) &&
                    646:         (InterfaceType != Eisa)) {
                    647: 
                    648:         return(ERROR_INVALID_PARAMETER);
                    649: 
                    650:     }
                    651: 
                    652:     NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
                    653: 
                    654:     for (i=0; i < NumberOfAdapters; i++) {
                    655: 
                    656:         if (Adapters[i].Index == NetcardId) {
                    657: 
                    658:             //
                    659:             // Store information
                    660:             //
                    661: 
                    662:             Adapter = (PLANCE_ADAPTER)DetectAllocateHeap(
                    663:                                          sizeof(LANCE_ADAPTER)
                    664:                                          );
                    665: 
                    666:             if (Adapter == NULL) {
                    667: 
                    668:                 return(ERROR_NOT_ENOUGH_MEMORY);
                    669: 
                    670:             }
                    671: 
                    672:             //
                    673:             // Copy across memory address
                    674:             //
                    675: 
                    676:             Adapter->MemoryMappedBaseAddress = SearchStates[i].MemoryAddress;
                    677:             Adapter->CardType = NetcardId;
                    678:             Adapter->InterfaceType = InterfaceType;
                    679:             Adapter->BusNumber = BusNumber;
                    680: 
                    681:             *Handle = (PVOID)Adapter;
                    682: 
                    683:             return(0);
                    684: 
                    685:         }
                    686: 
                    687:     }
                    688: 
                    689:     return(ERROR_INVALID_PARAMETER);
                    690: }
                    691: 
                    692: extern
                    693: LONG
                    694: LanceCloseHandleHandler(
                    695:     IN PVOID Handle
                    696:     )
                    697: 
                    698: /*++
                    699: 
                    700: Routine Description:
                    701: 
                    702:     This frees any resources associated with a handle.
                    703: 
                    704: Arguments:
                    705: 
                    706:    Handle - The handle.
                    707: 
                    708: Return Value:
                    709: 
                    710:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    711: 
                    712: --*/
                    713: 
                    714: {
                    715:     DetectFreeHeap(Handle);
                    716: 
                    717:     return(0);
                    718: }
                    719: 
                    720: LONG
                    721: LanceQueryCfgHandler(
                    722:     IN  PVOID Handle,
                    723:     OUT WCHAR *Buffer,
                    724:     IN  LONG BuffSize
                    725:     )
                    726: 
                    727: /*++
                    728: 
                    729: Routine Description:
                    730: 
                    731:     This routine calls the appropriate driver's query config handler to
                    732:     get the parameters for the adapter associated with the handle.
                    733: 
                    734: Arguments:
                    735: 
                    736:     Handle - The handle.
                    737: 
                    738:     Buffer - The resulting parameter list.
                    739: 
                    740:     BuffSize - Length of the given buffer in WCHARs.
                    741: 
                    742: Return Value:
                    743: 
                    744:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                    745: 
                    746: --*/
                    747: 
                    748: {
                    749:     PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)(Handle);
                    750:     NTSTATUS NtStatus;
                    751:     HANDLE TrapHandle;
                    752:     BOOLEAN FoundIo = FALSE;
                    753:     BOOLEAN FoundInterrupt = FALSE;
                    754:     UCHAR i;
                    755:     UCHAR InterruptList[5];
                    756:     UCHAR ResultList[5];
                    757:     ULONG InterruptListLength = 0;
                    758:     ULONG IoBaseAddress = 0;
                    759:     UCHAR InterruptNumber = 0;
                    760:     LONG OutputLengthLeft = BuffSize;
                    761:     LONG CopyLength;
                    762:     USHORT Value;
                    763: 
                    764:     ULONG StartPointer = (ULONG)Buffer;
                    765: 
                    766:     if ((Adapter->InterfaceType != Isa) &&
                    767:         (Adapter->InterfaceType != Eisa)) {
                    768: 
                    769:         return(ERROR_INVALID_PARAMETER);
                    770: 
                    771:     }
                    772: 
                    773:     if (Adapter->CardType == 1400) {
                    774: 
                    775:         //
                    776:         // The DePCA has no parameters
                    777:         //
                    778: 
                    779:         if (BuffSize > 0) {
                    780: 
                    781:             *Buffer = L'\0';
                    782:             return(0);
                    783: 
                    784:         } else {
                    785: 
                    786:             return(ERROR_INSUFFICIENT_BUFFER);
                    787: 
                    788:         }
                    789: 
                    790:     }
                    791: 
                    792:     //
                    793:     // Get the IoBaseAddress
                    794:     //
                    795: 
                    796:     switch(Adapter->CardType) {
                    797: 
                    798:         //
                    799:         // De100
                    800:         // De200
                    801:         // De201
                    802:         // De101
                    803:         //
                    804:         case 1000:
                    805:         case 1100:
                    806:         case 1200:
                    807:         case 1300:
                    808: 
                    809:             if (DetectCheckPortUsage(Adapter->InterfaceType,
                    810:                                      Adapter->BusNumber,
                    811:                                      0x200,
                    812:                                      0x10
                    813:                                     ) == STATUS_SUCCESS) {
                    814: 
                    815:                 if (!LanceHardwareDetails(Adapter->InterfaceType,
                    816:                                           Adapter->BusNumber,
                    817:                                           0x20C)) {
                    818: 
                    819:                     if ((DetectCheckPortUsage(Adapter->InterfaceType,
                    820:                                               Adapter->BusNumber,
                    821:                                               0x300,
                    822:                                               0x10
                    823:                                              ) == STATUS_SUCCESS)
                    824:                          &&
                    825:                          (LanceHardwareDetails(Adapter->InterfaceType,
                    826:                                                Adapter->BusNumber,
                    827:                                                0x30C))) {
                    828: 
                    829:                         IoBaseAddress = (ULONG)0x300;
                    830: 
                    831:                         FoundIo = TRUE;
                    832: 
                    833:                     }
                    834: 
                    835:                 } else {
                    836: 
                    837:                     IoBaseAddress = (ULONG)0x200;
                    838: 
                    839:                     FoundIo = TRUE;
                    840: 
                    841:                 }
                    842: 
                    843:             }
                    844: 
                    845:             break;
                    846: 
                    847:         default:
                    848: 
                    849:             return(ERROR_INVALID_PARAMETER);
                    850: 
                    851:     }
                    852: 
                    853:     if (FoundIo == FALSE) {
                    854: 
                    855:         goto BuildBuffer;
                    856:     }
                    857: 
                    858:     //
                    859:     // Get the rest of the memory info.
                    860:     // Guess that it is 64K aligned
                    861:     //
                    862:     Adapter->MemoryMappedBaseAddress = (PUCHAR)((ULONG)(Adapter->MemoryMappedBaseAddress) &
                    863:                                       0xF0000);
                    864: 
                    865:     //
                    866:     // Read amount of memory
                    867:     //
                    868: 
                    869:     NtStatus = DetectReadPortUshort(
                    870:                                Adapter->InterfaceType,
                    871:                                Adapter->BusNumber,
                    872:                                IoBaseAddress,
                    873:                                &Value
                    874:                                );
                    875: 
                    876:     if (NtStatus != STATUS_SUCCESS) {
                    877: 
                    878:         goto BuildBuffer;
                    879: 
                    880:     }
                    881: 
                    882:     if (Value & 0x20) {
                    883: 
                    884:         //
                    885:         // Definitely in 32K mode.
                    886:         //
                    887: 
                    888:         Adapter->MemoryMappedBaseAddress = (PUCHAR)((ULONG)Adapter->MemoryMappedBaseAddress |
                    889:                                            0x8000);
                    890:     }
                    891: 
                    892: 
                    893: 
                    894:     //
                    895:     // Get the interrupt number
                    896:     //
                    897: 
                    898:     switch(Adapter->CardType) {
                    899: 
                    900:         //
                    901:         // De100
                    902:         // De101
                    903:         //
                    904:         case 1000:
                    905:         case 1300:
                    906: 
                    907:             InterruptList[0] = 2;
                    908:             InterruptList[1] = 3;
                    909:             InterruptList[2] = 4;
                    910:             InterruptList[3] = 5;
                    911:             InterruptList[4] = 7;
                    912:             InterruptListLength = 5;
                    913:             break;
                    914: 
                    915:         //
                    916:         // De200
                    917:         //
                    918: 
                    919:         case 1100:
                    920: 
                    921:             InterruptList[0] = 5;
                    922:             InterruptList[1] = 9;
                    923:             InterruptList[2] = 10;
                    924:             InterruptList[3] = 11;
                    925:             InterruptList[4] = 15;
                    926:             InterruptListLength = 5;
                    927:             break;
                    928: 
                    929:         //
                    930:         // De201
                    931:         //
                    932: 
                    933:         case 1200:
                    934: 
                    935:             InterruptList[0] = 5;
                    936:             InterruptList[1] = 9;
                    937:             InterruptList[2] = 10;
                    938:             InterruptList[3] = 11;
                    939:             InterruptList[4] = 12;
                    940:             InterruptListLength = 5;
                    941:             break;
                    942: 
                    943:         default:
                    944: 
                    945:             return(ERROR_INVALID_PARAMETER);
                    946: 
                    947:     }
                    948: 
                    949:     //
                    950:     // Set the interrupt trap
                    951:     //
                    952: 
                    953:     NtStatus = DetectSetInterruptTrap(
                    954:                    Adapter->InterfaceType,
                    955:                    Adapter->BusNumber,
                    956:                    &TrapHandle,
                    957:                    InterruptList,
                    958:                    InterruptListLength
                    959:                    );
                    960: 
                    961:     if (NtStatus == STATUS_SUCCESS) {
                    962: 
                    963:         //
                    964:         // Create an interrupt
                    965:         //
                    966: 
                    967:         switch (Adapter->CardType) {
                    968: 
                    969:             //
                    970:             // De100
                    971:             // De200
                    972:             // De201
                    973:             // De101
                    974:             //
                    975:             case 1000:
                    976:             case 1100:
                    977:             case 1200:
                    978:             case 1300:
                    979: 
                    980:                 //
                    981:                 // Change to CSR0
                    982:                 //
                    983: 
                    984:                 NtStatus = DetectWritePortUshort(
                    985:                                Adapter->InterfaceType,
                    986:                                Adapter->BusNumber,
                    987:                                IoBaseAddress + 0x6,
                    988:                                0x0
                    989:                                );
                    990: 
                    991:                 if (NtStatus != STATUS_SUCCESS) {
                    992: 
                    993:                     goto BuildBuffer;
                    994: 
                    995:                 }
                    996: 
                    997:                 //
                    998:                 // Write STOP bit
                    999:                 //
                   1000: 
                   1001:                 NtStatus = DetectWritePortUshort(
                   1002:                                Adapter->InterfaceType,
                   1003:                                Adapter->BusNumber,
                   1004:                                IoBaseAddress + 0x4,
                   1005:                                0x4
                   1006:                                );
                   1007: 
                   1008:                 if (NtStatus != STATUS_SUCCESS) {
                   1009: 
                   1010:                     goto BuildBuffer;
                   1011: 
                   1012:                 }
                   1013: 
                   1014:                 //
                   1015:                 // Enable Interrupts in NICSR
                   1016:                 //
                   1017: 
                   1018:                 NtStatus = DetectWritePortUshort(
                   1019:                                Adapter->InterfaceType,
                   1020:                                Adapter->BusNumber,
                   1021:                                IoBaseAddress,
                   1022:                                0x2
                   1023:                                );
                   1024: 
                   1025:                 if (NtStatus != STATUS_SUCCESS) {
                   1026: 
                   1027:                     goto BuildBuffer;
                   1028: 
                   1029:                 }
                   1030: 
                   1031:                 //
                   1032:                 // Write INIT bit and INTERRUPT_ENABLE bit
                   1033:                 //
                   1034: 
                   1035:                 NtStatus = DetectWritePortUshort(
                   1036:                                Adapter->InterfaceType,
                   1037:                                Adapter->BusNumber,
                   1038:                                IoBaseAddress + 0x4,
                   1039:                                0x41
                   1040:                                );
                   1041: 
                   1042:                 if (NtStatus != STATUS_SUCCESS) {
                   1043: 
                   1044:                     goto BuildBuffer;
                   1045: 
                   1046:                 }
                   1047: 
                   1048:                 Sleep(100);
                   1049: 
                   1050:                 //
                   1051:                 // Write STOP bit
                   1052:                 //
                   1053: 
                   1054:                 NtStatus = DetectWritePortUshort(
                   1055:                                Adapter->InterfaceType,
                   1056:                                Adapter->BusNumber,
                   1057:                                (ULONG)(IoBaseAddress + 0x4),
                   1058:                                0x4
                   1059:                                );
                   1060: 
                   1061:                 if (NtStatus != STATUS_SUCCESS) {
                   1062: 
                   1063:                     return(ERROR_INVALID_PARAMETER);
                   1064: 
                   1065:                 }
                   1066: 
                   1067:                 //
                   1068:                 // Disable Interrupts in NICSR
                   1069:                 //
                   1070: 
                   1071:                 NtStatus = DetectWritePortUshort(
                   1072:                                Adapter->InterfaceType,
                   1073:                                Adapter->BusNumber,
                   1074:                                (ULONG)(IoBaseAddress),
                   1075:                                0x4
                   1076:                                );
                   1077: 
                   1078:                 if (NtStatus != STATUS_SUCCESS) {
                   1079: 
                   1080:                     return(ERROR_INVALID_PARAMETER);
                   1081: 
                   1082:                 }
                   1083: 
                   1084:                 break;
                   1085: 
                   1086:             default:
                   1087: 
                   1088:                 return(ERROR_INVALID_PARAMETER);
                   1089: 
                   1090:         }
                   1091: 
                   1092: 
                   1093:         //
                   1094:         // Check which one went off
                   1095:         //
                   1096: 
                   1097:         NtStatus = DetectQueryInterruptTrap(
                   1098:                        TrapHandle,
                   1099:                        ResultList,
                   1100:                        InterruptListLength
                   1101:                        );
                   1102: 
                   1103:         if (NtStatus != STATUS_SUCCESS) {
                   1104: 
                   1105:             goto BuildBuffer;
                   1106: 
                   1107:         }
                   1108: 
                   1109:         //
                   1110:         // Remove interrupt trap
                   1111:         //
                   1112: 
                   1113:         NtStatus = DetectRemoveInterruptTrap(
                   1114:                        TrapHandle
                   1115:                        );
                   1116: 
                   1117:         if (NtStatus != STATUS_SUCCESS) {
                   1118: 
                   1119:             goto BuildBuffer;
                   1120: 
                   1121:         }
                   1122: 
                   1123:         //
                   1124:         // Search resulting buffer to find the right interrupt
                   1125:         //
                   1126: 
                   1127:         for (i = 0; i < InterruptListLength; i++) {
                   1128: 
                   1129:             if ((ResultList[i] == 1) || (ResultList[i] == 2)) {
                   1130: 
                   1131:                 if (FoundInterrupt) {
                   1132: 
                   1133:                     //
                   1134:                     // Uh-oh, looks like interrupts on two different IRQs.
                   1135:                     //
                   1136: 
                   1137:                     FoundInterrupt = FALSE;
                   1138:                     goto BuildBuffer;
                   1139: 
                   1140:                 }
                   1141: 
                   1142:                 InterruptNumber = InterruptList[i];
                   1143:                 FoundInterrupt = TRUE;
                   1144: 
                   1145:             }
                   1146: 
                   1147:         }
                   1148: 
                   1149:     }
                   1150: 
                   1151: BuildBuffer :
                   1152: 
                   1153:     //
                   1154:     // Build resulting buffer
                   1155:     //
                   1156: 
                   1157:     if (!FoundIo) {
                   1158: 
                   1159:         //
                   1160:         // We found nothing...
                   1161:         //
                   1162: 
                   1163:         //
                   1164:         // Copy in final \0
                   1165:         //
                   1166: 
                   1167:         Buffer[0] = L'\0';
                   1168: 
                   1169:         return(0);
                   1170: 
                   1171:     }
                   1172: 
                   1173:     //
                   1174:     // First put in memory addr
                   1175:     //
                   1176: 
                   1177:     //
                   1178:     // Copy in the title string
                   1179:     //
                   1180: 
                   1181:     CopyLength = UnicodeStrLen(MemAddrString) + 1;
                   1182: 
                   1183:     if (OutputLengthLeft < CopyLength) {
                   1184: 
                   1185:         return(ERROR_INSUFFICIENT_BUFFER);
                   1186: 
                   1187:     }
                   1188: 
                   1189:     memcpy((PVOID)Buffer,
                   1190:             (PVOID)MemAddrString,
                   1191:             (CopyLength * sizeof(WCHAR))
                   1192:             );
                   1193: 
                   1194:     Buffer = &(Buffer[CopyLength]);
                   1195:     OutputLengthLeft -= CopyLength;
                   1196: 
                   1197:     //
                   1198:     // Copy in the value
                   1199:     //
                   1200: 
                   1201:     if (OutputLengthLeft < 8) {
                   1202: 
                   1203:         return(ERROR_INSUFFICIENT_BUFFER);
                   1204: 
                   1205:     }
                   1206: 
                   1207:     CopyLength = wsprintfW(Buffer,L"0x%x",(ULONG)(Adapter->MemoryMappedBaseAddress));
                   1208: 
                   1209:     if (CopyLength < 0) {
                   1210: 
                   1211:         return(ERROR_INSUFFICIENT_BUFFER);
                   1212: 
                   1213:     }
                   1214: 
                   1215:     CopyLength++;  // Add in the \0
                   1216: 
                   1217:     Buffer = &(Buffer[CopyLength]);
                   1218:     OutputLengthLeft -= CopyLength;
                   1219: 
                   1220:     //
                   1221:     // Now the amount of memory
                   1222:     //
                   1223: 
                   1224:     //
                   1225:     // Copy in the title string
                   1226:     //
                   1227: 
                   1228:     CopyLength = UnicodeStrLen(MemLengthString) + 1;
                   1229: 
                   1230:     if (OutputLengthLeft < CopyLength) {
                   1231: 
                   1232:         return(ERROR_INSUFFICIENT_BUFFER);
                   1233: 
                   1234:     }
                   1235: 
                   1236:     memcpy((PVOID)Buffer,
                   1237:            (PVOID)MemLengthString,
                   1238:            (CopyLength * sizeof(WCHAR))
                   1239:            );
                   1240: 
                   1241:     Buffer = &(Buffer[CopyLength]);
                   1242:     OutputLengthLeft -= CopyLength;
                   1243: 
                   1244:     //
                   1245:     // Copy in the value
                   1246:     //
                   1247: 
                   1248:     if (OutputLengthLeft < 8) {
                   1249: 
                   1250:         return(ERROR_INSUFFICIENT_BUFFER);
                   1251: 
                   1252:     }
                   1253: 
                   1254:     if ((ULONG)(Adapter->MemoryMappedBaseAddress) & 0x8000) {
                   1255: 
                   1256:         CopyLength = wsprintfW(Buffer,L"0x8000");
                   1257: 
                   1258:     } else {
                   1259: 
                   1260:         CopyLength = wsprintfW(Buffer,L"0x10000");
                   1261: 
                   1262:     }
                   1263: 
                   1264:     if (CopyLength < 0) {
                   1265: 
                   1266:         return(ERROR_INSUFFICIENT_BUFFER);
                   1267: 
                   1268:     }
                   1269: 
                   1270:     CopyLength++;  // Add in the \0
                   1271: 
                   1272:     Buffer = &(Buffer[CopyLength]);
                   1273:     OutputLengthLeft -= CopyLength;
                   1274: 
                   1275:     //
                   1276:     // Now the IoBaseAddress
                   1277:     //
                   1278: 
                   1279:     //
                   1280:     // Copy in the title string
                   1281:     //
                   1282: 
                   1283:     CopyLength = UnicodeStrLen(IoAddrString) + 1;
                   1284: 
                   1285:     if (OutputLengthLeft < CopyLength) {
                   1286: 
                   1287:         return(ERROR_INSUFFICIENT_BUFFER);
                   1288: 
                   1289:     }
                   1290: 
                   1291:     memcpy((PVOID)Buffer,
                   1292:            (PVOID)IoAddrString,
                   1293:            (CopyLength * sizeof(WCHAR))
                   1294:            );
                   1295: 
                   1296:     Buffer = &(Buffer[CopyLength]);
                   1297:     OutputLengthLeft -= CopyLength;
                   1298: 
                   1299:     //
                   1300:     // Copy in the value
                   1301:     //
                   1302: 
                   1303:     if (OutputLengthLeft < 6) {
                   1304: 
                   1305:         return(ERROR_INSUFFICIENT_BUFFER);
                   1306: 
                   1307:     }
                   1308: 
                   1309:     CopyLength = wsprintfW(Buffer,L"0x%x",IoBaseAddress);
                   1310: 
                   1311:     if (CopyLength < 0) {
                   1312: 
                   1313:         return(ERROR_INSUFFICIENT_BUFFER);
                   1314: 
                   1315:     }
                   1316: 
                   1317:     CopyLength++;  // Add in the \0
                   1318: 
                   1319:     Buffer = &(Buffer[CopyLength]);
                   1320:     OutputLengthLeft -= CopyLength;
                   1321: 
                   1322:     //
                   1323:     // Copy in the title string
                   1324:     //
                   1325: 
                   1326:     CopyLength = UnicodeStrLen(IoLengthString) + 1;
                   1327: 
                   1328:     if (OutputLengthLeft < CopyLength) {
                   1329: 
                   1330:         return(ERROR_INSUFFICIENT_BUFFER);
                   1331: 
                   1332:     }
                   1333: 
                   1334:     memcpy((PVOID)Buffer,
                   1335:            (PVOID)IoLengthString,
                   1336:            (CopyLength * sizeof(WCHAR))
                   1337:            );
                   1338: 
                   1339:     Buffer = &(Buffer[CopyLength]);
                   1340:     OutputLengthLeft -= CopyLength;
                   1341: 
                   1342:     //
                   1343:     // Copy in the value
                   1344:     //
                   1345: 
                   1346:     if (OutputLengthLeft < 5) {
                   1347: 
                   1348:         return(ERROR_INSUFFICIENT_BUFFER);
                   1349: 
                   1350:     }
                   1351: 
                   1352:     CopyLength = wsprintfW(Buffer,L"0x10");
                   1353: 
                   1354:     if (CopyLength < 0) {
                   1355: 
                   1356:         return(ERROR_INSUFFICIENT_BUFFER);
                   1357: 
                   1358:     }
                   1359: 
                   1360:     CopyLength++;  // Add in the \0
                   1361: 
                   1362:     Buffer = &(Buffer[CopyLength]);
                   1363:     OutputLengthLeft -= CopyLength;
                   1364: 
                   1365:     //
                   1366:     // Now the interrupt (if we found it)
                   1367:     //
                   1368: 
                   1369:     if (FoundInterrupt) {
                   1370: 
                   1371:         //
                   1372:         // Copy in the title string
                   1373:         //
                   1374: 
                   1375:         CopyLength = UnicodeStrLen(IrqString) + 1;
                   1376: 
                   1377:         if (OutputLengthLeft < CopyLength) {
                   1378: 
                   1379:             return(ERROR_INSUFFICIENT_BUFFER);
                   1380: 
                   1381:         }
                   1382: 
                   1383:         memcpy((PVOID)Buffer,
                   1384:                (PVOID)IrqString,
                   1385:                (CopyLength * sizeof(WCHAR))
                   1386:                );
                   1387: 
                   1388:         Buffer = &(Buffer[CopyLength]);
                   1389:         OutputLengthLeft -= CopyLength;
                   1390: 
                   1391:         //
                   1392:         // Copy in the value
                   1393:         //
                   1394: 
                   1395:         if (OutputLengthLeft < 3) {
                   1396: 
                   1397:             return(ERROR_INSUFFICIENT_BUFFER);
                   1398: 
                   1399:         }
                   1400: 
                   1401:         CopyLength = wsprintfW(Buffer,L"%d",InterruptNumber);
                   1402: 
                   1403:         if (CopyLength < 0) {
                   1404: 
                   1405:             return(ERROR_INSUFFICIENT_BUFFER);
                   1406: 
                   1407:         }
                   1408: 
                   1409:         CopyLength++;  // Add in the \0
                   1410: 
                   1411:         Buffer = &(Buffer[CopyLength]);
                   1412:         OutputLengthLeft -= CopyLength;
                   1413: 
                   1414:         //
                   1415:         // Copy in the title string (IRQTYPE)
                   1416:         //
                   1417: 
                   1418:         CopyLength = UnicodeStrLen(IrqTypeString) + 1;
                   1419: 
                   1420:         if (OutputLengthLeft < CopyLength) {
                   1421: 
                   1422:             return(ERROR_INSUFFICIENT_BUFFER);
                   1423: 
                   1424:         }
                   1425: 
                   1426:         memcpy((PVOID)Buffer,
                   1427:                (PVOID)IrqTypeString,
                   1428:                (CopyLength * sizeof(WCHAR))
                   1429:                );
                   1430: 
                   1431:         Buffer = &(Buffer[CopyLength]);
                   1432:         OutputLengthLeft -= CopyLength;
                   1433: 
                   1434:         //
                   1435:         // Copy in the value
                   1436:         //
                   1437: 
                   1438:         if (OutputLengthLeft < 2) {
                   1439: 
                   1440:             return(ERROR_INSUFFICIENT_BUFFER);
                   1441: 
                   1442:         }
                   1443: 
                   1444:         //
                   1445:         // All card types in this detection are ISA cards,
                   1446:         // which are LATCHED (0 == latched)
                   1447:         //
                   1448:         CopyLength = wsprintfW(Buffer,L"0");
                   1449: 
                   1450:         if (CopyLength < 0) {
                   1451: 
                   1452:             return(ERROR_INSUFFICIENT_BUFFER);
                   1453: 
                   1454:         }
                   1455: 
                   1456:         CopyLength++;  // Add in the \0
                   1457: 
                   1458:         Buffer = &(Buffer[CopyLength]);
                   1459:         OutputLengthLeft -= CopyLength;
                   1460: 
                   1461:     }
                   1462: 
                   1463:     //
                   1464:     // Copy in final \0
                   1465:     //
                   1466: 
                   1467:     CopyLength = (ULONG)Buffer - StartPointer;
                   1468:     Buffer[CopyLength] = L'\0';
                   1469: 
                   1470:     return(0);
                   1471: }
                   1472: 
                   1473: extern
                   1474: LONG
                   1475: LanceVerifyCfgHandler(
                   1476:     IN PVOID Handle,
                   1477:     IN WCHAR *Buffer
                   1478:     )
                   1479: 
                   1480: /*++
                   1481: 
                   1482: Routine Description:
                   1483: 
                   1484:     This routine verifys that a given parameter list is complete and
                   1485:     correct for the adapter associated with the handle.
                   1486: 
                   1487: Arguments:
                   1488: 
                   1489:     Handle - The handle.
                   1490: 
                   1491:     Buffer - The parameter list.
                   1492: 
                   1493: Return Value:
                   1494: 
                   1495:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   1496: 
                   1497: --*/
                   1498: 
                   1499: {
                   1500:     PLANCE_ADAPTER Adapter = (PLANCE_ADAPTER)(Handle);
                   1501:     NTSTATUS NtStatus;
                   1502:     HANDLE TrapHandle;
                   1503:     BOOLEAN Found = FALSE;
                   1504: 
                   1505:     UCHAR Interrupt;
                   1506:     ULONG MemoryAddress;
                   1507:     ULONG IoBaseAddress;
                   1508:     UCHAR Result;
                   1509:     USHORT Value;
                   1510: 
                   1511:     WCHAR *Place;
                   1512:     CHAR *DetectString;
                   1513: 
                   1514:     if ((Adapter->InterfaceType != Isa) &&
                   1515:         (Adapter->InterfaceType != Eisa)) {
                   1516: 
                   1517:         return(ERROR_INVALID_DATA);
                   1518: 
                   1519:     }
                   1520: 
                   1521:     if (Adapter->CardType != 1400) {
                   1522: 
                   1523:         //
                   1524:         // If not the DecPCA we need to parse out the parameters.
                   1525:         //
                   1526: 
                   1527: 
                   1528:         //
                   1529:         // Get the IoBaseAddress
                   1530:         //
                   1531: 
                   1532:         Place = FindParameterString(Buffer, IoAddrString);
                   1533: 
                   1534:         if (Place == NULL) {
                   1535: 
                   1536:             return(ERROR_INVALID_DATA);
                   1537: 
                   1538:         }
                   1539: 
                   1540:         Place += UnicodeStrLen(IoAddrString) + 1;
                   1541: 
                   1542:         //
                   1543:         // Now parse the thing.
                   1544:         //
                   1545: 
                   1546:         ScanForNumber(Place, &IoBaseAddress, &Found);
                   1547: 
                   1548:         if (Found == FALSE) {
                   1549: 
                   1550:             return(ERROR_INVALID_DATA);
                   1551: 
                   1552:         }
                   1553: 
                   1554:         //
                   1555:         // Get the interrupt number
                   1556:         //
                   1557: 
                   1558:         Place = FindParameterString(Buffer, IrqString);
                   1559: 
                   1560:         if (Place == NULL) {
                   1561: 
                   1562:             return(ERROR_INVALID_DATA);
                   1563: 
                   1564:         }
                   1565: 
                   1566:         Place += UnicodeStrLen(IrqString) + 1;
                   1567: 
                   1568:         //
                   1569:         // Now parse the thing.
                   1570:         //
                   1571: 
                   1572:         ScanForNumber(Place, &MemoryAddress, &Found);
                   1573: 
                   1574:         Interrupt = (UCHAR)MemoryAddress;
                   1575: 
                   1576:         if (Found == FALSE) {
                   1577: 
                   1578:             return(ERROR_INVALID_DATA);
                   1579: 
                   1580:         }
                   1581: 
                   1582:         //
                   1583:         // Get the memory address
                   1584:         //
                   1585: 
                   1586:         Place = FindParameterString(Buffer, MemAddrString);
                   1587: 
                   1588:         if (Place == NULL) {
                   1589: 
                   1590:             return(ERROR_INVALID_DATA);
                   1591: 
                   1592:         }
                   1593: 
                   1594:         Place += UnicodeStrLen(MemAddrString) + 1;
                   1595: 
                   1596:         //
                   1597:         // Now parse the thing.
                   1598:         //
                   1599: 
                   1600:         ScanForNumber(Place, &MemoryAddress, &Found);
                   1601: 
                   1602:         if (Found == FALSE) {
                   1603: 
                   1604:             return(ERROR_INVALID_DATA);
                   1605: 
                   1606:         }
                   1607: 
                   1608:     } else {
                   1609: 
                   1610:         //
                   1611:         // Set the DePCA values
                   1612:         //
                   1613: 
                   1614:         MemoryAddress = 0xD0000;
                   1615:         IoBaseAddress = 0x200;
                   1616:         Interrupt = 5;
                   1617: 
                   1618:     }
                   1619: 
                   1620:     //
                   1621:     // Verify memory address
                   1622:     //
                   1623: 
                   1624:     switch (Adapter->CardType) {
                   1625: 
                   1626:         //
                   1627:         // De100
                   1628:         // DePCA
                   1629:         //
                   1630: 
                   1631:         case 1000:
                   1632:         case 1400:
                   1633: 
                   1634:             DetectString = De100String;
                   1635: 
                   1636:             break;
                   1637: 
                   1638:         //
                   1639:         // De200
                   1640:         //
                   1641: 
                   1642:         case 1100:
                   1643: 
                   1644:             DetectString = De200String;
                   1645: 
                   1646:             break;
                   1647: 
                   1648:         //
                   1649:         // De201
                   1650:         //
                   1651: 
                   1652:         case 1200:
                   1653: 
                   1654:             DetectString = De201String;
                   1655: 
                   1656:             break;
                   1657: 
                   1658:         //
                   1659:         // De101
                   1660:         //
                   1661: 
                   1662:         case 1300:
                   1663: 
                   1664:             DetectString = De101String;
                   1665: 
                   1666:             break;
                   1667: 
                   1668:         default:
                   1669: 
                   1670:             return(ERROR_INVALID_DATA);
                   1671: 
                   1672:     }
                   1673: 
                   1674:     //
                   1675:     // Check now.
                   1676:     //
                   1677: 
                   1678:     if (!DecCardAt(Adapter->InterfaceType,
                   1679:                    Adapter->BusNumber,
                   1680:                    MemoryAddress | 0xC000,
                   1681:                    DetectString)) {
                   1682: 
                   1683:         return(ERROR_INVALID_DATA);
                   1684: 
                   1685:     }
                   1686: 
                   1687:     //
                   1688:     // Check the IoBaseAddress
                   1689:     //
                   1690: 
                   1691:     if (!LanceHardwareDetails(Adapter->InterfaceType,
                   1692:                               Adapter->BusNumber,
                   1693:                               IoBaseAddress + 0xC)) {
                   1694: 
                   1695:         //
                   1696:         // Not found
                   1697:         //
                   1698: 
                   1699:         return(ERROR_INVALID_DATA);
                   1700: 
                   1701:     }
                   1702: 
                   1703:     if (Adapter->CardType == 1400) {
                   1704: 
                   1705:         UCHAR Value;
                   1706: 
                   1707:         //
                   1708:         // For the DePCA we need to check for the Lan Config Register
                   1709:         //
                   1710: 
                   1711:         NtStatus = DetectReadPortUchar(
                   1712:                               Adapter->InterfaceType,
                   1713:                               Adapter->BusNumber,
                   1714:                               (ULONG)(0x800),
                   1715:                               &(Value)
                   1716:                               );
                   1717: 
                   1718:         if (NtStatus != STATUS_SUCCESS) {
                   1719: 
                   1720:             return(ERROR_INVALID_DATA);
                   1721: 
                   1722:         }
                   1723: 
                   1724:         if (Value == 0xFF) {
                   1725: 
                   1726:             //
                   1727:             // No such port, definitely not.
                   1728:             //
                   1729: 
                   1730:             return(ERROR_INVALID_DATA);
                   1731: 
                   1732:         }
                   1733: 
                   1734:     }
                   1735: 
                   1736:     //
                   1737:     // Read amount of memory (to continue verifying memory address)
                   1738:     //
                   1739: 
                   1740:     NtStatus = DetectReadPortUshort(
                   1741:                                Adapter->InterfaceType,
                   1742:                                Adapter->BusNumber,
                   1743:                                IoBaseAddress,
                   1744:                                &Value
                   1745:                                );
                   1746: 
                   1747:     if (NtStatus != STATUS_SUCCESS) {
                   1748: 
                   1749:         return(ERROR_INVALID_DATA);
                   1750: 
                   1751:     }
                   1752: 
                   1753:     if (Value & 0x20) {
                   1754: 
                   1755:         //
                   1756:         // Definitely in 32K mode.
                   1757:         //
                   1758: 
                   1759:         if (!(MemoryAddress & 0x8000)) {
                   1760: 
                   1761:             return(ERROR_INVALID_DATA);
                   1762: 
                   1763:         }
                   1764: 
                   1765:     } else {
                   1766: 
                   1767:         //
                   1768:         // Definitely in 64K mode.
                   1769:         //
                   1770: 
                   1771:         if (MemoryAddress & 0x8000) {
                   1772: 
                   1773:             return(ERROR_INVALID_DATA);
                   1774: 
                   1775:         }
                   1776: 
                   1777:     }
                   1778: 
                   1779:     //
                   1780:     // Set the interrupt trap -- we are checking the interrupt number now
                   1781:     //
                   1782: 
                   1783:     NtStatus = DetectSetInterruptTrap(
                   1784:                    Adapter->InterfaceType,
                   1785:                    Adapter->BusNumber,
                   1786:                    &TrapHandle,
                   1787:                    &Interrupt,
                   1788:                    1
                   1789:                    );
                   1790: 
                   1791:     if (NtStatus == STATUS_SUCCESS) {
                   1792: 
                   1793:         //
                   1794:         // Check that it is available
                   1795:         //
                   1796: 
                   1797:         NtStatus = DetectQueryInterruptTrap(
                   1798:                        TrapHandle,
                   1799:                        &Result,
                   1800:                        1
                   1801:                        );
                   1802: 
                   1803:         if (NtStatus != STATUS_SUCCESS) {
                   1804: 
                   1805:             return(ERROR_INVALID_DATA);
                   1806: 
                   1807:         }
                   1808: 
                   1809:         if (Result == 3) {
                   1810: 
                   1811:             //
                   1812:             // Remove interrupt trap
                   1813:             //
                   1814: 
                   1815:             DetectRemoveInterruptTrap(
                   1816:                        TrapHandle
                   1817:                        );
                   1818: 
                   1819:             return(ERROR_INVALID_DATA);
                   1820: 
                   1821:         }
                   1822: 
                   1823: 
                   1824:         //
                   1825:         // Create an interrupt
                   1826:         //
                   1827: 
                   1828:         switch (Adapter->CardType) {
                   1829: 
                   1830:             //
                   1831:             // De100
                   1832:             // De200
                   1833:             // De201
                   1834:             // De101
                   1835:             // DePCA
                   1836:             //
                   1837:             case 1000:
                   1838:             case 1100:
                   1839:             case 1200:
                   1840:             case 1300:
                   1841:             case 1400:
                   1842: 
                   1843:                 //
                   1844:                 // Change to CSR0
                   1845:                 //
                   1846: 
                   1847:                 NtStatus = DetectWritePortUshort(
                   1848:                                Adapter->InterfaceType,
                   1849:                                Adapter->BusNumber,
                   1850:                                (ULONG)(IoBaseAddress + 0x6),
                   1851:                                0x0
                   1852:                                );
                   1853: 
                   1854:                 if (NtStatus != STATUS_SUCCESS) {
                   1855: 
                   1856:                     return(ERROR_INVALID_DATA);
                   1857: 
                   1858:                 }
                   1859: 
                   1860:                 //
                   1861:                 // Write STOP bit
                   1862:                 //
                   1863: 
                   1864:                 NtStatus = DetectWritePortUshort(
                   1865:                                Adapter->InterfaceType,
                   1866:                                Adapter->BusNumber,
                   1867:                                (ULONG)(IoBaseAddress + 0x4),
                   1868:                                0x4
                   1869:                                );
                   1870: 
                   1871:                 if (NtStatus != STATUS_SUCCESS) {
                   1872: 
                   1873:                     return(ERROR_INVALID_DATA);
                   1874: 
                   1875:                 }
                   1876: 
                   1877:                 //
                   1878:                 // Enable Interrupts in NICSR
                   1879:                 //
                   1880: 
                   1881:                 NtStatus = DetectWritePortUshort(
                   1882:                                Adapter->InterfaceType,
                   1883:                                Adapter->BusNumber,
                   1884:                                (ULONG)(IoBaseAddress),
                   1885:                                0x2
                   1886:                                );
                   1887: 
                   1888:                 if (NtStatus != STATUS_SUCCESS) {
                   1889: 
                   1890:                     return(ERROR_INVALID_DATA);
                   1891: 
                   1892:                 }
                   1893: 
                   1894:                 //
                   1895:                 // Write INIT bit and INTERRUPT_ENABLE bit
                   1896:                 //
                   1897: 
                   1898:                 NtStatus = DetectWritePortUshort(
                   1899:                                Adapter->InterfaceType,
                   1900:                                Adapter->BusNumber,
                   1901:                                (ULONG)(IoBaseAddress + 0x4),
                   1902:                                0x41
                   1903:                                );
                   1904: 
                   1905:                 if (NtStatus != STATUS_SUCCESS) {
                   1906: 
                   1907:                     return(ERROR_INVALID_DATA);
                   1908: 
                   1909:                 }
                   1910: 
                   1911:                 Sleep(100);
                   1912: 
                   1913:                 //
                   1914:                 // Write STOP bit
                   1915:                 //
                   1916: 
                   1917:                 NtStatus = DetectWritePortUshort(
                   1918:                                Adapter->InterfaceType,
                   1919:                                Adapter->BusNumber,
                   1920:                                (ULONG)(IoBaseAddress + 0x4),
                   1921:                                0x4
                   1922:                                );
                   1923: 
                   1924:                 if (NtStatus != STATUS_SUCCESS) {
                   1925: 
                   1926:                     return(ERROR_INVALID_DATA);
                   1927: 
                   1928:                 }
                   1929: 
                   1930:                 //
                   1931:                 // Disable Interrupts in NICSR
                   1932:                 //
                   1933: 
                   1934:                 NtStatus = DetectWritePortUshort(
                   1935:                                Adapter->InterfaceType,
                   1936:                                Adapter->BusNumber,
                   1937:                                (ULONG)(IoBaseAddress),
                   1938:                                0x4
                   1939:                                );
                   1940: 
                   1941:                 if (NtStatus != STATUS_SUCCESS) {
                   1942: 
                   1943:                     return(ERROR_INVALID_DATA);
                   1944: 
                   1945:                 }
                   1946: 
                   1947:                 break;
                   1948: 
                   1949:             default:
                   1950: 
                   1951:                 return(ERROR_INVALID_DATA);
                   1952: 
                   1953:         }
                   1954: 
                   1955: 
                   1956:         //
                   1957:         // Check which one went off
                   1958:         //
                   1959: 
                   1960:         NtStatus = DetectQueryInterruptTrap(
                   1961:                        TrapHandle,
                   1962:                        &Result,
                   1963:                        1
                   1964:                        );
                   1965: 
                   1966:         if (NtStatus != STATUS_SUCCESS) {
                   1967: 
                   1968:             return(ERROR_INVALID_DATA);
                   1969: 
                   1970:         }
                   1971: 
                   1972:         //
                   1973:         // Remove interrupt trap
                   1974:         //
                   1975: 
                   1976:         NtStatus = DetectRemoveInterruptTrap(
                   1977:                        TrapHandle
                   1978:                        );
                   1979: 
                   1980:         if (NtStatus != STATUS_SUCCESS) {
                   1981: 
                   1982:             return(ERROR_INVALID_DATA);
                   1983: 
                   1984:         }
                   1985: 
                   1986:         if ((Result == 1) || (Result == 2)) {
                   1987: 
                   1988:             return(0);
                   1989: 
                   1990:         }
                   1991: 
                   1992:         return(ERROR_INVALID_DATA);
                   1993: 
                   1994:     } else {
                   1995: 
                   1996:         return(ERROR_INVALID_DATA);
                   1997: 
                   1998:     }
                   1999: 
                   2000: }
                   2001: 
                   2002: extern
                   2003: LONG LanceQueryMaskHandler(
                   2004:     IN  LONG NetcardId,
                   2005:     OUT WCHAR *Buffer,
                   2006:     IN  LONG BuffSize
                   2007:     )
                   2008: 
                   2009: /*++
                   2010: 
                   2011: Routine Description:
                   2012: 
                   2013:     This routine returns the parameter list information for a specific
                   2014:     network card.
                   2015: 
                   2016: Arguments:
                   2017: 
                   2018:     NetcardId - The id of the desired netcard.
                   2019: 
                   2020:     Buffer - The buffer for storing the parameter information.
                   2021: 
                   2022:     BuffSize - Length of Buffer in WCHARs.
                   2023: 
                   2024: Return Value:
                   2025: 
                   2026:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2027: 
                   2028: --*/
                   2029: 
                   2030: {
                   2031:     WCHAR *Result;
                   2032:     LONG Length;
                   2033:     LONG NumberOfAdapters;
                   2034:     LONG i;
                   2035: 
                   2036:     //
                   2037:     // Find the adapter
                   2038:     //
                   2039: 
                   2040:     NumberOfAdapters = sizeof(Adapters) / sizeof(ADAPTER_INFO);
                   2041: 
                   2042:     for (i=0; i < NumberOfAdapters; i++) {
                   2043: 
                   2044:         if (Adapters[i].Index == NetcardId) {
                   2045: 
                   2046:             Result = Adapters[i].Parameters;
                   2047: 
                   2048:             //
                   2049:             // Find the string length (Ends with 2 NULLs)
                   2050:             //
                   2051: 
                   2052:             for (Length=0; ; Length++) {
                   2053: 
                   2054:                 if (Result[Length] == L'\0') {
                   2055: 
                   2056:                     ++Length;
                   2057: 
                   2058:                     if (Result[Length] == L'\0') {
                   2059: 
                   2060:                         break;
                   2061: 
                   2062:                     }
                   2063: 
                   2064:                 }
                   2065: 
                   2066:             }
                   2067: 
                   2068:             Length++;
                   2069: 
                   2070:             if (BuffSize < Length) {
                   2071: 
                   2072:                 return(ERROR_INSUFFICIENT_BUFFER);
                   2073: 
                   2074:             }
                   2075: 
                   2076:             memcpy((PVOID)Buffer, Result, Length * sizeof(WCHAR));
                   2077: 
                   2078:             return(0);
                   2079: 
                   2080:         }
                   2081: 
                   2082:     }
                   2083: 
                   2084:     return(ERROR_INVALID_PARAMETER);
                   2085: 
                   2086: }
                   2087: 
                   2088: extern
                   2089: LONG
                   2090: LanceParamRangeHandler(
                   2091:     IN  LONG NetcardId,
                   2092:     IN  WCHAR *Param,
                   2093:     OUT LONG *plValues,
                   2094:     OUT LONG *plBuffSize
                   2095:     )
                   2096: 
                   2097: /*++
                   2098: 
                   2099: Routine Description:
                   2100: 
                   2101:     This routine returns a list of valid values for a given parameter name
                   2102:     for a given card.
                   2103: 
                   2104: Arguments:
                   2105: 
                   2106:     NetcardId - The Id of the card desired.
                   2107: 
                   2108:     Param - A WCHAR string of the parameter name to query the values of.
                   2109: 
                   2110:     plValues - A pointer to a list of LONGs into which we store valid values
                   2111:     for the parameter.
                   2112: 
                   2113:     plBuffSize - At entry, the length of plValues in LONGs.  At exit, the
                   2114:     number of LONGs stored in plValues.
                   2115: 
                   2116: Return Value:
                   2117: 
                   2118:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2119: 
                   2120: --*/
                   2121: 
                   2122: {
                   2123: 
                   2124:     //
                   2125:     // Do we want the IRQL
                   2126:     //
                   2127: 
                   2128:     if (memcmp(Param, IrqString, (UnicodeStrLen(IrqString) + 1) * sizeof(WCHAR)) == 0) {
                   2129: 
                   2130:         //
                   2131:         // Is there enough space
                   2132:         //
                   2133: 
                   2134:         if (*plBuffSize < 5) {
                   2135: 
                   2136:             *plBuffSize = 0;
                   2137:             return(ERROR_INSUFFICIENT_BUFFER);
                   2138: 
                   2139:         }
                   2140: 
                   2141:         //
                   2142:         // Find which card
                   2143:         //
                   2144: 
                   2145:         switch (NetcardId) {
                   2146: 
                   2147:             //
                   2148:             // De100
                   2149:             // De101
                   2150:             //
                   2151:             case 1000:
                   2152:             case 1300:
                   2153: 
                   2154:                 plValues[0] = 5;
                   2155:                 plValues[1] = 3;
                   2156:                 plValues[2] = 4;
                   2157:                 plValues[3] = 2;
                   2158:                 plValues[4] = 7;
                   2159:                 *plBuffSize = 5;
                   2160:                 break;
                   2161: 
                   2162:             //
                   2163:             // De200
                   2164:             // De201
                   2165:             //
                   2166: 
                   2167:             case 1100:
                   2168:             case 1200:
                   2169: 
                   2170:                 plValues[0] = 5;
                   2171:                 plValues[1] = 9;
                   2172:                 plValues[2] = 10;
                   2173:                 plValues[3] = 11;
                   2174:                 plValues[4] = 15;
                   2175:                 *plBuffSize = 5;
                   2176:                 break;
                   2177: 
                   2178:             default:
                   2179: 
                   2180:                 *plBuffSize = 0;
                   2181: 
                   2182:                 return(ERROR_INVALID_PARAMETER);
                   2183: 
                   2184:        }
                   2185: 
                   2186:        return(0);
                   2187: 
                   2188:     }
                   2189: 
                   2190:     //
                   2191:     // Do we want the IoBaseAddress
                   2192:     //
                   2193: 
                   2194:     if (memcmp(Param, IoAddrString, (UnicodeStrLen(IoAddrString) + 1) * sizeof(WCHAR)) == 0) {
                   2195: 
                   2196:         //
                   2197:         // Is there enough space
                   2198:         //
                   2199: 
                   2200:         if (*plBuffSize < 2) {
                   2201: 
                   2202:             *plBuffSize = 0;
                   2203:             return(ERROR_INSUFFICIENT_BUFFER);
                   2204: 
                   2205:         }
                   2206: 
                   2207:         //
                   2208:         // Find which card
                   2209:         //
                   2210: 
                   2211:         switch (NetcardId) {
                   2212: 
                   2213:             //
                   2214:             // De100
                   2215:             // De200
                   2216:             // De201
                   2217:             // De101
                   2218:             //
                   2219: 
                   2220:             case 1000:
                   2221:             case 1100:
                   2222:             case 1200:
                   2223:             case 1300:
                   2224: 
                   2225:                 plValues[0] = 0x300;
                   2226:                 plValues[1] = 0x200;
                   2227:                 *plBuffSize = 2;
                   2228:                 break;
                   2229: 
                   2230:             default:
                   2231: 
                   2232:                 *plBuffSize = 0;
                   2233: 
                   2234:                 return(ERROR_INVALID_PARAMETER);
                   2235: 
                   2236:        }
                   2237: 
                   2238:        return(0);
                   2239: 
                   2240:     }
                   2241: 
                   2242:     //
                   2243:     // Do we want the MemoryBaseAddress
                   2244:     //
                   2245: 
                   2246:     if (memcmp(Param, MemAddrString, (UnicodeStrLen(MemAddrString) + 1) * sizeof(WCHAR)) == 0) {
                   2247: 
                   2248:         //
                   2249:         // Is there enough space
                   2250:         //
                   2251: 
                   2252:         if (*plBuffSize < 6) {
                   2253: 
                   2254:             *plBuffSize = 0;
                   2255:             return(ERROR_INSUFFICIENT_BUFFER);
                   2256: 
                   2257:         }
                   2258: 
                   2259:         //
                   2260:         // Find which card
                   2261:         //
                   2262: 
                   2263:         switch (NetcardId) {
                   2264: 
                   2265:             //
                   2266:             // De100
                   2267:             // De200
                   2268:             // De201
                   2269:             // De101
                   2270:             //
                   2271: 
                   2272:             case 1000:
                   2273:             case 1100:
                   2274:             case 1200:
                   2275:             case 1300:
                   2276: 
                   2277:                 plValues[0] = 0xD0000;
                   2278:                 plValues[1] = 0xC8000;
                   2279:                 plValues[2] = 0xC0000;
                   2280:                 plValues[3] = 0xD8000;
                   2281:                 plValues[4] = 0xE0000;
                   2282:                 plValues[5] = 0xE8000;
                   2283:                 *plBuffSize = 6;
                   2284:                 break;
                   2285: 
                   2286:             default:
                   2287: 
                   2288:                 *plBuffSize = 0;
                   2289: 
                   2290:                 return(ERROR_INVALID_PARAMETER);
                   2291: 
                   2292:        }
                   2293: 
                   2294:        return(0);
                   2295: 
                   2296:     }
                   2297: 
                   2298:     return(ERROR_INVALID_PARAMETER);
                   2299: 
                   2300: }
                   2301: 
                   2302: extern
                   2303: LONG LanceQueryParameterNameHandler(
                   2304:     IN  WCHAR *Param,
                   2305:     OUT WCHAR *Buffer,
                   2306:     IN  LONG BufferSize
                   2307:     )
                   2308: 
                   2309: /*++
                   2310: 
                   2311: Routine Description:
                   2312: 
                   2313:     Returns a localized, displayable name for a specific parameter.  All the
                   2314:     parameters that this file uses are define by MS, so no strings are
                   2315:     needed here.
                   2316: 
                   2317: Arguments:
                   2318: 
                   2319:     Param - The parameter to be queried.
                   2320: 
                   2321:     Buffer - The buffer to store the result into.
                   2322: 
                   2323:     BufferSize - The length of Buffer in WCHARs.
                   2324: 
                   2325: Return Value:
                   2326: 
                   2327:     ERROR_INVALID_PARAMETER -- To indicate that the MS supplied strings
                   2328:     should be used.
                   2329: 
                   2330: --*/
                   2331: 
                   2332: {
                   2333:     return(ERROR_INVALID_PARAMETER);
                   2334: }
                   2335: 
                   2336: BOOLEAN
                   2337: DecCardAt(
                   2338:     IN INTERFACE_TYPE InterfaceType,
                   2339:     IN ULONG BusNumber,
                   2340:     IN ULONG MemoryAddress,
                   2341:     IN CHAR *DetectString
                   2342:     )
                   2343: 
                   2344: /*++
                   2345: 
                   2346: Routine Description:
                   2347: 
                   2348:     This routine checks for the instance of a Lance card at the memory
                   2349:     location given.  This is done by checking for the DEC copyright
                   2350:     notice in ROM and then for the model name of the card.
                   2351: 
                   2352: Arguments:
                   2353: 
                   2354:     InterfaceType - The type of bus, ISA or EISA.
                   2355: 
                   2356:     BusNumber - The bus number in the system.
                   2357: 
                   2358:     MemoryAddress - The address of the ROM space for the DEC card.
                   2359: 
                   2360:     DetectString - The model name of the card to search for.
                   2361: 
                   2362: Return Value:
                   2363: 
                   2364:     TRUE if a card is found, else FALSE.
                   2365: 
                   2366: --*/
                   2367: 
                   2368: {
                   2369:     UCHAR TmpBuffer[LENGTH_OF_COPYRIGHT];
                   2370:     LONG CopyrightLength;
                   2371:     LONG DetectLength;
                   2372:     NTSTATUS NtStatus;
                   2373: 
                   2374:     CopyrightLength = strlen(CopyrightString);
                   2375:     DetectLength = strlen(DetectString);
                   2376: 
                   2377:     NtStatus = DetectCheckMemoryUsage(
                   2378:                    InterfaceType,
                   2379:                    BusNumber,
                   2380:                    MemoryAddress,
                   2381:                    0x2000
                   2382:                    );
                   2383: 
                   2384:     if (NtStatus != STATUS_SUCCESS) {
                   2385: 
                   2386:         return(FALSE);
                   2387: 
                   2388:     }
                   2389: 
                   2390:     //
                   2391:     // Read memory
                   2392:     //
                   2393: 
                   2394:     NtStatus = DetectReadMappedMemory(
                   2395:                    InterfaceType,
                   2396:                    BusNumber,
                   2397:                    MemoryAddress + 16,
                   2398:                    CopyrightLength,
                   2399:                    TmpBuffer
                   2400:                    );
                   2401: 
                   2402:     //
                   2403:     // Compare to copyright notice
                   2404:     //
                   2405: 
                   2406:     if ((NtStatus == STATUS_SUCCESS) &&
                   2407:         (memcmp(TmpBuffer, CopyrightString, CopyrightLength) == 0)) {
                   2408: 
                   2409:         //
                   2410:         // So far so good, now check for the specific card
                   2411:         //
                   2412: 
                   2413:         //
                   2414:         // Read Memory
                   2415:         //
                   2416: 
                   2417:         NtStatus = DetectReadMappedMemory(
                   2418:                        InterfaceType,
                   2419:                        BusNumber,
                   2420:                        MemoryAddress + 6,
                   2421:                        DetectLength,
                   2422:                        TmpBuffer
                   2423:                        );
                   2424: 
                   2425:         //
                   2426:         // Compare
                   2427:         //
                   2428: 
                   2429:         if ((NtStatus == STATUS_SUCCESS) &&
                   2430:             (memcmp(TmpBuffer, DetectString, DetectLength) == 0)) {
                   2431: 
                   2432:                 return(TRUE);
                   2433:         }
                   2434: 
                   2435:     }
                   2436: 
                   2437:     return(FALSE);
                   2438: 
                   2439: }
                   2440: 
                   2441: LONG
                   2442: DecCardFirstNext(
                   2443:     IN  LONG SearchStateIndex,
                   2444:     IN  INTERFACE_TYPE InterfaceType,
                   2445:     IN  ULONG BusNumber,
                   2446:     IN  BOOL First,
                   2447:     IN  CHAR *DetectString,
                   2448:     OUT LONG *Confidence
                   2449:     )
                   2450: 
                   2451: /*++
                   2452: 
                   2453: Routine Description:
                   2454: 
                   2455:     This routine finds the instances of a physical adapter.  This routine
                   2456:     handles the general (most typical) kind of Lance card.
                   2457: 
                   2458: Arguments:
                   2459: 
                   2460:     SearchStateIndex - The index into SearchStates for the particular
                   2461:     adapter type we are searching for.
                   2462: 
                   2463:     InterfaceType - Either Isa, or Eisa.
                   2464: 
                   2465:     BusNumber - The bus number of the bus to search.
                   2466: 
                   2467:     First - TRUE is we are to search for the first instance of an
                   2468:     adapter, FALSE if we are to continue search from a previous stopping
                   2469:     point.
                   2470: 
                   2471:     DetectString - The model name of the adapter.
                   2472: 
                   2473:     Confidence - A pointer to a long for storing the confidence factor
                   2474:     that the card exists.
                   2475: 
                   2476: Return Value:
                   2477: 
                   2478:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2479: 
                   2480: --*/
                   2481: 
                   2482: {
                   2483: 
                   2484:     if (First) {
                   2485: 
                   2486:         //
                   2487:         // Reset to beginning
                   2488:         //
                   2489: 
                   2490:         SearchStates[SearchStateIndex].MemoryAddress = (PUCHAR)0xCC000;
                   2491: 
                   2492:     }
                   2493: 
                   2494:     while (SearchStates[SearchStateIndex].MemoryAddress != (PUCHAR)0xFC000) {
                   2495: 
                   2496:         //
                   2497:         // Is there a card at the current address?
                   2498:         //
                   2499: 
                   2500:         if (DecCardAt(InterfaceType,
                   2501:                       BusNumber,
                   2502:                       (ULONG)(SearchStates[SearchStateIndex].MemoryAddress),
                   2503:                       DetectString
                   2504:                       )) {
                   2505: 
                   2506:             //
                   2507:             // Found one!
                   2508:             //
                   2509: 
                   2510:             *Confidence = 100;
                   2511: 
                   2512:             //
                   2513:             // Move to next address for next time
                   2514:             //
                   2515: 
                   2516:             SearchStates[SearchStateIndex].MemoryAddress += 0x10000;
                   2517: 
                   2518:             return(0);
                   2519: 
                   2520:         }
                   2521: 
                   2522:         //
                   2523:         // Move to next address
                   2524:         //
                   2525: 
                   2526:         SearchStates[SearchStateIndex].MemoryAddress += 0x10000;
                   2527: 
                   2528:     }
                   2529: 
                   2530:     *Confidence = 0;
                   2531: 
                   2532:     return(0);
                   2533: 
                   2534: }
                   2535: LONG
                   2536: De100FirstNext(
                   2537:     IN  LONG SearchStateIndex,
                   2538:     IN  INTERFACE_TYPE InterfaceType,
                   2539:     IN  ULONG BusNumber,
                   2540:     IN  BOOL First,
                   2541:     OUT PVOID *Token,
                   2542:     OUT LONG *Confidence
                   2543:     )
                   2544: 
                   2545: /*++
                   2546: 
                   2547: Routine Description:
                   2548: 
                   2549:     This routine finds the instances of a physical adapter De100.
                   2550: 
                   2551: Arguments:
                   2552: 
                   2553:     SearchStateIndex - The index in SearchStates for the De100 adapter.
                   2554: 
                   2555:     InterfaceType - Either Isa, or Eisa.
                   2556: 
                   2557:     BusNumber - The bus number of the bus to search.
                   2558: 
                   2559:     First - TRUE is we are to search for the first instance of an
                   2560:     adapter, FALSE if we are to continue search from a previous stopping
                   2561:     point.
                   2562: 
                   2563:     Token - A pointer to a handle to return to identify the found
                   2564:     instance
                   2565: 
                   2566:     Confidence - A pointer to a long for storing the confidence factor
                   2567:     that the card exists.
                   2568: 
                   2569: Return Value:
                   2570: 
                   2571:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2572: 
                   2573: --*/
                   2574: 
                   2575: {
                   2576:     UNREFERENCED_PARAMETER(Token);
                   2577: 
                   2578:     return(DecCardFirstNext(SearchStateIndex,
                   2579:                             InterfaceType,
                   2580:                             BusNumber,
                   2581:                             First,
                   2582:                             De100String,
                   2583:                             Confidence
                   2584:                            )
                   2585:           );
                   2586: }
                   2587: LONG
                   2588: De200FirstNext(
                   2589:     IN  LONG SearchStateIndex,
                   2590:     IN  INTERFACE_TYPE InterfaceType,
                   2591:     IN  ULONG BusNumber,
                   2592:     IN  BOOL First,
                   2593:     OUT PVOID *Token,
                   2594:     OUT LONG *Confidence
                   2595:     )
                   2596: 
                   2597: /*++
                   2598: 
                   2599: Routine Description:
                   2600: 
                   2601:     This routine finds the instances of a physical adapter De200.
                   2602: 
                   2603: Arguments:
                   2604: 
                   2605:     SearchStateIndex - The index in SearchStates for the De200 adapter.
                   2606: 
                   2607:     InterfaceType - Either Isa, or Eisa.
                   2608: 
                   2609:     BusNumber - The bus number of the bus to search.
                   2610: 
                   2611:     First - TRUE is we are to search for the first instance of an
                   2612:     adapter, FALSE if we are to continue search from a previous stopping
                   2613:     point.
                   2614: 
                   2615:     Token - A pointer to a handle to return to identify the found
                   2616:     instance
                   2617: 
                   2618:     Confidence - A pointer to a long for storing the confidence factor
                   2619:     that the card exists.
                   2620: 
                   2621: Return Value:
                   2622: 
                   2623:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2624: 
                   2625: --*/
                   2626: 
                   2627: {
                   2628:     UNREFERENCED_PARAMETER(Token);
                   2629: 
                   2630:     return(DecCardFirstNext(SearchStateIndex,
                   2631:                             InterfaceType,
                   2632:                             BusNumber,
                   2633:                             First,
                   2634:                             De200String,
                   2635:                             Confidence
                   2636:                            )
                   2637:           );
                   2638: }
                   2639: LONG
                   2640: De201FirstNext(
                   2641:     IN  LONG SearchStateIndex,
                   2642:     IN  INTERFACE_TYPE InterfaceType,
                   2643:     IN  ULONG BusNumber,
                   2644:     IN  BOOL First,
                   2645:     OUT PVOID *Token,
                   2646:     OUT LONG *Confidence
                   2647:     )
                   2648: 
                   2649: /*++
                   2650: 
                   2651: Routine Description:
                   2652: 
                   2653:     This routine finds the instances of a physical adapter De201.
                   2654: 
                   2655: Arguments:
                   2656: 
                   2657:     SearchStateIndex - The index in SearchStates for the De201 adapter.
                   2658: 
                   2659:     InterfaceType - Either Isa, or Eisa.
                   2660: 
                   2661:     BusNumber - The bus number of the bus to search.
                   2662: 
                   2663:     First - TRUE is we are to search for the first instance of an
                   2664:     adapter, FALSE if we are to continue search from a previous stopping
                   2665:     point.
                   2666: 
                   2667:     Token - A pointer to a handle to return to identify the found
                   2668:     instance
                   2669: 
                   2670:     Confidence - A pointer to a long for storing the confidence factor
                   2671:     that the card exists.
                   2672: 
                   2673: Return Value:
                   2674: 
                   2675:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2676: 
                   2677: --*/
                   2678: 
                   2679: {
                   2680:     UNREFERENCED_PARAMETER(Token);
                   2681: 
                   2682:     return(DecCardFirstNext(SearchStateIndex,
                   2683:                             InterfaceType,
                   2684:                             BusNumber,
                   2685:                             First,
                   2686:                             De201String,
                   2687:                             Confidence
                   2688:                            )
                   2689:           );
                   2690: }
                   2691: LONG
                   2692: De101FirstNext(
                   2693:     IN  LONG SearchStateIndex,
                   2694:     IN  INTERFACE_TYPE InterfaceType,
                   2695:     IN  ULONG BusNumber,
                   2696:     IN  BOOL First,
                   2697:     OUT PVOID *Token,
                   2698:     OUT LONG *Confidence
                   2699:     )
                   2700: 
                   2701: /*++
                   2702: 
                   2703: Routine Description:
                   2704: 
                   2705:     This routine finds the instances of a physical adapter De101.
                   2706: 
                   2707: Arguments:
                   2708: 
                   2709:     SearchStateIndex - The index in SearchStates for the De101 adapter.
                   2710: 
                   2711:     InterfaceType - Either Isa, or Eisa.
                   2712: 
                   2713:     BusNumber - The bus number of the bus to search.
                   2714: 
                   2715:     First - TRUE is we are to search for the first instance of an
                   2716:     adapter, FALSE if we are to continue search from a previous stopping
                   2717:     point.
                   2718: 
                   2719:     Token - A pointer to a handle to return to identify the found
                   2720:     instance
                   2721: 
                   2722:     Confidence - A pointer to a long for storing the confidence factor
                   2723:     that the card exists.
                   2724: 
                   2725: Return Value:
                   2726: 
                   2727:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2728: 
                   2729: --*/
                   2730: 
                   2731: {
                   2732:     UNREFERENCED_PARAMETER(Token);
                   2733: 
                   2734:     return(DecCardFirstNext(SearchStateIndex,
                   2735:                             InterfaceType,
                   2736:                             BusNumber,
                   2737:                             First,
                   2738:                             De101String,
                   2739:                             Confidence
                   2740:                            )
                   2741:           );
                   2742: }
                   2743: LONG
                   2744: DePCAFirstNext(
                   2745:     IN  LONG SearchStateIndex,
                   2746:     IN  INTERFACE_TYPE InterfaceType,
                   2747:     IN  ULONG BusNumber,
                   2748:     IN  BOOL First,
                   2749:     OUT PVOID *Token,
                   2750:     OUT LONG *Confidence
                   2751:     )
                   2752: 
                   2753: /*++
                   2754: 
                   2755: Routine Description:
                   2756: 
                   2757:     This routine finds the instances of a physical adapter DePCA.
                   2758: 
                   2759: Arguments:
                   2760: 
                   2761:     SearchStateIndex - The index in SearchStates for the DePCA adapter.
                   2762: 
                   2763:     InterfaceType - Either Isa, or Eisa.
                   2764: 
                   2765:     BusNumber - The bus number of the bus to search.
                   2766: 
                   2767:     First - TRUE is we are to search for the first instance of an
                   2768:     adapter, FALSE if we are to continue search from a previous stopping
                   2769:     point.
                   2770: 
                   2771:     Token - A pointer to a handle to return to identify the found
                   2772:     instance
                   2773: 
                   2774:     Confidence - A pointer to a long for storing the confidence factor
                   2775:     that the card exists.
                   2776: 
                   2777: Return Value:
                   2778: 
                   2779:     0 if nothing went wrong, else the appropriate WINERROR.H value.
                   2780: 
                   2781: --*/
                   2782: 
                   2783: {
                   2784:     UCHAR Value;
                   2785:     HANDLE TrapHandle;
                   2786:     UCHAR Interrupt = 5;
                   2787:     NTSTATUS NtStatus;
                   2788: 
                   2789:     UNREFERENCED_PARAMETER(Token);
                   2790: 
                   2791:     if (!First) {
                   2792: 
                   2793:         *Confidence = 0;
                   2794:         return(0);
                   2795: 
                   2796:     }
                   2797: 
                   2798:     if (InterfaceType != Isa) {
                   2799: 
                   2800:         *Confidence = 0;
                   2801:         return(0);
                   2802: 
                   2803:     }
                   2804: 
                   2805:     //
                   2806:     // Check Memory base address
                   2807:     //
                   2808: 
                   2809:     if (!DecCardAt(InterfaceType,
                   2810:                    BusNumber,
                   2811:                    0xDC000,
                   2812:                    De100String
                   2813:                    )) {
                   2814: 
                   2815:         //
                   2816:         // Definitely not
                   2817:         //
                   2818: 
                   2819:         *Confidence = 0;
                   2820:         return(0);
                   2821: 
                   2822:     }
                   2823: 
                   2824:     //
                   2825:     // Check for the io base address
                   2826:     //
                   2827: 
                   2828:     if (!LanceHardwareDetails(InterfaceType, BusNumber, 0x20C)) {
                   2829: 
                   2830:         //
                   2831:         // Definitely not
                   2832:         //
                   2833: 
                   2834:         *Confidence = 0;
                   2835:         return(0);
                   2836: 
                   2837:     }
                   2838: 
                   2839:     //
                   2840:     // Check for the lan configuration register
                   2841:     //
                   2842: 
                   2843:     NtStatus = DetectReadPortUchar(
                   2844:                           InterfaceType,
                   2845:                           BusNumber,
                   2846:                           (ULONG)(0x800),
                   2847:                           &(Value)
                   2848:                           );
                   2849: 
                   2850:     if (NtStatus != STATUS_SUCCESS) {
                   2851: 
                   2852:         *Confidence = 0;
                   2853:         return(0);
                   2854: 
                   2855:     }
                   2856: 
                   2857:     if (Value == 0xFF) {
                   2858: 
                   2859:         //
                   2860:         // No such port, definitely not.
                   2861:         //
                   2862: 
                   2863:         *Confidence = 0;
                   2864:         return(0);
                   2865: 
                   2866:     }
                   2867: 
                   2868:     //
                   2869:     // Check for the interrupt
                   2870:     //
                   2871: 
                   2872:     //
                   2873:     // Set the interrupt trap -- we are checking the interrupt number now
                   2874:     //
                   2875: 
                   2876:     NtStatus = DetectSetInterruptTrap(
                   2877:                    InterfaceType,
                   2878:                    BusNumber,
                   2879:                    &TrapHandle,
                   2880:                    &Interrupt,
                   2881:                    1
                   2882:                    );
                   2883: 
                   2884:     if (NtStatus == STATUS_SUCCESS) {
                   2885: 
                   2886:         //
                   2887:         // Check that it is available
                   2888:         //
                   2889: 
                   2890:         NtStatus = DetectQueryInterruptTrap(
                   2891:                        TrapHandle,
                   2892:                        &Interrupt,
                   2893:                        1
                   2894:                        );
                   2895: 
                   2896:         if (NtStatus != STATUS_SUCCESS) {
                   2897: 
                   2898:             *Confidence = 0;
                   2899:             return(0);
                   2900: 
                   2901:         }
                   2902: 
                   2903:         if (Interrupt == 3) {
                   2904: 
                   2905:             //
                   2906:             // Remove interrupt trap
                   2907:             //
                   2908: 
                   2909:             DetectRemoveInterruptTrap(
                   2910:                        TrapHandle
                   2911:                        );
                   2912: 
                   2913:             *Confidence = 0;
                   2914:             return(0);
                   2915: 
                   2916:         }
                   2917: 
                   2918: 
                   2919:         //
                   2920:         // Create an interrupt
                   2921:         //
                   2922: 
                   2923:         //
                   2924:         // Enable Interrupts in NICSR
                   2925:         //
                   2926: 
                   2927:         NtStatus = DetectWritePortUshort(
                   2928:                        InterfaceType,
                   2929:                        BusNumber,
                   2930:                        (ULONG)(0x200),
                   2931:                        0x2
                   2932:                        );
                   2933: 
                   2934:         if (NtStatus != STATUS_SUCCESS) {
                   2935: 
                   2936:             *Confidence = 0;
                   2937:             return(0);
                   2938: 
                   2939:         }
                   2940: 
                   2941:         //
                   2942:         // Change to CSR0
                   2943:         //
                   2944: 
                   2945:         NtStatus = DetectWritePortUshort(
                   2946:                        InterfaceType,
                   2947:                        BusNumber,
                   2948:                        (ULONG)(0x206),
                   2949:                        0x0
                   2950:                        );
                   2951: 
                   2952:         if (NtStatus != STATUS_SUCCESS) {
                   2953: 
                   2954:             *Confidence = 0;
                   2955:             return(0);
                   2956: 
                   2957:         }
                   2958: 
                   2959:         //
                   2960:         // Write STOP bit
                   2961:         //
                   2962: 
                   2963:         NtStatus = DetectWritePortUshort(
                   2964:                        InterfaceType,
                   2965:                        BusNumber,
                   2966:                        (ULONG)(0x204),
                   2967:                        0x4
                   2968:                        );
                   2969: 
                   2970:         if (NtStatus != STATUS_SUCCESS) {
                   2971: 
                   2972:             *Confidence = 0;
                   2973:             return(0);
                   2974: 
                   2975:         }
                   2976: 
                   2977:         //
                   2978:         // Write INIT bit and INTERRUPT_ENABLE bit
                   2979:         //
                   2980: 
                   2981:         NtStatus = DetectWritePortUshort(
                   2982:                        InterfaceType,
                   2983:                        BusNumber,
                   2984:                        (ULONG)(0x204),
                   2985:                        0x41
                   2986:                        );
                   2987: 
                   2988:         if (NtStatus != STATUS_SUCCESS) {
                   2989: 
                   2990:             *Confidence = 0;
                   2991:             return(0);
                   2992: 
                   2993:         }
                   2994: 
                   2995:         Sleep(100);
                   2996: 
                   2997:         //
                   2998:         // Write STOP bit
                   2999:         //
                   3000: 
                   3001:         NtStatus = DetectWritePortUshort(
                   3002:                        InterfaceType,
                   3003:                        BusNumber,
                   3004:                        (ULONG)(0x204),
                   3005:                        0x4
                   3006:                        );
                   3007: 
                   3008:         if (NtStatus != STATUS_SUCCESS) {
                   3009: 
                   3010:             return(ERROR_INVALID_PARAMETER);
                   3011: 
                   3012:         }
                   3013: 
                   3014:         //
                   3015:         // Disable Interrupts in NICSR
                   3016:         //
                   3017: 
                   3018:         NtStatus = DetectWritePortUshort(
                   3019:                        InterfaceType,
                   3020:                        BusNumber,
                   3021:                        (ULONG)(0x200),
                   3022:                        0x4
                   3023:                        );
                   3024: 
                   3025:         if (NtStatus != STATUS_SUCCESS) {
                   3026: 
                   3027:             return(ERROR_INVALID_PARAMETER);
                   3028: 
                   3029:         }
                   3030: 
                   3031:         //
                   3032:         // Check which one went off
                   3033:         //
                   3034: 
                   3035:         NtStatus = DetectQueryInterruptTrap(
                   3036:                        TrapHandle,
                   3037:                        &Interrupt,
                   3038:                        1
                   3039:                        );
                   3040: 
                   3041:         if (NtStatus != STATUS_SUCCESS) {
                   3042: 
                   3043:             *Confidence = 0;
                   3044:             return(0);
                   3045: 
                   3046:         }
                   3047: 
                   3048:         //
                   3049:         // Remove interrupt trap
                   3050:         //
                   3051: 
                   3052:         NtStatus = DetectRemoveInterruptTrap(
                   3053:                        TrapHandle
                   3054:                        );
                   3055: 
                   3056:         if (NtStatus != STATUS_SUCCESS) {
                   3057: 
                   3058:             *Confidence = 0;
                   3059:             return(0);
                   3060: 
                   3061:         }
                   3062: 
                   3063: 
                   3064:         //
                   3065:         // Everything checks out
                   3066:         //
                   3067: 
                   3068:         if ((Interrupt == 1) || (Interrupt == 2)) {
                   3069: 
                   3070:             *Confidence = 100;
                   3071: 
                   3072:             return(0);
                   3073: 
                   3074:         }
                   3075: 
                   3076:     }
                   3077: 
                   3078:     *Confidence = 0;
                   3079:     return(0);
                   3080: 
                   3081: }
                   3082: 
                   3083: BOOLEAN
                   3084: LanceHardwareDetails(
                   3085:     IN INTERFACE_TYPE InterfaceType,
                   3086:     IN ULONG BusNumber,
                   3087:     IN ULONG IoBaseAddress
                   3088:     )
                   3089: 
                   3090: /*++
                   3091: 
                   3092: Routine Description:
                   3093: 
                   3094:     This routine checks for a signature in a well known port address
                   3095: 
                   3096: Arguments:
                   3097: 
                   3098:     InterfaceType - The type of the bus, EISA or Isa.
                   3099: 
                   3100:     BusNumber - The number of the bus in the system.
                   3101: 
                   3102:     IoBaseAddress - Address of port with the Lance signature.
                   3103: 
                   3104: Return Value:
                   3105: 
                   3106:     TRUE - if successful.
                   3107: 
                   3108: --*/
                   3109: 
                   3110: {
                   3111:     UCHAR Signature[] = { 0xff, 0x00, 0x55, 0xaa, 0xff, 0x00, 0x55, 0xaa};
                   3112:     UCHAR BytesRead[8];
                   3113:     NTSTATUS NtStatus;
                   3114:     UINT ReadCount;
                   3115: 
                   3116:     UINT Place;
                   3117: 
                   3118:     //
                   3119:     // Reset E-PROM state
                   3120:     //
                   3121:     // To do this we first read from the E-PROM address until the
                   3122:     // specific signature is reached (then the next bytes read from
                   3123:     // the E-PROM address will be the ethernet address of the card).
                   3124:     //
                   3125: 
                   3126: 
                   3127: 
                   3128:     //
                   3129:     // Read first part of the signature
                   3130:     //
                   3131: 
                   3132:     for (Place=0; Place < 8; Place++){
                   3133: 
                   3134:         NtStatus = DetectReadPortUchar(
                   3135:                           InterfaceType,
                   3136:                           BusNumber,
                   3137:                           (ULONG)(IoBaseAddress),
                   3138:                           &(BytesRead[Place])
                   3139:                           );
                   3140: 
                   3141:         if (NtStatus != STATUS_SUCCESS) {
                   3142: 
                   3143:             return(FALSE);
                   3144: 
                   3145:         }
                   3146: 
                   3147:     }
                   3148: 
                   3149:     ReadCount = 8;
                   3150: 
                   3151:     //
                   3152:     // This advances to the front of the circular buffer.
                   3153:     //
                   3154: 
                   3155:     while (ReadCount < 40) {
                   3156: 
                   3157:         //
                   3158:         // Check if we have read the signature.
                   3159:         //
                   3160: 
                   3161:         for (Place = 0; Place < 8; Place++){
                   3162: 
                   3163:             if (BytesRead[Place] != Signature[Place]){
                   3164: 
                   3165:                 Place = 10;
                   3166:                 break;
                   3167: 
                   3168:             }
                   3169: 
                   3170:         }
                   3171: 
                   3172:         //
                   3173:         // If we have read the signature, stop.
                   3174:         //
                   3175: 
                   3176:         if (Place != 10){
                   3177: 
                   3178:             break;
                   3179: 
                   3180:         }
                   3181: 
                   3182:         //
                   3183:         // else, move all the bytes down one and read then
                   3184:         // next byte.
                   3185:         //
                   3186: 
                   3187:         for (Place = 0; Place < 7; Place++){
                   3188: 
                   3189:             BytesRead[Place] = BytesRead[Place+1];
                   3190: 
                   3191:         }
                   3192: 
                   3193:         NtStatus = DetectReadPortUchar(
                   3194:                           InterfaceType,
                   3195:                           BusNumber,
                   3196:                           (ULONG)(IoBaseAddress),
                   3197:                           &(BytesRead[7]));
                   3198: 
                   3199:         if (NtStatus != STATUS_SUCCESS) {
                   3200: 
                   3201:             return(FALSE);
                   3202: 
                   3203:         }
                   3204: 
                   3205:         ReadCount++;
                   3206:     }
                   3207: 
                   3208: 
                   3209:     if (ReadCount == 40){
                   3210: 
                   3211:         return(FALSE);
                   3212: 
                   3213:     }
                   3214: 
                   3215:     return(TRUE);
                   3216: 
                   3217: }

unix.superglobalmegacorp.com

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