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