diff -ru --exclude=CVS ./net/bpf.c /usr/apv/sys/net/bpf.c
--- ./net/bpf.c	Wed Apr  4 01:18:04 2001
+++ /usr/apv/sys/net/bpf.c	Tue Aug  7 19:24:02 2001
@@ -1,10 +1,13 @@
-/*	$OpenBSD: bpf.c,v 1.25 2001/04/04 02:39:17 jason Exp $	*/
+/*	$OpenBSD: bpf.c,v 1.26 2001/05/16 12:53:34 ho Exp $	*/
 /*	$NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $	*/
 
 /*
  * Copyright (c) 1990, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
+ * This software has been derived at the University of Michigan
+ * from software originally created as described below.
+ *
  * This code is derived from the Stanford/CMU enet packet filter,
  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 
@@ -23,10 +26,12 @@
  *	This product includes software developed by the University of
  *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
+ *    nor the name of the University of Michigan
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * AND BY THE UNIVERSITY OF MICHIGAN ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
@@ -56,6 +61,9 @@
 #include <sys/vnode.h>
 
 #include <sys/file.h>
+#if defined(CITI_PACKET_VAULT)
+#include <sys/filedesc.h>
+#endif
 #include <sys/tty.h>
 #include <sys/uio.h>
 
@@ -75,7 +83,11 @@
 
 #define BPF_BUFSIZE 8192	/* 4096 too small for FDDI frames */
 
+#if defined(CITI_PACKET_VAULT)
+#define PRINET  4			/* non interruptible, high priority */
+#else
 #define PRINET  6			/* interruptible */
+#endif
 
 /*
  * The default read buffer size is patchable.
@@ -169,8 +181,6 @@
 		return (EIO);
 
 	MGETHDR(m, M_WAIT, MT_DATA);
-	if (m == 0)
-		return (ENOBUFS);
 	m->m_pkthdr.rcvif = 0;
 	m->m_pkthdr.len = len - hlen;
 
@@ -329,6 +339,12 @@
 	d->bd_bufsize = bpf_bufsize;
 	d->bd_sig = SIGIO;
 
+#if defined(CITI_PACKET_VAULT)
+	/* clear other fields.. */
+	d->bd_fd = 0;
+	d->bd_file = 0;
+#endif
+
 	return (0);
 }
 
@@ -361,12 +377,35 @@
  * into the hold slot, and the free buffer into the store slot.
  * Zero the length of the new store buffer.
  */
+#if defined(CITI_PACKET_VAULT)
+	/*
+	 * When we are writing to a file,
+	 * make sure we align the end of the blocks...
+	 *
+	 * (Normal code doesn't align the end of a
+	 * buffer when it is about to rotate the
+	 * buffers.  Since we are writing buffers to
+	 * a file, we want to align the end of the
+	 * present buffer so that the next buffer
+	 * we start writing will be aligned.)
+	 */
+#define ROTATE_BUFFERS(d) \
+	if ((d)->bd_file) { \
+	    (d)->bd_slen = BPF_WORDALIGN((d)->bd_slen); \
+	} \
+	(d)->bd_hbuf = (d)->bd_sbuf; \
+	(d)->bd_hlen = (d)->bd_slen; \
+	(d)->bd_sbuf = (d)->bd_fbuf; \
+	(d)->bd_slen = 0; \
+	(d)->bd_fbuf = 0;
+#else
 #define ROTATE_BUFFERS(d) \
 	(d)->bd_hbuf = (d)->bd_sbuf; \
 	(d)->bd_hlen = (d)->bd_slen; \
 	(d)->bd_sbuf = (d)->bd_fbuf; \
 	(d)->bd_slen = 0; \
 	(d)->bd_fbuf = 0;
+#endif
 /*
  *  bpfread - read next chunk of packets from buffers
  */
@@ -457,6 +496,35 @@
 	 */
 	splx(s);
 
