1 /* tm.c 4.2 12/18/80 */ 2 /* 3 * TM tape driver 4 */ 5 6 #include "../h/param.h" 7 #include "../h/inode.h" 8 #include "../h/pte.h" 9 #include "../h/uba.h" 10 #include "saio.h" 11 12 struct device { 13 short tmer; 14 short tmcs; 15 short tmbc; 16 u_short tmba; 17 short tmdb; 18 short tmrd; 19 }; 20 21 #define TMADDR ((struct device *)(PHYSUMEM + 0772520 - UNIBASE)) 22 23 #define GO 01 24 #define RCOM 02 25 #define WCOM 04 26 #define WEOT 06 27 #define SFORW 010 28 #define SREV 012 29 #define WIRG 014 30 #define REW 016 31 32 #define DENS 0 /* 1600 bpi */ 33 34 #define CRDY 0200 /* tmcs: control unit ready */ 35 #define TUR 1 /* tmer: tape unit ready */ 36 #define SDWN 010 /* tmer: tape settle down */ 37 #define HARD 0102200 /* tmer: ILC, EOT, NXM */ 38 #define EOT 0040000 /* tmer: at end of tape */ 39 40 #define SSEEK 1 41 #define SIO 2 42 43 tmopen(io) 44 register struct iob *io; 45 { 46 register skip; 47 48 tmstrategy(io, REW); 49 skip = io->i_boff; 50 while (skip--) { 51 io->i_cc = 0; 52 while (tmstrategy(io, SFORW)) 53 ; 54 } 55 } 56 57 tmclose(io) 58 register struct iob *io; 59 { 60 61 tmstrategy(io, REW); 62 } 63 64 tmstrategy(io, func) 65 register struct iob *io; 66 { 67 register int com, unit, errcnt; 68 int word; 69 int info; 70 71 unit = io->i_unit; 72 errcnt = 0; 73 retry: 74 tmquiet(); 75 com = (unit<<8)|DENS; 76 info = ubasetup(io, 1); 77 TMADDR->tmbc = -io->i_cc; 78 TMADDR->tmba = info; 79 if (func == READ) 80 TMADDR->tmcs = com | RCOM | GO; 81 else if (func == WRITE) 82 TMADDR->tmcs = com | WCOM | GO; 83 else if (func == SREV) { 84 TMADDR->tmbc = -1; 85 TMADDR->tmcs = com | SREV | GO; 86 return (0); 87 } else 88 TMADDR->tmcs = com | func | GO; 89 for (;;) { 90 word = TMADDR->tmcs; 91 if (word&CRDY) 92 break; 93 } 94 ; 95 ubafree(info); 96 word = TMADDR->tmer; 97 if (word&EOT) 98 return(0); 99 if (word < 0) { 100 if (errcnt == 0) 101 printf("tape error: er=%o", TMADDR->tmer); 102 if (errcnt==10) { 103 printf("\n"); 104 return(-1); 105 } 106 errcnt++; 107 tmstrategy(io, SREV); 108 goto retry; 109 } 110 if (errcnt) 111 printf(" recovered by retry\n"); 112 return (io->i_cc+TMADDR->tmbc); 113 } 114 115 tmquiet() 116 { 117 register word; 118 for (;;) { 119 word = TMADDR->tmcs; 120 if (word&CRDY) 121 break; 122 } 123 for (;;) { 124 word = TMADDR->tmer; 125 if ((word&TUR) && (word&SDWN)==0) 126 break; 127 } 128 } 129