|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
4: All Rights Reserved
5:
6: Module Name:
7:
8: iformat.c
9:
10: Abstract:
11:
12: Performs low level format of tape.
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: Q117iDFmt(
37: IN PTAPE_EXTENSION TapeExtension,
38: IN PIRP Irp,
39: OUT PIO_REQUEST IoRequestCurrent
40: )
41:
42: /*++
43:
44: Routine Description:
45:
46:
47:
48: Arguments:
49:
50: TapeExtension -
51:
52: Irp -
53:
54: IoRequestCurrent -
55:
56: Return Value:
57:
58:
59:
60: --*/
61:
62: {
63: STATUS retval; // return value
64: SHORT trk = 0; // current track counter
65: UCHAR speed; // holds change speed request
66: struct PerpMode perpMode;
67:
68: perpMode.command = PERP_MODE_COMMAND;
69: perpMode.drive_select = TapeExtension->QControllerData->PerpModeSelect;
70: perpMode.reserved = 0;
71: perpMode.over_write = TRUE;
72:
73: IoRequestCurrent->Data = MmGetSystemAddressForMdl(Irp->MdlAddress);
74:
75: //
76: // Set up NumTracks depending on drive type.
77: //
78:
79: switch (TapeExtension->DriveParms.DriveType) {
80:
81: case QIC40_DRIVE:
82:
83: TapeExtension->NumTracks = NUM_TTRK_40;
84: break;
85:
86: case QIC80_DRIVE:
87:
88: TapeExtension->NumTracks = NUM_TTRK_80;
89: break;
90:
91: case QIC500_DRIVE:
92:
93: TapeExtension->NumTracks = NUM_TTRK_500;
94: break;
95: }
96:
97: //
98: // Reset the FDC to make sure it is not in perpendicular Mode.
99: //
100:
101: Q117iResetFDC(TapeExtension);
102:
103: //
104: // Make sure that the tape drive is stopped and ready to start the format
105: // operation.
106: //
107:
108: if ((retval = Q117iStopTape(TapeExtension)) == NoErr) {
109:
110: //
111: // Retension the tape before each format since this is not now
112: // regularly done when a tape is inserted in the drive.
113: //
114:
115: if (retval == NoErr && TapeExtension->DriveParms.Version >=
116: FIRM_VERSION_60) {
117:
118: if ((retval = Q117iSetDriveMode(TapeExtension, PRIMARY_MODE)) ==
119: NoErr); {
120:
121: if ((retval = Q117iDReten(TapeExtension)) == NoErr); {
122:
123: retval = Q117iSetDriveMode(TapeExtension, FORMAT_MODE);
124:
125: }
126: }
127: }
128:
129: if (retval == NoErr) {
130:
131: if ((retval = Q117iWriteReferenceBurst(TapeExtension)) == NoErr) {
132:
133: //
134: // This is for the case where a QIC40 tape is fomatted in
135: // a QIC80 drive. The speed is set to FAST if the FDC
136: // supports the faster transfer rate.
137: //
138:
139: if (TapeExtension->XferRate.XferRate == SLOW &&
140: TapeExtension->XferRate.MaxRate == FAST) {
141:
142: speed = DFast;
143: retval = Q117iDFast_DSlow(TapeExtension, speed);
144:
145: }
146:
147: //
148: // Find out what the new tape format will be. This is
149: // necessary in case a QIC-40 tape is being formatted in
150: // a QIC-80 drive.
151: //
152:
153: if (retval == NoErr) {
154:
155: if ((retval = Q117iSetDriveMode(
156: TapeExtension,
157: PRIMARY_MODE)) == NoErr); {
158:
159: if ((retval = Q117iGetTapeParameters(TapeExtension)) == NoErr); {
160:
161: retval = Q117iSetDriveMode(TapeExtension, FORMAT_MODE);
162:
163: }
164:
165: }
166:
167: if (retval == NoErr) {
168:
169: //
170: // Now set up the FDC format command data. This is
171: // done now since it only needs to be done once and
172: // we don't want to use up any more time between
173: // segments than we have to.
174: //
175:
176: TapeExtension->QControllerData->FmtCmd.command = 0x4d;
177: TapeExtension->QControllerData->FmtCmd.N = FMT_BPS;
178: TapeExtension->QControllerData->FmtCmd.SC = FSC_SEG;
179: TapeExtension->QControllerData->FmtCmd.GPL = FMT_GPL;
180: TapeExtension->QControllerData->FmtCmd.drive =
181: (UCHAR)TapeExtension->DriveParms.DriveSelect;
182: TapeExtension->QControllerData->FmtCmd.D =
183: *(PUCHAR)(IoRequestCurrent->Data);
184:
185: CheckedDump(QIC117INFO,( "Q117i: Format pattern %x\n",
186: TapeExtension->QControllerData->FmtCmd.D));
187:
188: if (retval == NoErr) {
189:
190: do {
191:
192: // Enable Perpendicular Mode
193: if ((TapeExtension->DriveParms.DriveType == QIC500_DRIVE) &&
194: !TapeExtension->QControllerData->PerpendicularMode) {
195:
196: perpMode.wgate = 1;
197: perpMode.gap = 1;
198:
199: if ((retval = Q117iProgramFDC(
200: TapeExtension,
201: (CHAR *)&perpMode,
202: sizeof(perpMode),
203: FALSE)) != NoErr) {
204:
205: Q117iResetFDC(TapeExtension);
206: Q117iPauseTape(TapeExtension);
207:
208: } else {
209:
210: TapeExtension->QControllerData->PerpendicularMode = TRUE;
211:
212: }
213: }
214:
215: if (retval == NoErr) {
216:
217: *(PSHORT)IoRequestCurrent->Data = trk;
218: retval = Q117iFormatTrack(TapeExtension,
219: Irp,
220: trk,
221: IoRequestCurrent);
222:
223: CheckedDump(QIC117INFO,( "Q117i: Format track return %d (decimal)\n", retval));
224:
225: }
226:
227: if ((retval == BadFmt) ||
228: (retval == TapeFlt) ||
229: (retval == TimeOut)) {
230:
231: if ((retval = Q117iSetDriveMode(
232: TapeExtension,
233: PRIMARY_MODE)) == NoErr); {
234:
235: if ((retval = Q117iLogicalBOT(TapeExtension)) == NoErr); {
236:
237: retval = Q117iSetDriveMode(TapeExtension, FORMAT_MODE);
238:
239: }
240:
241: }
242:
243: if (retval == NoErr) {
244:
245: // Enable Perpendicular Mode
246: if ((TapeExtension->DriveParms.DriveType == QIC500_DRIVE) &&
247: !TapeExtension->QControllerData->PerpendicularMode) {
248:
249: perpMode.wgate = 1;
250: perpMode.gap = 1;
251:
252: if ((retval = Q117iProgramFDC(
253: TapeExtension,
254: (CHAR *)&perpMode,
255: sizeof(perpMode),
256: FALSE)) != NoErr) {
257:
258: Q117iResetFDC(TapeExtension);
259: Q117iPauseTape(TapeExtension);
260:
261: } else {
262:
263: TapeExtension->QControllerData->PerpendicularMode = TRUE;
264:
265: }
266: }
267:
268: if (retval == NoErr) {
269:
270: *(PSHORT)IoRequestCurrent->Data = trk;
271: retval = Q117iFormatTrack(TapeExtension,
272: Irp,
273: trk,
274: IoRequestCurrent);
275:
276: CheckedDump(QIC117INFO,( "Q117i: Format track retry return %d (decimal)\n", retval));
277: }
278:
279: }
280:
281: }
282:
283: } while (++trk < (SHORT)TapeExtension->NumTracks && retval == NoErr);
284:
285: }
286:
287: //
288: // Finish up the format by putting the tape drive
289: // back into primary mode, and ejecting the tape.
290: //
291:
292: if (retval == NoErr) {
293:
294: if ((retval = Q117iSetDriveMode(
295: TapeExtension,
296: PRIMARY_MODE)) == NoErr) {
297:
298: retval = Q117iDEject(TapeExtension);
299:
300: }
301:
302: }
303:
304: }
305:
306: }
307:
308: }
309:
310: }
311:
312: }
313:
314: if (TapeExtension->DriveParms.DriveType == QIC500_DRIVE) {
315:
316: // Disable Perpendicular Mode
317: perpMode.wgate = 0;
318: perpMode.gap = 0;
319:
320: if ((retval = Q117iProgramFDC(
321: TapeExtension,
322: (CHAR *)&perpMode,
323: sizeof(perpMode),
324: FALSE)) != NoErr) {
325:
326: Q117iResetFDC(TapeExtension);
327: Q117iPauseTape(TapeExtension);
328: return(retval);
329: }
330:
331: TapeExtension->QControllerData->PerpendicularMode = FALSE;
332:
333: }
334:
335: return(retval);
336: }
337:
338:
339: STATUS
340: Q117iFormatTrack(
341: IN PTAPE_EXTENSION TapeExtension,
342: IN PIRP Irp,
343: IN SHORT Track,
344: IN OUT PIO_REQUEST IoRequestCurrent
345: )
346:
347: /*++
348:
349: Routine Description:
350:
351: Format a track.
352:
353: This routine must first calculate the floppy id information for
354: the first sector on the requested tape track. First, the logical sector
355: is calculated. Next the head, cylinder, and starting sector are
356: calculated as follows:
357:
358: logical sector
359: head = -----------------------
360: sectors per floppy side
361:
362: logical sector % sectors per floppy side
363: cylinder = ------------------------------------------
364: floppy sectors per floppy track
365:
366: sector = logical sector % sectors per floppy side + 1
367:
368:
369:
370: Arguments:
371:
372: TapeExtension -
373:
374: Irp -
375:
376: Track - tape track to format.
377:
378: IoRequestCurrent - current Request Queue entry
379:
380: Return Value:
381:
382:
383:
384: --*/
385:
386: {
387: STATUS retval; // return value
388: LONG logSector; // logical sector number
389: SHORT i; // loop counter
390: union format_header hdrData; // sector id data
391: ULONG *hdrPtr; // pointer to sector id data for format
392: FDC_STATUS fStat; // FDC status response
393: SHORT statLength; // length of FDC status response
394: struct fdc_result result;
395:
396:
397: TapeExtension->FmtOp.Segments = TapeExtension->FmtOp.Head = 0;
398: logSector = (LONG)Track * (LONG)TapeExtension->TapeParms.FsectTtrack;
399:
400: while (logSector >= (SHORT)TapeExtension->TapeParms.FsectFside) {
401:
402: logSector -= TapeExtension->TapeParms.FsectFside;
403: TapeExtension->FmtOp.Head++;
404:
405: }
406:
407: TapeExtension->FmtOp.Cylinder = (UCHAR)((SHORT)logSector /
408: (SHORT)TapeExtension->TapeParms.FsectFtrack);
409: TapeExtension->FmtOp.Sector = (UCHAR)(((SHORT)logSector %
410: (SHORT)TapeExtension->TapeParms.FsectFtrack) + 1);
411:
412: TapeExtension->FmtOp.MdlAddress = Irp->MdlAddress;
413: TapeExtension->FmtOp.HdrPtr = (ULONG *)(IoRequestCurrent->Data);
414:
415: //
416: // Set the tape drive to the specified tape track.
417: //
418:
419: if ((retval = Q117iChangeTrack(TapeExtension, (SHORT)Track)) == NoErr) {
420:
421: //
422: // start the tape
423: //
424:
425: TapeExtension->FmtOp.retval = NoErr;
426: TapeExtension->TapePosition.LogFwd = TRUE;
427: TapeExtension->QControllerData->StartFormatMode = TRUE;
428: TapeExtension->QControllerData->EndFormatMode = FALSE;
429:
430: Q117iDLockUnlockDMA(TapeExtension, TRUE);
431:
432: retval = Q117iSendByte(TapeExtension, Logical_Fwd);
433:
434: CheckedDump(QIC117INFO,( "Q117i: FmtOp int retval %d (decimal)\n", TapeExtension->FmtOp.retval));
435: CheckedDump(QIC117INFO,( "Q117i: FmtOp retval %d (decimal)\n", retval));
436:
437: if (retval) {
438:
439: Q117iResetFDC(TapeExtension);
440: retval = Q117iStopTape(TapeExtension);
441:
442: if (retval == NoErr) {
443:
444: retval = BadFmt;
445:
446: }
447:
448: } else {
449:
450: //
451: // Complete the send byte we started during an interrupt
452: //
453:
454: if ((retval = Q117iReadFDC(TapeExtension, (CHAR *)&result, &statLength))
455: == NoErr) {
456:
457: if (! (result.ST0 & ST0_IC)) {
458:
459: if( TapeExtension->QControllerData->InterfaceType != MicroChannel) {
460:
461: if (result.ST0 !=
462: (UCHAR)(TapeExtension->DriveParms.DriveSelect | ST0_SE)) {
463:
464: retval = NECFlt;
465:
466: }
467: }
468:
469: if (TapeExtension->FmtOp.NCN != result.PCN) {
470:
471: retval = CmdFlt;
472:
473: }
474:
475: TapeExtension->QControllerData->FDC_Pcn = result.PCN;
476:
477: } else {
478:
479: retval = NECFlt;
480:
481: }
482:
483: }
484:
485: Q117iSleep(TapeExtension, mt_wt090ms, FALSE);
486:
487: //
488: // If the tape drive is ready when all of the segments have been
489: // formatted we must assume something went wrong (probably missed
490: // index pulses).
491: //
492:
493: if (Q117iGetDriveError(TapeExtension) == NotRdy) {
494:
495: if ((retval = Q117iWaitCommandComplete(
496: TapeExtension,
497: mt_wt035s)) == NoErr) {
498:
499: TapeExtension->TapePosition.LogFwd = FALSE;
500:
501: if (!TapeExtension->DriveParms.Status.BOT
502: && !TapeExtension->DriveParms.Status.EOT) {
503:
504: TapeExtension->FirmwareError = Bad_Log_Fwd;
505: retval = TapeFlt;
506:
507: }
508:
509: } else {
510:
511: Q117iStopTape(TapeExtension);
512: TapeExtension->FirmwareError = Motion_Timeout;
513:
514: }
515:
516: } else {
517:
518: retval = BadFmt;
519:
520: }
521:
522: }
523:
524: }
525:
526: TapeExtension->QControllerData->StartFormatMode = FALSE;
527: TapeExtension->QControllerData->EndFormatMode = FALSE;
528:
529: return(retval);
530: }
531:
532: STATUS
533: Q117iWriteReferenceBurst(
534: IN PTAPE_EXTENSION TapeExtension
535: )
536:
537: /*++
538:
539: Routine Description:
540:
541: Write the regerence burst on the tape.
542:
543: This operation may be attempted more than once if necessary to
544: successfully write the regerence burst. If the drive reports an
545: unreferenced tape after this operation then abort the format.
546:
547: Arguments:
548:
549: TapeExtension -
550:
551: Return Value:
552:
553:
554:
555: --*/
556:
557: {
558: STATUS retval; // return value
559: SHORT i = 0; // loop counter
560:
561: do {
562:
563: if ((retval = Q117iSendByte(TapeExtension, Write_Ref)) == NoErr) {
564:
565: retval = Q117iWaitCommandComplete(TapeExtension, mt_wt460s);
566:
567: }
568:
569: } while (++i < WRITE_REF_RPT &&
570: !TapeExtension->DriveParms.Status.Referenced &&
571: retval == NoErr);
572:
573: if ((retval == NoErr) && !TapeExtension->DriveParms.Status.Referenced) {
574:
575: retval = BadFmt;
576:
577: }
578:
579: return(retval);
580: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.