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