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