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