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