mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 20:27:55 +00:00
- Implemented ScsiPortCompleteRequest.
- Fixed the calculation of the max transfer size. - Rewrote parts of SpiScanAdapter and SpiSendInquiry to speed up device detection. - Fixed the handling of sense info data for HBA's which are auto request sense capability. - Added some more debug messages. svn path=/trunk/; revision=9641
This commit is contained in:
parent
5dabb7db10
commit
da9b36f495
4 changed files with 461 additions and 211 deletions
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.6 2003/11/13 14:20:03 ekohl Exp $
|
||||
# $Id: makefile,v 1.7 2004/06/07 16:37:07 hbirr Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
|
@ -12,6 +12,11 @@ TARGET_OBJECTS = $(TARGET_NAME).o
|
|||
|
||||
TARGET_CFLAGS = -Werror -Wall
|
||||
|
||||
DEP_OBJECTS = $(TARGET_OBJECTS)
|
||||
|
||||
include $(PATH_TO_TOP)/rules.mak
|
||||
|
||||
include $(TOOLS_PATH)/helper.mk
|
||||
|
||||
include $(TOOLS_PATH)/depend.mk
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: scsiport.c,v 1.57 2004/05/24 20:33:41 hbirr Exp $
|
||||
/* $Id: scsiport.c,v 1.58 2004/06/07 16:37:07 hbirr Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -37,9 +37,6 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
#define VERSION "0.0.1"
|
||||
|
||||
#include "scsiport_int.h"
|
||||
|
||||
/* TYPES *********************************************************************/
|
||||
|
@ -99,7 +96,9 @@ SpiGetLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
|
||||
static NTSTATUS
|
||||
SpiSendInquiry (IN PDEVICE_OBJECT DeviceObject,
|
||||
IN OUT PSCSI_REQUEST_BLOCK Srb);
|
||||
IN OUT PSCSI_REQUEST_BLOCK Srb,
|
||||
IN OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN OUT PKEVENT Event);
|
||||
|
||||
static VOID
|
||||
SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension);
|
||||
|
@ -113,10 +112,10 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
|
|||
IN PVOID ServiceContext);
|
||||
|
||||
static VOID STDCALL
|
||||
ScsiPortDpcForIsr(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext);
|
||||
ScsiPortDpc(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext);
|
||||
|
||||
static VOID STDCALL
|
||||
ScsiPortIoTimer(PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -227,8 +226,49 @@ ScsiPortCompleteRequest(IN PVOID HwDeviceExtension,
|
|||
IN UCHAR Lun,
|
||||
IN UCHAR SrbStatus)
|
||||
{
|
||||
DPRINT("ScsiPortCompleteRequest()\n");
|
||||
UNIMPLEMENTED;
|
||||
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
PLIST_ENTRY Entry;
|
||||
PIRP Irp;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
|
||||
DPRINT("ScsiPortCompleteRequest(HwDeviceExtension %x, PathId %d, TargetId %d, Lun %d, SrbStatus %x)\n",
|
||||
HwDeviceExtension, PathId, TargetId, Lun, SrbStatus);
|
||||
|
||||
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
|
||||
SCSI_PORT_DEVICE_EXTENSION,
|
||||
MiniPortDeviceExtension);
|
||||
|
||||
Entry = DeviceExtension->LunExtensionListHead.Flink;
|
||||
while (Entry != &DeviceExtension->LunExtensionListHead)
|
||||
{
|
||||
LunExtension = CONTAINING_RECORD(Entry,
|
||||
SCSI_PORT_LUN_EXTENSION,
|
||||
List);
|
||||
|
||||
|
||||
|
||||
if (PathId == (UCHAR)SP_UNTAGGED ||
|
||||
(PathId == LunExtension->PathId && TargetId == (UCHAR)SP_UNTAGGED) ||
|
||||
(PathId == LunExtension->PathId && TargetId == LunExtension->TargetId && Lun == (UCHAR)SP_UNTAGGED) ||
|
||||
(PathId == LunExtension->PathId && TargetId == LunExtension->TargetId && Lun == LunExtension->Lun))
|
||||
{
|
||||
Irp = LunExtension->NextIrp;
|
||||
while (Irp)
|
||||
{
|
||||
Srb = (PSCSI_REQUEST_BLOCK)Irp->Tail.Overlay.DriverContext[3];
|
||||
if (Srb->SrbStatus & SRB_FLAGS_IS_ACTIVE)
|
||||
{
|
||||
Srb->SrbStatus = SrbStatus;
|
||||
ScsiPortNotification(RequestComplete,
|
||||
HwDeviceExtension,
|
||||
Srb);
|
||||
}
|
||||
Irp = Irp->Tail.Overlay.DriverContext[1];
|
||||
}
|
||||
}
|
||||
Entry = Entry->Flink;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -518,7 +558,7 @@ ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension,
|
|||
* @unimplemented
|
||||
*/
|
||||
PSCSI_REQUEST_BLOCK STDCALL
|
||||
ScsiPortGetSrb(IN PVOID DeviceExtension,
|
||||
ScsiPortGetSrb(IN PVOID HwDeviceExtension,
|
||||
IN UCHAR PathId,
|
||||
IN UCHAR TargetId,
|
||||
IN UCHAR Lun,
|
||||
|
@ -696,7 +736,33 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
|
||||
|
||||
DPRINT ("ScsiPortInitialize() called!\n");
|
||||
|
||||
#if 0
|
||||
DPRINT1("HwInitializationDataSize: %d\n", HwInitializationData->HwInitializationDataSize);
|
||||
DPRINT1("AdapterInterfaceType: %d\n", HwInitializationData->AdapterInterfaceType);
|
||||
DPRINT1("HwInitialize: %x\n", HwInitializationData->HwInitialize);
|
||||
DPRINT1("HwStartIo: %x\n", HwInitializationData->HwStartIo);
|
||||
DPRINT1("HwInterrupt: %x\n", HwInitializationData->HwInterrupt);
|
||||
DPRINT1("HwFindAdapter: %x\n", HwInitializationData->HwFindAdapter);
|
||||
DPRINT1("HwResetBus: %x\n", HwInitializationData->HwResetBus);
|
||||
DPRINT1("HwDmaStarted: %x\n", HwInitializationData->HwDmaStarted);
|
||||
DPRINT1("HwAdapterState: %x\n", HwInitializationData->HwAdapterState);
|
||||
DPRINT1("DeviceExtensionSize: %d\n", HwInitializationData->DeviceExtensionSize);
|
||||
DPRINT1("SpecificLuExtensionSize: %d\n", HwInitializationData->SpecificLuExtensionSize);
|
||||
DPRINT1("SrbExtensionSize: %d\n", HwInitializationData->SrbExtensionSize);
|
||||
DPRINT1("NumberOfAccessRanges: %d\n", HwInitializationData->NumberOfAccessRanges);
|
||||
DPRINT1("Reserved: %x\n", HwInitializationData->Reserved);
|
||||
DPRINT1("MapBuffers: %d\n", HwInitializationData->MapBuffers);
|
||||
DPRINT1("NeedPhysicalAddresses: %d\n", HwInitializationData->NeedPhysicalAddresses);
|
||||
DPRINT1("TaggedQueueing: %d\n", HwInitializationData->TaggedQueueing);
|
||||
DPRINT1("AutoRequestSense: %d\n", HwInitializationData->AutoRequestSense);
|
||||
DPRINT1("MultipleRequestPerLu: %d\n", HwInitializationData->MultipleRequestPerLu);
|
||||
DPRINT1("ReceiveEvent: %d\n", HwInitializationData->ReceiveEvent);
|
||||
DPRINT1("VendorIdLength: %d\n", HwInitializationData->VendorIdLength);
|
||||
DPRINT1("VendorId: %x\n", HwInitializationData->VendorId);
|
||||
DPRINT1("ReservedUshort: %d\n", HwInitializationData->ReservedUshort);
|
||||
DPRINT1("DeviceIdLength: %d\n", HwInitializationData->DeviceIdLength);
|
||||
DPRINT1("DeviceId: %x\n", HwInitializationData->DeviceId);
|
||||
#endif
|
||||
if ((HwInitializationData->HwInitialize == NULL) ||
|
||||
(HwInitializationData->HwStartIo == NULL) ||
|
||||
(HwInitializationData->HwInterrupt == NULL) ||
|
||||
|
@ -779,7 +845,7 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
|
||||
/* Initialize the irp lists */
|
||||
InitializeListHead (&DeviceExtension->PendingIrpListHead);
|
||||
InitializeListHead (&DeviceExtension->ActiveIrpListHead);
|
||||
DeviceExtension->NextIrp = NULL;
|
||||
DeviceExtension->PendingIrpCount = 0;
|
||||
DeviceExtension->ActiveIrpCount = 0;
|
||||
|
||||
|
@ -787,12 +853,11 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
InitializeListHead (&DeviceExtension->LunExtensionListHead);
|
||||
|
||||
/* Initialize the spin lock in the controller extension */
|
||||
KeInitializeSpinLock (&DeviceExtension->IrpLock);
|
||||
KeInitializeSpinLock (&DeviceExtension->SpinLock);
|
||||
KeInitializeSpinLock (&DeviceExtension->Lock);
|
||||
|
||||
/* Initialize the DPC object */
|
||||
IoInitializeDpcRequest (PortDeviceObject,
|
||||
ScsiPortDpcForIsr);
|
||||
ScsiPortDpc);
|
||||
|
||||
/* Initialize the device timer */
|
||||
DeviceExtension->TimerState = IDETimerIdle;
|
||||
|
@ -853,8 +918,6 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
PortConfig->SrbExtensionSize = HwInitializationData->SrbExtensionSize;
|
||||
PortConfig->SpecificLuExtensionSize = HwInitializationData->SpecificLuExtensionSize;
|
||||
|
||||
PortConfig->SlotNumber = SlotNumber.u.AsULONG;
|
||||
|
||||
PortConfig->AccessRanges = (PACCESS_RANGE)(PortConfig + 1);
|
||||
|
||||
/* Search for matching PCI device */
|
||||
|
@ -897,6 +960,51 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
{
|
||||
DPRINT("ScsiPortInitialize(): Found HBA! (%x)\n", PortConfig->BusInterruptVector);
|
||||
|
||||
#if 0
|
||||
DPRINT1("SystemIoBusNumber: %x\n", PortConfig->SystemIoBusNumber);
|
||||
DPRINT1("AdapterInterfaceType: %x\n", PortConfig->AdapterInterfaceType);
|
||||
DPRINT1("BusInterruptLevel: %x\n", PortConfig->BusInterruptLevel);
|
||||
DPRINT1("BusInterruptVector: %x\n", PortConfig->BusInterruptVector);
|
||||
DPRINT1("InterruptMode: %x\n", PortConfig->InterruptMode);
|
||||
DPRINT1("MaximumTransferLength: %x\n", PortConfig->MaximumTransferLength);
|
||||
DPRINT1("NumberOfPhysicalBreaks: %x\n", PortConfig->NumberOfPhysicalBreaks);
|
||||
DPRINT1("DmaChannel: %x\n", PortConfig->DmaChannel);
|
||||
DPRINT1("DmaPort: %d\n", PortConfig->DmaPort);
|
||||
DPRINT1("DmaWidth: %d\n", PortConfig->DmaWidth);
|
||||
DPRINT1("DmaSpeed: %d\n", PortConfig->DmaSpeed);
|
||||
DPRINT1("AlignmentMask: %d\n", PortConfig->AlignmentMask);
|
||||
DPRINT1("NumberOfAccessRanges: %d\n", PortConfig->NumberOfAccessRanges);
|
||||
DPRINT1("NumberOfBuses: %d\n", PortConfig->NumberOfBuses);
|
||||
DPRINT1("ScatterGather: %d\n", PortConfig->ScatterGather);
|
||||
DPRINT1("Master: %d\n", PortConfig->Master);
|
||||
DPRINT1("CachesData: %d\n", PortConfig->CachesData);
|
||||
DPRINT1("AdapterScansDown: %d\n", PortConfig->AdapterScansDown);
|
||||
DPRINT1("AtdiskPrimaryClaimed: %d\n", PortConfig->AtdiskPrimaryClaimed);
|
||||
DPRINT1("AtdiskSecondaryClaimed: %d\n", PortConfig->AtdiskSecondaryClaimed);
|
||||
DPRINT1("Dma32BitAddresses: %d\n", PortConfig->Dma32BitAddresses);
|
||||
DPRINT1("DemandMode: %d\n", PortConfig->DemandMode);
|
||||
DPRINT1("MapBuffers: %d\n", PortConfig->MapBuffers);
|
||||
DPRINT1("NeedPhysicalAddresses: %d\n", PortConfig->NeedPhysicalAddresses);
|
||||
DPRINT1("TaggedQueuing: %d\n", PortConfig->TaggedQueuing);
|
||||
DPRINT1("AutoRequestSense: %d\n", PortConfig->AutoRequestSense);
|
||||
DPRINT1("MultipleRequestPerLu: %d\n", PortConfig->MultipleRequestPerLu);
|
||||
DPRINT1("ReceiveEvent: %d\n", PortConfig->ReceiveEvent);
|
||||
DPRINT1("RealModeInitialized: %d\n", PortConfig->RealModeInitialized);
|
||||
DPRINT1("BufferAccessScsiPortControlled: %d\n", PortConfig->BufferAccessScsiPortControlled);
|
||||
DPRINT1("MaximumNumberOfTargets: %d\n", PortConfig->MaximumNumberOfTargets);
|
||||
DPRINT1("SlotNumber: %d\n", PortConfig->SlotNumber);
|
||||
DPRINT1("BusInterruptLevel2: %x\n", PortConfig->BusInterruptLevel2);
|
||||
DPRINT1("BusInterruptVector2: %x\n", PortConfig->BusInterruptVector2);
|
||||
DPRINT1("InterruptMode2: %x\n", PortConfig->InterruptMode2);
|
||||
DPRINT1("DmaChannel2: %d\n", PortConfig->DmaChannel2);
|
||||
DPRINT1("DmaPort2: %d\n", PortConfig->DmaPort2);
|
||||
DPRINT1("DmaWidth2: %d\n", PortConfig->DmaWidth2);
|
||||
DPRINT1("DmaSpeed2: %d\n", PortConfig->DmaSpeed2);
|
||||
DPRINT1("DeviceExtensionSize: %d\n", PortConfig->DeviceExtensionSize);
|
||||
DPRINT1("SpecificLuExtensionSize: %d\n", PortConfig->SpecificLuExtensionSize);
|
||||
DPRINT1("SrbExtensionSize: %d\n", PortConfig->SrbExtensionSize);
|
||||
|
||||
#endif
|
||||
|
||||
if (DeviceExtension->VirtualAddress == NULL && DeviceExtension->SrbExtensionSize)
|
||||
{
|
||||
|
@ -929,7 +1037,7 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
|
||||
ScsiPortIsr,
|
||||
DeviceExtension,
|
||||
&DeviceExtension->SpinLock,
|
||||
NULL,
|
||||
MappedIrq,
|
||||
Dirql,
|
||||
Dirql,
|
||||
|
@ -963,8 +1071,19 @@ ScsiPortInitialize(IN PVOID Argument1,
|
|||
|
||||
PortCapabilities = DeviceExtension->PortCapabilities;
|
||||
PortCapabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
|
||||
PortCapabilities->MaximumTransferLength =
|
||||
PortConfig->MaximumTransferLength;
|
||||
if (PortConfig->ScatterGather == FALSE ||
|
||||
PortConfig->NumberOfPhysicalBreaks >= (0x100000000LL >> PAGE_SHIFT) ||
|
||||
PortConfig->MaximumTransferLength < PortConfig->NumberOfPhysicalBreaks * PAGE_SIZE)
|
||||
{
|
||||
PortCapabilities->MaximumTransferLength =
|
||||
PortConfig->MaximumTransferLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
PortCapabilities->MaximumTransferLength =
|
||||
PortConfig->NumberOfPhysicalBreaks * PAGE_SIZE;
|
||||
}
|
||||
|
||||
PortCapabilities->MaximumPhysicalPages =
|
||||
PortCapabilities->MaximumTransferLength / PAGE_SIZE;
|
||||
PortCapabilities->SupportedAsynchronousEvents = 0; /* FIXME */
|
||||
|
@ -1137,7 +1256,7 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
|||
Srb = (PSCSI_REQUEST_BLOCK) va_arg (ap, PSCSI_REQUEST_BLOCK);
|
||||
|
||||
DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
|
||||
DeviceExtension->IrpFlags |= IRP_FLAG_COMPLETE;
|
||||
DeviceExtension->Flags |= IRP_FLAG_COMPLETE;
|
||||
Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
|
||||
InterlockedIncrement((PLONG)&DeviceExtension->CompleteRequestCount);
|
||||
}
|
||||
|
@ -1145,7 +1264,7 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
|||
|
||||
case NextRequest:
|
||||
DPRINT("Notify: NextRequest\n");
|
||||
DeviceExtension->IrpFlags |= IRP_FLAG_NEXT;
|
||||
DeviceExtension->Flags |= IRP_FLAG_NEXT;
|
||||
InterlockedIncrement((PLONG)&DeviceExtension->NextRequestCount);
|
||||
break;
|
||||
|
||||
|
@ -1169,7 +1288,7 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
|||
Lun);
|
||||
if (LunExtension)
|
||||
{
|
||||
DeviceExtension->IrpFlags |= IRP_FLAG_NEXT_LU;
|
||||
DeviceExtension->Flags |= IRP_FLAG_NEXT_LU;
|
||||
InterlockedIncrement((PLONG)&LunExtension->NextLuRequestCount);
|
||||
InterlockedIncrement((PLONG)&DeviceExtension->NextLuRequestCount);
|
||||
}
|
||||
|
@ -1185,6 +1304,16 @@ ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
|
|||
DPRINT1 ("Unsupported notification %lu\n", NotificationType);
|
||||
break;
|
||||
}
|
||||
if (KeGetCurrentIrql() >= DISPATCH_LEVEL)
|
||||
{
|
||||
IoRequestDpc(DeviceExtension->DeviceObject,
|
||||
NULL,
|
||||
DeviceExtension);
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiProcessRequests(DeviceExtension, NULL);
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
@ -1353,7 +1482,11 @@ SpiGetPciConfigData (IN struct _HW_INITIALIZATION_DATA *HwInitializationData,
|
|||
}
|
||||
|
||||
NextSlotNumber->u.bits.DeviceNumber = DeviceNumber;
|
||||
NextSlotNumber->u.bits.FunctionNumber = FunctionNumber + 1;
|
||||
NextSlotNumber->u.bits.FunctionNumber = FunctionNumber;
|
||||
|
||||
PortConfig->SlotNumber = NextSlotNumber->u.AsULONG;
|
||||
|
||||
NextSlotNumber->u.bits.FunctionNumber += 1;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -1718,6 +1851,8 @@ SpiAllocateLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
LunExtension->PendingIrpCount = 0;
|
||||
LunExtension->ActiveIrpCount = 0;
|
||||
|
||||
LunExtension->NextIrp = NULL;
|
||||
|
||||
return LunExtension;
|
||||
}
|
||||
|
||||
|
@ -1780,20 +1915,16 @@ SpiGetLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
|
||||
static NTSTATUS
|
||||
SpiSendInquiry (IN PDEVICE_OBJECT DeviceObject,
|
||||
IN OUT PSCSI_REQUEST_BLOCK Srb)
|
||||
IN OUT PSCSI_REQUEST_BLOCK Srb,
|
||||
IN OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN OUT PKEVENT Event)
|
||||
{
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
PIO_STACK_LOCATION IrpStack;
|
||||
PKEVENT Event;
|
||||
PIRP Irp;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT ("SpiSendInquiry() called\n");
|
||||
|
||||
Event = ExAllocatePool (NonPagedPool,
|
||||
sizeof(KEVENT));
|
||||
if (Event == NULL)
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
KeInitializeEvent (Event,
|
||||
NotificationEvent,
|
||||
|
@ -1807,11 +1938,10 @@ SpiSendInquiry (IN PDEVICE_OBJECT DeviceObject,
|
|||
Srb->DataTransferLength,
|
||||
TRUE,
|
||||
Event,
|
||||
&IoStatusBlock);
|
||||
IoStatusBlock);
|
||||
if (Irp == NULL)
|
||||
{
|
||||
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
|
||||
ExFreePool (Event);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
|
@ -1823,102 +1953,152 @@ SpiSendInquiry (IN PDEVICE_OBJECT DeviceObject,
|
|||
/* Call the driver */
|
||||
Status = IoCallDriver (DeviceObject,
|
||||
Irp);
|
||||
if (Status == STATUS_PENDING)
|
||||
{
|
||||
KeWaitForSingleObject (Event,
|
||||
Suspended,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
Status = IoStatusBlock.Status;
|
||||
}
|
||||
|
||||
ExFreePool (Event);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
SpiScanAdapter (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
|
||||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
SCSI_REQUEST_BLOCK Srb;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
PCDB Cdb;
|
||||
ULONG Bus;
|
||||
ULONG Target;
|
||||
ULONG Lun;
|
||||
PVOID DataBuffer;
|
||||
NTSTATUS Status;
|
||||
|
||||
PSCSI_PORT_SCAN_ADAPTER ScanDataArray;
|
||||
PSCSI_PORT_SCAN_ADAPTER ScanData;
|
||||
ULONG i;
|
||||
ULONG MaxCount;
|
||||
ULONG WaitCount;
|
||||
ULONG ActiveCount;
|
||||
PVOID* EventArray;
|
||||
PKWAIT_BLOCK WaitBlockArray;
|
||||
|
||||
DPRINT ("SpiScanAdapter() called\n");
|
||||
|
||||
DataBuffer = ExAllocatePool(NonPagedPool, 256);
|
||||
MaxCount = DeviceExtension->PortConfig->NumberOfBuses *
|
||||
DeviceExtension->PortConfig->MaximumNumberOfTargets;
|
||||
|
||||
ScanDataArray = ExAllocatePool(NonPagedPool, MaxCount * (sizeof(SCSI_PORT_SCAN_ADAPTER) + sizeof(PVOID) + sizeof(KWAIT_BLOCK)));
|
||||
if (ScanDataArray == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
EventArray = (PVOID*)((PUCHAR)ScanDataArray + MaxCount * sizeof(SCSI_PORT_SCAN_ADAPTER));
|
||||
WaitBlockArray = (PKWAIT_BLOCK)((PUCHAR)EventArray + MaxCount * sizeof(PVOID));
|
||||
|
||||
for (Bus = 0; Bus < DeviceExtension->PortConfig->NumberOfBuses; Bus++)
|
||||
{
|
||||
for (Target = 0; Target < DeviceExtension->PortConfig->MaximumNumberOfTargets; Target++)
|
||||
{
|
||||
for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
|
||||
{
|
||||
RtlZeroMemory(&Srb,
|
||||
sizeof(SCSI_REQUEST_BLOCK));
|
||||
Srb.SrbFlags = SRB_FLAGS_DATA_IN;
|
||||
Srb.DataBuffer = DataBuffer;
|
||||
Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
|
||||
Srb.DataTransferLength = 255; //256;
|
||||
Srb.CdbLength = 6;
|
||||
Srb.Lun = Lun;
|
||||
Srb.PathId = Bus;
|
||||
Srb.TargetId = Target;
|
||||
Srb.SrbStatus = SRB_STATUS_SUCCESS;
|
||||
|
||||
Cdb = (PCDB) &Srb.Cdb;
|
||||
|
||||
Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
|
||||
Cdb->CDB6INQUIRY.AllocationLength = 255;
|
||||
Cdb->CDB6INQUIRY.LogicalUnitNumber = Lun;
|
||||
|
||||
RtlZeroMemory(Srb.DataBuffer, 256);
|
||||
|
||||
LunExtension = SpiAllocateLunExtension (DeviceExtension,
|
||||
Bus,
|
||||
Target,
|
||||
Lun);
|
||||
if (LunExtension == NULL)
|
||||
{
|
||||
DPRINT("Failed to allocate the LUN extension!\n");
|
||||
ExFreePool(DataBuffer);
|
||||
return;
|
||||
}
|
||||
|
||||
Status = SpiSendInquiry (DeviceExtension->DeviceObject,
|
||||
&Srb);
|
||||
DPRINT ("Target %lu Lun %lu", Target, Lun);
|
||||
DPRINT ("Status %lx Srb.SrbStatus %x\n", Status, Srb.SrbStatus);
|
||||
DPRINT ("DeviceTypeQualifier %x\n", ((PINQUIRYDATA)Srb.DataBuffer)->DeviceTypeQualifier);
|
||||
|
||||
if (NT_SUCCESS(Status) &&
|
||||
(Srb.SrbStatus == SRB_STATUS_SUCCESS ||
|
||||
Srb.SrbStatus == SRB_STATUS_DATA_OVERRUN) &&
|
||||
((PINQUIRYDATA)Srb.DataBuffer)->DeviceTypeQualifier == 0)
|
||||
{
|
||||
/* Copy inquiry data */
|
||||
RtlCopyMemory (&LunExtension->InquiryData,
|
||||
Srb.DataBuffer,
|
||||
sizeof(INQUIRYDATA));
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiRemoveLunExtension (LunExtension);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ScanData = &ScanDataArray[Bus * DeviceExtension->PortConfig->MaximumNumberOfTargets + Target];
|
||||
ScanData->Bus = Bus;
|
||||
ScanData->Target = Target;
|
||||
ScanData->Lun = 0;
|
||||
ScanData->Active = FALSE;
|
||||
}
|
||||
}
|
||||
do
|
||||
{
|
||||
ActiveCount = 0;
|
||||
WaitCount = 0;
|
||||
for (i = 0; i < MaxCount; i++)
|
||||
{
|
||||
ScanData = &ScanDataArray[i];
|
||||
Srb = &ScanData->Srb;
|
||||
if (ScanData->Active)
|
||||
{
|
||||
if (ScanData->Status == STATUS_PENDING &&
|
||||
0 == KeReadStateEvent(&ScanData->Event))
|
||||
{
|
||||
ActiveCount++;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScanData->Status = ScanData->IoStatusBlock.Status;
|
||||
}
|
||||
ScanData->Active = FALSE;
|
||||
DPRINT ("Target %lu Lun %lu\n", ScanData->Target, ScanData->Lun);
|
||||
DPRINT ("Status %lx Srb.SrbStatus %x\n", ScanData->Status, Srb->SrbStatus);
|
||||
DPRINT ("DeviceTypeQualifier %x\n", ((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier);
|
||||
|
||||
ExFreePool(DataBuffer);
|
||||
if (NT_SUCCESS(ScanData->Status) &&
|
||||
(Srb->SrbStatus == SRB_STATUS_SUCCESS ||
|
||||
Srb->SrbStatus == SRB_STATUS_DATA_OVERRUN) &&
|
||||
((PINQUIRYDATA)Srb->DataBuffer)->DeviceTypeQualifier == 0)
|
||||
{
|
||||
/* Copy inquiry data */
|
||||
RtlCopyMemory (&ScanData->LunExtension->InquiryData,
|
||||
Srb->DataBuffer,
|
||||
sizeof(INQUIRYDATA));
|
||||
ScanData->Lun++;
|
||||
}
|
||||
else
|
||||
{
|
||||
SpiRemoveLunExtension (ScanData->LunExtension);
|
||||
ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS;
|
||||
}
|
||||
}
|
||||
if (ScanData->Lun >= SCSI_MAXIMUM_LOGICAL_UNITS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
RtlZeroMemory(Srb, sizeof(SCSI_REQUEST_BLOCK));
|
||||
Srb->SrbFlags = SRB_FLAGS_DATA_IN;
|
||||
Srb->DataBuffer = ScanData->DataBuffer;
|
||||
Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
|
||||
Srb->DataTransferLength = 255; //256;
|
||||
Srb->CdbLength = 6;
|
||||
Srb->Lun = ScanData->Lun;
|
||||
Srb->PathId = ScanData->Bus;
|
||||
Srb->TargetId = ScanData->Target;
|
||||
Srb->SrbStatus = SRB_STATUS_SUCCESS;
|
||||
Cdb = (PCDB) &Srb->Cdb;
|
||||
|
||||
Cdb->CDB6INQUIRY.OperationCode = SCSIOP_INQUIRY;
|
||||
Cdb->CDB6INQUIRY.AllocationLength = 255;
|
||||
Cdb->CDB6INQUIRY.LogicalUnitNumber = ScanData->Lun;
|
||||
|
||||
RtlZeroMemory(Srb->DataBuffer, 256);
|
||||
|
||||
ScanData->LunExtension = SpiAllocateLunExtension (DeviceExtension,
|
||||
ScanData->Bus,
|
||||
ScanData->Target,
|
||||
ScanData->Lun);
|
||||
if (ScanData->LunExtension == NULL)
|
||||
{
|
||||
DPRINT1("Failed to allocate the LUN extension!\n");
|
||||
ScanData->Lun = SCSI_MAXIMUM_LOGICAL_UNITS;
|
||||
continue;
|
||||
}
|
||||
ScanData->Status = SpiSendInquiry (DeviceExtension->DeviceObject,
|
||||
Srb,
|
||||
&ScanData->IoStatusBlock,
|
||||
&ScanData->Event);
|
||||
ScanData->Active = TRUE;
|
||||
ActiveCount++;
|
||||
if (ScanData->Status == STATUS_PENDING)
|
||||
{
|
||||
EventArray[WaitCount] = &ScanData->Event;
|
||||
WaitCount++;
|
||||
}
|
||||
}
|
||||
if (WaitCount > 0 && WaitCount == ActiveCount)
|
||||
{
|
||||
KeWaitForMultipleObjects(WaitCount,
|
||||
EventArray,
|
||||
WaitAny,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL,
|
||||
WaitBlockArray);
|
||||
}
|
||||
}
|
||||
while (ActiveCount > 0);
|
||||
|
||||
ExFreePool(ScanDataArray);
|
||||
|
||||
DPRINT ("SpiScanAdapter() done\n");
|
||||
}
|
||||
|
||||
|
@ -2003,30 +2183,16 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
|
|||
IN PVOID ServiceContext)
|
||||
{
|
||||
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
BOOLEAN Result;
|
||||
|
||||
DPRINT("ScsiPortIsr() called!\n");
|
||||
|
||||
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)ServiceContext;
|
||||
|
||||
Result = DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
|
||||
if (Result == FALSE)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (DeviceExtension->IrpFlags)
|
||||
{
|
||||
IoRequestDpc(DeviceExtension->DeviceObject,
|
||||
NULL,
|
||||
DeviceExtension);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
return DeviceExtension->HwInterrupt(&DeviceExtension->MiniPortDeviceExtension);
|
||||
}
|
||||
|
||||
|
||||
// ScsiPortDpcForIsr
|
||||
// ScsiPortDpc
|
||||
// DESCRIPTION:
|
||||
//
|
||||
// RUN LEVEL:
|
||||
|
@ -2038,21 +2204,21 @@ ScsiPortIsr(IN PKINTERRUPT Interrupt,
|
|||
// IN PVOID DpcContext
|
||||
//
|
||||
static VOID STDCALL
|
||||
ScsiPortDpcForIsr(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext)
|
||||
ScsiPortDpc(IN PKDPC Dpc,
|
||||
IN PDEVICE_OBJECT DpcDeviceObject,
|
||||
IN PIRP DpcIrp,
|
||||
IN PVOID DpcContext)
|
||||
{
|
||||
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
|
||||
|
||||
DPRINT("ScsiPortDpcForIsr(Dpc %p DpcDeviceObject %p DpcIrp %p DpcContext %p)\n",
|
||||
DPRINT("ScsiPortDpc(Dpc %p DpcDeviceObject %p DpcIrp %p DpcContext %p)\n",
|
||||
Dpc, DpcDeviceObject, DpcIrp, DpcContext);
|
||||
|
||||
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DpcContext;
|
||||
|
||||
SpiProcessRequests(DeviceExtension, NULL);
|
||||
|
||||
DPRINT("ScsiPortDpcForIsr() done\n");
|
||||
DPRINT("ScsiPortDpc() done\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -2541,6 +2707,61 @@ ByeBye:
|
|||
return Status;
|
||||
}
|
||||
|
||||
static VOID
|
||||
SpiRemoveActiveIrp(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
PIRP Irp,
|
||||
PIRP PrevIrp)
|
||||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
PIRP CurrentIrp;
|
||||
LunExtension = Irp->Tail.Overlay.DriverContext[2];
|
||||
LunExtension->ActiveIrpCount--;
|
||||
DeviceExtension->ActiveIrpCount--;
|
||||
if (PrevIrp)
|
||||
{
|
||||
InterlockedExchangePointer(&PrevIrp->Tail.Overlay.DriverContext[0],
|
||||
Irp->Tail.Overlay.DriverContext[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedExchangePointer(&DeviceExtension->NextIrp,
|
||||
Irp->Tail.Overlay.DriverContext[0]);
|
||||
}
|
||||
if (LunExtension->NextIrp == Irp)
|
||||
{
|
||||
InterlockedExchangePointer(&LunExtension->NextIrp,
|
||||
Irp->Tail.Overlay.DriverContext[1]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
CurrentIrp = LunExtension->NextIrp;
|
||||
while (CurrentIrp)
|
||||
{
|
||||
if (CurrentIrp->Tail.Overlay.DriverContext[1] == Irp)
|
||||
{
|
||||
InterlockedExchangePointer(&CurrentIrp->Tail.Overlay.DriverContext[1],
|
||||
Irp->Tail.Overlay.DriverContext[1]);
|
||||
return;
|
||||
}
|
||||
CurrentIrp = CurrentIrp->Tail.Overlay.DriverContext[1];
|
||||
}
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
static VOID
|
||||
SpiAddActiveIrp(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
PIRP Irp)
|
||||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
LunExtension = Irp->Tail.Overlay.DriverContext[2];
|
||||
Irp->Tail.Overlay.DriverContext[0] = (PVOID)DeviceExtension->NextIrp;
|
||||
InterlockedExchangePointer(&DeviceExtension->NextIrp, Irp);
|
||||
Irp->Tail.Overlay.DriverContext[1] = (PVOID)LunExtension->NextIrp;
|
||||
InterlockedExchangePointer(&LunExtension->NextIrp, Irp);
|
||||
}
|
||||
|
||||
static VOID
|
||||
SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
||||
IN PIRP NextIrp)
|
||||
|
@ -2562,7 +2783,8 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
*
|
||||
* Irp is within the active irp list or while other processing:
|
||||
* Srb->OriginalRequest -> Irp
|
||||
* Irp->Tail.Overlay.DriverContext[0] and DriverContext[1] -> ListEntry for queue
|
||||
* Irp->Tail.Overlay.DriverContext[0] -> next irp, DeviceExtension->NextIrp is head.
|
||||
* Irp->Tail.Overlay.DriverContext[1] -> next irp, LunExtension->NextIrp is head.
|
||||
* Irp->Tail.Overlay.DriverContext[2] -> LunExtension
|
||||
* Irp->Tail.Overlay.DriverContext[3] -> current Srb (original or sense request)
|
||||
* IoStack->Parameters.Scsi.Srb -> original Srb
|
||||
|
@ -2576,13 +2798,14 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
LIST_ENTRY CompleteIrpListHead;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
PSCSI_REQUEST_BLOCK OriginalSrb;
|
||||
PIRP PrevIrp;
|
||||
|
||||
DPRINT("SpiProcessRequests() called\n");
|
||||
|
||||
InitializeListHead(&NextIrpListHead);
|
||||
InitializeListHead(&CompleteIrpListHead);
|
||||
|
||||
KeAcquireSpinLock(&DeviceExtension->IrpLock, &oldIrql);
|
||||
KeAcquireSpinLock(&DeviceExtension->Lock, &oldIrql);
|
||||
|
||||
if (NextIrp)
|
||||
{
|
||||
|
@ -2604,23 +2827,29 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
|
||||
while (DeviceExtension->CompleteRequestCount ||
|
||||
((DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS) && !IsListEmpty(&DeviceExtension->PendingIrpListHead) &&
|
||||
(DeviceExtension->NextRequestCount || DeviceExtension->NextLuRequestCount || IsListEmpty(&DeviceExtension->ActiveIrpListHead))))
|
||||
(DeviceExtension->NextRequestCount || DeviceExtension->NextLuRequestCount || DeviceExtension->NextIrp == NULL)))
|
||||
{
|
||||
DPRINT("CompleteRequestCount %d, NextRequestCount %d, NextLuRequestCount %d, PendingIrpList is %s, ActiveIrpList is %s\n",
|
||||
DeviceExtension->CompleteRequestCount,
|
||||
DeviceExtension->NextRequestCount,
|
||||
DeviceExtension->NextLuRequestCount,
|
||||
IsListEmpty(&DeviceExtension->PendingIrpListHead) ? "EMPTY" : "NOT empty",
|
||||
IsListEmpty(&DeviceExtension->ActiveIrpListHead) ? "EMPTY" : "NOT empty");
|
||||
DPRINT ("CompleteRequestCount %d, NextRequestCount %d, NextLuRequestCount %d, PendingIrpList is %s, ActiveIrpList is %s\n",
|
||||
DeviceExtension->CompleteRequestCount,
|
||||
DeviceExtension->NextRequestCount,
|
||||
DeviceExtension->NextLuRequestCount,
|
||||
IsListEmpty(&DeviceExtension->PendingIrpListHead) ? "EMPTY" : "NOT empty",
|
||||
DeviceExtension->NextIrp == NULL ? "EMPTY" : "NOT empty");
|
||||
|
||||
if (DeviceExtension->ActiveIrpCount == 0 && DeviceExtension->CompleteRequestCount > 0)
|
||||
{
|
||||
DeviceExtension->CompleteRequestCount = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (DeviceExtension->CompleteRequestCount > 0)
|
||||
{
|
||||
DeviceExtension->IrpFlags &= ~IRP_FLAG_COMPLETE;
|
||||
ListEntry = DeviceExtension->ActiveIrpListHead.Flink;
|
||||
while (ListEntry != &DeviceExtension->ActiveIrpListHead)
|
||||
DeviceExtension->Flags &= ~IRP_FLAG_COMPLETE;
|
||||
PrevIrp = NULL;
|
||||
Irp = DeviceExtension->NextIrp;
|
||||
while (Irp)
|
||||
{
|
||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
|
||||
ListEntry = ListEntry->Flink;
|
||||
NextIrp = (PIRP)Irp->Tail.Overlay.DriverContext[0];
|
||||
Srb = Irp->Tail.Overlay.DriverContext[3];
|
||||
if (!(Srb->SrbFlags & SRB_FLAGS_IS_ACTIVE))
|
||||
{
|
||||
|
@ -2630,6 +2859,17 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
OriginalSrb = IrpStack->Parameters.Scsi.Srb;
|
||||
|
||||
if (Srb->SrbStatus == SRB_STATUS_BUSY)
|
||||
{
|
||||
SpiRemoveActiveIrp(DeviceExtension, Irp, PrevIrp);
|
||||
SpiFreeSrbExtension(DeviceExtension, OriginalSrb);
|
||||
InsertHeadList(&DeviceExtension->PendingIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
DeviceExtension->PendingIrpCount++;
|
||||
LunExtension->PendingIrpCount++;
|
||||
Irp = NextIrp;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (OriginalSrb != Srb)
|
||||
{
|
||||
SENSE_DATA* SenseInfoBuffer;
|
||||
|
@ -2665,10 +2905,8 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
{
|
||||
CompleteThisRequest = FALSE;
|
||||
Irp->Tail.Overlay.DriverContext[3] = Srb;
|
||||
RemoveEntryList((PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
SpiRemoveActiveIrp(DeviceExtension, Irp, PrevIrp);
|
||||
SpiFreeSrbExtension(DeviceExtension, Srb);
|
||||
LunExtension->ActiveIrpCount--;
|
||||
DeviceExtension->ActiveIrpCount--;
|
||||
|
||||
Srb->OriginalRequest = LunExtension;
|
||||
Irp->Tail.Overlay.DriverContext[2] = 0;
|
||||
|
@ -2676,6 +2914,8 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
InsertHeadList(&DeviceExtension->PendingIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
DeviceExtension->PendingIrpCount++;
|
||||
LunExtension->PendingIrpCount++;
|
||||
Irp = NextIrp;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2689,20 +2929,38 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
}
|
||||
if (CompleteThisRequest)
|
||||
{
|
||||
RemoveEntryList((PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
SpiRemoveActiveIrp(DeviceExtension, Irp, PrevIrp);
|
||||
InsertHeadList(&CompleteIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
SpiFreeSrbExtension(DeviceExtension, OriginalSrb);
|
||||
LunExtension->ActiveIrpCount--;
|
||||
DeviceExtension->ActiveIrpCount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
PrevIrp = Irp;
|
||||
}
|
||||
Irp = NextIrp;
|
||||
continue;
|
||||
}
|
||||
PrevIrp = Irp;
|
||||
Irp = NextIrp;
|
||||
}
|
||||
}
|
||||
if (!IsListEmpty(&CompleteIrpListHead))
|
||||
{
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
|
||||
while (!IsListEmpty(&CompleteIrpListHead))
|
||||
{
|
||||
ListEntry = RemoveTailList(&CompleteIrpListHead);
|
||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
|
||||
Srb = Irp->Tail.Overlay.DriverContext[3];
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock);
|
||||
}
|
||||
if (DeviceExtension->NextLuRequestCount ||
|
||||
DeviceExtension->NextRequestCount)
|
||||
{
|
||||
BOOLEAN StartThisRequest;
|
||||
DeviceExtension->IrpFlags &= ~(IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU);
|
||||
DeviceExtension->Flags &= ~(IRP_FLAG_NEXT|IRP_FLAG_NEXT_LU);
|
||||
ListEntry = DeviceExtension->PendingIrpListHead.Flink;
|
||||
while (ListEntry != &DeviceExtension->PendingIrpListHead)
|
||||
{
|
||||
|
@ -2754,54 +3012,40 @@ SpiProcessRequests(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
{
|
||||
ListEntry = RemoveTailList(&NextIrpListHead);
|
||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
|
||||
InsertHeadList(&DeviceExtension->ActiveIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->IrpLock);
|
||||
SpiAddActiveIrp(DeviceExtension, Irp);
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
|
||||
|
||||
// Start this Irp
|
||||
SpiStartIo(DeviceExtension, Irp);
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->IrpLock);
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&DeviceExtension->PendingIrpListHead) &&
|
||||
IsListEmpty(&DeviceExtension->ActiveIrpListHead) &&
|
||||
(DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS))
|
||||
DeviceExtension->NextIrp == NULL &&
|
||||
(DeviceExtension->SrbExtensionSize == 0 || DeviceExtension->ActiveIrpCount < MAX_SRB_EXTENSIONS))
|
||||
{
|
||||
ListEntry = RemoveHeadList(&DeviceExtension->PendingIrpListHead);
|
||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
|
||||
Srb = Irp->Tail.Overlay.DriverContext[3];
|
||||
LunExtension = Srb->OriginalRequest;
|
||||
|
||||
LunExtension->PendingIrpCount--;
|
||||
DeviceExtension->PendingIrpCount--;
|
||||
InsertHeadList(&DeviceExtension->ActiveIrpListHead, (PLIST_ENTRY)&Irp->Tail.Overlay.DriverContext[0]);
|
||||
LunExtension->ActiveIrpCount++;
|
||||
DeviceExtension->ActiveIrpCount++;
|
||||
SpiAllocateSrbExtension(DeviceExtension, Srb);
|
||||
|
||||
Irp->Tail.Overlay.DriverContext[2] = LunExtension;
|
||||
Srb->OriginalRequest = Irp;
|
||||
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->IrpLock);
|
||||
LunExtension->PendingIrpCount--;
|
||||
DeviceExtension->PendingIrpCount--;
|
||||
SpiAddActiveIrp(DeviceExtension, Irp);
|
||||
LunExtension->ActiveIrpCount++;
|
||||
DeviceExtension->ActiveIrpCount++;
|
||||
SpiAllocateSrbExtension(DeviceExtension, Srb);
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->Lock);
|
||||
|
||||
// Start this irp
|
||||
/* Start this irp */
|
||||
SpiStartIo(DeviceExtension, Irp);
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->IrpLock);
|
||||
}
|
||||
|
||||
if (!IsListEmpty(&CompleteIrpListHead))
|
||||
{
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->IrpLock);
|
||||
while (!IsListEmpty(&CompleteIrpListHead))
|
||||
{
|
||||
ListEntry = RemoveTailList(&CompleteIrpListHead);
|
||||
Irp = CONTAINING_RECORD(ListEntry, IRP, Tail.Overlay.DriverContext[0]);
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
}
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->IrpLock);
|
||||
}
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->Lock);
|
||||
}
|
||||
}
|
||||
KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
|
||||
KeReleaseSpinLock(&DeviceExtension->Lock, oldIrql);
|
||||
|
||||
DPRINT("SpiProcessRequests() done\n");
|
||||
}
|
||||
|
@ -2812,7 +3056,6 @@ SpiStartIo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
{
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
PSCSI_REQUEST_BLOCK Srb;
|
||||
PIO_STACK_LOCATION IrpStack;
|
||||
|
||||
DPRINT("SpiStartIo() called!\n");
|
||||
|
||||
|
@ -2830,27 +3073,10 @@ SpiStartIo(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
|
|||
Srb))
|
||||
{
|
||||
DPRINT1("Synchronization failed!\n");
|
||||
|
||||
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel(&DeviceExtension->IrpLock);
|
||||
|
||||
RemoveEntryList((PLIST_ENTRY)Irp->Tail.Overlay.DriverContext[0]);
|
||||
LunExtension = Irp->Tail.Overlay.DriverContext[2];
|
||||
LunExtension->ActiveIrpCount--;
|
||||
SpiFreeSrbExtension(DeviceExtension, Srb);
|
||||
IrpStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
if (IrpStack->Parameters.Scsi.Srb != Srb)
|
||||
{
|
||||
ExFreePool(Srb);
|
||||
}
|
||||
DeviceExtension->ActiveIrpCount--;
|
||||
|
||||
KeReleaseSpinLockFromDpcLevel(&DeviceExtension->IrpLock);
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
DPRINT1("Irp %x, Srb->Function %02x, Srb->Cdb[0] %02x, Srb->SrbStatus %02x\n", Irp, Srb->Function, Srb->Cdb[0], Srb->SrbStatus);
|
||||
ScsiPortNotification(RequestComplete,
|
||||
&DeviceExtension->MiniPortDeviceExtension,
|
||||
Srb);
|
||||
}
|
||||
|
||||
DPRINT("SpiStartIo() done\n");
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include <defines.h>
|
||||
#include <reactos/resource.h>
|
||||
#include "scsiport_int.h"
|
||||
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
|
||||
|
@ -22,7 +23,7 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", RES_STR_COMPANY_NAME
|
||||
VALUE "FileDescription", "SCSI Port Driver\0"
|
||||
VALUE "FileVersion", "0.0.0\0"
|
||||
VALUE "FileVersion", VERSION
|
||||
VALUE "InternalName", "scsiport\0"
|
||||
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
|
||||
VALUE "OriginalFilename", "scsiport.sys\0"
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* DESCRIPTION
|
||||
* An enumeration containing the states in the timer DFA
|
||||
*/
|
||||
|
||||
#define VERSION "0.0.2"
|
||||
|
||||
typedef enum _SCSI_PORT_TIMER_STATES
|
||||
{
|
||||
IDETimerIdle,
|
||||
|
@ -41,6 +44,8 @@ typedef struct _SCSI_PORT_LUN_EXTENSION
|
|||
ULONG ActiveIrpCount;
|
||||
ULONG NextLuRequestCount;
|
||||
|
||||
PIRP NextIrp;
|
||||
|
||||
/* More data? */
|
||||
|
||||
UCHAR MiniportLunExtension[1]; /* must be the last entry */
|
||||
|
@ -62,10 +67,10 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
|
|||
PPORT_CONFIGURATION_INFORMATION PortConfig;
|
||||
ULONG PortNumber;
|
||||
|
||||
KSPIN_LOCK IrpLock;
|
||||
KSPIN_LOCK SpinLock;
|
||||
KSPIN_LOCK Lock;
|
||||
ULONG Flags;
|
||||
|
||||
PKINTERRUPT Interrupt;
|
||||
ULONG IrpFlags;
|
||||
|
||||
SCSI_PORT_TIMER_STATES TimerState;
|
||||
LONG TimerCount;
|
||||
|
@ -96,7 +101,7 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
|
|||
ULONG CommonBufferLength;
|
||||
|
||||
LIST_ENTRY PendingIrpListHead;
|
||||
LIST_ENTRY ActiveIrpListHead;
|
||||
PIRP NextIrp;
|
||||
ULONG PendingIrpCount;
|
||||
ULONG ActiveIrpCount;
|
||||
|
||||
|
@ -107,5 +112,18 @@ typedef struct _SCSI_PORT_DEVICE_EXTENSION
|
|||
UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
|
||||
} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct _SCSI_PORT_SCAN_ADAPTER
|
||||
{
|
||||
KEVENT Event;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
PSCSI_PORT_LUN_EXTENSION LunExtension;
|
||||
ULONG Lun;
|
||||
ULONG Bus;
|
||||
ULONG Target;
|
||||
SCSI_REQUEST_BLOCK Srb;
|
||||
UCHAR DataBuffer[256];
|
||||
BOOL Active;
|
||||
} SCSI_PORT_SCAN_ADAPTER, *PSCSI_PORT_SCAN_ADAPTER;
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue