Annotation of ntddk/src/scsi/qic117/format.c, revision 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.