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

reactos操作系统实现(109)

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