Annotation of ntddk/src/scsi/qic117/format.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:     format.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     Tells the driver to format the tape and calls Erase().
                     13: 
                     14:     If DoFormat is TRUE, does format pass and then bad sector mapping; else
                     15:     does only the bad sector mapping.
                     16: 
                     17: 
                     18: Revision History:
                     19: 
                     20: 
                     21: 
                     22: 
                     23: --*/
                     24: 
                     25: //
                     26: // include files
                     27: //
                     28: 
                     29: #include <ntddk.h>
                     30: #include <ntddtape.h>
                     31: #include "common.h"
                     32: #include "q117.h"
                     33: #include "protos.h"
                     34: 
                     35: #define QIC80_TRACKS_NUM             (VU_80TRACKS_PER_CART * 10)
                     36: #define TOTAL_GAS_BLOCKS             20
                     37: #define QIC80_TRACKS_DENOM_FACTOR    10
                     38: 
                     39: STATUS
                     40: q117Format(
                     41:     OUT LONG *NumberBad,
                     42:     IN UCHAR DoFormat,
                     43:     IN PQIC40_VENDOR_UNIQUE VendorUnique,
                     44:     IN OUT PQ117_CONTEXT Context
                     45:     )
                     46: 
                     47: /*++
                     48: 
                     49: Routine Description:
                     50: 
                     51:     Formats the tape.
                     52: 
                     53: Arguments:
                     54: 
                     55:     NumberBad - number of bad sectors
                     56: 
                     57:     DoFormat - flag of actually do a QIC40 format
                     58: 
                     59:     VendorUnique -
                     60: 
                     61:     Context -
                     62: 
                     63: Return Value:
                     64: 
                     65:     NT Status
                     66: 
                     67:     NoErr, any Driver error, UnusTape, RdncUnsc, <LinkBack>
                     68: 
                     69: 
                     70: --*/
                     71: 
                     72: {
                     73:     STATUS ret;                     // Return value from other routines called.
                     74:     PIO_REQUEST ioreq;
                     75:     IO_REQUEST wproIoreq;
                     76:     SEGMENT headerSegment[2];
                     77:     SEGMENT segment;
                     78:     ULONG numberFound;
                     79:     PTAPE_HEADER hdr;
                     80:     PVOID scrbuf;
                     81:     struct S_O_DGetCap tparms;      // tape parameters from the driver
                     82:     PSEGMENT_BUFFER bufferInfo;
                     83: 
                     84:     //
                     85:     // Check for write protected cart,  DSndWPro will
                     86:     // return stat = WProt in this case.
                     87:     //
                     88:     if (ret = q117DoCmd(&wproIoreq, DSndWPro, NULL, Context)) {
                     89: 
                     90:         return ret;
                     91: 
                     92:     }
                     93: 
                     94:     if (ret = q117InitFiler(Context)) {
                     95: 
                     96:         return(ret);
                     97: 
                     98:     }
                     99: 
                    100:     scrbuf = q117GetFreeBuffer(&bufferInfo,Context);
                    101: 
                    102:     if (DoFormat)  {
                    103: 
                    104:         //
                    105:         // Force the tape header,  volume list etc,  to be re-loaded
                    106:         //
                    107:         Context->CurrentTape.State = NeedInfoLoaded;
                    108: 
                    109:         *(UCHAR *)scrbuf=FORMAT_BYTE;
                    110: 
                    111:         q117GetTapeCapacity(&tparms,Context);
                    112: 
                    113:         if (ret=q117IssIOReq(scrbuf,DFmt,1l,bufferInfo,Context)) {
                    114: 
                    115:             //
                    116:             // <FMemErr>
                    117:             //
                    118: 
                    119:             return(ret);
                    120: 
                    121:         }
                    122: 
                    123:         ioreq = q117Dequeue(WaitForItem,Context);
                    124: 
                    125:         if (ioreq->Status) {
                    126: 
                    127:             return(ioreq->Status);
                    128: 
                    129:         }
                    130: 
                    131:         if (ret = q117GetTapeCapacity(NULL,Context)) {
                    132: 
                    133:             return(ret);
                    134: 
                    135:         }
                    136: 
                    137:         //
                    138:         // clear the bad block map (erase or's in new bad sectors)
                    139:         //
                    140: 
                    141:         RtlZeroMemory(
                    142:             Context->CurrentTape.BadMapPtr,
                    143:             sizeof(BAD_MAP));
                    144: 
                    145:         //
                    146:         // verify the tape (this will set up the bad sector map)
                    147:         //
                    148: 
                    149:         if (ret=q117VerifyFormat(Context)) {
                    150: 
                    151:             //
                    152:             // FMemErr, UnusTape, any Driver error, <LinkBack>, RdncUnsc.
                    153:             //
                    154: 
                    155:             return(ret);
                    156: 
                    157:         }
                    158: 
                    159:         //
                    160:         // find the first two error free segments for the tape headers
                    161:         //
                    162: 
                    163:         numberFound = segment = 0;
                    164:         while (segment <= Context->CurrentTape.LastSegment && numberFound < 2) {
                    165: 
                    166:             if (q117CountBits(Context, segment, 0l) == 0) {
                    167: 
                    168:                 headerSegment[numberFound++] = segment;
                    169: 
                    170:             }
                    171:             ++segment;
                    172:         }
                    173: 
                    174:         if (segment > Context->CurrentTape.LastSegment) {
                    175: 
                    176:             return(UnusTape);
                    177: 
                    178:         }
                    179: 
                    180:         //
                    181:         // find the first segment that data can be stored in (more than
                    182:         // 3 good sectors).
                    183:         //
                    184: 
                    185:         while (q117CountBits(Context, segment, 0l) >=
                    186:             (BLOCKS_PER_SEGMENT-ECC_BLOCKS_PER_SEGMENT) && segment <= Context->CurrentTape.LastSegment) {
                    187: 
                    188:             ++segment;
                    189: 
                    190:         }
                    191: 
                    192:         Context->CurrentTape.VolumeSegment = segment;
                    193: 
                    194:         //
                    195:         // count up all bad sectors and find the last segment that data
                    196:         // can be stored in.
                    197:         //
                    198: 
                    199:         q117GetBadSectors(Context);
                    200: 
                    201:         *NumberBad = Context->CurrentTape.BadSectors;
                    202: 
                    203:         if (Context->CurrentTape.VolumeSegment >= Context->CurrentTape.LastSegment) {
                    204: 
                    205:             return(UnusTape);
                    206: 
                    207:         }
                    208: 
                    209:         //
                    210:         // create the tape header
                    211:         //
                    212: 
                    213:         hdr = (PTAPE_HEADER)scrbuf;
                    214: 
                    215:         if (ret = q117BuildHeader(VendorUnique,headerSegment,hdr,Context)) {
                    216: 
                    217:             return(ret);
                    218: 
                    219:         }
                    220: 
                    221:         q117UpdateHeader(hdr,Context);
                    222: 
                    223:         //
                    224:         // Make memory image of header up to date after format.
                    225:         //
                    226:         RtlMoveMemory(
                    227:             Context->CurrentTape.TapeHeader,
                    228:             hdr,
                    229:             sizeof(*Context->CurrentTape.TapeHeader) );
                    230: 
                    231:         if (!ret) {
                    232: 
                    233:             //
                    234:             // erase the tape directory
                    235:             //
                    236: 
                    237:             ret=q117EraseQ(Context);
                    238: 
                    239:         }
                    240:     }
                    241:     return(ret);
                    242: }
                    243: 
                    244: 
                    245: STATUS
                    246: q117BuildHeader(
                    247:     OUT PQIC40_VENDOR_UNIQUE VendorUnique,
                    248:     IN SEGMENT *HeaderSect,
                    249:     IN OUT PTAPE_HEADER Header,
                    250:     IN PQ117_CONTEXT Context
                    251:     )
                    252: 
                    253: /*++
                    254: 
                    255: Routine Description:
                    256: 
                    257:     Builds the tape header for a format.
                    258: 
                    259: Arguments:
                    260: 
                    261:     VendorUnique - vendor unique section
                    262: 
                    263:     HeaderSect - header segment array
                    264: 
                    265:     Header - JUMBO header
                    266: 
                    267: Return Value:
                    268: 
                    269: 
                    270: 
                    271: --*/
                    272: 
                    273: {
                    274:     STATUS ret = NoErr;         // Return value from other routines called.
                    275:     LONG divisor, dividend;
                    276:     struct S_O_DGetCap capacity;
                    277: 
                    278:     //
                    279:     //      In two of the following calculations, we are changing from the number
                    280:     //  of items to the highest possible value for that item. Floppy sectors are
                    281:     //  numbered from 1 count, so the count is also the highest possible number.
                    282:     //  The rest are numbered 0 through count-1, so the highest possible number
                    283:     //  is count-1.
                    284:     //      The only fancy calculation is the number of floppy sides. This is
                    285:     //  obtained by obtaining the number of logical tape segments (SEG in the
                    286:     //  QIC-80 spec), and dividing by the number of segments per track. In addition,
                    287:     //  it may be necessary to round up in case of a remainder. To handle the
                    288:     //  remainder and the decrement simultaneuously, we decrement only if there
                    289:     //  is no remainder.
                    290:     //      See the QIC-80 spec, sec 5.3.1 on the identification of sectors, and
                    291:     //  7.1, bytes 24 through 29, for the defined values. Wouldn't it be nice
                    292:     //  if this stuff were better documented?   -- crc.
                    293:     //
                    294: 
                    295:     if (!(ret = q117GetTapeCapacity(&capacity,Context))) {
                    296: 
                    297:         RtlZeroMemory(
                    298:             VendorUnique,
                    299:             sizeof(*VendorUnique));
                    300: 
                    301:         //
                    302:         // Maximum floppy sectors. Warning: #define!
                    303:         //
                    304: 
                    305:         VendorUnique->correct_name.MaxFlopSect =
                    306:             capacity.MaxFSector;
                    307: 
                    308:         //
                    309:         // Tape segments per tape track
                    310:         //
                    311: 
                    312:         VendorUnique->correct_name.TrackSeg =
                    313:             (USHORT)capacity.SegmentsPerTrack;
                    314: 
                    315:         //
                    316:         // Tape tracks per cartridge
                    317:         //
                    318: 
                    319:         VendorUnique->correct_name.CartTracks =
                    320:             (UCHAR)capacity.TracksPerTape;
                    321: 
                    322:         //
                    323:         // Maximum floppy tracks
                    324:         //
                    325: 
                    326:         VendorUnique->correct_name.MaxFlopTrack =
                    327:             capacity.FTrackPerFSide-1;
                    328: 
                    329:         //
                    330:         // Maximum floppy sides
                    331:         //
                    332: 
                    333:         dividend = capacity.TracksPerTape * capacity.SegmentsPerTrack;
                    334:         divisor = capacity.SegmentsPerFTrack * capacity.FTrackPerFSide;
                    335:         VendorUnique->correct_name.MaxFlopSide =
                    336:             (UCHAR)(dividend / divisor);
                    337: 
                    338:         if( !(dividend % divisor) ) {
                    339: 
                    340:             VendorUnique->correct_name.MaxFlopSide--;
                    341: 
                    342:         }
                    343: 
                    344:     } else {
                    345: 
                    346:         return(ret);
                    347: 
                    348:     }
                    349: 
                    350:     //
                    351:     // zero the tape header structure to start with
                    352:     //
                    353: 
                    354:     RtlZeroMemory(Header,sizeof(TAPE_HEADER));
                    355: 
                    356:     //
                    357:     // fill in the valid info
                    358:     //
                    359: 
                    360:     Header->Signature = TapeHeaderSig;                 // set to 0xaa55aa55l
                    361:     Header->FormatCode = capacity.TapeFormatCode;      // set to 0x02
                    362:     Header->HeaderSegment = (USHORT)HeaderSect[0];     // segment number of header
                    363:     Header->DupHeaderSegment = (USHORT)HeaderSect[1];  // segment number of duplicate header
                    364:     Header->FirstSegment = (USHORT)Context->CurrentTape.VolumeSegment;  // segment number of Data area
                    365:     Header->LastSegment = (USHORT)Context->CurrentTape.LastSegment; // segment number of End of Data area
                    366: 
                    367:     //
                    368:     // time of most recent format
                    369:     //
                    370:     Header->CurrentFormat = 0l;    // lbt_qictime()
                    371: 
                    372:     //
                    373:     // time of most recent write to cartridge
                    374:     //
                    375:     Header->CurrentUpdate = 0l;    // lbt_qictime()
                    376: 
                    377:     //
                    378:     // tape name and name change date
                    379:     //
                    380:     Header->VendorUnique = *VendorUnique;
                    381: 
                    382:     Header->ReformatError = 0;     // 0xff if any of remaining data is lost
                    383:     Header->SegmentsUsed = 0;      // incremented every time a segment is used
                    384:     Header->InitialFormat = 0l;    //lbt_qictime()   time of initial format
                    385:     Header->FormatCount = 1;       // number of times tape has been formatted
                    386:     Header->FailedSectors = 0;     // the number entries in failed sector log
                    387: 
                    388:     //
                    389:     //  Set the name of manufacturer that formatted
                    390:     //
                    391: 
                    392:     strcpy(Header->ManufacturerName,"Microsoft Windows NT (CMS Driver)");
                    393:     q117SpacePadString(
                    394:         Header->ManufacturerName,
                    395:         sizeof(Header->ManufacturerName));
                    396: 
                    397:     //
                    398:     // set format lot code
                    399:     //
                    400: 
                    401:     if (Context->drive_type == QIC40_DRIVE) {
                    402: 
                    403:         strcpy(Header->LotCode,"User Formatted,  QIC 40 rev G.");
                    404: 
                    405:     } else {
                    406: 
                    407:         strcpy(Header->LotCode,"User Formatted,  QIC 80 rev D.");
                    408: 
                    409:     }
                    410: 
                    411:     q117SpacePadString(Header->LotCode,sizeof(Header->LotCode));
                    412: 
                    413:     //
                    414:     // fill in bad sector map just generated
                    415:     //
                    416: 
                    417:     RtlMoveMemory(
                    418:         &(Header->BadMap),
                    419:         Context->CurrentTape.BadMapPtr,
                    420:         sizeof(BAD_MAP));
                    421: 
                    422:     return(ret);
                    423: }

unix.superglobalmegacorp.com

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