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