+#if defined(CITI_PACKET_VAULT)
+	/*
+	 * Instead of moving the data to user space to be written to a file,
+	 * just write it to the file!  (If a file has been specified.)
+	 */
+	if (d->bd_file) {
+	    /* build an uid to pass to the fd... */
+	    struct file * fp = d->bd_file;
+	    struct uio auio;
+	    struct iovec aiov;
+
+	    aiov.iov_base = d->bd_hbuf;
+	    aiov.iov_len = d->bd_hlen;
+	    auio.uio_iov = &aiov;
+	    auio.uio_iovcnt = 1;
+	    auio.uio_resid = d->bd_hlen;
+	    auio.uio_rw = UIO_WRITE;
+	    auio.uio_segflg = UIO_SYSSPACE;
+	    auio.uio_procp = d->bd_procFd;
+	    error = (*fp->f_ops->fo_write)(fp, &fp->f_offset, &auio, fp->f_cred);
+	    if (error) {
+		printf( "%s[%d]: write error %d ", __FILE__, __LINE__, error );
+	    } else {
+		/* adjust uio_resid by number of bytes actually written */
+		uio->uio_resid -= d->bd_hlen;
+		uio->uio_offset += d->bd_hlen;
+	    }
+	} else {
+#endif
 	/*
 	 * Move data from hold buffer into user space.
 	 * We know the entire buffer is transferred since
@@ -464,6 +532,10 @@
 	 */
 	error = uiomove(d->bd_hbuf, d->bd_hlen, uio);
 
+#if defined(CITI_PACKET_VAULT)
+	}
+#endif
+
 	s = splimp();
 	d->bd_fbuf = d->bd_hbuf;
 	d->bd_hbuf = 0;
@@ -546,6 +618,11 @@
 	d->bd_hlen = 0;
 	d->bd_rcount = 0;
 	d->bd_dcount = 0;
+#if defined(CITI_PACKET_VAULT)
+	d->bd_rbcount = 0;
+	d->bd_rbscount = 0;
+	d->bd_dbcount = 0;
+#endif
 }
 
 /*
@@ -562,6 +639,11 @@
  *  BIOCGSTATS		Get packet stats.
  *  BIOCIMMEDIATE	Set immediate mode.
  *  BIOCVERSION		Get filter language version.
+#if defined(CITI_PACKET_VAULT)
+ *  BIOCSTFD		Set target fd
+ *  BIOCGTFD		Get target fd
+ *  BIOCGSTATS2		Get packet and byte stats.
+#endif
  */
 /* ARGSUSED */
 int
@@ -723,6 +805,23 @@
 			break;
 		}
 
+#if defined(CITI_PACKET_VAULT)
+	/*
+	 * Get packet stats.
+	 */
+	case BIOCGSTATS2:
+		{
+			struct bpf_stat2 *bs2 = (struct bpf_stat2 *)addr;
+
+			bs2->bs_recv = d->bd_rcount;
+			bs2->bs_drop = d->bd_dcount;
+			bs2->bs_brecv = d->bd_rbcount;
+			bs2->bs_bsrecv = d->bd_rbscount;
+			bs2->bs_bdrop = d->bd_dbcount;
+			break;
+		}
+#endif
+
 	/*
 	 * Set immediate mode.
 	 */
@@ -784,6 +883,49 @@
 	case BIOCGRSIG:
 		*(u_int *)addr = d->bd_sig;
 		break;
+#if defined(CITI_PACKET_VAULT)
+	/*
+	 * We want to be able to attach a file to collect the junk
+	 * associated with the stream. By doing it here in the driver,
+	 * we can make some better guarantees about collecting one
+	 * and only one copy of every packet...
+	 */
+	case BIOCSTFD:  /* set */
+		{
+		int fd = *(int *)addr;
+		register struct filedesc *fdp = p->p_fd;
+		struct file * fp;
+
+		if (fd == -1)	/* well, we've got to have some way to turn it off */
+		{
+#if 0
+			printf( "%s[%d]: turned off\n", __FILE__, __LINE__ );
+#endif
+			d->bd_file = 0;
+			d->bd_fd = -1;
+			d->bd_procFd = 0;
+		} else {
+			if (fd >= fdp->fd_nfiles ||
+				(fp = fdp->fd_ofiles[fd]) == NULL ||
+				(fp->f_flag & FREAD) == 0) {
+				return (EBADF);
+			} else {
+#if 0
+				printf( "%s[%d]: turned on\n", __FILE__, __LINE__ );
+#endif
+				d->bd_fd = fd;
+				d->bd_file = fp;
+				d->bd_procFd = p;
+			}
+		}
+		break;
+		}
+
+	case BIOCGTFD:  /* get */
+		*(int *)addr = d->bd_fd;
+		break;
+#endif	/* CITI_PACKET_VAULT */
+
 	}
 	return (error);
 }
