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 * @(#)ts.c 7.15 (Berkeley) 02/27/92
7 */
8
9 #include "ts.h"
10 #if NTS > 0
11 /*
12 * TS11 tape driver
13 *
14 * NB: This driver takes advantage of the fact that there is only one
15 * drive per controller.
16 *
17 * TODO:
18 * test dump code
19 */
20 #include "sys/param.h"
21 #include "sys/systm.h"
22 #include "sys/buf.h"
23 #include "sys/conf.h"
24 #include "sys/errno.h"
25 #include "sys/file.h"
26 #include "sys/map.h"
27 #include "sys/vm.h"
28 #include "sys/ioctl.h"
29 #include "sys/mtio.h"
30 #include "sys/cmap.h"
31 #include "sys/uio.h"
32 #include "sys/syslog.h"
33 #include "sys/tprintf.h"
34
35 #include "../include/pte.h"
36 #include "../include/cpu.h"
37 #include "ubareg.h"
38 #include "ubavar.h"
39 #include "tsreg.h"
40
41 /*
42 * There is a ctsbuf per tape controller.
43 * It is used as the token to pass to the internal routines
44 * to execute tape ioctls.
45 * In particular, when the tape is rewinding on close we release
46 * the user process but any further attempts to use the tape drive
47 * before the rewind completes will hang waiting for ctsbuf.
48 */
49 struct buf ctsbuf[NTS];
50
51 /*
52 * Driver unibus interface routines and variables.
53 */
54 int tsprobe(), tsslave(), tsattach(), tsdgo(), tsintr();
55 struct uba_ctlr *tsminfo[NTS];
56 struct uba_device *tsdinfo[NTS];
57 struct buf tsutab[NTS];
58 u_short tsstd[] = { 0772520, 0 };
59 /* need all these even though controller == drive */
60 struct uba_driver zsdriver =
61 { tsprobe, tsslave, tsattach, tsdgo, tsstd, "ts", tsdinfo, "zs", tsminfo };
62
63 /* bits in minor device */
64 #define TSUNIT(dev) (minor(dev)&03)
65 #define T_NOREWIND 04
66 #define T_1600BPI 010
67
68 #define INF (daddr_t)1000000L
69
70 /*
71 * Software state per tape transport.
72 * Also contains hardware state in message packets.
73 *
74 * 1. A tape drive is a unique-open device; we refuse opens when it is already.
75 * 2. We keep track of the current position on a block tape and seek
76 * before operations by forward/back spacing if necessary.
77 * 3. We remember if the last operation was a write on a tape, so if a tape
78 * is open read write and the last thing done is a write we can
79 * write a standard end of tape mark (two eofs).
80 * 4. We remember the status registers after the last command, using
81 * then internally and returning them to the SENSE ioctl.
82 */
83 struct ts_tsdata { /* data shared with ts11 controller */
84 struct ts_cmd t_cmd; /* the command packet (must be first) */
85 struct ts_sts t_sts; /* status packet, for returned status */
86 struct ts_char t_char; /* characteristics packet */
87 };
88 struct ts_softc {
89 char sc_openf; /* lock against multiple opens */
90 char sc_lastiow; /* last op was a write */
91 short sc_resid; /* copy of last bc */
92 daddr_t sc_blkno; /* block number, for block device tape */
93 daddr_t sc_nxrec; /* position of end of tape, if known */
94 struct ts_tsdata sc_ts;/* command and status packets */
95 struct ts_tsdata *sc_ubaddr; /* Unibus address of tsdata structure */
96 u_short sc_uba; /* Unibus addr of cmd pkt for tsdb */
97 short sc_density; /* value |'ed into char_mode for TC13 density */
98 tpr_t sc_tpr; /* tprintf handle */
99 int sc_blks; /* number of I/O operations since open */
100 int sc_softerrs; /* number of soft I/O errors since open */
101 } ts_softc[NTS];
102
103 /*
104 * States for um->um_tab.b_active, the per controller state flag.
105 * This is used to sequence control in the driver.
106 */
107 #define SSEEK 1 /* seeking */
108 #define SIO 2 /* doing seq i/o */
109 #define SCOM 3 /* sending control command */
110 #define SREW 4 /* sending a drive rewind */
111
112 /*
113 * Determine if there is a controller for
114 * a ts at address reg. Our goal is to make the
115 * device interrupt.
116 */
117 /*ARGSUSED*/
tsprobe(reg,ctlr,um)118 tsprobe(reg, ctlr, um)
119 caddr_t reg;
120 int ctlr;
121 struct uba_ctlr *um;
122 {
123 register int br, cvec; /* must be r11,r10; value-result */
124 register struct tsdevice *addr = (struct tsdevice *)reg;
125 register struct ts_softc *sc;
126 register int i;
127
128 #ifdef lint
129 br = 0; cvec = br; br = cvec;
130 tsintr(0);
131 #endif
132 addr->tssr = 0; /* initialize subsystem */
133 DELAY(100);
134 if ((addr->tssr & TS_NBA) == 0)
135 return (0);
136
137 /*
138 * Make it interrupt.
139 * TS_SETCHR|TS_IE alone refuses to interrupt for me.
140 */
141 sc = &ts_softc[ctlr];
142 tsmap(sc, numuba);
143 i = (int)&sc->sc_ubaddr->t_char;
144 sc->sc_ts.t_cmd.c_loba = i;
145 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3;
146 sc->sc_ts.t_cmd.c_size = sizeof(struct ts_char);
147 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_SETCHR;
148 sc->sc_ts.t_char.char_addr = (int)&sc->sc_ubaddr->t_sts;
149 sc->sc_ts.t_char.char_size = sizeof(struct ts_sts);
150 sc->sc_ts.t_char.char_mode = 0; /* mode is unimportant */
151 addr->tsdb = sc->sc_uba;
152 DELAY(20000);
153 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | TS_SENSE;
154 sc->sc_ts.t_cmd.c_repcnt = 1;
155 addr->tsdb = sc->sc_uba;
156 DELAY(20000);
157 /*
158 * The controller should have interrupted by now, but some do not,
159 * even if the delays above are extended to many seconds. If the
160 * vector is still unknown, we assume the drive is present at
161 * the usual vector.
162 */
163 if (cvec == 0 || cvec == 0x200) {
164 cvec = (int)reg & 7 ? 0260 : 0224;
165 br = 0x15;
166 }
167 return (sizeof(struct tsdevice));
168 }
169
170 /*
171 * Map in the command, status, and characteristics packet. We
172 * make them contiguous to keep overhead down. This also sets
173 * sc_uba (which then never changes).
174 */
tsmap(sc,uban)175 tsmap(sc, uban)
176 register struct ts_softc *sc;
177 int uban;
178 {
179 register int i;
180
181 i = uballoc(uban, (caddr_t)&sc->sc_ts, sizeof(sc->sc_ts), 0);
182 i = UBAI_ADDR(i);
183 sc->sc_ubaddr = (struct ts_tsdata *)i;
184 /*
185 * Note that i == the Unibus address of the command packet,
186 * and that it is a multiple of 4 (guaranteed by the compiler).
187 */
188 sc->sc_uba = i + ((i >> 16) & 3);
189 }
190
191 /*
192 * TS11 only supports one drive per controller;
193 * check for ui_slave == 0.
194 */
195 /*ARGSUSED*/
196 tsslave(ui, reg)
197 struct uba_device *ui;
198 caddr_t reg;
199 {
200
201 return (ui->ui_slave == 0); /* non-zero slave not allowed */
202 }
203
204 /*
205 * Record attachment of the unit to the controller.
206 */
207 /*ARGSUSED*/
208 tsattach(ui)
209 struct uba_device *ui;
210 {
211
212 /* void */
213 }
214
215 /*
216 * Open the device. Tapes are unique open
217 * devices, so we refuse if it is already open.
218 */
tsopen(dev,flag)219 tsopen(dev, flag)
220 dev_t dev;
221 int flag;
222 {
223 register int tsunit = TSUNIT(dev);
224 register struct uba_device *ui;
225 register struct ts_softc *sc;
226
227 if (tsunit >= NTS || (ui = tsdinfo[tsunit]) == 0 || ui->ui_alive == 0)
228 return (ENXIO);
229 if ((sc = &ts_softc[ui->ui_ctlr])->sc_openf)
230 return (EBUSY);
231 sc->sc_openf = 1;
232 sc->sc_density = (minor(dev) & T_1600BPI) ? TS_NRZI : 0;
233 tscommand(dev, TS_SENSE, 1);
234 if (ctsbuf[tsunit].b_flags & B_ERROR)
235 /*
236 * Try it again in case it went off-line
237 */
238 tscommand(dev, TS_SENSE, 1);
239 if (tsinit(ui->ui_ctlr)) {
240 sc->sc_openf = 0;
241 return (ENXIO);
242 }
243 if ((sc->sc_ts.t_sts.s_xs0&TS_ONL) == 0) {
244 sc->sc_openf = 0;
245 uprintf("ts%d: not online\n", tsunit);
246 return (EIO);
247 }
248 if ((flag&FWRITE) && (sc->sc_ts.t_sts.s_xs0&TS_WLK)) {
249 sc->sc_openf = 0;
250 uprintf("ts%d: no write ring\n", tsunit);
251 return (EIO);
252 }
253 sc->sc_blkno = (daddr_t)0;
254 sc->sc_nxrec = INF;
255 sc->sc_lastiow = 0;
256 sc->sc_blks = 0;
257 sc->sc_softerrs = 0;
258 sc->sc_tpr = tprintf_open();
259 return (0);
260 }
261
262 /*
263 * Close tape device.
264 *
265 * If tape was open for writing or last operation was
266 * a write, then write two EOF's and backspace over the last one.
267 * Unless this is a non-rewinding special file, rewind the tape.
268 * Make the tape available to others.
269 */
tsclose(dev,flag)270 tsclose(dev, flag)
271 register dev_t dev;
272 register int flag;
273 {
274 register struct ts_softc *sc = &ts_softc[TSUNIT(dev)];
275
276 if (flag == FWRITE || (flag&FWRITE) && sc->sc_lastiow) {
277 tscommand(dev, TS_WEOF, 1);
278 tscommand(dev, TS_WEOF, 1);
279 tscommand(dev, TS_SREV, 1);
280 }
281 if ((minor(dev)&T_NOREWIND) == 0)
282 /*
283 * 0 count means don't hang waiting for rewind complete
284 * rather ctsbuf stays busy until the operation completes
285 * preventing further opens from completing by
286 * preventing a TS_SENSE from completing.
287 */
288 tscommand(dev, TS_REW, 0);
289 if (sc->sc_blks > 100 && sc->sc_softerrs > sc->sc_blks / 100)
290 log(LOG_INFO, "ts%d: %d soft errors in %d blocks\n",
291 TSUNIT(dev), sc->sc_softerrs, sc->sc_blks);
292 tprintf_close(sc->sc_tpr);
293 sc->sc_openf = 0;
294 return (0);
295 }
296
297 /*
298 * Initialize a TS11. Set device characteristics.
299 */
tsinit(ctlr)300 tsinit(ctlr)
301 register int ctlr;
302 {
303 register struct ts_softc *sc = &ts_softc[ctlr];
304 register struct uba_ctlr *um = tsminfo[ctlr];
305 register struct tsdevice *addr = (struct tsdevice *)um->um_addr;
306 register int i;
307
308 if (addr->tssr & (TS_NBA|TS_OFL) || sc->sc_ts.t_sts.s_xs0 & TS_BOT) {
309 addr->tssr = 0; /* subsystem initialize */
310 tswait(addr);
311 i = (int)&sc->sc_ubaddr->t_char;
312 sc->sc_ts.t_cmd.c_loba = i;
313 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3;
314 sc->sc_ts.t_cmd.c_size = sizeof(struct ts_char);
315 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR;
316 sc->sc_ts.t_char.char_addr = (int)&sc->sc_ubaddr->t_sts;
317 sc->sc_ts.t_char.char_size = sizeof(struct ts_sts);
318 sc->sc_ts.t_char.char_mode = TS_ESS | TS_EAI | TS_ERI |
319 /* TS_ENB | */ sc->sc_density;
320 addr->tsdb = sc->sc_uba;
321 tswait(addr);
322 if (addr->tssr & TS_NBA)
323 return(1);
324 }
325 return(0);
326 }
327
328 /*
329 * Execute a command on the tape drive
330 * a specified number of times.
331 */
tscommand(dev,com,count)332 tscommand(dev, com, count)
333 dev_t dev;
334 int com, count;
335 {
336 register struct buf *bp;
337 register int s;
338 int didsleep = 0;
339
340 bp = &ctsbuf[TSUNIT(dev)];
341 s = spl5();
342 while (bp->b_flags&B_BUSY) {
343 /*
344 * This special check is because B_BUSY never
345 * gets cleared in the non-waiting rewind case.
346 */
347 if (bp->b_repcnt == 0 && (bp->b_flags&B_DONE))
348 break;
349 bp->b_flags |= B_WANTED;
350 sleep((caddr_t)bp, PRIBIO);
351 didsleep = 1;
352 }
353 bp->b_flags = B_BUSY|B_READ;
354 splx(s);
355 if (didsleep)
356 (void) tsinit(tsdinfo[TSUNIT(dev)]->ui_ctlr);
357 bp->b_dev = dev;
358 bp->b_repcnt = count;
359 bp->b_command = com;
360 bp->b_blkno = 0;
361 tsstrategy(bp);
362 /*
363 * In case of rewind from close, don't wait.
364 * This is the only case where count can be 0.
365 */
366 if (count == 0)
367 return;
368 biowait(bp);
369 if (bp->b_flags&B_WANTED)
370 wakeup((caddr_t)bp);
371 bp->b_flags &= B_ERROR;
372 }
373
374 /*
375 * Queue a tape operation.
376 */
tsstrategy(bp)377 tsstrategy(bp)
378 register struct buf *bp;
379 {
380 register int tsunit = TSUNIT(bp->b_dev);
381 register struct uba_ctlr *um;
382 register struct buf *dp;
383 int s;
384
385 /*
386 * Put transfer at end of controller queue
387 */
388 bp->av_forw = NULL;
389 um = tsdinfo[tsunit]->ui_mi;
390 dp = &tsutab[tsunit];
391 s = spl5();
392 if (dp->b_actf == NULL)
393 dp->b_actf = bp;
394 else
395 dp->b_actl->av_forw = bp;
396 dp->b_actl = bp;
397 um->um_tab.b_actf = um->um_tab.b_actl = dp;
398 /*
399 * If the controller is not busy, get
400 * it going.
401 */
402 if (um->um_tab.b_active == 0)
403 tsstart(um);
404 splx(s);
405 }
406
407 /*
408 * Start activity on a ts controller.
409 */
tsstart(um)410 tsstart(um)
411 register struct uba_ctlr *um;
412 {
413 register struct buf *bp;
414 register struct tsdevice *addr = (struct tsdevice *)um->um_addr;
415 register struct ts_softc *sc;
416 register struct uba_device *ui;
417 register int tsunit;
418 int cmd;
419 daddr_t blkno;
420
421 /*
422 * Start the controller if there is something for it to do.
423 */
424 loop:
425 if ((bp = um->um_tab.b_actf->b_actf) == NULL) {
426 um->um_tab.b_active = 0;
427 return;
428 }
429 tsunit = TSUNIT(bp->b_dev);
430 ui = tsdinfo[tsunit];
431 sc = &ts_softc[tsunit];
432 /*
433 * Default is that last command was NOT a write command;
434 * if we finish a write command we will notice this in tsintr().
435 */
436 sc->sc_lastiow = 0;
437 if (sc->sc_openf < 0 || (addr->tssr&TS_OFL)) {
438 /*
439 * Have had a hard error on a non-raw tape
440 * or the tape unit is now unavailable
441 * (e.g. taken off line).
442 */
443 bp->b_flags |= B_ERROR;
444 goto next;
445 }
446 if (bp == &ctsbuf[tsunit]) {
447 /*
448 * Execute control operation with the specified count.
449 */
450 um->um_tab.b_active =
451 bp->b_command == TS_REW ? SREW : SCOM;
452 sc->sc_ts.t_cmd.c_repcnt = bp->b_repcnt;
453 goto dobpcmd;
454 }
455 /*
456 * For raw I/O, save the current block
457 * number in case we have to retry.
458 */
459 if (bp->b_flags & B_RAW) {
460 if (um->um_tab.b_errcnt == 0)
461 sc->sc_blkno = bdbtofsb(bp->b_blkno);
462 } else {
463 /*
464 * Handle boundary cases for operation
465 * on non-raw tapes.
466 */
467 if (bdbtofsb(bp->b_blkno) > sc->sc_nxrec) {
468 /*
469 * Can't read past known end-of-file.
470 */
471 bp->b_flags |= B_ERROR;
472 bp->b_error = ENXIO;
473 goto next;
474 }
475 if (bdbtofsb(bp->b_blkno) == sc->sc_nxrec &&
476 bp->b_flags&B_READ) {
477 /*
478 * Reading at end of file returns 0 bytes.
479 */
480 bp->b_resid = bp->b_bcount;
481 clrbuf(bp);
482 goto next;
483 }
484 if ((bp->b_flags&B_READ) == 0)
485 /*
486 * Writing sets EOF
487 */
488 sc->sc_nxrec = bdbtofsb(bp->b_blkno) + 1;
489 }
490
491 /*
492 * If the data transfer command is in the correct place,
493 * set up all the registers except the csr, and give
494 * control over to the UNIBUS adapter routines, to
495 * wait for resources to start the i/o.
496 */
497 if ((blkno = sc->sc_blkno) == bdbtofsb(bp->b_blkno)) {
498 sc->sc_ts.t_cmd.c_size = bp->b_bcount;
499 if ((bp->b_flags&B_READ) == 0)
500 cmd = TS_WCOM;
501 else
502 cmd = TS_RCOM;
503 if (um->um_tab.b_errcnt)
504 cmd |= TS_RETRY;
505 um->um_tab.b_active = SIO;
506 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | cmd;
507 (void) ubago(ui);
508 return;
509 }
510 /*
511 * Tape positioned incorrectly;
512 * set to seek forwards or backwards to the correct spot.
513 * This happens for raw tapes only on error retries.
514 */
515 um->um_tab.b_active = SSEEK;
516 if (blkno < bdbtofsb(bp->b_blkno)) {
517 bp->b_command = TS_SFORW;
518 sc->sc_ts.t_cmd.c_repcnt = bdbtofsb(bp->b_blkno) - blkno;
519 } else {
520 bp->b_command = TS_SREV;
521 sc->sc_ts.t_cmd.c_repcnt = blkno - bdbtofsb(bp->b_blkno);
522 }
523 dobpcmd:
524 /*
525 * Do the command in bp.
526 */
527 sc->sc_ts.t_cmd.c_cmd = TS_ACK | TS_CVC | TS_IE | bp->b_command;
528 addr->tsdb = sc->sc_uba;
529 return;
530
531 next:
532 /*
533 * Done with this operation due to error or
534 * the fact that it doesn't do anything.
535 * Release UBA resources (if any), dequeue
536 * the transfer and continue processing this slave.
537 */
538 if (um->um_ubinfo)
539 ubadone(um);
540 um->um_tab.b_errcnt = 0;
541 um->um_tab.b_actf->b_actf = bp->av_forw;
542 biodone(bp);
543 goto loop;
544 }
545
546 /*
547 * The UNIBUS resources we needed have been
548 * allocated to us; start the device.
549 */
tsdgo(um)550 tsdgo(um)
551 register struct uba_ctlr *um;
552 {
553 register struct ts_softc *sc = &ts_softc[um->um_ctlr];
554 register int i;
555
556 /*
557 * The uba code uses byte-offset mode if using bdp;
558 * mask off the low bit here.
559 */
560 i = UBAI_ADDR(um->um_ubinfo);
561 if (UBAI_BDP(um->um_ubinfo))
562 i &= ~1;
563 sc->sc_ts.t_cmd.c_loba = i;
564 sc->sc_ts.t_cmd.c_hiba = (i >> 16) & 3;
565 ((struct tsdevice *)um->um_addr)->tsdb = sc->sc_uba;
566 }
567
568 /*
569 * Ts interrupt routine.
570 */
571 /*ARGSUSED*/
tsintr(tsunit)572 tsintr(tsunit)
573 register int tsunit;
574 {
575 register struct buf *bp;
576 register struct uba_ctlr *um;
577 register struct tsdevice *addr;
578 register struct ts_softc *sc;
579 register int state;
580
581 #ifdef QBA
582 (void) spl5();
583 #endif
584 um = tsdinfo[tsunit]->ui_mi;
585 if ((bp = um->um_tab.b_actf->b_actf) == NULL)
586 return;
587 addr = (struct tsdevice *)um->um_addr;
588 /*
589 * If last command was a rewind, and tape is still
590 * rewinding, wait for the rewind complete interrupt.
591 *
592 * SHOULD NEVER GET AN INTERRUPT IN THIS STATE.
593 */
594 if (um->um_tab.b_active == SREW) {
595 um->um_tab.b_active = SCOM;
596 if ((addr->tssr&TS_SSR) == 0)
597 return;
598 }
599 /*
600 * An operation completed... record status
601 */
602 sc = &ts_softc[um->um_ctlr];
603 if ((bp->b_flags & B_READ) == 0)
604 sc->sc_lastiow = 1;
605 state = um->um_tab.b_active;
606 /*
607 * Check for errors.
608 */
609 if (addr->tssr&TS_SC) {
610 switch (addr->tssr & TS_TC) {
611 case TS_UNREC: /* unrecoverable */
612 case TS_FATAL: /* fatal error */
613 case TS_RECNM: /* recoverable, no motion */
614 break;
615 case TS_ATTN: /* attention */
616 if (sc->sc_ts.t_sts.s_xs0 & TS_VCK) {
617 /* volume check - may have changed tapes */
618 bp->b_flags |= B_ERROR;
619 goto ignoreerr;
620 }
621 break;
622
623 case TS_SUCC: /* success termination */
624 printf("ts%d: success\n", tsunit);
625 goto ignoreerr;
626
627 case TS_ALERT: /* tape status alert */
628 /*
629 * If we hit the end of the tape file,
630 * update our position.
631 */
632 if (sc->sc_ts.t_sts.s_xs0 & (TS_TMK|TS_EOT)) {
633 tsseteof(bp); /* set blkno and nxrec */
634 state = SCOM; /* force completion */
635 /*
636 * Stuff bc so it will be unstuffed correctly
637 * later to get resid.
638 */
639 sc->sc_ts.t_sts.s_rbpcr = bp->b_bcount;
640 goto opdone;
641 }
642 /*
643 * If we were reading raw tape and the record was too
644 * long or too short, we don't consider this an error.
645 */
646 if ((bp->b_flags & (B_READ|B_RAW)) == (B_READ|B_RAW) &&
647 sc->sc_ts.t_sts.s_xs0&(TS_RLS|TS_RLL))
648 goto ignoreerr;
649 /* FALLTHROUGH */
650
651 case TS_RECOV: /* recoverable, tape moved */
652 /*
653 * If this was an i/o operation retry up to 8 times.
654 */
655 if (state == SIO) {
656 if (++um->um_tab.b_errcnt < 7) {
657 ubadone(um);
658 goto opcont;
659 } else
660 sc->sc_blkno++;
661 } else {
662 /*
663 * Non-i/o errors on non-raw tape
664 * cause it to close.
665 */
666 if ((bp->b_flags&B_RAW) == 0 &&
667 sc->sc_openf > 0)
668 sc->sc_openf = -1;
669 }
670 break;
671
672 case TS_REJECT: /* function reject */
673 if (state == SIO && sc->sc_ts.t_sts.s_xs0 & TS_WLE)
674 tprintf(sc->sc_tpr, "ts%d: write locked\n",
675 tsunit);
676 if ((sc->sc_ts.t_sts.s_xs0 & TS_ONL) == 0)
677 tprintf(sc->sc_tpr, "ts%d: offline\n",
678 tsunit);
679 break;
680 }
681 /*
682 * Couldn't recover error
683 */
684 tprintf(sc->sc_tpr, "ts%d: hard error bn%d tssr=%b xs0=%b",
685 tsunit, bp->b_blkno, addr->tssr, TSSR_BITS,
686 sc->sc_ts.t_sts.s_xs0, TSXS0_BITS);
687 if (sc->sc_ts.t_sts.s_xs1)
688 tprintf(sc->sc_tpr, " xs1=%b", sc->sc_ts.t_sts.s_xs1,
689 TSXS1_BITS);
690 if (sc->sc_ts.t_sts.s_xs2)
691 tprintf(sc->sc_tpr, " xs2=%b", sc->sc_ts.t_sts.s_xs2,
692 TSXS2_BITS);
693 if (sc->sc_ts.t_sts.s_xs3)
694 tprintf(sc->sc_tpr, " xs3=%b", sc->sc_ts.t_sts.s_xs3,
695 TSXS3_BITS);
696 tprintf(sc->sc_tpr, "\n");
697 bp->b_flags |= B_ERROR;
698 goto opdone;
699 }
700 /*
701 * Advance tape control FSM.
702 */
703 ignoreerr:
704 switch (state) {
705
706 case SIO:
707 /*
708 * Read/write increments tape block number
709 */
710 sc->sc_blkno++;
711 sc->sc_blks++;
712 if (um->um_tab.b_errcnt)
713 sc->sc_softerrs++;
714 goto opdone;
715
716 case SCOM:
717 /*
718 * For forward/backward space record update current position.
719 */
720 if (bp == &ctsbuf[tsunit])
721 switch ((int)bp->b_command) {
722
723 case TS_SFORW:
724 sc->sc_blkno += bp->b_repcnt;
725 break;
726
727 case TS_SREV:
728 sc->sc_blkno -= bp->b_repcnt;
729 break;
730 }
731 goto opdone;
732
733 case SSEEK:
734 sc->sc_blkno = bdbtofsb(bp->b_blkno);
735 goto opcont;
736
737 default:
738 panic("tsintr");
739 }
740 opdone:
741 /*
742 * Reset error count and remove
743 * from device queue.
744 */
745 um->um_tab.b_errcnt = 0;
746 um->um_tab.b_actf->b_actf = bp->av_forw;
747 bp->b_resid = sc->sc_ts.t_sts.s_rbpcr;
748 ubadone(um);
749 biodone(bp);
750 if (um->um_tab.b_actf->b_actf == 0) {
751 um->um_tab.b_active = 0;
752 return;
753 }
754 opcont:
755 tsstart(um);
756 }
757
tsseteof(bp)758 tsseteof(bp)
759 register struct buf *bp;
760 {
761 register int tsunit = TSUNIT(bp->b_dev);
762 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr];
763
764 if (bp == &ctsbuf[tsunit]) {
765 if (sc->sc_blkno > bdbtofsb(bp->b_blkno)) {
766 /* reversing */
767 sc->sc_nxrec = bdbtofsb(bp->b_blkno) -
768 sc->sc_ts.t_sts.s_rbpcr;
769 sc->sc_blkno = sc->sc_nxrec;
770 } else {
771 /* spacing forward */
772 sc->sc_blkno = bdbtofsb(bp->b_blkno) +
773 sc->sc_ts.t_sts.s_rbpcr;
774 sc->sc_nxrec = sc->sc_blkno - 1;
775 }
776 return;
777 }
778 /* eof on read */
779 sc->sc_nxrec = bdbtofsb(bp->b_blkno);
780 }
781
tsreset(uban)782 tsreset(uban)
783 int uban;
784 {
785 register struct uba_ctlr *um;
786 register struct uba_device *ui;
787 register int ts11, i;
788
789 for (ts11 = 0; ts11 < NTS; ts11++) {
790 if ((um = tsminfo[ts11]) == 0 || um->um_alive == 0 ||
791 um->um_ubanum != uban)
792 continue;
793 printf(" ts%d", ts11);
794 um->um_tab.b_active = 0;
795 um->um_tab.b_actf = um->um_tab.b_actl = 0;
796 if (ts_softc[ts11].sc_openf > 0)
797 ts_softc[ts11].sc_openf = -1;
798 if (um->um_ubinfo) {
799 printf("<%d>", UBAI_BDP(um->um_ubinfo));
800 um->um_ubinfo = 0;
801 }
802 /*
803 * tsdinfo should be 1-to-1 with tsminfo, but someone
804 * might have screwed up the config file:
805 */
806 for (i = 0; i < NTS; i++) {
807 if ((ui = tsdinfo[i]) != NULL &&
808 ui->ui_alive && ui->ui_mi == um) {
809 um->um_tab.b_actf = um->um_tab.b_actl =
810 &tsutab[i];
811 break;
812 }
813 }
814 tsmap(&ts_softc[ts11], uban);
815 (void) tsinit(ts11);
816 tsstart(um);
817 }
818 }
819
820 /*ARGSUSED*/
tsioctl(dev,cmd,data,flag)821 tsioctl(dev, cmd, data, flag)
822 caddr_t data;
823 dev_t dev;
824 {
825 int tsunit = TSUNIT(dev);
826 register struct ts_softc *sc = &ts_softc[tsdinfo[tsunit]->ui_ctlr];
827 register struct buf *bp = &ctsbuf[TSUNIT(dev)];
828 register int callcount;
829 int fcount, error = 0;
830 struct mtop *mtop;
831 struct mtget *mtget;
832 /* we depend of the values and order of the MT codes here */
833 static int tsops[] =
834 {TS_WEOF,TS_SFORWF,TS_SREVF,TS_SFORW,TS_SREV,TS_REW,TS_OFFL,TS_SENSE};
835
836 switch (cmd) {
837
838 case MTIOCTOP: /* tape operation */
839 mtop = (struct mtop *)data;
840 switch (mtop->mt_op) {
841
842 case MTWEOF:
843 callcount = mtop->mt_count;
844 fcount = 1;
845 break;
846
847 case MTFSF: case MTBSF:
848 case MTFSR: case MTBSR:
849 callcount = 1;
850 fcount = mtop->mt_count;
851 break;
852
853 case MTREW: case MTOFFL: case MTNOP:
854 callcount = 1;
855 fcount = 1;
856 break;
857
858 default:
859 return (ENXIO);
860 }
861 if (callcount <= 0 || fcount <= 0)
862 return (EINVAL);
863 while (--callcount >= 0) {
864 tscommand(dev, tsops[mtop->mt_op], fcount);
865 if ((mtop->mt_op == MTFSR || mtop->mt_op == MTBSR) &&
866 bp->b_resid)
867 return (EIO);
868 if ((bp->b_flags&B_ERROR) ||
869 sc->sc_ts.t_sts.s_xs0&TS_BOT)
870 break;
871 }
872 if (bp->b_flags&B_ERROR)
873 if ((error = bp->b_error)==0)
874 return (EIO);
875 return (error);
876
877 case MTIOCGET:
878 mtget = (struct mtget *)data;
879 mtget->mt_dsreg = 0;
880 mtget->mt_erreg = sc->sc_ts.t_sts.s_xs0;
881 mtget->mt_resid = sc->sc_resid;
882 mtget->mt_type = MT_ISTS;
883 break;
884
885 default:
886 return (ENXIO);
887 }
888 return (0);
889 }
890
891 #define DBSIZE 20
892
tsdump(dev)893 tsdump(dev)
894 dev_t dev;
895 {
896 register struct uba_device *ui;
897 register struct uba_regs *uba;
898 register struct tsdevice *addr;
899 register int i;
900 register struct pte *io;
901 int blk, num, unit, reg, start;
902 u_short db;
903 struct ts_tsdata *tc, *tc_ubaddr;
904
905 unit = TSUNIT(dev);
906 if (unit >= NTS)
907 return (ENXIO);
908 #define phys(a,b) ((b)((int)(a)&0x7fffffff))
909 ui = phys(tsdinfo[unit], struct uba_device *);
910 if (ui->ui_alive == 0)
911 return (ENXIO);
912 uba = phys(ui->ui_hd, struct uba_hd *)->uh_physuba;
913 ubainit(uba);
914 addr = (struct tsdevice *)ui->ui_physaddr;
915
916 /* map a ts_tsdata structure */
917 tc = phys(&ts_softc[0].sc_ts, struct ts_tsdata *);
918 num = btoc(sizeof(struct ts_tsdata)) + 1;
919 io = &uba->uba_map[reg = NUBMREG - num];
920 for (i = 0; i < num; i++)
921 *(int *)io++ = UBAMR_MRV | (btop(tc) + i);
922 i = (((int)tc & PGOFSET) | (reg << 9));
923 tc_ubaddr = (struct ts_tsdata *)i;
924 db = i + ((i >> 16) & 3);
925
926 /* init the drive */
927 addr->tssr = 0;
928 tswait(addr);
929 if ((addr->tssr & (TS_NBA|TS_OFL)) != TS_NBA)
930 return (EFAULT);
931
932 /* set characteristics */
933 i = (int)&tc_ubaddr->t_char;
934 tc->t_cmd.c_loba = i;
935 tc->t_cmd.c_hiba = (i >> 16) & 3;
936 tc->t_cmd.c_size = sizeof(struct ts_char);
937 tc->t_cmd.c_cmd = TS_ACK | TS_CVC | TS_SETCHR;
938 tc->t_char.char_addr = (int)&tc_ubaddr->t_sts;
939 tc->t_char.char_size = sizeof(struct ts_sts);
940 tc->t_char.char_mode = TS_ESS;
941 addr->tsdb = db;
942 tswait(addr);
943 if (addr->tssr & TS_NBA)
944 return (ENXIO);
945
946 /* dump */
947 tc->t_cmd.c_cmd = TS_ACK | TS_WCOM;
948 tc->t_cmd.c_repcnt = 1;
949 num = maxfree;
950 for (start = 0, num = maxfree; num > 0; start += blk, num -= blk) {
951 blk = num > DBSIZE ? DBSIZE : num;
952 io = uba->uba_map;
953 for (i = 0; i < blk; i++)
954 *(int *)io++ = UBAMR_MRV | (1 << UBAMR_DPSHIFT) |
955 (start + i);
956 *(int *)io = 0;
957 addr->tsdb = db;
958 tswait(addr);
959 }
960
961 /* eof */
962 tc->t_cmd.c_cmd = TS_WEOF;
963 addr->tsdb = db;
964 tswait(addr);
965 addr->tsdb = db;
966 tswait(addr);
967
968 if (addr->tssr&TS_SC)
969 return (EIO);
970 addr->tssr = 0;
971 tswait(addr);
972 return (0);
973 }
974
tswait(addr)975 tswait(addr)
976 register struct tsdevice *addr;
977 {
978
979 while ((addr->tssr & TS_SSR) == 0)
980 /* void */;
981 }
982
983 #endif /* NTS > 0 */
984