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*45803Sbostic * @(#)ht.c 7.6 (Berkeley) 12/16/90 723227Smckusick */ 8319Sbill 9319Sbill /* 103262Swnj * TM03/TU?? tape driver 11319Sbill */ 12*45803Sbostic #include "../include/pte.h" 13319Sbill 14*45803Sbostic #include "sys/param.h" 159186Ssam 16*45803Sbostic #include "../mba/htreg.h" 17*45803Sbostic #include "../mba/mbareg.h" 189186Ssam 19*45803Sbostic #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 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 55319Sbill htclose(io) 563262Swnj register struct iob *io; 57319Sbill { 583262Swnj htstrategy(io, HT_REW); 59319Sbill } 60319Sbill 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 } 833274Swnj if (func == READ || func == 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 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