atapi.c
来自「一个类似windows」· C语言 代码 · 共 2,047 行 · 第 1/5 页
C
2,047 行
/* Search the ISA bus for ide controllers */
#ifdef ENABLE_ISA
InitData.HwFindAdapter = AtapiFindIsaBusController;
InitData.NumberOfAccessRanges = 2;
InitData.AdapterInterfaceType = Isa;
InitData.VendorId = NULL;
InitData.VendorIdLength = 0;
InitData.DeviceId = NULL;
InitData.DeviceIdLength = 0;
Status = ScsiPortInitialize(DriverObject,
RegistryPath,
&InitData,
NULL);
// if (newStatus < statusToReturn)
// statusToReturn = newStatus;
#endif
DPRINT("Returning from DriverEntry\n");
return(Status);
}
BOOLEAN
AtapiClaimHwResources(PATAPI_MINIPORT_EXTENSION DevExt,
PPORT_CONFIGURATION_INFORMATION ConfigInfo,
INTERFACE_TYPE InterfaceType,
ULONG CommandPortBase,
ULONG ControlPortBase,
ULONG BusMasterPortBase,
ULONG InterruptVector)
{
SCSI_PHYSICAL_ADDRESS IoAddress;
PVOID IoBase;
#ifdef ENABLE_DMA
ULONG Length;
#endif
IoAddress = ScsiPortConvertUlongToPhysicalAddress(CommandPortBase);
IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
InterfaceType,
ConfigInfo->SystemIoBusNumber,
IoAddress,
8,
TRUE);
if (IoBase == NULL)
{
return FALSE;
}
DevExt->Handler = NULL;
DevExt->CommandPortBase = (ULONG)IoBase;
(*ConfigInfo->AccessRanges)[0].RangeStart = IoAddress;
(*ConfigInfo->AccessRanges)[0].RangeLength = 8;
(*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
if (ControlPortBase)
{
IoAddress = ScsiPortConvertUlongToPhysicalAddress(ControlPortBase + 2);
IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
InterfaceType,
ConfigInfo->SystemIoBusNumber,
IoAddress,
1,
TRUE);
if (IoBase == NULL)
{
ScsiPortFreeDeviceBase((PVOID)DevExt,
(PVOID)DevExt->CommandPortBase);
return FALSE;
}
DevExt->ControlPortBase = (ULONG)IoBase;
(*ConfigInfo->AccessRanges)[1].RangeStart = IoAddress;
(*ConfigInfo->AccessRanges)[1].RangeLength = 1;
(*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
}
if (BusMasterPortBase)
{
IoAddress = ScsiPortConvertUlongToPhysicalAddress(BusMasterPortBase);
IoBase = ScsiPortGetDeviceBase((PVOID)DevExt,
InterfaceType,
ConfigInfo->SystemIoBusNumber,
IoAddress,
8,
TRUE);
if (IoBase == NULL)
{
ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->CommandPortBase);
ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->ControlPortBase);
return FALSE;
}
DevExt->BusMasterRegisterBase = (ULONG)IoBase;
(*ConfigInfo->AccessRanges)[2].RangeStart = IoAddress;
(*ConfigInfo->AccessRanges)[2].RangeLength = 8;
(*ConfigInfo->AccessRanges)[2].RangeInMemory = FALSE;
#ifdef ENABLE_DMA
// ConfigInfo->DmaChannel = SP_UNINITIALIZED_VALUE;
// ConfigInfo->DmaPort = SP_UNINITIALIZED_VALUE;
ConfigInfo->DmaWidth = Width32Bits;
// ConfigInfo->DmaSpeed = Compatible;
ConfigInfo->ScatterGather = TRUE;
ConfigInfo->Master = TRUE;
ConfigInfo->NumberOfPhysicalBreaks = 0x10000 / PAGE_SIZE + 1;
ConfigInfo->Dma32BitAddresses = TRUE;
ConfigInfo->NeedPhysicalAddresses = TRUE;
ConfigInfo->MapBuffers = TRUE;
DevExt->PRDMaxCount = PAGE_SIZE / sizeof(PRD);
DevExt->PRDTable = ScsiPortGetUncachedExtension(DevExt, ConfigInfo, sizeof(PRD) * DevExt->PRDMaxCount);
if (DevExt->PRDTable != NULL)
{
DevExt->PRDTablePhysicalAddress = ScsiPortGetPhysicalAddress(DevExt, NULL, DevExt->PRDTable, &Length);
}
if (DevExt->PRDTable == NULL ||
DevExt->PRDTablePhysicalAddress.QuadPart == 0LL ||
Length < sizeof(PRD) * DevExt->PRDMaxCount)
{
ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->CommandPortBase);
ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->ControlPortBase);
ScsiPortFreeDeviceBase((PVOID)DevExt, (PVOID)DevExt->BusMasterRegisterBase);
return FALSE;
}
#endif
}
ConfigInfo->BusInterruptLevel = InterruptVector;
ConfigInfo->BusInterruptVector = InterruptVector;
ConfigInfo->InterruptMode = (InterfaceType == Isa) ? Latched : LevelSensitive;
if ((CommandPortBase == 0x1F0 || ControlPortBase == 0x3F4) && !ConfigInfo->AtdiskPrimaryClaimed)
{
ConfigInfo->AtdiskPrimaryClaimed = TRUE;
}
if ((CommandPortBase == 0x170 || ControlPortBase == 0x374) && !ConfigInfo->AtdiskSecondaryClaimed)
{
ConfigInfo->AtdiskSecondaryClaimed = TRUE;
}
return TRUE;
}
#ifdef ENABLE_PCI
static ULONG STDCALL
AtapiFindCompatiblePciController(PVOID DeviceExtension,
PVOID HwContext,
PVOID BusInformation,
PCHAR ArgumentString,
PPORT_CONFIGURATION_INFORMATION ConfigInfo,
PBOOLEAN Again)
{
PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
PCI_SLOT_NUMBER SlotNumber;
PCI_COMMON_CONFIG PciConfig;
ULONG DataSize;
ULONG StartDeviceNumber;
ULONG DeviceNumber;
ULONG StartFunctionNumber;
ULONG FunctionNumber;
BOOLEAN ChannelFound;
BOOLEAN DeviceFound;
ULONG BusMasterBasePort = 0;
DPRINT("AtapiFindCompatiblePciController() Bus: %lu Slot: %lu\n",
ConfigInfo->SystemIoBusNumber,
ConfigInfo->SlotNumber);
*Again = FALSE;
/* both channels were claimed: exit */
if (ConfigInfo->AtdiskPrimaryClaimed == TRUE &&
ConfigInfo->AtdiskSecondaryClaimed == TRUE)
return(SP_RETURN_NOT_FOUND);
SlotNumber.u.AsULONG = ConfigInfo->SlotNumber;
StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
{
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
{
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
ChannelFound = FALSE;
DeviceFound = FALSE;
DataSize = ScsiPortGetBusData(DeviceExtension,
PCIConfiguration,
ConfigInfo->SystemIoBusNumber,
SlotNumber.u.AsULONG,
&PciConfig,
PCI_COMMON_HDR_LENGTH);
if (DataSize != PCI_COMMON_HDR_LENGTH)
{
if (FunctionNumber == 0)
{
break;
}
else
{
continue;
}
}
DPRINT("%x %x\n", PciConfig.BaseClass, PciConfig.SubClass);
if (PciConfig.BaseClass == 0x01 &&
PciConfig.SubClass == 0x01) // &&
// (PciConfig.ProgIf & 0x05) == 0)
{
/* both channels are in compatibility mode */
DPRINT("Bus %1lu Device %2lu Func %1lu VenID 0x%04hx DevID 0x%04hx\n",
ConfigInfo->SystemIoBusNumber,
SlotNumber.u.bits.DeviceNumber,
SlotNumber.u.bits.FunctionNumber,
PciConfig.VendorID,
PciConfig.DeviceID);
DPRINT("ProgIF 0x%02hx\n", PciConfig.ProgIf);
DPRINT("Found IDE controller in compatibility mode!\n");
ConfigInfo->NumberOfBuses = 1;
ConfigInfo->MaximumNumberOfTargets = 2;
ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */
if (PciConfig.ProgIf & 0x80)
{
DPRINT("Found IDE Bus Master controller!\n");
if (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE)
{
BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
DPRINT(" IDE Bus Master Registers at IO %lx\n", BusMasterBasePort);
}
}
if (ConfigInfo->AtdiskPrimaryClaimed == FALSE)
{
/* Both channels unclaimed: Claim primary channel */
DPRINT("Primary channel!\n");
ChannelFound = AtapiClaimHwResources(DevExt,
ConfigInfo,
PCIBus,
0x1F0,
0x3F4,
BusMasterBasePort,
14);
*Again = TRUE;
}
else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE)
{
/* Primary channel already claimed: claim secondary channel */
DPRINT("Secondary channel!\n");
ChannelFound = AtapiClaimHwResources(DevExt,
ConfigInfo,
PCIBus,
0x170,
0x374,
BusMasterBasePort ? BusMasterBasePort + 8 : 0,
15);
*Again = FALSE;
}
/* Find attached devices */
if (ChannelFound)
{
DeviceFound = AtapiFindDevices(DevExt, ConfigInfo);
ConfigInfo->SlotNumber = SlotNumber.u.AsULONG;
DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_FOUND\n");
return(SP_RETURN_FOUND);
}
}
if (FunctionNumber == 0 && !(PciConfig.HeaderType & PCI_MULTIFUNCTION))
{
break;
}
}
StartFunctionNumber = 0;
}
DPRINT("AtapiFindCompatiblePciController() returns: SP_RETURN_NOT_FOUND\n");
return(SP_RETURN_NOT_FOUND);
}
#endif
#ifdef ENABLE_ISA
static ULONG STDCALL
AtapiFindIsaBusController(PVOID DeviceExtension,
PVOID HwContext,
PVOID BusInformation,
PCHAR ArgumentString,
PPORT_CONFIGURATION_INFORMATION ConfigInfo,
PBOOLEAN Again)
{
PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
BOOLEAN ChannelFound = FALSE;
BOOLEAN DeviceFound = FALSE;
DPRINT("AtapiFindIsaBusController() called!\n");
*Again = FALSE;
ConfigInfo->NumberOfBuses = 1;
ConfigInfo->MaximumNumberOfTargets = 2;
ConfigInfo->MaximumTransferLength = 0x10000; /* max 64Kbyte */
if (ConfigInfo->AtdiskPrimaryClaimed == FALSE)
{
/* Both channels unclaimed: Claim primary channel */
DPRINT("Primary channel!\n");
ChannelFound = AtapiClaimHwResources(DevExt,
ConfigInfo,
Isa,
0x1F0,
0x3F4,
0,
14);
*Again = TRUE;
}
else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE)
{
/* Primary channel already claimed: claim secondary channel */
DPRINT("Secondary channel!\n");
ChannelFound = AtapiClaimHwResources(DevExt,
ConfigInfo,
Isa,
0x170,
0x374,
0,
15);
*Again = FALSE;
}
else
{
DPRINT("AtapiFindIsaBusController() both channels claimed. Returns: SP_RETURN_NOT_FOUND\n");
*Again = FALSE;
return(SP_RETURN_NOT_FOUND);
}
/* Find attached devices */
if (ChannelFound)
{
DeviceFound = AtapiFindDevices(DevExt,
ConfigInfo);
DPRINT("AtapiFindIsaBusController() returns: SP_RETURN_FOUND\n");
return(SP_RETURN_FOUND);
}
*Again = FALSE;
return SP_RETURN_NOT_FOUND;
}
#endif
#ifdef ENABLE_NATIVE_PCI
static ULONG STDCALL
AtapiFindNativePciController(PVOID DeviceExtension,
PVOID HwContext,
PVOID BusInformation,
PCHAR ArgumentString,
PPORT_CONFIGURATION_INFORMATION ConfigInfo,
PBOOLEAN Again)
{
PATAPI_MINIPORT_EXTENSION DevExt = (PATAPI_MINIPORT_EXTENSION)DeviceExtension;
PCI_COMMON_CONFIG PciConfig;
PCI_SLOT_NUMBER SlotNumber;
ULONG DataSize;
ULONG DeviceNumber;
ULONG StartDeviceNumber;
ULONG FunctionNumber;
ULONG StartFunctionNumber;
ULONG BusMasterBasePort;
ULONG Count;
BOOLEAN ChannelFound;
DPRINT("AtapiFindNativePciController() called!\n");
SlotNumber.u.AsULONG = ConfigInfo->SlotNumber;
StartDeviceNumber = SlotNumber.u.bits.DeviceNumber;
StartFunctionNumber = SlotNumber.u.bits.FunctionNumber;
for (DeviceNumber = StartDeviceNumber; DeviceNumber < PCI_MAX_DEVICES; DeviceNumber++)
{
SlotNumber.u.bits.DeviceNumber = DeviceNumber;
for (FunctionNumber = StartFunctionNumber; FunctionNumber < PCI_MAX_FUNCTION; FunctionNumber++)
{
SlotNumber.u.bits.FunctionNumber = FunctionNumber;
DataSize = ScsiPortGetBusData(DeviceExtension,
PCIConfiguration,
ConfigInfo->SystemIoBusNumber,
SlotNumber.u.AsULONG,
&PciConfig,
PCI_COMMON_HDR_LENGTH);
if (DataSize != PCI_COMMON_HDR_LENGTH)
{
break;
}
for (Count = 0; Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER); Count++)
{
if (PciConfig.VendorID == PciNativeController[Count].VendorID &&
PciConfig.DeviceID == PciNativeController[Count].DeviceID)
{
break;
}
}
if (Count < sizeof(PciNativeController)/sizeof(PCI_NATIVE_CONTROLLER))
{
/* We have found a known native pci ide controller */
if ((PciConfig.ProgIf & 0x80) && (PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_SPACE))
{
DPRINT("Found IDE Bus Master controller!\n");
BusMasterBasePort = PciConfig.u.type0.BaseAddresses[4] & PCI_ADDRESS_IO_ADDRESS_MASK;
DPRINT(" IDE Bus Master Registers at IO %lx\n", BusMasterBasePort);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?