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