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