|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 Microsoft Corporation
4:
5: Module Name:
6:
7: mips\atd_conf.c
8:
9: Abstract:
10:
11: This file includes the routine to get mips platform-dependent
12: configuration information for the AT disk (aka ST506, and ISA
13: standard hard disk) driver for NT.
14:
15: If this driver is ported to a different platform, this file (and
16: atd_plat.h) will need to be modified extensively.
17:
18: Author:
19:
20: Chad Schwitters (CHADS)
21: Mike Glass (MGLASS)
22: Tony Ercolano (TONYE)
23:
24: Environment:
25:
26: Kernel mode only.
27:
28: Notes:
29:
30: Revision History:
31:
32: --*/
33:
34: #include "ntddk.h" // various NT definitions
35: #include "ntdddisk.h" // disk device driver I/O control codes
36: #include <atd_plat.h> // this driver's platform dependent stuff
37: #include <atd_data.h> // this driver's data declarations
38:
39: NTSTATUS
40: AtConfigCallBack(
41: IN PVOID Context,
42: IN PUNICODE_STRING PathName,
43: IN INTERFACE_TYPE BusType,
44: IN ULONG BusNumber,
45: IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
46: IN CONFIGURATION_TYPE ControllerType,
47: IN ULONG ControllerNumber,
48: IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
49: IN CONFIGURATION_TYPE PeripheralType,
50: IN ULONG PeripheralNumber,
51: IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
52: );
53:
54: BOOLEAN
55: GetGeometryFromIdentify(
56: PCONTROLLER_DATA ControllerData,
57: ULONG DiskNumber
58: );
59:
60: NTSTATUS
61: AtCreateNumericKey(
62: IN HANDLE Root,
63: IN ULONG Name,
64: IN PWSTR Prefix,
65: OUT PHANDLE NewKey
66: );
67:
68: BOOLEAN
69: IssueIdentify(
70: PCONTROLLER_DATA ControllerData,
71: PUCHAR Buffer,
72: ULONG DiskNumber
73: );
74:
75: #ifdef ALLOC_PRAGMA
76: #pragma alloc_text(init,AtConfigCallBack)
77: #pragma alloc_text(init,AtGetConfigInfo)
78: #endif
79:
80:
81: NTSTATUS
82: AtConfigCallBack(
83: IN PVOID Context,
84: IN PUNICODE_STRING PathName,
85: IN INTERFACE_TYPE BusType,
86: IN ULONG BusNumber,
87: IN PKEY_VALUE_FULL_INFORMATION *BusInformation,
88: IN CONFIGURATION_TYPE ControllerType,
89: IN ULONG ControllerNumber,
90: IN PKEY_VALUE_FULL_INFORMATION *ControllerInformation,
91: IN CONFIGURATION_TYPE PeripheralType,
92: IN ULONG PeripheralNumber,
93: IN PKEY_VALUE_FULL_INFORMATION *PeripheralInformation
94: )
95:
96: /*++
97:
98: Routine Description:
99:
100: This routine is used to acquire all of the configuration
101: information for each floppy disk controller and the
102: peripheral driver attached to that controller.
103:
104: Arguments:
105:
106: Context - Pointer to boolean.
107:
108: PathName - unicode registry path. Not Used.
109:
110: BusType - Internal, Isa, ...
111:
112: BusNumber - Should Always be zero.
113:
114: BusInformation - Configuration information about the bus. Not Used.
115:
116: ControllerType - Controller Type. Not Used.
117:
118: ControllerNumber - Which controller if there is more than one
119: controller in the system. Not Used
120:
121: ControllerInformation - Array of pointers to the three pieces of
122: registry information. Not Used
123:
124: PeripheralType - Peripheral Type. Not Used.
125:
126: PeripheralNumber - Which floppy if this controller is maintaining
127: more than one. Not Used
128:
129: PeripheralInformation - Arrya of pointers to the three pieces of
130: registry information. Not Used.
131:
132: Return Value:
133:
134: STATUS_SUCCESS
135:
136: --*/
137:
138: {
139:
140: ASSERT(BusNumber == 0);
141: *((PBOOLEAN)Context) = TRUE;
142: return STATUS_SUCCESS;
143:
144: }
145:
146: NTSTATUS
147: AtGetConfigInfo(
148: IN PDRIVER_OBJECT DriverObject,
149: IN PUNICODE_STRING RegistryPath,
150: IN OUT PCONFIG_DATA ConfigData
151: )
152:
153: /*++
154:
155: Routine Description:
156:
157: This routine is called once at initialization time by
158: AtDiskInitialize() to get information about the disks that are to be
159: supported.
160:
161: Some values here are simply assumed (i.e. number of controllers, and
162: base address of controller). Other are determined by poking CMOS
163: (i.e. how many drives are on the controller) or by peering into ROM (i.e.
164: sectors per track for each drive).
165:
166: Arguments:
167:
168: DriverObject - The driver object for this driver.
169:
170: RegistryPath - The string that takes us to this drivers service node.
171:
172: ConfigData - a pointer to the pointer to a data structure that
173: describes the controllers and the disks attached to them
174:
175: Return Value:
176:
177: Returns STATUS_SUCCESS unless there is no drive 0.
178:
179: --*/
180:
181: {
182: ULONG i, j, k;
183: PCONFIGURATION_INFORMATION configurationInformation;
184: BOOLEAN foundIt = FALSE;
185: ULONG diskCount;
186: INTERFACE_TYPE defaultInterfaceType;
187: ULONG defaultBusNumber;
188: KIRQL defaultIrql;
189: PHYSICAL_ADDRESS defaultBaseAddress;
190: PHYSICAL_ADDRESS defaultPortAddress;
191: UCHAR buffer[512];
192:
193: //
194: // Get the temporary configuration manager information.
195: //
196:
197: configurationInformation = IoGetConfigurationInformation( );
198: ConfigData->HardDiskCount = &configurationInformation->DiskCount;
199: ConfigData->ArcNamePrefix = TemporaryArcNamePrefix;
200: diskCount = configurationInformation->DiskCount;
201:
202: //
203: // This driver only knows how to work on the first isa
204: // or eisa bus in the system. Call IoQeuryDeviceDescription
205: // to make sure that there is such a bus on the system.
206: //
207:
208: foundIt = FALSE;
209:
210: //
211: // If it can't find the bus then just assume that it's the
212: // first isa bus.
213: //
214:
215: defaultInterfaceType = Isa;
216: defaultBusNumber = 0;
217:
218: //
219: // Start out with the assumption that it's *NOT* ok to use
220: // the controllers.
221: //
222:
223: ConfigData->Controller[0].OkToUseThisController = FALSE;
224: ConfigData->Controller[1].OkToUseThisController = FALSE;
225:
226: IoQueryDeviceDescription(
227: &defaultInterfaceType,
228: &defaultBusNumber,
229: NULL,
230: NULL,
231: NULL,
232: NULL,
233: AtConfigCallBack,
234: &foundIt
235: );
236:
237: if (!foundIt) {
238:
239: defaultInterfaceType = Eisa;
240: defaultBusNumber = 0;
241: IoQueryDeviceDescription(
242: &defaultInterfaceType,
243: &defaultBusNumber,
244: NULL,
245: NULL,
246: NULL,
247: NULL,
248: AtConfigCallBack,
249: &foundIt
250: );
251:
252: if (!foundIt) {
253:
254: defaultInterfaceType = Isa;
255: defaultBusNumber = 0;
256: AtDump(
257: ATERRORS,
258: ("ATDISK: Not EISA OR ISA BY CONFIG, ASSUME ISA\n")
259: );
260:
261: }
262: }
263:
264: //
265: // Check if primary io range is unclaimed.
266: //
267:
268: if (!configurationInformation->AtDiskPrimaryAddressClaimed) {
269:
270: //
271: // Fill in controller description.
272: //
273:
274: defaultBaseAddress.LowPart = 0x1f0;
275: defaultBaseAddress.HighPart = 0;
276: defaultPortAddress.LowPart = 0x3f6;
277: defaultPortAddress.HighPart = 0;
278:
279: defaultIrql = 14;
280: AtDiskControllerInfo(
281: DriverObject,
282: RegistryPath,
283: 0,
284: &ConfigData->Controller[0],
285: defaultBaseAddress,
286: defaultPortAddress,
287: defaultIrql,
288: defaultInterfaceType,
289: defaultBusNumber,
290: TRUE
291: );
292:
293: //
294: // On mips we always assume that we supposed to set
295: // the high bit in the low nibble for the control
296: // register.
297: //
298:
299: ConfigData->Controller[0].ControlFlags = 0x08;
300:
301: if (!AtControllerPresent(&ConfigData->Controller[0])) {
302:
303: goto SecondaryControllerCheck;
304:
305: }
306:
307: if (!AtResetController(
308: ConfigData->Controller[0].ControllerBaseAddress + STATUS_REGISTER,
309: ConfigData->Controller[0].ControlPortAddress,
310: ConfigData->Controller[0].ControlFlags
311: )) {
312:
313: goto SecondaryControllerCheck;
314:
315: }
316:
317: ConfigData->Controller[0].OkToUseThisController = TRUE;
318:
319: //
320: // Claim ATDISK primary IO address range.
321: //
322:
323: configurationInformation->AtDiskPrimaryAddressClaimed = TRUE;
324:
325:
326: //
327: // Get geometry information for disk 0 from IDENTIFY command.
328: //
329:
330: if (GetGeometryFromIdentify(&ConfigData->Controller[0],
331: 0)) {
332:
333: diskCount++;
334: ConfigData->Controller[0].Disk[0].DriveType = 0xFF;
335:
336: //
337: // Get geometry information for disk 1 from IDENTIFY command.
338: //
339:
340: if (GetGeometryFromIdentify(&ConfigData->Controller[0],
341: 1)) {
342:
343: diskCount++;
344: ConfigData->Controller[0].Disk[1].DriveType = 0xFF;
345: }
346: }
347: }
348:
349: //
350: // Check for secondary io range is unclaimed.
351: //
352: SecondaryControllerCheck:;
353:
354: if (!configurationInformation->AtDiskSecondaryAddressClaimed) {
355:
356: defaultBaseAddress.LowPart = 0x170;
357: defaultBaseAddress.HighPart = 0;
358: defaultPortAddress.LowPart = 0x376;
359: defaultPortAddress.HighPart = 0;
360:
361: defaultIrql = 15;
362: AtDiskControllerInfo(
363: DriverObject,
364: RegistryPath,
365: 1,
366: &ConfigData->Controller[1],
367: defaultBaseAddress,
368: defaultPortAddress,
369: defaultIrql,
370: defaultInterfaceType,
371: defaultBusNumber,
372: TRUE
373: );
374:
375: ConfigData->Controller[1].ControlFlags = 0x08;
376: if (!AtControllerPresent(&ConfigData->Controller[1])) {
377:
378: goto AllTheRestControllerCheck;
379:
380: }
381:
382: if (!AtResetController(
383: ConfigData->Controller[1].ControllerBaseAddress + STATUS_REGISTER,
384: ConfigData->Controller[1].ControlPortAddress,
385: ConfigData->Controller[1].ControlFlags
386: )) {
387:
388: goto AllTheRestControllerCheck;
389:
390: }
391:
392:
393: ConfigData->Controller[1].OkToUseThisController = TRUE;
394:
395: //
396: // Get geometry information for disk 0 from IDENTIFY command.
397: //
398:
399: configurationInformation->AtDiskSecondaryAddressClaimed = TRUE;
400:
401: if (GetGeometryFromIdentify(&ConfigData->Controller[1],
402: 0)) {
403:
404: diskCount++;
405: ConfigData->Controller[1].Disk[0].DriveType = 0xFF;
406:
407: //
408: // Get geometry information for disk 1 from IDENTIFY command.
409: //
410:
411: if (GetGeometryFromIdentify(&ConfigData->Controller[1],
412: 1)) {
413:
414: diskCount++;
415: ConfigData->Controller[1].Disk[1].DriveType = 0xFF;
416: }
417: }
418:
419: }
420:
421: //
422: // Go for the remaining controllers that we can deal with.
423: //
424:
425: AllTheRestControllerCheck:;
426:
427: for (i=2;i < MAXIMUM_NUMBER_OF_CONTROLLERS;i++) {
428:
429:
430: if (AtDiskControllerInfo(
431: DriverObject,
432: RegistryPath,
433: i,
434: &ConfigData->Controller[i],
435: defaultBaseAddress,
436: defaultPortAddress,
437: defaultIrql,
438: defaultInterfaceType,
439: defaultBusNumber,
440: FALSE
441: )) {
442:
443:
444: ConfigData->Controller[1].ControlFlags = 0x08;
445: if (!AtControllerPresent(&ConfigData->Controller[i])) {
446:
447: continue;
448:
449: }
450:
451: if (!AtResetController(
452: ConfigData->Controller[i].ControllerBaseAddress + STATUS_REGISTER,
453: ConfigData->Controller[i].ControlPortAddress,
454: ConfigData->Controller[i].ControlFlags
455: )) {
456:
457: continue;
458:
459: }
460:
461: ConfigData->Controller[i].OkToUseThisController = TRUE;
462:
463: //
464: // Get geometry information for disk 0 from IDENTIFY command.
465: //
466:
467: if (GetGeometryFromIdentify(&ConfigData->Controller[i],
468: 0)) {
469:
470: diskCount++;
471: ConfigData->Controller[i].Disk[0].DriveType = 0xFF;
472:
473: //
474: // Get geometry information for disk 1 from IDENTIFY command.
475: //
476:
477: if (GetGeometryFromIdentify(&ConfigData->Controller[i],
478: 1)) {
479:
480: diskCount++;
481: ConfigData->Controller[i].Disk[1].DriveType = 0xFF;
482: }
483: }
484: }
485: }
486:
487:
488: //
489: // Check if any disks were found.
490: //
491:
492: if (!diskCount) {
493: return STATUS_NO_SUCH_DEVICE;
494: }
495:
496: //
497: // Update device map in registry with disk information.
498: //
499:
500: for (i=0; i< MAXIMUM_NUMBER_OF_CONTROLLERS; i++) {
501: for (j=0; j < MAXIMUM_NUMBER_OF_DISKS_PER_CONTROLLER; j++) {
502:
503:
504: if (!ConfigData->Controller[i].Disk[j].DriveType) {
505: continue;
506: }
507:
508: //
509: // Issue IDENTIFY command.
510: //
511:
512: if (IssueIdentify(&ConfigData->Controller[i],
513: buffer,
514: j)) {
515:
516: PUSHORT tempS;
517: UCHAR tempByte;
518:
519: //
520: // Byte flip model number, revision, and serial number string.
521: //
522:
523: tempS = ((PIDENTIFY_DATA)buffer)->ModelNumber;
524: for (k=0; k<20; k++) {
525: tempByte = (UCHAR)(tempS[k] & 0x00FF);
526: tempS[k] = tempS[k] >> 8;
527: tempS[k] |= tempByte << 8;
528: }
529:
530: tempS = ((PIDENTIFY_DATA)buffer)->FirmwareRevision;
531: for (k=0; k<4; k++) {
532: tempByte = (UCHAR)(tempS[k] & 0x00FF);
533: tempS[k] = tempS[k] >> 8;
534: tempS[k] |= tempByte << 8;
535: }
536:
537: tempS = ((PIDENTIFY_DATA)buffer)->SerialNumber;
538: for (k=0; k<10; k++) {
539: tempByte = (UCHAR)(tempS[k] & 0x00FF);
540: tempS[k] = tempS[k] >> 8;
541: tempS[k] |= tempByte << 8;
542: }
543:
544: AtBuildDeviceMap(i,
545: j,
546: ConfigData->Controller[i].OriginalControllerBaseAddress,
547: ConfigData->Controller[i].OriginalControllerIrql,
548: &ConfigData->Controller[i].Disk[j],
549: (PIDENTIFY_DATA)buffer);
550:
551: } else {
552:
553: RtlZeroMemory(
554: &buffer[0],
555: 512
556: );
557:
558: }
559: }
560: }
561:
562: return STATUS_SUCCESS;
563: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.