|
|
1.1 root 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:
34: struct buf rutbuf[NUT]; /* bufs for raw i/o */
35: struct buf cutbuf[NUT]; /* bufs for control operations */
36: struct buf tjutab[NTJ]; /* bufs for slave queue headers */
37:
38: struct uba_ctlr *utminfo[NUT];
39: struct uba_device *tjdinfo[NTJ];
40: int utprobe(), utslave(), utattach(), utdgo(), utintr(), uttimer();
41: u_short utstd[] = { 0772440, 0 };
42: struct 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
52: short utdens[] = { UT_NRZI, UT_PE, UT_GCR, UT_NRZI };
53:
54: /* slave to controller mapping table */
55: short tjtout[NTJ];
56: #define UTUNIT(dev) (tjtout[TJUNIT(dev)])
57:
58: #define INF (daddr_t)1000000L /* a block number that wont exist */
59:
60: struct 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*/
84: utprobe(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*/
102: utslave(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:
114: utattach(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: */
123: utopen(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);
140: get:
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:
179: utclose(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:
195: utcommand(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: */
228: utstrategy(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:
265: utstart(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:
275: loop:
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:
405: dobpcmd:
406: /*
407: * Perform the command setup in bp.
408: */
409: addr->utcs1 = bp->b_command|UT_IE|UT_GO;
410: return;
411: next:
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: */
428: utdgo(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*/
441: utintr(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:
540: ignoreerr:
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:
615: opdone:
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;
650: opcont:
651: utstart(um);
652: }
653:
654: /*
655: * Watchdog timer routine.
656: */
657: uttimer(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: */
676: utread(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: */
691: utwrite(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: */
707: utphys(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*/
724: utioctl(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:
782: utreset(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:
828: utdump()
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:
869: utdwrite(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:
889: utwait(addr)
890: struct utdevice *addr;
891: {
892: register s;
893:
894: do
895: s = addr->utds;
896: while ((s&UTDS_DRY) == 0);
897: }
898:
899: uteof(addr)
900: struct utdevice *addr;
901: {
902:
903: utwait(addr);
904: addr->utcs1 = UT_WEOF|UT_GO;
905: }
906: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.