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*33526Sbostic * @(#)ht.c 7.3 (Berkeley) 02/22/88 723227Smckusick */ 8319Sbill 9319Sbill /* 103262Swnj * TM03/TU?? tape driver 11319Sbill */ 129804Ssam #include "../machine/pte.h" 13319Sbill 1433408Skarels #include "param.h" 1533408Skarels #include "inode.h" 1633408Skarels #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 { 32*33526Sbostic register struct htdevice *htaddr; 33*33526Sbostic register int i, skip; 34319Sbill 35*33526Sbostic htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr); 36*33526Sbostic if (mbainit(io->i_adapt) == 0) 37*33526Sbostic return (EADAPT); 38*33526Sbostic for (i = 0;; i++) { 39*33526Sbostic if (!httypes[i]) { 40*33526Sbostic printf("ht: not a tape\n"); 41*33526Sbostic return (ENXIO); 42*33526Sbostic } 433349Swnj if (httypes[i] == (htaddr->htdt&MBDT_TYPE)) 44*33526Sbostic break; 45*33526Sbostic } 463262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 473262Swnj htstrategy(io, HT_REW); 48*33526Sbostic for (skip = io->i_part; skip--;) { 49319Sbill io->i_cc = -1; 50*33526Sbostic while (htstrategy(io, HT_SFORW)); 513262Swnj DELAY(65536); 523262Swnj htstrategy(io, HT_SENSE); 53319Sbill } 5433408Skarels return (0); 55319Sbill } 56319Sbill 57319Sbill htclose(io) 583262Swnj register struct iob *io; 59319Sbill { 603262Swnj htstrategy(io, HT_REW); 61319Sbill } 62319Sbill 63319Sbill htstrategy(io, func) 643262Swnj register struct iob *io; 653262Swnj int func; 66319Sbill { 67*33526Sbostic register struct htdevice *htaddr; 683262Swnj register int den, errcnt, ds; 695159Sroot int er; 70319Sbill short fc; 71319Sbill 72319Sbill errcnt = 0; 73*33526Sbostic htaddr = (struct htdevice *)mbadrv(io->i_adapt, io->i_ctlr); 74319Sbill retry: 75*33526Sbostic den = HTTC_1600BPI | HTTC_PDP11 | io->i_unit; 763262Swnj htquiet(htaddr); 773349Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 783262Swnj htaddr->httc = den; 793262Swnj htaddr->htfc = -io->i_cc; 803262Swnj if (func == HT_SREV) { 813262Swnj htaddr->htfc = -1; 823262Swnj htaddr->htcs1 = HT_SREV|HT_GO; 833262Swnj return (0); 84319Sbill } 853274Swnj if (func == READ || func == WRITE) 86*33526Sbostic mbastart(io, io->i_ctlr, func); 87319Sbill else 883262Swnj htaddr->htcs1 = func|HT_GO; 893262Swnj htquiet(htaddr); 903262Swnj ds = htaddr->htds; 915159Sroot er = htaddr->hter; 923262Swnj if (ds & HTDS_TM) { 933262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 943262Swnj return (0); 95319Sbill } 963262Swnj if (ds & HTDS_ERR) { 973262Swnj htaddr->htcs1 = HT_DCLR|HT_GO; 985159Sroot if ((er & HTER_CORCRC) == 0) { 995159Sroot printf("ht error: ds=%b, er=%b\n", 1005159Sroot MASKREG(ds), HTDS_BITS, 1015159Sroot MASKREG(er), HTER_BITS); 102*33526Sbostic if (errcnt++ == 10) { 1035159Sroot printf("ht: unrecovered error\n"); 1045159Sroot return (-1); 1055159Sroot } 1065159Sroot htstrategy(io, HT_SREV); 1075159Sroot goto retry; 108319Sbill } 109319Sbill } 110319Sbill if (errcnt) 1113349Swnj printf("ht: recovered by retry\n"); 1123262Swnj fc = htaddr->htfc; 1133262Swnj return (io->i_cc+fc); 114319Sbill } 115319Sbill 116*33526Sbostic static 1173262Swnj htquiet(htaddr) 1183262Swnj register struct htdevice *htaddr; 119319Sbill { 120319Sbill register int s; 121319Sbill 122319Sbill do 1233262Swnj s = htaddr->htds; 1243262Swnj while ((s & HTDS_DRY) == 0); 125319Sbill } 126