reactos操作系统实现(109)
AtapiInterrupt函數(shù)是實現(xiàn)ATAPI的中斷功能,主要根據(jù)SRB來判斷是讀取數(shù)據(jù)還是寫入數(shù)據(jù),然后對IDE設(shè)備讀取或?qū)懭霐?shù)據(jù),還需要處理很多出錯的情況。具體實現(xiàn)代碼如下:
#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的擴展對象結(jié)構(gòu)。
#024????? PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
?
獲取當(dāng)前SRB數(shù)據(jù)。
#025????? PSCSI_REQUEST_BLOCK srb????????????? = deviceExtension->CurrentSrb;
#026????? PATAPI_REGISTERS_1 baseIoAddress1;
#027????? PATAPI_REGISTERS_2 baseIoAddress2;
?
每次讀取256個雙字節(jié),也就是512個字節(jié)。
#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的情況,或者使用一個默認(rèn)的基地址。
#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?
?
使用一個默認(rèn)的基地址
#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
?
如果沒有基地址,這個驅(qū)動程序不能訪問IDE控制器。
#068????????? return FALSE;
#069????? }
#070?
?
如果驅(qū)動程序不能接收中斷,就直接返回去。
#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?
?
讀取當(dāng)前狀態(tài)。
#082????? GetBaseStatus(baseIoAddress1, statusByte);
#083?
#084????? DebugPrint((3,
#085????????????????? "AtapiInterrupt: Entered with status (%x)/n",
#086????????????????? statusByte));
#087?
#088?
?
如果IDE的狀態(tài)為忙狀態(tài)。
#089????? if (statusByte & IDE_STATUS_BUSY) {
?
如果設(shè)備需要采用輪詢的方式,就直接返回。
#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次,還是忙狀態(tài),說明IDE還是在忙,沒有辦法響應(yīng),調(diào)用函數(shù)ScsiPortNotification來設(shè)置回調(diào)函數(shù)。
#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?
?
如果當(dāng)前IDE設(shè)備的狀態(tài)為出錯,就設(shè)置這個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?
?
如果沒有出錯,也沒有忙狀態(tài),判斷這個中斷的原因是什么。
#153????? if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
?
如果ATAPI設(shè)備中斷,就讀取中斷的原因,并設(shè)置傳送的字節(jié)數(shù)為512個字節(jié)。
#154?
#155????????? interruptReason = (ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason) & 0x3);
#156????????? atapiDev = TRUE;
#157????????? wordsThisInterrupt = 256;
#158?
#159 ?????} else {
#160?
?
如果是DRQ的方式傳送,就進(jìn)入下面處理。
#161????????? if (statusByte & IDE_STATUS_DRQ) {
#162?
?
多塊傳送數(shù)據(jù)。
#163????????????? if (deviceExtension->MaximumBlockXfer[srb->TargetId]) {
#164????????????????? wordsThisInterrupt = 256 * deviceExtension->MaximumBlockXfer[srb->TargetId];
#165?
#166????????????? }
#167?
?
讀取數(shù)據(jù)進(jìn)來。
#168????????????? if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
#169?
#170????????????????? interruptReason =? 0x2;
#171?
?
傳送數(shù)據(jù)出去。
#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?
?
如果需要補充寫字節(jié),就進(jìn)入下面處理。
#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?
?
下面獲取媒介的狀態(tài)。
#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?
?
根據(jù)中斷原因進(jìn)行處理。
#234????? if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
#235?
?
中斷原因是寫數(shù)據(jù)到IDE設(shè)備。
#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數(shù)據(jù)發(fā)送給設(shè)備。這里的WriteBuffer,其實是調(diào)用函數(shù)ScsiPortWritePortBufferUshort,它的作用就是把緩沖區(qū)里的數(shù)據(jù)發(fā)送到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?
?
確認(rèn)是否ATAPI設(shè)備。
#259????????? if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
#260?
#261????????????? //
#262????????????? // Pick up bytes to transfer and convert to words.
#263?? ???????????//
#264?
?
從ATAPI設(shè)備里讀取要傳送的字節(jié)數(shù),把字節(jié)轉(zhuǎn)換為字的個數(shù)。
#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?
?
如果要傳送的字個數(shù)大于剩余的個數(shù),那么就只傳送剩余的個數(shù)。
#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?
?
判斷是否剩余字個數(shù)小于256個字,如果是小于,就只傳送剩余個數(shù),否則就傳送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設(shè)備不忙。
#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?
?
調(diào)整已經(jīng)傳送的緩沖區(qū)字個數(shù),以便下一次傳送。
#360????????? deviceExtension->DataBuffer += wordCount;
#361????????? deviceExtension->WordsLeft -= wordCount;
#362?
#363????? ????return TRUE;
#364?
#365????? } else if (interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {
#366?
#367?
?
這是讀取數(shù)據(jù)命令。
#368????????? if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
#369?
#370????????????? //
#371??????? ??????// Pick up bytes to transfer and convert to words.
#372????????????? //
#373?
?
讀取IDE設(shè)備要傳送的字節(jié)數(shù),并轉(zhuǎn)換為字的個數(shù)。
#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?
?
請求的個數(shù)不等于IDE設(shè)備要傳送的字節(jié)數(shù),就提示。
#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?
?
如果只是傳送剩余的字節(jié),就設(shè)置傳送剩余字節(jié),否則就是傳送512個字節(jié)。
#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設(shè)備空閑。
#434???????????? WaitOnBusy(baseIoAddress2,statusByte);
#435?
?
讀取數(shù)據(jù)到緩沖區(qū)。
#436???????????? if (atapiDev || !deviceExtension->DWordIO) {
#437???????????????? ReadBuffer(baseIoAddress1,
#438?????????????????????????? deviceExtension->DataBuffer,
#439?????????? ????????????????wordCount);
#440?
#441???????????? } else {
?
使用4字節(jié)的方式讀取。
#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設(shè)備請示失敗。
#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?
?
調(diào)整已經(jīng)傳送的字節(jié)。
#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?
?
到這里已經(jīng)讀取數(shù)據(jù)完成。
#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?
?
否則是寫數(shù)據(jù)完成。
#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?
?
重新發(fā)送當(dāng)前SRB數(shù)據(jù)包。
#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?
?
運行到這里,已經(jīng)說明AtapiSendCommand函數(shù)發(fā)送失敗。
#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數(shù)據(jù)包的狀態(tài)出錯。
#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設(shè)備,并且復(fù)位IDE設(shè)備。
#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設(shè)備還是DRQ狀態(tài),就等一會,直到不是這個狀態(tài)。
#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?
?
清除中斷標(biāo)志。
#720????????? deviceExtension->ExpectingInterrupt = FALSE;
#721?
#722????????? //
#723????????? // Sanity check that there is a current request.
#724????????? //
#725?
?
檢查當(dāng)前請求包。
#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?
?
設(shè)置IDE設(shè)備可能處理下一個請求包。
#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()
轉(zhuǎn)載于:https://www.cnblogs.com/ajuanabc/archive/2009/10/19/2463676.html
總結(jié)
以上是生活随笔為你收集整理的reactos操作系统实现(109)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java毕业设计-企业员工考勤打卡管理系
- 下一篇: reactos操作系统实现(108)