xref: /csrg-svn/sys/vax/stand/tm.c (revision 33408)
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