|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.