现在的位置: 首页 > 综合 > 正文

reactos操作系统实现(104)

2013年10月03日 ⁄ 综合 ⁄ 共 13163字 ⁄ 字号 评论关闭

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()

抱歉!评论已关闭.