reactos操作系统实现(104)
AtapiFindPCIController函数是用来发现PCI总线上所有的IDE控制器,并发现相关的IDE设备。具体实现代码如下: #001 ULONG #002 NTAPI #003 AtapiFindPCIController( #004 IN PVOID HwDeviceExtension, #005 IN PVOID Context, #006 IN PVOID BusInformation, #007 IN PCHAR ArgumentString, #008 IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, #009 OUT PBOOLEAN Again #010 ) #011 /*++ #012 #013 Routine Description: #014 #015 This function is called by the OS-specific port driver after #016 the necessary storage has been allocated,to gather information #017 about the adapter's configuration. #018 #019 Arguments: #020 #021 HwDeviceExtension - HBA miniport driver's adapter data storage #022 Context - Address of adapter count #023 BusInformation - #024 ArgumentString - Used to determine whether driver is client of ntldr or crash dump utility. #025 ConfigInfo - Configuration information structure describing HBA #026 Again - Indicates search for adapters to continue #027 #028 Return Value: #029 #030 ULONG #031 #032 --*/ #033 #034 { #035 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension; #036 PULONG adapterCount = (PULONG)Context; #037 ULONG channel = 0; #038 static ULONG functionNumber, #039 slotNumber, #040 controllers; #041 ULONG i,j; #042 PUCHAR ioSpace; #043 BOOLEAN atapiOnly, #044 lastSlot, #045 controllerFound = FALSE, #046 deviceFound = FALSE; #047 UCHAR statusByte; #048 #049 // #050 // The following table specifies the ports to be checked when searching for #051 // an IDE controller. A zero entry terminates the search. #052 // #053
这里设置IDE控制器的几个控制端口。 #054 CONST ULONG AdapterAddresses[5] = {0x1F0,0x170,0x1e8,0x168,0}; #055 #056 // #057 // The following table specifies interrupt levels corresponding to the #058 // port addresses in the previous table. #059 // #060
设置相应的IDE控制器的中断号。 #061 CONST ULONG InterruptLevels[5] = {14,15,11,10,0}; #062
检查设备对象扩展是否分配,如果没有分配,就返回失败。 #063 if (!deviceExtension) { #064 return SP_RETURN_ERROR; #065 } #066 #067 // #068 // Since scsiport will call this function first before it calls AtapiFindController #069 // we need to bypass it if we have data installed in ConfigInfo,by the pcmcia driver. #070 // In that case atapifindcontroller should be called first. #071 // Instead of modifying atapi driverEntry to search of PCIBus first (now its ISA) #072 // the check is put here. #073 // #074
当总线0上的设备配置不为空时,就进入进找相应的IDE控制器。 #075 if (ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart) != 0) { #076
下面调用函数AtapiFindController来发现相应的IDE控制器。 #077 return AtapiFindController(HwDeviceExtension, #078 Context, #079 BusInformation, #080 ArgumentString, #081 ConfigInfo, #082 Again); #083 } #084 #085 #086 // #087 // Gronk PCI config space looking for the broken PCI IDE controllers that have only #088 // one FIFO for both channels. #089 // Don't do this. It's incorrect and nasty. It has to be done to work around these #090 // broken parts,no other reason can justify this. #091 // #092
下面查找分离的PCI设备配置空间。 #093 for (i = controllers; i < BROKEN_ADAPTERS; i++) { #094 #095 // #096 // Determine if both channels are enabled and have devices. #097 // #098 #099 lastSlot = FALSE; #100 #101 if (FindBrokenController(deviceExtension, #102 (PUCHAR)BrokenAdapters[i].VendorId, #103 BrokenAdapters[i].VendorIdLength, #104 (PUCHAR)BrokenAdapters[i].DeviceId, #105 BrokenAdapters[i].DeviceIdLength, #106 &functionNumber, #107 &slotNumber, #108 ConfigInfo->SystemIoBusNumber, #109 &lastSlot)) { #110 #111 slotNumber++; #112 functionNumber = 0; #113 controllerFound = TRUE; #114 #115 DebugPrint((1, #116 "Found broken PCI IDE controller: VendorId %s,DeviceId %s/n", #117 BrokenAdapters[i].VendorId, #118 BrokenAdapters[i].DeviceId)); #119 #120 if (AdapterAddresses[*adapterCount] != 0) { #121 #122 for (j = 0; j < 2; j++) { #123 #124 // #125 // Get the system physical address for this IO range. #126 // #127 #128 ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension, #129 ConfigInfo->AdapterInterfaceType, #130 ConfigInfo->SystemIoBusNumber, #131 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount]), #132 8, #133 TRUE); #134 #135 // #136 // Update the adapter count. #137 // #138
增加IDE控制器的个数。 #139 (*adapterCount)++; #140 #141 // #142 // Check if ioSpace accessible. #143 // #144 #145 if (!ioSpace) { #146 continue; #147 } #148 #149 // #150 // Select master. #151 // #152 #153 ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect,0xA0); #154 #155 // #156 // Check if card at this address. #157 // #158 #159 ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow,0xAA); #160 #161 // #162 // Check if indentifier can be read back. #163 // #164 #165 if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) { #166 #167 DebugPrint((2, #168 "AtapiFindPciController: Identifier read back from Master (%x)/n", #169 statusByte)); #170 #171 #172 // #173 // Select slave. #174 // #175 #176 ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->DriveSelect,0xB0); #177 #178 // #179 // See if slave is present. #180 // #181 #182 ScsiPortWritePortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow,0xAA); #183 #184 if ((statusByte = ScsiPortReadPortUchar(&((PIDE_REGISTERS_1)ioSpace)->CylinderLow)) != 0xAA) { #185 #186 DebugPrint((2, #187 "AtapiFindPciController: Identifier read back from Slave (%x)/n", #188 statusByte)); #189 #190 // #191 // #192 // No controller at this base address. #193 // #194 #195 ScsiPortFreeDeviceBase(HwDeviceExtension, #196 ioSpace); #197
继续查找第二个通道是否IDE控制器。 #198 // #199 // If the chip is there,but we couldn't find the primary channel,try the secondary. #200 // If we couldn't find a secondary,who cares. #201 // #202 #203 if (j == 1) { #204 #205 goto setStatusAndExit; #206 #207 } else { #208 continue; #209 } #210 } #211 } #212
如果发现了IDE控制器,就保存相应的配置参数。 #213 if (controllerFound) { #214 #215 // #216 // Record base IO address. #217 // #218 #219 deviceExtension->BaseIoAddress1[channel] = (PIDE_REGISTERS_1)(ioSpace); #220 #221 // #222 // Fill in the access array information. #223 // #224 #225 (*ConfigInfo->AccessRanges)[channel].RangeStart = #226 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]); #227 #228 (*ConfigInfo->AccessRanges)[channel].RangeLength = 8; #229 (*ConfigInfo->AccessRanges)[channel].RangeInMemory = FALSE; #230 #231 // #232 // Indicate the interrupt level corresponding to this IO range. #233 // #234
根据不同的通道进行保存中断号和中断方式。 #235 if (channel == 0) { #236 ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1]; #237 ConfigInfo->InterruptMode = Latched; #238 } else { #239 ConfigInfo->BusInterruptLevel2 = InterruptLevels[*adapterCount - 1]; #240 ConfigInfo->InterruptMode2 = Latched; #241 } #242 #243 // #244 // Get the system physical address for the second IO range. #245 // #246 #247 ioSpace = ScsiPortGetDeviceBase(HwDeviceExtension, #248 ConfigInfo->AdapterInterfaceType, #249 ConfigInfo->SystemIoBusNumber, #250 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1] + 0x206), #251 1, #252 TRUE); #253 #254 deviceExtension->BaseIoAddress2[channel] = (PIDE_REGISTERS_2)(ioSpace); #255 #256 deviceExtension->NumberChannels = 2; #257 #258 // #259 // Indicate only one bus. #260 // #261 #262 ConfigInfo->NumberOfBuses = 1; #263 #264 // #265 // Indicate four devices can be attached to the adapter,since we #266 // have to serialize access to the two channels. #267 // #268 #269 ConfigInfo->MaximumNumberOfTargets = 4; #270 #271 // #272 // Indicate maximum transfer length is 64k. #273 // #274 #275 ConfigInfo->MaximumTransferLength = 0x10000; #276 #277 DebugPrint((1, #278 "AtapiFindPciController: Found broken IDE at %x/n", #279 deviceExtension->BaseIoAddress1[channel])); #280 #281 // #282 // Since we will always pick up this part,and not atdisk,so indicate. #283 // #284 #285 atapiOnly = FALSE; #286
保存中断模式。 #287 // #288 // Save the Interrupe Mode for later use #289 // #290 deviceExtension->InterruptMode = ConfigInfo->InterruptMode; #291
查找这个IDE控制器上所有的设备。 #292 // #293 // Search for devices on this controller. #294 // #295 #296 if (FindDevices(HwDeviceExtension, #297 atapiOnly, #298 channel++)){ #299 deviceFound = TRUE; #300 } #301
判断是主IDE设备,还第二个IDE设备。 #302 // #303 // Claim primary or secondary ATA IO range. #304 // #305 #306 if (*adapterCount == 1) { #307 ConfigInfo->AtdiskPrimaryClaimed = TRUE; #308 deviceExtension->PrimaryAddress = TRUE; #309 #310 } else if (*adapterCount == 2) { #311 ConfigInfo->AtdiskSecondaryClaimed = TRUE; #312 deviceExtension->PrimaryAddress = FALSE; #313 } #314 } #315 } #316 } #317 } #318 #319 setStatusAndExit: #320 #321 if (lastSlot) { #322 slotNumber = 0; #323 functionNumber = 0; #324 } #325 #326 controllers = i; #327 #328 if (controllerFound && deviceFound) { #329
返回已经搜索到设备。 #330 *Again = TRUE; #331 return SP_RETURN_FOUND; #332 } #333 } #334 #335
已经搜索完成,没有任设备发现。 #336 // #337 // The entire table has been searched and no adapters have been found. #338 // #339 #340 *Again = FALSE; #341 #342 return SP_RETURN_NOT_FOUND; #343 #344} // end AtapiFindPCIController() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |