scsiport.c
来自「一个类似windows」· C语言 代码 · 共 2,184 行 · 第 1/5 页
C
2,184 行
InitializeListHead (&DeviceExtension->PendingIrpListHead);
DeviceExtension->NextIrp = NULL;
DeviceExtension->PendingIrpCount = 0;
DeviceExtension->ActiveIrpCount = 0;
/* Initialize LUN-Extension list */
InitializeListHead (&DeviceExtension->LunExtensionListHead);
/* Initialize the spin lock in the controller extension */
KeInitializeSpinLock (&DeviceExtension->Lock);
/* Initialize the DPC object */
IoInitializeDpcRequest (PortDeviceObject,
ScsiPortDpc);
/* Initialize the device timer */
DeviceExtension->TimerState = IDETimerIdle;
DeviceExtension->TimerCount = 0;
IoInitializeTimer (PortDeviceObject,
ScsiPortIoTimer,
DeviceExtension);
/* Allocate and initialize port configuration info */
DeviceExtension->PortConfig = ExAllocatePool (NonPagedPool,
PortConfigSize);
if (DeviceExtension->PortConfig == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
RtlZeroMemory (DeviceExtension->PortConfig,
PortConfigSize);
PortConfig = DeviceExtension->PortConfig;
PortConfig->Length = sizeof(PORT_CONFIGURATION_INFORMATION);
PortConfig->SystemIoBusNumber = BusNumber;
PortConfig->AdapterInterfaceType = HwInitializationData->AdapterInterfaceType;
PortConfig->InterruptMode =
(PortConfig->AdapterInterfaceType == PCIBus) ? LevelSensitive : Latched;
PortConfig->MaximumTransferLength = SP_UNINITIALIZED_VALUE;
PortConfig->NumberOfPhysicalBreaks = SP_UNINITIALIZED_VALUE;
PortConfig->DmaChannel = SP_UNINITIALIZED_VALUE;
PortConfig->DmaPort = SP_UNINITIALIZED_VALUE;
PortConfig->DmaWidth = 0;
PortConfig->DmaSpeed = Compatible;
PortConfig->AlignmentMask = 0;
PortConfig->NumberOfAccessRanges = HwInitializationData->NumberOfAccessRanges;
PortConfig->NumberOfBuses = 0;
for (i = 0; i < SCSI_MAXIMUM_BUSES; i++)
PortConfig->InitiatorBusId[i] = 255;
PortConfig->ScatterGather = FALSE;
PortConfig->Master = FALSE;
PortConfig->CachesData = FALSE;
PortConfig->AdapterScansDown = FALSE;
PortConfig->AtdiskPrimaryClaimed = SystemConfig->AtDiskPrimaryAddressClaimed;
PortConfig->AtdiskSecondaryClaimed = SystemConfig->AtDiskSecondaryAddressClaimed;
PortConfig->Dma32BitAddresses = FALSE;
PortConfig->DemandMode = FALSE;
PortConfig->MapBuffers = HwInitializationData->MapBuffers;
PortConfig->NeedPhysicalAddresses = HwInitializationData->NeedPhysicalAddresses;
PortConfig->TaggedQueuing = HwInitializationData->TaggedQueuing;
PortConfig->AutoRequestSense = HwInitializationData->AutoRequestSense;
PortConfig->MultipleRequestPerLu = HwInitializationData->MultipleRequestPerLu;
PortConfig->ReceiveEvent = HwInitializationData->ReceiveEvent;
PortConfig->RealModeInitialized = FALSE;
PortConfig->BufferAccessScsiPortControlled = FALSE;
PortConfig->MaximumNumberOfTargets = SCSI_MAXIMUM_TARGETS;
// PortConfig->MaximumNumberOfLogicalUnits = SCSI_MAXIMUM_LOGICAL_UNITS;
PortConfig->SrbExtensionSize = HwInitializationData->SrbExtensionSize;
PortConfig->SpecificLuExtensionSize = HwInitializationData->SpecificLuExtensionSize;
PortConfig->AccessRanges = (ACCESS_RANGE(*)[])(PortConfig + 1);
/* Search for matching PCI device */
if ((HwInitializationData->AdapterInterfaceType == PCIBus) &&
(HwInitializationData->VendorIdLength > 0) &&
(HwInitializationData->VendorId != NULL) &&
(HwInitializationData->DeviceIdLength > 0) &&
(HwInitializationData->DeviceId != NULL))
{
/* Get PCI device data */
DPRINT("VendorId '%.*s' DeviceId '%.*s'\n",
HwInitializationData->VendorIdLength,
HwInitializationData->VendorId,
HwInitializationData->DeviceIdLength,
HwInitializationData->DeviceId);
if (!SpiGetPciConfigData (HwInitializationData,
PortConfig,
BusNumber,
&SlotNumber))
{
Status = STATUS_UNSUCCESSFUL;
goto ByeBye;
}
}
/* Note: HwFindAdapter is called once for each bus */
Again = FALSE;
DPRINT("Calling HwFindAdapter() for Bus %lu\n", PortConfig->SystemIoBusNumber);
Result = (HwInitializationData->HwFindAdapter)(&DeviceExtension->MiniPortDeviceExtension,
HwContext,
0, /* BusInformation */
"", /* ArgumentString */
PortConfig,
&Again);
DPRINT("HwFindAdapter() Result: %lu Again: %s\n",
Result, (Again) ? "True" : "False");
if (Result == SP_RETURN_FOUND)
{
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)
{
ScsiPortGetUncachedExtension(&DeviceExtension->MiniPortDeviceExtension,
PortConfig,
0);
}
/* Register an interrupt handler for this device */
MappedIrq = HalGetInterruptVector(PortConfig->AdapterInterfaceType,
PortConfig->SystemIoBusNumber,
PortConfig->BusInterruptLevel,
#if 1
/*
* FIXME:
* Something is wrong in our interrupt conecting code.
* The promise Ultra100TX driver returns 0 for BusInterruptVector
* and a nonzero value for BusInterruptLevel. The driver does only
* work with this fix.
*/
PortConfig->BusInterruptLevel,
#else
PortConfig->BusInterruptVector,
#endif
&Dirql,
&Affinity);
DPRINT("AdapterInterfaceType %x, SystemIoBusNumber %x, BusInterruptLevel %x, BusInterruptVector %x\n",
PortConfig->AdapterInterfaceType, PortConfig->SystemIoBusNumber,
PortConfig->BusInterruptLevel, PortConfig->BusInterruptVector);
Status = IoConnectInterrupt(&DeviceExtension->Interrupt,
ScsiPortIsr,
DeviceExtension,
NULL,
MappedIrq,
Dirql,
Dirql,
PortConfig->InterruptMode,
TRUE,
Affinity,
FALSE);
if (!NT_SUCCESS(Status))
{
DbgPrint("Could not connect interrupt %d\n",
PortConfig->BusInterruptVector);
goto ByeBye;
}
if (!(HwInitializationData->HwInitialize)(&DeviceExtension->MiniPortDeviceExtension))
{
DbgPrint("HwInitialize() failed!");
Status = STATUS_UNSUCCESSFUL;
goto ByeBye;
}
/* Initialize port capabilities */
DeviceExtension->PortCapabilities = ExAllocatePool(NonPagedPool,
sizeof(IO_SCSI_CAPABILITIES));
if (DeviceExtension->PortCapabilities == NULL)
{
DbgPrint("Failed to allocate port capabilities!\n");
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
PortCapabilities = DeviceExtension->PortCapabilities;
PortCapabilities->Length = sizeof(IO_SCSI_CAPABILITIES);
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 */
PortCapabilities->AlignmentMask =
PortConfig->AlignmentMask;
PortCapabilities->TaggedQueuing =
PortConfig->TaggedQueuing;
PortCapabilities->AdapterScansDown =
PortConfig->AdapterScansDown;
PortCapabilities->AdapterUsesPio = TRUE; /* FIXME */
/* Scan the adapter for devices */
SpiScanAdapter (DeviceExtension);
/* Build the registry device map */
SpiBuildDeviceMap (DeviceExtension,
(PUNICODE_STRING)Argument2);
/* Create the dos device link */
swprintf(DosNameBuffer,
L"\\??\\Scsi%lu:",
SystemConfig->ScsiPortCount);
RtlInitUnicodeString(&DosDeviceName,
DosNameBuffer);
IoCreateSymbolicLink(&DosDeviceName,
&DeviceName);
/* Update the system configuration info */
if (PortConfig->AtdiskPrimaryClaimed == TRUE)
SystemConfig->AtDiskPrimaryAddressClaimed = TRUE;
if (PortConfig->AtdiskSecondaryClaimed == TRUE)
SystemConfig->AtDiskSecondaryAddressClaimed = TRUE;
SystemConfig->ScsiPortCount++;
PortDeviceObject = NULL;
DeviceFound = TRUE;
}
else
{
DPRINT("HwFindAdapter() Result: %lu\n", Result);
ExFreePool (PortConfig);
IoDeleteDevice (PortDeviceObject);
PortDeviceObject = NULL;
}
DPRINT("Bus: %lu MaxBus: %lu\n", BusNumber, MaxBus);
if (BusNumber >= MaxBus)
{
DPRINT("Scanned all buses!\n");
Status = STATUS_SUCCESS;
goto ByeBye;
}
if (Again == FALSE)
{
BusNumber++;
SlotNumber.u.AsULONG = 0;
}
}
ByeBye:
/* Clean up the mess */
if (PortDeviceObject != NULL)
{
DPRINT("Delete device: %p\n", PortDeviceObject);
DeviceExtension = PortDeviceObject->DeviceExtension;
if (DeviceExtension->PortCapabilities != NULL)
{
IoDisconnectInterrupt (DeviceExtension->Interrupt);
ExFreePool (DeviceExtension->PortCapabilities);
}
if (DeviceExtension->PortConfig != NULL)
{
ExFreePool (DeviceExtension->PortConfig);
}
IoDeleteDevice (PortDeviceObject);
}
DPRINT("ScsiPortInitialize() done!\n");
return (DeviceFound == FALSE) ? Status : STATUS_SUCCESS;
}
/*
* @unimplemented
*/
VOID STDCALL
ScsiPortIoMapTransfer(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb,
IN ULONG LogicalAddress,
IN ULONG Length)
{
DPRINT1("ScsiPortIoMapTransfer()\n");
UNIMPLEMENTED;
}
/*
* @unimplemented
*/
VOID STDCALL
ScsiPortLogError(IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb OPTIONAL,
IN UCHAR PathId,
IN UCHAR TargetId,
IN UCHAR Lun,
IN ULONG ErrorCode,
IN ULONG UniqueId)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
DPRINT1("ScsiPortLogError() called\n");
DPRINT1("Srb %x, PathId %d, TargetId %d, Lun %d, ErrorCode %x, UniqueId %x\n",
Srb, PathId, TargetId, Lun, ErrorCode, UniqueId);
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
SCSI_PORT_DEVICE_EXTENSION,
MiniPortDeviceExtension);
DPRINT("ScsiPortLogError() done\n");
}
/*
* @implemented
*/
VOID STDCALL
ScsiPortMoveMemory(OUT PVOID Destination,
IN PVOID Source,
IN ULONG Length)
{
RtlMoveMemory(Destination,
Source,
Length);
}
/*
* @implemented
*/
VOID
ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType,
IN PVOID HwDeviceExtension,
...)
{
PSCSI_PORT_DEVICE_EXTENSION DeviceExtension;
va_list ap;
DPRINT("ScsiPortNotification() called\n");
DeviceExtension = CONTAINING_RECORD(HwDeviceExtension,
SCSI_PORT_DEVICE_EXTENSION,
MiniPortDeviceExtension);
DPRINT("DeviceExtension %p\n", DeviceExtension);
va_start(ap, HwDeviceExtension);
switch (NotificationType)
{
case RequestComplete:
{
PSCSI_REQUEST_BLOCK Srb;
Srb = (PSCSI_REQUEST_BLOCK) va_arg (ap, PSCSI_REQUEST_BLOCK);
DPRINT("Notify: RequestComplete (Srb %p)\n", Srb);
DeviceExtension->Flags |= IRP_FLAG_COMPLETE;
Srb->SrbFlags &= ~SRB_FLAGS_IS_ACTIVE;
}
break;
case NextRequest:
DPRINT("Notify: NextRequest\n");
DeviceExtension->Flags |= IRP_FLAG_NEXT;
break;
case NextLuRequest:
{
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
PSCSI_PORT_LUN_EXTENSION LunExtension;
PathId = (UCHAR) va_arg (ap, int);
TargetId = (UCHAR) va_arg (ap, int);
Lun = (UCHAR) va_arg (ap, int);
DPRINT ("Notify: NextLuRequest(PathId %u TargetId %u Lun %u)\n",
PathId, TargetId, Lun);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?