Annotation of ntddk/src/scsi/qic117/fnddrv.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:     fnddrv.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     scans the floppy bus for a qic117 device.
        !            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: Q117iDFndDrv(
        !            37:     IN PTAPE_EXTENSION TapeExtension
        !            38:     )
        !            39: 
        !            40: /*++
        !            41: 
        !            42: Routine Description:
        !            43: 
        !            44:     Find if and where tape drive is (B or D). Configure the drive and tape
        !            45:     drive as necessary.
        !            46: 
        !            47: Arguments:
        !            48: 
        !            49:     TapeExtension -
        !            50: 
        !            51: Return Value:
        !            52: 
        !            53: 
        !            54: 
        !            55: --*/
        !            56: 
        !            57: {
        !            58: 
        !            59:     STATUS retval = NoErr;     // return value
        !            60:     SHORT i;                  // loop variable
        !            61:     LARGE_INTEGER controllerWait;
        !            62:     NTSTATUS waitStatus;
        !            63: 
        !            64: 
        !            65:     controllerWait = RtlLargeIntegerNegate(
        !            66:                         RtlConvertLongToLargeInteger(
        !            67:                         (LONG)(10 * 1000 * 15000)
        !            68:                         )
        !            69:                         );
        !            70: 
        !            71:     waitStatus = STATUS_SUCCESS;
        !            72: 
        !            73:     CheckedDump(QIC117INFO,( "Q117i: Waiting Controller Event\n"));
        !            74: 
        !            75:     waitStatus = KeWaitForSingleObject(
        !            76:         TapeExtension->QControllerData->ControllerEvent,
        !            77:         Executive,
        !            78:         KernelMode,
        !            79:         FALSE,
        !            80:         &controllerWait);
        !            81: 
        !            82: 
        !            83:     if (waitStatus == STATUS_TIMEOUT) {
        !            84: 
        !            85:         CheckedDump(QIC117INFO,( "Q117i: Timeout Controller Event\n"));
        !            86:         return (ControllerBusy);
        !            87: 
        !            88:     }
        !            89: 
        !            90:     CheckedDump(QIC117INFO,( "Q117i: Have Controller Event\n"));
        !            91: 
        !            92:     TapeExtension->QControllerData->CurrentInterrupt = TRUE;
        !            93: 
        !            94:     if (!TapeExtension->Found) {
        !            95: 
        !            96:         //
        !            97:         // If the tape drive address is already known, there is no need to
        !            98:         // look for it again.
        !            99:         //
        !           100: 
        !           101:         if ((retval = Q117iDLocateDrv(TapeExtension)) == NoErr) {
        !           102: 
        !           103:             //
        !           104:             // Now that we know where the tape drive is we must prepare
        !           105:             // it for the forthcoming operations.  First thing is to make
        !           106:             // sure that it is in Primary mode so there are no Invalid Command
        !           107:             // surprises.  Once in Primary mode, we can determine what flavor
        !           108:             // of drive is out there (CMS or alien; QIC-40, QIC-80, XR4, etc).
        !           109:             // Next, we need to determine the speed of the FDC so we can set the
        !           110:             // corresponding speed on our drive (currently this only applies to
        !           111:             // the CMS drive since we are the only multiple speed drive out
        !           112:             // there).  Finally, armed with the drive type and the FDC speed,
        !           113:             // we need to set the necessary speed in the tape drive which is
        !           114:             // done in ConfigureDrive.
        !           115:             //
        !           116: 
        !           117:             if (retval == NoErr) {
        !           118: 
        !           119:                 retval = Q117iSelectDrive(TapeExtension);
        !           120:                 TapeExtension->QControllerData->PerpModeSelect =
        !           121:                     (UCHAR)(1 << (TapeExtension->QControllerData->DriveSelect.SelectByte &
        !           122:                     DRIVE_ID_MASK));
        !           123: 
        !           124:             }
        !           125: 
        !           126:             if (retval != NoErr) {
        !           127: 
        !           128:                 if (TapeExtension->QControllerData->AdapterLocked) {
        !           129: 
        !           130:                     Q117iDLockUnlockDMA(TapeExtension, FALSE);
        !           131: 
        !           132:                 }
        !           133: 
        !           134:                 (VOID) Q117iResetFDC(TapeExtension);
        !           135: 
        !           136:                 CheckedDump(QIC117INFO,( "Q117iDFndDrv: Setting Controller Event\n"));
        !           137: 
        !           138:                 TapeExtension->NoPause = TRUE;
        !           139:                 TapeExtension->NewCart = FALSE;
        !           140:                 TapeExtension->QControllerData->CurrentInterrupt = FALSE;
        !           141: 
        !           142:                 (VOID) KeSetEvent(
        !           143:                     TapeExtension->QControllerData->ControllerEvent,
        !           144:                     (KPRIORITY) 0,
        !           145:                     FALSE );
        !           146: 
        !           147:                 return(retval);
        !           148: 
        !           149:             }
        !           150: 
        !           151:             //
        !           152:             // This fixes the Jumbo B firmware bug where a tape put into
        !           153:             // the drive slowly is perceive (incorrectly) as invalid media.
        !           154:             // Since there is no way of knowing the maker of the drive
        !           155:             // (e.g. CMS, Irwin, etc.), or the type of drive (QIC40, QIC80),
        !           156:             // it is assumed that it is a CMS QIC80 drive, and Q117ifrmware_fix
        !           157:             // is called.
        !           158:             //
        !           159: 
        !           160:             if (TapeExtension->FirmwareError == Inval_Media) {
        !           161: 
        !           162:                 if ((retval = Q117iClearTapeError(TapeExtension)) != NoErr) {
        !           163: 
        !           164:                     Q117iDDeselect(TapeExtension);
        !           165:                     return(retval);
        !           166: 
        !           167:                 }
        !           168:             }
        !           169: 
        !           170:             TapeExtension->DriveParms.Mode = DIAGNOSTIC_1_MODE;
        !           171:             retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE);
        !           172: 
        !           173:             if (retval && retval != NoTape) {
        !           174: 
        !           175:                 Q117iDDeselect(TapeExtension);
        !           176:                 return(retval);
        !           177: 
        !           178:             }
        !           179: 
        !           180:             TapeExtension->DriveParms.Flavor = UNKNOWN;
        !           181:             if ((retval = Q117iGetDriveType(TapeExtension)) != NoErr) {
        !           182: 
        !           183:                 CheckedDump(QIC117INFO,( "Q117i: GetDriveType Failed %d (decimal)\n", retval));
        !           184:                 Q117iDDeselect(TapeExtension);
        !           185:                 return(retval);
        !           186: 
        !           187:             }
        !           188: 
        !           189:             if ((retval = Q117iSenseSpeed(TapeExtension)) != NoErr) {
        !           190: 
        !           191:                 CheckedDump(QIC117INFO,( "Q117i: SenseSpeed Failed %d (decimal)\n", retval));
        !           192:                 Q117iDDeselect(TapeExtension);
        !           193:                 return(retval);
        !           194: 
        !           195:             }
        !           196: 
        !           197:             if ((retval = Q117iConfigureDrive(TapeExtension)) != NoErr) {
        !           198: 
        !           199:                 CheckedDump(QIC117INFO,( "Q117i: ConfigureDrive Failed %d (decimal)\n", retval));
        !           200:                 Q117iDDeselect(TapeExtension);
        !           201:                 return(retval);
        !           202: 
        !           203:             }
        !           204: 
        !           205:             TapeExtension->Found = TRUE;
        !           206: 
        !           207:         }
        !           208: 
        !           209:     } else {
        !           210: 
        !           211:         if ((retval = Q117iSelectDrive(TapeExtension)) != NoErr) {
        !           212: 
        !           213:             CheckedDump(QIC117INFO,( "Q117i: Select Failed %d (decimal)\n", retval));
        !           214:             Q117iDDeselect(TapeExtension);
        !           215:             return(retval);
        !           216: 
        !           217:         }
        !           218: 
        !           219:     }
        !           220: 
        !           221:     if (retval == NoErr) {
        !           222: 
        !           223:         retval = Q117iNewTape(TapeExtension);
        !           224: 
        !           225:         if (retval && (retval != NoTape) && (retval != NewCart)) {
        !           226: 
        !           227:             Q117iDDeselect(TapeExtension);
        !           228:             return(retval);
        !           229: 
        !           230:         } else {
        !           231: 
        !           232:             retval = NoErr;
        !           233: 
        !           234:         }
        !           235: 
        !           236:     }
        !           237: 
        !           238:     return(retval);
        !           239: }
        !           240: 
        !           241: 
        !           242: STATUS
        !           243: Q117iDLocateDrv(
        !           244:    IN PTAPE_EXTENSION TapeExtension
        !           245:    )
        !           246: 
        !           247: /*++
        !           248: 
        !           249: Routine Description:
        !           250: 
        !           251: 
        !           252: 
        !           253: Arguments:
        !           254: 
        !           255:    TapeExtension -
        !           256: 
        !           257: Return Value:
        !           258: 
        !           259: 
        !           260: 
        !           261: --*/
        !           262: 
        !           263: {
        !           264:     STATUS retval = NoErr;  // return value
        !           265:     SHORT i;                // loop variable
        !           266: 
        !           267:     //
        !           268:     // If the tape drive address is already known, there is no need to look for
        !           269:     // it again.
        !           270:     //
        !           271: 
        !           272:     if (!TapeExtension->Found) {
        !           273: 
        !           274:         //
        !           275:         // Reset the FDC to start in a known state.
        !           276:         //
        !           277: 
        !           278:         Q117iResetFDC(TapeExtension);
        !           279: 
        !           280:         //
        !           281:         // Look for the tape drive at drive B then at drive D.  Since the PCN
        !           282:         // of each channel of the FDC is independant, the global 'pcn must be
        !           283:         // manually maintained when switching between channels.  We can assume
        !           284:         // that the drive has been found (i.e. we can communicate) when we get
        !           285:         // any response except communication errors (DriveFlt or CmdFlt).
        !           286:         //
        !           287: 
        !           288:         Q117iSleep(TapeExtension, mt_wt001s, FALSE);
        !           289: 
        !           290:         for (i = 0; i < FIND_RETRIES; i++) {
        !           291: 
        !           292:             TapeExtension->DriveParms.Flavor = UNKNOWN;
        !           293:             Q117iResetFDC(TapeExtension);
        !           294:             retval = Q117iLookForDrive(TapeExtension, DRIVEU, TRUE);
        !           295: 
        !           296:             if (retval != DriveFlt && retval != CmdFlt) {
        !           297: 
        !           298:                 break;
        !           299: 
        !           300:             }
        !           301: 
        !           302:             TapeExtension->DriveParms.Flavor = CMS;
        !           303:             Q117iResetFDC(TapeExtension);
        !           304:             retval = Q117iLookForDrive(TapeExtension, DRIVEU, TRUE);
        !           305: 
        !           306:             if (retval != DriveFlt && retval != CmdFlt) {
        !           307: 
        !           308:                 break;
        !           309: 
        !           310:             }
        !           311: 
        !           312:             TapeExtension->DriveParms.Flavor = SUMMIT;
        !           313:             Q117iResetFDC(TapeExtension);
        !           314:             retval = Q117iLookForDrive(TapeExtension, DRIVEU, TRUE);
        !           315: 
        !           316:             if (retval != DriveFlt && retval != CmdFlt) {
        !           317: 
        !           318:                 break;
        !           319: 
        !           320:             }
        !           321: 
        !           322:             TapeExtension->DriveParms.Flavor = UNKNOWN;
        !           323:             Q117iResetFDC(TapeExtension);
        !           324:             retval = Q117iLookForDrive(TapeExtension, DRIVEB, TRUE);
        !           325: 
        !           326:             if (retval != DriveFlt && retval != CmdFlt) {
        !           327: 
        !           328:                 break;
        !           329: 
        !           330:             }
        !           331: 
        !           332:             Q117iResetFDC(TapeExtension);
        !           333:             retval = Q117iLookForDrive(TapeExtension, DRIVED, TRUE);
        !           334: 
        !           335:             if (retval != DriveFlt && retval != CmdFlt) {
        !           336: 
        !           337:                 break;
        !           338: 
        !           339:             }
        !           340: 
        !           341:             TapeExtension->DriveParms.Flavor = UNKNOWN;
        !           342:             Q117iResetFDC(TapeExtension);
        !           343:             retval = Q117iLookForDrive(TapeExtension, DRIVEUB, TRUE);
        !           344: 
        !           345:             if (retval != DriveFlt && retval != CmdFlt) {
        !           346: 
        !           347:                 break;
        !           348: 
        !           349:             }
        !           350: 
        !           351:             TapeExtension->DriveParms.Flavor = CMS;
        !           352:             Q117iResetFDC(TapeExtension);
        !           353:             retval = Q117iLookForDrive(TapeExtension, DRIVEUB, TRUE);
        !           354: 
        !           355:             if (retval != DriveFlt && retval != CmdFlt) {
        !           356: 
        !           357:                 break;
        !           358: 
        !           359:             }
        !           360: 
        !           361:             TapeExtension->DriveParms.Flavor = SUMMIT;
        !           362:             Q117iResetFDC(TapeExtension);
        !           363:             retval = Q117iLookForDrive(TapeExtension, DRIVEUB, TRUE);
        !           364: 
        !           365:             if (retval != DriveFlt && retval != CmdFlt) {
        !           366: 
        !           367:                 break;
        !           368: 
        !           369:             }
        !           370: 
        !           371:             Q117iSleep(TapeExtension, mt_wt001s, FALSE);
        !           372: 
        !           373:         }
        !           374: 
        !           375:         //
        !           376:         // Sort out the results of the drive address search.  A DriveFlt or a
        !           377:         // CmdFlt indicate that we could never successfully communicate with
        !           378:         // the tape drive at either address so we must assume that there is
        !           379:         // no tape drive present. A NECFlt indicates that we had serious
        !           380:         // trouble talking to the FDC so we must assume that it is either
        !           381:         // broken or not there.  The last thing to consider here is a TapeFlt.
        !           382:         // If the TapeFlt indicates either a hardware or software reset it is
        !           383:         // save to continue and the error can be ignored (since we must be
        !           384:         // starting a tape session neither of these errors should bother us).
        !           385:         // If the TapeFlt indicates any other error, it probably means some
        !           386:         // badness has happened.
        !           387:         //
        !           388: 
        !           389:         switch (retval) {
        !           390: 
        !           391:         case DriveFlt:
        !           392:         case CmdFlt:
        !           393:                 CheckedDump(QIC117INFO,( "Q117i: DLocateDrv Failed %d (decimal)\n", NoDrive));
        !           394:                 return(NoDrive);
        !           395: 
        !           396:         case NECFlt:
        !           397:                 CheckedDump(QIC117INFO,( "Q117i: DLocateDrv Failed %d (decimal)\n", NoFDC));
        !           398:                 return(NoFDC);
        !           399: 
        !           400:         case NotRdy:
        !           401:         case InvalCmd:
        !           402:                 retval = NoErr;
        !           403:                 break;
        !           404: 
        !           405:         case TapeFlt:
        !           406: 
        !           407:                 if (TapeExtension->FirmwareError == Swre_Reset ||
        !           408:                     TapeExtension->FirmwareError == Pwr_On_Reset ||
        !           409:                     TapeExtension->FirmwareError == Inval_Media ||
        !           410:                     TapeExtension->FirmwareError == Wtchdog_Reset) {
        !           411: 
        !           412:                     retval = NoErr;
        !           413: 
        !           414:                     break;
        !           415: 
        !           416:                 }
        !           417: 
        !           418:                 if (TapeExtension->FirmwareError == Xmit_Overrun) {
        !           419: 
        !           420:                     retval = NoDrive;
        !           421: 
        !           422:                 }
        !           423: 
        !           424:                 CheckedDump(QIC117INFO,( "Q117i: DLocateDrv Failed %d (decimal)\n", retval));
        !           425:                 return(retval);
        !           426: 
        !           427:         default:
        !           428:                 break;
        !           429: 
        !           430:         }
        !           431:     }
        !           432: 
        !           433: #if DBG
        !           434: 
        !           435:     if (retval) {
        !           436: 
        !           437:         CheckedDump(QIC117INFO,( "Q117i: DLocateDrv Failed %d (decimal)\n", retval));
        !           438: 
        !           439:     }
        !           440: 
        !           441: #endif
        !           442: 
        !           443:    return retval;
        !           444: }
        !           445: 
        !           446: 
        !           447: STATUS
        !           448: Q117iClearTapeError(
        !           449:     IN PTAPE_EXTENSION TapeExtension
        !           450:     )
        !           451: 
        !           452: /*++
        !           453: 
        !           454: Routine Description:
        !           455: 
        !           456:     To correct errors in the Jumbo B drive and firmware version 63.
        !           457: 
        !           458:     This piece of code added due to the face that the Jumbo B drives with
        !           459:     firmware 63 have a bug where you put a tape in very slowly, they sense
        !           460:     that they have a tape and engage the motor before the tape is actually
        !           461:     in. It may also cause the drive to think that the tape is write protected
        !           462:     when it actually is not. Sending it the New tape command causes it to go
        !           463:     through the tape loading sequence and fixes these 2 bugs.
        !           464: 
        !           465: Arguments:
        !           466: 
        !           467:     TapeExtension -
        !           468: 
        !           469: Return Value:
        !           470: 
        !           471: 
        !           472: 
        !           473: --*/
        !           474: 
        !           475: {
        !           476:     STATUS retval;
        !           477: 
        !           478:     //
        !           479:     // Send the NewTape command, and then clear the error byte.
        !           480:     //
        !           481: 
        !           482:     if ((retval = Q117iSendByte(TapeExtension, New_Tape)) == NoErr) {
        !           483: 
        !           484:         retval = Q117iWaitCommandComplete(TapeExtension, mt_wt150s);
        !           485: 
        !           486:     }
        !           487: 
        !           488:     return(retval);
        !           489: }
        !           490: 
        !           491: 
        !           492: STATUS
        !           493: Q117iLookForDrive(
        !           494:     IN PTAPE_EXTENSION TapeExtension,
        !           495:     IN UCHAR DriveSelector,
        !           496:     IN BOOLEAN WaitForTape
        !           497:     )
        !           498: /*++
        !           499: 
        !           500: Routine Description:
        !           501: 
        !           502: 
        !           503: 
        !           504: Arguments:
        !           505: 
        !           506:     TapeExtension -
        !           507: 
        !           508:     DriveSelector -
        !           509: 
        !           510: Return Value:
        !           511: 
        !           512: 
        !           513: 
        !           514: --*/
        !           515: 
        !           516: {
        !           517:     STATUS retval;     // Return value
        !           518: 
        !           519:     //
        !           520:     // Set the drive select parameters according to the desired target drive
        !           521:     // selector.
        !           522:     //
        !           523: 
        !           524:     switch (DriveSelector) {
        !           525: 
        !           526:     case DRIVEB:
        !           527:         TapeExtension->QControllerData->DriveSelect.SelectByte = selb;
        !           528:         TapeExtension->QControllerData->DriveSelect.DeselectByte = dselb;
        !           529:         TapeExtension->DriveParms.DriveSelect = curb;
        !           530:         break;
        !           531: 
        !           532:     case DRIVED:
        !           533:         TapeExtension->QControllerData->DriveSelect.SelectByte = seld;
        !           534:         TapeExtension->QControllerData->DriveSelect.DeselectByte = dseld;
        !           535:         TapeExtension->DriveParms.DriveSelect = curd;
        !           536:         break;
        !           537: 
        !           538:     case DRIVEU:
        !           539:         TapeExtension->QControllerData->DriveSelect.SelectByte = selu;
        !           540:         TapeExtension->QControllerData->DriveSelect.DeselectByte = dselu;
        !           541:         TapeExtension->DriveParms.DriveSelect = curu;
        !           542:         break;
        !           543: 
        !           544:     case DRIVEUB:
        !           545:         TapeExtension->QControllerData->DriveSelect.SelectByte = selub;
        !           546:         TapeExtension->QControllerData->DriveSelect.DeselectByte = dselub;
        !           547:         TapeExtension->DriveParms.DriveSelect = curub;
        !           548:         break;
        !           549: 
        !           550:     }
        !           551: 
        !           552:     //
        !           553:     // Try to communicate with the tape drive by requesting drive status.
        !           554:     // If we can successfully communicate with the drive, wait up to the
        !           555:     // approximate maximum autoload time (150 seconds) for the tape drive
        !           556:     // to become ready. This should cover a new tape being inserted
        !           557:     // immediatley before starting a tape session.
        !           558:     //
        !           559: 
        !           560:     if ((retval = Q117iSelectDrive(TapeExtension)) == NoErr) {
        !           561: 
        !           562:         if (WaitForTape) {
        !           563:             retval = Q117iWaitCommandComplete(TapeExtension, mt_wt460s);
        !           564:         } else {
        !           565:             retval = Q117iGetDriveError(TapeExtension);
        !           566:         }
        !           567: 
        !           568:         Q117iDeselectDrive(TapeExtension);
        !           569: 
        !           570:     }
        !           571: 
        !           572:     return(retval);
        !           573: }
        !           574: 
        !           575: STATUS
        !           576: Q117iGetDriveType(
        !           577:     IN PTAPE_EXTENSION TapeExtension
        !           578:     )
        !           579: 
        !           580: /*++
        !           581: 
        !           582: Routine Description:
        !           583: 
        !           584:     Determine what flavor tape drive the drive is talking to. Specifically,
        !           585:     is the current drive a CMS drive or a non-CMS drive.
        !           586: 
        !           587: Arguments:
        !           588: 
        !           589:     TapeExtension -
        !           590: 
        !           591: Return Value:
        !           592: 
        !           593: 
        !           594: 
        !           595: --*/
        !           596: 
        !           597: {
        !           598: 
        !           599:     STATUS retval;           // return value
        !           600:     USHORT vendorId = 0;    // vendor id number from tape drive
        !           601:     UCHAR signature;
        !           602:     BOOLEAN reportFailed=FALSE;
        !           603:     struct CmsStatus cmsStatus;
        !           604: 
        !           605:     //
        !           606:     // Assume that the tape drive is not a CMS drive and get the ROM version
        !           607:     // number.
        !           608:     //
        !           609: 
        !           610:     if ((retval = Q117iReport(
        !           611:                         TapeExtension,
        !           612:                         Report_ROM,
        !           613:                         (USHORT *)&TapeExtension->DriveParms.Version,
        !           614:                         READ_BYTE, NULL)) != NoErr) {
        !           615: 
        !           616:         return(retval);
        !           617: 
        !           618:     }
        !           619: 
        !           620:     CheckedDump(QIC117INFO,( "Q117i: FW Version %x\n", TapeExtension->DriveParms.Version));
        !           621: 
        !           622:     if ((retval = Q117iSendByte(TapeExtension, Report_Vendor32)) !=
        !           623:         NoErr) {
        !           624: 
        !           625:         return(retval);
        !           626: 
        !           627:     }
        !           628: 
        !           629:     if ((retval = Q117iReceiveByte(
        !           630:                         TapeExtension,
        !           631:                         READ_WORD,
        !           632:                         (USHORT *)&vendorId)) != NoErr) {
        !           633: 
        !           634:         Q117iGetDriveError(TapeExtension);
        !           635: 
        !           636:         if ((retval = Q117iSendByte(TapeExtension, Report_Vendor32)) !=
        !           637:             NoErr) {
        !           638: 
        !           639:             return(retval);
        !           640: 
        !           641:         }
        !           642: 
        !           643:         if ((retval = Q117iReceiveByte(
        !           644:                             TapeExtension,
        !           645:                             READ_BYTE,
        !           646:                             (USHORT *)&vendorId)) != NoErr) {
        !           647: 
        !           648:             Q117iGetDriveError(TapeExtension);
        !           649: 
        !           650:             if ((retval = Q117iSendByte(TapeExtension, Report_Vendor)) !=
        !           651:                 NoErr) {
        !           652: 
        !           653:                 return(retval);
        !           654: 
        !           655:             }
        !           656: 
        !           657:             if ((retval = Q117iReceiveByte(
        !           658:                                 TapeExtension,
        !           659:                                 READ_BYTE,
        !           660:                                 (USHORT *)&vendorId)) != NoErr) {
        !           661: 
        !           662:                 Q117iGetDriveError(TapeExtension);
        !           663:                 retval = NoErr;
        !           664:                 reportFailed = TRUE;
        !           665:                 CheckedDump(QIC117INFO,( "Q117i: Report Vendor ID Failed\n"));
        !           666: 
        !           667:             }
        !           668: 
        !           669:         }
        !           670: 
        !           671:     }
        !           672: 
        !           673:     CheckedDump(QIC117INFO,( "Q117i: Vendor ID %x\n", vendorId));
        !           674: 
        !           675:     if (vendorId == CMS_VEND_NO || reportFailed) {
        !           676: 
        !           677:         if ((retval = Q117iSetDriveMode(TapeExtension, DIAGNOSTIC_1_MODE)) !=
        !           678:             NoErr) {
        !           679: 
        !           680:             return(retval);
        !           681: 
        !           682:         }
        !           683: 
        !           684:         if ((retval = Q117iSendByte(TapeExtension, Rpt_Signature)) != NoErr) {
        !           685: 
        !           686:             return(retval);
        !           687: 
        !           688:         }
        !           689: 
        !           690:         if ((retval = Q117iReceiveByte(
        !           691:                         TapeExtension,
        !           692:                         READ_BYTE,
        !           693:                         (USHORT *)&signature)) != NoErr) {
        !           694: 
        !           695:             Q117iGetDriveError(TapeExtension);
        !           696:             retval = NoErr;
        !           697: 
        !           698:         }
        !           699: 
        !           700:         retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE);
        !           701: 
        !           702:         if (retval != NoErr && retval != NoTape) {
        !           703: 
        !           704:             return(retval);
        !           705: 
        !           706:         }
        !           707: 
        !           708:     }
        !           709: 
        !           710:     CheckedDump(QIC117INFO,( "Q117i: Signature %x\n", signature));
        !           711: 
        !           712:     if (vendorId == CMS_VEND_NO) {
        !           713: 
        !           714:         if (signature == CMS_SIG) {
        !           715: 
        !           716:             // Issue the Rpt_cmsStatus command to determine if the drive
        !           717:             // is an IOMEGA.
        !           718: 
        !           719:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !           720:                                             DIAGNOSTIC_1_MODE)) != NoErr) {
        !           721: 
        !           722:                 return(retval);
        !           723: 
        !           724:             }
        !           725: 
        !           726:             if ((retval = Q117iReport(
        !           727:                             TapeExtension,
        !           728:                             Rpt_CMS_Status,
        !           729:                             (USHORT *)&cmsStatus,
        !           730:                             READ_BYTE,
        !           731:                             NULL)) != NoErr) {
        !           732: 
        !           733:                 if ( TapeExtension->DriveParms.Version >= FIRM_VERSION_63 ) {
        !           734: 
        !           735:                     TapeExtension->DriveParms.Flavor = IOMEGA;
        !           736:                     CheckedDump(QIC117INFO,( "Q117i: Drive Vendor IOMEGA\n"));
        !           737: 
        !           738:                 } else {
        !           739: 
        !           740:                     TapeExtension->DriveParms.Flavor = CMS;
        !           741:                     CheckedDump(QIC117INFO,( "Q117i: Drive Vendor CMS\n"));
        !           742: 
        !           743:                 }
        !           744:                 Q117iGetDriveError(TapeExtension);
        !           745:                 retval = NoErr;
        !           746: 
        !           747:             } else {
        !           748: 
        !           749:                 TapeExtension->DriveParms.Flavor = CMS;
        !           750:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor CMS\n"));
        !           751: 
        !           752:             }
        !           753: 
        !           754:             //
        !           755:             // Put drive back into its original mode.
        !           756:             //
        !           757: 
        !           758:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !           759:                                             PRIMARY_MODE)) != NoErr) {
        !           760: 
        !           761:                 return(retval);
        !           762: 
        !           763:             }
        !           764: 
        !           765: 
        !           766:         } else {
        !           767: 
        !           768:             TapeExtension->DriveParms.Flavor = UNSUPPORTED;
        !           769:             CheckedDump(QIC117INFO,( "Q117i: Drive Vendor UNSUPPORTED\n"));
        !           770: 
        !           771:         }
        !           772: 
        !           773:     } else {
        !           774: 
        !           775:         if (vendorId == ARCHIVE_VEND_NO_OLD) {
        !           776: 
        !           777:             TapeExtension->DriveParms.Flavor = ARCHIVE;
        !           778:             CheckedDump(QIC117INFO,( "Q117i: Drive Vendor ARCHIVE (old version)\n"));
        !           779: 
        !           780:         } else {
        !           781: 
        !           782:             switch (vendorId & VENDOR_MASK) {
        !           783:             case SUMMIT_VEND_NO:
        !           784:                 TapeExtension->DriveParms.Flavor = SUMMIT;
        !           785:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor SUMMIT\n"));
        !           786:                 break;
        !           787: 
        !           788:             case IOMEGA_VEND_NO:
        !           789:                 TapeExtension->DriveParms.Flavor = IOMEGA;
        !           790:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor IOMEGA\n"));
        !           791:                 break;
        !           792: 
        !           793:             case WANGTEK_VEND_NO:
        !           794:                 TapeExtension->DriveParms.Flavor = WANGTEK;
        !           795:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor WANGTEK\n"));
        !           796:                 break;
        !           797: 
        !           798:             case CORE_VEND_NO:
        !           799:                 TapeExtension->DriveParms.Flavor = CORE;
        !           800:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor CORE\n"));
        !           801:                 break;
        !           802: 
        !           803:             case ARCHIVE_VEND_NO_NEW:
        !           804:                 TapeExtension->DriveParms.Flavor = ARCHIVE;
        !           805:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor ARCHIVE (new version)\n"));
        !           806:                 break;
        !           807: 
        !           808:             default:
        !           809:                 TapeExtension->DriveParms.Flavor = UNSUPPORTED;
        !           810:                 CheckedDump(QIC117INFO,( "Q117i: Drive Vendor UNSUPPORTED\n"));
        !           811: 
        !           812:                 if (reportFailed && (signature == CMS_SIG)) {
        !           813:                     TapeExtension->DriveParms.Flavor = CMS_ENHANCEMENTS;
        !           814:                     CheckedDump(QIC117INFO,( "Q117i: Drive Vendor CMS_ENHANCEMENTS\n"));
        !           815:                 }
        !           816:                 if (reportFailed && (signature != CMS_SIG)) {
        !           817:                     TapeExtension->DriveParms.Flavor = WANGTEK;
        !           818:                     CheckedDump(QIC117INFO,( "Q117i: Drive Vendor WANGTEK\n"));
        !           819:                 }
        !           820:             }
        !           821:         }
        !           822:     }
        !           823: 
        !           824:     //
        !           825:     // Get the miscellaneous drive train information from the drive
        !           826:     //
        !           827: 
        !           828:     if ((retval = Q117iGetDriveInfo(TapeExtension)) != NoErr) {
        !           829: 
        !           830:         CheckedDump(QIC117INFO,( "Q117i: GetDriveInfo Failed %d (decimal)\n", retval));
        !           831:         return(retval);
        !           832: 
        !           833:     }
        !           834: 
        !           835:     if ((retval = Q117iGetDriveSize(
        !           836:                 TapeExtension,
        !           837:                 reportFailed,
        !           838:                 vendorId,
        !           839:                 signature)) != NoErr) {
        !           840: 
        !           841:         CheckedDump(QIC117INFO,( "Q117i: GetDriveSize Failed %d (decimal)\n", retval));
        !           842:         return(retval);
        !           843: 
        !           844:     }
        !           845: 
        !           846:     q117iUpdateRegistryInfo( TapeExtension );
        !           847: 
        !           848:     return(retval);
        !           849: }
        !           850: 
        !           851: 
        !           852: STATUS
        !           853: Q117iGetDriveSize(
        !           854:     IN PTAPE_EXTENSION TapeExtension,
        !           855:     IN BOOLEAN ReportFailed,
        !           856:     IN USHORT VendorId,
        !           857:     IN UCHAR Signature
        !           858:     )
        !           859: 
        !           860: /*++
        !           861: 
        !           862: Routine Description:
        !           863: 
        !           864:     Determine the size of the tape drive (QIC40 or QIC80).
        !           865: 
        !           866:     To determine the drive type, an attempt is made to set the drive to
        !           867:     250Kbs speed. If the drive is a QIC40 this is a valid speed. If the drive
        !           868:     is a QIC80 this is an invalid speed and an error is returned.
        !           869: 
        !           870: 
        !           871: 
        !           872: Arguments:
        !           873: 
        !           874:     TapeExtension -
        !           875: 
        !           876: Return Value:
        !           877: 
        !           878: 
        !           879: 
        !           880: --*/
        !           881: 
        !           882: {
        !           883:     STATUS retval=NoErr;
        !           884:     struct DriveConfiguration driveConfig;
        !           885:     struct CmsStatus cmsStatus;
        !           886:     CHAR orgMode;
        !           887:          USHORT manDate=0;
        !           888: 
        !           889:     TapeExtension->DriveParms.ArchiveNativeMode = 0;
        !           890:     TapeExtension->DriveParms.SeekMode = SEEK_TIMED;
        !           891: 
        !           892:     switch (TapeExtension->DriveParms.Flavor) {
        !           893: 
        !           894:     case CMS:
        !           895: 
        !           896:         TapeExtension->SpeedChangeOK = TRUE;
        !           897:         TapeExtension->PegasusSupported = FALSE;
        !           898: 
        !           899:         if (TapeExtension->DriveParms.Version >= FIRM_VERSION_60) {
        !           900: 
        !           901:             TapeExtension->DriveParms.SeekMode = SEEK_SKIP;
        !           902: 
        !           903:             if (TapeExtension->DriveParms.Version >= FIRM_VERSION_87) {
        !           904: 
        !           905:                 TapeExtension->DriveParms.SeekMode = SEEK_SKIP_EXTENDED;
        !           906: 
        !           907:             }
        !           908: 
        !           909:         }
        !           910: 
        !           911:         if (TapeExtension->DriveParms.Version < FIRM_VERSION_110) {
        !           912: 
        !           913:             if ((retval = Q117iSendByte(TapeExtension, Select_Speed)) == NoErr) {
        !           914: 
        !           915:                 Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !           916: 
        !           917:                 if ((retval = Q117iSendByte(TapeExtension, TAPE_250Kbps + 2)) ==
        !           918:                     NoErr) {
        !           919: 
        !           920:                     retval = Q117iWaitCommandComplete(TapeExtension, mt_wt010s);
        !           921: 
        !           922:                     if (retval == NoErr) {
        !           923: 
        !           924:                         TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !           925:                         CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !           926: 
        !           927:                     } else if (retval == UnspRate) {
        !           928: 
        !           929:                         TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !           930:                         CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !           931:                         retval = NoErr;
        !           932: 
        !           933:                     }
        !           934:                 }
        !           935:             }
        !           936: 
        !           937:         } else {
        !           938: 
        !           939:             // For versions of 110 and greater, the drive type may be QIC500.
        !           940:             // Let's just issue the Rpt_cmsStatus command.
        !           941: 
        !           942:             orgMode = TapeExtension->DriveParms.Mode;
        !           943: 
        !           944:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !           945:                                             DIAGNOSTIC_1_MODE)) != NoErr) {
        !           946: 
        !           947:                 return(retval);
        !           948: 
        !           949:             }
        !           950: 
        !           951:             if ((retval = Q117iReport(
        !           952:                             TapeExtension,
        !           953:                             Rpt_CMS_Status,
        !           954:                             (USHORT *)&cmsStatus,
        !           955:                             READ_BYTE,
        !           956:                             NULL)) != NoErr) {
        !           957: 
        !           958:                 return(retval);
        !           959: 
        !           960:             }
        !           961: 
        !           962:             //
        !           963:             // Put drive back into its original mode.
        !           964:             //
        !           965: 
        !           966:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !           967:                                             PRIMARY_MODE)) != NoErr) {
        !           968: 
        !           969:                 return(retval);
        !           970: 
        !           971:             }
        !           972: 
        !           973:             if (orgMode != PRIMARY_MODE) {
        !           974: 
        !           975:                 if ((retval = Q117iSetDriveMode(TapeExtension,
        !           976:                                                 orgMode)) != NoErr) {
        !           977: 
        !           978:                     return(retval);
        !           979: 
        !           980:                 }
        !           981:             }
        !           982: 
        !           983:             if (!cmsStatus.DriveType) {
        !           984: 
        !           985:                 // If drive type is QIC80, the drive_type bit is set low
        !           986:                 // and the eagle bit is high.
        !           987: 
        !           988:                 if (!cmsStatus.Eagle) {
        !           989: 
        !           990:                     TapeExtension->DriveParms.DriveType = QIC500_DRIVE;
        !           991:                     CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC500_DRIVE\n"));
        !           992: 
        !           993:                 } else {
        !           994: 
        !           995:                     // Drive Type is QIC80
        !           996: 
        !           997:                     TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !           998:                     CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !           999: 
        !          1000:                 }
        !          1001: 
        !          1002:             } else {
        !          1003: 
        !          1004:                  // It must be a QIC40 Drive
        !          1005: 
        !          1006:                  TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1007:                  CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1008: 
        !          1009:             }
        !          1010:         }
        !          1011: 
        !          1012:         manDate = (UBYTE)TapeExtension->MiscDriveInfo.ManDate[0];
        !          1013:         manDate <<= 8;
        !          1014:         manDate |= (UBYTE)TapeExtension->MiscDriveInfo.ManDate[1];
        !          1015: 
        !          1016:         CheckedDump(QIC117INFO,( "Q117i: CMS Manufacture Date %d (decimal)\n",
        !          1017:             manDate));
        !          1018: 
        !          1019:         if ((TapeExtension->DriveParms.Version >= FIRM_VERSION_87) &&
        !          1020:             (manDate >= PEGASUS_START_DATE) &&
        !          1021:                                 (TapeExtension->DriveParms.DriveType != QIC40_DRIVE)) {
        !          1022: 
        !          1023:             CheckedDump(QIC117INFO,( "Q117i: Pegasus Drive Supported (CMS)\n"));
        !          1024:             TapeExtension->PegasusSupported = TRUE;
        !          1025: 
        !          1026:         }
        !          1027:         break;
        !          1028: 
        !          1029:     case SUMMIT:
        !          1030: 
        !          1031:         TapeExtension->DriveParms.SeekMode = SEEK_SKIP;
        !          1032: 
        !          1033:         if ((retval = Q117iSendByte(TapeExtension, Select_Speed)) == NoErr) {
        !          1034: 
        !          1035:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          1036: 
        !          1037:             if ((retval = Q117iSendByte(TapeExtension, (TAPE_1Mbps + 2))) == NoErr) {
        !          1038: 
        !          1039:                 retval = Q117iWaitCommandComplete(TapeExtension, mt_wt010s);
        !          1040: 
        !          1041:                 if (retval == NoErr) {
        !          1042: 
        !          1043:                     if ((retval = Q117iReport(TapeExtension,
        !          1044:                                             Report_Confg,
        !          1045:                                             (USHORT *)&driveConfig,
        !          1046:                                             READ_BYTE,
        !          1047:                                             NULL))
        !          1048:                                             == NoErr) {
        !          1049: 
        !          1050:                         if (driveConfig.XferRate == TAPE_1Mbps) {
        !          1051: 
        !          1052:                             TapeExtension->SpeedChangeOK = TRUE;
        !          1053:                             TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1054:                             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !          1055: 
        !          1056:                         } else {
        !          1057: 
        !          1058:                             TapeExtension->SpeedChangeOK = FALSE;
        !          1059:                             TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1060:                             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1061: 
        !          1062:                         }
        !          1063: 
        !          1064:                     }
        !          1065: 
        !          1066:                 } else if (retval == UnspRate) {
        !          1067: 
        !          1068:                     TapeExtension->SpeedChangeOK = FALSE;
        !          1069:                     TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1070:                     CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1071:                     retval = NoErr;
        !          1072: 
        !          1073:                 }
        !          1074:             }
        !          1075:         }
        !          1076: 
        !          1077:         break;
        !          1078: 
        !          1079:     case WANGTEK:
        !          1080: 
        !          1081:         TapeExtension->DriveParms.SeekMode = SEEK_SKIP;
        !          1082: 
        !          1083:         if (!ReportFailed &&
        !          1084:             ((VendorId & ~VENDOR_MASK) == WANGTEK_QIC80)) {
        !          1085: 
        !          1086:             TapeExtension->SpeedChangeOK = TRUE;
        !          1087:             TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1088:             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !          1089: 
        !          1090:         } else {
        !          1091: 
        !          1092:             TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1093:             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1094: 
        !          1095:         }
        !          1096:         break;
        !          1097: 
        !          1098:     case CORE:
        !          1099: 
        !          1100:         if ((VendorId & ~VENDOR_MASK) == CORE_QIC80) {
        !          1101: 
        !          1102:             TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1103:             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !          1104: 
        !          1105:         } else {
        !          1106: 
        !          1107:             TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1108:             CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1109: 
        !          1110:         }
        !          1111:         break;
        !          1112: 
        !          1113:     case IOMEGA:
        !          1114: 
        !          1115:         TapeExtension->DriveParms.SeekMode = SEEK_SKIP;
        !          1116:         TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1117:         TapeExtension->SpeedChangeOK = TRUE;
        !          1118:         CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !          1119:         break;
        !          1120: 
        !          1121:     case ARCHIVE:
        !          1122: 
        !          1123:         TapeExtension->DriveParms.SeekMode = SEEK_SKIP;
        !          1124: 
        !          1125:         if ((retval = Q117iSetDriveMode(TapeExtension, DIAGNOSTIC_1_MODE)) !=
        !          1126:             NoErr) {
        !          1127: 
        !          1128:             return(retval);
        !          1129: 
        !          1130:         }
        !          1131: 
        !          1132:         retval = Q117iGetDriveError(TapeExtension);
        !          1133: 
        !          1134:         if (retval == NoErr || retval == NoTape) {
        !          1135: 
        !          1136:             if ((retval = Q117iSendByte(TapeExtension, Rpt_Archive_Native_Mode)) != NoErr) {
        !          1137: 
        !          1138:                 return(retval);
        !          1139: 
        !          1140:             }
        !          1141: 
        !          1142:             if ((retval = Q117iReceiveByte(
        !          1143:                             TapeExtension,
        !          1144:                             READ_WORD,
        !          1145:                             (USHORT *)&TapeExtension->DriveParms.ArchiveNativeMode
        !          1146:                             )) == NoErr) {
        !          1147: 
        !          1148:                 TapeExtension->SpeedChangeOK = TRUE;
        !          1149: 
        !          1150:                 CheckedDump(QIC117INFO,( "Q117i: Archive Native Mode = %x)\n",
        !          1151:                     TapeExtension->DriveParms.ArchiveNativeMode));
        !          1152: 
        !          1153:                 if ((TapeExtension->DriveParms.ArchiveNativeMode &
        !          1154:                         ARCHIVE_MODEL_XKEII) != 0) {
        !          1155: 
        !          1156:                     TapeExtension->DriveParms.SeekMode = SEEK_SKIP_EXTENDED;
        !          1157: 
        !          1158:                 }
        !          1159: 
        !          1160:                 if ((TapeExtension->DriveParms.ArchiveNativeMode &
        !          1161:                         ARCHIVE_20_TRACK) != 0) {
        !          1162: 
        !          1163:                     TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1164:                     CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE (Archive Native Mode)\n"));
        !          1165: 
        !          1166:                 }
        !          1167: 
        !          1168:                 if ((TapeExtension->DriveParms.ArchiveNativeMode &
        !          1169:                         ARCHIVE_28_TRACK) != 0) {
        !          1170: 
        !          1171:                     TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1172:                     CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE (Archive Native Mode)\n"));
        !          1173: 
        !          1174:                 }
        !          1175: 
        !          1176:                 retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE);
        !          1177: 
        !          1178:                 if (retval != NoErr && retval != NoTape) {
        !          1179: 
        !          1180:                     return(retval);
        !          1181: 
        !          1182:                 }
        !          1183: 
        !          1184:             }
        !          1185: 
        !          1186:         } else {
        !          1187: 
        !          1188:             if (retval == InvalCmd) {
        !          1189: 
        !          1190:                 if ((retval = Q117iSendByte(TapeExtension, Soft_Reset)) == NoErr) {
        !          1191: 
        !          1192:                     Q117iSleep(TapeExtension, (mt_wt001s + mt_wt2ticks), FALSE);
        !          1193: 
        !          1194:                     if ((retval = Q117iSelectDrive(TapeExtension)) == NoErr) {
        !          1195: 
        !          1196:                         if ((retval = Q117iReport(
        !          1197:                                             TapeExtension,
        !          1198:                                             Report_Confg,
        !          1199:                                             (USHORT *)&driveConfig,
        !          1200:                                             READ_BYTE,
        !          1201:                                             NULL)) == NoErr) {
        !          1202: 
        !          1203:                             if (driveConfig.QIC80) {
        !          1204: 
        !          1205:                                 TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1206:                                 CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE (Archive Soft Reset)\n"));
        !          1207: 
        !          1208:                             } else {
        !          1209: 
        !          1210:                                 TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1211:                                 CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE (Archive Soft Reset)\n"));
        !          1212: 
        !          1213:                             }
        !          1214:                         }
        !          1215:                     }
        !          1216:                 }
        !          1217: 
        !          1218:             } else {
        !          1219: 
        !          1220:                 return(retval);
        !          1221: 
        !          1222:             }
        !          1223:         }
        !          1224: 
        !          1225: 
        !          1226:         break;
        !          1227: 
        !          1228:     default:
        !          1229: 
        !          1230:         if ((retval = Q117iSendByte(TapeExtension, Soft_Reset)) == NoErr) {
        !          1231: 
        !          1232:             Q117iSleep(TapeExtension, (mt_wt001s + mt_wt2ticks), FALSE);
        !          1233: 
        !          1234:             if ((retval = Q117iSelectDrive(TapeExtension)) == NoErr) {
        !          1235: 
        !          1236:                 if ((retval = Q117iReport(
        !          1237:                                     TapeExtension,
        !          1238:                                     Report_Confg,
        !          1239:                                     (USHORT *)&driveConfig,
        !          1240:                                     READ_BYTE,
        !          1241:                                     NULL)) == NoErr) {
        !          1242: 
        !          1243:                     if (driveConfig.QIC80) {
        !          1244: 
        !          1245:                         TapeExtension->DriveParms.DriveType = QIC80_DRIVE;
        !          1246:                         CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC80_DRIVE\n"));
        !          1247: 
        !          1248:                     } else {
        !          1249: 
        !          1250:                         TapeExtension->DriveParms.DriveType = QIC40_DRIVE;
        !          1251:                         CheckedDump(QIC117INFO,( "Q117i: Drive Type QIC40_DRIVE\n"));
        !          1252: 
        !          1253:                     }
        !          1254:                 }
        !          1255:             }
        !          1256:         }
        !          1257:     }
        !          1258: 
        !          1259:     return(retval);
        !          1260: }
        !          1261: 
        !          1262: VOID
        !          1263: q117iUpdateRegistryInfo(
        !          1264:     IN PTAPE_EXTENSION TapeExtension
        !          1265:     )
        !          1266: 
        !          1267: /*++
        !          1268: 
        !          1269: Routine Description:
        !          1270: 
        !          1271:     This function updates the devicemap.
        !          1272: 
        !          1273: Arguments:
        !          1274: 
        !          1275:     TapeExtension -
        !          1276: 
        !          1277: Return Value:
        !          1278: 
        !          1279:    Returns the status of the operation.
        !          1280: 
        !          1281: --*/
        !          1282: 
        !          1283: {
        !          1284:     HANDLE          lunKey;
        !          1285:     HANDLE          unitKey;
        !          1286:     UNICODE_STRING  ntUnicodeString;
        !          1287:     UNICODE_STRING  name;
        !          1288:     OBJECT_ATTRIBUTES objectAttributes;
        !          1289:     UNICODE_STRING string;
        !          1290:     UNICODE_STRING stringNum;
        !          1291:     WCHAR bufferNum[16];
        !          1292:     WCHAR buffer[64];
        !          1293:     NTSTATUS status;
        !          1294: 
        !          1295:     //
        !          1296:     // Create the Tape key in the device map.
        !          1297:     //
        !          1298: 
        !          1299:     RtlInitUnicodeString(
        !          1300:         &name,
        !          1301:         L"\\Registry\\Machine\\Hardware\\DeviceMap\\Tape"
        !          1302:         );
        !          1303: 
        !          1304:     //
        !          1305:     // Initialize the object for the key.
        !          1306:     //
        !          1307: 
        !          1308:     InitializeObjectAttributes( &objectAttributes,
        !          1309:                                 &name,
        !          1310:                                 OBJ_CASE_INSENSITIVE,
        !          1311:                                 NULL,
        !          1312:                                 (PSECURITY_DESCRIPTOR) NULL );
        !          1313: 
        !          1314:     //
        !          1315:     // Create the key or open it.
        !          1316:     //
        !          1317: 
        !          1318:     status = ZwOpenKey(&lunKey,
        !          1319:                         KEY_READ | KEY_WRITE,
        !          1320:                         &objectAttributes );
        !          1321: 
        !          1322:     if (!NT_SUCCESS(status)) {
        !          1323:         return;
        !          1324:     }
        !          1325: 
        !          1326:     //
        !          1327:     // Copy the Prefix into a string.
        !          1328:     //
        !          1329: 
        !          1330:     string.Length = 0;
        !          1331:     string.MaximumLength=64;
        !          1332:     string.Buffer = buffer;
        !          1333: 
        !          1334:     RtlInitUnicodeString(&stringNum,
        !          1335:         L"Unit ");
        !          1336: 
        !          1337:     RtlCopyUnicodeString(&string, &stringNum);
        !          1338: 
        !          1339:     //
        !          1340:     // Create a port number key entry.
        !          1341:     //
        !          1342: 
        !          1343:     stringNum.Length = 0;
        !          1344:     stringNum.MaximumLength = 16;
        !          1345:     stringNum.Buffer = bufferNum;
        !          1346: 
        !          1347:     CheckedDump(QIC117INFO,( "Q117i: Tape Device Number %d (decimal)\n", TapeExtension->TapeNumber));
        !          1348:     status = RtlIntegerToUnicodeString(TapeExtension->TapeNumber, 10, &stringNum);
        !          1349: 
        !          1350:     if (!NT_SUCCESS(status)) {
        !          1351:         return;
        !          1352:     }
        !          1353: 
        !          1354:     //
        !          1355:     // Append the prefix and the numeric name.
        !          1356:     //
        !          1357: 
        !          1358:     RtlAppendUnicodeStringToString(&string, &stringNum);
        !          1359: 
        !          1360:     InitializeObjectAttributes( &objectAttributes,
        !          1361:                                 &string,
        !          1362:                                 OBJ_CASE_INSENSITIVE,
        !          1363:                                 lunKey,
        !          1364:                                 (PSECURITY_DESCRIPTOR) NULL );
        !          1365: 
        !          1366:     status = ZwOpenKey(&unitKey,
        !          1367:                         KEY_READ | KEY_WRITE,
        !          1368:                         &objectAttributes );
        !          1369: 
        !          1370:     ZwClose(lunKey);
        !          1371: 
        !          1372:     switch (TapeExtension->DriveParms.Flavor) {
        !          1373: 
        !          1374:     case CMS:
        !          1375: 
        !          1376:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1377: 
        !          1378:             RtlInitUnicodeString(&ntUnicodeString,
        !          1379:                 L"Colorado Memory Systems Jumbo 250");
        !          1380: 
        !          1381:         } else {
        !          1382: 
        !          1383:             RtlInitUnicodeString(&ntUnicodeString,
        !          1384:                 L"Colorado Memory Systems Jumbo 120");
        !          1385: 
        !          1386:         }
        !          1387: 
        !          1388:         break;
        !          1389: 
        !          1390:     case SUMMIT:
        !          1391: 
        !          1392:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1393: 
        !          1394:             RtlInitUnicodeString(&ntUnicodeString,
        !          1395:                 L"Summit QIC-80 floppy tape drive");
        !          1396: 
        !          1397:         } else {
        !          1398: 
        !          1399:             RtlInitUnicodeString(&ntUnicodeString,
        !          1400:                 L"Summit QIC-40 floppy tape drive");
        !          1401: 
        !          1402:         }
        !          1403: 
        !          1404:         break;
        !          1405: 
        !          1406:     case WANGTEK:
        !          1407: 
        !          1408:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1409: 
        !          1410:             RtlInitUnicodeString(&ntUnicodeString,
        !          1411:                 L"Wangtek QIC-80 floppy tape drive");
        !          1412: 
        !          1413:         } else {
        !          1414: 
        !          1415:             RtlInitUnicodeString(&ntUnicodeString,
        !          1416:                 L"Wangtek QIC-40 floppy tape drive");
        !          1417: 
        !          1418:         }
        !          1419: 
        !          1420:         break;
        !          1421: 
        !          1422:     case CORE:
        !          1423: 
        !          1424:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1425: 
        !          1426:             RtlInitUnicodeString(&ntUnicodeString,
        !          1427:                 L"Core QIC-80 floppy tape drive");
        !          1428: 
        !          1429:         } else {
        !          1430: 
        !          1431:             RtlInitUnicodeString(&ntUnicodeString,
        !          1432:                 L"Core QIC-40 floppy tape drive");
        !          1433: 
        !          1434:         }
        !          1435: 
        !          1436:         break;
        !          1437: 
        !          1438:     case IOMEGA:
        !          1439: 
        !          1440:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1441: 
        !          1442:             RtlInitUnicodeString(&ntUnicodeString,
        !          1443:                 L"Iomega QIC-80 floppy tape drive");
        !          1444: 
        !          1445:         } else {
        !          1446: 
        !          1447:             RtlInitUnicodeString(&ntUnicodeString,
        !          1448:                 L"Iomega QIC-40 floppy tape drive");
        !          1449: 
        !          1450:         }
        !          1451: 
        !          1452:         break;
        !          1453: 
        !          1454:     case CMS_ENHANCEMENTS:
        !          1455: 
        !          1456:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1457: 
        !          1458:             RtlInitUnicodeString(&ntUnicodeString,
        !          1459:                 L"CMS Enhancements QIC-80 floppy tape drive");
        !          1460: 
        !          1461:         } else {
        !          1462: 
        !          1463:             RtlInitUnicodeString(&ntUnicodeString,
        !          1464:                 L"CMS Enhancements QIC-40 floppy tape drive");
        !          1465: 
        !          1466:         }
        !          1467: 
        !          1468:         break;
        !          1469: 
        !          1470:     case ARCHIVE:
        !          1471: 
        !          1472:         if (TapeExtension->DriveParms.DriveType == QIC80_DRIVE) {
        !          1473: 
        !          1474:             RtlInitUnicodeString(&ntUnicodeString,
        !          1475:                 L"Conner QIC-80 floppy tape drive");
        !          1476: 
        !          1477:         } else {
        !          1478: 
        !          1479:             RtlInitUnicodeString(&ntUnicodeString,
        !          1480:                 L"Conner QIC-40 floppy tape drive");
        !          1481: 
        !          1482:         }
        !          1483: 
        !          1484:         break;
        !          1485: 
        !          1486:     default:
        !          1487: 
        !          1488:         RtlInitUnicodeString(&ntUnicodeString,
        !          1489:             L"QIC-40/QIC-80 floppy tape drive");
        !          1490:     }
        !          1491: 
        !          1492:     //
        !          1493:     // Add Identifier value.
        !          1494:     //
        !          1495: 
        !          1496:     RtlInitUnicodeString(&name, L"Identifier");
        !          1497: 
        !          1498:     status = ZwSetValueKey(
        !          1499:         unitKey,
        !          1500:         &name,
        !          1501:         0,
        !          1502:         REG_SZ,
        !          1503:         ntUnicodeString.Buffer,
        !          1504:         ntUnicodeString.Length
        !          1505:         );
        !          1506: 
        !          1507:     ZwClose(unitKey);
        !          1508: 
        !          1509:     return;
        !          1510: 
        !          1511: } // end q117iUpdateRegistryInfo
        !          1512: 
        !          1513: STATUS
        !          1514: Q117iNewTape(
        !          1515:     IN PTAPE_EXTENSION TapeExtension
        !          1516:     )
        !          1517: 
        !          1518: /*++
        !          1519: 
        !          1520: Routine Description:
        !          1521: 
        !          1522:     Determine the format (if any) on a tape cartridge. This routine is
        !          1523:     executed whenever the driver detects that a new tape has been inserted
        !          1524:     into the tape drive.
        !          1525: 
        !          1526: Arguments:
        !          1527: 
        !          1528:     TapeExtension -
        !          1529: 
        !          1530: Return Value:
        !          1531: 
        !          1532: 
        !          1533: 
        !          1534: --*/
        !          1535: 
        !          1536: {
        !          1537:     STATUS retval;
        !          1538:     SHORT writeProtect;
        !          1539: 
        !          1540:     //
        !          1541:     // if we have a qic80 of firmware below a certain value
        !          1542:     // (FIRM_VERSION_63), and if we have an
        !          1543:     // unreferenced tape, and a cartridge is in the drive,
        !          1544:     // then we re-try the reference burst. Only if the
        !          1545:     // retry fails do we return an error.
        !          1546:     //
        !          1547:     // The firmware should do the retry automatically, but at the moment
        !          1548:     // it does not. This will be corrected, and the retry not commanded,
        !          1549:     // at some time to be determined. At that time, it should only be
        !          1550:     // necessary to change the #define used to determine the firmware
        !          1551:     // rev level.  --  crc
        !          1552:     //
        !          1553:     // Check to see if the drive is a Jumbo B with firmware 63.  This
        !          1554:     // firmware has 2 bugs.  If the tape is put in slowly, it can incorrectly
        !          1555:     // return an invalid media error or write protect status.
        !          1556:     //
        !          1557: 
        !          1558:     if (TapeExtension->DriveParms.Version <= FIRM_VERSION_63 &&
        !          1559:         TapeExtension->DriveParms.Version >= FIRM_VERSION_60 &&
        !          1560:         TapeExtension->DriveParms.Flavor == CMS) {
        !          1561: 
        !          1562:         retval = Q117iGetDriveError(TapeExtension);
        !          1563: 
        !          1564:         if (retval == TapeFlt && TapeExtension->FirmwareError == Inval_Media) {
        !          1565: 
        !          1566:             //
        !          1567:             // Fix both the invalid media error by sending a NewTape command
        !          1568:             // to the drive.
        !          1569: 
        !          1570:             retval = Q117iClearTapeError(TapeExtension);
        !          1571: 
        !          1572:         } else {
        !          1573: 
        !          1574:             //
        !          1575:             // Read the write protect status directly from port 2 on
        !          1576:             // the Jumbo B processor to determine if the drive got a
        !          1577:             // bogus write protect error.
        !          1578:             //
        !          1579: 
        !          1580:             if (TapeExtension->DriveParms.Status.WriteProtect &&
        !          1581:                 (retval = Q117iReadWrtProtect(TapeExtension, &writeProtect))
        !          1582:                 == NoErr) {
        !          1583: 
        !          1584:                 if (writeProtect == FALSE) {
        !          1585: 
        !          1586:                     retval = Q117iClearTapeError(TapeExtension);
        !          1587: 
        !          1588:                 }
        !          1589:             }
        !          1590:         }
        !          1591: 
        !          1592:         if (retval != NoErr) {
        !          1593: 
        !          1594:             return(retval);
        !          1595: 
        !          1596:         }
        !          1597:     }
        !          1598: 
        !          1599:     retval = Q117iGetDriveError(TapeExtension);
        !          1600: 
        !          1601:     if (TapeExtension->DriveParms.Status.Referenced == FALSE &&
        !          1602:         TapeExtension->DriveParms.Status.CartPresent == TRUE &&
        !          1603:         TapeExtension->DriveParms.Flavor == CMS &&
        !          1604:         TapeExtension->DriveParms.Version >= FIRM_VERSION_60 &&
        !          1605:         TapeExtension->DriveParms.Version <= FIRM_VERSION_63)  {
        !          1606: 
        !          1607:         //
        !          1608:         // command: seek reference burst. N.b: Non-interruptible!
        !          1609:         //
        !          1610: 
        !          1611:         if ((retval = Q117iSendByte(TapeExtension, Seek_LP)) != NoErr) {
        !          1612: 
        !          1613:             return(retval);
        !          1614: 
        !          1615:         }
        !          1616: 
        !          1617:         //
        !          1618:         // Wait for the drive to become ready again.
        !          1619:         //
        !          1620: 
        !          1621:         if ((retval = Q117iWaitCommandComplete(TapeExtension, mt_wt105s)) !=
        !          1622:             NoErr) {
        !          1623: 
        !          1624:             return(retval);
        !          1625: 
        !          1626:         }
        !          1627:     }
        !          1628: 
        !          1629:     //
        !          1630:     // Rewind tape -- needed for Archive drives
        !          1631:     //
        !          1632: 
        !          1633:     if ((TapeExtension->DriveParms.Status.CartPresent == TRUE) &&
        !          1634:         ((TapeExtension->DriveParms.Flavor == IOMEGA) ||
        !          1635:         (TapeExtension->DriveParms.Flavor == ARCHIVE))) {
        !          1636: 
        !          1637:         retval = Q117iGetDriveError(TapeExtension);
        !          1638: 
        !          1639:         if (TapeExtension->DriveParms.Status.BOT == FALSE) {
        !          1640: 
        !          1641:             if ((retval = Q117iSendByte(TapeExtension, Physical_Rev)) != NoErr) {
        !          1642: 
        !          1643:                 return(retval);
        !          1644: 
        !          1645:             }
        !          1646: 
        !          1647:             //
        !          1648:             //  Wait for the drive to become ready again.
        !          1649:             //
        !          1650: 
        !          1651:             if ((retval = Q117iWaitCommandComplete(TapeExtension, mt_wt460s)) !=
        !          1652:                 NoErr)  {
        !          1653: 
        !          1654:                 return(retval);
        !          1655: 
        !          1656:             }
        !          1657:         }
        !          1658: 
        !          1659:         if (TapeExtension->DriveParms.Status.Referenced == FALSE) {
        !          1660: 
        !          1661:             //
        !          1662:             //  command: seek reference burst. N.b: Non-interruptible!
        !          1663:             //
        !          1664: 
        !          1665:             if ((retval = Q117iSendByte(TapeExtension, Seek_LP)) != NoErr) {
        !          1666: 
        !          1667:                 return(retval);
        !          1668: 
        !          1669:             }
        !          1670: 
        !          1671:             //
        !          1672:             //  Wait for the drive to become ready again.
        !          1673:             //
        !          1674: 
        !          1675:             if ((retval = Q117iWaitCommandComplete(TapeExtension, mt_wt460s)) !=
        !          1676:                 NoErr) {
        !          1677: 
        !          1678:                 return(retval);
        !          1679: 
        !          1680:             }
        !          1681:         }
        !          1682:     }
        !          1683: 
        !          1684: 
        !          1685:     if ((retval = Q117iGetTapeParameters(TapeExtension)) != NoErr) {
        !          1686: 
        !          1687:         return(retval);
        !          1688: 
        !          1689:     }
        !          1690: 
        !          1691:     TapeExtension->TapePosition.C_Track = -1;
        !          1692:     TapeExtension->DriveParms.Mode = PRIMARY_MODE;
        !          1693:     TapeExtension->NewCart = FALSE;
        !          1694: 
        !          1695:     if  ((TapeExtension->TapeParms.TapeType == QIC80_SHORT ||
        !          1696:             TapeExtension->TapeParms.TapeType == QIC80_LONG ||
        !          1697:             TapeExtension->TapeParms.TapeType == QICEST_80) &&
        !          1698:             (TapeExtension->DriveParms.DriveType == QIC40_DRIVE)) {
        !          1699: 
        !          1700:         return(WrongFmt);
        !          1701: 
        !          1702:     }
        !          1703: 
        !          1704:     if (TapeExtension->XferRate.TapeFast == TAPE_2Mbps) {
        !          1705: 
        !          1706:         if  (TapeExtension->TapeParms.TapeType == QIC40_SHORT ||
        !          1707:              TapeExtension->TapeParms.TapeType == QIC40_LONG ||
        !          1708:              TapeExtension->TapeParms.TapeType == QICEST_40) {
        !          1709: 
        !          1710:             TapeExtension->XferRate.XferRate = SLOW;
        !          1711:             TapeExtension->XferRate.MaxRate = SLOW;
        !          1712:             TapeExtension->XferRate.TapeSlow = TAPE_500Kbps;
        !          1713:             TapeExtension->XferRate.FDC_Slow = FDC_500Kbps;
        !          1714:             TapeExtension->XferRate.SRT_Slow = SRT_500Kbps;
        !          1715:             retval = Q117iDFast_DSlow(TapeExtension, DSlow);
        !          1716: 
        !          1717:                 } else {
        !          1718: 
        !          1719:             if (TapeExtension->TapeParms.TapeType == QIC80_SHORT ||
        !          1720:                 TapeExtension->TapeParms.TapeType == QIC80_LONG ||
        !          1721:                 TapeExtension->TapeParms.TapeType == QICEST_80) {
        !          1722: 
        !          1723:                 TapeExtension->XferRate.XferRate = SLOW;
        !          1724:                 retval = Q117iDFast_DSlow(TapeExtension, DSlow);
        !          1725: 
        !          1726:                         }
        !          1727:                 }
        !          1728:         }
        !          1729: 
        !          1730:     if (TapeExtension->XferRate.TapeFast == TAPE_1Mbps) {
        !          1731: 
        !          1732:         if  (TapeExtension->TapeParms.TapeType == QIC40_SHORT ||
        !          1733:             TapeExtension->TapeParms.TapeType == QIC40_LONG ||
        !          1734:             TapeExtension->TapeParms.TapeType == QICEST_40) {
        !          1735: 
        !          1736:             TapeExtension->XferRate.XferRate = SLOW;
        !          1737:             retval = Q117iDFast_DSlow(TapeExtension, DSlow);
        !          1738: 
        !          1739:         } else {
        !          1740: 
        !          1741:             TapeExtension->XferRate.XferRate = TapeExtension->XferRate.MaxRate;
        !          1742: 
        !          1743:             if (TapeExtension->XferRate.XferRate == SLOW) {
        !          1744: 
        !          1745:                 retval = Q117iDFast_DSlow(TapeExtension, DSlow);
        !          1746: 
        !          1747:             } else {
        !          1748: 
        !          1749:                 retval = Q117iDFast_DSlow(TapeExtension, DFast);
        !          1750: 
        !          1751:             }
        !          1752:         }
        !          1753:     }
        !          1754: 
        !          1755:     return(retval);
        !          1756: }
        !          1757: 
        !          1758: 
        !          1759: STATUS
        !          1760: Q117iReadWrtProtect(
        !          1761:     IN PTAPE_EXTENSION TapeExtension,
        !          1762:     OUT SHORT *WriteProtect
        !          1763:     )
        !          1764: 
        !          1765: /*++
        !          1766: 
        !          1767: Routine Description:
        !          1768: 
        !          1769:     Reads the write protect status from the drive processor itself.
        !          1770: 
        !          1771:     This procedure is used due to the firmware 63 error where a tape put
        !          1772:     into the drive very slowly can cause the status byte to say (incorrectly)
        !          1773:     that the tape is write protected. It uses a Diagnostic command to read
        !          1774:     port 2 of the processor on the drive.
        !          1775: 
        !          1776: Arguments:
        !          1777: 
        !          1778:     TapeExtension -
        !          1779: 
        !          1780:     WriteProtect -
        !          1781: 
        !          1782: Return Value:
        !          1783: 
        !          1784: 
        !          1785: 
        !          1786: --*/
        !          1787: 
        !          1788: {
        !          1789:     STATUS retval;
        !          1790:     UCHAR port2Val;     // The port value from which the "real"
        !          1791:                         // write protect is read (bit 5)
        !          1792: 
        !          1793:     if ((retval = Q117iSetDriveMode(TapeExtension, DIAGNOSTIC_1_MODE)) ==
        !          1794:         NoErr) {
        !          1795: 
        !          1796:         if ((retval = Q117iReport(
        !          1797:                             TapeExtension,
        !          1798:                             Read_Port2,
        !          1799:                             (USHORT *)&port2Val,
        !          1800:                             READ_BYTE,
        !          1801:                             NULL)) == NoErr) {
        !          1802: 
        !          1803:             //
        !          1804:             // If bit 5 of port 2 on the return byte is 1, then the tape
        !          1805:             // is "really" write protected.
        !          1806:             //
        !          1807: 
        !          1808:             if (port2Val & WRITE_PROTECT_MASK) {
        !          1809: 
        !          1810:                 *WriteProtect = TRUE;
        !          1811: 
        !          1812:             } else {
        !          1813: 
        !          1814:                 *WriteProtect = FALSE;
        !          1815: 
        !          1816:             }
        !          1817: 
        !          1818:             retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE);
        !          1819:         }
        !          1820:     }
        !          1821: 
        !          1822:     return(retval);
        !          1823: }
        !          1824: 
        !          1825: 
        !          1826: STATUS
        !          1827: Q117iGetTapeParameters(
        !          1828:     IN PTAPE_EXTENSION TapeExtension
        !          1829:     )
        !          1830: 
        !          1831: /*++
        !          1832: 
        !          1833: Routine Description:
        !          1834: 
        !          1835:     Sets up the necessary tape capacity parameters in the driver according
        !          1836:     to the tape type (QIC40 or QIC80) and tape length (normal or extra length).
        !          1837: 
        !          1838: Arguments :
        !          1839: 
        !          1840:     TapeExtension -
        !          1841: 
        !          1842: Return Value:
        !          1843: 
        !          1844: 
        !          1845: 
        !          1846: --*/
        !          1847: 
        !          1848: {
        !          1849:     STATUS retval;
        !          1850:     CHAR orgMode;
        !          1851:     struct DriveConfiguration driveConfig;
        !          1852:     struct CmsStatus cmsStatus;
        !          1853:     struct TapeFormatLgth tapeFormatLength;
        !          1854:     BOOLEAN reportFailed = FALSE;
        !          1855: 
        !          1856:     if ((retval = Q117iReport(
        !          1857:                     TapeExtension,
        !          1858:                     Report_Confg,
        !          1859:                     (USHORT *)&driveConfig,
        !          1860:                     READ_BYTE,
        !          1861:                     NULL)) != NoErr) {
        !          1862: 
        !          1863:         return(retval);
        !          1864: 
        !          1865:     }
        !          1866: 
        !          1867:     /* Make a call to Report Tape Status */
        !          1868:     if ((retval = Q117iReport(
        !          1869:                     TapeExtension,
        !          1870:                     Report_Tape_Stat,
        !          1871:                     (USHORT *)&tapeFormatLength,
        !          1872:                     READ_BYTE,
        !          1873:                     NULL)) != NoErr) {
        !          1874: 
        !          1875:         Q117iGetDriveError(TapeExtension);
        !          1876:         retval = NoErr;
        !          1877:         reportFailed = TRUE;
        !          1878:         tapeFormatLength.Format = 0;
        !          1879:         tapeFormatLength.Length = 0;
        !          1880:     }
        !          1881: 
        !          1882:     if (!driveConfig.XL_Tape) {
        !          1883: 
        !          1884:         if (!driveConfig.QIC80) {
        !          1885: 
        !          1886:             if (!reportFailed && tapeFormatLength.Format == QIC_500) {
        !          1887: 
        !          1888:                 CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC500_SHORT\n"));
        !          1889:                 TapeExtension->TapeParms.TapeType =             QIC500_SHORT;
        !          1890:                 TapeExtension->TapeParms.FtrackFside =          FTK_FSD_500;
        !          1891:                 TapeExtension->TapeParms.SegTtrack =            SEG_TTRK_500;
        !          1892:                 TapeExtension->TapeParms.FsectFside =           FSC_FTK * FTK_FSD_500;
        !          1893:                 TapeExtension->TapeParms.LogSectors =           FSC_SEG * SEG_TTRK_500 * NUM_TTRK_500;
        !          1894:                 TapeExtension->TapeParms.FsectTtrack =          FSC_SEG * SEG_TTRK_500;
        !          1895:                 TapeExtension->TapeParms.TimeOut[L_SLOW] =      mt_wt130s;
        !          1896:                 TapeExtension->TapeParms.TimeOut[L_FAST] =      mt_wt065s;
        !          1897:                 TapeExtension->TapeParms.TimeOut[PHYSICAL] =    mt_wt065s;
        !          1898: 
        !          1899:             } else {
        !          1900: 
        !          1901:                 // Assume that the tape is a Standard length QIC40
        !          1902:                 CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC40_SHORT\n"));
        !          1903:                 TapeExtension->TapeParms.TapeType =             QIC40_SHORT;
        !          1904:                 TapeExtension->TapeParms.FtrackFside =          FTK_FSD_40;
        !          1905:                 TapeExtension->TapeParms.SegTtrack =            SEG_TTRK_40;
        !          1906:                 TapeExtension->TapeParms.FsectFside =           FSC_FTK * FTK_FSD_40;
        !          1907:                 TapeExtension->TapeParms.LogSectors =           FSC_SEG * SEG_TTRK_40 * NUM_TTRK_40;
        !          1908:                 TapeExtension->TapeParms.FsectTtrack =          FSC_SEG * SEG_TTRK_40;
        !          1909:                 TapeExtension->TapeParms.TimeOut[L_SLOW] =      mt_wt130s;
        !          1910:                 TapeExtension->TapeParms.TimeOut[L_FAST] =      mt_wt065s;
        !          1911:                 TapeExtension->TapeParms.TimeOut[PHYSICAL] =    mt_wt065s;
        !          1912: 
        !          1913:             }
        !          1914: 
        !          1915: 
        !          1916:         } else {
        !          1917: 
        !          1918:             CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC80_SHORT\n"));
        !          1919:             TapeExtension->TapeParms.TapeType = QIC80_SHORT;
        !          1920:             TapeExtension->TapeParms.FtrackFside = FTK_FSD_80;
        !          1921:             TapeExtension->TapeParms.SegTtrack = SEG_TTRK_80;
        !          1922:             TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_80;
        !          1923:             TapeExtension->TapeParms.LogSectors = (ULONG)FSC_SEG *
        !          1924:                                                     (ULONG)SEG_TTRK_80 *
        !          1925:                                                     (ULONG)NUM_TTRK_80;
        !          1926:             TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_80;
        !          1927:             TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt100s;
        !          1928:             TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt050s;
        !          1929:             TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt050s;
        !          1930: 
        !          1931:         }
        !          1932: 
        !          1933:     } else {
        !          1934: 
        !          1935: 
        !          1936:         if (!driveConfig.QIC80) {
        !          1937: 
        !          1938:             if (!reportFailed) {
        !          1939: 
        !          1940:                 switch (tapeFormatLength.Length) {
        !          1941: 
        !          1942:                 case (QICEST_900):
        !          1943: 
        !          1944:                     CheckedDump(QIC117INFO,( "Q117i: Tape Type QICEST_500\n"));
        !          1945:                     TapeExtension->TapeParms.TapeType = QICEST_500;
        !          1946:                     TapeExtension->TapeParms.FtrackFside = FTK_FSD_QICEST_500;
        !          1947:                     TapeExtension->TapeParms.SegTtrack = SEG_TTRK_500;
        !          1948:                     TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_QICEST_500;
        !          1949:                     TapeExtension->TapeParms.LogSectors = FSC_SEG * SEG_TTRK_500 * NUM_TTRK_500;
        !          1950:                     TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_500;
        !          1951:                     TapeExtension->TapeParms.TimeOut[L_SLOW] = mt_wt700s;
        !          1952:                     TapeExtension->TapeParms.TimeOut[L_FAST] = mt_wt350s;
        !          1953:                     TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt350s;
        !          1954:                     break;
        !          1955: 
        !          1956:                 case (QICEST):
        !          1957: 
        !          1958:                     CheckedDump(QIC117INFO,( "Q117i: Tape Type QICEST_40\n"));
        !          1959:                     TapeExtension->TapeParms.TapeType = QICEST_40;
        !          1960:                     TapeExtension->TapeParms.FtrackFside = FTK_FSD_QICEST_40;
        !          1961:                     TapeExtension->TapeParms.SegTtrack = SEG_TTRK_QICEST_40;
        !          1962:                     TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_QICEST_40;
        !          1963:                     TapeExtension->TapeParms.LogSectors = (ULONG)FSC_SEG *
        !          1964:                                                             (ULONG)SEG_TTRK_QICEST_40 *
        !          1965:                                                             (ULONG)NUM_TTRK_40;
        !          1966:                     TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_QICEST_40;
        !          1967:                     TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt700s;
        !          1968:                     TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt350s;
        !          1969:                     TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt350s;
        !          1970:                     break;
        !          1971: 
        !          1972:                 case (QIC_LONG):
        !          1973: 
        !          1974:                     CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC40_LONG\n"));
        !          1975:                     TapeExtension->TapeParms.TapeType = QIC40_LONG;
        !          1976:                     TapeExtension->TapeParms.FtrackFside = FTK_FSD_40L;
        !          1977:                     TapeExtension->TapeParms.SegTtrack = SEG_TTRK_40L;
        !          1978:                     TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_40L;
        !          1979:                     TapeExtension->TapeParms.LogSectors = FSC_SEG * SEG_TTRK_40L * NUM_TTRK_40;
        !          1980:                     TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_40L;
        !          1981:                     TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt200s;
        !          1982:                     TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt100s;
        !          1983:                     TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt100s;
        !          1984:                     break;
        !          1985:                 }
        !          1986: 
        !          1987:             } else {
        !          1988: 
        !          1989:                 // Assume that the tape type is QIC40_Long
        !          1990:                 CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC40_LONG\n"));
        !          1991:                 TapeExtension->TapeParms.TapeType = QIC40_LONG;
        !          1992:                 TapeExtension->TapeParms.FtrackFside = FTK_FSD_40L;
        !          1993:                 TapeExtension->TapeParms.SegTtrack = SEG_TTRK_40L;
        !          1994:                 TapeExtension->TapeParms.FsectFside =
        !          1995:                     FSC_FTK * FTK_FSD_40L;
        !          1996:                 TapeExtension->TapeParms.LogSectors =
        !          1997:                     FSC_SEG * SEG_TTRK_40L * NUM_TTRK_40;
        !          1998:                 TapeExtension->TapeParms.FsectTtrack =
        !          1999:                     FSC_SEG * SEG_TTRK_40L;
        !          2000:                 TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt200s;
        !          2001:                 TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt100s;
        !          2002:                 TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt100s;
        !          2003:             }
        !          2004: 
        !          2005:         } else {
        !          2006: 
        !          2007:             // drive_config.QIC80 == TRUE
        !          2008: 
        !          2009:             if (!reportFailed) {
        !          2010: 
        !          2011:                 switch (tapeFormatLength.Length) {
        !          2012: 
        !          2013:                 case (QICEST):
        !          2014: 
        !          2015:                     CheckedDump(QIC117INFO,( "Q117i: Tape Type QICEST_80\n"));
        !          2016:                     TapeExtension->TapeParms.TapeType = QICEST_80;
        !          2017:                     TapeExtension->TapeParms.FtrackFside = FTK_FSD_QICEST_80;
        !          2018:                     TapeExtension->TapeParms.SegTtrack = SEG_TTRK_QICEST_80;
        !          2019:                     TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_QICEST_80;
        !          2020:                     TapeExtension->TapeParms.LogSectors = (ULONG)FSC_SEG *
        !          2021:                                         (ULONG)SEG_TTRK_QICEST_80 *
        !          2022:                                         (ULONG)NUM_TTRK_80;
        !          2023:                     TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_QICEST_80;
        !          2024:                     TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt475s;
        !          2025:                     TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt250s;
        !          2026:                     TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt250s;
        !          2027:                     break;
        !          2028: 
        !          2029:                 case (QIC_LONG):
        !          2030: 
        !          2031:                     CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC80_LONG\n"));
        !          2032:                     TapeExtension->TapeParms.TapeType = QIC80_LONG;
        !          2033:                     TapeExtension->TapeParms.FtrackFside = FTK_FSD_80L;
        !          2034:                     TapeExtension->TapeParms.SegTtrack = SEG_TTRK_80L;
        !          2035:                     TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_80L;
        !          2036:                     TapeExtension->TapeParms.LogSectors = (ULONG)FSC_SEG *
        !          2037:                                         (ULONG)SEG_TTRK_80L *
        !          2038:                                         (ULONG)NUM_TTRK_80;
        !          2039:                     TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_80L;
        !          2040:                     TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt130s;
        !          2041:                     TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt065s;
        !          2042:                     TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt065s;
        !          2043:                     break;
        !          2044: 
        !          2045:                 }
        !          2046: 
        !          2047:             } else {
        !          2048: 
        !          2049:                 // Assume it is a QIC80_LONG
        !          2050: 
        !          2051:                 CheckedDump(QIC117INFO,( "Q117i: Tape Type QIC80_LONG\n"));
        !          2052:                 TapeExtension->TapeParms.TapeType = QIC80_LONG;
        !          2053:                 TapeExtension->TapeParms.FtrackFside = FTK_FSD_80L;
        !          2054:                 TapeExtension->TapeParms.SegTtrack = SEG_TTRK_80L;
        !          2055:                 TapeExtension->TapeParms.FsectFside = FSC_FTK * FTK_FSD_80L;
        !          2056:                 TapeExtension->TapeParms.LogSectors = (ULONG)FSC_SEG *
        !          2057:                                         (ULONG)SEG_TTRK_80L *
        !          2058:                                         (ULONG)NUM_TTRK_80;
        !          2059:                 TapeExtension->TapeParms.FsectTtrack = FSC_SEG * SEG_TTRK_80L;
        !          2060:                 TapeExtension->TapeParms.TimeOut[L_SLOW] =   mt_wt130s;
        !          2061:                 TapeExtension->TapeParms.TimeOut[L_FAST] =   mt_wt065s;
        !          2062:                 TapeExtension->TapeParms.TimeOut[PHYSICAL] = mt_wt065s;
        !          2063: 
        !          2064:             }
        !          2065:         }
        !          2066:     }
        !          2067: 
        !          2068:     TapeExtension->TapeParms.FsectSeg = FSC_SEG;
        !          2069:     TapeExtension->TapeParms.SegFtrack = SEG_FTK;
        !          2070:     TapeExtension->TapeParms.FsectFtrack = FSC_FTK;
        !          2071:     TapeExtension->TapeParms.RwGapLength = WRT_GPL;
        !          2072: 
        !          2073: 
        !          2074:     if ((TapeExtension->DriveParms.Flavor == CMS) &&
        !          2075:         ((TapeExtension->DriveParms.Version >= FIRM_VERSION_60) &&
        !          2076:         (TapeExtension->DriveParms.Version < FIRM_VERSION_87 ))) {
        !          2077: 
        !          2078:         if (driveConfig.XL_Tape) {
        !          2079: 
        !          2080:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !          2081:                                             DIAGNOSTIC_1_MODE)) != NoErr) {
        !          2082: 
        !          2083:                 return(retval);
        !          2084: 
        !          2085:             }
        !          2086: 
        !          2087:             if ((retval = Q117iReport(
        !          2088:                             TapeExtension,
        !          2089:                             Rpt_CMS_Status,
        !          2090:                             (USHORT *)&cmsStatus,
        !          2091:                             READ_BYTE,
        !          2092:                             NULL)) != NoErr) {
        !          2093: 
        !          2094:                 return(retval);
        !          2095: 
        !          2096:             } else {
        !          2097: 
        !          2098:                 if (cmsStatus.Pegasus) {
        !          2099: 
        !          2100:                     tapeFormatLength.Length = QICEST;
        !          2101: 
        !          2102:                 }
        !          2103: 
        !          2104: 
        !          2105:             }
        !          2106: 
        !          2107:             //
        !          2108:             // Put drive back into its original mode.
        !          2109:             //
        !          2110: 
        !          2111:             if ((retval = Q117iSetDriveMode(TapeExtension,
        !          2112:                                             PRIMARY_MODE)) != NoErr) {
        !          2113: 
        !          2114:                 return(retval);
        !          2115: 
        !          2116:             }
        !          2117: 
        !          2118: 
        !          2119:         }
        !          2120: 
        !          2121:     }
        !          2122: 
        !          2123:     // Determine the Tape Format Code
        !          2124: 
        !          2125:     if (tapeFormatLength.Length == QICEST ||
        !          2126:         tapeFormatLength.Length == QICEST_900) {
        !          2127: 
        !          2128:         CheckedDump(QIC117INFO,( "Q117i: Tape Format Code QICEST_FORMAT\n"));
        !          2129:         TapeExtension->TapeParms.TapeFormatCode = QICEST_FORMAT;
        !          2130: 
        !          2131:         if ( TapeExtension->DriveParms.Flavor == WANGTEK) {
        !          2132: 
        !          2133:             TapeExtension->DriveParms.SeekMode = SEEK_SKIP_EXTENDED;
        !          2134: 
        !          2135:         }
        !          2136: 
        !          2137:         if (!TapeExtension->PegasusSupported) {
        !          2138: 
        !          2139:             retval = TapeFlt;
        !          2140: 
        !          2141:         } else {
        !          2142: 
        !          2143:             if ( (TapeExtension->DriveParms.Flavor == CMS) &&
        !          2144:                 (TapeExtension->TapeParms.TapeType == QICEST_40) ) {
        !          2145: 
        !          2146:                 retval = TapeFlt;
        !          2147: 
        !          2148:             }
        !          2149: 
        !          2150:         }
        !          2151:     } else {
        !          2152: 
        !          2153:         CheckedDump(QIC117INFO,( "Q117i: Tape Format Code QIC_FORMAT\n"));
        !          2154:         TapeExtension->TapeParms.TapeFormatCode = QIC_FORMAT;
        !          2155: 
        !          2156:     }
        !          2157: 
        !          2158:     Q117iCalcFmtSegmentsAndTracks( TapeExtension );
        !          2159: 
        !          2160:     return(retval);
        !          2161: }
        !          2162: 
        !          2163: 
        !          2164: VOID
        !          2165: Q117iCalcFmtSegmentsAndTracks(
        !          2166:     IN PTAPE_EXTENSION TapeExtension
        !          2167:     )
        !          2168: 
        !          2169: /*++
        !          2170: 
        !          2171: Routine Description:
        !          2172: 
        !          2173:     Calculate the number of formattable segments given the current tape and
        !          2174:     drive type, and the number of tracks.
        !          2175: 
        !          2176: Arguments:
        !          2177: 
        !          2178:     TapeExtension -
        !          2179: 
        !          2180:     FormattableSegments -
        !          2181: 
        !          2182:     Tracks -
        !          2183: 
        !          2184: Return Value:
        !          2185: 
        !          2186:     None
        !          2187: 
        !          2188: --*/
        !          2189: 
        !          2190: {
        !          2191:     switch (TapeExtension->DriveParms.DriveType) {
        !          2192: 
        !          2193:         case (QIC80_DRIVE):
        !          2194: 
        !          2195:         //
        !          2196:         //Choose the segments per tape track value according to the length
        !          2197:         // of the tape.
        !          2198:         //
        !          2199: 
        !          2200:         switch (TapeExtension->TapeParms.TapeType) {
        !          2201: 
        !          2202:                 case (QIC40_SHORT):
        !          2203:                 case (QIC80_SHORT):
        !          2204: 
        !          2205:                         TapeExtension->TapeParms.FormattableSegs = (USHORT)SEG_TTRK_80;
        !          2206:                         break;
        !          2207: 
        !          2208:                 case (QIC40_LONG):
        !          2209:                 case (QIC80_LONG):
        !          2210: 
        !          2211:                         TapeExtension->TapeParms.FormattableSegs = (USHORT)SEG_TTRK_80L;
        !          2212:                         break;
        !          2213: 
        !          2214:                 case (QICEST_40):
        !          2215:                 case (QICEST_80):
        !          2216: 
        !          2217:                         TapeExtension->TapeParms.FormattableSegs = (USHORT)SEG_TTRK_QICEST_80;
        !          2218:                         break;
        !          2219: 
        !          2220:                 }
        !          2221: 
        !          2222:         if ((TapeExtension->NumTracks > NUM_TTRK_80) ||
        !          2223:             (TapeExtension->NumTracks == 0)) {
        !          2224: 
        !          2225:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)NUM_TTRK_80;
        !          2226:             TapeExtension->TapeParms.NumTtrack = (USHORT)NUM_TTRK_80;
        !          2227: 
        !          2228:         } else {
        !          2229: 
        !          2230:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)TapeExtension->NumTracks;
        !          2231:             TapeExtension->TapeParms.NumTtrack = (USHORT)TapeExtension->NumTracks;
        !          2232: 
        !          2233:         }
        !          2234:                 break;
        !          2235: 
        !          2236:         case (QIC40_DRIVE):
        !          2237: 
        !          2238:         //
        !          2239:         // Since a QIC40 drive can not detect a QIC80 formatted tape,
        !          2240:         // the seg_ttrack field in Q117itape_parms is correct.
        !          2241:         //
        !          2242: 
        !          2243:         TapeExtension->TapeParms.FormattableSegs = (USHORT)TapeExtension->TapeParms.SegTtrack;
        !          2244: 
        !          2245:         if ((TapeExtension->NumTracks == 0) ||
        !          2246:             (TapeExtension->NumTracks > NUM_TTRK_40)) {
        !          2247: 
        !          2248:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)NUM_TTRK_40;
        !          2249:             TapeExtension->TapeParms.NumTtrack = (USHORT)NUM_TTRK_40;
        !          2250: 
        !          2251:         } else {
        !          2252: 
        !          2253:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)TapeExtension->NumTracks;
        !          2254:             TapeExtension->TapeParms.NumTtrack = (USHORT)TapeExtension->NumTracks;
        !          2255: 
        !          2256:         }
        !          2257:                 break;
        !          2258: 
        !          2259:     case (QIC500_DRIVE):
        !          2260: 
        !          2261:         if (TapeExtension->TapeParms.TapeType == QICEST_500 ||
        !          2262:             TapeExtension->TapeParms.TapeType == QIC500_SHORT) {
        !          2263: 
        !          2264:             TapeExtension->TapeParms.FormattableSegs = (USHORT)TapeExtension->TapeParms.SegTtrack;
        !          2265: 
        !          2266:         } else {
        !          2267: 
        !          2268:             // A QIC40 or a QIC80 tape was detected in a QIC500_DRIVE drive
        !          2269: 
        !          2270:             TapeExtension->TapeParms.FormattableSegs = (USHORT)0;
        !          2271: 
        !          2272:         }
        !          2273: 
        !          2274:         if ((TapeExtension->NumTracks == 0) ||
        !          2275:             (TapeExtension->NumTracks > NUM_TTRK_500)) {
        !          2276: 
        !          2277:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)NUM_TTRK_500;
        !          2278:             TapeExtension->TapeParms.NumTtrack = (USHORT)NUM_TTRK_500;
        !          2279: 
        !          2280:         } else {
        !          2281: 
        !          2282:             TapeExtension->TapeParms.FormattableSegs *= (USHORT)TapeExtension->NumTracks;
        !          2283:             TapeExtension->TapeParms.NumTtrack = (USHORT)TapeExtension->NumTracks;
        !          2284: 
        !          2285:         }
        !          2286:         break;
        !          2287: 
        !          2288:     }
        !          2289: 
        !          2290: }
        !          2291: 
        !          2292: 
        !          2293: STATUS
        !          2294: Q117iMtnPreamble(
        !          2295:     IN PTAPE_EXTENSION TapeExtension,
        !          2296:     IN BOOLEAN Select
        !          2297:     )
        !          2298: 
        !          2299: /*++
        !          2300: 
        !          2301: Routine Description:
        !          2302: 
        !          2303: 
        !          2304: Arguments:
        !          2305: 
        !          2306:     TapeExtension -
        !          2307: 
        !          2308: Return Value:
        !          2309: 
        !          2310:     None
        !          2311: 
        !          2312: --*/
        !          2313: 
        !          2314: {
        !          2315:     STATUS retval;
        !          2316: 
        !          2317:     if (Select) {
        !          2318: 
        !          2319:         if ((retval = Q117iSendByte(TapeExtension, Mtn_Select_1)) == NoErr) {
        !          2320: 
        !          2321:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          2322:             retval = Q117iSendByte(TapeExtension, Mtn_Select_2);
        !          2323:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          2324: 
        !          2325:         }
        !          2326: 
        !          2327:     } else {
        !          2328: 
        !          2329:         retval = Q117iSendByte(TapeExtension, Mtn_Deselect);
        !          2330:         Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          2331: 
        !          2332:     }
        !          2333: 
        !          2334:     return(retval);
        !          2335: }
        !          2336: 
        !          2337: 
        !          2338: STATUS
        !          2339: Q117iGetDriveInfo(
        !          2340:     IN PTAPE_EXTENSION TapeExtension
        !          2341:     )
        !          2342: 
        !          2343: /*++
        !          2344: 
        !          2345: Routine Description:
        !          2346: 
        !          2347:     Gets the following Drive information:
        !          2348: 
        !          2349:         1) Drive Type/Model
        !          2350:         2) Firmware Revision
        !          2351:         3) OEM Field Flag
        !          2352:         4) OEM Field
        !          2353:         5) Serial Number
        !          2354:         6) Date of manufacture
        !          2355: 
        !          2356:         The OEM, Serial Number and the Date of manufacture are miscellaneous
        !          2357:         drive train information that is embedded in the drive's firmware.
        !          2358: 
        !          2359:     If the drive type is not CMS and/or the firmware revision is pre-80
        !          2360:     then zeros are returned in these fields. The drive type is obtained by
        !          2361:     making a call to Rpt_Cms_Status. This has been done to support the Jumbo
        !          2362:     B platform.
        !          2363: 
        !          2364: Arguments:
        !          2365: 
        !          2366:     TapeExtension -
        !          2367: 
        !          2368: Return Value:
        !          2369: 
        !          2370: 
        !          2371: 
        !          2372: --*/
        !          2373: 
        !          2374: {
        !          2375:     struct CmsStatus cmsStatus;
        !          2376:     CHAR currentMode;
        !          2377:     UCHAR bitBucket;
        !          2378:     SHORT i;
        !          2379:     STATUS retval;
        !          2380: 
        !          2381:     //
        !          2382:     // Initialize the Drive Train Miscellaneous Information value to NULL
        !          2383:     //
        !          2384: 
        !          2385:     TapeExtension->MiscDriveInfo.InfoExists        = FALSE;
        !          2386:     TapeExtension->MiscDriveInfo.SerialNumber[0]   = '\0';
        !          2387:     TapeExtension->MiscDriveInfo.ManDate[0]        = '\0';
        !          2388:     TapeExtension->MiscDriveInfo.ManDate[1]        = '\0';
        !          2389:     TapeExtension->MiscDriveInfo.Oem[0]             = '\0';
        !          2390: 
        !          2391:     //
        !          2392:     // Get the firmware revision number and store it in
        !          2393:     // TapeExtension->MiscDriveInfo.ROM_Version
        !          2394:     //
        !          2395: 
        !          2396:     TapeExtension->MiscDriveInfo.ROM_Version =
        !          2397:         TapeExtension->DriveParms.Version;
        !          2398: 
        !          2399:     if (TapeExtension->DriveParms.Flavor == CMS) {
        !          2400: 
        !          2401:         if (TapeExtension->MiscDriveInfo.ROM_Version >=
        !          2402:             FIRM_VERSION_60) {
        !          2403: 
        !          2404:             //
        !          2405:             // Save the current drive mode
        !          2406:             //
        !          2407: 
        !          2408:             currentMode = TapeExtension->DriveParms.Mode;
        !          2409:             retval = Q117iSetDriveMode(TapeExtension, DIAGNOSTIC_1_MODE);
        !          2410: 
        !          2411:             //
        !          2412:             // Since we are only looking at the firmware, ignore all
        !          2413:             // NoTape errors.
        !          2414:             //
        !          2415: 
        !          2416:             if (retval != NoErr && retval != NoTape) {
        !          2417: 
        !          2418:                 return(retval);
        !          2419: 
        !          2420:             }
        !          2421: 
        !          2422:             //
        !          2423:             // In order to support the Jumbo-B platform, the drive type
        !          2424:             // is gotten from cmsStatus and the drive type obtained from
        !          2425:             // the drive train info is thrown away.
        !          2426:             //
        !          2427: 
        !          2428:             //
        !          2429:             // Get the Drive Type and store it in
        !          2430:             // TapeExtension->MiscDriveInfo.DriveType
        !          2431:             //
        !          2432: 
        !          2433:             retval = Q117iReport(
        !          2434:                             TapeExtension,
        !          2435:                             Rpt_CMS_Status,
        !          2436:                             (USHORT *)&cmsStatus,
        !          2437:                             READ_BYTE,
        !          2438:                             NULL);
        !          2439: 
        !          2440:             //
        !          2441:             // Since we are only looking at the firmware, ignore all
        !          2442:             // NoTape errors.
        !          2443:             //
        !          2444: 
        !          2445:             if (retval != NoErr && retval != NoTape) {
        !          2446: 
        !          2447:                 return(retval);
        !          2448: 
        !          2449:             }
        !          2450: 
        !          2451:             TapeExtension->MiscDriveInfo.DriveType =
        !          2452:                 (CHAR)cmsStatus.DriveType;
        !          2453: 
        !          2454:         } else {
        !          2455: 
        !          2456:             TapeExtension->MiscDriveInfo.DriveType = -1;
        !          2457: 
        !          2458:         }
        !          2459: 
        !          2460:         if (TapeExtension->MiscDriveInfo.ROM_Version >= FIRM_VERSION_80) {
        !          2461: 
        !          2462:             //
        !          2463:             // Send the Get Drive Training Information Command to the Drive.
        !          2464:             //
        !          2465: 
        !          2466:             retval = Q117iSendByte(TapeExtension, Dtrain_Info);
        !          2467: 
        !          2468:             //
        !          2469:             // Since we are only looking at the firmware, ignore all
        !          2470:             // NoTape errors.
        !          2471:             //
        !          2472: 
        !          2473:             if (retval != NoErr && retval != NoTape) {
        !          2474: 
        !          2475:                 return(retval);
        !          2476: 
        !          2477:             }
        !          2478: 
        !          2479:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          2480: 
        !          2481:             //
        !          2482:             // Send the Get Descriptive Info Command to the Drive.
        !          2483:             //
        !          2484: 
        !          2485:             retval = Q117iSendByte(TapeExtension, Gdesp_Info);
        !          2486: 
        !          2487:             //
        !          2488:             // Since we are only looking at the firmware, ignore all
        !          2489:             // NoTape errors.
        !          2490:             //
        !          2491: 
        !          2492:             if (retval != NoErr && retval != NoTape) {
        !          2493: 
        !          2494:                 return(retval);
        !          2495: 
        !          2496:             }
        !          2497: 
        !          2498:             Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
        !          2499: 
        !          2500:             //
        !          2501:             // Set the info_exists flag to true.
        !          2502:             //
        !          2503: 
        !          2504:             TapeExtension->MiscDriveInfo.InfoExists = TRUE;
        !          2505: 
        !          2506:             //
        !          2507:             // Get the Drive Type and through it in the bit_bucket --
        !          2508:             // just to keep the data in sync.
        !          2509:             //
        !          2510: 
        !          2511:             retval = Q117iReport(
        !          2512:                             TapeExtension,
        !          2513:                             Read_Ram,
        !          2514:                             (USHORT *)&bitBucket,
        !          2515:                             READ_BYTE,
        !          2516:                             NULL);
        !          2517: 
        !          2518:             //
        !          2519:             // Since we are only looking at the firmware, ignore all
        !          2520:             // NoTape errors.
        !          2521:             //
        !          2522: 
        !          2523:             if (retval != NoErr && retval != NoTape) {
        !          2524: 
        !          2525:                 return(retval);
        !          2526: 
        !          2527:             }
        !          2528: 
        !          2529:             //
        !          2530:             // Get the Serial Number from the drive and store it in
        !          2531:             // TapeExtension->MiscDriveInfo.SerialNumber[]
        !          2532:             //
        !          2533: 
        !          2534:             for (i=0; i<SERIAL_NUM_LENGTH; ++i) {
        !          2535: 
        !          2536:                 retval = Q117iReport(
        !          2537:                             TapeExtension,
        !          2538:                             Read_Ram,
        !          2539:                             (USHORT *)&TapeExtension->MiscDriveInfo.SerialNumber[i],
        !          2540:                             READ_BYTE,
        !          2541:                             NULL);
        !          2542: 
        !          2543:                 //
        !          2544:                 // Since we are only looking at the firmware, ignore
        !          2545:                 // all NoTape errors.
        !          2546:                 //
        !          2547: 
        !          2548:                 if (retval != NoErr && retval != NoTape) {
        !          2549: 
        !          2550:                     return(retval);
        !          2551: 
        !          2552:                 }
        !          2553:             }
        !          2554: 
        !          2555:             //
        !          2556:             // Get the Manufacturing date from the drive and store it in
        !          2557:             // TapeExtension->MiscDriveInfo.ManDate[]
        !          2558:             //
        !          2559: 
        !          2560:             for (i=0; i<MAN_DATE_LENGTH; ++i) {
        !          2561: 
        !          2562:                 retval = Q117iReport(
        !          2563:                             TapeExtension,
        !          2564:                             Read_Ram,
        !          2565:                             (USHORT *)&TapeExtension->MiscDriveInfo.ManDate[i],
        !          2566:                             READ_BYTE,
        !          2567:                             NULL);
        !          2568: 
        !          2569:                 //
        !          2570:                 // Since we are only looking at the firmware, ignore
        !          2571:                 // all NoTape errors.
        !          2572:                 //
        !          2573: 
        !          2574:                 if (retval != NoErr && retval != NoTape) {
        !          2575: 
        !          2576:                     return(retval);
        !          2577: 
        !          2578:                 }
        !          2579: 
        !          2580:             }
        !          2581: 
        !          2582:             //
        !          2583:             // Get the OEM field from the drive and store it in
        !          2584:             // TapeExtension->MiscDriveInfo.Oem[]
        !          2585:             //
        !          2586: 
        !          2587:             for (i=0; i<OEM_LENGTH; ++i) {
        !          2588: 
        !          2589:                 retval = Q117iReport(
        !          2590:                             TapeExtension,
        !          2591:                             Read_Ram,
        !          2592:                             (USHORT *)&TapeExtension->MiscDriveInfo.Oem[i],
        !          2593:                             READ_BYTE,
        !          2594:                             NULL);
        !          2595: 
        !          2596:                 //
        !          2597:                 // Since we are only looking at the firmware, ignore
        !          2598:                 // all NoTape errors.
        !          2599:                 //
        !          2600: 
        !          2601:                 if (retval != NoErr && retval != NoTape) {
        !          2602: 
        !          2603:                     return(retval);
        !          2604: 
        !          2605:                 }
        !          2606: 
        !          2607:                 if (TapeExtension->MiscDriveInfo.Oem[i] == '\0') {
        !          2608: 
        !          2609:                     break;
        !          2610: 
        !          2611:                 }
        !          2612:             }
        !          2613:         }
        !          2614:     }
        !          2615: 
        !          2616:     if ((TapeExtension->DriveParms.Flavor == CMS) &&
        !          2617:         (TapeExtension->MiscDriveInfo.ROM_Version >= FIRM_VERSION_60)) {
        !          2618: 
        !          2619:         //
        !          2620:         // Exit the Diagnostics Mode by entering the Primary Mode
        !          2621:         //
        !          2622: 
        !          2623:         retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE);
        !          2624: 
        !          2625:         //
        !          2626:         // Since we are only looking at the firmware, ignore all NoTape errors
        !          2627:         //
        !          2628: 
        !          2629:         if (retval != NoErr && retval != NoTape) {
        !          2630: 
        !          2631:             return(retval);
        !          2632: 
        !          2633:         }
        !          2634: 
        !          2635:         //
        !          2636:         // Restore drive to original mode (current_mode)
        !          2637:         //
        !          2638: 
        !          2639:         if (currentMode != PRIMARY_MODE){
        !          2640: 
        !          2641:             retval = Q117iSetDriveMode(TapeExtension, currentMode);
        !          2642: 
        !          2643:             //
        !          2644:             // Since we are only looking at the firmware, ignore all NoTape errors
        !          2645:             //
        !          2646: 
        !          2647:             if (retval != NoErr && retval != NoTape) {
        !          2648: 
        !          2649:                 return(retval);
        !          2650: 
        !          2651:             }
        !          2652:         }
        !          2653:     }
        !          2654: 
        !          2655:     return(NoErr);
        !          2656: }

unix.superglobalmegacorp.com

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