1 /* 2 * Copyright (c) 1982, 1986 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 7.3 (Berkeley) 02/22/88 7 */ 8 9 /* 10 * TM11/TE?? 11 */ 12 #include "../machine/pte.h" 13 14 #include "param.h" 15 #include "inode.h" 16 #include "fs.h" 17 18 #include "../vaxuba/ubareg.h" 19 #include "../vaxuba/tmreg.h" 20 21 #include "saio.h" 22 #include "savax.h" 23 24 #define MAXCTLR 1 /* all addresses must be specified */ 25 u_short tmstd[MAXCTLR] = { 0172520 }; 26 27 tmopen(io) 28 register struct iob *io; 29 { 30 register int skip; 31 32 if ((u_int)io->i_ctlr >= MAXCTLR) 33 return (ECTLR); 34 if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short))) { 35 printf("tm: nonexistent device\n"); 36 return (ENXIO); 37 } 38 tmstrategy(io, TM_REW); 39 for (skip = io->i_part; skip--;) { 40 io->i_cc = 0; 41 tmstrategy(io, TM_SFORW); 42 } 43 return (0); 44 } 45 46 tmclose(io) 47 register struct iob *io; 48 { 49 tmstrategy(io, TM_REW); 50 } 51 52 tmstrategy(io, func) 53 register struct iob *io; 54 { 55 register int com, errcnt; 56 register struct tmdevice *tmaddr; 57 int word, info; 58 59 tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]); 60 errcnt = 0; 61 retry: 62 tmquiet(tmaddr); 63 info = ubasetup(io, 1); 64 tmaddr->tmbc = -io->i_cc; 65 tmaddr->tmba = info; 66 com = (io->i_unit<<8) | TM_GO; 67 if (func == READ) 68 tmaddr->tmcs = com | TM_RCOM; 69 else if (func == WRITE) 70 tmaddr->tmcs = com | TM_WCOM; 71 else if (func == TM_SREV) { 72 tmaddr->tmbc = -1; 73 tmaddr->tmcs = com | TM_SREV; 74 return (0); 75 } else 76 tmaddr->tmcs = com | func; 77 for (;;) { 78 word = tmaddr->tmcs; 79 DELAY(100); 80 if (word & TM_CUR) 81 break; 82 } 83 ubafree(io, info); 84 word = tmaddr->tmer; 85 if (word & TMER_EOT) 86 return (0); 87 if (word & TM_ERR) { 88 if (word & TMER_EOF) 89 return (0); 90 printf("tm tape error: er=%b\n", word, TMER_BITS); 91 if (errcnt++ == 10) { 92 printf("tm: unrecovered error\n"); 93 return (-1); 94 } 95 tmstrategy(io, TM_SREV); 96 goto retry; 97 } 98 if (errcnt) 99 printf("tm: recovered by retry\n"); 100 if (word & TMER_EOF) 101 return (0); 102 return (io->i_cc + tmaddr->tmbc); 103 } 104 105 tmquiet(tmaddr) 106 register struct tmdevice *tmaddr; 107 { 108 register word; 109 for (;;) { 110 word = tmaddr->tmcs; 111 DELAY(100); 112 if (word&TM_CUR) 113 break; 114 } 115 for (;;) { 116 word = tmaddr->tmer; 117 DELAY(100); 118 if ((word&TMER_TUR) && (word&TMER_SDWN)==0) 119 break; 120 } 121 } 122