Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/pmax/dev Overhaul the tz SCSI tape driver:
details: https://anonhg.NetBSD.org/src/rev/54697367e70c
branches: trunk
changeset: 476130:54697367e70c
user: simonb <simonb%NetBSD.org@localhost>
date: Tue Sep 07 13:53:36 1999 +0000
description:
Overhaul the tz SCSI tape driver:
+ Add a quirk table.
+ Assume all else is a modern drive that can do variable block
lengths (this is the main reason for this work - the old driver
only ever seemed to write 512 byte blocks!).
+ Keep track of values for mtget's mt_fileno, mt_blkno.
+ Handle a few extra MTIOCTOP commands.
Ideas gleaned from our MI scsi tape driver and the FreeBSD CAM tape
driver. Tested on a TKZ09 (DEC badged Exabyte 8500), a TLZ06 (DEC
DAT) and TK50.
Many thanks to Pierre Bergdolt for helping with testing.
diffstat:
sys/arch/pmax/dev/tz.c | 555 +++++++++++++++++++++++++++---------------------
1 files changed, 314 insertions(+), 241 deletions(-)
diffs (truncated from 797 to 300 lines):
diff -r e0240de259a4 -r 54697367e70c sys/arch/pmax/dev/tz.c
--- a/sys/arch/pmax/dev/tz.c Tue Sep 07 08:16:13 1999 +0000
+++ b/sys/arch/pmax/dev/tz.c Tue Sep 07 13:53:36 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tz.c,v 1.20 1999/08/31 01:12:52 simonb Exp $ */
+/* $NetBSD: tz.c,v 1.21 1999/09/07 13:53:36 simonb Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -65,11 +65,12 @@
#include <pmax/dev/device.h>
#include <pmax/dev/scsi.h>
-int tzprobe __P(( void *sd /*struct pmax_scsi_device *sd*/));
-int tzcommand __P((dev_t dev, int command, int code,
+static int tzprobe __P((void *sd /*struct pmax_scsi_device *sd*/));
+static int tzcommand __P((dev_t dev, int command, int code,
int count, caddr_t data));
-void tzstart __P((int unit));
-void tzdone __P((int unit, int error, int resid, int status));
+static void tzstart __P((int unit));
+static void tzdone __P((int unit, int error, int resid, int status));
+static int tzmount __P((dev_t dev));
struct pmax_driver tzdriver = {
"tz", tzprobe,
@@ -77,14 +78,37 @@
tzdone,
};
+struct tzmodes {
+ u_int quirks;
+ u_int8_t density;
+};
+
+struct tzquirk {
+ char *product;
+ u_int page_0_size;
+ u_int quirks;
+ int blklen;
+ struct tzmodes modes[2]; /* low density, high density */
+};
+
+#define TZ_Q_FORCE_BLKSIZE 0x0001
+#define TZ_Q_SENSE_HELP 0x0002 /* must do READ for good MODE SENSE */
+#define TZ_Q_IGNORE_LOADS 0x0004
+#define TZ_Q_BLKSIZE 0x0008 /* variable-block media_blksize > 0 */
+#define TZ_Q_UNIMODAL 0x0010 /* unimode drive rejects mode select */
+#define TZ_Q_DENSITY 0x0020 /* density codes valid */
+#define MAX_PAGE_0_SIZE 64
+
+
struct tz_softc {
struct device sc_dev; /* new config glue */
struct pmax_scsi_device *sc_sd; /* physical unit info */
int sc_flags; /* see below */
- int sc_tapeid; /* tape drive id */
int sc_blklen; /* 0 = variable len records */
long sc_numblks; /* number of blocks on tape */
tpr_t sc_ctty; /* terminal for error messages */
+ daddr_t sc_fileno; /* file number of current position */
+ daddr_t sc_blkno; /* block number of current position */
struct buf sc_tab; /* queue of pending operations */
struct buf sc_buf; /* buf for doing I/O */
struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */
@@ -94,16 +118,21 @@
struct scsi_fmt_sense sc_sense; /* sense data from last cmd */
struct ScsiTapeModeSelectHdr sc_mode; /* SCSI_MODE_SENSE data */
char sc_modelen; /* SCSI_MODE_SENSE data length */
+ struct tzquirk *sc_quirks; /* quirks for this drive */
+
} tz_softc[NTZ];
/* sc_flags values */
-#define TZF_ALIVE 0x01 /* drive found and ready */
-#define TZF_SENSEINPROGRESS 0x02 /* REQUEST_SENSE command in progress */
-#define TZF_ALTCMD 0x04 /* alternate command in progress */
-#define TZF_WRITTEN 0x08 /* tape has been written to */
-#define TZF_OPEN 0x10 /* device is open */
-#define TZF_WAIT 0x20 /* waiting for sc_tab to drain */
-#define TZF_SEENEOF 0x40 /* seen file mark on read */
+#define TZF_ALIVE 0x001 /* drive found and ready */
+#define TZF_MOUNTED 0x002 /* device is presently mounted */
+#define TZF_OPEN 0x004 /* device is open */
+#define TZF_SENSEINPROGRESS 0x008 /* REQUEST_SENSE command in progress */
+#define TZF_ALTCMD 0x010 /* alternate command in progress */
+#define TZF_WRITTEN 0x020 /* tape has been written to */
+#define TZF_WAIT 0x040 /* waiting for sc_tab to drain */
+#define TZF_SEENEOF 0x080 /* seen file mark on read */
+#define TZF_RDONLY 0x100 /* mode sense says write protected */
+#define TZF_DONTCOUNT 0x200 /* operation isn't to be counted for sc_blkno */
/* bits in minor device */
#define tzunit(x) (minor(x) >> 4) /* tz%d unit number */
@@ -117,19 +146,58 @@
#endif
+struct tzquirk tz_quirk_table[] = {
+ { "EXB-8200", 17, 0, 0, {
+ { 0, 0,},
+ { 0, 0,}
+ }},
+ { "TZK08", 17, 0, 0, {
+ { 0, 0,},
+ { 0, 0,}
+ }},
+ { "EXB-8500", 17, 0, 0, {
+ { 0, 0,},
+ { 0, 0,}
+ }},
+ { "TKZ09", 17, 0, 0, {
+ { 0, 0,},
+ { 0, 0,}
+ }},
+
+ { "VIPER 150", 0, TZ_Q_FORCE_BLKSIZE, 512, {
+ { 0, 0, },
+ { 0, 0, }
+ }},
+ { "5150ES SCSI", 0, TZ_Q_FORCE_BLKSIZE, 512, {
+ { 0, 0, },
+ { 0, 0, }
+ }},
+
+ /* The next two product ids are faked up in tzprobe() */
+ { "TK50 0x30", 14, 0, 0, {
+ { 0, 0,},
+ { 0, 0,}
+ }},
+ { "MT02", 0, 0, 0, {
+ { TZ_Q_DENSITY, 0x4 },
+ { TZ_Q_DENSITY, 0 }
+ }},
+};
+
+#define NQUIRKS (sizeof(tz_quirk_table) / sizeof(tz_quirk_table[0]))
+
/*
* Test to see if device is present.
* Return true if found and initialized ok.
*/
-int
+static int
tzprobe(xxxsd)
void *xxxsd;
{
-
+ int i;
+ char vid[9], pid[17], revl[5];
struct pmax_scsi_device *sd = xxxsd;
-
struct tz_softc *sc = &tz_softc[sd->sd_unit];
- int i;
ScsiInquiryData inqbuf;
if (sd->sd_unit >= NTZ)
@@ -148,6 +216,9 @@
sc->sc_dev.dv_unit = sd->sd_unit; /* XXX */
sc->sc_dev.dv_class = DV_TAPE; /* XXX */
+ sc->sc_fileno = -1;
+ sc->sc_blkno = -1;
+
/* try to find out what type of device this is */
sc->sc_flags = TZF_ALTCMD; /* force use of sc_cdb */
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
@@ -189,21 +260,19 @@
sd->sd_slave);
if (i == 5 && inqbuf.version == 1 && (inqbuf.qualifier == 0x50 ||
inqbuf.qualifier == 0x30)) {
- printf(" TK50\n");
- sc->sc_tapeid = MT_ISTK50;
+ strcpy(pid, "TK50");
+ printf(" %s\n", pid);
if (inqbuf.qualifier == 0x30)
- sc->sc_modelen = 14;
+ strcpy(pid, "TK50 0x30");
} else if (i >= 5 && inqbuf.version == 1 && inqbuf.qualifier == 0 &&
inqbuf.length == 0) {
/* assume Emultex MT02 controller */
- printf(" MT02\n");
- sc->sc_tapeid = MT_ISMT02;
+ strcpy(pid, "MT02");
+ printf(" %s\n", pid);
} else if (inqbuf.version > 2 || i < 36) {
printf(" GENERIC SCSI tape device: qual 0x%x, ver %d\n",
inqbuf.qualifier, inqbuf.version);
- sc->sc_tapeid = 0;
} else {
- char vid[9], pid[17], revl[5];
bcopy((caddr_t)inqbuf.vendorID, (caddr_t)vid, 8);
bcopy((caddr_t)inqbuf.productID, (caddr_t)pid, 16);
@@ -221,28 +290,19 @@
break;
revl[i+1] = 0;
printf(" %s %s rev %s\n", vid, pid, revl);
+ }
- if (bcmp("EXB-8200", pid, 8) == 0) {
- sc->sc_tapeid = MT_ISEXABYTE;
- sc->sc_modelen = 17;
- } else if (bcmp("VIPER 150", pid, 9) == 0) {
- sc->sc_tapeid = MT_ISVIPER1;
- } else if (bcmp("5150ES SCSI", pid, 11)) {
- sc->sc_tapeid = MT_ISVIPER1;
- } else if (bcmp("Python 25501", pid, 12) == 0) {
- sc->sc_tapeid = MT_ISPYTHON;
- } else if (bcmp("HP35450A", pid, 8) == 0) {
-#if 0
- /* XXX "extra" stat makes the HP drive happy at boot time */
- stat = scsi_test_unit_rdy(ctlr, slave, unit);
-#endif
- sc->sc_tapeid = MT_ISHPDAT;
- } else if (bcmp("123107 SCSI", pid, 11) == 0) {
- sc->sc_tapeid = MT_ISMFOUR;
- } else {
- printf("tz%d: assuming GENERIC SCSI tape device\n",
- sd->sd_unit);
- sc->sc_tapeid = 0;
+ sc->sc_quirks = NULL;
+ for (i = 0; i < NQUIRKS; i++) {
+ if (bcmp(pid, tz_quirk_table[i].product,
+ strlen(tz_quirk_table[i].product)) == 0) {
+ sc->sc_quirks = &tz_quirk_table[i];
+ if (tz_quirk_table[i].quirks & TZ_Q_FORCE_BLKSIZE)
+ sc->sc_blklen = tz_quirk_table[i].blklen;
+ if (tz_quirk_table[i].page_0_size > 0) {
+ sc->sc_modelen = tz_quirk_table[i].page_0_size;
+ }
+ break;
}
}
@@ -261,7 +321,7 @@
/*
* Perform a special tape command on a SCSI Tape drive.
*/
-int
+static int
tzcommand(dev, command, code, count, data)
dev_t dev;
int command;
@@ -279,6 +339,7 @@
sc->sc_flags |= TZF_WAIT;
sleep(&sc->sc_flags, PZERO);
}
+ sc->sc_flags |= TZF_DONTCOUNT; /* don't count any operations in blkno */
sc->sc_flags |= TZF_ALTCMD; /* force use of sc_cdb */
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
c = (ScsiGroup0Cmd *)sc->sc_cdb.cdb;
@@ -293,11 +354,6 @@
sc->sc_buf.b_flags = B_BUSY;
else {
sc->sc_buf.b_flags = B_BUSY | B_READ;
-#if 0
- /* this seems to work but doesn't give us a speed advantage */
- if (command == SCSI_TEST_UNIT_READY)
- sc->sc_cmd.flags |= SCSICMD_USE_SYNC;
-#endif
}
sc->sc_buf.b_bcount = data ? count : 0;
sc->sc_buf.b_un.b_addr = data;
@@ -307,23 +363,55 @@
sc->sc_tab.b_actb = &sc->sc_buf.b_actf;
tzstart(sc->sc_sd->sd_unit);
error = biowait(&sc->sc_buf);
+ sc->sc_flags &= ~TZF_DONTCOUNT; /* clear don't count flag */
sc->sc_flags &= ~TZF_ALTCMD; /* force use of sc_cdb */
sc->sc_buf.b_flags = 0;
sc->sc_cmd.flags = 0;
if (sc->sc_buf.b_resid)
printf("tzcommand: resid %ld\n", sc->sc_buf.b_resid); /* XXX */
- if (error == 0)
+ if (error == 0) {
+ switch (command) {
+ case SCSI_SPACE:
+ if (sc->sc_blkno != -1) {
+ if (code == 0) {
+ sc->sc_blkno += count;
+ } else {
+ sc->sc_fileno += count;
+ sc->sc_blkno = 0;
+ }
+ }
+ sc->sc_flags &= ~TZF_SEENEOF;
+ break;
+
+ case SCSI_WRITE_EOF:
+ if (sc->sc_blkno != -1) {
+ sc->sc_fileno += count;
+ sc->sc_blkno = 0;
+ }
+ sc->sc_flags &= ~TZF_SEENEOF;
+ break;
+ case SCSI_LOAD_UNLOAD:
+ case SCSI_REWIND:
+ sc->sc_fileno = 0;
+ sc->sc_blkno = 0;
Home |
Main Index |
Thread Index |
Old Index