1 /* tm.c 4.1 11/14/80 */ 2 /* 3 * TM tape driver 4 */ 5 6 #include "../h/param.h" 7 #include "../h/inode.h" 8 #include "../h/pte.h" 9 #include "../h/uba.h" 10 #include "saio.h" 11 12 struct device { 13 short tmer; 14 short tmcs; 15 short tmbc; 16 u_short tmba; 17 short tmdb; 18 short tmrd; 19 }; 20 21 #define TMADDR ((struct device *)(PHYSUMEM + 0772520 - UNIBASE)) 22 23 #define GO 01 24 #define RCOM 02 25 #define WCOM 04 26 #define WEOF 06 27 #define SFORW 010 28 #define SREV 012 29 #define WIRG 014 30 #define REW 016 31 #define DENS 060000 /* 9-channel */ 32 #define IENABLE 0100 33 #define CRDY 0200 34 #define GAPSD 010000 35 #define TUR 1 36 #define SDWN 010 37 #define HARD 0102200 /* ILC, EOT, NXM */ 38 #define EOF 0040000 39 40 #define SSEEK 1 41 #define SIO 2 42 43 tmopen(io) 44 register struct iob *io; 45 { 46 register skip; 47 48 tmstrategy(io, REW); 49 skip = io->i_boff; 50 while (skip--) { 51 io->i_cc = 0; 52 while (tmstrategy(io, SFORW)) 53 ; 54 } 55 } 56 57 tmclose(io) 58 register struct iob *io; 59 { 60 tmstrategy(io, REW); 61 } 62 63 tmstrategy(io, func) 64 register struct iob *io; 65 { 66 register int com, unit, errcnt; 67 int info; 68 69 unit = io->i_unit; 70 errcnt = 0; 71 retry: 72 tmquiet(); 73 com = (unit<<8)|DENS; 74 info = ubasetup(io, 1); 75 TMADDR->tmbc = -io->i_cc; 76 TMADDR->tmba = info; 77 if (func == READ) 78 TMADDR->tmcs = com | RCOM | GO; 79 else if (func == WRITE) 80 TMADDR->tmcs = com | WCOM | GO; 81 else if (func == SREV) { 82 TMADDR->tmbc = -1; 83 TMADDR->tmcs = com | SREV | GO; 84 return(0); 85 } else 86 TMADDR->tmcs = com | func | GO; 87 while ((TMADDR->tmcs&CRDY) == 0) 88 ; 89 ubafree(info); 90 if (TMADDR->tmer&EOF) 91 return(0); 92 if (TMADDR->tmer < 0) { 93 if (errcnt == 0) 94 printf("tape error: er=%o", TMADDR->tmer); 95 if (errcnt==10) { 96 printf("\n"); 97 return(-1); 98 } 99 errcnt++; 100 tmstrategy(io, SREV); 101 goto retry; 102 } 103 if (errcnt) 104 printf(" recovered by retry\n"); 105 return( io->i_cc+TMADDR->tmbc ); 106 } 107 108 tmquiet() 109 { 110 while ((TMADDR->tmcs&CRDY) == 0) 111 ; 112 while ((TMADDR->tmer&TUR) == 0) 113 ; 114 while ((TMADDR->tmer&SDWN) != 0) 115 ; 116 } 117