AtapiFindPCIController@H_403_4@函数是用来发现PCI@H_403_4@总线上所有的IDE@H_403_4@控制器,并发现相关的IDE@H_403_4@设备。具体实现代码如下:@H_403_4@@H_403_4@
#003 @H_403_4@AtapiFindPCIController(@H_403_4@
#004 @H_403_4@IN PVOID HwDeviceExtension,@H_403_4@
#005 @H_403_4@IN PVOID Context,@H_403_4@
#006 @H_403_4@IN PVOID BusInformation,@H_403_4@
#007 @H_403_4@IN PCHAR ArgumentString,@H_403_4@
#008 @H_403_4@IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,@H_403_4@
#009 @H_403_4@OUT PBOOLEAN Again@H_403_4@
#013 @H_403_4@Routine Description:@H_403_4@
#015 @H_403_4@This function is called by the OS-specific port driver after@H_403_4@
#016 @H_403_4@the necessary storage has been allocated,to gather information@H_403_4@
#017 @H_403_4@about the adapter's configuration.@H_403_4@
#019 @H_403_4@Arguments:@H_403_4@
#021 @H_403_4@HwDeviceExtension - HBA miniport driver's adapter data storage@H_403_4@
#022 @H_403_4@Context - Address of adapter count@H_403_4@
#023 @H_403_4@BusInformation -@H_403_4@
#024 @H_403_4@ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility.@H_403_4@
#025 @H_403_4@ConfigInfo - Configuration information structure describing HBA@H_403_4@
#026 @H_403_4@Again - Indicates search for adapters to continue@H_403_4@
#028 @H_403_4@Return Value:@H_403_4@
#035 @H_403_4@PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;@H_403_4@
#036 @H_403_4@PULONG @H_403_4@adapterCount @H_403_4@= (PULONG)Context;@H_403_4@
#037 @H_403_4@ULONG @H_403_4@channel @H_403_4@= 0;@H_403_4@
#038 @H_403_4@static ULONG @H_403_4@functionNumber,@H_403_4@
#039 @H_403_4@slotNumber,@H_403_4@
#040 @H_403_4@controllers;@H_403_4@
#041 @H_403_4@ULONG @H_403_4@i,j;@H_403_4@
#042 @H_403_4@PUCHAR @H_403_4@ioSpace;@H_403_4@
#043 @H_403_4@BOOLEAN @H_403_4@atapiOnly,@H_403_4@
#044 @H_403_4@lastSlot,@H_403_4@
#045 @H_403_4@controllerFound = FALSE,@H_403_4@
#046 @H_403_4@deviceFound = FALSE;@H_403_4@
#047 @H_403_4@UCHAR @H_403_4@statusByte;@H_403_4@
#050 @H_403_4@// The following table specifies the ports to be checked when searching for@H_403_4@
#051 @H_403_4@// an IDE controller. @H_403_4@A zero entry terminates the search.@H_403_4@
@H_403_4@
这里设置IDE@H_403_4@控制器的几个控制端口。@H_403_4@@H_403_4@
#054 @H_403_4@CONST ULONG AdapterAddresses[5] = {0x1F0,0x170,0x1e8,0x168,0};@H_403_4@
#057 @H_403_4@// The following table specifies interrupt levels corresponding to the@H_403_4@
#058 @H_403_4@// port addresses in the prevIoUs table.@H_403_4@
@H_403_4@
设置相应的IDE@H_403_4@控制器的中断号。@H_403_4@@H_403_4@
#061 @H_403_4@CONST ULONG InterruptLevels[5] = {14,15,11,10,0};@H_403_4@
@H_403_4@
检查设备对象扩展是否分配,如果没有分配,就返回失败。@H_403_4@@H_403_4@
#063 @H_403_4@if (!deviceExtension) {@H_403_4@
#064 @H_403_4@return SP_RETURN_ERROR;@H_403_4@
#068 @H_403_4@// Since scsiport will call this function first before it calls AtapiFindController@H_403_4@
#069 @H_403_4@// we need to bypass it if we have data installed in ConfigInfo,by the pcmcia driver.@H_403_4@
#070 @H_403_4@// In that case atapifindcontroller should be called first.@H_403_4@
#071 @H_403_4@// Instead of modifying atapi @H_403_4@driverEntry to search of PCIBus first (now its ISA)@H_403_4@
#072 @H_403_4@// the check is put here.@H_403_4@
@H_403_4@
当总线0@H_403_4@上的设备配置不为空时,就进入进找相应的IDE@H_403_4@控制器。@H_403_4@@H_403_4@
#075 @H_403_4@if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) {@H_403_4@
@H_403_4@
下面调用函数AtapiFindController@H_403_4@来发现相应的IDE@H_403_4@控制器。@H_403_4@@H_403_4@
#077 @H_403_4@return AtapiFindController(HwDeviceExtension,@H_403_4@
#078 @H_403_4@Context,@H_403_4@
#079 @H_403_4@BusInformation,@H_403_4@
#080 @H_403_4@ArgumentString,@H_403_4@
#081 @H_403_4@@H_403_4@ConfigInfo,@H_403_4@
#082 @H_403_4@Again);@H_403_4@
#087 @H_403_4@// Gronk PCI config space looking for the broken PCI IDE controllers that have only@H_403_4@
#088 @H_403_4@// one FIFO for both channels.@H_403_4@
#089 @H_403_4@// Don't do this. It's incorrect and nasty. It has to be done to work around these@H_403_4@
#090 @H_403_4@// broken parts,no other reason can justify this.@H_403_4@
@H_403_4@
下面查找分离的PCI@H_403_4@设备配置空间。@H_403_4@@H_403_4@
#093 @H_403_4@for (i = controllers; i < BROKEN_ADAPTERS; i++) {@H_403_4@
#095 @H_403_4@@H_403_4@//@H_403_4@
#096 @H_403_4@// Determine if both channels are enabled and have devices.@H_403_4@
#099 @H_403_4@lastSlot = FALSE;@H_403_4@
#101 @H_403_4@if (FindBrokenController(deviceExtension,@H_403_4@
#102 @H_403_4@(PUCHAR)BrokenAdapters[i].VendorId,@H_403_4@
#103 @H_403_4@BrokenAdapters[i].VendorIdLength,@H_403_4@
#104 @H_403_4@(PUCHAR)BrokenAdapters[i].DeviceId,@H_403_4@
#105 @H_403_4@BrokenAdapters[i].DeviceIdLength,@H_403_4@
#106 @H_403_4@@H_403_4@&functionNumber,@H_403_4@
#107 @H_403_4@&slotNumber,@H_403_4@
#108 @H_403_4@ConfigInfo->SystemIoBusNumber,@H_403_4@
#109 @H_403_4@&lastSlot)) {@H_403_4@
#111 @H_403_4@slotNumber++;@H_403_4@
#112 @H_403_4@functionNumber = 0;@H_403_4@
#113 @H_403_4@controllerFound = TRUE;@H_403_4@
#115 @H_403_4@DebugPrint((1,@H_403_4@
#116 @H_403_4@"Found broken PCI IDE controller: VendorId %s,DeviceId %s/n",@H_403_4@
#117 @H_403_4@BrokenAdapters[i].VendorId,@H_403_4@
#118 @H_403_4@BrokenAdapters[i].DeviceId));@H_403_4@
#120 @H_403_4@if (AdapterAddresses[*adapterCount] != 0) {@H_403_4@
#122 @H_403_4@for (j = 0; j < 2; j++) {@H_403_4@
#125 @H_403_4@@H_403_4@// Get the system physical address for this IO range.@H_403_4@
#128 @H_403_4@ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,@H_403_4@
#129 @H_403_4@ConfigInfo->AdapterInterfaceType,@H_403_4@
#130 @H_403_4@ConfigInfo->SystemIoBusNumber,@H_403_4@
#131 @H_403_4@ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]),@H_403_4@
#132 @H_403_4@@H_403_4@8,@H_403_4@
#136 @H_403_4@// Update the adapter count.@H_403_4@
@H_403_4@
增加IDE@H_403_4@控制器的个数。@H_403_4@@H_403_4@
#139 @H_403_4@@H_403_4@(*adapterCount)++;@H_403_4@
#142 @H_403_4@// Check if ioSpace accessible.@H_403_4@
#145 @H_403_4@if (!ioSpace) {@H_403_4@
#146 @H_403_4@continue;@H_403_4@
#147 @H_403_4@@H_403_4@}@H_403_4@
#150 @H_403_4@// Select master.@H_403_4@
#153 @H_403_4@ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect,0xA0);@H_403_4@
#155 @H_403_4@@H_403_4@//@H_403_4@
#156 @H_403_4@// Check if card at this address.@H_403_4@
#159 @H_403_4@ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow,0xAA);@H_403_4@
#162 @H_403_4@@H_403_4@// Check if indentifier can be read back.@H_403_4@
#165 @H_403_4@if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {@H_403_4@
#167 @H_403_4@DebugPrint((2,@H_403_4@
#168 @H_403_4@"AtapiFindPciController: Identifier read back from Master (%x)/n",@H_403_4@
#169 @H_403_4@statusByte));@H_403_4@
#173 @H_403_4@// Select slave.@H_403_4@
#176 @H_403_4@ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect,0xB0);@H_403_4@
#179 @H_403_4@// See if slave is present.@H_403_4@
#180 @H_403_4@@H_403_4@//@H_403_4@
#182 @H_403_4@ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow,0xAA);@H_403_4@
#184 @H_403_4@if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) {@H_403_4@
#186 @H_403_4@DebugPrint((2,@H_403_4@
#187 @H_403_4@"AtapiFindPciController: Identifier read back from Slave (%x)/n",@H_403_4@
#188 @H_403_4@statusByte));@H_403_4@
#190 @H_403_4@@H_403_4@//@H_403_4@
#192 @H_403_4@// No controller at this base address.@H_403_4@
#195 @H_403_4@ScsiPortFreeDeviceBase(HwDeviceExtension,@H_403_4@
#196 @H_403_4@ioSpace);@H_403_4@
@H_403_4@
继续查找第二个通道是否IDE@H_403_4@控制器。@H_403_4@@H_403_4@
#199 @H_403_4@// If the chip is there,but we couldn't find the primary channel,try the secondary.@H_403_4@
#200 @H_403_4@@H_403_4@// If we couldn't find a secondary,who cares.@H_403_4@
#203 @H_403_4@if (j == 1) {@H_403_4@
#205 @H_403_4@goto setStatusAndExit;@H_403_4@
#207 @H_403_4@@H_403_4@} else {@H_403_4@
#208 @H_403_4@continue;@H_403_4@
@H_403_4@
如果发现了IDE@H_403_4@控制器,就保存相应的配置参数。@H_403_4@@H_403_4@
#213 @H_403_4@if (controllerFound) {@H_403_4@
#216 @H_403_4@// Record base IO address.@H_403_4@
#219 @H_403_4@deviceExtension->BaseIoAddress1[channel] = (PIDE_REGISTERS_1)(ioSpace);@H_403_4@
#221 @H_403_4@@H_403_4@//@H_403_4@
#222 @H_403_4@// Fill in the access array information.@H_403_4@
#225 @H_403_4@(*ConfigInfo->AccessRanges)[channel].RangeStart =@H_403_4@
#226 @H_403_4@ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);@H_403_4@
#228 @H_403_4@(*ConfigInfo->AccessRanges)[channel].RangeLength = 8;@H_403_4@
#229 @H_403_4@(*ConfigInfo->AccessRanges)[channel].RangeInMemory = FALSE;@H_403_4@
#232 @H_403_4@// Indicate the interrupt level corresponding to this IO range.@H_403_4@
@H_403_4@
根据不同的通道进行保存中断号和中断方式。@H_403_4@@H_403_4@
#235 @H_403_4@if (channel == 0) {@H_403_4@
#236 @H_403_4@@H_403_4@ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];@H_403_4@
#237 @H_403_4@ConfigInfo->InterruptMode = Latched;@H_403_4@
#238 @H_403_4@} else {@H_403_4@
#239 @H_403_4@ConfigInfo->BusInterruptLevel2 = InterruptLevels[*adapterCount - 1];@H_403_4@
#240 @H_403_4@ConfigInfo->InterruptMode2 = Latched;@H_403_4@
#244 @H_403_4@// Get the system physical address for the second IO range.@H_403_4@
#247 @H_403_4@ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension,@H_403_4@
#248 @H_403_4@ConfigInfo->AdapterInterfaceType,@H_403_4@
#249 @H_403_4@@H_403_4@ConfigInfo->SystemIoBusNumber,@H_403_4@
#250 @H_403_4@ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1] + 0x206),@H_403_4@
#251 @H_403_4@@H_403_4@1,@H_403_4@
#254 @H_403_4@deviceExtension->BaseIoAddress2[channel] = (PIDE_REGISTERS_2)(ioSpace);@H_403_4@
#256 @H_403_4@deviceExtension->NumberChannels = 2;@H_403_4@
#259 @H_403_4@// Indicate only one bus.@H_403_4@
#262 @H_403_4@ConfigInfo->NumberOfBuses = 1;@H_403_4@
#264 @H_403_4@@H_403_4@//@H_403_4@
#265 @H_403_4@// Indicate four devices can be attached to the adapter,since we@H_403_4@
#266 @H_403_4@// have to serialize access to the two channels.@H_403_4@
#269 @H_403_4@ConfigInfo->MaximumNumberOfTargets = 4;@H_403_4@
#272 @H_403_4@// Indicate maximum transfer length is 64k.@H_403_4@
#275 @H_403_4@ConfigInfo->MaximumTransferLength = 0x10000;@H_403_4@
#277 @H_403_4@DebugPrint((1,@H_403_4@
#278 @H_403_4@"AtapiFindPciController: Found broken IDE at %x/n",@H_403_4@
#279 @H_403_4@deviceExtension->BaseIoAddress1[channel]));@H_403_4@
#281 @H_403_4@@H_403_4@//@H_403_4@
#282 @H_403_4@// Since we will always pick up this part,and not atdisk,so indicate.@H_403_4@
#285 @H_403_4@atapiOnly = FALSE;@H_403_4@
@H_403_4@
#287 @H_403_4@@H_403_4@//@H_403_4@
#288 @H_403_4@// Save the Interrupe Mode for later use@H_403_4@
#290 @H_403_4@deviceExtension->InterruptMode = ConfigInfo->InterruptMode;@H_403_4@
@H_403_4@
查找这个IDE@H_403_4@控制器上所有的设备。@H_403_4@@H_403_4@
#292 @H_403_4@@H_403_4@//@H_403_4@
#293 @H_403_4@// Search for devices on this controller.@H_403_4@
#296 @H_403_4@if (FindDevices(HwDeviceExtension,@H_403_4@
#297 @H_403_4@atapiOnly,@H_403_4@
#298 @H_403_4@@H_403_4@channel++)){@H_403_4@
#299 @H_403_4@deviceFound = TRUE;@H_403_4@
@H_403_4@
判断是主IDE@H_403_4@设备,还第二个IDE@H_403_4@设备。@H_403_4@@H_403_4@
#303 @H_403_4@// Claim primary or secondary ATA IO range.@H_403_4@
#306 @H_403_4@if (*adapterCount == 1) {@H_403_4@
#307 @H_403_4@ConfigInfo->AtdiskPrimaryClaimed = TRUE;@H_403_4@
#308 @H_403_4@deviceExtension->PrimaryAddress = TRUE;@H_403_4@
#310 @H_403_4@} else if (*adapterCount == 2) {@H_403_4@
#311 @H_403_4@ConfigInfo->AtdiskSecondaryClaimed = TRUE;@H_403_4@
#312 @H_403_4@deviceExtension->PrimaryAddress = FALSE;@H_403_4@
#314 @H_403_4@@H_403_4@}@H_403_4@
#319 @H_403_4@setStatusAndExit:@H_403_4@
#321 @H_403_4@if (lastSlot) {@H_403_4@
#322 @H_403_4@slotNumber = 0;@H_403_4@
#323 @H_403_4@functionNumber = 0;@H_403_4@
#326 @H_403_4@controllers = i;@H_403_4@
#328 @H_403_4@if (controllerFound && deviceFound) {@H_403_4@
@H_403_4@
#330 @H_403_4@*Again = TRUE;@H_403_4@
#331 @H_403_4@return SP_RETURN_FOUND;@H_403_4@
@H_403_4@
已经搜索完成,没有任设备发现。@H_403_4@@H_403_4@
#337 @H_403_4@// The entire table has been searched and no adapters have been found.@H_403_4@
#340 @H_403_4@*Again = FALSE;@H_403_4@
#342 @H_403_4@return SP_RETURN_NOT_FOUND;@H_403_4@
#344} // end AtapiFindPCIController()@H_403_4@