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*33550Sbostic * @(#)tm.c 7.4 (Berkeley) 02/24/88 723244Smckusick */ 83263Swnj 91811Sbill /* 103263Swnj * TM11/TE?? 111811Sbill */ 129806Ssam #include "../machine/pte.h" 131811Sbill 1433408Skarels #include "param.h" 1533408Skarels #include "inode.h" 1633408Skarels #include "fs.h" 179186Ssam 189186Ssam #include "../vaxuba/ubareg.h" 199186Ssam #include "../vaxuba/tmreg.h" 209186Ssam 211811Sbill #include "saio.h" 223263Swnj #include "savax.h" 231811Sbill 2433531Sbostic #define MAXCTLR 1 /* all addresses must be specified */ 2533531Sbostic u_short tmstd[MAXCTLR] = { 0172520 }; 261811Sbill 271811Sbill tmopen(io) 281924Swnj register struct iob *io; 291811Sbill { 3033531Sbostic register int skip; 311811Sbill 3233531Sbostic if ((u_int)io->i_ctlr >= MAXCTLR) 3333531Sbostic return (ECTLR); 34*33550Sbostic if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short))) 3533408Skarels return (ENXIO); 363263Swnj tmstrategy(io, TM_REW); 3733531Sbostic for (skip = io->i_part; skip--;) { 381811Sbill io->i_cc = 0; 393477Sroot tmstrategy(io, TM_SFORW); 401811Sbill } 4133408Skarels return (0); 421811Sbill } 431811Sbill 441811Sbill tmclose(io) 451924Swnj register struct iob *io; 461811Sbill { 473263Swnj tmstrategy(io, TM_REW); 481811Sbill } 491811Sbill 501811Sbill tmstrategy(io, func) 511924Swnj register struct iob *io; 521811Sbill { 5333531Sbostic register int com, errcnt; 5433531Sbostic register struct tmdevice *tmaddr; 553263Swnj int word, info; 561811Sbill 5733531Sbostic tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]); 581811Sbill errcnt = 0; 591811Sbill retry: 603263Swnj tmquiet(tmaddr); 611811Sbill info = ubasetup(io, 1); 623263Swnj tmaddr->tmbc = -io->i_cc; 633263Swnj tmaddr->tmba = info; 6433531Sbostic com = (io->i_unit<<8) | TM_GO; 651811Sbill if (func == READ) 6633531Sbostic tmaddr->tmcs = com | TM_RCOM; 671811Sbill else if (func == WRITE) 6833531Sbostic tmaddr->tmcs = com | TM_WCOM; 693263Swnj else if (func == TM_SREV) { 703263Swnj tmaddr->tmbc = -1; 7133531Sbostic tmaddr->tmcs = com | TM_SREV; 721924Swnj return (0); 731811Sbill } else 7433531Sbostic tmaddr->tmcs = com | func; 751924Swnj for (;;) { 763263Swnj word = tmaddr->tmcs; 7713568Ssam DELAY(100); 7811383Ssam if (word & TM_CUR) 791924Swnj break; 801924Swnj } 813263Swnj ubafree(io, info); 823263Swnj word = tmaddr->tmer; 8311383Ssam if (word & TMER_EOT) 8411383Ssam return (0); 8511383Ssam if (word & TM_ERR) { 8611383Ssam if (word & TMER_EOF) 8711383Ssam return (0); 8833531Sbostic printf("tm tape error: er=%b\n", word, TMER_BITS); 8933531Sbostic if (errcnt++ == 10) { 9033531Sbostic printf("tm: unrecovered error\n"); 9111383Ssam return (-1); 921811Sbill } 933263Swnj tmstrategy(io, TM_SREV); 941811Sbill goto retry; 951811Sbill } 961811Sbill if (errcnt) 9733531Sbostic printf("tm: 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