Annotation of ntddk/src/scsi/qic117/seek.c, revision 1.1.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.