123244Smckusick /*
235052Skarels * Copyright (c) 1982, 1986, 1988 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*49100Sbostic * @(#)tm.c 7.8 (Berkeley) 05/04/91
723244Smckusick */
83263Swnj
91811Sbill /*
103263Swnj * TM11/TE??
111811Sbill */
121811Sbill
1345803Sbostic #include "sys/param.h"
149186Ssam
1545803Sbostic #include "../include/pte.h"
1635052Skarels
1745803Sbostic #include "../uba/ubareg.h"
1845803Sbostic #include "../uba/tmreg.h"
199186Ssam
2045803Sbostic #include "stand/saio.h"
213263Swnj #include "savax.h"
221811Sbill
2333531Sbostic #define MAXCTLR 1 /* all addresses must be specified */
2433531Sbostic u_short tmstd[MAXCTLR] = { 0172520 };
251811Sbill
tmopen(io)261811Sbill tmopen(io)
271924Swnj register struct iob *io;
281811Sbill {
2933531Sbostic register int skip;
301811Sbill
3135052Skarels if ((u_int)io->i_adapt >= nuba)
3235052Skarels return (EADAPT);
3333531Sbostic if ((u_int)io->i_ctlr >= MAXCTLR)
3433531Sbostic return (ECTLR);
3533550Sbostic if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
3633408Skarels return (ENXIO);
373263Swnj tmstrategy(io, TM_REW);
3833531Sbostic for (skip = io->i_part; skip--;) {
391811Sbill io->i_cc = 0;
403477Sroot tmstrategy(io, TM_SFORW);
411811Sbill }
4233408Skarels return (0);
431811Sbill }
441811Sbill
tmclose(io)451811Sbill tmclose(io)
461924Swnj register struct iob *io;
471811Sbill {
483263Swnj tmstrategy(io, TM_REW);
491811Sbill }
501811Sbill
tmstrategy(io,func)511811Sbill tmstrategy(io, func)
521924Swnj register struct iob *io;
531811Sbill {
5433531Sbostic register int com, errcnt;
5533531Sbostic register struct tmdevice *tmaddr;
563263Swnj int word, info;
571811Sbill
5833531Sbostic tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
591811Sbill errcnt = 0;
601811Sbill retry:
613263Swnj tmquiet(tmaddr);
621811Sbill info = ubasetup(io, 1);
633263Swnj tmaddr->tmbc = -io->i_cc;
643263Swnj tmaddr->tmba = info;
6533531Sbostic com = (io->i_unit<<8) | TM_GO;
66*49100Sbostic if (func == F_READ)
6733531Sbostic tmaddr->tmcs = com | TM_RCOM;
68*49100Sbostic else if (func == F_WRITE)
6933531Sbostic tmaddr->tmcs = com | TM_WCOM;
703263Swnj else if (func == TM_SREV) {
713263Swnj tmaddr->tmbc = -1;
7233531Sbostic tmaddr->tmcs = com | TM_SREV;
731924Swnj return (0);
741811Sbill } else
7533531Sbostic tmaddr->tmcs = com | func;
761924Swnj for (;;) {
773263Swnj word = tmaddr->tmcs;
7813568Ssam DELAY(100);
7911383Ssam if (word & TM_CUR)
801924Swnj break;
811924Swnj }
823263Swnj ubafree(io, info);
833263Swnj word = tmaddr->tmer;
8411383Ssam if (word & TMER_EOT)
8511383Ssam return (0);
8611383Ssam if (word & TM_ERR) {
8711383Ssam if (word & TMER_EOF)
8811383Ssam return (0);
8933531Sbostic printf("tm tape error: er=%b\n", word, TMER_BITS);
9033531Sbostic if (errcnt++ == 10) {
9133531Sbostic printf("tm: unrecovered error\n");
9211383Ssam return (-1);
931811Sbill }
943263Swnj tmstrategy(io, TM_SREV);
951811Sbill goto retry;
961811Sbill }
971811Sbill if (errcnt)
9833531Sbostic printf("tm: recovered by retry\n");
9911383Ssam if (word & TMER_EOF)
10011383Ssam return (0);
10111383Ssam return (io->i_cc + tmaddr->tmbc);
1021811Sbill }
1031811Sbill
tmquiet(tmaddr)1043263Swnj tmquiet(tmaddr)
1055157Sroot register struct tmdevice *tmaddr;
1061811Sbill {
1071924Swnj register word;
1081924Swnj for (;;) {
1093263Swnj word = tmaddr->tmcs;
11013568Ssam DELAY(100);
1113263Swnj if (word&TM_CUR)
1121924Swnj break;
1131924Swnj }
1141924Swnj for (;;) {
1153263Swnj word = tmaddr->tmer;
11613568Ssam DELAY(100);
1173263Swnj if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
1181924Swnj break;
1191924Swnj }
1201811Sbill }
121