1*5151Ssam /* mt.c 4.1 81/12/01 */ 2*5151Ssam 3*5151Ssam /* 4*5151Ssam * TM78/TU78 tape driver 5*5151Ssam */ 6*5151Ssam 7*5151Ssam #include "../h/mtreg.h" 8*5151Ssam #include "../h/param.h" 9*5151Ssam #include "../h/inode.h" 10*5151Ssam #include "../h/pte.h" 11*5151Ssam #include "../h/mbareg.h" 12*5151Ssam #include "saio.h" 13*5151Ssam #include "savax.h" 14*5151Ssam 15*5151Ssam short mttypes[] = 16*5151Ssam { MBDT_TU78, 0 }; 17*5151Ssam 18*5151Ssam #define MASKREG(reg) ((reg)&0xffff) 19*5151Ssam 20*5151Ssam mtopen(io) 21*5151Ssam register struct iob *io; 22*5151Ssam { 23*5151Ssam register int skip; 24*5151Ssam register struct mtdevice *mtaddr = (struct mtdevice *)mbadrv(io->i_unit); 25*5151Ssam int i; 26*5151Ssam 27*5151Ssam for (i = 0; mttypes[i]; i++) 28*5151Ssam if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE)) 29*5151Ssam goto found; 30*5151Ssam _stop("not a tape\n"); 31*5151Ssam found: 32*5151Ssam mbainit(UNITTOMBA(io->i_unit)); 33*5151Ssam mtaddr->mtid = MTID_CLR; 34*5151Ssam DELAY(250); 35*5151Ssam while ((mtaddr->mtid & MTID_RDY) == 0) 36*5151Ssam ; 37*5151Ssam mtstrategy(io, MT_REW); 38*5151Ssam skip = io->i_boff; 39*5151Ssam while (skip--) { 40*5151Ssam io->i_cc = -1; 41*5151Ssam mtstrategy(io, MT_SFORWF); 42*5151Ssam } 43*5151Ssam } 44*5151Ssam 45*5151Ssam mtclose(io) 46*5151Ssam register struct iob *io; 47*5151Ssam { 48*5151Ssam 49*5151Ssam mtstrategy(io, MT_REW); 50*5151Ssam } 51*5151Ssam 52*5151Ssam mtstrategy(io, func) 53*5151Ssam register struct iob *io; 54*5151Ssam int func; 55*5151Ssam { 56*5151Ssam register int errcnt, s, ic; 57*5151Ssam register struct mtdevice *mtaddr = 58*5151Ssam (struct mtdevice *)mbadrv(io->i_unit); 59*5151Ssam 60*5151Ssam errcnt = 0; 61*5151Ssam retry: 62*5151Ssam if (func == READ || func == WRITE) { 63*5151Ssam mtaddr->mtca = 1<<2; /* 1 record */ 64*5151Ssam mtaddr->mtbc = io->i_cc; 65*5151Ssam mtaddr->mter = 0; 66*5151Ssam mbastart(io, func); 67*5151Ssam do 68*5151Ssam s = mtaddr->mter & MTER_INTCODE; 69*5151Ssam while (s == 0); 70*5151Ssam ic = s; 71*5151Ssam DELAY(2000); 72*5151Ssam } else { 73*5151Ssam mtaddr->mtas = -1; 74*5151Ssam mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO; 75*5151Ssam rwait: 76*5151Ssam do 77*5151Ssam s = mtaddr->mtas&0xffff; 78*5151Ssam while (s == 0); 79*5151Ssam mtaddr->mtas = mtaddr->mtas; /* clear attention */ 80*5151Ssam ic = mtaddr->mtner & MTER_INTCODE; 81*5151Ssam } 82*5151Ssam switch (ic) { 83*5151Ssam case MTER_TM: 84*5151Ssam case MTER_EOT: 85*5151Ssam case MTER_LEOT: 86*5151Ssam return (0); 87*5151Ssam 88*5151Ssam case MTER_DONE: 89*5151Ssam break; 90*5151Ssam 91*5151Ssam case MTER_RWDING: 92*5151Ssam goto rwait; 93*5151Ssam default: 94*5151Ssam printf("mt hard error: er=%b\n", 95*5151Ssam MASKREG(mtaddr->mter)); 96*5151Ssam mtaddr->mtid = MTID_CLR; 97*5151Ssam DELAY(250); 98*5151Ssam while ((mtaddr->mtid & MTID_RDY) == 0) 99*5151Ssam ; 100*5151Ssam return (-1); 101*5151Ssam 102*5151Ssam case MTER_RETRY: 103*5151Ssam printf("mt error: er=%b\n", 104*5151Ssam MASKREG(mtaddr->mter)); 105*5151Ssam if (errcnt == 10) { 106*5151Ssam printf("mt: unrecovered error\n"); 107*5151Ssam return (-1); 108*5151Ssam } 109*5151Ssam errcnt++; 110*5151Ssam goto retry; 111*5151Ssam } 112*5151Ssam if (errcnt) 113*5151Ssam printf("mt: recovered by retry\n"); 114*5151Ssam return (io->i_cc); /* NO PARTIAL RECORD READS!!! */ 115*5151Ssam } 116