123227Smckusick /*
229300Smckusick * Copyright (c) 1982, 1986 Regents of the University of California.
323227Smckusick * All rights reserved. The Berkeley software License Agreement
423227Smckusick * specifies the terms and conditions for redistribution.
523227Smckusick *
6*49100Sbostic * @(#)ht.c 7.7 (Berkeley) 05/04/91
723227Smckusick */
8319Sbill
9319Sbill /*
103262Swnj * TM03/TU?? tape driver
11319Sbill */
1245803Sbostic #include "../include/pte.h"
13319Sbill
1445803Sbostic #include "sys/param.h"
159186Ssam
1645803Sbostic #include "../mba/htreg.h"
1745803Sbostic #include "../mba/mbareg.h"
189186Ssam
1945803Sbostic #include "stand/saio.h"
203262Swnj #include "savax.h"
21319Sbill
223349Swnj short httypes[] =
233349Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
243349Swnj
253349Swnj #define MASKREG(reg) ((reg)&0xffff)
263349Swnj
htopen(io)27319Sbill htopen(io)
283262Swnj register struct iob *io;
29319Sbill {
3033526Sbostic register struct htdevice *htaddr;
3133526Sbostic register int i, skip;
32319Sbill
3333526Sbostic htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
3433526Sbostic if (mbainit(io->i_adapt) == 0)
3533526Sbostic return (EADAPT);
3633526Sbostic for (i = 0;; i++) {
3733526Sbostic if (!httypes[i]) {
3833526Sbostic printf("ht: not a tape\n");
3933526Sbostic return (ENXIO);
4033526Sbostic }
413349Swnj if (httypes[i] == (htaddr->htdt&MBDT_TYPE))
4233526Sbostic break;
4333526Sbostic }
443262Swnj htaddr->htcs1 = HT_DCLR|HT_GO;
453262Swnj htstrategy(io, HT_REW);
4633526Sbostic for (skip = io->i_part; skip--;) {
47319Sbill io->i_cc = -1;
4833526Sbostic while (htstrategy(io, HT_SFORW));
493262Swnj DELAY(65536);
503262Swnj htstrategy(io, HT_SENSE);
51319Sbill }
5233408Skarels return (0);
53319Sbill }
54319Sbill
htclose(io)55319Sbill htclose(io)
563262Swnj register struct iob *io;
57319Sbill {
583262Swnj htstrategy(io, HT_REW);
59319Sbill }
60319Sbill
htstrategy(io,func)61319Sbill htstrategy(io, func)
623262Swnj register struct iob *io;
633262Swnj int func;
64319Sbill {
6533526Sbostic register struct htdevice *htaddr;
663262Swnj register int den, errcnt, ds;
675159Sroot int er;
68319Sbill short fc;
69319Sbill
70319Sbill errcnt = 0;
7133526Sbostic htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr);
72319Sbill retry:
7333526Sbostic den = HTTC_1600BPI | HTTC_PDP11 | io->i_unit;
743262Swnj htquiet(htaddr);
753349Swnj htaddr->htcs1 = HT_DCLR|HT_GO;
763262Swnj htaddr->httc = den;
773262Swnj htaddr->htfc = -io->i_cc;
783262Swnj if (func == HT_SREV) {
793262Swnj htaddr->htfc = -1;
803262Swnj htaddr->htcs1 = HT_SREV|HT_GO;
813262Swnj return (0);
82319Sbill }
83*49100Sbostic if (func == F_READ || func == F_WRITE)
8433526Sbostic mbastart(io, io->i_ctlr, func);
85319Sbill else
863262Swnj htaddr->htcs1 = func|HT_GO;
873262Swnj htquiet(htaddr);
883262Swnj ds = htaddr->htds;
895159Sroot er = htaddr->hter;
903262Swnj if (ds & HTDS_TM) {
913262Swnj htaddr->htcs1 = HT_DCLR|HT_GO;
923262Swnj return (0);
93319Sbill }
943262Swnj if (ds & HTDS_ERR) {
953262Swnj htaddr->htcs1 = HT_DCLR|HT_GO;
965159Sroot if ((er & HTER_CORCRC) == 0) {
975159Sroot printf("ht error: ds=%b, er=%b\n",
985159Sroot MASKREG(ds), HTDS_BITS,
995159Sroot MASKREG(er), HTER_BITS);
10033526Sbostic if (errcnt++ == 10) {
1015159Sroot printf("ht: unrecovered error\n");
1025159Sroot return (-1);
1035159Sroot }
1045159Sroot htstrategy(io, HT_SREV);
1055159Sroot goto retry;
106319Sbill }
107319Sbill }
108319Sbill if (errcnt)
1093349Swnj printf("ht: recovered by retry\n");
1103262Swnj fc = htaddr->htfc;
1113262Swnj return (io->i_cc+fc);
112319Sbill }
113319Sbill
11433526Sbostic static
htquiet(htaddr)1153262Swnj htquiet(htaddr)
1163262Swnj register struct htdevice *htaddr;
117319Sbill {
118319Sbill register int s;
119319Sbill
120319Sbill do
1213262Swnj s = htaddr->htds;
1223262Swnj while ((s & HTDS_DRY) == 0);
123319Sbill }
124