2.11BSD/sys/pdpstand/tm.c
/*
* Copyright (c) 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*
* @(#)tm.c 2.3 (2.11BSD) 1997/1/19
*/
/*
* TM11 - TU10/TE10/TS03 standalone tape driver
*/
#include "../h/param.h"
#include "../pdpuba/tmreg.h"
#include "saio.h"
#define NTM 2
struct tmdevice *TMcsr[NTM + 1] =
{
(struct tmdevice *)0172520,
(struct tmdevice *)0,
(struct tmdevice *)-1
};
extern int tapemark; /* flag to indicate tapemark
has been encountered (see sys.c) */
/*
* Bits in device code.
*/
#define T_NOREWIND 04 /* not used in stand alone driver */
#define TMDENS(dev) (((dev) & 030) >> 3)
tmclose(io)
struct iob *io;
{
tmstrategy(io, TM_REW);
}
tmopen(io)
register struct iob *io;
{
register skip;
if (genopen(NTM, io) < 0)
return(-1);
io->i_flgs |= F_TAPE;
tmstrategy(io, TM_REW);
skip = io->i_part;
while (skip--) {
io->i_cc = 0;
while (tmstrategy(io, TM_SFORW))
continue;
}
return(0);
}
u_short tmdens[4] = { TM_D800, TM_D1600, TM_D6250, TM_D800 };
tmstrategy(io, func)
register struct iob *io;
{
int com, unit = io->i_unit;
register struct tmdevice *tmaddr;
int errcnt = 0, ctlr = io->i_ctlr, bae, lo16, fnc;
tmaddr = TMcsr[ctlr];
retry:
while ((tmaddr->tmcs&TM_CUR) == 0)
continue;
while ((tmaddr->tmer&TMER_TUR) == 0)
continue;
while ((tmaddr->tmer&TMER_SDWN) != 0)
continue;
iomapadr(io->i_ma, &bae, &lo16);
com = (unit<<8)|(bae<<4) | tmdens[TMDENS(unit)];
tmaddr->tmbc = -io->i_cc;
tmaddr->tmba = (caddr_t)lo16;
switch (func)
{
case READ:
fnc = TM_RCOM;
break;
case WRITE:
fnc = TM_WCOM;
break;
/*
* Just pass all others thru - all other functions are TM_* opcodes and
* had better be valid.
*/
default:
fnc = func;
break;
}
tmaddr->tmcs = com | fnc | TM_GO;
while ((tmaddr->tmcs&TM_CUR) == 0)
continue;
if (tmaddr->tmer&TMER_EOF) {
tapemark=1;
return(0);
}
if (tmaddr->tmer & TM_ERR) {
if (errcnt == 0)
printf("\n%s err: er=%o cs=%o",
devname(io), tmaddr->tmer, tmaddr->tmcs);
if (errcnt++ == 10) {
printf("\n(FATAL ERROR)\n");
return(-1);
}
tmstrategy(io, TM_SREV);
goto retry;
}
return(io->i_cc+tmaddr->tmbc);
}
tmseek(io, space)
register struct iob *io;
int space;
{
int fnc;
if (space < 0)
{
fnc = TM_SREV;
space = -space;
}
else
fnc = TM_SFORW;
io->i_cc = space;
tmstrategy(io, fnc);
return(0);
}