* Sync to trunk HEAD (r53318).
[reactos.git] / drivers / storage / classpnp / classp.h
1 /*++
2
3 Copyright (C) Microsoft Corporation, 1991 - 1999
4
5 Module Name:
6
7 classp.h
8
9 Abstract:
10
11 Private header file for classpnp.sys modules. This contains private
12 structure and function declarations as well as constant values which do
13 not need to be exported.
14
15 Author:
16
17 Environment:
18
19 kernel mode only
20
21 Notes:
22
23
24 Revision History:
25
26 --*/
27
28 #include <stddef.h>
29 #include <stdarg.h>
30 #include <ntddk.h>
31
32 #include <scsi.h>
33 #include <wmidata.h>
34 #include <classpnp.h>
35
36 #if CLASS_INIT_GUID
37 #include <initguid.h>
38 #endif
39
40 #include <mountdev.h>
41 #include <ioevent.h>
42 #include <pseh/pseh2.h>
43
44 #include "wmistr.h"
45
46 extern CLASSPNP_SCAN_FOR_SPECIAL_INFO ClassBadItems[];
47
48 extern GUID ClassGuidQueryRegInfoEx;
49
50
51 #define CLASSP_REG_SUBKEY_NAME (L"Classpnp")
52
53 #define CLASSP_REG_HACK_VALUE_NAME (L"HackMask")
54 #define CLASSP_REG_MMC_DETECTION_VALUE_NAME (L"MMCDetectionState")
55 #define CLASSP_REG_WRITE_CACHE_VALUE_NAME (L"WriteCacheEnableOverride")
56 #define CLASSP_REG_PERF_RESTORE_VALUE_NAME (L"RestorePerfAtCount")
57 #define CLASSP_REG_REMOVAL_POLICY_VALUE_NAME (L"UserRemovalPolicy")
58
59 #define CLASS_PERF_RESTORE_MINIMUM (0x10)
60 #define CLASS_ERROR_LEVEL_1 (0x4)
61 #define CLASS_ERROR_LEVEL_2 (0x8)
62
63 #define FDO_HACK_CANNOT_LOCK_MEDIA (0x00000001)
64 #define FDO_HACK_GESN_IS_BAD (0x00000002)
65 #define FDO_HACK_NO_SYNC_CACHE (0x00000004)
66
67 #define FDO_HACK_VALID_FLAGS (0x00000007)
68 #define FDO_HACK_INVALID_FLAGS (~FDO_HACK_VALID_FLAGS)
69
70 /*
71 * Lots of retries of synchronized SCSI commands that devices may not
72 * even support really slows down the system (especially while booting).
73 * (Even GetDriveCapacity may be failed on purpose if an external disk is powered off).
74 * If a disk cannot return a small initialization buffer at startup
75 * in two attempts (with delay interval) then we cannot expect it to return
76 * data consistently with four retries.
77 * So don't set the retry counts as high here as for data SRBs.
78 *
79 * If we find that these requests are failing consecutively,
80 * despite the retry interval, on otherwise reliable media,
81 * then we should either increase the retry interval for
82 * that failure or (by all means) increase these retry counts as appropriate.
83 */
84 #define NUM_LOCKMEDIAREMOVAL_RETRIES 1
85 #define NUM_MODESENSE_RETRIES 1
86 #define NUM_DRIVECAPACITY_RETRIES 1
87
88
89 #define CLASS_FILE_OBJECT_EXTENSION_KEY 'eteP'
90 #define CLASSP_VOLUME_VERIFY_CHECKED 0x34
91
92 #define CLASS_TAG_PRIVATE_DATA 'CPcS'
93 #define CLASS_TAG_PRIVATE_DATA_FDO 'FPcS'
94 #define CLASS_TAG_PRIVATE_DATA_PDO 'PPcS'
95
96 struct _MEDIA_CHANGE_DETECTION_INFO {
97
98 //
99 // Mutex to synchronize enable/disable requests and media state changes
100 //
101
102 KMUTEX MediaChangeMutex;
103
104 //
105 // The current state of the media (present, not present, unknown)
106 // protected by MediaChangeSynchronizationEvent
107 //
108
109 MEDIA_CHANGE_DETECTION_STATE MediaChangeDetectionState;
110
111 //
112 // This is a count of how many time MCD has been disabled. if it is
113 // set to zero, then we'll poll the device for MCN events with the
114 // then-current method (ie. TEST UNIT READY or GESN). this is
115 // protected by MediaChangeMutex
116 //
117
118 LONG MediaChangeDetectionDisableCount;
119
120
121 //
122 // The timer value to support media change events. This is a countdown
123 // value used to determine when to poll the device for a media change.
124 // The max value for the timer is 255 seconds. This is not protected
125 // by an event -- simply InterlockedExchanged() as needed.
126 //
127
128 LONG MediaChangeCountDown;
129
130 //
131 // recent changes allowed instant retries of the MCN irp. Since this
132 // could cause an infinite loop, keep a count of how many times we've
133 // retried immediately so that we can catch if the count exceeds an
134 // arbitrary limit.
135 //
136
137 LONG MediaChangeRetryCount;
138
139 //
140 // use GESN if it's available
141 //
142
143 struct {
144 BOOLEAN Supported;
145 BOOLEAN HackEventMask;
146 UCHAR EventMask;
147 UCHAR NoChangeEventMask;
148 PUCHAR Buffer;
149 PMDL Mdl;
150 ULONG BufferSize;
151 } Gesn;
152
153 //
154 // If this value is one, then the irp is currently in use.
155 // If this value is zero, then the irp is available.
156 // Use InterlockedCompareExchange() to set from "available" to "in use".
157 // ASSERT that InterlockedCompareExchange() showed previous value of
158 // "in use" when changing back to "available" state.
159 // This also implicitly protects the MediaChangeSrb and SenseBuffer
160 //
161
162 LONG MediaChangeIrpInUse;
163
164 //
165 // Pointer to the irp to be used for media change detection.
166 // protected by Interlocked MediaChangeIrpInUse
167 //
168
169 PIRP MediaChangeIrp;
170
171 //
172 // The srb for the media change detection.
173 // protected by Interlocked MediaChangeIrpInUse
174 //
175
176 SCSI_REQUEST_BLOCK MediaChangeSrb;
177 PUCHAR SenseBuffer;
178 ULONG SrbFlags;
179
180 //
181 // Second timer to keep track of how long the media change IRP has been
182 // in use. If this value exceeds the timeout (#defined) then we should
183 // print out a message to the user and set the MediaChangeIrpLost flag
184 // protected by using Interlocked() operations in ClasspSendMediaStateIrp,
185 // the only routine which should modify this value.
186 //
187
188 LONG MediaChangeIrpTimeInUse;
189
190 //
191 // Set by CdRomTickHandler when we determine that the media change irp has
192 // been lost
193 //
194
195 BOOLEAN MediaChangeIrpLost;
196
197 };
198
199 typedef enum {
200 SimpleMediaLock,
201 SecureMediaLock,
202 InternalMediaLock
203 } MEDIA_LOCK_TYPE, *PMEDIA_LOCK_TYPE;
204
205 typedef struct _FAILURE_PREDICTION_INFO {
206 FAILURE_PREDICTION_METHOD Method;
207 ULONG CountDown; // Countdown timer
208 ULONG Period; // Countdown period
209
210 PIO_WORKITEM WorkQueueItem;
211
212 KEVENT Event;
213 } FAILURE_PREDICTION_INFO, *PFAILURE_PREDICTION_INFO;
214
215
216
217 //
218 // This struct must always fit within four PVOIDs of info,
219 // as it uses the irp's "PVOID DriverContext[4]" to store
220 // this info
221 //
222 typedef struct _CLASS_RETRY_INFO {
223 struct _CLASS_RETRY_INFO *Next;
224 } CLASS_RETRY_INFO, *PCLASS_RETRY_INFO;
225
226
227
228 typedef struct _CSCAN_LIST {
229
230 //
231 // The current block which has an outstanding request.
232 //
233
234 ULONGLONG BlockNumber;
235
236 //
237 // The list of blocks past the CurrentBlock to which we're going to do
238 // i/o. This list is maintained in sorted order.
239 //
240
241 LIST_ENTRY CurrentSweep;
242
243 //
244 // The list of blocks behind the current block for which we'll have to
245 // wait until the next scan across the disk. This is kept as a stack,
246 // the cost of sorting it is taken when it's moved over to be the
247 // running list.
248 //
249
250 LIST_ENTRY NextSweep;
251
252 } CSCAN_LIST, *PCSCAN_LIST;
253
254 //
255 // add to the front of this structure to help prevent illegal
256 // snooping by other utilities.
257 //
258
259
260
261 typedef enum _CLASS_DETECTION_STATE {
262 ClassDetectionUnknown = 0,
263 ClassDetectionUnsupported = 1,
264 ClassDetectionSupported = 2
265 } CLASS_DETECTION_STATE, *PCLASS_DETECTION_STATE;
266
267
268 typedef struct _CLASS_ERROR_LOG_DATA {
269 LARGE_INTEGER TickCount; // Offset 0x00
270 ULONG PortNumber; // Offset 0x08
271
272 UCHAR ErrorPaging : 1; // Offset 0x0c
273 UCHAR ErrorRetried : 1;
274 UCHAR ErrorUnhandled : 1;
275 UCHAR ErrorReserved : 5;
276
277 UCHAR Reserved[3];
278
279 SCSI_REQUEST_BLOCK Srb; // Offset 0x10
280
281 /*
282 * We define the SenseData as the default length.
283 * Since the sense data returned by the port driver may be longer,
284 * SenseData must be at the end of this structure.
285 * For our internal error log, we only log the default length.
286 */
287 SENSE_DATA SenseData; // Offset 0x50 for x86 (or 0x68 for ia64) (ULONG32 Alignment required!)
288 } CLASS_ERROR_LOG_DATA, *PCLASS_ERROR_LOG_DATA;
289
290 #define NUM_ERROR_LOG_ENTRIES 16
291
292
293
294 typedef struct _TRANSFER_PACKET {
295
296 LIST_ENTRY AllPktsListEntry; // entry in fdoData's static AllTransferPacketsList
297 SINGLE_LIST_ENTRY SlistEntry; // for when in free list (use fast slist)
298
299 PIRP Irp;
300 PDEVICE_OBJECT Fdo;
301
302 /*
303 * This is the client IRP that this TRANSFER_PACKET is currently
304 * servicing.
305 */
306 PIRP OriginalIrp;
307 BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes;
308
309 /*
310 * Stuff for retrying the transfer.
311 */
312 ULONG NumRetries;
313 KTIMER RetryTimer;
314 KDPC RetryTimerDPC;
315 ULONG RetryIntervalSec;
316
317 /*
318 * Event for synchronizing the transfer (optional).
319 * (Note that we can't have the event in the packet itself because
320 * by the time a thread waits on an event the packet may have
321 * been completed and re-issued.
322 */
323 PKEVENT SyncEventPtr;
324
325 /*
326 * Stuff for retrying during extreme low-memory stress
327 * (when we retry 1 page at a time).
328 */
329 BOOLEAN InLowMemRetry;
330 PUCHAR LowMemRetry_remainingBufPtr;
331 ULONG LowMemRetry_remainingBufLen;
332 LARGE_INTEGER LowMemRetry_nextChunkTargetLocation;
333
334 /*
335 * Fields used for cancelling the packet.
336 */
337 // BOOLEAN Cancelled;
338 // KEVENT CancelledEvent;
339
340 /*
341 * We keep the buffer and length values here as well
342 * as in the SRB because some miniports return
343 * the transferred length in SRB.DataTransferLength,
344 * and if the SRB failed we need that value again for the retry.
345 * We don't trust the lower stack to preserve any of these values in the SRB.
346 */
347 PUCHAR BufPtrCopy;
348 ULONG BufLenCopy;
349 LARGE_INTEGER TargetLocationCopy;
350
351 /*
352 * This is a standard SCSI structure that receives a detailed
353 * report about a SCSI error on the hardware.
354 */
355 SENSE_DATA SrbErrorSenseData;
356
357 /*
358 * This is the SRB block for this TRANSFER_PACKET.
359 * For IOCTLs, the SRB block includes two DWORDs for
360 * device object and ioctl code; so these must
361 * immediately follow the SRB block.
362 */
363 SCSI_REQUEST_BLOCK Srb;
364 // ULONG SrbIoctlDevObj; // not handling ioctls yet
365 // ULONG SrbIoctlCode;
366
367 } TRANSFER_PACKET, *PTRANSFER_PACKET;
368
369 /*
370 * MIN_INITIAL_TRANSFER_PACKETS is the minimum number of packets that
371 * we preallocate at startup for each device (we need at least one packet
372 * to guarantee forward progress during memory stress).
373 * MIN_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs
374 * we allow to build up and remain for each device;
375 * we _lazily_ work down to this number when they're not needed.
376 * MAX_WORKINGSET_TRANSFER_PACKETS is the number of TRANSFER_PACKETs
377 * that we _immediately_ reduce to when they are not needed.
378 *
379 * The absolute maximum number of packets that we will allocate is
380 * whatever is required by the current activity, up to the memory limit;
381 * as soon as stress ends, we snap down to MAX_WORKINGSET_TRANSFER_PACKETS;
382 * we then lazily work down to MIN_WORKINGSET_TRANSFER_PACKETS.
383 */
384 #define MIN_INITIAL_TRANSFER_PACKETS 1
385 #define MIN_WORKINGSET_TRANSFER_PACKETS_Consumer 4
386 #define MAX_WORKINGSET_TRANSFER_PACKETS_Consumer 64
387 #define MIN_WORKINGSET_TRANSFER_PACKETS_Server 64
388 #define MAX_WORKINGSET_TRANSFER_PACKETS_Server 1024
389 #define MIN_WORKINGSET_TRANSFER_PACKETS_Enterprise 256
390 #define MAX_WORKINGSET_TRANSFER_PACKETS_Enterprise 2048
391
392
393 //
394 // add to the front of this structure to help prevent illegal
395 // snooping by other utilities.
396 //
397 struct _CLASS_PRIVATE_FDO_DATA {
398
399 //
400 // this private structure allows us to
401 // dynamically re-enable the perf benefits
402 // lost due to transient error conditions.
403 // in w2k, a reboot was required. :(
404 //
405 struct {
406 ULONG OriginalSrbFlags;
407 ULONG SuccessfulIO;
408 ULONG ReEnableThreshhold; // 0 means never
409 } Perf;
410
411 ULONG_PTR HackFlags;
412
413 STORAGE_HOTPLUG_INFO HotplugInfo;
414
415 // Legacy. Still used by obsolete legacy code.
416 struct {
417 LARGE_INTEGER Delta; // in ticks
418 LARGE_INTEGER Tick; // when it should fire
419 PCLASS_RETRY_INFO ListHead; // singly-linked list
420 ULONG Granularity; // static
421 KSPIN_LOCK Lock; // protective spin lock
422 KDPC Dpc; // DPC routine object
423 KTIMER Timer; // timer to fire DPC
424 } Retry;
425
426 BOOLEAN TimerStarted;
427 BOOLEAN LoggedTURFailureSinceLastIO;
428
429 //
430 // privately allocated release queue irp
431 // protected by fdoExtension->ReleaseQueueSpinLock
432 //
433 BOOLEAN ReleaseQueueIrpAllocated;
434 PIRP ReleaseQueueIrp;
435
436 /*
437 * Queues for TRANSFER_PACKETs that contextualize the IRPs and SRBs
438 * that we send down to the port driver.
439 * (The free list is an slist so that we can use fast
440 * interlocked operations on it; but the relatively-static
441 * AllTransferPacketsList list has to be
442 * a doubly-linked list since we have to dequeue from the middle).
443 */
444 LIST_ENTRY AllTransferPacketsList;
445 SLIST_HEADER FreeTransferPacketsList;
446 ULONG NumFreeTransferPackets;
447 ULONG NumTotalTransferPackets;
448 ULONG DbgPeakNumTransferPackets;
449
450 /*
451 * Queue for deferred client irps
452 */
453 LIST_ENTRY DeferredClientIrpList;
454
455 /*
456 * Precomputed maximum transfer length for the hardware.
457 */
458 ULONG HwMaxXferLen;
459
460 /*
461 * SCSI_REQUEST_BLOCK template preconfigured with the constant values.
462 * This is slapped into the SRB in the TRANSFER_PACKET for each transfer.
463 */
464 SCSI_REQUEST_BLOCK SrbTemplate;
465
466 KSPIN_LOCK SpinLock;
467
468 /*
469 * Circular array of timestamped logs of errors that occurred on this device.
470 */
471 ULONG ErrorLogNextIndex;
472 CLASS_ERROR_LOG_DATA ErrorLogs[NUM_ERROR_LOG_ENTRIES];
473
474 };
475
476
477 #define MIN(a, b) ((a) < (b) ? (a) : (b))
478 #define MAX(a, b) ((a) > (b) ? (a) : (b))
479
480
481 #define NOT_READY_RETRY_INTERVAL 10
482 #define MINIMUM_RETRY_UNITS ((LONGLONG)32)
483
484
485 /*
486 * Simple singly-linked-list queuing macros, with no synchronization.
487 */
488 static inline VOID SimpleInitSlistHdr(SINGLE_LIST_ENTRY *SListHdr)
489 {
490 SListHdr->Next = NULL;
491 }
492 static inline VOID SimplePushSlist(SINGLE_LIST_ENTRY *SListHdr, SINGLE_LIST_ENTRY *SListEntry)
493 {
494 SListEntry->Next = SListHdr->Next;
495 SListHdr->Next = SListEntry;
496 }
497 static inline SINGLE_LIST_ENTRY *SimplePopSlist(SINGLE_LIST_ENTRY *SListHdr)
498 {
499 SINGLE_LIST_ENTRY *sListEntry = SListHdr->Next;
500 if (sListEntry){
501 SListHdr->Next = sListEntry->Next;
502 sListEntry->Next = NULL;
503 }
504 return sListEntry;
505 }
506 static inline BOOLEAN SimpleIsSlistEmpty(SINGLE_LIST_ENTRY *SListHdr)
507 {
508 return (SListHdr->Next == NULL);
509 }
510
511 NTSTATUS
512 DriverEntry(
513 IN PDRIVER_OBJECT DriverObject,
514 IN PUNICODE_STRING RegistryPath
515 );
516
517 VOID
518 ClassUnload(
519 IN PDRIVER_OBJECT DriverObject
520 );
521
522 NTSTATUS
523 ClassCreateClose(
524 IN PDEVICE_OBJECT DeviceObject,
525 IN PIRP Irp
526 );
527
528 NTSTATUS
529 ClasspCreateClose(
530 IN PDEVICE_OBJECT DeviceObject,
531 IN PIRP Irp
532 );
533
534 VOID
535 ClasspCleanupProtectedLocks(
536 IN PFILE_OBJECT_EXTENSION FsContext
537 );
538
539 NTSTATUS
540 ClasspEjectionControl(
541 IN PDEVICE_OBJECT Fdo,
542 IN PIRP Irp,
543 IN MEDIA_LOCK_TYPE LockType,
544 IN BOOLEAN Lock
545 );
546
547 NTSTATUS
548 ClassReadWrite(
549 IN PDEVICE_OBJECT DeviceObject,
550 IN PIRP Irp
551 );
552
553 NTSTATUS
554 ClassDeviceControlDispatch(
555 PDEVICE_OBJECT DeviceObject,
556 PIRP Irp
557 );
558
559 NTSTATUS
560 ClassDeviceControl(
561 PDEVICE_OBJECT DeviceObject,
562 PIRP Irp
563 );
564
565 NTSTATUS
566 ClassDispatchPnp(
567 PDEVICE_OBJECT DeviceObject,
568 PIRP Irp
569 );
570
571 NTSTATUS
572 ClassPnpStartDevice(
573 IN PDEVICE_OBJECT DeviceObject
574 );
575
576 NTSTATUS
577 ClassInternalIoControl (
578 IN PDEVICE_OBJECT DeviceObject,
579 IN PIRP Irp
580 );
581
582 NTSTATUS
583 ClassShutdownFlush(
584 IN PDEVICE_OBJECT DeviceObject,
585 IN PIRP Irp
586 );
587
588 NTSTATUS
589 ClassSystemControl(
590 IN PDEVICE_OBJECT DeviceObject,
591 IN PIRP Irp
592 );
593
594 //
595 // Class internal routines
596 //
597
598 NTSTATUS
599 ClassAddDevice(
600 IN PDRIVER_OBJECT DriverObject,
601 IN OUT PDEVICE_OBJECT PhysicalDeviceObject
602 );
603
604 NTSTATUS
605 ClasspSendSynchronousCompletion(
606 IN PDEVICE_OBJECT DeviceObject,
607 IN PIRP Irp,
608 IN PVOID Context
609 );
610
611 VOID
612 RetryRequest(
613 PDEVICE_OBJECT DeviceObject,
614 PIRP Irp,
615 PSCSI_REQUEST_BLOCK Srb,
616 BOOLEAN Associated,
617 ULONG RetryInterval
618 );
619
620 NTSTATUS
621 ClassIoCompletion(
622 IN PDEVICE_OBJECT DeviceObject,
623 IN PIRP Irp,
624 IN PVOID Context
625 );
626
627 NTSTATUS
628 ClassPnpQueryFdoRelations(
629 IN PDEVICE_OBJECT Fdo,
630 IN PIRP Irp
631 );
632
633 NTSTATUS
634 ClassRetrieveDeviceRelations(
635 IN PDEVICE_OBJECT Fdo,
636 IN DEVICE_RELATION_TYPE RelationType,
637 OUT PDEVICE_RELATIONS *DeviceRelations
638 );
639
640 NTSTATUS
641 ClassGetPdoId(
642 IN PDEVICE_OBJECT Pdo,
643 IN BUS_QUERY_ID_TYPE IdType,
644 IN PUNICODE_STRING IdString
645 );
646
647 NTSTATUS
648 ClassQueryPnpCapabilities(
649 IN PDEVICE_OBJECT PhysicalDeviceObject,
650 IN PDEVICE_CAPABILITIES Capabilities
651 );
652
653 VOID
654 ClasspStartIo(
655 IN PDEVICE_OBJECT DeviceObject,
656 IN PIRP Irp
657 );
658
659 NTSTATUS
660 ClasspPagingNotificationCompletion(
661 IN PDEVICE_OBJECT DeviceObject,
662 IN PIRP Irp,
663 IN PDEVICE_OBJECT RealDeviceObject
664 );
665
666 NTSTATUS
667 ClasspMediaChangeCompletion(
668 PDEVICE_OBJECT DeviceObject,
669 PIRP Irp,
670 PVOID Context
671 );
672
673 PFILE_OBJECT_EXTENSION
674 ClasspGetFsContext(
675 IN PCOMMON_DEVICE_EXTENSION CommonExtension,
676 IN PFILE_OBJECT FileObject
677 );
678
679 NTSTATUS
680 ClasspMcnControl(
681 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
682 IN PIRP Irp,
683 IN PSCSI_REQUEST_BLOCK Srb
684 );
685
686 VOID
687 ClasspRegisterMountedDeviceInterface(
688 IN PDEVICE_OBJECT DeviceObject
689 );
690
691 NTSTATUS
692 ClasspDisableTimer(
693 PDEVICE_OBJECT DeviceObject
694 );
695
696 NTSTATUS
697 ClasspEnableTimer(
698 PDEVICE_OBJECT DeviceObject
699 );
700
701 //
702 // routines for dictionary list support
703 //
704
705 VOID
706 InitializeDictionary(
707 IN PDICTIONARY Dictionary
708 );
709
710 BOOLEAN
711 TestDictionarySignature(
712 IN PDICTIONARY Dictionary
713 );
714
715 NTSTATUS
716 AllocateDictionaryEntry(
717 IN PDICTIONARY Dictionary,
718 IN ULONGLONG Key,
719 IN ULONG Size,
720 IN ULONG Tag,
721 OUT PVOID *Entry
722 );
723
724 PVOID
725 GetDictionaryEntry(
726 IN PDICTIONARY Dictionary,
727 IN ULONGLONG Key
728 );
729
730 VOID
731 FreeDictionaryEntry(
732 IN PDICTIONARY Dictionary,
733 IN PVOID Entry
734 );
735
736
737 NTSTATUS
738 ClasspAllocateReleaseRequest(
739 IN PDEVICE_OBJECT Fdo
740 );
741
742 VOID
743 ClasspFreeReleaseRequest(
744 IN PDEVICE_OBJECT Fdo
745 );
746
747 NTSTATUS
748 ClassReleaseQueueCompletion(
749 IN PDEVICE_OBJECT DeviceObject,
750 IN PIRP Irp,
751 IN PVOID Context
752 );
753
754 VOID
755 ClasspReleaseQueue(
756 IN PDEVICE_OBJECT DeviceObject,
757 IN PIRP ReleaseQueueIrp
758 );
759
760 VOID
761 ClasspDisablePowerNotification(
762 PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
763 );
764
765 //
766 // class power routines
767 //
768
769 NTSTATUS
770 ClassDispatchPower(
771 IN PDEVICE_OBJECT DeviceObject,
772 IN PIRP Irp
773 );
774
775 NTSTATUS
776 ClassMinimalPowerHandler(
777 IN PDEVICE_OBJECT DeviceObject,
778 IN PIRP Irp
779 );
780
781 //
782 // Child list routines
783 //
784
785 VOID
786 ClassAddChild(
787 IN PFUNCTIONAL_DEVICE_EXTENSION Parent,
788 IN PPHYSICAL_DEVICE_EXTENSION Child,
789 IN BOOLEAN AcquireLock
790 );
791
792 PPHYSICAL_DEVICE_EXTENSION
793 ClassRemoveChild(
794 IN PFUNCTIONAL_DEVICE_EXTENSION Parent,
795 IN PPHYSICAL_DEVICE_EXTENSION Child,
796 IN BOOLEAN AcquireLock
797 );
798
799 VOID
800 ClasspRetryDpcTimer(
801 IN PCLASS_PRIVATE_FDO_DATA FdoData
802 );
803
804 VOID
805 ClasspRetryRequestDpc(
806 IN PKDPC Dpc,
807 IN PDEVICE_OBJECT DeviceObject,
808 IN PVOID Arg1,
809 IN PVOID Arg2
810 );
811
812 VOID
813 ClassFreeOrReuseSrb(
814 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
815 IN PSCSI_REQUEST_BLOCK Srb
816 );
817
818 VOID
819 ClassRetryRequest(
820 IN PDEVICE_OBJECT SelfDeviceObject,
821 IN PIRP Irp,
822 IN LARGE_INTEGER TimeDelta100ns // in 100ns units
823 );
824
825 VOID
826 ClasspBuildRequestEx(
827 IN PFUNCTIONAL_DEVICE_EXTENSION Fdo,
828 IN PIRP Irp,
829 IN PSCSI_REQUEST_BLOCK Srb
830 );
831
832 NTSTATUS
833 ClasspAllocateReleaseQueueIrp(
834 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
835 );
836
837 NTSTATUS
838 ClasspInitializeGesn(
839 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
840 IN PMEDIA_CHANGE_DETECTION_INFO Info
841 );
842
843 VOID
844 ClasspSendNotification(
845 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
846 IN const GUID * Guid,
847 IN ULONG ExtraDataSize,
848 IN PVOID ExtraData
849 );
850
851 VOID
852 ClassSendEjectionNotification(
853 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
854 );
855
856 VOID
857 ClasspScanForSpecialInRegistry(
858 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
859 );
860
861 VOID
862 ClasspScanForClassHacks(
863 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension,
864 IN ULONG_PTR Data
865 );
866
867 NTSTATUS
868 ClasspInitializeHotplugInfo(
869 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
870 );
871
872 VOID
873 ClasspPerfIncrementErrorCount(
874 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
875 );
876 VOID
877 ClasspPerfIncrementSuccessfulIo(
878 IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension
879 );
880
881
882 PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo);
883 VOID DestroyTransferPacket(PTRANSFER_PACKET Pkt);
884 VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, PTRANSFER_PACKET Pkt);
885 PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded);
886 VOID SetupReadWriteTransferPacket(PTRANSFER_PACKET pkt, PVOID Buf, ULONG Len, LARGE_INTEGER DiskLocation, PIRP OriginalIrp);
887 VOID SubmitTransferPacket(PTRANSFER_PACKET Pkt);
888 NTSTATUS TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Context);
889 VOID ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp);
890 VOID TransferPacketRetryTimerDpc(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2);
891 BOOLEAN InterpretTransferPacketError(PTRANSFER_PACKET Pkt);
892 BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt);
893 VOID EnqueueDeferredClientIrp(PCLASS_PRIVATE_FDO_DATA FdoData, PIRP Irp);
894 PIRP DequeueDeferredClientIrp(PCLASS_PRIVATE_FDO_DATA FdoData);
895 VOID InitLowMemRetry(PTRANSFER_PACKET Pkt, PVOID BufPtr, ULONG Len, LARGE_INTEGER TargetLocation);
896 BOOLEAN StepLowMemRetry(PTRANSFER_PACKET Pkt);
897 VOID SetupEjectionTransferPacket(TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp);
898 VOID SetupModeSenseTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSenseBuffer, UCHAR ModeSenseBufferLen, UCHAR PageMode, PIRP OriginalIrp);
899 VOID SetupDriveCapacityTransferPacket(TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp);
900 PMDL BuildDeviceInputMdl(PVOID Buffer, ULONG BufferLen);
901 VOID FreeDeviceInputMdl(PMDL Mdl);
902 NTSTATUS InitializeTransferPackets(PDEVICE_OBJECT Fdo);
903 VOID DestroyAllTransferPackets(PDEVICE_OBJECT Fdo);
904
905
906
907
908