ReactOS  0.4.15-dev-1377-ga59cecd
fdo.c File Reference
#include "scsiport.h"
#include <debug.h>
Include dependency graph for fdo.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS SpiSendInquiry (_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_LUN_INFO LunInfo)
 
VOID SpiScanAdapter (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 
NTSTATUS CallHWInitialize (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 Calls HwInitialize routine of the miniport and sets up interrupts Should be called inside ScsiPortInitialize (for legacy drivers) or inside IRP_MN_START_DEVICE for pnp drivers. More...
 
VOID SpiCleanupAfterInit (_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 11 of file fdo.c.

Function Documentation

◆ CallHWInitialize()

NTSTATUS CallHWInitialize ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Calls HwInitialize routine of the miniport and sets up interrupts Should be called inside ScsiPortInitialize (for legacy drivers) or inside IRP_MN_START_DEVICE for pnp drivers.

Parameters
[in]DeviceExtensionThe device extension
Returns
NTSTATUS of the operation

Definition at line 459 of file fdo.c.

461 {
462  PPORT_CONFIGURATION_INFORMATION PortConfig = DeviceExtension->PortConfig;
464  KIRQL OldIrql;
465 
466  /* Deal with interrupts */
467  if (DeviceExtension->HwInterrupt == NULL ||
468  (PortConfig->BusInterruptLevel == 0 && PortConfig->BusInterruptVector == 0))
469  {
470  /* No interrupts */
471  DeviceExtension->InterruptCount = 0;
472 
473  DPRINT1("Interrupt Count: 0\n");
474 
476 
477  /* This code path will ALWAYS crash so stop it now */
478  __debugbreak();
479  }
480  else
481  {
482  BOOLEAN InterruptShareable;
484  ULONG InterruptVector[2], i, MappedIrq[2];
485  KIRQL Dirql[2], MaxDirql;
486  KAFFINITY Affinity[2];
487 
488  DeviceExtension->InterruptLevel[0] = PortConfig->BusInterruptLevel;
489  DeviceExtension->InterruptLevel[1] = PortConfig->BusInterruptLevel2;
490 
491  InterruptVector[0] = PortConfig->BusInterruptVector;
492  InterruptVector[1] = PortConfig->BusInterruptVector2;
493 
494  InterruptMode[0] = PortConfig->InterruptMode;
495  InterruptMode[1] = PortConfig->InterruptMode2;
496 
497  DeviceExtension->InterruptCount =
498  (PortConfig->BusInterruptLevel2 != 0 ||
499  PortConfig->BusInterruptVector2 != 0) ? 2 : 1;
500 
501  for (i = 0; i < DeviceExtension->InterruptCount; i++)
502  {
503  /* Register an interrupt handler for this device */
504  MappedIrq[i] = HalGetInterruptVector(
505  PortConfig->AdapterInterfaceType, PortConfig->SystemIoBusNumber,
506  DeviceExtension->InterruptLevel[i], InterruptVector[i], &Dirql[i],
507  &Affinity[i]);
508  }
509 
510  if (DeviceExtension->InterruptCount == 1 || Dirql[0] > Dirql[1])
511  MaxDirql = Dirql[0];
512  else
513  MaxDirql = Dirql[1];
514 
515  for (i = 0; i < DeviceExtension->InterruptCount; i++)
516  {
517  /* Determine IRQ sharability as usual */
518  if (PortConfig->AdapterInterfaceType == MicroChannel ||
520  {
521  InterruptShareable = TRUE;
522  }
523  else
524  {
525  InterruptShareable = FALSE;
526  }
527 
529  &DeviceExtension->Interrupt[i], (PKSERVICE_ROUTINE)ScsiPortIsr, DeviceExtension,
530  &DeviceExtension->IrqLock, MappedIrq[i], Dirql[i], MaxDirql, InterruptMode[i],
531  InterruptShareable, Affinity[i], FALSE);
532 
533  if (!(NT_SUCCESS(Status)))
534  {
535  DPRINT1("Could not connect interrupt %d\n", InterruptVector[i]);
536  DeviceExtension->Interrupt[i] = NULL;
537  return Status;
538  }
539  }
540 
541  if (!NT_SUCCESS(Status))
542  return Status;
543  }
544 
545  /* Save IoAddress (from access ranges) */
546  if (PortConfig->NumberOfAccessRanges != 0)
547  {
548  DeviceExtension->IoAddress = ((*(PortConfig->AccessRanges))[0]).RangeStart.LowPart;
549 
550  DPRINT("Io Address %x\n", DeviceExtension->IoAddress);
551  }
552 
553  /* Set flag that it's allowed to disconnect during this command */
554  DeviceExtension->Flags |= SCSI_PORT_DISCONNECT_ALLOWED;
555 
556  /* Initialize counter of active requests (-1 means there are none) */
557  DeviceExtension->ActiveRequestCounter = -1;
558 
559  /* Analyze what we have about DMA */
560  if (DeviceExtension->AdapterObject != NULL && PortConfig->Master &&
561  PortConfig->NeedPhysicalAddresses)
562  {
563  DeviceExtension->MapRegisters = TRUE;
564  }
565  else
566  {
567  DeviceExtension->MapRegisters = FALSE;
568  }
569 
570  /* Call HwInitialize at DISPATCH_LEVEL */
572 
574  DeviceExtension->Interrupt[0], DeviceExtension->HwInitialize,
575  DeviceExtension->MiniPortDeviceExtension))
576  {
577  DPRINT1("HwInitialize() failed!\n");
580  }
581 
582  /* Check if a notification is needed */
583  if (DeviceExtension->InterruptData.Flags & SCSI_PORT_NOTIFICATION_NEEDED)
584  {
585  /* Call DPC right away, because we're already at DISPATCH_LEVEL */
586  ScsiPortDpcForIsr(NULL, DeviceExtension->DeviceObject, NULL, NULL);
587  }
588 
589  /* Lower irql back to what it was */
591 
592  return Status;
593 }
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
INTERFACE_TYPE AdapterInterfaceType
Definition: srb.h:55
_In_ PKSERVICE_ROUTINE _In_opt_ PVOID _In_opt_ PKSPIN_LOCK _In_ ULONG _In_ KIRQL _In_ KIRQL _In_ KINTERRUPT_MODE InterruptMode
Definition: iofuncs.h:798
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
KSERVICE_ROUTINE ScsiPortIsr
Definition: scsiport.h:377
#define TRUE
Definition: types.h:120
LONG NTSTATUS
Definition: precomp.h:26
ACCESS_RANGE(* AccessRanges)[]
Definition: srb.h:70
IO_DPC_ROUTINE ScsiPortDpcForIsr
Definition: scsiport.h:369
#define SCSI_PORT_NOTIFICATION_NEEDED
Definition: scsiport.h:30
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
KSERVICE_ROUTINE * PKSERVICE_ROUTINE
Definition: ketypes.h:500
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
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:22
unsigned char BOOLEAN
enum _KINTERRUPT_MODE KINTERRUPT_MODE
void DPRINT(...)
Definition: polytest.cpp:61
KINTERRUPT_MODE InterruptMode2
Definition: srb.h:97
NTHALAPI ULONG NTAPI HalGetInterruptVector(INTERFACE_TYPE, ULONG, ULONG, ULONG, PKIRQL, PKAFFINITY)
KINTERRUPT_MODE InterruptMode
Definition: srb.h:60
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG _Out_ PKIRQL _Out_ PKAFFINITY Affinity
Definition: halfuncs.h:170
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define UNIMPLEMENTED
Definition: debug.h:115
BOOLEAN NTAPI KeSynchronizeExecution(IN OUT PKINTERRUPT Interrupt, IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine, IN PVOID SynchronizeContext OPTIONAL)
Definition: interrupt.c:142
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_ADAPTER_HARDWARE_ERROR
Definition: ntstatus.h:430
#define SCSI_PORT_DISCONNECT_ALLOWED
Definition: scsiport.h:38

Referenced by ScsiPortInitialize().

◆ SpiCleanupAfterInit()

VOID SpiCleanupAfterInit ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 596 of file fdo.c.

598 {
599  PSCSI_LUN_INFO LunInfo;
600  PVOID Ptr;
601  ULONG Bus, Lun;
602 
603  /* Check if we have something to clean up */
604  if (DeviceExtension == NULL)
605  return;
606 
607  /* Stop the timer */
608  IoStopTimer(DeviceExtension->DeviceObject);
609 
610  /* Disconnect the interrupts */
611  while (DeviceExtension->InterruptCount)
612  {
613  if (DeviceExtension->Interrupt[--DeviceExtension->InterruptCount])
614  IoDisconnectInterrupt(DeviceExtension->Interrupt[DeviceExtension->InterruptCount]);
615  }
616 
617  /* Delete ConfigInfo */
618  if (DeviceExtension->BusesConfig)
619  {
620  for (Bus = 0; Bus < DeviceExtension->BusNum; Bus++)
621  {
622  if (!DeviceExtension->BusesConfig->BusScanInfo[Bus])
623  continue;
624 
625  LunInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus]->LunInfo;
626 
627  while (LunInfo)
628  {
629  /* Free current, but save pointer to the next one */
630  Ptr = LunInfo->Next;
631  ExFreePool(LunInfo);
632  LunInfo = Ptr;
633  }
634 
635  ExFreePool(DeviceExtension->BusesConfig->BusScanInfo[Bus]);
636  }
637 
638  ExFreePool(DeviceExtension->BusesConfig);
639  }
640 
641  /* Free PortConfig */
642  if (DeviceExtension->PortConfig)
643  ExFreePool(DeviceExtension->PortConfig);
644 
645  /* Free LUNs*/
646  for(Lun = 0; Lun < LUS_NUMBER; Lun++)
647  {
648  while (DeviceExtension->LunExtensionList[Lun])
649  {
650  Ptr = DeviceExtension->LunExtensionList[Lun];
651  DeviceExtension->LunExtensionList[Lun] = DeviceExtension->LunExtensionList[Lun]->Next;
652 
653  ExFreePool(Ptr);
654  }
655  }
656 
657  /* Free common buffer (if it exists) */
658  if (DeviceExtension->SrbExtensionBuffer != NULL &&
659  DeviceExtension->CommonBufferLength != 0)
660  {
661  if (!DeviceExtension->AdapterObject)
662  {
663  ExFreePool(DeviceExtension->SrbExtensionBuffer);
664  }
665  else
666  {
667  HalFreeCommonBuffer(DeviceExtension->AdapterObject,
668  DeviceExtension->CommonBufferLength,
669  DeviceExtension->PhysicalAddress,
670  DeviceExtension->SrbExtensionBuffer,
671  FALSE);
672  }
673  }
674 
675  /* Free SRB info */
676  if (DeviceExtension->SrbInfo != NULL)
677  ExFreePool(DeviceExtension->SrbInfo);
678 
679  /* Unmap mapped addresses */
680  while (DeviceExtension->MappedAddressList != NULL)
681  {
682  MmUnmapIoSpace(DeviceExtension->MappedAddressList->MappedAddress,
683  DeviceExtension->MappedAddressList->NumberOfBytes);
684 
685  Ptr = DeviceExtension->MappedAddressList;
686  DeviceExtension->MappedAddressList = DeviceExtension->MappedAddressList->NextMappedAddress;
687 
688  ExFreePool(Ptr);
689  }
690 
691  /* Finally delete the device object */
692  DPRINT("Deleting device %p\n", DeviceExtension->DeviceObject);
693  IoDeleteDevice(DeviceExtension->DeviceObject);
694 }
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define LUS_NUMBER
Definition: scsiport.h:23
#define FALSE
Definition: types.h:117
VOID NTAPI IoStopTimer(PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:166
VOID NTAPI IoDisconnectInterrupt(PKINTERRUPT InterruptObject)
Definition: irq.c:140
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
VOID NTAPI MmUnmapIoSpace(IN PVOID BaseAddress, IN SIZE_T NumberOfBytes)
Definition: iosup.c:193
#define NULL
Definition: types.h:112
struct _SCSI_LUN_INFO * Next
Definition: scsiport.h:163
unsigned int ULONG
Definition: retypes.h:1
VOID NTAPI HalFreeCommonBuffer(IN PADAPTER_OBJECT AdapterObject, IN ULONG Length, IN PHYSICAL_ADDRESS LogicalAddress, IN PVOID VirtualAddress, IN BOOLEAN CacheEnabled)
Definition: dma.c:61
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ScsiPortInitialize().

◆ SpiScanAdapter()

VOID SpiScanAdapter ( _In_ PSCSI_PORT_DEVICE_EXTENSION  DeviceExtension)

Definition at line 231 of file fdo.c.

233 {
234  PSCSI_PORT_LUN_EXTENSION LunExtension;
235  ULONG Bus;
236  ULONG Target;
237  ULONG Lun;
238  PSCSI_BUS_SCAN_INFO BusScanInfo;
239  PSCSI_LUN_INFO LastLunInfo, LunInfo, LunInfoExists;
240  BOOLEAN DeviceExists;
241  ULONG Hint;
243  ULONG DevicesFound;
244 
245  DPRINT("SpiScanAdapter() called\n");
246 
247  /* Scan all buses */
248  for (Bus = 0; Bus < DeviceExtension->BusNum; Bus++)
249  {
250  DPRINT(" Scanning bus %d\n", Bus);
251  DevicesFound = 0;
252 
253  /* Get pointer to the scan information */
254  BusScanInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus];
255 
256  if (BusScanInfo)
257  {
258  /* Find the last LUN info in the list */
259  LunInfo = DeviceExtension->BusesConfig->BusScanInfo[Bus]->LunInfo;
260  LastLunInfo = LunInfo;
261 
262  while (LunInfo != NULL)
263  {
264  LastLunInfo = LunInfo;
265  LunInfo = LunInfo->Next;
266  }
267  }
268  else
269  {
270  /* We need to allocate this buffer */
272  if (!BusScanInfo)
273  {
274  DPRINT1("Out of resources!\n");
275  return;
276  }
277 
278  /* Store the pointer in the BusScanInfo array */
279  DeviceExtension->BusesConfig->BusScanInfo[Bus] = BusScanInfo;
280 
281  /* Fill this struct (length and bus ids for now) */
282  BusScanInfo->Length = sizeof(SCSI_BUS_SCAN_INFO);
283  BusScanInfo->LogicalUnitsCount = 0;
284  BusScanInfo->BusIdentifier = DeviceExtension->PortConfig->InitiatorBusId[Bus];
285  BusScanInfo->LunInfo = NULL;
286 
287  /* Set pointer to the last LUN info to NULL */
288  LastLunInfo = NULL;
289  }
290 
291  /* Create LUN information structure */
293  if (!LunInfo)
294  {
295  DPRINT1("Out of resources!\n");
296  return;
297  }
298 
299  RtlZeroMemory(LunInfo, sizeof(SCSI_LUN_INFO));
300 
301  /* Create LunExtension */
302  LunExtension = SpiAllocateLunExtension(DeviceExtension);
303 
304  /* And send INQUIRY to every target */
305  for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
306  {
307  /* TODO: Support scan bottom-up */
308 
309  /* Skip if it's the same address */
310  if (Target == BusScanInfo->BusIdentifier)
311  continue;
312 
313  /* Try to find an existing device here */
314  DeviceExists = FALSE;
315  LunInfoExists = BusScanInfo->LunInfo;
316 
317  /* Find matching address on this bus */
318  while (LunInfoExists)
319  {
320  if (LunInfoExists->TargetId == Target)
321  {
322  DeviceExists = TRUE;
323  break;
324  }
325 
326  /* Advance to the next one */
327  LunInfoExists = LunInfoExists->Next;
328  }
329 
330  /* No need to bother rescanning, since we already did that before */
331  if (DeviceExists)
332  continue;
333 
334  /* Scan all logical units */
335  for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
336  {
337  if ((!LunExtension) || (!LunInfo))
338  break;
339 
340  /* Add extension to the list */
341  Hint = (Target + Lun) % LUS_NUMBER;
342  LunExtension->Next = DeviceExtension->LunExtensionList[Hint];
343  DeviceExtension->LunExtensionList[Hint] = LunExtension;
344 
345  /* Fill Path, Target, Lun fields */
346  LunExtension->PathId = LunInfo->PathId = (UCHAR)Bus;
347  LunExtension->TargetId = LunInfo->TargetId = (UCHAR)Target;
348  LunExtension->Lun = LunInfo->Lun = (UCHAR)Lun;
349 
350  /* Set flag to prevent race conditions */
351  LunExtension->Flags |= SCSI_PORT_SCAN_IN_PROGRESS;
352 
353  /* Zero LU extension contents */
354  if (DeviceExtension->LunExtensionSize)
355  {
356  RtlZeroMemory(LunExtension + 1,
357  DeviceExtension->LunExtensionSize);
358  }
359 
360  /* Finally send the inquiry command */
361  Status = SpiSendInquiry(DeviceExtension->DeviceObject, LunInfo);
362 
363  if (NT_SUCCESS(Status))
364  {
365  /* Let's see if we really found a device */
366  PINQUIRYDATA InquiryData = (PINQUIRYDATA)LunInfo->InquiryData;
367 
368  /* Check if this device is unsupported */
370  {
371  DeviceExtension->LunExtensionList[Hint] =
372  DeviceExtension->LunExtensionList[Hint]->Next;
373 
374  continue;
375  }
376 
377  /* Clear the "in scan" flag */
378  LunExtension->Flags &= ~SCSI_PORT_SCAN_IN_PROGRESS;
379 
380  DPRINT("SpiScanAdapter(): Found device of type %d at bus %d tid %d lun %d\n",
381  InquiryData->DeviceType, Bus, Target, Lun);
382 
383  /*
384  * Cache the inquiry data into the LUN extension (or alternatively
385  * we could save a pointer to LunInfo within the LunExtension?)
386  */
387  RtlCopyMemory(&LunExtension->InquiryData,
388  InquiryData,
390 
391  /* Add this info to the linked list */
392  LunInfo->Next = NULL;
393  if (LastLunInfo)
394  LastLunInfo->Next = LunInfo;
395  else
396  BusScanInfo->LunInfo = LunInfo;
397 
398  /* Store the last LUN info */
399  LastLunInfo = LunInfo;
400 
401  /* Store DeviceObject */
402  LunInfo->DeviceObject = DeviceExtension->DeviceObject;
403 
404  /* Allocate another buffer */
406  if (!LunInfo)
407  {
408  DPRINT1("Out of resources!\n");
409  break;
410  }
411 
412  RtlZeroMemory(LunInfo, sizeof(SCSI_LUN_INFO));
413 
414  /* Create a new LU extension */
415  LunExtension = SpiAllocateLunExtension(DeviceExtension);
416 
417  DevicesFound++;
418  }
419  else
420  {
421  /* Remove this LUN from the list */
422  DeviceExtension->LunExtensionList[Hint] =
423  DeviceExtension->LunExtensionList[Hint]->Next;
424 
425  /* Decide whether we are continuing or not */
427  continue;
428  else
429  break;
430  }
431  }
432  }
433 
434  /* Free allocated buffers */
435  if (LunExtension)
436  ExFreePoolWithTag(LunExtension, TAG_SCSIPORT);
437 
438  if (LunInfo)
440 
441  /* Sum what we found */
442  BusScanInfo->LogicalUnitsCount += (UCHAR)DevicesFound;
443  DPRINT(" Found %d devices on bus %d\n", DevicesFound, Bus);
444  }
445 
446  DPRINT("SpiScanAdapter() done\n");
447 }
PSCSI_LUN_INFO LunInfo
Definition: scsiport.h:172
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1310
#define TRUE
Definition: types.h:120
#define SCSI_MAXIMUM_LOGICAL_UNITS
Definition: srb.h:21
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_SCSIPORT
Definition: scsiport.h:20
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
PSCSI_PORT_LUN_EXTENSION SpiAllocateLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
Definition: pdo.c:16
#define SCSI_PORT_SCAN_IN_PROGRESS
Definition: scsiport.h:50
PVOID DeviceObject
Definition: scsiport.h:162
struct _INQUIRYDATA * PINQUIRYDATA
#define LUS_NUMBER
Definition: scsiport.h:23
struct _SCSI_PORT_LUN_EXTENSION * Next
Definition: scsiport.h:126
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
void DPRINT(...)
Definition: polytest.cpp:61
UCHAR DeviceTypeQualifier
Definition: cdrw_hw.h:1117
UCHAR InquiryData[INQUIRYDATABUFFERSIZE]
Definition: scsiport.h:164
Status
Definition: gdiplustypes.h:24
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
UCHAR PathId
Definition: scsiport.h:158
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
unsigned char UCHAR
Definition: xmlstorage.h:181
#define DEVICE_QUALIFIER_NOT_SUPPORTED
Definition: cdrw_hw.h:1155
UCHAR DeviceType
Definition: cdrw_hw.h:1116
INQUIRYDATA InquiryData
Definition: scsiport.h:131
UCHAR TargetId
Definition: scsiport.h:159
UCHAR LogicalUnitsCount
Definition: scsiport.h:170
#define NULL
Definition: types.h:112
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
struct _SCSI_LUN_INFO * Next
Definition: scsiport.h:163
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _SCSI_BUS_SCAN_INFO SCSI_BUS_SCAN_INFO
static NTSTATUS SpiSendInquiry(_In_ PDEVICE_OBJECT DeviceObject, _Inout_ PSCSI_LUN_INFO LunInfo)
Definition: fdo.c:17

◆ SpiSendInquiry()

static NTSTATUS SpiSendInquiry ( _In_ PDEVICE_OBJECT  DeviceObject,
_Inout_ PSCSI_LUN_INFO  LunInfo 
)
static

Definition at line 17 of file fdo.c.

20 {
22  PIO_STACK_LOCATION IrpStack;
23  KEVENT Event;
24  KIRQL Irql;
25  PIRP Irp;
27  PINQUIRYDATA InquiryBuffer;
28  PSENSE_DATA SenseBuffer;
29  BOOLEAN KeepTrying = TRUE;
30  ULONG RetryCount = 0;
32  PCDB Cdb;
33  PSCSI_PORT_LUN_EXTENSION LunExtension;
34  PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
35 
36  DPRINT("SpiSendInquiry() called\n");
37 
38  DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
39 
41  if (InquiryBuffer == NULL)
43 
45  if (SenseBuffer == NULL)
46  {
47  ExFreePoolWithTag(InquiryBuffer, TAG_SCSIPORT);
49  }
50 
51  while (KeepTrying)
52  {
53  /* Initialize event for waiting */
56  FALSE);
57 
58  /* Create an IRP */
61  NULL,
62  0,
63  InquiryBuffer,
65  TRUE,
66  &Event,
67  &IoStatusBlock);
68  if (Irp == NULL)
69  {
70  DPRINT("IoBuildDeviceIoControlRequest() failed\n");
71 
72  /* Quit the loop */
74  KeepTrying = FALSE;
75  continue;
76  }
77 
78  /* Prepare SRB */
80 
81  Srb.Length = sizeof(SCSI_REQUEST_BLOCK);
82  Srb.OriginalRequest = Irp;
83  Srb.PathId = LunInfo->PathId;
84  Srb.TargetId = LunInfo->TargetId;
85  Srb.Lun = LunInfo->Lun;
86  Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
88  Srb.TimeOutValue = 4;
89  Srb.CdbLength = 6;
90 
91  Srb.SenseInfoBuffer = SenseBuffer;
92  Srb.SenseInfoBufferLength = SENSE_BUFFER_SIZE;
93 
94  Srb.DataBuffer = InquiryBuffer;
95  Srb.DataTransferLength = INQUIRYDATABUFFERSIZE;
96 
97  /* Attach Srb to the Irp */
98  IrpStack = IoGetNextIrpStackLocation (Irp);
99  IrpStack->Parameters.Scsi.Srb = &Srb;
100 
101  /* Fill in CDB */
102  Cdb = (PCDB)Srb.Cdb;
103  Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
104  Cdb->CDB6INQUIRY.LogicalUnitNumber = LunInfo->Lun;
105  Cdb->CDB6INQUIRY.AllocationLength = INQUIRYDATABUFFERSIZE;
106 
107  /* Call the driver */
109 
110  /* Wait for it to complete */
111  if (Status == STATUS_PENDING)
112  {
113  DPRINT("SpiSendInquiry(): Waiting for the driver to process request...\n");
115  Executive,
116  KernelMode,
117  FALSE,
118  NULL);
120  }
121 
122  DPRINT("SpiSendInquiry(): Request processed by driver, status = 0x%08X\n", Status);
123 
124  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_SUCCESS)
125  {
126  /* All fine, copy data over */
127  RtlCopyMemory(LunInfo->InquiryData,
128  InquiryBuffer,
130 
131  /* Quit the loop */
133  KeepTrying = FALSE;
134  continue;
135  }
136 
137  DPRINT("Inquiry SRB failed with SrbStatus 0x%08X\n", Srb.SrbStatus);
138 
139  /* Check if the queue is frozen */
140  if (Srb.SrbStatus & SRB_STATUS_QUEUE_FROZEN)
141  {
142  /* Something weird happened, deal with it (unfreeze the queue) */
143  KeepTrying = FALSE;
144 
145  DPRINT("SpiSendInquiry(): the queue is frozen at TargetId %d\n", Srb.TargetId);
146 
147  LunExtension = SpiGetLunExtension(DeviceExtension,
148  LunInfo->PathId,
149  LunInfo->TargetId,
150  LunInfo->Lun);
151 
152  /* Clear frozen flag */
153  LunExtension->Flags &= ~LUNEX_FROZEN_QUEUE;
154 
155  /* Acquire the spinlock */
156  KeAcquireSpinLock(&DeviceExtension->SpinLock, &Irql);
157 
158  /* Process the request */
159  SpiGetNextRequestFromLun(DeviceObject->DeviceExtension, LunExtension);
160 
161  /* SpiGetNextRequestFromLun() releases the spinlock,
162  so we just lower irql back to what it was before */
163  KeLowerIrql(Irql);
164  }
165 
166  /* Check if data overrun happened */
167  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN)
168  {
169  DPRINT("Data overrun at TargetId %d\n", LunInfo->TargetId);
170 
171  /* Nothing dramatic, just copy data, but limiting the size */
172  RtlCopyMemory(LunInfo->InquiryData,
173  InquiryBuffer,
174  (Srb.DataTransferLength > INQUIRYDATABUFFERSIZE) ?
175  INQUIRYDATABUFFERSIZE : Srb.DataTransferLength);
176 
177  /* Quit the loop */
179  KeepTrying = FALSE;
180  }
181  else if ((Srb.SrbStatus & SRB_STATUS_AUTOSENSE_VALID) &&
182  SenseBuffer->SenseKey == SCSI_SENSE_ILLEGAL_REQUEST)
183  {
184  /* LUN is not valid, but some device responds there.
185  Mark it as invalid anyway */
186 
187  /* Quit the loop */
189  KeepTrying = FALSE;
190  }
191  else
192  {
193  /* Retry a couple of times if no timeout happened */
194  if ((RetryCount < 2) &&
195  (SRB_STATUS(Srb.SrbStatus) != SRB_STATUS_NO_DEVICE) &&
197  {
198  RetryCount++;
199  KeepTrying = TRUE;
200  }
201  else
202  {
203  /* That's all, quit the loop */
204  KeepTrying = FALSE;
205 
206  /* Set status according to SRB status */
207  if (SRB_STATUS(Srb.SrbStatus) == SRB_STATUS_BAD_FUNCTION ||
209  {
211  }
212  else
213  {
215  }
216  }
217  }
218  }
219 
220  /* Free buffers */
221  ExFreePoolWithTag(InquiryBuffer, TAG_SCSIPORT);
222  ExFreePoolWithTag(SenseBuffer, TAG_SCSIPORT);
223 
224  DPRINT("SpiSendInquiry() done with Status 0x%08X\n", Status);
225 
226  return Status;
227 }
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
#define TRUE
Definition: types.h:120
PSCSI_PORT_LUN_EXTENSION SpiGetLunExtension(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _In_ UCHAR PathId, _In_ UCHAR TargetId, _In_ UCHAR Lun)
Definition: pdo.c:57
struct SCSI_PORT_DEVICE_EXTENSION * PSCSI_PORT_DEVICE_EXTENSION
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define TAG_SCSIPORT
Definition: scsiport.h:20
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
VOID SpiGetNextRequestFromLun(_In_ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, _Inout_ PSCSI_PORT_LUN_EXTENSION LunExtension)
Definition: scsi.c:372
#define SRB_STATUS_BAD_SRB_BLOCK_LENGTH
Definition: srb.h:352
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
_Out_ PKIRQL Irql
Definition: csq.h:179
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
UCHAR KIRQL
Definition: env_spec_w32.h:591
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define FALSE
Definition: types.h:117
_In_ PIRP Irp
Definition: csq.h:116
_In_ PVOID _In_ ULONG Event
Definition: iotypes.h:450
unsigned char BOOLEAN
#define INQUIRYDATABUFFERSIZE
Definition: cdrw_hw.h:1113
union _CDB * PCDB
void DPRINT(...)
Definition: polytest.cpp:61
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
Status
Definition: gdiplustypes.h:24
#define SRB_STATUS_BAD_FUNCTION
Definition: srb.h:356
#define STATUS_PENDING
Definition: ntstatus.h:82
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:156
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
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:881
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_SUCCESS
Definition: shellext.h:65
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
struct _CDB::_CDB6INQUIRY CDB6INQUIRY
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
#define LUNEX_FROZEN_QUEUE
Definition: scsiport.h:45

Referenced by SpiScanAdapter().