@@ -991,6 +1133,10 @@
 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
 		++d->bd_rcount;
 		slen = bpf_filter(d->bd_filter, pkt, pktlen, pktlen);
+#if defined(CITI_PACKET_VAULT)
+		d->bd_rbcount += pktlen;
+		d->bd_rbscount += (slen == (u_int)-1) ? pktlen : slen;
+#endif
 		if (slen != 0)
 			bpf_catchpacket(d, pkt, pktlen, slen, bcopy);
 	}
@@ -1046,6 +1192,10 @@
 	for (d = bp->bif_dlist; d != 0; d = d->bd_next) {
 		++d->bd_rcount;
 		slen = bpf_filter(d->bd_filter, (u_char *)m, pktlen, 0);
+#if defined(CITI_PACKET_VAULT)
+		d->bd_rbcount += pktlen;
+		d->bd_rbscount += (slen == (u_int)-1) ? pktlen : slen;
+#endif
 		if (slen != 0)
 			bpf_catchpacket(d, (u_char *)m, pktlen, slen, bpf_mcopy);
 	}
@@ -1095,6 +1245,9 @@
 			 * so drop the packet.
 			 */
 			++d->bd_dcount;
+#if defined(CITI_PACKET_VAULT)
+			d->bd_dbcount += pktlen;
+#endif
 			return;
 		}
 		ROTATE_BUFFERS(d);
@@ -1145,14 +1298,7 @@
 	register struct bpf_d *d;
 {
 	d->bd_fbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
-	if (d->bd_fbuf == 0)
-		return (ENOBUFS);
-
 	d->bd_sbuf = (caddr_t)malloc(d->bd_bufsize, M_DEVBUF, M_WAITOK);
-	if (d->bd_sbuf == 0) {
-		free(d->bd_fbuf, M_DEVBUF);
-		return (ENOBUFS);
-	}
 	d->bd_slen = 0;
 	d->bd_hlen = 0;
 	return (0);
diff -ru --exclude=CVS ./net/bpf.h /usr/apv/sys/net/bpf.h
--- ./net/bpf.h	Sun Jun 18 23:00:54 2000
+++ /usr/apv/sys/net/bpf.h	Tue Aug  7 19:24:02 2001
@@ -5,6 +5,9 @@
  * Copyright (c) 1990, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
+ * This software has been derived at the University of Michigan
+ * from software originally created as described below.
+ *
  * This code is derived from the Stanford/CMU enet packet filter,
  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
@@ -23,10 +26,12 @@
  *	This product includes software developed by the University of
  *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
+ *    nor the name of the University of Michigan
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * AND BY THE UNIVERSITY OF MICHIGAN ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
@@ -76,6 +81,19 @@
 	u_int bs_drop;		/* number of packets dropped */
 };
 
