ReactOS  0.4.15-dev-3182-g7b62228
xferpkt.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1991 - 2010
4 
5 Module Name:
6 
7  xferpkt.c
8 
9 Abstract:
10 
11  Packet routines for CLASSPNP
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19 
20 Revision History:
21 
22 --*/
23 
24 #include "classp.h"
25 #include "debug.h"
26 
27 #ifdef DEBUG_USE_WPP
28 #include "xferpkt.tmh"
29 #endif
30 
31 #ifdef ALLOC_PRAGMA
32  #pragma alloc_text(PAGE, InitializeTransferPackets)
33  #pragma alloc_text(PAGE, DestroyAllTransferPackets)
34  #pragma alloc_text(PAGE, SetupEjectionTransferPacket)
35  #pragma alloc_text(PAGE, SetupModeSenseTransferPacket)
36  #pragma alloc_text(PAGE, CleanupTransferPacketToWorkingSetSizeWorker)
37  #pragma alloc_text(PAGE, ClasspSetupPopulateTokenTransferPacket)
38 #endif
39 
40 /*
41  * InitializeTransferPackets
42  *
43  * Allocate/initialize TRANSFER_PACKETs and related resources.
44  */
46 {
47  PCOMMON_DEVICE_EXTENSION commonExt = Fdo->DeviceExtension;
48  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
49  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
50  PSTORAGE_ADAPTER_DESCRIPTOR adapterDesc = commonExt->PartitionZeroExtension->AdapterDescriptor;
51  PSTORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR devIoCapabilityDesc = NULL;
52  STORAGE_PROPERTY_ID propertyId;
53  OSVERSIONINFOEXW osVersionInfo;
54  ULONG hwMaxPages;
55  ULONG arraySize;
56  ULONG index;
57  ULONG maxOutstandingIOPerLUN;
58  ULONG minWorkingSetTransferPackets;
59  ULONG maxWorkingSetTransferPackets;
60 
62 
63  PAGED_CODE();
64 
65  //
66  // Precompute the maximum transfer length
67  //
68  NT_ASSERT(adapterDesc->MaximumTransferLength);
69 
70  hwMaxPages = adapterDesc->MaximumPhysicalPages ? adapterDesc->MaximumPhysicalPages-1 : 0;
71 
72  fdoData->HwMaxXferLen = MIN(adapterDesc->MaximumTransferLength, hwMaxPages << PAGE_SHIFT);
73  fdoData->HwMaxXferLen = MAX(fdoData->HwMaxXferLen, PAGE_SIZE);
74 
75  //
76  // Allocate per-node free packet lists
77  //
78  arraySize = KeQueryHighestNodeNumber() + 1;
79  fdoData->FreeTransferPacketsLists =
80  ExAllocatePoolWithTag(NonPagedPoolNxCacheAligned,
81  sizeof(PNL_SLIST_HEADER) * arraySize,
83 
84  if (fdoData->FreeTransferPacketsLists == NULL) {
86  return status;
87  }
88 
89  for (index = 0; index < arraySize; index++) {
93  }
94 
96 
97  //
98  // Set the packet threshold numbers based on the Windows Client or Server SKU.
99  //
100 
101  osVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
102  status = RtlGetVersion((POSVERSIONINFOW) &osVersionInfo);
103 
105 
106  //
107  // Retrieve info on IO capability supported by port drivers
108  //
109 
111  status = ClassGetDescriptor(fdoExt->CommonExtension.LowerDeviceObject,
112  &propertyId,
113  (PVOID *)&devIoCapabilityDesc);
114 
115  if (NT_SUCCESS(status) && (devIoCapabilityDesc != NULL)) {
116  maxOutstandingIOPerLUN = devIoCapabilityDesc->LunMaxIoCount;
117  FREE_POOL(devIoCapabilityDesc);
118 
119 #if DBG
120  fdoData->MaxOutstandingIOPerLUN = maxOutstandingIOPerLUN;
121 #endif
122 
123  } else {
124  maxOutstandingIOPerLUN = MAX_OUTSTANDING_IO_PER_LUN_DEFAULT;
125 
126 #if DBG
127  fdoData->MaxOutstandingIOPerLUN = 0;
128 #endif
129 
130  }
131 
132  //
133  // StorageDeviceIoCapabilityProperty support is optional so
134  // ignore any failures.
135  //
136 
138 
139 
140  if ((osVersionInfo.wProductType != VER_NT_DOMAIN_CONTROLLER) &&
141  (osVersionInfo.wProductType != VER_NT_SERVER)) {
142 
143  // this is Client SKU
144 
145  minWorkingSetTransferPackets = MIN_WORKINGSET_TRANSFER_PACKETS_Client;
146 
147  // Note: the reason we use max here is to guarantee a reasonable large max number
148  // in the case where the port driver may return a very small supported outstanding
149  // IOs. For example, even EMMC drive only reports 1 outstanding IO supported, we
150  // may still want to set this value to be at least
151  // MAX_WORKINGSET_TRANSFER_PACKETS_Client.
152  maxWorkingSetTransferPackets = max(MAX_WORKINGSET_TRANSFER_PACKETS_Client,
153  2 * maxOutstandingIOPerLUN);
154 
155  } else {
156 
157  // this is Server SKU
158  // Note: the addition max here to make sure we set the min to be at least
159  // MIN_WORKINGSET_TRANSFER_PACKETS_Server_LowerBound no matter what maxOutstandingIOPerLUN
160  // reported. We shouldn't set this value to be smaller than client system.
161  // In other words, the minWorkingSetTransferPackets for server will always between
162  // MIN_WORKINGSET_TRANSFER_PACKETS_Server_LowerBound and MIN_WORKINGSET_TRANSFER_PACKETS_Server_UpperBound
163 
164  minWorkingSetTransferPackets =
167  maxOutstandingIOPerLUN));
168 
169  maxWorkingSetTransferPackets = max(MAX_WORKINGSET_TRANSFER_PACKETS_Server,
170  2 * maxOutstandingIOPerLUN);
171  }
172 
173 
174  fdoData->LocalMinWorkingSetTransferPackets = minWorkingSetTransferPackets;
175  fdoData->LocalMaxWorkingSetTransferPackets = maxWorkingSetTransferPackets;
176 
177  //
178  // Allow class driver to override the settings
179  //
180  if (commonExt->DriverExtension->WorkingSet != NULL) {
181  PCLASS_WORKING_SET workingSet = commonExt->DriverExtension->WorkingSet;
182 
183  // override only if non-zero
184  if (workingSet->XferPacketsWorkingSetMinimum != 0)
185  {
186  fdoData->LocalMinWorkingSetTransferPackets = workingSet->XferPacketsWorkingSetMinimum;
187  // adjust maximum upwards if needed
189  {
191  }
192  }
193  // override only if non-zero
194  if (workingSet->XferPacketsWorkingSetMaximum != 0)
195  {
196  fdoData->LocalMaxWorkingSetTransferPackets = workingSet->XferPacketsWorkingSetMaximum;
197  // adjust minimum downwards if needed
199  {
201  }
202  }
203  // that's all the adjustments required/allowed
204  } // end working set size special code
205 
206  for (index = 0; index < arraySize; index++) {
208  PTRANSFER_PACKET pkt = NewTransferPacket(Fdo);
209  if (pkt) {
211  pkt->AllocateNode = index;
213  } else {
215  break;
216  }
217  }
219  }
220 
221  //
222  // Pre-initialize our SCSI_REQUEST_BLOCK template with all
223  // the constant fields. This will save a little time for each xfer.
224  // NOTE: a CdbLength field of 10 may not always be appropriate
225  //
226 
227  if (NT_SUCCESS(status)) {
228  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
229  ULONG ByteSize = 0;
230 
231  #if (NTDDI_VERSION >= NTDDI_WINBLUE)
232  if ((fdoExt->MiniportDescriptor != NULL) &&
233  (fdoExt->MiniportDescriptor->Size >= RTL_SIZEOF_THROUGH_FIELD(STORAGE_MINIPORT_DESCRIPTOR, ExtraIoInfoSupported)) &&
234  (fdoExt->MiniportDescriptor->ExtraIoInfoSupported == TRUE)) {
236  fdoExt->AdapterDescriptor->AddressType,
238  &ByteSize,
239  2,
242  );
243  } else {
245  fdoExt->AdapterDescriptor->AddressType,
247  &ByteSize,
248  1,
250  );
251  }
252  #else
254  fdoExt->AdapterDescriptor->AddressType,
256  &ByteSize,
257  1,
259  );
260  #endif
261  if (NT_SUCCESS(status)) {
263  } else {
264  NT_ASSERT(FALSE);
265  }
266  } else {
267  fdoData->SrbTemplate = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(SCSI_REQUEST_BLOCK), '-brs');
268  if (fdoData->SrbTemplate == NULL) {
270  } else {
271  RtlZeroMemory(fdoData->SrbTemplate, sizeof(SCSI_REQUEST_BLOCK));
272  fdoData->SrbTemplate->Length = sizeof(SCSI_REQUEST_BLOCK);
273  fdoData->SrbTemplate->Function = SRB_FUNCTION_EXECUTE_SCSI;
274  }
275  }
276  }
277 
278  if (status == STATUS_SUCCESS) {
281  SrbSetCdbLength(fdoData->SrbTemplate, 10);
282  }
283 
284  return status;
285 }
286 
287 
289 {
290  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
291  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
292  TRANSFER_PACKET *pkt;
293  ULONG index;
294  ULONG arraySize;
295 
296  PAGED_CODE();
297 
298  //
299  // fdoData->FreeTransferPacketsLists could be NULL if
300  // there was an error during start device.
301  //
302  if (fdoData->FreeTransferPacketsLists != NULL) {
303 
305 
306  arraySize = KeQueryHighestNodeNumber() + 1;
307  for (index = 0; index < arraySize; index++) {
309  while (pkt) {
313  }
314 
316  }
317  }
318 
319  FREE_POOL(fdoData->SrbTemplate);
320 }
321 
323 #ifdef _MSC_VER
324 #pragma warning(suppress:28195) // This function may not allocate memory in some error cases.
325 #endif
326 PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo)
327 {
328  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
329  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
330  PTRANSFER_PACKET newPkt = NULL;
331  ULONG transferLength = (ULONG)-1;
333 
334  if (NT_SUCCESS(status)) {
335  status = RtlULongAdd(fdoData->HwMaxXferLen, PAGE_SIZE, &transferLength);
336  if (!NT_SUCCESS(status)) {
337 
338  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_RW, "Integer overflow in calculating transfer packet size."));
340  }
341  }
342 
343  /*
344  * Allocate the actual packet.
345  */
346  if (NT_SUCCESS(status)) {
347  newPkt = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(TRANSFER_PACKET), 'pnPC');
348  if (newPkt == NULL) {
349  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate transfer packet."));
351  } else {
352  RtlZeroMemory(newPkt, sizeof(TRANSFER_PACKET));
354  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
355 #if (NTDDI_VERSION >= NTDDI_WINBLUE)
356  if ((fdoExt->MiniportDescriptor != NULL) &&
357  (fdoExt->MiniportDescriptor->Size >= RTL_SIZEOF_THROUGH_FIELD(STORAGE_MINIPORT_DESCRIPTOR, ExtraIoInfoSupported)) &&
358  (fdoExt->MiniportDescriptor->ExtraIoInfoSupported == TRUE)) {
360  fdoExt->AdapterDescriptor->AddressType,
362  NULL,
363  2,
366  );
367  } else {
369  fdoExt->AdapterDescriptor->AddressType,
371  NULL,
372  1,
374  );
375  }
376 #else
378  fdoExt->AdapterDescriptor->AddressType,
380  NULL,
381  1,
383  );
384 #endif
385  } else {
386 #ifdef _MSC_VER
387 #pragma prefast(suppress:6014, "The allocated memory that Pkt->Srb points to will be freed in DestroyTransferPacket().")
388 #endif
389  newPkt->Srb = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(SCSI_REQUEST_BLOCK), '-brs');
390  if (newPkt->Srb == NULL) {
392  }
393 
394  }
395 
396  if (status != STATUS_SUCCESS)
397  {
398  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate SRB."));
399  FREE_POOL(newPkt);
400  }
401  }
402  }
403 
404  /*
405  * Allocate Irp for the packet.
406  */
407  if (NT_SUCCESS(status) && newPkt != NULL) {
408  newPkt->Irp = IoAllocateIrp(Fdo->StackSize, FALSE);
409  if (newPkt->Irp == NULL) {
410  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate IRP for transfer packet."));
412  }
413  }
414 
415  /*
416  * Allocate a MDL. Add one page to the length to insure an extra page
417  * entry is allocated if the buffer does not start on page boundaries.
418  */
419  if (NT_SUCCESS(status) && newPkt != NULL) {
420 
421  NT_ASSERT(transferLength != (ULONG)-1);
422 
423  newPkt->PartialMdl = IoAllocateMdl(NULL,
424  transferLength,
425  FALSE,
426  FALSE,
427  NULL);
428  if (newPkt->PartialMdl == NULL) {
429  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate MDL for transfer packet."));
431  } else {
432  NT_ASSERT(newPkt->PartialMdl->Size >= (CSHORT)(sizeof(MDL) + BYTES_TO_PAGES(fdoData->HwMaxXferLen) * sizeof(PFN_NUMBER)));
433  }
434 
435  }
436 
437  /*
438  * Allocate per-packet retry history, if required
439  */
440  if (NT_SUCCESS(status) &&
441  (fdoData->InterpretSenseInfo != NULL) &&
442  (newPkt != NULL)
443  ) {
444  // attempt to allocate also the history
445  ULONG historyByteCount = 0;
446 
447  // SAL annotation and ClassInitializeEx() should both catch this case
448  NT_ASSERT(fdoData->InterpretSenseInfo->HistoryCount != 0);
449  _Analysis_assume_(fdoData->InterpretSenseInfo->HistoryCount != 0);
450 
451  historyByteCount = sizeof(SRB_HISTORY_ITEM) * fdoData->InterpretSenseInfo->HistoryCount;
452  historyByteCount += sizeof(SRB_HISTORY) - sizeof(SRB_HISTORY_ITEM);
453 
454  newPkt->RetryHistory = (PSRB_HISTORY)ExAllocatePoolWithTag(NonPagedPoolNx, historyByteCount, 'hrPC');
455 
456  if (newPkt->RetryHistory == NULL) {
457  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "Failed to allocate MDL for transfer packet."));
459  } else {
460  // call this routine directly once since it's the first initialization of
461  // the structure and the internal maximum count field is not yet setup.
462  HistoryInitializeRetryLogs(newPkt->RetryHistory, fdoData->InterpretSenseInfo->HistoryCount);
463  }
464  }
465 
466  /*
467  * Enqueue the packet in our static AllTransferPacketsList
468  * (just so we can find it during debugging if its stuck somewhere).
469  */
470  if (NT_SUCCESS(status) && newPkt != NULL)
471  {
472  KIRQL oldIrql;
473  newPkt->Fdo = Fdo;
474 #if DBG
475  newPkt->DbgPktId = InterlockedIncrement((volatile LONG *)&fdoData->DbgMaxPktId);
476 #endif
477  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
479  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
480 
481  } else {
482  // free any resources acquired above (in reverse order)
483  if (newPkt != NULL) {
484  FREE_POOL(newPkt->RetryHistory);
485  if (newPkt->PartialMdl != NULL) { IoFreeMdl(newPkt->PartialMdl); }
486  if (newPkt->Irp != NULL) { IoFreeIrp(newPkt->Irp); }
487  if (newPkt->Srb != NULL) { FREE_POOL(newPkt->Srb); }
488  FREE_POOL(newPkt);
489  }
490  }
491 
492  return newPkt;
493 }
494 
495 
496 /*
497  * DestroyTransferPacket
498  *
499  */
501 {
503  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
504  KIRQL oldIrql;
505 
506  NT_ASSERT(!Pkt->SlistEntry.Next);
507 // NT_ASSERT(!Pkt->OriginalIrp);
508 
509  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
510 
511  /*
512  * Delete the packet from our all-packets queue.
513  */
518 
519  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
520 
522  IoFreeIrp(Pkt->Irp);
524  FREE_POOL(Pkt->Srb);
525  FREE_POOL(Pkt);
526 }
527 
528 
530 {
531  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
532  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
533  ULONG allocateNode;
534  KIRQL oldIrql;
535 
536  NT_ASSERT(!Pkt->SlistEntry.Next);
537 
538  allocateNode = Pkt->AllocateNode;
540  InterlockedIncrement((volatile LONG *)&(fdoData->FreeTransferPacketsLists[allocateNode].NumFreeTransferPackets));
541 
542  /*
543  * If the total number of packets is larger than LocalMinWorkingSetTransferPackets,
544  * that means that we've been in stress. If all those packets are now
545  * free, then we are now out of stress and can free the extra packets.
546  * Attempt to free down to LocalMaxWorkingSetTransferPackets immediately, and
547  * down to LocalMinWorkingSetTransferPackets lazily (one at a time).
548  * However, since we're at DPC, do this is a work item. If the device is removed
549  * or we are unable to allocate the work item, do NOT free more than
550  * MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE. Subsequent IO completions will end up freeing
551  * up the rest, even if it is MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE at a time.
552  */
553  if (fdoData->FreeTransferPacketsLists[allocateNode].NumFreeTransferPackets >=
554  fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets) {
555 
556  /*
557  * 1. Immediately snap down to our UPPER threshold.
558  */
559  if (fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets >
561 
562  ULONG isRemoved;
563  PIO_WORKITEM workItem = NULL;
564 
565  workItem = IoAllocateWorkItem(Fdo);
566 
567  //
568  // Acquire a remove lock in order to make sure the device object and its
569  // private data structures will exist when the workitem fires.
570  // The remove lock will be released by the workitem (CleanupTransferPacketToWorkingSetSize).
571  //
572  isRemoved = ClassAcquireRemoveLock(Fdo, (PIRP)workItem);
573 
574  if (workItem && !isRemoved) {
575 
576  TracePrint((TRACE_LEVEL_INFORMATION,
577  TRACE_FLAG_GENERAL,
578  "EnqueueFreeTransferPacket: Device (%p), queuing work item to clean up free transfer packets.\n",
579  Fdo));
580 
581  //
582  // Queue a work item to trim down the total number of transfer packets to with the
583  // working size.
584  //
586 
587  } else {
588 
589  if (workItem) {
590  IoFreeWorkItem(workItem);
591  }
592 
593  if (isRemoved != REMOVE_COMPLETE) {
594  ClassReleaseRemoveLock(Fdo, (PIRP)workItem);
595  }
596 
597  TracePrint((TRACE_LEVEL_ERROR,
598  TRACE_FLAG_GENERAL,
599  "EnqueueFreeTransferPacket: Device (%p), Failed to allocate memory for the work item.\n",
600  Fdo));
601 
603  }
604  }
605 
606  /*
607  * 2. Lazily work down to our LOWER threshold (by only freeing one packet at a time).
608  */
609  if (fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets >
611  /*
612  * Check the counter again with lock held. This eliminates a race condition
613  * while still allowing us to not grab the spinlock in the common codepath.
614  *
615  * Note that the spinlock does not synchronize with threads dequeuing free
616  * packets to send (DequeueFreeTransferPacket does that with a lightweight
617  * interlocked exchange); the spinlock prevents multiple threads in this function
618  * from deciding to free too many extra packets at once.
619  */
620  PTRANSFER_PACKET pktToDelete = NULL;
621 
622  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "Exiting stress, lazily freeing one of %d/%d packets from node %d.",
623  fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets,
625  allocateNode));
626 
627  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
628  if ((fdoData->FreeTransferPacketsLists[allocateNode].NumFreeTransferPackets >=
629  fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets) &&
630  (fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets >
632 
633  pktToDelete = DequeueFreeTransferPacketEx(Fdo, FALSE, allocateNode);
634  if (pktToDelete) {
635  InterlockedDecrement((volatile LONG *)&(fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets));
636  } else {
637  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW,
638  "Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (2). Node=%d",
640  Fdo,
641  fdoData->FreeTransferPacketsLists[allocateNode].NumTotalTransferPackets,
642  allocateNode));
643  }
644  }
645  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
646 
647  if (pktToDelete) {
648  DestroyTransferPacket(pktToDelete);
649  }
650  }
651 
652  }
653 
654 }
655 
657 {
658  return DequeueFreeTransferPacketEx(Fdo, AllocIfNeeded, KeGetCurrentNodeNumber());
659 }
660 
663  _In_ BOOLEAN AllocIfNeeded,
664  _In_ ULONG Node)
665 {
666  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
667  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
668  PTRANSFER_PACKET pkt;
669  PSLIST_ENTRY slistEntry;
670 
672 
673  if (slistEntry) {
674  slistEntry->Next = NULL;
675  pkt = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
677 
678  // when dequeuing the packet, also reset the history data
680 
681  } else {
682  if (AllocIfNeeded) {
683  /*
684  * We are in stress and have run out of lookaside packets.
685  * In order to service the current transfer,
686  * allocate an extra packet.
687  * We will free it lazily when we are out of stress.
688  */
689  pkt = NewTransferPacket(Fdo);
690  if (pkt) {
695  } else {
696  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_RW, "DequeueFreeTransferPacket: packet allocation failed"));
697  }
698  } else {
699  pkt = NULL;
700  }
701  }
702 
703  return pkt;
704 }
705 
706 
707 
708 /*
709  * SetupReadWriteTransferPacket
710  *
711  * This function is called once to set up the first attempt to send a packet.
712  * It is not called before a retry, as SRB fields may be modified for the retry.
713  *
714  * Set up the Srb of the TRANSFER_PACKET for the transfer.
715  * The Irp is set up in SubmitTransferPacket because it must be reset
716  * for each packet submission.
717  */
719  PVOID Buf,
720  ULONG Len,
721  LARGE_INTEGER DiskLocation,
723 {
725  PCOMMON_DEVICE_EXTENSION commonExtension = Pkt->Fdo->DeviceExtension;
726  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
728  UCHAR majorFunc = origCurSp->MajorFunction;
729  LARGE_INTEGER logicalBlockAddr;
730  ULONG numTransferBlocks;
731  PCDB pCdb;
732  ULONG srbLength;
733  ULONG timeoutValue = fdoExt->TimeOutValue;
734 
735  logicalBlockAddr.QuadPart = Int64ShrlMod32(DiskLocation.QuadPart, fdoExt->SectorShift);
736  numTransferBlocks = Len >> fdoExt->SectorShift;
737 
738  /*
739  * This field is useful when debugging, since low-memory conditions are
740  * handled differently for CDROM (which is the only driver using StartIO)
741  */
743 
744  /*
745  * Slap the constant SRB fields in from our pre-initialized template.
746  * We'll then only have to fill in the unique fields for this transfer.
747  * Tell lower drivers to sort the SRBs by the logical block address
748  * so that disk seeks are minimized.
749  */
750  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
751  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
752  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
753  } else {
754  srbLength = fdoData->SrbTemplate->Length;
755  }
756  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
757  SrbSetDataBuffer(Pkt->Srb, Buf);
759  SrbSetQueueSortKey(Pkt->Srb, logicalBlockAddr.LowPart);
760  if (logicalBlockAddr.QuadPart > 0xFFFFFFFF) {
761  //
762  // If the requested LBA is more than max ULONG set the
763  // QueueSortKey to the maximum value, so that these
764  // requests can be added towards the end of the queue.
765  //
766 
767  SrbSetQueueSortKey(Pkt->Srb, 0xFFFFFFFF);
768  }
771 
772 
773  SrbSetTimeOutValue(Pkt->Srb, timeoutValue);
774 
775  /*
776  * Arrange values in CDB in big-endian format.
777  */
778  pCdb = SrbGetCdb(Pkt->Srb);
779  if (pCdb) {
780  if (TEST_FLAG(fdoExt->DeviceFlags, DEV_USE_16BYTE_CDB)) {
781  REVERSE_BYTES_QUAD(&pCdb->CDB16.LogicalBlock, &logicalBlockAddr);
782  REVERSE_BYTES(&pCdb->CDB16.TransferLength, &numTransferBlocks);
783  pCdb->CDB16.OperationCode = (majorFunc==IRP_MJ_READ) ? SCSIOP_READ16 : SCSIOP_WRITE16;
784  SrbSetCdbLength(Pkt->Srb, 16);
785  } else {
786  pCdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte3;
787  pCdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte2;
788  pCdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte1;
789  pCdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddr.LowPart)->Byte0;
790  pCdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&numTransferBlocks)->Byte1;
791  pCdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&numTransferBlocks)->Byte0;
792  pCdb->CDB10.OperationCode = (majorFunc==IRP_MJ_READ) ? SCSIOP_READ : SCSIOP_WRITE;
793  }
794  }
795 
796  /*
797  * Set SRB and IRP flags
798  */
799  SrbAssignSrbFlags(Pkt->Srb, fdoExt->SrbFlags);
800  if (TEST_FLAG(OriginalIrp->Flags, IRP_PAGING_IO) ||
803  }
805 
806  /*
807  * Allow caching only if this is not a write-through request.
808  * If write-through and caching is enabled on the device, force
809  * media access.
810  * Ignore SL_WRITE_THROUGH for reads; it's only set because the file handle was opened with WRITE_THROUGH.
811  */
812  if ((majorFunc == IRP_MJ_WRITE) && TEST_FLAG(origCurSp->Flags, SL_WRITE_THROUGH) && pCdb) {
813  pCdb->CDB10.ForceUnitAccess = fdoExt->CdbForceUnitAccess;
814  } else {
816  }
817 
818  /*
819  * Remember the buf and len in the SRB because miniports
820  * can overwrite SRB.DataTransferLength and we may need it again
821  * for the retry.
822  */
823  Pkt->BufPtrCopy = Buf;
824  Pkt->BufLenCopy = Len;
825  Pkt->TargetLocationCopy = DiskLocation;
826 
828  Pkt->NumRetries = fdoData->MaxNumberOfIoRetries;
829  Pkt->SyncEventPtr = NULL;
831 #if !defined(__REACTOS__) && NTDDI_VERSION >= NTDDI_WINBLUE
834 #endif
835 
836 
837  if (pCdb) {
838  DBGLOGFLUSHINFO(fdoData, TRUE, (BOOLEAN)(pCdb->CDB10.ForceUnitAccess), FALSE);
839  } else {
840  DBGLOGFLUSHINFO(fdoData, TRUE, FALSE, FALSE);
841  }
842 }
843 
844 
845 /*
846  * SubmitTransferPacket
847  *
848  * Set up the IRP for the TRANSFER_PACKET submission and send it down.
849  */
851 {
852  PCOMMON_DEVICE_EXTENSION commonExtension = Pkt->Fdo->DeviceExtension;
853  PDEVICE_OBJECT nextDevObj = commonExtension->LowerDeviceObject;
855  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExtension->PrivateFdoData;
856  BOOLEAN idleRequest = FALSE;
857  PIO_STACK_LOCATION nextSp;
858 
859  NT_ASSERT(Pkt->Irp->CurrentLocation == Pkt->Irp->StackCount+1);
860 
861  /*
862  * Attach the SRB to the IRP.
863  * The reused IRP's stack location has to be rewritten for each retry
864  * call because IoCompleteRequest clears the stack locations.
865  */
867 
868 
869  nextSp = IoGetNextIrpStackLocation(Pkt->Irp);
870  nextSp->MajorFunction = IRP_MJ_SCSI;
871  nextSp->Parameters.Scsi.Srb = (PSCSI_REQUEST_BLOCK)Pkt->Srb;
872 
873  SrbSetScsiStatus(Pkt->Srb, 0);
874  Pkt->Srb->SrbStatus = 0;
876 
878  /*
879  * Only dereference the "original IRP"'s stack location
880  * if its a real client irp (as opposed to a static irp
881  * we're using just for result status for one of the non-IO scsi commands).
882  *
883  * For read/write, propagate the storage-specific IRP stack location flags
884  * (e.g. SL_OVERRIDE_VERIFY_VOLUME, SL_WRITE_THROUGH).
885  */
887  nextSp->Flags = origCurSp->Flags;
888  }
889 
890  //
891  // If the request is not split, we can use the original IRP MDL. If the
892  // request needs to be split, we need to use a partial MDL. The partial MDL
893  // is needed because more than one driver might be mapping the same MDL
894  // and this causes problems.
895  //
896  if (Pkt->UsePartialMdl == FALSE) {
897  Pkt->Irp->MdlAddress = Pkt->OriginalIrp->MdlAddress;
898  } else {
900  Pkt->Irp->MdlAddress = Pkt->PartialMdl;
901  }
902 
903 
906 
907  //
908  // Set the original irp here for SFIO.
909  //
911 
912  //
913  // No need to lock for IdlePrioritySupported, since it will
914  // be modified only at initialization time.
915  //
916  if (fdoData->IdlePrioritySupported == TRUE) {
917  idleRequest = ClasspIsIdleRequest(Pkt->OriginalIrp);
918  if (idleRequest) {
920  } else {
922  }
923  }
924 
926  return IoCallDriver(nextDevObj, Pkt->Irp);
927 }
928 
929 
930 NTSTATUS
931 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
933 {
936  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
937  BOOLEAN packetDone = FALSE;
938  BOOLEAN idleRequest = FALSE;
939  ULONG transferLength;
940  LARGE_INTEGER completionTime;
941  ULONGLONG lastIoCompletionTime;
942 
943  UNREFERENCED_PARAMETER(NullFdo);
944 
945  /*
946  * Put all the assertions and spew in here so we don't have to look at them.
947  */
948  DBGLOGRETURNPACKET(pkt);
949  DBGCHECKRETURNEDPKT(pkt);
951 
952 
953  completionTime = ClasspGetCurrentTime();
954 
955  //
956  // Record the time at which the last IO completed while snapping the old
957  // value to be used later. This can occur on multiple threads and hence
958  // could be overwritten with an older value. This is OK because this value
959  // is maintained as a heuristic.
960  //
961 
962 #ifdef _WIN64
963 #ifndef __REACTOS__
964  lastIoCompletionTime = ReadULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart);
965  WriteULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart,
966  completionTime.QuadPart);
967 #else
968  lastIoCompletionTime = *(volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart;
969  *((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart) = completionTime.QuadPart;
970 #endif
971 #else
972  lastIoCompletionTime = InterlockedExchangeNoFence64((volatile LONG64*)&fdoData->LastIoCompletionTime.QuadPart,
973  completionTime.QuadPart);
974 #endif
975 
976  if (fdoData->IdlePrioritySupported == TRUE) {
977  idleRequest = ClasspIsIdleRequest(pkt->OriginalIrp);
978  if (idleRequest) {
980  NT_ASSERT(fdoData->ActiveIdleIoCount >= 0);
981  } else {
982  fdoData->LastNonIdleIoTime = completionTime;
984  NT_ASSERT(fdoData->ActiveIoCount >= 0);
985  }
986  }
987 
988  //
989  // If partial MDL was used, unmap the pages. When the packet is retried, the
990  // MDL will be recreated. If the packet is done, the MDL will be ready to be reused.
991  //
992  if (pkt->UsePartialMdl) {
994  }
995 
996  if (SRB_STATUS(pkt->Srb->SrbStatus) == SRB_STATUS_SUCCESS) {
997 
998  NT_ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
999 
1000  transferLength = SrbGetDataTransferLength(pkt->Srb);
1001 
1003 
1004  /*
1005  * The port driver should not have allocated a sense buffer
1006  * if the SRB succeeded.
1007  */
1008  NT_ASSERT(!PORT_ALLOCATED_SENSE_EX(fdoExt, pkt->Srb));
1009 
1010  /*
1011  * Add this packet's transferred length to the original IRP's.
1012  */
1014  (LONG)transferLength);
1015 
1016 
1017  if ((pkt->InLowMemRetry) ||
1018  (pkt->DriverUsesStartIO && pkt->LowMemRetry_remainingBufLen > 0)) {
1019  packetDone = StepLowMemRetry(pkt);
1020  } else {
1021  packetDone = TRUE;
1022  }
1023 
1024  }
1025  else {
1026  /*
1027  * The packet failed. We may retry it if possible.
1028  */
1029  BOOLEAN shouldRetry;
1030 
1031  /*
1032  * Make sure IRP status matches SRB error status (since we propagate it).
1033  */
1034  if (NT_SUCCESS(Irp->IoStatus.Status)){
1035  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1036  }
1037 
1038  /*
1039  * The packet failed.
1040  * So when sending the packet down we either saw either an error or STATUS_PENDING,
1041  * and so we returned STATUS_PENDING for the original IRP.
1042  * So now we must mark the original irp pending to match that, _regardless_ of
1043  * whether we actually switch threads here by retrying.
1044  * (We also have to mark the irp pending if the lower driver marked the irp pending;
1045  * that is dealt with farther down).
1046  */
1049  }
1050 
1051  /*
1052  * Interpret the SRB error (to a meaningful IRP status)
1053  * and determine if we should retry this packet.
1054  * This call looks at the returned SENSE info to figure out what to do.
1055  */
1056  shouldRetry = InterpretTransferPacketError(pkt);
1057 
1058  /*
1059  * If the SRB queue is locked-up, release it.
1060  * Do this after calling the error handler.
1061  */
1062  if (pkt->Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN){
1063  ClassReleaseQueue(pkt->Fdo);
1064  }
1065 
1066 
1067  if (NT_SUCCESS(Irp->IoStatus.Status)){
1068  /*
1069  * The error was recovered above in the InterpretTransferPacketError() call.
1070  */
1071 
1072  NT_ASSERT(!shouldRetry);
1073 
1074  /*
1075  * In the case of a recovered error,
1076  * add the transfer length to the original Irp as we would in the success case.
1077  */
1080 
1081  if ((pkt->InLowMemRetry) ||
1082  (pkt->DriverUsesStartIO && pkt->LowMemRetry_remainingBufLen > 0)) {
1083  packetDone = StepLowMemRetry(pkt);
1084  } else {
1085  packetDone = TRUE;
1086  }
1087  } else {
1088  if (shouldRetry && (pkt->NumRetries > 0)){
1089  packetDone = RetryTransferPacket(pkt);
1090  } else if (shouldRetry && (pkt->RetryHistory != NULL)){
1091  // don't limit retries if class driver has custom interpretation routines
1092  packetDone = RetryTransferPacket(pkt);
1093  } else {
1094  packetDone = TRUE;
1095  }
1096  }
1097  }
1098 
1099  /*
1100  * If the packet is completed, put it back in the free list.
1101  * If it is the last packet servicing the original request, complete the original irp.
1102  */
1103  if (packetDone){
1104  LONG numPacketsRemaining;
1105  PIRP deferredIrp;
1106  PDEVICE_OBJECT Fdo = pkt->Fdo;
1107  UCHAR uniqueAddr = 0;
1108 
1109  /*
1110  * In case a remove is pending, bump the lock count so we don't get freed
1111  * right after we complete the original irp.
1112  */
1113  ClassAcquireRemoveLock(Fdo, (PVOID)&uniqueAddr);
1114 
1115 
1116  /*
1117  * Sometimes the port driver can allocates a new 'sense' buffer
1118  * to report transfer errors, e.g. when the default sense buffer
1119  * is too small. If so, it is up to us to free it.
1120  * Now that we're done using the sense info, free it if appropriate.
1121  * Then clear the sense buffer so it doesn't pollute future errors returned in this packet.
1122  */
1123  if (PORT_ALLOCATED_SENSE_EX(fdoExt, pkt->Srb)) {
1124  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "Freeing port-allocated sense buffer for pkt %ph.", pkt));
1128  } else {
1131  }
1132 
1133  RtlZeroMemory(&pkt->SrbErrorSenseData, sizeof(pkt->SrbErrorSenseData));
1134 
1135  /*
1136  * Call IoSetMasterIrpStatus to set appropriate status
1137  * for the Master IRP.
1138  */
1140 
1141  if (!NT_SUCCESS(Irp->IoStatus.Status)){
1142  /*
1143  * If the original I/O originated in user space (i.e. it is thread-queued),
1144  * and the error is user-correctable (e.g. media is missing, for removable media),
1145  * alert the user.
1146  * Since this is only one of possibly several packets completing for the original IRP,
1147  * we may do this more than once for a single request. That's ok; this allows
1148  * us to test each returned status with IoIsErrorUserInduced().
1149  */
1150  if (IoIsErrorUserInduced(Irp->IoStatus.Status) &&
1152  pkt->OriginalIrp->Tail.Overlay.Thread){
1153 
1155  }
1156  }
1157 
1158  /*
1159  * We use a field in the original IRP to count
1160  * down the transfer pieces as they complete.
1161  */
1162  numPacketsRemaining = InterlockedDecrement(
1163  (PLONG)&pkt->OriginalIrp->Tail.Overlay.DriverContext[0]);
1164 
1165  if (numPacketsRemaining > 0){
1166  /*
1167  * More transfer pieces remain for the original request.
1168  * Wait for them to complete before completing the original irp.
1169  */
1170  } else {
1171 
1172  /*
1173  * All the transfer pieces are done.
1174  * Complete the original irp if appropriate.
1175  */
1176  NT_ASSERT(numPacketsRemaining == 0);
1178 
1180  KIRQL oldIrql;
1181 
1182  if (NT_SUCCESS(pkt->OriginalIrp->IoStatus.Status)){
1185  }
1187 
1188  /*
1189  * We submitted all the downward irps, including this last one, on the thread
1190  * that the OriginalIrp came in on. So the OriginalIrp is completing on a
1191  * different thread iff this last downward irp is completing on a different thread.
1192  * If BlkCache is loaded, for example, it will often complete
1193  * requests out of the cache on the same thread, therefore not marking the downward
1194  * irp pending and not requiring us to do so here. If the downward request is completing
1195  * on the same thread, then by not marking the OriginalIrp pending we can save an APC
1196  * and get extra perf benefit out of BlkCache.
1197  * Note that if the packet ever cycled due to retry or LowMemRetry,
1198  * we set the pending bit in those codepaths.
1199  */
1200  if (pkt->Irp->PendingReturned){
1202  }
1203 
1204 
1206 
1207  //
1208  // Drop the count only after completing the request, to give
1209  // Mm some amount of time to issue its next critical request
1210  //
1211 
1213  {
1214  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
1215 
1217  {
1218  fdoData->MaxInterleavedNormalIo = 0;
1219  } else {
1221  }
1222 
1223  fdoData->NumHighPriorityPagingIo--;
1224 
1225  if (fdoData->NumHighPriorityPagingIo == 0)
1226  {
1227  LARGE_INTEGER period;
1228 
1229  //
1230  // Exiting throttle mode
1231  //
1232 
1234 
1235  period.QuadPart = fdoData->ThrottleStopTime.QuadPart - fdoData->ThrottleStartTime.QuadPart;
1237  }
1238 
1239  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
1240  }
1241 
1242  if (idleRequest) {
1243  ClasspCompleteIdleRequest(fdoExt);
1244  }
1245 
1246  /*
1247  * We may have been called by one of the class drivers (e.g. cdrom)
1248  * via the legacy API ClassSplitRequest.
1249  * This is the only case for which the packet engine is called for an FDO
1250  * with a StartIo routine; in that case, we have to call IoStartNextPacket
1251  * now that the original irp has been completed.
1252  */
1253  if (fdoExt->CommonExtension.DriverExtension->InitData.ClassStartIo) {
1255  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "SRB_FLAGS_DONT_START_NEXT_PACKET should never be set here (?)"));
1256  } else {
1257  KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
1258  IoStartNextPacket(Fdo, TRUE); // yes, some IO is now cancellable
1259  KeLowerIrql(oldIrql);
1260  }
1261  }
1262  }
1263  }
1264 
1265  /*
1266  * If the packet was synchronous, write the final result back to the issuer's status buffer
1267  * and signal his event.
1268  */
1269  if (pkt->SyncEventPtr){
1270  KeSetEvent(pkt->SyncEventPtr, 0, FALSE);
1271  pkt->SyncEventPtr = NULL;
1272  }
1273 
1274  /*
1275  * If the operation isn't a normal read/write, but needs to do more
1276  * operation-specific processing, call the operation's continuation
1277  * routine. The operation may create and queue another transfer packet
1278  * within this routine, but pkt is still freed after returning from the
1279  * continuation routine.
1280  */
1281  if (pkt->ContinuationRoutine != NULL){
1283  pkt->ContinuationRoutine = NULL;
1284  }
1285 
1286  /*
1287  * Free the completed packet.
1288  */
1289  pkt->UsePartialMdl = FALSE;
1290 // pkt->OriginalIrp = NULL;
1291  pkt->InLowMemRetry = FALSE;
1293 
1294  /*
1295  * Now that we have freed some resources,
1296  * try again to send one of the previously deferred irps.
1297  */
1298  deferredIrp = DequeueDeferredClientIrp(Fdo);
1299  if (deferredIrp){
1300  ServiceTransferRequest(Fdo, deferredIrp, TRUE);
1301  }
1302 
1303  ClassReleaseRemoveLock(Fdo, (PVOID)&uniqueAddr);
1304  }
1305 
1307 }
1308 
1309 
1310 /*
1311  * SetupEjectionTransferPacket
1312  *
1313  * Set up a transferPacket for a synchronous Ejection Control transfer.
1314  */
1316  BOOLEAN PreventMediaRemoval,
1317  PKEVENT SyncEventPtr,
1318  PIRP OriginalIrp)
1319 {
1321  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1322  PCDB pCdb;
1323  ULONG srbLength;
1324 
1325  PAGED_CODE();
1326 
1327  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1328  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1329  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1330  } else {
1331  srbLength = fdoData->SrbTemplate->Length;
1332  }
1333  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1334 
1336  SrbSetCdbLength(Pkt->Srb, 6);
1341 
1343 
1344  pCdb = SrbGetCdb(Pkt->Srb);
1345  if (pCdb) {
1346  pCdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
1347  pCdb->MEDIA_REMOVAL.Prevent = PreventMediaRemoval;
1348  }
1349 
1350  Pkt->BufPtrCopy = NULL;
1351  Pkt->BufLenCopy = 0;
1352 
1355  Pkt->SyncEventPtr = SyncEventPtr;
1357 }
1358 
1359 
1360 /*
1361  * SetupModeSenseTransferPacket
1362  *
1363  * Set up a transferPacket for a synchronous Mode Sense transfer.
1364  */
1366  PKEVENT SyncEventPtr,
1367  PVOID ModeSenseBuffer,
1368  UCHAR ModeSenseBufferLen,
1369  UCHAR PageMode,
1370  UCHAR SubPage,
1371  PIRP OriginalIrp,
1373 
1374 {
1376  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1377  PCDB pCdb;
1378  ULONG srbLength;
1379 
1380  PAGED_CODE();
1381 
1382  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1383  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1384  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1385  } else {
1386  srbLength = fdoData->SrbTemplate->Length;
1387  }
1388  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1389 
1391  SrbSetCdbLength(Pkt->Srb, 6);
1396  SrbSetDataBuffer(Pkt->Srb, ModeSenseBuffer);
1397  SrbSetDataTransferLength(Pkt->Srb, ModeSenseBufferLen);
1398 
1399 
1401 
1402  pCdb = SrbGetCdb(Pkt->Srb);
1403  if (pCdb) {
1404  pCdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
1405  pCdb->MODE_SENSE.PageCode = PageMode;
1406  pCdb->MODE_SENSE.SubPageCode = SubPage;
1407  pCdb->MODE_SENSE.Pc = PageControl;
1408  pCdb->MODE_SENSE.AllocationLength = (UCHAR)ModeSenseBufferLen;
1409  }
1410 
1411  Pkt->BufPtrCopy = ModeSenseBuffer;
1412  Pkt->BufLenCopy = ModeSenseBufferLen;
1413 
1416  Pkt->SyncEventPtr = SyncEventPtr;
1418 }
1419 
1420 /*
1421  * SetupModeSelectTransferPacket
1422  *
1423  * Set up a transferPacket for a synchronous Mode Select transfer.
1424  */
1426  PKEVENT SyncEventPtr,
1427  PVOID ModeSelectBuffer,
1428  UCHAR ModeSelectBufferLen,
1429  BOOLEAN SavePages,
1430  PIRP OriginalIrp)
1431 
1432 {
1434  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1435  PCDB pCdb;
1436  ULONG srbLength;
1437 
1438  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1439  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1440  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1441  } else {
1442  srbLength = fdoData->SrbTemplate->Length;
1443  }
1444  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1445 
1447  SrbSetCdbLength(Pkt->Srb, 6);
1452  SrbSetDataBuffer(Pkt->Srb, ModeSelectBuffer);
1453  SrbSetDataTransferLength(Pkt->Srb, ModeSelectBufferLen);
1454 
1456 
1457  pCdb = SrbGetCdb(Pkt->Srb);
1458  if (pCdb) {
1459  pCdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
1460  pCdb->MODE_SELECT.SPBit = SavePages;
1461  pCdb->MODE_SELECT.PFBit = 1;
1462  pCdb->MODE_SELECT.ParameterListLength = (UCHAR)ModeSelectBufferLen;
1463  }
1464 
1465  Pkt->BufPtrCopy = ModeSelectBuffer;
1466  Pkt->BufLenCopy = ModeSelectBufferLen;
1467 
1470  Pkt->SyncEventPtr = SyncEventPtr;
1472 }
1473 
1474 
1475 /*
1476  * SetupDriveCapacityTransferPacket
1477  *
1478  * Set up a transferPacket for a synchronous Drive Capacity transfer.
1479  */
1482  ULONG ReadCapacityBufferLen,
1483  PKEVENT SyncEventPtr,
1484  PIRP OriginalIrp,
1485  BOOLEAN Use16ByteCdb)
1486 {
1488  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1489  PCDB pCdb;
1490  ULONG srbLength;
1491  ULONG timeoutValue = fdoExt->TimeOutValue;
1492 
1493  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1494  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1495  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1496  } else {
1497  srbLength = fdoData->SrbTemplate->Length;
1498  }
1499  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1500 
1505 
1506 
1507  SrbSetTimeOutValue(Pkt->Srb, timeoutValue);
1509  SrbSetDataTransferLength(Pkt->Srb, ReadCapacityBufferLen);
1510 
1512 
1513  pCdb = SrbGetCdb(Pkt->Srb);
1514  if (pCdb) {
1515  if (Use16ByteCdb == TRUE) {
1516  NT_ASSERT(ReadCapacityBufferLen >= sizeof(READ_CAPACITY_DATA_EX));
1517  SrbSetCdbLength(Pkt->Srb, 16);
1518  pCdb->CDB16.OperationCode = SCSIOP_READ_CAPACITY16;
1519  REVERSE_BYTES(&pCdb->CDB16.TransferLength, &ReadCapacityBufferLen);
1520  pCdb->AsByte[1] = 0x10; // Service Action
1521  } else {
1522  SrbSetCdbLength(Pkt->Srb, 10);
1523  pCdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
1524  }
1525  }
1526 
1528  Pkt->BufLenCopy = ReadCapacityBufferLen;
1529 
1532 #if !defined(__REACTOS__) && NTDDI_VERSION >= NTDDI_WINBLUE
1534 #endif
1535 
1536  Pkt->SyncEventPtr = SyncEventPtr;
1538 }
1539 
1540 
1541 #if 0
1542  /*
1543  * SetupSendStartUnitTransferPacket
1544  *
1545  * Set up a transferPacket for a synchronous Send Start Unit transfer.
1546  */
1547  VOID SetupSendStartUnitTransferPacket( TRANSFER_PACKET *Pkt,
1548  PIRP OriginalIrp)
1549  {
1551  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1552  PCDB pCdb;
1553 
1554  PAGED_CODE();
1555 
1557 
1558  /*
1559  * Initialize the SRB.
1560  * Use a very long timeout value to give the drive time to spin up.
1561  */
1562  Pkt->Srb->Length = sizeof(SCSI_REQUEST_BLOCK);
1563  Pkt->Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
1564  Pkt->Srb->TimeOutValue = START_UNIT_TIMEOUT;
1565  Pkt->Srb->CdbLength = 6;
1566  Pkt->Srb->OriginalRequest = Pkt->Irp;
1567  Pkt->Srb->SenseInfoBuffer = &Pkt->SrbErrorSenseData;
1568  Pkt->Srb->SenseInfoBufferLength = sizeof(Pkt->SrbErrorSenseData);
1569  Pkt->Srb->Lun = 0;
1570 
1574 
1575  pCdb = (PCDB)Pkt->Srb->Cdb;
1576  pCdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
1577  pCdb->START_STOP.Start = 1;
1578  pCdb->START_STOP.Immediate = 0;
1579  pCdb->START_STOP.LogicalUnitNumber = 0;
1580 
1582  Pkt->NumRetries = 0;
1583  Pkt->SyncEventPtr = NULL;
1585  }
1586 #endif
1587 
1588 
1589 VOID
1590 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
1592  _In_ PVOID Fdo,
1595  )
1596 {
1598 
1599  PAGED_CODE();
1600 
1602 
1603  //
1604  // Release the remove lock acquired in EnqueueFreeTransferPacket
1605  //
1607 
1608  if (IoWorkItem != NULL) {
1610  }
1611 }
1612 
1613 
1614 VOID
1617  _In_ BOOLEAN LimitNumPktToDelete,
1618  _In_ ULONG Node
1619  )
1620 
1621 /*
1622 Routine Description:
1623 
1624  This function frees the resources for the free transfer packets attempting
1625  to bring them down within the working set size.
1626 
1627 Arguments:
1628  Fdo: The FDO that represents the device whose transfer packet size needs to be trimmed.
1629  LimitNumPktToDelete: Flag to indicate if the number of packets freed in one call should be capped.
1630  Node: NUMA node transfer packet is associated with.
1631 
1632 --*/
1633 
1634 {
1635  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
1636  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1637  KIRQL oldIrql;
1638  SINGLE_LIST_ENTRY pktList;
1639  PSINGLE_LIST_ENTRY slistEntry;
1640  PTRANSFER_PACKET pktToDelete;
1641  ULONG requiredNumPktToDelete = fdoData->FreeTransferPacketsLists[Node].NumTotalTransferPackets -
1643 
1644  if (LimitNumPktToDelete) {
1645  requiredNumPktToDelete = MIN(requiredNumPktToDelete, MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE);
1646  }
1647 
1648  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "CleanupTransferPacketToWorkingSetSize (%p): Exiting stress, block freeing %d packets.", Fdo, requiredNumPktToDelete));
1649 
1650  /*
1651  * Check the counter again with lock held. This eliminates a race condition
1652  * while still allowing us to not grab the spinlock in the common codepath.
1653  *
1654  * Note that the spinlock does not synchronize with threads dequeuing free
1655  * packets to send (DequeueFreeTransferPacket does that with a lightweight
1656  * interlocked exchange); the spinlock prevents multiple threads in this function
1657  * from deciding to free too many extra packets at once.
1658  */
1659  SimpleInitSlistHdr(&pktList);
1660  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
1663  (requiredNumPktToDelete--)){
1664 
1665  pktToDelete = DequeueFreeTransferPacketEx(Fdo, FALSE, Node);
1666  if (pktToDelete){
1667  SimplePushSlist(&pktList,
1668  (PSINGLE_LIST_ENTRY)&pktToDelete->SlistEntry);
1670  } else {
1671  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW,
1672  "Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (1). Node=%d",
1674  Fdo,
1676  Node));
1677  break;
1678  }
1679  }
1680  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
1681 
1682  slistEntry = SimplePopSlist(&pktList);
1683  while (slistEntry) {
1684  pktToDelete = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
1685  DestroyTransferPacket(pktToDelete);
1686  slistEntry = SimplePopSlist(&pktList);
1687  }
1688 
1689  return;
1690 }
1691 
1692 
1696 VOID
1697 ClasspSetupPopulateTokenTransferPacket(
1698  _In_ __drv_aliasesMem POFFLOAD_READ_CONTEXT OffloadReadContext,
1700  _In_ ULONG Length,
1701  _In_reads_bytes_(Length) PUCHAR PopulateTokenBuffer,
1704  )
1705 
1706 /*++
1707 
1708 Routine description:
1709 
1710  This routine is called once to set up a packet for PopulateToken.
1711  It builds up the SRB by setting the appropriate fields.
1712 
1713 Arguments:
1714 
1715  Pkt - The transfer packet to be sent down to the lower driver
1716  SyncEventPtr - The event that gets signaled once the IRP contained in the packet completes
1717  Length - Length of the buffer being sent as part of the command
1718  PopulateTokenBuffer - The buffer that contains the LBA ranges information for the PopulateToken operation
1719  OriginalIrp - The Io request to be processed
1720  ListIdentifier - The identifier that will be used to correlate a subsequent command to retrieve the token
1721 
1722 Return Value:
1723 
1724  Nothing
1725 
1726 --*/
1727 
1728 {
1730  PCLASS_PRIVATE_FDO_DATA fdoData;
1731  PCDB pCdb;
1732  ULONG srbLength;
1733 
1734  PAGED_CODE();
1735 
1736  TracePrint((TRACE_LEVEL_VERBOSE,
1737  TRACE_FLAG_IOCTL,
1738  "ClasspSetupPopulateTokenTransferPacket (%p): Entering function. Irp %p\n",
1739  Pkt->Fdo,
1740  OriginalIrp));
1741 
1742  fdoExt = Pkt->Fdo->DeviceExtension;
1743  fdoData = fdoExt->PrivateFdoData;
1744 
1745  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1746  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1747  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1748  } else {
1749  srbLength = fdoData->SrbTemplate->Length;
1750  }
1751  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1752 
1754  SrbSetCdbLength(Pkt->Srb, 16);
1759  SrbSetDataBuffer(Pkt->Srb, PopulateTokenBuffer);
1761 
1763 
1764  pCdb = SrbGetCdb(Pkt->Srb);
1765  if (pCdb) {
1766  pCdb->TOKEN_OPERATION.OperationCode = SCSIOP_POPULATE_TOKEN;
1767  pCdb->TOKEN_OPERATION.ServiceAction = SERVICE_ACTION_POPULATE_TOKEN;
1768 
1769  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ListIdentifier, &ListIdentifier);
1770  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ParameterListLength, &Length);
1771  }
1772 
1773  Pkt->BufPtrCopy = PopulateTokenBuffer;
1774  Pkt->BufLenCopy = Length;
1775 
1779 
1781  Pkt->ContinuationContext = OffloadReadContext;
1782 
1783  TracePrint((TRACE_LEVEL_VERBOSE,
1784  TRACE_FLAG_IOCTL,
1785  "ClasspSetupPopulateTokenTransferPacket (%p): Exiting function with Irp %p\n",
1786  Pkt->Fdo,
1787  OriginalIrp));
1788 
1789  return;
1790 }
1791 
1792 
1796 VOID
1797 ClasspSetupReceivePopulateTokenInformationTransferPacket(
1798  _In_ POFFLOAD_READ_CONTEXT OffloadReadContext,
1800  _In_ ULONG Length,
1801  _In_reads_bytes_(Length) PUCHAR ReceivePopulateTokenInformationBuffer,
1804  )
1805 
1806 /*++
1807 
1808 Routine description:
1809 
1810  This routine is called once to set up a packet for read token retrieval.
1811  It builds up the SRB by setting the appropriate fields.
1812 
1813 Arguments:
1814 
1815  Pkt - The transfer packet to be sent down to the lower driver
1816  Length - Length of the buffer being sent as part of the command
1817  ReceivePopulateTokenInformationBuffer - The buffer into which the target will pass back the token
1818  OriginalIrp - The Io request to be processed
1819  ListIdentifier - The identifier that will be used to correlate this command with its corresponding previous populate token operation
1820 
1821 Return Value:
1822 
1823  Nothing
1824 
1825 --*/
1826 
1827 {
1829  PCLASS_PRIVATE_FDO_DATA fdoData;
1830  PCDB pCdb;
1831  ULONG srbLength;
1832 
1833  TracePrint((TRACE_LEVEL_VERBOSE,
1834  TRACE_FLAG_IOCTL,
1835  "ClasspSetupReceivePopulateTokenInformationTransferPacket (%p): Entering function. Irp %p\n",
1836  Pkt->Fdo,
1837  OriginalIrp));
1838 
1839  fdoExt = Pkt->Fdo->DeviceExtension;
1840  fdoData = fdoExt->PrivateFdoData;
1841 
1842  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1843  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1844  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1845  } else {
1846  srbLength = fdoData->SrbTemplate->Length;
1847  }
1848  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1849 
1851  SrbSetCdbLength(Pkt->Srb, 16);
1856  SrbSetDataBuffer(Pkt->Srb, ReceivePopulateTokenInformationBuffer);
1858 
1860 
1861  pCdb = SrbGetCdb(Pkt->Srb);
1862  if (pCdb) {
1865 
1866  REVERSE_BYTES(&pCdb->RECEIVE_TOKEN_INFORMATION.ListIdentifier, &ListIdentifier);
1867  REVERSE_BYTES(&pCdb->RECEIVE_TOKEN_INFORMATION.AllocationLength, &Length);
1868  }
1869 
1870  Pkt->BufPtrCopy = ReceivePopulateTokenInformationBuffer;
1871  Pkt->BufLenCopy = Length;
1872 
1876 
1878  Pkt->ContinuationContext = OffloadReadContext;
1879 
1880  TracePrint((TRACE_LEVEL_VERBOSE,
1881  TRACE_FLAG_IOCTL,
1882  "ClasspSetupReceivePopulateTokenInformationTransferPacket (%p): Exiting function with Irp %p\n",
1883  Pkt->Fdo,
1884  OriginalIrp));
1885 
1886  return;
1887 }
1888 
1889 
1893 VOID
1894 ClasspSetupWriteUsingTokenTransferPacket(
1895  _In_ __drv_aliasesMem POFFLOAD_WRITE_CONTEXT OffloadWriteContext,
1897  _In_ ULONG Length,
1898  _In_reads_bytes_ (Length) PUCHAR WriteUsingTokenBuffer,
1901  )
1902 
1903 /*++
1904 
1905 Routine description:
1906 
1907  This routine is called once to set up a packet for WriteUsingToken.
1908  It builds up the SRB by setting the appropriate fields. It is not called
1909  before a retry as the SRB fields may be modified for the retry.
1910 
1911  The IRP is set up in SubmitTransferPacket because it must be reset for
1912  each packet submission.
1913 
1914 Arguments:
1915 
1916  Pkt - The transfer packet to be sent down to the lower driver
1917  Length - Length of the buffer being sent as part of the command
1918  WriteUsingTokenBuffer - The buffer that contains the read token and the write LBA ranges information for the WriteUsingToken operation
1919  OriginalIrp - The Io request to be processed
1920  ListIdentifier - The identifier that will be used to correlate a subsequent command to retrieve extended results in case of command failure
1921 
1922 Return Value:
1923 
1924  Nothing
1925 
1926 --*/
1927 
1928 {
1930  PCLASS_PRIVATE_FDO_DATA fdoData;
1931  PCDB pCdb;
1932  ULONG srbLength;
1933 
1934  TracePrint((TRACE_LEVEL_VERBOSE,
1935  TRACE_FLAG_IOCTL,
1936  "ClasspSetupWriteUsingTokenTransferPacket (%p): Entering function. Irp %p\n",
1937  Pkt->Fdo,
1938  OriginalIrp));
1939 
1940  fdoExt = Pkt->Fdo->DeviceExtension;
1941  fdoData = fdoExt->PrivateFdoData;
1942 
1943  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1944  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1945  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1946  } else {
1947  srbLength = fdoData->SrbTemplate->Length;
1948  }
1949  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1950 
1952  SrbSetCdbLength(Pkt->Srb, 16);
1957  SrbSetDataBuffer(Pkt->Srb, WriteUsingTokenBuffer);
1959 
1961 
1962  pCdb = SrbGetCdb(Pkt->Srb);
1963  if (pCdb) {
1964  pCdb->TOKEN_OPERATION.OperationCode = SCSIOP_WRITE_USING_TOKEN;
1965  pCdb->TOKEN_OPERATION.ServiceAction = SERVICE_ACTION_WRITE_USING_TOKEN;
1966 
1967  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ParameterListLength, &Length);
1968  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ListIdentifier, &ListIdentifier);
1969  }
1970 
1971  Pkt->BufPtrCopy = WriteUsingTokenBuffer;
1972  Pkt->BufLenCopy = Length;
1973 
1977 
1979  Pkt->ContinuationContext = OffloadWriteContext;
1980 
1981  TracePrint((TRACE_LEVEL_VERBOSE,
1982  TRACE_FLAG_IOCTL,
1983  "ClasspSetupWriteUsingTokenTransferPacket (%p): Exiting function with Irp %p\n",
1984  Pkt->Fdo,
1985  OriginalIrp));
1986 
1987  return;
1988 }
1989 
1990 
1994 VOID
1995 ClasspSetupReceiveWriteUsingTokenInformationTransferPacket(
1996  _In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext,
1998  _In_ ULONG Length,
1999  _In_reads_bytes_ (Length) PUCHAR ReceiveWriteUsingTokenInformationBuffer,
2002  )
2003 
2004 /*++
2005 
2006 Routine description:
2007 
2008  This routine is called once to set up a packet for extended results for
2009  WriteUsingToken operation. It builds up the SRB by setting the appropriate fields.
2010 
2011 Arguments:
2012 
2013  Pkt - The transfer packet to be sent down to the lower driver
2014  SyncEventPtr - The event that gets signaled once the IRP contained in the packet completes
2015  Length - Length of the buffer being sent as part of the command
2016  ReceiveWriteUsingTokenInformationBuffer - The buffer into which the target will pass back the extended results
2017  OriginalIrp - The Io request to be processed
2018  ListIdentifier - The identifier that will be used to correlate this command with its corresponding previous write using token operation
2019 
2020 Return Value:
2021 
2022  Nothing
2023 
2024 --*/
2025 
2026 {
2028  PCLASS_PRIVATE_FDO_DATA fdoData;
2029  PCDB pCdb;
2030  ULONG srbLength;
2031 
2032  TracePrint((TRACE_LEVEL_VERBOSE,
2033  TRACE_FLAG_IOCTL,
2034  "ClasspSetupReceiveWriteUsingTokenInformationTransferPacket (%p): Entering function. Irp %p\n",
2035  Pkt->Fdo,
2036  OriginalIrp));
2037 
2038  fdoExt = Pkt->Fdo->DeviceExtension;
2039  fdoData = fdoExt->PrivateFdoData;
2040 
2041  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
2042  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
2043  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
2044  } else {
2045  srbLength = fdoData->SrbTemplate->Length;
2046  }
2047  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
2048 
2050  SrbSetCdbLength(Pkt->Srb, 16);
2055  SrbSetDataBuffer(Pkt->Srb, ReceiveWriteUsingTokenInformationBuffer);
2057 
2059 
2060  pCdb = SrbGetCdb(Pkt->Srb);
2061  if (pCdb) {
2064 
2065  REVERSE_BYTES(&pCdb->RECEIVE_TOKEN_INFORMATION.AllocationLength, &Length);
2066  REVERSE_BYTES(&pCdb->RECEIVE_TOKEN_INFORMATION.ListIdentifier, &ListIdentifier);
2067  }
2068 
2069  Pkt->BufPtrCopy = ReceiveWriteUsingTokenInformationBuffer;
2070  Pkt->BufLenCopy = Length;
2071 
2075 
2077  Pkt->ContinuationContext = OffloadWriteContext;
2078 
2079  TracePrint((TRACE_LEVEL_VERBOSE,
2080  TRACE_FLAG_IOCTL,
2081  "ClasspSetupReceiveWriteUsingTokenInformationTransferPacket (%p): Exiting function with Irp %p\n",
2082  Pkt->Fdo,
2083  OriginalIrp));
2084 
2085  return;
2086 }
2087 
2088 
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
NTSTATUS SubmitTransferPacket(PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:850
VOID ClasspWriteUsingTokenTransferPacketDone(_In_ PVOID Context)
Definition: class.c:15519
#define SCSIOP_WRITE_USING_TOKEN
Definition: scsi.h:341
struct _FOUR_BYTE * PFOUR_BYTE
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define SRB_FLAGS_DISABLE_AUTOSENSE
Definition: srb.h:391
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
return STATUS_NOT_SUPPORTED
#define max(a, b)
Definition: svc.c:63
VOID SetupModeSenseTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSenseBuffer, UCHAR ModeSenseBufferLen, UCHAR PageMode, UCHAR SubPage, PIRP OriginalIrp, UCHAR PageControl)
Definition: xferpkt.c:1365
NTKRNLVISTAAPI VOID IoSetMasterIrpStatus(_Inout_ PIRP MasterIrp, _In_ NTSTATUS Status)
Definition: io.c:131
FORCEINLINE UCHAR SrbGetSenseInfoBufferLength(_In_ PVOID Srb)
Definition: srbhelper.h:638
enum _STORAGE_PROPERTY_ID STORAGE_PROPERTY_ID
VOID ClasspCompleteIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:713
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
* PSTORAGE_ADAPTER_DESCRIPTOR
Definition: ntddstor.h:599
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1325
struct _SRB_HISTORY_ITEM SRB_HISTORY_ITEM
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
BOOLEAN DriverUsesStartIO
Definition: classp.h:543
#define _In_opt_
Definition: ms_sal.h:309
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
FORCEINLINE ULONG SrbGetSrbFlags(_In_ PVOID Srb)
Definition: srbhelper.h:927
VOID NTAPI IoReuseIrp(IN OUT PIRP Irp, IN NTSTATUS Status)
Definition: irp.c:1971
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
IO_PAGING_PRIORITY FASTCALL IoGetPagingIoPriority(IN PIRP Irp)
Definition: irp.c:1748
#define DBGLOGFLUSHINFO(_fdoData, _isIO, _isFUA, _isFlush)
Definition: debug.h:129
Definition: ntbasedef.h:628
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define REMOVE_COMPLETE
Definition: classpnp.h:98
LARGE_INTEGER ThrottleStartTime
Definition: classp.h:836
PDRIVER_STARTIO ClassStartIo
Definition: classpnp.h:543
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define TRUE
Definition: types.h:120
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
#define MIN_WORKINGSET_TRANSFER_PACKETS_Server_LowerBound
Definition: classp.h:634
#define MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE
Definition: classp.h:639
#define HISTORYINITIALIZERETRYLOGS(_packet)
Definition: classp.h:2330
unsigned char * PUCHAR
Definition: retypes.h:3
ULONG ClassMaxInterleavePerCriticalIo
Definition: class.c:88
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2817
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
DECLSPEC_CACHEALIGN SLIST_HEADER SListHeader
Definition: classp.h:644
KSPIN_LOCK SpinLock
Definition: classp.h:795
UCHAR NumThinProvisioningRetries
Definition: classp.h:517
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
#define NUM_WRITE_USING_TOKEN_RETRIES
Definition: classp.h:205
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
BOOLEAN LoggedTURFailureSinceLastIO
Definition: classp.h:753
VOID NTAPI KeAcquireSpinLock(PKSPIN_LOCK SpinLock, PKIRQL OldIrql)
Definition: spinlock.c:50
FORCEINLINE LARGE_INTEGER ClasspGetCurrentTime(VOID)
Definition: classp.h:1280
VOID ClasspReceiveWriteUsingTokenInformationTransferPacketDone(_In_ POFFLOAD_WRITE_CONTEXT OffloadWriteContext)
Definition: class.c:16071
#define MIN_WORKINGSET_TRANSFER_PACKETS_Client
Definition: classp.h:631
_In_opt_ PVOID _In_ PIO_WORKITEM IoWorkItem
Definition: iotypes.h:520
ULONG LocalMinWorkingSetTransferPackets
Definition: classp.h:711
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
PIRP DequeueDeferredClientIrp(PDEVICE_OBJECT Fdo)
Definition: clntirp.c:113
UCHAR NumIoTimeoutRetries
Definition: classp.h:518
VOID SetupModeSelectTransferPacket(TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSelectBuffer, UCHAR ModeSelectBufferLen, BOOLEAN SavePages, PIRP OriginalIrp)
Definition: xferpkt.c:1425
IO_STATUS_BLOCK IoStatus
PCONTINUATION_ROUTINE ContinuationRoutine
Definition: classp.h:608
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
#define SCSIOP_WRITE16
Definition: scsi.h:915
NTKRNLVISTAAPI USHORT NTAPI KeGetCurrentNodeNumber(VOID)
LIST_ENTRY AllPktsListEntry
Definition: classp.h:499
struct _CDB::_CDB10 CDB10
LIST_ENTRY AllTransferPacketsList
Definition: classp.h:771
#define InsertTailList(ListHead, Entry)
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
FORCEINLINE PVOID SrbGetDataBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:728
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
#define DEV_USE_16BYTE_CDB
Definition: classpnp.h:183
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
UCHAR NumRetries
Definition: classp.h:516
* PSTORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR
Definition: ntddstor.h:695
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
#define SRB_STATUS(Status)
Definition: srb.h:381
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LARGE_INTEGER TargetLocationCopy
Definition: classp.h:564
#define SRB_FLAGS_DONT_START_NEXT_PACKET
Definition: srb.h:407
LARGE_INTEGER LastIoCompletionTime
Definition: classp.h:940
struct _CDB::_CDB16 CDB16
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE VOID FREE_PORT_ALLOCATED_SENSE_BUFFER_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2560
#define IRP_MJ_SCSI
T MIN(T a, T b)
Definition: polytest.cpp:79
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID SetupReadWriteTransferPacket(PTRANSFER_PACKET Pkt, PVOID Buf, ULONG Len, LARGE_INTEGER DiskLocation, PIRP OriginalIrp)
Definition: xferpkt.c:718
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
#define _Analysis_assume_(expr)
Definition: ms_sal.h:2901
ULONG DbgPeakNumTransferPackets
Definition: classp.h:647
ULONG PFN_NUMBER
Definition: ke.h:9
_In_ ULONG _In_ UCHAR _In_ UCHAR PageControl
Definition: cdrom.h:1316
LARGE_INTEGER ThrottleStopTime
Definition: classp.h:841
#define IO_DISK_INCREMENT
Definition: iotypes.h:600
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
FORCEINLINE VOID SrbSetScsiStatus(_In_ PVOID Srb, _In_ UCHAR ScsiStatus)
Definition: srbhelper.h:1056
#define FALSE
Definition: types.h:117
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP _In_ ULONG ListIdentifier
Definition: classp.h:1757
_In_ PIRP Irp
Definition: csq.h:116
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define InterlockedExchangeNoFence64
Definition: interlocked.h:174
long LONG
Definition: pedump.c:60
PVOID DefaultStorageRequestBlockAllocateRoutine(_In_ CLONG ByteSize)
Definition: srblib.c:28
NTKRNLVISTAAPI VOID NTAPI IoQueueWorkItemEx(_Inout_ PIO_WORKITEM IoWorkItem, _In_ PIO_WORKITEM_ROUTINE_EX WorkerRoutine, _In_ WORK_QUEUE_TYPE QueueType, _In_opt_ __drv_aliasesMem PVOID Context)
Definition: io.c:55
#define SERVICE_ACTION_POPULATE_TOKEN
Definition: scsi.h:442
union node Node
Definition: types.h:1255
DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets
Definition: classp.h:645
#define _IRQL_requires_min_(irql)
Definition: driverspecs.h:231
PDEVICE_OBJECT Fdo
Definition: classp.h:503
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define VER_NT_DOMAIN_CONTROLLER
#define SCSIOP_READ16
Definition: scsi.h:914
NTSTATUS NTAPI TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Context)
Definition: xferpkt.c:932
#define __drv_aliasesMem
Definition: btrfs_drv.h:205
FORCEINLINE BOOLEAN ClasspIsIdleRequest(PIRP Irp)
Definition: classp.h:1268
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
WDF_INTERRUPT_PRIORITY priority
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
FORCEINLINE BOOLEAN PORT_ALLOCATED_SENSE_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2547
union _CDB * PCDB
struct _CDB::_RECEIVE_TOKEN_INFORMATION RECEIVE_TOKEN_INFORMATION
#define _In_
Definition: ms_sal.h:308
#define NUM_DRIVECAPACITY_RETRIES
Definition: classp.h:161
#define _IRQL_requires_same_
Definition: driverspecs.h:232
#define NUM_LOCKMEDIAREMOVAL_RETRIES
Definition: classp.h:158
VOID(* PCONTINUATION_ROUTINE)(_In_ PVOID Context)
Definition: classp.h:492
GLuint index
Definition: glext.h:6031
struct _CDB::_START_STOP START_STOP
BOOLEAN InLowMemRetry
Definition: classp.h:544
__drv_allocatesMem(Mem)
Definition: xferpkt.c:322
#define InterlockedExchangeAdd
Definition: interlocked.h:181
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
FORCEINLINE ULONG SrbGetDataTransferLength(_In_ PVOID Srb)
Definition: srbhelper.h:765
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3351
struct _CDB::_MODE_SELECT MODE_SELECT
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
struct _CDB::_MODE_SENSE MODE_SENSE
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
LIST_ENTRY DeferredClientIrpList
Definition: classp.h:777
#define MIN_INITIAL_TRANSFER_PACKETS
Definition: classp.h:630
#define NUM_POPULATE_TOKEN_RETRIES
Definition: classp.h:204
struct _SRB_HISTORY * PSRB_HISTORY
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
enum _IO_PAGING_PRIORITY IO_PAGING_PRIORITY
VOID NTAPI CleanupTransferPacketToWorkingSetSizeWorker(_In_ PVOID Fdo, _In_opt_ PVOID Context, _In_ PIO_WORKITEM IoWorkItem)
Definition: xferpkt.c:1591
int64_t LONG64
Definition: typedefs.h:68
PVOID ContinuationContext
Definition: classp.h:609
BOOLEAN UsePartialMdl
Definition: classp.h:595
PIRP OriginalIrp
Definition: classp.h:509
FORCEINLINE VOID ClasspSrbSetOriginalIrp(_In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb, _In_ PIRP Irp)
Definition: classp.h:2530
VOID ClasspPerfIncrementSuccessfulIo(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: utils.c:486
#define NUM_MODESELECT_RETRIES
Definition: classp.h:160
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define SERVICE_ACTION_RECEIVE_TOKEN_INFORMATION
Definition: scsi.h:447
uint64_t ULONGLONG
Definition: typedefs.h:67
PSRB_HISTORY RetryHistory
Definition: classp.h:598
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
struct _CDB::_TOKEN_OPERATION TOKEN_OPERATION
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
struct _TRANSFER_PACKET * PTRANSFER_PACKET
#define HISTORYLOGSENDPACKET(_packet)
Definition: classp.h:2345
ULONG NumTotalTransferPackets
Definition: classp.h:646
_In_ PREAD_CAPACITY_DATA ReadCapacityBuffer
Definition: cdrom.h:1103
#define Len
Definition: deflate.h:82
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
#define PSLIST_ENTRY
Definition: rtltypes.h:134
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_Must_inspect_result_ _In_ WDFDEVICE Fdo
Definition: wdffdo.h:461
unsigned __int64 ULONG64
Definition: imports.h:198
#define BYTES_TO_PAGES(Size)
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define NUM_MODESENSE_RETRIES
Definition: classp.h:159
#define DBGLOGSENDPACKET(_pkt)
Definition: debug.h:127
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
VOID SetupDriveCapacityTransferPacket(TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp, BOOLEAN Use16ByteCdb)
Definition: xferpkt.c:1480
#define CLASS_TAG_PRIVATE_DATA
Definition: classp.h:189
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
MDL
Definition: mmtypes.h:117
#define index(s, c)
Definition: various.h:29
BOOLEAN IdlePrioritySupported
Definition: classp.h:808
#define InterlockedDecrement
Definition: armddk.h:52
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
#define SCSIOP_RECEIVE_ROD_TOKEN_INFORMATION
Definition: scsi.h:343
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:600
#define SCSIOP_READ_CAPACITY16
Definition: scsi.h:364
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
PCLASS_WORKING_SET WorkingSet
Definition: classpnp.h:588
#define SERVICE_ACTION_WRITE_USING_TOKEN
Definition: scsi.h:443
#define SCSIOP_POPULATE_TOKEN
Definition: scsi.h:340
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
ULONG LowPart
Definition: typedefs.h:106
#define HISTORYLOGRETURNEDPACKET(_packet)
Definition: classp.h:2357
ULONG NumHighPriorityPagingIo
Definition: classp.h:826
#define PAGE_SIZE
Definition: env_spec_w32.h:49
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
NTSTATUS CreateStorageRequestBlock(_Inout_ PSTORAGE_REQUEST_BLOCK *Srb, _In_ USHORT AddressType, _In_opt_ PSRB_ALLOCATE_ROUTINE AllocateRoutine, _Inout_opt_ ULONG *ByteSize, _In_ ULONG NumSrbExData,...)
Definition: srblib.c:249
FORCEINLINE VOID SimplePushSlist(SINGLE_LIST_ENTRY *SListHdr, SINGLE_LIST_ENTRY *SListEntry)
Definition: classp.h:1215
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2695
#define MmPrepareMdlForReuse(_Mdl)
struct _OSVERSIONINFOEXW OSVERSIONINFOEXW
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
T MAX(T a, T b)
Definition: polytest.cpp:85
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
UCHAR MaxNumberOfIoRetries
Definition: classp.h:976
LARGE_INTEGER LongestThrottlePeriod
Definition: classp.h:846
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define Int64ShrlMod32(a, b)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2793
ULONG LowMemRetry_remainingBufLen
Definition: classp.h:546
#define InterlockedIncrement
Definition: armddk.h:53
VOID DestroyTransferPacket(_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:500
#define DBGCHECKRETURNEDPKT(_pkt)
Definition: debug.h:126
FORCEINLINE PVOID SrbGetSenseInfoBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:619
VOID CleanupTransferPacketToWorkingSetSize(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN LimitNumPktToDelete, _In_ ULONG Node)
Definition: xferpkt.c:1615
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define MIN_WORKINGSET_TRANSFER_PACKETS_Server_UpperBound
Definition: classp.h:633
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define min(a, b)
Definition: monoChain.cc:55
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
Definition: xferpkt.c:661
#define NULL
Definition: types.h:112
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID ClasspPopulateTokenTransferPacketDone(_In_ PVOID Context)
Definition: class.c:14166
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define __drv_freesMem(kind)
Definition: driverspecs.h:271
VOID NTAPI KeRaiseIrql(KIRQL NewIrql, PKIRQL OldIrql)
Definition: spinlock.c:27
BOOLEAN InterpretTransferPacketError(PTRANSFER_PACKET Pkt)
Definition: retry.c:40
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:397
VOID DestroyAllTransferPackets(PDEVICE_OBJECT Fdo)
Definition: xferpkt.c:288
#define START_UNIT_TIMEOUT
Definition: cdrom.h:132
#define IRP_PAGING_IO
#define SL_WRITE_THROUGH
Definition: iotypes.h:1824
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
VOID HistoryInitializeRetryLogs(_Out_ PSRB_HISTORY History, ULONG HistoryCount)
Definition: history.c:36
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define VER_NT_SERVER
BOOLEAN StepLowMemRetry(PTRANSFER_PACKET Pkt)
Definition: retry.c:706
FORCEINLINE SINGLE_LIST_ENTRY * SimplePopSlist(SINGLE_LIST_ENTRY *SListHdr)
Definition: classp.h:1220
VOID SetupEjectionTransferPacket(TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp)
Definition: xferpkt.c:1315
Definition: mem.c:156
PMDL PartialMdl
Definition: classp.h:596
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
NTSTATUS InitializeTransferPackets(PDEVICE_OBJECT Fdo)
Definition: xferpkt.c:45
PUCHAR BufPtrCopy
Definition: classp.h:562
struct tagContext Context
Definition: acpixf.h:1034
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
CLASS_INIT_DATA InitData
Definition: classpnp.h:577
#define MAX_WORKINGSET_TRANSFER_PACKETS_Server
Definition: classp.h:635
unsigned int ULONG
Definition: retypes.h:1
SLIST_ENTRY SlistEntry
Definition: classp.h:500
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
FORCEINLINE VOID SrbSetSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:964
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
FORCEINLINE VOID SimpleInitSlistHdr(SINGLE_LIST_ENTRY *SListHdr)
Definition: classp.h:1211
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define MAX_WORKINGSET_TRANSFER_PACKETS_Client
Definition: classp.h:632
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define STATUS_SUCCESS
Definition: shellext.h:65
ULONG MaxInterleavedNormalIo
Definition: classp.h:831
PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo
Definition: classp.h:958
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392
NTKRNLVISTAAPI USHORT NTAPI KeQueryHighestNodeNumber(VOID)
PTRANSFER_PACKET DequeueFreeTransferPacket(PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded)
Definition: xferpkt.c:656
VOID NTAPI KeLowerIrql(KIRQL NewIrql)
Definition: spinlock.c:39
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3128
IoMarkIrpPending(Irp)
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
short CSHORT
Definition: umtypes.h:127
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
signed int * PLONG
Definition: retypes.h:5
FORCEINLINE VOID SrbSetQueueSortKey(_In_ PVOID Srb, _In_ ULONG QueueSortKey)
Definition: srbhelper.h:839
static SERVICE_STATUS status
Definition: service.c:31
#define DBGLOGRETURNPACKET(_pkt)
Definition: debug.h:128
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define MAX_OUTSTANDING_IO_PER_LUN_DEFAULT
Definition: classp.h:638
VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, __drv_aliasesMem PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:529
ULONG AllocateNode
Definition: classp.h:611
VOID ClasspReceivePopulateTokenInformationTransferPacketDone(_In_ PVOID Context)
Definition: class.c:14504
_IRQL_requires_max_(APC_LEVEL)
Definition: xferpkt.c:1693
#define SET_FLAG(Flags, Bit)
Definition: cdrom.h:1493
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
LARGE_INTEGER LastNonIdleIoTime
Definition: classp.h:935
UCHAR AsByte[16]
Definition: scsi.h:1988
#define REVERSE_BYTES_QUAD(Destination, Source)
Definition: scsi.h:3452
ULONG BufLenCopy
Definition: classp.h:563
#define IRP_SYNCHRONOUS_PAGING_IO
LONGLONG QuadPart
Definition: typedefs.h:114
BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt)
Definition: retry.c:453
Definition: dlist.c:348
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define PAGED_CODE()
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
#define _In_reads_bytes_(size)
Definition: ms_sal.h:321
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
#define NT_ASSERT
Definition: rtlfuncs.h:3310
ULONG LocalMaxWorkingSetTransferPackets
Definition: classp.h:712
Definition: ps.c:97