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

reactos操作系统实现(109)

2009-10-19 22:11 369 查看
AtapiInterrupt函数是实现ATAPI的中断功能,主要根据SRB来判断是读取数据还是写入数据,然后对IDE设备读取或写入数据,还需要处理很多出错的情况。具体实现代码如下:

#001 BOOLEAN

#002 NTAPI

#003 AtapiInterrupt(

#004 IN PVOID
HwDeviceExtension

#005 )

#006

#007 /*++

#008

#009 Routine Description:

#010

#011 This is the interrupt
service routine for ATAPI IDE miniport driver.

#012

#013 Arguments:

#014

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

#016

#017 Return Value:

#018

#019 TRUE if expecting an
interrupt.

#020

#021 --*/

#022

#023 {

获取IDE的扩展对象结构。

#024 PHW_DEVICE_EXTENSION
deviceExtension = HwDeviceExtension;

获取当前SRB数据。

#025 PSCSI_REQUEST_BLOCK
srb =
deviceExtension->CurrentSrb;

#026 PATAPI_REGISTERS_1
baseIoAddress1;

#027 PATAPI_REGISTERS_2
baseIoAddress2;

每次读取256个双字节,也就是512个字节。

#028 ULONG wordCount = 0,
wordsThisInterrupt = 256;

#029 ULONG status;

#030 ULONG i;

#031 UCHAR
statusByte,interruptReason;

#032 BOOLEAN atapiDev =
FALSE;

#033

获取IDE的基地址。

#034 if (srb) {

如果有SRB,说明直接从SRB里读取基地址就行了。

#035 baseIoAddress1
=
(PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[srb->TargetId
>> 1];

#036 baseIoAddress2
=
(PATAPI_REGISTERS_2)deviceExtension->BaseIoAddress2[srb->TargetId
>> 1];

#037 } else {

否则就需要PPC的情况,或者使用一个默认的基地址。

#038 DebugPrint((2,

#039
"AtapiInterrupt: CurrentSrb is NULL/n"));

#040 //

#041 // We can only
support one ATAPI IDE master on Carolina, so find

#042 // the base address
that is non NULL and clear its interrupt before

#043 // returning.

#044 //

#045

#046 #ifdef _PPC_

#047

#048 if
((PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0] != NULL) {

#049 baseIoAddress1 =
(PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];

#050 } else {

#051 baseIoAddress1 =
(PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];

#052 }

#053

#054
GetBaseStatus(baseIoAddress1, statusByte);

#055 #else

#056

使用一个默认的基地址

#057 if
(deviceExtension->InterruptMode == LevelSensitive) {

#058 if
(deviceExtension->BaseIoAddress1[0] != NULL) {

#059
baseIoAddress1 =
(PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];

#060
GetBaseStatus(baseIoAddress1, statusByte);

#061 }

#062 if
(deviceExtension->BaseIoAddress1[1] != NULL) {

#063
baseIoAddress1 =
(PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];

#064 GetBaseStatus(baseIoAddress1,
statusByte);

#065 }

#066 }

#067 #endif

如果没有基地址,这个驱动程序不能访问IDE控制器。

#068 return FALSE;

#069 }

#070

如果驱动程序不能接收中断,就直接返回去。

#071 if
(!(deviceExtension->ExpectingInterrupt)) {

#072

#073 DebugPrint((3,

#074
"AtapiInterrupt: Unexpected interrupt./n"));

#075 return FALSE;

#076 }

#077

#078 //

#079 // Clear interrupt by
reading status.

#080 //

#081

读取当前状态。

#082 GetBaseStatus(baseIoAddress1,
statusByte);

#083

#084 DebugPrint((3,

#085
"AtapiInterrupt: Entered with status (%x)/n",

#086
statusByte));

#087

#088

如果IDE的状态为忙状态。

#089 if (statusByte &
IDE_STATUS_BUSY) {

如果设备需要采用轮询的方式,就直接返回。

#090 if
(deviceExtension->DriverMustPoll) {

#091

#092 //

#093 // Crashdump is
polling and we got caught with busy asserted.

#094 // Just go away,
and we will be polled again shortly.

#095 //

#096

#097 DebugPrint((3,

#098
"AtapiInterrupt: Hit BUSY while polling during
crashdump./n"));

#099

#100 return TRUE;

#101 }

#102

#103 //

#104 // Ensure BUSY is
non-asserted.

#105 //

#106

如果查询10次,还是忙状态,说明IDE还是在忙,没有办法响应,调用函数ScsiPortNotification来设置回调函数。

#107 for (i = 0; i <
10; i++) {

#108

#109
GetBaseStatus(baseIoAddress1, statusByte);

#110 if (!(statusByte
& IDE_STATUS_BUSY)) {

#111 break;

#112 }

#113
ScsiPortStallExecution(5000);

#114 }

#115

#116 if (i == 10) {

#117

#118 DebugPrint((2,

#119
"AtapiInterrupt: BUSY on entry. Status %x, Base IO %x/n",

#120
statusByte,

#121
baseIoAddress1));

#122

#123
ScsiPortNotification(RequestTimerCall,

#124
HwDeviceExtension,

#125 AtapiCallBack,

#126
500);

#127 return TRUE;

#128 }

#129 }

#130

#131

#132 //

#133 // Check for error
conditions.

#134 //

#135

如果当前IDE设备的状态为出错,就设置这个SRB请求完成,并且是出错返回。

