Annotation of ntddk/src/scsi/qic117/send.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:     send.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     Sends a QIC117 command to the drive.
        !            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: Q117iSendByte(
        !            37:     IN PTAPE_EXTENSION TapeExtension,
        !            38:     IN FIRMWARE_CMD Command
        !            39:     )
        !            40: 
        !            41: /*++
        !            42: 
        !            43: Routine Description:
        !            44: 
        !            45:     Transmit a command to the tape drive using step pulses generated by
        !            46:     the FDC.
        !            47: 
        !            48:         Using the Present Cylinder Number (pcn) of the FDC calculate a New
        !            49:         Cylinder Number (ncn) that will make the FDC generate the number of
        !            50:         step pulses corresponding to the command byte.
        !            51: 
        !            52:         Execute a Seek with the FDC.
        !            53: 
        !            54:         Sense Interrupt Status of the FDC and make sure that the pcn concurs
        !            55:         with the ncn, which indicates that the correct number of step pulses
        !            56:         were issued.
        !            57: 
        !            58: Arguments:
        !            59: 
        !            60:     TapeExtension -
        !            61: 
        !            62:     Command -
        !            63: 
        !            64: Return Value:
        !            65: 
        !            66: 
        !            67: 
        !            68: --*/
        !            69: 
        !            70: {
        !            71:     STATUS retval = NoErr;
        !            72:     SHORT statLength;
        !            73:     struct seek_cmd seek;
        !            74:     struct fdc_result result;
        !            75: #if DBG
        !            76:     BOOLEAN save;
        !            77: 
        !            78:     // Lockout commands used to receive the status
        !            79:     save = TapeExtension->DbgLockout;
        !            80:     TapeExtension->DbgLockout = TRUE;
        !            81: #endif
        !            82: 
        !            83:     if (TapeExtension->QControllerData->AbortRequested) {
        !            84: 
        !            85:         return(DAbort);
        !            86: 
        !            87:     }
        !            88: 
        !            89:     if (Command >= 128) {
        !            90: 
        !            91:         return(InvalCmd);
        !            92: 
        !            93:     }
        !            94: 
        !            95:     if (TapeExtension->QControllerData->FDC_Pcn < 128) {
        !            96: 
        !            97:         seek.NCN = TapeExtension->QControllerData->FDC_Pcn + Command;
        !            98: 
        !            99:     } else {
        !           100: 
        !           101:         seek.NCN = TapeExtension->QControllerData->FDC_Pcn - Command;
        !           102: 
        !           103:     }
        !           104: 
        !           105:     seek.cmd = 0x0f;
        !           106:     seek.drive = (UCHAR)TapeExtension->DriveParms.DriveSelect;
        !           107:     (VOID) Q117iResetInterruptEvent(TapeExtension);
        !           108: 
        !           109:     if ((retval = Q117iProgramFDC(
        !           110:                     TapeExtension,
        !           111:                     (CHAR *)&seek,
        !           112:                     sizeof(seek),
        !           113:                     FALSE)) != NoErr) {
        !           114: 
        !           115:         return(retval);
        !           116: 
        !           117:     }
        !           118: 
        !           119:     if (TapeExtension->QControllerData->StartFormatMode) {
        !           120: 
        !           121:         TapeExtension->FmtOp.NCN = seek.NCN;
        !           122: 
        !           123:         if (TapeExtension->XferRate.XferRate == SLOW) {
        !           124: 
        !           125:             CheckedDump(QIC117INFO,( "Q117i: FmtOp L_SLOW timeout %ld (decimal)\n",
        !           126:                     TapeExtension->TapeParms.TimeOut[L_SLOW]));
        !           127:             retval = Q117iSleep(TapeExtension, TapeExtension->TapeParms.TimeOut[L_SLOW], TRUE);
        !           128: 
        !           129:         } else {
        !           130: 
        !           131:             CheckedDump(QIC117INFO,( "Q117i: FmtOp L_FAST timeout %ld (decimal)\n",
        !           132:                     TapeExtension->TapeParms.TimeOut[L_FAST]));
        !           133:             retval = Q117iSleep(TapeExtension, TapeExtension->TapeParms.TimeOut[L_FAST], TRUE);
        !           134: 
        !           135:         }
        !           136: 
        !           137:         if ((retval == TimeOut) && (TapeExtension->FmtOp.retval == NoErr)) {
        !           138: 
        !           139:                       TapeExtension->QControllerData->StartFormatMode = FALSE;
        !           140:                                 TapeExtension->QControllerData->EndFormatMode = FALSE;
        !           141:                                 IoFlushAdapterBuffers(
        !           142:                                          TapeExtension->QControllerData->AdapterObject,
        !           143:                                          TapeExtension->FmtOp.MdlAddress,
        !           144:                                          TapeExtension->QControllerData->MapRegisterBase,
        !           145:                                          (PVOID)( (ULONG) MmGetMdlVirtualAddress(TapeExtension->FmtOp.MdlAddress )
        !           146:                                                        + TapeExtension->RdWrOp.BytesTransferredSoFar ),
        !           147:                                          TapeExtension->RdWrOp.TotalBytesOfTransfer,
        !           148:                                          DMA_READ );
        !           149: 
        !           150:         }
        !           151: 
        !           152:         if (retval == NoErr) {
        !           153: 
        !           154:             retval = TapeExtension->FmtOp.retval;
        !           155: 
        !           156:         }
        !           157: 
        !           158:         TapeExtension->QControllerData->StartFormatMode = FALSE;
        !           159: 
        !           160:     } else {
        !           161: 
        !           162:         Q117iSleep(TapeExtension, mt_wt001s, TRUE);
        !           163: 
        !           164:         // For some unknown reason, we occasionally miss an interrupt.
        !           165:         // Despite the timeout, we still press on as if we received the interrupt.
        !           166:         // Therefore, we go ahead and perform the sense interrupt status.  If
        !           167:         // status register 0 is bad, then we assume that we truly did miss the
        !           168:         // interrupt.  Otherwise, we go on as if nothing happened.
        !           169:         //
        !           170: 
        !           171:         if ((retval = Q117iReadFDC(TapeExtension, (CHAR *)&result, &statLength))
        !           172:             != NoErr) {
        !           173: 
        !           174:             return(retval);
        !           175: 
        !           176:         } else {
        !           177: 
        !           178:             //
        !           179:             // If the sense interrupt status is O.K., then proceed as if
        !           180:             // nothing happened. If, however, there is an error returned by
        !           181:             // status register 0, then return a NECFLT.
        !           182:             //
        !           183: 
        !           184:             if (! (result.ST0 & ST0_IC)) {
        !           185: 
        !           186:                 //
        !           187:                 // If we timed out, then we did the sense interrupt status
        !           188:                 // without clearing the interrupt from the interrupt controller.
        !           189:                 // Since the FDC did not indicate an error, we assume that we
        !           190:                 // missed the interrupt and send the EOI. Only needed for an
        !           191:                 // 82072.
        !           192:                 //
        !           193: 
        !           194:                 if (TapeExtension->QControllerData->InterfaceType != MicroChannel) {
        !           195: 
        !           196:                     if (result.ST0 !=
        !           197:                         (UCHAR)(TapeExtension->DriveParms.DriveSelect | ST0_SE)) {
        !           198: 
        !           199:                         return(NECFlt);
        !           200: 
        !           201:                     }
        !           202:                 }
        !           203: 
        !           204:                 if (seek.NCN != result.PCN) {
        !           205: 
        !           206:                     return(CmdFlt);
        !           207: 
        !           208:                 }
        !           209: 
        !           210:                 TapeExtension->QControllerData->FDC_Pcn = result.PCN;
        !           211: 
        !           212:             } else {
        !           213: 
        !           214:                 return(NECFlt);
        !           215: 
        !           216:             }
        !           217:         }
        !           218:     #if DBG
        !           219:         TapeExtension->DbgLockout = save;
        !           220:         DbgAddEntry(0x1234567b);
        !           221:         DbgAddEntry((UCHAR)Command);
        !           222:     #endif
        !           223: 
        !           224:     } 
        !           225: 
        !           226:     return(retval);
        !           227: }

unix.superglobalmegacorp.com

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