📄 scsiport.c
字号:
IN BOOLEAN InIoSpace)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
PHYSICAL_ADDRESS TranslatedAddress;
PMAPPED_ADDRESS DeviceBase;
ULONG AddressSpace;
PVOID MappedAddress;
//DPRINT ("ScsiPortGetDeviceBase() called\n");
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
SCSI_PORT_DEVICE_EXTENSION,
MiniPortDeviceExtension);
AddressSpace = (ULONG)InIoSpace;
if (HalTranslateBusAddress(BusType,
SystemIoBusNumber,
IoAddress,
&AddressSpace,
&TranslatedAddress) == FALSE)
{
return NULL;
}
/* i/o space */
if (AddressSpace != 0)
return((PVOID)TranslatedAddress.u.LowPart);
MappedAddress = MmMapIoSpace(TranslatedAddress,
NumberOfBytes,
FALSE);
DeviceBase = ExAllocatePoolWithTag(NonPagedPool,
sizeof(MAPPED_ADDRESS), TAG_SCSIPORT);
if (DeviceBase == NULL)
return MappedAddress;
DeviceBase->MappedAddress = MappedAddress;
DeviceBase->NumberOfBytes = NumberOfBytes;
DeviceBase->IoAddress = IoAddress;
DeviceBase->BusNumber = SystemIoBusNumber;
/* Link it to the Device Extension list */
DeviceBase->NextMappedAddress = DeviceExtension->MappedAddressList;
DeviceExtension->MappedAddressList = DeviceBase;
return MappedAddress;
}
/*
* @implemented
*/
PVOID STDCALL
ScsiPortGetLogicalUnit(IN PVOID HwDeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun)
{
UNIMPLEMENTED;
#if 0
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;
}
#endif
return NULL;
}
/*
* @unimplemented
*/
SCSI_PHYSICAL_ADDRESS STDCALL
ScsiPortGetPhysicalAddress(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
IN PVOID VirtualAddress,
OUT ULONG *Length)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
SCSI_PHYSICAL_ADDRESS PhysicalAddress;
ULONG BufferLength = 0;
ULONG Offset;
PSCSI_SG_ADDRESS SGList;
PSCSI_REQUEST_BLOCK_INFO SrbInfo;
DPRINT("ScsiPortGetPhysicalAddress(%p %p %p %p)\n",
HwDeviceExtension, Srb, VirtualAddress, Length);
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
SCSI_PORT_DEVICE_EXTENSION,
MiniPortDeviceExtension);
if (Srb == NULL || Srb->SenseInfoBuffer == VirtualAddress)
{
/* Simply look it up in the allocated common buffer */
Offset = (PUCHAR)VirtualAddress - (PUCHAR)DeviceExtension->SrbExtensionBuffer;
BufferLength = DeviceExtension->CommonBufferLength - Offset;
PhysicalAddress.QuadPart = DeviceExtension->PhysicalAddress.QuadPart + Offset;
}
else if (DeviceExtension->MapRegisters)
{
/* Scatter-gather list must be used */
SrbInfo = SpiGetSrbData(DeviceExtension,
Srb->PathId,
Srb->TargetId,
Srb->Lun,
Srb->QueueTag);
SGList = SrbInfo->ScatterGather;
/* Find needed item in the SG list */
Offset = (PCHAR)VirtualAddress - (PCHAR)Srb->DataBuffer;
while (Offset >= SGList->Length)
{
Offset -= SGList->Length;
SGList++;
}
/* We're done, store length and physical address */
BufferLength = SGList->Length - Offset;
PhysicalAddress.QuadPart = SGList->PhysicalAddress.QuadPart + Offset;
}
else
{
/* Nothing */
*Length = 0;
PhysicalAddress.QuadPart = (LONGLONG)(SP_UNINITIALIZED_VALUE);
}
*Length = BufferLength;
return PhysicalAddress;
}
/*
* @unimplemented
*/
PSCSI_REQUEST_BLOCK STDCALL
ScsiPortGetSrb(IN PVOID DeviceExtension,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun,
IN LONG QueueTag)
{
DPRINT1("ScsiPortGetSrb() unimplemented\n");
UNIMPLEMENTED;
return NULL;
}
/*
* @implemented
*/
PVOID STDCALL
ScsiPortGetUncachedExtension(IN PVOID HwDeviceExtension,
IN PPORT_CONFIGURATION_INFORMATION ConfigInfo,
IN ULONG NumberOfBytes)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DEVICE_DESCRIPTION DeviceDescription;
ULONG MapRegistersCount;
NTSTATUS Status;
DPRINT("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->SrbExtensionBuffer != 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, &MapRegistersCount);
/* Fail in case of error */
if (DeviceExtension->AdapterObject == NULL)
{
DPRINT1("HalGetAdapter() failed\n");
return NULL;
}
/* Set number of physical breaks */
if (ConfigInfo->NumberOfPhysicalBreaks != 0 &&
MapRegistersCount > ConfigInfo->NumberOfPhysicalBreaks)
{
DeviceExtension->PortCapabilities.MaximumPhysicalPages =
ConfigInfo->NumberOfPhysicalBreaks;
}
else
{
DeviceExtension->PortCapabilities.MaximumPhysicalPages = MapRegistersCount;
}
}
/* Update auto request sense feature */
DeviceExtension->SupportsAutoSense = ConfigInfo->AutoRequestSense;
/* Update Srb extension size */
if (DeviceExtension->SrbExtensionSize != ConfigInfo->SrbExtensionSize)
DeviceExtension->SrbExtensionSize = ConfigInfo->SrbExtensionSize;
/* Update Srb extension alloc flag */
if (ConfigInfo->AutoRequestSense || DeviceExtension->SrbExtensionSize)
DeviceExtension->NeedSrbExtensionAlloc = TRUE;
/* Allocate a common DMA buffer */
Status = SpiAllocateCommonBuffer(DeviceExtension, NumberOfBytes);
if (!NT_SUCCESS(Status))
{
DPRINT1("SpiAllocateCommonBuffer() failed with Status = 0x%08X!\n", Status);
return NULL;
}
return DeviceExtension->NonCachedExtension;
}
static NTSTATUS
SpiAllocateCommonBuffer(PSCSI_PORT_DEVICE_EXTENSION DeviceExtension, ULONG NonCachedSize)
{
PVOID *SrbExtension, CommonBuffer;
ULONG CommonBufferLength, BufSize;
/* If size is 0, set it to 16 */
if (!DeviceExtension->SrbExtensionSize)
DeviceExtension->SrbExtensionSize = 16;
/* Calculate size */
BufSize = DeviceExtension->SrbExtensionSize;
/* Add autosense data size if needed */
if (DeviceExtension->SupportsAutoSense)
BufSize += sizeof(SENSE_DATA);
/* Round it */
BufSize = (BufSize + sizeof(LONGLONG) - 1) & ~(sizeof(LONGLONG) - 1);
/* Sum up into the total common buffer length, and round it to page size */
CommonBufferLength =
ROUND_TO_PAGES(NonCachedSize + BufSize * DeviceExtension->RequestsNumber);
/* Allocate it */
if (!DeviceExtension->AdapterObject)
{
/* From nonpaged pool if there is no DMA */
CommonBuffer = ExAllocatePoolWithTag(NonPagedPool, CommonBufferLength, TAG_SCSIPORT);
}
else
{
/* Perform a full request since we have a DMA adapter*/
CommonBuffer = HalAllocateCommonBuffer(DeviceExtension->AdapterObject,
CommonBufferLength,
&DeviceExtension->PhysicalAddress,
FALSE );
}
/* Fail in case of error */
if (!CommonBuffer)
return STATUS_INSUFFICIENT_RESOURCES;
/* Zero it */
RtlZeroMemory(CommonBuffer, CommonBufferLength);
/* Store its size in Device Extension */
DeviceExtension->CommonBufferLength = CommonBufferLength;
/* SrbExtension buffer is located at the beginning of the buffer */
DeviceExtension->SrbExtensionBuffer = CommonBuffer;
/* Non-cached extension buffer is located at the end of
the common buffer */
if (NonCachedSize)
{
CommonBufferLength -= NonCachedSize;
DeviceExtension->NonCachedExtension = (PUCHAR)CommonBuffer + CommonBufferLength;
}
else
{
DeviceExtension->NonCachedExtension = NULL;
}
if (DeviceExtension->NeedSrbExtensionAlloc)
{
/* Look up how many SRB data structures we need */
DeviceExtension->SrbDataCount = CommonBufferLength / BufSize;
/* Initialize the free SRB extensions list */
SrbExtension = (PVOID *)CommonBuffer;
DeviceExtension->FreeSrbExtensions = SrbExtension;
/* Fill the remainding pointers (if we have more than 1 SRB) */
while (CommonBufferLength >= 2 * BufSize)
{
*SrbExtension = (PVOID*)((PCHAR)SrbExtension + BufSize);
SrbExtension = *SrbExtension;
CommonBufferLength -= BufSize;
}
}
return STATUS_SUCCESS;
}
/*
* @implemented
*/
PVOID STDCALL
ScsiPortGetVirtualAddress(IN PVOID HwDeviceExtension,
IN SCSI_PHYSICAL_ADDRESS PhysicalAddress)
{
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->SrbExtensionBuffer + Offset);
}
static VOID
SpiInitOpenKeys(PCONFIGURATION_INFO ConfigInfo, PUNICODE_STRING RegistryPath)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING KeyName;
NTSTATUS Status;
/* Open the service key */
InitializeObjectAttributes(&ObjectAttributes,
RegistryPath,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = ZwOpenKey(&ConfigInfo->ServiceKey,
KEY_READ,
&ObjectAttributes);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -