Annotation of ntddk/src/scsi/qic117/send.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
                      4: All Rights Reserved
                      5: 
                      6: Module Name:
                      7: 
                      8:     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.