|
|
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.