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