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