您的位置:首页 > Web前端 > React

reactos操作系统实现(104)

2009-10-14 21:17 459 查看
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()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: