123244Smckusick /* 2*29311Smckusick * 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*29311Smckusick * @(#)tm.c 7.1 (Berkeley) 06/05/86 723244Smckusick */ 83263Swnj 91811Sbill /* 103263Swnj * TM11/TE?? 111811Sbill */ 129806Ssam #include "../machine/pte.h" 131811Sbill 141811Sbill #include "../h/param.h" 151811Sbill #include "../h/inode.h" 167447Sroot #include "../h/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 323263Swnj tmstrategy(io, TM_REW); 331811Sbill skip = io->i_boff; 341811Sbill while (skip--) { 351811Sbill io->i_cc = 0; 363477Sroot tmstrategy(io, TM_SFORW); 371811Sbill } 381811Sbill } 391811Sbill 401811Sbill tmclose(io) 411924Swnj register struct iob *io; 421811Sbill { 431924Swnj 443263Swnj tmstrategy(io, TM_REW); 451811Sbill } 461811Sbill 471811Sbill tmstrategy(io, func) 481924Swnj register struct iob *io; 491811Sbill { 501811Sbill register int com, unit, errcnt; 515157Sroot register struct tmdevice *tmaddr = 525157Sroot (struct tmdevice *)ubamem(io->i_unit, tmstd[0]); 533263Swnj int word, info; 541811Sbill 551811Sbill unit = io->i_unit; 561811Sbill errcnt = 0; 571811Sbill retry: 583263Swnj tmquiet(tmaddr); 593263Swnj com = (unit<<8); 601811Sbill info = ubasetup(io, 1); 613263Swnj tmaddr->tmbc = -io->i_cc; 623263Swnj tmaddr->tmba = info; 631811Sbill if (func == READ) 643263Swnj tmaddr->tmcs = com | TM_RCOM | TM_GO; 651811Sbill else if (func == WRITE) 663263Swnj tmaddr->tmcs = com | TM_WCOM | TM_GO; 673263Swnj else if (func == TM_SREV) { 683263Swnj tmaddr->tmbc = -1; 693263Swnj tmaddr->tmcs = com | TM_SREV | TM_GO; 701924Swnj return (0); 711811Sbill } else 723263Swnj tmaddr->tmcs = com | func | TM_GO; 731924Swnj for (;;) { 743263Swnj word = tmaddr->tmcs; 7513568Ssam DELAY(100); 7611383Ssam if (word & TM_CUR) 771924Swnj break; 781924Swnj } 793263Swnj ubafree(io, info); 803263Swnj word = tmaddr->tmer; 8111383Ssam if (word & TMER_EOT) 8211383Ssam return (0); 8311383Ssam if (word & TM_ERR) { 8411383Ssam if (word & TMER_EOF) 8511383Ssam return (0); 861811Sbill if (errcnt == 0) 8711383Ssam printf("te error: er=%b", word, TMER_BITS); 8811383Ssam if (errcnt == 10) { 891811Sbill printf("\n"); 9011383Ssam return (-1); 911811Sbill } 921811Sbill errcnt++; 933263Swnj tmstrategy(io, TM_SREV); 941811Sbill goto retry; 951811Sbill } 961811Sbill if (errcnt) 971811Sbill printf(" recovered by retry\n"); 9811383Ssam if (word & TMER_EOF) 9911383Ssam return (0); 10011383Ssam return (io->i_cc + tmaddr->tmbc); 1011811Sbill } 1021811Sbill 1033263Swnj tmquiet(tmaddr) 1045157Sroot register struct tmdevice *tmaddr; 1051811Sbill { 1061924Swnj register word; 1071924Swnj for (;;) { 1083263Swnj word = tmaddr->tmcs; 10913568Ssam DELAY(100); 1103263Swnj if (word&TM_CUR) 1111924Swnj break; 1121924Swnj } 1131924Swnj for (;;) { 1143263Swnj word = tmaddr->tmer; 11513568Ssam DELAY(100); 1163263Swnj if ((word&TMER_TUR) && (word&TMER_SDWN)==0) 1171924Swnj break; 1181924Swnj } 1191811Sbill } 120