+/* #if defined(CITI_PACKET_VAULT) */
+/*
+ * Struct returned by BIOCGSTATS2.
+ */
+struct bpf_stat2 {
+	u_int bs_recv;		/* number of packets received */
+	u_int bs_drop;		/* number of packets dropped */
+	u_int64_t bs_brecv;	/* number of bytes received */
+	u_int64_t bs_bsrecv;	/* number of bytes snapped */
+	u_int64_t bs_bdrop;	/* number of bytes dropped */
+};
+/* #endif */
+
 /*
  * Struct return by BIOCVERSION.  This represents the version number of 
  * the filter language described by the instruction encodings below.
@@ -113,6 +131,11 @@
 #define BIOCVERSION	_IOR('B',113, struct bpf_version)
 #define BIOCSRSIG	_IOW('B',114, u_int)
 #define BIOCGRSIG	_IOR('B',115, u_int)
+/* #if defined(CITI_PACKET_VAULT) */
+#define BIOCSTFD        _IOW('B',116, u_int)
+#define BIOCGTFD        _IOR('B',116, u_int)
+#define BIOCGSTATS2	_IOR('B',117, struct bpf_stat2)
+/* #endif */
 
 /*
  * Structure prepended to each packet.
diff -ru --exclude=CVS ./net/bpfdesc.h /usr/apv/sys/net/bpfdesc.h
--- ./net/bpfdesc.h	Sun Jun 18 23:00:54 2000
+++ /usr/apv/sys/net/bpfdesc.h	Tue Aug  7 19:24:02 2001
@@ -5,6 +5,9 @@
  * Copyright (c) 1990, 1991, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
+ * This software has been derived at the University of Michigan
+ * from software originally created as described below.
+ *
  * This code is derived from the Stanford/CMU enet packet filter,
  * (net/enet.c) distributed as part of 4.3BSD, and code contributed
  * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
@@ -23,10 +26,12 @@
  *	This product includes software developed by the University of
  *	California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
+ *    nor the name of the University of Michigan
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS
+ * AND BY THE UNIVERSITY OF MICHIGAN ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
@@ -71,7 +76,11 @@
 	struct bpf_insn *bd_filter; 	/* filter code */
 	u_long		bd_rcount;	/* number of packets received */
 	u_long		bd_dcount;	/* number of packets dropped */
-
+/* #if defined(CITI_PACKET_VAULT) */
+	u_int64_t	bd_rbcount;	/* number of bytes received */
+	u_int64_t	bd_rbscount;	/* number of bytes snapped */
+	u_int64_t	bd_dbcount;	/* number of bytes dropped */
+/* #endif */
 	u_char		bd_promisc;	/* true if listening promiscuously */
 	u_char		bd_state;	/* idle, waiting, or timed out */
 	u_char		bd_immediate;	/* true to return on packet arrival */
@@ -82,6 +91,11 @@
 	uid_t		bd_sigeuid;	/* euid for process that set pgid */
 	u_char		bd_pad;		/* explicit alignment */
 	struct selinfo	bd_sel;		/* bsd select info */
+/* #if defined(CITI_PACKET_VAULT) */
+	int		bd_fd;		/* just to have to return... */
+	struct file *	bd_file;	/* output file (when attached via ioctl) */
+	struct proc *	bd_procFd;	/* proc which owns the fd */
+/* #endif */
 };
 
 /*
diff -ru --exclude=CVS ./scsi/ch.c /usr/apv/sys/scsi/ch.c
--- ./scsi/ch.c	Tue Apr  3 16:45:10 2001
+++ /usr/apv/sys/scsi/ch.c	Tue Aug  7 19:24:02 2001
@@ -5,6 +5,9 @@
  * Copyright (c) 1996, 1997 Jason R. Thorpe <thorpej@and.com>
  * All rights reserved.
  *
+ * This software has been derived at the University of Michigan
+ * from software originally created by Jason R. Thorpe as described below.
+ *
  * Partially based on an autochanger driver written by Stefan Grefen
  * and on an autochanger driver written by the Systems Programming Group
  * at the University of Utah Computer Science Department.
@@ -21,10 +24,12 @@
  *    must display the following acknowledgements:
  *	This product includes software developed by Jason R. Thorpe
  *	for And Communications, http://www.and.com/
- * 4. The name of the author may not be used to endorse or promote products
+ * 4. The name of the author and/or the University of Michigan
+ *    may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND BY THE UNIVERSITY OF MICHIGAN
+ * ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
@@ -556,18 +561,29 @@
 		printf("%s: warning, READ ELEMENT STATUS avail != count\n",
 		    sc->sc_dev.dv_xname);
 
+#ifdef CITI_PACKET_VAULT
+	user_data = (u_int8_t *)malloc(avail+(52*avail), M_DEVBUF, M_WAITOK);
+#else
 	user_data = (u_int8_t *)malloc(avail, M_DEVBUF, M_WAITOK);
+#endif /* CITI_PACKET_VAULT */
 
 	desc = (struct read_element_status_descriptor *)((u_long)data +
 	    sizeof(struct read_element_status_header) +
 	    sizeof(struct read_element_status_page_header));
 	for (i = 0; i < avail; ++i) {
 		user_data[i] = desc->flags1;
+#ifdef CITI_PACKET_VAULT
+		bcopy((char *)desc, user_data+avail+52*i, 52);
+#endif /* CITI_PACKET_VAULT */
 		(u_long)desc += desclen;
 	}
 
 	/* Copy flags array out to userspace. */
