1*1924Swnj /* tm.c 4.2 12/18/80 */ 21811Sbill /* 31811Sbill * TM tape driver 41811Sbill */ 51811Sbill 61811Sbill #include "../h/param.h" 71811Sbill #include "../h/inode.h" 81811Sbill #include "../h/pte.h" 91811Sbill #include "../h/uba.h" 101811Sbill #include "saio.h" 111811Sbill 121811Sbill struct device { 131811Sbill short tmer; 141811Sbill short tmcs; 151811Sbill short tmbc; 161811Sbill u_short tmba; 171811Sbill short tmdb; 181811Sbill short tmrd; 191811Sbill }; 201811Sbill 211811Sbill #define TMADDR ((struct device *)(PHYSUMEM + 0772520 - UNIBASE)) 221811Sbill 231811Sbill #define GO 01 241811Sbill #define RCOM 02 251811Sbill #define WCOM 04 26*1924Swnj #define WEOT 06 271811Sbill #define SFORW 010 281811Sbill #define SREV 012 291811Sbill #define WIRG 014 301811Sbill #define REW 016 311811Sbill 32*1924Swnj #define DENS 0 /* 1600 bpi */ 33*1924Swnj 34*1924Swnj #define CRDY 0200 /* tmcs: control unit ready */ 35*1924Swnj #define TUR 1 /* tmer: tape unit ready */ 36*1924Swnj #define SDWN 010 /* tmer: tape settle down */ 37*1924Swnj #define HARD 0102200 /* tmer: ILC, EOT, NXM */ 38*1924Swnj #define EOT 0040000 /* tmer: at end of tape */ 39*1924Swnj 401811Sbill #define SSEEK 1 411811Sbill #define SIO 2 421811Sbill 431811Sbill tmopen(io) 44*1924Swnj register struct iob *io; 451811Sbill { 461811Sbill register skip; 471811Sbill 481811Sbill tmstrategy(io, REW); 491811Sbill skip = io->i_boff; 501811Sbill while (skip--) { 511811Sbill io->i_cc = 0; 521811Sbill while (tmstrategy(io, SFORW)) 531811Sbill ; 541811Sbill } 551811Sbill } 561811Sbill 571811Sbill tmclose(io) 58*1924Swnj register struct iob *io; 591811Sbill { 60*1924Swnj 611811Sbill tmstrategy(io, REW); 621811Sbill } 631811Sbill 641811Sbill tmstrategy(io, func) 65*1924Swnj register struct iob *io; 661811Sbill { 671811Sbill register int com, unit, errcnt; 68*1924Swnj int word; 691811Sbill int info; 701811Sbill 711811Sbill unit = io->i_unit; 721811Sbill errcnt = 0; 731811Sbill retry: 741811Sbill tmquiet(); 751811Sbill com = (unit<<8)|DENS; 761811Sbill info = ubasetup(io, 1); 771811Sbill TMADDR->tmbc = -io->i_cc; 781811Sbill TMADDR->tmba = info; 791811Sbill if (func == READ) 801811Sbill TMADDR->tmcs = com | RCOM | GO; 811811Sbill else if (func == WRITE) 821811Sbill TMADDR->tmcs = com | WCOM | GO; 831811Sbill else if (func == SREV) { 841811Sbill TMADDR->tmbc = -1; 851811Sbill TMADDR->tmcs = com | SREV | GO; 86*1924Swnj return (0); 871811Sbill } else 881811Sbill TMADDR->tmcs = com | func | GO; 89*1924Swnj for (;;) { 90*1924Swnj word = TMADDR->tmcs; 91*1924Swnj if (word&CRDY) 92*1924Swnj break; 93*1924Swnj } 941811Sbill ; 951811Sbill ubafree(info); 96*1924Swnj word = TMADDR->tmer; 97*1924Swnj if (word&EOT) 981811Sbill return(0); 99*1924Swnj if (word < 0) { 1001811Sbill if (errcnt == 0) 1011811Sbill printf("tape error: er=%o", TMADDR->tmer); 1021811Sbill if (errcnt==10) { 1031811Sbill printf("\n"); 1041811Sbill return(-1); 1051811Sbill } 1061811Sbill errcnt++; 1071811Sbill tmstrategy(io, SREV); 1081811Sbill goto retry; 1091811Sbill } 1101811Sbill if (errcnt) 1111811Sbill printf(" recovered by retry\n"); 112*1924Swnj return (io->i_cc+TMADDR->tmbc); 1131811Sbill } 1141811Sbill 1151811Sbill tmquiet() 1161811Sbill { 117*1924Swnj register word; 118*1924Swnj for (;;) { 119*1924Swnj word = TMADDR->tmcs; 120*1924Swnj if (word&CRDY) 121*1924Swnj break; 122*1924Swnj } 123*1924Swnj for (;;) { 124*1924Swnj word = TMADDR->tmer; 125*1924Swnj if ((word&TUR) && (word&SDWN)==0) 126*1924Swnj break; 127*1924Swnj } 1281811Sbill } 129