/* TYPES *********************************************************************/
-
+/*
+ * SCSI_PORT_TIMER_STATES
+ *
+ * DESCRIPTION
+ * An enumeration containing the states in the timer DFA
+ */
typedef enum _SCSI_PORT_TIMER_STATES
{
IDETimerIdle,
} 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
*
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;
-/*
- * SCSI_PORT_TIMER_STATES
- *
- * DESCRIPTION
- * An enumeration containing the states in the timer DFA
- */
-
-
-
#define IRP_FLAG_COMPLETE 0x00000001
#define IRP_FLAG_NEXT 0x00000002
static NTSTATUS
ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension,
- IN ULONG PortCount);
+ IN ULONG PortCount,
+ IN OUT PSCSI_PORT_DEVICE_EXTENSION *RealDeviceExtension);
static VOID
ScsiPortInquire(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension);
ScsiPortInitSenseRequestSrb(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
PSCSI_REQUEST_BLOCK OriginalSrb);
+static NTSTATUS
+ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ PUNICODE_STRING RegistryPath);
+
+
/* FUNCTIONS *****************************************************************/
/**********************************************************************
IN UCHAR Lun,
IN UCHAR SrbStatus)
{
+ DPRINT("ScsiPortCompleteRequest()\n");
UNIMPLEMENTED;
}
ULONG STDCALL
ScsiPortConvertPhysicalAddressToUlong(IN SCSI_PHYSICAL_ADDRESS Address)
{
+ DPRINT("ScsiPortConvertPhysicalAddressToUlong()\n");
return(Address.u.LowPart);
}
VOID STDCALL
ScsiPortFlushDma(IN PVOID HwDeviceExtension)
{
+ DPRINT("ScsiPortFlushDma()\n");
UNIMPLEMENTED;
}
ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension,
IN PVOID MappedAddress)
{
- UNIMPLEMENTED;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
+ PSCSI_PORT_DEVICE_BASE DeviceBase;
+ PLIST_ENTRY Entry;
+
+ DPRINT("ScsiPortFreeDeviceBase() called\n");
+
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
+ if (IsListEmpty(&DeviceExtension->DeviceBaseListHead))
+ return;
+
+ Entry = DeviceExtension->DeviceBaseListHead.Flink;
+ while (Entry != &DeviceExtension->DeviceBaseListHead)
+ {
+ DeviceBase = CONTAINING_RECORD(Entry,
+ SCSI_PORT_DEVICE_BASE,
+ List);
+ if (DeviceBase->MappedAddress == MappedAddress)
+ {
+ MmUnmapIoSpace(DeviceBase->MappedAddress,
+ DeviceBase->NumberOfBytes);
+ RemoveEntryList(Entry);
+ ExFreePool(DeviceBase);
+
+ return;
+ }
+
+ Entry = Entry->Flink;
+ }
}
IN ULONG NumberOfBytes,
IN BOOLEAN InIoSpace)
{
- ULONG AddressSpace;
+ PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PHYSICAL_ADDRESS TranslatedAddress;
- PVOID VirtualAddress;
- PVOID Buffer;
- BOOLEAN rc;
+ PSCSI_PORT_DEVICE_BASE DeviceBase;
+ ULONG AddressSpace;
+ PVOID MappedAddress;
- AddressSpace = (ULONG)InIoSpace;
+ DPRINT("ScsiPortGetDeviceBase() called\n");
- if (!HalTranslateBusAddress(BusType,
- SystemIoBusNumber,
- IoAddress,
- &AddressSpace,
- &TranslatedAddress))
+ AddressSpace = (ULONG)InIoSpace;
+ if (HalTranslateBusAddress(BusType,
+ SystemIoBusNumber,
+ IoAddress,
+ &AddressSpace,
+ &TranslatedAddress) == FALSE)
return NULL;
/* i/o space */
if (AddressSpace != 0)
- return (PVOID)TranslatedAddress.u.LowPart;
+ return((PVOID)TranslatedAddress.u.LowPart);
+
+ MappedAddress = MmMapIoSpace(TranslatedAddress,
+ NumberOfBytes,
+ FALSE);
+
+ DeviceBase = ExAllocatePool(NonPagedPool,
+ sizeof(SCSI_PORT_DEVICE_BASE));
+ if (DeviceBase == NULL)
+ return(MappedAddress);
- VirtualAddress = MmMapIoSpace(TranslatedAddress,
- NumberOfBytes,
- FALSE);
+ DeviceBase->MappedAddress = MappedAddress;
+ DeviceBase->NumberOfBytes = NumberOfBytes;
+ DeviceBase->IoAddress = IoAddress;
+ DeviceBase->SystemIoBusNumber = SystemIoBusNumber;
- Buffer = ExAllocatePool(NonPagedPool,0x20);
- if (Buffer == NULL)
- return VirtualAddress;
+ DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
+ SCSI_PORT_DEVICE_EXTENSION,
+ MiniPortDeviceExtension);
- return NULL; /* ?? */
+ InsertHeadList(&DeviceExtension->DeviceBaseListHead,
+ &DeviceBase->List);
+
+ return(MappedAddress);
}
IN UCHAR TargetId,
IN UCHAR Lun)
{
+ DPRINT("ScsiPortGetLogicalUnit()\n");
UNIMPLEMENTED;
}
IN PVOID VirtualAddress,
OUT ULONG *Length)
{
+ DPRINT("ScsiPortGetPhysicalAddress()\n");
UNIMPLEMENTED;
}
IN UCHAR Lun,
IN LONG QueueTag)
{
+ DPRINT("ScsiPortGetSrb()\n");
UNIMPLEMENTED;
}
IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
IN ULONG NumberOfBytes)
{
+ DPRINT("ScsiPortGetUncachedExtension()\n");
UNIMPLEMENTED;
}
ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension,
IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
{
+ DPRINT("ScsiPortGetVirtualAddress()\n");
UNIMPLEMENTED;
}
PDRIVER_OBJECT DriverObject = (PDRIVER_OBJECT)Argument1;
PUNICODE_STRING RegistryPath = (PUNICODE_STRING)Argument2;
PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension;
+ PSCSI_PORT_DEVICE_EXTENSION RealDeviceExtension;
PCONFIGURATION_INFORMATION SystemConfig;
PPORT_CONFIGURATION_INFORMATION PortConfig;
BOOLEAN Again;
ExAllocatePool(PagedPool,
sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges);
+ for (i = 0; i < SCSI_MAXIMUM_BUSES; i++)
+ PortConfig->InitiatorBusId[i] = 255;
PortConfig->SystemIoBusNumber = 0;
PortConfig->SlotNumber = 0;
{
DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber);
+ InitializeListHead(&PseudoDeviceExtension->DeviceBaseListHead);
+
// RtlZeroMemory(AccessRanges,
// sizeof(ACCESS_RANGE) * PortConfig->NumberOfAccessRanges);
Status = ScsiPortCreatePortDevice(DriverObject,
PseudoDeviceExtension,
- SystemConfig->ScsiPortCount);
+ SystemConfig->ScsiPortCount,
+ &RealDeviceExtension);
if (!NT_SUCCESS(Status))
{
return(Status);
}
+ /* Build the registry device map */
+ ScsiPortBuildDeviceMap(RealDeviceExtension,
+ (PUNICODE_STRING)Argument2);
+
/* Update the configuration info */
SystemConfig->AtDiskPrimaryAddressClaimed = PortConfig->AtdiskPrimaryClaimed;
SystemConfig->AtDiskSecondaryAddressClaimed = PortConfig->AtdiskSecondaryClaimed;
IN ULONG LogicalAddress,
IN ULONG Length)
{
+ DPRINT("ScsiPortIoMapTransfer()\n");
UNIMPLEMENTED;
}
IN ULONG ErrorCode,
IN ULONG UniqueId)
{
+ DPRINT("ScsiPortLogError()\n");
UNIMPLEMENTED;
}
IN ULONG Offset,
IN ULONG Length)
{
+ DPRINT("ScsiPortSetBusDataByOffset()\n");
return(HalSetBusDataByOffset(BusDataType,
SystemIoBusNumber,
SlotNumber,
IN ULONG NumberOfBytes,
IN BOOLEAN InIoSpace)
{
+ DPRINT("ScsiPortValidateRange()\n");
return(TRUE);
}
static NTSTATUS
ScsiPortCreatePortDevice(IN PDRIVER_OBJECT DriverObject,
IN PSCSI_PORT_DEVICE_EXTENSION PseudoDeviceExtension,
- IN ULONG PortNumber)
+ IN ULONG PortNumber,
+ IN OUT PSCSI_PORT_DEVICE_EXTENSION *RealDeviceExtension)
{
PSCSI_PORT_DEVICE_EXTENSION PortDeviceExtension;
PIO_SCSI_CAPABILITIES PortCapabilities;
UNICODE_STRING DosDeviceName;
NTSTATUS Status;
ULONG AccessRangeSize;
-
-#if 0
ULONG MappedIrq;
KIRQL Dirql;
KAFFINITY Affinity;
-#endif
DPRINT("ScsiPortCreatePortDevice() called\n");
-#if 0
+ *RealDeviceExtension = NULL;
+
MappedIrq = HalGetInterruptVector(PseudoDeviceExtension->PortConfig.AdapterInterfaceType,
PseudoDeviceExtension->PortConfig.SystemIoBusNumber,
- 0,
PseudoDeviceExtension->PortConfig.BusInterruptLevel,
+ PseudoDeviceExtension->PortConfig.BusInterruptVector,
&Dirql,
&Affinity);
-#endif
/* Create a unicode device name */
swprintf(NameBuffer,
PseudoDeviceExtension->PortConfig.AccessRanges,
AccessRangeSize);
+ /* Copy device base list */
+ if (IsListEmpty(&PseudoDeviceExtension->DeviceBaseListHead))
+ {
+ InitializeListHead(&PortDeviceExtension->DeviceBaseListHead);
+ }
+ else
+ {
+ PseudoDeviceExtension->DeviceBaseListHead.Flink =
+ PortDeviceExtension->DeviceBaseListHead.Flink;
+ PseudoDeviceExtension->DeviceBaseListHead.Blink =
+ PortDeviceExtension->DeviceBaseListHead.Blink;
+ PortDeviceExtension->DeviceBaseListHead.Blink->Flink =
+ &PortDeviceExtension->DeviceBaseListHead;
+ PortDeviceExtension->DeviceBaseListHead.Flink->Blink =
+ &PortDeviceExtension->DeviceBaseListHead;
+ }
+
PortDeviceExtension->DeviceObject = PortDeviceObject;
PortDeviceExtension->PortNumber = PortNumber;
ScsiPortIsr,
PortDeviceExtension,
&PortDeviceExtension->SpinLock,
- PortDeviceExtension->PortConfig.BusInterruptVector, // MappedIrq,
- PortDeviceExtension->PortConfig.BusInterruptLevel, // Dirql,
- 15, //Dirql,
+ MappedIrq,
+ Dirql,
+ Dirql,
PortDeviceExtension->PortConfig.InterruptMode,
- FALSE,
- 0xFFFF, //Affinity,
+ TRUE,
+ Affinity,
FALSE);
if (!NT_SUCCESS(Status))
{
/* FIXME: Copy more configuration data? */
+
/* Create the dos device link */
swprintf(DosNameBuffer,
L"\\??\\Scsi%lu:",
IoCreateSymbolicLink(&DosDeviceName,
&DeviceName);
+ *RealDeviceExtension = PortDeviceExtension;
+
DPRINT("ScsiPortCreatePortDevice() done\n");
return(STATUS_SUCCESS);
{
Srb.PathId = Bus;
- AdapterInfo->BusData[Bus].InitiatorBusId = 0; /* ? */
+ AdapterInfo->BusData[Bus].InitiatorBusId =
+ DeviceExtension->PortConfig.InitiatorBusId[Bus];
AdapterInfo->BusData[Bus].InquiryDataOffset =
- (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo);
+ (ULONG)((PUCHAR)UnitInfo - (PUCHAR)AdapterInfo);
PrevUnit = NULL;
UnitCount = 0;
}
-#if 0
+/**********************************************************************
+ * NAME INTERNAL
+ * ScsiPortBuildDeviceMap
+ *
+ * DESCRIPTION
+ * Builds the registry device map of all device which are attached
+ * to the given SCSI HBA port. The device map is located at:
+ * \Registry\Machine\DeviceMap\Scsi
+ *
+ * RUN LEVEL
+ * PASSIVE_LEVEL
+ *
+ * ARGUMENTS
+ * DeviceExtension
+ * ...
+ *
+ * RegistryPath
+ * Name of registry driver service key.
+ *
+ * RETURNS
+ * NTSTATUS
+ */
+
static NTSTATUS
-ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension)
+ScsiPortBuildDeviceMap(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension,
+ PUNICODE_STRING RegistryPath)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
- WCHAR NameBuffer[32];
+ UNICODE_STRING ValueName;
+ WCHAR NameBuffer[64];
ULONG Disposition;
HANDLE ScsiKey;
HANDLE ScsiPortKey;
HANDLE ScsiBusKey;
+ HANDLE ScsiInitiatorKey;
HANDLE ScsiTargetKey;
- HANDLE ScsiUnitKey;
+ HANDLE ScsiLunKey;
ULONG BusNumber;
+ UCHAR CurrentTarget;
+ PSCSI_ADAPTER_BUS_INFO AdapterInfo;
+ PSCSI_INQUIRY_DATA UnitInfo;
+ PINQUIRYDATA InquiryData;
+ PWCHAR DriverName;
+ ULONG UlongData;
+ PWCHAR TypeName;
NTSTATUS Status;
+ DPRINT("ScsiPortBuildDeviceMap() called\n");
+
+ if (DeviceExtension == NULL || RegistryPath == NULL)
+ {
+ DPRINT1("Invalid parameter\n");
+ return(STATUS_INVALID_PARAMETER);
+ }
+
/* Open or create the 'Scsi' subkey */
RtlInitUnicodeStringFromLiteral(&KeyName,
- L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
+ L"\\Registry\\Machine\\Hardware\\DeviceMap\\Scsi");
InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- OBJ_OPENIF,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
0,
NULL);
- Status = NtCreateKey(&ScsiKey,
+ Status = ZwCreateKey(&ScsiKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
REG_OPTION_VOLATILE,
&Disposition);
if (!NT_SUCCESS(Status))
- return(Status);
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ return(Status);
+ }
/* Create new 'Scsi Port X' subkey */
+ DPRINT("Scsi Port %lu\n",
+ DeviceExtension->PortNumber);
+
swprintf(NameBuffer,
L"Scsi Port %lu",
DeviceExtension->PortNumber);
0,
ScsiKey,
NULL);
- Status = NtCreateKey(&ScsiPortKey,
+ Status = ZwCreateKey(&ScsiPortKey,
KEY_ALL_ACCESS,
&ObjectAttributes,
0,
NULL,
REG_OPTION_VOLATILE,
&Disposition);
+ ZwClose(ScsiKey);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ return(Status);
+ }
+
+ /*
+ * Create port-specific values
+ */
+
+ /* Set 'DMA Enabled' (REG_DWORD) value */
+ UlongData = (ULONG)!DeviceExtension->PortCapabilities->AdapterUsesPio;
+ DPRINT(" DMA Enabled = %s\n", (UlongData) ? "TRUE" : "FALSE");
+ RtlInitUnicodeString(&ValueName,
+ L"DMA Enabled");
+ Status = ZwSetValueKey(ScsiPortKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ &UlongData,
+ sizeof(ULONG));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('DMA Enabled') failed (Status %lx)\n", Status);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
+
+ /* Set 'Driver' (REG_SZ) value */
+ DriverName = wcsrchr(RegistryPath->Buffer, L'\\') + 1;
+ DPRINT(" Driver = '%S'\n", DriverName);
+ RtlInitUnicodeString(&ValueName,
+ L"Driver");
+ Status = ZwSetValueKey(ScsiPortKey,
+ &ValueName,
+ 0,
+ REG_SZ,
+ DriverName,
+ wcslen(DriverName) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('Driver') failed (Status %lx)\n", Status);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
+
+ /* Set 'Interrupt' (REG_DWORD) value (NT4 only) */
+ UlongData = (ULONG)DeviceExtension->PortConfig.BusInterruptLevel;
+ DPRINT(" Interrupt = %lu\n", UlongData);
+ RtlInitUnicodeString(&ValueName,
+ L"Interrupt");
+ Status = ZwSetValueKey(ScsiPortKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ &UlongData,
+ sizeof(ULONG));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('Interrupt') failed (Status %lx)\n", Status);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
+
+ /* Set 'IOAddress' (REG_DWORD) value (NT4 only) */
+ UlongData = ScsiPortConvertPhysicalAddressToUlong(DeviceExtension->PortConfig.AccessRanges[0].RangeStart);
+ DPRINT(" IOAddress = %lx\n", UlongData);
+ RtlInitUnicodeString(&ValueName,
+ L"IOAddress");
+ Status = ZwSetValueKey(ScsiPortKey,
+ &ValueName,
+ 0,
+ REG_DWORD,
+ &UlongData,
+ sizeof(ULONG));
if (!NT_SUCCESS(Status))
{
- NtClose(ScsiKey);
+ DPRINT("ZwSetValueKey('IOAddress') failed (Status %lx)\n", Status);
+ ZwClose(ScsiPortKey);
return(Status);
}
- /* Add port-specific values */
+ /* Enumerate buses */
+ for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig.NumberOfBuses; BusNumber++)
+ {
+ /* Create 'Scsi Bus X' key */
+ DPRINT(" Scsi Bus %lu\n", BusNumber);
+ swprintf(NameBuffer,
+ L"Scsi Bus %lu",
+ BusNumber);
+ RtlInitUnicodeString(&KeyName,
+ NameBuffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ 0,
+ ScsiPortKey,
+ NULL);
+ Status = ZwCreateKey(&ScsiBusKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
- /* 'DMA Enabled' (REG_DWORD) */
- DPRINT1("DMA Enabled = %s\n",
- (DeviceExtension->PortCapabilities->AdapterUsesPio)?"TRUE":"FALSE");
+ /* Create 'Initiator Id X' key */
+ DPRINT(" Initiator Id %u\n",
+ DeviceExtension->PortConfig.InitiatorBusId[BusNumber]);
+ swprintf(NameBuffer,
+ L"Initiator Id %u",
+ DeviceExtension->PortConfig.InitiatorBusId[BusNumber]);
+ RtlInitUnicodeString(&KeyName,
+ NameBuffer);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ 0,
+ ScsiBusKey,
+ NULL);
+ Status = ZwCreateKey(&ScsiInitiatorKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ ZwClose(ScsiBusKey);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
- /* 'Driver' (REG_SZ) */
+ /* FIXME: Are there any initiator values (??) */
- /* 'Interrupt' (REG_DWORD) (NT4 only) */
- DPRINT1("Interrupt = %lx\n", DeviceExtension->PortConfig.BusInterruptLevel);
+ ZwClose(ScsiInitiatorKey);
- /* 'IOAddress' (REG_DWORD) (NT4 only) */
- DPRINT1("IOAddress = %lx\n",
- ScsiPortConvertPhysicalAddressToUlong(DeviceExtension->PortConfig.AccessRanges[0].RangeStart));
+ /* Enumerate targets */
+ CurrentTarget = (UCHAR)-1;
+ ScsiTargetKey = NULL;
+ AdapterInfo = (PSCSI_ADAPTER_BUS_INFO)DeviceExtension->PortBusInfo;
+ if (AdapterInfo->BusData[BusNumber].NumberOfLogicalUnits != 0)
+ {
+ UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
+ AdapterInfo->BusData[BusNumber].InquiryDataOffset);
- /* Create 'Scsi Bus X' keys */
- for (BusNumber = 0; BusNumber < DeviceExtension->PortConfig.NumberOfBuses; BusNumber++)
- {
- swprintf(NameBuffer,
- L"Scsi Bus %lu",
- DeviceExtension->PortNumber);
- RtlInitUnicodeString(&KeyName,
- NameBuffer);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
+ while (AdapterInfo->BusData[BusNumber].InquiryDataOffset)
+ {
+ if (UnitInfo->TargetId != CurrentTarget)
+ {
+ /* Close old target key */
+ if (ScsiTargetKey != NULL)
+ {
+ ZwClose(ScsiTargetKey);
+ ScsiTargetKey = NULL;
+ }
+
+ /* Create 'Target Id X' key */
+ DPRINT(" Target Id %u\n",
+ UnitInfo->TargetId);
+ swprintf(NameBuffer,
+ L"Target Id %u",
+ UnitInfo->TargetId);
+ 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);
+ ZwClose(ScsiBusKey);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
+
+ 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,
+ 0,
+ ScsiTargetKey,
+ NULL);
+ Status = ZwCreateKey(&ScsiLunKey,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
0,
- ScsiPortKey,
- NULL);
- Status = NtCreateKey(&ScsiBusKey,
- KEY_ALL_ACCESS,
- &ObjectAttributes,
- 0,
- NULL,
- REG_OPTION_VOLATILE,
- &Disposition);
- if (!NT_SUCCESS(Status))
- {
- NtClose(ScsiPortKey);
- NtClose(ScsiKey);
- return(Status);
- }
+ NULL,
+ REG_OPTION_VOLATILE,
+ &Disposition);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwCreateKey() failed (Status %lx)\n", Status);
+ ZwClose(ScsiTargetKey);
+ ZwClose(ScsiBusKey);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
- /* Create target keys */
+ /* 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) * 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 (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) * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("ZwSetValueKey('Type') failed (Status %lx)\n", Status);
+ ZwClose(ScsiLunKey);
+ ZwClose(ScsiTargetKey);
+ ZwClose(ScsiBusKey);
+ ZwClose(ScsiPortKey);
+ return(Status);
+ }
- NtClose(ScsiBusKey);
+ ZwClose(ScsiLunKey);
+
+ if (UnitInfo->NextInquiryDataOffset == 0)
+ break;
+
+ UnitInfo = (PSCSI_INQUIRY_DATA)((PUCHAR)AdapterInfo +
+ UnitInfo->NextInquiryDataOffset);
+ }
+
+ /* Close old target key */
+ if (ScsiTargetKey != NULL)
+ {
+ ZwClose(ScsiTargetKey);
+ ScsiTargetKey = NULL;
+ }
+ }
+
+ ZwClose(ScsiBusKey);
}
- NtClose(ScsiPortKey);
- NtClose(ScsiKey);
+ ZwClose(ScsiPortKey);
+
+ DPRINT("ScsiPortBuildDeviceMap() done\n");
return(Status);
}
-#endif
/* EOF */