1*3268Swnj /* ts.c 4.1 81/03/15 */ 2*3268Swnj 3*3268Swnj /* 4*3268Swnj * TS11 tape driver 5*3268Swnj */ 6*3268Swnj 7*3268Swnj #include "../h/param.h" 8*3268Swnj #include "../h/tsreg.h" 9*3268Swnj #include "../h/inode.h" 10*3268Swnj #include "../h/pte.h" 11*3268Swnj #include "../h/ubareg.h" 12*3268Swnj #include "saio.h" 13*3268Swnj #include "savax.h" 14*3268Swnj 15*3268Swnj 16*3268Swnj u_short tsstd[] = { 0772520 }; 17*3268Swnj 18*3268Swnj struct iob ctsbuf; 19*3268Swnj 20*3268Swnj u_short ts_uba; /* Unibus address of ts structure */ 21*3268Swnj 22*3268Swnj struct device *tsaddr = 0; 23*3268Swnj 24*3268Swnj struct ts { 25*3268Swnj struct ts_cmd ts_cmd; 26*3268Swnj struct ts_char ts_char; 27*3268Swnj struct ts_sts ts_sts; 28*3268Swnj } ts; 29*3268Swnj 30*3268Swnj tsopen(io) 31*3268Swnj register struct iob *io; 32*3268Swnj { 33*3268Swnj static struct ts *ts_ubaddr; 34*3268Swnj 35*3268Swnj if (tsaddr == 0) 36*3268Swnj tsaddr = ubamem(io->i_unit, tsstd[0]); 37*3268Swnj if (ts_ubaddr==0 || tsaddr->tssr&(TS_OFL|TS_NBA) || (tsaddr->tssr&TS_SSR)==0) { 38*3268Swnj long i = 0; 39*3268Swnj tsaddr->tssr = 0; 40*3268Swnj while ((tsaddr->tssr & TS_SSR)==0) { 41*3268Swnj if (++i > 1000000) { 42*3268Swnj printf("ts: not ready\n"); 43*3268Swnj return; 44*3268Swnj } 45*3268Swnj } 46*3268Swnj } 47*3268Swnj if (tsaddr->tssr&TS_OFL) { 48*3268Swnj printf("ts: offline\n"); 49*3268Swnj return; 50*3268Swnj } 51*3268Swnj if (tsaddr->tssr&TS_NBA) { 52*3268Swnj ctsbuf.i_ma = (caddr_t) &ts; 53*3268Swnj ctsbuf.i_cc = sizeof(ts); 54*3268Swnj if (ts_ubaddr == 0) 55*3268Swnj ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 0); 56*3268Swnj ts_uba = (u_short)((long)ts_ubaddr + (((long)ubaddr >> 16) & 03)); 57*3268Swnj ts.ts_char.char_addr = (int)&ts_ubaddr->ts_sts; 58*3268Swnj ts.ts_char.char_size = sizeof(ts.ts_sts); 59*3268Swnj ts.ts_char.char_mode = TS_ESS; /* Stop on 2 tape marks */ 60*3268Swnj ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR; /* write characteristics */ 61*3268Swnj ts.ts_cmd.c_addr = (int)&ts_ubaddr->ts_char; 62*3268Swnj ts.ts_cmd.c_size = sizeof(ts.ts_char); 63*3268Swnj tsaddr->tsdb = ts_uba; 64*3268Swnj } 65*3268Swnj tsstrategy(io, TS_REW); 66*3268Swnj if (io->i_cc = io->i_boff) 67*3268Swnj tsstrategy(io, TS_SFORWF); 68*3268Swnj } 69*3268Swnj 70*3268Swnj tsclose(io) 71*3268Swnj register struct iob *io; 72*3268Swnj { 73*3268Swnj tsstrategy(io, TS_REW); 74*3268Swnj } 75*3268Swnj 76*3268Swnj tsstrategy(io, func) 77*3268Swnj register struct iob *io; 78*3268Swnj { 79*3268Swnj register int errcnt, info; 80*3268Swnj 81*3268Swnj errcnt = 0; 82*3268Swnj retry: 83*3268Swnj while ((tsaddr->tssr & TS_SSR) == 0) 84*3268Swnj ; 85*3268Swnj info = ubasetup(io, 1); 86*3268Swnj ts.ts_cmd.c_size = io->i_cc; 87*3268Swnj ts.ts_cmd.c_addr = info&0777777; 88*3268Swnj if (func == READ) 89*3268Swnj func = TS_RCOM; 90*3268Swnj else if (func == WRITE) 91*3268Swnj func = TS_WCOM; 92*3268Swnj ts.ts_cmd.c_cmd = TS_ACK|TS_CVC|func; 93*3268Swnj tsaddr->tsdb = ts_uba; 94*3268Swnj while ((tsaddr->tssr & TS_SSR) == 0) 95*3268Swnj ; 96*3268Swnj ubafree(io, info); 97*3268Swnj if (ts.ts_sts.s_xs0 & TS_TMK) /* tape mark */ 98*3268Swnj return (0); 99*3268Swnj if (tsaddr->tssr & TS_SC) { 100*3268Swnj if (errcnt == 0) 101*3268Swnj printf("ts tape error: er=%o", tsaddr->tssr); 102*3268Swnj if (errcnt==10) { 103*3268Swnj printf("\n"); 104*3268Swnj return (-1); 105*3268Swnj } 106*3268Swnj errcnt++; 107*3268Swnj if (func == TS_RCOM || func == TS_WCOM) 108*3268Swnj func |= TS_RETRY; 109*3268Swnj goto retry; 110*3268Swnj } 111*3268Swnj if (errcnt) 112*3268Swnj printf(" recovered by retry\n"); 113*3268Swnj return (io->i_cc - ts.ts_sts.s_rbpcr); 114*3268Swnj } 115