merge in NFS code from Rick Macklem
[unix-history] / usr / src / sys / vax / stand / mt.c
CommitLineData
55b4dbd0 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
55b4dbd0
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
c18e27ed 6 * @(#)mt.c 7.4 (Berkeley) %G%
55b4dbd0 7 */
8d272394
SL
8
9/*
10 * TM78/TU78 tape driver
26d5a33e 11 * Made to work reliably by by Jeffrey R. Schwab (Purdue)
8d272394 12 */
c18e27ed 13#include "machine/pte.h"
8d272394 14
39c71180
MK
15#include "param.h"
16#include "inode.h"
17#include "fs.h"
a031a31b
SL
18
19#include "../vaxmba/mtreg.h"
20#include "../vaxmba/mbareg.h"
21
8d272394
SL
22#include "saio.h"
23#include "savax.h"
24
25short mttypes[] =
26 { MBDT_TU78, 0 };
27
28#define MASKREG(reg) ((reg)&0xffff)
29
30mtopen(io)
31 register struct iob *io;
32{
1e07c79f
KB
33 register struct mtdevice *mtaddr;
34 register int i, skip;
35
36 if (mbainit(io->i_adapt) == 0)
37 return (EADAPT);
38 mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
39 for (i = 0;; i++) {
40 if (!mttypes[i]) {
41 printf("mt: not a tape\n");
42 return (ENXIO);
43 }
8d272394 44 if (mttypes[i] == (mtaddr->mtdt&MBDT_TYPE))
1e07c79f
KB
45 break;
46 }
8d272394
SL
47 mtaddr->mtid = MTID_CLR;
48 DELAY(250);
1e07c79f 49 while ((mtaddr->mtid & MTID_RDY) == 0);
26d5a33e
SL
50
51 /* clear any attention bits present on open */
52 i = mtaddr->mtner;
53 mtaddr->mtas = mtaddr->mtas;
54
8d272394 55 mtstrategy(io, MT_REW);
1e07c79f 56 for (skip = io->i_part; skip--;) {
8d272394
SL
57 io->i_cc = -1;
58 mtstrategy(io, MT_SFORWF);
59 }
39c71180 60 return (0);
8d272394
SL
61}
62
63mtclose(io)
64 register struct iob *io;
65{
8d272394
SL
66 mtstrategy(io, MT_REW);
67}
68
69mtstrategy(io, func)
70 register struct iob *io;
71 int func;
72{
73 register int errcnt, s, ic;
1e07c79f
KB
74 register struct mtdevice *mtaddr;
75 struct mba_regs *mba;
8d272394
SL
76
77 errcnt = 0;
1e07c79f
KB
78 mtaddr = (struct mtdevice *)mbadrv(io->i_adapt, io->i_ctlr);
79 mba = mbamba(io->i_adapt);
8d272394 80retry:
26d5a33e
SL
81 /* code to trap for attention up prior to start of command */
82 if ((mtaddr->mtas & 0xffff) != 0) {
83 printf("mt unexpected attention er=%x - continuing\n",
84 MASKREG(mtaddr->mtner));
85 mtaddr->mtas = mtaddr->mtas;
86 }
87
8d272394
SL
88 if (func == READ || func == WRITE) {
89 mtaddr->mtca = 1<<2; /* 1 record */
90 mtaddr->mtbc = io->i_cc;
1e07c79f 91 mbastart(io, io->i_ctlr, func);
26d5a33e
SL
92 /* wait for mba to go idle and read result status */
93 while((mba->mba_sr & MBSR_DTBUSY) != 0)
94 ;
95 ic = mtaddr->mter & MTER_INTCODE;
8d272394 96 } else {
8d272394
SL
97 mtaddr->mtncs[0] = (-io->i_cc << 8)|func|MT_GO;
98 rwait:
99 do
100 s = mtaddr->mtas&0xffff;
101 while (s == 0);
8d272394 102 ic = mtaddr->mtner & MTER_INTCODE;
26d5a33e 103 mtaddr->mtas = mtaddr->mtas; /* clear attention */
8d272394
SL
104 }
105 switch (ic) {
106 case MTER_TM:
107 case MTER_EOT:
108 case MTER_LEOT:
109 return (0);
110
111 case MTER_DONE:
26d5a33e
SL
112 /* make sure a record was read */
113 if ((mtaddr->mtca & (1 << 2)) != 0) {
114 printf("mt record count not decremented - retrying\n");
115 goto retry;
116 }
8d272394
SL
117 break;
118
119 case MTER_RWDING:
120 goto rwait;
121 default:
26d5a33e 122 printf("mt hard error: er=%x\n",
8d272394
SL
123 MASKREG(mtaddr->mter));
124 mtaddr->mtid = MTID_CLR;
125 DELAY(250);
126 while ((mtaddr->mtid & MTID_RDY) == 0)
127 ;
128 return (-1);
129
130 case MTER_RETRY:
26d5a33e 131 printf("mt error: er=%x\n", MASKREG(mtaddr->mter));
1e07c79f 132 if (errcnt++ == 10) {
8d272394
SL
133 printf("mt: unrecovered error\n");
134 return (-1);
135 }
8d272394
SL
136 goto retry;
137 }
138 if (errcnt)
139 printf("mt: recovered by retry\n");
140 return (io->i_cc); /* NO PARTIAL RECORD READS!!! */
141}