Annotation of ntddk/src/scsi/qic117/update.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:     update.c
        !             9: 
        !            10: Abstract:
        !            11: 
        !            12:     Performs the various tape updating functions.
        !            13: 
        !            14: Revision History:
        !            15: 
        !            16: 
        !            17: 
        !            18: 
        !            19: --*/
        !            20: 
        !            21: //
        !            22: // include files
        !            23: //
        !            24: 
        !            25: #include <ntddk.h>
        !            26: #include <ntddtape.h>
        !            27: #include "common.h"
        !            28: #include "q117.h"
        !            29: #include "protos.h"
        !            30: 
        !            31: 
        !            32: STATUS
        !            33: q117UpdateHeader(
        !            34:     IN PTAPE_HEADER Header,
        !            35:     IN PQ117_CONTEXT Context
        !            36:     )
        !            37: 
        !            38: /*++
        !            39: 
        !            40: Routine Description:
        !            41: 
        !            42:     This routine updates the tape header.
        !            43: 
        !            44: Arguments:
        !            45: 
        !            46:     Header -
        !            47: 
        !            48:     Context -
        !            49: 
        !            50: Return Value:
        !            51: 
        !            52: 
        !            53: 
        !            54: --*/
        !            55: 
        !            56: {
        !            57:     STATUS ret;
        !            58:     PVOID scrbuf;
        !            59:     PSEGMENT_BUFFER bufferInfo;
        !            60: 
        !            61:     //
        !            62:     // put saved logical part of header into transfer buffer
        !            63:     //
        !            64:     scrbuf = q117GetFreeBuffer(&bufferInfo,Context);
        !            65:     RtlMoveMemory(scrbuf, Header, sizeof(TAPE_HEADER));
        !            66: 
        !            67:     //
        !            68:     // write out the TapeHeader structure
        !            69:     //
        !            70:     ret = q117FillTapeBlocks(
        !            71:                 DWriteBad,
        !            72:                 (SEGMENT)0,
        !            73:                 Header->DupHeaderSegment,
        !            74:                 scrbuf,
        !            75:                 Header->HeaderSegment,
        !            76:                 Header->DupHeaderSegment,
        !            77:                 bufferInfo,
        !            78:                 Context);
        !            79:     return(ret);
        !            80: }
        !            81: 
        !            82: STATUS
        !            83: q117Update(
        !            84:     IN OUT PQ117_CONTEXT Context
        !            85:     )
        !            86: 
        !            87: /*++
        !            88: 
        !            89: Routine Description:
        !            90: 
        !            91:     This routine updates tape directory with cur_vol.
        !            92: 
        !            93: Arguments:
        !            94: 
        !            95:     Link -
        !            96: 
        !            97:     Context -
        !            98: 
        !            99: Return Value:
        !           100: 
        !           101: 
        !           102: 
        !           103: --*/
        !           104: {
        !           105:     STATUS ret;     // Return value from other routines called.
        !           106: 
        !           107:     Context->ActiveVolume.DataSize = Context->CurrentOperation.BytesOnTape;
        !           108: 
        !           109:     //
        !           110:     // update volume table entry (to be written to tape directory)
        !           111:     //
        !           112:     Context->ActiveVolume.EndingSegment = (USHORT)Context->CurrentOperation.CurrentSegment-1;
        !           113: 
        !           114: 
        !           115:     if (Context->CurrentOperation.UpdateBadMap) {
        !           116:         if (ret = q117DoUpdateBad(Context))
        !           117:             return(ret);
        !           118:     }
        !           119: 
        !           120:     //
        !           121:     // update volume directory
        !           122:     //
        !           123:     // thevoldir->endblock was set to 0 at StartBack().
        !           124:     //
        !           125:     ret=q117AppVolTD(&Context->ActiveVolume,Context);
        !           126:     if (ret==NoErr)  {
        !           127:         Context->CurrentOperation.EndOfUsedTape = Context->ActiveVolume.EndingSegment;
        !           128: #ifndef NO_MARKS
        !           129:         ret = q117DoUpdateMarks(Context);
        !           130: #endif
        !           131:     } else {
        !           132:         Context->CurrentOperation.EndOfUsedTape=0;
        !           133:     }
        !           134: 
        !           135:     //
        !           136:     // Set the tape status.
        !           137:     //
        !           138:     q117SetTpSt(Context);
        !           139:     return(ret);
        !           140: }
        !           141: 
        !           142: 
        !           143: STATUS
        !           144: q117DoUpdateBad(
        !           145:     IN OUT PQ117_CONTEXT Context
        !           146:     )
        !           147: 
        !           148: /*++
        !           149: 
        !           150: Routine Description:
        !           151: 
        !           152: 
        !           153: 
        !           154: Arguments:
        !           155: 
        !           156:     Context -
        !           157: 
        !           158: Return Value:
        !           159: 
        !           160: 
        !           161: 
        !           162: --*/
        !           163: {
        !           164:     STATUS ret;
        !           165:     PVOID scrbuf;
        !           166:     PSEGMENT_BUFFER bufferInfo;
        !           167:     PTAPE_HEADER hdr;
        !           168: 
        !           169:     //
        !           170:     //rdr - Beta fix
        !           171:     //
        !           172: 
        !           173: //    return(BadTape);
        !           174: 
        !           175:     CheckedDump(QIC117INFO,( "Q117i: Starting DoUpdateBad\n"));
        !           176: 
        !           177: 
        !           178:     //
        !           179:     // read the header segment in
        !           180:     //
        !           181:     //if (ret = q117ReadHeaderSegment(&hdr,Context)) {
        !           182:     //
        !           183:     //    return(ret);
        !           184:     //
        !           185:     //}
        !           186:     hdr = Context->CurrentTape.TapeHeader;
        !           187: 
        !           188:     //
        !           189:     // put in the new bad sector map
        !           190:     //
        !           191: 
        !           192:     //RtlMoveMemory(&(hdr->BadMap),
        !           193:     //    Context->CurrentTape.BadMapPtr,
        !           194:     //    sizeof(BAD_MAP));
        !           195: 
        !           196:     scrbuf = q117GetFreeBuffer(&bufferInfo,Context);
        !           197: 
        !           198:     //
        !           199:     // put saved logical part of header into transfer buffer
        !           200:     //
        !           201: 
        !           202:     RtlMoveMemory(scrbuf, hdr, sizeof(TAPE_HEADER));
        !           203: 
        !           204:     //
        !           205:     // write out the TapeHeader structure
        !           206:     //
        !           207: 
        !           208:     if ( ret = q117FillTapeBlocks(
        !           209:                 DWriteBad,
        !           210:                 (SEGMENT)0,
        !           211:                 hdr->DupHeaderSegment,
        !           212:                 scrbuf,
        !           213:                 hdr->HeaderSegment,
        !           214:                 hdr->DupHeaderSegment,
        !           215:                 bufferInfo,
        !           216:                 Context) ) {
        !           217: 
        !           218:         return(UpdErr);
        !           219: 
        !           220:     }
        !           221: 
        !           222:     //
        !           223:     // tape directory potentialy corrupted by FillTapeBlocks(), so just
        !           224:     // re-read it
        !           225:     //
        !           226:     Context->tapedir = (PIO_REQUEST)NULL;
        !           227: 
        !           228:     CheckedDump(QIC117INFO,( "Q117i: Ending DoUpdateBad (Success)\n"));
        !           229:     return(NoErr);
        !           230: }
        !           231: 
        !           232: #ifndef NO_MARKS
        !           233: 
        !           234: STATUS
        !           235: q117DoUpdateMarks(
        !           236:     IN OUT PQ117_CONTEXT Context
        !           237:     )
        !           238: 
        !           239: /*++
        !           240: 
        !           241: Routine Description:
        !           242: 
        !           243: 
        !           244: 
        !           245: Arguments:
        !           246: 
        !           247:     Context -
        !           248: 
        !           249: Return Value:
        !           250: 
        !           251: 
        !           252: 
        !           253: --*/
        !           254: {
        !           255:     STATUS ret;
        !           256:     PSEGMENT_BUFFER bufferInfo;
        !           257:     PVOID scrbuf;
        !           258:     PIO_REQUEST ioreq;
        !           259: 
        !           260: 
        !           261:     scrbuf = q117GetFreeBuffer(&bufferInfo,Context);
        !           262: 
        !           263:     //
        !           264:     // Fill in the mark list
        !           265:     //
        !           266:     RtlZeroMemory(scrbuf,
        !           267:         q117GoodDataBytes(
        !           268:             (SEGMENT)Context->ActiveVolume.DirectorySize, Context )
        !           269:         );
        !           270: 
        !           271:     RtlMoveMemory(scrbuf, &Context->MarkArray, sizeof(Context->MarkArray));
        !           272: 
        !           273:     ret=q117IssIOReq(scrbuf,DWrite,
        !           274:         Context->ActiveVolume.DirectorySize * BLOCKS_PER_SEGMENT,bufferInfo,Context);
        !           275: 
        !           276:     if (!ret) {
        !           277:         //
        !           278:         // Wait for data to be written
        !           279:         //
        !           280:         ioreq=q117Dequeue(WaitForItem,Context);
        !           281: 
        !           282:         ret = ioreq->Status;
        !           283: 
        !           284:     }
        !           285: 
        !           286:     return(ret);
        !           287: }
        !           288: 
        !           289: STATUS
        !           290: q117GetMarks(
        !           291:     IN OUT PQ117_CONTEXT Context
        !           292:     )
        !           293: 
        !           294: /*++
        !           295: 
        !           296: Routine Description:
        !           297: 
        !           298: 
        !           299: 
        !           300: Arguments:
        !           301: 
        !           302:     Context -
        !           303: 
        !           304: Return Value:
        !           305: 
        !           306: 
        !           307: 
        !           308: --*/
        !           309: {
        !           310:     STATUS ret;
        !           311:     PSEGMENT_BUFFER bufferInfo;
        !           312:     PVOID scrbuf;
        !           313:     PIO_REQUEST ioreq;
        !           314: 
        !           315: 
        !           316:     scrbuf = q117GetFreeBuffer(&bufferInfo,Context);
        !           317: 
        !           318:     //
        !           319:     // Read this data block into memory
        !           320:     //
        !           321:     ret=q117IssIOReq(scrbuf,DRead,
        !           322:         Context->ActiveVolume.DirectorySize * BLOCKS_PER_SEGMENT,bufferInfo,Context);
        !           323: 
        !           324:     if (!ret) {
        !           325:         // Wait for data to be read
        !           326:         ioreq=q117Dequeue(WaitForItem,Context);
        !           327: 
        !           328:         if (ioreq->Status != BadBlk && ioreq->Status) {
        !           329: 
        !           330:             ret = ioreq->Status;
        !           331: 
        !           332:         } else {
        !           333: 
        !           334:             /* correct data segment with Reed-Solomon and Heroic retries */
        !           335:             ret = q117ReconstructSegment(ioreq,Context);
        !           336:         }
        !           337: 
        !           338:         if (!ret) {
        !           339:             RtlMoveMemory(&Context->MarkArray, scrbuf, sizeof(Context->MarkArray));
        !           340:         }
        !           341: 
        !           342:     }
        !           343: 
        !           344:     return(ret);
        !           345: }
        !           346: #endif
        !           347: 
        !           348: STATUS
        !           349: q117FillTapeBlocks(
        !           350:     IN OUT DRIVER_COMMAND Command,
        !           351:     IN SEGMENT CurrentSegment,
        !           352:     IN SEGMENT EndSegment,
        !           353:     IN OUT PVOID Buffer,
        !           354:     IN SEGMENT FirstGood,
        !           355:     IN SEGMENT SecondGood,
        !           356:     IN PSEGMENT_BUFFER BufferInfo,
        !           357:     IN PQ117_CONTEXT Context
        !           358:     )
        !           359: 
        !           360: /*++
        !           361: 
        !           362: Routine Description:
        !           363: 
        !           364: 
        !           365: 
        !           366: Arguments:
        !           367: 
        !           368:     Command -
        !           369: 
        !           370:     CurrentSegment -
        !           371: 
        !           372:     EndSegment -
        !           373: 
        !           374:     Buffer -
        !           375: 
        !           376:     FirstGood -
        !           377: 
        !           378:     SecondGood -
        !           379: 
        !           380:     BufferInfo -
        !           381: 
        !           382:     Context -
        !           383: 
        !           384: Return Value:
        !           385: 
        !           386: 
        !           387: 
        !           388: --*/
        !           389: {
        !           390:     STATUS ret;
        !           391:     CHAR iocmd;
        !           392:     PIO_REQUEST ioreq;
        !           393:     ULONG cur_seg = 0;     // The current segment being processed
        !           394:     BAD_LIST badList[BLOCKS_PER_SEGMENT];
        !           395:     ULONG listEntry;
        !           396:     USHORT listIndex;
        !           397: 
        !           398:     //
        !           399:     // set queue into single buffer mode
        !           400:     //
        !           401:     q117QueueSingle(Context);
        !           402: 
        !           403:     //
        !           404:     // get pointer to free buffer
        !           405:     //
        !           406:     if (Buffer == NULL) {
        !           407:         Buffer = q117GetFreeBuffer(&BufferInfo,Context);
        !           408:     }
        !           409: 
        !           410:     do {
        !           411:         while(!q117QueueFull(Context) && CurrentSegment <= EndSegment) {
        !           412:             if (Command == DWriteBad && (CurrentSegment == FirstGood || CurrentSegment == SecondGood)) {
        !           413:                 iocmd = DWrite;
        !           414:             } else {
        !           415:                 iocmd = Command;
        !           416:             }
        !           417: 
        !           418:             //
        !           419:             // We need to skip segments with no data area (less than 4
        !           420:             // good segments)
        !           421:             //
        !           422:             while (q117GoodDataBytes(CurrentSegment,Context) <= 0) {
        !           423:                 ++CurrentSegment;
        !           424:             }
        !           425:             if (ret=q117IssIOReq(Buffer,iocmd,(LONG)CurrentSegment * BLOCKS_PER_SEGMENT,BufferInfo,Context)) {
        !           426: 
        !           427:                 return(ret);
        !           428:             }
        !           429:             ++CurrentSegment;
        !           430:         }
        !           431: 
        !           432:         ioreq = q117Dequeue(WaitForItem,Context);
        !           433: 
        !           434:         if ((ioreq->Status!=NoErr) &&
        !           435:             (ioreq->Status!=BadBlk) &&
        !           436:             (ioreq->Status!=BadMark)) {
        !           437: 
        !           438:             //
        !           439:             // Any Driver error except BadBlk.
        !           440:             //
        !           441:             return(ioreq->Status);
        !           442:         }
        !           443:         if (Command == DVerify) {
        !           444: 
        !           445:             if (Context->CurrentTape.TapeFormatCode == QIC_FORMAT) {
        !           446: 
        !           447:                 Context->CurrentTape.BadMapPtr->BadSectors[(ioreq->Block)/BLOCKS_PER_SEGMENT] =
        !           448:                     ioreq->BadList|ioreq->RetryList;
        !           449: 
        !           450:             } else {
        !           451: 
        !           452:                 if ((ioreq->BadList|ioreq->RetryList) != 0l) {
        !           453: 
        !           454:                     q117BadMapToBadList(
        !           455:                         (SEGMENT)((ioreq->Block)/BLOCKS_PER_SEGMENT),
        !           456:                         (ioreq->BadList | ioreq->RetryList),
        !           457:                         badList);
        !           458: 
        !           459:                     listIndex = 0;
        !           460: 
        !           461:                     do {
        !           462: 
        !           463:                         RtlMoveMemory(
        !           464:                             Context->CurrentTape.BadMapPtr->BadList[Context->CurrentTape.CurBadListIndex++].ListEntry,
        !           465:                             badList[listIndex++].ListEntry,
        !           466:                             (ULONG)LIST_ENTRY_SIZE);
        !           467: 
        !           468:                         listEntry = q117BadListEntryToSector(badList[listIndex].ListEntry);
        !           469: 
        !           470:                     } while (listEntry &&
        !           471:                             (listIndex < BLOCKS_PER_SEGMENT));
        !           472: 
        !           473:                 }
        !           474: 
        !           475:             }
        !           476: 
        !           477:         }
        !           478: 
        !           479:     //
        !           480:     // Till nothing left in the queue.
        !           481:     //
        !           482:     } while (!q117QueueEmpty(Context) || CurrentSegment <= EndSegment);
        !           483: 
        !           484:     q117QueueNormal(Context);
        !           485:     return(NoErr);
        !           486: }

unix.superglobalmegacorp.com

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