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