|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1992 Microsoft Corporation ! 4: ! 5: Module Name: ! 6: ! 7: physlogi.c ! 8: ! 9: Abstract: ! 10: ! 11: This module contains functions used specifically by tape drivers. ! 12: It contains functions that do physical to pseudo-logical and pseudo- ! 13: logical to physical tape block address/position translation. ! 14: ! 15: Author: ! 16: ! 17: Mike Colandreo (Maynard) ! 18: ! 19: Environment: ! 20: ! 21: kernel mode only ! 22: ! 23: Revision History: ! 24: ! 25: --*/ ! 26: ! 27: #include "ntddk.h" ! 28: #include "tape.h" ! 29: #include "physlogi.h" ! 30: ! 31: // ! 32: // defines for various QIC physical tape format constants ! 33: // ! 34: ! 35: #define QIC_150_BOT_OFFSET 2 ! 36: #define QIC_525_PSEUDO_PHYSICAL_BLOCK_SIZE 512 ! 37: #define QIC_525_PHYSICAL_BLOCK_SIZE 1024 ! 38: #define QIC_525_DATA_BLKS_PER_FRAME 14 ! 39: #define QIC_525_ECC_BLKS_PER_FRAME 2 ! 40: #define QIC_525_BLKS_PER_FRAME 16 ! 41: #define QIC_525_BOT_OFFSET 16 ! 42: #define QIC_1350_PHYSICAL_BLOCK_SIZE 512 ! 43: #define QIC_1350_DATA_BLKS_PER_FRAME 52 ! 44: #define QIC_1350_ECC_BLKS_PER_FRAME 12 ! 45: #define QIC_1350_BLKS_PER_FRAME 64 ! 46: #define QIC_1350_BOT_OFFSET 64 ! 47: ! 48: ! 49: ULONG ! 50: TapePhysicalBlockToLogicalBlock( ! 51: IN UCHAR DensityCode, ! 52: IN ULONG PhysicalBlockAddress, ! 53: IN ULONG BlockLength, ! 54: IN BOOLEAN FromBOT ! 55: ) ! 56: ! 57: /*++ ! 58: Routine Description: ! 59: ! 60: This routine will translate from a QIC physical tape format ! 61: specific physical/absolute block address to a pseudo-logical ! 62: block address. ! 63: ! 64: Arguments: ! 65: ! 66: DensityCode // tape media density code ! 67: PhysicalBlockAddress // tape format specific tape block address ! 68: BlockLength // mode select/sense block length setting ! 69: FromBOT // true/false - translate from BOT ! 70: ! 71: Return Value: ! 72: ! 73: ULONG ! 74: ! 75: --*/ ! 76: ! 77: { ! 78: ULONG logicalBlockAddress; ! 79: ULONG frames; ! 80: ! 81: ! 82: logicalBlockAddress = PhysicalBlockAddress; ! 83: ! 84: switch ( DensityCode ) { ! 85: case 0: ! 86: logicalBlockAddress = 0xFFFFFFFF; ! 87: break; ! 88: ! 89: case QIC_24: ! 90: logicalBlockAddress--; ! 91: break; ! 92: ! 93: case QIC_120: ! 94: logicalBlockAddress--; ! 95: break; ! 96: ! 97: case QIC_150: ! 98: if (FromBOT) { ! 99: if (logicalBlockAddress > QIC_150_BOT_OFFSET) { ! 100: logicalBlockAddress -= QIC_150_BOT_OFFSET; ! 101: } else { ! 102: logicalBlockAddress = 0; ! 103: } ! 104: } else { ! 105: logicalBlockAddress--; ! 106: } ! 107: break; ! 108: ! 109: case QIC_525: ! 110: case QIC_1000: ! 111: case QIC_2GB: ! 112: if (FromBOT && (logicalBlockAddress >= QIC_525_BOT_OFFSET)) { ! 113: logicalBlockAddress -= QIC_525_BOT_OFFSET; ! 114: } ! 115: if (logicalBlockAddress != 0) { ! 116: frames = logicalBlockAddress/QIC_525_BLKS_PER_FRAME; ! 117: logicalBlockAddress -= QIC_525_ECC_BLKS_PER_FRAME*frames; ! 118: switch (BlockLength) { ! 119: case QIC_525_PHYSICAL_BLOCK_SIZE: ! 120: break; ! 121: ! 122: case QIC_525_PSEUDO_PHYSICAL_BLOCK_SIZE: ! 123: logicalBlockAddress *= 2; ! 124: break; ! 125: ! 126: default: ! 127: if (BlockLength > QIC_525_PHYSICAL_BLOCK_SIZE) { ! 128: if ((BlockLength%QIC_525_PHYSICAL_BLOCK_SIZE) == 0) { ! 129: logicalBlockAddress /= ! 130: BlockLength/QIC_525_PHYSICAL_BLOCK_SIZE; ! 131: } else { ! 132: logicalBlockAddress /= ! 133: 1+(BlockLength/QIC_525_PHYSICAL_BLOCK_SIZE); ! 134: } ! 135: } ! 136: break; ! 137: } ! 138: } ! 139: break; ! 140: ! 141: case QIC_1350: ! 142: case QIC_2100: ! 143: if (FromBOT && (logicalBlockAddress >= QIC_1350_BOT_OFFSET)) { ! 144: logicalBlockAddress -= QIC_1350_BOT_OFFSET; ! 145: } ! 146: if (logicalBlockAddress != 0) { ! 147: frames = logicalBlockAddress/QIC_1350_BLKS_PER_FRAME; ! 148: logicalBlockAddress -= QIC_1350_ECC_BLKS_PER_FRAME*frames; ! 149: if (BlockLength > QIC_1350_PHYSICAL_BLOCK_SIZE) { ! 150: if ((BlockLength%QIC_1350_PHYSICAL_BLOCK_SIZE) == 0) { ! 151: logicalBlockAddress /= ! 152: BlockLength/QIC_1350_PHYSICAL_BLOCK_SIZE; ! 153: } else { ! 154: logicalBlockAddress /= ! 155: 1+(BlockLength/QIC_1350_PHYSICAL_BLOCK_SIZE); ! 156: } ! 157: } ! 158: } ! 159: break; ! 160: } ! 161: ! 162: return logicalBlockAddress; ! 163: ! 164: } // end TapePhysicalBlockToLogicalBlock() ! 165: ! 166: ! 167: TAPE_PHYS_POSITION ! 168: TapeLogicalBlockToPhysicalBlock( ! 169: IN UCHAR DensityCode, ! 170: IN ULONG LogicalBlockAddress, ! 171: IN ULONG BlockLength, ! 172: IN BOOLEAN FromBOT ! 173: ) ! 174: ! 175: /*++ ! 176: Routine Description: ! 177: ! 178: This routine will translate from a pseudo-logical block address ! 179: to a QIC physical tape format specific physical/absolute block ! 180: address and (space) block delta. ! 181: ! 182: Arguments: ! 183: ! 184: DensityCode // tape media density code ! 185: LogicalBlockAddress // pseudo-logical tape block address ! 186: BlockLength // mode select/sense block length setting ! 187: FromBOT // true/false - translate from BOT ! 188: ! 189: Return Value: ! 190: ! 191: TAPE_PHYS_POSITION info/structure ! 192: ! 193: --*/ ! 194: ! 195: { ! 196: TAPE_PHYS_POSITION physPosition; ! 197: ULONG physicalBlockAddress; ! 198: ULONG remainder = 0; ! 199: ULONG frames; ! 200: ! 201: ! 202: physicalBlockAddress = LogicalBlockAddress; ! 203: ! 204: switch ( DensityCode ) { ! 205: case 0: ! 206: physicalBlockAddress = 0xFFFFFFFF; ! 207: break; ! 208: ! 209: case QIC_24: ! 210: physicalBlockAddress++; ! 211: break; ! 212: ! 213: case QIC_120: ! 214: physicalBlockAddress++; ! 215: break; ! 216: ! 217: case QIC_150: ! 218: if (FromBOT) { ! 219: physicalBlockAddress += QIC_150_BOT_OFFSET; ! 220: } else { ! 221: physicalBlockAddress++; ! 222: } ! 223: break; ! 224: ! 225: case QIC_525: ! 226: case QIC_1000: ! 227: case QIC_2GB: ! 228: if (physicalBlockAddress != 0) { ! 229: switch (BlockLength) { ! 230: case QIC_525_PHYSICAL_BLOCK_SIZE: ! 231: break; ! 232: ! 233: case QIC_525_PSEUDO_PHYSICAL_BLOCK_SIZE: ! 234: remainder = physicalBlockAddress & 0x00000001; ! 235: physicalBlockAddress >>= 1; ! 236: break; ! 237: ! 238: default: ! 239: if (BlockLength > QIC_525_PHYSICAL_BLOCK_SIZE) { ! 240: if ((BlockLength%QIC_525_PHYSICAL_BLOCK_SIZE) == 0) { ! 241: physicalBlockAddress *= ! 242: BlockLength/QIC_525_PHYSICAL_BLOCK_SIZE; ! 243: } else { ! 244: physicalBlockAddress *= ! 245: 1+(BlockLength/QIC_525_PHYSICAL_BLOCK_SIZE); ! 246: } ! 247: } ! 248: break; ! 249: ! 250: } ! 251: frames = physicalBlockAddress/QIC_525_DATA_BLKS_PER_FRAME; ! 252: physicalBlockAddress += QIC_525_ECC_BLKS_PER_FRAME*frames; ! 253: } ! 254: if (FromBOT) { ! 255: physicalBlockAddress += QIC_525_BOT_OFFSET; ! 256: } ! 257: break; ! 258: ! 259: case QIC_1350: ! 260: case QIC_2100: ! 261: if (physicalBlockAddress != 0) { ! 262: if (BlockLength > QIC_1350_PHYSICAL_BLOCK_SIZE) { ! 263: if ((BlockLength%QIC_1350_PHYSICAL_BLOCK_SIZE) == 0) { ! 264: physicalBlockAddress *= ! 265: BlockLength/QIC_1350_PHYSICAL_BLOCK_SIZE; ! 266: } else { ! 267: physicalBlockAddress *= ! 268: 1+(BlockLength/QIC_1350_PHYSICAL_BLOCK_SIZE); ! 269: } ! 270: } ! 271: frames = physicalBlockAddress/QIC_1350_DATA_BLKS_PER_FRAME; ! 272: physicalBlockAddress += QIC_1350_ECC_BLKS_PER_FRAME*frames; ! 273: } ! 274: if (FromBOT) { ! 275: physicalBlockAddress += QIC_1350_BOT_OFFSET; ! 276: } ! 277: break; ! 278: } ! 279: ! 280: physPosition.SeekBlockAddress = physicalBlockAddress; ! 281: physPosition.SpaceBlockCount = remainder; ! 282: ! 283: return physPosition; ! 284: ! 285: } // end TapeLogicalBlockToPhysicalBlock()
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.