Annotation of ntddk/src/scsi/qic117/seek.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:     seek.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     positions tape to correct location to be before the desired track and block
        !            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: Q117iSeek(
        !            37:     IN PTAPE_EXTENSION TapeExtension
        !            38:     )
        !            39: 
        !            40: /*++
        !            41: 
        !            42: Routine Description:
        !            43: 
        !            44:     Reposition tape for desired track and block.
        !            45: 
        !            46:         Change track first if necessary.
        !            47: 
        !            48:         Seek at high speed to approximately get to the specified area on
        !            49:         the tape.
        !            50: 
        !            51:         Read ID marks from the tape until the tape is positioned 1 block in
        !            52:         front of (logically) the desired block.
        !            53: 
        !            54: Arguments:
        !            55: 
        !            56:     TapeExtension -
        !            57: 
        !            58: Return Value:
        !            59: 
        !            60: 
        !            61: 
        !            62: --*/
        !            63: 
        !            64: {
        !            65:     STATUS retval = NoErr;
        !            66:     BOOLEAN newTrack;
        !            67:     SHORT seekCount;
        !            68:     BOOLEAN retensionFlag = FALSE;
        !            69: 
        !            70:     newTrack = FALSE;
        !            71:     seekCount = MAX_SEEK_COUNT;
        !            72: 
        !            73:     do {
        !            74: 
        !            75:         if (TapeExtension->TapePosition.D_Segment == 0)
        !            76: 
        !            77:             if ((retval = Q117iLogicalBOT(TapeExtension)) != NoErr) {
        !            78: 
        !            79:                 return(retval);
        !            80: 
        !            81:             }
        !            82: 
        !            83:         if (TapeExtension->TapePosition.D_Track !=
        !            84:             TapeExtension->TapePosition.C_Track) {
        !            85: 
        !            86:             if ((retval = Q117iChangeTrack(
        !            87:                             TapeExtension,
        !            88:                             TapeExtension->TapePosition.D_Track)) != NoErr) {
        !            89: 
        !            90:                 return(retval);
        !            91: 
        !            92:             }
        !            93: 
        !            94:             if (!TapeExtension->DriveParms.Status.BOT &&
        !            95:                 !TapeExtension->DriveParms.Status.EOT) {
        !            96: 
        !            97:                 newTrack = TRUE;
        !            98: 
        !            99:             }
        !           100: 
        !           101:         }
        !           102: 
        !           103:         if (TapeExtension->TapePosition.D_Segment == 0)
        !           104:             return(NoErr);
        !           105: 
        !           106:         if (newTrack == TRUE) {
        !           107: 
        !           108:             retval = Q117iReadIDRepeat(TapeExtension);
        !           109: 
        !           110:         }
        !           111: 
        !           112:         if (retval == NoErr) {
        !           113: 
        !           114:             retval = Q117iHighSpeedSeek(TapeExtension);
        !           115: 
        !           116:         }
        !           117: 
        !           118:         if (retval == NoErr) {
        !           119: 
        !           120:             retval = Q117iReadIDRepeat(TapeExtension);
        !           121: 
        !           122:         }
        !           123: 
        !           124:         --seekCount;
        !           125: 
        !           126:         if ((retval == SeekErr || seekCount == 0) && retensionFlag == FALSE) {
        !           127: 
        !           128:             if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !           129: 
        !           130:                 return(retval);
        !           131: 
        !           132:             }
        !           133: 
        !           134:             if ((retval = Q117iDReten(TapeExtension)) != NoErr) {
        !           135: 
        !           136:                 return(retval);
        !           137: 
        !           138:             }
        !           139: 
        !           140:             seekCount = MAX_SEEK_COUNT;
        !           141:             retensionFlag = TRUE;
        !           142:             retval = NoErr;
        !           143: 
        !           144:         }
        !           145: 
        !           146:         if (retval != NoErr) {
        !           147: 
        !           148:             return(retval);
        !           149: 
        !           150:         }
        !           151: 
        !           152:     } while (!((0 <= ((TapeExtension->TapePosition.D_Segment - 1) -
        !           153:                     TapeExtension->TapePosition.C_Segment)) &&
        !           154:             (((TapeExtension->TapePosition.D_Segment - 1) -
        !           155:                 TapeExtension->TapePosition.C_Segment) <= 10)) &&
        !           156:             (seekCount > 0));
        !           157: 
        !           158:     if (seekCount == 0) {
        !           159: 
        !           160:         CheckedDump(QIC117WARN,( "SeekErr - seekCount = 0\n" ));
        !           161:         return(SeekErr);
        !           162: 
        !           163:     }
        !           164: 
        !           165:     do {
        !           166: 
        !           167:         if ((retval = Q117iReadIDRepeat(TapeExtension)) != NoErr) {
        !           168: 
        !           169:             return(retval);
        !           170: 
        !           171:         }
        !           172: 
        !           173: 
        !           174:     } while ((TapeExtension->TapePosition.D_Segment - 1) >
        !           175:             TapeExtension->TapePosition.C_Segment);
        !           176: 
        !           177:     return(retval);
        !           178: }
        !           179: 
        !           180: 
        !           181: STATUS
        !           182: Q117iChangeTrack(
        !           183:     IN PTAPE_EXTENSION TapeExtension,
        !           184:     IN SHORT DestinationTrack
        !           185:     )
        !           186: 
        !           187: /*++
        !           188: 
        !           189: Routine Description:
        !           190: 
        !           191:     Position the tape drive head to a new track.
        !           192: 
        !           193: Arguments:
        !           194: 
        !           195:     TapeExtension -
        !           196: 
        !           197:     DestinationTrack -
        !           198: 
        !           199: Return Value:
        !           200: 
        !           201: 
        !           202: 
        !           203: --*/
        !           204: 
        !           205: {
        !           206:     STATUS retval;
        !           207: 
        !           208:     if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !           209: 
        !           210:         return(retval);
        !           211: 
        !           212:     }
        !           213: 
        !           214:     if ((retval = Q117iSendByte(TapeExtension, Seek_Track)) != NoErr) {
        !           215: 
        !           216:         return(retval);
        !           217: 
        !           218:     }
        !           219: 
        !           220:     Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           221: 
        !           222:     if ((retval = Q117iSendByte(TapeExtension, (CHAR)(DestinationTrack + 2)))
        !           223:         != NoErr) {
        !           224: 
        !           225:         return(retval);
        !           226: 
        !           227:     }
        !           228: 
        !           229:     if ((retval = Q117iWaitCommandComplete(TapeExtension, mt_wt007s)) !=
        !           230:         NoErr) {
        !           231: 
        !           232:         return(retval);
        !           233: 
        !           234:     }
        !           235: 
        !           236:     TapeExtension->TapePosition.C_Track =
        !           237:         TapeExtension->TapePosition.D_Track;
        !           238: 
        !           239:     if (TapeExtension->DriveParms.Status.BOT ||
        !           240:         TapeExtension->DriveParms.Status.EOT) {
        !           241: 
        !           242:         if (((TapeExtension->TapePosition.C_Track / 2 * 2 ==
        !           243:                 TapeExtension->TapePosition.C_Track) &&
        !           244:                 (TapeExtension->DriveParms.Status.BOT)) ||
        !           245:             ((TapeExtension->TapePosition.C_Track / 2 * 2 !=
        !           246:                 TapeExtension->TapePosition.C_Track) &&
        !           247:                 (TapeExtension->DriveParms.Status.EOT))) {
        !           248: 
        !           249:             TapeExtension->TapePosition.C_Segment = 0;
        !           250: 
        !           251:         } else {
        !           252: 
        !           253:             TapeExtension->TapePosition.C_Segment =
        !           254:                 TapeExtension->TapeParms.SegTtrack;
        !           255: 
        !           256:         }
        !           257: 
        !           258:     }
        !           259:     return(retval);
        !           260: }
        !           261: 
        !           262: 
        !           263: STATUS
        !           264: Q117iReadIDRepeat(
        !           265:     IN PTAPE_EXTENSION TapeExtension
        !           266:     )
        !           267: 
        !           268: /*++
        !           269: 
        !           270: Routine Description:
        !           271: 
        !           272:     Read an ID field off of the tape with the FDC. Read_id_repeat will
        !           273:     attempt 10 times to read a legal ID field before a failure is returned.
        !           274: 
        !           275: Arguments:
        !           276: 
        !           277:     TapeExtension -
        !           278: 
        !           279: Return Value:
        !           280: 
        !           281: 
        !           282: 
        !           283: --*/
        !           284: 
        !           285: {
        !           286:     STATUS retval;
        !           287:     SHORT readIdCnt;
        !           288:     FDC_STATUS status;
        !           289: 
        !           290:     readIdCnt = NumBad;
        !           291: 
        !           292:     while (readIdCnt > 0) {
        !           293: 
        !           294:         --readIdCnt;
        !           295: 
        !           296:         if ((retval = Q117iStartTape(TapeExtension)) != NoErr) {
        !           297: 
        !           298:             return(retval);
        !           299: 
        !           300:         }
        !           301: 
        !           302:         retval = Q117iDoReadID(TapeExtension, mt_wttrks, &status);
        !           303: 
        !           304:         if (retval && retval != TimeOut) {
        !           305: 
        !           306:             return(retval);
        !           307: 
        !           308:         }
        !           309: 
        !           310:         if (!retval && !(status.ST0 & ST0_IC) &&
        !           311:             (TapeExtension->QControllerData->InterfaceType != MicroChannel ||
        !           312:                 !(status.ST1 & ST1_MA))) {
        !           313: 
        !           314:             break;
        !           315: 
        !           316:         } else {
        !           317: 
        !           318:             if ((retval = Q117iChangeTrack(
        !           319:                             TapeExtension,
        !           320:                             TapeExtension->TapePosition.D_Track)) != NoErr) {
        !           321: 
        !           322:                 return(retval);
        !           323: 
        !           324:             }
        !           325: 
        !           326:             if (TapeExtension->DriveParms.Status.BOT ||
        !           327:                 TapeExtension->DriveParms.Status.EOT) {
        !           328: 
        !           329:                 if (((TapeExtension->TapePosition.C_Track / 2 * 2 ==
        !           330:                         TapeExtension->TapePosition.C_Track) &&
        !           331:                         (TapeExtension->DriveParms.Status.BOT)) ||
        !           332:                     ((TapeExtension->TapePosition.C_Track / 2 * 2 !=
        !           333:                         TapeExtension->TapePosition.C_Track) &&
        !           334:                         (TapeExtension->DriveParms.Status.EOT))) {
        !           335: 
        !           336:                     TapeExtension->TapePosition.C_Segment = 0;
        !           337:                     return(NoErr);
        !           338: 
        !           339:                 } else {
        !           340: 
        !           341:                     TapeExtension->TapePosition.C_Segment =
        !           342:                         TapeExtension->TapeParms.SegTtrack;
        !           343:                     return(NoErr);
        !           344: 
        !           345:                 }
        !           346:             }
        !           347:         }
        !           348:     }
        !           349: 
        !           350:     if (readIdCnt == 0) {
        !           351:         CheckedDump(QIC117WARN,( "SeekErr - readIdCnt = 0\n" ));
        !           352:         return(SeekErr);
        !           353:     }
        !           354: 
        !           355:     TapeExtension->TapePosition.C_Segment =
        !           356:         (status.H * TapeExtension->TapeParms.FtrackFside +
        !           357:         status.C) * SEG_FTK + (status.R - 1) / FSC_SEG;
        !           358:     TapeExtension->TapePosition.C_Track =
        !           359:         TapeExtension->TapePosition.C_Segment /
        !           360:         TapeExtension->TapeParms.SegTtrack;
        !           361:     TapeExtension->TapePosition.C_Segment =
        !           362:         TapeExtension->TapePosition.C_Segment %
        !           363:         TapeExtension->TapeParms.SegTtrack;
        !           364: 
        !           365:     return(retval);
        !           366: }
        !           367: 
        !           368: 
        !           369: STATUS
        !           370: Q117iDoReadID(
        !           371:     IN PTAPE_EXTENSION TapeExtension,
        !           372:     IN QIC_TIME ReadIdDelay,
        !           373:     IN FDC_STATUS *ReadIdStatus
        !           374:     )
        !           375: 
        !           376: /*++
        !           377: 
        !           378: Routine Description:
        !           379: 
        !           380:     Try to read an ID fiedl off of the tape via the FDC.
        !           381: 
        !           382: Arguments:
        !           383: 
        !           384:     TapeExtension -
        !           385: 
        !           386:     ReadIdDelay -
        !           387: 
        !           388:     ReadIdStatus -
        !           389: 
        !           390: Return Value:
        !           391: 
        !           392: 
        !           393: 
        !           394: --*/
        !           395: 
        !           396: {
        !           397:     STATUS retval;
        !           398:     SHORT statLength;
        !           399:     struct read_id_cmd readId;
        !           400: 
        !           401:     readId.command = 0x4a;
        !           402:     readId.drive = (UCHAR)TapeExtension->DriveParms.DriveSelect;
        !           403: 
        !           404:     (VOID) Q117iResetInterruptEvent(TapeExtension);
        !           405:     if ((retval = Q117iProgramFDC(
        !           406:                     TapeExtension,
        !           407:                     (CHAR *)&readId,
        !           408:                     sizeof(readId),
        !           409:                     TRUE)) != NoErr) {
        !           410: 
        !           411:         Q117iResetFDC(TapeExtension);
        !           412:         return(retval);
        !           413: 
        !           414:     }
        !           415: 
        !           416:     if ((retval = Q117iSleep(
        !           417:                     TapeExtension,
        !           418:                     ReadIdDelay,
        !           419:                     TRUE)) == TimeOut) {
        !           420: 
        !           421:         Q117iResetFDC(TapeExtension);
        !           422:         return(retval);
        !           423: 
        !           424:     }
        !           425: 
        !           426:     if ((retval = Q117iReadFDC(
        !           427:                     TapeExtension,
        !           428:                     (CHAR *)ReadIdStatus,
        !           429:                     &statLength)) != NoErr) {
        !           430: 
        !           431:         return(retval);
        !           432: 
        !           433:     }
        !           434: 
        !           435:     return(retval);
        !           436: }
        !           437: 
        !           438: 
        !           439: VOID
        !           440: Q117iGetComFirmStr(
        !           441:     IN PTAPE_EXTENSION TapeExtension,
        !           442:     IN OUT CHAR **Ptr,
        !           443:     IN SHORT Index
        !           444:     )
        !           445: 
        !           446: /*++
        !           447: 
        !           448: Routine Description:
        !           449: 
        !           450:     Takes a string and fills it with a requested DComFirm string.
        !           451: 
        !           452: Arguments:
        !           453: 
        !           454:     TapeExtension -
        !           455: 
        !           456:     Ptr - a byte pointer that points to memory into which the requested
        !           457:     DComFirm string is to be placed.
        !           458: 
        !           459:     Index - a number that indicates which DcomFirm string to place in the
        !           460:     memory pointed to by the Ptr parameter.
        !           461: 
        !           462: Return Value:
        !           463: 
        !           464:     None
        !           465: 
        !           466: --*/
        !           467: 
        !           468: {
        !           469:     SHORT numChars;  // number of chars in requested DComfirm str
        !           470: 
        !           471: 
        !           472:     switch(Index) {
        !           473: 
        !           474:     case DCOMFIRM_READ_RAM_REQ:
        !           475:         *Ptr = DCOMFIRM_READ_RAM_STRING;
        !           476:         numChars = DCOMFIRM_NUM_READ_RAM_CHARS;
        !           477:         break;
        !           478: 
        !           479:     case DCOMFIRM_SET_RAM_REQ:
        !           480:         *Ptr = DCOMFIRM_SET_RAM_STRING;
        !           481:         numChars = DCOMFIRM_NUM_SET_RAM_CHARS;
        !           482:         break;
        !           483: 
        !           484:     case DCOMFIRM_WRITE_RAM_REQ:
        !           485:         *Ptr = DCOMFIRM_WRITE_RAM_STRING;
        !           486:         numChars = DCOMFIRM_NUM_WRITE_RAM_CHARS;
        !           487:         break;
        !           488: 
        !           489:     }
        !           490: 
        !           491: }
        !           492: 
        !           493: 
        !           494: STATUS
        !           495: Q117iLogicalBOT(
        !           496:     IN PTAPE_EXTENSION TapeExtension
        !           497:     )
        !           498: 
        !           499: /*++
        !           500: 
        !           501: Routine Description:
        !           502: 
        !           503:     Go at high speed to logical BOT. Logical BOT is physical BOT for even
        !           504:     numbered tracks and physical EOT for odd numbered tracks.
        !           505: 
        !           506: Arguments:
        !           507: 
        !           508:     TapeExtension -
        !           509: 
        !           510: Return Value:
        !           511: 
        !           512: 
        !           513: 
        !           514: --*/
        !           515: 
        !           516: {
        !           517:     STATUS retval;
        !           518:     CHAR *string;      // holds DComFirm string
        !           519:     SHORT direction;   // tells physical direction of tape movement
        !           520: 
        !           521: 
        !           522:     if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !           523: 
        !           524:         return(retval);
        !           525: 
        !           526:     }
        !           527: 
        !           528:     if ((TapeExtension->TapePosition.D_Track / 2 * 2) ==
        !           529:         TapeExtension->TapePosition.D_Track) {
        !           530: 
        !           531:         retval = Q117iSendByte(TapeExtension, Physical_Rev);
        !           532:         direction = REVERSE;
        !           533: 
        !           534:     } else {
        !           535: 
        !           536:         retval = Q117iSendByte(TapeExtension, Physical_Fwd);
        !           537:         direction = FORWARD;
        !           538: 
        !           539:     }
        !           540: 
        !           541:     if (retval) {
        !           542: 
        !           543:         return(retval);
        !           544: 
        !           545:     }
        !           546: 
        !           547:     //
        !           548:     // This is part of the Sankyo motor "hack."  While the motor is moving
        !           549:     // at high speed to the end of the tape, the driver sets the RAM pointer
        !           550:     // on the 8051 to point to the byte in memory that contains the bit that
        !           551:     // tells whether or not the EOT/BOT sensor is over a hole.  This
        !           552:     // concurrent operation is purely for performance enhancement (saves
        !           553:     // ~220 msec).
        !           554:     //
        !           555: 
        !           556:     if ((TapeExtension->DriveParms.Version == FIRM_VERSION_64) &&
        !           557:             (TapeExtension->DriveParms.Flavor == CMS)) {
        !           558: 
        !           559:         Q117iSleep(TapeExtension, mt_wt200ms, FALSE);
        !           560: 
        !           561:         //
        !           562:         // Set the ram ptr to the byte with the hole_flag bit.
        !           563:         //
        !           564: 
        !           565:         Q117iGetComFirmStr(TapeExtension, &string, DCOMFIRM_SET_RAM_REQ);
        !           566:         string[DCOMFIRM_SETRAM_HI_NIB_INDEX] =
        !           567:             HOLE_FLAG_BYTE_ADD_UPPER_NIBBLE;
        !           568:         string[DCOMFIRM_SETRAM_LOW_NIB_INDEX] =
        !           569:             HOLE_FLAG_BYTE_ADD_LOWER_NIBBLE;
        !           570: 
        !           571:         if ((retval = Q117iDComFirm(TapeExtension, (CHAR  *)string)) !=
        !           572:             NoErr) {
        !           573: 
        !           574:             return(retval);
        !           575: 
        !           576:         }
        !           577:     }
        !           578: 
        !           579:     if ((retval = Q117iWaitCommandComplete(
        !           580:                         TapeExtension,
        !           581:                         TapeExtension->TapeParms.TimeOut[PHYSICAL])) !=
        !           582:         NoErr) {
        !           583: 
        !           584:         return(retval);
        !           585: 
        !           586:     }
        !           587: 
        !           588:     if (TapeExtension->DriveParms.Version == FIRM_VERSION_64) {
        !           589: 
        !           590:         //
        !           591:         // Prepare the communication string to read the byte with the
        !           592:         // hole_flag bit in it.
        !           593:         //
        !           594: 
        !           595:         //
        !           596:         // Wait for the motor to stop.
        !           597:         //
        !           598: 
        !           599:         Q117iSleep(TapeExtension, mt_wt260ms, FALSE);
        !           600: 
        !           601: 
        !           602:         //
        !           603:         // Read the byte with the hole flag bit in it.  If the bit is 0,
        !           604:         // that means the drive has stopped over a hole.  In that case,
        !           605:         // the tape zone counter must be adjusted and written to the drive,
        !           606:         // and the driver saves the day.
        !           607:         //
        !           608: 
        !           609:         Q117iGetComFirmStr(TapeExtension, &string,DCOMFIRM_READ_RAM_REQ);
        !           610: 
        !           611:         if ((retval = Q117iDComFirm(TapeExtension, (CHAR  *)string)) !=
        !           612:             NoErr) {
        !           613: 
        !           614:             return(retval);
        !           615: 
        !           616:         }
        !           617: 
        !           618:         if (!(string[DCOMFIRM_READ_RTRN_BYTE_INDEX] & HOLE_INDICATOR_MASK)) {
        !           619: 
        !           620:             if (direction == REVERSE) {
        !           621: 
        !           622:                 //
        !           623:                 // If at BOT, the only cause for concern is when the EOT/BOT
        !           624:                 // sensor is over the rightmost hole of the BOT pair.  To
        !           625:                 // differentiate this from the case where the sensor is
        !           626:                 // sitting over the leftmost hole, read the double hole
        !           627:                 // distance counter.  If it is non-zero, do nothing.
        !           628:                 //
        !           629: 
        !           630:                 //
        !           631:                 // Set the ram ptr to 0x3B, the double hole counter,
        !           632:                 //
        !           633: 
        !           634:                 Q117iGetComFirmStr(
        !           635:                     TapeExtension, &string, DCOMFIRM_SET_RAM_REQ);
        !           636:                 string[DCOMFIRM_SETRAM_HI_NIB_INDEX] =
        !           637:                     DBL_HOLE_CNTER_ADD_UPPER_NIBBLE;
        !           638:                 string[DCOMFIRM_SETRAM_LOW_NIB_INDEX] =
        !           639:                     DBL_HOLE_CNTER_ADD_LOWER_NIBBLE;
        !           640:                 if ( (retval = Q117iDComFirm(
        !           641:                                     TapeExtension,
        !           642:                                     (CHAR  *)string)) != NoErr) {
        !           643: 
        !           644:                     return(retval);
        !           645: 
        !           646:                 }
        !           647: 
        !           648:                 //
        !           649:                 // Read the double hole counter.
        !           650:                 //
        !           651: 
        !           652:                 Q117iGetComFirmStr(
        !           653:                     TapeExtension, &string,DCOMFIRM_READ_RAM_REQ);
        !           654: 
        !           655:                 if ((retval = Q117iDComFirm(
        !           656:                                 TapeExtension,
        !           657:                                 (CHAR  *)string)) != NoErr) {
        !           658: 
        !           659:                     return(retval);
        !           660: 
        !           661:                 }
        !           662: 
        !           663:                 if (!(string[DCOMFIRM_READ_RTRN_BYTE_INDEX])) {
        !           664: 
        !           665:                     if ((retval = Q117iAdjustTapeZone(TapeExtension, (SHORT) AT_BOT))
        !           666:                         != NoErr) {
        !           667: 
        !           668:                         return(retval);
        !           669: 
        !           670:                     }
        !           671:                 }
        !           672: 
        !           673:             } else {
        !           674: 
        !           675:                 if ((retval = Q117iAdjustTapeZone(TapeExtension, (SHORT) AT_EOT)) !=
        !           676:                     NoErr) {
        !           677: 
        !           678:                     return(retval);
        !           679: 
        !           680:                 }
        !           681:             }
        !           682:         }
        !           683:     }
        !           684:     if ((TapeExtension->TapePosition.D_Track / 2 * 2) ==
        !           685:         TapeExtension->TapePosition.D_Track) {
        !           686: 
        !           687:         if (!TapeExtension->DriveParms.Status.BOT) {
        !           688: 
        !           689:             CheckedDump(QIC117WARN,( "SeekErr - not at BOT\n" ));
        !           690:             return(SeekErr);
        !           691: 
        !           692:         }
        !           693: 
        !           694:     } else {
        !           695: 
        !           696:         if (!TapeExtension->DriveParms.Status.EOT) {
        !           697: 
        !           698:             CheckedDump(QIC117WARN,( "SeekErr - not at EOT\n" ));
        !           699:             return(SeekErr);
        !           700: 
        !           701:         }
        !           702:     }
        !           703: 
        !           704:     TapeExtension->TapePosition.C_Segment = 0;
        !           705:     return(NoErr);
        !           706: }
        !           707: 
        !           708: 
        !           709: STATUS
        !           710: Q117iAdjustTapeZone(
        !           711:     IN PTAPE_EXTENSION TapeExtension,
        !           712:     IN SHORT TapePosition
        !           713:     )
        !           714: 
        !           715: /*++
        !           716: 
        !           717: Routine Description:
        !           718: 
        !           719:     Adjust the tape zone counter to compensate for stopping with the EOT/BOT
        !           720:     sensor over a hole.
        !           721: 
        !           722: Arguments:
        !           723: 
        !           724:     TapeExtension -
        !           725: 
        !           726:     TapePosition - tells wheather EOT or BOT
        !           727: 
        !           728: Return Value:
        !           729: 
        !           730: 
        !           731: 
        !           732: --*/
        !           733: 
        !           734: {
        !           735: 
        !           736:     CHAR highNibble;
        !           737:     CHAR lowNibble;
        !           738:     CHAR *string;
        !           739:     STATUS retval = NoErr;
        !           740: 
        !           741:     //
        !           742:     // Set the pointer in the 8051 RAM to the tape zone counter.
        !           743:     //
        !           744: 
        !           745:     Q117iGetComFirmStr(TapeExtension, &string, DCOMFIRM_SET_RAM_REQ);
        !           746:     string[DCOMFIRM_SETRAM_HI_NIB_INDEX] = TAPE_ZONE_BYTE_ADD_UPPER_NIBBLE;
        !           747:     string[DCOMFIRM_SETRAM_LOW_NIB_INDEX] = TAPE_ZONE_BTYE_ADD_LOWER_NIBBLE;
        !           748: 
        !           749:     retval = Q117iDComFirm(TapeExtension, (CHAR  *)string);
        !           750: 
        !           751:     if (retval == NoErr) {
        !           752: 
        !           753:         if (TapePosition == AT_EOT) {
        !           754: 
        !           755:             highNibble = EOT_ZONE_COUNTER_UPPER_NIBBLE;
        !           756:             lowNibble = EOT_ZONE_COUNTER_LOWER_NIBBLE;
        !           757: 
        !           758:         } else {
        !           759: 
        !           760:             highNibble = BOT_ZONE_COUNTER_UPPER_NIBBLE;
        !           761:             lowNibble = BOT_ZONE_COUNTER_LOWER_NIBBLE;
        !           762: 
        !           763:         }
        !           764: 
        !           765:         //
        !           766:         // Write the upper and lower nybbles of the tape zone counter.
        !           767:         //
        !           768: 
        !           769:         Q117iGetComFirmStr(TapeExtension, &string, DCOMFIRM_WRITE_RAM_REQ);
        !           770:         string[DCOMFIRM_WRTRAM_HI_NIB_INDEX] = highNibble;
        !           771:         string[DCOMFIRM_WRTRAM_LOW_NIB_INDEX] = lowNibble;
        !           772:         retval = Q117iDComFirm(TapeExtension, (CHAR  *)string);
        !           773:     }
        !           774: 
        !           775:     return(retval);
        !           776: }
        !           777: 
        !           778: 
        !           779: STATUS
        !           780: Q117iHighSpeedSeek(
        !           781:     IN PTAPE_EXTENSION TapeExtension
        !           782:     )
        !           783: 
        !           784: /*++
        !           785: 
        !           786: Routine Description:
        !           787: 
        !           788:     Execute a High Speed Seek.  There are two methods of doing this now.
        !           789:     First, if the Skip commands are not implemented, the high speed seek
        !           790:     is accomplished by calculating the approximate amount of time needed
        !           791:     at high speed to reach the target position and allowing the tape drive
        !           792:     to go at 90 ips for that amount of time.  If the Skip commands are
        !           793:     implemented, the high speed seek is merely the proper command with
        !           794:     a calculated offset.
        !           795: 
        !           796:     The Seeking is done by using either the Skip_N_Segments command or by using
        !           797:     the time seeking algorithm provided by Q117iWaitSeek. The Skip_N_Segments commands
        !           798:     are not reliable in all versions of the firmware. Only in versions for JUMBO_B
        !           799:     and greater are the commands available at all and only in versions of 65 and
        !           800:     greater are the Skip_N_Segment commands reliable for skipping past the
        !           801:     DC erased gap.
        !           802: 
        !           803: Arguments:
        !           804: 
        !           805:     TapeExtension -
        !           806: 
        !           807: Return Value:
        !           808: 
        !           809: 
        !           810: 
        !           811: --*/
        !           812: 
        !           813: {
        !           814:     STATUS retval = NoErr;
        !           815:     SHORT seekOffset;
        !           816:     SHORT i;
        !           817:     CHAR seekDir;
        !           818:     CHAR skipNSegs;
        !           819:     USHORT skip;
        !           820: 
        !           821:     //
        !           822:     // Determine the logical direction that the tape needs to be moved
        !           823:     //
        !           824: 
        !           825:     if ((seekOffset = (TapeExtension->TapePosition.D_Segment - 1) -
        !           826:                             TapeExtension->TapePosition.C_Segment) >= 0) {
        !           827: 
        !           828:         seekDir = FWD;
        !           829: 
        !           830:     } else {
        !           831: 
        !           832:         seekDir = REV;
        !           833:         seekOffset = 0 - seekOffset;
        !           834: 
        !           835:     }
        !           836: 
        !           837:     if (seekDir == REV || seekOffset > STOP_LEN) {
        !           838: 
        !           839:         if((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !           840: 
        !           841:                 return(retval);
        !           842: 
        !           843:         }
        !           844: 
        !           845:         if (seekDir == FWD) {
        !           846: 
        !           847:             if (TapeExtension->DriveParms.SeekMode == SEEK_TIMED) {
        !           848: 
        !           849:                 seekOffset -= SEEK_SLOP;
        !           850: 
        !           851:             } else {
        !           852: 
        !           853:                 seekOffset -= 1;
        !           854: 
        !           855:             }
        !           856: 
        !           857:         } else {
        !           858: 
        !           859:             //
        !           860:             // seek direction is reverse
        !           861:             //
        !           862: 
        !           863:             if (TapeExtension->DriveParms.Status.BOT ||
        !           864:                 TapeExtension->DriveParms.Status.EOT) {
        !           865: 
        !           866:                 switch (TapeExtension->TapeParms.TapeType) {
        !           867: 
        !           868:                 case QIC40_SHORT:
        !           869:                 case QIC80_SHORT:
        !           870:                     seekOffset += QIC_REV_OFFSET;
        !           871:                     break;
        !           872: 
        !           873:                 case QIC40_LONG:
        !           874:                 case QIC80_LONG:
        !           875:                 case QIC500_SHORT:
        !           876:                     seekOffset += QIC_REV_OFFSET_L;
        !           877:                     break;
        !           878: 
        !           879:                 case QICEST_40:
        !           880:                 case QICEST_80:
        !           881:                 case QICEST_500:
        !           882:                     seekOffset += QICEST_REV_OFFSET;
        !           883:                     break;
        !           884: 
        !           885:                 }
        !           886: 
        !           887:             } else {
        !           888: 
        !           889:                 if (TapeExtension->DriveParms.SeekMode == SEEK_TIMED) {
        !           890: 
        !           891:                     seekOffset += SEEK_SLOP;
        !           892: 
        !           893:                 } else {
        !           894: 
        !           895:                     seekOffset += 1;
        !           896: 
        !           897:                 }
        !           898: 
        !           899:             }
        !           900:         }
        !           901: 
        !           902:         switch (TapeExtension->DriveParms.SeekMode) {
        !           903: 
        !           904:         case SEEK_SKIP:
        !           905:             //
        !           906:             // Determine the offset to be used for the Skip_N_Segment commands
        !           907:             //
        !           908: 
        !           909:             CheckedDump(QIC117SHOWQD,( "Q117i: Skip_N_Segments Seek\n"));
        !           910: 
        !           911:             if (seekDir == FWD) {
        !           912: 
        !           913:                 skipNSegs = Skip_N_Fwd;
        !           914: 
        !           915:             } else {
        !           916: 
        !           917:                 skipNSegs = Skip_N_Rev;
        !           918: 
        !           919:             }
        !           920: 
        !           921:             // Skip the first bytes worth of segments
        !           922: 
        !           923:             if ((retval = Q117iSendByte(
        !           924:                     TapeExtension,
        !           925:                     skipNSegs)) != NoErr) {
        !           926: 
        !           927:                 return(retval);
        !           928: 
        !           929:             }
        !           930: 
        !           931:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           932: 
        !           933:             if ((retval = Q117iSendByte(
        !           934:                     TapeExtension,
        !           935:                     ((seekOffset & 0xf) + 2))) != NoErr) {
        !           936: 
        !           937:                 return(retval);
        !           938: 
        !           939:             }
        !           940: 
        !           941:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           942: 
        !           943:             seekOffset >>= 4;
        !           944: 
        !           945:             if ((retval = Q117iSendByte(
        !           946:                     TapeExtension,
        !           947:                     ((seekOffset & 0x0f)+2))) != NoErr) {
        !           948: 
        !           949:                 return(retval);
        !           950: 
        !           951:             }
        !           952: 
        !           953:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           954: 
        !           955:             if ((retval = Q117iWaitCommandComplete(
        !           956:                     TapeExtension,
        !           957:                     TapeExtension->TapeParms.TimeOut[PHYSICAL])) != NoErr) {
        !           958: 
        !           959:                 return(retval);
        !           960: 
        !           961:             }
        !           962: 
        !           963:             seekOffset >>= 4;
        !           964: 
        !           965:             for (;seekOffset != 0; --seekOffset) {
        !           966: 
        !           967:                 // Skip the second bytes worth of segments
        !           968: 
        !           969:                 for (i=0; i<2; ++i) {
        !           970:                     if (i) {
        !           971: 
        !           972:                         skip = 1;
        !           973: 
        !           974:                     } else {
        !           975: 
        !           976:                         skip = MAX_SKIP;
        !           977: 
        !           978:                     }
        !           979: 
        !           980:                     if ((retval = Q117iSendByte(
        !           981:                             TapeExtension,
        !           982:                             skipNSegs)) != NoErr) {
        !           983: 
        !           984:                         return(retval);
        !           985: 
        !           986:                     }
        !           987: 
        !           988:                     Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           989: 
        !           990:                     if ((retval = Q117iSendByte(
        !           991:                             TapeExtension,
        !           992:                             ((skip & 0xf) + 2))) != NoErr) {
        !           993: 
        !           994:                         return(retval);
        !           995: 
        !           996:                     }
        !           997: 
        !           998:                     Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           999: 
        !          1000:                     if ((retval = Q117iSendByte(
        !          1001:                             TapeExtension,
        !          1002:                             ((skip >> 4) + 2))) != NoErr) {
        !          1003: 
        !          1004:                         return(retval);
        !          1005: 
        !          1006:                     }
        !          1007: 
        !          1008:                     Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          1009: 
        !          1010:                     if ((retval = Q117iWaitCommandComplete(
        !          1011:                             TapeExtension,
        !          1012:                             TapeExtension->TapeParms.TimeOut[PHYSICAL])) != NoErr) {
        !          1013: 
        !          1014:                         return(retval);
        !          1015: 
        !          1016:                     }
        !          1017:                 }
        !          1018:             }
        !          1019: 
        !          1020:             break;
        !          1021: 
        !          1022:         case SEEK_SKIP_EXTENDED:
        !          1023: 
        !          1024:             if (seekDir == FWD) {
        !          1025: 
        !          1026:                 skipNSegs = Skip_N_Fwd_Ext;
        !          1027: 
        !          1028:             } else {
        !          1029: 
        !          1030:                 skipNSegs = Skip_N_Rev_Ext;
        !          1031: 
        !          1032:             }
        !          1033: 
        !          1034: 
        !          1035:             if ((retval = Q117iSendByte(
        !          1036:                     TapeExtension,
        !          1037:                     skipNSegs)) != NoErr) {
        !          1038: 
        !          1039:                 return(retval);
        !          1040: 
        !          1041:             }
        !          1042: 
        !          1043:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          1044: 
        !          1045:             for (i = 0; i < MAX_SEEK_NIBBLES; i++) {
        !          1046: 
        !          1047:                 if ((retval = Q117iSendByte(
        !          1048:                         TapeExtension,
        !          1049:                         ((seekOffset & 0xf) + 2))) != NoErr) {
        !          1050: 
        !          1051:                     return(retval);
        !          1052: 
        !          1053:                 }
        !          1054: 
        !          1055:                 Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          1056: 
        !          1057:                 seekOffset >>= 4;
        !          1058: 
        !          1059:             }
        !          1060: 
        !          1061:             if ((retval = Q117iWaitCommandComplete(
        !          1062:                     TapeExtension,
        !          1063:                     TapeExtension->TapeParms.TimeOut[PHYSICAL])) != NoErr) {
        !          1064: 
        !          1065:                 return(retval);
        !          1066: 
        !          1067:             }
        !          1068: 
        !          1069:             break;
        !          1070: 
        !          1071:         default: // SEEK_TIMED
        !          1072: 
        !          1073:             //
        !          1074:             // Skip segments commands are not available
        !          1075:             //
        !          1076: 
        !          1077:             CheckedDump(QIC117SHOWQD,( "Q117i: Timed Seek\n"));
        !          1078: 
        !          1079: 
        !          1080:             if (((seekDir == FWD) &&
        !          1081:                     (TapeExtension->TapePosition.C_Track / 2 * 2 ==
        !          1082:                     TapeExtension->TapePosition.C_Track)) ||
        !          1083:                     ((seekDir == REV) &&
        !          1084:                     (TapeExtension->TapePosition.C_Track / 2 * 2 !=
        !          1085:                     TapeExtension->TapePosition.C_Track))) {
        !          1086: 
        !          1087:                 if ((retval = Q117iSendByte(TapeExtension, Physical_Fwd)) !=
        !          1088:                         NoErr) {
        !          1089: 
        !          1090:                     return(retval);
        !          1091: 
        !          1092:                 }
        !          1093: 
        !          1094:             } else {
        !          1095: 
        !          1096:                 if ((retval = Q117iSendByte(TapeExtension, Physical_Rev)) !=
        !          1097:                         NoErr) {
        !          1098: 
        !          1099:                     return(retval);
        !          1100: 
        !          1101:                 }
        !          1102:             }
        !          1103: 
        !          1104:             if ((retval = Q117iWaitSeek(TapeExtension, seekOffset)) != NoErr) {
        !          1105: 
        !          1106:                 return(retval);
        !          1107: 
        !          1108:             }
        !          1109: 
        !          1110:             if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
        !          1111: 
        !          1112:                 return(retval);
        !          1113: 
        !          1114:             }
        !          1115:         }
        !          1116:     }
        !          1117:     return(retval);
        !          1118: }
        !          1119: 
        !          1120: 
        !          1121: STATUS
        !          1122: Q117iWaitSeek(
        !          1123:     IN PTAPE_EXTENSION TapeExtension,
        !          1124:     SHORT SeekDelay
        !          1125:     )
        !          1126: 
        !          1127: /*++
        !          1128: 
        !          1129: Routine Description:
        !          1130: 
        !          1131:     Execute a timed high speed seek.  This routine is used for CMS drives
        !          1132:     that have not implemented the Skip commands (all those before firmware
        !          1133:     version 34) and all non-CMS drives.
        !          1134: 
        !          1135: Arguments:
        !          1136: 
        !          1137:     TapeExtension -
        !          1138: 
        !          1139:     SeekDelay -
        !          1140: 
        !          1141: Return Value:
        !          1142: 
        !          1143: 
        !          1144: 
        !          1145: --*/
        !          1146: 
        !          1147: {
        !          1148:     STATUS retval;
        !          1149: 
        !          1150:     do {
        !          1151: 
        !          1152:         Q117iSleep(TapeExtension, mt_wt200ms, FALSE);
        !          1153:         retval = Q117iGetDriveError(TapeExtension);
        !          1154: 
        !          1155:         if (retval && retval != NotRdy) {
        !          1156: 
        !          1157:             return(retval);
        !          1158: 
        !          1159:         }
        !          1160: 
        !          1161:         if (retval == NoErr) {
        !          1162: 
        !          1163:             if (TapeExtension->DriveParms.Status.BOT ||
        !          1164:                 TapeExtension->DriveParms.Status.EOT) {
        !          1165: 
        !          1166:                 break;
        !          1167: 
        !          1168:             }
        !          1169: 
        !          1170:             return(DriveFlt);
        !          1171:         }
        !          1172: 
        !          1173:         --SeekDelay;
        !          1174: 
        !          1175:     } while (SeekDelay > 0);
        !          1176: 
        !          1177:     return(NoErr);
        !          1178: }

unix.superglobalmegacorp.com

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