ReactOS  0.4.15-dev-1152-g6c94e4f
xferpkt.c File Reference
#include "classp.h"
#include "debug.h"
Include dependency graph for xferpkt.c:

Go to the source code of this file.

Functions

NTSTATUS InitializeTransferPackets (PDEVICE_OBJECT Fdo)
 
VOID DestroyAllTransferPackets (PDEVICE_OBJECT Fdo)
 
 __drv_allocatesMem (Mem)
 
VOID DestroyTransferPacket (_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt)
 
VOID EnqueueFreeTransferPacket (PDEVICE_OBJECT Fdo, __drv_aliasesMem PTRANSFER_PACKET Pkt)
 
PTRANSFER_PACKET DequeueFreeTransferPacket (PDEVICE_OBJECT Fdo, BOOLEAN AllocIfNeeded)
 
PTRANSFER_PACKET DequeueFreeTransferPacketEx (_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
 
VOID SetupReadWriteTransferPacket (PTRANSFER_PACKET Pkt, PVOID Buf, ULONG Len, LARGE_INTEGER DiskLocation, PIRP OriginalIrp)
 
NTSTATUS SubmitTransferPacket (PTRANSFER_PACKET Pkt)
 
NTSTATUS NTAPI TransferPktComplete (IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Context)
 
VOID SetupEjectionTransferPacket (TRANSFER_PACKET *Pkt, BOOLEAN PreventMediaRemoval, PKEVENT SyncEventPtr, PIRP OriginalIrp)
 
VOID SetupModeSenseTransferPacket (TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSenseBuffer, UCHAR ModeSenseBufferLen, UCHAR PageMode, UCHAR SubPage, PIRP OriginalIrp, UCHAR PageControl)
 
VOID SetupModeSelectTransferPacket (TRANSFER_PACKET *Pkt, PKEVENT SyncEventPtr, PVOID ModeSelectBuffer, UCHAR ModeSelectBufferLen, BOOLEAN SavePages, PIRP OriginalIrp)
 
VOID SetupDriveCapacityTransferPacket (TRANSFER_PACKET *Pkt, PVOID ReadCapacityBuffer, ULONG ReadCapacityBufferLen, PKEVENT SyncEventPtr, PIRP OriginalIrp, BOOLEAN Use16ByteCdb)
 
VOID NTAPI CleanupTransferPacketToWorkingSetSizeWorker (_In_ PVOID Fdo, _In_opt_ PVOID Context, _In_ PIO_WORKITEM IoWorkItem)
 
VOID CleanupTransferPacketToWorkingSetSize (_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN LimitNumPktToDelete, _In_ ULONG Node)
 
 _IRQL_requires_max_ (APC_LEVEL)
 

Function Documentation

◆ __drv_allocatesMem()

__drv_allocatesMem ( Mem  )

Definition at line 322 of file xferpkt.c.

324  :28195) // This function may not allocate memory in some error cases.
325 #endif
326 PTRANSFER_PACKET NewTransferPacket(PDEVICE_OBJECT Fdo)
327 {
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 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _SRB_HISTORY_ITEM SRB_HISTORY_ITEM
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
KSPIN_LOCK SpinLock
Definition: classp.h:795
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
NTKRNLVISTAAPI USHORT NTAPI KeGetCurrentNodeNumber(VOID)
LIST_ENTRY AllPktsListEntry
Definition: classp.h:499
LIST_ENTRY AllTransferPacketsList
Definition: classp.h:771
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG PFN_NUMBER
Definition: ke.h:8
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
#define STATUS_INTEGER_OVERFLOW
Definition: ntstatus.h:385
long LONG
Definition: pedump.c:60
PVOID DefaultStorageRequestBlockAllocateRoutine(_In_ CLONG ByteSize)
Definition: srblib.c:28
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _SRB_HISTORY * PSRB_HISTORY
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PSRB_HISTORY RetryHistory
Definition: classp.h:598
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:673
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define BYTES_TO_PAGES(Size)
MDL
Definition: mmtypes.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
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
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
#define InterlockedIncrement
Definition: armddk.h:53
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
VOID HistoryInitializeRetryLogs(_Out_ PSRB_HISTORY History, ULONG HistoryCount)
Definition: history.c:36
PMDL PartialMdl
Definition: classp.h:596
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
PCLASS_INTERPRET_SENSE_INFO2 InterpretSenseInfo
Definition: classp.h:958
return STATUS_SUCCESS
Definition: btrfs.c:3014
short CSHORT
Definition: umtypes.h:127
ULONG AllocateNode
Definition: classp.h:611
#define _Analysis_assume_(expr)
Definition: no_sal2.h:10
#define NT_ASSERT
Definition: rtlfuncs.h:3312
Definition: ps.c:97

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 1688 of file xferpkt.c.

1723 {
1725  PCLASS_PRIVATE_FDO_DATA fdoData;
1726  PCDB pCdb;
1727  ULONG srbLength;
1728 
1729  PAGED_CODE();
1730 
1731  TracePrint((TRACE_LEVEL_VERBOSE,
1732  TRACE_FLAG_IOCTL,
1733  "ClasspSetupPopulateTokenTransferPacket (%p): Entering function. Irp %p\n",
1734  Pkt->Fdo,
1735  OriginalIrp));
1736 
1737  fdoExt = Pkt->Fdo->DeviceExtension;
1738  fdoData = fdoExt->PrivateFdoData;
1739 
1740  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1741  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1742  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1743  } else {
1744  srbLength = fdoData->SrbTemplate->Length;
1745  }
1746  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1747 
1749  SrbSetCdbLength(Pkt->Srb, 16);
1754  SrbSetDataBuffer(Pkt->Srb, PopulateTokenBuffer);
1756 
1758 
1759  pCdb = SrbGetCdb(Pkt->Srb);
1760  if (pCdb) {
1761  pCdb->TOKEN_OPERATION.OperationCode = SCSIOP_POPULATE_TOKEN;
1762  pCdb->TOKEN_OPERATION.ServiceAction = SERVICE_ACTION_POPULATE_TOKEN;
1763 
1764  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ListIdentifier, &ListIdentifier);
1765  REVERSE_BYTES(&pCdb->TOKEN_OPERATION.ParameterListLength, &Length);
1766  }
1767 
1768  Pkt->BufPtrCopy = PopulateTokenBuffer;
1769  Pkt->BufLenCopy = Length;
1770 
1774 
1776  Pkt->ContinuationContext = OffloadReadContext;
1777 
1778  TracePrint((TRACE_LEVEL_VERBOSE,
1779  TRACE_FLAG_IOCTL,
1780  "ClasspSetupPopulateTokenTransferPacket (%p): Exiting function with Irp %p\n",
1781  Pkt->Fdo,
1782  OriginalIrp));
1783 
1784  return;
1785 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
Definition: cdrw_hw.h:28
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
PCONTINUATION_ROUTINE ContinuationRoutine
Definition: classp.h:608
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
UCHAR NumRetries
Definition: classp.h:516
#define FALSE
Definition: types.h:117
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP _In_ ULONG ListIdentifier
Definition: classp.h:1757
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
#define SERVICE_ACTION_POPULATE_TOKEN
Definition: scsi.h:442
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
#define NUM_POPULATE_TOKEN_RETRIES
Definition: classp.h:204
PVOID ContinuationContext
Definition: classp.h:609
PIRP OriginalIrp
Definition: classp.h:509
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 SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
#define SCSIOP_POPULATE_TOKEN
Definition: scsi.h:340
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
VOID ClasspPopulateTokenTransferPacketDone(_In_ PVOID Context)
Definition: class.c:14166
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PUCHAR BufPtrCopy
Definition: classp.h:562
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
ULONG BufLenCopy
Definition: classp.h:563
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ CleanupTransferPacketToWorkingSetSize()

