Annotation of ntddk/src/scsi/qic117/stbk.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:     stbk.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     These routines setup all of the global variables for appending
        !            13:     to current tape.
        !            14: 
        !            15: 
        !            16: Revision History:
        !            17: 
        !            18: 
        !            19: 
        !            20: 
        !            21: --*/
        !            22: 
        !            23: //
        !            24: // include files
        !            25: //
        !            26: 
        !            27: #include <ntddk.h>
        !            28: #include <ntddtape.h>
        !            29: #include "common.h"
        !            30: #include "q117.h"
        !            31: #include "protos.h"
        !            32: 
        !            33: 
        !            34: STATUS
        !            35: q117StartBack(
        !            36:     IN OUT PVOLUME_TABLE_ENTRY TheVolumeTable,
        !            37:     IN PQ117_CONTEXT Context
        !            38:     )
        !            39: 
        !            40: /*++
        !            41: 
        !            42: Routine Description:
        !            43: 
        !            44:     This routine gets the necessry information for backing up to the
        !            45:     end of the current tape.
        !            46: 
        !            47: Arguments:
        !            48: 
        !            49:     TheVolumeTable - volume table entry to be used for updating the tape
        !            50:     directory and for tape linking.
        !            51: 
        !            52: Return value:
        !            53: 
        !            54:     Error in return value.
        !            55: 
        !            56: --*/
        !            57: 
        !            58: {
        !            59:     STATUS ret = NoErr;       // Return value from other routines called
        !            60:     LONG i;                  // Loop variable.
        !            61:     VOLUME_TABLE_ENTRY temp;
        !            62: 
        !            63:     //
        !            64:     // Check to see if anyone has read the last
        !            65:     // volume entry since Init was called
        !            66:     //
        !            67: 
        !            68:     if (Context->CurrentOperation.EndOfUsedTape==0) {
        !            69: 
        !            70:         //
        !            71:         // read tape directory (this sets CurrentOperation.EndOfUsedTape)
        !            72:         //
        !            73:         if (ret=q117GetEndBlock(&temp,&i,Context))
        !            74: 
        !            75:             //
        !            76:             // RdncUnsc (had to skip over the bad sector map), any
        !            77:             // Driver error except BadBlk, <EndOfVol>, <LinkRC>.
        !            78:             //
        !            79:             return(ret);
        !            80:     }
        !            81: 
        !            82:     if (Context->ActiveVolumeNumber == Context->CurrentTape.MaximumVolumes) {
        !            83:         return(VolFull);
        !            84:     }
        !            85: 
        !            86:     if (Context->CurrentOperation.EndOfUsedTape ==
        !            87:             Context->CurrentTape.LastSegment) {
        !            88: 
        !            89:         return(TapeFull);
        !            90: 
        !            91:     }
        !            92: 
        !            93:     //
        !            94:     // fill in the appropriate information in
        !            95:     // the volume entry
        !            96:     //
        !            97:     TheVolumeTable->Signature=VolumeTableSig;
        !            98:     TheVolumeTable->CreationTime = 0;        // lbt_qictime()
        !            99:     TheVolumeTable->NotVerified = TRUE;      // set if volume not verified yet
        !           100:     TheVolumeTable->NoNewName = FALSE;       // set if new file names (redirection) disallowed
        !           101:     TheVolumeTable->SequenceNumber = 1;      // multi-cartridge sequence number
        !           102: 
        !           103:     ret = q117StartComm(TheVolumeTable,Context);
        !           104: 
        !           105:     //
        !           106:     // do common initialization (start or link)
        !           107:     //
        !           108: 
        !           109:     return(ret);
        !           110: }
        !           111: 
        !           112: 
        !           113: STATUS
        !           114: q117StartAppend(
        !           115:     IN OUT ULONG BytesAlreadyThere,
        !           116:     IN PVOLUME_TABLE_ENTRY TheVolumeTable,
        !           117:     IN OUT PQ117_CONTEXT Context
        !           118:     )
        !           119: 
        !           120: /*++
        !           121: 
        !           122: Routine Description:
        !           123: 
        !           124: 
        !           125: 
        !           126: 
        !           127: Arguments:
        !           128: 
        !           129:     BytesAlreadyThere -
        !           130: 
        !           131:     TheVolumeTable -
        !           132: 
        !           133:     Context -
        !           134: 
        !           135: Return Value:
        !           136: 
        !           137: 
        !           138: --*/
        !           139: 
        !           140: {
        !           141:     STATUS ret = NoErr;            // Return value from other routines called.
        !           142:     PSEGMENT_BUFFER bufferInfo;
        !           143:     PIO_REQUEST ioreq;
        !           144:     int queuePointer;
        !           145: 
        !           146: 
        !           147:     //
        !           148:     // Set up as if we were starting a backup from scratch
        !           149:     //
        !           150: 
        !           151:     ret = q117StartBack(TheVolumeTable,Context);
        !           152: 
        !           153:     if (!ret) {
        !           154: 
        !           155:         //
        !           156:         // Now advance past the existing data
        !           157:         //
        !           158: 
        !           159:         //
        !           160:         // Walk through the previous backup
        !           161:         // to find the ending data and segment
        !           162:         //
        !           163: 
        !           164:         while (BytesAlreadyThere >=
        !           165:                 (ULONG)Context->CurrentOperation.SegmentBytesRemaining) {
        !           166: 
        !           167:             //
        !           168:             // Adjust counters as if we had backed up the data
        !           169:             //
        !           170:             BytesAlreadyThere -=
        !           171:                 Context->CurrentOperation.SegmentBytesRemaining;
        !           172: 
        !           173:             Context->CurrentOperation.BytesOnTape +=
        !           174:                 Context->CurrentOperation.SegmentBytesRemaining;
        !           175: 
        !           176:             ++Context->CurrentOperation.CurrentSegment;
        !           177: 
        !           178:             Context->CurrentOperation.SegmentBytesRemaining =
        !           179:                 q117GoodDataBytes(
        !           180:                     Context->CurrentOperation.CurrentSegment,
        !           181:                     Context);
        !           182:         }
        !           183: 
        !           184:         //
        !           185:         // If there is data in the segment we are going to append to
        !           186:         //
        !           187:         if (BytesAlreadyThere) {
        !           188:             Context->CurrentOperation.BytesOnTape += BytesAlreadyThere;
        !           189: 
        !           190:             //
        !           191:             // Get pointer to current buffer and buffer info
        !           192:             //
        !           193:             Context->CurrentOperation.SegmentPointer =
        !           194:                 q117GetFreeBuffer(&bufferInfo,Context);
        !           195: 
        !           196:             queuePointer = q117GetQueueIndex(Context);
        !           197: 
        !           198:             //
        !           199:             // Read this data block into memory
        !           200:             //
        !           201:             ret=q117IssIOReq(
        !           202:                     Context->CurrentOperation.SegmentPointer,
        !           203:                     DRead,
        !           204:                     SEGMENT_TO_BLOCK( Context->CurrentOperation.CurrentSegment),
        !           205:                     bufferInfo,
        !           206:                     Context);
        !           207: 
        !           208:             if (!ret) {
        !           209: 
        !           210:                 //
        !           211:                 // Wait for data to be read
        !           212:                 //
        !           213:                 ioreq=q117Dequeue(WaitForItem,Context);
        !           214: 
        !           215:                 if (ioreq->Status != BadBlk && ioreq->Status) {
        !           216:                     ret = ioreq->Status;
        !           217:                 } else {
        !           218: 
        !           219:                     //
        !           220:                     // correct data segment with Reed-Solomon and
        !           221:                     // Heroic retries
        !           222:                     //
        !           223:                     ret = q117ReconstructSegment(ioreq,Context);
        !           224:                 }
        !           225:             }
        !           226: 
        !           227:             //
        !           228:             // Setup queue to write this buffer back out
        !           229:             //
        !           230:             q117SetQueueIndex(queuePointer,Context);
        !           231: 
        !           232:             //
        !           233:             // Now adjust pointer into buffer to point pass data
        !           234:             //  that is already there.
        !           235:             //
        !           236:             (UCHAR *)Context->CurrentOperation.SegmentPointer +=
        !           237:                 BytesAlreadyThere;
        !           238: 
        !           239:             Context->CurrentOperation.SegmentBytesRemaining -=
        !           240:                 (USHORT)BytesAlreadyThere;
        !           241: 
        !           242:         }
        !           243:     }
        !           244: 
        !           245:     return(ret);
        !           246: 
        !           247: }
        !           248: 
        !           249: 
        !           250: STATUS
        !           251: q117StartComm(
        !           252:     OUT PVOLUME_TABLE_ENTRY TheVolumeTable,
        !           253:     IN OUT PQ117_CONTEXT Context
        !           254:     )
        !           255: 
        !           256: /*++
        !           257: 
        !           258: Routine Description:
        !           259: 
        !           260:     This routine gets the necessary information for backing up to the end
        !           261:     of the current tape.
        !           262: 
        !           263: Arguments:
        !           264: 
        !           265:     TheVolumeTable -  volume table entry to be used for updating the tape
        !           266:     directory and for tape linking.
        !           267: 
        !           268: Return Value:
        !           269: 
        !           270:     Error in return value.
        !           271: 
        !           272: --*/
        !           273: 
        !           274: {
        !           275:     LONG ret = NoErr;
        !           276: 
        !           277:     //
        !           278:     // zero out appropriate information
        !           279:     //
        !           280:     TheVolumeTable->MultiCartridge = FALSE;  // set if volume spans another tape
        !           281:     TheVolumeTable->DirectorySize = 0;       // number of bytes reserved for directory
        !           282:     TheVolumeTable->DataSize = 0;            // size of data area (includes other cartridges)
        !           283:     TheVolumeTable->EndingSegment = 0;
        !           284:     TheVolumeTable->NoNewName = FALSE;       // allow restoring to new name (re-direction)
        !           285:     TheVolumeTable->reserved = 0;            // QIC-40 spec. says to zero this out
        !           286: 
        !           287:     //
        !           288:     // set global variables
        !           289:     //
        !           290:     Context->CurrentOperation.CurrentSegment =
        !           291:         Context->CurrentOperation.EndOfUsedTape+1;
        !           292: 
        !           293:     Context->CurrentOperation.LastSegment = Context->CurrentTape.LastSegment;
        !           294: 
        !           295:     // clear out the flag for update of bad map
        !           296:     Context->CurrentOperation.UpdateBadMap = FALSE;
        !           297: 
        !           298:     Context->CurrentOperation.BytesZeroFilled = 0;
        !           299:     Context->CurrentOperation.BytesOnTape = 0;
        !           300:     Context->CurrentOperation.SegmentPointer = q117GetFreeBuffer(NULL, Context);
        !           301: 
        !           302: #ifndef NO_MARKS
        !           303: 
        !           304:     //
        !           305:     // We need to skip segments with no data area (too many bad sectors)
        !           306:     //
        !           307:     while ((Context->CurrentOperation.SegmentBytesRemaining =
        !           308:             q117GoodDataBytes(
        !           309:                 Context->CurrentOperation.CurrentSegment,
        !           310:                 Context)
        !           311:             ) <= 0) {
        !           312: 
        !           313:         ++Context->CurrentOperation.CurrentSegment;
        !           314:     }
        !           315: 
        !           316: 
        !           317:     //
        !           318:     // Use the directorySize field to store the segment that has marks
        !           319:     //
        !           320:     TheVolumeTable->DirectorySize =
        !           321:         (ULONG)Context->CurrentOperation.CurrentSegment++;
        !           322: 
        !           323: #endif
        !           324: 
        !           325:     //
        !           326:     // We need to skip segments with no data area (too many bad sectors)
        !           327:     //
        !           328:     while ((Context->CurrentOperation.SegmentBytesRemaining = q117GoodDataBytes(
        !           329:                                     Context->CurrentOperation.CurrentSegment,
        !           330:                                     Context)) <= 0) {
        !           331:         ++Context->CurrentOperation.CurrentSegment;
        !           332:     }
        !           333: 
        !           334:     TheVolumeTable->StartSegment = Context->CurrentOperation.CurrentSegment;
        !           335:     return(ret);
        !           336: }

unix.superglobalmegacorp.com

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