reactos操作系统实现(109)
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, #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() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |