|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1991 Microsoft Corporation
4:
5: Module Name:
6:
7: atd_data.h
8:
9: Abstract:
10:
11: This file includes data and hardware (non-platform-dependent)
12: declarations for the AT disk (aka ST506 and standard hard disk)
13: driver for NT.
14:
15: Author:
16:
17: Chad Schwitters (chads) 21-Feb-1991.
18:
19: Environment:
20:
21: Kernel mode only.
22:
23: Notes:
24:
25: Revision History:
26:
27: --*/
28:
29:
30:
31: //
32: // Define our out dbg print routines.
33: //
34:
35: #if DBG
36: extern ULONG AtDebugLevel;
37: #define ATBUGCHECK ((ULONG)0x80000000)
38: #define ATDIAG1 ((ULONG)0x00000001)
39: #define ATDIAG2 ((ULONG)0x00000002)
40: #define ATERRORS ((ULONG)0x00000004)
41: #define ATINIT ((ULONG)0x00000008)
42: #define AtDump(LEVEL,STRING) \
43: do { \
44: ULONG _level = (LEVEL); \
45: if (AtDebugLevel & _level) { \
46: DbgPrint STRING; \
47: } \
48: if (_level == ATBUGCHECK) { \
49: ASSERT(FALSE); \
50: } \
51: } while (0)
52: #else
53: #define AtDump(LEVEL,STRING) do {NOTHING;} while (0)
54: #endif
55:
56: //BUGBUG delete TemporaryArcNamePrefix when HalGetNumberOfBusses is defined
57:
58: #if defined(i386) || (defined(MIPS) && defined(COMPAQ))
59: static CCHAR TemporaryArcNamePrefix[] = { "\\ArcName\\multi(0)" };
60: #else
61: static CCHAR TemporaryArcNamePrefix[] = { "\\ArcName\\eisa(0)" };
62: #endif
63:
64: //
65: // The number of controllers is arbitrary. No machines with more than
66: // two are known, but we'll use a larger number to be safe. The number
67: // of disks per controller is a hardware limitation, and some of the code
68: // takes advantage of the fact that it's known to be 2.
69: //
70:
71: #define MAXIMUM_NUMBER_OF_CONTROLLERS 6
72: #define MAXIMUM_NUMBER_OF_DISKS_PER_CONTROLLER 2
73:
74: //
75: // For device name manipulation, we allocate a buffer since there is no
76: // preset limit on name size. The system hands us a prefix, and we
77: // allocate the buffer to be the size of that prefix plus the delta defined
78: // below. This size gives us room for
79: // PREFIX + <disk number> + \partition + <partition number>
80: // with up to five digits per number.
81: //
82:
83: #define DEVICE_NAME_DELTA 20
84:
85: //
86: // Partitions need to be linked to ARC names, in case we're booting off
87: // the partition. The system hands us a prefix, and we allocate the
88: // buffer to be the size of that prefix plus the delta defined below.
89: // This size gives us room for
90: // PREFIX + disk(<#>)rdisk(<#>)partition(<#>)
91: // with up to five digits per number.
92: //
93:
94: #define ARC_NAME_DELTA 39
95:
96: //
97: // When writing a message to the error log file, we need to allocate a
98: // buffer for the message. This is the message structure we impose, along
99: // with some values for the first field.
100: //
101:
102: typedef struct _ERROR_LOG_ENTRY {
103: CCHAR ErrorType;
104: CCHAR Data1;
105: CCHAR Data2;
106: CCHAR Data3;
107: CCHAR Data4;
108: CCHAR Data5;
109: } ERROR_LOG_ENTRY;
110: typedef ERROR_LOG_ENTRY *PERROR_LOG_ENTRY;
111:
112: #define ERROR_LOG_ENTRY_LENGTH sizeof( ERROR_LOG_ENTRY )
113:
114: #define ERROR_LOG_TYPE_CORRECTABLE_ERROR 1
115: #define ERROR_LOG_TYPE_ERROR 2
116: #define ERROR_LOG_TYPE_TIMEOUT 3
117: #define ERROR_LOG_TYPE_TIMEOUT_DURING_RESET 4
118:
119: //
120: // If the hardware state gets messed up, we'll retry the current packet.
121: // This says how many times we'll retry before giving up and returning
122: // an error. Note that the hardware invisibly retries 8 times.
123: //
124:
125: #define RETRY_IRP_MAXIMUM_COUNT 10
126:
127: //
128: // When we're resetting the controller, we have to go through some states
129: // as various operations finish (that is, interrupt). Here's the states
130: // in order.
131: //
132:
133: #define RESET_NOT_RESETTING 0
134: #define RESET_FIRST_DRIVE_SET 1
135: #define RESET_FIRST_DRIVE_RECALIBRATED 2
136: #define RESET_SECOND_DRIVE_SET 3
137: #define RESET_SECOND_DRIVE_RECALIBRATED 4
138:
139: //
140: // The I/O system calls our timer routine once every second. If the timer
141: // counter is -1, the timer is "off" and the timer routine will just return.
142: // When we want to make sure a hardware event will occur, we set the timer.
143: // The timer routine decrements the counter once a second. The timer
144: // expires if the counter hits 0. We give the timer extra time for
145: // recalibrates since they're so slow.
146: //
147:
148: #define CANCEL_TIMER -1
149: #define EXPIRED_TIMER 0
150: #define START_TIMER 9
151: #define START_TIMER_FOR_RECALIBRATE 11
152: #define START_BUSY_COUNTDOWN 60
153:
154: //
155: // ST506 controller commands for the command register.
156: //
157:
158: #define READ_COMMAND 0x20 // retries enabled
159: #define WRITE_COMMAND 0x30 // retries enabled
160: #define RECALIBRATE_COMMAND 0x10 // move drive heads to track 0
161: #define SEEK_COMMAND 0x70 // normally implied in read/write
162: #define SET_DRIVE_PARAMETERS_COMMAND 0x91 // set drive parameters
163: #define IDENTIFY_COMMAND 0xEC // identify drive parameters
164:
165: //
166: // ST506 controller bit masks for the status register.
167: //
168:
169: #define BUSY_STATUS 0x80 // busy bit in status register
170: #define ERROR_STATUS 0x01 // error bit in status register
171: #define CORRECTED_ERROR_STATUS 0x04 // corrected error in status register
172: #define DATA_REQUEST_STATUS 0x08 // data request bit in status register
173:
174: //
175: // ST506 controller bit masks for the drive select/head register.
176: //
177:
178: #define DRIVE_1 0xA0 // drive 1 (C:), 512 bytes/sector
179: // DRIVE/HEAD port, ext bit on
180: #define DRIVE_2_SELECTED 0x10 // bit that says drive 2 is selected
181:
182: #define DRIVE_2 DRIVE_1 | DRIVE_2_SELECTED
183:
184: //
185: // Define object extensions used by the driver. The first is a controller
186: // extension, which starts at the end of each controller object.
187: //
188:
189: typedef struct _CONTROLLER_EXTENSION {
190: PCONTROLLER_OBJECT ControllerObject; // "extension" points to object
191: struct _CONTROLLER_EXTENSION *NextControllerExtension; // link 'em together
192: struct _DISK_EXTENSION *Disk1; // have to access the disks from ISR
193: struct _DISK_EXTENSION *Disk2; // this one's NULL if only one disk
194: PKPOWER_NOTIFY PowerNotifyObject; // ptr to power notify object
195: PKPOWER_STATUS PowerStatusObject1; // ptr to 1st power status object
196: PKPOWER_STATUS PowerStatusObject2; // ptr to 2nd power status object
197: PKDPC PowerNotifyDpcObject; // ptr to DPC object for power notify
198: PDEVICE_OBJECT WhichDeviceObject; // set to D.O. that expects interrupt
199: PDEVICE_OBJECT FirstFailingDeviceObject; // for timeout while resetting
200: PUCHAR ControllerAddress; // base addr of controller registers
201: PUCHAR ControlPortAddress;
202: LONG InterruptTimer; // used to time out operations
203: CCHAR ResettingController; // >0 while controller is being reset
204: CCHAR ControlFlags; // OR into CONTROL_PORT
205: BOOLEAN InterruptRequiresDpc; // true if ISR should queue DPC
206: BOOLEAN PowerFailed; // system sets to TRUE @ power fail
207: BOOLEAN PowerRecoveryNotDone;
208: BOOLEAN ControllerAddressMapped;
209: BOOLEAN ControllerPortMapped;
210: struct _DISK_EXTENSION *BusyDevice; // Set when we find the device is
211: // busy (e.g. spin up on laptop)
212: LONG BusyCountDown;
213: PKINTERRUPT InterruptObject; // only one needed per controller
214: CCHAR GarbageCan[1]; // THIS MUST BE AT THE END OF
215: // OF THE CONTROLLER EXTENSION!!!
216: // When the controller extension
217: // is allocated we will actually
218: // allocate
219: // sizeof(CONTROLLER_EXTENSION) +
220: // (BYTES_PER_INTERRUPT-1) where
221: // GarbageCan will be an array
222: // of size BYTES_PER_INTERRUPT.
223: // This array is used to fill
224: // and empty the controller cache
225: // in case of an error.
226: } CONTROLLER_EXTENSION;
227:
228: typedef CONTROLLER_EXTENSION *PCONTROLLER_EXTENSION;
229:
230: //
231: // This is the disk extension, which is attached to all partition 0
232: // device objects (which represent the disk). Note that the first three
233: // fields are identical to those of the partition extension, so that the
234: // same code can access the disk via partition 0 or partition n.
235: //
236:
237: typedef struct _DISK_EXTENSION {
238: struct _DISK_EXTENSION *Partition0; // ptr to self; must be first field
239: LARGE_INTEGER StartingOffset; // first disk sector of this partition
240: LARGE_INTEGER PartitionLength; // number of sectors in partition
241: PCONTROLLER_EXTENSION ControllerExtension; // ptr to disk's controller
242: PDEVICE_OBJECT DeviceObject; // ptr to this disk's object
243: PDEVICE_OBJECT PartitionObjects; // ptr to chain of partition objects
244: struct _DISK_EXTENSION *OtherDiskExtension; // other disk on controller
245: ULONG FirstSectorOfRequest; // start sector of whole request
246: ULONG FirstSectorOfTransfer; // start sector for current transfer
247: ULONG RemainingRequestLength; // # of sectors left in current op
248: ULONG TotalTransferLength; // length of current transfer
249: ULONG RemainingTransferLength; // length left in current transfer
250: ULONG SequenceNumber; // Sequence number that is incremented
251: // on every new irp for this device.
252: HANDLE DirectoryHandle; // handle to disk's device directory
253: PCCHAR CurrentAddress; // working address in user's buffer
254: USHORT BytesPerSector; // disk-specific values
255: USHORT SectorsPerTrack; // ...
256: USHORT PretendSectorsPerTrack; // ...
257: USHORT NumberOfCylinders; // ...
258: USHORT PretendNumberOfCylinders; // ...
259: USHORT TracksPerCylinder; // ...
260: USHORT PretendTracksPerCylinder; // ...
261: USHORT WritePrecomp; // ...
262: USHORT BytesPerInterrupt; // ...
263: CCHAR ByteShiftToSector; // ...
264: CCHAR ReadCommand; // ...
265: CCHAR WriteCommand; // ...
266: CCHAR VerifyCommand; // ...
267: CCHAR OperationType; // current command (ie IRP_MJ_READ)
268: UCHAR DeviceUnit; // which disk we are to the controller
269: CCHAR IrpRetryCount; // count of retries by driver
270: BOOLEAN PacketIsBeingRetried; // when driver calls AtDiskStartIo
271: } DISK_EXTENSION;
272:
273: typedef DISK_EXTENSION *PDISK_EXTENSION;
274:
275: //
276: // This is the partition extension, which is attached to all partition
277: // "n" device objects - except for partition 0, which gets a disk
278: // extension. Note that the first three fields are identical to those of
279: // the disk extension, so that the same code can access the disk via
280: // partition 0 or partition n.
281: //
282:
283: typedef struct _PARTITION_EXTENSION {
284: PDISK_EXTENSION Partition0; // ptr to partn. 0, must be 1st field
285: LARGE_INTEGER StartingOffset; // first disk sector of this partition
286: LARGE_INTEGER PartitionLength; // number of sectors in partition
287: LARGE_INTEGER HiddenSectors; // number of hidden sectors
288: PDEVICE_OBJECT NextPartitionObject; // ptr to next partition's object
289: ULONG PartitionNumber; // 1-based number of partition
290: UCHAR PartitionType; // type of this partition
291: BOOLEAN BootIndicator; // indicates partition bootable or not
292: } PARTITION_EXTENSION;
293: typedef PARTITION_EXTENSION *PPARTITION_EXTENSION;
294:
295: //
296: // Fixed disk parameter table structure
297: //
298:
299: #pragma pack(1) // This structure is packed
300: typedef struct _FIXED_DISK_PARAMETER_TABLE {
301: USHORT MaxCylinders;
302: CCHAR MaxHeads;
303: UCHAR Signature;
304: UCHAR TranslatedSectorsPerTrack;
305: USHORT StartWritePrecomp;
306: CCHAR EccBurstLength;
307: CCHAR ControlFlags;
308: USHORT TranslatedMaxCylinders;
309: UCHAR TranslatedMaxHeads;
310: USHORT LandingZone;
311: CCHAR SectorsPerTrack;
312: UCHAR ReservedForFuture;
313: } FIXED_DISK_PARAMETER_TABLE;
314:
315: typedef FIXED_DISK_PARAMETER_TABLE *PFIXED_DISK_PARAMETER_TABLE;
316:
317: #pragma pack()
318:
319: //
320: // This structure holds all of the configuration data; it's filled in by
321: // AtGetConfigInfo() and read by other initialization routines.
322: //
323:
324: typedef struct _DRIVE_DATA {
325: PFIXED_DISK_PARAMETER_TABLE ParameterTableAddress;
326: USHORT NumberOfCylinders;
327: USHORT TracksPerCylinder;
328: USHORT SectorsPerTrack;
329: USHORT PretendNumberOfCylinders;
330: USHORT PretendTracksPerCylinder;
331: USHORT PretendSectorsPerTrack;
332: USHORT BytesPerSector;
333: USHORT BytesPerInterrupt;
334: USHORT WritePrecomp;
335: UCHAR DriveType;
336: CCHAR ReadCommand;
337: CCHAR WriteCommand;
338: CCHAR VerifyCommand;
339: BOOLEAN DisableReadCache;
340: } DRIVE_DATA, *PDRIVE_DATA;
341:
342: typedef struct _CONTROLLER_DATA {
343: DRIVE_DATA Disk[MAXIMUM_NUMBER_OF_DISKS_PER_CONTROLLER];
344: PUCHAR ControllerBaseAddress;
345: PUCHAR ControlPortAddress;
346: PHYSICAL_ADDRESS OriginalControllerBaseAddress;
347: PHYSICAL_ADDRESS OriginalControlPortAddress;
348: KINTERRUPT_MODE InterruptMode;
349: KAFFINITY ProcessorNumber;
350: INTERFACE_TYPE InterfaceType;
351: ULONG BusNumber;
352: ULONG RangeOfControllerBase;
353: ULONG RangeOfControlPort;
354: BOOLEAN SaveFloatState;
355: BOOLEAN SharableVector;
356: BOOLEAN ControllerBaseMapped;
357: BOOLEAN ControlPortMapped;
358: BOOLEAN OkToUseThisController;
359: KIRQL ControllerIrql;
360: KIRQL OriginalControllerIrql;
361: ULONG ControllerVector;
362: CCHAR ControlFlags;
363: UCHAR OriginalControllerVector;
364: } CONTROLLER_DATA, *PCONTROLLER_DATA;
365:
366:
367: typedef struct _CONFIG_DATA {
368: PCCHAR NtNamePrefix;
369: PCCHAR ArcNamePrefix;
370: PULONG HardDiskCount;
371: HANDLE DeviceKey;
372: CONTROLLER_DATA Controller[MAXIMUM_NUMBER_OF_CONTROLLERS];
373: } CONFIG_DATA, *PCONFIG_DATA;
374:
375: //
376: // IDENTIFY data
377: //
378:
379: typedef struct _IDENTIFY_DATA {
380: USHORT GeneralConfiguration; // 00
381: USHORT NumberOfCylinders; // 02
382: USHORT Reserved1; // 04
383: USHORT NumberOfHeads; // 06
384: USHORT UnformattedBytesPerTrack; // 08
385: USHORT UnformattedBytesPerSector; // 0A
386: USHORT SectorsPerTrack; // 0C
387: USHORT VendorUnique1[3]; // 0E
388: USHORT SerialNumber[10]; // 14
389: USHORT BufferType; // 28
390: USHORT BufferSectorSize; // 2A
391: USHORT NumberOfEccBytes; // 2C
392: USHORT FirmwareRevision[4]; // 2E
393: USHORT ModelNumber[20]; // 36
394: UCHAR MaximumBlockTransfer; // 5E
395: UCHAR VendorUnique2; // 5F
396: USHORT DoubleWordIo; // 60
397: USHORT Capabilities; // 62
398: USHORT Reserved2; // 64
399: UCHAR VendorUnique3; // 66
400: UCHAR PioCycleTimingMode; // 67
401: UCHAR VendorUnique4; // 68
402: UCHAR DmaCycleTimingMode; // 69
403: USHORT TranslationFieldsValid:1; // 6A
404: USHORT Reserved3:15;
405: USHORT NumberOfCurrentCylinders; // 6C
406: USHORT NumberOfCurrentHeads; // 6E
407: USHORT CurrentSectorsPerTrack; // 70
408: ULONG CurrentSectorCapacity; // 72
409: USHORT Reserved4[197]; // 76
410: } IDENTIFY_DATA, *PIDENTIFY_DATA;
411:
412: //
413: // Prototypes of external routines.
414: //
415:
416: int
417: sprintf(
418: char *s,
419: const char *format,
420: ...
421: );
422:
423: //
424: // Device driver routine declarations.
425: //
426:
427: NTSTATUS
428: DriverEntry(
429: IN OUT PDRIVER_OBJECT DriverObject,
430: IN PUNICODE_STRING RegistryPath
431: );
432:
433: NTSTATUS
434: AtGetConfigInfo(
435: IN PDRIVER_OBJECT DriverObject,
436: IN PUNICODE_STRING RegistryPath,
437: IN OUT PCONFIG_DATA ConfigData
438: );
439:
440: NTSTATUS
441: AtInitializeController(
442: IN struct _CONFIG_DATA *ConfigData,
443: IN CCHAR ControllerNumber,
444: IN PDRIVER_OBJECT DriverObject
445: );
446:
447: NTSTATUS
448: AtInitializePowerFail(
449: IN PCONTROLLER_EXTENSION ControllerExtension
450: );
451:
452: NTSTATUS
453: AtInitializeDisk(
454: IN struct _CONFIG_DATA *ConfigData,
455: IN CCHAR ContNumber,
456: IN CCHAR DiskNumber,
457: IN PDRIVER_OBJECT DriverObject,
458: IN PCONTROLLER_EXTENSION ControllerExtension
459: );
460:
461: NTSTATUS
462: AtDiskDispatchCreateClose(
463: IN PDEVICE_OBJECT DeviceObject,
464: IN PIRP Irp
465: );
466:
467: NTSTATUS
468: AtDiskDispatchDeviceControl(
469: IN PDEVICE_OBJECT DeviceObject,
470: IN PIRP Irp
471: );
472:
473: NTSTATUS
474: AtDiskDispatchReadWrite(
475: IN PDEVICE_OBJECT DeviceObject,
476: IN PIRP Irp
477: );
478:
479: VOID
480: AtDiskStartIo(
481: IN PDEVICE_OBJECT DeviceObject,
482: IN PIRP Irp
483: );
484:
485: IO_ALLOCATION_ACTION
486: AtInitiate(
487: IN PDEVICE_OBJECT DeviceObject,
488: IN PIRP Irp,
489: IN PVOID MapRegisterBase,
490: IN PVOID Context
491: );
492:
493: BOOLEAN
494: AtStartDevice(
495: IN PVOID Context
496: );
497:
498: BOOLEAN
499: AtDiskInterruptService(
500: IN PKINTERRUPT Interrupt,
501: IN PVOID Context
502: );
503:
504: VOID
505: AtDiskDeferredProcedure(
506: IN PKDPC Dpc,
507: IN PVOID DeferredContext,
508: IN PVOID SystemArgument1,
509: IN PVOID SystemArgument2
510: );
511:
512: BOOLEAN
513: AtDiskStartReset(
514: IN PVOID Context
515: );
516:
517: VOID
518: AtDiskUnloadDriver(
519: IN PDRIVER_OBJECT DriverObject
520: );
521:
522: VOID
523: AtDiskCheckTimer(
524: IN PDEVICE_OBJECT DeviceObject,
525: IN PVOID TimerCounter
526: );
527:
528: BOOLEAN
529: AtCheckTimerSync(
530: IN PVOID Context
531: );
532:
533: NTSTATUS
534: AtWaitControllerBusy(
535: PUCHAR StatusRegisterAddress,
536: ULONG MicrosecondsToDelay,
537: ULONG TimesToDelay
538: );
539:
540: NTSTATUS
541: AtWaitControllerReady(
542: IN PCONTROLLER_EXTENSION ControllerExtension,
543: IN ULONG MicrosecondsToDelay,
544: IN ULONG TimesToDelay
545: );
546:
547: VOID
548: AtLogError(
549: IN PDEVICE_OBJECT DeviceObject,
550: IN ULONG SequenceNumber,
551: IN UCHAR MajorFunctionCode,
552: IN UCHAR RetryCount,
553: IN ULONG UniqueErrorValue,
554: IN NTSTATUS FinalStatus,
555: IN NTSTATUS SpecificIOStatus,
556: IN CCHAR ErrorType,
557: IN UCHAR Parameter1,
558: IN UCHAR Parameter2,
559: IN UCHAR Parameter3,
560: IN UCHAR Parameter4,
561: IN UCHAR Parameter5,
562: IN UCHAR Parameter6,
563: IN UCHAR Parameter7
564: );
565:
566: PVOID
567: AtGetTranslatedMemory(
568: IN INTERFACE_TYPE BusType,
569: IN ULONG BusNumber,
570: IN PHYSICAL_ADDRESS IoAddress,
571: IN ULONG NumberOfBytes,
572: IN BOOLEAN InIoSpace,
573: OUT PBOOLEAN MappedAddress
574: );
575:
576: BOOLEAN
577: AtReportUsage(
578: IN PCONFIG_DATA ConfigData,
579: IN UCHAR ControllerNumber,
580: IN PDRIVER_OBJECT DriverObject
581: );
582:
583: VOID
584: AtBuildDeviceMap(
585: IN ULONG ControllerNumber,
586: IN ULONG DiskNumber,
587: IN PHYSICAL_ADDRESS ControllerAddress,
588: IN KIRQL Irql,
589: IN PDRIVE_DATA Disk,
590: IN PIDENTIFY_DATA DiskData
591: );
592:
593: BOOLEAN
594: AtDiskControllerInfo(
595: IN PDRIVER_OBJECT DriverObject,
596: IN PUNICODE_STRING RegistryPath,
597: IN ULONG WhichController,
598: IN OUT PCONTROLLER_DATA Controller,
599: IN PHYSICAL_ADDRESS DefaultBaseAddress,
600: IN PHYSICAL_ADDRESS DefaultPortAddress,
601: IN KIRQL DefaultIrql,
602: IN INTERFACE_TYPE DefaultInterfaceType,
603: IN ULONG DefaultBusNumber,
604: IN BOOLEAN UseDefaults
605: );
606:
607: BOOLEAN
608: AtResetController(
609: IN PUCHAR StatusRegAddress,
610: IN PUCHAR DriveControlAddress,
611: IN CCHAR ControlFlags
612: );
613:
614: BOOLEAN
615: AtControllerPresent(
616: PCONTROLLER_DATA ControllerData
617: );
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.