+#ifdef CITI_PACKET_VAULT
+	error = copyout(user_data, uptr, avail+(52*avail));
+#else
 	error = copyout(user_data, uptr, avail);
+#endif /* CITI_PACKET_VAULT */
 
  done:
 	if (data != NULL)
@@ -591,6 +607,9 @@
 	 */
 	bzero(&cmd, sizeof(cmd));
 	cmd.opcode = READ_ELEMENT_STATUS;
+#ifdef CITI_PACKET_VAULT
+	cmd.byte2 |= READ_ELEMENT_STATUS_VOLTAG;
+#endif /* CITI_PACKET_VAULT */
 	_lto2b(first, cmd.sea);
 	_lto2b(count, cmd.count);
 	_lto3b(datalen, cmd.len);
diff -ru --exclude=CVS ./scsi/scsiconf.c /usr/apv/sys/scsi/scsiconf.c
--- ./scsi/scsiconf.c	Sun Jan 28 20:49:21 2001
+++ /usr/apv/sys/scsi/scsiconf.c	Tue Aug  7 19:24:02 2001
@@ -4,6 +4,9 @@
 /*
  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
  *
+ * This software has been derived at the University of Michigan
+ * from software originally created by Charles Hannum as described below.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -15,10 +18,12 @@
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *	This product includes software developed by Charles Hannum.
- * 4. The name of the author may not be used to endorse or promote products
+ * 4. The name of the author and/or the University of Michigan
+ *    may not be used to endorse or promote products
  *    derived from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND BY THE UNIVERSITY OF MICHIGAN
+ * ``AS IS'' AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
@@ -765,12 +770,39 @@
 #endif /* SCSI_2_DEF */
 
 	/* Now go ask the device all about itself. */
+#ifdef CITI_PACKET_VAULT
+/*
+ * We get all zeroes in response to the first inquiry of a Qualstar TLS-8211
+ * changer, but we get valid data in response to a second inquiry.  This
+ * hack seems to work without interfering with devices that work correctly.
+ */
+#define	SCSI_RETRIES	3	/* how many times to try */
+#define	SCSI_CHK_BYTES	8	/* how many bytes to check */
+{
+	int i, lim = 0;
+
+	bzero(&inqbuf, sizeof(inqbuf));
+	do {
+		unsigned char *p = (char *)&inqbuf;
+
+		if (lim > 0)
+			delay(1000000);
+		if (scsi_inquire(sc_link, &inqbuf, scsi_autoconf) != 0)
+			goto bad;
+		for (i = 0; i < SCSI_CHK_BYTES; i++)
+			if (*p++ != 0)
+				break;
+	} while (i >= SCSI_CHK_BYTES && lim++ < SCSI_RETRIES);
+}
+#else /* CITI_PACKET_VAULT */
 	bzero(&inqbuf, sizeof(inqbuf));
 	if (scsi_inquire(sc_link, &inqbuf, scsi_autoconf) != 0)
 		goto bad;
+#endif /* CITI_PACKET_VAULT */
 
 	{
 		int len = inqbuf.additional_length;
+
 		while (len < 3)
 			inqbuf.unused[len++] = '\0';
 		while (len < 3 + 28)
