加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactos操作系统实现(106)

发布时间:2020-12-15 05:00:13 所属栏目:百科 来源:网络整理
导读:FindDevices 函数主要用来查找 ATAPI 控制器,并且获取磁盘的参数。如果找到 IDE 的设备就返回 TRUE ,否则返回 FALSE 。其实是通过 ATAPI 的标志和 IssueIdentify 命令来判断 IDE 设备。 #001 BOOLEAN #002 NTAPI #003 FindDevices( #004 IN PVOID HwDevice

FindDevices函数主要用来查找ATAPI控制器,并且获取磁盘的参数。如果找到IDE的设备就返回TRUE,否则返回FALSE。其实是通过ATAPI的标志和IssueIdentify命令来判断IDE设备。

#001 BOOLEAN

#002 NTAPI

#003 FindDevices(

#004 IN PVOID HwDeviceExtension,

#005 IN BOOLEAN AtapiOnly,

#006 IN ULONG Channel

#007 )

#008

#009 /*++

#010

#011 Routine Description:

#012

#013 This routine is called from AtapiFindController to identify

#014 devices attached to an IDE controller.

#015

#016 Arguments:

#017

#018 HwDeviceExtension - HBA miniport driver's adapter data storage

#019 AtapiOnly - Indicates that routine should return TRUE only if

#020 an ATAPI device is attached to the controller.

#021

#022 Return Value:

#023

#024 TRUE - True if devices found.

#025

#026 --*/

#027

#028 {

HwDeviceExtension是主机总线适配器的数据。

#029 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;

获取PCI总线配置空间的两个寄存器地址。

#030 PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[Channel];

#031 PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[Channel];

#032 BOOLEAN deviceResponded = FALSE,

#033 skipSetParameters = FALSE;

#034 ULONG waitCount = 10000;

#035 ULONG deviceNumber;

#036 ULONG i;

#037 UCHAR signatureLow,

#038 signatureHigh;

#039 UCHAR statusByte;

#040

#041 //

#042 // Clear expecting interrupt flag and current SRB field.

#043 //

#044

清空需要中断的标志和SRB

#045 deviceExtension->ExpectingInterrupt = FALSE;

#046 deviceExtension->CurrentSrb = NULL;

#047

#048 //

#049 // Search for devices.

#050 //

#051

每个IDE控制器上最多有两个设备。

#052 for (deviceNumber = 0; deviceNumber < 2; deviceNumber++) {

#053

#054 //

#055 // Select the device.

#056 //

#057

选择IDE主控制器。

#058 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#059 (UCHAR)((deviceNumber << 4) | 0xA0));

#060

#061 //

#062 // Check here for some SCSI adapters that incorporate IDE emulation.

#063 //

#064

获取当前IDE控制器的状态,如果不成功就继续查找下一个。如果读回来的状态等于0XFF,说明总线是在浮动状态,也就是总是接到正5V的电源上。

#065 GetStatus(baseIoAddress2,statusByte);

#066 if (statusByte == 0xFF) {

#067 continue;

#068 }

#069

发送ATAPI的命令实现软件复位IDE控制器。

#070 AtapiSoftReset(baseIoAddress1,deviceNumber);

#071 WaitOnBusy(baseIoAddress2,statusByte);

#072

读取ATAPI的类型,比如是PATAPI,还是SATAPI/PATA/SATA

#073 signatureLow = ScsiPortReadPortUchar(&baseIoAddress1->CylinderLow);

#074 signatureHigh = ScsiPortReadPortUchar(&baseIoAddress1->CylinderHigh);

#075

#076 if (signatureLow == 0x14 && signatureHigh == 0xEB) {

#077

如果发现是PATAPI的标志。

#078 //

#079 // ATAPI signature found.

#080 // Issue the ATAPI identify command if this

#081 // is not for the crash dump utility.

#082 //

#083

#084 atapiIssueId:

#085

如果设置不是轮询模式。

#086 if (!deviceExtension->DriverMustPoll) {

#087

#088 //

#089 // Issue ATAPI packet identify command.

#090 //

#091

发送IDE标识命令。

#092 if (IssueIdentify(HwDeviceExtension,

#093 deviceNumber,

#094 Channel,

#095 IDE_COMMAND_ATAPI_IDENTIFY)) {

#096

#097 //

#098 // Indicate ATAPI device.

#099 //

#100

#101 DebugPrint((1,

#102 "FindDevices: Device %x is ATAPI/n",

#103 deviceNumber));

#104

标识这里发现了ATAPI设备。

#105 deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_ATAPI_DEVICE;

#106 deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_DEVICE_PRESENT;

#107

#108 deviceResponded = TRUE;

#109

#110 GetStatus(baseIoAddress2,statusByte);

#111 if (statusByte & IDE_STATUS_ERROR) {

#112 AtapiSoftReset(baseIoAddress1,deviceNumber);

#113 }

#114

#115

#116 } else {

#117

没有发现任何ATAPI设备。

#118 //

#119 // Indicate no working device.

#120 //

#121

#122 DebugPrint((1,

#123 "FindDevices: Device %x not responding/n",

#124 deviceNumber));

#125

#126 deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] &= ~DFLAGS_DEVICE_PRESENT;

#127 }

#128

#129 }

#130

#131 } else {

#132

#133 //

#134 // Issue IDE Identify. If an Atapi device is actually present,the signature

#135 // will be asserted,and the drive will be recognized as such.

#136 //

其它ATA设备类型,发送一个标识命令。

#137

#138 if (IssueIdentify(HwDeviceExtension,

#139 deviceNumber,

#140 Channel,

#141 IDE_COMMAND_IDENTIFY)) {

#142

#143 //

#144 // IDE drive found.

#145 //

#146

如果发送标识命令成功,说明发现了IDE设备。

#147

#148 DebugPrint((1,

#149 "FindDevices: Device %x is IDE/n",

#150 deviceNumber));

#151

#152 deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] |= DFLAGS_DEVICE_PRESENT;

#153

#154 if (!AtapiOnly) {

#155 deviceResponded = TRUE;

#156 }

#157

#158 //

#159 // Indicate IDE - not ATAPI device.

#160 //

#161

但这个设备不是ATAPI设备。

#162 deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] &= ~DFLAGS_ATAPI_DEVICE;

#163

#164

#165 } else {

#166

#167 //

#168 // Look to see if an Atapi device is present.

#169 //

#170

再次查找,是否找到ATAPI标志,如果找到就再回去检查是否读取标识成功。

#171 AtapiSoftReset(baseIoAddress1,deviceNumber);

#172

#173 WaitOnBusy(baseIoAddress2,statusByte);

#174

#175 signatureLow = ScsiPortReadPortUchar(&baseIoAddress1->CylinderLow);

#176 signatureHigh = ScsiPortReadPortUchar(&baseIoAddress1->CylinderHigh);

#177

#178 if (signatureLow == 0x14 && signatureHigh == 0xEB) {

#179 goto atapiIssueId;

#180 }

#181 }

#182 }

#183 }

#184

开始对一些特别的IDE控制器进行参数转换处理。

#185 for (i = 0; i < 2; i++) {

#186 if ((deviceExtension->DeviceFlags[i + (Channel * 2)] & DFLAGS_DEVICE_PRESENT) &&

#187 (!(deviceExtension->DeviceFlags[i + (Channel * 2)] & DFLAGS_ATAPI_DEVICE)) && deviceResponded) {

#188

下面是对一些磁道和磁头的特别处理。

#189 //

#190 // This hideous hack is to deal with ESDI devices that return

#191 // garbage geometry in the IDENTIFY data.

#192 // This is ONLY for the crashdump environment as

#193 // these are ESDI devices.

#194 //

#195

#196 if (deviceExtension->IdentifyData[i].SectorsPerTrack ==

#197 0x35 &&

#198 deviceExtension->IdentifyData[i].NumberOfHeads ==

#199 0x07) {

#200

#201 DebugPrint((1,

#202 "FindDevices: Found nasty Compaq ESDI!/n"));

#203

#204 //

#205 // Change these values to something reasonable.

#206 //

#207

#208 deviceExtension->IdentifyData[i].SectorsPerTrack =

#209 0x34;

#210 deviceExtension->IdentifyData[i].NumberOfHeads =

#211 0x0E;

#212 }

#213

#214 if (deviceExtension->IdentifyData[i].SectorsPerTrack ==

#215 0x35 &&

#216 deviceExtension->IdentifyData[i].NumberOfHeads ==

#217 0x0F) {

#218

#219 DebugPrint((1,

#220 "FindDevices: Found nasty Compaq ESDI!/n"));

#221

#222 //

#223 // Change these values to something reasonable.

#224 //

#225

