|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.