VOID CleanupTransferPacketToWorkingSetSize ( _In_ PDEVICE_OBJECT  Fdo,
_In_ BOOLEAN  LimitNumPktToDelete,
_In_ ULONG  Node 
)

Definition at line 1610 of file xferpkt.c.

1629 {
1630  PFUNCTIONAL_DEVICE_EXTENSION fdoExt = Fdo->DeviceExtension;
1631  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1632  KIRQL oldIrql;
1633  SINGLE_LIST_ENTRY pktList;
1634  PSINGLE_LIST_ENTRY slistEntry;
1635  PTRANSFER_PACKET pktToDelete;
1636  ULONG requiredNumPktToDelete = fdoData->FreeTransferPacketsLists[Node].NumTotalTransferPackets -
1638 
1639  if (LimitNumPktToDelete) {
1640  requiredNumPktToDelete = MIN(requiredNumPktToDelete, MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE);
1641  }
1642 
1643  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "CleanupTransferPacketToWorkingSetSize (%p): Exiting stress, block freeing %d packets.", Fdo, requiredNumPktToDelete));
1644 
1645  /*
1646  * Check the counter again with lock held. This eliminates a race condition
1647  * while still allowing us to not grab the spinlock in the common codepath.
1648  *
1649  * Note that the spinlock does not synchronize with threads dequeuing free
1650  * packets to send (DequeueFreeTransferPacket does that with a lightweight
1651  * interlocked exchange); the spinlock prevents multiple threads in this function
1652  * from deciding to free too many extra packets at once.
1653  */
1654  SimpleInitSlistHdr(&pktList);
1655  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
1658  (requiredNumPktToDelete--)){
1659 
1660  pktToDelete = DequeueFreeTransferPacketEx(Fdo, FALSE, Node);
1661  if (pktToDelete){
1662  SimplePushSlist(&pktList,
1663  (PSINGLE_LIST_ENTRY)&pktToDelete->SlistEntry);
1665  } else {
1666  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW,
1667  "Extremely unlikely condition (non-fatal): %d packets dequeued at once for Fdo %p. NumTotalTransferPackets=%d (1). Node=%d",
1669  Fdo,
1671  Node));
1672  break;
1673  }
1674  }
1675  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
1676 
1677  slistEntry = SimplePopSlist(&pktList);
1678  while (slistEntry) {
1679  pktToDelete = CONTAINING_RECORD(slistEntry, TRANSFER_PACKET, SlistEntry);
1680  DestroyTransferPacket(pktToDelete);
1681  slistEntry = SimplePopSlist(&pktList);
1682  }
1683 
1684  return;
1685 }
Definition: ntbasedef.h:629
#define MAX_CLEANUP_TRANSFER_PACKETS_AT_ONCE
Definition: classp.h:639
KSPIN_LOCK SpinLock
Definition: classp.h:795
__inline VOID SimplePushSlist(SINGLE_LIST_ENTRY *SListHdr, SINGLE_LIST_ENTRY *SListEntry)
Definition: classp.h:1215
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
T MIN(T a, T b)
Definition: polytest.cpp:79
UCHAR KIRQL
Definition: env_spec_w32.h:591
__inline VOID SimpleInitSlistHdr(SINGLE_LIST_ENTRY *SListHdr)
Definition: classp.h:1211
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
union node Node
Definition: types.h:1255
DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets
Definition: classp.h:645
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
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ULONG NumTotalTransferPackets
Definition: classp.h:646
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define InterlockedDecrement
Definition: armddk.h:52
VOID DestroyTransferPacket(_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:500
PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
Definition: xferpkt.c:661
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
__inline SINGLE_LIST_ENTRY * SimplePopSlist(SINGLE_LIST_ENTRY *SListHdr)
Definition: classp.h:1220
unsigned int ULONG
Definition: retypes.h:1
SLIST_ENTRY SlistEntry
Definition: classp.h:500
Definition: dlist.c:348
ULONG LocalMaxWorkingSetTransferPackets
Definition: classp.h:712

Referenced by CleanupTransferPacketToWorkingSetSizeWorker(), and EnqueueFreeTransferPacket().

◆ CleanupTransferPacketToWorkingSetSizeWorker()

VOID NTAPI CleanupTransferPacketToWorkingSetSizeWorker ( _In_ PVOID  Fdo,
_In_opt_ PVOID  Context,
_In_ PIO_WORKITEM  IoWorkItem 
)

Definition at line 1586 of file xferpkt.c.

1591 {
1593 
1594  PAGED_CODE();
1595 
1597 
1598  //
1599  // Release the remove lock acquired in EnqueueFreeTransferPacket
1600  //
1602 
1603  if (IoWorkItem != NULL) {
1605  }
1606 }
_In_opt_ PVOID _In_ PIO_WORKITEM IoWorkItem
Definition: iotypes.h:503
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
smooth NULL
Definition: ftsmooth.c:416
VOID CleanupTransferPacketToWorkingSetSize(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN LimitNumPktToDelete, _In_ ULONG Node)
Definition: xferpkt.c:1610
struct tagContext Context
Definition: acpixf.h:1034
unsigned int ULONG
Definition: retypes.h:1
Definition: dlist.c:348
#define PAGED_CODE()

Referenced by EnqueueFreeTransferPacket().

◆ DequeueFreeTransferPacket()

PTRANSFER_PACKET DequeueFreeTransferPacket ( PDEVICE_OBJECT  Fdo,
BOOLEAN  AllocIfNeeded 
)

Definition at line 656 of file xferpkt.c.

657 {
658  return DequeueFreeTransferPacketEx(Fdo, AllocIfNeeded, KeGetCurrentNodeNumber());
659 }
NTKRNLVISTAAPI USHORT NTAPI KeGetCurrentNodeNumber(VOID)
PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
Definition: xferpkt.c:661

Referenced by ClasspContinueOffloadWrite(), ClasspModeSelect(), ClasspModeSense(), ClasspReceivePopulateTokenInformation(), ClasspReceiveWriteUsingTokenInformation(), ClassReadDriveCapacity(), and ServiceTransferRequest().

◆ DequeueFreeTransferPacketEx()

PTRANSFER_PACKET DequeueFreeTransferPacketEx ( _In_ PDEVICE_OBJECT  Fdo,
_In_ BOOLEAN  AllocIfNeeded,
_In_ ULONG  Node 
)

Definition at line 661 of file xferpkt.c.

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 }
#define max(a, b)
Definition: svc.c:63
#define HISTORYINITIALIZERETRYLOGS(_packet)
Definition: classp.h:2330
DECLSPEC_CACHEALIGN SLIST_HEADER SListHeader
Definition: classp.h:644
PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead)
Definition: interlocked.c:55
ULONG DbgPeakNumTransferPackets
Definition: classp.h:647
long LONG
Definition: pedump.c:60
union node Node
Definition: types.h:1255
DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets
Definition: classp.h:645
smooth NULL
Definition: ftsmooth.c:416
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
ULONG NumTotalTransferPackets
Definition: classp.h:646
#define PSLIST_ENTRY
Definition: rtltypes.h:134
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define InterlockedDecrement
Definition: armddk.h:52
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define InterlockedIncrement
Definition: armddk.h:53
Definition: dlist.c:348

Referenced by CleanupTransferPacketToWorkingSetSize(), DequeueFreeTransferPacket(), DestroyAllTransferPackets(), and EnqueueFreeTransferPacket().

◆ DestroyAllTransferPackets()

VOID DestroyAllTransferPackets ( PDEVICE_OBJECT  Fdo)

Definition at line 288 of file xferpkt.c.

289 {
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 }
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
long LONG
Definition: pedump.c:60
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
GLuint index
Definition: glext.h:6031
LIST_ENTRY DeferredClientIrpList
Definition: classp.h:777
ULONG NumTotalTransferPackets
Definition: classp.h:646
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define index(s, c)
Definition: various.h:29
#define InterlockedDecrement
Definition: armddk.h:52
VOID DestroyTransferPacket(_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:500
PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
Definition: xferpkt.c:661
unsigned int ULONG
Definition: retypes.h:1
NTKRNLVISTAAPI USHORT NTAPI KeQueryHighestNodeNumber(VOID)
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ DestroyTransferPacket()

VOID DestroyTransferPacket ( _In_ __drv_freesMem(mem) PTRANSFER_PACKET  Pkt)

Definition at line 500 of file xferpkt.c.

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 }
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
KSPIN_LOCK SpinLock
Definition: classp.h:795
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
LIST_ENTRY AllPktsListEntry
Definition: classp.h:499
LIST_ENTRY AllTransferPacketsList
Definition: classp.h:771
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PSRB_HISTORY RetryHistory
Definition: classp.h:598
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
PMDL PartialMdl
Definition: classp.h:596
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
SLIST_ENTRY SlistEntry
Definition: classp.h:500
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by CleanupTransferPacketToWorkingSetSize(), DestroyAllTransferPackets(), and EnqueueFreeTransferPacket().

◆ EnqueueFreeTransferPacket()

VOID EnqueueFreeTransferPacket ( PDEVICE_OBJECT  Fdo,
__drv_aliasesMem PTRANSFER_PACKET  Pkt 
)

Definition at line 529 of file xferpkt.c.

