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