Annotation of ntddk/src/scsi/qic117/readwrt.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
        !             4: All Rights Reserved
        !             5: 
        !             6: Module Name:
        !             7: 
        !             8:     readwrt.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     Performs low-level read and write operations (with position logic).
        !            13: 
        !            14: Revision History:
        !            15: 
        !            16: 
        !            17: 
        !            18: 
        !            19: --*/
        !            20: 
        !            21: //
        !            22: // include files
        !            23: //
        !            24: 
        !            25: #include <ntddk.h>                        // various NT definitions
        !            26: #include <ntdddisk.h>                    // disk device driver I/O control codes
        !            27: #include <ntiologc.h>
        !            28: #include "common.h"
        !            29: #include "drvtask.h"                     // this driver's data declarations
        !            30: #include "mt1defs.h"                     // this driver's data declarations
        !            31: #include "mt1strc.h"                     // this driver's data declarations
        !            32: #include "q117data.h"                    // this driver's data declarations
        !            33: 
        !            34: 
        !            35: STATUS
        !            36: Q117iReadWrite(
        !            37:     IN PTAPE_EXTENSION TapeExtension,
        !            38:     IN OUT PIO_REQUEST IoRequestCurrent,
        !            39:     IN OUT PIRP Irp
        !            40:     )
        !            41: 
        !            42: /*++
        !            43: 
        !            44: 
        !            45: Routine Description:
        !            46: 
        !            47:     Process a data read or write.
        !            48: 
        !            49:     The first Wrong Cylinder error is ignored incase of a bad seek. On the
        !            50:     system 50, 60, 80 the first N Over Run errors are ignored due to the VGA
        !            51:     16-bit access bug (see PS/2 compatability manual).
        !            52: 
        !            53: Arguments:
        !            54: 
        !            55:     TapeExtension -
        !            56: 
        !            57:     IoRequestCurrent -
        !            58: 
        !            59:     Irp -
        !            60: 
        !            61: Return Value:
        !            62: 
        !            63: 
        !            64: 
        !            65: --*/
        !            66: {
        !            67:     STATUS retval = NoErr;
        !            68:     UCHAR i;
        !            69:     BOOLEAN dmaDir;
        !            70:     STATUS status = NoErr;
        !            71:     STATUS sleep_ret = NoErr;
        !            72:     RDV_COMMAND         rdWrCmd;
        !            73:     PIO_STACK_LOCATION irpSp;
        !            74:     struct PerpMode perpMode;
        !            75: 
        !            76:     perpMode.command = PERP_MODE_COMMAND;
        !            77:     perpMode.drive_select = TapeExtension->QControllerData->PerpModeSelect;
        !            78:     perpMode.reserved = 0;
        !            79:     perpMode.over_write = TRUE;
        !            80: 
        !            81:     irpSp = IoGetCurrentIrpStackLocation( Irp );
        !            82: 
        !            83:     Q117iGetRetryCounts(TapeExtension, IoRequestCurrent->Command);
        !            84: 
        !            85:     IoRequestCurrent->RetryList = 0l;
        !            86:     TapeExtension->RdWrOp.BytesTransferredSoFar = 0l;
        !            87:     TapeExtension->RdWrOp.TotalBytesOfTransfer = 0l;
        !            88:     TapeExtension->RdWrOp.RetryCount = TapeExtension->RdWrOp.RetryTimes;
        !            89:     TapeExtension->RdWrOp.RetrySectorId = 0;
        !            90:     TapeExtension->RdWrOp.SeekFlag = TRUE;
        !            91: 
        !            92:     if ((retval = Q117iCalcPosition(
        !            93:                         TapeExtension,
        !            94:                         IoRequestCurrent->Block,
        !            95:                         IoRequestCurrent->Number)) != NoErr) {
        !            96: 
        !            97:         return(retval);
        !            98: 
        !            99:     }
        !           100: 
        !           101:     TapeExtension->RdWrOp.CurLst = IoRequestCurrent->BadList;
        !           102: 
        !           103:     TapeExtension->RdWrOp.Scount = 0;
        !           104: 
        !           105:     for (i = 0; i < IoRequestCurrent->Number; i++) {
        !           106: 
        !           107:         if ((TapeExtension->RdWrOp.CurLst & 1) == 0) {
        !           108: 
        !           109:             TapeExtension->RdWrOp.Scount++;
        !           110: 
        !           111:         }
        !           112: 
        !           113:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
        !           114: 
        !           115:     }
        !           116: 
        !           117:     TapeExtension->RdWrOp.CurLst = IoRequestCurrent->BadList;
        !           118:     TapeExtension->RdWrOp.DataAmount = 0;
        !           119: 
        !           120:     while (TapeExtension->RdWrOp.Scount != 0 ||
        !           121:         TapeExtension->RdWrOp.DataAmount != 0) {
        !           122: 
        !           123:         if (TapeExtension->RdWrOp.DataAmount == 0) {
        !           124: 
        !           125:             Q117iNextGoodSectors(TapeExtension);
        !           126: 
        !           127:         }
        !           128: 
        !           129:         if ((TapeExtension->TapePosition.D_Track !=
        !           130:                 TapeExtension->TapePosition.C_Track) ||
        !           131:             (TapeExtension->TapePosition.C_Segment >
        !           132:                 TapeExtension->TapePosition.D_Segment) ||
        !           133:             ((TapeExtension->TapePosition.C_Segment !=
        !           134:                 TapeExtension->TapePosition.D_Segment) &&
        !           135:             ((TapeExtension->TapePosition.LogFwd != TRUE) ||
        !           136:             ((TapeExtension->TapePosition.D_Segment - 1) !=
        !           137:                 TapeExtension->TapePosition.C_Segment))))
        !           138: 
        !           139:             if ((retval = Q117iSeek(TapeExtension)) != NoErr) {
        !           140: 
        !           141:                 return(retval);
        !           142: 
        !           143:             }
        !           144: 
        !           145:         if (IoRequestCurrent->Command == DWrite ||
        !           146:             IoRequestCurrent->Command == DWriteBad) {
        !           147: 
        !           148:             dmaDir = DMA_READ;
        !           149: 
        !           150:             if ((TapeExtension->DriveParms.DriveType == QIC500_DRIVE) &&
        !           151:                 !TapeExtension->QControllerData->PerpendicularMode) {
        !           152: 
        !           153:                 // Enable Perpendicular Mode
        !           154:                 perpMode.wgate = 1;
        !           155:                 perpMode.gap = 1;
        !           156: 
        !           157:                 if ((retval = Q117iProgramFDC(
        !           158:                                 TapeExtension,
        !           159:                                 (CHAR *)&perpMode,
        !           160:                                 sizeof(perpMode),
        !           161:                                 FALSE)) != NoErr) {
        !           162: 
        !           163:                     Q117iResetFDC(TapeExtension);
        !           164:                     Q117iPauseTape(TapeExtension);
        !           165:                     return(retval);
        !           166:                 }
        !           167: 
        !           168:                 TapeExtension->QControllerData->PerpendicularMode = TRUE;
        !           169:             }
        !           170: 
        !           171:         } else {
        !           172: 
        !           173:             dmaDir = DMA_WRITE;
        !           174: 
        !           175:             if (TapeExtension->QControllerData->PerpendicularMode) {
        !           176: 
        !           177:                 // Disable Perpendicular Mode
        !           178:                 perpMode.wgate = 0;
        !           179:                 perpMode.gap = 0;
        !           180: 
        !           181:                 if ((retval = Q117iProgramFDC(
        !           182:                                 TapeExtension,
        !           183:                                 (CHAR *)&perpMode,
        !           184:                                 sizeof(perpMode),
        !           185:                                 FALSE)) != NoErr) {
        !           186: 
        !           187:                     Q117iResetFDC(TapeExtension);
        !           188:                     Q117iPauseTape(TapeExtension);
        !           189:                     return(retval);
        !           190:                 }
        !           191: 
        !           192:                 TapeExtension->QControllerData->PerpendicularMode = FALSE;
        !           193:             }
        !           194: 
        !           195:         }
        !           196: 
        !           197:         TapeExtension->RdWrOp.TotalBytesOfTransfer =
        !           198:             (ULONG)(TapeExtension->RdWrOp.DataAmount * PHY_SIZ);
        !           199: 
        !           200:         hio_ProgramDMA(TapeExtension, Irp, dmaDir);
        !           201: 
        !           202:         switch (IoRequestCurrent->Command) {
        !           203: 
        !           204:         case DWrite:
        !           205:             rdWrCmd.command = WRITE;
        !           206:             break;
        !           207: 
        !           208:         case DWriteBad:
        !           209:             rdWrCmd.command = WRTDEL;
        !           210:             break;
        !           211: 
        !           212:         default:
        !           213:             rdWrCmd.command = READ;
        !           214: 
        !           215:         }
        !           216: 
        !           217:         rdWrCmd.drive = (UCHAR)TapeExtension->DriveParms.DriveSelect;
        !           218:         rdWrCmd.C = TapeExtension->RdWrOp.D_FTK;
        !           219:         rdWrCmd.H = TapeExtension->RdWrOp.D_Head;
        !           220:         rdWrCmd.R = TapeExtension->RdWrOp.D_Sect;
        !           221:         rdWrCmd.N = WRT_BPS;
        !           222:         rdWrCmd.EOT = (UCHAR)TapeExtension->TapeParms.FsectFtrack;
        !           223:         rdWrCmd.GPL = (UCHAR)TapeExtension->TapeParms.RwGapLength;
        !           224:         rdWrCmd.DTL = 0xff;
        !           225: 
        !           226:         if ((retval = Q117iStartTape(TapeExtension)) != NoErr) {
        !           227: 
        !           228:             hio_FlushDMA(TapeExtension, Irp, dmaDir);
        !           229:             return(retval);
        !           230: 
        !           231:         }
        !           232: 
        !           233:         (VOID) Q117iResetInterruptEvent(TapeExtension);
        !           234:         if ((retval = Q117iProgramFDC(
        !           235:                             TapeExtension,
        !           236:                             (CHAR *)&rdWrCmd,
        !           237:                             sizeof(RDV_COMMAND),
        !           238:                             TRUE)) != NoErr) {
        !           239: 
        !           240:             hio_FlushDMA(TapeExtension, Irp, dmaDir);
        !           241:             Q117iResetFDC(TapeExtension);
        !           242:             Q117iPauseTape(TapeExtension);
        !           243:             return(retval);
        !           244:         }
        !           245: 
        !           246:         sleep_ret = Q117iSleep(TapeExtension, mt_wttrks, TRUE);
        !           247:         hio_FlushDMA(TapeExtension, Irp, dmaDir);
        !           248: 
        !           249:         switch (sleep_ret) {
        !           250: 
        !           251:         case TimeOut:
        !           252:             if ((retval = Q117iRW_Timeout(
        !           253:                                 TapeExtension,
        !           254:                                 IoRequestCurrent,
        !           255:                                 &status)) != NoErr) {
        !           256: 
        !           257:                     return(retval);
        !           258: 
        !           259:             }
        !           260: 
        !           261:             if (TapeExtension->RdWrOp.NoDat == 0) {
        !           262: 
        !           263:                     return(status);
        !           264: 
        !           265:             }
        !           266: 
        !           267:             break;
        !           268: 
        !           269:         case NoErr:
        !           270: 
        !           271:             if ((retval = Q117iRW_Normal(
        !           272:                                 TapeExtension,
        !           273:                                 IoRequestCurrent,
        !           274:                                 &status)) != NoErr) {
        !           275: 
        !           276:                     return(retval);
        !           277: 
        !           278:             }
        !           279: 
        !           280:             if (status == BadMark || TapeExtension->RdWrOp.NoDat == 0) {
        !           281: 
        !           282:                     return(status);
        !           283: 
        !           284:             }
        !           285: 
        !           286:             break;
        !           287: 
        !           288:         }
        !           289:     } /* end of while loop */
        !           290: 
        !           291:     if (IoRequestCurrent->Command == DRetry) {
        !           292: 
        !           293:         if (TapeExtension->TapePosition.LogFwd == TRUE) {
        !           294: 
        !           295:             retval = Q117iGetDriveError(TapeExtension);
        !           296: 
        !           297:             if (retval && (retval != NotRdy)) {
        !           298: 
        !           299:                 return(retval);
        !           300: 
        !           301:             }
        !           302: 
        !           303:             Q117iPauseTape(TapeExtension);
        !           304:         }
        !           305: 
        !           306:         if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command)) !=
        !           307:             NoErr) {
        !           308: 
        !           309:             return(retval);
        !           310: 
        !           311:         }
        !           312:     }
        !           313: 
        !           314: 
        !           315: #if DBG
        !           316:     if ((QIC117DebugLevel & QIC117MAKEBAD) && status == NoErr &&
        !           317:         IoRequestCurrent->Command == DWrite) {
        !           318: 
        !           319:         LARGE_INTEGER time;
        !           320: 
        !           321: 
        !           322:         // Use the system time as a "Randomizer" to fake bad sectors
        !           323:         KeQuerySystemTime(&time);
        !           324:         time.LowPart /= 10;
        !           325:         if (time.LowPart & 1) {
        !           326:             status = BadBlk;
        !           327: 
        !           328:             IoRequestCurrent->BadList |= 1 << (time.LowPart & 31);
        !           329:             if (time.LowPart & 0x100) {
        !           330:                 IoRequestCurrent->BadList |= 1 << ((time.LowPart>>6) & 31);
        !           331:             }
        !           332:             if ((time.LowPart & 0xa00) == 0xa00) {
        !           333:                 IoRequestCurrent->BadList |= 1 << ((time.LowPart>>10) & 31);
        !           334:             }
        !           335:             CheckedDump(QIC117MAKEBAD, ("badblk generated\n"));
        !           336:         } else {
        !           337:             CheckedDump(QIC117MAKEBAD, ("no sim\n"));
        !           338:         }
        !           339:     }
        !           340: #endif
        !           341: 
        !           342:     return(status);
        !           343: }
        !           344: 
        !           345: 
        !           346: STATUS
        !           347: Q117iCalcPosition(
        !           348:     IN PTAPE_EXTENSION TapeExtension,
        !           349:     IN ULONG Block,
        !           350:     IN UCHAR Number
        !           351:     )
        !           352: 
        !           353: /*++
        !           354: 
        !           355: Routine Description:
        !           356: 
        !           357:     Calculate the desired tape position from the Logical Sector Number
        !           358:     in the I/O Request.
        !           359: 
        !           360: Arguments:
        !           361: 
        !           362:     TapeExtension -
        !           363: 
        !           364:     Block -
        !           365: 
        !           366:     Number -
        !           367: 
        !           368: Return Value:
        !           369: 
        !           370: 
        !           371: 
        !           372: --*/
        !           373: 
        !           374: {
        !           375:     ULONG logSect;
        !           376: 
        !           377:     //
        !           378:     // First check if the desired sector is a legal one, i.e. is less
        !           379:     // than the maximum number of sectors on the tape.
        !           380:     //
        !           381: 
        !           382:     CheckedDump(QIC117STOP,( "q117i: requested block %lx\n", Block ));
        !           383: 
        !           384:     if (Block >= TapeExtension->TapeParms.LogSectors) {
        !           385: 
        !           386:         return(BadReq);
        !           387: 
        !           388:     }
        !           389: 
        !           390:     //
        !           391:     // Now we need to determine the sector ID information so that we
        !           392:     // can properly program the FDC.  The ID information required is the
        !           393:     // head, cylinder, and sector numbers.  The head number is calculated
        !           394:     // as logSect / (floppy sectors per floppy side).  This calculation
        !           395:     // is done in the while loop which also determines the logical floppy
        !           396:     // sector on the floppy side.  The cylinder number (d_FTK) and the
        !           397:     // sector number (d_sect) are calculated last as (logical floppy sector)
        !           398:     //  / (floppy sectors per floppy cylinder).
        !           399:     //
        !           400: 
        !           401:     logSect = Block;
        !           402:     TapeExtension->RdWrOp.D_Head = 0;
        !           403: 
        !           404:     while (logSect >= TapeExtension->TapeParms.FsectFside) {
        !           405: 
        !           406:         logSect -= TapeExtension->TapeParms.FsectFside;
        !           407:         TapeExtension->RdWrOp.D_Head++;
        !           408: 
        !           409:     }
        !           410: 
        !           411:     TapeExtension->RdWrOp.D_FTK = (UCHAR)(logSect / FSC_FTK);
        !           412: 
        !           413:     //
        !           414:     // fast logSect % 128
        !           415:     //
        !           416: 
        !           417:     TapeExtension->RdWrOp.D_Sect = (UCHAR)(logSect % FSC_FTK) + 1;
        !           418:     TapeExtension->RdWrOp.S_Sect = (UCHAR)TapeExtension->RdWrOp.D_Sect;
        !           419: 
        !           420:     //
        !           421:     // Next, we need the tape positioning data.  This is the data that
        !           422:     // we need to find out where, physically, on the tape we need to be.
        !           423:     // The tape track is determined first as
        !           424:     // (logical sector number) / (floppy sectors per tape track).  The
        !           425:     // remainder from this calculation is the absolute sector number
        !           426:     // on the tape track.  Lastly, the physical segment is determined by
        !           427:     // dividing the physical sector number by the number of sectors per
        !           428:     // segment.
        !           429:     //
        !           430: 
        !           431:     logSect = Block;
        !           432:     TapeExtension->TapePosition.D_Track = 0;
        !           433: 
        !           434:     while (logSect >= TapeExtension->TapeParms.FsectTtrack) {
        !           435: 
        !           436:         logSect -= TapeExtension->TapeParms.FsectTtrack;
        !           437:         TapeExtension->TapePosition.D_Track++;
        !           438: 
        !           439:     }
        !           440: 
        !           441:     logSect = logSect / FSC_SEG;
        !           442:     TapeExtension->TapePosition.D_Segment = (SHORT)logSect;
        !           443: 
        !           444:     //
        !           445:     // Finally, if the IO Request requests a read that will cross a segment
        !           446:     // boundary then an error is returned.
        !           447:     //
        !           448: 
        !           449:     if((((TapeExtension->RdWrOp.D_Sect - 1) & 0x1f) + Number) >
        !           450:     TapeExtension->TapeParms.FsectSeg) {
        !           451: 
        !           452:         return(BadReq);
        !           453: 
        !           454:     }
        !           455: 
        !           456:     return(NoErr);
        !           457: }
        !           458: 
        !           459: 
        !           460: VOID
        !           461: Q117iGetRetryCounts(
        !           462:     IN PTAPE_EXTENSION TapeExtension,
        !           463:     IN DRIVER_COMMAND Command
        !           464:     )
        !           465: 
        !           466: /*++
        !           467: 
        !           468: Routine Description:
        !           469: 
        !           470:     Determine the retry count information according to the drive command
        !           471:     eiher read, write, verify, or retry.
        !           472: 
        !           473: Arguments:
        !           474: 
        !           475:     TapeExtension -
        !           476: 
        !           477:     Command -
        !           478: 
        !           479: Return Value:
        !           480: 
        !           481:     None
        !           482: 
        !           483: --*/
        !           484: 
        !           485: {
        !           486:     switch (Command) {
        !           487: 
        !           488:     case DWrite:
        !           489:     case DWriteBad:
        !           490:         TapeExtension->RdWrOp.RetryTimes = WTIMES;
        !           491:         TapeExtension->RdWrOp.NoDat = 3;
        !           492:         break;
        !           493: 
        !           494:     case DRead:
        !           495:     case DReadBad:
        !           496:         TapeExtension->RdWrOp.RetryTimes = ANTIMES;
        !           497:         TapeExtension->RdWrOp.NoDat = 3;
        !           498:         break;
        !           499: 
        !           500:     case DVerify:
        !           501:         TapeExtension->RdWrOp.RetryTimes = VTIMES;
        !           502:         TapeExtension->RdWrOp.NoDat = 2;
        !           503:         break;
        !           504: 
        !           505:     case DRetry:
        !           506:         TapeExtension->RdWrOp.RetryTimes = ARTIMES;
        !           507:         TapeExtension->RdWrOp.NoDat = ARTIMES;
        !           508:         TapeExtension->RetrySeqNum = 0;
        !           509: 
        !           510:     }
        !           511: }
        !           512: 
        !           513: 
        !           514: void
        !           515: Q117iNextGoodSectors(
        !           516:     IN PTAPE_EXTENSION TapeExtension
        !           517:     )
        !           518: 
        !           519: /*++
        !           520: 
        !           521: Routine Description:
        !           522: 
        !           523:     Determine the next block of good sectors to read/write/verify.
        !           524: 
        !           525: Arguments:
        !           526: 
        !           527:     TapeExtension -
        !           528: 
        !           529: Return Value:
        !           530: 
        !           531:     None
        !           532: 
        !           533: --*/
        !           534: 
        !           535: {
        !           536:     TapeExtension->RdWrOp.DataAmount = 0;
        !           537: 
        !           538:     while (TapeExtension->RdWrOp.CurLst & 1) {
        !           539: 
        !           540:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
        !           541:         TapeExtension->RdWrOp.D_Sect++;
        !           542: 
        !           543:     }
        !           544: 
        !           545:     do {
        !           546: 
        !           547:         TapeExtension->RdWrOp.DataAmount++;
        !           548:         TapeExtension->RdWrOp.Scount--;
        !           549:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
        !           550: 
        !           551:     } while (!(TapeExtension->RdWrOp.CurLst & 1) &&
        !           552:             TapeExtension->RdWrOp.Scount);
        !           553: }
        !           554: 
        !           555: 
        !           556: STATUS
        !           557: Q117iRW_Timeout(
        !           558:     IN PTAPE_EXTENSION TapeExtension,
        !           559:     IN OUT PIO_REQUEST IoRequestCurrent,
        !           560:     OUT STATUS *Status
        !           561:     )
        !           562: 
        !           563: /*++
        !           564: 
        !           565: Routine Description:
        !           566: 
        !           567:     Process a TIMEOUT error while reading/writing/verifying. If the FDC
        !           568:     does not report any status within the amount of time that the tape
        !           569:     would pass apporximately 4 segments, it must be assumed that there is no
        !           570:     data on the tape.
        !           571: 
        !           572: Arguments:
        !           573: 
        !           574:     TapeExtension -
        !           575: 
        !           576:     IoRequestCurrent -
        !           577: 
        !           578:     Status -
        !           579: 
        !           580: Return Value:
        !           581: 
        !           582: 
        !           583: 
        !           584: --*/
        !           585: 
        !           586: {
        !           587:     STATUS retval;
        !           588: 
        !           589:     Q117iResetFDC(TapeExtension);
        !           590: 
        !           591:     if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !           592: 
        !           593:         return(retval);
        !           594: 
        !           595:     }
        !           596: 
        !           597:     if ((retval = Q117iChangeTrack(
        !           598:                         TapeExtension,
        !           599:                         TapeExtension->TapePosition.D_Track)) != NoErr) {
        !           600: 
        !           601:         return(retval);
        !           602: 
        !           603:     }
        !           604: 
        !           605:     if (TapeExtension->DriveParms.Status.BOT ||
        !           606:         TapeExtension->DriveParms.Status.EOT) {
        !           607: 
        !           608:         TapeExtension->TapePosition.C_Segment =
        !           609:             TapeExtension->TapeParms.SegTtrack;
        !           610: 
        !           611:     }
        !           612: 
        !           613:     if (--TapeExtension->RdWrOp.NoDat == 0) {
        !           614: 
        !           615:         if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command))
        !           616:             != NoErr) {
        !           617: 
        !           618:             return(retval);
        !           619: 
        !           620:         }
        !           621: 
        !           622:         *Status = BadBlk;
        !           623:         IoRequestCurrent->BadList = -
        !           624:             1l << (TapeExtension->RdWrOp.D_Sect -
        !           625:                 TapeExtension->RdWrOp.S_Sect);
        !           626: 
        !           627:     }
        !           628:     return(retval);
        !           629: }
        !           630: 
        !           631: 
        !           632: STATUS
        !           633: Q117iRW_Normal(
        !           634:     IN PTAPE_EXTENSION TapeExtension,
        !           635:     IN OUT PIO_REQUEST IoRequestCurrent,
        !           636:     OUT STATUS *Status
        !           637:     )
        !           638: 
        !           639: /*++
        !           640: 
        !           641: 
        !           642: Routine Description:
        !           643: 
        !           644:     Process a read/write/verify operation that has returned normally from
        !           645:     the FDC.
        !           646: 
        !           647: Arguments:
        !           648: 
        !           649:     TapeExtension -
        !           650: 
        !           651:     IoRequestCurrent -
        !           652: 
        !           653:     Status -
        !           654: 
        !           655: Return Value:
        !           656: 
        !           657: 
        !           658: 
        !           659: --*/
        !           660: 
        !           661: {
        !           662:     STATUS retval;
        !           663:     SHORT statLength;
        !           664: 
        !           665:     if ((retval = Q117iReadFDC(
        !           666:                     TapeExtension,
        !           667:                     (CHAR *)&TapeExtension->QControllerData->FdcStat,
        !           668:                     &statLength)) != NoErr) {
        !           669: 
        !           670:         Q117iPauseTape(TapeExtension);
        !           671:         return(retval);
        !           672: 
        !           673:     }
        !           674: 
        !           675:     if (statLength != 7) {
        !           676: 
        !           677:         Q117iResetFDC(TapeExtension);
        !           678:         Q117iGetDriveError(TapeExtension);
        !           679:         Q117iPauseTape(TapeExtension);
        !           680: 
        !           681:         if (TapeExtension->RdWrOp.NoDat == 0) {
        !           682: 
        !           683:             if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command))
        !           684:                 != NoErr) {
        !           685: 
        !           686:                 return(retval);
        !           687: 
        !           688:             }
        !           689: 
        !           690:             *Status = BadBlk;
        !           691:             IoRequestCurrent->BadList =
        !           692:                 -1l << (TapeExtension->RdWrOp.D_Sect -
        !           693:                         TapeExtension->RdWrOp.S_Sect);
        !           694:         }
        !           695:         return(NoErr);
        !           696:     }
        !           697: 
        !           698:     if (TapeExtension->QControllerData->FdcStat.ST1 == 0 &&
        !           699:         TapeExtension->QControllerData->FdcStat.ST2 == 0) {
        !           700: 
        !           701:         //
        !           702:         // no errors
        !           703:         //
        !           704: 
        !           705:         DbgAddEntry(TapeExtension->RdWrOp.D_Sect);
        !           706:         DbgAddEntry(TapeExtension->RdWrOp.DataAmount);
        !           707:         DbgAddEntry(TapeExtension->RdWrOp.CurLst);
        !           708:         DbgAddEntry(TapeExtension->RdWrOp.BytesTransferredSoFar);
        !           709: 
        !           710:         TapeExtension->RdWrOp.SeekFlag = TRUE;
        !           711:         TapeExtension->TapePosition.C_Segment =
        !           712:             TapeExtension->TapePosition.D_Segment;
        !           713:         TapeExtension->RdWrOp.D_Sect +=
        !           714:             (UCHAR)TapeExtension->RdWrOp.DataAmount;
        !           715:         TapeExtension->RdWrOp.BytesTransferredSoFar +=
        !           716:             (ULONG)(TapeExtension->RdWrOp.DataAmount*PHY_SIZ);
        !           717:         TapeExtension->RdWrOp.DataAmount = 0;
        !           718:         return(NoErr);
        !           719:     }
        !           720: 
        !           721:     if ((IoRequestCurrent->Command == DReadBad) &&
        !           722:         (TapeExtension->QControllerData->FdcStat.ST2 & ST2_CM)) {
        !           723: 
        !           724:         IoRequestCurrent->BadList = 0xffffffff;
        !           725:         *Status = BadMark;
        !           726:         return(NoErr);
        !           727: 
        !           728:     }
        !           729: 
        !           730:     if ((TapeExtension->QControllerData->FdcStat.ST2 & ST2_WC) ||
        !           731:         (TapeExtension->QControllerData->FdcStat.ST1 &
        !           732:             (ST1_OR | ST1_ND | ST1_MA))) {
        !           733: 
        !           734:         if (TapeExtension->RdWrOp.SeekFlag == TRUE) {
        !           735: 
        !           736:             TapeExtension->TapePosition.C_Segment =
        !           737:                 TapeExtension->TapePosition.D_Segment + 1;
        !           738:             TapeExtension->RdWrOp.SeekFlag = FALSE;
        !           739:             return(NoErr);
        !           740: 
        !           741:         }
        !           742:     }
        !           743: 
        !           744:     if ((IoRequestCurrent->Command == DVerify) &&
        !           745:         (TapeExtension->QControllerData->FdcStat.ST1 & ST1_MA)) {
        !           746: 
        !           747:         if (TapeExtension->RdWrOp.SeekFlag == TRUE) {
        !           748: 
        !           749:             retval = Q117iGetDriveError(TapeExtension);
        !           750: 
        !           751:             if (retval && (retval != NotRdy)) {
        !           752: 
        !           753:                 return(retval);
        !           754: 
        !           755:             }
        !           756: 
        !           757:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
        !           758: 
        !           759:                 return(retval);
        !           760: 
        !           761:             }
        !           762: 
        !           763:             if ((retval = Q117iReadIDRepeat(TapeExtension)) != NoErr) {
        !           764: 
        !           765:                 return(retval);
        !           766: 
        !           767:             }
        !           768: 
        !           769:             TapeExtension->RdWrOp.SeekFlag = FALSE;
        !           770:             return(NoErr);
        !           771:         }
        !           772:     }
        !           773: 
        !           774:     TapeExtension->TapePosition.C_Segment =
        !           775:         TapeExtension->TapePosition.D_Segment;
        !           776: 
        !           777:     retval = Q117iRetryCode(
        !           778:                 TapeExtension,
        !           779:                 IoRequestCurrent,
        !           780:                 &TapeExtension->QControllerData->FdcStat,
        !           781:                 Status);
        !           782: 
        !           783:     return(retval);
        !           784: }
        !           785: 
        !           786: 
        !           787: STATUS
        !           788: Q117iRetryCode(
        !           789:     IN PTAPE_EXTENSION TapeExtension,
        !           790:     IN OUT PIO_REQUEST IoRequestCurrent,
        !           791:     OUT FDC_STATUS *FdcStatus,
        !           792:     OUT STATUS *Status
        !           793:     )
        !           794: 
        !           795: /*++
        !           796: 
        !           797: Routine Description:
        !           798: 
        !           799:     Orchestrate retries for read/write/verify (and retyr) commands.
        !           800: 
        !           801: Arguments:
        !           802: 
        !           803:     TapeExtension -
        !           804: 
        !           805:     IoRequestCurrent -
        !           806: 
        !           807:     FdcStatus -
        !           808: 
        !           809:     Status -
        !           810: 
        !           811: Return Value:
        !           812: 
        !           813: 
        !           814: 
        !           815: --*/
        !           816: {
        !           817:     STATUS retval;
        !           818:     SHORT sectorsRead;
        !           819: 
        !           820:     if (TapeExtension->RdWrOp.RetryTimes != 0) {
        !           821: 
        !           822:         if (IoRequestCurrent->Command != DRetry) {
        !           823: 
        !           824:             retval = Q117iGetDriveError(TapeExtension);
        !           825: 
        !           826:             if (retval && (retval != NotRdy)) {
        !           827: 
        !           828:                 return(retval);
        !           829: 
        !           830:             }
        !           831: 
        !           832:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
        !           833: 
        !           834:                 return(retval);
        !           835: 
        !           836:             }
        !           837: 
        !           838:         }
        !           839: 
        !           840:         if ((retval = Q117iReadIDRepeat(TapeExtension)) != NoErr) {
        !           841: 
        !           842:             return(retval);
        !           843: 
        !           844:         }
        !           845: 
        !           846:     } else {
        !           847: 
        !           848:         TapeExtension->RdWrOp.SeekFlag = TRUE;
        !           849: 
        !           850:     }
        !           851: 
        !           852:     if ((TapeExtension->RdWrOp.RetryTimes == 0) ||
        !           853:         (FdcStatus->R == TapeExtension->RdWrOp.RetrySectorId)) {
        !           854: 
        !           855:         if ((TapeExtension->RdWrOp.RetryTimes == 0) ||
        !           856:             (--TapeExtension->RdWrOp.RetryCount == 0)) {
        !           857: 
        !           858:             TapeExtension->RdWrOp.SeekFlag = TRUE;
        !           859:             IoRequestCurrent->BadList |=
        !           860:                 1l << (FdcStatus->R - TapeExtension->RdWrOp.S_Sect);
        !           861:             *Status = BadBlk;
        !           862:             sectorsRead = FdcStatus->R + 1 - TapeExtension->RdWrOp.D_Sect;
        !           863:             TapeExtension->RdWrOp.D_Sect = FdcStatus->R + 1;
        !           864:             TapeExtension->RdWrOp.DataAmount -= sectorsRead;
        !           865:             TapeExtension->RdWrOp.BytesTransferredSoFar +=
        !           866:                 sectorsRead * PHY_SIZ;
        !           867:             TapeExtension->RdWrOp.RetryCount =
        !           868:                 TapeExtension->RdWrOp.RetryTimes;
        !           869:             TapeExtension->RdWrOp.RetrySectorId = 0;
        !           870:             retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command);
        !           871: 
        !           872:         } else {
        !           873: 
        !           874:             retval = Q117iNextTry(TapeExtension, IoRequestCurrent->Command);
        !           875: 
        !           876:         }
        !           877: 
        !           878:     } else {
        !           879: 
        !           880:         IoRequestCurrent->RetryList |=
        !           881:             1l << (FdcStatus->R - TapeExtension->RdWrOp.S_Sect);
        !           882:         TapeExtension->RdWrOp.RetrySectorId = FdcStatus->R;
        !           883:         TapeExtension->RdWrOp.RetryCount =
        !           884:             TapeExtension->RdWrOp.RetryTimes;
        !           885:         sectorsRead = FdcStatus->R - TapeExtension->RdWrOp.D_Sect;
        !           886:         TapeExtension->RdWrOp.D_Sect = FdcStatus->R;
        !           887:         TapeExtension->RdWrOp.DataAmount -= sectorsRead;
        !           888:         TapeExtension->RdWrOp.BytesTransferredSoFar +=
        !           889:             sectorsRead * PHY_SIZ;
        !           890: 
        !           891:     }
        !           892: 
        !           893:     return(retval);
        !           894: }
        !           895: 
        !           896: 
        !           897: 
        !           898: STATUS
        !           899: Q117iNextTry(
        !           900:     IN PTAPE_EXTENSION TapeExtension,
        !           901:     IN DRIVER_COMMAND Command
        !           902:     )
        !           903: 
        !           904: /*++
        !           905: 
        !           906: Routine Description:
        !           907: 
        !           908:     Determines the next tape drive head position during off-track retries.
        !           909: 
        !           910: Arguments:
        !           911: 
        !           912:     TapeExtension -
        !           913: 
        !           914:     Command -
        !           915: 
        !           916: Return Value:
        !           917: 
        !           918: 
        !           919: 
        !           920: --*/
        !           921: 
        !           922: {
        !           923:     STATUS retval = NoErr;
        !           924: 
        !           925:     if (Command == DRetry) {
        !           926: 
        !           927:         retval = Q117iGetDriveError(TapeExtension);
        !           928: 
        !           929:         if (retval && (retval != NotRdy)) {
        !           930: 
        !           931:             return(retval);
        !           932: 
        !           933:         }
        !           934: 
        !           935:         TapeExtension->RetrySeqNum++;
        !           936: 
        !           937:         if (TapeExtension->RdWrOp.RetryCount > 3) {
        !           938: 
        !           939:             retval = Q117iSendByte(TapeExtension, Pause);
        !           940: 
        !           941:         } else {
        !           942: 
        !           943:             retval = Q117iSendByte(TapeExtension, Micro_Pause);
        !           944: 
        !           945:         }
        !           946: 
        !           947:         if (retval) {
        !           948: 
        !           949:             return(retval);
        !           950: 
        !           951:         }
        !           952: 
        !           953:         retval = Q117iWaitCommandComplete(TapeExtension, mt_wt016s);
        !           954:         TapeExtension->TapePosition.LogFwd = FALSE;
        !           955: 
        !           956:     }
        !           957: 
        !           958:     return(retval);
        !           959: }
        !           960: 
        !           961: 
        !           962: STATUS
        !           963: Q117iSetBack(
        !           964:     IN PTAPE_EXTENSION TapeExtension,
        !           965:     IN DRIVER_COMMAND Command
        !           966:     )
        !           967: 
        !           968: /*++
        !           969: 
        !           970: Routine Description:
        !           971: 
        !           972:     Reset any tape drive head offset due to off-track retries.
        !           973: 
        !           974: Arguments:
        !           975: 
        !           976:     TapeExtension -
        !           977: 
        !           978:     Command -
        !           979: 
        !           980: Return Value:
        !           981: 
        !           982: 
        !           983: 
        !           984: --*/
        !           985: {
        !           986:     STATUS retval = NoErr;
        !           987: 
        !           988:     if (Command == DRetry) {
        !           989: 
        !           990:         if (TapeExtension->TapePosition.LogFwd == TRUE) {
        !           991: 
        !           992:             retval = Q117iGetDriveError(TapeExtension);
        !           993: 
        !           994:             if (retval && (retval != NotRdy)) {
        !           995: 
        !           996:                 return(retval);
        !           997: 
        !           998:             }
        !           999: 
        !          1000:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
        !          1001: 
        !          1002:                 return(retval);
        !          1003: 
        !          1004:             }
        !          1005: 
        !          1006:         }
        !          1007: 
        !          1008:         if ((retval = Q117iSendByte(TapeExtension, Seek_Track)) != NoErr) {
        !          1009: 
        !          1010:             return(retval);
        !          1011: 
        !          1012:         }
        !          1013: 
        !          1014:         Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          1015: 
        !          1016:         if ((retval = Q117iSendByte(
        !          1017:                         TapeExtension,
        !          1018:                         (CHAR)(TapeExtension->TapePosition.C_Track + 2))) !=
        !          1019:             NoErr) {
        !          1020: 
        !          1021:             return(retval);
        !          1022: 
        !          1023:         }
        !          1024: 
        !          1025:         retval = Q117iWaitCommandComplete(TapeExtension, mt_wt007s);
        !          1026:     }
        !          1027: 
        !          1028:     return(retval);
        !          1029: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.