reactos操作系统实现(107)

前端之家收集整理的这篇文章主要介绍了reactos操作系统实现(107)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

IssueIdentify函数主要是发送IDENTIFY命令给一个ATAPI设备,并且获取这个设备相关信息,比如磁头的个数。

#001 BOOLEAN

#002 NTAPI

#003 IssueIdentify(

#004 IN PVOID HwDeviceExtension,

#005 IN ULONG DeviceNumber,

#006 IN ULONG Channel,

#007 IN UCHAR Command

#008 )

#009

#010 /*++

#011

#012 Routine Description:

#013

#014 Issue IDENTIFY command to a device.

#015

#016 Arguments:

#017

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

#019 DeviceNumber - Indicates which device.

#020 Command - Either the standard (EC) or the ATAPI packet (A1) IDENTIFY.

#021

#022 Return Value:

#023

#024 TRUE if all goes well.

#025

#026 --*/

#027

#028 {

获取IDE控制器的IO基地址。

#029 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;

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

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

#032 ULONG waitCount = 20000;

#033 ULONG i,j;

#034 UCHAR statusByte;

#035 UCHAR signatureLow,

#036 signatureHigh;

#037

#038 //

#039 // Select device 0 or 1.

#040 //

#041

选择设备0,或者设备1

#042 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#043 (UCHAR)((DeviceNumber << 4) | 0xA0));

#044

#045 //

#046 // Check that the status register makes sense.

#047 //

#048

获取选择设备的状态。

#049 GetBaseStatus(baseIoAddress1,statusByte);

#050

如果发送命令不是IDENTIFY,就不进入处理。

#051 if (Command == IDE_COMMAND_IDENTIFY) {

#052

#053 //

#054 // Mask status byte ERROR bits.

#055 //

#056

获取错误状态位。

#057 statusByte &= ~(IDE_STATUS_ERROR | IDE_STATUS_INDEX);

#058

#059 DebugPrint((1,

#060 "IssueIdentify: Checking for IDE. Status (%x)/n",

#061 statusByte));

#062

#063 //

#064 // Check if register value is reasonable.

#065 //

#066

如果IDE控制器不空闲,就不复位它。

#067 if (statusByte != IDE_STATUS_IDLE) {

#068

#069 //

#070 // Reset the controller.

#071 //

#072

复位IDE控制器。

#073 AtapiSoftReset(baseIoAddress1,DeviceNumber);

#074

重新选择控制器。

#075 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#076 (UCHAR)((DeviceNumber << 4) | 0xA0));

#077

获取执行命令完成。

#078 WaitOnBusy(baseIoAddress2,statusByte);

#079

读取ATAPI标识,如果还是ATAPI就返回出错。

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

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

#082

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

#084

#085 //

#086 // Device is Atapi.

#087 //

#088

#089 return FALSE;

#090 }

#091

发送IDE_DC_RESET_CONTROLLER命令。

#092 DebugPrint((1,

#093 "IssueIdentify: Resetting controller./n"));

#094

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

#096 ScsiPortStallExecution(500 * 1000);

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

#098

#099

#100 // We really should wait up to 31 seconds

#101 // The ATA spec. allows device 0 to come back from BUSY in 31 seconds!

#102 // (30 seconds for device 1)

IDE控制器准备好。

#103 do {

#104

#105 //

#106 // Wait for Busy to drop.

#107 //

#108

#109 ScsiPortStallExecution(100);

#110 GetStatus(baseIoAddress2,statusByte);

#111

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

#113

#114 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,

#115 (UCHAR)((DeviceNumber << 4) | 0xA0));

#116

#117 //

#118 // Another check for signature,to deal with one model Atapi that doesn't assert signature after

#119 // a soft reset.

#120 //

#121

如果读取IDE标识,还是ATAPI就返回出错。

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

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

#124

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

#126

#127 //

#128 // Device is Atapi.

#129 //

#130

#131 return FALSE;

#132 }

#133

#134 statusByte &= ~IDE_STATUS_INDEX;

#135

如果读取不成功,还是忙等,那么说明这个控制器有问题返回。

#136 if (statusByte != IDE_STATUS_IDLE) {

#137

#138 //

#139 // Give up on this.

#140 //

#141

#142 return FALSE;

#143 }

#144

#145 }

#146

#147 } else {

#148

#149 DebugPrint((1,

#150 "IssueIdentify: Checking for ATAPI. Status (%x)/n",

#151 statusByte));

#152

#153 }

#154

#155 //

#156 // Load CylinderHigh and CylinderLow with number bytes to transfer.

#157 //

#158

#159 ScsiPortWritePortUchar(&baseIoAddress1->CylinderHigh,(0x200 >> 8));

#160 ScsiPortWritePortUchar(&baseIoAddress1->CylinderLow, (0x200 & 0xFF));

#161

#162 for (j = 0; j < 2; j++) {

#163

#164 //

#165 // Send IDENTIFY command.

#166 //

#167

#168 WaitOnBusy(baseIoAddress2,statusByte);

#169

发送一个IDENTIFY命令。

#170 ScsiPortWritePortUchar(&baseIoAddress1->Command,Command);

#171

#172 //

#173 // Wait for DRQ.

#174 //

#175

DRQ状态出现。

#176 for (i = 0; i < 4; i++) {

#177

#178 WaitForDrq(baseIoAddress2,statusByte);

#179

如果出现DRQ状态,说明回应数据已经准备好。

#180 if (statusByte & IDE_STATUS_DRQ) {

#181

#182 //

#183 // Read status to acknowledge any interrupts generated.

#184 //

#185

#186 GetBaseStatus(baseIoAddress1,statusByte);

#187

#188 //

#189 // One last check for Atapi.

#190 //

#191

#192

如果读取还是ATAPI标识,说明出错。

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

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

#195

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

#197

#198 //

#199 // Device is Atapi.

#200 //

#201

#202 return FALSE;

#203 }

#204

#205 break;

#206 }

#207

如果读取还是ATAPI标识,说明出错。

#208 if (Command == IDE_COMMAND_IDENTIFY) {

#209

#210 //

#211 // Check the signature. If DRQ didn't come up it's likely Atapi.

#212 //

#213

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

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

#216

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

#218

#219 //

#220 // Device is Atapi.

#221 //

#222

#223 return FALSE;

#224 }

#225 }

#226

#227 WaitOnBusy(baseIoAddress2,statusByte);

#228 }

#229

进行第二次尝试复位。

#230 if (i == 4 && j == 0) {

#231

#232 //

#233 // Device didn't respond correctly. It will be given one more chances.

#234 //

#235

#236 DebugPrint((1,

#237 "IssueIdentify: DRQ never asserted (%x). Error reg (%x)/n",

#238 statusByte,

#239 ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1)));

#240

#241 AtapiSoftReset(baseIoAddress1,DeviceNumber);

#242

#243 GetStatus(baseIoAddress2,statusByte);

#244

#245 DebugPrint((1,

#246 "IssueIdentify: Status after soft reset (%x)/n",

#247 statusByte));

#248

#249 } else {

#250

#251 break;

#252

#253 }

#254 }

#255

#256 //

#257 // Check for error on really stupid master devices that assert random

#258 // patterns of bits in the status register at the slave address.

#259 //

#260

如果状态出错,说明不认识这个命令。

#261 if ((Command == IDE_COMMAND_IDENTIFY) && (statusByte & IDE_STATUS_ERROR)) {

#262 return FALSE;

#263 }

#264

#265 DebugPrint((1,

#266 "IssueIdentify: Status before read words %x/n",

#267 statusByte));

#268

#269 //

#270 // Suck out 256 words. After waiting for one model that asserts busy

#271 // after receiving the Packet Identify command.

#272 //

#273

等准备好数据。

#274 WaitOnBusy(baseIoAddress2,statusByte);

#275

#276 if (!(statusByte & IDE_STATUS_DRQ)) {

#277 return FALSE;

#278 }

#279

IDEIDE_COMMAND_IDENTIFY命令返回的512个字节。

#280 ReadBuffer(baseIoAddress1,

#281 (PUSHORT)&deviceExtension->FullIdentifyData,

#282 256);

#283

#284 //

#285 // Check out a few capabilities / limitations of the device.

#286 //

#287

检查IDE控制器兼容性。

#288 if (deviceExtension->FullIdentifyData.SpecialFunctionsEnabled & 1) {

#289

#290 //

#291 // Determine if this drive supports the MSN functions.

#292 //

#293

查看是否支持可移动特性。

#294 DebugPrint((2,"IssueIdentify: Marking drive %d as removable. SFE = %d/n",

#295 Channel * 2 + DeviceNumber,

#296 deviceExtension->FullIdentifyData.SpecialFunctionsEnabled));

#297

#298

#299 deviceExtension->DeviceFlags[(Channel * 2) + DeviceNumber] |= DFLAGS_REMOVABLE_DRIVE;

#300 }

#301

设置最大块传送参数。

#302 if (deviceExtension->FullIdentifyData.MaximumBlockTransfer) {

#303

#304 //

#305 // Determine max. block transfer for this device.

#306 //

#307

#308 deviceExtension->MaximumBlockXfer[(Channel * 2) + DeviceNumber] =

#309 (UCHAR)(deviceExtension->FullIdentifyData.MaximumBlockTransfer & 0xFF);

#310 }

#311

#312 ScsiPortMoveMemory(&deviceExtension->IdentifyData[(Channel * 2) + DeviceNumber],&deviceExtension->FullIdentifyData,sizeof(IDENTIFY_DATA2));

#313

#314 if (deviceExtension->IdentifyData[(Channel * 2) + DeviceNumber].GeneralConfiguration & 0x20 &&

#315 Command != IDE_COMMAND_IDENTIFY) {

#316

#317 //

#318 // This device interrupts with the assertion of DRQ after receiving

#319 // Atapi Packet Command

#320 //

#321

#322 deviceExtension->DeviceFlags[(Channel * 2) + DeviceNumber] |= DFLAGS_INT_DRQ;

#323

#324 DebugPrint((2,

#325 "IssueIdentify: Device interrupts on assertion of DRQ./n"));

#326

#327 } else {

#328

#329 DebugPrint((2,

#330 "IssueIdentify: Device does not interrupt on assertion of DRQ./n"));

#331 }

判断这个是否磁带设备。

#332

#333 if (((deviceExtension->IdentifyData[(Channel * 2) + DeviceNumber].GeneralConfiguration & 0xF00) == 0x100) &&

#334 Command != IDE_COMMAND_IDENTIFY) {

#335

#336 //

#337 // This is a tape.

#338 //

#339

这是一个TAPE设备。

#340 deviceExtension->DeviceFlags[(Channel * 2) + DeviceNumber] |= DFLAGS_TAPE_DEVICE;

#341

#342 DebugPrint((2,

#343 "IssueIdentify: Device is a tape drive./n"));

#344

#345 } else {

#346

#347 DebugPrint((2,

#348 "IssueIdentify: Device is not a tape drive./n"));

#349 }

#350

#351 //

#352 // Work around for some IDE and one model Atapi that will present more than

#353 // 256 bytes for the Identify data.

#354 //

#355

#356 WaitOnBusy(baseIoAddress2,statusByte);

#357

读取超过256个字节IDE传送的数据。

#358 for (i = 0; i < 0x10000; i++) {

#359

#360 GetStatus(baseIoAddress2,statusByte);

#361

#362 if (statusByte & IDE_STATUS_DRQ) {

#363

#364 //

#365 // Suck out any remaining bytes and throw away.

#366 //

#367

#368 ScsiPortReadPortUshort(&baseIoAddress1->Data);

#369

#370 } else {

#371

#372 break;

#373

#374 }

#375 }

#376

#377 DebugPrint((3,

#378 "IssueIdentify: Status after read words (%x)/n",

#379 statusByte));

#380

#381 return TRUE;

#382

#383 } // end IssueIdentify()

猜你在找的React相关文章