1*5158Sroot /* ts.c 4.4 81/12/01 */ 23268Swnj 33268Swnj /* 43268Swnj * TS11 tape driver 53268Swnj */ 63268Swnj 73268Swnj #include "../h/param.h" 83268Swnj #include "../h/tsreg.h" 93268Swnj #include "../h/inode.h" 103268Swnj #include "../h/pte.h" 113268Swnj #include "../h/ubareg.h" 123268Swnj #include "saio.h" 133268Swnj #include "savax.h" 143268Swnj 153268Swnj 163268Swnj u_short tsstd[] = { 0772520 }; 173268Swnj 183268Swnj struct iob ctsbuf; 193268Swnj 203268Swnj u_short ts_uba; /* Unibus address of ts structure */ 213268Swnj 22*5158Sroot struct tsdevice *tsaddr = 0; 233268Swnj 243268Swnj struct ts { 253268Swnj struct ts_cmd ts_cmd; 263268Swnj struct ts_char ts_char; 273268Swnj struct ts_sts ts_sts; 283268Swnj } ts; 293268Swnj 303268Swnj tsopen(io) 313268Swnj register struct iob *io; 323268Swnj { 333268Swnj static struct ts *ts_ubaddr; 343344Swnj long i = 0; 353268Swnj 363268Swnj if (tsaddr == 0) 373268Swnj tsaddr = ubamem(io->i_unit, tsstd[0]); 383344Swnj tsaddr->tssr = 0; 393344Swnj while ((tsaddr->tssr & TS_SSR)==0) { 403344Swnj if (++i > 1000000) { 413344Swnj printf("ts: not ready\n"); 423344Swnj return; 433268Swnj } 443268Swnj } 453268Swnj if (tsaddr->tssr&TS_OFL) { 463268Swnj printf("ts: offline\n"); 473268Swnj return; 483268Swnj } 493268Swnj if (tsaddr->tssr&TS_NBA) { 503344Swnj int i; 513344Swnj 523268Swnj ctsbuf.i_ma = (caddr_t) &ts; 533268Swnj ctsbuf.i_cc = sizeof(ts); 543268Swnj if (ts_ubaddr == 0) 553344Swnj ts_ubaddr = (struct ts *)ubasetup(&ctsbuf, 2); 563344Swnj ts_uba = (u_short)((long)ts_ubaddr + (((long)ts_ubaddr>>16)&03)); 573268Swnj ts.ts_char.char_addr = (int)&ts_ubaddr->ts_sts; 583268Swnj ts.ts_char.char_size = sizeof(ts.ts_sts); 593344Swnj ts.ts_char.char_mode = TS_ESS; 603344Swnj ts.ts_cmd.c_cmd = TS_ACK|TS_SETCHR; 613344Swnj i = (int)&ts_ubaddr->ts_char; 623344Swnj ts.ts_cmd.c_loba = i; 633344Swnj ts.ts_cmd.c_hiba = (i>>16)&3; 643268Swnj ts.ts_cmd.c_size = sizeof(ts.ts_char); 653268Swnj tsaddr->tsdb = ts_uba; 663268Swnj } 673268Swnj tsstrategy(io, TS_REW); 683268Swnj if (io->i_cc = io->i_boff) 693268Swnj tsstrategy(io, TS_SFORWF); 703268Swnj } 713268Swnj 723268Swnj tsclose(io) 733268Swnj register struct iob *io; 743268Swnj { 753344Swnj 763268Swnj tsstrategy(io, TS_REW); 773268Swnj } 783268Swnj 793268Swnj tsstrategy(io, func) 803268Swnj register struct iob *io; 813268Swnj { 823344Swnj register int errcnt, info = 0; 833268Swnj 843268Swnj errcnt = 0; 853268Swnj retry: 863268Swnj while ((tsaddr->tssr & TS_SSR) == 0) 873344Swnj DELAY(100); 883344Swnj if (func == TS_REW || func == TS_SFORWF) 893344Swnj ts.ts_cmd.c_repcnt = io->i_cc; 903344Swnj else { 913344Swnj info = ubasetup(io, 1); 923344Swnj ts.ts_cmd.c_size = io->i_cc; 933344Swnj ts.ts_cmd.c_loba = info; 943344Swnj ts.ts_cmd.c_hiba = (info>>16)&3; 953344Swnj } 963268Swnj if (func == READ) 973268Swnj func = TS_RCOM; 983268Swnj else if (func == WRITE) 993268Swnj func = TS_WCOM; 1003268Swnj ts.ts_cmd.c_cmd = TS_ACK|TS_CVC|func; 1013268Swnj tsaddr->tsdb = ts_uba; 1023344Swnj do 1033344Swnj DELAY(100) 1043344Swnj while ((tsaddr->tssr & TS_SSR) == 0); 1053344Swnj if (info) 1063344Swnj ubafree(io, info); 1073344Swnj if (ts.ts_sts.s_xs0 & TS_TMK) 1083268Swnj return (0); 1093268Swnj if (tsaddr->tssr & TS_SC) { 1103349Swnj printf("ts tape error: er=%b, xs0=%b", 1113349Swnj tsaddr->tssr, TSSR_BITS, 1123349Swnj ts.ts_sts.s_xs0, TSXS0_BITS); 1133268Swnj if (errcnt==10) { 1143349Swnj printf("ts: unrecovered error\n"); 1153268Swnj return (-1); 1163268Swnj } 1173268Swnj errcnt++; 1183268Swnj if (func == TS_RCOM || func == TS_WCOM) 1193268Swnj func |= TS_RETRY; 1203268Swnj goto retry; 1213268Swnj } 1223268Swnj if (errcnt) 1233349Swnj printf("ts: recovered by retry\n"); 1243268Swnj return (io->i_cc - ts.ts_sts.s_rbpcr); 1253268Swnj } 126