4.4BSD/usr/src/sys/vax/stand/tm.c

Compare this file to the similar file:
Show the results in this format:

/*
 * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
 * All rights reserved.  The Berkeley software License Agreement
 * specifies the terms and conditions for redistribution.
 *
 *	@(#)tm.c	7.8 (Berkeley) 5/4/91
 */

/*
 * TM11/TE??
 */

#include "sys/param.h"

#include "../include/pte.h"

#include "../uba/ubareg.h"
#include "../uba/tmreg.h"

#include "stand/saio.h"
#include "savax.h"

#define	MAXCTLR		1		/* all addresses must be specified */
u_short	tmstd[MAXCTLR] = { 0172520 };

tmopen(io)
	register struct iob *io;
{
	register int skip;

	if ((u_int)io->i_adapt >= nuba)
		return (EADAPT);
	if ((u_int)io->i_ctlr >= MAXCTLR)
		return (ECTLR);
	if (badaddr((char *)ubamem(io->i_adapt, tmstd[io->i_ctlr]), sizeof(short)))
		return (ENXIO);
	tmstrategy(io, TM_REW);
	for (skip = io->i_part; skip--;) {
		io->i_cc = 0;
		tmstrategy(io, TM_SFORW);
	}
	return (0);
}

tmclose(io)
	register struct iob *io;
{
	tmstrategy(io, TM_REW);
}

tmstrategy(io, func)
	register struct iob *io;
{
	register int com, errcnt;
	register struct tmdevice *tmaddr;
	int word, info;

	tmaddr = (struct tmdevice *)ubamem(io->i_adapt, tmstd[io->i_ctlr]);
	errcnt = 0;
retry:
	tmquiet(tmaddr);
	info = ubasetup(io, 1);
	tmaddr->tmbc = -io->i_cc;
	tmaddr->tmba = info;
	com = (io->i_unit<<8) | TM_GO;
	if (func == F_READ)
		tmaddr->tmcs = com | TM_RCOM;
	else if (func == F_WRITE)
		tmaddr->tmcs = com | TM_WCOM;
	else if (func == TM_SREV) {
		tmaddr->tmbc = -1;
		tmaddr->tmcs = com | TM_SREV;
		return (0);
	} else
		tmaddr->tmcs = com | func;
	for (;;) {
		word = tmaddr->tmcs;
		DELAY(100);
		if (word & TM_CUR)
			break;
	}
	ubafree(io, info);
	word = tmaddr->tmer;
	if (word & TMER_EOT)
		return (0);
	if (word & TM_ERR) {
		if (word & TMER_EOF)
			return (0);
		printf("tm tape error: er=%b\n", word, TMER_BITS);
		if (errcnt++ == 10) {
			printf("tm: unrecovered error\n");
			return (-1);
		}
		tmstrategy(io, TM_SREV);
		goto retry;
	}
	if (errcnt)
		printf("tm: recovered by retry\n");
	if (word & TMER_EOF)
		return (0);
	return (io->i_cc + tmaddr->tmbc);
}

tmquiet(tmaddr)
	register struct tmdevice *tmaddr;
{
	register word;
	for (;;) {
		word = tmaddr->tmcs;
		DELAY(100);
		if (word&TM_CUR)
			break;
	}
	for (;;) {
		word = tmaddr->tmer;
		DELAY(100);
		if ((word&TMER_TUR) && (word&TMER_SDWN)==0)
			break;
	}
}