fixups just pre lint
[unix-history] / usr / src / sys / vax / mba / ht.c
CommitLineData
d565635a 1/* ht.c 4.9 81/03/08 */
0deaf016 2
89bd2f01 3#include "tu.h"
a5cc519e 4#if NHT > 0
786dff00 5/*
fcc37d29 6 * TM03/TU?? tape driver
d565635a
BJ
7 *
8 * TODO:
9 * test tape writing
10 * test error handling
11 * test 2 tapes
12 * test tape with disk on same mba
13 * test dump code
14 * try a mounted filesys on tape to check positioning code
15 * test ioctl's
16 * see how many rewind interrups we get if we kick when not at BOT
786dff00 17 */
786dff00
BJ
18#include "../h/param.h"
19#include "../h/systm.h"
20#include "../h/buf.h"
21#include "../h/conf.h"
22#include "../h/dir.h"
23#include "../h/file.h"
24#include "../h/user.h"
25#include "../h/map.h"
80e7c811 26#include "../h/pte.h"
89bd2f01
BJ
27#include "../h/mbareg.h"
28#include "../h/mbavar.h"
fcc37d29
BJ
29#include "../h/mtio.h"
30#include "../h/ioctl.h"
f0a3ddbd 31#include "../h/cmap.h"
0deaf016 32#include "../h/cpu.h"
786dff00 33
fcc37d29
BJ
34#include "../h/htreg.h"
35
36struct buf rhtbuf[NHT];
37struct buf chtbuf[NHT];
38
39short httypes[] =
40 { MBDT_TE16, MBDT_TU45, MBDT_TU77, 0 };
89bd2f01
BJ
41struct mba_device *htinfo[NHT];
42int htdkinit(), htattach(), htslave(), htustart(), htndtint(), htdtint();
fcc37d29 43struct mba_driver htdriver =
89bd2f01
BJ
44 { htattach, htslave, htustart, 0, htdtint, htndtint,
45 httypes, "ht", "tu", htinfo };
fcc37d29
BJ
46
47#define MASKREG(r) ((r) & 0xffff)
48
49/* bits in minor device */
89bd2f01 50#define TUUNIT(dev) (minor(dev)&03)
fcc37d29
BJ
51#define H_NOREWIND 04
52#define H_1600BPI 08
786dff00 53
d565635a 54#define HTUNIT(dev) (tutoht[TUUNIT(dev)])
89bd2f01 55
fcc37d29
BJ
56#define INF (daddr_t)1000000L /* a block number that wont exist */
57
d565635a 58struct tu_softc {
fcc37d29
BJ
59 char sc_openf;
60 char sc_flags;
61 daddr_t sc_blkno;
62 daddr_t sc_nxrec;
63 u_short sc_erreg;
64 u_short sc_dsreg;
65 short sc_resid;
66 short sc_dens;
89bd2f01
BJ
67 struct mba_device *sc_mi;
68 int sc_slave;
d565635a
BJ
69} tu_softc[NTU];
70short tutoht[NTU];
fcc37d29 71
fcc37d29
BJ
72/*
73 * Bits for sc_flags.
74 */
75#define H_WRITTEN 1 /* last operation was a write */
76#define H_ERASED 2 /* last write retry was an erase gap */
77#define H_REWIND 4 /* last unit start was a rewind */
786dff00 78
fcc37d29 79/*ARGSUSED*/
89bd2f01
BJ
80htattach(mi)
81 struct mba_device *mi;
82{
83
84}
85
86htslave(mi, ms)
87 struct mba_device *mi;
88 struct mba_slave *ms;
fcc37d29 89{
d565635a 90 register struct tu_softc *sc = &tu_softc[ms->ms_unit];
fcc37d29 91
89bd2f01
BJ
92 sc->sc_mi = mi;
93 sc->sc_slave = ms->ms_slave;
d565635a 94 tutoht[ms->ms_unit] = mi->mi_unit;
fcc37d29 95}
786dff00
BJ
96
97htopen(dev, flag)
fcc37d29
BJ
98 dev_t dev;
99 int flag;
786dff00 100{
d565635a 101 register int tuunit;
89bd2f01 102 register struct mba_device *mi;
d565635a
BJ
103 register struct tu_softc *sc;
104 int dens;
786dff00 105
d565635a
BJ
106 tuunit = TUUNIT(dev);
107 if (tuunit >= NTU || (sc = &tu_softc[tuunit])->sc_openf ||
89bd2f01 108 (mi = htinfo[HTUNIT(dev)]) == 0 || mi->mi_alive == 0) {
786dff00
BJ
109 u.u_error = ENXIO;
110 return;
111 }
fcc37d29 112 htcommand(dev, HT_SENSE, 1);
d565635a
BJ
113 dens =
114 ((minor(dev)&H_1600BPI)?HTTC_1600BPI:HTTC_800BPI)|
115 HTTC_PDP11|sc->sc_slave;
fcc37d29 116 if ((sc->sc_dsreg & HTDS_MOL) == 0 ||
d565635a
BJ
117 (sc->sc_dsreg & HTDS_BOT) == 0 && (flag&FWRITE) &&
118 dens != sc->sc_dens ||
fcc37d29
BJ
119 (flag & (FREAD|FWRITE)) == FWRITE && sc->sc_dsreg&HTDS_WRL) {
120 u.u_error = EIO;
121 return;
122 }
fcc37d29
BJ
123 sc->sc_openf = 1;
124 sc->sc_blkno = (daddr_t)0;
125 sc->sc_nxrec = INF;
126 sc->sc_flags = 0;
d565635a 127 sc->sc_dens = dens;
786dff00
BJ
128}
129
130htclose(dev, flag)
fcc37d29
BJ
131 register dev_t dev;
132 register flag;
786dff00 133{
d565635a 134 register struct tu_softc *sc = &tu_softc[TUUNIT(dev)];
786dff00 135
fcc37d29
BJ
136 if (flag == FWRITE || ((flag&FWRITE) && (sc->sc_flags&H_WRITTEN))) {
137 htcommand(dev, HT_WEOF, 1);
138 htcommand(dev, HT_WEOF, 1);
139 htcommand(dev, HT_SREV, 1);
786dff00 140 }
fcc37d29 141 if ((minor(dev)&H_NOREWIND) == 0)
fcc37d29
BJ
142 htcommand(dev, HT_REW, 0);
143 sc->sc_openf = 0;
786dff00
BJ
144}
145
fcc37d29
BJ
146htcommand(dev, com, count)
147 dev_t dev;
148 int com, count;
786dff00
BJ
149{
150 register struct buf *bp;
151
fcc37d29 152 bp = &chtbuf[HTUNIT(dev)];
81263dba 153 (void) spl5();
fcc37d29 154 while (bp->b_flags&B_BUSY) {
89bd2f01
BJ
155 if (bp->b_command == H_REWIND && bp->b_repcnt == 0 &&
156 (bp->b_flags&B_DONE))
157 break;
786dff00
BJ
158 bp->b_flags |= B_WANTED;
159 sleep((caddr_t)bp, PRIBIO);
160 }
dc637456 161 bp->b_flags = B_BUSY|B_READ;
81263dba 162 (void) spl0();
786dff00 163 bp->b_dev = dev;
fcc37d29
BJ
164 bp->b_command = com;
165 bp->b_repcnt = count;
786dff00 166 bp->b_blkno = 0;
786dff00 167 htstrategy(bp);
fcc37d29
BJ
168 if (count == 0)
169 return;
786dff00 170 iowait(bp);
fcc37d29 171 if (bp->b_flags&B_WANTED)
786dff00 172 wakeup((caddr_t)bp);
fcc37d29 173 bp->b_flags &= B_ERROR;
786dff00
BJ
174}
175
176htstrategy(bp)
fcc37d29 177 register struct buf *bp;
786dff00 178{
d565635a 179 register struct mba_device *mi = htinfo[HTUNIT(bp->b_dev)];
fcc37d29 180 register struct buf *dp;
786dff00 181
786dff00 182 bp->av_forw = NULL;
fcc37d29 183 dp = &mi->mi_tab;
81263dba 184 (void) spl5();
fcc37d29
BJ
185 if (dp->b_actf == NULL)
186 dp->b_actf = bp;
786dff00 187 else
fcc37d29
BJ
188 dp->b_actl->av_forw = bp;
189 dp->b_actl = bp;
190 if (dp->b_active == 0)
191 mbustart(mi);
81263dba 192 (void) spl0();
786dff00
BJ
193}
194
fcc37d29 195htustart(mi)
89bd2f01 196 register struct mba_device *mi;
786dff00 197{
fcc37d29
BJ
198 register struct htdevice *htaddr =
199 (struct htdevice *)mi->mi_drv;
200 register struct buf *bp = mi->mi_tab.b_actf;
d565635a 201 register struct tu_softc *sc = &tu_softc[TUUNIT(bp->b_dev)];
786dff00
BJ
202 daddr_t blkno;
203
fcc37d29
BJ
204 htaddr->httc = sc->sc_dens;
205 sc->sc_dsreg = htaddr->htds;
206 sc->sc_erreg = htaddr->hter;
207 sc->sc_resid = htaddr->htfc;
208 sc->sc_flags &= ~(H_WRITTEN|H_REWIND);
209 if ((htaddr->htdt & HTDT_SPR) == 0 || (htaddr->htds & HTDS_MOL) == 0)
210 if (sc->sc_openf > 0)
211 sc->sc_openf = -1;
212 if (sc->sc_openf < 0) {
213 bp->b_flags |= B_ERROR;
214 return (MBU_NEXT);
215 }
d565635a 216 if (bp != &chtbuf[HTUNIT(bp->b_dev)]) {
fcc37d29
BJ
217 if (dbtofsb(bp->b_blkno) > sc->sc_nxrec) {
218 bp->b_flags |= B_ERROR;
219 bp->b_error = ENXIO;
0deaf016 220 return (MBU_NEXT);
d565635a
BJ
221 }
222 if (dbtofsb(bp->b_blkno) == sc->sc_nxrec &&
fcc37d29
BJ
223 bp->b_flags&B_READ) {
224 bp->b_resid = bp->b_bcount;
225 clrbuf(bp);
0deaf016 226 return (MBU_NEXT);
d565635a
BJ
227 }
228 if ((bp->b_flags&B_READ)==0)
fcc37d29
BJ
229 sc->sc_nxrec = dbtofsb(bp->b_blkno) + 1;
230 } else {
0deaf016 231 if (bp->b_command == HT_SENSE)
fcc37d29
BJ
232 return (MBU_NEXT);
233 if (bp->b_command == HT_REW)
234 sc->sc_flags |= H_REWIND;
235 else
236 htaddr->htfc = -bp->b_bcount;
237 htaddr->htcs1 = bp->b_command|HT_GO;
238 return (MBU_STARTED);
239 }
240 if ((blkno = sc->sc_blkno) == dbtofsb(bp->b_blkno)) {
241 htaddr->htfc = -bp->b_bcount;
242 if ((bp->b_flags&B_READ) == 0) {
d565635a
BJ
243 if (mi->mi_tab.b_errcnt) {
244 if ((sc->sc_flags & H_ERASED) == 0) {
fcc37d29
BJ
245 sc->sc_flags |= H_ERASED;
246 htaddr->htcs1 = HT_ERASE | HT_GO;
247 return (MBU_STARTED);
248 }
d565635a
BJ
249 sc->sc_flags &= ~H_ERASED;
250 }
fcc37d29
BJ
251 if (htaddr->htds & HTDS_EOT) {
252 bp->b_resid = bp->b_bcount;
253 return (MBU_NEXT);
254 }
786dff00 255 }
fcc37d29 256 return (MBU_DODATA);
786dff00 257 }
fcc37d29
BJ
258 if (blkno < dbtofsb(bp->b_blkno)) {
259 htaddr->htfc = blkno - dbtofsb(bp->b_blkno);
260 htaddr->htcs1 = HT_SFORW|HT_GO;
786dff00 261 } else {
fcc37d29
BJ
262 htaddr->htfc = dbtofsb(bp->b_blkno) - blkno;
263 htaddr->htcs1 = HT_SREV|HT_GO;
786dff00 264 }
fcc37d29 265 return (MBU_STARTED);
786dff00
BJ
266}
267
d565635a 268htdtint(mi, mbsr)
89bd2f01 269 register struct mba_device *mi;
d565635a 270 int mbsr;
786dff00 271{
fcc37d29
BJ
272 register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv;
273 register struct buf *bp = mi->mi_tab.b_actf;
d565635a 274 register struct tu_softc *sc;
0deaf016 275 int ds, er, mbs;
786dff00 276
d565635a 277 sc = &tu_softc[TUUNIT(bp->b_dev)];
fcc37d29
BJ
278 ds = sc->sc_dsreg = MASKREG(htaddr->htds);
279 er = sc->sc_erreg = MASKREG(htaddr->hter);
280 sc->sc_resid = MASKREG(htaddr->htfc);
d565635a 281 mbs = mbsr;
fcc37d29
BJ
282 sc->sc_blkno++;
283 if((bp->b_flags & B_READ) == 0)
284 sc->sc_flags |= H_WRITTEN;
d565635a 285 if ((ds&(HTDS_ERR|HTDS_MOL)) != HTDS_MOL || mbs & MBSR_EBITS) {
fcc37d29 286 htaddr->htcs1 = HT_DCLR|HT_GO;
0deaf016
BJ
287 mbclrattn(mi);
288 if (bp == &rhtbuf[HTUNIT(bp->b_dev)]) {
fcc37d29 289 er &= ~HTER_FCE;
d565635a 290 mbs &= ~(MBSR_DTABT|MBSR_MBEXC);
0deaf016 291 }
fcc37d29
BJ
292 if (bp->b_flags & B_READ && ds & HTDS_PES)
293 er &= ~(HTER_CSITM|HTER_CORCRC);
d565635a 294 if (er&HTER_HARD || mbs&MBSR_EBITS || (ds&HTDS_MOL) == 0 ||
0deaf016 295 er && ++mi->mi_tab.b_errcnt >= 7) {
fcc37d29
BJ
296 if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0)
297 sc->sc_openf = -1;
d565635a 298 printf("tu%d: hard error bn%d mbsr=%b er=%b\n",
89bd2f01 299 TUUNIT(bp->b_dev), bp->b_blkno,
d565635a 300 mbsr, mbsr_bits,
fcc37d29 301 MASKREG(htaddr->hter), HTER_BITS);
786dff00 302 bp->b_flags |= B_ERROR;
fcc37d29 303 return (MBD_DONE);
786dff00 304 }
fcc37d29
BJ
305 if (er)
306 return (MBD_RETRY);
786dff00 307 }
fcc37d29
BJ
308 bp->b_resid = 0;
309 if (bp->b_flags & B_READ)
310 if (ds&HTDS_TM) { /* must be a read, right? */
311 bp->b_resid = bp->b_bcount;
312 sc->sc_nxrec = dbtofsb(bp->b_blkno);
313 } else if(bp->b_bcount > MASKREG(htaddr->htfc))
314 bp->b_resid = bp->b_bcount - MASKREG(htaddr->htfc);
315 return (MBD_DONE);
316}
786dff00 317
fcc37d29 318htndtint(mi)
89bd2f01 319 register struct mba_device *mi;
fcc37d29
BJ
320{
321 register struct htdevice *htaddr = (struct htdevice *)mi->mi_drv;
322 register struct buf *bp = mi->mi_tab.b_actf;
d565635a 323 register struct tu_softc *sc;
fcc37d29 324 int er, ds, fc;
786dff00 325
d565635a
BJ
326 ds = MASKREG(htaddr->htds);
327 er = MASKREG(htaddr->hter);
328 fc = MASKREG(htaddr->htfc);
329 if (er) {
fcc37d29 330 htaddr->htcs1 = HT_DCLR|HT_GO;
0deaf016
BJ
331 mbclrattn(mi);
332 }
d565635a
BJ
333 if (bp == 0)
334 return (MBN_SKIP);
335 sc = &tu_softc[TUUNIT(bp->b_dev)];
336 sc->sc_dsreg = ds;
337 sc->sc_erreg = er;
338 sc->sc_resid = fc;
339 if (bp == &chtbuf[HTUNIT(bp->b_dev)]) {
340 switch (bp->b_command) {
341 case HT_REWOFFL:
fcc37d29
BJ
342 /* offline is on purpose; don't do anything special */
343 ds |= HTDS_MOL;
d565635a
BJ
344 break;
345 case HT_SREV:
346 /* if backspace file hit bot, its not an error */
347 if (er == (HTER_NEF|HTER_FCE) && ds&HTDS_BOT &&
348 bp->b_repcnt == INF)
349 er &= ~HTER_NEF;
350 break;
351 }
fcc37d29
BJ
352 er &= ~HTER_FCE;
353 if (er == 0)
354 ds &= ~HTDS_ERR;
355 }
356 if ((ds & (HTDS_ERR|HTDS_MOL)) != HTDS_MOL) {
357 if ((ds & HTDS_MOL) == 0 && sc->sc_openf > 0)
358 sc->sc_openf = -1;
89bd2f01
BJ
359 printf("tu%d: hard error bn%d er=%b ds=%b\n",
360 TUUNIT(bp->b_dev), bp->b_blkno,
fcc37d29
BJ
361 sc->sc_erreg, HTER_BITS, sc->sc_dsreg, HTDS_BITS);
362 bp->b_flags |= B_ERROR;
363 return (MBN_DONE);
786dff00 364 }
d565635a 365 if (bp == &chtbuf[HTUNIT(bp->b_dev)]) {
fcc37d29
BJ
366 if (sc->sc_flags & H_REWIND)
367 return (ds & HTDS_BOT ? MBN_DONE : MBN_RETRY);
368 bp->b_resid = -sc->sc_resid;
369 return (MBN_DONE);
370 }
371 if (ds & HTDS_TM)
d565635a 372 if (sc->sc_blkno > dbtofsb(bp->b_blkno)) {
fcc37d29
BJ
373 sc->sc_nxrec = dbtofsb(bp->b_blkno) - fc;
374 sc->sc_blkno = sc->sc_nxrec;
d565635a 375 } else {
fcc37d29
BJ
376 sc->sc_blkno = dbtofsb(bp->b_blkno) + fc;
377 sc->sc_nxrec = sc->sc_blkno - 1;
378 }
379 else
380 sc->sc_blkno = dbtofsb(bp->b_blkno);
381 return (MBN_RETRY);
786dff00
BJ
382}
383
384htread(dev)
fcc37d29 385 dev_t dev;
786dff00 386{
fcc37d29 387
786dff00 388 htphys(dev);
fcc37d29
BJ
389 if (u.u_error)
390 return;
391 physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_READ, minphys);
786dff00
BJ
392}
393
394htwrite(dev)
395{
fcc37d29 396
786dff00 397 htphys(dev);
fcc37d29
BJ
398 if (u.u_error)
399 return;
400 physio(htstrategy, &rhtbuf[HTUNIT(dev)], dev, B_WRITE, minphys);
786dff00
BJ
401}
402
403htphys(dev)
fcc37d29 404 dev_t dev;
786dff00 405{
d565635a
BJ
406 register int htunit;
407 register struct tu_softc *sc;
408 register struct mba_device *mi;
786dff00
BJ
409 daddr_t a;
410
d565635a
BJ
411 htunit = HTUNIT(dev);
412 if (htunit >= NHT || (mi = htinfo[htunit]) == 0 || mi->mi_alive == 0) {
fcc37d29
BJ
413 u.u_error = ENXIO;
414 return;
786dff00 415 }
fcc37d29 416 a = u.u_offset >> 9;
d565635a 417 sc = &tu_softc[TUUNIT(dev)];
fcc37d29
BJ
418 sc->sc_blkno = dbtofsb(a);
419 sc->sc_nxrec = dbtofsb(a)+1;
786dff00 420}
f0a3ddbd 421
fcc37d29
BJ
422/*ARGSUSED*/
423htioctl(dev, cmd, addr, flag)
424 dev_t dev;
425 int cmd;
426 caddr_t addr;
427 int flag;
428{
d565635a
BJ
429 register struct tu_softc *sc = &tu_softc[TUUNIT(dev)];
430 register struct buf *bp = &chtbuf[HTUNIT(dev)];
fcc37d29
BJ
431 register callcount;
432 int fcount;
433 struct mtop mtop;
434 struct mtget mtget;
435 /* we depend of the values and order of the MT codes here */
436 static htops[] =
437 {HT_WEOF,HT_SFORW,HT_SREV,HT_SFORW,HT_SREV,HT_REW,HT_REWOFFL,HT_SENSE};
438
439 switch (cmd) {
440 case MTIOCTOP: /* tape operation */
441 if (copyin((caddr_t)addr, (caddr_t)&mtop, sizeof(mtop))) {
442 u.u_error = EFAULT;
443 return;
444 }
445 switch(mtop.mt_op) {
446 case MTWEOF:
447 callcount = mtop.mt_count;
448 fcount = 1;
449 break;
450 case MTFSF: case MTBSF:
451 callcount = mtop.mt_count;
452 fcount = INF;
453 break;
454 case MTFSR: case MTBSR:
455 callcount = 1;
456 fcount = mtop.mt_count;
457 break;
458 case MTREW: case MTOFFL:
459 callcount = 1;
460 fcount = 1;
461 break;
462 default:
463 u.u_error = ENXIO;
464 return;
465 }
466 if (callcount <= 0 || fcount <= 0) {
467 u.u_error = ENXIO;
468 return;
469 }
470 while (--callcount >= 0) {
471 htcommand(dev, htops[mtop.mt_op], fcount);
472 if ((mtop.mt_op == MTFSR || mtop.mt_op == MTBSR) &&
473 bp->b_resid) {
474 u.u_error = EIO;
475 break;
476 }
d565635a 477 if ((bp->b_flags&B_ERROR) || sc->sc_dsreg&HTDS_BOT)
fcc37d29
BJ
478 break;
479 }
480 geterror(bp);
481 return;
482 case MTIOCGET:
483 mtget.mt_dsreg = sc->sc_dsreg;
484 mtget.mt_erreg = sc->sc_erreg;
485 mtget.mt_resid = sc->sc_resid;
486 if (copyout((caddr_t)&mtget, addr, sizeof(mtget)))
487 u.u_error = EFAULT;
488 return;
489 default:
490 u.u_error = ENXIO;
491 }
492}
f0a3ddbd
BJ
493
494#define DBSIZE 20
495
fcc37d29 496htdump()
f0a3ddbd 497{
89bd2f01 498 register struct mba_device *mi;
fcc37d29
BJ
499 register struct mba_regs *mp;
500 register struct htdevice *htaddr;
501 int blk, num;
502 int start;
503
504 start = 0;
505 num = maxfree;
506#define phys(a,b) ((b)((int)(a)&0x7fffffff))
507 if (htinfo[0] == 0)
508 return (ENXIO);
89bd2f01 509 mi = phys(htinfo[0], struct mba_device *);
fcc37d29 510 mp = phys(mi->mi_hd, struct mba_hd *)->mh_physmba;
d565635a 511 mbainit(mp);
fcc37d29
BJ
512 htaddr = (struct htdevice *)&mp->mba_drv[mi->mi_drive];
513 htaddr->httc = HTTC_PDP11|HTTC_1600BPI;
514 htaddr->htcs1 = HT_DCLR|HT_GO;
f0a3ddbd
BJ
515 while (num > 0) {
516 blk = num > DBSIZE ? DBSIZE : num;
fcc37d29
BJ
517 htdwrite(start, blk, htaddr, mp);
518 start += blk;
f0a3ddbd
BJ
519 num -= blk;
520 }
fcc37d29
BJ
521 htwait(htaddr);
522 htaddr->htcs1 = HT_REW|HT_GO;
523 hteof(htaddr);
524 hteof(htaddr);
f0a3ddbd
BJ
525}
526
fcc37d29
BJ
527htdwrite(dbuf, num, htaddr, mp)
528 register dbuf, num;
529 register struct htdevice *htaddr;
530 struct mba_regs *mp;
f0a3ddbd 531{
fcc37d29 532 register struct pte *io;
f0a3ddbd
BJ
533 register int i;
534
fcc37d29
BJ
535 htwait(htaddr);
536 io = mp->mba_map;
f0a3ddbd 537 for (i = 0; i < num; i++)
fcc37d29
BJ
538 *(int *)io++ = dbuf++ | PG_V;
539 htaddr->htfc = -(num*NBPG);
540 mp->mba_sr = -1;
541 mp->mba_bcr = -(num*NBPG);
542 mp->mba_var = 0;
543 htaddr->htcs1 = HT_WCOM|HT_GO;
f0a3ddbd
BJ
544}
545
fcc37d29
BJ
546htwait(htaddr)
547 struct htdevice *htaddr;
f0a3ddbd
BJ
548{
549 register s;
550
551 do
fcc37d29
BJ
552 s = htaddr->htds;
553 while ((s & HTDS_DRY) == 0);
f0a3ddbd
BJ
554}
555
fcc37d29
BJ
556hteof(htaddr)
557 struct htdevice *htaddr;
f0a3ddbd
BJ
558{
559
fcc37d29
BJ
560 htwait(htaddr);
561 htaddr->htcs1 = HT_WEOF|HT_GO;
f0a3ddbd 562}
a5cc519e 563#endif