Annotation of ntddk/src/scsi/qic117/readwrt.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
                      4: All Rights Reserved
                      5: 
                      6: Module Name:
                      7: 
                      8:     readwrt.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     Performs low-level read and write operations (with position logic).
                     13: 
                     14: Revision History:
                     15: 
                     16: 
                     17: 
                     18: 
                     19: --*/
                     20: 
                     21: //
                     22: // include files
                     23: //
                     24: 
                     25: #include <ntddk.h>                        // various NT definitions
                     26: #include <ntdddisk.h>                    // disk device driver I/O control codes
                     27: #include <ntiologc.h>
                     28: #include "common.h"
                     29: #include "drvtask.h"                     // this driver's data declarations
                     30: #include "mt1defs.h"                     // this driver's data declarations
                     31: #include "mt1strc.h"                     // this driver's data declarations
                     32: #include "q117data.h"                    // this driver's data declarations
                     33: 
                     34: 
                     35: STATUS
                     36: Q117iReadWrite(
                     37:     IN PTAPE_EXTENSION TapeExtension,
                     38:     IN OUT PIO_REQUEST IoRequestCurrent,
                     39:     IN OUT PIRP Irp
                     40:     )
                     41: 
                     42: /*++
                     43: 
                     44: 
                     45: Routine Description:
                     46: 
                     47:     Process a data read or write.
                     48: 
                     49:     The first Wrong Cylinder error is ignored incase of a bad seek. On the
                     50:     system 50, 60, 80 the first N Over Run errors are ignored due to the VGA
                     51:     16-bit access bug (see PS/2 compatability manual).
                     52: 
                     53: Arguments:
                     54: 
                     55:     TapeExtension -
                     56: 
                     57:     IoRequestCurrent -
                     58: 
                     59:     Irp -
                     60: 
                     61: Return Value:
                     62: 
                     63: 
                     64: 
                     65: --*/
                     66: {
                     67:     STATUS retval = NoErr;
                     68:     UCHAR i;
                     69:     BOOLEAN dmaDir;
                     70:     STATUS status = NoErr;
                     71:     STATUS sleep_ret = NoErr;
                     72:     RDV_COMMAND         rdWrCmd;
                     73:     PIO_STACK_LOCATION irpSp;
                     74:     struct PerpMode perpMode;
                     75: 
                     76:     perpMode.command = PERP_MODE_COMMAND;
                     77:     perpMode.drive_select = TapeExtension->QControllerData->PerpModeSelect;
                     78:     perpMode.reserved = 0;
                     79:     perpMode.over_write = TRUE;
                     80: 
                     81:     irpSp = IoGetCurrentIrpStackLocation( Irp );
                     82: 
                     83:     Q117iGetRetryCounts(TapeExtension, IoRequestCurrent->Command);
                     84: 
                     85:     IoRequestCurrent->RetryList = 0l;
                     86:     TapeExtension->RdWrOp.BytesTransferredSoFar = 0l;
                     87:     TapeExtension->RdWrOp.TotalBytesOfTransfer = 0l;
                     88:     TapeExtension->RdWrOp.RetryCount = TapeExtension->RdWrOp.RetryTimes;
                     89:     TapeExtension->RdWrOp.RetrySectorId = 0;
                     90:     TapeExtension->RdWrOp.SeekFlag = TRUE;
                     91: 
                     92:     if ((retval = Q117iCalcPosition(
                     93:                         TapeExtension,
                     94:                         IoRequestCurrent->Block,
                     95:                         IoRequestCurrent->Number)) != NoErr) {
                     96: 
                     97:         return(retval);
                     98: 
                     99:     }
                    100: 
                    101:     TapeExtension->RdWrOp.CurLst = IoRequestCurrent->BadList;
                    102: 
                    103:     TapeExtension->RdWrOp.Scount = 0;
                    104: 
                    105:     for (i = 0; i < IoRequestCurrent->Number; i++) {
                    106: 
                    107:         if ((TapeExtension->RdWrOp.CurLst & 1) == 0) {
                    108: 
                    109:             TapeExtension->RdWrOp.Scount++;
                    110: 
                    111:         }
                    112: 
                    113:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
                    114: 
                    115:     }
                    116: 
                    117:     TapeExtension->RdWrOp.CurLst = IoRequestCurrent->BadList;
                    118:     TapeExtension->RdWrOp.DataAmount = 0;
                    119: 
                    120:     while (TapeExtension->RdWrOp.Scount != 0 ||
                    121:         TapeExtension->RdWrOp.DataAmount != 0) {
                    122: 
                    123:         if (TapeExtension->RdWrOp.DataAmount == 0) {
                    124: 
                    125:             Q117iNextGoodSectors(TapeExtension);
                    126: 
                    127:         }
                    128: 
                    129:         if ((TapeExtension->TapePosition.D_Track !=
                    130:                 TapeExtension->TapePosition.C_Track) ||
                    131:             (TapeExtension->TapePosition.C_Segment >
                    132:                 TapeExtension->TapePosition.D_Segment) ||
                    133:             ((TapeExtension->TapePosition.C_Segment !=
                    134:                 TapeExtension->TapePosition.D_Segment) &&
                    135:             ((TapeExtension->TapePosition.LogFwd != TRUE) ||
                    136:             ((TapeExtension->TapePosition.D_Segment - 1) !=
                    137:                 TapeExtension->TapePosition.C_Segment))))
                    138: 
                    139:             if ((retval = Q117iSeek(TapeExtension)) != NoErr) {
                    140: 
                    141:                 return(retval);
                    142: 
                    143:             }
                    144: 
                    145:         if (IoRequestCurrent->Command == DWrite ||
                    146:             IoRequestCurrent->Command == DWriteBad) {
                    147: 
                    148:             dmaDir = DMA_READ;
                    149: 
                    150:             if ((TapeExtension->DriveParms.DriveType == QIC500_DRIVE) &&
                    151:                 !TapeExtension->QControllerData->PerpendicularMode) {
                    152: 
                    153:                 // Enable Perpendicular Mode
                    154:                 perpMode.wgate = 1;
                    155:                 perpMode.gap = 1;
                    156: 
                    157:                 if ((retval = Q117iProgramFDC(
                    158:                                 TapeExtension,
                    159:                                 (CHAR *)&perpMode,
                    160:                                 sizeof(perpMode),
                    161:                                 FALSE)) != NoErr) {
                    162: 
                    163:                     Q117iResetFDC(TapeExtension);
                    164:                     Q117iPauseTape(TapeExtension);
                    165:                     return(retval);
                    166:                 }
                    167: 
                    168:                 TapeExtension->QControllerData->PerpendicularMode = TRUE;
                    169:             }
                    170: 
                    171:         } else {
                    172: 
                    173:             dmaDir = DMA_WRITE;
                    174: 
                    175:             if (TapeExtension->QControllerData->PerpendicularMode) {
                    176: 
                    177:                 // Disable Perpendicular Mode
                    178:                 perpMode.wgate = 0;
                    179:                 perpMode.gap = 0;
                    180: 
                    181:                 if ((retval = Q117iProgramFDC(
                    182:                                 TapeExtension,
                    183:                                 (CHAR *)&perpMode,
                    184:                                 sizeof(perpMode),
                    185:                                 FALSE)) != NoErr) {
                    186: 
                    187:                     Q117iResetFDC(TapeExtension);
                    188:                     Q117iPauseTape(TapeExtension);
                    189:                     return(retval);
                    190:                 }
                    191: 
                    192:                 TapeExtension->QControllerData->PerpendicularMode = FALSE;
                    193:             }
                    194: 
                    195:         }
                    196: 
                    197:         TapeExtension->RdWrOp.TotalBytesOfTransfer =
                    198:             (ULONG)(TapeExtension->RdWrOp.DataAmount * PHY_SIZ);
                    199: 
                    200:         hio_ProgramDMA(TapeExtension, Irp, dmaDir);
                    201: 
                    202:         switch (IoRequestCurrent->Command) {
                    203: 
                    204:         case DWrite:
                    205:             rdWrCmd.command = WRITE;
                    206:             break;
                    207: 
                    208:         case DWriteBad:
                    209:             rdWrCmd.command = WRTDEL;
                    210:             break;
                    211: 
                    212:         default:
                    213:             rdWrCmd.command = READ;
                    214: 
                    215:         }
                    216: 
                    217:         rdWrCmd.drive = (UCHAR)TapeExtension->DriveParms.DriveSelect;
                    218:         rdWrCmd.C = TapeExtension->RdWrOp.D_FTK;
                    219:         rdWrCmd.H = TapeExtension->RdWrOp.D_Head;
                    220:         rdWrCmd.R = TapeExtension->RdWrOp.D_Sect;
                    221:         rdWrCmd.N = WRT_BPS;
                    222:         rdWrCmd.EOT = (UCHAR)TapeExtension->TapeParms.FsectFtrack;
                    223:         rdWrCmd.GPL = (UCHAR)TapeExtension->TapeParms.RwGapLength;
                    224:         rdWrCmd.DTL = 0xff;
                    225: 
                    226:         if ((retval = Q117iStartTape(TapeExtension)) != NoErr) {
                    227: 
                    228:             hio_FlushDMA(TapeExtension, Irp, dmaDir);
                    229:             return(retval);
                    230: 
                    231:         }
                    232: 
                    233:         (VOID) Q117iResetInterruptEvent(TapeExtension);
                    234:         if ((retval = Q117iProgramFDC(
                    235:                             TapeExtension,
                    236:                             (CHAR *)&rdWrCmd,
                    237:                             sizeof(RDV_COMMAND),
                    238:                             TRUE)) != NoErr) {
                    239: 
                    240:             hio_FlushDMA(TapeExtension, Irp, dmaDir);
                    241:             Q117iResetFDC(TapeExtension);
                    242:             Q117iPauseTape(TapeExtension);
                    243:             return(retval);
                    244:         }
                    245: 
                    246:         sleep_ret = Q117iSleep(TapeExtension, mt_wttrks, TRUE);
                    247:         hio_FlushDMA(TapeExtension, Irp, dmaDir);
                    248: 
                    249:         switch (sleep_ret) {
                    250: 
                    251:         case TimeOut:
                    252:             if ((retval = Q117iRW_Timeout(
                    253:                                 TapeExtension,
                    254:                                 IoRequestCurrent,
                    255:                                 &status)) != NoErr) {
                    256: 
                    257:                     return(retval);
                    258: 
                    259:             }
                    260: 
                    261:             if (TapeExtension->RdWrOp.NoDat == 0) {
                    262: 
                    263:                     return(status);
                    264: 
                    265:             }
                    266: 
                    267:             break;
                    268: 
                    269:         case NoErr:
                    270: 
                    271:             if ((retval = Q117iRW_Normal(
                    272:                                 TapeExtension,
                    273:                                 IoRequestCurrent,
                    274:                                 &status)) != NoErr) {
                    275: 
                    276:                     return(retval);
                    277: 
                    278:             }
                    279: 
                    280:             if (status == BadMark || TapeExtension->RdWrOp.NoDat == 0) {
                    281: 
                    282:                     return(status);
                    283: 
                    284:             }
                    285: 
                    286:             break;
                    287: 
                    288:         }
                    289:     } /* end of while loop */
                    290: 
                    291:     if (IoRequestCurrent->Command == DRetry) {
                    292: 
                    293:         if (TapeExtension->TapePosition.LogFwd == TRUE) {
                    294: 
                    295:             retval = Q117iGetDriveError(TapeExtension);
                    296: 
                    297:             if (retval && (retval != NotRdy)) {
                    298: 
                    299:                 return(retval);
                    300: 
                    301:             }
                    302: 
                    303:             Q117iPauseTape(TapeExtension);
                    304:         }
                    305: 
                    306:         if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command)) !=
                    307:             NoErr) {
                    308: 
                    309:             return(retval);
                    310: 
                    311:         }
                    312:     }
                    313: 
                    314: 
                    315: #if DBG
                    316:     if ((QIC117DebugLevel & QIC117MAKEBAD) && status == NoErr &&
                    317:         IoRequestCurrent->Command == DWrite) {
                    318: 
                    319:         LARGE_INTEGER time;
                    320: 
                    321: 
                    322:         // Use the system time as a "Randomizer" to fake bad sectors
                    323:         KeQuerySystemTime(&time);
                    324:         time.LowPart /= 10;
                    325:         if (time.LowPart & 1) {
                    326:             status = BadBlk;
                    327: 
                    328:             IoRequestCurrent->BadList |= 1 << (time.LowPart & 31);
                    329:             if (time.LowPart & 0x100) {
                    330:                 IoRequestCurrent->BadList |= 1 << ((time.LowPart>>6) & 31);
                    331:             }
                    332:             if ((time.LowPart & 0xa00) == 0xa00) {
                    333:                 IoRequestCurrent->BadList |= 1 << ((time.LowPart>>10) & 31);
                    334:             }
                    335:             CheckedDump(QIC117MAKEBAD, ("badblk generated\n"));
                    336:         } else {
                    337:             CheckedDump(QIC117MAKEBAD, ("no sim\n"));
                    338:         }
                    339:     }
                    340: #endif
                    341: 
                    342:     return(status);
                    343: }
                    344: 
                    345: 
                    346: STATUS
                    347: Q117iCalcPosition(
                    348:     IN PTAPE_EXTENSION TapeExtension,
                    349:     IN ULONG Block,
                    350:     IN UCHAR Number
                    351:     )
                    352: 
                    353: /*++
                    354: 
                    355: Routine Description:
                    356: 
                    357:     Calculate the desired tape position from the Logical Sector Number
                    358:     in the I/O Request.
                    359: 
                    360: Arguments:
                    361: 
                    362:     TapeExtension -
                    363: 
                    364:     Block -
                    365: 
                    366:     Number -
                    367: 
                    368: Return Value:
                    369: 
                    370: 
                    371: 
                    372: --*/
                    373: 
                    374: {
                    375:     ULONG logSect;
                    376: 
                    377:     //
                    378:     // First check if the desired sector is a legal one, i.e. is less
                    379:     // than the maximum number of sectors on the tape.
                    380:     //
                    381: 
                    382:     CheckedDump(QIC117STOP,( "q117i: requested block %lx\n", Block ));
                    383: 
                    384:     if (Block >= TapeExtension->TapeParms.LogSectors) {
                    385: 
                    386:         return(BadReq);
                    387: 
                    388:     }
                    389: 
                    390:     //
                    391:     // Now we need to determine the sector ID information so that we
                    392:     // can properly program the FDC.  The ID information required is the
                    393:     // head, cylinder, and sector numbers.  The head number is calculated
                    394:     // as logSect / (floppy sectors per floppy side).  This calculation
                    395:     // is done in the while loop which also determines the logical floppy
                    396:     // sector on the floppy side.  The cylinder number (d_FTK) and the
                    397:     // sector number (d_sect) are calculated last as (logical floppy sector)
                    398:     //  / (floppy sectors per floppy cylinder).
                    399:     //
                    400: 
                    401:     logSect = Block;
                    402:     TapeExtension->RdWrOp.D_Head = 0;
                    403: 
                    404:     while (logSect >= TapeExtension->TapeParms.FsectFside) {
                    405: 
                    406:         logSect -= TapeExtension->TapeParms.FsectFside;
                    407:         TapeExtension->RdWrOp.D_Head++;
                    408: 
                    409:     }
                    410: 
                    411:     TapeExtension->RdWrOp.D_FTK = (UCHAR)(logSect / FSC_FTK);
                    412: 
                    413:     //
                    414:     // fast logSect % 128
                    415:     //
                    416: 
                    417:     TapeExtension->RdWrOp.D_Sect = (UCHAR)(logSect % FSC_FTK) + 1;
                    418:     TapeExtension->RdWrOp.S_Sect = (UCHAR)TapeExtension->RdWrOp.D_Sect;
                    419: 
                    420:     //
                    421:     // Next, we need the tape positioning data.  This is the data that
                    422:     // we need to find out where, physically, on the tape we need to be.
                    423:     // The tape track is determined first as
                    424:     // (logical sector number) / (floppy sectors per tape track).  The
                    425:     // remainder from this calculation is the absolute sector number
                    426:     // on the tape track.  Lastly, the physical segment is determined by
                    427:     // dividing the physical sector number by the number of sectors per
                    428:     // segment.
                    429:     //
                    430: 
                    431:     logSect = Block;
                    432:     TapeExtension->TapePosition.D_Track = 0;
                    433: 
                    434:     while (logSect >= TapeExtension->TapeParms.FsectTtrack) {
                    435: 
                    436:         logSect -= TapeExtension->TapeParms.FsectTtrack;
                    437:         TapeExtension->TapePosition.D_Track++;
                    438: 
                    439:     }
                    440: 
                    441:     logSect = logSect / FSC_SEG;
                    442:     TapeExtension->TapePosition.D_Segment = (SHORT)logSect;
                    443: 
                    444:     //
                    445:     // Finally, if the IO Request requests a read that will cross a segment
                    446:     // boundary then an error is returned.
                    447:     //
                    448: 
                    449:     if((((TapeExtension->RdWrOp.D_Sect - 1) & 0x1f) + Number) >
                    450:     TapeExtension->TapeParms.FsectSeg) {
                    451: 
                    452:         return(BadReq);
                    453: 
                    454:     }
                    455: 
                    456:     return(NoErr);
                    457: }
                    458: 
                    459: 
                    460: VOID
                    461: Q117iGetRetryCounts(
                    462:     IN PTAPE_EXTENSION TapeExtension,
                    463:     IN DRIVER_COMMAND Command
                    464:     )
                    465: 
                    466: /*++
                    467: 
                    468: Routine Description:
                    469: 
                    470:     Determine the retry count information according to the drive command
                    471:     eiher read, write, verify, or retry.
                    472: 
                    473: Arguments:
                    474: 
                    475:     TapeExtension -
                    476: 
                    477:     Command -
                    478: 
                    479: Return Value:
                    480: 
                    481:     None
                    482: 
                    483: --*/
                    484: 
                    485: {
                    486:     switch (Command) {
                    487: 
                    488:     case DWrite:
                    489:     case DWriteBad:
                    490:         TapeExtension->RdWrOp.RetryTimes = WTIMES;
                    491:         TapeExtension->RdWrOp.NoDat = 3;
                    492:         break;
                    493: 
                    494:     case DRead:
                    495:     case DReadBad:
                    496:         TapeExtension->RdWrOp.RetryTimes = ANTIMES;
                    497:         TapeExtension->RdWrOp.NoDat = 3;
                    498:         break;
                    499: 
                    500:     case DVerify:
                    501:         TapeExtension->RdWrOp.RetryTimes = VTIMES;
                    502:         TapeExtension->RdWrOp.NoDat = 2;
                    503:         break;
                    504: 
                    505:     case DRetry:
                    506:         TapeExtension->RdWrOp.RetryTimes = ARTIMES;
                    507:         TapeExtension->RdWrOp.NoDat = ARTIMES;
                    508:         TapeExtension->RetrySeqNum = 0;
                    509: 
                    510:     }
                    511: }
                    512: 
                    513: 
                    514: void
                    515: Q117iNextGoodSectors(
                    516:     IN PTAPE_EXTENSION TapeExtension
                    517:     )
                    518: 
                    519: /*++
                    520: 
                    521: Routine Description:
                    522: 
                    523:     Determine the next block of good sectors to read/write/verify.
                    524: 
                    525: Arguments:
                    526: 
                    527:     TapeExtension -
                    528: 
                    529: Return Value:
                    530: 
                    531:     None
                    532: 
                    533: --*/
                    534: 
                    535: {
                    536:     TapeExtension->RdWrOp.DataAmount = 0;
                    537: 
                    538:     while (TapeExtension->RdWrOp.CurLst & 1) {
                    539: 
                    540:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
                    541:         TapeExtension->RdWrOp.D_Sect++;
                    542: 
                    543:     }
                    544: 
                    545:     do {
                    546: 
                    547:         TapeExtension->RdWrOp.DataAmount++;
                    548:         TapeExtension->RdWrOp.Scount--;
                    549:         TapeExtension->RdWrOp.CurLst = TapeExtension->RdWrOp.CurLst >> 1;
                    550: 
                    551:     } while (!(TapeExtension->RdWrOp.CurLst & 1) &&
                    552:             TapeExtension->RdWrOp.Scount);
                    553: }
                    554: 
                    555: 
                    556: STATUS
                    557: Q117iRW_Timeout(
                    558:     IN PTAPE_EXTENSION TapeExtension,
                    559:     IN OUT PIO_REQUEST IoRequestCurrent,
                    560:     OUT STATUS *Status
                    561:     )
                    562: 
                    563: /*++
                    564: 
                    565: Routine Description:
                    566: 
                    567:     Process a TIMEOUT error while reading/writing/verifying. If the FDC
                    568:     does not report any status within the amount of time that the tape
                    569:     would pass apporximately 4 segments, it must be assumed that there is no
                    570:     data on the tape.
                    571: 
                    572: Arguments:
                    573: 
                    574:     TapeExtension -
                    575: 
                    576:     IoRequestCurrent -
                    577: 
                    578:     Status -
                    579: 
                    580: Return Value:
                    581: 
                    582: 
                    583: 
                    584: --*/
                    585: 
                    586: {
                    587:     STATUS retval;
                    588: 
                    589:     Q117iResetFDC(TapeExtension);
                    590: 
                    591:     if ((retval = Q117iStopTape(TapeExtension)) != NoErr) {
                    592: 
                    593:         return(retval);
                    594: 
                    595:     }
                    596: 
                    597:     if ((retval = Q117iChangeTrack(
                    598:                         TapeExtension,
                    599:                         TapeExtension->TapePosition.D_Track)) != NoErr) {
                    600: 
                    601:         return(retval);
                    602: 
                    603:     }
                    604: 
                    605:     if (TapeExtension->DriveParms.Status.BOT ||
                    606:         TapeExtension->DriveParms.Status.EOT) {
                    607: 
                    608:         TapeExtension->TapePosition.C_Segment =
                    609:             TapeExtension->TapeParms.SegTtrack;
                    610: 
                    611:     }
                    612: 
                    613:     if (--TapeExtension->RdWrOp.NoDat == 0) {
                    614: 
                    615:         if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command))
                    616:             != NoErr) {
                    617: 
                    618:             return(retval);
                    619: 
                    620:         }
                    621: 
                    622:         *Status = BadBlk;
                    623:         IoRequestCurrent->BadList = -
                    624:             1l << (TapeExtension->RdWrOp.D_Sect -
                    625:                 TapeExtension->RdWrOp.S_Sect);
                    626: 
                    627:     }
                    628:     return(retval);
                    629: }
                    630: 
                    631: 
                    632: STATUS
                    633: Q117iRW_Normal(
                    634:     IN PTAPE_EXTENSION TapeExtension,
                    635:     IN OUT PIO_REQUEST IoRequestCurrent,
                    636:     OUT STATUS *Status
                    637:     )
                    638: 
                    639: /*++
                    640: 
                    641: 
                    642: Routine Description:
                    643: 
                    644:     Process a read/write/verify operation that has returned normally from
                    645:     the FDC.
                    646: 
                    647: Arguments:
                    648: 
                    649:     TapeExtension -
                    650: 
                    651:     IoRequestCurrent -
                    652: 
                    653:     Status -
                    654: 
                    655: Return Value:
                    656: 
                    657: 
                    658: 
                    659: --*/
                    660: 
                    661: {
                    662:     STATUS retval;
                    663:     SHORT statLength;
                    664: 
                    665:     if ((retval = Q117iReadFDC(
                    666:                     TapeExtension,
                    667:                     (CHAR *)&TapeExtension->QControllerData->FdcStat,
                    668:                     &statLength)) != NoErr) {
                    669: 
                    670:         Q117iPauseTape(TapeExtension);
                    671:         return(retval);
                    672: 
                    673:     }
                    674: 
                    675:     if (statLength != 7) {
                    676: 
                    677:         Q117iResetFDC(TapeExtension);
                    678:         Q117iGetDriveError(TapeExtension);
                    679:         Q117iPauseTape(TapeExtension);
                    680: 
                    681:         if (TapeExtension->RdWrOp.NoDat == 0) {
                    682: 
                    683:             if ((retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command))
                    684:                 != NoErr) {
                    685: 
                    686:                 return(retval);
                    687: 
                    688:             }
                    689: 
                    690:             *Status = BadBlk;
                    691:             IoRequestCurrent->BadList =
                    692:                 -1l << (TapeExtension->RdWrOp.D_Sect -
                    693:                         TapeExtension->RdWrOp.S_Sect);
                    694:         }
                    695:         return(NoErr);
                    696:     }
                    697: 
                    698:     if (TapeExtension->QControllerData->FdcStat.ST1 == 0 &&
                    699:         TapeExtension->QControllerData->FdcStat.ST2 == 0) {
                    700: 
                    701:         //
                    702:         // no errors
                    703:         //
                    704: 
                    705:         DbgAddEntry(TapeExtension->RdWrOp.D_Sect);
                    706:         DbgAddEntry(TapeExtension->RdWrOp.DataAmount);
                    707:         DbgAddEntry(TapeExtension->RdWrOp.CurLst);
                    708:         DbgAddEntry(TapeExtension->RdWrOp.BytesTransferredSoFar);
                    709: 
                    710:         TapeExtension->RdWrOp.SeekFlag = TRUE;
                    711:         TapeExtension->TapePosition.C_Segment =
                    712:             TapeExtension->TapePosition.D_Segment;
                    713:         TapeExtension->RdWrOp.D_Sect +=
                    714:             (UCHAR)TapeExtension->RdWrOp.DataAmount;
                    715:         TapeExtension->RdWrOp.BytesTransferredSoFar +=
                    716:             (ULONG)(TapeExtension->RdWrOp.DataAmount*PHY_SIZ);
                    717:         TapeExtension->RdWrOp.DataAmount = 0;
                    718:         return(NoErr);
                    719:     }
                    720: 
                    721:     if ((IoRequestCurrent->Command == DReadBad) &&
                    722:         (TapeExtension->QControllerData->FdcStat.ST2 & ST2_CM)) {
                    723: 
                    724:         IoRequestCurrent->BadList = 0xffffffff;
                    725:         *Status = BadMark;
                    726:         return(NoErr);
                    727: 
                    728:     }
                    729: 
                    730:     if ((TapeExtension->QControllerData->FdcStat.ST2 & ST2_WC) ||
                    731:         (TapeExtension->QControllerData->FdcStat.ST1 &
                    732:             (ST1_OR | ST1_ND | ST1_MA))) {
                    733: 
                    734:         if (TapeExtension->RdWrOp.SeekFlag == TRUE) {
                    735: 
                    736:             TapeExtension->TapePosition.C_Segment =
                    737:                 TapeExtension->TapePosition.D_Segment + 1;
                    738:             TapeExtension->RdWrOp.SeekFlag = FALSE;
                    739:             return(NoErr);
                    740: 
                    741:         }
                    742:     }
                    743: 
                    744:     if ((IoRequestCurrent->Command == DVerify) &&
                    745:         (TapeExtension->QControllerData->FdcStat.ST1 & ST1_MA)) {
                    746: 
                    747:         if (TapeExtension->RdWrOp.SeekFlag == TRUE) {
                    748: 
                    749:             retval = Q117iGetDriveError(TapeExtension);
                    750: 
                    751:             if (retval && (retval != NotRdy)) {
                    752: 
                    753:                 return(retval);
                    754: 
                    755:             }
                    756: 
                    757:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
                    758: 
                    759:                 return(retval);
                    760: 
                    761:             }
                    762: 
                    763:             if ((retval = Q117iReadIDRepeat(TapeExtension)) != NoErr) {
                    764: 
                    765:                 return(retval);
                    766: 
                    767:             }
                    768: 
                    769:             TapeExtension->RdWrOp.SeekFlag = FALSE;
                    770:             return(NoErr);
                    771:         }
                    772:     }
                    773: 
                    774:     TapeExtension->TapePosition.C_Segment =
                    775:         TapeExtension->TapePosition.D_Segment;
                    776: 
                    777:     retval = Q117iRetryCode(
                    778:                 TapeExtension,
                    779:                 IoRequestCurrent,
                    780:                 &TapeExtension->QControllerData->FdcStat,
                    781:                 Status);
                    782: 
                    783:     return(retval);
                    784: }
                    785: 
                    786: 
                    787: STATUS
                    788: Q117iRetryCode(
                    789:     IN PTAPE_EXTENSION TapeExtension,
                    790:     IN OUT PIO_REQUEST IoRequestCurrent,
                    791:     OUT FDC_STATUS *FdcStatus,
                    792:     OUT STATUS *Status
                    793:     )
                    794: 
                    795: /*++
                    796: 
                    797: Routine Description:
                    798: 
                    799:     Orchestrate retries for read/write/verify (and retyr) commands.
                    800: 
                    801: Arguments:
                    802: 
                    803:     TapeExtension -
                    804: 
                    805:     IoRequestCurrent -
                    806: 
                    807:     FdcStatus -
                    808: 
                    809:     Status -
                    810: 
                    811: Return Value:
                    812: 
                    813: 
                    814: 
                    815: --*/
                    816: {
                    817:     STATUS retval;
                    818:     SHORT sectorsRead;
                    819: 
                    820:     if (TapeExtension->RdWrOp.RetryTimes != 0) {
                    821: 
                    822:         if (IoRequestCurrent->Command != DRetry) {
                    823: 
                    824:             retval = Q117iGetDriveError(TapeExtension);
                    825: 
                    826:             if (retval && (retval != NotRdy)) {
                    827: 
                    828:                 return(retval);
                    829: 
                    830:             }
                    831: 
                    832:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
                    833: 
                    834:                 return(retval);
                    835: 
                    836:             }
                    837: 
                    838:         }
                    839: 
                    840:         if ((retval = Q117iReadIDRepeat(TapeExtension)) != NoErr) {
                    841: 
                    842:             return(retval);
                    843: 
                    844:         }
                    845: 
                    846:     } else {
                    847: 
                    848:         TapeExtension->RdWrOp.SeekFlag = TRUE;
                    849: 
                    850:     }
                    851: 
                    852:     if ((TapeExtension->RdWrOp.RetryTimes == 0) ||
                    853:         (FdcStatus->R == TapeExtension->RdWrOp.RetrySectorId)) {
                    854: 
                    855:         if ((TapeExtension->RdWrOp.RetryTimes == 0) ||
                    856:             (--TapeExtension->RdWrOp.RetryCount == 0)) {
                    857: 
                    858:             TapeExtension->RdWrOp.SeekFlag = TRUE;
                    859:             IoRequestCurrent->BadList |=
                    860:                 1l << (FdcStatus->R - TapeExtension->RdWrOp.S_Sect);
                    861:             *Status = BadBlk;
                    862:             sectorsRead = FdcStatus->R + 1 - TapeExtension->RdWrOp.D_Sect;
                    863:             TapeExtension->RdWrOp.D_Sect = FdcStatus->R + 1;
                    864:             TapeExtension->RdWrOp.DataAmount -= sectorsRead;
                    865:             TapeExtension->RdWrOp.BytesTransferredSoFar +=
                    866:                 sectorsRead * PHY_SIZ;
                    867:             TapeExtension->RdWrOp.RetryCount =
                    868:                 TapeExtension->RdWrOp.RetryTimes;
                    869:             TapeExtension->RdWrOp.RetrySectorId = 0;
                    870:             retval = Q117iSetBack(TapeExtension, IoRequestCurrent->Command);
                    871: 
                    872:         } else {
                    873: 
                    874:             retval = Q117iNextTry(TapeExtension, IoRequestCurrent->Command);
                    875: 
                    876:         }
                    877: 
                    878:     } else {
                    879: 
                    880:         IoRequestCurrent->RetryList |=
                    881:             1l << (FdcStatus->R - TapeExtension->RdWrOp.S_Sect);
                    882:         TapeExtension->RdWrOp.RetrySectorId = FdcStatus->R;
                    883:         TapeExtension->RdWrOp.RetryCount =
                    884:             TapeExtension->RdWrOp.RetryTimes;
                    885:         sectorsRead = FdcStatus->R - TapeExtension->RdWrOp.D_Sect;
                    886:         TapeExtension->RdWrOp.D_Sect = FdcStatus->R;
                    887:         TapeExtension->RdWrOp.DataAmount -= sectorsRead;
                    888:         TapeExtension->RdWrOp.BytesTransferredSoFar +=
                    889:             sectorsRead * PHY_SIZ;
                    890: 
                    891:     }
                    892: 
                    893:     return(retval);
                    894: }
                    895: 
                    896: 
                    897: 
                    898: STATUS
                    899: Q117iNextTry(
                    900:     IN PTAPE_EXTENSION TapeExtension,
                    901:     IN DRIVER_COMMAND Command
                    902:     )
                    903: 
                    904: /*++
                    905: 
                    906: Routine Description:
                    907: 
                    908:     Determines the next tape drive head position during off-track retries.
                    909: 
                    910: Arguments:
                    911: 
                    912:     TapeExtension -
                    913: 
                    914:     Command -
                    915: 
                    916: Return Value:
                    917: 
                    918: 
                    919: 
                    920: --*/
                    921: 
                    922: {
                    923:     STATUS retval = NoErr;
                    924: 
                    925:     if (Command == DRetry) {
                    926: 
                    927:         retval = Q117iGetDriveError(TapeExtension);
                    928: 
                    929:         if (retval && (retval != NotRdy)) {
                    930: 
                    931:             return(retval);
                    932: 
                    933:         }
                    934: 
                    935:         TapeExtension->RetrySeqNum++;
                    936: 
                    937:         if (TapeExtension->RdWrOp.RetryCount > 3) {
                    938: 
                    939:             retval = Q117iSendByte(TapeExtension, Pause);
                    940: 
                    941:         } else {
                    942: 
                    943:             retval = Q117iSendByte(TapeExtension, Micro_Pause);
                    944: 
                    945:         }
                    946: 
                    947:         if (retval) {
                    948: 
                    949:             return(retval);
                    950: 
                    951:         }
                    952: 
                    953:         retval = Q117iWaitCommandComplete(TapeExtension, mt_wt016s);
                    954:         TapeExtension->TapePosition.LogFwd = FALSE;
                    955: 
                    956:     }
                    957: 
                    958:     return(retval);
                    959: }
                    960: 
                    961: 
                    962: STATUS
                    963: Q117iSetBack(
                    964:     IN PTAPE_EXTENSION TapeExtension,
                    965:     IN DRIVER_COMMAND Command
                    966:     )
                    967: 
                    968: /*++
                    969: 
                    970: Routine Description:
                    971: 
                    972:     Reset any tape drive head offset due to off-track retries.
                    973: 
                    974: Arguments:
                    975: 
                    976:     TapeExtension -
                    977: 
                    978:     Command -
                    979: 
                    980: Return Value:
                    981: 
                    982: 
                    983: 
                    984: --*/
                    985: {
                    986:     STATUS retval = NoErr;
                    987: 
                    988:     if (Command == DRetry) {
                    989: 
                    990:         if (TapeExtension->TapePosition.LogFwd == TRUE) {
                    991: 
                    992:             retval = Q117iGetDriveError(TapeExtension);
                    993: 
                    994:             if (retval && (retval != NotRdy)) {
                    995: 
                    996:                 return(retval);
                    997: 
                    998:             }
                    999: 
                   1000:             if ((retval = Q117iPauseTape(TapeExtension)) != NoErr) {
                   1001: 
                   1002:                 return(retval);
                   1003: 
                   1004:             }
                   1005: 
                   1006:         }
                   1007: 
                   1008:         if ((retval = Q117iSendByte(TapeExtension, Seek_Track)) != NoErr) {
                   1009: 
                   1010:             return(retval);
                   1011: 
                   1012:         }
                   1013: 
                   1014:         Q117iSleep(TapeExtension, mt_wt2ticks, FALSE);
                   1015: 
                   1016:         if ((retval = Q117iSendByte(
                   1017:                         TapeExtension,
                   1018:                         (CHAR)(TapeExtension->TapePosition.C_Track + 2))) !=
                   1019:             NoErr) {
                   1020: 
                   1021:             return(retval);
                   1022: 
                   1023:         }
                   1024: 
                   1025:         retval = Q117iWaitCommandComplete(TapeExtension, mt_wt007s);
                   1026:     }
                   1027: 
                   1028:     return(retval);
                   1029: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.