#define VERSION "0.0.1"
+#include "scsiport_int.h"
-/* TYPES *********************************************************************/
-
-/*
- * SCSI_PORT_TIMER_STATES
- *
- * DESCRIPTION
- * An enumeration containing the states in the timer DFA
- */
-typedef enum _SCSI_PORT_TIMER_STATES
-{
- IDETimerIdle,
- IDETimerCmdWait,
- IDETimerResetWaitForBusyNegate,
- IDETimerResetWaitForDrdyAssert
-} SCSI_PORT_TIMER_STATES;
-
-
-typedef struct _SCSI_PORT_DEVICE_BASE
-{
- LIST_ENTRY List;
-
- PVOID MappedAddress;
- ULONG NumberOfBytes;
- SCSI_PHYSICAL_ADDRESS IoAddress;
- ULONG SystemIoBusNumber;
-} SCSI_PORT_DEVICE_BASE, *PSCSI_PORT_DEVICE_BASE;
-
-
-/*
- * SCSI_PORT_DEVICE_EXTENSION
- *
- * DESCRIPTION
- * First part of the port objects device extension. The second
- * part is the miniport-specific device extension.
- */
-
-typedef struct _SCSI_PORT_DEVICE_EXTENSION
-{
- ULONG Length;
- ULONG MiniPortExtensionSize;
- PORT_CONFIGURATION_INFORMATION PortConfig;
- ULONG PortNumber;
-
- KSPIN_LOCK IrpLock;
- KSPIN_LOCK SpinLock;
- PKINTERRUPT Interrupt;
- PIRP CurrentIrp;
- ULONG IrpFlags;
-
- SCSI_PORT_TIMER_STATES TimerState;
- LONG TimerCount;
-
- BOOLEAN Initializing;
-
- LIST_ENTRY DeviceBaseListHead;
-
- ULONG PortBusInfoSize;
- PSCSI_ADAPTER_BUS_INFO PortBusInfo;
-
- PIO_SCSI_CAPABILITIES PortCapabilities;
-
- PDEVICE_OBJECT DeviceObject;
- PCONTROLLER_OBJECT ControllerObject;
-
- PHW_STARTIO HwStartIo;
- PHW_INTERRUPT HwInterrupt;
-
- PSCSI_REQUEST_BLOCK OriginalSrb;
- SCSI_REQUEST_BLOCK InternalSrb;
- SENSE_DATA InternalSenseData;
-
- UCHAR MiniPortDeviceExtension[1]; /* must be the last entry */
-} SCSI_PORT_DEVICE_EXTENSION, *PSCSI_PORT_DEVICE_EXTENSION;
+//#define USE_DEVICE_QUEUES
+/* TYPES *********************************************************************/
#define IRP_FLAG_COMPLETE 0x00000001
#define IRP_FLAG_NEXT 0x00000002
+#define IRP_FLAG_NEXT_LU 0x00000004
/* GLOBALS *******************************************************************/
IN ULONG PortCount,
IN OUT PSCSI_PORT_DEVICE_EXTENSION *RealDeviceExtension);
+static PSCSI_PORT_LUN_EXTENSION
+SpiAllocateLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun);
+
+static PSCSI_PORT_LUN_EXTENSION
+SpiGetLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun);
+
static VOID
-ScsiPortInquire(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension);
+SpiInquirePort (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension);
+
+static ULONG
+SpiGetInquiryData (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ OUT PSCSI_ADAPTER_BUS_INFO AdapterBusInfo);
static BOOLEAN STDCALL
ScsiPortIsr(IN PKINTERRUPT Interrupt,
PSCSI_REQUEST_BLOCK OriginalSrb);
static NTSTATUS
-ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
- PUNICODE_STRING RegistryPath);
+SpiBuildDeviceMap (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ PUNICODE_STRING RegistryPath);
/* FUNCTIONS *****************************************************************/
*
* RETURN VALUE
* None.
+ *
+ * @implemented
*/
VOID
}
+/*
+ * @unimplemented
+ */
VOID STDCALL
ScsiPortCompleteRequest(IN PVOID HwDeviceExtension,
IN UCHAR PathId,
}
+/*
+ * @implemented
+ */
ULONG STDCALL
ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
{
}
+/*
+ * @unimplemented
+ */
VOID STDCALL
ScsiPortFlushDma(IN PVOID HwDeviceExtension)
{
}
+/*
+ * @implemented
+ */
VOID STDCALL
ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
IN PVOID MappedAddress)
}
+/*
+ * @implemented
+ */
ULONG STDCALL
ScsiPortGetBusData(IN PVOID DeviceExtension,
IN ULONG BusDataType,
}
+/*
+ * @implemented
+ */
PVOID STDCALL
ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension,
IN INTERFACE_TYPE BusType,
}
+/*
+ * @implemented
+ */
PVOID STDCALL
ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun)
{
- DPRINT("ScsiPortGetLogicalUnit()\n");
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+ PLIST_ENTRY Entry;
+
+ DPRINT("ScsiPortGetLogicalUnit() called\n");
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+ if (IsListEmpty(&DeviceExtension->LunExtensionListHead))
+ return NULL;
+
+ Entry = DeviceExtension->LunExtensionListHead.Flink;
+ while (Entry != &DeviceExtension->LunExtensionListHead)
+ {
+ LunExtension = CONTAINING_RECORD(Entry,
+ SCSI_PORT_LUN_EXTENSION,
+ List);
+ if (LunExtension->PathId == PathId &&
+ LunExtension->TargetId == TargetId &&
+ LunExtension->Lun == Lun)
+ {
+ return (PVOID)&LunExtension->MiniportLunExtension;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ return NULL;
}
+/*
+ * @unimplemented
+ */
SCSI_PHYSICAL_ADDRESS STDCALL
ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
IN PVOID VirtualAddress,
OUT ULONG *Length)
{
- DPRINT("ScsiPortGetPhysicalAddress()\n");
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ SCSI_PHYSICAL_ADDRESS PhysicalAddress;
+ ULONG BufferLength = 0;
+ ULONG Offset;
+
+ DPRINT1("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
+ HwDeviceExtension, Srb, VirtualAddress, Length);
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+
+ *Length = 0;
+
+ if (Srb == NULL)
+ {
+ if ((ULONG_PTR)DeviceExtension->VirtualAddress > (ULONG_PTR)VirtualAddress)
+ {
+ PhysicalAddress.QuadPart = 0ULL;
+ return PhysicalAddress;
+ }
+
+ Offset = (ULONG_PTR)VirtualAddress - (ULONG_PTR)DeviceExtension->VirtualAddress;
+ if (Offset >= DeviceExtension->CommonBufferLength)
+ {
+ PhysicalAddress.QuadPart = 0ULL;
+ return PhysicalAddress;
+ }
+
+ PhysicalAddress.QuadPart =
+ DeviceExtension->PhysicalAddress.QuadPart + (ULONGLONG)Offset;
+ BufferLength = DeviceExtension->CommonBufferLength - Offset;
+ }
+ else
+ {
+ /* FIXME */
+ DPRINT1("Srb != NULL is not implemented yet!\n");
+ UNIMPLEMENTED;
+ }
+
+ *Length = BufferLength;
+
+ return PhysicalAddress;
}
+/*
+ * @unimplemented
+ */
PSCSI_REQUEST_BLOCK STDCALL
ScsiPortGetSrb(IN PVOID DeviceExtension,
IN UCHAR PathId,
}
+/*
+ * @implemented
+ */
PVOID STDCALL
ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension,
IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
IN ULONG NumberOfBytes)
{
- DPRINT("ScsiPortGetUncachedExtension()\n");
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ DEVICE_DESCRIPTION DeviceDescription;
+
+ DPRINT1("ScsiPortGetUncachedExtension(%p %p %lu)\n",
+ HwDeviceExtension, ConfigInfo, NumberOfBytes);
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+
+ /* Check for allocated common DMA buffer */
+ if (DeviceExtension->VirtualAddress != NULL)
+ {
+ DPRINT1("The HBA has already got a common DMA buffer!\n");
+ return NULL;
+ }
+
+ /* Check for DMA adapter object */
+ if (DeviceExtension->AdapterObject == NULL)
+ {
+ /* Initialize DMA adapter description */
+ RtlZeroMemory(&DeviceDescription,
+ sizeof(DEVICE_DESCRIPTION));
+ DeviceDescription.Version = DEVICE_DESCRIPTION_VERSION;
+ DeviceDescription.Master = ConfigInfo->Master;
+ DeviceDescription.ScatterGather = ConfigInfo->ScatterGather;
+ DeviceDescription.DemandMode = ConfigInfo->DemandMode;
+ DeviceDescription.Dma32BitAddresses = ConfigInfo->Dma32BitAddresses;
+ DeviceDescription.BusNumber = ConfigInfo->SystemIoBusNumber;
+ DeviceDescription.DmaChannel = ConfigInfo->DmaChannel;
+ DeviceDescription.InterfaceType = ConfigInfo->AdapterInterfaceType;
+ DeviceDescription.DmaWidth = ConfigInfo->DmaWidth;
+ DeviceDescription.DmaSpeed = ConfigInfo->DmaSpeed;
+ DeviceDescription.MaximumLength = ConfigInfo->MaximumTransferLength;
+ DeviceDescription.DmaPort = ConfigInfo->DmaPort;
+
+ /* Get a DMA adapter object */
+ DeviceExtension->AdapterObject = HalGetAdapter(&DeviceDescription,
+ &DeviceExtension->MapRegisterCount);
+ if (DeviceExtension->AdapterObject == NULL)
+ {
+ DPRINT1("HalGetAdapter() failed\n");
+ return NULL;
+ }
+ }
+
+ /* Allocate a common DMA buffer */
+ DeviceExtension->CommonBufferLength = NumberOfBytes;
+ DeviceExtension->VirtualAddress =
+ HalAllocateCommonBuffer(DeviceExtension->AdapterObject,
+ DeviceExtension->CommonBufferLength,
+ &DeviceExtension->PhysicalAddress,
+ FALSE);
+ if (DeviceExtension->VirtualAddress == NULL)
+ {
+ DPRINT1("HalAllocateCommonBuffer() failed!\n");
+ DeviceExtension->CommonBufferLength = 0;
+ return NULL;
+ }
+
+ return DeviceExtension->VirtualAddress;
}
+/*
+ * @implemented
+ */
PVOID STDCALL
ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension,
IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
{
- DPRINT("ScsiPortGetVirtualAddress()\n");
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ ULONG Offset;
+
+ DPRINT("ScsiPortGetVirtualAddress(%p %I64x)\n",
+ HwDeviceExtension, PhysicalAddress.QuadPart);
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+
+ if (DeviceExtension->PhysicalAddress.QuadPart > PhysicalAddress.QuadPart)
+ return NULL;
+
+ Offset = (ULONG)(PhysicalAddress.QuadPart - DeviceExtension->PhysicalAddress.QuadPart);
+ if (Offset >= DeviceExtension->CommonBufferLength)
+ return NULL;
+
+ return (PVOID)((ULONG_PTR)DeviceExtension->VirtualAddress + Offset);
}
*
* RETURN VALUE
* Status.
+ *
+ * @implemented
*/
ULONG STDCALL
return(STATUS_INVALID_PARAMETER);
DriverObject->DriverStartIo = ScsiPortStartIo;
- DriverObject->MajorFunction[IRP_MJ_CREATE] = ScsiPortCreateClose;
- DriverObject->MajorFunction[IRP_MJ_CLOSE] = ScsiPortCreateClose;
- DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ScsiPortDeviceControl;
- DriverObject->MajorFunction[IRP_MJ_SCSI] = ScsiPortDispatchScsi;
+ DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)ScsiPortCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)ScsiPortCreateClose;
+ DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)ScsiPortDeviceControl;
+ DriverObject->MajorFunction[IRP_MJ_SCSI] = (PDRIVER_DISPATCH)ScsiPortDispatchScsi;
SystemConfig = IoGetConfigurationInformation();
ExtensionSize);
PseudoDeviceExtension->Length = ExtensionSize;
PseudoDeviceExtension->MiniPortExtensionSize = HwInitializationData->DeviceExtensionSize;
+ PseudoDeviceExtension->LunExtensionSize = HwInitializationData->SpecificLuExtensionSize;
PseudoDeviceExtension->HwStartIo = HwInitializationData->HwStartIo;
PseudoDeviceExtension->HwInterrupt = HwInitializationData->HwInterrupt;
// RtlZeroMemory(AccessRanges,
// sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges);
+ PseudoDeviceExtension->AdapterObject = NULL;
+ PseudoDeviceExtension->MapRegisterCount = 0;
+ PseudoDeviceExtension->PhysicalAddress.QuadPart = 0ULL;
+ PseudoDeviceExtension->VirtualAddress = NULL;
+ PseudoDeviceExtension->CommonBufferLength = 0;
+
RtlZeroMemory(PseudoDeviceExtension->MiniPortDeviceExtension,
PseudoDeviceExtension->MiniPortExtensionSize);
return(Status);
}
+ /* Get inquiry data */
+ SpiInquirePort (RealDeviceExtension);
+
/* Build the registry device map */
- ScsiPortBuildDeviceMap(RealDeviceExtension,
- (PUNICODE_STRING)Argument2);
+ SpiBuildDeviceMap (RealDeviceExtension,
+ (PUNICODE_STRING)Argument2);
/* Update the configuration info */
SystemConfig->AtDiskPrimaryAddressClaimed = PortConfig->AtdiskPrimaryClaimed;
}
+/*
+ * @unimplemented
+ */
VOID STDCALL
ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
}
+/*
+ * @unimplemented
+ */
VOID STDCALL
ScsiPortLogError(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
}
+/*
+ * @implemented
+ */
VOID STDCALL
ScsiPortMoveMemory(OUT PVOID Destination,
IN PVOID Source,
}
+/*
+ * @implemented
+ */
VOID
ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
IN PVOID HwDeviceExtension,
...)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ va_list ap;
DPRINT("ScsiPortNotification() called\n");
if (DeviceExtension->Initializing == TRUE)
return;
+ va_start(ap, HwDeviceExtension);
+
switch (NotificationType)
{
case RequestComplete:
- DPRINT("Notify: RequestComplete\n");
- DeviceExtension->IrpFlags |= IRP_FLAG_COMPLETE;
+ {
+ PSCSI_REQUEST_BLOCK Srb;
+
+ Srb = (PSCSI_REQUEST_BLOCK) va_arg (ap, PSCSI_REQUEST_BLOCK);
+
+ DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
+ DeviceExtension->IrpFlags |= IRP_FLAG_COMPLETE;
+ }
break;
case NextRequest:
DeviceExtension->IrpFlags |= IRP_FLAG_NEXT;
break;
+ case NextLuRequest:
+ {
+ UCHAR PathId;
+ UCHAR TargetId;
+ UCHAR Lun;
+
+ PathId = (UCHAR) va_arg (ap, int);
+ TargetId = (UCHAR) va_arg (ap, int);
+ Lun = (UCHAR) va_arg (ap, int);
+
+ DPRINT1 ("Notify: NextLuRequest(PathId %u TargetId %u Lun %u)\n",
+ PathId, TargetId, Lun);
+ /* FIXME: Implement it! */
+
+// DeviceExtension->IrpFlags |= IRP_FLAG_NEXT_LU;
+
+ }
+ break;
+
+ case ResetDetected:
+ DPRINT1("Notify: ResetDetected\n");
+ /* FIXME: ??? */
+ break;
+
default:
+ DPRINT1 ("Unsupported notification %lu\n", NotificationType);
break;
}
+
+ va_end(ap);
}
+/*
+ * @implemented
+ */
ULONG STDCALL
ScsiPortSetBusDataByOffset(IN PVOID DeviceExtension,
IN ULONG BusDataType,
}
+/*
+ * @implemented
+ */
BOOLEAN STDCALL
ScsiPortValidateRange(IN PVOID HwDeviceExtension,
IN INTERFACE_TYPE BusType,
IN PIRP Irp)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
PIO_STACK_LOCATION Stack;
PSCSI_REQUEST_BLOCK Srb;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("Srb->Function: %lu\n", Srb->Function);
DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n", Srb->PathId, Srb->TargetId, Srb->Lun);
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ Srb->PathId,
+ Srb->TargetId,
+ Srb->Lun);
+ if (LunExtension == NULL)
+ {
+ Status = STATUS_NO_SUCH_DEVICE;
+
+ Srb->SrbStatus = SRB_STATUS_NO_DEVICE;
+ Irp->IoStatus.Status = Status;
+ Irp->IoStatus.Information = 0;
+
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return(Status);
+ }
+
switch (Srb->Function)
{
case SRB_FUNCTION_EXECUTE_SCSI:
- IoStartPacket(DeviceObject, Irp, NULL, NULL);
+ case SRB_FUNCTION_IO_CONTROL:
+#ifdef USE_DEVICE_QUEUES
+ if (Srb->SrbFlags & SRB_FLAGS_BYPASS_FROZEN_QUEUE)
+ {
+ IoStartPacket (DeviceObject, Irp, NULL, NULL);
+ }
+ else
+ {
+ KIRQL oldIrql;
+
+ KeRaiseIrql (DISPATCH_LEVEL,
+ &oldIrql);
+
+ if (!KeInsertByKeyDeviceQueue (&LunExtension->DeviceQueue,
+ &Irp->Tail.Overlay.DeviceQueueEntry,
+ Srb->QueueSortKey))
+ {
+ Srb->SrbStatus = SRB_STATUS_SUCCESS;
+ IoStartPacket (DeviceObject, Irp, NULL, NULL);
+ }
+
+ KeLowerIrql (oldIrql);
+ }
+#else
+ IoStartPacket (DeviceObject, Irp, NULL, NULL);
+#endif
return(STATUS_PENDING);
case SRB_FUNCTION_SHUTDOWN:
break;
case SRB_FUNCTION_CLAIM_DEVICE:
- {
- PSCSI_ADAPTER_BUS_INFO AdapterInfo;
- PSCSI_INQUIRY_DATA UnitInfo;
- PINQUIRYDATA InquiryData;
-
- DPRINT(" SRB_FUNCTION_CLAIM_DEVICE\n");
- DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n", Srb->PathId, Srb->TargetId, Srb->Lun);
-
- Srb->DataBuffer = NULL;
-
- if (DeviceExtension->PortBusInfo != NULL)
- {
- AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
-
- if (AdapterInfo->BusData[Srb->PathId].NumberOfLogicalUnits == 0)
- break;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
- AdapterInfo->BusData[Srb->PathId].InquiryDataOffset);
-
- while (AdapterInfo->BusData[Srb->PathId].InquiryDataOffset)
- {
- InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData;
-
- if ((UnitInfo->TargetId == Srb->TargetId) &&
- (UnitInfo->Lun == Srb->Lun) &&
- (UnitInfo->DeviceClaimed == FALSE))
- {
- UnitInfo->DeviceClaimed = TRUE;
- DPRINT("Claimed device!\n");
-
- /* FIXME: Hack!!!!! */
- Srb->DataBuffer = DeviceObject;
+ DPRINT(" SRB_FUNCTION_CLAIM_DEVICE\n");
- break;
- }
-
- if (UnitInfo->NextInquiryDataOffset == 0)
- break;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + UnitInfo->NextInquiryDataOffset);
- }
- }
- }
+ /* Reference device object and keep the pointer */
+ ObReferenceObject(DeviceObject);
+ LunExtension->DeviceObject = DeviceObject;
+ LunExtension->DeviceClaimed = TRUE;
+ Srb->DataBuffer = DeviceObject;
break;
case SRB_FUNCTION_RELEASE_DEVICE:
{
- PSCSI_ADAPTER_BUS_INFO AdapterInfo;
- PSCSI_INQUIRY_DATA UnitInfo;
- PINQUIRYDATA InquiryData;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
DPRINT(" SRB_FUNCTION_RELEASE_DEVICE\n");
DPRINT("PathId: %lu TargetId: %lu Lun: %lu\n", Srb->PathId, Srb->TargetId, Srb->Lun);
- if (DeviceExtension->PortBusInfo != NULL)
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ Srb->PathId,
+ Srb->TargetId,
+ Srb->Lun);
+ if (LunExtension != NULL)
{
- AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
-
- if (AdapterInfo->BusData[Srb->PathId].NumberOfLogicalUnits == 0)
- break;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
- AdapterInfo->BusData[Srb->PathId].InquiryDataOffset);
-
- while (AdapterInfo->BusData[Srb->PathId].InquiryDataOffset)
- {
- InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData;
-
- if ((UnitInfo->TargetId == Srb->TargetId) &&
- (UnitInfo->Lun == Srb->Lun) &&
- (UnitInfo->DeviceClaimed == TRUE))
- {
- UnitInfo->DeviceClaimed = FALSE;
- DPRINT("Released device!\n");
- break;
- }
-
- if (UnitInfo->NextInquiryDataOffset == 0)
- break;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo + UnitInfo->NextInquiryDataOffset);
- }
+ /* Dereference device object */
+ ObDereferenceObject(LunExtension->DeviceObject);
+ LunExtension->DeviceObject = NULL;
+ LunExtension->DeviceClaimed = FALSE;
}
}
break;
switch (Stack->Parameters.DeviceIoControl.IoControlCode)
{
+ case IOCTL_SCSI_GET_DUMP_POINTERS:
+ {
+ PDUMP_POINTERS DumpPointers;
+ DPRINT(" IOCTL_SCSI_GET_DUMP_POINTERS\n");
+ DumpPointers = (PDUMP_POINTERS)Irp->AssociatedIrp.SystemBuffer;
+ DumpPointers->DeviceObject = DeviceObject;
+
+ Irp->IoStatus.Information = sizeof(DUMP_POINTERS);
+ }
+ break;
case IOCTL_SCSI_GET_CAPABILITIES:
{
DPRINT(" IOCTL_SCSI_GET_INQUIRY_DATA\n");
/* Copy inquiry data to the port device extension */
- memcpy(Irp->AssociatedIrp.SystemBuffer,
- DeviceExtension->PortBusInfo,
- DeviceExtension->PortBusInfoSize);
-
- DPRINT("BufferSize: %lu\n", DeviceExtension->PortBusInfoSize);
- Irp->IoStatus.Information = DeviceExtension->PortBusInfoSize;
+ Irp->IoStatus.Information =
+ SpiGetInquiryData(DeviceExtension,
+ Irp->AssociatedIrp.SystemBuffer);
+ DPRINT("Inquiry data size: %lu\n", Irp->IoStatus.Information);
}
break;
IN PIRP Irp)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
PIO_STACK_LOCATION IrpStack;
- KIRQL OldIrql;
+ PSCSI_REQUEST_BLOCK Srb;
+ KIRQL oldIrql;
+ BOOLEAN Result;
DPRINT("ScsiPortStartIo() called!\n");
DeviceExtension = DeviceObject->DeviceExtension;
IrpStack = IoGetCurrentIrpStackLocation(Irp);
- // FIXME: implement the supported functions
+ DPRINT("DeviceExtension %p\n", DeviceExtension);
- switch (IrpStack->MajorFunction)
+ if (IrpStack->MajorFunction != IRP_MJ_SCSI)
{
- case IRP_MJ_SCSI:
- {
- BOOLEAN Result;
- PSCSI_REQUEST_BLOCK Srb;
- KIRQL oldIrql;
+ DPRINT("No IRP_MJ_SCSI!\n");
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest (Irp,
+ IO_NO_INCREMENT);
+ IoStartNextPacket (DeviceObject,
+ FALSE);
+ return;
+ }
- DPRINT("IRP_MJ_SCSI\n");
+ Srb = IrpStack->Parameters.Scsi.Srb;
- Srb = IrpStack->Parameters.Scsi.Srb;
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ Srb->PathId,
+ Srb->TargetId,
+ Srb->Lun);
+ if (LunExtension == NULL)
+ {
+ DPRINT("No IRP_MJ_SCSI!\n");
+ Irp->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest (Irp,
+ IO_NO_INCREMENT);
+ IoStartNextPacket (DeviceObject,
+ FALSE);
+ return;
+ }
- DPRINT("DeviceExtension %p\n", DeviceExtension);
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = Srb->DataTransferLength;
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = Srb->DataTransferLength;
+ DeviceExtension->CurrentIrp = Irp;
- DeviceExtension->CurrentIrp = Irp;
+ if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
+ ScsiPortStartPacket,
+ DeviceExtension))
+ {
+ DPRINT("Synchronization failed!\n");
- if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
- ScsiPortStartPacket,
- DeviceExtension))
- {
- DPRINT("Synchronization failed!\n");
-
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
- IoStartNextPacket(DeviceObject,
- FALSE);
- }
- KeAcquireSpinLock(&DeviceExtension->IrpLock, &oldIrql);
- if (DeviceExtension->IrpFlags & IRP_FLAG_COMPLETE)
- {
- DeviceExtension->IrpFlags &= ~IRP_FLAG_COMPLETE;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
- }
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp,
+ IO_NO_INCREMENT);
+ IoStartNextPacket(DeviceObject,
+ FALSE);
+ }
- if (DeviceExtension->IrpFlags & IRP_FLAG_NEXT)
- {
- DeviceExtension->IrpFlags &= ~IRP_FLAG_NEXT;
- KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
- IoStartNextPacket(DeviceObject,
- FALSE);
- }
- else
- {
- KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
- }
- }
- break;
+ KeAcquireSpinLock(&DeviceExtension->IrpLock, &oldIrql);
+ if (DeviceExtension->IrpFlags & IRP_FLAG_COMPLETE)
+ {
+ DeviceExtension->IrpFlags &= ~IRP_FLAG_COMPLETE;
+ IoCompleteRequest(Irp,
+ IO_NO_INCREMENT);
+ }
- default:
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
- IoCompleteRequest(Irp,
- IO_NO_INCREMENT);
- IoStartNextPacket(DeviceObject,
- FALSE);
- break;
+ if (DeviceExtension->IrpFlags & IRP_FLAG_NEXT)
+ {
+ DeviceExtension->IrpFlags &= ~IRP_FLAG_NEXT;
+ KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
+ IoStartNextPacket(DeviceObject,
+ FALSE);
+ }
+ else
+ {
+ KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
}
+
DPRINT("ScsiPortStartIo() done\n");
}
{
DbgPrint("Could not Connect Interrupt %d\n",
PortDeviceExtension->PortConfig.BusInterruptVector);
+ IoDeleteDevice(PortDeviceObject);
return(Status);
}
PortDeviceExtension->PortConfig.AdapterScansDown;
PortCapabilities->AdapterUsesPio = TRUE; /* FIXME */
- /* Initialize inquiry data */
- PortDeviceExtension->PortBusInfoSize = 0;
- PortDeviceExtension->PortBusInfo = NULL;
+ /* Initialize LUN-Extension list */
+ InitializeListHead(&PortDeviceExtension->LunExtensionListHead);
DPRINT("DeviceExtension %p\n", PortDeviceExtension);
- ScsiPortInquire(PortDeviceExtension);
-
/* FIXME: Copy more configuration data? */
}
+static PSCSI_PORT_LUN_EXTENSION
+SpiAllocateLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun)
+{
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+ ULONG LunExtensionSize;
+
+ DPRINT("SpiAllocateLunExtension (%p %u %u %u)\n",
+ DeviceExtension, PathId, TargetId, Lun);
+
+ LunExtensionSize =
+ sizeof(SCSI_PORT_LUN_EXTENSION) + DeviceExtension->LunExtensionSize;
+ DPRINT("LunExtensionSize %lu\n", LunExtensionSize);
+
+ LunExtension = ExAllocatePool(NonPagedPool,
+ LunExtensionSize);
+ if (LunExtension == NULL)
+ {
+ return NULL;
+ }
+
+ RtlZeroMemory(LunExtension,
+ LunExtensionSize);
+
+ InsertTailList(&DeviceExtension->LunExtensionListHead,
+ &LunExtension->List);
+
+ LunExtension->PathId = PathId;
+ LunExtension->TargetId = TargetId;
+ LunExtension->Lun = Lun;
+
+ KeInitializeDeviceQueue (&LunExtension->DeviceQueue);
+
+ return LunExtension;
+}
+
+
+static PSCSI_PORT_LUN_EXTENSION
+SpiGetLunExtension (IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ IN UCHAR PathId,
+ IN UCHAR TargetId,
+ IN UCHAR Lun)
+{
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+ PLIST_ENTRY Entry;
+
+ DPRINT("SpiGetLunExtension(%p %u %u %u) called\n",
+ DeviceExtension, PathId, TargetId, Lun);
+
+ if (IsListEmpty(&DeviceExtension->LunExtensionListHead))
+ return NULL;
+
+ Entry = DeviceExtension->LunExtensionListHead.Flink;
+ while (Entry != &DeviceExtension->LunExtensionListHead)
+ {
+ LunExtension = CONTAINING_RECORD(Entry,
+ SCSI_PORT_LUN_EXTENSION,
+ List);
+ if (LunExtension->PathId == PathId &&
+ LunExtension->TargetId == TargetId &&
+ LunExtension->Lun == Lun)
+ {
+ return LunExtension;
+ }
+
+ Entry = Entry->Flink;
+ }
+
+ return NULL;
+}
+
+
static VOID
-ScsiPortInquire(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
+SpiInquirePort(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
{
- PSCSI_ADAPTER_BUS_INFO AdapterInfo;
- PSCSI_INQUIRY_DATA UnitInfo, PrevUnit;
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
SCSI_REQUEST_BLOCK Srb;
ULONG Bus;
ULONG Target;
- ULONG UnitCount;
- ULONG DataSize;
+ ULONG Lun;
BOOLEAN Result;
- DPRINT("ScsiPortInquire() called\n");
+ DPRINT("SpiInquirePort() called\n");
DeviceExtension->Initializing = TRUE;
- /* Copy inquiry data to the port device extension */
- AdapterInfo =(PSCSI_ADAPTER_BUS_INFO)ExAllocatePool(NonPagedPool, 4096);
- RtlZeroMemory(AdapterInfo, 4096);
- AdapterInfo->NumberOfBuses = DeviceExtension->PortConfig.NumberOfBuses;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)
- ((PUCHAR)AdapterInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
- (sizeof(SCSI_BUS_DATA) * (AdapterInfo->NumberOfBuses - 1)));
-
RtlZeroMemory(&Srb,
sizeof(SCSI_REQUEST_BLOCK));
+ Srb.SrbFlags = SRB_FLAGS_DATA_IN;
Srb.DataBuffer = ExAllocatePool(NonPagedPool, 256);
Srb.Function = SRB_FUNCTION_EXECUTE_SCSI;
Srb.DataTransferLength = 256;
Srb.Cdb[0] = SCSIOP_INQUIRY;
- for (Bus = 0; Bus < AdapterInfo->NumberOfBuses; Bus++)
+ for (Bus = 0; Bus < DeviceExtension->PortConfig.NumberOfBuses; Bus++)
{
Srb.PathId = Bus;
- AdapterInfo->BusData[Bus].InitiatorBusId =
- DeviceExtension->PortConfig.InitiatorBusId[Bus];
- AdapterInfo->BusData[Bus].InquiryDataOffset =
- (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo);
-
- PrevUnit = NULL;
- UnitCount = 0;
-
for (Target = 0; Target < DeviceExtension->PortConfig.MaximumNumberOfTargets; Target++)
{
Srb.TargetId = Target;
- Srb.Lun = 0;
- Srb.SrbStatus = SRB_STATUS_SUCCESS;
-
- Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
- &Srb);
- DPRINT("Result: %s Srb.SrbStatus %lx\n", (Result)?"True":"False", Srb.SrbStatus);
- if (Result == TRUE && Srb.SrbStatus == SRB_STATUS_SUCCESS)
+ for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
{
- UnitInfo->PathId = Bus;
- UnitInfo->TargetId = Target;
- UnitInfo->Lun = 0;
- UnitInfo->InquiryDataLength = INQUIRYDATABUFFERSIZE;
- memcpy(&UnitInfo->InquiryData,
- Srb.DataBuffer,
- INQUIRYDATABUFFERSIZE);
- if (PrevUnit != NULL)
- PrevUnit->NextInquiryDataOffset = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
- PrevUnit = UnitInfo;
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)UnitInfo + sizeof(SCSI_INQUIRY_DATA)+INQUIRYDATABUFFERSIZE-1);
- UnitCount++;
+ Srb.Lun = Lun;
+ Srb.SrbStatus = SRB_STATUS_SUCCESS;
+
+ Result = DeviceExtension->HwStartIo(&DeviceExtension->MiniPortDeviceExtension,
+ &Srb);
+ DPRINT("Result %s Srb.SrbStatus %lx\n", (Result) ? "TRUE" : "FALSE", Srb.SrbStatus);
+
+ if (Result == TRUE && Srb.SrbStatus == SRB_STATUS_SUCCESS)
+ {
+ LunExtension = SpiAllocateLunExtension(DeviceExtension,
+ Bus,
+ Target,
+ Lun);
+ if (LunExtension != NULL)
+ {
+ /* Copy inquiry data */
+ memcpy(&LunExtension->InquiryData,
+ Srb.DataBuffer,
+ sizeof(INQUIRYDATA));
+ }
+ }
}
}
- DPRINT("UnitCount: %lu\n", UnitCount);
- AdapterInfo->BusData[Bus].NumberOfLogicalUnits = UnitCount;
- if (UnitCount == 0)
- AdapterInfo->BusData[Bus].InquiryDataOffset = 0;
}
- DataSize = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterInfo);
ExFreePool(Srb.DataBuffer);
DeviceExtension->Initializing = FALSE;
- /* copy inquiry data to the port driver's device extension */
- DeviceExtension->PortBusInfoSize = DataSize;
- DeviceExtension->PortBusInfo = ExAllocatePool(NonPagedPool,
- DataSize);
- RtlCopyMemory(DeviceExtension->PortBusInfo,
- AdapterInfo,
- DataSize);
+ DPRINT("SpiInquirePort() done\n");
+}
+
+
+static ULONG
+SpiGetInquiryData(IN PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ OUT PSCSI_ADAPTER_BUS_INFO AdapterBusInfo)
+{
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
+ PSCSI_INQUIRY_DATA UnitInfo, PrevUnit;
+ ULONG Bus;
+ ULONG Target;
+ ULONG Lun;
+ ULONG UnitCount;
+
+ DPRINT("SpiGetInquiryData() called\n");
+
+ /* Copy inquiry data to the port device extension */
+ AdapterBusInfo->NumberOfBuses = DeviceExtension->PortConfig.NumberOfBuses;
+
+ UnitInfo = (PSCSI_INQUIRY_DATA)
+ ((PUCHAR)AdapterBusInfo + sizeof(SCSI_ADAPTER_BUS_INFO) +
+ (sizeof(SCSI_BUS_DATA) * (AdapterBusInfo->NumberOfBuses - 1)));
+
+ for (Bus = 0; Bus < AdapterBusInfo->NumberOfBuses; Bus++)
+ {
+ AdapterBusInfo->BusData[Bus].InitiatorBusId =
+ DeviceExtension->PortConfig.InitiatorBusId[Bus];
+ AdapterBusInfo->BusData[Bus].InquiryDataOffset =
+ (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterBusInfo);
+
+ PrevUnit = NULL;
+ UnitCount = 0;
+
+ for (Target = 0; Target < DeviceExtension->PortConfig.MaximumNumberOfTargets; Target++)
+ {
+ for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
+ {
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ Bus,
+ Target,
+ Lun);
+ if (LunExtension != NULL)
+ {
+ DPRINT("(Bus %lu Target %lu Lun %lu)\n",
+ Bus, Target, Lun);
+
+ UnitInfo->PathId = Bus;
+ UnitInfo->TargetId = Target;
+ UnitInfo->Lun = Lun;
+ UnitInfo->InquiryDataLength = INQUIRYDATABUFFERSIZE;
+ memcpy(&UnitInfo->InquiryData,
+ &LunExtension->InquiryData,
+ INQUIRYDATABUFFERSIZE);
+ if (PrevUnit != NULL)
+ PrevUnit->NextInquiryDataOffset = (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterBusInfo);
+ PrevUnit = UnitInfo;
+ UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)UnitInfo + sizeof(SCSI_INQUIRY_DATA)+INQUIRYDATABUFFERSIZE-1);
+ UnitCount++;
+ }
+ }
+ }
+ DPRINT("UnitCount: %lu\n", UnitCount);
+ AdapterBusInfo->BusData[Bus].NumberOfLogicalUnits = UnitCount;
+ if (UnitCount == 0)
+ AdapterBusInfo->BusData[Bus].InquiryDataOffset = 0;
+ }
- ExFreePool(AdapterInfo);
+ DPRINT("Data size: %lu\n", (ULONG)UnitInfo - (ULONG)AdapterBusInfo);
- DPRINT("ScsiPortInquire() done\n");
+ return (ULONG)((PUCHAR)UnitInfo-(PUCHAR)AdapterBusInfo);
}
KIRQL oldIrql;
DPRINT("ScsiPortDpcForIsr(Dpc %p DpcDeviceObject %p DpcIrp %p DpcContext %p)\n",
- Dpc, DpcDeviceObject, DpcIrp, DpcContext);
+ Dpc, DpcDeviceObject, DpcIrp, DpcContext);
DeviceExtension = (PSCSI_PORT_DEVICE_EXTENSION)DpcContext;
KeAcquireSpinLock(&DeviceExtension->IrpLock, &oldIrql);
if (DeviceExtension->IrpFlags)
- {
- IrpStack = IoGetCurrentIrpStackLocation(DeviceExtension->CurrentIrp);
- Srb = IrpStack->Parameters.Scsi.Srb;
-
- if (DeviceExtension->OriginalSrb != NULL)
{
- DPRINT("Got sense data!\n");
-
- DPRINT("Valid: %x\n", DeviceExtension->InternalSenseData.Valid);
- DPRINT("ErrorCode: %x\n", DeviceExtension->InternalSenseData.ErrorCode);
- DPRINT("SenseKey: %x\n", DeviceExtension->InternalSenseData.SenseKey);
- DPRINT("SenseCode: %x\n", DeviceExtension->InternalSenseData.AdditionalSenseCode);
+ IrpStack = IoGetCurrentIrpStackLocation(DeviceExtension->CurrentIrp);
+ Srb = IrpStack->Parameters.Scsi.Srb;
- /* Copy sense data */
- if (DeviceExtension->OriginalSrb->SenseInfoBufferLength != 0)
+ if (DeviceExtension->OriginalSrb != NULL)
{
- RtlCopyMemory(DeviceExtension->OriginalSrb->SenseInfoBuffer,
- &DeviceExtension->InternalSenseData,
- sizeof(SENSE_DATA));
- DeviceExtension->OriginalSrb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
- }
+ DPRINT("Got sense data!\n");
- /* Clear current sense data */
- RtlZeroMemory(&DeviceExtension->InternalSenseData, sizeof(SENSE_DATA));
+ DPRINT("Valid: %x\n", DeviceExtension->InternalSenseData.Valid);
+ DPRINT("ErrorCode: %x\n", DeviceExtension->InternalSenseData.ErrorCode);
+ DPRINT("SenseKey: %x\n", DeviceExtension->InternalSenseData.SenseKey);
+ DPRINT("SenseCode: %x\n", DeviceExtension->InternalSenseData.AdditionalSenseCode);
- IrpStack->Parameters.Scsi.Srb = DeviceExtension->OriginalSrb;
- DeviceExtension->OriginalSrb = NULL;
- }
- else if ((SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) &&
- (Srb->ScsiStatus == SCSISTAT_CHECK_CONDITION))
- {
- DPRINT("SCSIOP_REQUEST_SENSE required!\n");
+ /* Copy sense data */
+ if (DeviceExtension->OriginalSrb->SenseInfoBufferLength != 0)
+ {
+ RtlCopyMemory(DeviceExtension->OriginalSrb->SenseInfoBuffer,
+ &DeviceExtension->InternalSenseData,
+ sizeof(SENSE_DATA));
+ DeviceExtension->OriginalSrb->SrbStatus |= SRB_STATUS_AUTOSENSE_VALID;
+ }
- DeviceExtension->OriginalSrb = Srb;
- IrpStack->Parameters.Scsi.Srb = ScsiPortInitSenseRequestSrb(DeviceExtension,
- Srb);
- KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
- if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
- ScsiPortStartPacket,
- DeviceExtension))
- {
- DPRINT("Synchronization failed!\n");
+ /* Clear current sense data */
+ RtlZeroMemory(&DeviceExtension->InternalSenseData, sizeof(SENSE_DATA));
- DpcIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- DpcIrp->IoStatus.Information = 0;
- IoCompleteRequest(DpcIrp,
- IO_NO_INCREMENT);
- IoStartNextPacket(DpcDeviceObject,
- FALSE);
+ IrpStack->Parameters.Scsi.Srb = DeviceExtension->OriginalSrb;
+ DeviceExtension->OriginalSrb = NULL;
}
+ else if ((SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) &&
+ (Srb->ScsiStatus == SCSISTAT_CHECK_CONDITION))
+ {
+ DPRINT("SCSIOP_REQUEST_SENSE required!\n");
- return;
- }
+ DeviceExtension->OriginalSrb = Srb;
+ IrpStack->Parameters.Scsi.Srb = ScsiPortInitSenseRequestSrb(DeviceExtension,
+ Srb);
+ KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
+ if (!KeSynchronizeExecution(DeviceExtension->Interrupt,
+ ScsiPortStartPacket,
+ DeviceExtension))
+ {
+ DPRINT1("Synchronization failed!\n");
+
+ DpcIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ DpcIrp->IoStatus.Information = 0;
+ IoCompleteRequest(DpcIrp,
+ IO_NO_INCREMENT);
+ IoStartNextPacket(DpcDeviceObject,
+ FALSE);
+ }
- DeviceExtension->CurrentIrp = NULL;
+ return;
+ }
+ DeviceExtension->CurrentIrp = NULL;
-// DpcIrp->IoStatus.Information = 0;
-// DpcIrp->IoStatus.Status = STATUS_SUCCESS;
+// DpcIrp->IoStatus.Information = 0;
+// DpcIrp->IoStatus.Status = STATUS_SUCCESS;
- if (DeviceExtension->IrpFlags & IRP_FLAG_COMPLETE)
- {
- DeviceExtension->IrpFlags &= ~IRP_FLAG_COMPLETE;
- IoCompleteRequest(DpcIrp, IO_NO_INCREMENT);
- }
+ if (DeviceExtension->IrpFlags & IRP_FLAG_COMPLETE)
+ {
+ DeviceExtension->IrpFlags &= ~IRP_FLAG_COMPLETE;
+ IoCompleteRequest(DpcIrp, IO_NO_INCREMENT);
+ }
- if (DeviceExtension->IrpFlags & IRP_FLAG_NEXT)
- {
- DeviceExtension->IrpFlags &= ~IRP_FLAG_NEXT;
- KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
- IoStartNextPacket(DpcDeviceObject, FALSE);
+ if (DeviceExtension->IrpFlags & IRP_FLAG_NEXT)
+ {
+ DeviceExtension->IrpFlags &= ~IRP_FLAG_NEXT;
+ KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
+ IoStartNextPacket(DpcDeviceObject, FALSE);
+ }
+ else
+ {
+ KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
+ }
}
- else
+ else
{
KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
}
- }
- else
- {
- KeReleaseSpinLock(&DeviceExtension->IrpLock, oldIrql);
- }
+
DPRINT("ScsiPortDpcForIsr() done\n");
}
/**********************************************************************
* NAME INTERNAL
- * ScsiPortBuildDeviceMap
+ * SpiBuildDeviceMap
*
* DESCRIPTION
* Builds the registry device map of all device which are attached
*/
static NTSTATUS
-ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
- PUNICODE_STRING RegistryPath)
+SpiBuildDeviceMap (PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ PUNICODE_STRING RegistryPath)
{
+ PSCSI_PORT_LUN_EXTENSION LunExtension;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
UNICODE_STRING ValueName;
WCHAR NameBuffer[64];
ULONG Disposition;
HANDLE ScsiKey;
- HANDLE ScsiPortKey;
- HANDLE ScsiBusKey;
- HANDLE ScsiInitiatorKey;
- HANDLE ScsiTargetKey;
- HANDLE ScsiLunKey;
+ HANDLE ScsiPortKey = NULL;
+ HANDLE ScsiBusKey = NULL;
+ HANDLE ScsiInitiatorKey = NULL;
+ HANDLE ScsiTargetKey = NULL;
+ HANDLE ScsiLunKey = NULL;
ULONG BusNumber;
- UCHAR CurrentTarget;
- PSCSI_ADAPTER_BUS_INFO AdapterInfo;
- PSCSI_INQUIRY_DATA UnitInfo;
- PINQUIRYDATA InquiryData;
+ ULONG Target;
+ ULONG CurrentTarget;
+ ULONG Lun;
PWCHAR DriverName;
ULONG UlongData;
PWCHAR TypeName;
NTSTATUS Status;
- DPRINT("ScsiPortBuildDeviceMap() called\n");
+ DPRINT("SpiBuildDeviceMap() called\n");
if (DeviceExtension == NULL || RegistryPath == NULL)
{
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
- ZwClose(ScsiPortKey);
- return(Status);
+ goto ByeBye;
}
/* Create 'Initiator Id X' key */
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
- ZwClose(ScsiBusKey);
- ZwClose(ScsiPortKey);
- return(Status);
+ goto ByeBye;
}
/* FIXME: Are there any initiator values (??) */
ZwClose(ScsiInitiatorKey);
+ ScsiInitiatorKey = NULL;
/* Enumerate targets */
- CurrentTarget = (UCHAR)-1;
+ CurrentTarget = (ULONG)-1;
ScsiTargetKey = NULL;
- AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
- if (AdapterInfo->BusData[BusNumber].NumberOfLogicalUnits != 0)
+ for (Target = 0; Target < DeviceExtension->PortConfig.MaximumNumberOfTargets; Target++)
{
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
- AdapterInfo->BusData[BusNumber].InquiryDataOffset);
-
- while (AdapterInfo->BusData[BusNumber].InquiryDataOffset)
+ for (Lun = 0; Lun < SCSI_MAXIMUM_LOGICAL_UNITS; Lun++)
{
- if (UnitInfo->TargetId != CurrentTarget)
+ LunExtension = SpiGetLunExtension(DeviceExtension,
+ BusNumber,
+ Target,
+ Lun);
+ if (LunExtension != NULL)
{
- /* Close old target key */
- if (ScsiTargetKey != NULL)
+ if (Target != CurrentTarget)
{
- ZwClose(ScsiTargetKey);
- ScsiTargetKey = NULL;
+ /* Close old target key */
+ if (ScsiTargetKey != NULL)
+ {
+ ZwClose(ScsiTargetKey);
+ ScsiTargetKey = NULL;
+ }
+
+ /* Create 'Target Id X' key */
+ DPRINT(" Target Id %lu\n", Target);
+ swprintf(NameBuffer,
+ L"Target Id %lu",
+ Target);
+ RtlInitUnicodeString(&KeyName,
+ NameBuffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ 0,
+ ScsiBusKey,
+ NULL);
+ Status = ZwCreateKey(&ScsiTargetKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ goto ByeBye;
+ }
+
+ CurrentTarget = Target;
}
- /* Create 'Target Id X' key */
- DPRINT(" Target Id %u\n",
- UnitInfo->TargetId);
+ /* Create 'Logical Unit Id X' key */
+ DPRINT(" Logical Unit Id %lu\n", Lun);
swprintf(NameBuffer,
- L"Target Id %u",
- UnitInfo->TargetId);
+ L"Logical Unit Id %lu",
+ Lun);
RtlInitUnicodeString(&KeyName,
NameBuffer);
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
0,
- ScsiBusKey,
+ ScsiTargetKey,
NULL);
- Status = ZwCreateKey(&ScsiTargetKey,
+ Status = ZwCreateKey(&ScsiLunKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
if (!NT_SUCCESS(Status))
{
DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
- ZwClose(ScsiBusKey);
- ZwClose(ScsiPortKey);
- return(Status);
+ goto ByeBye;
}
- CurrentTarget = UnitInfo->TargetId;
- }
-
- /* Create 'Logical Unit Id X' key */
- DPRINT(" Logical Unit Id %u\n",
- UnitInfo->Lun);
- swprintf(NameBuffer,
- L"Logical Unit Id %u",
- UnitInfo->Lun);
- RtlInitUnicodeString(&KeyName,
- NameBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
+ /* Set 'Identifier' (REG_SZ) value */
+ swprintf(NameBuffer,
+ L"%.8S%.16S%.4S",
+ LunExtension->InquiryData.VendorId,
+ LunExtension->InquiryData.ProductId,
+ LunExtension->InquiryData.ProductRevisionLevel);
+ DPRINT(" Identifier = '%S'\n", NameBuffer);
+ RtlInitUnicodeString(&ValueName,
+ L"Identifier");
+ Status = ZwSetValueKey(ScsiLunKey,
+ &ValueName,
0,
- ScsiTargetKey,
- NULL);
- Status = ZwCreateKey(&ScsiLunKey,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
- ZwClose(ScsiTargetKey);
- ZwClose(ScsiBusKey);
- ZwClose(ScsiPortKey);
- return(Status);
- }
+ REG_SZ,
+ NameBuffer,
+ (wcslen(NameBuffer) + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status);
+ goto ByeBye;
+ }
- /* Set values for logical unit */
- InquiryData = (PINQUIRYDATA)UnitInfo->InquiryData;
-
- /* Set 'Identifier' (REG_SZ) value */
- swprintf(NameBuffer,
- L"%.8S%.16S%.4S",
- InquiryData->VendorId,
- InquiryData->ProductId,
- InquiryData->ProductRevisionLevel);
- DPRINT(" Identifier = '%S'\n",
- NameBuffer);
- RtlInitUnicodeString(&ValueName,
- L"Identifier");
- Status = ZwSetValueKey(ScsiLunKey,
- &ValueName,
- 0,
- REG_SZ,
- NameBuffer,
- (wcslen(NameBuffer) + 1) * sizeof(WCHAR));
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwSetValueKey('Identifier') failed (Status %lx)\n", Status);
- ZwClose(ScsiLunKey);
- ZwClose(ScsiTargetKey);
- ZwClose(ScsiBusKey);
- ZwClose(ScsiPortKey);
- return(Status);
- }
+ /* Set 'Type' (REG_SZ) value */
+ switch (LunExtension->InquiryData.DeviceType)
+ {
+ case 0:
+ TypeName = L"DiskPeripheral";
+ break;
+ case 1:
+ TypeName = L"TapePeripheral";
+ break;
+ case 2:
+ TypeName = L"PrinterPeripheral";
+ break;
+ case 4:
+ TypeName = L"WormPeripheral";
+ break;
+ case 5:
+ TypeName = L"CdRomPeripheral";
+ break;
+ case 6:
+ TypeName = L"ScannerPeripheral";
+ break;
+ case 7:
+ TypeName = L"OpticalDiskPeripheral";
+ break;
+ case 8:
+ TypeName = L"MediumChangerPeripheral";
+ break;
+ case 9:
+ TypeName = L"CommunicationPeripheral";
+ break;
+ default:
+ TypeName = L"OtherPeripheral";
+ break;
+ }
+ DPRINT(" Type = '%S'\n", TypeName);
+ RtlInitUnicodeString(&ValueName,
+ L"Type");
+ Status = ZwSetValueKey(ScsiLunKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ TypeName,
+ (wcslen(TypeName) + 1) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
+ goto ByeBye;
+ }
- /* Set 'Type' (REG_SZ) value */
- switch (InquiryData->DeviceType)
- {
- case 0:
- TypeName = L"DiskPeripheral";
- break;
- case 1:
- TypeName = L"TapePeripheral";
- break;
- case 2:
- TypeName = L"PrinterPeripheral";
- break;
- case 4:
- TypeName = L"WormPeripheral";
- break;
- case 5:
- TypeName = L"CdRomPeripheral";
- break;
- case 6:
- TypeName = L"ScannerPeripheral";
- break;
- case 7:
- TypeName = L"OpticalDiskPeripheral";
- break;
- case 8:
- TypeName = L"MediumChangerPeripheral";
- break;
- case 9:
- TypeName = L"CommunicationPeripheral";
- break;
- default:
- TypeName = L"OtherPeripheral";
- break;
- }
- DPRINT(" Type = '%S'\n", TypeName);
- RtlInitUnicodeString(&ValueName,
- L"Type");
- Status = ZwSetValueKey(ScsiLunKey,
- &ValueName,
- 0,
- REG_SZ,
- TypeName,
- (wcslen(TypeName) + 1) * sizeof(WCHAR));
- if (!NT_SUCCESS(Status))
- {
- DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
ZwClose(ScsiLunKey);
- ZwClose(ScsiTargetKey);
- ZwClose(ScsiBusKey);
- ZwClose(ScsiPortKey);
- return(Status);
+ ScsiLunKey = NULL;
}
-
- ZwClose(ScsiLunKey);
-
- if (UnitInfo->NextInquiryDataOffset == 0)
- break;
-
- UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
- UnitInfo->NextInquiryDataOffset);
}
/* Close old target key */
}
}
- ZwClose(ScsiBusKey);
- }
+ ZwClose(ScsiBusKey);
+ ScsiBusKey = NULL;
+ }
- ZwClose(ScsiPortKey);
+ByeBye:
+ if (ScsiLunKey != NULL)
+ ZwClose (ScsiLunKey);
- DPRINT("ScsiPortBuildDeviceMap() done\n");
+ if (ScsiInitiatorKey != NULL)
+ ZwClose (ScsiInitiatorKey);
- return(Status);
+ if (ScsiTargetKey != NULL)
+ ZwClose (ScsiTargetKey);
+
+ if (ScsiBusKey != NULL)
+ ZwClose (ScsiBusKey);
+
+ if (ScsiPortKey != NULL)
+ ZwClose (ScsiPortKey);
+
+ DPRINT("SpiBuildDeviceMap() done\n");
+
+ return Status;
}
/* EOF */