530 {
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 
602  CleanupTransferPacketToWorkingSetSize(Fdo, TRUE, allocateNode);
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 }
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
#define REMOVE_COMPLETE
Definition: classpnp.h:98
#define TRUE
Definition: types.h:120
DECLSPEC_CACHEALIGN SLIST_HEADER SListHeader
Definition: classp.h:644
KSPIN_LOCK SpinLock
Definition: classp.h:795
ULONG LocalMinWorkingSetTransferPackets
Definition: classp.h:711
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
PIO_WORKITEM NTAPI IoAllocateWorkItem(IN PDEVICE_OBJECT DeviceObject)
Definition: iowork.c:75
VOID NTAPI IoFreeWorkItem(IN PIO_WORKITEM IoWorkItem)
Definition: iowork.c:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
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
DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets
Definition: classp.h:645
PVOID DeviceExtension
Definition: env_spec_w32.h:418
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI CleanupTransferPacketToWorkingSetSizeWorker(_In_ PVOID Fdo, _In_opt_ PVOID Context, _In_ PIO_WORKITEM IoWorkItem)
Definition: xferpkt.c:1586
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
ULONG NumTotalTransferPackets
Definition: classp.h:646
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define InterlockedDecrement
Definition: armddk.h:52
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define InterlockedIncrement
Definition: armddk.h:53
VOID DestroyTransferPacket(_In_ __drv_freesMem(mem) PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:500
VOID CleanupTransferPacketToWorkingSetSize(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN LimitNumPktToDelete, _In_ ULONG Node)
Definition: xferpkt.c:1610
PTRANSFER_PACKET DequeueFreeTransferPacketEx(_In_ PDEVICE_OBJECT Fdo, _In_ BOOLEAN AllocIfNeeded, _In_ ULONG Node)
Definition: xferpkt.c:661
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
unsigned int ULONG
Definition: retypes.h:1
SLIST_ENTRY SlistEntry
Definition: classp.h:500
ULONG AllocateNode
Definition: classp.h:611
#define NT_ASSERT
Definition: rtlfuncs.h:3312
ULONG LocalMaxWorkingSetTransferPackets
Definition: classp.h:712

Referenced by InitializeTransferPackets(), ServiceTransferRequest(), and TransferPktComplete().

◆ InitializeTransferPackets()

NTSTATUS InitializeTransferPackets ( PDEVICE_OBJECT  Fdo)

Definition at line 45 of file xferpkt.c.

46 {
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;
212  EnqueueFreeTransferPacket(Fdo, pkt);
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 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:269
UCHAR wProductType
Definition: rtltypes.h:278
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define max(a, b)
Definition: svc.c:63
enum _STORAGE_PROPERTY_ID STORAGE_PROPERTY_ID
* PSTORAGE_ADAPTER_DESCRIPTOR
Definition: ntddstor.h:599
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS NTAPI RtlGetVersion(IN OUT PRTL_OSVERSIONINFOW lpVersionInformation)
Definition: version.c:158
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
#define TRUE
Definition: types.h:120
#define MIN_WORKINGSET_TRANSFER_PACKETS_Server_LowerBound
Definition: classp.h:634
struct _FUNCTIONAL_DEVICE_EXTENSION * PartitionZeroExtension
Definition: classpnp.h:599
LONG NTSTATUS
Definition: precomp.h:26
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
DECLSPEC_CACHEALIGN SLIST_HEADER SListHeader
Definition: classp.h:644
#define MIN_WORKINGSET_TRANSFER_PACKETS_Client
Definition: classp.h:631
ULONG LocalMinWorkingSetTransferPackets
Definition: classp.h:711
LIST_ENTRY AllTransferPacketsList
Definition: classp.h:771
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
* PSTORAGE_DEVICE_IO_CAPABILITY_DESCRIPTOR
Definition: ntddstor.h:695
T MIN(T a, T b)
Definition: polytest.cpp:79
ULONG DbgPeakNumTransferPackets
Definition: classp.h:647
#define FALSE
Definition: types.h:117
#define FREE_POOL(_PoolPtr)
Definition: cdrom.h:782
long LONG
Definition: pedump.c:60
PVOID DefaultStorageRequestBlockAllocateRoutine(_In_ CLONG ByteSize)
Definition: srblib.c:28
DECLSPEC_CACHEALIGN ULONG NumFreeTransferPackets
Definition: classp.h:645
#define VER_NT_DOMAIN_CONTROLLER
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
GLuint index
Definition: glext.h:6031
FORCEINLINE VOID InitializeSListHead(_Out_ PSLIST_HEADER SListHead)
Definition: rtlfuncs.h:3353
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
#define MIN_INITIAL_TRANSFER_PACKETS
Definition: classp.h:630
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
ULONG NumTotalTransferPackets
Definition: classp.h:646
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:673
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
PPNL_SLIST_HEADER FreeTransferPacketsLists
Definition: classp.h:772
#define CLASS_TAG_PRIVATE_DATA
Definition: classp.h:189
#define index(s, c)
Definition: various.h:29
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:600
PCLASS_WORKING_SET WorkingSet
Definition: classpnp.h:588
#define PAGE_SIZE
Definition: env_spec_w32.h:49
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
struct _OSVERSIONINFOEXW OSVERSIONINFOEXW
T MAX(T a, T b)
Definition: polytest.cpp:85
#define InterlockedIncrement
Definition: armddk.h:53
#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 VER_NT_SERVER
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
#define MAX_WORKINGSET_TRANSFER_PACKETS_Server
Definition: classp.h:635
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAX_WORKINGSET_TRANSFER_PACKETS_Client
Definition: classp.h:632
NTKRNLVISTAAPI USHORT NTAPI KeQueryHighestNodeNumber(VOID)
return STATUS_SUCCESS
Definition: btrfs.c:3014
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
static SERVICE_STATUS status
Definition: service.c:31
#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
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
ULONG LocalMaxWorkingSetTransferPackets
Definition: classp.h:712
Definition: ps.c:97

Referenced by ClassPnpStartDevice().

◆ SetupDriveCapacityTransferPacket()

VOID SetupDriveCapacityTransferPacket ( TRANSFER_PACKET Pkt,
PVOID  ReadCapacityBuffer,
ULONG  ReadCapacityBufferLen,
PKEVENT  SyncEventPtr,
PIRP  OriginalIrp,
BOOLEAN  Use16ByteCdb 
)

Definition at line 1475 of file xferpkt.c.

1481 {
1483  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1484  PCDB pCdb;
1485  ULONG srbLength;
1486  ULONG timeoutValue = fdoExt->TimeOutValue;
1487 
1488  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1489  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1490  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1491  } else {
1492  srbLength = fdoData->SrbTemplate->Length;
1493  }
1494  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1495 
1500 
1501 
1502  SrbSetTimeOutValue(Pkt->Srb, timeoutValue);
1504  SrbSetDataTransferLength(Pkt->Srb, ReadCapacityBufferLen);
1505 
1507 
1508  pCdb = SrbGetCdb(Pkt->Srb);
1509  if (pCdb) {
1510  if (Use16ByteCdb == TRUE) {
1511  NT_ASSERT(ReadCapacityBufferLen >= sizeof(READ_CAPACITY_DATA_EX));
1512  SrbSetCdbLength(Pkt->Srb, 16);
1513  pCdb->CDB16.OperationCode = SCSIOP_READ_CAPACITY16;
1514  REVERSE_BYTES(&pCdb->CDB16.TransferLength, &ReadCapacityBufferLen);
1515  pCdb->AsByte[1] = 0x10; // Service Action
1516  } else {
1517  SrbSetCdbLength(Pkt->Srb, 10);
1518  pCdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
1519  }
1520  }
1521 
1523  Pkt->BufLenCopy = ReadCapacityBufferLen;
1524 
1527 #if !defined(__REACTOS__) && NTDDI_VERSION >= NTDDI_WINBLUE
1529 #endif
1530 
1531  Pkt->SyncEventPtr = SyncEventPtr;
1533 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define TRUE
Definition: types.h:120
Definition: cdrw_hw.h:28
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
UCHAR NumIoTimeoutRetries
Definition: classp.h:518
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
struct _CDB::_CDB10 CDB10
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
UCHAR NumRetries
Definition: classp.h:516
struct _CDB::_CDB16 CDB16
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define NUM_DRIVECAPACITY_RETRIES
Definition: classp.h:161
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
PIRP OriginalIrp
Definition: classp.h:509
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
_In_ PREAD_CAPACITY_DATA ReadCapacityBuffer
Definition: cdrom.h:1103
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
#define SCSIOP_READ_CAPACITY16
Definition: scsi.h:364
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PUCHAR BufPtrCopy
Definition: classp.h:562
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
UCHAR AsByte[16]
Definition: scsi.h:1988
ULONG BufLenCopy
Definition: classp.h:563
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ClassReadDriveCapacity().

◆ SetupEjectionTransferPacket()

VOID SetupEjectionTransferPacket ( TRANSFER_PACKET Pkt,
BOOLEAN  PreventMediaRemoval,
PKEVENT  SyncEventPtr,
PIRP  OriginalIrp 
)

Definition at line 1310 of file xferpkt.c.

1314 {
1316  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1317  PCDB pCdb;
1318  ULONG srbLength;
1319 
1320  PAGED_CODE();
1321 
1322  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1323  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1324  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1325  } else {
1326  srbLength = fdoData->SrbTemplate->Length;
1327  }
1328  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1329 
1331  SrbSetCdbLength(Pkt->Srb, 6);
1336 
1338 
1339  pCdb = SrbGetCdb(Pkt->Srb);
1340  if (pCdb) {
1341  pCdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
1342  pCdb->MEDIA_REMOVAL.Prevent = PreventMediaRemoval;
1343  }
1344 
1345  Pkt->BufPtrCopy = NULL;
1346  Pkt->BufLenCopy = 0;
1347 
1350  Pkt->SyncEventPtr = SyncEventPtr;
1352 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
Definition: cdrw_hw.h:28
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
UCHAR NumRetries
Definition: classp.h:516
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define NUM_LOCKMEDIAREMOVAL_RETRIES
Definition: classp.h:158
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
PIRP OriginalIrp
Definition: classp.h:509
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
PUCHAR BufPtrCopy
Definition: classp.h:562
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
ULONG BufLenCopy
Definition: classp.h:563
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ SetupModeSelectTransferPacket()

VOID SetupModeSelectTransferPacket ( TRANSFER_PACKET Pkt,
PKEVENT  SyncEventPtr,
PVOID  ModeSelectBuffer,
UCHAR  ModeSelectBufferLen,
BOOLEAN  SavePages,
PIRP  OriginalIrp 
)

Definition at line 1420 of file xferpkt.c.

1427 {
1429  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1430  PCDB pCdb;
1431  ULONG srbLength;
1432 
1433  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1434  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1435  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1436  } else {
1437  srbLength = fdoData->SrbTemplate->Length;
1438  }
1439  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1440 
1442  SrbSetCdbLength(Pkt->Srb, 6);
1447  SrbSetDataBuffer(Pkt->Srb, ModeSelectBuffer);
1448  SrbSetDataTransferLength(Pkt->Srb, ModeSelectBufferLen);
1449 
1451 
1452  pCdb = SrbGetCdb(Pkt->Srb);
1453  if (pCdb) {
1454  pCdb->MODE_SELECT.OperationCode = SCSIOP_MODE_SELECT;
1455  pCdb->MODE_SELECT.SPBit = SavePages;
1456  pCdb->MODE_SELECT.PFBit = 1;
1457  pCdb->MODE_SELECT.ParameterListLength = (UCHAR)ModeSelectBufferLen;
1458  }
1459 
1460  Pkt->BufPtrCopy = ModeSelectBuffer;
1461  Pkt->BufLenCopy = ModeSelectBufferLen;
1462 
1465  Pkt->SyncEventPtr = SyncEventPtr;
1467 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
Definition: cdrw_hw.h:28
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
UCHAR NumRetries
Definition: classp.h:516
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _CDB::_MODE_SELECT MODE_SELECT
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
PIRP OriginalIrp
Definition: classp.h:509
#define NUM_MODESELECT_RETRIES
Definition: classp.h:160
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
unsigned char UCHAR
Definition: xmlstorage.h:181
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PUCHAR BufPtrCopy
Definition: classp.h:562
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
ULONG BufLenCopy
Definition: classp.h:563
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ClasspModeSelect().

◆ SetupModeSenseTransferPacket()

VOID SetupModeSenseTransferPacket ( TRANSFER_PACKET Pkt,
PKEVENT  SyncEventPtr,
PVOID  ModeSenseBuffer,
UCHAR  ModeSenseBufferLen,
UCHAR  PageMode,
UCHAR  SubPage,
PIRP  OriginalIrp,
UCHAR  PageControl 
)

Definition at line 1360 of file xferpkt.c.

1369 {
1371  PCLASS_PRIVATE_FDO_DATA fdoData = fdoExt->PrivateFdoData;
1372  PCDB pCdb;
1373  ULONG srbLength;
1374 
1375  PAGED_CODE();
1376 
1377  if (fdoExt->AdapterDescriptor->SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK) {
1378  srbLength = ((PSTORAGE_REQUEST_BLOCK) fdoData->SrbTemplate)->SrbLength;
1379  NT_ASSERT(((PSTORAGE_REQUEST_BLOCK) Pkt->Srb)->SrbLength >= srbLength);
1380  } else {
1381  srbLength = fdoData->SrbTemplate->Length;
1382  }
1383  RtlCopyMemory(Pkt->Srb, fdoData->SrbTemplate, srbLength); // copies _contents_ of SRB blocks
1384 
1386  SrbSetCdbLength(Pkt->Srb, 6);
1391  SrbSetDataBuffer(Pkt->Srb, ModeSenseBuffer);
1392  SrbSetDataTransferLength(Pkt->Srb, ModeSenseBufferLen);
1393 
1394 
1396 
1397  pCdb = SrbGetCdb(Pkt->Srb);
1398  if (pCdb) {
1399  pCdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
1400  pCdb->MODE_SENSE.PageCode = PageMode;
1401  pCdb->MODE_SENSE.SubPageCode = SubPage;
1402  pCdb->MODE_SENSE.Pc = PageControl;
1403  pCdb->MODE_SENSE.AllocationLength = (UCHAR)ModeSenseBufferLen;
1404  }
1405 
1406  Pkt->BufPtrCopy = ModeSenseBuffer;
1407  Pkt->BufLenCopy = ModeSenseBufferLen;
1408 
1411  Pkt->SyncEventPtr = SyncEventPtr;
1413 }
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1325
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
Definition: cdrw_hw.h:28
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
UCHAR NumRetries
Definition: classp.h:516
_In_ ULONG _In_ UCHAR _In_ UCHAR PageControl
Definition: cdrom.h:1316
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
struct _CDB::_MODE_SENSE MODE_SENSE
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
PIRP OriginalIrp
Definition: classp.h:509
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define NUM_MODESENSE_RETRIES
Definition: classp.h:159
unsigned char UCHAR
Definition: xmlstorage.h:181
FORCEINLINE VOID SrbSetRequestAttribute(_In_ PVOID Srb, _In_ UCHAR RequestAttribute)
Definition: srbhelper.h:1131
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PUCHAR BufPtrCopy
Definition: classp.h:562
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
ULONG BufLenCopy
Definition: classp.h:563
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ClasspModeSense().

◆ SetupReadWriteTransferPacket()

VOID SetupReadWriteTransferPacket ( PTRANSFER_PACKET  Pkt,
PVOID  Buf,
ULONG  Len,
LARGE_INTEGER  DiskLocation,
PIRP  OriginalIrp 
)

Definition at line 718 of file xferpkt.c.

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 }
struct _FOUR_BYTE * PFOUR_BYTE
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:655
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
FORCEINLINE VOID SrbAssignSrbFlags(_In_ PVOID Srb, _In_ ULONG Flags)
Definition: srbhelper.h:946
BOOLEAN DriverUsesStartIO
Definition: classp.h:543
FORCEINLINE VOID SrbSetOriginalRequest(_In_ PVOID Srb, _In_opt_ PVOID OriginalRequest)
Definition: srbhelper.h:710
PSTORAGE_REQUEST_BLOCK_HEADER SrbTemplate
Definition: classp.h:790
FORCEINLINE VOID SrbSetDataTransferLength(_In_ PVOID Srb, _In_ ULONG DataTransferLength)
Definition: srbhelper.h:784
#define DBGLOGFLUSHINFO(_fdoData, _isIO, _isFUA, _isFlush)
Definition: debug.h:129
PDRIVER_STARTIO ClassStartIo
Definition: class2.h:93
#define TRUE
Definition: types.h:120
Definition: cdrw_hw.h:28
UCHAR NumThinProvisioningRetries
Definition: classp.h:517
#define REVERSE_BYTES(Destination, Source)
Definition: scsi.h:3465
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
UCHAR NumIoTimeoutRetries
Definition: classp.h:518
FORCEINLINE PCDB SrbGetCdb(_In_ PVOID Srb)
Definition: srbhelper.h:583
#define SCSIOP_WRITE16
Definition: scsi.h:915
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define DEV_USE_16BYTE_CDB
Definition: classpnp.h:183
UCHAR NumRetries
Definition: classp.h:516
LARGE_INTEGER TargetLocationCopy
Definition: classp.h:564
struct _CDB::_CDB16 CDB16
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_READ16
Definition: scsi.h:914
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
* PSTORAGE_REQUEST_BLOCK
Definition: srb.h:652
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
FORCEINLINE VOID SrbSetCdbLength(_In_ PVOID Srb, _In_ UCHAR CdbLength)
Definition: srbhelper.h:1093
#define SRB_CLASS_FLAGS_PAGING
Definition: cdrom.h:165
PIRP OriginalIrp
Definition: classp.h:509
FORCEINLINE VOID SrbSetTimeOutValue(_In_ PVOID Srb, _In_ ULONG TimeOutValue)
Definition: srbhelper.h:821
PSTORAGE_ADAPTER_DESCRIPTOR AdapterDescriptor
Definition: classpnp.h:877
#define Len
Definition: deflate.h:82
unsigned char UCHAR
Definition: xmlstorage.h:181
PCLASS_DRIVER_EXTENSION DriverExtension
Definition: classpnp.h:600
ULONG LowPart
Definition: typedefs.h:106
PKEVENT SyncEventPtr
Definition: classp.h:535
_In_ PTRANSFER_PACKET _In_ ULONG _In_ PIRP OriginalIrp
Definition: classp.h:1757
UCHAR MaxNumberOfIoRetries
Definition: classp.h:976
#define Int64ShrlMod32(a, b)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:397
#define IRP_PAGING_IO
#define SL_WRITE_THROUGH
Definition: iotypes.h:1804
#define IRP_MJ_READ
Definition: rdpdr.c:46
FORCEINLINE VOID SrbSetDataBuffer(_In_ PVOID Srb, _In_opt_ __drv_aliasesMem PVOID DataBuffer)
Definition: srbhelper.h:747
PUCHAR BufPtrCopy
Definition: classp.h:562
CLASS_INIT_DATA InitData
Definition: classpnp.h:577
unsigned int ULONG
Definition: retypes.h:1
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
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
FORCEINLINE VOID SrbSetQueueSortKey(_In_ PVOID Srb, _In_ ULONG QueueSortKey)
Definition: srbhelper.h:839
#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 CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ServiceTransferRequest(), and StepLowMemRetry().

◆ SubmitTransferPacket()

NTSTATUS SubmitTransferPacket ( PTRANSFER_PACKET  Pkt)

Definition at line 850 of file xferpkt.c.

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 }
__inline VOID ClasspSrbSetOriginalIrp(_In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb, _In_ PIRP Irp)
Definition: classp.h:2530
_In_ PTRANSFER_PACKET Pkt
Definition: classp.h:1754
VOID NTAPI IoReuseIrp(IN OUT PIRP Irp, IN NTSTATUS Status)
Definition: irp.c:1971
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
#define TRUE
Definition: types.h:120
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
FORCEINLINE PVOID SrbGetDataBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:728
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
VOID NTAPI IoBuildPartialMdl(IN PMDL SourceMdl, IN PMDL TargetMdl, IN PVOID VirtualAddress, IN ULONG Length)
Definition: iomdl.c:96
FORCEINLINE VOID SrbSetScsiStatus(_In_ PVOID Srb, _In_ UCHAR ScsiStatus)
Definition: srbhelper.h:1056
#define FALSE
Definition: types.h:117
PDEVICE_OBJECT Fdo
Definition: classp.h:503
NTSTATUS NTAPI TransferPktComplete(IN PDEVICE_OBJECT NullFdo, IN PIRP Irp, IN PVOID Context)
Definition: xferpkt.c:932
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
FORCEINLINE ULONG SrbGetDataTransferLength(_In_ PVOID Srb)
Definition: srbhelper.h:765
BOOLEAN UsePartialMdl
Definition: classp.h:595
PIRP OriginalIrp
Definition: classp.h:509
#define SENSE_BUFFER_SIZE_EX
Definition: scsi.h:596
#define HISTORYLOGSENDPACKET(_packet)
Definition: classp.h:2345
#define DBGLOGSENDPACKET(_pkt)
Definition: debug.h:127
BOOLEAN IdlePrioritySupported
Definition: classp.h:808
__inline BOOLEAN ClasspIsIdleRequest(PIRP Irp)
Definition: classp.h:1268
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define InterlockedIncrement
Definition: armddk.h:53
PDEVICE_OBJECT LowerDeviceObject
Definition: classpnp.h:598
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PMDL PartialMdl
Definition: classp.h:596
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:423
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by ClasspContinueOffloadWrite(), ClasspModeSelect(), ClasspModeSense(), ClasspReceivePopulateTokenInformation(), ClasspReceiveWriteUsingTokenInformation(), ClassReadDriveCapacity(), ServiceTransferRequest(), and TransferPacketRetryTimerDpc().

