|
|
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.