|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
4: All Rights Reserved
5:
6: Module Name:
7:
8: queue.c
9:
10: Abstract:
11:
12: Queue management routines.
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 NEXT_QUEUE_ITEM(a) (((a)+1)%Context->SegmentBuffersAvailable)
32:
33: #define PREV_QUEUE_ITEM(a) ((((a)+Context->SegmentBuffersAvailable)-1) \
34: %Context->SegmentBuffersAvailable)
35:
36:
37:
38: STATUS
39: q117IssIOReq(
40: IN OUT PVOID Data,
41: IN DRIVER_COMMAND Command,
42: IN LONG Block,
43: IN OUT PSEGMENT_BUFFER BufferInfo,
44: IN OUT PQ117_CONTEXT Context
45: )
46:
47: /*++
48:
49: Routine Description:
50:
51: Calls a driver operation and handles IO buffer.
52:
53: Arguments:
54:
55: Data - if not NULL, pointer to operation data.
56:
57: Command - driver command to execute.
58:
59: Block - if applicable, tape block to work on.
60:
61: BufferInfo -
62:
63: Context -
64:
65: Return Value:
66:
67:
68:
69: --*/
70:
71: {
72: PIO_REQUEST ioreq; // Pointer to IORequest
73: UCHAR goodSectors;
74: STATUS ret; // Return value from other routines called.
75: LONG curreq;
76:
77: Context->tapedir = NULL;
78:
79: //
80: // if queue empty, set queue to start where we left off
81: //
82: if (Context->QueueTailIndex==0xffffffff) {
83: Context->QueueTailIndex=Context->QueueHeadIndex;
84: } else {
85: //
86: // Go to the next IORequest.
87: //
88: Context->QueueTailIndex=NEXT_QUEUE_ITEM(Context->QueueTailIndex);
89: if (Context->QueueTailIndex==Context->QueueHeadIndex) {
90: return(FCodeErr);
91: }
92: }
93:
94: curreq = Context->QueueTailIndex;
95:
96: //
97: // Get needed request pointers.
98: //
99: ioreq = (PIO_REQUEST)&Context->IoRequest[curreq];
100:
101: if (Data) {
102:
103: ioreq->Data = Data;
104:
105: } else {
106:
107: ioreq->Data = Context->SegmentBuffer[curreq].logical;
108: BufferInfo = &Context->SegmentBuffer[curreq];
109:
110: }
111:
112: ioreq->Command = Command;
113:
114: //
115: // If the command is a read or write operation
116: //
117: if ( Command == DRead || Command == DWrite || Command == DVerify ||
118: Command == DWriteBad || Command == DReadBad ) {
119:
120: ioreq->BadList = q117ReadBadSectorList(Context, (SEGMENT)(Block/BLOCKS_PER_SEGMENT));
121: ioreq->Number=BLOCKS_PER_SEGMENT;
122:
123: } else {
124:
125: ioreq->BadList=0xfffffffel;
126: ioreq->Number=1;
127:
128: }
129:
130: ioreq->RetryList = 0;
131: ioreq->Block = Block;
132:
133: goodSectors = (UCHAR) (BLOCKS_PER_SEGMENT -
134: q117CountBits(NULL, 0, ioreq->BadList));
135:
136: if (Command == DWrite) {
137: q117RdsMakeCRC(ioreq->Data, goodSectors);
138: }
139:
140: ret = q117ReqIO(ioreq, BufferInfo,Context);
141:
142: return(ret);
143: }
144:
145:
146: BOOLEAN
147: q117QueueFull(
148: IN PQ117_CONTEXT Context
149: )
150:
151: /*++
152:
153: Routine Description:
154:
155: Checks for a full filer queue.
156:
157: Arguments:
158:
159: Context -
160:
161: Return Value:
162:
163:
164:
165: --*/
166:
167: {
168: if (Context->QueueTailIndex == 0xffffffff) {
169: return(FALSE);
170: }
171: return(NEXT_QUEUE_ITEM(Context->QueueTailIndex) == Context->QueueHeadIndex);
172: }
173:
174:
175: BOOLEAN
176: q117QueueEmpty(
177: IN PQ117_CONTEXT Context
178: )
179:
180: /*++
181:
182: RoutineDescription:
183:
184: Empties the filer queue.
185:
186: Arguments:
187:
188: Context -
189:
190: Return Value:
191:
192:
193:
194: --*/
195:
196: {
197: return(Context->QueueTailIndex == 0xffffffff);
198: }
199:
200:
201: PVOID
202: q117GetFreeBuffer(
203: OUT PSEGMENT_BUFFER *BufferInfo,
204: IN PQ117_CONTEXT Context
205: )
206:
207: /*++
208:
209: Routine Description:
210:
211: Gets a filer buffer.
212:
213: Arguments:
214:
215: BufferInfo -
216:
217: Context -
218:
219: Return Value:
220:
221:
222:
223: --*/
224:
225: {
226: LONG index;
227:
228: if (Context->QueueTailIndex == 0xffffffff) {
229: index = Context->QueueHeadIndex;
230: } else {
231: index = NEXT_QUEUE_ITEM(Context->QueueTailIndex);
232: }
233:
234: if (BufferInfo != NULL) {
235: *BufferInfo = &Context->SegmentBuffer[index];
236: }
237: return(Context->SegmentBuffer[index].logical);
238: }
239:
240:
241: PVOID
242: q117GetLastBuffer(
243: IN PQ117_CONTEXT Context
244: )
245:
246: /*++
247:
248: Routine Description:
249:
250: Gets the last buffer that was operated upon.
251:
252: Arguments:
253:
254: Context -
255:
256: Return Value:
257:
258:
259:
260: --*/
261:
262: {
263: return(Context->SegmentBuffer[PREV_QUEUE_ITEM(Context->QueueHeadIndex)].logical);
264: }
265:
266:
267: PIO_REQUEST
268: q117Dequeue(
269: IN DEQUEUE_TYPE Type,
270: IN OUT PQ117_CONTEXT Context
271: )
272:
273: /*++
274:
275: Routine Description:
276:
277: Waits for a driver command to complete.
278:
279: Arguments:
280:
281: Type -
282:
283: Context -
284:
285: Return Value:
286:
287:
288:
289: --*/
290:
291: {
292: LONG ioreq;
293:
294: ioreq = Context->QueueHeadIndex;
295: if (Type == WaitForItem) {
296: q117WaitIO((PIO_REQUEST)&Context->IoRequest[ioreq],Context);
297: }
298:
299: //
300: // There is only 1 item in the queue.
301: //
302: if (Context->QueueHeadIndex==Context->QueueTailIndex) {
303: Context->QueueTailIndex=0xffffffff;
304: }
305: Context->QueueHeadIndex=NEXT_QUEUE_ITEM(Context->QueueHeadIndex);
306:
307: return((PIO_REQUEST)&Context->IoRequest[ioreq]);
308: }
309:
310:
311: VOID
312: q117ClearQueue(
313: IN OUT PQ117_CONTEXT Context
314: )
315:
316: /*++
317:
318: Routine Description:
319:
320: Reinitializes the driver and the queue.
321:
322: Arguments:
323:
324: Context -
325:
326: Return Value:
327:
328: None
329:
330: --*/
331:
332: {
333: KEVENT done_event;
334: IO_STATUS_BLOCK ioSTATUS;
335:
336: q117AbortIo(Context,&done_event, &ioSTATUS);
337:
338: while(!q117QueueEmpty(Context)) {
339:
340: q117Dequeue(WaitForItem, Context);
341:
342: }
343:
344: q117AbortIoDone(Context,&done_event);
345:
346: Context->QueueTailIndex=0xffffffff;
347: }
348:
349:
350: VOID
351: q117QueueSingle(
352: IN OUT PQ117_CONTEXT Context
353: )
354:
355: /*++
356:
357: Routine Description:
358:
359: Switches to a single request queue.
360:
361: Arguments:
362:
363: Context -
364:
365: Return Value:
366:
367: None.
368:
369: --*/
370:
371: {
372: //
373: // Set number of requests to maximum.
374: //
375: Context->QueueTailIndex=0xffffffff;
376: Context->QueueHeadIndex=0;
377: }
378:
379:
380: VOID
381: q117QueueNormal(
382: IN OUT PQ117_CONTEXT Context
383: )
384:
385: /*++
386:
387: Routine Description:
388:
389: Switches to the normal queue.
390:
391: Arguments:
392:
393: Context -
394:
395: Return Value:
396:
397: None.
398:
399: --*/
400:
401: {
402: //
403: // Set QUEUE up only if we are not in QueueOneBuffer mode.
404: //
405: // Set number of requests to number of segment buffers.
406: //
407: Context->QueueTailIndex=0xffffffff;
408: Context->QueueHeadIndex=0;
409: }
410:
411:
412: PIO_REQUEST
413: q117GetCurReq(
414: IN PQ117_CONTEXT Context
415: )
416:
417: /*++
418:
419: Routine Description:
420:
421: Gets the current iorequest.
422:
423: Arguments:
424:
425: Context -
426:
427: Return Value:
428:
429:
430:
431: --*/
432:
433: {
434: return((PIO_REQUEST)&Context->IoRequest[Context->QueueHeadIndex]);
435: }
436:
437:
438: ULONG
439: q117GetQueueIndex(
440: IN PQ117_CONTEXT Context
441: )
442:
443: /*++
444:
445: Routine Description:
446:
447: Gets the current iorequest pointer.
448:
449: Arguments:
450:
451: Context -
452:
453: Return Value:
454:
455:
456:
457: --*/
458: {
459: return Context->QueueHeadIndex;
460: }
461:
462:
463: VOID
464: q117SetQueueIndex(
465: IN ULONG Index,
466: OUT PQ117_CONTEXT Context
467: )
468:
469: /*++
470:
471: Routine Description:
472:
473: Sets the current io request pointer.
474:
475: Arguments:
476:
477: Index -
478:
479: Context -
480:
481: Return Value:
482:
483: None.
484:
485: --*/
486:
487: {
488: Context->QueueHeadIndex = Index;
489: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.