merge of 4.1b and 4.1c
[unix-history] / usr / src / sys / vax / uba / ut.c
CommitLineData
a1edc12b 1/* ut.c 4.21 82/10/17 */
b02cd1e9 2
7c6c07eb 3#include "tj.h"
b02cd1e9 4#if NUT > 0
b02cd1e9
BJ
5/*
6 * System Industries Model 9700 Tape Drive
7 * emulates a TU45 on the UNIBUS
8 *
9 * TODO:
10 * check out attention processing
11 * try reset code and dump code
12 */
13#include "../h/param.h"
14#include "../h/systm.h"
15#include "../h/buf.h"
16#include "../h/conf.h"
17#include "../h/dir.h"
18#include "../h/file.h"
19#include "../h/user.h"
20#include "../h/map.h"
21#include "../h/pte.h"
b02cd1e9 22#include "../h/ioctl.h"
942f05a9 23#include "../h/mtio.h"
b02cd1e9 24#include "../h/cmap.h"
740e4029 25#include "../h/uio.h"
b02cd1e9 26
896962b1
BJ
27#include "../vax/cpu.h"
28#include "../vaxuba/ubareg.h"
29#include "../vaxuba/ubavar.h"
30#include "../vaxuba/utreg.h"
b02cd1e9
BJ
31
32struct buf rutbuf[NUT]; /* bufs for raw i/o */
33struct buf cutbuf[NUT]; /* bufs for control operations */
34struct buf tjutab[NTJ]; /* bufs for slave queue headers */
35
36struct uba_ctlr *utminfo[NUT];
37struct uba_device *tjdinfo[NTJ];
407582e3 38int utprobe(), utslave(), utattach(), utdgo(), utintr(), uttimer();
b02cd1e9
BJ
39u_short utstd[] = { 0772440, 0 };
40struct uba_driver utdriver =
41 { utprobe, utslave, utattach, utdgo, utstd, "tj", tjdinfo, "ut", utminfo, 0 };
42
43/* bits in minor device */
44#define TJUNIT(dev) (minor(dev)&03)
45#define T_NOREWIND 04
46#define T_1600BPI 010
47#define T_6250BPI 020
48short utdens[] = { UT_NRZI, UT_PE, UT_GCR, UT_NRZI };
49
50/* slave to controller mapping table */
51short tjtout[NTJ];
52#define UTUNIT(dev) (tjtout[TJUNIT(dev)])
53
54#define INF (daddr_t)1000000L /* a block number that wont exist */
55
56struct tj_softc {
57 char sc_openf; /* exclusive open */
58 char sc_lastiow; /* last I/O operation was a write */
59 daddr_t sc_blkno; /* next block to transfer */
60 daddr_t sc_nxrec; /* next record on tape */
61 u_short sc_erreg; /* image of uter */
62 u_short sc_dsreg; /* image of utds */
c36079e2 63 u_short sc_resid; /* residual from transfer */
b02cd1e9 64 u_short sc_dens; /* sticky selected density */
407582e3
BJ
65 daddr_t sc_timo; /* time until timeout expires */
66 short sc_tact; /* timeout is active flag */
b02cd1e9
BJ
67} tj_softc[NTJ];
68
69/*
70 * Internal per/slave states found in sc_state
71 */
72#define SSEEK 1 /* seeking */
73#define SIO 2 /* doing sequential I/O */
74#define SCOM 3 /* sending a control command */
75#define SREW 4 /* doing a rewind op */
c36079e2
SL
76#define SERASE 5 /* erase inter-record gap */
77#define SERASED 6 /* erased inter-record gap */
b02cd1e9 78
89b8a44c 79/*ARGSUSED*/
b02cd1e9
BJ
80utprobe(reg)
81 caddr_t reg;
82{
83 register int br, cvec;
84#ifdef lint
85 br=0; cvec=br; br=cvec;
89b8a44c 86 utintr(0);
b02cd1e9 87#endif
c36079e2 88 /*
e090266d
BJ
89 * The SI documentation says you must set the RDY bit
90 * (even though it's read-only) to force an interrupt.
c36079e2 91 */
e090266d 92 ((struct utdevice *) reg)->utcs1 = UT_IE|UT_NOP|UT_RDY;
b02cd1e9 93 DELAY(10000);
9c0adba0 94 return (sizeof (struct utdevice));
b02cd1e9
BJ
95}
96
97/*ARGSUSED*/
98utslave(ui, reg)
99 struct uba_device *ui;
100 caddr_t reg;
101{
102 /*
103 * A real TU45 would support the slave present bit
104 * int the drive type register, but this thing doesn't,
105 * so there's no way to determine if a slave is present or not.
106 */
107 return(1);
108}
109
110utattach(ui)
111 struct uba_device *ui;
112{
113 tjtout[ui->ui_unit] = ui->ui_mi->um_ctlr;
114}
115
116/*
117 * Open the device with exclusive access.
118 */
119utopen(dev, flag)
120 dev_t dev;
121 int flag;
122{
123 register int tjunit = TJUNIT(dev);
124 register struct uba_device *ui;
125 register struct tj_softc *sc;
126 int olddens, dens;
2311123d 127 register int s;
b02cd1e9
BJ
128
129 if (tjunit >= NTJ || (sc = &tj_softc[tjunit])->sc_openf ||
7da157da
BJ
130 (ui = tjdinfo[tjunit]) == 0 || ui->ui_alive == 0)
131 return (ENXIO);
b02cd1e9 132 olddens = sc->sc_dens;
7da157da
BJ
133 dens = sc->sc_dens =
134 utdens[(minor(dev)&(T_1600BPI|T_6250BPI))>>3]|
135 PDP11FMT|(ui->ui_slave&07);
b02cd1e9
BJ
136get:
137 utcommand(dev, UT_SENSE, 1);
138 if (sc->sc_dsreg&UTDS_PIP) {
139 sleep((caddr_t) &lbolt, PZERO+1);
140 goto get;
141 }
142 sc->sc_dens = olddens;
143 if ((sc->sc_dsreg&UTDS_MOL) == 0) {
144 uprintf("tj%d: not online\n", tjunit);
7da157da 145 return (EIO);
b02cd1e9
BJ
146 }
147 if ((flag&FWRITE) && (sc->sc_dsreg&UTDS_WRL)) {
148 uprintf("tj%d: no write ring\n", tjunit);
7da157da 149 return (EIO);
b02cd1e9
BJ
150 }
151 if ((sc->sc_dsreg&UTDS_BOT) == 0 && (flag&FWRITE) &&
152 dens != sc->sc_dens) {
153 uprintf("tj%d: can't change density in mid-tape\n", tjunit);
7da157da 154 return (EIO);
b02cd1e9
BJ
155 }
156 sc->sc_openf = 1;
157 sc->sc_blkno = (daddr_t)0;
158 sc->sc_nxrec = INF;
159 sc->sc_lastiow = 0;
160 sc->sc_dens = dens;
c36079e2
SL
161 /*
162 * For 6250 bpi take exclusive use of the UNIBUS.
163 */
164 ui->ui_driver->ud_xclu = (dens&(T_1600BPI|T_6250BPI)) == T_6250BPI;
2311123d 165 s = spl6();
407582e3
BJ
166 if (sc->sc_tact == 0) {
167 sc->sc_timo = INF;
168 sc->sc_tact = 1;
169 timeout(uttimer, (caddr_t)dev, 5*hz);
170 }
2311123d 171 splx(s);
7da157da 172 return (0);
b02cd1e9
BJ
173}
174
175utclose(dev, flag)
176 register dev_t dev;
177 register flag;
178{
179 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
180
181 if (flag == FWRITE || ((flag&FWRITE) && sc->sc_lastiow)) {
182 utcommand(dev, UT_WEOF, 1);
183 utcommand(dev, UT_WEOF, 1);
184 utcommand(dev, UT_SREV, 1);
185 }
186 if ((minor(dev)&T_NOREWIND) == 0)
187 utcommand(dev, UT_REW, 0);
188 sc->sc_openf = 0;
189}
190
191utcommand(dev, com, count)
192 dev_t dev;
193 int com, count;
194{
195 register struct buf *bp;
2311123d 196 register int s;
b02cd1e9
BJ
197
198 bp = &cutbuf[UTUNIT(dev)];
2311123d 199 s = spl5();
b02cd1e9
BJ
200 while (bp->b_flags&B_BUSY) {
201 if(bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
202 break;
203 bp->b_flags |= B_WANTED;
204 sleep((caddr_t)bp, PRIBIO);
205 }
206 bp->b_flags = B_BUSY|B_READ;
2311123d 207 splx(s);
b02cd1e9
BJ
208 bp->b_dev = dev;
209 bp->b_command = com;
210 bp->b_repcnt = count;
211 bp->b_blkno = 0;
212 utstrategy(bp);
213 if (count == 0)
214 return;
215 iowait(bp);
216 if (bp->b_flags&B_WANTED)
217 wakeup((caddr_t)bp);
218 bp->b_flags &= B_ERROR;
219}
220
221/*
222 * Queue a tape operation.
223 */
224utstrategy(bp)
225 register struct buf *bp;
226{
227 int tjunit = TJUNIT(bp->b_dev);
228 register struct uba_ctlr *um;
229 register struct buf *dp;
230
231 /*
232 * Put transfer at end of unit queue
233 */
234 dp = &tjutab[tjunit];
235 bp->av_forw = NULL;
236 (void) spl5();
237 if (dp->b_actf == NULL) {
238 dp->b_actf = bp;
239 /*
240 * Transport not active, so...
241 * put at end of controller queue
242 */
243 dp->b_forw = NULL;
244 um = tjdinfo[tjunit]->ui_mi;
245 if (um->um_tab.b_actf == NULL)
246 um->um_tab.b_actf = dp;
247 else
248 um->um_tab.b_actl->b_forw = dp;
249 um->um_tab.b_actl = dp;
250 } else
251 dp->b_actl->av_forw = bp;
252 dp->b_actl = bp;
253 /*
254 * If the controller is not busy, set it going.
255 */
c36079e2 256 if (um->um_tab.b_state == 0)
b02cd1e9
BJ
257 utstart(um);
258 (void) spl0();
259}
260
261utstart(um)
262 register struct uba_ctlr *um;
263{
c36079e2 264 register struct utdevice *addr;
b02cd1e9
BJ
265 register struct buf *bp, *dp;
266 register struct tj_softc *sc;
267 struct uba_device *ui;
268 int tjunit;
269 daddr_t blkno;
270
271loop:
272 /*
273 * Scan controller queue looking for units with
274 * transaction queues to dispatch
275 */
276 if ((dp = um->um_tab.b_actf) == NULL)
277 return;
278 if ((bp = dp->b_actf) == NULL) {
279 um->um_tab.b_actf = dp->b_forw;
280 goto loop;
281 }
c36079e2 282 addr = (struct utdevice *)um->um_addr;
b02cd1e9
BJ
283 tjunit = TJUNIT(bp->b_dev);
284 ui = tjdinfo[tjunit];
285 sc = &tj_softc[tjunit];
286 /* note slave select, density, and format were merged on open */
c36079e2
SL
287 addr->uttc = sc->sc_dens;
288 sc->sc_dsreg = addr->utds;
289 sc->sc_erreg = addr->uter;
290 /* watch this, sports fans */
291 sc->sc_resid = bp->b_flags&B_READ ?
292 bp->b_bcount - ((-addr->utfc)&0xffff) : -addr->utwc<<1;
b02cd1e9
BJ
293 /*
294 * Default is that last command was NOT a write command;
295 * if we do a write command we will notice this in utintr().
296 */
297 sc->sc_lastiow = 0;
c36079e2 298 if (sc->sc_openf < 0 || (addr->utds&UTDS_MOL) == 0) {
b02cd1e9
BJ
299 /*
300 * Have had a hard error on a non-raw tape
301 * or the tape unit is now unavailable
302 * (e.g. taken off line).
303 */
304 bp->b_flags |= B_ERROR;
305 goto next;
306 }
307 if (bp == &cutbuf[UTUNIT(bp->b_dev)]) {
308 /*
309 * Execute a control operation with the specified
310 * count.
311 */
312 if (bp->b_command == UT_SENSE)
313 goto next;
314 /*
315 * Set next state; handle timeouts
316 */
407582e3 317 if (bp->b_command == UT_REW) {
c36079e2 318 um->um_tab.b_state = SREW;
407582e3
BJ
319 sc->sc_timo = 5*60;
320 } else {
c36079e2 321 um->um_tab.b_state = SCOM;
407582e3
BJ
322 sc->sc_timo = imin(imax(10*(int)-bp->b_repcnt,60),5*60);
323 }
b02cd1e9
BJ
324 /* NOTE: this depends on the ut command values */
325 if (bp->b_command >= UT_SFORW && bp->b_command <= UT_SREVF)
c36079e2 326 addr->utfc = -bp->b_repcnt;
b02cd1e9
BJ
327 goto dobpcmd;
328 }
329 /*
330 * The following checks boundary conditions for operations
331 * on non-raw tapes. On raw tapes the initialization of
332 * sc->sc_nxrec by utphys causes them to be skipped normally
333 * (except in the case of retries).
334 */
fb739082 335 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
b02cd1e9
BJ
336 /* can't read past end of file */
337 bp->b_flags |= B_ERROR;
338 bp->b_error = ENXIO;
339 goto next;
340 }
fb739082 341 if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec && (bp->b_flags&B_READ)) {
b02cd1e9
BJ
342 /* read at eof returns 0 count */
343 bp->b_resid = bp->b_bcount;
344 clrbuf(bp);
345 goto next;
346 }
347 if ((bp->b_flags&B_READ) == 0)
fb739082 348 sc->sc_nxrec = bdbtofsb(bp->b_blkno)+1;
b02cd1e9
BJ
349 /*
350 * If the tape is correctly positioned, set up all the
351 * registers but the csr, and give control over to the
352 * UNIBUS adaptor routines, to wait for resources to
353 * start I/O.
354 */
fb739082 355 if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) {
c36079e2
SL
356 addr->utwc = -(((bp->b_bcount)+1)>>1);
357 addr->utfc = -bp->b_bcount;
b02cd1e9
BJ
358 if ((bp->b_flags&B_READ) == 0) {
359 /*
360 * On write error retries erase the
c36079e2 361 * inter-record gap before rewriting.
b02cd1e9 362 */
c36079e2 363 if (um->um_tab.b_errcnt) {
c36079e2 364 if (um->um_tab.b_state != SERASED) {
64614526 365 um->um_tab.b_state = SERASE;
407582e3 366 sc->sc_timo = 60;
c36079e2
SL
367 addr->utcs1 = UT_ERASE|UT_IE|UT_GO;
368 return;
369 }
c36079e2
SL
370 }
371 um->um_cmd = UT_WCOM;
b02cd1e9
BJ
372 } else
373 um->um_cmd = UT_RCOM;
407582e3 374 sc->sc_timo = 60;
c36079e2 375 um->um_tab.b_state = SIO;
b02cd1e9
BJ
376 (void) ubago(ui);
377 return;
378 }
379 /*
380 * Tape positioned incorrectly; seek forwards or
381 * backwards to the correct spot. This happens for
382 * raw tapes only on error retries.
383 */
c36079e2 384 um->um_tab.b_state = SSEEK;
fb739082
SL
385 if (blkno < bdbtofsb(bp->b_blkno)) {
386 addr->utfc = blkno - bdbtofsb(bp->b_blkno);
b02cd1e9
BJ
387 bp->b_command = UT_SFORW;
388 } else {
fb739082 389 addr->utfc = bdbtofsb(bp->b_blkno) - blkno;
b02cd1e9
BJ
390 bp->b_command = UT_SREV;
391 }
407582e3 392 sc->sc_timo = imin(imax(10 * -addr->utfc, 60), 5*60);
b02cd1e9
BJ
393
394dobpcmd:
395 /*
396 * Perform the command setup in bp.
397 */
c36079e2 398 addr->utcs1 = bp->b_command|UT_IE|UT_GO;
b02cd1e9
BJ
399 return;
400next:
401 /*
402 * Advance to the next command in the slave queue,
403 * posting notice and releasing resources as needed.
404 */
b02cd1e9
BJ
405 if (um->um_ubinfo)
406 ubadone(um);
407 um->um_tab.b_errcnt = 0;
408 dp->b_actf = bp->av_forw;
409 iodone(bp);
410 goto loop;
411}
412
413/*
414 * Start operation on controller --
415 * UNIBUS resources have been allocated.
416 */
417utdgo(um)
418 register struct uba_ctlr *um;
419{
420 register struct utdevice *addr = (struct utdevice *)um->um_addr;
421
422 addr->utba = (u_short) um->um_ubinfo;
423 addr->utcs1 = um->um_cmd|((um->um_ubinfo>>8)&0x30)|UT_IE|UT_GO;
b02cd1e9
BJ
424}
425
426/*
427 * Ut interrupt handler
428 */
429/*ARGSUSED*/
430utintr(ut11)
431 int ut11;
432{
433 struct buf *dp;
434 register struct buf *bp;
435 register struct uba_ctlr *um = utminfo[ut11];
436 register struct utdevice *addr;
437 register struct tj_softc *sc;
c36079e2 438 u_short tjunit, cs2, cs1;
b02cd1e9
BJ
439 register state;
440
441 if ((dp = um->um_tab.b_actf) == NULL)
442 return;
443 bp = dp->b_actf;
444 tjunit = TJUNIT(bp->b_dev);
445 addr = (struct utdevice *)tjdinfo[tjunit]->ui_addr;
446 sc = &tj_softc[tjunit];
447 /*
448 * Record status...
449 */
da9ebd7c 450 sc->sc_timo = INF;
b02cd1e9
BJ
451 sc->sc_dsreg = addr->utds;
452 sc->sc_erreg = addr->uter;
c36079e2
SL
453 sc->sc_resid = bp->b_flags&B_READ ?
454 bp->b_bcount - (-addr->utfc)&0xffff : -addr->utwc<<1;
c36079e2 455 if ((bp->b_flags&B_READ) == 0)
b02cd1e9 456 sc->sc_lastiow = 1;
c36079e2
SL
457 state = um->um_tab.b_state;
458 um->um_tab.b_state = 0;
b02cd1e9
BJ
459 /*
460 * Check for errors...
461 */
462 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE)) {
64614526
BJ
463 /*
464 * To clear the ERR bit, we must issue a drive clear
465 * command, and to clear the TRE bit we must set the
466 * controller clear bit.
467 */
468 cs2 = addr->utcs2;
469 if ((cs1 = addr->utcs1)&UT_TRE)
470 addr->utcs2 |= UTCS2_CLR;
471 /* is this dangerous ?? */
472 while ((addr->utcs1&UT_RDY) == 0)
473 ;
474 addr->utcs1 = UT_CLEAR|UT_GO;
b02cd1e9 475 /*
c36079e2 476 * If we hit a tape mark or EOT update our position.
b02cd1e9 477 */
64614526 478 if (sc->sc_dsreg&(UTDS_TM|UTDS_EOT)) {
b02cd1e9 479 /*
64614526 480 * Set blkno and nxrec
b02cd1e9
BJ
481 */
482 if (bp == &cutbuf[UTUNIT(bp->b_dev)]) {
fb739082 483 if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
b02cd1e9 484 sc->sc_nxrec =
fb739082 485 bdbtofsb(bp->b_blkno) - addr->utfc;
b02cd1e9
BJ
486 sc->sc_blkno = sc->sc_nxrec;
487 } else {
b02cd1e9 488 sc->sc_blkno =
fb739082 489 bdbtofsb(bp->b_blkno) + addr->utfc;
b02cd1e9
BJ
490 sc->sc_nxrec = sc->sc_blkno-1;
491 }
c36079e2 492 } else
fb739082 493 sc->sc_nxrec = bdbtofsb(bp->b_blkno);
b02cd1e9 494 state = SCOM; /* force completion */
b02cd1e9 495 /*
c36079e2
SL
496 * Stuff so we can unstuff later
497 * to get the residual.
b02cd1e9 498 */
c36079e2 499 addr->utwc = (-bp->b_bcount)>>1;
b02cd1e9 500 addr->utfc = -bp->b_bcount;
c36079e2
SL
501 if (sc->sc_dsreg&UTDS_EOT)
502 goto harderror;
b02cd1e9
BJ
503 goto opdone;
504 }
b02cd1e9
BJ
505 /*
506 * If we were reading from a raw tape and the only error
507 * was that the record was too long, then we don't consider
508 * this an error.
509 */
510 if (bp == &rutbuf[UTUNIT(bp->b_dev)] && (bp->b_flags&B_READ) &&
511 (sc->sc_erreg&UTER_FCE))
512 goto ignoreerr;
c36079e2
SL
513 /*
514 * Fix up errors which occur due to backspacing "over" the
515 * front of the tape.
516 */
517 if ((sc->sc_dsreg&UTDS_BOT) &&
518 (bp->b_command == UT_SREV || bp->b_command == UT_SREV) &&
519 ((sc->sc_erreg &= ~(UTER_NEF|UTER_FCE)) == 0))
520 goto opdone;
b02cd1e9
BJ
521 /*
522 * Retry soft errors up to 8 times
523 */
524 if ((sc->sc_erreg&UTER_HARD) == 0 && state == SIO) {
525 if (++um->um_tab.b_errcnt < 7) {
526 sc->sc_blkno++;
527 ubadone(um);
528 goto opcont;
529 }
530 } else
c36079e2 531harderror:
b02cd1e9
BJ
532 /*
533 * Hard or non-I/O errors on non-raw tape
c36079e2
SL
534 * cause it to close; also, reading off the
535 * end of the tape.
b02cd1e9 536 */
c36079e2
SL
537 if (sc->sc_openf > 0 &&
538 bp != &rutbuf[UTUNIT(bp->b_dev)] ||
539 sc->sc_dsreg&UTDS_EOT)
b02cd1e9
BJ
540 sc->sc_openf = -1;
541 /*
542 * Couldn't recover error.
543 */
c36079e2
SL
544 printf("ut%d: hard error bn%d cs1=%b er=%b cs2=%b ds=%b\n",
545 tjunit, bp->b_blkno, cs1, UT_BITS, sc->sc_erreg,
546 UTER_BITS, cs2, UTCS2_BITS, sc->sc_dsreg, UTDS_BITS);
b02cd1e9
BJ
547 bp->b_flags |= B_ERROR;
548 goto opdone;
549 }
550ignoreerr:
551 /*
552 * Advance tape control FSM.
553 */
554 switch (state) {
555
556 case SIO: /* read/write increments tape block # */
557 sc->sc_blkno++;
c36079e2 558 break;
b02cd1e9
BJ
559
560 case SCOM: /* forw/rev space updates current position */
561 if (bp == &cutbuf[UTUNIT(bp->b_dev)])
562 switch (bp->b_command) {
563
564 case UT_SFORW:
565 sc->sc_blkno -= bp->b_repcnt;
566 break;
567
568 case UT_SREV:
569 sc->sc_blkno += bp->b_repcnt;
570 break;
571 }
c36079e2 572 break;
b02cd1e9
BJ
573
574 case SSEEK:
fb739082 575 sc->sc_blkno = bdbtofsb(bp->b_blkno);
b02cd1e9
BJ
576 goto opcont;
577
c36079e2
SL
578 case SERASE:
579 /*
580 * Completed erase of the inter-record gap due to a
581 * write error; now retry the write operation.
582 */
583 um->um_tab.b_state = SERASED;
584 goto opcont;
585
586 case SREW: /* clear attention bit */
587 addr->utcs1 = UT_CLEAR|UT_GO;
588 break;
589
b02cd1e9 590 default:
c36079e2 591 printf("bad state %d\n", state);
b02cd1e9
BJ
592 panic("utintr");
593 }
594
595opdone:
596 /*
597 * Reset error count and remove
598 * from device queue
599 */
600 um->um_tab.b_errcnt = 0;
c36079e2
SL
601 dp->b_actf = bp->av_forw;
602 bp->b_resid = bp->b_command&B_READ ?
603 bp->b_bcount - ((-addr->utfc)&0xffff) : -addr->utwc<<1;
b02cd1e9
BJ
604 ubadone(um);
605 iodone(bp);
606 /*
607 * Circulate slave to end of controller queue
608 * to give other slaves a chance
609 */
610 um->um_tab.b_actf = dp->b_forw;
611 if (dp->b_actf) {
612 dp->b_forw = NULL;
613 if (um->um_tab.b_actf == NULL)
614 um->um_tab.b_actf = dp;
615 else
616 um->um_tab.b_actl->b_forw = dp;
617 um->um_tab.b_actl = dp;
618 }
619 if (um->um_tab.b_actf == 0)
620 return;
621opcont:
622 utstart(um);
407582e3
BJ
623}
624
625/*
626 * Watchdog timer routine.
627 */
628uttimer(dev)
629 int dev;
630{
631 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
afa0df56 632 register short x;
407582e3
BJ
633
634 if (sc->sc_timo != INF && (sc->sc_timo -= 5) < 0) {
d6357dcf 635 printf("tj%d: lost interrupt\n", TJUNIT(dev));
407582e3 636 sc->sc_timo = INF;
afa0df56 637 x = spl5();
407582e3 638 utintr(UTUNIT(dev));
afa0df56 639 (void) splx(x);
407582e3
BJ
640 }
641 timeout(uttimer, (caddr_t)dev, 5*hz);
b02cd1e9
BJ
642}
643
644/*
645 * Raw interface for a read
646 */
740e4029 647utread(dev, uio)
b02cd1e9 648 dev_t dev;
740e4029 649 struct uio *uio;
b02cd1e9 650{
0cd5eac7 651 int errno;
740e4029 652
0cd5eac7
BJ
653 errno = utphys(dev, uio);
654 if (errno)
655 return (errno);
656 return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_READ, minphys, uio));
b02cd1e9
BJ
657}
658
659/*
660 * Raw interface for a write
661 */
002227dd 662utwrite(dev, uio)
740e4029 663 dev_t dev;
002227dd 664 struct uio *uio;
b02cd1e9 665{
0cd5eac7
BJ
666 int errno;
667
668 errno = utphys(dev, uio);
669 if (errno)
670 return (errno);
671 return (physio(utstrategy, &rutbuf[UTUNIT(dev)], dev, B_WRITE, minphys, uio));
b02cd1e9
BJ
672}
673
674/*
675 * Check for valid device number dev and update our notion
676 * of where we are on the tape
677 */
740e4029 678utphys(dev, uio)
b02cd1e9 679 dev_t dev;
740e4029 680 struct uio *uio;
b02cd1e9
BJ
681{
682 register int tjunit = TJUNIT(dev);
683 register struct tj_softc *sc;
684 register struct uba_device *ui;
b02cd1e9 685
002227dd
BJ
686 if (tjunit >= NTJ || (ui=tjdinfo[tjunit]) == 0 || ui->ui_alive == 0)
687 return (ENXIO);
b02cd1e9 688 sc = &tj_softc[tjunit];
002227dd 689 sc->sc_blkno = bdbtofsb(uio->uio_offset>>9);
c36079e2 690 sc->sc_nxrec = sc->sc_blkno+1;
002227dd 691 return (0);
b02cd1e9
BJ
692}
693
694/*ARGSUSED*/
942f05a9 695utioctl(dev, cmd, data, flag)
b02cd1e9 696 dev_t dev;
942f05a9 697 caddr_t data;
b02cd1e9
BJ
698{
699 register struct tj_softc *sc = &tj_softc[TJUNIT(dev)];
700 register struct buf *bp = &cutbuf[UTUNIT(dev)];
701 register callcount;
702 int fcount;
942f05a9
SL
703 struct mtop *mtop;
704 struct mtget *mtget;
b02cd1e9
BJ
705 /* we depend of the values and order of the MT codes here */
706 static utops[] =
707 {UT_WEOF,UT_SFORWF,UT_SREVF,UT_SFORW,UT_SREV,UT_REW,UT_REWOFFL,UT_SENSE};
708
709 switch (cmd) {
710
711 case MTIOCTOP:
942f05a9
SL
712 mtop = (struct mtop *)data;
713 switch(mtop->mt_op) {
b02cd1e9
BJ
714
715 case MTWEOF:
942f05a9 716 callcount = mtop->mt_count;
b02cd1e9
BJ
717 fcount = 1;
718 break;
719
720 case MTFSF: case MTBSF:
721 case MTFSR: case MTBSR:
722 callcount = 1;
942f05a9 723 fcount = mtop->mt_count;
b02cd1e9
BJ
724 break;
725
726 case MTREW: case MTOFFL: case MTNOP:
727 callcount = 1;
728 fcount = 1;
729 break;
730
731 default:
7da157da 732 return (ENXIO);
b02cd1e9 733 }
7da157da
BJ
734 if (callcount <= 0 || fcount <= 0)
735 return (EINVAL);
b02cd1e9 736 while (--callcount >= 0) {
942f05a9 737 utcommand(dev, utops[mtop->mt_op], fcount);
c36079e2 738 /* note this depends on the mtop values */
942f05a9 739 if ((mtop->mt_op >= MTFSF || mtop->mt_op <= MTBSR) &&
b02cd1e9 740 bp->b_resid) {
7da157da 741 return (EIO);
b02cd1e9
BJ
742 if ((bp->b_flags&B_ERROR) || (sc->sc_dsreg&UTDS_BOT))
743 break;
744 }
a1edc12b 745 return (geterror(bp));
b02cd1e9
BJ
746
747 case MTIOCGET:
942f05a9
SL
748 mtget = (struct mtget *)data;
749 mtget->mt_dsreg = sc->sc_dsreg;
750 mtget->mt_erreg = sc->sc_erreg;
751 mtget->mt_resid = sc->sc_resid;
752 mtget->mt_type = MT_ISUT;
7da157da 753 break;
b02cd1e9
BJ
754
755 default:
7da157da 756 return (ENXIO);
b02cd1e9 757 }
7da157da 758 return (0);
b02cd1e9
BJ
759}
760
761utreset(uban)
762 int uban;
763{
764 register struct uba_ctlr *um;
765 register ut11, tjunit;
766 register struct uba_device *ui;
767 register struct buf *dp;
768
769 for (ut11 = 0; ut11 < NUT; ut11++) {
770 if ((um = utminfo[ut11]) == 0 || um->um_alive == 0 ||
771 um->um_ubanum != uban)
772 continue;
773 printf(" ut%d", ut11);
c36079e2 774 um->um_tab.b_state = 0;
b02cd1e9
BJ
775 um->um_tab.b_actf = um->um_tab.b_actl = 0;
776 if (um->um_ubinfo) {
777 printf("<%d>", (um->um_ubinfo>>28)&0xf);
778 ubadone(um);
779 }
780 ((struct utdevice *)(um->um_addr))->utcs1 = UT_CLEAR|UT_GO;
c36079e2 781 ((struct utdevice *)(um->um_addr))->utcs2 |= UTCS2_CLR;
b02cd1e9
BJ
782 for (tjunit = 0; tjunit < NTJ; tjunit++) {
783 if ((ui = tjdinfo[tjunit]) == 0 || ui->ui_mi != um ||
784 ui->ui_alive == 0)
785 continue;
786 dp = &tjutab[tjunit];
c36079e2 787 dp->b_state = 0;
b02cd1e9
BJ
788 dp->b_forw = 0;
789 if (um->um_tab.b_actf == NULL)
790 um->um_tab.b_actf = dp;
791 else
792 um->um_tab.b_actl->b_forw = dp;
793 um->um_tab.b_actl = dp;
794 if (tj_softc[tjunit].sc_openf > 0)
795 tj_softc[tjunit].sc_openf = -1;
796 }
797 utstart(um);
798 }
799}
800
801/*
802 * Do a stand-alone core dump to tape --
803 * from here down, routines are used only in dump context
804 */
805#define DBSIZE 20
806
807utdump()
808{
809 register struct uba_device *ui;
810 register struct uba_regs *up;
c36079e2 811 register struct utdevice *addr;
b02cd1e9
BJ
812 int blk, num = maxfree;
813 int start = 0;
814
815#define phys(a,b) ((b)((int)(a)&0x7fffffff))
816 if (tjdinfo[0] == 0)
817 return (ENXIO);
818 ui = phys(tjdinfo[0], struct uba_device *);
819 up = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
89b8a44c 820 ubainit(up);
b02cd1e9 821 DELAY(1000000);
c36079e2 822 addr = (struct utdevice *)ui->ui_physaddr;
89b8a44c 823 utwait(addr);
c36079e2
SL
824 /*
825 * Be sure to set the appropriate density here. We use
826 * 6250, but maybe it should be done at 1600 to insure the
827 * tape can be read by most any other tape drive available.
828 */
829 addr->uttc = UT_GCR|PDP11FMT; /* implicit slave 0 or-ed in */
830 addr->utcs1 = UT_CLEAR|UT_GO;
b02cd1e9
BJ
831 while (num > 0) {
832 blk = num > DBSIZE ? DBSIZE : num;
c36079e2
SL
833 utdwrite(start, blk, addr, up);
834 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE))
835 return(EIO);
b02cd1e9
BJ
836 start += blk;
837 num -= blk;
838 }
c36079e2
SL
839 uteof(addr);
840 uteof(addr);
841 utwait(addr);
842 if ((addr->utds&UTDS_ERR) || (addr->utcs1&UT_TRE))
b02cd1e9 843 return(EIO);
c36079e2 844 addr->utcs1 = UT_REW|UT_GO;
b02cd1e9
BJ
845 return (0);
846}
847
c36079e2 848utdwrite(dbuf, num, addr, up)
b02cd1e9 849 register dbuf, num;
c36079e2 850 register struct utdevice *addr;
b02cd1e9
BJ
851 struct uba_regs *up;
852{
853 register struct pte *io;
854 register int npf;
855
c36079e2 856 utwait(addr);
b02cd1e9
BJ
857 io = up->uba_map;
858 npf = num + 1;
859 while (--npf != 0)
860 *(int *)io++ = (dbuf++ | (1<<UBAMR_DPSHIFT) | UBAMR_MRV);
861 *(int *)io = 0;
c36079e2
SL
862 addr->utwc = -((num*NBPG)>>1);
863 addr->utfc = -(num*NBPG);
864 addr->utba = 0;
865 addr->utcs1 = UT_WCOM|UT_GO;
b02cd1e9
BJ
866}
867
c36079e2
SL
868utwait(addr)
869 struct utdevice *addr;
b02cd1e9
BJ
870{
871 register s;
872
873 do
c36079e2 874 s = addr->utds;
b02cd1e9
BJ
875 while ((s&UTDS_DRY) == 0);
876}
877
c36079e2
SL
878uteof(addr)
879 struct utdevice *addr;
b02cd1e9
BJ
880{
881
c36079e2
SL
882 utwait(addr);
883 addr->utcs1 = UT_WEOF|UT_GO;
b02cd1e9
BJ
884}
885#endif