123244Smckusick /* 229311Smckusick * Copyright (c) 1982, 1986 Regents of the University of California. 323244Smckusick * All rights reserved. The Berkeley software License Agreement 423244Smckusick * specifies the terms and conditions for redistribution. 523244Smckusick * 6*33408Skarels * @(#)tm.c 7.2 (Berkeley) 01/28/88 723244Smckusick */ 83263Swnj 91811Sbill /* 103263Swnj * TM11/TE?? 111811Sbill */ 129806Ssam #include "../machine/pte.h" 131811Sbill 14*33408Skarels #include "param.h" 15*33408Skarels #include "inode.h" 16*33408Skarels #include "fs.h" 179186Ssam 189186Ssam #include "../vaxuba/ubareg.h" 199186Ssam #include "../vaxuba/tmreg.h" 209186Ssam 211811Sbill #include "saio.h" 223263Swnj #include "savax.h" 231811Sbill 241811Sbill 253263Swnj u_short tmstd[] = { 0172520 }; 261811Sbill 271811Sbill tmopen(io) 281924Swnj register struct iob *io; 291811Sbill { 301811Sbill register skip; 311811Sbill 32*33408Skarels if (badaddr((char *)ubamem(io->i_unit, tmstd[0]), sizeof (short))) { 33*33408Skarels printf("nonexistent device\n"); 34*33408Skarels return (ENXIO); 35*33408Skarels } 363263Swnj tmstrategy(io, TM_REW); 371811Sbill skip = io->i_boff; 381811Sbill while (skip--) { 391811Sbill io->i_cc = 0; 403477Sroot tmstrategy(io, TM_SFORW); 411811Sbill } 42*33408Skarels return (0); 431811Sbill } 441811Sbill 451811Sbill tmclose(io) 461924Swnj register struct iob *io; 471811Sbill { 481924Swnj 493263Swnj tmstrategy(io, TM_REW); 501811Sbill } 511811Sbill 521811Sbill tmstrategy(io, func) 531924Swnj register struct iob *io; 541811Sbill { 551811Sbill register int com, unit, errcnt; 565157Sroot register struct tmdevice *tmaddr = 575157Sroot (struct tmdevice *)ubamem(io->i_unit, tmstd[0]); 583263Swnj int word, info; 591811Sbill 601811Sbill unit = io->i_unit; 611811Sbill errcnt = 0; 621811Sbill retry: 633263Swnj tmquiet(tmaddr); 643263Swnj com = (unit<<8); 651811Sbill info = ubasetup(io, 1); 663263Swnj tmaddr->tmbc = -io->i_cc; 673263Swnj tmaddr->tmba = info; 681811Sbill if (func == READ) 693263Swnj tmaddr->tmcs = com | TM_RCOM | TM_GO; 701811Sbill else if (func == WRITE) 713263Swnj tmaddr->tmcs = com | TM_WCOM | TM_GO; 723263Swnj else if (func == TM_SREV) { 733263Swnj tmaddr->tmbc = -1; 743263Swnj tmaddr->tmcs = com | TM_SREV | TM_GO; 751924Swnj return (0); 761811Sbill } else 773263Swnj tmaddr->tmcs = com | func | TM_GO; 781924Swnj for (;;) { 793263Swnj word = tmaddr->tmcs; 8013568Ssam DELAY(100); 8111383Ssam if (word & TM_CUR) 821924Swnj break; 831924Swnj } 843263Swnj ubafree(io, info); 853263Swnj word = tmaddr->tmer; 8611383Ssam if (word & TMER_EOT) 8711383Ssam return (0); 8811383Ssam if (word & TM_ERR) { 8911383Ssam if (word & TMER_EOF) 9011383Ssam return (0); 911811Sbill if (errcnt == 0) 9211383Ssam printf("te error: er=%b", word, TMER_BITS); 9311383Ssam if (errcnt == 10) { 941811Sbill printf("\n"); 9511383Ssam return (-1); 961811Sbill } 971811Sbill errcnt++; 983263Swnj tmstrategy(io, TM_SREV); 991811Sbill goto retry; 1001811Sbill } 1011811Sbill if (errcnt) 1021811Sbill printf(" recovered by retry\n"); 10311383Ssam if (word & TMER_EOF) 10411383Ssam return (0); 10511383Ssam return (io->i_cc + tmaddr->tmbc); 1061811Sbill } 1071811Sbill 1083263Swnj tmquiet(tmaddr) 1095157Sroot register struct tmdevice *tmaddr; 1101811Sbill { 1111924Swnj register word; 1121924Swnj for (;;) { 1133263Swnj word = tmaddr->tmcs; 11413568Ssam DELAY(100); 1153263Swnj if (word&TM_CUR) 1161924Swnj break; 1171924Swnj } 1181924Swnj for (;;) { 1193263Swnj word = tmaddr->tmer; 12013568Ssam DELAY(100); 1213263Swnj if ((word&TMER_TUR) && (word&TMER_SDWN)==0) 1221924Swnj break; 1231924Swnj } 1241811Sbill } 125