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*33408Skarels * @(#)ht.c 7.2 (Berkeley) 01/28/88 723227Smckusick */ 8319Sbill 9319Sbill /* 103262Swnj * TM03/TU?? tape driver 11319Sbill */ 129804Ssam #include "../machine/pte.h" 13319Sbill 14*33408Skarels #include "param.h" 15*33408Skarels #include "inode.h" 16*33408Skarels #include "fs.h" 179186Ssam 189186Ssam #include "../vaxmba/htreg.h" 199186Ssam #include "../vaxmba/mbareg.h" 209186Ssam 21319Sbill #include "saio.h" 223262Swnj #include "savax.h" 23319Sbill 243349Swnj short httypes[] = 253349Swnj { MBDT_TM03, MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 }; 263349Swnj 273349Swnj #define MASKREG(reg) ((reg)&0xffff) 283349Swnj 29319Sbill htopen(io) 303262Swnj register struct iob *io; 31319Sbill { 323262Swnj register int skip; 3310865Ssam register struct htdevice *htaddr = 3410865Ssam (struct htdevice *)mbadrv(io->i_unit); 35*33408Skarels register int i; 36319Sbill 37*33408Skarels if (mbainit(UNITTOMBA(io->i_unit)) == 0) 38*33408Skarels return (ENXIO); 393349Swnj for (i = 0; httypes[i]; i++) 403349Swnj if (httypes[i] == (htaddr->htdt&MBDT_TYPE)) 413349Swnj goto found; 42*33408Skarels printf("not a tape\n"); 43*33408Skarels return (ENXIO); 443349Swnj found: 453262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 463262Swnj htstrategy(io, HT_REW); 47319Sbill skip = io->i_boff; 48319Sbill while (skip--) { 49319Sbill io->i_cc = -1; 503262Swnj while (htstrategy(io, HT_SFORW)) 51319Sbill ; 523262Swnj DELAY(65536); 533262Swnj htstrategy(io, HT_SENSE); 54319Sbill } 55*33408Skarels return (0); 56319Sbill } 57319Sbill 58319Sbill htclose(io) 593262Swnj register struct iob *io; 60319Sbill { 613262Swnj 623262Swnj htstrategy(io, HT_REW); 63319Sbill } 64319Sbill 65319Sbill htstrategy(io, func) 663262Swnj register struct iob *io; 673262Swnj int func; 68319Sbill { 693262Swnj register int den, errcnt, ds; 705159Sroot int er; 71319Sbill short fc; 723262Swnj register struct htdevice *htaddr = 733262Swnj (struct htdevice *)mbadrv(io->i_unit); 74319Sbill 75319Sbill errcnt = 0; 76319Sbill retry: 773262Swnj den = HTTC_1600BPI|HTTC_PDP11; 783262Swnj htquiet(htaddr); 793349Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 803262Swnj htaddr->httc = den; 813262Swnj htaddr->htfc = -io->i_cc; 823262Swnj if (func == HT_SREV) { 833262Swnj htaddr->htfc = -1; 843262Swnj htaddr->htcs1 = HT_SREV|HT_GO; 853262Swnj return (0); 86319Sbill } 873274Swnj if (func == READ || func == WRITE) 883262Swnj mbastart(io, func); 89319Sbill else 903262Swnj htaddr->htcs1 = func|HT_GO; 913262Swnj htquiet(htaddr); 923262Swnj ds = htaddr->htds; 935159Sroot er = htaddr->hter; 943262Swnj if (ds & HTDS_TM) { 953262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 963262Swnj return (0); 97319Sbill } 983262Swnj if (ds & HTDS_ERR) { 993262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 1005159Sroot if ((er & HTER_CORCRC) == 0) { 1015159Sroot printf("ht error: ds=%b, er=%b\n", 1025159Sroot MASKREG(ds), HTDS_BITS, 1035159Sroot MASKREG(er), HTER_BITS); 1045159Sroot if (errcnt == 10) { 1055159Sroot printf("ht: unrecovered error\n"); 1065159Sroot return (-1); 1075159Sroot } 1085159Sroot errcnt++; 1095159Sroot htstrategy(io, HT_SREV); 1105159Sroot goto retry; 111319Sbill } 112319Sbill } 113319Sbill if (errcnt) 1143349Swnj printf("ht: recovered by retry\n"); 1153262Swnj fc = htaddr->htfc; 1163262Swnj return (io->i_cc+fc); 117319Sbill } 118319Sbill 1193262Swnj htquiet(htaddr) 1203262Swnj register struct htdevice *htaddr; 121319Sbill { 122319Sbill register int s; 123319Sbill 124319Sbill do 1253262Swnj s = htaddr->htds; 1263262Swnj while ((s & HTDS_DRY) == 0); 127319Sbill } 128