◆ TransferPktComplete()

NTSTATUS NTAPI TransferPktComplete ( IN PDEVICE_OBJECT  NullFdo,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 932 of file xferpkt.c.

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  lastIoCompletionTime = ReadULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart);
964  WriteULong64NoFence((volatile ULONG64*)&fdoData->LastIoCompletionTime.QuadPart,
965  completionTime.QuadPart);
966 #else
967  lastIoCompletionTime = InterlockedExchangeNoFence64((volatile LONG64*)&fdoData->LastIoCompletionTime.QuadPart,
968  completionTime.QuadPart);
969 #endif
970 
971  if (fdoData->IdlePrioritySupported == TRUE) {
972  idleRequest = ClasspIsIdleRequest(pkt->OriginalIrp);
973  if (idleRequest) {
975  NT_ASSERT(fdoData->ActiveIdleIoCount >= 0);
976  } else {
977  fdoData->LastNonIdleIoTime = completionTime;
979  NT_ASSERT(fdoData->ActiveIoCount >= 0);
980  }
981  }
982 
983  //
984  // If partial MDL was used, unmap the pages. When the packet is retried, the
985  // MDL will be recreated. If the packet is done, the MDL will be ready to be reused.
986  //
987  if (pkt->UsePartialMdl) {
989  }
990 
991  if (SRB_STATUS(pkt->Srb->SrbStatus) == SRB_STATUS_SUCCESS) {
992 
993  NT_ASSERT(NT_SUCCESS(Irp->IoStatus.Status));
994 
995  transferLength = SrbGetDataTransferLength(pkt->Srb);
996 
998 
999  /*
1000  * The port driver should not have allocated a sense buffer
1001  * if the SRB succeeded.
1002  */
1003  NT_ASSERT(!PORT_ALLOCATED_SENSE_EX(fdoExt, pkt->Srb));
1004 
1005  /*
1006  * Add this packet's transferred length to the original IRP's.
1007  */
1009  (LONG)transferLength);
1010 
1011 
1012  if ((pkt->InLowMemRetry) ||
1013  (pkt->DriverUsesStartIO && pkt->LowMemRetry_remainingBufLen > 0)) {
1014  packetDone = StepLowMemRetry(pkt);
1015  } else {
1016  packetDone = TRUE;
1017  }
1018 
1019  }
1020  else {
1021  /*
1022  * The packet failed. We may retry it if possible.
1023  */
1024  BOOLEAN shouldRetry;
1025 
1026  /*
1027  * Make sure IRP status matches SRB error status (since we propagate it).
1028  */
1029  if (NT_SUCCESS(Irp->IoStatus.Status)){
1030  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1031  }
1032 
1033  /*
1034  * The packet failed.
1035  * So when sending the packet down we either saw either an error or STATUS_PENDING,
1036  * and so we returned STATUS_PENDING for the original IRP.
1037  * So now we must mark the original irp pending to match that, _regardless_ of
1038  * whether we actually switch threads here by retrying.
1039  * (We also have to mark the irp pending if the lower driver marked the irp pending;
1040  * that is dealt with farther down).
1041  */
1044  }
1045 
1046  /*
1047  * Interpret the SRB error (to a meaningful IRP status)
1048  * and determine if we should retry this packet.
1049  * This call looks at the returned SENSE info to figure out what to do.
1050  */
1051  shouldRetry = InterpretTransferPacketError(pkt);
1052 
1053  /*
1054  * If the SRB queue is locked-up, release it.
1055  * Do this after calling the error handler.
1056  */
1057  if (pkt->Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN){
1058  ClassReleaseQueue(pkt->Fdo);
1059  }
1060 
1061 
1062  if (NT_SUCCESS(Irp->IoStatus.Status)){
1063  /*
1064  * The error was recovered above in the InterpretTransferPacketError() call.
1065  */
1066 
1067  NT_ASSERT(!shouldRetry);
1068 
1069  /*
1070  * In the case of a recovered error,
1071  * add the transfer length to the original Irp as we would in the success case.
1072  */
1075 
1076  if ((pkt->InLowMemRetry) ||
1077  (pkt->DriverUsesStartIO && pkt->LowMemRetry_remainingBufLen > 0)) {
1078  packetDone = StepLowMemRetry(pkt);
1079  } else {
1080  packetDone = TRUE;
1081  }
1082  } else {
1083  if (shouldRetry && (pkt->NumRetries > 0)){
1084  packetDone = RetryTransferPacket(pkt);
1085  } else if (shouldRetry && (pkt->RetryHistory != NULL)){
1086  // don't limit retries if class driver has custom interpretation routines
1087  packetDone = RetryTransferPacket(pkt);
1088  } else {
1089  packetDone = TRUE;
1090  }
1091  }
1092  }
1093 
1094  /*
1095  * If the packet is completed, put it back in the free list.
1096  * If it is the last packet servicing the original request, complete the original irp.
1097  */
1098  if (packetDone){
1099  LONG numPacketsRemaining;
1100  PIRP deferredIrp;
1101  PDEVICE_OBJECT Fdo = pkt->Fdo;
1102  UCHAR uniqueAddr = 0;
1103 
1104  /*
1105  * In case a remove is pending, bump the lock count so we don't get freed
1106  * right after we complete the original irp.
1107  */
1108  ClassAcquireRemoveLock(Fdo, (PVOID)&uniqueAddr);
1109 
1110 
1111  /*
1112  * Sometimes the port driver can allocates a new 'sense' buffer
1113  * to report transfer errors, e.g. when the default sense buffer
1114  * is too small. If so, it is up to us to free it.
1115  * Now that we're done using the sense info, free it if appropriate.
1116  * Then clear the sense buffer so it doesn't pollute future errors returned in this packet.
1117  */
1118  if (PORT_ALLOCATED_SENSE_EX(fdoExt, pkt->Srb)) {
1119  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "Freeing port-allocated sense buffer for pkt %ph.", pkt));
1123  } else {
1126  }
1127 
1128  RtlZeroMemory(&pkt->SrbErrorSenseData, sizeof(pkt->SrbErrorSenseData));
1129 
1130  /*
1131  * Call IoSetMasterIrpStatus to set appropriate status
1132  * for the Master IRP.
1133  */
1135 
1136  if (!NT_SUCCESS(Irp->IoStatus.Status)){
1137  /*
1138  * If the original I/O originated in user space (i.e. it is thread-queued),
1139  * and the error is user-correctable (e.g. media is missing, for removable media),
1140  * alert the user.
1141  * Since this is only one of possibly several packets completing for the original IRP,
1142  * we may do this more than once for a single request. That's ok; this allows
1143  * us to test each returned status with IoIsErrorUserInduced().
1144  */
1145  if (IoIsErrorUserInduced(Irp->IoStatus.Status) &&
1147  pkt->OriginalIrp->Tail.Overlay.Thread){
1148 
1150  }
1151  }
1152 
1153  /*
1154  * We use a field in the original IRP to count
1155  * down the transfer pieces as they complete.
1156  */
1157  numPacketsRemaining = InterlockedDecrement(
1158  (PLONG)&pkt->OriginalIrp->Tail.Overlay.DriverContext[0]);
1159 
1160  if (numPacketsRemaining > 0){
1161  /*
1162  * More transfer pieces remain for the original request.
1163  * Wait for them to complete before completing the original irp.
1164  */
1165  } else {
1166 
1167  /*
1168  * All the transfer pieces are done.
1169  * Complete the original irp if appropriate.
1170  */
1171  NT_ASSERT(numPacketsRemaining == 0);
1173 
1175  KIRQL oldIrql;
1176 
1177  if (NT_SUCCESS(pkt->OriginalIrp->IoStatus.Status)){
1180  }
1182 
1183  /*
1184  * We submitted all the downward irps, including this last one, on the thread
1185  * that the OriginalIrp came in on. So the OriginalIrp is completing on a
1186  * different thread iff this last downward irp is completing on a different thread.
1187  * If BlkCache is loaded, for example, it will often complete
1188  * requests out of the cache on the same thread, therefore not marking the downward
1189  * irp pending and not requiring us to do so here. If the downward request is completing
1190  * on the same thread, then by not marking the OriginalIrp pending we can save an APC
1191  * and get extra perf benefit out of BlkCache.
1192  * Note that if the packet ever cycled due to retry or LowMemRetry,
1193  * we set the pending bit in those codepaths.
1194  */
1195  if (pkt->Irp->PendingReturned){
1197  }
1198 
1199 
1201 
1202  //
1203  // Drop the count only after completing the request, to give
1204  // Mm some amount of time to issue its next critical request
1205  //
1206 
1208  {
1209  KeAcquireSpinLock(&fdoData->SpinLock, &oldIrql);
1210 
1212  {
1213  fdoData->MaxInterleavedNormalIo = 0;
1214  } else {
1216  }
1217 
1218  fdoData->NumHighPriorityPagingIo--;
1219 
1220  if (fdoData->NumHighPriorityPagingIo == 0)
1221  {
1222  LARGE_INTEGER period;
1223 
1224  //
1225  // Exiting throttle mode
1226  //
1227 
1229 
1230  period.QuadPart = fdoData->ThrottleStopTime.QuadPart - fdoData->ThrottleStartTime.QuadPart;
1232  }
1233 
1234  KeReleaseSpinLock(&fdoData->SpinLock, oldIrql);
1235  }
1236 
1237  if (idleRequest) {
1238  ClasspCompleteIdleRequest(fdoExt);
1239  }
1240 
1241  /*
1242  * We may have been called by one of the class drivers (e.g. cdrom)
1243  * via the legacy API ClassSplitRequest.
1244  * This is the only case for which the packet engine is called for an FDO
1245  * with a StartIo routine; in that case, we have to call IoStartNextPacket
1246  * now that the original irp has been completed.
1247  */
1248  if (fdoExt->CommonExtension.DriverExtension->InitData.ClassStartIo) {
1250  TracePrint((TRACE_LEVEL_INFORMATION, TRACE_FLAG_RW, "SRB_FLAGS_DONT_START_NEXT_PACKET should never be set here (?)"));
1251  } else {
1252  KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);
1253  IoStartNextPacket(Fdo, TRUE); // yes, some IO is now cancellable
1254  KeLowerIrql(oldIrql);
1255  }
1256  }
1257  }
1258  }
1259 
1260  /*
1261  * If the packet was synchronous, write the final result back to the issuer's status buffer
1262  * and signal his event.
1263  */
1264  if (pkt->SyncEventPtr){
1265  KeSetEvent(pkt->SyncEventPtr, 0, FALSE);
1266  pkt->SyncEventPtr = NULL;
1267  }
1268 
1269  /*
1270  * If the operation isn't a normal read/write, but needs to do more
1271  * operation-specific processing, call the operation's continuation
1272  * routine. The operation may create and queue another transfer packet
1273  * within this routine, but pkt is still freed after returning from the
1274  * continuation routine.
1275  */
1276  if (pkt->ContinuationRoutine != NULL){
1278  pkt->ContinuationRoutine = NULL;
1279  }
1280 
1281  /*
1282  * Free the completed packet.
1283  */
1284  pkt->UsePartialMdl = FALSE;
1285 // pkt->OriginalIrp = NULL;
1286  pkt->InLowMemRetry = FALSE;
1287  EnqueueFreeTransferPacket(Fdo, pkt);
1288 
1289  /*
1290  * Now that we have freed some resources,
1291  * try again to send one of the previously deferred irps.
1292  */
1293  deferredIrp = DequeueDeferredClientIrp(Fdo);
1294  if (deferredIrp){
1295  ServiceTransferRequest(Fdo, deferredIrp, TRUE);
1296  }
1297 
1298  ClassReleaseRemoveLock(Fdo, (PVOID)&uniqueAddr);
1299  }
1300 
1302 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define max(a, b)
Definition: svc.c:63
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
NTKRNLVISTAAPI VOID IoSetMasterIrpStatus(_Inout_ PIRP MasterIrp, _In_ NTSTATUS Status)
Definition: io.c:131
FORCEINLINE UCHAR SrbGetSenseInfoBufferLength(_In_ PVOID Srb)
Definition: srbhelper.h:638
VOID ClasspCompleteIdleRequest(PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: clntirp.c:713
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define ClassAcquireRemoveLock(devobj, tag)
Definition: classpnp.h:100
BOOLEAN DriverUsesStartIO
Definition: classp.h:543
FORCEINLINE ULONG SrbGetSrbFlags(_In_ PVOID Srb)
Definition: srbhelper.h:927
IO_PAGING_PRIORITY FASTCALL IoGetPagingIoPriority(IN PIRP Irp)
Definition: irp.c:1748
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
LARGE_INTEGER ThrottleStartTime
Definition: classp.h:836
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
ULONG ClassMaxInterleavePerCriticalIo
Definition: class.c:88
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
COMMON_DEVICE_EXTENSION CommonExtension
Definition: classpnp.h:873
KSPIN_LOCK SpinLock
Definition: classp.h:795
VOID NTAPI ClassReleaseQueue(_In_ PDEVICE_OBJECT Fdo)
Definition: class.c:11589
BOOLEAN LoggedTURFailureSinceLastIO
Definition: classp.h:753
PSTORAGE_REQUEST_BLOCK_HEADER Srb
Definition: classp.h:580
PIRP DequeueDeferredClientIrp(PDEVICE_OBJECT Fdo)
Definition: clntirp.c:113
IO_STATUS_BLOCK IoStatus
PCONTINUATION_ROUTINE ContinuationRoutine
Definition: classp.h:608
FORCEINLINE VOID SrbSetSenseInfoBufferLength(_In_ PVOID Srb, _In_ UCHAR SenseInfoBufferLength)
Definition: srbhelper.h:675
#define TRACE_LEVEL_INFORMATION
Definition: storswtr.h:29
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
UCHAR NumRetries
Definition: classp.h:516
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SRB_FLAGS_DONT_START_NEXT_PACKET
Definition: srb.h:407
LARGE_INTEGER LastIoCompletionTime
Definition: classp.h:940
UCHAR KIRQL
Definition: env_spec_w32.h:591
__inline VOID FREE_PORT_ALLOCATED_SENSE_BUFFER_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2560
LARGE_INTEGER ThrottleStopTime
Definition: classp.h:841
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
#define InterlockedExchangeNoFence64
Definition: interlocked.h:174
long LONG
Definition: pedump.c:60
PDEVICE_OBJECT Fdo
Definition: classp.h:503
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN InLowMemRetry
Definition: classp.h:544
#define InterlockedExchangeAdd
Definition: interlocked.h:181
FORCEINLINE ULONG SrbGetDataTransferLength(_In_ PVOID Srb)
Definition: srbhelper.h:765
#define TEST_FLAG(Flags, Bit)
Definition: cdrom.h:1495
enum _IO_PAGING_PRIORITY IO_PAGING_PRIORITY
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
VOID ClasspPerfIncrementSuccessfulIo(IN PFUNCTIONAL_DEVICE_EXTENSION FdoExtension)
Definition: utils.c:486
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
PSRB_HISTORY RetryHistory
Definition: classp.h:598
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct _TRANSFER_PACKET * PTRANSFER_PACKET
__inline LARGE_INTEGER ClasspGetCurrentTime(VOID)
Definition: classp.h:1280
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
unsigned __int64 ULONG64
Definition: imports.h:198
unsigned char UCHAR
Definition: xmlstorage.h:181
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
BOOLEAN IdlePrioritySupported
Definition: classp.h:808
#define InterlockedDecrement
Definition: armddk.h:52
__inline BOOLEAN ClasspIsIdleRequest(PIRP Irp)
Definition: classp.h:1268
#define HISTORYLOGRETURNEDPACKET(_packet)
Definition: classp.h:2357
ULONG NumHighPriorityPagingIo
Definition: classp.h:826
NTSTATUS ServiceTransferRequest(PDEVICE_OBJECT Fdo, PIRP Irp, BOOLEAN PostToDpc)
Definition: class.c:3341
PKEVENT SyncEventPtr
Definition: classp.h:535
#define MmPrepareMdlForReuse(_Mdl)
LARGE_INTEGER LongestThrottlePeriod
Definition: classp.h:846
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
__inline BOOLEAN PORT_ALLOCATED_SENSE_EX(_In_ PFUNCTIONAL_DEVICE_EXTENSION FdoExtension, _In_ PSTORAGE_REQUEST_BLOCK_HEADER Srb)
Definition: classp.h:2547
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
ULONG LowMemRetry_remainingBufLen
Definition: classp.h:546
#define DBGCHECKRETURNEDPKT(_pkt)
Definition: debug.h:126
FORCEINLINE PVOID SrbGetSenseInfoBuffer(_In_ PVOID Srb)
Definition: srbhelper.h:619
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
BOOLEAN InterpretTransferPacketError(PTRANSFER_PACKET Pkt)
Definition: retry.c:40
#define IRP_PAGING_IO
BOOLEAN StepLowMemRetry(PTRANSFER_PACKET Pkt)
Definition: retry.c:706
PMDL PartialMdl
Definition: classp.h:596
unsigned int ULONG
Definition: retypes.h:1
FORCEINLINE VOID SrbSetSenseInfoBuffer(_In_ PVOID Srb, _In_opt_ PVOID SenseInfoBuffer)
Definition: srbhelper.h:657
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static int priority
Definition: timer.c:163
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
SENSE_DATA_EX SrbErrorSenseData
Definition: classp.h:570
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
ULONG MaxInterleavedNormalIo
Definition: classp.h:831
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
IoMarkIrpPending(Irp)
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
signed int * PLONG
Definition: retypes.h:5
#define DBGLOGRETURNPACKET(_pkt)
Definition: debug.h:128
VOID EnqueueFreeTransferPacket(PDEVICE_OBJECT Fdo, __drv_aliasesMem PTRANSFER_PACKET Pkt)
Definition: xferpkt.c:529
LARGE_INTEGER LastNonIdleIoTime
Definition: classp.h:935
LONGLONG QuadPart
Definition: typedefs.h:114
BOOLEAN RetryTransferPacket(PTRANSFER_PACKET Pkt)
Definition: retry.c:453
BOOLEAN CompleteOriginalIrpWhenLastPacketCompletes
Definition: classp.h:510
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
#define NT_ASSERT
Definition: rtlfuncs.h:3312

Referenced by SubmitTransferPacket().