1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Ralph Campbell.
7 *
8 * %sccs.include.redist.c%
9 *
10 * @(#)tz.c 8.5 (Berkeley) 06/02/95
11 *
12 * from: $Header: /sprite/src/kernel/dev/RCS/devSCSITape.c,
13 * v 8.14 89/07/31 17:26:13 mendel Exp $ SPRITE (Berkeley)
14 */
15
16 /*
17 * SCSI CCS (Command Command Set) tape driver.
18 */
19 #include "tz.h"
20 #if NTZ > 0
21
22 #include <sys/param.h>
23 #include <sys/systm.h>
24 #include <sys/buf.h>
25 #include <sys/errno.h>
26 #include <sys/file.h>
27 #include <sys/ioctl.h>
28 #include <sys/mtio.h>
29 #include <sys/syslog.h>
30 #include <sys/tprintf.h>
31
32 #include <pmax/dev/device.h>
33 #include <pmax/dev/scsi.h>
34
35 int tzprobe();
36 void tzstart(), tzdone();
37
38 struct driver tzdriver = {
39 "tz", tzprobe, tzstart, tzdone,
40 };
41
42 struct tz_softc {
43 struct scsi_device *sc_sd; /* physical unit info */
44 int sc_flags; /* see below */
45 int sc_tapeid; /* tape drive id */
46 int sc_blklen; /* 0 = variable len records */
47 long sc_numblks; /* number of blocks on tape */
48 tpr_t sc_ctty; /* terminal for error messages */
49 struct buf sc_tab; /* queue of pending operations */
50 struct buf sc_buf; /* buf for doing I/O */
51 struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */
52 struct ScsiCmd sc_cmd; /* command for controller */
53 ScsiGroup0Cmd sc_rwcmd; /* SCSI cmd for read/write */
54 struct scsi_fmt_cdb sc_cdb; /* SCSI cmd if not read/write */
55 struct scsi_fmt_sense sc_sense; /* sense data from last cmd */
56 struct ScsiTapeModeSelectHdr sc_mode; /* SCSI_MODE_SENSE data */
57 char sc_modelen; /* SCSI_MODE_SENSE data length */
58 } tz_softc[NTZ];
59
60 /* sc_flags values */
61 #define TZF_ALIVE 0x01 /* drive found and ready */
62 #define TZF_SENSEINPROGRESS 0x02 /* REQUEST_SENSE command in progress */
63 #define TZF_ALTCMD 0x04 /* alternate command in progress */
64 #define TZF_WRITTEN 0x08 /* tape has been written to */
65 #define TZF_OPEN 0x10 /* device is open */
66 #define TZF_WAIT 0x20 /* waiting for sc_tab to drain */
67 #define TZF_SEENEOF 0x40 /* seen file mark on read */
68
69 /* bits in minor device */
70 #define tzunit(x) (minor(x) >> 4) /* tz%d unit number */
71 #define TZ_NOREWIND 0x01 /* don't rewind on close */
72 #define TZ_HIDENSITY 0x02
73 #define TZ_EXSFMK 0x04
74 #define TZ_FIXEDBLK 0x08
75
76 #ifdef DEBUG
77 int tzdebug = 0;
78 #endif
79
80 /*
81 * Test to see if device is present.
82 * Return true if found and initialized ok.
83 */
84 tzprobe(sd)
85 struct scsi_device *sd;
86 {
87 register struct tz_softc *sc = &tz_softc[sd->sd_unit];
88 register int i;
89 ScsiInquiryData inqbuf;
90 ScsiClass7Sense *sp;
91
92 /* init some parameters that don't change */
93 sc->sc_sd = sd;
94 sc->sc_cmd.sd = sd;
95 sc->sc_cmd.unit = sd->sd_unit;
96 sc->sc_cmd.flags = 0;
97 sc->sc_rwcmd.unitNumber = sd->sd_slave;
98
99 /* try to find out what type of device this is */
100 sc->sc_flags = TZF_ALTCMD; /* force use of sc_cdb */
101 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
102 scsiGroup0Cmd(SCSI_INQUIRY, sd->sd_slave, 0, sizeof(inqbuf),
103 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
104 sc->sc_buf.b_flags = B_BUSY | B_READ;
105 sc->sc_buf.b_bcount = sizeof(inqbuf);
106 sc->sc_buf.b_un.b_addr = (caddr_t)&inqbuf;
107 sc->sc_buf.b_actf = (struct buf *)0;
108 sc->sc_buf.b_actb = &sc->sc_tab.b_actf;
109 sc->sc_tab.b_actf = &sc->sc_buf;
110 sc->sc_tab.b_actb = &sc->sc_buf.b_actf;
111 tzstart(sd->sd_unit);
112 if (biowait(&sc->sc_buf) ||
113 (i = sizeof(inqbuf) - sc->sc_buf.b_resid) < 5)
114 goto bad;
115 if (inqbuf.type != SCSI_TAPE_TYPE || !inqbuf.rmb)
116 goto bad;
117
118 /* check for device ready to clear UNIT_ATTN */
119 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
120 scsiGroup0Cmd(SCSI_TEST_UNIT_READY, sd->sd_slave, 0, 0,
121 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
122 sc->sc_buf.b_flags = B_BUSY | B_READ;
123 sc->sc_buf.b_bcount = 0;
124 sc->sc_buf.b_un.b_addr = (caddr_t)0;
125 sc->sc_buf.b_actf = (struct buf *)0;
126 sc->sc_buf.b_actb = &sc->sc_tab.b_actf;
127 sc->sc_tab.b_actf = &sc->sc_buf;
128 sc->sc_tab.b_actb = &sc->sc_buf.b_actf;
129 tzstart(sd->sd_unit);
130 (void) biowait(&sc->sc_buf);
131
132 sc->sc_flags = TZF_ALIVE;
133 sc->sc_modelen = 12;
134 sc->sc_buf.b_flags = 0;
135 printf("tz%d at %s%d drive %d slave %d", sd->sd_unit,
136 sd->sd_cdriver->d_name, sd->sd_ctlr, sd->sd_drive,
137 sd->sd_slave);
138 if (i == 5 && inqbuf.version == 1 && inqbuf.qualifier == 0x50) {
139 printf(" TK50\n");
140 sc->sc_tapeid = MT_ISTK50;
141 } else if (i >= 5 && inqbuf.version == 1 && inqbuf.qualifier == 0 &&
142 inqbuf.length == 0) {
143 /* assume Emultex MT02 controller */
144 printf(" MT02\n");
145 sc->sc_tapeid = MT_ISMT02;
146 } else if (inqbuf.version > 2 || i < 36) {
147 printf(" GENERIC SCSI tape device: qual 0x%x, ver %d\n",
148 inqbuf.qualifier, inqbuf.version);
149 sc->sc_tapeid = 0;
150 } else {
151 char vid[9], pid[17], revl[5];
152
153 bcopy((caddr_t)inqbuf.vendorID, (caddr_t)vid, 8);
154 bcopy((caddr_t)inqbuf.productID, (caddr_t)pid, 16);
155 bcopy((caddr_t)inqbuf.revLevel, (caddr_t)revl, 4);
156 for (i = 8; --i > 0; )
157 if (vid[i] != ' ')
158 break;
159 vid[i+1] = 0;
160 for (i = 16; --i > 0; )
161 if (pid[i] != ' ')
162 break;
163 pid[i+1] = 0;
164 for (i = 4; --i > 0; )
165 if (revl[i] != ' ')
166 break;
167 revl[i+1] = 0;
168 printf(" %s %s rev %s\n", vid, pid, revl);
169
170 if (bcmp("EXB-8200", pid, 8) == 0) {
171 sc->sc_tapeid = MT_ISEXABYTE;
172 sc->sc_modelen = 17;
173 } else if (bcmp("VIPER 150", pid, 9) == 0) {
174 sc->sc_tapeid = MT_ISVIPER1;
175 } else if (bcmp("Python 25501", pid, 12) == 0) {
176 sc->sc_tapeid = MT_ISPYTHON;
177 } else if (bcmp("HP35450A", pid, 8) == 0) {
178 #if 0
179 /* XXX "extra" stat makes the HP drive happy at boot time */
180 stat = scsi_test_unit_rdy(ctlr, slave, unit);
181 #endif
182 sc->sc_tapeid = MT_ISHPDAT;
183 } else if (bcmp("123107 SCSI", pid, 11) == 0) {
184 sc->sc_tapeid = MT_ISMFOUR;
185 } else {
186 printf("tz%d: assuming GENERIC SCSI tape device\n",
187 sd->sd_unit,
188 inqbuf.type, inqbuf.qualifier, inqbuf.version);
189 sc->sc_tapeid = 0;
190 }
191 }
192 return (1);
193
194 bad:
195 /* doesn't exist or not a CCS device */
196 sc->sc_flags = 0;
197 sc->sc_buf.b_flags = 0;
198 return (0);
199 }
200
201 /*
202 * Perform a special tape command on a SCSI Tape drive.
203 */
tzcommand(dev,command,code,count,data)204 tzcommand(dev, command, code, count, data)
205 dev_t dev;
206 int command;
207 int code;
208 int count;
209 caddr_t data;
210 {
211 register struct tz_softc *sc = &tz_softc[tzunit(dev)];
212 register ScsiGroup0Cmd *c;
213 int s, error;
214
215 s = splbio();
216 /* wait for pending operations to finish */
217 while (sc->sc_tab.b_actf) {
218 sc->sc_flags |= TZF_WAIT;
219 sleep(&sc->sc_flags, PZERO);
220 }
221 sc->sc_flags |= TZF_ALTCMD; /* force use of sc_cdb */
222 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
223 c = (ScsiGroup0Cmd *)sc->sc_cdb.cdb;
224 c->command = command;
225 c->unitNumber = sc->sc_sd->sd_slave;
226 c->highAddr = code;
227 c->midAddr = count >> 16;
228 c->lowAddr = count >> 8;
229 c->blockCount = count;
230 c->control = 0;
231 if (command == SCSI_MODE_SELECT)
232 sc->sc_buf.b_flags = B_BUSY;
233 else {
234 sc->sc_buf.b_flags = B_BUSY | B_READ;
235 #if 0
236 /* this seems to work but doesn't give us a speed advantage */
237 if (command == SCSI_TEST_UNIT_READY)
238 sc->sc_cmd.flags |= SCSICMD_USE_SYNC;
239 #endif
240 }
241 sc->sc_buf.b_bcount = data ? count : 0;
242 sc->sc_buf.b_un.b_addr = data;
243 sc->sc_buf.b_actf = (struct buf *)0;
244 sc->sc_buf.b_actb = &sc->sc_tab.b_actf;
245 sc->sc_tab.b_actf = &sc->sc_buf;
246 sc->sc_tab.b_actb = &sc->sc_buf.b_actf;
247 tzstart(sc->sc_sd->sd_unit);
248 error = biowait(&sc->sc_buf);
249 sc->sc_flags &= ~TZF_ALTCMD; /* force use of sc_cdb */
250 sc->sc_buf.b_flags = 0;
251 sc->sc_cmd.flags = 0;
252 if (sc->sc_buf.b_resid)
253 printf("tzcommand: resid %d\n", sc->sc_buf.b_resid); /* XXX */
254 if (error == 0)
255 switch (command) {
256 case SCSI_SPACE:
257 case SCSI_WRITE_EOF:
258 case SCSI_REWIND:
259 sc->sc_flags &= ~TZF_SEENEOF;
260 }
261 splx(s);
262 return (error);
263 }
264
265 void
tzstart(unit)266 tzstart(unit)
267 int unit;
268 {
269 register struct tz_softc *sc = &tz_softc[unit];
270 register struct buf *bp = sc->sc_tab.b_actf;
271 register int n;
272
273 sc->sc_cmd.buf = bp->b_un.b_addr;
274 sc->sc_cmd.buflen = bp->b_bcount;
275
276 if (sc->sc_flags & (TZF_SENSEINPROGRESS | TZF_ALTCMD)) {
277 if (bp->b_flags & B_READ)
278 sc->sc_cmd.flags &= ~SCSICMD_DATA_TO_DEVICE;
279 else
280 sc->sc_cmd.flags |= SCSICMD_DATA_TO_DEVICE;
281 sc->sc_cmd.cmd = sc->sc_cdb.cdb;
282 sc->sc_cmd.cmdlen = sc->sc_cdb.len;
283 } else {
284 if (bp->b_flags & B_READ) {
285 sc->sc_cmd.flags = 0;
286 sc->sc_rwcmd.command = SCSI_READ;
287 sc->sc_flags &= ~TZF_WRITTEN;
288 } else {
289 sc->sc_cmd.flags = SCSICMD_DATA_TO_DEVICE;
290 sc->sc_rwcmd.command = SCSI_WRITE;
291 sc->sc_flags |= TZF_WRITTEN;
292 }
293 sc->sc_cmd.cmd = (u_char *)&sc->sc_rwcmd;
294 sc->sc_cmd.cmdlen = sizeof(sc->sc_rwcmd);
295 if (sc->sc_blklen) {
296 /* fixed sized records */
297 n = bp->b_bcount / sc->sc_blklen;
298 if (bp->b_bcount % sc->sc_blklen) {
299 tprintf(sc->sc_ctty,
300 "tz%d: I/O not block aligned %d/%ld\n",
301 unit, sc->sc_blklen, bp->b_bcount);
302 tzdone(unit, EIO, bp->b_bcount, 0);
303 }
304 sc->sc_rwcmd.highAddr = 1;
305 } else {
306 /* variable sized records */
307 n = bp->b_bcount;
308 sc->sc_rwcmd.highAddr = 0;
309 }
310 sc->sc_rwcmd.midAddr = n >> 16;
311 sc->sc_rwcmd.lowAddr = n >> 8;
312 sc->sc_rwcmd.blockCount = n;
313 }
314
315 /* tell controller to start this command */
316 (*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd);
317 }
318
319 /*
320 * This is called by the controller driver when the command is done.
321 */
322 void
tzdone(unit,error,resid,status)323 tzdone(unit, error, resid, status)
324 int unit;
325 int error; /* error number from errno.h */
326 int resid; /* amount not transfered */
327 int status; /* SCSI status byte */
328 {
329 register struct tz_softc *sc = &tz_softc[unit];
330 register struct buf *bp = sc->sc_tab.b_actf;
331 register struct buf *dp;
332 extern int cold;
333
334 if (bp == NULL) {
335 printf("tz%d: bp == NULL\n", unit);
336 return;
337 }
338 if (sc->sc_flags & TZF_SENSEINPROGRESS) {
339 sc->sc_flags &= ~TZF_SENSEINPROGRESS;
340 *bp->b_actb = dp = bp->b_actf; /* remove sc_errbuf */
341 #ifdef DIAGNOSTIC
342 if (!dp)
343 panic("tzdone");
344 #endif
345 dp->b_actb = bp->b_actb;
346 bp = dp;
347
348 if (error || (status & SCSI_STATUS_CHECKCOND)) {
349 printf("tz%d: error reading sense data: error %d scsi status 0x%x\n",
350 unit, error, status);
351 /*
352 * We got an error during the REQUEST_SENSE,
353 * fill in no sense for data.
354 */
355 sc->sc_sense.sense[0] = 0x70;
356 sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE;
357 } else if (!cold) {
358 ScsiClass7Sense *sp;
359 long resid;
360
361 sp = (ScsiClass7Sense *)sc->sc_sense.sense;
362 if (sp->error7 != 0x70)
363 goto prerr;
364 if (sp->valid) {
365 resid = (sp->info1 << 24) | (sp->info2 << 16) |
366 (sp->info3 << 8) | sp->info4;
367 if (sc->sc_blklen)
368 resid *= sc->sc_blklen;
369 } else
370 resid = 0;
371 switch (sp->key) {
372 case SCSI_CLASS7_NO_SENSE:
373 /*
374 * Hit a filemark, end of media, or
375 * end of record.
376 * Fixed length blocks, an error.
377 */
378 if (sp->endOfMedia) {
379 bp->b_error = ENOSPC;
380 bp->b_resid = resid;
381 break;
382 }
383 if (sc->sc_blklen && sp->badBlockLen) {
384 tprintf(sc->sc_ctty,
385 "tz%d: Incorrect Block Length, expected %d got %d\n",
386 unit, sc->sc_blklen, resid);
387 break;
388 }
389 if (resid < 0) {
390 /*
391 * Variable length records but
392 * attempted to read less than a
393 * full record.
394 */
395 tprintf(sc->sc_ctty,
396 "tz%d: Partial Read of Variable Length Tape Block, expected %d read %d\n",
397 unit, bp->b_bcount - resid,
398 bp->b_bcount);
399 bp->b_resid = 0;
400 break;
401 }
402 if (sp->fileMark)
403 sc->sc_flags |= TZF_SEENEOF;
404 /*
405 * Attempting to read more than a record is
406 * OK. Just record how much was actually read.
407 */
408 bp->b_flags &= ~B_ERROR;
409 bp->b_error = 0;
410 bp->b_resid = resid;
411 break;
412
413 case SCSI_CLASS7_UNIT_ATTN:
414 if (!(sc->sc_flags & TZF_OPEN))
415 break;
416
417 default:
418 prerr:
419 printf("tz%d: ", unit);
420 scsiPrintSense((ScsiClass7Sense *)
421 sc->sc_sense.sense,
422 sizeof(sc->sc_sense.sense) - resid);
423 }
424 }
425 } else if (error || (status & SCSI_STATUS_CHECKCOND)) {
426 #ifdef DEBUG
427 if (!cold && tzdebug)
428 printf("tz%d: error %d scsi status 0x%x\n",
429 unit, error, status);
430 #endif
431 /* save error info */
432 sc->sc_sense.status = status;
433 bp->b_flags |= B_ERROR;
434 bp->b_error = error;
435 bp->b_resid = resid;
436
437 if (status & SCSI_STATUS_CHECKCOND) {
438 /*
439 * Start a REQUEST_SENSE command.
440 * Since we are called at interrupt time, we can't
441 * wait for the command to finish; that's why we use
442 * the sc_flags field.
443 */
444 sc->sc_flags |= TZF_SENSEINPROGRESS;
445 sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
446 scsiGroup0Cmd(SCSI_REQUEST_SENSE, sc->sc_sd->sd_slave,
447 0, sizeof(sc->sc_sense.sense),
448 (ScsiGroup0Cmd *)sc->sc_cdb.cdb);
449 sc->sc_errbuf.b_flags = B_BUSY | B_PHYS | B_READ;
450 sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense);
451 sc->sc_errbuf.b_un.b_addr = (caddr_t)sc->sc_sense.sense;
452 sc->sc_errbuf.b_actf = bp;
453 sc->sc_errbuf.b_actb = bp->b_actb;
454 *bp->b_actb = &sc->sc_errbuf;
455 bp->b_actb = &sc->sc_errbuf.b_actf;
456 tzstart(unit);
457 return;
458 }
459 } else {
460 sc->sc_sense.status = status;
461 bp->b_resid = resid;
462 }
463
464 if (dp = bp->b_actf)
465 dp->b_actb = bp->b_actb;
466 else
467 sc->sc_tab.b_actb = bp->b_actb;
468 *bp->b_actb = dp;
469 biodone(bp);
470 if (sc->sc_tab.b_actf)
471 tzstart(unit);
472 else {
473 sc->sc_tab.b_active = 0;
474 if (sc->sc_flags & TZF_WAIT) {
475 sc->sc_flags &= ~TZF_WAIT;
476 wakeup(&sc->sc_flags);
477 }
478 }
479 }
480
481 /* ARGSUSED */
tzopen(dev,flags,type,p)482 tzopen(dev, flags, type, p)
483 dev_t dev;
484 int flags, type;
485 struct proc *p;
486 {
487 register int unit = tzunit(dev);
488 register struct tz_softc *sc = &tz_softc[unit];
489 int error;
490
491 if (unit >= NTZ || sc->sc_sd == NULL)
492 return (ENXIO);
493 if (!(sc->sc_flags & TZF_ALIVE)) {
494 /* check again, tape may have been turned off at boot time */
495 if (!tzprobe(sc->sc_sd))
496 return (ENXIO);
497 }
498 if (sc->sc_flags & TZF_OPEN)
499 return (EBUSY);
500
501 /* clear UNIT_ATTENTION */
502 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0);
503 while (error) {
504 ScsiClass7Sense *sp = (ScsiClass7Sense *)sc->sc_sense.sense;
505
506 /* return error if last error was not UNIT_ATTENTION */
507 if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND) ||
508 sp->error7 != 0x70 || sp->key != SCSI_CLASS7_UNIT_ATTN)
509 return (error);
510
511 /*
512 * Try it again just to be sure and
513 * try to negotiate synchonous transfers.
514 */
515 error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0);
516 }
517
518 /* get the current mode settings */
519 error = tzcommand(dev, SCSI_MODE_SENSE, 0,
520 sc->sc_modelen, (caddr_t)&sc->sc_mode);
521 if (error)
522 return (error);
523
524 /* check for write protected tape */
525 if ((flags & FWRITE) && sc->sc_mode.writeprot) {
526 uprintf("tz%d: write protected\n", unit);
527 return (EACCES);
528 }
529
530 /* set record length */
531 switch (sc->sc_tapeid) {
532 case MT_ISAR:
533 case MT_ISHPDAT:
534 case MT_ISVIPER1:
535 sc->sc_blklen = 512;
536 break;
537
538 case MT_ISEXABYTE:
539 #if 0
540 if (minor(dev) & TZ_FIXEDBLK)
541 sc->sc_blklen = 1024;
542 else
543 sc->sc_blklen = st_exblklen;
544 #endif
545 break;
546
547 case MT_ISPYTHON:
548 case MT_ISMFOUR:
549 case MT_ISTK50:
550 sc->sc_blklen = 0;
551 break;
552
553 default:
554 sc->sc_blklen = (sc->sc_mode.block_size2 << 16) |
555 (sc->sc_mode.block_size1 << 8) | sc->sc_mode.block_size0;
556 }
557
558 /* save total number of blocks on tape */
559 sc->sc_numblks = (sc->sc_mode.blocks_2 << 16) |
560 (sc->sc_mode.blocks_1 << 8) | sc->sc_mode.blocks_0;
561
562 /* setup for mode select */
563 sc->sc_mode.len = 0;
564 sc->sc_mode.media = 0;
565 sc->sc_mode.bufferedMode = 1;
566 sc->sc_mode.blocks_0 = 0;
567 sc->sc_mode.blocks_1 = 0;
568 sc->sc_mode.blocks_2 = 0;
569 sc->sc_mode.block_size0 = sc->sc_blklen >> 16;
570 sc->sc_mode.block_size1 = sc->sc_blklen >> 8;
571 sc->sc_mode.block_size2 = sc->sc_blklen;
572
573 /* check for tape density changes */
574 switch (sc->sc_tapeid) {
575 case MT_ISAR:
576 if (minor(dev) & TZ_HIDENSITY)
577 sc->sc_mode.density = 0x5;
578 else {
579 if (flags & FWRITE) {
580 uprintf("Can only write QIC-24\n");
581 return (EIO);
582 }
583 sc->sc_mode.density = 0x4;
584 }
585 break;
586
587 case MT_ISMT02:
588 /*
589 * The tape density is set automatically when the tape
590 * is loaded. We only need to change it if we are writing.
591 */
592 if (flags & FWRITE) {
593 if (minor(dev) & TZ_HIDENSITY)
594 sc->sc_mode.density = 0;
595 else
596 sc->sc_mode.density = 0x4;
597 }
598 break;
599
600 case MT_ISEXABYTE:
601 #if 0
602 if (minor(dev) & TZ_HIDENSITY)
603 uprintf("EXB-8200 density support only\n");
604 sc->sc_mode.vupb = (u_char)st_exvup;
605 sc->sc_mode.rsvd5 = 0;
606 sc->sc_mode.p5 = 0;
607 sc->sc_mode.motionthres = (u_char)st_exmotthr;
608 sc->sc_mode.reconthres = (u_char)st_exreconthr;
609 sc->sc_mode.gapthres = (u_char)st_exgapthr;
610 #endif
611 break;
612
613 case MT_ISHPDAT:
614 case MT_ISVIPER1:
615 case MT_ISPYTHON:
616 case MT_ISTK50:
617 if (minor(dev) & TZ_HIDENSITY)
618 uprintf("tz%d: Only one density supported\n", unit);
619 break;
620
621 case MT_ISMFOUR:
622 break; /* XXX could do density select? */
623 }
624
625 /* set the current mode settings */
626 error = tzcommand(dev, SCSI_MODE_SELECT, 0,
627 sc->sc_modelen, (caddr_t)&sc->sc_mode);
628 if (error)
629 return (error);
630
631 sc->sc_ctty = tprintf_open(p);
632 sc->sc_flags = TZF_ALIVE | TZF_OPEN;
633 return (0);
634 }
635
tzclose(dev,flag)636 tzclose(dev, flag)
637 dev_t dev;
638 int flag;
639 {
640 register struct tz_softc *sc = &tz_softc[tzunit(dev)];
641 int error = 0;
642
643 if (!(sc->sc_flags & TZF_OPEN))
644 return (0);
645 if (flag == FWRITE ||
646 ((flag & FWRITE) && (sc->sc_flags & TZF_WRITTEN))) {
647 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0);
648 #if 0
649 /*
650 * Cartridge tapes don't do double EOFs on EOT.
651 */
652 switch (sc->sc_tapeid) {
653 case MT_ISAR:
654 case MT_ISMT02:
655 break;
656
657 default:
658 error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0);
659 if (minor(dev) & TZ_NOREWIND)
660 (void) tzcommand(dev, SCSI_SPACE, 0, -1, 0);
661 }
662 #endif
663 }
664 if ((minor(dev) & TZ_NOREWIND) == 0)
665 (void) tzcommand(dev, SCSI_REWIND, 0, 0, 0);
666 sc->sc_flags &= ~(TZF_OPEN | TZF_WRITTEN);
667 tprintf_close(sc->sc_ctty);
668 return (error);
669 }
670
tzioctl(dev,cmd,data,flag)671 tzioctl(dev, cmd, data, flag)
672 dev_t dev;
673 u_long cmd;
674 caddr_t data;
675 int flag;
676 {
677 register struct tz_softc *sc = &tz_softc[tzunit(dev)];
678 register struct buf *bp = &sc->sc_buf;
679 struct mtop *mtop;
680 struct mtget *mtget;
681 int code, count;
682 static tzops[] = {
683 SCSI_WRITE_EOF, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE, SCSI_SPACE,
684 SCSI_REWIND, SCSI_REWIND, SCSI_TEST_UNIT_READY
685 };
686
687 switch (cmd) {
688
689 case MTIOCTOP: /* tape operation */
690 mtop = (struct mtop *)data;
691 if ((unsigned)mtop->mt_op < MTREW && mtop->mt_count <= 0)
692 return (EINVAL);
693 switch (mtop->mt_op) {
694
695 case MTWEOF:
696 code = 0;
697 count = mtop->mt_count;
698 break;
699
700 case MTFSF:
701 code = 1;
702 count = mtop->mt_count;
703 break;
704
705 case MTBSF:
706 code = 1;
707 count = -mtop->mt_count;
708 break;
709
710 case MTFSR:
711 code = 0;
712 count = mtop->mt_count;
713 break;
714
715 case MTBSR:
716 code = 0;
717 count = -mtop->mt_count;
718 break;
719
720 case MTREW:
721 case MTOFFL:
722 case MTNOP:
723 code = 0;
724 count = 0;
725 break;
726
727 default:
728 return (EINVAL);
729 }
730 return (tzcommand(dev, tzops[mtop->mt_op], code, count, 0));
731
732 case MTIOCGET:
733 mtget = (struct mtget *)data;
734 mtget->mt_dsreg = 0;
735 mtget->mt_erreg = sc->sc_sense.status;
736 mtget->mt_resid = 0;
737 mtget->mt_type = 0;
738 break;
739
740 default:
741 return (EINVAL);
742 }
743 return (0);
744 }
745
746 void
tzstrategy(bp)747 tzstrategy(bp)
748 register struct buf *bp;
749 {
750 register int unit = tzunit(bp->b_dev);
751 register struct tz_softc *sc = &tz_softc[unit];
752 register struct buf *dp;
753 register int s;
754
755 if (sc->sc_flags & TZF_SEENEOF) {
756 bp->b_resid = bp->b_bcount;
757 biodone(bp);
758 return;
759 }
760 bp->b_actf = NULL;
761 dp = &sc->sc_tab;
762 s = splbio();
763 bp->b_actb = dp->b_actb;
764 *dp->b_actb = bp;
765 dp->b_actb = &bp->b_actf;
766 if (dp->b_active == 0) {
767 dp->b_active = 1;
768 tzstart(unit);
769 }
770 splx(s);
771 }
772 #endif
773