1*9186Ssam /* mt.c 4.3 82/11/13 */ 25151Ssam 35151Ssam /* 45151Ssam * TM78/TU78 tape driver 55151Ssam */ 65151Ssam 75151Ssam #include "../h/param.h" 8*9186Ssam #include "../h/pte.h" 95151Ssam #include "../h/inode.h" 107446Sroot #include "../h/fs.h" 11*9186Ssam 12*9186Ssam #include "../vaxmba/mtreg.h" 13*9186Ssam #include "../vaxmba/mbareg.h" 14*9186Ssam 155151Ssam #include "saio.h" 165151Ssam #include "savax.h" 175151Ssam 185151Ssam short mttypes[] = 195151Ssam { MBDT_TU78, 0 }; 205151Ssam 215151Ssam #define MASKREG(reg) ((reg)&0xffff) 225151Ssam 235151Ssam mtopen(io) 245151Ssam register struct iob *io; 255151Ssam { 265151Ssam register int skip; 275151Ssam register struct mtdevice *mtaddr = (struct mtdevice *)mbadrv(io->i_unit); 285151Ssam int i; 295151Ssam 305151Ssam for (i = 0; mttypes[i]; i++) 315151Ssam if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE)) 325151Ssam goto found; 335151Ssam _stop("not a tape\n"); 345151Ssam found: 355151Ssam mbainit(UNITTOMBA(io->i_unit)); 365151Ssam mtaddr->mtid = MTID_CLR; 375151Ssam DELAY(250); 385151Ssam while ((mtaddr->mtid & MTID_RDY) == 0) 395151Ssam ; 405151Ssam mtstrategy(io, MT_REW); 415151Ssam skip = io->i_boff; 425151Ssam while (skip--) { 435151Ssam io->i_cc = -1; 445151Ssam mtstrategy(io, MT_SFORWF); 455151Ssam } 465151Ssam } 475151Ssam 485151Ssam mtclose(io) 495151Ssam register struct iob *io; 505151Ssam { 515151Ssam 525151Ssam mtstrategy(io, MT_REW); 535151Ssam } 545151Ssam 555151Ssam mtstrategy(io, func) 565151Ssam register struct iob *io; 575151Ssam int func; 585151Ssam { 595151Ssam register int errcnt, s, ic; 605151Ssam register struct mtdevice *mtaddr = 615151Ssam (struct mtdevice *)mbadrv(io->i_unit); 625151Ssam 635151Ssam errcnt = 0; 645151Ssam retry: 655151Ssam if (func == READ || func == WRITE) { 665151Ssam mtaddr->mtca = 1<<2; /* 1 record */ 675151Ssam mtaddr->mtbc = io->i_cc; 685151Ssam mtaddr->mter = 0; 695151Ssam mbastart(io, func); 705151Ssam do 715151Ssam s = mtaddr->mter & MTER_INTCODE; 725151Ssam while (s == 0); 735151Ssam ic = s; 745151Ssam DELAY(2000); 755151Ssam } else { 765151Ssam mtaddr->mtas = -1; 775151Ssam mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO; 785151Ssam rwait: 795151Ssam do 805151Ssam s = mtaddr->mtas&0xffff; 815151Ssam while (s == 0); 825151Ssam mtaddr->mtas = mtaddr->mtas; /* clear attention */ 835151Ssam ic = mtaddr->mtner & MTER_INTCODE; 845151Ssam } 855151Ssam switch (ic) { 865151Ssam case MTER_TM: 875151Ssam case MTER_EOT: 885151Ssam case MTER_LEOT: 895151Ssam return (0); 905151Ssam 915151Ssam case MTER_DONE: 925151Ssam break; 935151Ssam 945151Ssam case MTER_RWDING: 955151Ssam goto rwait; 965151Ssam default: 975151Ssam printf("mt hard error: er=%b\n", 985151Ssam MASKREG(mtaddr->mter)); 995151Ssam mtaddr->mtid = MTID_CLR; 1005151Ssam DELAY(250); 1015151Ssam while ((mtaddr->mtid & MTID_RDY) == 0) 1025151Ssam ; 1035151Ssam return (-1); 1045151Ssam 1055151Ssam case MTER_RETRY: 1065151Ssam printf("mt error: er=%b\n", 1075151Ssam MASKREG(mtaddr->mter)); 1085151Ssam if (errcnt == 10) { 1095151Ssam printf("mt: unrecovered error\n"); 1105151Ssam return (-1); 1115151Ssam } 1125151Ssam errcnt++; 1135151Ssam goto retry; 1145151Ssam } 1155151Ssam if (errcnt) 1165151Ssam printf("mt: recovered by retry\n"); 1175151Ssam return (io->i_cc); /* NO PARTIAL RECORD READS!!! */ 1185151Ssam } 119