Annotation of ntddk/src/scsi/qic117/mapbad.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:     mapbad.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     These routines map out bad blocks.
                     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: #define SECTOR_POINTER(i,x)  (((UBYTE *)ioArray[i].Data)+(x)*BYTES_PER_SECTOR)
                     32: 
                     33: void
                     34: q117RotateData(
                     35:     IN OUT PQ117_CONTEXT Context,
                     36:     IN PIO_REQUEST IoArray,
                     37:     IN int IoLast,
                     38:     IN int ShiftAmount
                     39:     );
                     40: 
                     41: 
                     42: STATUS
                     43: q117MapBadBlock (
                     44:     IN PIO_REQUEST IoRequest,
                     45:     OUT PVOID *DataPointer,
                     46:     IN OUT USHORT *BytesLeft,
                     47:     IN OUT SEGMENT *CurrentSegment,
                     48:     IN OUT USHORT *Remainder,
                     49:     IN OUT PQ117_CONTEXT Context
                     50:     )
                     51: 
                     52: /*++
                     53: 
                     54: Routine Description:
                     55: 
                     56:     Moves existing blocks out of bad sector area and into other
                     57:     segments (that already have data in them).
                     58: 
                     59: Arguments:
                     60: 
                     61:     IoRequest -
                     62: 
                     63:     DataPointer -
                     64: 
                     65:     BytesLeft -
                     66: 
                     67:     CurrentSegment -
                     68: 
                     69:     Remainder -
                     70: 
                     71:     Context -
                     72: 
                     73: Return Value:
                     74: 
                     75: 
                     76: 
                     77: --*/
                     78: 
                     79: {
                     80:     IO_REQUEST ioArray[UNIX_MAXBFS];
                     81:     LONG queueItemsUsed;
                     82:     LONG i;
                     83:     UCHAR newBadSectors;
                     84:     UCHAR overflowSectors;
                     85:     LONG cur_bad;
                     86:     ULONG oldBadSectorMap;
                     87:     ULONG currentIndex;
                     88:     LONG ret;
                     89:     SEGMENT currentSegment;
                     90:     USHORT bytesBad;
                     91: 
                     92:     //
                     93:     // get current queue position
                     94:     //
                     95:     currentIndex = q117GetQueueIndex(Context);
                     96: 
                     97:     //
                     98:     // get the current queue list (and clear queue)
                     99:     //
                    100:     queueItemsUsed = 0;
                    101:     ioArray[queueItemsUsed++] = *IoRequest;
                    102:     CheckedDump(QIC117SHOWTD,("Re-mapping: %x ", ioArray[0].Block));
                    103: 
                    104:     while (!q117QueueEmpty(Context)) {
                    105: 
                    106:         ioArray[queueItemsUsed++] = *q117Dequeue(FlushItem, Context);
                    107:         CheckedDump(QIC117SHOWTD,("%x " ,
                    108:             ioArray[queueItemsUsed-1].Block));
                    109: 
                    110:     }
                    111:     CheckedDump(QIC117SHOWTD,("\n"));
                    112: 
                    113:     q117ClearQueue(Context);
                    114: 
                    115:     //
                    116:     // write out current buffer
                    117:     //
                    118:     Context->CurrentOperation.UpdateBadMap = TRUE;
                    119:     bytesBad = overflowSectors = 0;
                    120:     currentSegment = BLOCK_TO_SEGMENT(IoRequest->Block);
                    121:     cur_bad = q117CountBits(Context, currentSegment, 0l);
                    122: 
                    123:     while (newBadSectors = q117CountBits(NULL, 0,
                    124:                         (~(oldBadSectorMap =
                    125:                         q117ReadBadSectorList(Context, currentSegment))) &
                    126:                         ioArray[0].BadList)) {
                    127: 
                    128: 
                    129:         CheckedDump(QIC117SHOWTD | QIC117SHOWBAD,("Current: %x New: %x\n" ,
                    130:             oldBadSectorMap,
                    131:             ioArray[0].BadList
                    132:             ));
                    133: 
                    134:         //
                    135:         // add bits to bad sector map and set global flag to update bad
                    136:         // sector map
                    137:         //
                    138:         ret = q117UpdateBadMap(Context, currentSegment, ioArray[0].BadList);
                    139:         if (ret != NoErr) {
                    140:             return(ret);
                    141:         }
                    142: 
                    143:         //
                    144:         // update total number of mapped out sectors
                    145:         //
                    146:         cur_bad += newBadSectors;
                    147:         bytesBad += newBadSectors * BYTES_PER_SECTOR;
                    148:         overflowSectors += newBadSectors;
                    149: 
                    150:         if (cur_bad+ECC_BLOCKS_PER_SEGMENT >= BLOCKS_PER_SEGMENT) {
                    151:             //
                    152:             // fake a write (because all data blocks are bad)
                    153:             //
                    154:             ioArray[0].BadList = 0;
                    155: 
                    156:         } else {
                    157: 
                    158:             //
                    159:             // move extra data out of the way of correction sectors
                    160:             //
                    161:             CheckedDump(QIC117SHOWTD,("moving %x to %x (%x bytes)\n" ,
                    162:                 DATA_BLOCKS_PER_SEGMENT-cur_bad,
                    163:                 BLOCKS_PER_SEGMENT-overflowSectors,
                    164:                 bytesBad));
                    165: 
                    166:             RtlMoveMemory(
                    167:                 SECTOR_POINTER(0,BLOCKS_PER_SEGMENT-overflowSectors),
                    168:                 SECTOR_POINTER(0,DATA_BLOCKS_PER_SEGMENT-cur_bad),
                    169:                 bytesBad);
                    170: 
                    171:             //
                    172:             // compute error correction and write out smaller chunk of data
                    173:             //
                    174:             q117IssIOReq(
                    175:                 ioArray[0].Data,
                    176:                 DWrite,
                    177:                 ioArray[0].Block,
                    178:                 ioArray[0].BufferInfo,
                    179:                 Context);
                    180: 
                    181:             IoRequest = q117Dequeue(WaitForItem, Context);
                    182: 
                    183:             if (IoRequest->Status && IoRequest->Status != BadBlk) {
                    184:                 return(IoRequest->Status);
                    185:             }
                    186: 
                    187: 
                    188:             //
                    189:             // Get new bad sectors (if any)
                    190:             //
                    191:             ioArray[0].BadList = IoRequest->BadList;
                    192: 
                    193:             //
                    194:             // move data back to contiguous form
                    195:             //
                    196:             CheckedDump(QIC117SHOWTD,("moving %x to %x (%x bytes)\n" ,
                    197:                 BLOCKS_PER_SEGMENT-overflowSectors,
                    198:                 DATA_BLOCKS_PER_SEGMENT-cur_bad,
                    199:                 bytesBad));
                    200: 
                    201:             RtlMoveMemory(
                    202:                 SECTOR_POINTER(0,DATA_BLOCKS_PER_SEGMENT-cur_bad),
                    203:                 SECTOR_POINTER(0,BLOCKS_PER_SEGMENT-overflowSectors),
                    204:                 bytesBad);
                    205:         }
                    206: 
                    207:     } // end of while
                    208: 
                    209:     //
                    210:     // move bytes mapped out into start of current segment
                    211:     //
                    212:     if (cur_bad+ECC_BLOCKS_PER_SEGMENT < BLOCKS_PER_SEGMENT) {
                    213: 
                    214:         CheckedDump(QIC117SHOWTD,("moving %x to %x (%x bytes)\n" ,
                    215:             DATA_BLOCKS_PER_SEGMENT-cur_bad,
                    216:             0,
                    217:             bytesBad));
                    218: 
                    219:         RtlMoveMemory(
                    220:             SECTOR_POINTER(0,0),
                    221:             SECTOR_POINTER(0,DATA_BLOCKS_PER_SEGMENT-cur_bad),
                    222:             bytesBad);
                    223: 
                    224:     }
                    225: 
                    226:     //
                    227:     // We need to skip segments with no data area (less than 4 good segments)
                    228:     //
                    229:     while ((*BytesLeft = q117GoodDataBytes(*CurrentSegment,Context)) <= 0) {
                    230:         ++(*CurrentSegment);
                    231:     }
                    232: 
                    233:     //
                    234:     // if we hit the end of the tape or we are in the directory
                    235:     //
                    236:     if (*CurrentSegment == Context->CurrentOperation.LastSegment) {
                    237:         //
                    238:         // if fill data >= number of new bad sectors then continue
                    239:         //
                    240:         if (Context->CurrentOperation.BytesZeroFilled < bytesBad) {
                    241:             //
                    242:             // update the bad sector map and return BadBlk detected
                    243:             //
                    244:             if (ret = q117DoUpdateBad(Context))
                    245:                 return(ret);
                    246:             else
                    247:                 return(BadBlk);
                    248:         }
                    249:     }
                    250: 
                    251:     //
                    252:     // if insufficient space in next good segment then error out
                    253:     //
                    254:     if (bytesBad > *BytesLeft) {
                    255:         //
                    256:         // update the bad sector map and return BadBlk detected
                    257:         //
                    258:         if (ret = q117DoUpdateBad(Context))
                    259:             return(ret);
                    260:         else
                    261:             return(BadBlk);
                    262:     }
                    263: 
                    264:     //
                    265:     // if more than one item was queued, move all previous data
                    266:     // out of queue 0 and put overflow into queue 0.
                    267:     //
                    268: 
                    269:     if (queueItemsUsed > 1) {
                    270: 
                    271:         //
                    272:         // Rotate the memory through the
                    273:         // buffers leaving the most recent data in the item 0
                    274:         //
                    275:         q117RotateData(
                    276:             Context,
                    277:             ioArray,
                    278:             queueItemsUsed-1,
                    279:             overflowSectors
                    280:             );
                    281:     }
                    282: 
                    283:     //
                    284:     // set current queue position back (and re-queue data)
                    285:     //
                    286:     q117SetQueueIndex(currentIndex, Context);
                    287: 
                    288:     for (i=1;i<queueItemsUsed;++i)
                    289:         q117IssIOReq((PVOID)NULL,DWrite,ioArray[i].Block,NULL,Context);
                    290: 
                    291:     //
                    292:     // set the current data pointer and bytes left in buffer
                    293:     //
                    294: 
                    295:     if (Context->CurrentOperation.BytesZeroFilled) {
                    296: 
                    297:         if (Context->CurrentOperation.BytesZeroFilled >= bytesBad) {
                    298:             Context->CurrentOperation.BytesZeroFilled -= bytesBad;
                    299:             *Remainder = 0;
                    300:         } else {
                    301:             *Remainder = bytesBad - Context->CurrentOperation.BytesZeroFilled;
                    302:         }
                    303: 
                    304:     } else {
                    305: 
                    306:         *Remainder = bytesBad;
                    307: 
                    308:     }
                    309: 
                    310:     *DataPointer = (UCHAR *)ioArray[0].Data + *Remainder;
                    311:     *BytesLeft -= *Remainder;
                    312: 
                    313:     return(NoErr);
                    314: }
                    315: 
                    316: STATUS
                    317: q117UpdateBadMap(
                    318:     IN OUT PQ117_CONTEXT Context,
                    319:     IN SEGMENT Segment,
                    320:     IN ULONG BadSectors
                    321:     )
                    322: 
                    323: /*++
                    324: 
                    325: Routine Description:
                    326: 
                    327:     if bitmap bad sector map, or in bad sectors
                    328:     else
                    329:         make badsectors bitmap into a list of sectors
                    330:         and merge them into the existing bad sector map.
                    331: 
                    332: Arguments:
                    333: 
                    334:     IoRequest -
                    335: 
                    336:     DataPointer -
                    337: 
                    338:     BytesLeft -
                    339: 
                    340:     CurrentSegment -
                    341: 
                    342:     Remainder -
                    343: 
                    344:     Context -
                    345: 
                    346: Return Value:
                    347: 
                    348: 
                    349: 
                    350: --*/
                    351: 
                    352: {
                    353:     BAD_LIST badList[BLOCKS_PER_SEGMENT];
                    354:     ULONG  curSector;
                    355:     ULONG  newSector;
                    356:     USHORT insertionPoint = 0;
                    357:     USHORT listEnd = 0;
                    358:     USHORT currentSectorIndex = 0;
                    359:     UCHAR newCount;
                    360: 
                    361: #if DBG
                    362: 
                    363:     USHORT i,j;
                    364:     ULONG  tmpSector;
                    365: 
                    366: #endif
                    367: 
                    368:     if (Context->CurrentTape.TapeFormatCode == QIC_FORMAT) {
                    369: 
                    370:         Context->CurrentTape.BadMapPtr->BadSectors[Segment] |=
                    371:             BadSectors;
                    372: 
                    373:     } else {
                    374: 
                    375:         newCount = q117CountBits(NULL, 0,
                    376:                         (~(q117ReadBadSectorList(Context, Segment))) &
                    377:                         BadSectors);
                    378: 
                    379:                 CheckedDump(QIC117SHOWBAD,( "UpdateBadMap newCount = %d\n", newCount));
                    380: 
                    381:         // Convert bad sector map (bit field) into a list of sectors
                    382:         // that need to be inserted into the list
                    383:         q117BadMapToBadList(Segment, 
                    384:                                   ((~(q117ReadBadSectorList(Context, Segment))) &
                    385:                         BadSectors), badList);
                    386: 
                    387:         // Get first entry to add
                    388:         newSector = q117BadListEntryToSector(badList[currentSectorIndex].ListEntry);
                    389: 
                    390:         // Get first entry in table
                    391:         curSector = q117BadListEntryToSector(Context->CurrentTape.BadMapPtr->BadList[listEnd++].ListEntry);
                    392: 
                    393:         // While entry in table valid,   and not at end of the list
                    394:         while (curSector && (listEnd < MAX_BAD_LIST) ) {
                    395: 
                    396:             // If entry less than new item,  then increment insertionPoint
                    397:             if (newSector > curSector) {
                    398: 
                    399:                 insertionPoint++;
                    400: 
                    401:             }
                    402: 
                    403:             // Get next sector
                    404:             curSector = q117BadListEntryToSector(Context->CurrentTape.BadMapPtr->BadList[listEnd++].ListEntry);
                    405:         }
                    406: 
                    407:         //
                    408:         // Now,  list end will be the real end of list
                    409:         // and insertionPoint will be the point at which the first
                    410:         // sector int the new sector list needs to be added.
                    411:         //
                    412:         listEnd--;
                    413: 
                    414: #if DBG
                    415: 
                    416:     CheckedDump(QIC117SHOWBAD,( "\n\nQ117 BSL: BSL to add ---\n"));
                    417:          for (i=0; i < newCount; i++) {
                    418:         tmpSector = q117BadListEntryToSector(badList[i].ListEntry);
                    419:              CheckedDump(QIC117SHOWBAD,( "  %08lx",tmpSector));
                    420:                   if (!((i+1) % 5)) {
                    421:                         CheckedDump(QIC117SHOWBAD,( "\n"));
                    422:                   }
                    423:          }
                    424:     CheckedDump(QIC117SHOWBAD,( "\n"));
                    425: 
                    426: #endif
                    427: 
                    428:         // make sure there is enough room for the new items
                    429:         if ((listEnd + newCount) >= MAX_BAD_LIST) {
                    430: 
                    431:             return(UnusTape);
                    432: 
                    433:         }
                    434: 
                    435:         //
                    436:         // While more sectors to merge
                    437:         //
                    438:         while (currentSectorIndex < newCount) {
                    439: 
                    440:             newSector = q117BadListEntryToSector(
                    441:                             badList[currentSectorIndex].ListEntry
                    442:                             );
                    443: 
                    444:             //
                    445:             // get new insertion point (skip any lessor sectors).  First
                    446:             // time through,  this will already be done.
                    447:             //
                    448: 
                    449:             while (insertionPoint <= listEnd) {
                    450: 
                    451:                 //
                    452:                 // Get sector at insertionPoint
                    453:                 //
                    454:                 curSector = q117BadListEntryToSector(
                    455:                             Context->CurrentTape.BadMapPtr->
                    456:                             BadList[insertionPoint].ListEntry
                    457:                             );
                    458: 
                    459:                 //
                    460:                 // if new sector is bigger than the current sector
                    461:                 // get the next one
                    462:                 //
                    463:                 if (newSector > curSector) {
                    464: 
                    465:                     ++insertionPoint;
                    466: 
                    467:                 } else {
                    468: 
                    469:                     // We found our next insertion point
                    470:                     break;
                    471: 
                    472:                 }
                    473: 
                    474:             }
                    475: 
                    476:             //
                    477:             // If the sector we need to add is not the same as the current
                    478:             // sector at the insertionPoint or we are past the end of the
                    479:             // current list,  then we need to add the sector
                    480:             // to the list.
                    481:             // NOTE:  curSector will not be valid at end of list,  but
                    482:             // we don't care.
                    483:             //
                    484: 
                    485:             if (curSector != newSector || insertionPoint > listEnd) {
                    486: 
                    487:                 //
                    488:                 // make space for the new entry (if inserting)
                    489:                 //
                    490:                 if (listEnd >= insertionPoint) {
                    491:                     RtlMoveMemory(
                    492:                         Context->CurrentTape.BadMapPtr->
                    493:                             BadList[insertionPoint+1].ListEntry,
                    494:                         Context->CurrentTape.BadMapPtr->
                    495:                             BadList[insertionPoint].ListEntry,
                    496:                         ((ULONG)(listEnd - insertionPoint + 1)
                    497:                             * LIST_ENTRY_SIZE)
                    498:                         );
                    499: 
                    500:                 }
                    501: 
                    502:                 //
                    503:                 // add the new entry
                    504:                 //
                    505:                 RtlMoveMemory(
                    506:                     Context->CurrentTape.BadMapPtr->
                    507:                         BadList[insertionPoint].ListEntry,
                    508:                     badList[currentSectorIndex].ListEntry,
                    509:                     LIST_ENTRY_SIZE);
                    510: 
                    511:                 ++insertionPoint;
                    512: 
                    513:                 //
                    514:                 // we just made our list bigger
                    515:                 //
                    516:                 ++listEnd;
                    517: 
                    518:             }
                    519: 
                    520:             //
                    521:             // Now get next sector to add
                    522:             //
                    523:             ++currentSectorIndex;
                    524: 
                    525:         }
                    526: 
                    527: #if DBG
                    528: 
                    529:     CheckedDump(QIC117SHOWBAD,( "\n\nQ117 BSL: New BSL ------\n"));
                    530:          for (i=0; i < listEnd; i++) {
                    531:         tmpSector = q117BadListEntryToSector(Context->CurrentTape.BadMapPtr->BadList[i].ListEntry);
                    532:              CheckedDump(QIC117SHOWBAD,( "  %08lx",tmpSector));
                    533:                   if (!((i+1) % 5)) {
                    534:                         CheckedDump(QIC117SHOWBAD,( "\n"));
                    535:                   }
                    536:          }
                    537:         CheckedDump(QIC117SHOWBAD,( "\n"));
                    538: 
                    539: #endif
                    540: 
                    541:     }
                    542: 
                    543:     return(NoErr);
                    544: }
                    545: 
                    546: VOID
                    547: q117BadMapToBadList(
                    548:     IN SEGMENT Segment,
                    549:     IN ULONG BadSectors,
                    550:     IN BAD_LIST_PTR BadListPtr
                    551:     )
                    552: 
                    553: /*++
                    554: 
                    555: Routine Description:
                    556: 
                    557: Arguments:
                    558: 
                    559:     IoRequest -
                    560: 
                    561:     DataPointer -
                    562: 
                    563:     BytesLeft -
                    564: 
                    565:     CurrentSegment -
                    566: 
                    567:     Remainder -
                    568: 
                    569:     Context -
                    570: 
                    571: Return Value:
                    572: 
                    573: 
                    574: 
                    575: --*/
                    576: 
                    577: {
                    578:     USHORT listIndex = 0;
                    579:     ULONG sector;
                    580: 
                    581:     CheckedDump(QIC117SHOWBAD,( "BadMapToList Segment -> %08lx\n",Segment));
                    582:     sector = (ULONG)((Segment * BLOCKS_PER_SEGMENT) + 1);
                    583: 
                    584:     while (BadSectors &&
                    585:             (listIndex < BLOCKS_PER_SEGMENT)) {
                    586: 
                    587:         if (BadSectors & 1l) {
                    588: 
                    589:             BadListPtr[listIndex].ListEntry[0] = (UBYTE)(sector & 0xff);
                    590:             BadListPtr[listIndex].ListEntry[1] = (UBYTE)((sector >> 8) & 0xff);
                    591:             BadListPtr[listIndex].ListEntry[2] = (UBYTE)((sector >> 16) & 0xff);
                    592:                         CheckedDump(QIC117SHOWBAD,( "BadMapToList -> %08lx\n",sector));
                    593:             listIndex++;
                    594: 
                    595:         }
                    596: 
                    597:         sector++;
                    598:         BadSectors >>= 1;
                    599:     }
                    600: 
                    601:     if (listIndex < BLOCKS_PER_SEGMENT) {
                    602: 
                    603:         BadListPtr[listIndex].ListEntry[0] = (UBYTE)0;
                    604:         BadListPtr[listIndex].ListEntry[1] = (UBYTE)0;
                    605:         BadListPtr[listIndex].ListEntry[2] = (UBYTE)0;
                    606: 
                    607:     }
                    608: 
                    609:     return;
                    610: }
                    611: 
                    612: ULONG
                    613: q117BadListEntryToSector(
                    614:     IN UCHAR *ListEntry
                    615:     )
                    616: 
                    617: /*++
                    618: 
                    619: Routine Description:
                    620: 
                    621: Arguments:
                    622: 
                    623:     IoRequest -
                    624: 
                    625:     DataPointer -
                    626: 
                    627:     BytesLeft -
                    628: 
                    629:     CurrentSegment -
                    630: 
                    631:     Remainder -
                    632: 
                    633:     Context -
                    634: 
                    635: Return Value:
                    636: 
                    637: 
                    638: 
                    639: --*/
                    640: 
                    641: {
                    642:     ULONG sector = 0l;
                    643: 
                    644: #ifndef i386
                    645: 
                    646:     sector = (UBYTE)ListEntry[2];
                    647:     sector <<= 8;
                    648:     sector |= (UBYTE)ListEntry[1];
                    649:     sector <<= 8;
                    650:     sector |= (UBYTE)ListEntry[0];
                    651: 
                    652:     return(sector);
                    653: 
                    654: #else
                    655: 
                    656:     return((0x00FFFFFF & *(ULONG *)ListEntry));
                    657: 
                    658: #endif
                    659: 
                    660: }
                    661: 
                    662: void
                    663: q117RotateData(
                    664:     IN OUT PQ117_CONTEXT Context,
                    665:     IN PIO_REQUEST IoArray,
                    666:     IN int IoLast,
                    667:     IN int ShiftAmount
                    668:     )
                    669: /*++
                    670: 
                    671: Routine Description:
                    672: 
                    673:     This routine shifts the data around _ShiftAmount_ times,  by one
                    674:     sector.
                    675: 
                    676:     Sample:
                    677: 
                    678:     IoArray[        0       1       2       3
                    679:     data sector     0 1     2 3 4   5 6 7   8
                    680: 
                    681:     Step 1: data 0 shifted up
                    682: 
                    683:     IoArray[        0       1       2       3
                    684:     data sector     0 0 1   2 3 4   5 6 7   8
                    685:                     s                       d
                    686: 
                    687:     Step 2: source copied to dest
                    688: 
                    689:     IoArray[        0       1       2       3
                    690:     data sector     8 0 1   2 3 4   5 6 7   8
                    691:                                         d   s
                    692: 
                    693:     Step 3: pointers decremented (source wraps) and source copied to dest
                    694: 
                    695:     IoArray[        0       1       2       3
                    696:     data sector     8 0 1   2 3 4   5 6 7   7
                    697:                                       d s
                    698: 
                    699:     Step 4: pointers decremented and source copied to dest
                    700: 
                    701:     IoArray[        0       1       2       3
                    702:     data sector     8 0 1   2 3 4   5 6 6   7
                    703:                                     d s
                    704: 
                    705: 
                    706:     Step 5: pointers decremented and source copied to dest
                    707: 
                    708:     IoArray[        0       1       2       3
                    709:     data sector     8 0 1   2 3 4   5 5 6   7
                    710:                                 d   s
                    711: 
                    712: 
                    713:     Step 6: pointers decremented and source copied to dest
                    714: 
                    715:     IoArray[        0       1       2       3
                    716:     data sector     8 0 1   2 3 4   4 5 6   7
                    717:                               d s
                    718: 
                    719: 
                    720:     Step 7: pointers decremented and source copied to dest
                    721: 
                    722:     IoArray[        0       1       2       3
                    723:     data sector     8 0 1   2 3 3   4 5 6   7
                    724:                             d s
                    725: 
                    726: 
                    727:     Step 8: pointers decremented and source copied to dest
                    728: 
                    729:     IoArray[        0       1       2       3
                    730:     data sector     8 0 1   2 2 3   4 5 6   7
                    731:                         d   s
                    732: 
                    733:     Step 9: pointers decremented and source copied to dest
                    734: 
                    735:     IoArray[        0       1       2       3
                    736:     data sector     8 0 1   1 2 3   4 5 6   7
                    737:                       d s
                    738: 
                    739:     Step 10: pointers decremented and source copied to dest
                    740: 
                    741:     IoArray[        0       1       2       3
                    742:     data sector     8 0 0   1 2 3   4 5 6   7
                    743:                     d s
                    744: 
                    745:     Step 10: pointers decremented and source copied to dest
                    746: 
                    747:     IoArray[        0       1       2       3
                    748:     data sector     8 8 0   1 2 3   4 5 6   7
                    749:                     s                       d
                    750: 
                    751:     Step 11: process starts over at step 2
                    752: 
                    753:     Step 12: data in buffer 0 shifted back down.
                    754: 
                    755: 
                    756: 
                    757: Arguments:
                    758: 
                    759: Return Value:
                    760: 
                    761: 
                    762: 
                    763: --*/
                    764: {
                    765:     UCHAR *finish;
                    766:     UCHAR *source;
                    767:     int sourceSize;
                    768:     int sourceIndex;
                    769:     UCHAR *destination;
                    770:     int destinationSize;
                    771:     int destinationIndex;
                    772:     int loop;
                    773: 
                    774:     //
                    775:     // Shift over by one (possibly into ECC area to allow for a non
                    776:     // destructive rotate.  This will be shifted back after operation
                    777:     //
                    778:     RtlMoveMemory((UCHAR *)IoArray[0].Data + BYTES_PER_SECTOR, IoArray[0].Data,
                    779:         ShiftAmount * BYTES_PER_SECTOR);
                    780: 
                    781:     for (loop = 0; loop < ShiftAmount; ++loop) {
                    782: 
                    783:         //
                    784:         // Begin by overwriting area we just moved out of (see above move)
                    785:         //
                    786: 
                    787:         destination = IoArray[0].Data;
                    788:         destinationSize = BYTES_PER_SECTOR;
                    789:         destinationIndex = 0;
                    790: 
                    791:         //
                    792:         // source points to last sector in queue
                    793:         //
                    794:         sourceIndex = IoLast;
                    795:         sourceSize =
                    796:             q117GoodDataBytes(
                    797:                 BLOCK_TO_SEGMENT(IoArray[sourceIndex].Block),
                    798:                 Context
                    799:                 );
                    800:         source = (UCHAR *)IoArray[sourceIndex].Data + sourceSize
                    801:                     - BYTES_PER_SECTOR;
                    802: 
                    803:         finish = source;
                    804: 
                    805:         do {
                    806: 
                    807:             //
                    808:             // shift the data
                    809:             //
                    810:             CheckedDump(QIC117SHOWTD,("shifting %x-%x[%x]{%x} to %x-%x[%x]\n" ,
                    811:                 sourceIndex, IoArray[sourceIndex].Block,
                    812:                 sourceSize - BYTES_PER_SECTOR,
                    813:                 (ULONG *)source,
                    814:                 destinationIndex,  IoArray[destinationIndex].Block,
                    815:                 destinationSize - BYTES_PER_SECTOR));
                    816: 
                    817:             RtlMoveMemory(destination, source, BYTES_PER_SECTOR);
                    818: 
                    819:             //
                    820:             // Decrement the pointer
                    821:             //
                    822:             destinationSize -= BYTES_PER_SECTOR;
                    823:             destination -= BYTES_PER_SECTOR;
                    824: 
                    825:             if (destinationSize == 0) {
                    826: 
                    827:                 if (destinationIndex == 0) {
                    828: 
                    829:                     destinationIndex = IoLast;
                    830: 
                    831:                 } else {
                    832: 
                    833:                     --destinationIndex;
                    834: 
                    835:                 }
                    836: 
                    837:                 if (destinationIndex == 0) {
                    838: 
                    839:                     destinationSize = (ShiftAmount+1) * BYTES_PER_SECTOR;
                    840: 
                    841:                 } else {
                    842: 
                    843:                     destinationSize =
                    844:                         q117GoodDataBytes(
                    845:                             BLOCK_TO_SEGMENT(IoArray[destinationIndex].Block),
                    846:                             Context
                    847:                             );
                    848: 
                    849:                 }
                    850:                 destination = (UCHAR *)IoArray[destinationIndex].Data
                    851:                             + destinationSize
                    852:                             - BYTES_PER_SECTOR;
                    853:             }
                    854: 
                    855:             //
                    856:             // Decrement the pointer
                    857:             //
                    858:             sourceSize -= BYTES_PER_SECTOR;
                    859:             source -= BYTES_PER_SECTOR;
                    860: 
                    861:             //
                    862:             // If we hit the begining of the buffer,
                    863:             // go to the previous buffer.
                    864:             //
                    865:             if (sourceSize == 0) {
                    866: 
                    867:                 if (sourceIndex == 0) {
                    868: 
                    869:                     sourceIndex = IoLast;
                    870: 
                    871:                 } else {
                    872: 
                    873:                     --sourceIndex;
                    874: 
                    875:                 }
                    876: 
                    877:                 if (sourceIndex == 0) {
                    878: 
                    879:                     sourceSize = (ShiftAmount+1) * BYTES_PER_SECTOR;
                    880: 
                    881:                 } else {
                    882: 
                    883:                     sourceSize =
                    884:                         q117GoodDataBytes(
                    885:                             BLOCK_TO_SEGMENT(IoArray[sourceIndex].Block),
                    886:                             Context
                    887:                             );
                    888: 
                    889:                 }
                    890:                 source = (UCHAR *)IoArray[sourceIndex].Data + sourceSize
                    891:                     - BYTES_PER_SECTOR;
                    892:             }
                    893: 
                    894:         } while (source != finish);
                    895: 
                    896:     }
                    897: 
                    898:     //
                    899:     // move the data back to the start of the buffer
                    900:     //
                    901:     RtlMoveMemory(
                    902:         (UCHAR *)IoArray[0].Data,
                    903:         (UCHAR *)IoArray[0].Data + BYTES_PER_SECTOR,
                    904:         ShiftAmount * BYTES_PER_SECTOR
                    905:         );
                    906: }

unix.superglobalmegacorp.com

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