#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  COPYRIGHT MANIFEST README patchlevel.h Makefile scsiinfo.1
#   scsiinfo.c utils.c utils.h uscsi.h uscsi.c sundev sundev/dmaga.h
#   sunos4.h sunos4.c sunos5.h sunos5.c common.h common.c format.c
#   format.h esp.c isp.c ispvar.h param.h
# Wrapped by jdd@coke on Tue Mar 28 13:53:18 1995
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'COPYRIGHT' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'COPYRIGHT'\"
else
echo shar: Extracting \"'COPYRIGHT'\" \(917 characters\)
sed "s/^X//" >'COPYRIGHT' <<'END_OF_FILE'
X/*
X * Copyright University of Toronto 1993, 1994.
X * Written by John DiMarco 
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. The author and the University of Toronto are not responsible 
X *    for the consequences of use of this software, no matter how awful, 
X *    even if they arise from flaws in it.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Since few users ever read sources,
X *    credits must appear in the documentation.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.  Since few users
X *    ever read sources, credits must appear in the documentation.
X *
X * 4. This notice may not be removed or altered.
X */
END_OF_FILE
if test 917 -ne `wc -c <'COPYRIGHT'`; then
    echo shar: \"'COPYRIGHT'\" unpacked with wrong size!
fi
# end of 'COPYRIGHT'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(801 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
XCOPYRIGHT		Copyright notice
XMANIFEST		This file
XMakefile		makefile
XREADME			Read this file first
Xpatchlevel.h		Patch level/version 
Xscsiinfo.1		scsiinfo manual page
Xscsiinfo.c		scsiinfo main source
Xsunos4.h		SunOS 4.1.x dependent header
Xsunos4.c		SunOS 4.1.x dependent code
Xsunos5.h		SunOS 5.x dependent header
Xsunos5.c		SunOS 5.x dependent code
Xcommon.h		Machine-independent header
Xcommon.c		Machine-independent code
Xesp.c			ESP support
Xisp.c			ISP support
Xispvar.h		ISP header support for Solaris 2.N, where N<4
Xparam.h			Parameters header
Xuscsi.c			User SCSI routines
Xuscsi.h			header file for uscsi.c
Xutils.c			misc utilities
Xutils.h			header file for utils.c
Xsundev/dmaga.h		Empty file to fool cpp
Xformat.c		Format informat 
Xformat.h		header file for format.c
Xisp.h			header file for isp support
END_OF_FILE
if test 801 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(5122 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XNovember 11, 1994  Release 4.0
X
XNew in release 4.0:
X        o ISP support for Solaris 2.x, thanks to 
X		calum.mackay@mrc-bsu.cam.ac.uk (Calum Mackay)
X	o Code restructuring to support multiple host adapter types.
X	o Support for loadable SCSI drivers, thanks to
X		mml@pupcyc2.Princeton.EDU (Michael Lowry)
X        o Miscellaneous minor enhancements and bugfixes.
X
XSCSIINFO displays information about SCSI devices attached to a given system,
Xas seen by Sun's scsi device driver. For each target known to the SCSI host
Xadapter, scsinfo reports whether it is synchronous or asynchronous, whether
Xor not the tranfers to/from the target are clean or susceptible to noise, and
Xwhether or not the target can disconnect and reconnect. When a target
Xsupports synchronous transfer, the negotiated maximum transfer rate (in
XMB/sec) is reported.
X
XAs of version 4.0, scsiinfo supports both the ESP and ISP host adapters.
X
XAs of version 3.0, scsiinfo supports querying SCSI disks attached to ESP host
Xadapters for geometry and formatting information, and optionally generates a
Xformat.dat entry based on these values.
X
XAs of version 2.0, scsiinfo supports querying SCSI devices attached to ESP
Xhost adapters for vendor, product, and revision information, in the style of
Xthe OpenBoot prom's probe-scsi and probe-scsi-all commands.
X
XSCSI Notes: 
X
XThe negotiated maxiumum synchronous transfer rate will normally be the lesser
Xof the maximum rate supported by the adapter and the maximum rate supported
Xby the device, but it can be lower than this under various circumstances.
XThis rate is typically negotiated at reboot (SunOS 4.1 and 4.1.1 report it
Xfor each synchronous device), but it can also be renegotiated during
Xoperation if necessary.
X
XSCSIINFO notes:
X        - "-s" option is most useful for SunOS 4.1.2 and above, since in
X          these versions of the OS, the SCSI driver no longer reports the
X          transfer rates it negotiates with synchronous SCSI devices on boot.
X	  Try adding scsiinfo -s to /etc/rc.boot.
X        - Does nothing on suns without ESP or ISP host adapters or without 
X          openboot prom support. 
X        - Supports multiple ESP or ISP host adapters
X        - Scsiinfo needs to be recompiled on any (even minor) OS releases.
X          For example, a 4.1.1 binary will not work on 4.1.2 or 4.1.3.
X        - Scsiinfo can only probe a SCSI device when the following conditions
X          are met:
X                - the device's device-driver supports user-mode SCSI commands.  
X                - scsiinfo can find the device's character special file. 
X                - the character special file is readable. 
X                - nothing holds an exclusive open on the special file. 
X          Sun's 4.x tape driver doesn't support user-mode SCSI commands. Sun's
X          disk drivers do. Sun's 4.x CD-ROM driver only does when there is
X          valid media in the drive. In Solaris 2.2 or greater, /usr/sbin/vold,
X          if it is running, may hold an exclusive open on the CD-ROM device, 
X          preventing a probe from succeeding. If scsiinfo cannot probe a drive,
X          it returns a message saying why the probe may have failed. 
X	- The format.dat entries generated by SCSIINFO are certainly not
X	  perfect. Firstly, SCSIINFO just guesses at the bpt figure (bpt =
X          bits per track), because there's no standard way of querying the
X	  drive for this figure. Secondly, some drives may be overly
X	  optimistic in their estimation of the number of blocks available;
X	  if a format.dat entry runs into problems, try reducing ncyl until
X	  it works. Finally, many drives simply don't return an rpm figure
X	  (it wasn't required in the SCSI-1 standard); if this is the case,
X	  SCSIINFO will report an error and make a guess of 3600rpm, which
X	  may not be correct.
X
XInstallation:
X        1. Edit the Makefile.
X        2. Compile. 
X        3. scsiinfo needs to be able to read the kernel namelist and core
X           image (eg. /dev/kmem). For use by users without read permissions 
X           on /dev/kmem, it can be made setgid kmem or setgid sys. 
X           "make install" will install it setgid kmem.
X        4. If SCSI probing (scsiinfo -p) or drive format querying (scsiinfo
X           -f or -F) is to work for a given device, scsiinfo will need to 
X	   be able to access the device via a raw/character device file in
X	   /dev (or /devices/... in Solaris 2.x). In Solaris 2.3 and later,
X	   scsiinfo must be run by root (or made setuid root) if probing or 
X           format querying is desired. 
X
XPorting notes:
X          - The drivers tend to change sometimes between releases;
X            the code is written to be as portable as possible, but future
X            (greater than 5.4) versions of SunOS 5.x may break something. 
X
XComments, bug reports, fixes, enhancements, etc. are welcome.
X
XJohn 
X--
XJohn DiMarco <jdd@cdf.toronto.edu>                        Office: EA201B
XComputing Disciplines Facility Systems Manager            Phone: 416-978-1928
XUniversity of Toronto                                     Fax:   416-978-1931
Xhttp://www.cdf.toronto.edu/personal/jdd/jdd.html
END_OF_FILE
if test 5122 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(109 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
Xstatic char patchlevel[] = "scsiinfo Version 4.0beta $Id: patchlevel.h,v 3.6 1995/03/28 18:43:40 jdd Exp $";
END_OF_FILE
if test 109 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(2391 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC = cc # or gcc, if you prefer
XINCLUDEDIRS = -I. 
X
X#
X# Remove -lelf for SunOS 4.x
X#
XLIBRARIES = -lkvm -lelf
X
X#
X# Hard-code SUNOS_VERSION if you're using a non-sun make (eg. gnu make). For 
X# example, SUNOS_VERSION = 4.1.3
X#
XSUNOS_VERSION:sh = /usr/bin/uname -r
X
X#
X# DRVR_SPECIFIC_WKAROUNDS adds some smarts to scsiinfo to recognize
X# the presence of certain 3rd party drivers requiring special handling. 
X# Leave this in unless you experience problems.
X#
X# Remove ISP if you have trouble compiling scsiinfo on early (<2.3) versions
X# of Solaris 2.x. 
X
XDEFS = -DISP -DESP -DDRVR_SPECIFIC_WKAROUNDS -DSUNOS_VERSION=\"$(SUNOS_VERSION)\" 
X
XCFLAGS = $(DEFS) -g -v $(INCLUDEDIRS)
XLDFLAGS = 
XLINTFLAGS = $(DEFS) -ha $(INCLUDEDIRS) 
XSRCS = scsiinfo.c utils.c uscsi.c format.c common.c esp.c isp.c sunos5.c sunos4.c
XOBJS = $(SRCS:.c=.o)
XRM = /bin/rm -rf
X
X#
X# Use /usr/bin/install for SunOS 4.x
X#
XINSTALL = /usr/ucb/install 
X
XETCDIR = /local/etc
XMANDIR = /local/man/man1
X
X#
X# Set MODE to 4755, if you want this to run setuid root. 
X# -p/-f/-F may not work otherwise. By default, scsiinfo is set to run setgid
X# sys (or kmem for SunOS 4.x), which allows only root to use -p/-f/-F, but 
X# everything else to work for other users. 
X#
XMODE = 2755
XOWNER = root 
XGROUP = sys # kmem for SunOS 4.x
X
X#
X# End of user-configurable options
X#
X
Xall:: scsiinfo
X
Xscsiinfo: $(OBJS) 
X	$(RM) $@
X	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBRARIES)
Xlint:
X	lint $(LINTFLAGS) $(SRCS)
Xlintport:
X	lint -p $(LINTFLAGS) $(SRCS)
Xclean:
X	rm -f $(OBJS) scsiinfo
Xdepend:
X	makedepend -- $(CFLAGS) -- $(SRCS)
X
Xinstall: scsiinfo
X	$(INSTALL) -m $(MODE) -o $(OWNER) -g $(GROUP) scsiinfo $(ETCDIR) 
X
Xinstall.man: scsiinfo.1
X	$(INSTALL) -m 644 scsiinfo.1 $(MANDIR)
X
Xshar:
X	shar COPYRIGHT MANIFEST README patchlevel.h Makefile scsiinfo.1 \
X	scsiinfo.c utils.c utils.h uscsi.h uscsi.c sundev sundev/dmaga.h \
X	sunos4.h sunos4.c sunos5.h sunos5.c common.h common.c \
X	format.c format.h esp.c isp.c ispvar.h param.h >scsiinfo.shar
X
X# DO NOT DELETE THIS LINE -- make depend depends on it.
Xcommon.o: patchlevel.h utils.h uscsi.h format.h common.h
Xesp.o: patchlevel.h uscsi.h format.h utils.h common.h param.h
Xformat.o: utils.h uscsi.h
Xisp.o: ispvar.h patchlevel.h uscsi.h format.h utils.h param.h common.h
Xscsiinfo.o: patchlevel.h uscsi.h format.h utils.h param.h
Xsunos4.o: sunos4.h common.h utils.h common.h utils.h
Xuscsi.o: utils.h
Xutils.o: utils.h
END_OF_FILE
if test 2391 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'scsiinfo.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scsiinfo.1'\"
else
echo shar: Extracting \"'scsiinfo.1'\" \(6059 characters\)
sed "s/^X//" >'scsiinfo.1' <<'END_OF_FILE'
X.TH scsiinfo 1 "Nov 12, 1993"
X.SH scsiinfo
Xscsiinfo \- obtain information about scsi devices attached to a Sun system 
X.SH SYNOPSIS
X.B scsiinfo
X[
X.B \-Vcopqs
X]
X.if n .ti +0.9i
X[
X.B -f\ raw_disk_device
X]
X[
X.B -F\ raw_disk_device
X]
X.if n .ti +0.9i
X[
X.B -K\ kernel_namelist
X] [
X.B -C\ core_image
X]
X.SH DESCRIPTION
X.B scsiinfo
Xdisplays information about SCSI devices attached to a given system, as seen
Xby the Sun ESP and ISP device drivers. For each target known to the SCSI host
Xadapter,
X.B scsinfo
Xreports whether it is synchronous or asynchronous, whether or not the
Xtranfers to/from the target are clean or susceptible to noise, and whether or
Xnot the target can disconnect and reconnect. For ISP devices, it indicates
Xwhether or not the target supports tagged queueing and/or wide SCSI
Xtransfers. When a target supports synchronous transfer, the negotiated
Xmaximum transfer rate (in MB/sec) is reported. Furthermore,
X.B scsiinfo
Xcan query SCSI devices for vendor, product, and revision information.
XFinally,
X.B scsiinfo
Xcan query a SCSI disk for format and geometry information, and generate a
Xsuitable format.dat entry for it.
X.SH OPTIONS
X.IP \fB\-c\fP
XIn addition, provide type and speed (clock rate) information about the ESP and
XISP controllers on the machine. 
X.IP \fB\-V\fP
XPrint out 
X.B scsiinfo
Xversion information and exit.
X.IP \fB\-s\fP
XReport "Target now Synchronous" messages for all synchronous devices in
Xthe style of the SunOS 4.1 and 4.1.1 kernels at bootup. 
X.IP \fB\-p\fP
XProbe SCSI devices, report their type, whether or not they are removable or
Xnon-removable, and report the device's vendor, product, and revision data.
XThis option provides much the same information as the Openboot prom's 
X"probe-scsi-all" command. This option may require special privileges, depending
Xon how 
X.B scsiinfo
Xis installed, and may not work for all devices.
X.IP \fB\-q\fP
XQuiet mode. Do not display transfer information for the specified devices.
XUseful in shell scripts when only the return status is desired. 
X.IP \fB\-f\ raw_disk_device\ \fP
XReport disk format and geometry information. The raw disk device to be queried
X(eg /dev/rsd0c or /dev/rdsk/c0t0d0s2) must be specified.
X.IP \fB\-F\ raw_disk_device\ \fP
XQuery the specified raw disk device for format and geometry information, and 
Xconstruct a format.dat entry for it. 
X.IP \fB\-o\fP
XWhen querying a drive for format settings (using \fB\-f\fP or \fB\-F\fP), 
Xreport the original manufacturer's defined settings, instead of the settings
Xcurrently in effect. This is useful if the drive is not formatted correctly
Xor at all. 
X.IP \fB\-K\ kernel_namelist\ \fP
XUse the specified kernel namelist instead of the running kernel.
X.IP \fB\-C\ core_image\ \fP
XUse the specified kernel core image instead of the current contents of
Xphysical memory (eg. /dev/mem).
X.SH SEE ALSO
XSunOS 4.x: devinfo(8S), SunOS 5.x: prtconf(1M)
X.SH DIAGNOSTICS
XThe return status of 
X.B scsiinfo
Xindicates the number of ESP devices detected whose connections have been 
Xdetermined by the kernel to be noisy. Because the ISP driver does not keep 
Xtrack of this information, noisy ISP devices will not be reflected in this
Xresult. 
X.B scsiinfo
Xreturns -1 (255) if unable to read the kernel or if run on an unsupported
Xarchitecture. 
X.SH HISTORY
XWritten by John DiMarco <jdd@cdf.toronto.edu> at the University of Toronto.
XISP support under Solaris 2.x was added by Calum Mackay 
X<calum.mackay@mrc-bsu.cam.ac.uk>. Support for loadable SCSI device drivers 
Xunder SunOS 4.x was added by Michael Lowry <mml@pupcyc2.Princeton.EDU>.
X.SH LIMITATIONS
XOnly machines with Sun ESP and/or ISP SCSI host adapters and Openboot proms 
Xare supported. These include sun4c, sun4d, and sun4m machines. 
X.PP
XBecause the Sun ISP driver does not keep track of whether or not a specific 
Xdevice is noisy,
X.B scsiinfo
Xwill report 
X.B Unknown 
Xin that field for ISP devices. 
X.PP
XSCSI devices that do not have loaded drivers or which have drivers that
Xdo not support Sun's user SCSI interface, cannot be probed by scsiinfo -p.
XIn particular, CD-ROM devices using the Sun 4.x driver apparently cannot be 
Xprobed unless a CD is loaded. Furthermore, if some process is exclusively
Xholding open a device, 
X.B scsiinfo
Xwill not be able to probe it. This is often the case with the CD-ROM under 
XSolaris 2.x, when the Volume Manager is running.
X.PP
XSince the user-mode SCSI interface requires read access to a raw character 
Xdevice, probing and format/geometry querying will only work if the user running 
X.B scsiinfo
Xcan read the appropriate device file, or if 
X.B scsiinfo
Xis installed setgid or setuid to a group or user that has the appropriate
Xprivileges. If
X.B scsiinfo 
Xcannot probe a device, it will report what it believes to be the reason.
X.PP
XOptions other than
X.B -o
Xhave no effect when 
X.B -f
Xor 
X.B -F 
Xis specified. 
X.B -o
Xhas no effect if
X.B -f
Xor
X.B -F 
Xis not specified.
X.PP
XWhen generating a format.dat entry, 
X.B scsiinfo
Xjust makes an educated guess for the bpt (bits per track) figure, since it 
Xisn't possible to query the drive for this.
X.PP
XWhen queried for format and geometry information, some disks drives do
Xnot report a value for rpm (rotations per minute), as the SCSI-1 standard did 
Xnot require it.
X.B scsiinfo
Xwill use 3600 in this case, or if the reported value is obviously wrong. 
XFurthermore, some disk drives may be overly optimistic when reporting 
Xphysical capacity, which causes 
X.B scsiinfo
Xto generate an format.dat entry for the drive that causes format to report
Xerrors when labelling. If this occurs, decrease the value of ncyl until
Xthe problem goes away.
X.PP
XUnder Solaris 2.x, if a Central Data SCSITerminal Server is attached to a
Xparticular SCSI controller, device transfer rates and noise information will 
Xbe unavailable for any device on that controller. The Central Data driver 
Xappears to clobber the data structures that 
X.B scsiinfo
Xobtains this information from.
X.PP
XAs far as 
X.B scsiinfo
Xis concerned, 1 MB = 1000 KB, and 1GB = 1000000 KB. This is the industry 
Xconvention for reporting disk sizes. 
END_OF_FILE
if test 6059 -ne `wc -c <'scsiinfo.1'`; then
    echo shar: \"'scsiinfo.1'\" unpacked with wrong size!
fi
# end of 'scsiinfo.1'
fi
if test -f 'scsiinfo.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'scsiinfo.c'\"
else
echo shar: Extracting \"'scsiinfo.c'\" \(3961 characters\)
sed "s/^X//" >'scsiinfo.c' <<'END_OF_FILE'
X/*
X * scsiinfo.c  -  determine SCSI info. 
X *                ESP and ISP SCSI host adapters are supported.
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X * 
X * ISP support by: Calum Mackay, University of Cambridge, BSU
X *                 calum.mackay@mrc-bsu.cam.ac.uk
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: scsiinfo.c,v 3.10 1995/03/28 18:44:17 jdd Exp $";
X#endif
X
X#include "patchlevel.h"
X#include "uscsi.h"
X#include "format.h"
X#include <stdio.h>
X
X#ifdef FILENAME_MAX     /* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X#include <sys/param.h>
X#include <values.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <nlist.h>
X#include <kvm.h>
X#include <fcntl.h>
X#include <sys/utsname.h>
X#include "utils.h"
X#include "param.h"
X
X/* os-independent globals */
Xchar *progname;
Xint d;
Xint parameter = 0; /* for param.h */
Xkvm_t *kd; /* kernel file descriptor */
X
X/* include OS-dependent stuff */
X#define GLOBALS /* ensure os-dependent globals are defined */
X#ifdef SYSV
X#include <sunos5.h>
X#else 
X#include <sunos4.h>
X#endif
X
X#ifdef ESP
Xextern int process_esp();
X#endif /* ESP */
X
X#ifdef ISP
Xextern int process_isp();
X#endif /* ISP */
X
Xstatic int noisycount=0; /* number of noisy devices */
Xstatic int formatinfo=0; /* Report format info */
Xstatic int formatdat=0;  /* Generate format.dat */
X
Xstatic void usage()
X{
X	fprintf(stderr, "\
XUsage: %s [-V][-o][-f diskdev][-F diskdev]\n\
X       [-c][-s][-p][-q][-K kernelimage][-C coreimage]\n\
X", 
X			progname);
X	exit(-1);
X}
X
Xint main(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	int c;
X	int errflg = 0;
X	extern char *optarg;
X	struct utsname un;
X	char *diskdevice;
X	char *kernelimage=NULL, *coreimage=NULL;
X
X	progname = argv[0];
X	while ((c = getopt(argc, argv, "Vodcspqf:F:K:C:")) != EOF)
X		switch (c) {
X		case 'V':
X			printf("%s\n", patchlevel);
X			printf("Compiled for: SunOS %s,", SUNOS_VERSION);
X#ifdef ESP
X			printf(" ESP");
X#endif /* ESP */
X#ifdef ISP
X			printf(", ISP");
X#endif /* ISP */
X			printf(", FORMAT");
X			printf("\n");
X			exit(0);
X			break;
X		case 'd':
X			++d;
X			break;
X		case 'c': 
X			/* output controller information */
X			set_param(P_CONTROLLER);
X			break;
X		case 's':
X			/* Use SunOS4.x boot-style "now Synchronous" format */
X			set_param(P_SUNOS4STYLE);
X			break;
X		case 'p':
X			/* probe probe-able devices */
X			set_param(P_PROBE);
X			break;
X		case 'q':
X			/* quiet mode */
X			set_param(P_QUIET);
X			break;
X		case 'o':
X			/* use manufacturer's original settings for fmt info */
X			set_param(P_ORIGINAL);
X			break;
X		case 'f': 
X			/* output format info */
X			formatinfo++;
X			diskdevice=optarg;
X			break;
X		case 'F':
X			/* output format.dat */
X			formatinfo++;
X			formatdat++;
X			diskdevice=optarg;
X			break;
X		case 'K': 
X			/* kernel image */
X			kernelimage=optarg;
X			break;
X		case 'C': 
X			/* core image */
X			coreimage=optarg;
X			break;
X		default:
X			/* parameter error */
X			errflg++;
X			break;
X		}
X	if (errflg) {
X		usage();
X	}
X
X	/* get OS version and machinetype */
X	(void)uname(&un);
X
X
X	/* generate format information if specified */
X	if(formatinfo){
X		format(formatdat, un.release, diskdevice, 
X				param_is_set(P_ORIGINAL));
X		exit(0);
X	} 
X
X	/* quit if we have an OS or kernel architecture mismatch */
X	if(!STREQ(SUNOS_VERSION, un.release)){
X		Error(
X		  "Version mismatch: compiled for SunOS %s, this is SunOS %s.",
X		      SUNOS_VERSION, un.release);
X	}
X	if((0!=strncmp(un.machine,"sun4",4)) || strlen(un.machine)<(u_int)5){
X		Error( "%s kernel architecture not supported.", un.machine);
X	}
X
X	/* open the kernel */
X        if(NULL==(kd=kvm_open(kernelimage,coreimage,NULL,O_RDONLY,progname))){
X		Error("Cannot read kernel, giving up.");
X        }
X        if(0!=kvm_nlist(kd, nl)){
X                Error("Cannot read a required kernel symbol.");
X        }
X
X	/* Now process the defined controllers */
X#ifdef ESP
X	noisycount += process_esp();
X#endif /* ESP */
X
X#ifdef ISP
X	noisycount += process_isp();
X#endif /* ISP */
X	return(0);
X}
END_OF_FILE
if test 3961 -ne `wc -c <'scsiinfo.c'`; then
    echo shar: \"'scsiinfo.c'\" unpacked with wrong size!
fi
# end of 'scsiinfo.c'
fi
if test -f 'utils.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utils.c'\"
else
echo shar: Extracting \"'utils.c'\" \(3963 characters\)
sed "s/^X//" >'utils.c' <<'END_OF_FILE'
X/*
X * utils.c: miscellaneous utilities
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: utils.c,v 1.6 1995/03/28 18:46:39 jdd Exp $";
X#endif
X
X#include <stdio.h>
X#include <stdlib.h>
X#ifdef FILENAME_MAX
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X#include <varargs.h>
X#include "utils.h"
X
X#ifdef lint
X#undef va_arg
X#define va_arg(x,y) (y)NULL
X#endif
X
Xextern char *progname;
Xextern int d;
X
X/*
X * Error(): behaves like fprintf(stderr, ...) followed by exit(-1), except
X *          that the 'programname: ' preceeds the print, and a newline
X *	    follows it.
X */
X/*VARARGS*/
Xvoid Error(va_alist)
Xva_dcl
X{
X	va_list args;
X	char *format;
X
X	va_start(args);
X	format = va_arg(args, char *);
X	fprintf(stderr, "%s: ", progname);
X	vfprintf(stderr, format, args);
X	fprintf(stderr, "\n");
X	va_end(args);
X	exit(-1);
X}
X
X/*
X * dfprintf(): behaves like fprintf, except the first argument must be a
X *            debugging level. The message will only be printed if "d"
X *            is equal to or greater than the debugging level.
X */
X/*VARARGS*/
Xvoid dfprintf(va_alist)
Xva_dcl
X{
X	va_list args;
X	int debugLevel;
X	FILE *stream;
X	char *format;
X	
X	va_start(args);
X	debugLevel = va_arg(args, int);
X	stream = va_arg(args, FILE *);
X	format = va_arg(args, char *);
X	if(d >= debugLevel){
X		vfprintf(stream, format, args);
X	}
X	va_end(args);
X}
X	
X/*
X * Warning(): behaves like Error, except returns rather than exits.
X */
X/*VARARGS*/
Xvoid Warning(va_alist)
Xva_dcl
X{
X	va_list args;
X	char *format;
X
X	va_start(args);
X	format = va_arg(args, char *);
X    fprintf(stderr, "%s: ", progname);
X    vfprintf(stderr, format, args);
X    fprintf(stderr, "\n");
X    va_end(args);
X}
X
XFILE *efopen(file, mode)
Xchar *file, *mode;
X{
X	FILE *fp;
X	if (NULL!=(fp=fopen(file,mode)))
X		return(fp);
X	Error("can't open file \"%s\" mode \"%s\"", file, mode);
X	/*NOTREACHED*/
X}
X
Xvoid efclose(f)
XFILE *f;
X{
X	if(EOF==fclose(f))
X		Error("can't close file");
X	/*NOTREACHED*/
X}
X
X/*
X * mylib_malloc(): Checks if it gets a NULL pointer, calls Error if so.
X */
Xchar *mylib_malloc(size, file, line)
Xunsigned size;
Xchar *file;
Xint line;
X{
X	char *result;
X
X	result = malloc(size);
X	if(NULL==result){
X		Error("Out of memory at line %d in \"%s\".", line, file);
X	}
X	return(result);
X}
X
X/*
X * mylib_realloc(): Checks if it gets a NULL pointer, calls Error if so.
X */
Xchar *mylib_realloc(ptr, size, file, line)
Xchar *ptr, *file;
Xunsigned size;
Xint line;
X{
X	char *result;
X
X	result = realloc(ptr, size);
X	if(NULL==result){
X		Error("Out of memory at line %d in \"%s\".", line, file);
X	}
X	return(result);
X}
X
X/*
X * mylib_scopy(): Takes a string and creates a new physical copy of it.
X */
Xchar *mylib_scopy(string, file, line)
Xchar *string, *file;
Xint line;
X{
X	char *result;
X
X	result = malloc((unsigned)strlen(string)+1);
X
X	if(NULL==result){
X		Error("Out of memory at line %d in \"%s\".", line, file);
X	}
X	(void)strcpy(result, string);
X	return(result);
X}
X
X/*
X * mylib_srcopy(): Reallocs first string to make room for second, copies it.
X */
Xchar *mylib_srcopy(s1, s2, file, line)
Xchar *s1, *s2, *file;
Xint line;
X{
X	s1=mylib_realloc(s1, (unsigned)strlen(s2)+1, file, line);
X	(void)strcpy(s1, s2);
X	return(s1);
X}
X
X/*
X * cat(): Take a list of strings, followed by NULL, return their concatenation
X *        in malloc'ed space.
X */
X/*VARARGS*/
Xchar *cat(va_alist)
Xva_dcl
X{
X	va_list args;
X	unsigned length=1;
X	char *str, *newstr;
X
X	/* get length */
X	va_start(args);
X	loop{
X		str = va_arg(args, char *);
X		if(NULL!=str){
X			 length+=strlen(str);
X		} else {
X			break;
X		}
X	}
X	va_end(args);
X
X	newstr=malloc(length);
X	if(NULL==newstr) Error("Out of memory in cat()");
X	
X	newstr[0]=(char)0;
X
X	/* create string */
X	va_start(args);
X	loop{
X		str = va_arg(args, char *);
X		if(NULL!=str) {
X			(void)strcat(newstr, str);
X		} else {
X			break;
X		}
X	}
X va_end(args);
X#ifdef lint
X	args=args; /* make lint shut up about "args set but not used" */
X#endif
X	return(newstr);
X}
END_OF_FILE
if test 3963 -ne `wc -c <'utils.c'`; then
    echo shar: \"'utils.c'\" unpacked with wrong size!
fi
# end of 'utils.c'
fi
if test -f 'utils.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utils.h'\"
else
echo shar: Extracting \"'utils.h'\" \(1816 characters\)
sed "s/^X//" >'utils.h' <<'END_OF_FILE'
X/*
X * utils.h: header file for utils.c, various useful macros
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: utils.h,v 1.3 1994/08/17 19:02:35 jdd Exp $
X */
X
X/* new - mallocs any sized type */
X#ifndef lint
X#define new(t) (t *)mylib_malloc(sizeof(t),__FILE__,__LINE__)
X#else
X#define new(t) (t *)NULL
X#endif
X
X/* mem - mallocs a given number of bytes */
X#define mem(l) mylib_malloc((unsigned)l,__FILE__,__LINE__)
X
X/* rmem - reallocs a given number of bytes */
X#define rmem(c,l) mylib_realloc(c,(unsigned)l,__FILE__,__LINE__)
X
X/* s - returns a copy of a given string */
X#define s(c) mylib_scopy(c,__FILE__,__LINE__)
X
X/* rs - returns a copy of the second string in place of the first string, 
X        using realloc */
X#define rs(c,d) mylib_srcopy(c,strlen(d),__FILE__,__LINE__)
X
X/* assert - error message if statement is false */
X#ifdef DEBUG
X#define assert(c) if(!(c))(void)fprintf(stderr,"%s: %d: Assert false\n",__FILE__,__LINE__)
X#else
X#define assert(c) 0
X#endif
X
X/* STREQ - indicate whether two strings are equal */
X#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
X
X#define loop for(;;)
X#define NUL(x) (x)NULL
X#ifndef TRUE
X#define TRUE 1 
X#endif
X#ifndef FALSE
X#define FALSE 0 
X#endif
X#define YES 1
X#define NO 0
X
X/* Error - print like fprintf(stderr, ...) and die. Progname included at
X	   beginning of message, newline at end. */
Xextern void Error();
X/* Warning - like error, without dying */
Xextern void Warning();
X
Xextern char *mylib_malloc();   
Xextern char *mylib_realloc();
Xextern char *mylib_scopy();
Xextern char *mylib_srcopy();
Xextern char *cat();
Xextern char *getstr();
Xextern FILE *efopen();
Xextern void efclose();
Xextern void dfprintf();
X
Xextern char *progname; /* application's name. Used by Error, Warning. */
Xextern int d; /* debug level */
END_OF_FILE
if test 1816 -ne `wc -c <'utils.h'`; then
    echo shar: \"'utils.h'\" unpacked with wrong size!
fi
# end of 'utils.h'
fi
if test -f 'uscsi.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uscsi.h'\"
else
echo shar: Extracting \"'uscsi.h'\" \(322 characters\)
sed "s/^X//" >'uscsi.h' <<'END_OF_FILE'
X/*
X * uscsi.h - header file for uscsi.c
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X * 
X * $Id: uscsi.h,v 3.1 1994/08/17 19:02:35 jdd Exp $
X */
X
X/* Exported Procedures */
X
Xextern int scsi_probe();
Xextern int scsi_inquiry();
Xextern int scsi_modeinfo();
Xextern int scsi_capacity();
END_OF_FILE
if test 322 -ne `wc -c <'uscsi.h'`; then
    echo shar: \"'uscsi.h'\" unpacked with wrong size!
fi
# end of 'uscsi.h'
fi
if test -f 'uscsi.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'uscsi.c'\"
else
echo shar: Extracting \"'uscsi.c'\" \(6372 characters\)
sed "s/^X//" >'uscsi.c' <<'END_OF_FILE'
X/*
X * uscsi.c - User SCSI routines for querying devices.
X *
X * Author: John DiMarco,
X *         University of Toronto, Computing Disciplines Facility
X *         jdd@cdf.toronto.edu
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: uscsi.c,v 3.10 1995/03/28 18:45:50 jdd Exp $";
X#endif
X
X#include <stdio.h>
X#ifdef FILENAME_MAX     /* defined in stdio.h only in SYSV systems */
X#define SYSV
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
X#include <sys/param.h>
X#include <values.h>
X#include <sys/types.h>
X#include <unistd.h>
X#include <fcntl.h>
X#include "utils.h"
X
Xextern int d;
X
X#ifdef SYSV
X
X#include <stdlib.h>
X#include <sys/scsi/generic/mode.h>
X#include <sys/scsi/generic/commands.h>
X#include <sys/scsi/impl/types.h>
X#include <sys/scsi/impl/uscsi.h>
X#include <sys/systeminfo.h>
X#define gethostname(b, l) sysinfo(SI_HOSTNAME, b, (long)l)
X#define bzero(b,l) memset(b,0,l)
X
X#else /* SYSV */
X
X#include <scsi/impl/types.h>
X#include <scsi/impl/uscsi.h>
X
X#endif /* SYSV */
X
X#define SCSIBUFLEN 8000
X
Xstatic char *scsi_dtype(dtype)
Xu_char dtype;
X{
X	switch(dtype){
X	case DTYPE_DIRECT: 	return("Disk");
X	case DTYPE_SEQUENTIAL: 	return("Tape");
X	case DTYPE_PRINTER: 	return("Printer");
X	case DTYPE_PROCESSOR: 	return("Processor");
X	case DTYPE_WORM:	return("WORM");
X	case DTYPE_RODIRECT:	return("Disk(RO)");
X	case DTYPE_SCANNER:	return("Scanner");
X	case DTYPE_OPTICAL:	return("Optical");
X	case DTYPE_CHANGER:	return("Changer");
X	case DTYPE_COMM:	return("Comm");
X	default:		return("Unknown");
X	}
X}
X
Xint scsi_probe(devname, lun)
Xchar *devname;
Xint lun;
X{
X	int dfd;
X	struct uscsi_cmd cmd;
X	union scsi_cdb cdb;
X	struct scsi_inquiry *inq;
X	char buff[SCSIBUFLEN]; 
X
X	if(-1==(dfd=open(devname, O_RDONLY|O_NDELAY))) return(-1);
X
X	inq = (struct scsi_inquiry *)buff;
X	
X	/* set up SCSI inquiry command */
X	bzero(&cdb, sizeof(cdb));
X	bzero(inq, sizeof(inq));
X	cdb.scc_cmd = SCMD_INQUIRY;
X	cdb.scc_lun = lun;
X 	cdb.g0_count0 = 200;
X	cmd.uscsi_cdb=(caddr_t)&cdb;
X	cmd.uscsi_cdblen=6; /* SCSI Group 0 cmd */
X	cmd.uscsi_bufaddr=(caddr_t)inq;
X	cmd.uscsi_buflen=SCSIBUFLEN;
X	cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_SILENT|USCSI_ISOLATE|USCSI_READ;
X
X	if(-1==ioctl(dfd, USCSICMD, &cmd)) { (void)close(dfd); return(-1); }
X	(void)close(dfd);
X
X	printf("%s ", inq->inq_rmb?"Removable":"Non-removable");
X	printf("%s:\t", scsi_dtype(inq->inq_dtype));
X	printf("%-8.8s %-16.16s %-4.4s", inq->inq_vid, inq->inq_pid, 
X		inq->inq_revision);
X	return(0);
X}
X
Xint scsi_inquiry(fd, devicetype, vendor, product)
Xint fd, *devicetype;
Xchar *vendor, *product;
X{
X        struct uscsi_cmd cmd;
X        union scsi_cdb cdb;
X        struct scsi_inquiry *inq;
X        char buff[SCSIBUFLEN];
X
X        inq = (struct scsi_inquiry *)buff;
X
X        /* set up SCSI inquiry command */
X        bzero(&cdb, sizeof(cdb));
X        bzero(inq, sizeof(inq));
X        cdb.scc_cmd = SCMD_INQUIRY;
X        cdb.g0_count0 = 200;
X        cmd.uscsi_cdb=(caddr_t)&cdb;
X        cmd.uscsi_cdblen=6; /* SCSI Group 0 cmd */
X        cmd.uscsi_bufaddr=(caddr_t)inq;
X        cmd.uscsi_buflen=SCSIBUFLEN;
X        cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_SILENT|USCSI_ISOLATE|USCSI_READ;
X
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X
X	*devicetype=inq->inq_dtype;
X	strncpy(vendor, inq->inq_vid, 8);
X	strncpy(product, inq->inq_pid, 16);
X	return(0);
X}
X
Xint scsi_capacity(fd, capacity)
Xint fd, *capacity;
X{
X        struct uscsi_cmd cmd;
X        union scsi_cdb cdb;
X        struct scsi_read_capacity {
X		int sectors;
X		int sector_size;
X		char junk[2];
X	} *inq;
X        char buff[SCSIBUFLEN];
X
X        inq = (struct scsi_read_capacity *)buff;
X
X        /* set up SCSI read_capacity command */
X        bzero(&cdb, sizeof(cdb));
X        bzero(inq, sizeof(inq));
X        cdb.scc_cmd = SCMD_READ_CAPACITY;
X        cmd.uscsi_cdb=(caddr_t)&cdb;
X        cmd.uscsi_cdblen=10;  /* SCSI Group 1 cmd */
X        cmd.uscsi_bufaddr=(caddr_t)inq;
X        cmd.uscsi_buflen=SCSIBUFLEN;
X        cmd.uscsi_flags=USCSI_READ;
X
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X
X	*capacity=1+inq->sectors;
X	return(0);
X}
X
X/* 
X * Note carefully: 
X * scsi_modeinfo assumes the open device is a direct access device, and it
X * doesn't bother checking before going ahead.
X * 
X * Also, scsi_modeinfo won't set rpm if the drive doesn't return the
X * information (eg. SCSI-1 drives). 
X */
X
Xint scsi_modeinfo(fd, original, nsect, sector_size, pcyl, nhead, rpm, 
X			trks_zone, asect, atrks)
Xint fd, original;
Xint *nsect, *sector_size, *pcyl, *nhead, *rpm, *trks_zone, *asect, *atrks;
X{
X        struct uscsi_cmd cmd;
X        union scsi_cdb cdb;
X        struct mode_format mfmt;
X	struct mode_geometry mgeom;
X        char buff[SCSIBUFLEN];
X	char *buffp;
X
X        bzero(&cdb, sizeof(cdb));
X        bzero(&mfmt, sizeof(mfmt));
X	cdb.scc_cmd = SCMD_MODE_SENSE;
X	/* cdb.g0_addr1 = MODEPAGE_ALLPAGES | (0x80 * original); */
X	cdb.g0_count0 = 255;
X	cmd.uscsi_cdb=(caddr_t)&cdb;
X	cmd.uscsi_cdblen=6; /* SCSI Group 0 cmd */
X	cmd.uscsi_bufaddr=(caddr_t)buff;
X	cmd.uscsi_buflen=SCSIBUFLEN;
X	cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_ISOLATE|USCSI_READ;
X	
X	/* grab the format page */
X	cdb.g0_addr1 = DAD_MODE_FORMAT | (0x80 * original);
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X	buffp = MODE_PAGE_ADDR((struct mode_header *)buff, char);
X	memset((char *)&mfmt, 0, sizeof(mfmt));
X	memcpy((char *)&mfmt, buffp, sizeof(struct mode_page));
X	memcpy((char *)&mfmt, buffp, mfmt.mode_page.length);
X
X	*trks_zone = (int)mfmt.tracks_per_zone;
X	*asect = (int)mfmt.alt_sect_zone;
X	*nsect = (int)mfmt.sect_track;
X	*atrks = (int)mfmt.alt_tracks_vol;
X	*sector_size = (int)mfmt.data_bytes_sect;
X
X	/* now grab the geometry page */
X	cdb.g0_addr1 = DAD_MODE_GEOMETRY | (0x80 * original);
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X	buffp = MODE_PAGE_ADDR((struct mode_header *)buff, char);
X	memset((char *)&mgeom, 0, sizeof(mgeom));
X	memcpy((char *)&mgeom, buffp, sizeof(struct mode_page));
X	memcpy((char *)&mgeom, buffp, mgeom.mode_page.length);
X
X	*pcyl = (int)(mgeom.cyl_ub<<16) + (int)(mgeom.cyl_mb<<8) + 
X		(int)mgeom.cyl_lb;
X	*nhead = (int)mgeom.heads;
X
X	/* 
X	 * SCSI-1 devices don't report rpm, which was tacked onto
X	 * the end of the mode_geometry structure in SCSI-2, so only 
X	 * set rpm if enough data was returned to ensure the
X	 * geometry structure was filled at least that far.
X	 */
X	if(mgeom.mode_page.length > (((u_int)&mgeom.rpm)-((u_int)&mgeom))){
X		*rpm = (int)mgeom.rpm;
X	}
X
X	return(0);
X}
END_OF_FILE
if test 6372 -ne `wc -c <'uscsi.c'`; then
    echo shar: \"'uscsi.c'\" unpacked with wrong size!
fi
# end of 'uscsi.c'
fi
if test ! -d 'sundev' ; then
    echo shar: Creating directory \"'sundev'\"
    mkdir 'sundev'
fi
if test -f 'sundev/dmaga.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sundev/dmaga.h'\"
else
echo shar: Extracting \"'sundev/dmaga.h'\" \(0 characters\)
sed "s/^X//" >'sundev/dmaga.h' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'sundev/dmaga.h'`; then
    echo shar: \"'sundev/dmaga.h'\" unpacked with wrong size!
fi
# end of 'sundev/dmaga.h'
fi
if test -f 'sunos4.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunos4.h'\"
else
echo shar: Extracting \"'sunos4.h'\" \(1703 characters\)
sed "s/^X//" >'sunos4.h' <<'END_OF_FILE'
X/*
X * sunos4.h: SunOS 4.1.x dependent code. 
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * modified by Michael Lowry, Princeton University, Physics
X *         mml@pupcyc2.princeton.edu
X *    to use the scsi_device list to obtain target and lun values
X * 
X * $Id: sunos4.h,v 1.7 1995/03/28 18:45:18 jdd Exp $
X */
X
X#define _mon_openprom_h /* SunOS 4.1.2 silliness */
X
Xextern struct dev_info devi;
X
X/* make sure these match up with the def'n of nl in sunos4.c */
X#define N_NESP 0
X#define N_ESP_SOFTC 1
X#define N_SD_ROOT 2
Xextern struct nlist nl[]; 
X
X#ifndef NPHASE
X#define OLD_SUNOS /* SunOS 4.1.1 or earlier */
X#undef CNUM
X#define CNUM (esp_p-esp_softc)
X#endif
X
X#include <sun/openprom.h>
X#define ddi_get_unit(a) ((struct dev_info *)a)->devi_unit
X#define ddi_get_name(a) ((struct dev_info *)a)->devi_name
X#define ddi_get_child(a) ((struct dev_info *)a)->devi_slaves
X#define ddi_get_parent(a) ((struct dev_info *)a)->devi_parent
X#define ddi_get_next_sibling(a) ((struct dev_info *)a)->devi_next
X#define DDI_CF2(a) (NULL != ((struct dev_info *)a)->devi_driver)
Xtypedef struct dev_info *dev_info_t;
X
X
X/*
X * device name is DEV_PREFIX<device>DEV_INFIX<addr>DEV_SUFFIX,
X * disk device name is DEV_PREFIX<device>DEV_INFIX<addr>DISK_SUFFIX,
X * 
X * For SunOS4: r<device><addr> or r<device><addr>c for disk
X */
X#define DEV_PREFIX "r"
X#define DEV_INFIX ""
X#define DEV_SUFFIX ""
X#define DISK_SUFFIX "c"
X#define TAPE_PREFIX "nr"
X#define TAPE_SUFFIX ""
X
Xextern void init_scsitarget();
Xextern int get_scsiaddr();
Xextern char *get_addr();
Xextern char *get_devicepath();
X#ifdef ESP
Xextern u_int get_nesp();
X#endif /* ESP */
X#ifdef ISP
Xextern u_int get_iesp();
X#endif /* ISP */
END_OF_FILE
if test 1703 -ne `wc -c <'sunos4.h'`; then
    echo shar: \"'sunos4.h'\" unpacked with wrong size!
fi
# end of 'sunos4.h'
fi
if test -f 'sunos4.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunos4.c'\"
else
echo shar: Extracting \"'sunos4.c'\" \(3041 characters\)
sed "s/^X//" >'sunos4.c' <<'END_OF_FILE'
X#include <stdio.h>
X#ifdef FILENAME_MAX     /* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X#ifndef SYSV
X/*
X * sunos4.c: SunOS 4.1.x dependent code. 
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * with modifications by Michael Lowry, Princeton University, Physics
X *         mml@pupcyc2.princeton.edu
X *    to use the scsi_device list to obtain target and lun values
X * 
X * $Id: sunos4.c,v 1.1 1995/03/28 18:44:40 jdd Exp $
X */
X
X#include <nlist.h>
X#include <scsi/impl/types.h>
X#include "sunos4.h"
X#include "common.h"
X#include "utils.h"
X
Xstruct nlist nl[]={
X        { "_nesp" },
X        { "_esp_softc" },
X        { "_sd_root" },
X        { "" },
X};
X
Xstruct dev_info devi; /* device info from kernel, used in OS-dependent files */
X
Xstatic struct target_lookup {
X	struct scsi_conf *sc;
X	struct target_lookup *next;
X} *sctable = NUL(struct target_lookup *);
X
X#ifdef ESP
X/* Get number of ESP controllers */
Xu_int get_nesp(){
X	u_int  nesp;
X        if(-1==kvm(nl[N_NESP].n_value, nesp)) {
X                Error("kvm_read: nesp");
X        }
X	return(nesp);
X}
X#endif /* ESP */
X
X#ifdef ISP
X/* Get number of ISP controllers */
Xu_int get_nisp(){
X	return(0); /* ISP controllers not supported under SunOS 4.x */
X}
X#endif /* ISP */
X
X/* Get path to specified controller. Returned string is malloc'ed */
Xchar *get_devicepath(j)
Xint j;
X{
X	return(s("/dev"));
X}
X
X/* Get address of specified device. Note: returned in static storage */
Xchar *get_addr(di)
Xstruct dev_info *di;
X{
X	static char buff[20];
X	sprintf(buff, "%d", ddi_get_unit(di));
X	return(buff);
X}
X
Xvoid init_scsitarget(){
X	/* Grab scsi_conf table */
X/* Actually construct a psuedo one from the scsi_device linked list */
X
X	struct scsi_conf *sctmp; 
X	struct target_lookup *tltmp;
X	struct scsi_device sdtmp;
X	struct dev_info ditmp;
X	u_long tableaddr, sd_ptr;
X
X	tableaddr=(u_long)nl[N_SD_ROOT].n_value;
X	if(-1==kvm(tableaddr, sd_ptr)){
X		Error("get kvm: sd_root\n");
X	}
X	while (sd_ptr) {
X		sctmp=new(struct scsi_conf);
X		/* get trgt & lun from scsi_device structure */
X		if(-1==kvm(sd_ptr, sdtmp)){
X			Error("get kvm: scsi_device\n");
X		}
X                sctmp->target= (char)sdtmp.sd_address.a_target;
X                sctmp->lun   = (char)sdtmp.sd_address.a_lun;
X
X		/* get unit & name from associated dev_info structure */
X		if(-1==kvm(sdtmp.sd_dev, ditmp)){
X			Error("get kvm: scsi_dev_info\n");
X		}
X		sctmp->dunit = (char)ditmp.devi_unit;
X		sctmp->tname = s(kvmstr(ditmp.devi_name));
X
X		/* add new entry to lookup table */
X		tltmp = new(struct target_lookup);
X		tltmp->next = sctable;
X		tltmp->sc = sctmp;
X		sctable=tltmp;
X
X		sd_ptr  = (u_long)sdtmp.sd_next;
X	}
X}
X
Xint get_scsiaddr(name, di, target, lun)
Xchar *name;
Xstruct dev_info *di;
Xint *target, *lun;
X{
X	int unit;
X	struct target_lookup *i;
X
X	unit=ddi_get_unit(di);
X	for(i=sctable; NULL!=i; i=i->next){
X		if((unit==(int)i->sc->dunit) &&
X		   STREQ(name, i->sc->tname)){
X			*target = (int)i->sc->target;
X			*lun = (int)i->sc->lun;
X			return(0);
X		}
X	}
X	return(-1);
X}
X#endif /* !SYSV */
END_OF_FILE
if test 3041 -ne `wc -c <'sunos4.c'`; then
    echo shar: \"'sunos4.c'\" unpacked with wrong size!
fi
# end of 'sunos4.c'
fi
if test -f 'sunos5.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunos5.h'\"
else
echo shar: Extracting \"'sunos5.h'\" \(1813 characters\)
sed "s/^X//" >'sunos5.h' <<'END_OF_FILE'
X/*
X * sunos5.h: SunOS 5.x dependent code. 
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: sunos5.h,v 1.9 1995/03/28 18:45:35 jdd Exp $
X */
X
X#ifdef DRVR_SPECIFIC_WKAROUNDS
X#ifndef CENTRAL_DATA_CT
X#define CENTRAL_DATA_CT "ct"
X#endif /* ndef CENTRAL_DATA_CT */
X#endif /* DRVR_SPECIFIC_WKAROUNDS */
X
X#include <stdlib.h>
X#include <unistd.h>
X#include <string.h>
X#include <errno.h>
X#include <sys/ddi.h>
X#include <sys/sunddi.h>
X#include <sys/ddi_impldefs.h>
X#include <sys/scsi/conf/device.h>
X#define _KERNEL
X#include <sys/scsi/impl/transport.h>
X#undef  _KERNEL
X#include "common.h"
X
Xextern struct dev_info devi;
X
X/* make sure these match up with the def'n of nl in sunos5.c */
X#define N_ESP_SOFTC 0
X#define N_ISP_HEAD 1
Xextern struct nlist nl[];
X
X#define ddi_get_instance(a) ((struct dev_info *)a)->devi_instance
X#define ddi_get_name(a) ((struct dev_info *)a)->devi_name
X#define ddi_get_addr(a) ((struct dev_info *)a)->devi_addr
X#define ddi_get_child(a) ((struct dev_info *)a)->devi_child
X#define ddi_get_parent(a) ((struct dev_info *)a)->devi_parent
X#define ddi_get_next_sibling(a) ((struct dev_info *)a)->devi_sibling
X#define ddi_get_driver_private(a) ((struct dev_info *)a)->devi_driver_data
X
X/*
X * device name is DEV_PREFIX<device>DEV_INFIX<addr>DEV_SUFFIX,
X * disk device name is DEV_PREFIX<device>DEV_INFIX<addr>DISK_SUFFIX,
X * 
X * For SunOS5: <device>@<addr>: or <device>@<addr>:c,raw for disk
X */
X#define DEV_PREFIX ""
X#define DEV_INFIX "@"
X#define DEV_SUFFIX ":"
X#define DISK_SUFFIX ":c,raw"
X#define TAPE_PREFIX ""
X#define TAPE_SUFFIX ":lbn"
X
Xextern void init_scsitarget();
Xextern int get_scsiaddr();
Xextern char *get_addr();
Xextern char *get_devicepath();
X#ifdef ESP
Xextern u_int get_nesp();
X#endif /* ESP */
X#ifdef ISP
Xextern u_int get_iesp();
X#endif /* ISP */
END_OF_FILE
if test 1813 -ne `wc -c <'sunos5.h'`; then
    echo shar: \"'sunos5.h'\" unpacked with wrong size!
fi
# end of 'sunos5.h'
fi
if test -f 'sunos5.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sunos5.c'\"
else
echo shar: Extracting \"'sunos5.c'\" \(2843 characters\)
sed "s/^X//" >'sunos5.c' <<'END_OF_FILE'
X#include <stdio.h>
X#ifdef FILENAME_MAX     /* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X#ifdef SYSV
X/*
X * sunos5.c: SunOS 5.x dependent code. 
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: sunos5.c,v 1.1 1995/03/28 18:44:46 jdd Exp $
X */
X
X#include <sunos5.h>
X#include "common.h"
X#include "utils.h"
X
Xstruct nlist nl[]={
X        { "esp_softc" },
X	{ "isp_head" },
X        { "" },
X};
X
Xstruct dev_info devi; /* device info from kernel, used in OS-dependent files */
X
X#ifdef ESP 
X/* Get number of ESP controllers */
Xu_int get_nesp(){
X        return((u_int)255);
X}
X#endif /* ESP */
X
X#ifdef ISP 
X/* Get number of ISP controllers */
Xu_int get_nisp(){
X        return((u_int)255);
X}
X#endif /* ISP */
X
X
X
X/* 
X * Get path to specified controller device. Returned string is malloc'ed.
X * assumption: global variable devi points to controller device info.
X */
Xchar *get_devicepath(j)
Xunsigned int j;
X{
X	char *devicepath, *cp;
X
X	/* Grab the name */
X	devicepath=s(kvmstr((u_long)ddi_get_name(&devi)));
X	/* ... and the address */
X	cp=cat(devicepath, "@", kvmstr((u_long)ddi_get_addr(&devi)), NULL);
X	free(devicepath);
X	devicepath=cp;
X	/*
X	 * At this point, devicepath should be eg. esp@addr,addr. Now
X	 * trace backwards up the devinfo tree until we get to the
X	 * root. At each branch, record the name and address in
X	 * devicepath as in "...device@addr,addr/device@addr,addr/..."
X	 */
X	{
X		/* construct path */
X		struct dev_info di, *parent;
X		char *name;
X
X		for(parent=ddi_get_parent(&devi);
X		    NULL!=parent;
X		    parent=ddi_get_parent(&di)){
X			/* grab the parent */
X			if(-1==kvm((u_long)parent, di)){
X				Error("kvm read: #%d parent %s", j,
X					devicepath);
X			}
X			/* get its name */
X			name=kvmstr((u_long)ddi_get_name(&di));
X
X			/* get the address, add both to devicepath */
X			if(DDI_CF1(&di)){
X				char *pathcomp, *newpath;
X
X				pathcomp=cat(name, "@", NULL);
X				name=kvmstr((u_long)ddi_get_addr(&di));
X				if(!*name){
X					free(pathcomp);
X				} else {
X					newpath = cat(pathcomp,
X							name,
X							"/",
X							devicepath,
X							NULL);
X					free(devicepath);
X					free(pathcomp);
X					devicepath=newpath;
X				}
X			}
X		}
X	}
X	/* almost done. just add "/devices/" to head of devicepath */
X	cp=cat("/devices/", devicepath, NULL);
X	free(devicepath);
X	devicepath=cp;
X
X	return(devicepath);
X}
X
X/* Get address of specified device. Note: returned in static storage */
Xchar *get_addr(di)
Xstruct dev_info *di;
X{
X	return(kvmstr((u_long)ddi_get_addr(di)));
X}
X
Xvoid init_scsitarget(){}
X
Xint get_scsiaddr(name, di, target, lun)
Xchar *name;
Xstruct dev_info *di;
Xint *target, *lun;
X{
X	struct scsi_device sd;
X
X	if(-1==kvm((u_long)ddi_get_driver_private(di), sd)){
X		return(-1);
X	}
X	*target = (int)sd.sd_address.a_target;
X	*lun = (int)sd.sd_address.a_lun;
X	return(0);
X}
X#endif /* SYSV */
END_OF_FILE
if test 2843 -ne `wc -c <'sunos5.c'`; then
    echo shar: \"'sunos5.c'\" unpacked with wrong size!
fi
# end of 'sunos5.c'
fi
if test -f 'common.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'common.h'\"
else
echo shar: Extracting \"'common.h'\" \(563 characters\)
sed "s/^X//" >'common.h' <<'END_OF_FILE'
X/*
X * common.h - header file for common.c
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: common.h,v 1.1 1995/03/28 18:40:13 jdd Exp $
X */
X
X/* note: assumes kernel pointer is kd */
X
X#include <kvm.h>
X
Xextern kvm_t *kd;
X
X#define kvm(a,b) kvm_read(kd,(u_long)a,(char *)&b,sizeof(b))
X
X#define SUNDISK "sd"
X#define SUNTAPE "st"
X
X/* SCSI width definitions */
X#define NARROW 8
X#define WIDE 16
X
X/* Exported Procedures */
X
Xextern char *kvmstr();
Xvoid boot_synch_message();
Xvoid do_scsi_probe();
Xchar *compute_devicename();
END_OF_FILE
if test 563 -ne `wc -c <'common.h'`; then
    echo shar: \"'common.h'\" unpacked with wrong size!
fi
# end of 'common.h'
fi
if test -f 'common.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'common.c'\"
else
echo shar: Extracting \"'common.c'\" \(3318 characters\)
sed "s/^X//" >'common.c' <<'END_OF_FILE'
X/*
X * common.c  -  General routines common to all controllers. 
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X * 
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: common.c,v 1.1 1995/03/28 18:39:50 jdd Exp $";
X#endif
X
X#include "patchlevel.h"
X
X#include <stdio.h>
X#include <sys/param.h>
X#include <values.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <nlist.h>
X#include <fcntl.h>
X#include <sys/utsname.h>
X#include <errno.h>
X#include "utils.h"
X#include "uscsi.h"
X#include "format.h"
X#include "common.h"
X
X#define BUFFSIZE 255
X
X#ifdef FILENAME_MAX     /* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X/* include OS-dependent stuff */
X#ifdef SYSV
X#include <sunos5.h>
X#else
X#include <sunos4.h>
X#endif
X
Xchar *kvmstr(address)
Xu_long address;
X{
X	static char buff[BUFFSIZE];
X
X	if(-1==kvm_read(kd, address, buff, sizeof(buff))){
X		Error("kvmstr");
X	}
X	buff[BUFFSIZE-1]='\0'; /* just in case it's not null-terminated */
X	return(buff);
X}
X	
Xvoid boot_synch_message(ctlr_type, ctlr_num, i, speed, width)
Xchar *ctlr_type;	/* type of controller */
Xint ctlr_num;  	 	/* controller number */
Xint width;     	 	/* scsi transfer width in bits */ 
Xint i;  		/* target index */
Xunsigned int speed;	/* target speed */
X{
X	switch(speed) {
X		case ((u_int)-1) :
X			printf(
X	  "%s%d:\tTarget %d now Synchronous at unknown max transmit rate\n",
X			ctlr_type, ctlr_num, i);
X			break;
X		case 0 :
X			break;
X		default :
X			printf(
X	  "%s%d:\tTarget %d now Synchronous at %d.%d mb/s max transmit rate\n",
X			 ctlr_type, ctlr_num, i,
X				(width/8)*speed/1000, (width/8)*speed%1000);
X	}
X}
X
Xvoid do_scsi_probe(devicename, lun)
Xchar *devicename;
Xint lun;
X{
X	printf("\t");
X	if(-1==(scsi_probe(devicename, lun))){
X		switch(errno){
X		case EACCES:
X			printf(
X"<<< SCSI probe failed: no permission to access device special file >>>\n");
X			break;
X		case ENOTTY:
X			printf(
X"<<< SCSI probe failed: device driver doesn't support probing >>>\n");
X			break;
X		case ENXIO:
X		case EIO:
X			printf(
X"<<< SCSI probe failed: device not accessible (media not loaded?) >>>\n");
X			break;
X		case EBUSY:
X			printf(
X"<<< SCSI probe failed: device is busy >>>\n");
X			break;
X		case ENOENT:
X			printf(
X"<<< SCSI probe failed: device special file not available >>>\n");
X			break;
X		default:
X			perror("scsi probe failed");
X			break;
X		}
X	} else {
X		printf("\n");
X	}
X}
X
Xchar *compute_devicename(dname, devicepath, addrname)
Xchar *dname, *devicepath, *addrname;
X{
X	char *devicename;
X
X	/* compute device name */
X	if(STREQ(SUNDISK, dname)){
X		/* 
X		 * This is a disk. 
X		 *
X		 * We want to query the device corresponding to partition c/2 
X		 * eg. rsd0c or sd@0,0:c,raw
X		 */
X		devicename = cat(
X			devicepath, "/", 
X			DEV_PREFIX, dname, 
X			DEV_INFIX, addrname, 
X			DISK_SUFFIX, NULL);
X	} else if(STREQ(SUNTAPE, dname)) {
X		/* 
X		 * This is a tape.
X		 *
X		 * We want to query the no-rewind BSD-style device.
X		 * eg. nrst0 or st@0,0:bn
X		 */
X		devicename = cat(
X			devicepath, "/",
X			TAPE_PREFIX,
X			dname, DEV_INFIX,
X			addrname,
X			TAPE_SUFFIX, NULL);
X	} else {
X		/* 
X		 * Don't know what device this is. 
X		 * 
X		 * Use best guess for devicename: eg. rNN0 or NN@0,0:
X		 */ 
X		devicename = cat(
X			devicepath, "/", 
X			DEV_PREFIX,
X			dname, DEV_INFIX, 
X			addrname, 
X			DEV_SUFFIX, NULL);
X	}
X	return(devicename);
X}
END_OF_FILE
if test 3318 -ne `wc -c <'common.c'`; then
    echo shar: \"'common.c'\" unpacked with wrong size!
fi
# end of 'common.c'
fi
if test -f 'format.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'format.c'\"
else
echo shar: Extracting \"'format.c'\" \(5217 characters\)
sed "s/^X//" >'format.c' <<'END_OF_FILE'
X/*
X * format.c - code for providing format info, generating format.dat using
X *            uscsi queries.
X *
X * Author: John DiMarco,
X *         University of Toronto, Computing Disciplines Facility
X *         jdd@cdf.toronto.edu
X *
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: format.c,v 3.11 1995/03/28 18:41:59 jdd Exp $";
X#endif
X
X#include <stdio.h>
X#include <fcntl.h>
X#include <sys/stat.h>
X#include "utils.h"
X#include "uscsi.h"
X
X#ifndef DTYPE_DIRECT
X#define DTYPE_DIRECT 0x00
X#endif /* DTYPE_DIRECT */
X
X#define MAX_RPM 14400
X#define MIN_RPM 3000
X#define VENDOR_SIZE 8
X#define PRODUCT_SIZE 16
X#define STANDARD_ACYL 2
X#define FUDGEFACTOR 1.15
X#define SECTORSIZE 512
X#define MD21 "MD21"
X#define SCSI "SCSI"
X
Xextern int d;
X
Xstatic int acyl = STANDARD_ACYL;
X
Xvoid format(formatdat, osversion, diskdevice, original)
Xint formatdat;
Xchar *osversion;
Xchar *diskdevice;
Xint original;
X{
X	struct stat sb;
X	int fd, i;
X	int devicetype;
X	char vendor[VENDOR_SIZE+1], product[PRODUCT_SIZE+1];
X	int capacity;
X	int nsect, sector_size;
X	int pcyl, nhead, rpm=-1;
X	int trks_zone, atrks, asect;
X	char disk_type[VENDOR_SIZE+PRODUCT_SIZE+2], *ctlr, *cname;
X	int fmt_time, ncyl, bpt_, csize;
X
X	/* preliminary stuff */
X	if(d) printf("Generating format.dat for %s, SunOS %s\n", diskdevice,
X			osversion);
X	if(stat(diskdevice, &sb)<0){
X		perror(diskdevice);
X		Error("Cannot access device, giving up.");
X	}
X	if(!S_ISCHR(sb.st_mode)){
X		Error("%s must be a raw disk device.", diskdevice);
X	}
X	if(0>(fd=open(diskdevice, O_RDONLY|O_NDELAY))){
X		perror(diskdevice);
X		Error("Cannot open device, giving up.");
X	}
X
X	/* get vendor and product */
X	if(0>scsi_inquiry(fd, &devicetype, vendor, product)){
X		perror(diskdevice);
X		Error("SCSI INQUIRY failed, giving up.");
X	}
X	if(DTYPE_DIRECT!=devicetype){
X		Error("%s is not a hard disk.", diskdevice);
X	}
X
X	/* get number of blocks available */
X	if(0>scsi_capacity(fd, &capacity)){
X		perror(diskdevice);
X		Error("SCSI READ_CAPACITY failed, giving up.");
X	}
X
X	/* get nsect, sector_size, pcyl, nhead, rpm, disk_type, ctlr, 
X	   fmt_time, acyl, ncyl, bpt, trks_zone, atrks, asect */
X
X	if(0>scsi_modeinfo(fd, original, &nsect, &sector_size, &pcyl, &nhead, 
X		&rpm, &trks_zone, &asect, &atrks)){
X		perror(diskdevice);
X		Error("SCSI mode select failed, giving up.");
X	}
X	if(SECTORSIZE != sector_size){
X		if(sector_size){
X			Error(
X		"Drive is formatted with with sector size %d, should be %d",
X				sector_size, SECTORSIZE);
X		} else {
X			Warning("Drive claims sector size 0, using %d bytes",
X				SECTORSIZE);
X			sector_size=SECTORSIZE;
X		}
X	}
X	if(-1==rpm){
X		Warning("Drive doesn't report rpm; assuming 3600.");
X		rpm=3600;
X	} else if(rpm>MAX_RPM || rpm<MIN_RPM){
X		Warning(
X	   "Drive claims to have strange RPM value %d, using 3600.", rpm);
X		rpm=3600;
X	}
X	if(nhead<1) {
X		Error(
X	"Drive claims to have %d heads. This makes no sense. Giving up.", 
X		nhead);
X	}
X
X	if(nsect<1) {
X		Error(
X	"Drive claims to have %d sectors. This makes no sense. Giving up.", 
X		nsect);
X	}
X
X	vendor[VENDOR_SIZE]='\0';
X	for(i=VENDOR_SIZE-1;i>0 && vendor[i]==' ';i--){
X		vendor[i]='\0';
X	}
X	product[sizeof(product)-1]='\0';
X	for(i=PRODUCT_SIZE-1;i>0 && product[i]==' ';i--){
X		product[i]='\0';
X	}
X	sprintf(disk_type, "%s %s", vendor, product);
X
X	{
X		int osmajor=0, osminor=0, subosminor=0;
X
X		sscanf(osversion, "%d.%d.%d", &osmajor, &osminor, &subosminor);
X		if(4==osmajor && osminor<2 && subosminor<2){
X			ctlr=MD21;
X		} else {
X			ctlr=SCSI;
X		}
X		if(osmajor<5) {
X			cname="c";
X		} else {
X			cname="2";
X		}
X	}
X
X	fmt_time = (capacity / 1000000) + 1;
X
X	ncyl = (capacity / (nhead * nsect)) - acyl;
X
X	bpt_ = (int) (FUDGEFACTOR * SECTORSIZE) * nsect;
X
X	csize = ncyl*nhead*nsect;
X
X	if(formatdat){
X		printf("disk_type = \"%s\" \\\n", disk_type);
X		printf(  "\t: ctlr = %s : fmt_time = %d \\\n", ctlr, fmt_time);
X
X		/* only output the following if they're nondefault */
X		printf(  "\t");
X		if(1 != trks_zone) printf(": trks_zone = %d ", trks_zone);
X		if(nhead != atrks) printf(": atrks = %d ", atrks);
X		if(1 != asect) printf(" : asect = %d ", asect);
X		printf(" \\\n");
X
X		printf(  "\t: ncyl = %d : acyl = %d", ncyl, acyl);
X		printf(     " : pcyl = %d : nhead = %d", pcyl, nhead);
X		printf(     " : nsect = %d \\\n", nsect);
X
X		printf(  "\t: rpm = %d : bpt = %d\n", rpm, bpt_);
X
X		printf("\n");
X		printf("partition = \"%s\" \\\n", disk_type);
X		printf(  "\t: disk = \"%s\" : ctlr = %s \\\n", disk_type, ctlr);
X		printf(  "\t: %s = 0, %d\n", cname, csize);
X	} else {
X		printf("Vendor:                      %s\n", vendor);
X		printf("Model:                       %s\n", product);
X		printf("Formatted Capacity:          %d sectors ", capacity); 
X		if(capacity >= 2000000){
X			printf("(%.2f GB)\n", (float)capacity/2000000);
X		} else {
X			printf("(%.2f MB)\n", (float)capacity/2000);
X		}
X		printf("Sector size:                 %d bytes\n", sector_size);
X		printf("Physical Cylinders:          %d\n", pcyl);
X		printf("Heads:                       %d\n", nhead);
X		printf("Sectors per track (Avg.):    %d\n", nsect);
X		printf("Tracks per zone:             %d\n", trks_zone);
X		printf("Alternate Sectors per zone:  %d\n", asect);
X		printf("Alternate Tracks per volume: %d\n", atrks);
X		printf("Rotational speed:            %d rpm\n", rpm);
X	}
X}
END_OF_FILE
if test 5217 -ne `wc -c <'format.c'`; then
    echo shar: \"'format.c'\" unpacked with wrong size!
fi
# end of 'format.c'
fi
if test -f 'format.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'format.h'\"
else
echo shar: Extracting \"'format.h'\" \(237 characters\)
sed "s/^X//" >'format.h' <<'END_OF_FILE'
X/*
X * format.h - header file for format.c
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: format.h,v 1.2 1994/08/17 19:02:35 jdd Exp $
X */
X
X/* Exported Procedures */
Xextern void format();
END_OF_FILE
if test 237 -ne `wc -c <'format.h'`; then
    echo shar: \"'format.h'\" unpacked with wrong size!
fi
# end of 'format.h'
fi
if test -f 'esp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'esp.c'\"
else
echo shar: Extracting \"'esp.c'\" \(6591 characters\)
sed "s/^X//" >'esp.c' <<'END_OF_FILE'
X/*
X * esp.c  -  process ESP host adapters.
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X * 
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: esp.c,v 1.2 1995/03/28 18:40:50 jdd Exp $";
X#endif
X
X#ifdef ESP
X
X#include "uscsi.h"
X#include "format.h"
X#include <stdio.h>
X
X#ifdef FILENAME_MAX     /* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X#include <sys/param.h>
X#include <values.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <nlist.h>
X#include <fcntl.h>
X#include <sys/utsname.h>
X#include "utils.h"
X#include "common.h"
X#include "param.h"
X
X/* include OS-dependent stuff */
X#ifdef SYSV
X#include <sunos5.h>
X#include <sys/scsi/adapters/espvar.h>
X#else 
X#ifdef SUNOS4_1_0
X/* no espvar.h in SunOS 4.1 */
X#include <scsi/adapters/espreg.h>
X#else /* !SUNOS4_1_0 */
X#include <scsi/adapters/espvar.h>
X#endif /* !SUNOS4_1_0 */
X#include <sunos4.h>
X#endif /* !SYSV */
X
Xstatic char *espType(typecode)
Xunsigned int typecode;
X{
X	/* see /usr/include/[sys/]scsi/adapters/espreg.h */
X	switch(typecode){
X	case 0:		return("ESP100/NCR53C90");
X	case 1: 	return("ESP100A/NCR53C90A");
X	case 2:		return("ESP236");
X	case 3:		return("FAS100/100A");
X	case 4:		return("FAS236");
X	case 5:		return("FAST");
X	default:	return("unknown");
X	}
X}
X
Xstatic u_int esp_get_speed(esp, i)
Xstruct esp *esp;
Xint i; /* target index */
X{
X	u_int cycletime, speed;
X
X	/*
X	 * Synch cycle time in milliseconds is the
X	 * number of ticks in the period divided
X	 * by the tick rate. e_clock_conv is the
X	 * esp's tick rate in units of 5MHz.
X	 */
X	cycletime = esp->e_clock_conv ? (esp->e_period[i] *
X			(1000/(int)(5*esp->e_clock_conv))) : 0;
X
X	/*
X	 * Compute speed in thousanths of MBs/sec.
X	 */
X	speed = cycletime?((((1000*1000*1000)/cycletime)+999)/1000):0;
X
X	return(speed);
X}
X
Xstatic void esp_controller_message(cnum, esp)
Xint cnum;
Xstruct esp *esp;
X{
X	printf("esp%d:", cnum);
X	printf(" type %d (%s)", (u_int)esp->e_type,
X		espType(esp->e_type));
X	printf(" speed %dMHz", (u_int)esp->e_clock_conv*5);
X	printf("\n");
X}
X
Xstatic void esp_synch_message(esp, i, speed)
Xstruct esp *esp;
Xint i;
Xu_int speed;
X{
X	if(esp->e_weak & ~(esp->e_targets)) {
X		/* don't believe esp synch info if e_weak mentions 
X		 * unprobed targets; something has gone awry. Some versions of 
X		 * the 5.x ct driver for the Central Data STS do this.
X		 */
X		if(0==esp->e_type){
X			/* Since this host adapter uses an NCR 53C90, not a 
X			 * 53C90A or later, e_weak is bogus probably because 
X			 * synch scsi is turned off in the kernel (53C90s are
X			 * overly susceptible to noise when doing synchronous 
X			 * transfers). See esp_ss1_esp0sync.
X			 */
X			printf("Asynchronous");
X		} else {
X			printf("Unknown");
X		}
X	} else if(speed && (esp->e_sync_known & (1<<i))){
X		printf("Synchronous(%d.%dMB/sec)", speed/1000, speed%1000);
X	} else {
X		printf("Asynchronous");
X	}
X	if(esp->e_weak & ~(esp->e_targets)) {
X		/* again, don't believe e_weak if mentions unprobed targets */
X		printf(" Unknown");
X	} else if(esp->e_weak & (1<<i)){
X		printf(" Noisy");
X	} else {
X		printf(" Clean");
X	}
X	if(esp->e_nodisc & ~(esp->e_targets)) {
X		/* don't believe e_nodisc if it mentions unprobed targets */
X		printf(" Unknown");
X	} else if(esp->e_nodisc & (1<<i)){
X		printf(" CannotReconnect");
X	} else {
X		printf(" CanReconnect");
X	}
X}
X
Xint process_esp()
X{
X	u_long addr;
X	struct esp esp[1], *esp_p, *esp_softc;
X	int noisycount=0; /* number of noisy devices */
X	u_int j, nesp;
X
X        if(-1==kvm(nl[N_ESP_SOFTC].n_value, addr)){
X		return(0); /* esp driver not loaded */
X        }
X        if((u_long)NULL==addr) return(0); /* no esp's */
X
X        if(-1==kvm(addr, esp[0])){
X                Error("kvm read: initial esp");
X        }
X	esp_softc=esp_p=(struct esp *)addr;
X
X	nesp=get_nesp();
X	if(0==nesp) return(0);
X
X	for(j=0;j<nesp;j++){
X		struct dev_info di, *next;
X		char *devicepath, *dname;
X
X		if((u_long)NULL==addr) break;
X
X                if(-1==kvm(addr, esp[0])){
X			Error("kvm read: esp #%d", j);
X		}
X
X		/* 
X		 * grab the devinfo structure for the esp controller. CNUM 
X		 * requires it, and we need it to determine the device names.
X		 */
X		if(-1==kvm(esp->e_dev, devi)){
X			Error("kvm read: #%d esp devinfo", j);
X		} 
X
X		if(param_is_set(P_PROBE)) devicepath = get_devicepath(j);
X
X		esp->e_dev=(dev_info_t)&devi; /* for CNUM */
X
X		if(param_is_set(P_CONTROLLER)) {
X			esp_controller_message(CNUM, esp);
X		}
X
X		init_scsitarget();
X
X		/* 
X		 * Now, traverse esp's devinfo child list, looking for
X		 * attached drivers (i.e. DDI_CF2 is true). If we find
X		 * an attached driver, we presume it is an active device.
X		 */
X
X		for(next=ddi_get_child(&devi);
X		    NULL!=next; 
X		    next=ddi_get_next_sibling(&di)){
X			char *devicename, *addrname;
X			int target, lun;
X
X			if(-1==kvm(next, di)){
X			    Error("kvm read: #%d esp devinfo child", j);
X			}
X
X			if(!DDI_CF2(&di)) continue; /* no device attached */
X
X			/*
X			 * Get the device name and address, and 
X			 * compute the device path for it
X			 */
X
X			/* get device name */
X			dname=s(kvmstr((u_long)ddi_get_name(&di)));
X			/* ... and address */
X			addrname=s(get_addr(&di));
X
X#ifdef CENTRAL_DATA_CT
X			if(STREQ(CENTRAL_DATA_CT, dname)) {
X				/* 
X				 * The Central Data STS driver attach
X				 * routine always returns success, so 
X				 * the kernel thinks that there's an STS
X				 * at every target. But the only targets
X				 * that really have an STS are the ones
X				 * that have a non-zero devi_minor. 
X				 */
X				if(!di.devi_minor) continue;
X			}
X#endif /* CENTRAL_DATA_CT */
X
X			if(param_is_set(P_PROBE)) {
X				devicename = compute_devicename(dname, 
X							devicepath, addrname);
X			}
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			if(0==lun && (esp->e_weak & (1<<target))) noisycount++;
X
X			if(!param_is_set(P_QUIET)){
X				if(param_is_set(P_SUNOS4STYLE)) {
X					if(lun==0){
X						boot_synch_message("esp",
X							CNUM, target, 
X							esp_get_speed(esp, 
X								target), 
X								NARROW);
X					}
X				} else {
X					printf(
X					   "esp%d: %s%s tgt %d lun %d:\n\t", 
X						CNUM, dname, addrname, 
X						target, lun);
X					esp_synch_message(esp, target, 
X						esp_get_speed(esp, target));
X					printf("\n");
X				}
X			}
X			if(param_is_set(P_PROBE)) {
X				do_scsi_probe(devicename, lun);
X				free(devicename);
X			}
X			free(addrname);
X			free(dname);
X		}
X
X#ifdef OLD_SUNOS
X		/* SunOS 4.1.1 and previous use a table of esp structures */
X		addr=(u_long)(++esp_p);
X#else
X		/* SunOS 4.1.2 and later use a linked list of esp structures */
X                addr=(u_long)esp->e_next;
X#endif
X
X	}
X	return(noisycount);
X}
X
X#endif /* ESP */
END_OF_FILE
if test 6591 -ne `wc -c <'esp.c'`; then
    echo shar: \"'esp.c'\" unpacked with wrong size!
fi
# end of 'esp.c'
fi
if test -f 'isp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'isp.c'\"
else
echo shar: Extracting \"'isp.c'\" \(5904 characters\)
sed "s/^X//" >'isp.c' <<'END_OF_FILE'
X/*
X * isp.c  -  process ISP host adapters.
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X * 
X * ISP support by: Calum Mackay, University of Cambridge, BSU
X *                 calum.mackay@mrc-bsu.cam.ac.uk
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: isp.c,v 1.1 1995/03/28 18:42:24 jdd Exp $";
X#endif
X
X#ifdef ISP
X
X#include <stdio.h>
X#ifdef FILENAME_MAX	/* defined in stdio.h only for SunOS >=5.x */
X#define SYSV
X#endif
X
X#ifdef SYSV
X#include <sunos5.h>
X
X#ifdef SCSI_HBA_TRAN_CLONE /* SunOS 5.4 or later */
X#include <sys/scsi/adapters/ispmail.h>
X#include <sys/scsi/adapters/ispvar.h>
X/* 
X * It's ugly and dangerous to redefine CNUM here, but SunOS 5.4 ispvar.h's 
X * idea of CNUM is completely wrong. It uses data structures that existed in
X * 2.3 but no longer exist in 2.4.
X */
X#undef CNUM
X#define CNUM(isp)               (ddi_get_instance(isp->isp_tran->tran_hba_dip))
X#else /* !SCSI_HBA_TRAN_CLONE */
X#include "ispvar.h"
X#endif /* !SCSI_HBA_TRAN_CLONE */
X
X#include "uscsi.h"
X#include "format.h"
X
X#include <sys/param.h>
X#include <values.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <nlist.h>
X#include <kvm.h>
X#include <fcntl.h>
X#include <sys/utsname.h>
X#include "utils.h"
X#include "param.h"
X#include "common.h"
X
Xextern int get_nisp();
X
Xtypedef struct {
X        int     period;         /* ISP_xM_SYNC_PERIOD */
X        int     speed;          /* x000 */
X} isp_speed_mapping;
X
Xisp_speed_mapping isp_speed[] = {
X        ISP_10M_SYNC_PERIOD, 10000,
X        ISP_8M_SYNC_PERIOD,   8000,
X        ISP_5M_SYNC_PERIOD,   5000,
X        ISP_4M_SYNC_PERIOD,   4000
X#define ISP_PERIOD_TABLE 4      /* Number of elements in isp_speed[] */
X};
X
Xstatic int isp_get_speed(isp, i)
Xstruct isp *isp;
Xint i; /* target index */
X{
X	int index;
X
X	for ( index = 0; index < ISP_PERIOD_TABLE; index++ )
X		if ( isp_speed[index].period == PERIOD_MASK(isp->isp_synch[i]) )
X			return(isp_speed[index].speed);
X
X	return(-1);
X}
X
Xstatic void isp_synch_message(isp, i, speed)
Xstruct isp *isp;
Xint i;
Xu_int speed;
X{
X	int width = NARROW;
X	if(isp->isp_cap[i] & ISP_CAP_WIDE) width = WIDE;
X
X	switch (speed) {
X		case -1 :
X			if ( isp->isp_cap[i] & ISP_CAP_SYNC ) {
X				printf("Synchronous(Unknown MB/sec)" );
X			}
X			else {
X				printf("Asynchronous");
X			}
X			break;
X		case 0 :
X			printf("Asynchronous");
X			break;
X		default :
X			if(speed && (isp->isp_cap[i] & ISP_CAP_SYNC)){
X				printf("Synchronous(%d.%dMB/sec)",
X					width*speed/1000, width*speed%1000);
X			}
X			else {
X				printf("Asynchronous"); 
X			}
X			break;
X	}
X	printf(" Unknown"); /* isp driver doesn't keep track of errors */
X	if(isp->isp_cap[i] & ISP_CAP_DISCONNECT){
X		printf(" CanReconnect");
X	} else {
X		printf(" CannotReconnect");
X	}
X	if(isp->isp_cap[i] & ISP_CAP_TAG){
X		printf(" TaggedQueing");
X	} else {
X		printf(" NoTaggedQueing");
X	}
X	if(width == WIDE){
X		printf(" Wide");
X	} else {
X		printf(" Narrow");
X	}
X}
X
Xstatic void isp_controller_message(cnum, isp)
Xint cnum;
Xstruct isp *isp;
X{
X	printf("isp%d:", cnum);
X	printf(" QLGC ISP 1000" );
X	printf(" firmware revision %d.%d\n", (int) isp->isp_major_rev,
X						(int) isp->isp_minor_rev );
X}
X
Xint process_isp()
X{
X	u_long addr;
X	struct isp isp[1];
X	u_int j, nisp;
X	int noisycount=0;
X
X	if(-1==kvm(nl[N_ISP_HEAD].n_value, addr)){
X		return(0); /* isp driver not loaded */
X	}
X
X	if((u_long)NULL==addr) return(0); /* no isp's */
X
X        if(-1==kvm(addr, isp)){
X		Error("kvm read: initial isp");
X	}
X
X	nisp=get_nisp();
X	if(0==nisp) return(0);
X
X	for(j=0;j<nisp;j++){
X		struct dev_info di, *next;
X		char *devicepath, *dname;
X
X		if((u_long)NULL==addr) break;
X
X                if(-1==kvm(addr, isp[0])){
X			Error("kvm read: isp #%d", j);
X		}
X
X		/* 
X		 * grab the devinfo structure for the isp controller. CNUM 
X		 * requires it, and we need it to determine the device names.
X		 */
X		if(-1==kvm((u_long)isp->isp_dip, devi)){
X			Error("kvm read: #%d isp devinfo", j);
X		}
X
X		if(param_is_set(P_PROBE)) devicepath = get_devicepath(j);
X
X		isp->isp_dip=(dev_info_t)&devi; /* for CNUM */
X
X		if(param_is_set(P_CONTROLLER)) {
X			isp_controller_message(CNUM(isp), isp);
X		}
X
X		init_scsitarget();
X
X		/* 
X		 * Now, traverse isp's devinfo child list, looking for
X		 * attached drivers (i.e. DDI_CF2 is true). If we find
X		 * an attached driver, we presume it is an active device.
X		 */
X
X		for(next=ddi_get_child(&devi);
X		    NULL!=next; 
X		    next=ddi_get_next_sibling(&di)){
X			char *devicename, *addrname;
X			int target, lun;
X
X			if(-1==kvm((u_long)next, di)){
X			    Error("kvm read: #%d isp devinfo child", j);
X			}
X
X			if(!DDI_CF2(&di)) continue; /* no device attached */
X
X			/*
X			 * Get the device name and address, and 
X			 * compute the device path for it
X			 */
X
X			/* get device name */
X			dname=s(kvmstr((u_long)ddi_get_name(&di)));
X			/* ... and address */
X			addrname=s(get_addr(&di));
X
X#ifdef CENTRAL_DATA_CT
X			if(STREQ(CENTRAL_DATA_CT, dname)) {
X				/* special case for Central Data STS driver */
X				if(!di.devi_minor) continue;
X			} 
X#endif /* CENTRAL_DATA_CT */
X
X			if(param_is_set(P_PROBE)) {
X				devicename = compute_devicename(dname, 
X							devicepath, addrname);
X			}
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			if(!param_is_set(P_QUIET)){
X				if(param_is_set(P_SUNOS4STYLE)) {
X					if(lun==0){
X						boot_synch_message("isp",
X							CNUM(isp), target, 
X							isp_get_speed(isp,
X								target),
X								WIDE);
X					}
X				} else {
X					printf(
X					   "isp%d: %s%s tgt %d lun %d:\n\t", 
X						CNUM(isp), dname, addrname, 
X						target, lun);
X					isp_synch_message(isp, target, 
X						isp_get_speed(isp, target));
X					printf("\n");
X				}
X			}
X
X
X			if(param_is_set(P_PROBE)) {
X				do_scsi_probe(devicename, lun);
X				free(devicename);
X			}
X			free(addrname);
X			free(dname);
X		}
X                addr=(u_long)isp->isp_next;
X	}
X
X	return(noisycount);
X
X}
X#else /* !SYSV */
Xint process_isp(){}
X#endif /* !SYSV */
X#endif /* ISP */
END_OF_FILE
if test 5904 -ne `wc -c <'isp.c'`; then
    echo shar: \"'isp.c'\" unpacked with wrong size!
fi
# end of 'isp.c'
fi
if test -f 'ispvar.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ispvar.h'\"
else
echo shar: Extracting \"'ispvar.h'\" \(2723 characters\)
sed "s/^X//" >'ispvar.h' <<'END_OF_FILE'
X/*
X * isp.h - header file for ISP controller support.
X *
X * Info originally from Solaris 2.4EA
X *
X * $Id: ispvar.h,v 1.1 1995/03/28 18:42:33 jdd Exp $
X */
X
X#ifndef ISP_H
X#define ISP_H
X
X/* ISP capability defines */
X#define	ISP_CAP_DISCONNECT	0x8000
X#define	ISP_CAP_PARITY		0x4000
X#define	ISP_CAP_WIDE		0x2000
X#define	ISP_CAP_SYNC		0x1000
X#define	ISP_CAP_TAG		0x0800
X#define	ISP_CAP_AUTOSENSE	0x0400
X#define	ISP_CAP_ERRSTOP		0x0200
X#define	ISP_CAP_ERRSYNC		0x0100
X
X/* synchronous periods */
X#define	ISP_10M_SYNC_PERIOD	0x0019
X#define	ISP_8M_SYNC_PERIOD	0x0025
X#define	ISP_5M_SYNC_PERIOD	0x0032
X#define	ISP_4M_SYNC_PERIOD	0x0041
X
X#define	PERIOD_MASK(val)	((val) & 0xff)
X
X#define	CNUM(isp)		(ddi_get_instance(isp->isp_tran.tran_dev))
X#define	NTARGETS_WIDE		16
X#define	ISP_MAX_REQUESTS	256
X#define	ISP_MAX_SLOTS		(NTARGETS_WIDE * ISP_MAX_REQUESTS)
X#define	ISP_MAX_MBOX_REGS		6
X
Xstruct isp_mbox_cmd {
X	u_int		timeout;
X	u_char		retry_cnt;
X	u_char		n_mbox_out;
X	u_char		n_mbox_in;
X	u_short		mbox_out [ISP_MAX_MBOX_REGS];
X	u_short		mbox_in  [ISP_MAX_MBOX_REGS];
X};
X
Xstruct isp_mbox {
X	ksema_t			mbox_sema;
X	u_char			mbox_flags;
X	struct isp_mbox_cmd 	mbox_cmd;
X};
X
Xstruct isp_slot	{
X	struct scsi_cmd	*slot_cmd;
X	clock_t		slot_deadline;
X};
X
Xstruct isp {
X	struct scsi_transport	isp_tran;
X#define	isp_dip			isp_tran.tran_dev
X#define	isp_iblock		isp_tran.tran_lkarg
X	struct isp		*isp_next;
X	short			isp_major_rev;
X	short			isp_minor_rev;
X	u_char			isp_burstsize;
X	u_char			isp_initiator_id;
X	u_short			isp_cap[NTARGETS_WIDE];
X	u_short			isp_synch[NTARGETS_WIDE];
X	volatile struct ispregs		*isp_reg;
X	struct isp_mbox		isp_mbox;
X	u_char			isp_shutdown;
X	caddr_t			isp_cmdarea;
X	ddi_dma_cookie_t	isp_dmacookie;
X	ddi_dma_handle_t	isp_dmahandle;
X	u_long			isp_request_dvma,
X				isp_response_dvma;
X	int			isp_queue_space;
X	kmutex_t		isp_request_mutex;
X	kmutex_t		isp_response_mutex;
X	u_short			isp_request_in,
X				isp_request_out;
X	u_short			isp_response_in,
X				isp_response_out;
X	struct isp_request	*isp_request_ptr,
X				*isp_request_base;
X	struct isp_response	*isp_response_ptr,
X				*isp_response_base;
X	kmutex_t		isp_waitq_mutex;
X	struct	scsi_cmd	*isp_waitf;
X	struct	scsi_cmd	*isp_waitb;
X	kmutex_t		isp_pkt_alloc_mutex;
X	kmutex_t		isp_pkt_free_mutex;
X	int			isp_resource_cb_id;
X	caddr_t			isp_std_pkt_pool_anchor;
X	caddr_t			isp_std_pkt_pool_free;
X	caddr_t			isp_ext_pkt_pool_anchor;
X	caddr_t			isp_ext_pkt_pool_free;
X#ifdef ISP_PERF
X	u_int			isp_request_count,
X				isp_mail_requests;
X	u_int			isp_intr_count,
X				isp_perf_ticks;
X	u_int			isp_rpio_count,
X				isp_wpio_count;
X#endif
X	int			isp_timeout_id;
X	u_char			isp_tags[NTARGETS_WIDE];
X	u_short			isp_last_tgt_watched;
X	struct	isp_slot	isp_slots[ISP_MAX_SLOTS];
X};
X
X#endif /* ISP_H */
END_OF_FILE
if test 2723 -ne `wc -c <'ispvar.h'`; then
    echo shar: \"'ispvar.h'\" unpacked with wrong size!
fi
# end of 'ispvar.h'
fi
if test -f 'param.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'param.h'\"
else
echo shar: Extracting \"'param.h'\" \(448 characters\)
sed "s/^X//" >'param.h' <<'END_OF_FILE'
X/*
X * param.h: Command-line Parameter passing definitions
X *
X * Author: John DiMarco, University of Toronto, CDF
X *         jdd@cdf.toronto.edu
X *
X * $Id: param.h,v 1.1 1995/03/28 18:42:59 jdd Exp $
X */
X
Xextern int parameter; /* defined in scsiinfo.c */
X
X#define P_CONTROLLER 0
X#define P_SUNOS4STYLE 1
X#define P_PROBE 2
X#define P_QUIET 3
X#define P_ORIGINAL 4
X
X#define set_param(a) (parameter |= 1<<(a))
X#define param_is_set(a) (parameter & 1<<(a))
END_OF_FILE
if test 448 -ne `wc -c <'param.h'`; then
    echo shar: \"'param.h'\" unpacked with wrong size!
fi
# end of 'param.h'
fi
echo shar: End of shell archive.
exit 0
