1 /* tm.c 4.6 81/12/01 */ 2 3 /* 4 * TM11/TE?? 5 */ 6 7 #include "../h/param.h" 8 #include "../h/inode.h" 9 #include "../h/pte.h" 10 #include "../h/ubareg.h" 11 #include "saio.h" 12 #include "savax.h" 13 14 #include "../h/tmreg.h" 15 16 u_short tmstd[] = { 0172520 }; 17 18 tmopen(io) 19 register struct iob *io; 20 { 21 register skip; 22 23 tmstrategy(io, TM_REW); 24 skip = io->i_boff; 25 while (skip--) { 26 io->i_cc = 0; 27 tmstrategy(io, TM_SFORW); 28 } 29 } 30 31 tmclose(io) 32 register struct iob *io; 33 { 34 35 tmstrategy(io, TM_REW); 36 } 37 38 tmstrategy(io, func) 39 register struct iob *io; 40 { 41 register int com, unit, errcnt; 42 register struct tmdevice *tmaddr = 43 (struct tmdevice *)ubamem(io->i_unit, tmstd[0]); 44 int word, info; 45 46 unit = io->i_unit; 47 errcnt = 0; 48 retry: 49 tmquiet(tmaddr); 50 com = (unit<<8); 51 info = ubasetup(io, 1); 52 tmaddr->tmbc = -io->i_cc; 53 tmaddr->tmba = info; 54 if (func == READ) 55 tmaddr->tmcs = com | TM_RCOM | TM_GO; 56 else if (func == WRITE) 57 tmaddr->tmcs = com | TM_WCOM | TM_GO; 58 else if (func == TM_SREV) { 59 tmaddr->tmbc = -1; 60 tmaddr->tmcs = com | TM_SREV | TM_GO; 61 return (0); 62 } else 63 tmaddr->tmcs = com | func | TM_GO; 64 for (;;) { 65 word = tmaddr->tmcs; 66 if (word&TM_CUR) 67 break; 68 } 69 ubafree(io, info); 70 word = tmaddr->tmer; 71 if (word&TMER_EOT) 72 return(0); 73 if (word < 0) { 74 if (errcnt == 0) 75 printf("te error: er=%b", tmaddr->tmer, TMER_BITS); 76 if (errcnt==10) { 77 printf("\n"); 78 return(-1); 79 } 80 errcnt++; 81 tmstrategy(io, TM_SREV); 82 goto retry; 83 } 84 if (errcnt) 85 printf(" recovered by retry\n"); 86 return (io->i_cc+tmaddr->tmbc); 87 } 88 89 tmquiet(tmaddr) 90 register struct tmdevice *tmaddr; 91 { 92 register word; 93 for (;;) { 94 word = tmaddr->tmcs; 95 if (word&TM_CUR) 96 break; 97 } 98 for (;;) { 99 word = tmaddr->tmer; 100 if ((word&TMER_TUR) && (word&TMER_SDWN)==0) 101 break; 102 } 103 } 104