ReactOS 0.4.16-dev-122-g325d74c
obsolete.c
Go to the documentation of this file.
1/*++
2
3Copyright (C) Microsoft Corporation, 1991 - 2010
4
5Module Name:
6
7 obsolete.c
8
9Abstract:
10
11 THESE ARE EXPORTED CLASSPNP FUNCTIONS (and their subroutines)
12 WHICH ARE NOW OBSOLETE.
13 BUT WE NEED TO KEEP THEM AROUND FOR LEGACY REASONS.
14
15Environment:
16
17 kernel mode only
18
19Notes:
20
21
22Revision History:
23
24--*/
25
26#include "classp.h"
27#include "debug.h"
28
29#ifdef DEBUG_USE_WPP
30#include "obsolete.tmh"
31#endif
32
35
36#ifdef ALLOC_PRAGMA
37 #pragma alloc_text(PAGE, ClassDeleteSrbLookasideList)
38 #pragma alloc_text(PAGE, ClassInitializeSrbLookasideList)
39 #pragma alloc_text(PAGE, ClasspInitializeCScanList)
40#endif
41
42typedef struct _CSCAN_LIST_ENTRY {
46
47
48
49
50
51/*
52 * ClassSplitRequest
53 *
54 * This is a legacy exported function.
55 * It is called by storage miniport driver that have their own
56 * StartIo routine when the transfer size is too large for the hardware.
57 * We map it to our new read/write handler.
58 */
59VOID
60NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
62{
63 PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
64 PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
65
66 if (MaximumBytes > fdoData->HwMaxXferLen) {
67 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "ClassSplitRequest - driver requesting split to size that "
68 "hardware is unable to handle!\n"));
69 }
70
71 if (MaximumBytes < fdoData->HwMaxXferLen){
72 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "ClassSplitRequest - driver requesting smaller HwMaxXferLen "
73 "than required"));
74 fdoData->HwMaxXferLen = MAX(MaximumBytes, PAGE_SIZE);
75 }
76
78}
79
80
81/*++////////////////////////////////////////////////////////////////////////////
82
83ClassIoCompleteAssociated()
84
85Routine Description:
86
87 This routine executes when the port driver has completed a request.
88 It looks at the SRB status in the completing SRB and if not success
89 it checks for valid request sense buffer information. If valid, the
90 info is used to update status with more precise message of type of
91 error. This routine deallocates the SRB. This routine is used for
92 requests which were build by split request. After it has processed
93 the request it decrements the Irp count in the master Irp. If the
94 count goes to zero then the master Irp is completed.
95
96Arguments:
97
98 Fdo - Supplies the functional device object which represents the target.
99
100 Irp - Supplies the Irp which has completed.
101
102 Context - Supplies a pointer to the SRB.
103
104Return Value:
105
106 NT status
107
108--*/
110NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
113 IN PIRP Irp,
115 )
116{
117 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
118
121
122 PIRP originalIrp = Irp->AssociatedIrp.MasterIrp;
123 LONG irpCount;
124
126 BOOLEAN retry;
127
128 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassIoCompleteAssociated is OBSOLETE !"));
129
130 //
131 // Check SRB status for success of completing request.
132 //
134
135 LONGLONG retryInterval;
136
137 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassIoCompleteAssociated: IRP %p, SRB %p", Irp, srb));
138
139 //
140 // Release the queue if it is frozen.
141 //
142
145 }
146
148 Fdo,
149 Irp,
150 srb,
151 irpStack->MajorFunction,
153 irpStack->Parameters.DeviceIoControl.IoControlCode :
154 0,
156 ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4),
157 &status,
158 &retryInterval);
159
160 //
161 // If the status is verified required and the this request
162 // should bypass verify required then retry the request.
163 //
164
165 if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
167
169 retry = TRUE;
170 }
171
172#ifndef __REACTOS__
173#pragma warning(suppress:4213) // okay to cast Arg4 as a ulong for this use case
174 if (retry && ((ULONG)(ULONG_PTR)irpStack->Parameters.Others.Argument4)--) {
175#else
176 if (retry && (*(ULONG *)&irpStack->Parameters.Others.Argument4)--) {
177#endif
178
179 //
180 // Retry request. If the class driver has supplied a StartIo,
181 // call it directly for retries.
182 //
183
184 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "Retry request %p\n", Irp));
185
186 if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
187 FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
188 }
189
190 RetryRequest(Fdo, Irp, srb, TRUE, retryInterval);
191
193 }
194
195 } else {
196
197 //
198 // Set status for successful request.
199 //
200
202
203 } // end if (SRB_STATUS(srb->SrbStatus) ...
204
205 //
206 // Return SRB to list.
207 //
208
209 if (PORT_ALLOCATED_SENSE(fdoExtension, srb)) {
210 FREE_PORT_ALLOCATED_SENSE_BUFFER(fdoExtension, srb);
211 }
212
213 ClassFreeOrReuseSrb(fdoExtension, srb);
214
215 //
216 // Set status in completing IRP.
217 //
218
219 Irp->IoStatus.Status = status;
220
221 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassIoCompleteAssociated: Partial xfer IRP %p\n", Irp));
222
223 //
224 // Get next stack location. This original request is unused
225 // except to keep track of the completing partial IRPs so the
226 // stack location is valid.
227 //
228
229 irpStack = IoGetNextIrpStackLocation(originalIrp);
230
231 //
232 // Update status only if error so that if any partial transfer
233 // completes with error, then the original IRP will return with
234 // error. If any of the asynchronous partial transfer IRPs fail,
235 // with an error then the original IRP will return 0 bytes transfered.
236 // This is an optimization for successful transfers.
237 //
238
239 if (!NT_SUCCESS(status)) {
240
241 originalIrp->IoStatus.Status = status;
242 originalIrp->IoStatus.Information = 0;
243
244 //
245 // Set the hard error if necessary.
246 //
247
249 (originalIrp->Tail.Overlay.Thread != NULL)) {
250
251 //
252 // Store DeviceObject for filesystem.
253 //
254
255 IoSetHardErrorOrVerifyDevice(originalIrp, Fdo);
256 }
257 }
258
259 //
260 // Decrement and get the count of remaining IRPs.
261 //
262
263 irpCount = InterlockedDecrement(
264 (PLONG)&irpStack->Parameters.Others.Argument1);
265
266 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL, "ClassIoCompleteAssociated: Partial IRPs left %d\n",
267 irpCount));
268
269 //
270 // Ensure that the irpCount doesn't go negative. This was happening once
271 // because classpnp would get confused if it ran out of resources when
272 // splitting the request.
273 //
274
275 NT_ASSERT(irpCount >= 0);
276
277 if (irpCount == 0) {
278
279 //
280 // All partial IRPs have completed.
281 //
282
283 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_GENERAL,
284 "ClassIoCompleteAssociated: All partial IRPs complete %p\n",
285 originalIrp));
286
288
289 //
290 // Acquire a separate copy of the remove lock so the debugging code
291 // works okay and we don't have to hold up the completion of this
292 // irp until after we start the next packet(s).
293 //
294
295 KIRQL oldIrql;
296 UCHAR uniqueAddress = 0;
297 ClassAcquireRemoveLock(Fdo, (PIRP)&uniqueAddress);
298 ClassReleaseRemoveLock(Fdo, originalIrp);
300
301 KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
302 IoStartNextPacket(Fdo, TRUE); // yes, some IO is now cancellable
303 KeLowerIrql(oldIrql);
304
305 ClassReleaseRemoveLock(Fdo, (PIRP)&uniqueAddress);
306
307 } else {
308
309 //
310 // just complete this request
311 //
312
313 ClassReleaseRemoveLock(Fdo, originalIrp);
315
316 }
317
318 }
319
320 //
321 // Deallocate IRP and indicate the I/O system should not attempt any more
322 // processing.
323 //
324
325 IoFreeIrp(Irp);
327
328} // end ClassIoCompleteAssociated()
329
330
331/*++////////////////////////////////////////////////////////////////////////////
332
333RetryRequest()
334
335Routine Description:
336
337 This is a wrapper around the delayed retry DPC routine, RetryRequestDPC.
338 This reinitalizes the necessary fields, queues the request, and sets
339 a timer to call the DPC if someone hasn't already done so.
340
341Arguments:
342
343 DeviceObject - Supplies the device object associated with this request.
344
345 Irp - Supplies the request to be retried.
346
347 Srb - Supplies a Pointer to the SCSI request block to be retied.
348
349 Assocaiated - Indicates this is an assocatied Irp created by split request.
350
351 TimeDelta100ns - How long, in 100ns units, before retrying the request.
352
353Return Value:
354
355 None
356
357--*/
358VOID
361 PIRP Irp,
363 BOOLEAN Associated,
364 LONGLONG TimeDelta100ns
365 )
366{
369 ULONG transferByteCount;
370 ULONG dataTransferLength;
372
373 // This function is obsolete but is still used by some of our class drivers.
374 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "RetryRequest is OBSOLETE !"));
375
376 //
377 // Determine the transfer count of the request. If this is a read or a
378 // write then the transfer count is in the Irp stack. Otherwise assume
379 // the MDL contains the correct length. If there is no MDL then the
380 // transfer length must be zero.
381 //
382
383 dataTransferLength = SrbGetDataTransferLength(srbHeader);
384 if (currentIrpStack->MajorFunction == IRP_MJ_READ ||
385 currentIrpStack->MajorFunction == IRP_MJ_WRITE) {
386
387 _Analysis_assume_(currentIrpStack->Parameters.Read.Length <= dataTransferLength);
388 transferByteCount = currentIrpStack->Parameters.Read.Length;
389
390 } else if (Irp->MdlAddress != NULL) {
391
392 //
393 // Note this assumes that only read and write requests are spilt and
394 // other request do not need to be. If the data buffer address in
395 // the MDL and the SRB don't match then transfer length is most
396 // likely incorrect.
397 //
398
399 NT_ASSERT(SrbGetDataBuffer(srbHeader) == MmGetMdlVirtualAddress(Irp->MdlAddress));
400 _Analysis_assume_(Irp->MdlAddress->ByteCount <= dataTransferLength);
401 transferByteCount = Irp->MdlAddress->ByteCount;
402
403 } else {
404
405 transferByteCount = 0;
406 }
407
408 //
409 // this is a safety net. this should not normally be hit, since we are
410 // not guaranteed to be an fdoExtension
411 //
412
414
415 //
416 // Reset byte count of transfer in SRB Extension.
417 //
418
419 SrbSetDataTransferLength(srbHeader, transferByteCount);
420
421 //
422 // Zero SRB statuses.
423 //
424
425 srbHeader->SrbStatus = 0;
426 SrbSetScsiStatus(srbHeader, 0);
427
428 //
429 // If this is the last retry, then disable all the special flags.
430 //
431
432 if ( 0 == (ULONG)(ULONG_PTR)currentIrpStack->Parameters.Others.Argument4 ) {
433 //
434 // Set the no disconnect flag, disable synchronous data transfers and
435 // disable tagged queuing. This fixes some errors.
436 // NOTE: Cannot clear these flags, just add to them
437 //
438
439 SrbSetSrbFlags(srbHeader,
442
443 SrbSetQueueTag(srbHeader, SP_UNTAGGED);
444 }
445
446
447 //
448 // Set up major SCSI function.
449 //
450
451 nextIrpStack->MajorFunction = IRP_MJ_SCSI;
452
453 //
454 // Save SRB address in next stack for port driver.
455 //
456
457 nextIrpStack->Parameters.Scsi.Srb = Srb;
458
459 if (Associated){
461 }
462 else {
464 }
465
466 ClassRetryRequest(DeviceObject, Irp, TimeDelta100ns);
467 return;
468} // end RetryRequest()
469
470
471/*++
472
473ClassBuildRequest()
474
475Routine Description:
476
477 This routine allocates an SRB for the specified request then calls
478 ClasspBuildRequestEx to create a SCSI operation to read or write the device.
479
480 If no SRB is available then the request will be queued to be issued later
481 when requests are available. Drivers which do not want the queueing
482 behavior should allocate the SRB themselves and call ClasspBuildRequestEx
483 to issue it.
484
485Arguments:
486
487 Fdo - Supplies the functional device object associated with this request.
488
489 Irp - Supplies the request to be retried.
490
491Note:
492
493 If the IRP is for a disk transfer, the byteoffset field
494 will already have been adjusted to make it relative to
495 the beginning of the disk.
496
497
498Return Value:
499
500 NT Status
501
502--*/
504NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
508 )
509{
510 PFUNCTIONAL_DEVICE_EXTENSION fdoExtension = Fdo->DeviceExtension;
511
513
514 // This function is obsolete, but still called by CDROM.SYS .
515 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassBuildRequest is OBSOLETE !"));
516
517 //
518 // Allocate an Srb.
519 //
520
521 srb = ClasspAllocateSrb(fdoExtension);
522
523 if (srb == NULL) {
525 }
526
527 ClasspBuildRequestEx(fdoExtension, Irp, srb);
528 return STATUS_SUCCESS;
529
530} // end ClassBuildRequest()
531
532
533VOID
534#ifdef _MSC_VER
535#pragma prefast(suppress:28194) // Srb may not be aliased if it is NULL
536#endif
539 _In_ PIRP Irp,
541 )
542
543/*++
544
545ClasspBuildRequestEx()
546
547Routine Description:
548
549 This routine allocates and builds an Srb for a read or write request.
550 The block address and length are supplied by the Irp. The retry count
551 is stored in the current stack for use by ClassIoComplete which
552 processes these requests when they complete. The Irp is ready to be
553 passed to the port driver when this routine returns.
554
555Arguments:
556
557 FdoExtension - Supplies the device extension associated with this request.
558
559 Irp - Supplies the request to be issued.
560
561 Srb - Supplies an SRB to be used for the request.
562
563Note:
564
565 If the IRP is for a disk transfer, the byteoffset field
566 will already have been adjusted to make it relative to
567 the beginning of the disk.
568
569
570Return Value:
571
572 NT Status
573
574--*/
575{
578
579 LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
580
581 PCDB cdb;
582 ULONG logicalBlockAddress;
583 USHORT transferBlocks;
586
587 // This function is obsolete, but still called by CDROM.SYS .
588 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClasspBuildRequestEx is OBSOLETE !"));
589
590 if (Srb == NULL) {
592 return;
593 }
594
595 //
596 // Calculate relative sector address.
597 //
598
599 logicalBlockAddress =
600 (ULONG)(Int64ShrlMod32(startingOffset.QuadPart,
601 FdoExtension->SectorShift));
602
603 //
604 // Prepare the SRB.
605 // NOTE - for extended SRB, size used is based on allocation in ClasspAllocateSrb.
606 //
607
608 if (FdoExtension->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
612 1,
614 if (!NT_SUCCESS(status)) {
616 return;
617 }
618
620 } else {
622
623 //
624 // Write length to SRB.
625 //
626
627 Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
628
630 }
631
632
633 //
634 // Set up IRP Address.
635 //
636
637 SrbSetOriginalRequest(srbHeader, Irp);
638
639 //
640 // Set up data buffer
641 //
642
643 SrbSetDataBuffer(srbHeader,
644 MmGetMdlVirtualAddress(Irp->MdlAddress));
645
646 //
647 // Save byte count of transfer in SRB Extension.
648 //
649
650 SrbSetDataTransferLength(srbHeader,
651 currentIrpStack->Parameters.Read.Length);
652
653 //
654 // Initialize the queue actions field.
655 //
656
658
659 //
660 // Queue sort key is Relative Block Address.
661 //
662
663 SrbSetQueueSortKey(srbHeader, logicalBlockAddress);
664
665 //
666 // Indicate auto request sense by specifying buffer and size.
667 //
668
669 SrbSetSenseInfoBuffer(srbHeader, FdoExtension->SenseData);
671
672 //
673 // Set timeout value of one unit per 64k bytes of data.
674 //
675
676 SrbSetTimeOutValue(srbHeader,
677 ((SrbGetDataTransferLength(srbHeader) + 0xFFFF) >> 16) *
678 FdoExtension->TimeOutValue);
679
680 //
681 // Indicate that 10-byte CDB's will be used.
682 //
683
684 SrbSetCdbLength(srbHeader, 10);
685
686 //
687 // Fill in CDB fields.
688 //
689
690 cdb = SrbGetCdb(srbHeader);
691 NT_ASSERT(cdb != NULL);
692
693 transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >>
694 FdoExtension->SectorShift);
695
696 //
697 // Move little endian values into CDB in big endian format.
698 //
699
700 cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
701 cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
702 cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
703 cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
704
705 cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
706 cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
707
708 //
709 // Set transfer direction flag and Cdb command.
710 //
711
712 if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
713
714 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "ClassBuildRequest: Read Command\n"));
715
717 cdb->CDB10.OperationCode = SCSIOP_READ;
718
719 } else {
720
721 TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "ClassBuildRequest: Write Command\n"));
722
724 cdb->CDB10.OperationCode = SCSIOP_WRITE;
725
726 }
727
728 //
729 // If this is not a write-through request, then allow caching.
730 //
731
732 if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
733
735
736 } else {
737
738 //
739 // If write caching is enable then force media access in the
740 // cdb.
741 //
742
743 cdb->CDB10.ForceUnitAccess = FdoExtension->CdbForceUnitAccess;
744 }
745
748 }
749
750 //
751 // OR in the default flags from the device object.
752 //
753
754 SrbSetSrbFlags(srbHeader, FdoExtension->SrbFlags);
755
756 //
757 // Set up major SCSI function.
758 //
759
760 nextIrpStack->MajorFunction = IRP_MJ_SCSI;
761
762 //
763 // Save SRB address in next stack for port driver.
764 //
765
766 nextIrpStack->Parameters.Scsi.Srb = Srb;
767
768 //
769 // Save retry count in current IRP stack.
770 //
771
772 currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
773
774 //
775 // Set up IoCompletion routine address.
776 //
777
779
780}
781
782
784{
786
787 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClasspInsertCScanList is OBSOLETE !"));
788
789 //
790 // Iterate through the list. Insert this entry in the sorted list in
791 // order (after other requests for the same block). At each stop if
792 // blockNumber(Entry) >= blockNumber(t) then move on.
793 //
794
795 for(t = (PCSCAN_LIST_ENTRY) ListHead->Flink;
796 t != (PCSCAN_LIST_ENTRY) ListHead;
797 t = (PCSCAN_LIST_ENTRY) t->Entry.Flink) {
798
799 if(Entry->BlockNumber < t->BlockNumber) {
800
801 //
802 // Set the pointers in entry to the right location.
803 //
804
805 Entry->Entry.Flink = &(t->Entry);
806 Entry->Entry.Blink = t->Entry.Blink;
807
808 //
809 // Set the pointers in the surrounding elements to refer to us.
810 //
811
812 t->Entry.Blink->Flink = &(Entry->Entry);
813 t->Entry.Blink = &(Entry->Entry);
814 return;
815 }
816 }
817
818 //
819 // Insert this entry at the tail of the list. If the list was empty this
820 // will also be the head of the list.
821 //
822
823 InsertTailList(ListHead, &(Entry->Entry));
824
825}
826
827
829/*++
830
831Routine Description:
832
833 This routine inserts an entry into the CScan list based on it's block number
834 and priority. It is assumed that the caller is providing synchronization
835 to the access of the list.
836
837 Low priority requests are always scheduled to run on the next sweep across
838 the disk. Normal priority requests will be inserted into the current or
839 next sweep based on the standard C-SCAN algorithm.
840
841Arguments:
842
843 List - the list to insert into
844
845 Irp - the irp to be inserted.
846
847 BlockNumber - the block number for this request.
848
849 LowPriority - indicates that the request is lower priority and should be
850 done on the next sweep across the disk.
851
852Return Value:
853
854 none
855
856--*/
857{
858 PCSCAN_LIST_ENTRY entry = (PCSCAN_LIST_ENTRY)Irp->Tail.Overlay.DriverContext;
859
860 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInsertCScanList is OBSOLETE !"));
861
862 //
863 // Set the block number in the entry. We need this to keep the list sorted.
864 //
865 entry->BlockNumber = BlockNumber;
866
867 //
868 // If it's a normal priority request and further down the disk than our
869 // current position then insert this entry into the current sweep.
870 //
871
872 if((LowPriority != TRUE) && (BlockNumber > List->BlockNumber)) {
873 ClasspInsertCScanList(&(List->CurrentSweep), entry);
874 } else {
875 ClasspInsertCScanList(&(List->NextSweep), entry);
876 }
877 return;
878}
879
880
881
884/*++
885
886Routine Description:
887
888 This routine will attempt to reuse the provided SRB to start a blocked
889 read/write request.
890 If there is no need to reuse the request it will be returned
891 to the SRB lookaside list.
892
893Arguments:
894
895 Fdo - the device extension
896
897 Srb - the SRB which is to be reused or freed.
898
899Return Value:
900
901 none.
902
903--*/
904
905{
906 PCOMMON_DEVICE_EXTENSION commonExt = &FdoExtension->CommonExtension;
907
908 // This function is obsolete, but still called by DISK.SYS .
909 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassFreeOrReuseSrb is OBSOLETE !"));
910
911 //
912 // safety net. this should never occur. if it does, it's a potential
913 // memory leak.
914 //
916
917 if (commonExt->IsSrbLookasideListInitialized){
918 /*
919 * Put the SRB back in our lookaside list.
920 *
921 * Note: Some class drivers use ClassIoComplete
922 * to complete SRBs that they themselves allocated.
923 * So we may be putting a "foreign" SRB
924 * (e.g. with a different pool tag) into our lookaside list.
925 */
927 }
928 else {
929 TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_GENERAL,"ClassFreeOrReuseSrb: someone is trying to use an uninitialized SrbLookasideList !!!"));
930 FREE_POOL(Srb);
931 }
932}
933
934
935/*++////////////////////////////////////////////////////////////////////////////
936
937ClassDeleteSrbLookasideList()
938
939Routine Description:
940
941 This routine deletes a lookaside listhead for srbs, and should be called
942 only during the final removal.
943
944 If called at other times, the caller is responsible for
945 synchronization and removal issues.
946
947Arguments:
948
949 CommonExtension - Pointer to the CommonExtension containing the listhead.
950
951Return Value:
952
953 None
954
955--*/
957VOID
958NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
959ClassDeleteSrbLookasideList(_Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension)
960{
961 PAGED_CODE();
962
963 // This function is obsolete, but is still called by some of our code.
964 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassDeleteSrbLookasideList is OBSOLETE !"));
965
966 if (CommonExtension->IsSrbLookasideListInitialized){
967 CommonExtension->IsSrbLookasideListInitialized = FALSE;
968 ExDeleteNPagedLookasideList(&CommonExtension->SrbLookasideList);
969 }
970 else {
971 TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassDeleteSrbLookasideList: attempt to delete uninitialized or freed srblookasidelist"));
972 }
973}
974
975
976/*++////////////////////////////////////////////////////////////////////////////
977
978ClassInitializeSrbLookasideList()
979
980Routine Description:
981
982 This routine sets up a lookaside listhead for srbs, and should be called
983 only from the ClassInitDevice() routine to prevent race conditions.
984
985 If called from other locations, the caller is responsible for
986 synchronization and removal issues.
987
988Arguments:
989
990 CommonExtension - Pointer to the CommonExtension containing the listhead.
991
992 NumberElements - Supplies the maximum depth of the lookaside list.
993
994
995Note:
996
997 The Windows 2000 version of classpnp did not return any status value from
998 this call.
999
1000--*/
1001
1003VOID
1004NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1005ClassInitializeSrbLookasideList( _Inout_ PCOMMON_DEVICE_EXTENSION CommonExtension,
1007{
1008 size_t sizeNeeded;
1010
1011 PAGED_CODE();
1012
1013 // This function is obsolete, but still called by DISK.SYS .
1014 // TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_GENERAL, "ClassInitializeSrbLookasideList is OBSOLETE !"));
1015
1016 NT_ASSERT(!CommonExtension->IsSrbLookasideListInitialized);
1017 if (!CommonExtension->IsSrbLookasideListInitialized){
1018
1019 if (CommonExtension->IsFdo == TRUE) {
1020 fdo = (PFUNCTIONAL_DEVICE_EXTENSION)CommonExtension;
1021
1022 //
1023 // Check FDO extension on the SRB type supported
1024 //
1026
1027 //
1028 // It's 16 byte CDBs for now. Need to change when classpnp uses >16
1029 // byte CDBs or support new address types.
1030 //
1032
1033 } else {
1034 sizeNeeded = sizeof(SCSI_REQUEST_BLOCK);
1035 }
1036
1037 } else {
1038
1039 //
1040 // For PDO, use the max of old and new SRB as can't guarantee we can get
1041 // corresponding FDO to determine SRB support.
1042 //
1044 }
1045
1046 ExInitializeNPagedLookasideList(&CommonExtension->SrbLookasideList,
1047 NULL,
1048 NULL,
1050 sizeNeeded,
1051 '$scS',
1053
1054 CommonExtension->IsSrbLookasideListInitialized = TRUE;
1055 }
1056
1057}
1058
1059
1060
1061
1063{
1064 PAGED_CODE();
1065 RtlZeroMemory(List, sizeof(CSCAN_LIST));
1066 InitializeListHead(&(List->CurrentSweep));
1067 InitializeListHead(&(List->NextSweep));
1068}
1069
1070
1071
1073{
1074 NT_ASSERT(IsListEmpty(&(List->CurrentSweep)) == TRUE);
1075
1076 //
1077 // If the next sweep is empty then there's nothing to do.
1078 //
1079
1080 if(IsListEmpty(&(List->NextSweep))) {
1081 return;
1082 }
1083
1084 //
1085 // Copy the next sweep list head into the current sweep list head.
1086 //
1087
1088 List->CurrentSweep = List->NextSweep;
1089
1090 //
1091 // Unlink the next sweep list from the list head now that we have a copy
1092 // of it.
1093 //
1094
1095 InitializeListHead(&(List->NextSweep));
1096
1097 //
1098 // Update the next sweep list to point back to the current sweep list head.
1099 //
1100
1101 List->CurrentSweep.Flink->Blink = &(List->CurrentSweep);
1102 List->CurrentSweep.Blink->Flink = &(List->CurrentSweep);
1103
1104 return;
1105}
1106
1107
1108
1110{
1112
1113 //
1114 // If the current sweep is empty then promote the next sweep.
1115 //
1116
1117 if(IsListEmpty(&(List->CurrentSweep))) {
1119 }
1120
1121 //
1122 // If the current sweep is still empty then we're done.
1123 //
1124
1125 if(IsListEmpty(&(List->CurrentSweep))) {
1126 return NULL;
1127 }
1128
1129 //
1130 // Remove the head entry from the current sweep. Record it's block number
1131 // so that nothing before it on the disk gets into the current sweep.
1132 //
1133
1134 entry = (PCSCAN_LIST_ENTRY) RemoveHeadList(&(List->CurrentSweep));
1135
1136 List->BlockNumber = entry->BlockNumber;
1137
1138 return CONTAINING_RECORD(entry, IRP, Tail.Overlay.DriverContext);
1139}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define PAGED_CODE()
unsigned char BOOLEAN
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define MAX(x, y)
Definition: rdesktop.h:175
#define __drv_aliasesMem
Definition: btrfs_drv.h:203
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:826
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER(_In_ PCDROM_DEVICE_EXTENSION DeviceExtension, _In_ PSCSI_REQUEST_BLOCK Srb)
Definition: cdrom.h:839
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_READ
Definition: cdrw_hw.h:905
NTSTATUS InitializeStorageRequestBlock(_Inout_bytecount_(ByteSize) PSTORAGE_REQUEST_BLOCK Srb, _In_ USHORT AddressType, _In_ ULONG ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:206
FORCEINLINE UCHAR GET_FDO_EXTENSON_SENSE_DATA_LENGTH(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: classpnp.h:1437
#define ClasspFreeSrb(ext, srb)
Definition: classpnp.h:150
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
#define ClasspAllocateSrb(ext)
Definition: classpnp.h:146
struct _FUNCTIONAL_DEVICE_EXTENSION * PFUNCTIONAL_DEVICE_EXTENSION
#define CLASS_SRBEX_SCSI_CDB16_BUFFER_SIZE
Definition: classpnp.h:695
_In_ ULONG NumberElements
Definition: classpnp.h:1137
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS NTAPI ClassIoComplete(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: class.c:3768
VOID ClassRetryRequest(IN PDEVICE_OBJECT SelfDeviceObject, IN PIRP Irp, _In_ _In_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) IN LONGLONG TimeDelta100ns)
Definition: class.c:12317
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
BOOLEAN InterpretSenseInfoWithoutHistory(_In_ PDEVICE_OBJECT Fdo, _In_opt_ PIRP OriginalRequest, _In_ PSCSI_REQUEST_BLOCK Srb, UCHAR MajorFunctionCode, ULONG IoDeviceCode, ULONG PreviousRetryCount, _Out_ NTSTATUS *Status, _Out_opt_ _Deref_out_range_(0, MAXIMUM_RETRY_FOR_SINGLE_IO_IN_100NS_UNITS) LONGLONG *RetryIn100nsUnits)
Definition: class.c:12844
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
struct _CSCAN_LIST_ENTRY * PCSCAN_LIST_ENTRY
VOID RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated, LONGLONG TimeDelta100ns)
Definition: obsolete.c:359
PIRP ClassRemoveCScanList(IN PCSCAN_LIST List)
Definition: obsolete.c:1109
VOID ClasspInitializeCScanList(IN PCSCAN_LIST List)
Definition: obsolete.c:1062
VOID ClasspInsertCScanList(IN PLIST_ENTRY ListHead, IN PCSCAN_LIST_ENTRY Entry)
Definition: obsolete.c:783
NTSTATUS NTAPI ClassIoCompleteAssociated(IN PDEVICE_OBJECT Fdo, IN PIRP Irp, IN PVOID Context)
Definition: obsolete.c:111
VOID ClasspBuildRequestEx(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp, _In_ __drv_aliasesMem PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:537
VOID NTAPI ClassSplitRequest(_In_ PDEVICE_OBJECT Fdo, _In_ PIRP Irp, _In_ ULONG MaximumBytes)
Definition: obsolete.c:61
VOID ClasspStartNextSweep(PCSCAN_LIST List)
Definition: obsolete.c:1072
struct _CSCAN_LIST_ENTRY CSCAN_LIST_ENTRY
NTSTATUS NTAPI ClassBuildRequest(_In_ PDEVICE_OBJECT Fdo, _In_ PIRP Irp)
Definition: obsolete.c:505
VOID ClassFreeOrReuseSrb(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, IN __drv_freesMem(mem) PSCSI_REQUEST_BLOCK Srb)
Definition: obsolete.c:882
VOID ClassInsertCScanList(IN PCSCAN_LIST List, IN PIRP Irp, IN ULONGLONG BlockNumber, IN BOOLEAN LowPriority)
Definition: obsolete.c:828
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FLAGS_FREE_SENSE_BUFFER
Definition: srb.h:406
#define SP_UNTAGGED
Definition: srb.h:233
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:396
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:423
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:395
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:405
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
@ FdoExtension
Definition: precomp.h:48
#define __drv_freesMem(kind)
Definition: driverspecs.h:272
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
struct _FOUR_BYTE * PFOUR_BYTE
GLdouble GLdouble t
Definition: gl.h:2047
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:490
uint32_t entry
Definition: isohybrid.c:63
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
#define _Inout_
Definition: ms_sal.h:378
#define _In_
Definition: ms_sal.h:308
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
#define Int64ShrlMod32(a, b)
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
#define STORAGE_ADDRESS_TYPE_BTL8
Definition: srb.h:666
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:661
@ SrbExDataTypeScsiCdb16
Definition: srb.h:459
struct SRB_ALIGN _STORAGE_REQUEST_BLOCK_HEADER * PSTORAGE_REQUEST_BLOCK_HEADER
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
#define STATUS_SUCCESS
Definition: shellext.h:65
FORCEINLINE VOID SrbSetSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:964
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
FORCEINLINE VOID SrbSetQueueSortKey(_In_ PVOID Srb, _In_ ULONG QueueSortKey)
Definition: srbhelper.h:839
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
FORCEINLINE VOID SrbClearSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:982
FORCEINLINE VOID SrbSetScsiStatus(_In_ PVOID Srb, _In_ UCHAR ScsiStatus)
Definition: srbhelper.h:1056
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
FORCEINLINE ULONG SrbGetSrbFlags(_In_ PVOID Srb)
Definition: srbhelper.h:927
FORCEINLINE VOID SrbSetQueueTag(_In_ PVOID Srb, _In_ ULONG QueueTag)
Definition: srbhelper.h:853
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
FORCEINLINE PVOID SrbGetDataBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:728
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
FORCEINLINE ULONG SrbGetDataTransferLength(_In_ PVOID Srb)
Definition: srbhelper.h:765
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
base of all file and directory entries
Definition: entries.h:83
Entry(ENTRY_TYPE etype)
Definition: entries.cpp:35
CLASS_INIT_DATA InitData
Definition: classpnp.h:577
PDRIVER_STARTIO ClassStartIo
Definition: classpnp.h:543
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:600
BOOLEAN IsSrbLookasideListInitialized
Definition: classpnp.h:610
Definition: obsolete.c:42
LIST_ENTRY Entry
Definition: obsolete.c:43
ULONGLONG BlockNumber
Definition: obsolete.c:44
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
struct _IO_STACK_LOCATION::@3974::@3996 Scsi
struct _IO_STACK_LOCATION::@3974::@3978 Read
struct _IO_STACK_LOCATION::@1575::@1576 DeviceIoControl
union _IO_STACK_LOCATION::@1575 Parameters
struct _IO_STACK_LOCATION::@3974::@4013 Others
union _IRP::@1577 AssociatedIrp
IO_STATUS_BLOCK IoStatus
Definition: typedefs.h:120
UCHAR Function
Definition: srb.h:250
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
Definition: mem.c:156
Definition: ps.c:97
#define max(a, b)
Definition: svc.c:63
int64_t LONGLONG
Definition: typedefs.h:68
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
Definition: cdrw_hw.h:28
struct _CDB::_CDB10 CDB10
LONGLONG QuadPart
Definition: typedefs.h:114
#define SrbGetCdb(srb)
Definition: usbstor.h:18
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
#define IRP_MJ_SCSI
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1823
#define IRP_PAGING_IO
#define POOL_NX_ALLOCATION
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#define IRP_SYNCHRONOUS_PAGING_IO
#define MmGetMdlVirtualAddress(_Mdl)
#define NT_ASSERT
Definition: rtlfuncs.h:3324
unsigned char UCHAR
Definition: xmlstorage.h:181