ReactOS 0.4.17-dev-1321-g5c122a9
fdo.c File Reference
#include "precomp.h"
#include "inline.h"
#include <debug.h>
Include dependency graph for fdo.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static VOID NTAPI PortStarvedCsqInsertIrp (_In_ PIO_CSQ Csq, _In_ PIRP Irp)
 
static VOID NTAPI PortStarvedCsqRemoveIrp (_In_ PIO_CSQ Csq, _In_ PIRP Irp)
 
static PIRP NTAPI PortStarvedCsqPeekNextIrp (_In_ PIO_CSQ Csq, _In_ PIRP Irp, _In_ PVOID PeekContext)
 
static VOID NTAPI PortStarvedCsqAcquireLock (_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
 
static VOID NTAPI PortStarvedCsqReleaseLock (_In_ PIO_CSQ Csq, _In_ KIRQL Irql)
 
static VOID NTAPI PortStarvedCsqCompleteCanceledIrp (_In_ PIO_CSQ Csq, _In_ PIRP Irp)
 
NTSTATUS PortInitializeStarvedRequestQueue (_In_ PSTARVED_REQUEST_QUEUE Queue)
 
VOID PortQueueStarvedRequest (_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ PIRP Irp)
 Queues a request that could not allocate its private contexts.
 
VOID PortRetryStarvedRequest (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Retries one queued request, so each completion lets exactly one through.
 
VOID PortFlushStarvedRequests (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Fails every queued request, for when the adapter goes away.
 
VOID PortAllocateRequestReserve (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Reserves the memory a single request needs, so IO can still be issued out of pool.
 
VOID PortFreeRequestReserve (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Releases the reserve. No request may be using it anymore.
 
static BOOLEAN NTAPI PortFdoInterruptRoutine (_In_ PKINTERRUPT Interrupt, _In_ PVOID ServiceContext)
 
static BOOLEAN NTAPI PortFdoMessageInterruptRoutine (_In_ PKINTERRUPT Interrupt, _In_ PVOID ServiceContext, _In_ ULONG MessageId)
 
static NTSTATUS PortFdoConnectMessageInterrupt (_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
 Connects the adapter on message signaled interrupts, falling back to a line interrupt.
 
static NTSTATUS PortFdoConnectInterrupt (_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
 
static VOID PortFdoDisconnectInterrupt (_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS PortFdoStartMiniport (_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS PortFdoStartDevice (_In_ PFDO_DEVICE_EXTENSION DeviceExtension, _In_ PIRP Irp)
 
static NTSTATUS PortSendReportLuns (_In_ PPDO_DEVICE_EXTENSION PdoExtension, _Out_ PULONG LunCount, _Out_writes_(LunListSize) PUCHAR LunList, _In_ ULONG LunListSize)
 
static NTSTATUS PortSendInquiry (_In_ PPDO_DEVICE_EXTENSION PdoExtension)
 
static NTSTATUS PortFdoScanBus (_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
 
static NTSTATUS PortFdoQueryBusRelations (_In_ PFDO_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG_PTR Information)
 
static NTSTATUS PortFdoFilterRequirements (PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
 
static PPDO_DEVICE_EXTENSION FdoScanPdoList (_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG Bus, _In_ ULONG Target, _In_ ULONG Lun)
 Walks the PDO list for a unit, the caller keeps the list from changing.
 
PPDO_DEVICE_EXTENSION FdoFindLun (_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG Bus, _In_ ULONG Target, _In_ ULONG Lun)
 
static KIRQL PortFdoAcquireInterruptLocks (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Keeps every interrupt service routine of the adapter from running.
 
static VOID PortFdoReleaseInterruptLocks (_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ KIRQL OldIrql)
 
static VOID PortFdoStopAdapter (_In_ PFDO_DEVICE_EXTENSION FdoExtension)
 Tells the miniport to stop the adapter with its interrupt service routines held off.
 
PPDO_DEVICE_EXTENSION NTAPI FdoFindLunAboveDispatch (_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG Bus, _In_ ULONG Target, _In_ ULONG Lun)
 Finds a unit from an interrupt service routine or any other caller above DISPATCH_LEVEL.
 
VOID NTAPI PortFdoLinkPdo (_Inout_ PFDO_DEVICE_EXTENSION FdoExtension, _Inout_ PPDO_DEVICE_EXTENSION PdoExtension)
 Adds a PDO where both the list lock and the interrupt service routines respect it.
 
VOID NTAPI PortFdoUnlinkPdo (_Inout_ PFDO_DEVICE_EXTENSION FdoExtension, _Inout_ PPDO_DEVICE_EXTENSION PdoExtension)
 
VOID NTAPI PortFdoBusChangeDpc (_In_ PKDPC Dpc, _In_opt_ PVOID DeferredContext, _In_opt_ PVOID SystemArgument1, _In_opt_ PVOID SystemArgument2)
 
NTSTATUS NTAPI PortFdoScsi (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 
NTSTATUS NTAPI PortFdoPnp (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file fdo.c.

Function Documentation

◆ FdoFindLun()

PPDO_DEVICE_EXTENSION FdoFindLun ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension,
_In_ ULONG  Bus,
_In_ ULONG  Target,
_In_ ULONG  Lun 
)

Definition at line 1306 of file fdo.c.

1311{
1314
1318
1319 return PdoExtension;
1320}
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1315
@ PdoExtension
Definition: precomp.h:62
@ FdoExtension
Definition: precomp.h:61
VOID FASTCALL KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock, IN PKLOCK_QUEUE_HANDLE LockHandle)
Definition: spinlock.c:130
VOID FASTCALL KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
Definition: spinlock.c:166
static PPDO_DEVICE_EXTENSION FdoScanPdoList(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ ULONG Bus, _In_ ULONG Target, _In_ ULONG Lun)
Walks the PDO list for a unit, the caller keeps the list from changing.
Definition: fdo.c:1279
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
*LockHandle LockHandle _Out_ PKLOCK_QUEUE_HANDLE LockHandle
Definition: kefuncs.h:717

Referenced by StorPortDeviceBusy(), StorPortDeviceReady(), StorPortGetLogicalUnit(), and StorPortSetDeviceQueueDepth().

◆ FdoFindLunAboveDispatch()

PPDO_DEVICE_EXTENSION NTAPI FdoFindLunAboveDispatch ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension,
_In_ ULONG  Bus,
_In_ ULONG  Target,
_In_ ULONG  Lun 
)

Finds a unit from an interrupt service routine or any other caller above DISPATCH_LEVEL.

Definition at line 1405 of file fdo.c.

1410{
1412 KIRQL OldIrql;
1413
1414 /* At device IRQL the caller is an ISR or synchronized routine and already holds a lock */
1415 if (KeGetCurrentIrql() >= FdoExtension->InterruptIrql)
1416 return FdoScanPdoList(FdoExtension, Bus, Target, Lun);
1417
1421
1422 return PdoExtension;
1423}
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
static VOID PortFdoReleaseInterruptLocks(_In_ PFDO_DEVICE_EXTENSION FdoExtension, _In_ KIRQL OldIrql)
Definition: fdo.c:1361
static KIRQL PortFdoAcquireInterruptLocks(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Keeps every interrupt service routine of the adapter from running.
Definition: fdo.c:1330
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by StorPortGetLogicalUnit().

◆ FdoScanPdoList()

static PPDO_DEVICE_EXTENSION FdoScanPdoList ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension,
_In_ ULONG  Bus,
_In_ ULONG  Target,
_In_ ULONG  Lun 
)
static

Walks the PDO list for a unit, the caller keeps the list from changing.

Definition at line 1279 of file fdo.c.

1284{
1286 PLIST_ENTRY PdoEntry;
1287
1288 for (PdoEntry = FdoExtension->PdoListHead.Flink;
1289 PdoEntry != &FdoExtension->PdoListHead;
1290 PdoEntry = PdoEntry->Flink)
1291 {
1292 PdoExtension = CONTAINING_RECORD(PdoEntry, PDO_DEVICE_EXTENSION, PdoListEntry);
1293
1294 if (PdoExtension->Bus == Bus && PdoExtension->Target == Target &&
1295 PdoExtension->Lun == Lun)
1296 {
1297 return PdoExtension;
1298 }
1299 }
1300
1301 return NULL;
1302}
#define NULL
Definition: types.h:112
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by FdoFindLun(), and FdoFindLunAboveDispatch().

◆ PortAllocateRequestReserve()

VOID PortAllocateRequestReserve ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)

Reserves the memory a single request needs, so IO can still be issued out of pool.

Definition at line 168 of file fdo.c.

170{
171 ULONG SrbExtensionSize = FdoExtension->Miniport.PortConfig.SrbExtensionSize;
172
173 FdoExtension->ReservedRequestReference =
175 sizeof(*FdoExtension->ReservedRequestReference),
177 if (FdoExtension->ReservedRequestReference == NULL)
178 {
179 DPRINT1("Failed to reserve a request packet\n");
180 return;
181 }
182
183 if (SrbExtensionSize == 0)
184 {
185 return;
186 }
187
188 FdoExtension->ReservedSrbExtension = ExAllocatePoolWithTag(NonPagedPool,
189 SrbExtensionSize,
191 if (FdoExtension->ReservedSrbExtension == NULL)
192 {
193 DPRINT1("Failed to reserve an SRB extension\n");
194
195 /* A packet alone is useless if the miniport wants an SRB extension */
196 ExFreePoolWithTag(FdoExtension->ReservedRequestReference, TAG_QUEUED_REQUEST);
197 FdoExtension->ReservedRequestReference = NULL;
198 }
199}
#define DPRINT1
Definition: precomp.h:8
#define TAG_SRB_EXTENSION
Definition: precomp.h:42
#define TAG_QUEUED_REQUEST
Definition: precomp.h:41
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
uint32_t ULONG
Definition: typedefs.h:59

Referenced by PortFdoStartDevice().

◆ PortFdoAcquireInterruptLocks()

static KIRQL PortFdoAcquireInterruptLocks ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)
static

Keeps every interrupt service routine of the adapter from running.

Returns
The IRQL to hand back to PortFdoReleaseInterruptLocks.

Definition at line 1330 of file fdo.c.

1332{
1333 KIRQL OldIrql;
1334 ULONG Index;
1335
1337
1338 if (!FdoExtension->MessageInterrupts)
1339 {
1340 if (FdoExtension->Interrupt != NULL)
1342
1343 return OldIrql;
1344 }
1345
1346 /* Each message has its own lock, a routine on any of them may be reading the list */
1347 for (Index = 0; Index < FdoExtension->MessageInfo->MessageCount; Index++)
1348 {
1349 KIRQL Irql = KeAcquireInterruptSpinLock(FdoExtension->MessageInfo->MessageInfo[Index].InterruptObject);
1350
1351 if (Index == 0)
1352 OldIrql = Irql;
1353 }
1354
1355 return OldIrql;
1356}
_Out_ PKIRQL Irql
Definition: csq.h:179
KIRQL NTAPI KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
Definition: spinlock.c:154
_In_ WDFCOLLECTION _In_ ULONG Index

Referenced by FdoFindLunAboveDispatch(), PortFdoLinkPdo(), PortFdoStopAdapter(), and PortFdoUnlinkPdo().

◆ PortFdoBusChangeDpc()

VOID NTAPI PortFdoBusChangeDpc ( _In_ PKDPC  Dpc,
_In_opt_ PVOID  DeferredContext,
_In_opt_ PVOID  SystemArgument1,
_In_opt_ PVOID  SystemArgument2 
)

Definition at line 1471 of file fdo.c.

1476{
1478
1482
1483 DPRINT1("Bus change, invalidating bus relations\n");
1484
1486}
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
VOID NTAPI IoInvalidateDeviceRelations(IN PDEVICE_OBJECT DeviceObject, IN DEVICE_RELATION_TYPE Type)
Definition: pnpmgr.c:1770
_Must_inspect_result_ _In_ PWDF_DPC_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFDPC * Dpc
Definition: wdfdpc.h:112
@ BusRelations
Definition: iotypes.h:2154
_In_opt_ PVOID _In_opt_ PVOID SystemArgument1
Definition: ketypes.h:756
_In_opt_ PVOID DeferredContext
Definition: ketypes.h:755
_In_opt_ PVOID _In_opt_ PVOID _In_opt_ PVOID SystemArgument2
Definition: ketypes.h:757

Referenced by PortAddDevice().

◆ PortFdoConnectInterrupt()

static NTSTATUS PortFdoConnectInterrupt ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 314 of file fdo.c.

316{
318 KIRQL Irql;
323
324 DPRINT("PortFdoConnectInterrupt(%p)\n",
325 DeviceExtension);
326
327 /* No resources, no interrupt. Done! */
328 if (DeviceExtension->AllocatedResources == NULL ||
329 DeviceExtension->TranslatedResources == NULL)
330 {
331 DPRINT("Checkpoint\n");
332 return STATUS_SUCCESS;
333 }
334
335 /* A miniport that can take messages gets them in preference to a line */
336 if (DeviceExtension->Miniport.PortConfig.HwMSInterruptRoutine != NULL)
337 return PortFdoConnectMessageInterrupt(DeviceExtension);
338
339 /* Get the interrupt data from the resource list */
340 Status = GetResourceListInterrupt(DeviceExtension,
341 &Vector,
342 &Irql,
345 &Affinity);
346 if (!NT_SUCCESS(Status))
347 {
348 DPRINT("GetResourceListInterrupt() failed (Status 0x%08lx)\n", Status);
349 return Status;
350 }
351
352 DPRINT1("Vector: %lu\n", Vector);
353 DPRINT1("Irql: %lu\n", Irql);
354
355 DPRINT1("Affinity: 0x%08lx\n", Affinity);
356
357 /* Connect the interrupt */
358 Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
360 DeviceExtension,
361 NULL,
362 Vector,
363 Irql,
364 Irql,
367 Affinity,
368 FALSE);
369 if (NT_SUCCESS(Status))
370 {
371 DeviceExtension->InterruptIrql = Irql;
372 }
373 else
374 {
375 DPRINT1("IoConnectInterrupt() failed (Status 0x%08lx)\n", Status);
376 }
377
378 return Status;
379}
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG_PTR KAFFINITY
Definition: compat.h:85
NTSTATUS GetResourceListInterrupt(PFDO_DEVICE_EXTENSION DeviceExtension, PULONG Vector, PKIRQL Irql, KINTERRUPT_MODE *InterruptMode, PBOOLEAN ShareVector, PKAFFINITY Affinity)
Definition: misc.c:242
Status
Definition: gdiplustypes.h:24
NTSTATUS NTAPI IoConnectInterrupt(OUT PKINTERRUPT *InterruptObject, IN PKSERVICE_ROUTINE ServiceRoutine, IN PVOID ServiceContext, IN PKSPIN_LOCK SpinLock, IN ULONG Vector, IN KIRQL Irql, IN KIRQL SynchronizeIrql, IN KINTERRUPT_MODE InterruptMode, IN BOOLEAN ShareVector, IN KAFFINITY ProcessorEnableMask, IN BOOLEAN FloatingSave)
Definition: irq.c:23
enum _KINTERRUPT_MODE KINTERRUPT_MODE
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
static NTSTATUS PortFdoConnectMessageInterrupt(_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
Connects the adapter on message signaled interrupts, falling back to a line interrupt.
Definition: fdo.c:262
static BOOLEAN NTAPI PortFdoInterruptRoutine(_In_ PKINTERRUPT Interrupt, _In_ PVOID ServiceContext)
Definition: fdo.c:224
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:174
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:825
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE _In_ BOOLEAN ShareVector
Definition: iofuncs.h:826

Referenced by PortFdoStartMiniport().

◆ PortFdoConnectMessageInterrupt()

static NTSTATUS PortFdoConnectMessageInterrupt ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension)
static

Connects the adapter on message signaled interrupts, falling back to a line interrupt.

Definition at line 262 of file fdo.c.

264{
267
269
271 Parameters.MessageBased.PhysicalDeviceObject = DeviceExtension->PhysicalDevice;
272 Parameters.MessageBased.ConnectionContext.InterruptMessageTable = &DeviceExtension->MessageInfo;
273 Parameters.MessageBased.MessageServiceRoutine = PortFdoMessageInterruptRoutine;
274 Parameters.MessageBased.ServiceContext = DeviceExtension;
275 Parameters.MessageBased.SpinLock = NULL;
276 Parameters.MessageBased.SynchronizeIrql = 0;
277 Parameters.MessageBased.FloatingSave = FALSE;
278 Parameters.MessageBased.FallBackServiceRoutine = PortFdoInterruptRoutine;
279
281 if (!NT_SUCCESS(Status))
282 {
283 DPRINT1("IoConnectInterruptEx() failed (Status 0x%08lx)\n", Status);
284 return Status;
285 }
286
287 if (Parameters.Version == CONNECT_LINE_BASED)
288 {
289 /* No MSI, the line interrupt object came back in the same union */
290 DeviceExtension->Interrupt = (PKINTERRUPT)DeviceExtension->MessageInfo;
291 DeviceExtension->MessageInfo = NULL;
292
293 DPRINT1("Adapter fell back to a line interrupt\n");
294 return STATUS_SUCCESS;
295 }
296
297 DeviceExtension->MessageInterrupts = TRUE;
298 DeviceExtension->InterruptIrql = DeviceExtension->MessageInfo->UnifiedIrql;
299
300 /* The synchronization helpers work on a single interrupt object */
301 if (DeviceExtension->MessageInfo->MessageCount > 0)
302 DeviceExtension->Interrupt = DeviceExtension->MessageInfo->MessageInfo[0].InterruptObject;
303
304 DPRINT1("Connected %lu message interrupts at IRQL %lu\n",
305 DeviceExtension->MessageInfo->MessageCount,
306 DeviceExtension->InterruptIrql);
307
308 return STATUS_SUCCESS;
309}
_In_ HANDLE _In_ CONST PDXGKMDT_OPM_GET_INFO_PARAMETERS Parameters
Definition: dispmprt.h:321
#define TRUE
Definition: types.h:120
struct _KINTERRUPT * PKINTERRUPT
Definition: nt_native.h:32
NTSTATUS NTAPI IoConnectInterruptEx(_Inout_ PIO_CONNECT_INTERRUPT_PARAMETERS Parameters)
Definition: irq.c:199
static BOOLEAN NTAPI PortFdoMessageInterruptRoutine(_In_ PKINTERRUPT Interrupt, _In_ PVOID ServiceContext, _In_ ULONG MessageId)
Definition: fdo.c:242
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define CONNECT_LINE_BASED
#define CONNECT_MESSAGE_BASED

Referenced by PortFdoConnectInterrupt().

◆ PortFdoDisconnectInterrupt()

static VOID PortFdoDisconnectInterrupt ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 384 of file fdo.c.

386{
388
389 DPRINT("PortFdoDisconnectInterrupt(%p)\n", DeviceExtension);
390
391 if (DeviceExtension->MessageInterrupts)
392 {
394 Parameters.ConnectionContext.InterruptMessageTable = DeviceExtension->MessageInfo;
396
397 DeviceExtension->MessageInterrupts = FALSE;
398 DeviceExtension->MessageInfo = NULL;
399 }
400 else if (DeviceExtension->Interrupt != NULL)
401 {
402 IoDisconnectInterrupt(DeviceExtension->Interrupt);
403 }
404
405 DeviceExtension->Interrupt = NULL;
406 DeviceExtension->InterruptIrql = 0;
407}
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:142
VOID NTAPI IoDisconnectInterruptEx(_In_ PIO_DISCONNECT_INTERRUPT_PARAMETERS Parameters)
Definition: irq.c:224

Referenced by PortFdoPnp().

◆ PortFdoFilterRequirements()

static NTSTATUS PortFdoFilterRequirements ( PFDO_DEVICE_EXTENSION  DeviceExtension,
PIRP  Irp 
)
static

Definition at line 1254 of file fdo.c.

1257{
1259
1260 DPRINT("PortFdoFilterRequirements(%p %p)\n", DeviceExtension, Irp);
1261
1262 /* Get the bus number and the slot number */
1263 RequirementsList =(PIO_RESOURCE_REQUIREMENTS_LIST)Irp->IoStatus.Information;
1265 {
1266 DeviceExtension->BusNumber = RequirementsList->BusNumber;
1267 DeviceExtension->SlotNumber = RequirementsList->SlotNumber;
1268 }
1269
1270 return STATUS_SUCCESS;
1271}
_In_ PIRP Irp
Definition: kse.h:79
if(dx< 0)
Definition: linetemp.h:194
ULONG BusNumber
Definition: pci.h:88
_In_ WDFIORESREQLIST RequirementsList
Definition: wdfresource.h:65
struct _IO_RESOURCE_REQUIREMENTS_LIST * PIO_RESOURCE_REQUIREMENTS_LIST

Referenced by PortFdoPnp().

◆ PortFdoInterruptRoutine()

static BOOLEAN NTAPI PortFdoInterruptRoutine ( _In_ PKINTERRUPT  Interrupt,
_In_ PVOID  ServiceContext 
)
static

Definition at line 224 of file fdo.c.

227{
228 PFDO_DEVICE_EXTENSION DeviceExtension;
229
230 // DPRINT1("PortFdoInterruptRoutine(%p %p)\n",
231 // Interrupt, ServiceContext);
232
233 DeviceExtension = (PFDO_DEVICE_EXTENSION)ServiceContext;
234
235 return MiniportHwInterrupt(&DeviceExtension->Miniport);
236}
BOOLEAN MiniportHwInterrupt(_In_ PMINIPORT Miniport)
Definition: miniport.c:436
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID ServiceContext
Definition: iofuncs.h:820

Referenced by PortFdoConnectInterrupt(), and PortFdoConnectMessageInterrupt().

◆ PortFdoLinkPdo()

VOID NTAPI PortFdoLinkPdo ( _Inout_ PFDO_DEVICE_EXTENSION  FdoExtension,
_Inout_ PPDO_DEVICE_EXTENSION  PdoExtension 
)

Adds a PDO where both the list lock and the interrupt service routines respect it.

Definition at line 1431 of file fdo.c.

1434{
1436 KIRQL OldIrql;
1437
1440
1441 InsertHeadList(&FdoExtension->PdoListHead, &PdoExtension->PdoListEntry);
1442 FdoExtension->PdoCount++;
1443
1446}
#define InsertHeadList(ListHead, Entry)

Referenced by PortCreatePdo().

◆ PortFdoMessageInterruptRoutine()

static BOOLEAN NTAPI PortFdoMessageInterruptRoutine ( _In_ PKINTERRUPT  Interrupt,
_In_ PVOID  ServiceContext,
_In_ ULONG  MessageId 
)
static

Definition at line 242 of file fdo.c.

246{
247 PFDO_DEVICE_EXTENSION DeviceExtension;
248
250
251 DeviceExtension = (PFDO_DEVICE_EXTENSION)ServiceContext;
252
253 return MiniportHwMSInterrupt(&DeviceExtension->Miniport, MessageId);
254}
_In_ ULONG MessageId
Definition: hubioctl.cpp:1369
BOOLEAN NTAPI MiniportHwMSInterrupt(_In_ PMINIPORT Miniport, _In_ ULONG MessageId)
Definition: miniport.c:603
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFINTERRUPT * Interrupt
Definition: wdfinterrupt.h:379

Referenced by PortFdoConnectMessageInterrupt().

◆ PortFdoPnp()

NTSTATUS NTAPI PortFdoPnp ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 1519 of file fdo.c.

1522{
1523 PFDO_DEVICE_EXTENSION DeviceExtension;
1527
1528 DPRINT1("PortFdoPnp(%p %p)\n",
1529 DeviceObject, Irp);
1530
1531 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1532 ASSERT(DeviceExtension);
1533 ASSERT(DeviceExtension->ExtensionType == FdoExtension);
1534
1536
1537 switch (Stack->MinorFunction)
1538 {
1539 case IRP_MN_START_DEVICE: /* 0x00 */
1540 DPRINT("IRP_MJ_PNP / IRP_MN_START_DEVICE\n");
1541 Status = PortFdoStartDevice(DeviceExtension, Irp);
1542 break;
1543
1544 case IRP_MN_QUERY_REMOVE_DEVICE: /* 0x01 */
1545 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_REMOVE_DEVICE\n");
1546 break;
1547
1548 case IRP_MN_REMOVE_DEVICE: /* 0x02 */
1549 DPRINT1("IRP_MJ_PNP / IRP_MN_REMOVE_DEVICE\n");
1550 PortFdoStopAdapter(DeviceExtension);
1551 PortFdoDisconnectInterrupt(DeviceExtension);
1552
1553 /* Nothing may tell PnP about this adapter once it is gone */
1554 KeRemoveQueueDpc(&DeviceExtension->BusChangeDpc);
1555 KeFlushQueuedDpcs();
1556 MiniportFreeAdapterResources(&DeviceExtension->Miniport);
1557 PortFlushStarvedRequests(DeviceExtension);
1558 PortFreeRequestReserve(DeviceExtension);
1559 if (DeviceExtension->RequestReferenceLookasideInitialized)
1560 {
1563 }
1564 DeviceExtension->PnpState = dsRemoved;
1565 break;
1566
1567 case IRP_MN_CANCEL_REMOVE_DEVICE: /* 0x03 */
1568 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_REMOVE_DEVICE\n");
1569 break;
1570
1571 case IRP_MN_STOP_DEVICE: /* 0x04 */
1572 DPRINT1("IRP_MJ_PNP / IRP_MN_STOP_DEVICE\n");
1573 PortFdoStopAdapter(DeviceExtension);
1574 PortFdoDisconnectInterrupt(DeviceExtension);
1575 MiniportFreeAdapterResources(&DeviceExtension->Miniport);
1576 DeviceExtension->PnpState = dsStopped;
1577 break;
1578
1579 case IRP_MN_QUERY_STOP_DEVICE: /* 0x05 */
1580 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_STOP_DEVICE\n");
1581 break;
1582
1583 case IRP_MN_CANCEL_STOP_DEVICE: /* 0x06 */
1584 DPRINT1("IRP_MJ_PNP / IRP_MN_CANCEL_STOP_DEVICE\n");
1585 break;
1586
1587 case IRP_MN_QUERY_DEVICE_RELATIONS: /* 0x07 */
1588 switch (Stack->Parameters.QueryDeviceRelations.Type)
1589 {
1590 case BusRelations:
1591 DPRINT(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / BusRelations\n");
1592 Status = PortFdoQueryBusRelations(DeviceExtension, &Information);
1593 break;
1594
1595 case RemovalRelations:
1596 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / RemovalRelations\n");
1597 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp);
1598
1599 default:
1600 DPRINT1(" IRP_MJ_PNP / IRP_MN_QUERY_DEVICE_RELATIONS / Unknown type 0x%lx\n",
1601 Stack->Parameters.QueryDeviceRelations.Type);
1602 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp);
1603 }
1604 break;
1605
1607 DPRINT("IRP_MJ_PNP / IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n");
1608 PortFdoFilterRequirements(DeviceExtension, Irp);
1609 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp);
1610
1611 case IRP_MN_QUERY_PNP_DEVICE_STATE: /* 0x14 */
1612 DPRINT1("IRP_MJ_PNP / IRP_MN_QUERY_PNP_DEVICE_STATE\n");
1613 break;
1614
1615 case IRP_MN_DEVICE_USAGE_NOTIFICATION: /* 0x16 */
1616 DPRINT1("IRP_MJ_PNP / IRP_MN_DEVICE_USAGE_NOTIFICATION\n");
1617 break;
1618
1619 case IRP_MN_SURPRISE_REMOVAL: /* 0x17 */
1620 DPRINT1("IRP_MJ_PNP / IRP_MN_SURPRISE_REMOVAL\n");
1621 break;
1622
1623 default:
1624 DPRINT1("IRP_MJ_PNP / Unknown IOCTL 0x%lx\n", Stack->MinorFunction);
1625 return ForwardIrpAndForget(DeviceExtension->LowerDevice, Irp);
1626 }
1627
1628 Irp->IoStatus.Information = Information;
1629 Irp->IoStatus.Status = Status;
1631
1632 return Status;
1633}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
#define STATUS_NOT_SUPPORTED
Definition: d3dkmdt.h:48
BOOLEAN NTAPI KeRemoveQueueDpc(IN PKDPC Dpc)
Definition: dpc.c:878
@ dsRemoved
Definition: pci.h:38
DRIVER_DISPATCH ForwardIrpAndForget
Definition: i8042prt.h:341
@ dsStopped
Definition: isapnp.h:30
VOID NTAPI ExDeleteNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside)
Definition: lookas.c:170
#define ASSERT(a)
Definition: mode.c:44
#define IRP_MN_SURPRISE_REMOVAL
Definition: ntifs_ex.h:408
#define IoCompleteRequest
Definition: irp.c:1272
VOID PortFlushStarvedRequests(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Fails every queued request, for when the adapter goes away.
Definition: fdo.c:153
static VOID PortFdoStopAdapter(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Tells the miniport to stop the adapter with its interrupt service routines held off.
Definition: fdo.c:1389
static NTSTATUS PortFdoFilterRequirements(PFDO_DEVICE_EXTENSION DeviceExtension, PIRP Irp)
Definition: fdo.c:1254
VOID PortFreeRequestReserve(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Releases the reserve. No request may be using it anymore.
Definition: fdo.c:205
static NTSTATUS PortFdoStartDevice(_In_ PFDO_DEVICE_EXTENSION DeviceExtension, _In_ PIRP Irp)
Definition: fdo.c:519
static NTSTATUS PortFdoQueryBusRelations(_In_ PFDO_DEVICE_EXTENSION DeviceExtension, _Out_ PULONG_PTR Information)
Definition: fdo.c:1187
static VOID PortFdoDisconnectInterrupt(_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:384
VOID NTAPI MiniportFreeAdapterResources(_In_ PMINIPORT Miniport)
Tells the miniport the adapter is going away.
Definition: miniport.c:419
PDEVICE_OBJECT LowerDevice
Definition: i8042prt.h:130
NPAGED_LOOKASIDE_LIST RequestReferenceLookaside
Definition: precomp.h:302
DEVICE_STATE PnpState
Definition: i8042prt.h:132
EXTENSION_TYPE ExtensionType
Definition: precomp.h:244
BOOLEAN RequestReferenceLookasideInitialized
Definition: precomp.h:303
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
_In_ WDFREQUEST _In_ NTSTATUS _In_ ULONG_PTR Information
Definition: wdfrequest.h:1049
#define IRP_MN_CANCEL_STOP_DEVICE
@ RemovalRelations
Definition: iotypes.h:2157
#define IRP_MN_QUERY_PNP_DEVICE_STATE
#define IO_NO_INCREMENT
Definition: iotypes.h:598
#define IRP_MN_START_DEVICE
#define IRP_MN_DEVICE_USAGE_NOTIFICATION
#define IRP_MN_REMOVE_DEVICE
#define IRP_MN_FILTER_RESOURCE_REQUIREMENTS
#define IRP_MN_QUERY_DEVICE_RELATIONS
#define IRP_MN_QUERY_STOP_DEVICE
#define IRP_MN_CANCEL_REMOVE_DEVICE
#define IRP_MN_STOP_DEVICE
#define IRP_MN_QUERY_REMOVE_DEVICE

Referenced by PortDispatchPnp().

◆ PortFdoQueryBusRelations()

static NTSTATUS PortFdoQueryBusRelations ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension,
_Out_ PULONG_PTR  Information 
)
static

Definition at line 1187 of file fdo.c.

1190{
1192 PDEVICE_RELATIONS DeviceRelations = NULL;
1195 PLIST_ENTRY PdoEntry;
1196 ULONG PdoCount, PdoIndex = 0;
1197
1198 DPRINT("PortFdoQueryBusRelations(%p %p)\n",
1199 DeviceExtension, Information);
1200
1201 Status = PortFdoScanBus(DeviceExtension);
1202
1203 PdoCount = DeviceExtension->PdoCount;
1204
1205 DPRINT1("Units found: %lu\n", PdoCount);
1206
1207 /* Following part referred to SCSIport */
1208 DeviceRelations = ExAllocatePoolWithTag(PagedPool,
1209 FIELD_OFFSET(DEVICE_RELATIONS, Objects[PdoCount]),
1211 if (!DeviceRelations)
1212 {
1213 *Information = 0;
1215 }
1216
1217 /* Set PDO pointers */
1218 KeAcquireInStackQueuedSpinLock(&DeviceExtension->PdoListLock, &LockHandle);
1219
1220 for (PdoEntry = DeviceExtension->PdoListHead.Flink;
1221 PdoEntry != &DeviceExtension->PdoListHead && PdoIndex < PdoCount;
1222 PdoEntry = PdoEntry->Flink)
1223 {
1226 PdoListEntry);
1227
1228 if (PdoExtension->PnpState == dsRemoved ||
1229 PdoExtension->PnpState == dsSurpriseRemoved)
1230 {
1231 continue;
1232 }
1233
1235
1236 DeviceRelations->Objects[PdoIndex] = PdoExtension->Device;
1237
1238 /* Next one */
1239 ++PdoIndex;
1240 }
1241
1243
1244 DeviceRelations->Count = PdoIndex;
1245
1246 *Information = (ULONG_PTR)DeviceRelations;
1247
1248 return Status;
1249}
@ dsSurpriseRemoved
Definition: pci.h:39
#define ULONG_PTR
Definition: config.h:101
#define TAG_DEVICE_RELATION
Definition: precomp.h:30
#define PagedPool
Definition: env_spec_w32.h:308
static NTSTATUS PortFdoScanBus(_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:1102
PDEVICE_OBJECT Objects[1]
Definition: iotypes.h:2165
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by PortFdoPnp().

◆ PortFdoReleaseInterruptLocks()

static VOID PortFdoReleaseInterruptLocks ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension,
_In_ KIRQL  OldIrql 
)
static

Definition at line 1361 of file fdo.c.

1364{
1365 ULONG Index;
1366
1367 if (!FdoExtension->MessageInterrupts)
1368 {
1369 if (FdoExtension->Interrupt != NULL)
1371
1372 return;
1373 }
1374
1375 /* Only the first lock taken drops back to the caller's IRQL */
1376 for (Index = FdoExtension->MessageInfo->MessageCount; Index > 0; Index--)
1377 {
1378 KeReleaseInterruptSpinLock(FdoExtension->MessageInfo->MessageInfo[Index - 1].InterruptObject,
1379 (Index == 1) ? OldIrql : KeGetCurrentIrql());
1380 }
1381}
VOID NTAPI KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt, IN KIRQL OldIrql)
Definition: spinlock.c:171

Referenced by FdoFindLunAboveDispatch(), PortFdoLinkPdo(), PortFdoStopAdapter(), and PortFdoUnlinkPdo().

◆ PortFdoScanBus()

static NTSTATUS PortFdoScanBus ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 1102 of file fdo.c.

1104{
1106 ULONG Bus, Target, Index;
1108 ULONG LunCount = 0;
1109
1110 /* The most units a single target can carry */
1112
1113 DPRINT("PortFdoScanBus(%p)\n", DeviceExtension);
1114
1115 DPRINT("NumberOfBuses: %lu\n", DeviceExtension->Miniport.PortConfig.NumberOfBuses);
1116 DPRINT("MaximumNumberOfTargets: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets);
1117 DPRINT("MaximumNumberOfLogicalUnits: %lu\n", DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits);
1118
1119 /* Scan all buses */
1120 for (Bus = 0; Bus < DeviceExtension->Miniport.PortConfig.NumberOfBuses; Bus++)
1121 {
1122 DPRINT("Scanning bus %ld\n", Bus);
1123
1124 /* Scan all targets */
1125 for (Target = 0; Target < DeviceExtension->Miniport.PortConfig.MaximumNumberOfTargets; Target++)
1126 {
1127 DPRINT(" Scanning target %ld:%ld\n", Bus, Target);
1128
1129 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, 0);
1130 Status = PortCreatePdo(DeviceExtension, Bus, Target, 0, &PdoExtension);
1131 if (!NT_SUCCESS(Status))
1132 continue;
1133
1134 /* Ask the target which units it has before probing any of them */
1135 LunCount = 0;
1136 PortSendReportLuns(PdoExtension, &LunCount, LunList, RTL_NUMBER_OF(LunList));
1137
1138 /* Scan LUN 0 */
1140 DPRINT("PortSendInquiry returned 0x%08lx\n", Status);
1141 if (!NT_SUCCESS(Status))
1142 {
1144 }
1145 else
1146 {
1147 DPRINT("VendorId: %.8s\n", PdoExtension->InquiryBuffer->VendorId);
1148 DPRINT("ProductId: %.16s\n", PdoExtension->InquiryBuffer->ProductId);
1149 DPRINT("ProductRevisionLevel: %.4s\n", PdoExtension->InquiryBuffer->ProductRevisionLevel);
1150 DPRINT("VendorSpecific: %.20s\n", PdoExtension->InquiryBuffer->VendorSpecific);
1151 }
1152
1153 /* Scan the rest of the units the target reported */
1154 for (Index = 0; Index < LunCount; Index++)
1155 {
1156 ULONG Lun = LunList[Index];
1157
1158 /* Unit zero was done above, and the report may not name it */
1159 if (Lun == 0)
1160 continue;
1161
1162 /* The miniport cannot address units past the limit it gave */
1163 if (Lun >= DeviceExtension->Miniport.PortConfig.MaximumNumberOfLogicalUnits)
1164 continue;
1165
1166 DPRINT(" Scanning logical unit %ld:%ld:%ld\n", Bus, Target, Lun);
1167 Status = PortCreatePdo(DeviceExtension, Bus, Target, Lun, &PdoExtension);
1168 if (!NT_SUCCESS(Status))
1169 continue;
1170
1172 DPRINT("PortSendInquiry returned 0x%08lx\n", Status);
1173 if (!NT_SUCCESS(Status))
1175 }
1176 }
1177 }
1178
1179 DPRINT("PortFdoScanBus() done!\n");
1180
1181 return STATUS_SUCCESS;
1182}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define SCSI_MAXIMUM_LUNS_PER_TARGET
Definition: srb.h:23
static NTSTATUS PortSendInquiry(_In_ PPDO_DEVICE_EXTENSION PdoExtension)
Definition: fdo.c:898
static NTSTATUS PortSendReportLuns(_In_ PPDO_DEVICE_EXTENSION PdoExtension, _Out_ PULONG LunCount, _Out_writes_(LunListSize) PUCHAR LunList, _In_ ULONG LunListSize)
Definition: fdo.c:611
NTSTATUS PortDeletePdo(_In_ PPDO_DEVICE_EXTENSION PdoExtension)
Definition: pdo.c:126
NTSTATUS PortCreatePdo(_In_ PFDO_DEVICE_EXTENSION FdoDeviceExtension, _In_ ULONG Bus, _In_ ULONG Target, _In_ ULONG Lun, _Out_ PPDO_DEVICE_EXTENSION *PdoDeviceExtension)
Definition: pdo.c:21
unsigned char UCHAR
Definition: typedefs.h:53

Referenced by PortFdoQueryBusRelations().

◆ PortFdoScsi()

NTSTATUS NTAPI PortFdoScsi ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp 
)

Definition at line 1491 of file fdo.c.

1494{
1495 PFDO_DEVICE_EXTENSION DeviceExtension;
1496// PIO_STACK_LOCATION Stack;
1499
1500 DPRINT("PortFdoScsi(%p %p)\n", DeviceObject, Irp);
1501
1502 DeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
1503 ASSERT(DeviceExtension);
1504 ASSERT(DeviceExtension->ExtensionType == FdoExtension);
1505
1506// Stack = IoGetCurrentIrpStackLocation(Irp);
1507
1508
1509 Irp->IoStatus.Information = Information;
1510 Irp->IoStatus.Status = Status;
1512
1513 return Status;
1514}

Referenced by PortDispatchScsi().

◆ PortFdoStartDevice()

static NTSTATUS PortFdoStartDevice ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension,
_In_ PIRP  Irp 
)
static

Definition at line 519 of file fdo.c.

522{
526
527 DPRINT1("PortFdoStartDevice(%p %p)\n",
528 DeviceExtension, Irp);
529
530 ASSERT(DeviceExtension->ExtensionType == FdoExtension);
531
532 /* Get the current stack location */
534
535 /* Start the lower device if the FDO is in 'stopped' state */
536 if (DeviceExtension->PnpState == dsStopped)
537 {
538 if (IoForwardIrpSynchronously(DeviceExtension->LowerDevice, Irp))
539 {
540 Status = Irp->IoStatus.Status;
541 }
542 else
543 {
545 }
546
547 if (!NT_SUCCESS(Status))
548 {
549 DPRINT1("Lower device failed the IRP (Status 0x%08lx)\n", Status);
550 return Status;
551 }
552 }
553
554 /* Change to the 'started' state */
555 DeviceExtension->PnpState = dsStarted;
556
557 /* Copy the raw and translated resource lists into the device extension */
558 if (Stack->Parameters.StartDevice.AllocatedResources != NULL &&
559 Stack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL)
560 {
561 DeviceExtension->AllocatedResources = CopyResourceList(NonPagedPool,
562 Stack->Parameters.StartDevice.AllocatedResources);
563 if (DeviceExtension->AllocatedResources == NULL)
564 return STATUS_NO_MEMORY;
565
566 DeviceExtension->TranslatedResources = CopyResourceList(NonPagedPool,
567 Stack->Parameters.StartDevice.AllocatedResourcesTranslated);
568 if (DeviceExtension->TranslatedResources == NULL)
569 return STATUS_NO_MEMORY;
570 }
571
572 /* Get the bus interface of the lower (bus) device */
573 Status = QueryBusInterface(DeviceExtension->LowerDevice,
574 (PGUID)&GUID_BUS_INTERFACE_STANDARD,
576 1,
577 &DeviceExtension->BusInterface,
578 NULL);
579 DPRINT1("Status: 0x%08lx\n", Status);
580 if (NT_SUCCESS(Status))
581 {
582 DPRINT1("Context: %p\n", DeviceExtension->BusInterface.Context);
583 DeviceExtension->BusInitialized = TRUE;
584 }
585
586 /* Start the miniport (FindAdapter & Initialize) */
587 Status = PortFdoStartMiniport(DeviceExtension);
588 if (!NT_SUCCESS(Status))
589 {
590 DPRINT1("FdoStartMiniport() failed (Status 0x%08lx)\n", Status);
591 DeviceExtension->PnpState = dsStopped;
592 }
593 else
594 {
595 /* SrbExtensionSize is only known once the miniport is up */
596 PortAllocateRequestReserve(DeviceExtension);
597 }
598
599 /* Claim and increase SCSI port number */
600 /* TODO: Reverse this when stopping adapter */
601 ConfigInfo = IoGetConfigurationInformation();
602 DeviceExtension->ScsiPortNumber = ConfigInfo->ScsiPortCount;
603 ConfigInfo->ScsiPortCount++;
604
605 return Status;
606}
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
NTSTATUS QueryBusInterface(PDEVICE_OBJECT DeviceObject, PGUID Guid, USHORT Size, USHORT Version, PBUS_INTERFACE_STANDARD Interface, PVOID InterfaceSpecificData)
Definition: misc.c:122
PCM_RESOURCE_LIST CopyResourceList(POOL_TYPE PoolType, PCM_RESOURCE_LIST Source)
Definition: misc.c:92
PCONFIGURATION_INFORMATION NTAPI IoGetConfigurationInformation(VOID)
Returns a pointer to the I/O manager's global configuration information structure.
Definition: iorsrce.c:998
@ dsStarted
Definition: isapnp.h:31
BOOLEAN NTAPI IoForwardIrpSynchronously(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1657
static NTSTATUS PortFdoStartMiniport(_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:412
VOID PortAllocateRequestReserve(_In_ PFDO_DEVICE_EXTENSION FdoExtension)
Reserves the memory a single request needs, so IO can still be issued out of pool.
Definition: fdo.c:168
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

Referenced by PortFdoPnp().

◆ PortFdoStartMiniport()

static NTSTATUS PortFdoStartMiniport ( _In_ PFDO_DEVICE_EXTENSION  DeviceExtension)
static

Definition at line 412 of file fdo.c.

414{
419
420 DPRINT1("PortFdoStartMiniport(%p)\n", DeviceExtension);
421
422 /* Query the physical device, a filter may sit between us and it */
423 InterfaceType = GetBusInterface(DeviceExtension->PhysicalDevice);
425 {
426 /* Only a virtual miniport, registered under Internal, can drive such a device */
427 DPRINT1("The bus this adapter sits on is unknown, trying Internal\n");
429 }
430
431 /* Get the driver init data for the given interface type */
432 InitData = PortGetDriverInitData(DeviceExtension->DriverExtension,
434 if (InitData == NULL)
435 {
436 DPRINT1("No init data registered for bus type %lu\n", InterfaceType);
438 }
439
440 /* The request path needs this even if no uncached extension is ever asked for */
441 DeviceExtension->HwInitData = InitData;
442
443 /* Initialize the miniport */
444 Status = MiniportInitialize(&DeviceExtension->Miniport,
445 DeviceExtension,
446 InitData);
447 if (!NT_SUCCESS(Status))
448 {
449 DPRINT1("MiniportInitialize() failed (Status 0x%08lx)\n", Status);
450 return Status;
451 }
452
453 /* Call the miniports FindAdapter function */
454 Status = MiniportFindAdapter(&DeviceExtension->Miniport);
455 if (!NT_SUCCESS(Status))
456 {
457 DPRINT1("MiniportFindAdapter() failed (Status 0x%08lx)\n", Status);
458 return Status;
459 }
460
461 /* The SRB format is only known after HwFindAdapter */
462 if (!DeviceExtension->RequestReferenceLookasideInitialized)
463 {
464 if (DeviceExtension->Miniport.PortConfig.SrbType == SRB_TYPE_STORAGE_REQUEST_BLOCK)
466 else
468
469 ExInitializeNPagedLookasideList(&DeviceExtension->RequestReferenceLookaside,
470 NULL,
471 NULL,
472 0,
475 0);
476 DeviceExtension->RequestReferenceLookasideInitialized = TRUE;
477 }
478
479 /* Find out which adapter control requests the miniport takes */
480 MiniportQueryAdapterControl(&DeviceExtension->Miniport);
481 MiniportQueryUnitControl(&DeviceExtension->Miniport);
482
483 /* Connect the configured interrupt */
484 Status = PortFdoConnectInterrupt(DeviceExtension);
485 if (!NT_SUCCESS(Status))
486 {
487 DPRINT1("PortFdoConnectInterrupt() failed (Status 0x%08lx)\n", Status);
488 return Status;
489 }
490
491 // FIXME: Find an appropriate place
492 DeviceExtension->OutstandingRequestMax = DeviceExtension->Miniport.PortConfig.MaxNumberOfIO;
493
494 /* Call the miniports HwInitialize function */
495 Status = MiniportHwInitialize(&DeviceExtension->Miniport);
496 if (!NT_SUCCESS(Status))
497 {
498 DPRINT1("MiniportHwInitialize() failed (Status 0x%08lx)\n", Status);
499 return Status;
500 }
501
502 /* Call the HwPassiveInitRoutine function, if available */
503 if (DeviceExtension->HwPassiveInitRoutine != NULL)
504 {
505 DPRINT1("Calling HwPassiveInitRoutine()\n");
506 if (!DeviceExtension->HwPassiveInitRoutine(&DeviceExtension->Miniport.MiniportExtension->HwDeviceExtension))
507 {
508 DPRINT1("HwPassiveInitRoutine() failed\n");
509 return STATUS_UNSUCCESSFUL;
510 }
511 }
512
513 return STATUS_SUCCESS;
514}
INTERFACE_TYPE GetBusInterface(PDEVICE_OBJECT DeviceObject)
Definition: misc.c:33
struct _QUEUED_REQUEST_REFERENCE QUEUED_REQUEST_REFERENCE
PHW_INITIALIZATION_DATA PortGetDriverInitData(PDRIVER_OBJECT_EXTENSION DriverExtension, INTERFACE_TYPE InterfaceType)
Definition: storport.c:87
NDIS_STATUS NTAPI MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext)
Definition: ndis.c:50
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:218
static ULONG RequestSize
Definition: ping.c:63
@ InterfaceTypeUndefined
Definition: restypes.h:121
@ Internal
Definition: restypes.h:122
enum _INTERFACE_TYPE INTERFACE_TYPE
#define SRB_TYPE_STORAGE_REQUEST_BLOCK
Definition: srb.h:664
static NTSTATUS PortFdoConnectInterrupt(_In_ PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: fdo.c:314
NTSTATUS MiniportFindAdapter(_In_ PMINIPORT Miniport)
Definition: miniport.c:325
VOID NTAPI MiniportQueryAdapterControl(_In_ PMINIPORT Miniport)
Asks the miniport which adapter control requests it handles.
Definition: miniport.c:456
NTSTATUS MiniportHwInitialize(_In_ PMINIPORT Miniport)
Definition: miniport.c:399
VOID NTAPI MiniportQueryUnitControl(_In_ PMINIPORT Miniport)
Asks the miniport which unit control requests it handles.
Definition: miniport.c:529
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID InterfaceType
Definition: wdffdo.h:463

Referenced by PortFdoStartDevice().

◆ PortFdoStopAdapter()

static VOID PortFdoStopAdapter ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)
static

Tells the miniport to stop the adapter with its interrupt service routines held off.

Definition at line 1389 of file fdo.c.

1391{
1392 KIRQL OldIrql;
1393
1397}
@ ScsiStopAdapter
Definition: srb.h:178
SCSI_ADAPTER_CONTROL_STATUS NTAPI MiniportAdapterControl(_In_ PMINIPORT Miniport, _In_ SCSI_ADAPTER_CONTROL_TYPE ControlType, _In_opt_ PVOID Parameters)
Sends one adapter control request, if the miniport claimed it.
Definition: miniport.c:504

Referenced by PortFdoPnp().

◆ PortFdoUnlinkPdo()

VOID NTAPI PortFdoUnlinkPdo ( _Inout_ PFDO_DEVICE_EXTENSION  FdoExtension,
_Inout_ PPDO_DEVICE_EXTENSION  PdoExtension 
)

Definition at line 1451 of file fdo.c.

Referenced by PortDeletePdo().

◆ PortFlushStarvedRequests()

VOID PortFlushStarvedRequests ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)

Fails every queued request, for when the adapter goes away.

Definition at line 153 of file fdo.c.

155{
156 PIRP Irp;
157
158 while ((Irp = IoCsqRemoveNextIrp(&FdoExtension->StarvedRequests.Csq, NULL)) != NULL)
159 {
161 }
162}
NTKERNELAPI PIRP NTAPI IoCsqRemoveNextIrp(_Inout_ PIO_CSQ Csq, _In_opt_ PVOID PeekContext)
IoCsqRemoveNextIrp - Removes the next IRP from the queue.
Definition: csq.c:398
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:348
FORCEINLINE VOID StorpCompleteRequest(_In_ PIRP Irp, _In_ UCHAR SrbStatus, _In_ NTSTATUS IrpStatus)
Completes a request with specified SRB status and IRP status.
Definition: inline.h:19

Referenced by PortFdoPnp().

◆ PortFreeRequestReserve()

VOID PortFreeRequestReserve ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)

Releases the reserve. No request may be using it anymore.

Definition at line 205 of file fdo.c.

207{
208 if (FdoExtension->ReservedSrbExtension != NULL)
209 {
210 ExFreePoolWithTag(FdoExtension->ReservedSrbExtension, TAG_SRB_EXTENSION);
211 FdoExtension->ReservedSrbExtension = NULL;
212 }
213
214 if (FdoExtension->ReservedRequestReference != NULL)
215 {
216 ExFreePoolWithTag(FdoExtension->ReservedRequestReference, TAG_QUEUED_REQUEST);
217 FdoExtension->ReservedRequestReference = NULL;
218 }
219}

Referenced by PortFdoPnp().

◆ PortInitializeStarvedRequestQueue()

NTSTATUS PortInitializeStarvedRequestQueue ( _In_ PSTARVED_REQUEST_QUEUE  Queue)

Definition at line 105 of file fdo.c.

107{
109 InitializeListHead(&Queue->ListHead);
110
111 return IoCsqInitialize(&Queue->Csq,
118}
NTKERNELAPI NTSTATUS NTAPI IoCsqInitialize(_Out_ PIO_CSQ Csq, _In_ PIO_CSQ_INSERT_IRP CsqInsertIrp, _In_ PIO_CSQ_REMOVE_IRP CsqRemoveIrp, _In_ PIO_CSQ_PEEK_NEXT_IRP CsqPeekNextIrp, _In_ PIO_CSQ_ACQUIRE_LOCK CsqAcquireLock, _In_ PIO_CSQ_RELEASE_LOCK CsqReleaseLock, _In_ PIO_CSQ_COMPLETE_CANCELED_IRP CsqCompleteCanceledIrp)
Set up a CSQ struct to initialize the queue.
Definition: csq.c:103
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
static VOID NTAPI PortStarvedCsqInsertIrp(_In_ PIO_CSQ Csq, _In_ PIRP Irp)
Definition: fdo.c:24
static VOID NTAPI PortStarvedCsqAcquireLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: fdo.c:71
static PIRP NTAPI PortStarvedCsqPeekNextIrp(_In_ PIO_CSQ Csq, _In_ PIRP Irp, _In_ PVOID PeekContext)
Definition: fdo.c:48
static VOID NTAPI PortStarvedCsqRemoveIrp(_In_ PIO_CSQ Csq, _In_ PIRP Irp)
Definition: fdo.c:36
static VOID NTAPI PortStarvedCsqCompleteCanceledIrp(_In_ PIO_CSQ Csq, _In_ PIRP Irp)
Definition: fdo.c:95
static VOID NTAPI PortStarvedCsqReleaseLock(_In_ PIO_CSQ Csq, _In_ KIRQL Irql)
Definition: fdo.c:83
_Must_inspect_result_ _In_ WDFDEVICE _In_ PIRP _In_ WDFQUEUE Queue
Definition: wdfdevice.h:2231

Referenced by PortAddDevice().

◆ PortQueueStarvedRequest()

VOID PortQueueStarvedRequest ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension,
_In_ PIRP  Irp 
)

Queues a request that could not allocate its private contexts.

Definition at line 124 of file fdo.c.

127{
128 IoCsqInsertIrp(&FdoExtension->StarvedRequests.Csq, Irp, NULL);
129}
NTKERNELAPI VOID NTAPI IoCsqInsertIrp(_Inout_ PIO_CSQ Csq, _Inout_ PIRP Irp, _Out_opt_ PIO_CSQ_IRP_CONTEXT Context)
Insert an IRP into the CSQ.
Definition: csq.c:177

Referenced by PortPdoStarveRequest().

◆ PortRetryStarvedRequest()

VOID PortRetryStarvedRequest ( _In_ PFDO_DEVICE_EXTENSION  FdoExtension)

Retries one queued request, so each completion lets exactly one through.

Definition at line 135 of file fdo.c.

137{
138 PIRP Irp;
139
140 Irp = IoCsqRemoveNextIrp(&FdoExtension->StarvedRequests.Csq, NULL);
141 if (Irp == NULL)
142 {
143 return;
144 }
145
147}
NTSTATUS NTAPI PortPdoScsi(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
Definition: srb.c:548

Referenced by PortCompleteRequest().

◆ PortSendInquiry()

static NTSTATUS PortSendInquiry ( _In_ PPDO_DEVICE_EXTENSION  PdoExtension)
static

Definition at line 898 of file fdo.c.

900{
902 PIO_STACK_LOCATION IrpStack;
904// KIRQL Irql;
905 PIRP Irp;
907 PSENSE_DATA SenseBuffer;
908 BOOLEAN KeepTrying = TRUE;
909 ULONG RetryCount = 0;
911 PCDB Cdb;
912// PSCSI_PORT_LUN_EXTENSION LunExtension;
913// PFDO_DEVICE_EXTENSION DeviceExtension;
914
915 DPRINT("PortSendInquiry(%p)\n", PdoExtension);
916
917 if (PdoExtension->InquiryBuffer == NULL)
918 {
920 if (PdoExtension->InquiryBuffer == NULL)
922 }
923
925 if (SenseBuffer == NULL)
926 {
928 }
929
930 while (KeepTrying)
931 {
932 /* Initialize event for waiting */
935 FALSE);
936
937 /* Create an IRP */
939 PdoExtension->Device,
940 NULL,
941 0,
942 PdoExtension->InquiryBuffer,
944 TRUE,
945 &Event,
947 if (Irp == NULL)
948 {
949 DPRINT1("IoBuildDeviceIoControlRequest() failed\n");
950
951 /* Quit the loop */
953 KeepTrying = FALSE;
954 continue;
955 }
956
957 /* Prepare SRB */
959
960 Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
962 Srb.PathId = PdoExtension->Bus;
963 Srb.TargetId = PdoExtension->Target;
964 Srb.Lun = PdoExtension->Lun;
967 Srb.TimeOutValue = 4;
968 Srb.CdbLength = 6;
969
970 Srb.SenseInfoBuffer = SenseBuffer;
972
973 Srb.DataBuffer = PdoExtension->InquiryBuffer;
975
976 /* Attach Srb to the Irp */
977 IrpStack = IoGetNextIrpStackLocation(Irp);
978 IrpStack->Parameters.Scsi.Srb = &Srb;
979
980 /* Fill in CDB */
981 Cdb = (PCDB)Srb.Cdb;
982 Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
983 Cdb->CDB6INQUIRY.LogicalUnitNumber = PdoExtension->Lun;
984 Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
985
986 /* Call the driver */
988
989 /* Wait for it to complete */
990 if (Status == STATUS_PENDING)
991 {
992 DPRINT1("PortSendInquiry(): Waiting for the driver to process request...\n");
994 Executive,
996 FALSE,
997 NULL);
998 Status = IoStatusBlock.Status;
999 }
1000
1001 DPRINT1("PortSendInquiry(): Request processed by driver, status = 0x%08X\n", Status);
1002
1004 {
1005 DPRINT1("Found a device!\n");
1006
1007 /* Quit the loop */
1009 KeepTrying = FALSE;
1010 continue;
1011 }
1012
1013 DPRINT1("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
1014
1015 /* Check if the queue is frozen */
1017 {
1018 /* Something weird happened, deal with it (unfreeze the queue) */
1019 KeepTrying = FALSE;
1020
1021 DPRINT1("SpiSendInquiry(): the queue is frozen at TargetId %d\n", Srb.TargetId);
1022
1023// LunExtension = SpiGetLunExtension(DeviceExtension,
1024// LunInfo->PathId,
1025// LunInfo->TargetId,
1026// LunInfo->Lun);
1027
1028 /* Clear frozen flag */
1029// LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
1030
1031 /* Acquire the spinlock */
1032// KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
1033
1034 /* Process the request */
1035// SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension);
1036
1037 /* SpiGetNextRequestFromLun() releases the spinlock,
1038 so we just lower irql back to what it was before */
1039// KeLowerIrql(Irql);
1040 }
1041
1042 /* Check if data overrun happened */
1044 {
1045 DPRINT("Data overrun at TargetId %d\n", PdoExtension->Target);
1046
1047 /* Quit the loop */
1049 KeepTrying = FALSE;
1050 }
1052 SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST)
1053 {
1054 /* LUN is not valid, but some device responds there.
1055 Mark it as invalid anyway */
1056
1057 /* Quit the loop */
1059 KeepTrying = FALSE;
1060 }
1061 else
1062 {
1063 /* Retry a couple of times if no timeout happened */
1064 if ((RetryCount < 2) &&
1067 {
1068 RetryCount++;
1069 KeepTrying = TRUE;
1070 }
1071 else
1072 {
1073 /* That's all, quit the loop */
1074 KeepTrying = FALSE;
1075
1076 /* Set status according to SRB status */
1079 {
1081 }
1082 else
1083 {
1085 }
1086 }
1087 }
1088 }
1089
1090 /* Free the sense buffer */
1091 ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
1092
1093 DPRINT1("PortSendInquiry() done with Status 0x%08X\n", Status);
1094
1095 return Status;
1096}
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
union _CDB * PCDB
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
_In_ PIO_STATUS_BLOCK IoStatusBlock
Definition: dispmprt.h:608
_Check_return_ _In_ DXGK_EVENT_TYPE _In_ ULONG Event
Definition: dispmprt.h:1287
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_STATUS_BAD_SRB_BLOCK_LENGTH
Definition: srb.h:360
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:387
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:350
#define SRB_STATUS_BAD_FUNCTION
Definition: srb.h:364
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
#define SRB_STATUS(Status)
Definition: srb.h:389
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:386
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
#define TAG_INQUIRY_DATA
Definition: precomp.h:37
#define TAG_SENSE_DATA
Definition: precomp.h:40
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define KernelMode
Definition: asm.h:38
@ NotificationEvent
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:913
#define IoCallDriver
Definition: irp.c:1257
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
union _IO_STACK_LOCATION::@1823 Parameters
struct _IO_STACK_LOCATION::@5136::@5158 Scsi
ULONG TimeOutValue
Definition: srb.h:262
UCHAR TargetId
Definition: srb.h:254
PVOID OriginalRequest
Definition: srb.h:266
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID DataBuffer
Definition: srb.h:263
UCHAR PathId
Definition: srb.h:253
UCHAR CdbLength
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:279
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR Function
Definition: srb.h:250
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
USHORT Length
Definition: srb.h:249
UCHAR SrbStatus
Definition: srb.h:251
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define STATUS_PENDING
Definition: telnetd.h:14
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
Definition: cdrw_hw.h:28
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2721
@ Executive
Definition: ketypes.h:467

Referenced by PortFdoScanBus().

◆ PortSendReportLuns()

static NTSTATUS PortSendReportLuns ( _In_ PPDO_DEVICE_EXTENSION  PdoExtension,
_Out_ PULONG  LunCount,
_Out_writes_(LunListSize) PUCHAR  LunList,
_In_ ULONG  LunListSize 
)
static

Definition at line 611 of file fdo.c.

616{
619 PCDB Cdb;
620 PIRP Irp;
622 PIO_STACK_LOCATION IrpStack;
624 PSENSE_DATA SenseBuffer;
626 PREPORT_LUNS_DATA ReportLunsData;
627 BOOLEAN KeepTrying = TRUE;
628 BOOLEAN BufferReallocated = FALSE;
629 ULONG RetryCount = 0;
630
631 DPRINT("PortSendReportLuns(%p)\n", PdoExtension);
632
633 /* Allocate sense buffer */
634 /* TODO: Reuse sense buffers */
635 /* FIXME: Do we need sense buffer here? Can I pass a NULL? */
637 if (SenseBuffer == NULL)
638 {
640 }
641
642 /* Allocate REPORT LUNS return buffer. Use buffer size for the case of a single LUN */
644 ReportLunsData =
646 if (ReportLunsData == NULL)
647 {
649 }
650
651 while (KeepTrying)
652 {
653 /* Initialize event for waiting */
656 FALSE);
657
658 /* Create an IRP */
660 PdoExtension->Device,
661 NULL,
662 0,
663 ReportLunsData,
665 TRUE,
666 &Event,
668 if (Irp == NULL)
669 {
670 DPRINT("IoBuildDeviceIoControlRequest() failed\n");
671
672 /* Quit the loop */
674 KeepTrying = FALSE;
675 continue;
676 }
677
678 /* Prepare SRB */
680
681 Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
683 Srb.PathId = PdoExtension->Bus;
684 Srb.TargetId = PdoExtension->Target;
685 Srb.Lun = PdoExtension->Lun;
688 Srb.TimeOutValue = 4;
689 Srb.CdbLength = 12;
690
691 Srb.SenseInfoBuffer = SenseBuffer;
693
694 Srb.DataBuffer = ReportLunsData;
696
697 /* Attach Srb to the Irp */
698 IrpStack = IoGetNextIrpStackLocation(Irp);
699 IrpStack->Parameters.Scsi.Srb = &Srb;
700
701 /* Fill in CDB */
702 Cdb = (PCDB)Srb.Cdb;
703 Cdb->REPORT_LUNS.OperationCode = SCSIOP_REPORT_LUNS;
704 Cdb->REPORT_LUNS.AllocationLength[0] = (BufferSize >> (3*8)) & 0xFF;
705 Cdb->REPORT_LUNS.AllocationLength[1] = (BufferSize >> (2*8)) & 0xFF;
706 Cdb->REPORT_LUNS.AllocationLength[2] = (BufferSize >> (1*8)) & 0xFF;
707 Cdb->REPORT_LUNS.AllocationLength[3] = (BufferSize >> (0*8)) & 0xFF;
708
709 /* Call the driver */
711
712 /* Wait for it to complete */
714 {
715 DPRINT1("PortSendReportLuns(): Waiting for the driver to process request...\n");
717 Executive,
719 FALSE,
720 NULL);
721 Status = IoStatusBlock.Status;
722 }
723
724 DPRINT("PortSendReportLuns(): Request processed by driver, status = 0x%08X\n", Status);
725
727 {
728 ULONG DataSize = 0;
729 ULONG Reported;
730 ULONG Index;
731
732 /* The reported length covers the descriptors alone */
733 DataSize |= (((ULONG)ReportLunsData->LunListLength[0]) << (8*3));
734 DataSize |= (((ULONG)ReportLunsData->LunListLength[1]) << (8*2));
735 DataSize |= (((ULONG)ReportLunsData->LunListLength[2]) << (8*1));
736 DataSize |= (((ULONG)ReportLunsData->LunListLength[3]) << (8*0));
737 Reported = DataSize / sizeof(*ReportLunsData->LunDescriptor);
738
739 /* A device with more units than the first guess held is asked again */
740 if ((DataSize > BufferSize - FIELD_OFFSET(REPORT_LUNS_DATA, LunDescriptor)) &&
741 !BufferReallocated)
742 {
743 ExFreePoolWithTag(ReportLunsData, TAG_REPORT_LUN_DATA);
744
747 if (ReportLunsData == NULL)
748 {
749 DPRINT1("Cannot reallocate REPORT_LUNS buffer\n");
750 ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
752 }
753
754 BufferReallocated = TRUE;
755 continue;
756 }
757
758 /* Only what actually arrived can be read back out */
759 Reported = min(Reported,
760 (BufferSize - FIELD_OFFSET(REPORT_LUNS_DATA, LunDescriptor)) /
761 sizeof(*ReportLunsData->LunDescriptor));
762
763 *LunCount = 0;
764 for (Index = 0; Index < Reported; Index++)
765 {
766 PLUN_DESCRIPTOR Descriptor = &ReportLunsData->LunDescriptor[Index];
767
768 /* Only units named the flat way fit in a single byte */
769 if (Descriptor->AddressMethod != 0)
770 continue;
771
772 if (*LunCount >= LunListSize)
773 break;
774
775 LunList[(*LunCount)++] = Descriptor->Level1Address;
776 }
777
778 /* Quit the loop */
780 KeepTrying = FALSE;
781 continue;
782 }
783
784 DPRINT1("REPORT_LUNS SRB failed with SrbStatus 0x%08X Status %08X\n",
786
787 /* Check if the queue is frozen */
789 {
790 /* Something weird happened, deal with it (unfreeze the queue) */
791 KeepTrying = FALSE;
792
793 DPRINT1("PortSendReportLuns(): the queue is frozen at TargetId %d\n", Srb.TargetId);
794 /* TODO: What do we do with this crap */
795#if 0
796 LunExtension = SpiGetLunExtension(DeviceExtension,
797 LunInfo->PathId,
798 LunInfo->TargetId,
799 LunInfo->Lun);
800
801 /* Clear frozen flag */
802 LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
803
804 /* Acquire the spinlock */
805 KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
806
807 /* Process the request */
808 SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension);
809
810 /* SpiGetNextRequestFromLun() releases the spinlock,
811 so we just lower irql back to what it was before */
813#endif
814 }
815
816 /* Check if data overrun happened, then resize buffer once */
817 /* FIXME: Needs coverage test */
819 {
820 /* If the buffer has already been reallocated we ditch the device */
821 if (BufferReallocated)
822 {
823 DPRINT1("Data overrun again (!) at TargetId %d, give up\n", PdoExtension->Target);
824
826 KeepTrying = FALSE;
827 continue;
828 }
829
830 /* Miniport will return how many bytes should we actually allocate */
831 BufferSize = 0;
832 BufferSize |= (((ULONG)ReportLunsData->LunListLength[0]) << (8*3));
833 BufferSize |= (((ULONG)ReportLunsData->LunListLength[1]) << (8*2));
834 BufferSize |= (((ULONG)ReportLunsData->LunListLength[2]) << (8*1));
835 BufferSize |= (((ULONG)ReportLunsData->LunListLength[3]) << (8*0));
836 BufferSize += FIELD_OFFSET(REPORT_LUNS_DATA, LunDescriptor);
837
838 DPRINT1("Data overrun at TargetId %d, %d bytes needed\n",
839 PdoExtension->Target,
840 BufferSize);
841
842 /* Allocate a larger buffer */
843 ExFreePoolWithTag(ReportLunsData, TAG_REPORT_LUN_DATA);
845 if (ReportLunsData == NULL)
846 {
847 DPRINT1("Cannot reallocate REPORT_LUNS buffer\n");
848
850 KeepTrying = FALSE;
851 continue;
852 }
853 BufferReallocated = TRUE;
854
855 /* Continue trying with a larger buffer */
856 continue;
857 }else
858 {
859 /* Retry a couple of times if no timeout happened */
860 if ((RetryCount < 2) &&
863 {
864 RetryCount++;
865 KeepTrying = TRUE;
866 }
867 else
868 {
869 /* That's all, quit the loop */
870 KeepTrying = FALSE;
871
872 /* Set status according to SRB status */
875 {
877 }
878 else
879 {
881 }
882 }
883 }
884 }
885
886 /* Free Sense data and Report LUNs buffer */
887 ExFreePoolWithTag(ReportLunsData, TAG_REPORT_LUN_DATA);
888 ExFreePoolWithTag(SenseBuffer, TAG_SENSE_DATA);
889
890 DPRINT1("PortSendReportLuns() done with Status 0x%08X\n", Status);
891
892 return Status;
893}
#define BufferSize
Definition: mmc.h:75
_In_ ULONG BufferSize
Definition: dispmprt.h:490
#define SCSIOP_REPORT_LUNS
Definition: scsi.h:921
#define SRB_STATUS_PENDING
Definition: srb.h:340
#define TAG_REPORT_LUN_DATA
Definition: precomp.h:39
struct _REPORT_LUNS_DATA REPORT_LUNS_DATA
struct _REPORT_LUNS_DATA * PREPORT_LUNS_DATA
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define min(a, b)
Definition: monoChain.cc:55
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4757
VOID SpiGetNextRequestFromLun(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension, _Inout_opt_ PKIRQL OldIrql)
Definition: scsi.c:342
UCHAR Level1Address
Definition: precomp.h:410
LUN_DESCRIPTOR LunDescriptor[1]
Definition: precomp.h:420
UCHAR LunListLength[4]
Definition: precomp.h:418
struct _CDB::_REPORT_LUNS REPORT_LUNS
_Must_inspect_result_ _In_ WDFIORESLIST _In_ PIO_RESOURCE_DESCRIPTOR Descriptor
Definition: wdfresource.h:342

Referenced by PortFdoScanBus().

◆ PortStarvedCsqAcquireLock()

static VOID NTAPI PortStarvedCsqAcquireLock ( _In_ PIO_CSQ  Csq,
_Out_ PKIRQL  Irql 
)
static

◆ PortStarvedCsqCompleteCanceledIrp()

static VOID NTAPI PortStarvedCsqCompleteCanceledIrp ( _In_ PIO_CSQ  Csq,
_In_ PIRP  Irp 
)
static

Definition at line 95 of file fdo.c.

98{
100
102}
#define SRB_STATUS_ABORTED
Definition: srb.h:342
#define STATUS_CANCELLED
Definition: udferr_usr.h:170

Referenced by PortInitializeStarvedRequestQueue().

◆ PortStarvedCsqInsertIrp()

static VOID NTAPI PortStarvedCsqInsertIrp ( _In_ PIO_CSQ  Csq,
_In_ PIRP  Irp 
)
static

Definition at line 24 of file fdo.c.

27{
29
30 InsertTailList(&Queue->ListHead, &Irp->Tail.Overlay.ListEntry);
31}
#define InsertTailList(ListHead, Entry)

Referenced by PortInitializeStarvedRequestQueue().

◆ PortStarvedCsqPeekNextIrp()

static PIRP NTAPI PortStarvedCsqPeekNextIrp ( _In_ PIO_CSQ  Csq,
_In_ PIRP  Irp,
_In_ PVOID  PeekContext 
)
static

Definition at line 48 of file fdo.c.

52{
55
57
58 Entry = (Irp == NULL) ? Queue->ListHead.Flink : Irp->Tail.Overlay.ListEntry.Flink;
59
60 if (Entry == &Queue->ListHead)
61 {
62 return NULL;
63 }
64
65 return CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
66}
_In_opt_ PIRP _In_opt_ PVOID PeekContext
Definition: csq.h:160
PLIST_ENTRY Entry
Definition: devhcd.cpp:1262
const UCHAR * Tail
Definition: hubmsos.cpp:145

Referenced by PortInitializeStarvedRequestQueue().

◆ PortStarvedCsqReleaseLock()

static VOID NTAPI PortStarvedCsqReleaseLock ( _In_ PIO_CSQ  Csq,
_In_ KIRQL  Irql 
)
static

Definition at line 83 of file fdo.c.

86{
88
90}
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

Referenced by PortInitializeStarvedRequestQueue().

◆ PortStarvedCsqRemoveIrp()

static VOID NTAPI PortStarvedCsqRemoveIrp ( _In_ PIO_CSQ  Csq,
_In_ PIRP  Irp 
)
static

Definition at line 36 of file fdo.c.

39{
41
42 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
43}

Referenced by PortInitializeStarvedRequestQueue().