Annotation of ntddk/src/scsi/qic117/stbk.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:     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.