#226 deviceExtension->IdentifyData[i].SectorsPerTrack =

#227 0x34;

#228 deviceExtension->IdentifyData[i].NumberOfHeads =

#229 0x0F;

#230 }

#231

#232

#233 if (deviceExtension->IdentifyData[i].SectorsPerTrack ==

#234 0x36 &&

#235 deviceExtension->IdentifyData[i].NumberOfHeads ==

#236 0x07) {

#237

#238 DebugPrint((1,

#239 "FindDevices: Found nasty UltraStor ESDI!/n"));

#240

#241 //

#242 // Change these values to something reasonable.

#243 //

#244

#245 deviceExtension->IdentifyData[i].SectorsPerTrack =

#246 0x3F;

#247 deviceExtension->IdentifyData[i].NumberOfHeads =

#248 0x10;

#249 skipSetParameters = TRUE;

#250 }

#251

#252

对磁盘进行参数设置。

#253 if (!skipSetParameters) {

#254

#255 WaitOnBusy(baseIoAddress2,statusByte);

#256

#257 //

#258 // Select the device.

#259 //

#260

#261 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#262 (UCHAR)((i << 4) | 0xA0));

#263

#264 GetStatus(baseIoAddress2,statusByte);

#265

#266 if (statusByte & IDE_STATUS_ERROR) {

#267

#268 //

#269 // Reset the device.

#270 //

#271

#272 DebugPrint((2,

#273 "FindDevices: Resetting controller before SetDriveParameters./n"));

#274

#275 ScsiPortWritePortUchar(&baseIoAddress2->AlternateStatus,IDE_DC_RESET_CONTROLLER );

#276 ScsiPortStallExecution(500 * 1000);

#277 ScsiPortWritePortUchar(&baseIoAddress2->AlternateStatus,IDE_DC_REENABLE_CONTROLLER);

#278 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#279 (UCHAR)((i << 4) | 0xA0));

#280

#281 do {

#282

#283 //

#284 // Wait for Busy to drop.

#285 //

#286

#287 ScsiPortStallExecution(100);

#288 GetStatus(baseIoAddress2,statusByte);

#289

#290 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);

#291 }

#292

#293 WaitOnBusy(baseIoAddress2,statusByte);

#294 DebugPrint((2,

#295 "FindDevices: Status before SetDriveParameters: (%x) (%x)/n",

#296 statusByte,

#297 ScsiPortReadPortUchar(&baseIoAddress1->DriveSelect)));

#298

#299 //

#300 // Use the IDENTIFY data to set drive parameters.

#301 //

#302

#303 if (!SetDriveParameters(HwDeviceExtension,i,Channel)) {

#304

#305 DebugPrint((0,

#306 "AtapHwInitialize: Set drive parameters for device %d failed/n",

#307 i));

#308

#309 //

#310 // Don't use this device as writes could cause corruption.

#311 //

#312

#313 deviceExtension->DeviceFlags[i + Channel] = 0;

#314 continue;

#315

#316 }

#317 if (deviceExtension->DeviceFlags[deviceNumber + (Channel * 2)] & DFLAGS_REMOVABLE_DRIVE) {

#318

#319 //

#320 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...

#321 //

#322

#323 AtapiOnly = FALSE;

#324 }

#325

#326

#327 //

#328 // Indicate that a device was found.

#329 //

#330

#331 if (!AtapiOnly) {

#332 deviceResponded = TRUE;

#333 }

#334 }

#335 }

#336 }

#337

#338 //

#339 // Make sure master device is selected on exit.

#340 //

#341

选择主控制器。

#342 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,0xA0);

#343

#344 //

#345 // Reset the controller. This is a feeble attempt to leave the ESDI

#346 // controllers in a state that ATDISK driver will recognize them.

#347 // The problem in ATDISK has to do with timings as it is not reproducible

#348 // in debug. The reset should restore the controller to its poweron state

#349 // and give the system enough time to settle.

#350 //

#351

复位IDE控制器。

#352 if (!deviceResponded) {

#353

#354 ScsiPortWritePortUchar(&baseIoAddress2->AlternateStatus,IDE_DC_RESET_CONTROLLER );

#355 ScsiPortStallExecution(50 * 1000);

#356 ScsiPortWritePortUchar(&baseIoAddress2->AlternateStatus,IDE_DC_REENABLE_CONTROLLER);

#357 }

#358

#359 return deviceResponded;

#360

#361} // end FindDevices()

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读