#136 if (statusByte &
IDE_STATUS_ERROR) {

#137

#138 if (srb->Cdb[0]
!= SCSIOP_REQUEST_SENSE) {

#139

#140 //

#141 // Fail this
request.

#142 //

#143

#144 status =
SRB_STATUS_ERROR;

#145 goto
CompleteRequest;

#146 }

#147 }

#148

#149 //

#150 // check reason for this
interrupt.

#151 //

#152

如果没有出错,也没有忙状态,判断这个中断的原因是什么。

#153 if
(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {

如果ATAPI设备中断,就读取中断的原因,并设置传送的字节数为512个字节。

#154

#155 interruptReason =
(ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason) & 0x3);

#156 atapiDev = TRUE;

#157 wordsThisInterrupt =
256;

#158

#159 } else {

#160

如果是DRQ的方式传送,就进入下面处理。

#161 if (statusByte &
IDE_STATUS_DRQ) {

#162

多块传送数据。

#163 if
(deviceExtension->MaximumBlockXfer[srb->TargetId]) {

#164
wordsThisInterrupt = 256 * deviceExtension->MaximumBlockXfer[srb->TargetId];

#165

#166
}

#167

读取数据进来。

#168
if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {

#169

#170
interruptReason = 0x2;

#171

传送数据出去。

#172 } else if
(srb->SrbFlags & SRB_FLAGS_DATA_OUT) {

#173
interruptReason = 0x0;

#174

#175 } else {

错误请求中断。

#176 status =
SRB_STATUS_ERROR;

#177 goto
CompleteRequest;

#178 }

#179

#180 } else if
(statusByte & IDE_STATUS_BUSY) {

#181

#182 return FALSE;

#183

#184 } else {

#185

如果需要补充写字节,就进入下面处理。

#186 if
(deviceExtension->WordsLeft) {

#187

#188 ULONG k;

#189

#190 //

#191 // Funky
behaviour seen with PCI IDE (not all, just one).

#192 // The ISR
hits with DRQ low, but comes up later.

#193 //

#194

#195 for (k = 0;
k < 5000; k++) {

#196
GetStatus(baseIoAddress2,statusByte);

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

#198
ScsiPortStallExecution(100);

#199 } else {

#200
break;

#201 }

#202 }

#203

#204 if (k ==
5000) {

#205

#206 //

#207 // reset
the controller.

#208 //

#209

#210
DebugPrint((1,

#211 "AtapiInterrupt: Resetting due to DRQ
not up. Status %x, Base IO %x/n",

#212
statusByte,

#213
baseIoAddress1));

#214

#215
AtapiResetController(HwDeviceExtension,srb->PathId);

#216 return
TRUE;

#217 } else {

#218

#219
interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x2 :
0x0;

#220 }

#221

#222 } else {

#223

下面获取媒介的状态。

#224 //

#225 // Command
complete - verify, write, or the SMART enable/disable.

#226 //

#227 // Also
get_media_status

#228

#229
interruptReason = 0x3;

#230 }

#231 }

#232 }

#233

根据中断原因进行处理。

#234 if (interruptReason ==
0x1 && (statusByte & IDE_STATUS_DRQ)) {

#235

中断原因是写数据到IDE设备。

#236 //

#237 // Write the packet.

#238 //

#239

#240 DebugPrint((2,

#241
"AtapiInterrupt: Writing Atapi packet./n"));

#242

#243 //

#244 // Send CDB to
device.

#245 //

#246

把CDB数据发送给设备。这里的WriteBuffer,其实是调用函数ScsiPortWritePortBufferUshort,它的作用就是把缓冲区里的数据发送到HBA总线上。

#247 WriteBuffer(baseIoAddress1,

#248
(PUSHORT)srb->Cdb,

#249 6);

#250

#251 return TRUE;

#252

#253 } else if
(interruptReason == 0x0 && (statusByte & IDE_STATUS_DRQ)) {

#254

#255 //

#256 // Write the data.

#257 //

#258

确认是否ATAPI设备。

#259 if
(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {

#260

#261 //

#262 // Pick up bytes
to transfer and convert to words.

#263 //

#264

从ATAPI设备里读取要传送的字节数,把字节转换为字的个数。

#265 wordCount =

#266
ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);

#267

#268 wordCount |=

#269
ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;

#270

#271 //

#272 // Covert bytes
to words.

#273 //

#274

#275 wordCount
>>= 1;

#276

#277 if (wordCount !=
deviceExtension->WordsLeft) {

#278 DebugPrint((3,

#279
"AtapiInterrupt: %d words requested; %d words xferred/n",

#280
deviceExtension->WordsLeft,

#281
wordCount));

#282 }

#283

如果要传送的字个数大于剩余的个数,那么就只传送剩余的个数。

#284 //

#285 // Verify this
makes sense.

#286 //

#287

#288 if (wordCount
> deviceExtension->WordsLeft) {

#289 wordCount =
deviceExtension->WordsLeft;

#290 }

#291

#292 } else {

#293

#294 //

#295 // IDE path.
Check if words left is at least 256.

#296 //

#297

判断是否剩余字个数小于256个字,如果是小于,就只传送剩余个数,否则就传送256个字。

#298 if
(deviceExtension->WordsLeft < wordsThisInterrupt) {

#299

#300 //

#301 // Transfer
only words requested.

#302 //

#303

#304 wordCount =
deviceExtension->WordsLeft;

#305

#306 } else {

#307

#308 //

#309 // Transfer
next block.

#310 //

#311

#312 wordCount =
wordsThisInterrupt;

#313 }

#314 }

#315

#316 //

#317 // Ensure that this
is a write command.

#318 //

#319

检查它是写的命令。

#320 if (srb->SrbFlags
& SRB_FLAGS_DATA_OUT) {

#321

#322 DebugPrint((3,

#323
"AtapiInterrupt: Write interrupt/n"));

#324

等到IDE设备不忙。

#325
WaitOnBusy(baseIoAddress2,statusByte);

#326

判断是否写到第三个基地址。

#327 if (atapiDev ||
!deviceExtension->DWordIO) {

#328

#329
WriteBuffer(baseIoAddress1,

#330
deviceExtension->DataBuffer,

#331
wordCount);

#332 } else {

#333

#334
PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;

#335

#336
WriteBuffer2(address3,

#337
(PULONG)(deviceExtension->DataBuffer),

#338 wordCount / 2);

#339 }

#340 } else {

#341

如果不是写的命令,就提示出错返回。

#342 DebugPrint((1,

#343
"AtapiInterrupt: Int reason %x, but srb is for a write %x./n",

#344
interruptReason,

#345
srb));

#346

#347 //

#348 // Fail this
request.

#349 //

#350

#351 status =
SRB_STATUS_ERROR;

#352 goto
CompleteRequest;

#353 }

#354

#355

#356 //

#357 // Advance data
buffer pointer and bytes left.

#358 //

#359

调整已经传送的缓冲区字个数,以便下一次传送。

#360
deviceExtension->DataBuffer += wordCount;

#361
deviceExtension->WordsLeft -= wordCount;

#362

#363 return TRUE;

#364

#365 } else if
(interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {

#366

#367

这是读取数据命令。

#368 if
(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {

#369

#370 //

#371 // Pick up bytes to transfer and convert
to words.

#372 //

#373

读取IDE设备要传送的字节数,并转换为字的个数。

#374 wordCount =

#375
ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);

#376

#377 wordCount |=

#378
ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;

#379

#380 //

#381 // Covert bytes
to words.

#382 //

#383

#384 wordCount
>>= 1;

#385

请求的个数不等于IDE设备要传送的字节数,就提示。

#386 if (wordCount !=
deviceExtension->WordsLeft) {

#387
DebugPrint((3,

#388
"AtapiInterrupt: %d words requested; %d words xferred/n",

#389
deviceExtension->WordsLeft,

#390 wordCount));

#391 }

#392

#393 //

#394 // Verify this
makes sense.

#395 //

#396

如果取得最小的值来传送。

#397 if (wordCount
> deviceExtension->WordsLeft) {

#398 wordCount = deviceExtension->WordsLeft;

#399 }

#400

#401 } else {

#402

#403 //

#404 // Check if
words left is at least 256.

#405 //

#406

如果只是传送剩余的字节,就设置传送剩余字节,否则就是传送512个字节。

#407 if (deviceExtension->WordsLeft <
wordsThisInterrupt) {

#408

#409 //

#410 // Transfer
only words requested.

#411 //

#412

#413 wordCount =
deviceExtension->WordsLeft;

#414

#415 } else {

#416

#417 //

#418 // Transfer
next block.

#419 //

#420

#421 wordCount =
wordsThisInterrupt;

#422 }

#423 }

#424

#425 //

#426 // Ensure that this
is a read command.

#427
//

#428

检查这个命令是读取的命令。

#429
if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {

#430

#431 DebugPrint((3,

#432
"AtapiInterrupt: Read interrupt/n"));

#433

等待IDE设备空闲。

#434
WaitOnBusy(baseIoAddress2,statusByte);

#435

读取数据到缓冲区。

#436 if (atapiDev ||
!deviceExtension->DWordIO) {

#437
ReadBuffer(baseIoAddress1,

#438
deviceExtension->DataBuffer,

#439 wordCount);

#440

#441 } else {

使用4字节的方式读取。

#442
PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;

#443

#444
ReadBuffer2(address3,

#445
(PULONG)(deviceExtension->DataBuffer),

#446
wordCount / 2);

#447 }

#448 } else {

#449

处理这个IDE设备请示失败。

#450 DebugPrint((1,

#451
"AtapiInterrupt: Int reason %x, but srb is for a read %x./n",

#452
interruptReason,

#453
srb));

#454

#455 //

#456 // Fail this
request.

#457 //

#458

#459 status =
SRB_STATUS_ERROR;

#460 goto CompleteRequest;

#461 }

#462

#463 //

#464 // Translate ATAPI
data back to SCSI data if needed

#465 //

#466

#467 if (srb->Cdb[0]
== ATAPI_MODE_SENSE &&

#468
deviceExtension->DeviceFlags[srb->TargetId] &
DFLAGS_ATAPI_DEVICE) {

#469

#470 //

#471 //convert and
adjust the wordCount

#472 //

#473

#474 wordCount -=
Atapi2Scsi(srb, (char *)deviceExtension->DataBuffer,

#475
wordCount << 1);

#476 }

#477 //

#478 // Advance data
buffer pointer and bytes left.

#479 //

#480

调整已经传送的字节。

#481
deviceExtension->DataBuffer += wordCount;

#482
deviceExtension->WordsLeft -= wordCount;

#483

#484 //

#485 // Check for read
command complete.

#486 //

#487

检查是否读取完成。

#488 if
(deviceExtension->WordsLeft == 0) {

#489

#490 if
(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {

#491

#492 //

#493 // Work
around to make many atapi devices return correct sector size

#494 // of 2048.
Also certain devices will have sector count == 0x00, check

#495 // for that
also.

#496 //

#497

#498 if
((srb->Cdb[0] == 0x25) &&

#499
((deviceExtension->IdentifyData[srb->TargetId].GeneralConfiguration
>> 8) & 0x1f) == 0x05)
{

#500

#501 deviceExtension->DataBuffer
-= wordCount;

#502 if
(deviceExtension->DataBuffer[0] == 0x00) {

#503

#504
*((ULONG *) &(deviceExtension->DataBuffer[0])) = 0xFFFFFF7F;

#505

#506 }

#507

#508 *((ULONG *)
&(deviceExtension->DataBuffer[2])) = 0x00080000;

#509
deviceExtension->DataBuffer += wordCount;

#510 }

#511 } else {

#512

#513 //

#514 // Completion
for IDE drives.

#515 //

#516

到这里已经读取数据完成。

#517

#518 if
(deviceExtension->WordsLeft) {

#519

#520 status =
SRB_STATUS_DATA_OVERRUN;

#521

#522 } else {

#523

#524 status = SRB_STATUS_SUCCESS;

#525

#526 }

#527

#528 goto
CompleteRequest;

#529

#530 }

#531 }

#532

#533 return TRUE;

#534

#535 } else if
(interruptReason == 0x3 &&
!(statusByte & IDE_STATUS_DRQ)) {

#536

#537 //

#538 // Command complete.

#539 //

#540

否则是写数据完成。

#541 if
(deviceExtension->WordsLeft) {

#542

#543 status =
SRB_STATUS_DATA_OVERRUN;

#544

#545 } else {

#546

#547 status =
SRB_STATUS_SUCCESS;

#548

#549 }

#550

#551 CompleteRequest:

#552

#553 //

#554 // Check and see if
we are processing our secret (mechanism status/request sense) srb

#555 //

#556 if
(deviceExtension->OriginalSrb) {

#557

#558 ULONG srbStatus;

#559

#560 if
(srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {

#561

#562 if (status
== SRB_STATUS_SUCCESS) {

#563 // Bingo!!

#564
AtapiHwInitializeChanger (HwDeviceExtension,

#565
srb->TargetId,

#566
(PMECHANICAL_STATUS_INFORMATION_HEADER) srb->DataBuffer);

#567

#568 // Get
ready to issue the original srb

#569 srb =
deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;

#570
deviceExtension->OriginalSrb = NULL;

#571

#572 } else {

#573 //
failed! Get the sense key and maybe try
again

#574 srb =
deviceExtension->CurrentSrb = BuildRequestSenseSrb (

#575
HwDeviceExtension,

#576
deviceExtension->OriginalSrb->PathId,

#577
deviceExtension->OriginalSrb->TargetId);

#578 }

#579

重新发送当前SRB数据包。

#580 srbStatus =
AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);

#581 if
(srbStatus == SRB_STATUS_PENDING) {

#582 return
TRUE;

#583 }

#584

#585 } else { //
srb->Cdb[0] == SCSIOP_REQUEST_SENSE)

#586

#587 PSENSE_DATA
senseData = (PSENSE_DATA) srb->DataBuffer;

#588

#589 if (status
== SRB_STATUS_DATA_OVERRUN) {

#590 // Check
to see if we at least get mininum number of bytes

#591 if
((srb->DataTransferLength - deviceExtension->WordsLeft) >

#592
(FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) +
sizeof(senseData->AdditionalSenseLength))) {

#593 status = SRB_STATUS_SUCCESS;

#594 }

#595 }

#596

#597 if (status
== SRB_STATUS_SUCCESS) {

#598 if
((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&

#599 deviceExtension->MechStatusRetryCount)
{

#600

#601 //
The sense key doesn't say the last request is illegal, so try again

#602
deviceExtension->MechStatusRetryCount--;

#603 srb =
deviceExtension->CurrentSrb = BuildMechanismStatusSrb (

#604
HwDeviceExtension,

#605
deviceExtension->OriginalSrb->PathId,

#606
deviceExtension->OriginalSrb->TargetId);

#607 } else {

#608

#609 //
last request was illegal. No point
trying again

#610

#611 AtapiHwInitializeChanger
(HwDeviceExtension,

#612
srb->TargetId,

#613
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);

#614

#615 //
Get ready to issue the original srb

#616 srb
= deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;

#617
deviceExtension->OriginalSrb = NULL;

#618 }

#619

#620
srbStatus = AtapiSendCommand(HwDeviceExtension,
deviceExtension->CurrentSrb);

#621 if
(srbStatus == SRB_STATUS_PENDING) {

#622
return TRUE;

#623 }

#624 }

#625 }

#626

#627 // If we get
here, it means AtapiSendCommand() has failed

#628 // Can't
recover. Pretend the original srb has
failed and complete it.

#629

运行到这里,已经说明AtapiSendCommand函数发送失败。

#630 if (deviceExtension->OriginalSrb)
{

#631
AtapiHwInitializeChanger (HwDeviceExtension,

#632
srb->TargetId,

#633
(PMECHANICAL_STATUS_INFORMATION_HEADER) NULL);

#634 srb =
deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;

#635
deviceExtension->OriginalSrb = NULL;

#636 }

#637

#638 // fake an error
and read no data

#639 status = SRB_STATUS_ERROR;

#640
srb->ScsiStatus = 0;

#641
deviceExtension->DataBuffer = srb->DataBuffer;

#642
deviceExtension->WordsLeft = srb->DataTransferLength;

#643
deviceExtension->RDP = FALSE;

#644

#645 } else if (status ==
SRB_STATUS_ERROR) {

#646

#647 //

#648 // Map error to
specific SRB status and handle request sense.

#649 //

#650

SRB数据包的状态出错。

#651 status =
MapError(deviceExtension,

#652
srb);

#653

#654
deviceExtension->RDP = FALSE;

#655

#656 } else {

#657

#658 //

#659 // Wait for busy
to drop.

#660 //

#661

忙等IDE设备,并且复位IDE设备。

#662 for (i = 0; i
< 30; i++) {

#663
GetStatus(baseIoAddress2,statusByte);

#664 if
(!(statusByte & IDE_STATUS_BUSY)) {

#665 break;

#666 }

#667 ScsiPortStallExecution(500);

#668 }

#669

#670 if (i == 30) {

#671

#672 //

#673 // reset the
controller.

#674 //

#675

#676
DebugPrint((1,

#677 "AtapiInterrupt: Resetting due to BSY
still up - %x. Base Io %x/n",

#678
statusByte,

#679
baseIoAddress1));

#680
AtapiResetController(HwDeviceExtension,srb->PathId);

#681 return TRUE;

#682 }

#683

#684 //

#685 // Check to see
if DRQ is still up.

#686 //

#687

如果IDE设备还是DRQ状态,就等一会,直到不是这个状态。

#688 if (statusByte
& IDE_STATUS_DRQ) {

#689

#690 for (i = 0; i < 500; i++) {

#691
GetStatus(baseIoAddress2,statusByte);

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

#693
break;

#694 }

#695 ScsiPortStallExecution(100);

#696

#697 }

#698

#699 if (i ==
500) {

#700

#701 //

#702 // reset
the controller.

#703 //

#704

#705 DebugPrint((1,

#706
"AtapiInterrupt: Resetting due to DRQ still up - %x/n",

#707
statusByte));

#708
AtapiResetController(HwDeviceExtension,srb->PathId);

#709 return TRUE;

#710 }

#711

#712 }

#713 }

#714

#715

#716 //

#717 // Clear interrupt
expecting flag.

#718 //

#719

清除中断标志。

#720
deviceExtension->ExpectingInterrupt = FALSE;

#721

#722 //

#723 // Sanity check that
there is a current request.

#724 //

#725

检查当前请求包。

#726 if (srb != NULL) {

#727

#728 //

#729 // Set status in
SRB.

#730 //

#731

#732
srb->SrbStatus = (UCHAR)status;

#733

#734 //

#735 // Check for
underflow.

#736 //

#737

#738 if
(deviceExtension->WordsLeft) {

#739

#740 //

#741 // Subtract
out residual words and update if filemark hit,

#742 // setmark
hit , end of data, end of media...

#743 //

#744

#745 if
(!(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_TAPE_DEVICE))
{

#746 if (status
== SRB_STATUS_DATA_OVERRUN) {

#747
srb->DataTransferLength -= deviceExtension->WordsLeft;

#748 } else {

#749
srb->DataTransferLength = 0;

#750 }

#751 } else {

#752
srb->DataTransferLength -= deviceExtension->WordsLeft;

#753 }

#754 }

#755

#756 if
(srb->Function != SRB_FUNCTION_IO_CONTROL) {

#757

#758 //

#759 // Indicate
command complete.

#760 //

#761

#762 if
(!(deviceExtension->RDP)) {

#763
ScsiPortNotification(RequestComplete,

#764
deviceExtension,

#765
srb);

#766

#767 }

#768 } else {

#769

#770
PSENDCMDOUTPARAMS cmdOutParameters =
(PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));

#771 UCHAR error = 0;

#772

#773 if (status
!= SRB_STATUS_SUCCESS) {

#774 error =
ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1);

#775 }

#776

#777 //

#778 // Build the
SMART status block depending upon the completion status.

#779 //

#780

#781
cmdOutParameters->cBufferSize = wordCount;

#782
cmdOutParameters->DriverStatus.bDriverError = (error) ?
SMART_IDE_ERROR : 0;

#783
cmdOutParameters->DriverStatus.bIDEError = error;

#784

#785 //

#786 // If the
sub-command is return smart status, jam the value from cylinder low and high,
into the

#787 // data
buffer.

#788 //

#789

#790 if
(deviceExtension->SmartCommand == RETURN_SMART_STATUS) {

#791
cmdOutParameters->bBuffer[0] = RETURN_SMART_STATUS;

#792 cmdOutParameters->bBuffer[1] =
ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason);

#793
cmdOutParameters->bBuffer[2] =
ScsiPortReadPortUchar(&baseIoAddress1->Unused1);

#794
cmdOutParameters->bBuffer[3] = ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);

#795
cmdOutParameters->bBuffer[4] =
ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh);

#796
cmdOutParameters->bBuffer[5] =
ScsiPortReadPortUchar(&baseIoAddress1->DriveSelect);

#797
cmdOutParameters->bBuffer[6] = SMART_CMD;

#798
cmdOutParameters->cBufferSize = 8;

#799 }

#800

#801 //

#802 // Indicate
command complete.

#803 //

#804

#805
ScsiPortNotification(RequestComplete,

#806
deviceExtension,

#807 srb);

#808

#809 }

#810

#811 } else {

#812

#813 DebugPrint((1,

#814
"AtapiInterrupt: No SRB!/n"));

#815 }

#816

#817 //

#818 // Indicate ready
for next request.

#819 //

#820

设置IDE设备可能处理下一个请求包。

#821 if (!(deviceExtension->RDP))
{

#822

#823 //

#824 // Clear current
SRB.

#825 //

#826

#827
deviceExtension->CurrentSrb = NULL;

#828

#829
ScsiPortNotification(NextRequest,

#830 deviceExtension,

#831
NULL);

#832 } else {

#833

#834
ScsiPortNotification(RequestTimerCall,

#835
HwDeviceExtension,

#836 AtapiCallBack,

#837
2000);

#838 }

#839

#840 return TRUE;

#841

#842 } else {

#843

#844 //

#845 // Unexpected int.

#846 //

#847

#848 DebugPrint((3,

#849
"AtapiInterrupt: Unexpected interrupt. InterruptReason %x. Status
%x./n",

#850
interruptReason,

#851
statusByte));

#852 return FALSE;

#853 }

#854

#855 return TRUE;

#856

#857 } // end AtapiInterrupt()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: