#! /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 DISCLAIMER MANIFEST Makefile README patchlevel.h
#   scsiinfo.1 scsiinfo.c sunos4.h sunos4.c sunos5.h sunos5.c common.h
#   common.c esp.c isp.c fas.c ptisp.c glm.c pln.c ispvar.h param.h
#   uscsi.c uscsi.h utils.c utils.h format.c format.h notch.c notch.h
#   include include/sundev include/sundev/dmaga.h include/sys
#   include/sys/scsi include/sys/scsi/adapters
#   include/sys/scsi/adapters/espcmd.h include/ptisp
#   include/ptisp/ispmail4.h include/ptisp/ptisp4.h
#   include/ptisp/ispmail5.h include/ptisp/ispvar5.h mkadapters
# Wrapped by jdd@dvp.cs on Tue Jul 17 13:13:45 2001
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'\" \(961 characters\)
sed "s/^X//" >'COPYRIGHT' <<'END_OF_FILE'
X/*
X * Copyright University of Toronto 1993, 1994, 1995, 1996, 1997, 1998, 1999,
X * 					2000.
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 961 -ne `wc -c <'COPYRIGHT'`; then
    echo shar: \"'COPYRIGHT'\" unpacked with wrong size!
fi
# end of 'COPYRIGHT'
fi
if test -f 'DISCLAIMER' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'DISCLAIMER'\"
else
echo shar: Extracting \"'DISCLAIMER'\" \(668 characters\)
sed "s/^X//" >'DISCLAIMER' <<'END_OF_FILE'
X******************************************************
X*                                                    *
X*                    DISCLAIMER                      *
X*                                                    *
X******************************************************
X
XThis is not a supported product.
X
XNO LIABILITY WILL BE  ACCEPTED BY THE UNIVERSITY OF 
XTORONTO, SUN MICROSYSTEMS, OR ANY OTHER INSTITUTION 
XMENTIONED IN ANY WAY HEREIN, FOR ANY LOSS (DIRECT OR 
XCONSEQUENTIAL) INCURRED IN ANY WAY BY ANY PARTY THROUGH 
XTHE USE OF THIS INFORMATION OR SOFTWARE.
X
XNO WARRANTY OF ANY SORT IS IMPLIED OR GIVEN FOR ANY
XCODE DERIVED FROM THIS INFORMATION OR SOFTARE.
END_OF_FILE
if test 668 -ne `wc -c <'DISCLAIMER'`; then
    echo shar: \"'DISCLAIMER'\" unpacked with wrong size!
fi
# end of 'DISCLAIMER'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1558 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
XCOPYRIGHT				Copyright notice
XDISCLAIMER				Legal disclaimer
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
Xfas.c					FAS support
Xptisp.c					PTISP support
Xglm.c					GLM support
Xpln.c					PLN support
Xispvar.h				ISP header support for Solaris 2.3
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
Xformat.c				Format information 
Xformat.h				header file for format.c
Xnotch.c					Notch Report
Xnotch.h					header file for notch.c
Xinclude					Directory to fool cpp
Xinclude/sundev				Directory to fool cpp
Xinclude/sundev/dmaga.h  		Empty file to fool cpp
Xinclude/sys				Directory to fool cpp
Xinclude/sys/scsi			Directory to fool cpp
Xinclude/sys/scsi/adapters		Directory to fool cpp
Xinclude/sys/scsi/adapters/espcmd.h	Empty file to fool cpp
Xinclude/ptisp				Directory for PTISP headers
Xinclude/ptisp/ispmail4.h		PTISP header (SunOS 4.x)
Xinclude/ptisp/ptisp4.h			PTISP header (SunOS 4.x)
Xinclude/ptisp/ispmail5.h		PTISP header (SunOS 5.x)
Xinclude/ptisp/ispvar5.h			PTISP header (SunOS 5.x)
Xmkadapters				Script to generate host adapter defines
END_OF_FILE
if test 1558 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(3816 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCC = cc # you can use gcc, if you like.  Don't use /usr/ucb/cc; it won't work.
XINCLUDEDIRS = -Iinclude
X
X#
X# Remove -lelf for SunOS 4.x
X#
XLIBRARIES = -lkvm -lelf
X
X#
X# You can hard-code the SUNOS_VERSION if you wish. 
X# For example, SUNOS_VERSION = -DSUNOS_VERSION=\"4.1.3\"
X#
XSUNOS_VERSION = -DSUNOS_VERSION=\"`/usr/bin/uname -r`\"
X
X#
X# The following determines which host adapters are supported.  Remove
X# a given host adapter from the mkadapters line below if you do not wish to 
X# have support for it compiled into scsiinfo.  Note that mkadapters will
X# not include support for a given adapter if the appropriate include files are
X# not available for it.
X#
Xall:: scsiinfo
X
Xadapters:
X	$(RM) adapters
X	./mkadapters esp isp fas glm ptisp pln >adapters
X
Xinclude adapters
X
X#
X# remove -DNOTCH_REPORT if you have trouble compiling notch.c
X#
X# Add -D_LARGEFILE64_SOURCE if you're using gcc version 2.7.2.1 or a later
X# version of 2.7.2 and you have problems compiling the source on Solaris 2.6.
X#
XDEFS = $(ADAPTERS) -DNOTCH_REPORT
X
X#
X# Optimization flag.  Optimization isn't really an issue for scsiinfo, so 
X# it might as well be left at -g.  For Solaris 7 running in 64-bit mode, 
X# if you have ver 5.0+ of Sun's compilers, add -xarch=v9 to OPT, LDFLAGS.
X#
XOPT = -g 
XLDFLAGS = 
X
XCFLAGS = $(SUNOS_VERSION) $(DEFS) $(OPT) $(INCLUDEDIRS)
XLINTFLAGS = $(SUNOS_VERSION) $(DEFS) -ha $(INCLUDEDIRS) 
XSRCS = scsiinfo.c utils.c uscsi.c format.c common.c esp.c isp.c fas.c ptisp.c \
X	glm.c pln.c sunos5.c sunos4.c notch.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
XBINDIR = /local/sbin
XMANDIR = /local/man/man1
X
X#
X# Set MODE to 4755, if you want this to run setuid root (not recommended). 
X# The -p/-r/-F options will normally not work except for root. By default, 
X# scsiinfo is set to run setgid sys (or kmem for SunOS 4.x), which allows 
X# only root to use -p/-r/-F, but everything else to work for other users. 
X#
XMODE = 2755
XOWNER = root 
XGROUP = sys # kmem for SunOS 4.x
X
XMANMODE = 644
XMANOWNER = root
XMANGROUP = staff
XMANSECT = 1
X
X#
X# End of user-configurable options
X#
X
Xscsiinfo: adapters $(OBJS) 
X	$(RM) $@
X	$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBRARIES)
Xlint:
X	lint $(LINTFLAGS) $(SRCS)
Xlintport:
X	lint -p $(LINTFLAGS) $(SRCS)
Xclean:
X	$(RM) $(OBJS) scsiinfo adapters
X
XDEPENDLINE = ' DO NOT DELETE THIS LINE  -- make depend depends on it.'
Xdepend:
X	-/bin/echo '/^\043'$(DEPENDLINE)'$$/,$$d\nw\nq' | /bin/ed Makefile >/dev/null || /bin/true
X	makedepend -f- -- $(CFLAGS) -I. -- $(SRCS) | ( /bin/echo '\043'$(DEPENDLINE); sed -e 's/\/usr\/include\/[^ ]*//g' -e '/:[ ]*$$/d' -e '/^[ ]*$$/d' -e 's/  */ /g' ) | awk '{for(i=2;i<=NF;i++){file[$$1]=file[$$1]" "$$i}}END{for(i in file){print i""file[i]}}' | sort 
X
Xinstall: scsiinfo
X	$(INSTALL) -m $(MODE) -o $(OWNER) -g $(GROUP) scsiinfo $(BINDIR) 
X
Xinstall.man: scsiinfo.1
X	$(INSTALL) -m $(MANMODE) -o $(MANOWNER) -g $(MANGROUP) scsiinfo.1 $(MANDIR)/scsiinfo.$(MANSECT)
X
Xshar:
X	shar `awk '{print $$1}' MANIFEST` >scsiinfo-`awk '{print $$7;exit}' patchlevel.h`.shar
X
X# Dependancies
Xcommon.o: utils.h uscsi.h format.h common.h sunos5.h sunos4.h
Xesp.o: uscsi.h format.h utils.h common.h param.h sunos5.h sunos4.h
Xfas.o: uscsi.h format.h utils.h common.h param.h sunos5.h
Xformat.o: utils.h uscsi.h
Xglm.o: uscsi.h format.h utils.h common.h param.h sunos5.h
Xisp.o: sunos5.h common.h uscsi.h format.h utils.h param.h
Xnotch.o: uscsi.h utils.h
Xpln.o: uscsi.h format.h utils.h common.h param.h sunos5.h
Xptisp.o: uscsi.h format.h utils.h common.h param.h sunos5.h \
X	include/ptisp/ispmail5.h include/ptisp/ispvar5.h
Xscsiinfo.o: patchlevel.h uscsi.h format.h utils.h param.h sunos5.h \
X	sunos4.h common.h notch.h
Xsunos4.o: sunos4.h common.h utils.h 
Xsunos5.o: sunos5.h common.h utils.h
Xuscsi.o: utils.h uscsi.h
Xutils.o: utils.h
END_OF_FILE
if test 3816 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(6919 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XJul 16, 2001   Release 4.7
X
XNew in release 4.7:
X        o support for Sun's PLN fibre-channel SCSI host adapter.
X        o support for Sun's simple SCSI target (sst) driver.
X        o -O support (Solaris 2.x) to check for devices already open.
X        o autodetection of host adapter include files.
X        o Solaris 8 support.
X
XScsiinfo displays information about SCSI devices attached to a given system,
Xas seen by a supported SCSI device driver.  For each target known to the SCSI
Xhost adapter, scsiinfo reports SCSI transfer information for the device.  In
Xparticular, when a target supports synchronous transfer, the negotiated
Xmaximum transfer rate (in MB/sec) is reported.  Scsiinfo can also report the
Xtype and speed of each supported host adapter attached to the system.  In
Xaddition, it supports querying SCSI disks for geometry and formatting and
Xoptionally generates a format.dat entry based on these values.  Finally,
Xscsiinfo supports querying SCSI devices for vendor, product, and revision
Xinformation, in the style of the Sun OpenBoot prom's probe-scsi and
Xprobe-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, but it can also be renegotiated
Xduring operation if necessary.
X
XScsiinfo notes:
X        - The "-s" option is intended for those who liked the "device now
X	  synchronous" messages produced by SunOS 4.1 and 4.1.1, and missed
X	  them in SunOS 4.1.2 and later.  Try adding "scsiinfo -s" to
X	  /etc/rc.boot or equivalent.
X        - scsiinfo does little on suns without supported host adapters,
X	  openboot prom support, and/or user-mode SCSI support.  On machines 
X	  with none of these (eg. sun3s), scsiinfo does nothing useful.
X        - Scsiinfo needs to be recompiled on any (even minor) OS releases.
X          For example, a SunOS 4.1.1 binary will not work on 4.1.2 or 4.1.3.
X	  On occasion, the installation of a kernel patch will require a
X	  recompile.  Examples include 104245 and 104246 on Solaris 2.5.1,
X	  which changes the fas data structure in the kernel, and 105580 in
X	  Solaris 2.6 and 106925 in Solaris 7, which changes the glm kernel
X	  data structure.
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,
X	  although Sun's 4.x disk drivers do. Sun's 4.x CD-ROM driver only
X	  does when there is valid media in the drive. In Solaris 2.2 or
X	  greater, /usr/sbin/vold, if it is running, may hold an exclusive
X	  open on a CD-ROM device, preventing a probe from succeeding. If
X	  scsiinfo cannot probe a drive, it returns a message saying why the
X	  probe may have failed.
X	- The format.dat entries generated by scsiinfo are not necessarily
X	  perfect.  Firstly, scsiinfo just guesses at the bpt figure (bpt =
X          bits per track), because there is no standard way of querying the
X	  drive for this figure.  Secondly, many drives simply don't return 
X	  an rpm figure (it was not required in the SCSI-1 standard); if this
X	  is the case, scsiinfo will assume 3600rpm for format.dat entries,
X	  which may not be correct.  Finally, different revisions of the same
X	  model of drive may have slightly different capacities.  If this is
X	  the case, an entry generated on one drive may not work on another
X	  drive of the same model.
X	- no, despite reports to the contrary (even some in documentation
X	  from sun) it is not true for SCSI disks that ncyl + acyl must equal
X	  pcyl in a format.dat entry.
X	- some device drivers complain at open() if the device is already 
X	  being used; -O will attempt to check (Solaris 2.x) if the device
X	  is in use before attempting an open.
X
XInstallation:
X        1. Edit the Makefile according to the directions therein.  
X        2. Compile. NB: Don't use /usr/ucb/cc under Solaris 2.x; it won't work!
X        3. Scsiinfo needs to be able to read the kernel namelist (eg.
X	   /dev/ksyms or /vmunix) and core image (eg. /dev/kmem).  For use 
X	   by users without read permissions on /dev/kmem, it can be made 
X	   setgid kmem (SunOS 4.x) or setgid sys (Solaris 2.x). 
X        4. If SCSI probing (scsiinfo -p), drive format querying (scsiinfo
X	   -r or -F), or notch querying (-N) is to work for a given device,
X	   scsiinfo will need to be able to access the device via a
X	   raw/character device file in /dev (or /devices/... in Solaris
X	   2.x). In Solaris 2.3 and later, scsiinfo must be run by root (or
X	   made setuid root) if probing or format querying is desired.
X
XPorting notes:
X          - Sun's drivers sometimes change sometimes between releases;
X            the code is written to be as portable as possible, but future
X            (greater than 5.8) versions of SunOS 5.x may break something. 
X	  - Scsiinfo is quite Sun-specific, and much of it would need to
X	    be rewritten to port it to a machine from a different vendor.
X
XCompiler notes:
X	  - The Cygnus 2.0.x version of gcc for Solaris 2.x that is
X	    distributed on the Sun Catalyst Volume 4 CD does not compile
X	    scsiinfo correctly.  In fact, it has numerous bugs, and it should
X	    be used for only one task: to compile a more recent version of gcc.
X	  - Again, don't use Sun's BSD compatibility compiler (/usr/ucb/cc) on 
X            Solaris 2.x; it will not compile scsiinfo correctly. Use
X	    /opt/SUNWspro/bin/cc or gcc instead.
X	  - Some people have reported problems compiling scsiinfo on Solaris
X	    2.4 with include files generated by the "fixincludes" script that
X            comes with older versions of gcc (for example, gcc 2.6.0).  If
X	    you run into this problem, try a newer version of gcc.
X	  - to run scsiinfo (except for -F/-r) on a 64-bit version of Solaris
X	    (e.g. Solaris 7 or later running in 64-bit mode), you need to 
X            compile it with Sun's 5.x or later compilers, using the 
X            -xarch=sparcv9 flag for both compiling and linking.  See the 
X            Makefile for details.
X
XFTP site:
X	The latest version of scsiinfo can normally (at least at the time of
X	this writing) be found at ftp://ftp.cs.toronto.edu/pub/jdd/scsiinfo/
X
XComments, bug reports, fixes, enhancements, etc. are welcome.
X
XJohn
X--
XJohn DiMarco <jdd@cs.toronto.edu>                         Office: SF2101
XCSLab Systems Manager                                     Phone: 416-978-5300
XUniversity of Toronto                                     Fax:   416-978-1931
Xhttp://www.cs.toronto.edu/~jdd
END_OF_FILE
if test 6919 -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'\" \(2211 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
Xstatic char patchlevel[] = "scsiinfo ver 4.7 $Id: patchlevel.h,v 3.23 2001/07/16 15:59:59 jdd Exp $";
X/*
X * New in release 4.7:
X *         o support for Sun's PLN fibre-channel SCSI host adapter.
X *         o support for Sun's simple SCSI target (sst) driver.
X *         o -O support (Solaris 2.x) to check for devices already open.
X *         o autodetection of adapter include files at compile time 
X *         o Solaris 8 support.
X * 
X * New in release 4.6:
X *         o "-r all" and "-F all" now generates output for all probed devices.
X *         o other options can now be combined with -r and -F
X *         o Some sanity checking for FAS and GLM controllers.
X *         o Compiling for 64-bit mode under SunOS 5.7 documented, added to -V.
X *         o fixes for -p with PCI ISP and GLM controllers 
X *         o better handling for SCSI-1 disks that do not report rpm.
X * 
X * New in release 4.5:
X *         o GLM support.
X *         o -r and -p now reports SCSI capabilities.
X *         o -r now reports supported SCSI transfer widths.
X *
X * New in release 4.4: 
X *         o Solaris 2.6 support.
X *         o -r for disks now indicates cache status.
X *         o Notch report for (some) disks, thanks to
X *                 Rod van Meter <rdv@alumni.caltech.edu>
X *         o added revision and serial output for -r.
X *         o Support for SCSI host adapters from Performance Technologies, Inc,
X *                 thanks to Peter Vernam <vernam@draper.com>
X * 
X * New in release 4.3:
X *         o 2.5.1 support.
X *         o FAS support.
X * 
X * New in release 4.2:
X *         o Solaris 2.5 support.
X *         o Generalized SCSI device querying.
X *         o Tape blocksize limits reported.
X * 
X * New in release 4.1:
X *         o ISP support more robust.
X *         o Workaround for a Solaris 2.3 kernel bug.
X * 
X * New in release 4.0:
X *         o ISP support for Solaris 2.x, thanks to
X *                 Calum Mackay <calum.mackay@uk.sun.com>
X *         o Code restructuring to support multiple host adapter types.
X *         o Support for loadable SCSI drivers, thanks to
X *                 Michael Lowry <mml@pupcyc2.Princeton.EDU>
X *         o Miscellaneous minor enhancements and bugfixes.
X */
END_OF_FILE
if test 2211 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
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'\" \(8158 characters\)
sed "s/^X//" >'scsiinfo.1' <<'END_OF_FILE'
X.TH scsiinfo 1 "$Date: 2000/10/20 20:43:04 $"
X.SH scsiinfo
Xscsiinfo \- obtain information about scsi devices attached to a Sun system (v4.7)
X.SH SYNOPSIS
X.B scsiinfo
X[
X.B \-VcopqsnO
X]
X.if n .ti +0.9i
X[
X.B -r\ raw_device
X]
X[
X.B -F\ raw_disk_device
X]
X.if n .ti +0.9i
X[
X.B -N\ 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, ISP, FAS, PLN and GLM device drivers, and the Performance 
XTechnologies PTISP device driver. For each target known to the SCSI host
Xadapter,
X.B scsiinfo
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, FAS, PLN, GLM, and
XPTISP devices, it indicates whether or not the target supports tagged
Xqueueing and/or wide SCSI transfers. When a target supports synchronous
Xtransfer, the negotiated maximum transfer rate (in MB/sec) is reported
X(except for PLN, where the driver does not keep track of the required 
Xinformation).
XFurthermore,
X.B scsiinfo
Xcan query all SCSI devices attached to supported controllers, for vendor, product, and revision 
Xinformation.  Moreover, 
X.B scsiinfo
Xcan query individual devices in greater detail, depending on the type of
Xdevice.  Finally,
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
XProvide controller information about the supported SCSI controllers on 
Xthe machine, in addition to SCSI device information. 
X.IP \fB\-V\fP
XPrint out 
X.B scsiinfo
Xversion and compilation 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 boot. 
X.IP \fB\-n\fP
XDo not output the line containing the Synchronous transfer rate, etc.
X.IP \fB\-O\fP
XBefore opening a device, check to see if another process is holding it open.
XIf so, do not attempt to open the device.
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. 
XIn addition, for every successfully
Xprobed device, 
X.B scsiinfo
Xreturns, in brackets, letter codes indicating which special SCSI features
Xare currently supported.  These are: 
X.B A
Xfor relative addressing,
X.B S
Xfor synchronous transfers,
X.B L
Xfor linked commands,
X.B T
Xfor tagged queueing,
Xand 
X.B R
Xfor soft reset.
XThis 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\-r\ raw_device\ \fP
XReport device information.  For disks, reports disk format and geometry 
Xinformation.  For tapes, report minimum and maximum block sizes.  
XA raw device (e.g. /dev/rsd0c or /dev/rdsk/c0t0d0s2) must be specified.
XThe special device
X.B all
Xtells
X.B scsiinfo
Xto output a report on all the devices that would be listed by \fB\-p\fP.
XThe use of 
X.B all
Xrequires the same privileges as for \fB\-p\fP.
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. The special device
X.B all
Xtells
X.B scsiinfo
Xto output a format.dat entry for all the devices that would be listed by \fB\-p\fP.  The use of 
X.B all
Xrequires the same privileges as for \fB\-p\fP.
X.IP \fB\-N\ raw_disk_device\ \fP
XProduce a notch report for the specified disk device.  Only works for 
Xcertain disks (e.g. some Seagates).  See
Xhttp://www.isi.edu/netstation/zcav/index.html for more information.
X.IP \fB\-o\fP
XWhen querying a SCSI device (using \fB\-r\fP or \fB\-F\fP), 
Xreport the original manufacturer's defined settings, instead of the settings
Xcurrently in effect. This is useful for unformatted (or incompatibly 
Xformatted) disks.  This option only has an effect if \fB\-r\fP or \fB\-F\fP
Xare specified.
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 (e.g. /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 and PTISP drivers do not
Xkeep track of this information, noisy ISP devices will not be reflected in 
Xthis result. 
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 SunOS 5.x (i.e. Solaris 2.x) was contributed by Calum Mackay 
X<calum.mackay@uk.sun.com>. Support for loadable SCSI device drivers 
Xunder SunOS 4.x was contributed by Michael Lowry <mml@pupcyc2.Princeton.EDU>.
XThe Notch reporting code was contributed by Rodney Van Meter 
X<rdv@alumni.caltech.edu>.  PTISP support was contributed by Peter Vernam 
X<vernam@draper.com>. PLN support was contributed by 
XJim Pirzyk <pirzyk@hotmail.com>.
X.SH LIMITATIONS
XOnly machines with Openboot proms are supported.  Only ESP
Xand PTISP host adapters are supported under SunOS 4.x
X.PP
XBecause the Sun ISP driver and the Performance Technologies PTISP driver 
Xdo not keep track of whether or not a specific device is noisy,
X.B scsiinfo
Xwill report 
X.B Unknown 
Xin that field for those devices. 
X.PP
XSCSI devices that do not have loaded drivers or have drivers that
Xdo not support Sun's user-mode SCSI interface cannot be probed by scsiinfo -p
Xor queried by scsiinfo -r.  In particular, tape drivers in versions
Xof SunOS before 5.5, and CD-ROM drivers before 5.0, do not support probing
Xor querying unless media is loaded.
XFurthermore, if some process is exclusively holding open a device,
X.B scsiinfo
Xwill not be able to probe it. This is often the case for CD-ROMs under the
Xcontrol of the Volume Management server (vold) in SunOS 5.2 or later,
Xor for disks under the control of the Veritas Volume Manager (e.g. on
Xan SSA connected to a PLN controller).
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 
Xrunning 
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
XWhen generating a format.dat entry, 
X.B scsiinfo
Xjust makes an educated guess for the bpt (bytes per track) figure, since it 
Xisn't possible to query the drive for this.
X.PP
X.B scsiinfo
Xis not capable of reporting a device's serial number under SunOS 4.x.
X.PP
XWhen queried for format and geometry information, some older disks drives do
Xnot report a value for rpm (rotations per minute); it was not required by the 
XSCSI-1 standard.
XWhen generating a format.dat entry,
X.B scsiinfo
Xwill assume an rpm of 3600.
X.PP
XQuerying for notch information is not supported on many drives.  Many models
Xof drive do not support it at all, or only partially.  In fact, even if
Xit works on a drive of a particular model, it may not work on all firmware 
Xrevisions of that model.
X.PP
XDifferent revisions of a given model of disk may have slightly
Xdifferent capacities.  If this is the case, an entry generated by 
X.B scsiinfo
Xon one disk may not work on another of the same model.
X.PP
XAs far as 
X.B scsiinfo
Xis concerned, 1 MB = 1000 KB, and 1GB = 1000000 KB.  While this can be
Xconfusing to those who expect 1MB to be 1024KB, and 1GB to be 1024MB, it is
Xthe industry convention for reporting disk sizes.
X.PP
X.B scsiinfo
Xhas nothing to do with the Linux program of the same name.
END_OF_FILE
if test 8158 -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'\" \(6139 characters\)
sed "s/^X//" >'scsiinfo.c' <<'END_OF_FILE'
X/*
X * scsiinfo.c - main src file.
X *
X * Author: John DiMarco, University of Toronto, CSLab <jdd@cs.toronto.edu>
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: scsiinfo.c,v 3.27 2000/03/30 22:06:36 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;		/* program name */
Xint d;			/* debugging */
Xint parameter = 0; 	/* for param.h */
Xkvm_t *kd; 		/* kernel file descriptor */
Xchar *osrelease;	/* for OS revision checking */
Xu_int devicecount = 0;	/* number of SCSI devices found */
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_SUPPORT
Xextern int process_esp();
X#endif /* ESP_SUPPORT */
X
X#ifdef ISP_SUPPORT
Xextern int process_isp();
X#endif /* ISP_SUPPORT */
X
X#ifdef FAS_SUPPORT
Xextern int process_fas();
X#endif /* FAS_SUPPORT */
X
X#ifdef PTISP_SUPPORT
Xextern int process_ptisp();
X#endif /* PTISP_SUPPORT */
X
X#ifdef GLM_SUPPORT
Xextern int process_glm();
X#endif /* GLM_SUPPORT */
X
X#ifdef PLN_SUPPORT
Xextern int process_pln();
X#endif /* PLN_SUPPORT */
X
X#ifdef NOTCH_REPORT
X#include "notch.h"
Xstatic int notchreport=0; /* Produce a notch report */
X#endif /* NOTCH_REPORT */
X
Xstatic int noisycount=0; /* number of noisy devices */
X
Xstatic void usage()
X{
X	fprintf(stderr, "\
XUsage: %s [-V][-o][-r device][-f diskdev][-F diskdev]%s\n\
X       [-c][-n][-s][-p][-q][-O][-K kernelimage][-C coreimage]\n",  progname, 
X#ifdef NOTCH_REPORT
X	"[-N diskdev]");
X#else /* !NOTCH_REPORT */
X	"");
X#endif /* !NOTCH_REPORT */
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	static struct utsname un;
X	static char *device=NULL;
X#ifdef NOTCH_REPORT
X	static char *notchdevice;
X#endif /* NOTCHREPORT */
X	char *kernelimage=NULL, *coreimage=NULL;
X
X	/* synch messages are on by default, unless -n flag */
X	set_param(P_SYNCH);
X
X	progname = argv[0];
X	while ((c = getopt(argc, argv, "VodcsnOpqr:f:F:N:K:C:")) != EOF)
X		switch (c) {
X		case 'V':
X			printf("%s\n", patchlevel);
X			printf("Compiled for SunOS %s:", 
X				SUNOS_VERSION[0]?SUNOS_VERSION:"?.?");
X#ifdef ESP_SUPPORT
X			printf(" ESP");
X#endif /* ESP_SUPPORT */
X#ifdef PTISP_SUPPORT
X			printf(" PTISP");
X#endif /* PTISP_SUPPORT */
X
X#ifdef SYSV
X	/* adapters below are only supported for SunOS 5.x */
X#ifdef ISP_SUPPORT
X			printf(" ISP");
X#endif /* ISP_SUPPORT */
X#ifdef FAS_SUPPORT
X			printf(" FAS");
X#endif /* FAS_SUPPORT */
X#ifdef GLM_SUPPORT
X			printf(" GLM");
X#endif /* GLM_SUPPORT */
X#ifdef PLN_SUPPORT
X			printf(" PLN");
X#endif /* PLN_SUPPORT */
X#ifdef __sparcv9
X			printf(" 64BIT");
X#endif /* __sparcv9 */
X#endif /* SYSV */
X
X#ifdef NOTCH_REPORT
X			printf(" NOTCH");
X#endif /* NOTCH_REPORT */
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 'n':
X			/* disable synch messages */
X			clear_param(P_SYNCH);
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.dat */
X			set_param(P_FORMATDAT);
X			/* fall thru */
X		case 'f': 
X		case 'r': 
X			/* output (format) report */
X			set_param(P_REPORT);
X			device=optarg;
X			break;
X#ifdef NOTCH_REPORT
X		case 'N': 
X			/* produce disk notch report */
X			notchreport++;
X			notchdevice=optarg;
X			break;
X#endif /* NOTCH_REPORT */
X		case 'K': 
X			/* kernel image */
X			kernelimage=optarg;
X			break;
X		case 'C': 
X			/* core image */
X			coreimage=optarg;
X			break;
X		case 'O':
X			/* check if something has device open before probing */
X			set_param(P_OPENCHECK);
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	osrelease=s(un.release);
X
X
X	/* generate format information if specified */
X	if(NULL!=device && !STREQ(device, "all")){
X		if(param_is_set(P_REPORT)){
X			report(param_is_set(P_FORMATDAT), osrelease, device, 
X					param_is_set(P_ORIGINAL));
X			exit(0);
X		} 
X	}
X#ifdef NOTCH_REPORT
X	if(notchreport){
X		report_notches(notchdevice);
X		exit(0);
X	}
X#endif /* NOTCH_REPORT */
X
X#ifndef SKIP_OSCHECK
X	/* quit if we have an OS or kernel architecture mismatch */
X	if(STREQ("", SUNOS_VERSION)){
X		Warning(
X		"WARNING: SUNOS_VERSION was not specified at compile time.");
X	} else {
X		if(!STREQ(SUNOS_VERSION, un.release)){
X			Warning(
X		  "WARNING: compiled for SunOS %s; this is SunOS %s. Results may be incorrect.",
X		      SUNOS_VERSION, un.release);
X		}
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#endif /* SKIP_OSCHECK */
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("kernel symbols read unsuccessful");
X        }
X
X	/* Now process the defined controllers */
X#ifdef ESP_SUPPORT
X	noisycount += process_esp();
X#endif /* ESP_SUPPORT */
X
X#ifdef ISP_SUPPORT
X	noisycount += process_isp();
X#endif /* ISP_SUPPORT */
X
X#ifdef FAS_SUPPORT
X	noisycount += process_fas();
X#endif /* FAS_SUPPORT */
X
X#ifdef PTISP_SUPPORT
X	noisycount += process_ptisp();
X#endif /* PTISP_SUPPORT */
X
X#ifdef GLM_SUPPORT
X	noisycount += process_glm();
X#endif /* GLM_SUPPORT */
X
X#ifdef PLN_SUPPORT
X	noisycount += process_pln();
X#endif /* PLN_SUPPORT */
X	return(noisycount);
X}
END_OF_FILE
if test 6139 -ne `wc -c <'scsiinfo.c'`; then
    echo shar: \"'scsiinfo.c'\" unpacked with wrong size!
fi
# end of 'scsiinfo.c'
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'\" \(2064 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.12 2000/02/24 21:41:07 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
X#define N_NPTISP 3
X#define N_PTISP_SOFTC 4
X
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#define SST_SUFFIX ""
X
Xextern void init_scsitarget();
Xextern int get_scsiaddr();
Xextern char *get_addr();
Xextern char *get_devicepath();
Xextern int opencheck();
X
X#ifdef ESP_SUPPORT
Xextern u_int get_nesp();
X#endif /* ESP_SUPPORT */
X
X#ifdef ISP_SUPPORT
X/* ISP controller not supported under SunOS 4.x */
X#undef ISP_SUPPORT
X#endif /* ISP_SUPPORT */
X
X#ifdef FAS_SUPPORT
X/* FAS controller not supported under SunOS 4.x */
X#undef FAS_SUPPORT
X#endif /* FAS_SUPPORT */
X
X#ifdef PTISP_SUPPORT
Xextern u_int get_nptisp();
X#endif /* PTISP_SUPPORT */
END_OF_FILE
if test 2064 -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'\" \(3822 characters\)
sed "s/^X//" >'sunos4.c' <<'END_OF_FILE'
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.5 2000/02/24 21:41:20 jdd Exp $
X */
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#ifndef SYSV
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	{ "_nptisp" },
X	{ "_ptisp_softc" },
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_SUPPORT
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_SUPPORT */
X
X#ifdef ISP_SUPPORT
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_SUPPORT */
X
X#ifdef FAS_SUPPORT
X/* Get number of FAS controllers */
Xu_int get_nfas(){
X	return(0); /* FAS controllers not supported under SunOS 4.x */
X}
X#endif /* FAS_SUPPORT */
X
X#ifdef PTISP_SUPPORT
X/* Get number of PTISP controllers */
Xu_int get_nptisp(){
X	u_int  nptisp;
X	if (N_UNDF == nl[N_NPTISP].n_type) {
X		return((u_int)0);
X	} else if(0>kvm(nl[N_NPTISP].n_value, nptisp)) {
X		Error("kvm_read: nptisp");
X	}
X	return(nptisp);
X}
X#endif /* PTISP_SUPPORT */
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}
Xint opencheck(devname)
Xchar *devname;
X{
X	/* 
X	 * Not implemented.  Implementation is straightforward, though:
X	 * convert the device name to a vnode, then grub around in the kernel,
X	 * looking through all the open files for this vnode.  
X         */
X	return(0);
X}
X#endif /* !SYSV */
END_OF_FILE
if test 3822 -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'\" \(3551 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.23 2000/02/24 21:40:51 jdd Exp $
X */
X
X#include <stdlib.h>
X#include <unistd.h>
X#include <string.h>
X#include <errno.h>
X#include <sys/map.h>
X#include <signal.h>
X
X/* 
X * The following includes are pretty messy.
X * 
X * We want some of the kernel-level definitions in sys/ddi.h and sys/sunddi.h
X * but they're not accessible in 2.5beta unless _KERNEL is defined.  And
X * cmn_err.h is included by sunddi.h, but if it's included with _KERNEL
X * defined, it defines prototypes for various functions that are incompatible
X * with the prototypes in stdio.h and stdlib.h.  So include it first, without
X * _KERNEL, so it'll be skipped later.  Also, there's a prototype for swab in
X * sunddi.h in 2.5beta that's incompatible with the one in stdlib, so we
X * redefine swab to something else.  Ditto for the str* routines in 2.1.
X */ 
X#include <sys/cmn_err.h>
X#ifndef _KERNEL
X#define _KERNEL
X#endif /* !_KERNEL */
X/* 
X * In solaris 2.6, with some versions of gcc, we need _LARGEFILE64_SOURCE
X * defined here, else there'll be parse errors in sys/resource.h (which is 
X * included  from sys/vnode.h, which is included from sys/stream.h, which is 
X * included from sys/ddi.h)
X */
X#ifdef _gcc_
XSYNTAX ERROR
X#ifndef _LARGEFILE64_SOURCE
X#define _LARGEFILE64_SOURCE
X#endif /* _LARGEFILE64_SOURCE */
X#endif /* _gcc_ */
X#include <sys/ddi.h>
X#define strcpy _badstrcpy
X#define strncpy _badstrncpy
X#define strchr _badstrchr
X#define strcmp _badstrcmp
X#define strncmp _badstrncmp
X#define swab _badswab  
X#include <sys/sunddi.h>
X#undef strcpy
X#undef strncpy
X#undef strchr
X#undef strcmp
X#undef strncmp
X#undef swab
X#undef _KERNEL
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
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
X#define N_FAS_HEAD 2
X#define N_PTISP_HEAD 3
X#define N_GLM_HEAD 4
X#define N_PLN_SOFTC 5
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#define SST_SUFFIX "character"
X
Xextern void init_scsitarget();
Xextern int get_scsiaddr();
Xextern char *get_addr();
Xextern char *get_devicepath();
Xextern int opencheck();
X#ifdef ESP_SUPPORT
Xextern u_int get_nesp();
X#endif /* ESP_SUPPORT */
X#ifdef ISP_SUPPORT
Xextern u_int get_nisp();
X#endif /* ISP_SUPPORT */
X#ifdef FAS_SUPPORT
Xextern u_int get_nfas();
X#endif /* FAS_SUPPORT */
X#ifdef PTISP_SUPPORT
Xextern u_int get_nptisp();
X#endif /* PTISP_SUPPORT */
X#ifdef GLM_SUPPORT
Xextern u_int get_nglm();
X#endif /* GLM_SUPPORT */
X#ifdef PLN_SUPPORT
Xextern u_int get_npln();
X#endif /* PLN_SUPPORT */
END_OF_FILE
if test 3551 -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'\" \(5796 characters\)
sed "s/^X//" >'sunos5.c' <<'END_OF_FILE'
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.11 2000/02/24 21:40:27 jdd Exp $
X */
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#include "common.h"
X#include "utils.h"
X#include <sys/utssys.h>
X
Xstruct nlist nl[]={
X        { "esp_softc" },
X	{ "isp_head" },
X	{ "fas_head" },
X	{ "ptisp_head" },
X	{ "glm_head" },
X	{ "pln_softc" },
X        { "" },
X};
X
Xstruct dev_info devi; /* device info from kernel, used in OS-dependent files */
X
X#ifdef ESP_SUPPORT
X/* Get number of ESP controllers */
Xu_int get_nesp(){
X        return((u_int)255);
X}
X#endif /* ESP_SUPPORT */
X
X#ifdef ISP_SUPPORT 
X/* Get number of ISP controllers */
Xu_int get_nisp(){
X        return((u_int)255);
X}
X#endif /* ISP_SUPPORT */
X
X#ifdef FAS_SUPPORT
X/* Get number of FAS controllers */
Xu_int get_nfas(){
X        return((u_int)255);
X}
X#endif /* FAS_SUPPORT */
X
X#ifdef PTISP_SUPPORT
X/* Get number of PTISP controllers */
Xu_int get_nptisp(){
X	if (!nl[N_PTISP_HEAD].n_type){
X		return((u_int)0);
X	} else {
X		return((u_int)255);
X	}
X}
X#endif /* PTISP_SUPPORT */
X
X#ifdef GLM_SUPPORT
X/* Get number of GLM controllers */
Xu_int get_nglm(){
X        return((u_int)255);
X}
X#endif /* GLM_SUPPORT */
X
X#ifdef PLN_SUPPORT
X/* Get number of PLN controllers */
Xu_int get_npln(){
X        return((u_int)255);
X}
X#endif /* PLN_SUPPORT */
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			/* 
X			 * If this name is "pci[0-9]*", there's a PCI address
X			 * in the name that we want to get rid of.  
X			 */
X#define 		PCI "pci"
X			if(0==strncmp(PCI, name, strlen(PCI)) &&
X					isdigit(name[strlen(PCI)])){
X				name[strlen(PCI)]='\0'; 
X			}
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	if(0>access(devicepath, F_OK) && errno==ENOENT){
X		/* 
X		 * Devicepath doesn't work.  We need to apply a kludge
X		 * or two.  The PCI GLM driver replaces "glm" (for U5/10)
X		 * or the 2nd occurrence of "pci" (for U250/U450) with "scsi";
X		 * Rather than try to keep track of the (inconsistent)
X		 * differences between various Ultras, we'll just stroll along
X		 * devicepath until we find out where it stops working, and
X		 * replace the problematic component with "scsi".
X		 */
X		char *newpath = cat("/", strtok(devicepath, "/"), NULL);
X		while(NULL!=(cp=strtok(NULL, "/"))){
X			char *testpath = cat(newpath, "/", cp, NULL);
X			if(0>access(testpath, F_OK) && errno==ENOENT){
X				/* 
X				 * Testpath doesn't work -- fix this 
X				 * component.  
X				 */
X				char *f = newpath;
X				newpath=cat(newpath, "/scsi", strchr(cp, '@'), 
X					NULL);
X				free(f);
X				free(testpath);
X			} else {
X				/* component is ok; testpath is good */
X				free(newpath);
X				newpath=testpath;
X			}
X		}
X		{ char *f = devicepath; devicepath = newpath; free(f); }
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
X/* 
X * opencheck() -- check to see if some other process has the specified 
X * device open.  This is a front end to the utssys() system call. 
X */
Xint opencheck(devname)
Xchar *devname;
X{
X	/* if the device doesn't exist, clearly nobody is holding it open... */
X	if(0>access(devname, F_OK)) return(0);
X
X        /*
X         * Use utssys (undocumented back-end for fuser in Solaris)
X         * which takes a filename, a couple of flags (see sys/utssys.h) and a
X         * buffer to store returned info. It only tries to use the buffer if
X         * there's info to return; if we pass it a NULL buffer it'll return
X         * EFAULT if it tries to use it, so a simple check to see if someone is
X         * holding open the device is to simply do the following and check if
X         * EFAULT error.
X         */
X        if(0>utssys(devname,F_FILE_ONLY,UTS_FUSERS, NULL)){
X       		if(EFAULT==errno) return(1);
X                return(-1);
X	}
X	return(0);
X}
X
X#endif /* SYSV */
END_OF_FILE
if test 5796 -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'\" \(606 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.3 2000/01/25 13:58:53 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 SSADISK "ssd"
X#define SUNTAPE "st"
X#define SUNSST "sst"
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 606 -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'\" \(4222 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.10 2000/01/25 13:58:53 jdd Exp $";
X#endif
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	char *bp;
X
X	/* 
X	 * Get one byte at a time until buffsize or null byte.  Otherwise
X	 * this can trigger a bug in the kernel and cause a system panic.
X	 */
X	for(bp=buff;bp<(buff+BUFFSIZE);bp++){
X		if(-1==kvm_read(kd, address+(bp-buff), bp, sizeof(char))){
X			Error("kvmstr");
X		}
X		if('\0'==*bp) break;
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.%.3d 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(device, devicename, lun)
Xchar *device, *devicename;
Xint lun;
X{
X#ifdef SKIP_EPOCH
X				/* Do not attempt to probe any Epoch/EMC     *
X				 * library-unit devices (they can hard-hang).*/
X				if (STREQ("ss", device) ||
X				    STREQ("mo", device) ||
X				    STREQ("sj", device) ||
X				    STREQ("ds", device)) 
X				       return;
X#endif /* SKIP_EPOCH */
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) || STREQ(SSADISK, 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 if(STREQ(SUNSST, dname)) {
X		/*
X		 * This is Sun's simple SCSI target driver, which is used by 
X		 * various folk for miscellaneous devices.
X		 * 
X		 * We want to query the character device,
X		 * e.g. rsst0 or sst@0,0:character
X		 */
X		devicename = cat(
X			devicepath, "/", 
X			DEV_PREFIX,
X			dname, DEV_INFIX, 
X			addrname, 
X			DEV_SUFFIX, SST_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 4222 -ne `wc -c <'common.c'`; then
    echo shar: \"'common.c'\" unpacked with wrong size!
fi
# end of 'common.c'
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'\" \(7565 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.15 2001/07/16 15:49:25 jdd Exp $";
X#endif
X
X#ifdef ESP_SUPPORT
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/scsi_address.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
X/*  
X * SunOS 5.6 got rid of e_targets, so use e_target_scsi_options_defined
X * instead.  We see if we're running 5.6 by checking for 
X * ESP_OPT_SLOW_FIFO_FLUSH which first showed up in 5.6.
X */
X#ifdef ESP_OPT_SLOW_FIFO_FLUSH
X#define e_targets e_target_scsi_options_defined
X#ifndef ESP_TRUSTING
X#define ESP_TRUSTING /* e_target_scsi_options_defined is often zero */
X#endif /* ESP_TRUSTING */
X#endif /* ESP_OPT_SLOW_FIFO_FLUSH */
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#ifndef ESP_TRUSTING
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 
X#endif /* ESP_TRUSTING */
X	if(speed && (esp->e_sync_known & (1<<i))){
X		printf("Synchronous(%d.%.3dMB/sec)", speed/1000, speed%1000);
X	} else {
X		printf("Asynchronous");
X	}
X#ifndef ESP_TRUSTING
X	if(esp->e_weak & ~(esp->e_targets)) {
X		/* again, don't believe e_weak if mentions unprobed targets */
X		printf(" Unknown");
X	} else 
X#endif /* ESP_TRUSTING */
X	if(esp->e_weak & (1<<i)){
X		printf(" Noisy");
X	} else {
X		printf(" Clean");
X	}
X#ifndef ESP_TRUSTING
X	if(esp->e_nodisc & ~(esp->e_targets)) {
X		/* don't believe e_nodisc if it mentions unprobed targets */
X		printf(" Unknown");
X	} else 
X#endif /* ESP_TRUSTING */
X	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];
X
X#ifdef OLD_SUNOS
X	struct esp *esp_softc, *esp_p;
X#endif /* OLD_SUNOS */
X
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
X#ifdef OLD_SUNOS
X	esp_softc=esp_p=(struct esp *)addr;
X#endif /* OLD_SUNOS */
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		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			devicecount++;
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			devicename = compute_devicename(dname, 
X						devicepath, addrname);
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			banner(param_is_set(P_FORMATDAT),
X				param_is_set(P_REPORT), devicecount);
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("esp%d: %s%s tgt %d lun %d:\n", 
X						CNUM, dname, addrname, 
X						target, lun);
X					if(param_is_set(P_SYNCH)){
X						printf("\t");
X						esp_synch_message(esp, target, 
X						 esp_get_speed(esp, target));
X						printf("\n");
X					}
X				}
X			} 
X			if(param_is_set(P_PROBE)) {
X				do_scsi_probe(dname, devicename, lun);
X			}
X			if(param_is_set(P_REPORT)){
X				report(param_is_set(P_FORMATDAT), 
X					osrelease, devicename,
X					param_is_set(P_ORIGINAL));
X			}
X			free(devicename);
X			free(addrname);
X			free(dname);
X		}
X
X		free(devicepath);
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_SUPPORT */
END_OF_FILE
if test 7565 -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'\" \(7214 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, Sun Microsystems
X *                 <calum.mackay@uk.sun.com>
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: isp.c,v 1.19 2001/07/17 17:13:02 jdd Exp $";
X#endif
X
X#ifdef ISP_SUPPORT
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#ifndef ISP_20M_SYNC_PERIOD
X#define ISP_20M_SYNC_PERIOD     0x000C
X#endif /* ISP_20M_SYNC_PERIOD */
X#if defined(ISP_FROM_INTR)
X/* Changes in revision info in ispvar.h between 1.82 and 1.83 */
X#ifdef isp_major_rev
X#undef isp_major_rev
X#endif /* isp_major_rev */
X#define isp_major_rev isp_maj_min_rev / 256
X#ifdef isp_minor_rev
X#undef isp_minor_rev
X#endif /* isp_minor_rev */
X#define	isp_minor_rev isp_maj_min_rev % 256
X#endif /* ISP_OLD_SIZE */
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
Xtypedef struct {
X        int     period;         /* ISP_xM_SYNC_PERIOD */
X        int     speed;          /* x000 */
X} isp_speed_mapping;
X
Xstatic isp_speed_mapping isp_speed[] = {
X        ISP_20M_SYNC_PERIOD, 20000,
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 5      /* Number of elements in isp_speed[] */
X};
X
Xstatic u_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((u_int)-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 (u_int)-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.%.3dMB/sec)",
X					(width/8)*speed/1000, 
X					(width/8)*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(" TaggedQueuing");
X	} else {
X		printf(" NoTaggedQueuing");
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#ifdef SCSI_HBA_TRAN_CLONE
X		{
X			scsi_hba_tran_t tran;
X			/* 
X			 * Grab the transport devinfo structure for the isp 
X			 * controller. Needed for CNUM. 
X			 */
X			if(-1==kvm((u_long)isp->isp_tran, tran)){
X				Error("kvm read: #%d isp tran", j);
X			}
X			isp->isp_tran=(scsi_hba_tran_t *)&tran; 
X			if(-1==kvm((u_long)isp->isp_tran->tran_hba_dip, devi)){
X				Error("kvm read: #%d isp devinfo", j);
X			}
X			isp->isp_tran->tran_hba_dip=(dev_info_t *)&devi;
X		}
X#else /* !SCSI_HBA_TRAN_CLONE */
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		isp->isp_dip=(dev_info_t)&devi; /* for CNUM */
X#endif /* !SCSI_HBA_TRAN_CLONE */
X
X		devicepath = get_devicepath(j);
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			devicecount++;
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			devicename = compute_devicename(dname, 
X						devicepath, addrname);
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			banner(param_is_set(P_FORMATDAT), 
X				param_is_set(P_REPORT), devicecount);
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("isp%d: %s%s tgt %d lun %d:\n", 
X						CNUM(isp), dname, addrname, 
X						target, lun);
X					if(param_is_set(P_SYNCH)){
X						printf("\t");
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_REPORT)){
X				report(param_is_set(P_FORMATDAT), 
X					osrelease, devicename,
X					param_is_set(P_ORIGINAL));
X			}
X			if(param_is_set(P_PROBE)){
X				do_scsi_probe(dname, devicename, lun);
X			}
X			free(devicename);
X			free(addrname);
X			free(dname);
X		}
X		free(devicepath);
X                addr=(u_long)isp->isp_next;
X	}
X
X	return(noisycount);
X
X}
X#else /* !SYSV */
X/* ISP isn't supported on SunOS 4.x */
Xint process_isp(){}
X#endif /* !SYSV */
X#endif /* ISP_SUPPORT */
END_OF_FILE
if test 7214 -ne `wc -c <'isp.c'`; then
    echo shar: \"'isp.c'\" unpacked with wrong size!
fi
# end of 'isp.c'
fi
if test -f 'fas.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fas.c'\"
else
echo shar: Extracting \"'fas.c'\" \(6576 characters\)
sed "s/^X//" >'fas.c' <<'END_OF_FILE'
X/*
X * fas.c  -  process FAS 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: fas.c,v 1.8 1999/04/22 17:40:16 jdd Exp $";
X#endif
X
X#ifdef FAS_SUPPORT
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#ifdef SYSV
X#include "sunos5.h"
X#include <sys/scsi/adapters/fasreg.h>
X#include <sys/scsi/adapters/fasvar.h>
X
X#undef SYNC_KNOWN
X#undef NODISC
X#undef NOTAG
X#undef NOWIDE
X#undef NOISY
X
X#ifndef SYNC_KNOWN
X#define SYNC_KNOWN(i) (fas->f_sync_known & (1<<(i)))
X#endif /* SYNC_KNOWN */
X
X#ifdef notdef	/* f_nodisc doesn't exit */
X#ifndef NODISC
X#define NODISC(i) (fas->f_nodisc & (1<<(i)))
X#endif /* NODISC */
X#endif /* notdef */
X
X#ifndef NOTAG
X#define NOTAG(i) (fas->f_notag & (1<<(i)))
X#endif /* NOTAG */
X
X#ifndef NOWIDE
X#define NOWIDE(i) (fas->f_nowide & (1<<(i)))
X#endif /* NOWIDE */
X
X#ifndef NOISY
X#define NOISY(i) (fas->f_backoff & (1<<(i)))
X#endif /* NOISY */
X
X/* 
X * The following is a sanity check. It makes no sense if the same device
X * is both sync and nosync, or both wide and nowide.
X */
X#ifndef INSANE
X#define INSANE ((fas->f_sync_enabled & fas->f_nosync) || (fas->f_wide_enabled & fas->f_nowide))
X#endif /* INSANE */
X
Xstatic char *fasType(typecode)
Xunsigned int typecode;
X{
X	/* see /usr/include/sys/scsi/adapters/fasreg.h */
X	switch(typecode){
X	case 0:		return("FAS366");
X	case 5:		return("FAST");
X	default:	return("unknown");
X	}
X}
X
Xstatic u_int fas_get_speed(fas, i)
Xstruct fas *fas;
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. fas_clock_conv is the
X	 * fas's tick rate in units of 5MHz.
X	 */
X	cycletime = fas->f_clock_conv ? (fas->f_sync_period[i] *
X			(1000/(int)(5*fas->f_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	if(!NOWIDE(i)) speed *= 2;
X
X#ifdef DEBUG
X        dfprintf(2, stderr, "Target %d: clock %u, minperiod %u, nowide %u\n",
X		i, fas->f_clock_conv, fas->f_sync_period[i], NOWIDE(i));
X#endif /* DEBUG */
X
X	return(speed);
X}
X
Xstatic void fas_controller_message(cnum, fas)
Xint cnum;
Xstruct fas *fas;
X{
X	printf("fas%d:", cnum);
X	printf(" type %d (%s)", (u_int)fas->f_type,
X		fasType(fas->f_type));
X	printf(" speed %dMHz", (u_int)fas->f_clock_conv*5);
X	printf("\n");
X}
X
Xstatic void fas_synch_message(fas, i, speed)
Xstruct fas *fas;
Xint i;
Xu_int speed;
X{
X	if(speed && SYNC_KNOWN(i)){
X		printf("Synchronous(%d.%.3dMB/sec)", speed/1000, speed%1000);
X	} else {
X		printf("Asynchronous");
X	}
X	if(NOISY(i)){
X		printf(" Noisy");
X	} else {
X		printf(" Clean");
X	}
X#ifdef notdef
X	if(NODISC(i)){
X		printf(" CannotReconnect");
X	} else {
X		printf(" CanReconnect");
X	}
X#endif /* notdef */
X	if(NOTAG(i)){
X		printf(" NoTaggedQueuing");
X	} else {
X		printf(" TaggedQueuing");
X	}
X	if(NOWIDE(i)){
X		printf(" Narrow");
X	} else {
X		printf(" Wide");
X	}
X}
X
Xint process_fas()
X{
X	u_long addr;
X	struct fas fas[1];
X	int noisycount=0; /* number of noisy devices */
X	u_int j, nfas;
X
X        if(-1==kvm(nl[N_FAS_HEAD].n_value, addr)){
X		return(0); /* fas driver not loaded */
X        }
X        if((u_long)NULL==addr) return(0); /* no fas's */
X
X        if(-1==kvm(addr, fas[0])){
X                Error("kvm read: initial fas");
X        }
X
X	nfas=get_nfas();
X	if(0==nfas) return(0);
X
X	for(j=0;j<nfas;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, fas[0])){
X			Error("kvm read: fas #%d", j);
X		}
X
X		/* 
X		 * grab the devinfo structure for the fas controller. CNUM 
X		 * requires it, and we need it to determine the device names.
X		 */
X		if(-1==kvm(fas->f_dev, devi)){
X			Error("kvm read: #%d fas devinfo", j);
X		} 
X
X		devicepath = get_devicepath(j);
X
X		fas->f_dev=(dev_info_t)&devi; 
X
X#ifdef INSANE
X                if(INSANE){
X                        Warning(
X"The kernel data structure for fas%d failed a sanity check.\n\
X  There may be a mismatch between the compile-time headers and the currently\n\
X  running kernel.  A recompile on this machine may be necessary.", CNUM);
X                }
X#endif /* INSANE */
X
X
X		if(param_is_set(P_CONTROLLER)) {
X			fas_controller_message(CNUM, fas);
X		}
X
X		init_scsitarget();
X
X		/* 
X		 * Now, traverse fas'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 fas devinfo child", j);
X			}
X
X			if(!DDI_CF2(&di)) continue; /* no device attached */
X
X			devicecount++;
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			devicename = compute_devicename(dname, 
X						devicepath, addrname);
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			if(0==lun && NOISY(target)) noisycount++;
X
X			banner(param_is_set(P_FORMATDAT), 
X				param_is_set(P_REPORT), devicecount);
X			if(!param_is_set(P_QUIET)){
X				if(param_is_set(P_SUNOS4STYLE)) {
X					if(lun==0){
X						boot_synch_message("fas",
X							CNUM, target, 
X							fas_get_speed(fas, 
X								target), 
X								NARROW);
X					}
X				} else {
X					printf("fas%d: %s%s tgt %d lun %d:\n", 
X						CNUM, dname, addrname, 
X						target, lun);
X					if(param_is_set(P_SYNCH)){
X						printf("\t");
X						fas_synch_message(fas, target, 
X						 fas_get_speed(fas, target));
X						printf("\n");
X					}
X				}
X			}
X			if(param_is_set(P_PROBE)) {
X				do_scsi_probe(dname, devicename, lun);
X			}
X			if(param_is_set(P_REPORT)) {
X				report(param_is_set(P_FORMATDAT),
X					osrelease, devicename,
X					param_is_set(P_ORIGINAL));
X			}
X			free(devicename);
X			free(addrname);
X			free(dname);
X		}
X
X		free(devicepath);
X
X                addr=(u_long)fas->f_next;
X
X	}
X	return(noisycount);
X}
X
X#else /* !SYSV */
X/* FAS isn't supported on SunOS 4.x */
Xint process_fas(){}
X#endif /* SYSV */
X#endif /* FAS_SUPPORT */
END_OF_FILE
if test 6576 -ne `wc -c <'fas.c'`; then
    echo shar: \"'fas.c'\" unpacked with wrong size!
fi
# end of 'fas.c'
fi
if test -f 'ptisp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ptisp.c'\"
else
echo shar: Extracting \"'ptisp.c'\" \(9063 characters\)
sed "s/^X//" >'ptisp.c' <<'END_OF_FILE'
X/*
X * ptisp.c  -  process PTISP host adapters.
X *
X * Author: Peter Vernam, Draper Laboratory <vernam@draper.com>
X * 
X * This module was adapted from John DiMarco's (University of Toronto, CDF
X * <jdd@cdf.toronto.edu>) esp.c and isp.c modules to provide support for the
X * Performance Technologies (315 Science Parkway, Rochester, NY 14620;
X * 716-256-0248) ptisp driver and host adapter.
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: ptisp.c,v 1.11 2000/01/26 16:05:15 jdd Exp $";
X#endif
X
X#ifdef PTISP_SUPPORT
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
Xtypedef struct {
X	int     period;         /* ISP_xM_SYNC_PERIOD */
X	int     speed;          /* x000 */
X} isp_speed_mapping;
X
X
X#ifdef SYSV
X#include "sunos5.h"
X#ifndef VERS_ACCHDL
X	/* 
X	 * ddi_acc_handle_t is used in ispvar5.h, but not defined
X	 * under Solaris 2.4. Since the include file in 2.5 that defines
X	 * it also defines VERS_ACCHDL, if VERS_ACCHDL isn't defined, we'd
X	 * better define it before including ispvar5.h.
X	 */
Xtypedef void *ddi_acc_handle_t;
X#endif /* VERS_ACCHDL */
X
X#include "ptisp/ispmail5.h"
X#ifndef SCSI_HBA_TRAN_CLONE
X#define scsi_hba_tran_t struct scsi_transport
X#define NTARGETS_WIDE 15
X#endif /* SCSI_HBA_TRAN_CLONE */
X#include "ptisp/ispvar5.h"
X
X#define TEN_M ISP_10M_SYNC_PERIOD
X#define EIGHT_M ISP_8M_SYNC_PERIOD
X#define FIVE_M ISP_5M_SYNC_PERIOD
X#define FOUR_M ISP_4M_SYNC_PERIOD
X
X#define PTISP_SYNC isp_synch
X#define PTISP_CAP isp_cap
X#define PTISP_MAJOR_REV isp_major_rev
X#define PTISP_MINOR_REV isp_minor_rev
X#define PTISP_DIFFMODE ptisp_diffmode
X#define PTISP_DEV isp_dip
X
X#define N_PTISP_SYMBOL N_PTISP_HEAD
X
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#ifdef SCSI_HBA_TRAN_CLONE
X#define CNUM		(ddi_get_instance(ptisp->isp_tran->tran_hba_dip))
X#else /* SCSI_HBA_TRAN_CLONE */
X#define CNUM		(ddi_get_instance(ptisp->isp_tran->tran_dev))
X#endif /* SCSI_HBA_TRAN_CLONE */
X
X#else /* !SYSV */
X#include <scsi/scsi_types.h>
X#include <scsi/impl/transport.h>
X#include "sunos4.h"
X#include "ptisp/ispmail4.h"
X#include "ptisp/ptisp4.h"
X
X#define TEN_M ISP_CAP_10M_SYNC_PERIOD
X#define EIGHT_M ISP_CAP_8M_SYNC_PERIOD
X#define FIVE_M ISP_CAP_5M_SYNC_PERIOD
X#define FOUR_M ISP_CAP_4M_SYNC_PERIOD
X
X#define PTISP_SYNC sync
X#define PTISP_CAP cap
X#define PTISP_MAJOR_REV major_rev
X#define PTISP_MINOR_REV minor_rev
X#define PTISP_DIFFMODE diffmode
X#define PTISP_DEV dev
X
X#define N_PTISP_SYMBOL N_PTISP_SOFTC
X
X#define PERIOD_MASK(val)	((val) & 0xff)
X#undef CNUM
X#define CNUM			(ptisp->unit_no)
X
X#endif /* !SYSV */
X
Xstatic isp_speed_mapping isp_speed[] = {
X#ifdef USE_SUN_ISP_SPEEDS
X	TEN_M, 		10000,
X	EIGHT_M,   	8000,
X	FIVE_M,   	5000,
X	FOUR_M,   	4000
X#define ISP_PERIOD_TABLE 4      /* Number of elements in isp_speed[] */
X#else /* !USE_SUN_ISP_SPEEDS */
X	0x0c, 		20000,
X	0x10, 		15000,
X	0x15, 		12000,
X	0x19, 		10000,
X	0x1e,  		8000,
X	0x21,  		7000,
X	0x25,  		6500,
X	0x2a,  		6000,
X	0x2d,  		5500,
X	0x32,  		5000,
X	0x38,  		4500,
X	0x3a,  		4000,
X	0x42,  		3000
X#define ISP_PERIOD_TABLE 13     /* Number of elements in isp_speed[] */
X#endif /* !USE_SUN_ISP_SPEEDS */
X};
X
X
Xstatic u_int ptisp_get_speed(ptisp, i)
Xstruct ptisp *ptisp;
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(ptisp->PTISP_SYNC[i])){
X			return(isp_speed[index].speed);
X		}
X	}
X	return((u_int)-1);
X}
X
Xstatic void ptisp_synch_message(ptisp, i, speed)
Xstruct ptisp *ptisp;
Xint i;
Xu_int speed;
X{
X	int width = NARROW;
X	u_short ptisp_cap = ptisp->PTISP_CAP[i];
X	if(ptisp_cap & ISP_CAP_WIDE) width = WIDE;
X
X	switch (speed) {
X		case (u_int)-1 :
X			if ( ptisp_cap & 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 && (ptisp_cap & ISP_CAP_SYNC)){
X				printf("Synchronous(%d.%.3dMB/sec)",
X					(width/8)*speed/1000, 
X					(width/8)*speed%1000);
X			}
X			else {
X				printf("Asynchronous"); 
X			}
X			break;
X	}
X	printf(" Unknown"); /* ptisp driver doesn't keep track of errors */
X	if(ptisp_cap & ISP_CAP_DISCONNECT){
X		printf(" CanReconnect");
X	} else {
X		printf(" CannotReconnect");
X	}
X	if(ptisp_cap & ISP_CAP_TAG){
X		printf(" TaggedQueuing");
X	} else {
X		printf(" NoTaggedQueuing");
X	}
X	if(width == WIDE){
X		printf(" Wide");
X	} else {
X		printf(" Narrow");
X	}
X}
X
Xstatic void ptisp_controller_message(cnum, ptisp)
Xint cnum;
Xstruct ptisp *ptisp;
X{
X	printf("ptisp%d:", cnum);
X	printf(" PTI/QLGC ISP 1000" );
X	printf(" firmware revision %d.%d", (int) ptisp->PTISP_MAJOR_REV,
X		(int) ptisp->PTISP_MINOR_REV );
X	if(ptisp->PTISP_DIFFMODE) {
X		printf(", Differential");
X	} else {
X		printf(", Single-ended");
X	}
X	printf("\n");
X}
X
Xint process_ptisp()
X{
X	u_long addr;
X	struct ptisp ptisp[1];
X	u_int j, nptisp;
X	int noisycount=0;
X#ifndef SYSV
X	struct ptisp *ptisp_softc, *ptisp_p;
X#endif /* !SYSV */
X	if (!nl[N_PTISP_SYMBOL].n_type) {
X		return(0); /* ptisp driver not loaded */
X	}
X
X	if(-1==kvm(nl[N_PTISP_SYMBOL].n_value, addr)){
X		return(0); /* ptisp driver not loaded */
X	}
X
X	if((u_long)NULL==addr) return(0); /* no ptisp's */
X
X        if(-1==kvm(addr, ptisp[0])){
X		Error("kvm read: initial ptisp");
X	}
X
X#ifndef SYSV
X	ptisp_softc = ptisp_p = (struct ptisp *)addr;
X#endif /* !SYSV */
X
X	nptisp=get_nptisp();
X	if(0==nptisp) return(0);
X
X	for(j=0;j<nptisp;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, ptisp[0])){
X			Error("kvm read: ptisp #%d", j);
X		}
X
X#ifdef SCSI_HBA_TRAN_CLONE
X		{
X			scsi_hba_tran_t tran;
X			/* 
X			 * Grab the transport devinfo structure for the ptisp 
X			 * controller. Needed for CNUM. 
X			 */
X			if(-1==kvm((u_long)ptisp->isp_tran, tran)){
X				Error("kvm read: #%d ptisp tran", j);
X			}
X			ptisp->isp_tran=(scsi_hba_tran_t *)&tran; 
X			if(-1==kvm((u_long)ptisp->isp_tran->tran_hba_dip, 
X					devi)){
X				Error("kvm read: #%d ptisp devinfo", j);
X			}
X			ptisp->isp_tran->tran_hba_dip=(dev_info_t *)&devi;
X		}
X#else /* !SCSI_HBA_TRAN_CLONE */
X		/* 
X		 * grab the devinfo structure for the ptisp controller. CNUM 
X		 * requires it, and we need it to determine the device names.
X		 */
X		if(-1==kvm((u_long)ptisp->PTISP_DEV, devi)){
X			Error("kvm read: #%d ptisp devinfo", j);
X		}
X		ptisp->PTISP_DEV=(dev_info_t)&devi; /* for CNUM */
X#endif /* !SCSI_HBA_TRAN_CLONE */
X
X		devicepath = get_devicepath(j);
X
X		if(param_is_set(P_CONTROLLER)) {
X			ptisp_controller_message(CNUM, ptisp);
X		}
X
X		init_scsitarget();
X
X		/* 
X		 * Now, traverse ptisp'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 ptisp devinfo child", j);
X			}
X
X			if(!DDI_CF2(&di)) continue; /* no device attached */
X
X			devicecount++;
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			devicename = compute_devicename(dname, 
X						devicepath, addrname);
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			banner(param_is_set(P_FORMATDAT), 
X				param_is_set(P_REPORT), devicecount);
X			if(!param_is_set(P_QUIET)){
X				if(param_is_set(P_SUNOS4STYLE)) {
X					if(lun==0){
X						boot_synch_message("ptisp",
X							CNUM, target, 
X						  	ptisp_get_speed(ptisp,
X								target),
X								WIDE);
X					}
X				} else {
X					printf(
X					     "ptisp%d: %s%s tgt %d lun %d:\n",
X						CNUM, dname, addrname, 
X						target, lun);
X					if(param_is_set(P_SYNCH)){
X					    printf("\t");
X					    ptisp_synch_message(ptisp, target, 
X					     ptisp_get_speed(ptisp, target));
X					    printf("\n");
X					}
X				}
X			}
X
X
X			if(param_is_set(P_REPORT)){
X				report(param_is_set(P_FORMATDAT), 
X					osrelease, devicename,
X					param_is_set(P_ORIGINAL));
X			}
X			if(param_is_set(P_PROBE)){
X				do_scsi_probe(dname, devicename, lun);
X			}
X			free(devicename);
X			free(addrname);
X			free(dname);
X		}
X		free(devicepath);
X#ifdef SYSV
X                addr=(u_long)ptisp->isp_next;
X#else
X                addr=(u_long)(++ptisp_p);
X#endif
X	}
X
X	return(noisycount);
X
X}
X
X#endif /* PTISP_SUPPORT */
END_OF_FILE
if test 9063 -ne `wc -c <'ptisp.c'`; then
    echo shar: \"'ptisp.c'\" unpacked with wrong size!
fi
# end of 'ptisp.c'
fi
if test -f 'glm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'glm.c'\"
else
echo shar: Extracting \"'glm.c'\" \(7280 characters\)
sed "s/^X//" >'glm.c' <<'END_OF_FILE'
X/*
X * glm.c  -  process GLM host adapters.
X *
X * Author: John DiMarco, University of Toronto, CSLab
X *         jdd@cs.toronto.edu
X * 
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: glm.c,v 1.11 2000/12/22 14:05:35 jdd Exp $";
X#endif
X
X#ifdef GLM_SUPPORT
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#ifdef SYSV
X#include "sunos5.h"
X
X#ifdef _NOTE
X#undef _NOTE
X#endif /* _NOTE */
X#define _NOTE(x) 
X
X#include <sys/scsi/adapters/glmreg.h>
X#include <sys/scsi/adapters/glmvar.h>
X
X
X#ifndef CNUM
X#define CNUM(glm)      (ddi_get_instance(glm->g_tran->tran_hba_dip))
X#endif /* CNUM */
X
X#undef SYNC_KNOWN
X#undef NOWIDE
X#undef NOISY
X#undef NEXT
X
X#ifndef SYNC_KNOWN
X#define SYNC_KNOWN(i) ((glm->g_syncstate[i])==NSYNC_SDTR_DONE)
X#endif /* SYNC_KNOWN */
X
X#ifndef NOWIDE
X#define NOWIDE(i) (glm->g_nowide & (1<<(i)))
X#endif /* NOWIDE */
X
X#ifndef NOISY
X#define NOISY(i) (glm->g_backoff & (1<<(i)))
X#endif /* NOISY */
X
X#ifndef NEXT
X#define NEXT(g) ((u_long)(g)->g_next)
X#endif /* NEXT */
X
X/* 
X * The following is a sanity check.  We know there are no glms of type 0,
X * so if glm->g_devid is zero, it's very likely that the kernel data 
X * structure we're looking at isn't what we think it is, and hence our 
X * results are bogus.  Similarly, if the clock of the controller isn't 
X * 10Mhz x Power-of-2, it's likely bogus.
X * 
X */
X#ifndef INSANE
X#define INSANE (0==glm->g_devid) || (	(10!=glm->g_sclock) && \
X					(20!=glm->g_sclock) && \
X					(40!=glm->g_sclock) && \
X					(80!=glm->g_sclock) && \
X					(160!=glm->g_sclock) && \
X					(320!=glm->g_sclock) )
X#endif /* INSANE */
X
Xstatic char *glmType(typecode)
Xunsigned int typecode;
X{
X	/* see /usr/include/sys/scsi/adapters/glmreg.h */
X	switch(typecode){
X	case GLM_53c825:		return("NCR53C825");
X	case GLM_53c875:		return("NCR53C875");
X	default:	return("unknown");
X	}
X}
X
Xstatic u_int glm_get_speed(glm, i)
Xstruct glm *glm;
Xint i; /* target index */
X{
X	u_int speed;
X
X	/*
X	 * Synch cycle time in milliseconds is the
X	 * number of ticks in the period divided
X	 * by the tick rate. glm_sclock is the
X	 * glm's tick rate in units of 1MHz.
X	 */
X
X	/* 
X         * We don't seem to need to worry about the clock anymore; the
X	 * period seems to indicate the number of nanoseconds per xfer 
X	 * (where xfer is one byte for narrow, two bytes for wide) 
X         */
X
X	speed = glm->g_minperiod[i]?(1000000/glm->g_minperiod[i]):0;
X
X	if(!NOWIDE(i)) speed *= 2;
X
X#ifdef DEBUG
X	dfprintf(2, stderr, "Target %d: sclock %u, minperiod %u, nowide %u\n",
X			i, glm->g_sclock, glm->g_minperiod[i], NOWIDE(i));
X#endif /* DEBUG */
X
X	return(speed);
X}
X
Xstatic void glm_controller_message(cnum, glm)
Xint cnum;
Xstruct glm *glm;
X{
X	printf("glm%d:", cnum);
X	printf(" type %d (%s)", (u_int)glm->g_devid,
X		glmType(glm->g_devid));
X	printf(" speed %dMHz", (u_int)glm->g_sclock);
X	printf("\n");
X}
X
Xstatic void glm_synch_message(glm, i, speed)
Xstruct glm *glm;
Xint i;
Xu_int speed;
X{
X	if(speed && SYNC_KNOWN(i)){
X		printf("Synchronous(%d.%.3dMB/sec)", speed/1000, speed%1000);
X	} else {
X		printf("Asynchronous");
X	}
X	if(NOISY(i)){
X		printf(" Noisy");
X	} else {
X		printf(" Clean");
X	}
X#ifdef TAGGED
X        if(TAGGED(i)){
X                printf(" TaggedQueuing");
X        } else {
X                printf(" NoTaggedQueuing");
X        }
X#endif /* TAGGED */
X	if(NOWIDE(i)){
X		printf(" Narrow");
X	} else {
X		printf(" Wide");
X	}
X}
X
Xint process_glm()
X{
X	u_long addr;
X	struct glm glm[1];
X	int noisycount=0; /* number of noisy devices */
X	u_int j, nglm;
X
X        if(-1==kvm(nl[N_GLM_HEAD].n_value, addr)){
X		return(0); /* glm driver not loaded */
X        }
X        if((u_long)NULL==addr) return(0); /* no glm's */
X
X        if(-1==kvm(addr, glm[0])){
X                Error("kvm read: initial glm");
X        }
X
X	nglm=get_nglm();
X	if(0==nglm) return(0);
X
X	for(j=0;j<nglm;j++){
X		struct dev_info di, *next;
X		char *devicepath, *dname;
X		scsi_hba_tran_t tran;
X
X		if((u_long)NULL==addr) break;
X
X                if(-1==kvm(addr, glm[0])){
X			Error("kvm read: glm #%d", j);
X		}
X
X		/* 
X		 * Grab the transport devinfo structure for the glm
X		 * controller. Needed for CNUM. 
X		 */
X		if(-1==kvm((u_long)glm->g_tran, tran)){
X			Error("kvm read: #%d glm tran", j);
X		}
X		glm->g_tran=(scsi_hba_tran_t *)&tran; 
X		if(-1==kvm((u_long)glm->g_tran->tran_hba_dip, devi)){
X			Error("kvm read: #%d glm devinfo", j);
X		}
X		glm->g_tran->tran_hba_dip=(dev_info_t *)&devi;
X
X		/* 
X		 * grab the devinfo structure for the glm controller. CNUM 
X		 * requires it, and we need it to determine the device names.
X		 */
X		if(-1==kvm(glm->g_dip, devi)){
X			Error("kvm read: #%d glm devinfo", j);
X		} 
X
X		devicepath = get_devicepath(j);
X
X		glm->g_dip=(dev_info_t)&devi; 
X
X#ifdef INSANE
X		if(INSANE){
X			Warning(
X"The kernel data structure for glm%d failed a sanity check.\n\
X  There may be a mismatch between the compile-time headers and the currently\n\
X  running kernel.  A recompile on this machine may be necessary.", CNUM(glm));
X		}
X#endif /* INSANE */
X
X		if(param_is_set(P_CONTROLLER)) {
X			glm_controller_message(CNUM(glm), glm);
X		}
X
X		init_scsitarget();
X
X		/* 
X		 * Now, traverse glm'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 glm devinfo child", j);
X			}
X
X			if(!DDI_CF2(&di)) continue; /* no device attached */
X
X			devicecount++;
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			devicename = compute_devicename(dname, 
X						devicepath, addrname);
X
X			if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X				Error("scsiaddr: #%d", j);
X			}
X
X			if(0==lun && NOISY(target)) noisycount++;
X
X			banner(param_is_set(P_FORMATDAT),
X				param_is_set(P_REPORT), devicecount);
X			if(!param_is_set(P_QUIET)){
X				if(param_is_set(P_SUNOS4STYLE)) {
X					if(lun==0){
X						boot_synch_message("glm",
X							CNUM(glm), target, 
X							glm_get_speed(glm, 
X								target), 
X								NARROW);
X					}
X				} else {
X					printf("glm%d: %s%s tgt %d lun %d:\n", 
X						CNUM(glm), dname, addrname, 
X						target, lun);
X					if(param_is_set(P_SYNCH)){
X						printf("\t");
X						glm_synch_message(glm, target, 
X						 glm_get_speed(glm, target));
X						printf("\n");
X					}
X				}
X			}
X			if(param_is_set(P_PROBE)) {
X				do_scsi_probe(dname, devicename, lun);
X			}
X			if(param_is_set(P_REPORT)) {
X				report(param_is_set(P_FORMATDAT),
X					osrelease, devicename,
X					param_is_set(P_ORIGINAL));
X			}
X			free(devicename);
X			free(addrname);
X			free(dname);
X		}
X
X		free(devicepath);
X
X		addr=NEXT(glm);
X	}
X	return(noisycount);
X}
X
X#else /* !SYSV */
X/* GLM isn't supported on SunOS 4.x */
Xint process_glm(){}
X#endif /* SYSV */
X#endif /* GLM_SUPPORT */
END_OF_FILE
if test 7280 -ne `wc -c <'glm.c'`; then
    echo shar: \"'glm.c'\" unpacked with wrong size!
fi
# end of 'glm.c'
fi
if test -f 'pln.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'pln.c'\"
else
echo shar: Extracting \"'pln.c'\" \(5889 characters\)
sed "s/^X//" >'pln.c' <<'END_OF_FILE'
X/*
X * pln.c  -  process PLN host adapters.
X *
X * PLN support by Jim Pirzyk <pirzyk@hotmail.com>
X * 
X */
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: pln.c,v 1.5 2000/03/23 22:09:39 jdd Exp $";
X#endif
X
X#ifdef PLN_SUPPORT
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#ifdef SYSV
X#include "sunos5.h"
X
X#include <sys/fc4/fcp.h>
X#include <sys/fc4/fc_transport.h>
X
X#ifdef _NOTE
X#undef _NOTE
X#endif /* _NOTE */
X#define _NOTE(x)
X
X#define _KMEMUSER
X#include <sys/scsi/adapters/plndef.h>
X#include <sys/scsi/targets/pln_ctlr.h>
X#include <sys/scsi/adapters/plnvar.h>
X
X#ifndef CNUM
X#define CNUM(pln)      (ddi_get_instance(pln->pln_tran->tran_hba_dip))
X#endif /* CNUM */
X
Xstatic void pln_controller_message (cnum, pln) 
Xint cnum;
Xstruct pln *pln;
X{
X	printf("pln%d:", cnum);
X	printf(" type FC-PH v%2.1f,", (float) (FC_PH_VERSION - 2));
X	printf(" %hu internal busses, %hu targets per bus", 
X		pln->pln_nports, pln->pln_ntargets);
X     printf("\n");
X}
X
Xstatic u_int pln_get_speed(pln, i)
Xstruct pln *pln;
Xint i; /* target index */
X{
X	return 0;
X}
X
Xstatic void pln_synch_message(pln, i, speed)
Xstruct pln *pln;
Xint i;
Xu_int speed;
X{
X	printf("Unknown");
X	printf(" Clean");
X	printf(" CannotReconnect");
X	printf(" TaggedQueuing");
X	printf(" Wide");
X}
X
Xint process_pln()
X{
X	u_long addr;
X	struct pln pln[1];
X	int noisycount=0; /* number of noisy devices */
X     u_int j, npln;
X
X
X	if(-1==kvm(nl[N_PLN_SOFTC].n_value, addr)){
X		return(0); /* pln driver not loaded */
X	}
X	if((u_long)NULL==addr) return(0); /* no pln's */ 
X
X	if(-1==kvm(addr, pln[0])){
X		Error("kvm read: initial pln");
X	}
X
X	npln=get_npln();
X     if(0==npln) return(0);
X
X	for(j=0;j<npln;j++){
X		struct dev_info di, *next;
X		char *devicepath, *dname;
X		scsi_hba_tran_t tran;
X
X		if((u_long)NULL==addr) break;
X
X		if(-1==kvm(addr, pln[0])){
X			Error("kvm read: pln #%d", j);
X		}
X
X		/*
X		 * Grab the transport devinfo structure for the pln
X                 * controller. Needed for CNUM.
X                 */
X		if(-1==kvm((u_long)pln->pln_tran, tran)){
X               Error("kvm read: #%d pln tran", j);
X          }
X          pln->pln_tran=(scsi_hba_tran_t *)&tran;
X          if(-1==kvm((u_long)pln->pln_tran->tran_hba_dip, devi)){
X               Error("kvm read: #%d pln devinfo", j);
X          }
X		pln->pln_tran->tran_hba_dip=(dev_info_t *)&devi;
X
X          /*
X           * grab the devinfo structure for the pln controller. CNUM
X           * requires it, and we need it to determine the device names.
X           */
X          if(-1==kvm(pln->pln_dip, devi)){
X               Error("kvm read: #%d pln devinfo", j);
X          }
X
X          devicepath = get_devicepath(j);
X
X		pln->pln_dip=(dev_info_t)&devi; /* for CNUM */ 
X
X		if(param_is_set(P_CONTROLLER)) {
X               pln_controller_message(CNUM(pln), pln);
X          }
X
X          init_scsitarget();
X
X	  /*
X           * Now, traverse pln'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               devicecount++;
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               devicename = compute_devicename(dname,
X                              devicepath, addrname);
X
X               if(-1==get_scsiaddr(dname, &di, &target, &lun)){
X                    Error("scsiaddr: #%d", j);
X               }
X
X               banner(param_is_set(P_FORMATDAT),
X                    param_is_set(P_REPORT), devicecount);
X               if(!param_is_set(P_QUIET)){
X                    if(param_is_set(P_SUNOS4STYLE)) {
X                         if(lun==0){
X                              boot_synch_message("pln",
X                                   CNUM(pln), target,
X                                   pln_get_speed(pln,
X                                        target),
X                                        NARROW);
X                         }
X                    } else {
X                         printf("pln%d: %s%s tgt %d lun %d:\n",
X                              CNUM(pln), dname, addrname,
X						target, lun);
X                         if(param_is_set(P_SYNCH)){
X                              printf("\t");
X                              pln_synch_message(pln, target,
X                               pln_get_speed(pln, target));
X                              printf("\n");
X                         }
X                    }
X               }
X               if(param_is_set(P_PROBE)) {
X                    do_scsi_probe(dname, devicename, lun);
X               }
X               if(param_is_set(P_REPORT)) {
X                    report(param_is_set(P_FORMATDAT),
X                         osrelease, devicename,
X                         param_is_set(P_ORIGINAL));
X               }
X               free(devicename);
X               free(addrname);
X               free(dname);
X          }
X
X          addr=(u_long)pln->pln_next;
X
X     }
X     return(noisycount);
X}
X
X#else /* !SYSV */
X/* PLN isn't supported on SunOS 4.x */
Xint process_pln(){}
X#endif /* SYSV */
X#endif /* PLN_SUPPORT */
END_OF_FILE
if test 5889 -ne `wc -c <'pln.c'`; then
    echo shar: \"'pln.c'\" unpacked with wrong size!
fi
# end of 'pln.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'\" \(2761 characters\)
sed "s/^X//" >'ispvar.h' <<'END_OF_FILE'
X/*
X * ispvar.h - header file for ISP controller support.
X *
X * Info originally from Solaris 2.4EA
X *
X * $Id: ispvar.h,v 1.3 1997/09/17 20:51:02 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_20M_SYNC_PERIOD	0x000C
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 2761 -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'\" \(694 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.3 2000/02/24 21:42:16 jdd Exp $
X */
X
X/* defined in scsiinfo.c */
Xextern int parameter; 
Xextern u_int devicecount;
Xextern char *osrelease;
X
X/* max 32 parameters before we need to worry about portability */
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#define P_REPORT 5
X#define P_FORMATDAT 6
X#define P_SYNCH 7
X#define P_OPENCHECK 8
X
X#define set_param(a) (parameter |= 1<<(a))
X#define clear_param(a) (parameter &= ~(1<<(a)))
X#define param_is_set(a) (parameter & 1<<(a))
END_OF_FILE
if test 694 -ne `wc -c <'param.h'`; then
    echo shar: \"'param.h'\" unpacked with wrong size!
fi
# end of 'param.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'\" \(10004 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.26 2000/02/24 21:39:43 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#include "param.h"
X#include "uscsi.h"
X
Xextern int d;
X
X#ifdef SYSV
X
X#include <stdlib.h>
X#include <errno.h>
X
X/* silly workaround for a bug in gcc <<2.6.2 for Solaris 2.4 */
X#include <sys/byteorder.h>
X#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
X#ifdef __i386__
X#define _BIT_FIELDS_LTOH
X#else /* !__i386__ */
X#define _BIT_FIELDS_HTOL
X#endif /* !__i386__ */
X#endif /* !defined(_BIT... */
X#ifdef _BIT_FIELDS_HTOL
X#ifndef ntohl
X#define ntohl(x) (x)
X#define ntohs(x) (x)
X#endif /* ndef ntohl */
X#endif /* _BIT_FIELDS_HTOL */
X
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
Xint scsi_read_blklim(fd, max_bll, min_bll)
Xint fd;
Xunsigned int *max_bll, *min_bll; 
X{
X        struct uscsi_cmd cmd;
X        union scsi_cdb cdb;
X        struct scsi_read_blklim {
X                unsigned char reserved;
X                unsigned char max[3];
X                unsigned char min[2];
X        } *rbl;
X        unsigned char buff[SCSIBUFLEN];
X
X        rbl = (struct scsi_read_blklim *)buff;
X
X        /* set up SCSI read_blklim command */
X        bzero(&cdb, sizeof(cdb));
X        bzero(rbl, sizeof(rbl));
X        cdb.scc_cmd = SCMD_READ_BLKLIM;
X        cmd.uscsi_cdb=(caddr_t)&cdb;
X        cmd.uscsi_cdblen=6;  /* SCSI Group 0 cmd */
X        cmd.uscsi_bufaddr=(caddr_t)rbl;
X        cmd.uscsi_buflen=SCSIBUFLEN;
X        cmd.uscsi_flags=USCSI_READ;
X
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X
X/* {int i; for(i=0;i<6;i++) printf("%.2X ", (u_int)buff[i]); printf("\n");} */
X
X	*max_bll=rbl->max[0]*(256*256)+rbl->max[1]*256+rbl->max[2];
X	*min_bll=rbl->min[0]*256+rbl->min[1];
X
X        return(0);
X}
X
Xchar *scsi_dtype(dtype)
Xu_int 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("CD-ROM");
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(param_is_set(P_OPENCHECK) && opencheck(devname)){
X		/* 
X		 * If somebody is holding this device open, assume it's
X		 * busy and don't try to open it. Some device drivers (e.g.
X		 * pln) complain bitterly if somebody tries to open a device
X	 	 * that someone else already has an exclusive open on.
X		 */
X		errno=EBUSY;
X		return(-1);
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\t\t[%s%s%s%s%s]", inq->inq_vid, 
X		inq->inq_pid, inq->inq_revision, 
X		(inq->inq_reladdr?"A":""), (inq->inq_sync?"S":""),
X		(inq->inq_linked?"L":""), (inq->inq_cmdque?"T":""),
X		(inq->inq_sftre?"R":""));
X	return(0);
X}
X
Xint scsi_inquiry(fd, devicetype, vendor, product, revision, serial, capability)
Xint fd, *devicetype, *capability;
Xchar *vendor, *product, *revision, *serial;
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, sizeof(inq->inq_vid));
X	strncpy(product, inq->inq_pid, sizeof(inq->inq_pid));
X	strncpy(revision, inq->inq_revision, sizeof(inq->inq_revision));
X	strncpy(serial, inq->inq_revision+REVISION_SIZE, SERIAL_SIZE);
X	/* Could use inq_serial in the previous line, but it's only defined 
X	 * in the SunOS 5.x headers, unfortunately, and even there, it's the
X	 * wrong size (12 bytes, not 20 as the SCSI2 spec dictates) so I'll 
X	 * hard-code its size and location instead. */
X
X	/* 
X	 * set capability -- it contains byte 7 (all the capability bit 
X	 * flags) set the way we want them.  We can't just pass the byte 
X	 * "as is", since the bits are in a different order depending on
X	 * endien-ness.
X	 */ 
X	if(inq->inq_reladdr) *capability |= INQ_RELADR;
X	if(inq->inq_wbus32)  *capability |= INQ_WBUS32;
X	if(inq->inq_wbus16)  *capability |= INQ_WBUS16;
X	if(inq->inq_sync)    *capability |= INQ_SYNC;
X	if(inq->inq_linked)  *capability |= INQ_LINKED;
X	if(inq->inq_cmdque)  *capability |= INQ_CMDQUE;
X	if(inq->inq_sftre)   *capability |= INQ_SFTRE;
X
X	return(0);
X}
X
Xint scsi_capacity(fd, capacity)
Xint fd; 
Xunsigned long *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+ntohl((u_long)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, cache_status)
Xint fd, original;
Xint *nsect, *sector_size, *pcyl, *nhead, *rpm, *trks_zone, *asect, *atrks,
X*cache_status;
X{
X        struct uscsi_cmd cmd;
X        union scsi_cdb cdb;
X        struct mode_format mfmt;
X	struct mode_geometry mgeom;
X	struct mode_cache mcache;
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)ntohs((u_short)mfmt.tracks_per_zone);
X	*asect = (int)ntohs((u_short)mfmt.alt_sect_zone);
X	*nsect = (int)ntohs((u_short)mfmt.sect_track);
X	*atrks = (int)ntohs((u_short)mfmt.alt_tracks_vol);
X	*sector_size = (int)ntohs((u_short)mfmt.data_bytes_sect);
X
X	/* 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)ntohs((u_short)mgeom.rpm);
X	}
X
X	/* grab the cache page */
X        cdb.g0_addr1 = DAD_MODE_CACHE | (0x80 * original);
X        if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X        buffp = MODE_PAGE_ADDR((struct mode_header *)buff, char);
X	memset((char *)&mcache, 0, sizeof(mcache));
X	memcpy((char *)&mcache, buffp, sizeof(struct mode_page));
X	memcpy((char *)&mcache, buffp, mcache.mode_page.length);
X
X	*cache_status=(mcache.wce<<1)+(1-mcache.rcd);
X
X	return(0);
X}
END_OF_FILE
if test 10004 -ne `wc -c <'uscsi.c'`; then
    echo shar: \"'uscsi.c'\" unpacked with wrong size!
fi
# end of 'uscsi.c'
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'\" \(925 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.4 1998/08/07 20:55:50 jdd Exp $
X */
X
X/* Exported Procedures */
X
Xextern int scsi_read_blklim();
Xextern int scsi_probe();
Xextern int scsi_inquiry();
Xextern int scsi_modeinfo();
Xextern int scsi_capacity();
Xextern char *scsi_dtype();
X
X#define INQ_WBUS32	0x02
X#define INQ_WBUS16	0x04
X
X#define INQ_RELADR	0x01
X#define INQ_TXT_RELADR	"REL_ADDR"
X
X#define INQ_SYNC	0x08
X#define INQ_TXT_SYNC	"SYNC_SCSI"
X
X#define INQ_LINKED	0x10
X#define INQ_TXT_LINKED	"LINK_CMD"
X
X#define INQ_RSRVED	0x20
X#define INQ_TXT_RSRVED	"RESERVED"
X
X#define INQ_CMDQUE	0x40
X#define INQ_TXT_CMDQUE	"TAG_QUEUE"
X
X#define INQ_SFTRE	0x80
X#define INQ_TXT_SFTRE	"SOFT_RESET"
X
X/* size of various fields in INQUIRY data */
X
X#define VENDOR_SIZE 	8
X#define PRODUCT_SIZE 	16
X#define REVISION_SIZE 	4
X#define SERIAL_SIZE 	20
END_OF_FILE
if test 925 -ne `wc -c <'uscsi.h'`; then
    echo shar: \"'uscsi.h'\" unpacked with wrong size!
fi
# end of 'uscsi.h'
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 'format.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'format.c'\"
else
echo shar: Extracting \"'format.c'\" \(9086 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.30 2000/02/24 21:38:52 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#include "param.h"
X
X#ifndef DTYPE_DIRECT
X#define DTYPE_DIRECT 0x00
X#endif /* DTYPE_DIRECT */
X
X#ifndef DTYPE_SEQUENTIAL
X#define DTYPE_SEQUENTIAL 0x01
X#endif /* DTYPE_SEQUENTIAL */
X
X#define MAX_RPM 32767
X#define MIN_RPM 3000
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
Xstatic void basereport(devicetype, vendor, product, revision, serial, cap)
Xint devicetype, cap;
Xchar *vendor, *product, *revision, *serial;
X{
X
X
X	printf("Vendor:                      %s\n", vendor);
X	printf("Model:                       %s\n", product);
X	printf("Revision:                    %s\n", revision);
X	printf("Serial:                      %s\n", serial);
X	printf("Device Type:                 %s\n", scsi_dtype(devicetype));
X	printf("Data Transfer Width(s):      ");
X		if(cap&INQ_WBUS32)	printf("32, ");
X		if(cap&INQ_WBUS16)	printf("16, ");
X		printf("8\n");
X#ifdef LONG_REPORT_FORMAT
X#define SUPPORTS(c, f) (((c)&(f))?"Supported":"Unsupported")
X	printf("Relative Addressing:         %s\n", SUPPORTS(cap,INQ_RELADR));	
X	printf("Synchronous Transfers:	     %s\n", SUPPORTS(cap,INQ_SYNC));
X	printf("Linked Commands:             %s\n", SUPPORTS(cap,INQ_LINKED));
X	printf("Tagged Queuing:	             %s\n", SUPPORTS(cap,INQ_CMDQUE));
X	printf("Soft Reset:                  %s\n", SUPPORTS(cap,INQ_SFTRE));
X#else /* !LONG_REPORT_FORMAT */
X	printf("Supported Features:         ");
X	if(cap&INQ_RELADR) printf(" %s", INQ_TXT_RELADR);
X	if(cap&INQ_SYNC)   printf(" %s", INQ_TXT_SYNC);
X	if(cap&INQ_LINKED) printf(" %s", INQ_TXT_LINKED);
X	if(cap&INQ_CMDQUE) printf(" %s", INQ_TXT_CMDQUE);
X	if(cap&INQ_SFTRE)  printf(" %s", INQ_TXT_SFTRE);
X	printf("\n");
X#endif /* LONG_REPORT_FORMAT */
X}
X
Xstatic void format(formatdat, osversion, fd, diskdevice, 
X			original, vendor, product, revision, serial, cap)
Xint formatdat, fd;
Xchar *osversion, *diskdevice, *vendor, *product, *revision, *serial;
Xint original, cap;
X{
X        unsigned long capacity;
X        int nsect, sector_size, cache_status;
X        int pcyl, nhead, rpm=-1;
X        static int trks_zone, atrks, asect;/* 4.1.1 cc bad code unless static */
X        char disk_type[VENDOR_SIZE+PRODUCT_SIZE+2], *ctlr, *cname;
X        int fmt_time, ncyl, bpt_, csize;
X
X	/* get number of blocks available */
X	if(0>scsi_capacity(fd, &capacity)){
X		perror(diskdevice);
X		Warning("SCSI READ_CAPACITY failed");
X		return;
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, &cache_status)){
X		perror(diskdevice);
X		Warning("SCSI mode select failed.");
X	}
X	if(SECTORSIZE != sector_size){
X		if(sector_size){
X			Warning(
X		"Drive is formatted with with sector size %d, should be %d",
X				sector_size, SECTORSIZE);
X			return;
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.") */ ;
X	} else if(rpm>MAX_RPM || rpm<MIN_RPM){
X		Warning( "Drive claims to have strange RPM value: %d", rpm);
X		rpm=-1;
X	}
X	if(nhead<1) {
X		Warning(
X	"Drive claims to have %d heads. This makes no sense. Giving up.", 
X		nhead);
X		return;
X	}
X
X	if(nsect<1) {
X		Warning(
X	"Drive claims to have %d sectors. This makes no sense. Giving up.", 
X		nsect);
X		return;
X	}
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 = (int)(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", (-1==rpm)?3600: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		basereport(DTYPE_DIRECT,vendor,product,revision,serial,cap);
X		printf("Formatted Capacity:          %ld sectors ", capacity); 
X		if(capacity >= 2000000){
X			/* 
X			 * I want GB to the first decimal place, since that
X			 * is what people are used to when they buy disks. 
X			 */
X			printf("(%.1f GB)\n", (((float)capacity)/2000000.0));
X		} else {
X			/* 
X			 * I really only care about MB to the nearest 
X			 * integer but I'll work in terms of floats just in 
X			 * case I change my mind. 
X			 */
X			printf("(%.0f MB)\n", (((float)capacity)/2000.0));
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		if(-1==rpm){
X			printf("Rotational speed:            NA\n", rpm);
X		} else {
X			printf("Rotational speed:            %d rpm\n", rpm);
X		}
X		printf("Cache:                       ");
X		switch(cache_status){
X			case 0:
X				printf("Disabled\n");
X				break;
X			case 1:
X				printf("Read-Only\n");
X				break;
X			case 2:
X				printf("Write-Only\n");
X				break;
X			case 3:
X				printf("Read-Write\n");
X				break;
X			default:
X				printf("Unknown\n");
X				break;
X		}
X	}
X}
X
Xvoid report(formatdat, osversion, device, original)
Xint formatdat;
Xchar *osversion;
Xchar *device;
Xint original;
X{
X	struct stat sb;
X	int fd, i, cap;
X	u_int devicetype;
X	u_int max_bll, min_bll;
X	static char vendor[VENDOR_SIZE+1];
X	static char product[PRODUCT_SIZE+1];
X	static char revision[REVISION_SIZE+1];
X	static char serial[SERIAL_SIZE+1];
X
X	/* preliminary stuff */
X	if(d) printf("Generating report for %s, SunOS %s\n", device,
X			osversion);
X	if(stat(device, &sb)<0){
X		perror(device);
X		Warning("Cannot stat device.");
X		return;
X	}
X	if(!S_ISCHR(sb.st_mode)){
X		Warning("%s must be a raw SCSI device.", device);
X		return;
X	}
X	if(param_is_set(P_OPENCHECK) && opencheck(device)){
X		Warning("Device is currently busy.");
X		return;
X	}
X	if(0>(fd=open(device, O_RDONLY|O_NDELAY))){
X		perror(device);
X		Warning("Cannot open device.");
X		return;
X	}
X
X	/* get vendor, product, revision, and serial */
X	strncpy(serial, "Unknown", sizeof(serial));
X	if(0>scsi_inquiry(fd, &devicetype, vendor, product, revision, 
X			serial, &cap)){
X		perror(device);
X		Warning("SCSI INQUIRY failed.");
X		return;
X	}
X
X	/* ensure null termination without trailing spaces */
X	vendor[VENDOR_SIZE]='\0';
X	for(i=VENDOR_SIZE-1;i>0 && vendor[i]==' ';i--) vendor[i]='\0';
X	product[PRODUCT_SIZE]='\0';
X	for(i=PRODUCT_SIZE-1;i>0 && product[i]==' ';i--) product[i]='\0';
X	revision[REVISION_SIZE]='\0';
X	for(i=REVISION_SIZE-1;i>0 && revision[i]==' ';i--) revision[i]='\0';
X	serial[SERIAL_SIZE]='\0';
X	for(i=SERIAL_SIZE-1;i>0 && serial[i]==' ';i--) serial[i]='\0';
X
X	if(formatdat && DTYPE_DIRECT!=devicetype){
X	     Warning("Can't create format.dat entry for device of type: %s\n",
X			scsi_dtype(devicetype));
X		return;
X	}
X	switch(devicetype){
X	case DTYPE_DIRECT:
X		format(formatdat, osversion, fd, device, original, vendor, 
X			product, revision, serial, cap);
X		break;
X	case DTYPE_SEQUENTIAL:
X		if(0>scsi_read_blklim(fd, &max_bll, &min_bll)){
X			perror(device);
X			Warning("SCSI READ BLOCK LIMITS failed.");
X			return;
X		}
X		basereport(devicetype, vendor, product, revision, serial, cap);
X		printf("Maximum block length:        %u bytes\n", max_bll);
X		printf("Minimum block length:        %u bytes\n", min_bll);
X		break;
X	default:
X		basereport(devicetype, vendor, product, revision, serial, cap);
X		break;
X	}
X}
X
Xvoid banner(formatdat, report, devicecount)
Xint formatdat, report;
Xu_int devicecount; /* NOTUSED */
X{
X	if(devicecount>1){
X		if(formatdat){
X			printf("\n");
X		} else if(report){
X			printf("----------------------------\n");
X		}
X	}
X}
END_OF_FILE
if test 9086 -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'\" \(259 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.4 1999/04/22 17:41:05 jdd Exp $
X */
X
X/* Exported Procedures */
Xextern void report();
Xextern void banner();
END_OF_FILE
if test 259 -ne `wc -c <'format.h'`; then
    echo shar: \"'format.h'\" unpacked with wrong size!
fi
# end of 'format.h'
fi
if test -f 'notch.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'notch.c'\"
else
echo shar: Extracting \"'notch.c'\" \(11581 characters\)
sed "s/^X//" >'notch.c' <<'END_OF_FILE'
X/*
X * notch.c - routines for producing a drive notch report.  Generally works 
X *           only for later Seagate drives (eg. ST5150N).
X *
X * Can report the Notch and Partition Page, to the extent the drive
X * supports it (many don't very well) by setting the Active Notch and
X * iterating.
X * 
X * Does a SEND/RECEIVE DIAGNOSTIC with the Translate Address page for
X * every sector on the drive.
X *
X * Rod Van Meter (rdv@alumni.caltech.edu, http://www.alumni.caltech.edu/~rdv/)
X *
X * Author: Rod Van Meter
X *         University of Southern California, Information Sciences Institute
X *         rdv@isi.edu
X */
X
X#include <stdio.h>
X#include "uscsi.h"
X
X#ifdef NOTCH_REPORT
X
X#ifndef lint
Xstatic char rcsid[] = "$Id: notch.c,v 1.9 1999/04/19 23:41:07 jdd Exp $";
X#endif
X
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 <sys/stat.h>
X#include "utils.h"
X
Xextern int d;
X
X#ifdef SYSV
X
X#include <stdlib.h>
X
X/* silly workaround for a bug in gcc <<2.6.2 for Solaris 2.4 */
X#include <sys/byteorder.h>
X#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
X#ifdef __i386__
X#define _BIT_FIELDS_LTOH
X#else /* !__i386__ */
X#define _BIT_FIELDS_HTOL
X#endif /* !__i386__ */
X#endif /* !defined(_BIT... */
X
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#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#if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
X#if !defined(vax) && !defined(i386) 
X/* SunOS 4.x assumes that if it's not intel or vax, it's big-endian. */
X#define _BIT_FIELDS_HTOL
X#else /* !defined(vax)... */
X#define _BIT_FIELDS_LTOH
X#endif /* !defined(vax)... */
X#endif /* !defined(_BIT... */
X
X#endif /* SYSV */
X
X#define SCSIBUFLEN 8000
X
Xstruct mode_notch {
X	struct	mode_page mode_page;	/* common mode page header */
X#if defined(_BIT_FIELDS_LTOH)
X	u_char  reserved : 6,
X	        lpn : 1,	/* logical or physical notch? */
X                nd : 1;		/* notched drive? */
X#elif defined(_BIT_FIELDS_HTOL)
X	u_char	nd : 1,		/* notched drive? */
X		lpn : 1,	/* logical or physical notch? */
X		reserved : 6;
X#else
Xerror: One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
X#endif  /* _BIT_FIELDS_LTOH */
X	u_char  reserved1;
X	u_char  maxnotch_ub;
X	u_char  maxnotch_lb;
X	u_char  active_notch_ub;
X	u_char  active_notch_lb;
X	u_int   start;
X	u_int   end;
X	u_int   pages_notched_ul;
X	u_int   pages_notched_ll;
X};
X
X#define NOTCH_PAGE_LENGTH 0x16
X#define MODE_SELECT_PAGE_FORMAT 0x10
X
Xstruct diag_addr_trans {
X    /* struct diag_page diag_page;	/ * common header */
X    u_char	page_code;
X    u_char	reserved;
X    u_short	length;
X    u_char	supplied;	/* actually 3-bit field */
X    u_char	translate;
X    u_char	addr[8];
X};
X
X#define TRANSLATE_PAGE_LENGTH	0x0a
X#define DAD_TRANSLATE		0x40
X#define TRANS_BLOCK_FORMAT	0x00
X#define TRANS_PHYS_FORMAT	0x05
X#define SEND_DIAG_PAGE_FORMAT	0x10 /* cdb byte 1 */
X
Xstatic int scsi_set_active_notch(fd,notch)
X	int fd;
X	int notch;
X{
X    struct uscsi_cmd cmd;
X    union scsi_cdb cdb;
X    struct mode_notch mnotch;
X    char buff[SCSIBUFLEN];
X    char *buffp;
X    int i;
X    
X    bzero(&cdb, sizeof(cdb));
X    bzero(&mnotch, sizeof(mnotch));
X    bzero(buff,SCSIBUFLEN);
X    mnotch.mode_page.length = NOTCH_PAGE_LENGTH;
X    mnotch.mode_page.code = DAD_MODE_NOTCHPART;
X    mnotch.active_notch_ub = notch >> 8;
X    mnotch.active_notch_lb = notch & 0xff;
X    cdb.scc_cmd = SCMD_MODE_SELECT;
X    cdb.g0_count0 = sizeof(mnotch)+MODE_HEADER_LENGTH;
X    cdb.cdb_un.tag = MODE_SELECT_PAGE_FORMAT;
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=sizeof(mnotch)+MODE_HEADER_LENGTH;
X    cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_ISOLATE;
X
X    buff[0] = sizeof(mnotch)+MODE_HEADER_LENGTH - 1;
X    buffp = MODE_PAGE_ADDR((struct mode_header *)buff, char);
X    /* don't need both, since we already know */
X    /* memcpy(buffp, (char *)&mnotch, sizeof(struct mode_page)); */
X    memcpy(buffp, (char *)&mnotch, mnotch.mode_page.length);
X
X    /* write the notch page */
X    /* cdb.g0_addr1 = DAD_MODE_NOTCHPART; */
X
X#ifdef ZONE_DEBUG
X    printf("cdb: ");
X    for (i = 0 ; i < 6 ; i++ )
X	printf("0x%02x ",((char *)&cdb)[i]);
X    printf("\ndata: ");
X    for (i = 0 ; i < NOTCH_PAGE_LENGTH+MODE_HEADER_LENGTH ; i++ )
X	printf("0x%02x ",buff[i]);
X    printf("\n");
X#endif
X
X    if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X    
X    return(0);
X}
X
Xstatic int scsi_read_active_notch(fd,maxnotchp,notchp,startp,endp,
X		pagesup,pageslp)
X	int fd;
X	int *maxnotchp,*notchp,*startp,*endp,*pagesup,*pageslp;
X{
X    struct uscsi_cmd cmd;
X    union scsi_cdb cdb;
X    struct mode_notch mnotch;
X    char buff[SCSIBUFLEN];
X    char *buffp;
X    
X    bzero(&cdb, sizeof(cdb));
X    bzero(&mnotch, sizeof(mnotch));
X
X    cdb.scc_cmd = SCMD_MODE_SENSE;
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    /* read the notch page */
X    cdb.g0_addr1 = DAD_MODE_NOTCHPART;
X    if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X    
X    buffp = MODE_PAGE_ADDR((struct mode_header *)buff, char);
X    memcpy((char *)&mnotch, buffp, sizeof(struct mode_page));
X    memcpy((char *)&mnotch, buffp, mnotch.mode_page.length);
X
X    *maxnotchp = (mnotch.maxnotch_ub << 8) + mnotch.maxnotch_lb;
X    *notchp = (mnotch.active_notch_ub << 8) + mnotch.active_notch_lb;
X    *startp = mnotch.start;
X    *endp = mnotch.end;
X    *pagesup = mnotch.pages_notched_ul;
X    *pageslp = mnotch.pages_notched_ll;
X
X    return(0);
X}
X
Xstatic int scsi_translate_address_receive(fd,diskdevice,highp,lowp)
X	int fd;
X	char *diskdevice;
X	int *highp,*lowp;
X{
X    struct uscsi_cmd cmd;
X    union scsi_cdb cdb;
X    struct diag_addr_trans dat;
X    char buff[SCSIBUFLEN];
X    int i;
X    
X    bzero(&cdb, sizeof(cdb));
X    bzero(&dat, sizeof(dat));
X    bzero(buff, sizeof(dat));
X
X    cdb.scc_cmd = SCMD_GDIAG;
X    cdb.g0_count0 = sizeof(dat);
X
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 = sizeof(dat);
X    cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_ISOLATE|USCSI_READ;
X
X#ifdef ZONE_DEBUG
X    printf("cdb: ");
X    for (i = 0 ; i < 6 ; i++ )
X	printf("0x%02x ",((char *)&cdb)[i]);
X    printf("\ndata: ");
X    for (i = 0 ; i < sizeof(dat) ; i++ )
X	printf("0x%02x ",buff[i]);
X    printf("\n");
X#endif
X
X    if(-1==ioctl(fd, USCSICMD, &cmd)) return(-1);
X    
X#ifdef ZONE_DEBUG
X    printf("buff: ");
X    for (i = 0 ; i < sizeof(dat) ; i++ )
X	printf("0x%02x ",buff[i]);
X    printf("\n");
X#endif
X
X    /*
X    memcpy((char *)&dat, buff, sizeof(struct mode_page));
X    memcpy((char *)&dat, buff, dat.length);
X     */
X    memcpy((char *)&dat, buff, sizeof(dat));
X
X    *highp = (dat.addr[0] << 24) + (dat.addr[1] << 16) + (dat.addr[2] << 8)
X	+ dat.addr[3];
X    *lowp = (dat.addr[4] << 24) + (dat.addr[5] << 16) + (dat.addr[6] << 8)
X	+ dat.addr[7];
X    return(0);
X}
X
Xstatic int scsi_translate_address_send(fd,diskdevice,block)
X	int fd;
X	char *diskdevice;
X	int block;
X{
X    struct uscsi_cmd cmd;
X    union scsi_cdb cdb;
X    struct diag_addr_trans dat;
X    char buff[SCSIBUFLEN];
X    int i;
X    
X    bzero(&cdb, sizeof(cdb));
X    bzero(&dat, sizeof(dat));
X
X    cdb.scc_cmd = SCMD_SDIAG;
X
X    cdb.cdb_un.tag = SEND_DIAG_PAGE_FORMAT;
X    cdb.g0_count0 = sizeof(dat);
X
X    /* SELF TEST
X    cdb.cdb_un.tag = 4;
X    cdb.g0_count0 = 0;
X     */
X
X    dat.length = TRANSLATE_PAGE_LENGTH;
X    dat.page_code = DAD_TRANSLATE;
X    dat.addr[0] = block >> 24;
X    dat.addr[1] = (block >> 16) & 0xff;
X    dat.addr[2] = (block >> 8) & 0xff;
X    dat.addr[3] = block & 0xff;
X    dat.supplied = TRANS_BLOCK_FORMAT;
X    dat.translate = TRANS_PHYS_FORMAT;
X
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 = sizeof(dat);
X    cmd.uscsi_flags=USCSI_DIAGNOSE|USCSI_ISOLATE;
X
X    memcpy(buff, (char *)&dat, sizeof(dat));
X
X#ifdef ZONE_DEBUG
X    printf("cdb: ");
X    for (i = 0 ; i < 6 ; i++ )
X	printf("0x%02x ",((char *)&cdb)[i]);
X    printf("\ndata: ");
X    for (i = 0 ; i < sizeof(dat) ; i++ )
X	printf("0x%02x ",buff[i]);
X    printf("\n");
X#endif
X
X    return ioctl(fd, USCSICMD, &cmd);
X}
X
Xstatic void scsi_translate_address(fd,diskdevice,block,highp,lowp)
X	int fd;
X	char *diskdevice;
X	int block,*highp,*lowp;
X{
X    if (0>scsi_translate_address_send(fd,diskdevice,block)) {
X	perror(diskdevice);
X	Error("SCSI send diag failed, giving up.");
X	return;
X    }
X    if (0>scsi_translate_address_receive(fd,diskdevice,highp,lowp)) {
X	perror(diskdevice);
X	Error("SCSI rcv diag failed, giving up.");
X	return;
X    }
X}
X
Xstatic void notches(fd,diskdevice,capacity)
X	int fd;
X	char *diskdevice;
X	unsigned long capacity;
X{
X    int i;
X    int maxnot,maxnotches,notch,start,end,pagesu,pagesl,
X        high_ba = 0,low_ba = 0,last_hba = -2,last_lba = -2;
X
X    if(0>scsi_read_active_notch(fd, &maxnotches, &notch,
X				&start, &end, &pagesu, &pagesl)) {
X	perror(diskdevice);
X	Error("SCSI mode sense failed. Drive does not support notch queries.");
X    }
X    printf("\nNotch Page 0: maxnotches: %d notch: %d start: %d end: %d pages: 0x%x 0x%x\n",
X	   maxnotches,notch,start,end,pagesu,pagesl);
X	printf("i\tmaxnot\tnotch\tstart\t\tend\t\tpagesU\tpagesL\n");
X
X    maxnot = maxnotches;
X    for ( i = 1 ; i <= maxnot ; i++ ) {
X	if(0>scsi_set_active_notch(fd,i)) {
X	    printf("SCSI mode sense failed at notch %d\n",i); fflush(stdout);
X	    perror(diskdevice);
X	    /* Error("SCSI mode select failed, giving up."); */
X	    break;
X	}
X	if(0>scsi_read_active_notch(fd, &maxnotches, &notch,
X				    &start, &end, &pagesu, &pagesl)) {
X	    printf("SCSI mode sense failed at notch %d\n",i); fflush(stdout);
X	    perror(diskdevice);
X	    /* Error("SCSI mode sense failed, giving up."); */
X	    /* printf("SCSI mode sense failed, giving up.\n"); */
X	    break;
X	}
X	printf("%d\t%d\t%d\t0x%08x\t0x%08x\t0x%x\t0x%x\n",
X	       i,maxnotches,notch,start,end,pagesu,pagesl);
X    }
X    if(0>scsi_set_active_notch(fd,0)) {
X	printf("SCSI mode select failed when resetting active notch\n"); fflush(stdout);
X	perror(diskdevice);
X	/* Error("SCSI mode select failed, giving up."); */
X    }
X    printf("\nblock\tcyl\thead\tsector\n");
X    for ( i = 0 ; i < capacity ; i++ ) {
X	scsi_translate_address(fd,diskdevice,i,&high_ba,&low_ba);
X	if (high_ba != last_hba || low_ba != last_lba +1) {
X	    if (i)
X		printf("%d\t0x%04x\t0x%02x\t0x%02x\n",
X		       i-1,last_hba >> 8, last_hba & 0xff, last_lba);
X	    printf("%d\t0x%04x\t0x%02x\t0x%02x\n",
X		   i, high_ba >> 8, high_ba & 0xff, low_ba);
X	}
X	last_hba = high_ba; last_lba = low_ba;
X    }
X    return;
X}
X
Xvoid report_notches(device)
Xchar *device;
X{
X	unsigned long capacity;
X	struct stat sb;
X	int fd;
X
X	if(stat(device, &sb)<0){
X		perror(device);
X		Error("Cannot access device, giving up.");
X	}
X	if(!S_ISCHR(sb.st_mode)){
X		Error("%s must be a raw disk device.", device);
X	}
X	if(0>(fd=open(device, O_RDONLY|O_NDELAY))){
X		perror(device);
X		Error("Cannot open device, giving up.");
X	}
X	/* get number of blocks available */
X	if(0>scsi_capacity(fd, &capacity)){
X		perror(device);
X		Error("SCSI READ_CAPACITY failed, giving up.");
X	}
X	notches(fd, device, capacity);
X}
X
X#endif /* NOTCH_REPORT */
END_OF_FILE
if test 11581 -ne `wc -c <'notch.c'`; then
    echo shar: \"'notch.c'\" unpacked with wrong size!
fi
# end of 'notch.c'
fi
if test -f 'notch.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'notch.h'\"
else
echo shar: Extracting \"'notch.h'\" \(334 characters\)
sed "s/^X//" >'notch.h' <<'END_OF_FILE'
X/*
X * notch.h - header file for notch.c
X *
X * Author: Rodney Van Meter
X *         University of Southern California, Information Sciences Institute
X *         rdv@isi.edu
X * 
X * $Id: notch.h,v 1.1 1997/04/05 21:10:44 jdd Exp $
X */
X
X/* Exported Procedures */
X
X#ifdef NOTCH_REPORT
Xextern int report_notches();
X#endif /* NOTCH_REPORT */
END_OF_FILE
if test 334 -ne `wc -c <'notch.h'`; then
    echo shar: \"'notch.h'\" unpacked with wrong size!
fi
# end of 'notch.h'
fi
if test ! -d 'include' ; then
    echo shar: Creating directory \"'include'\"
    mkdir 'include'
fi
if test ! -d 'include/sundev' ; then
    echo shar: Creating directory \"'include/sundev'\"
    mkdir 'include/sundev'
fi
if test -f 'include/sundev/dmaga.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/sundev/dmaga.h'\"
else
echo shar: Extracting \"'include/sundev/dmaga.h'\" \(0 characters\)
sed "s/^X//" >'include/sundev/dmaga.h' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'include/sundev/dmaga.h'`; then
    echo shar: \"'include/sundev/dmaga.h'\" unpacked with wrong size!
fi
# end of 'include/sundev/dmaga.h'
fi
if test ! -d 'include/sys' ; then
    echo shar: Creating directory \"'include/sys'\"
    mkdir 'include/sys'
fi
if test ! -d 'include/sys/scsi' ; then
    echo shar: Creating directory \"'include/sys/scsi'\"
    mkdir 'include/sys/scsi'
fi
if test ! -d 'include/sys/scsi/adapters' ; then
    echo shar: Creating directory \"'include/sys/scsi/adapters'\"
    mkdir 'include/sys/scsi/adapters'
fi
if test -f 'include/sys/scsi/adapters/espcmd.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/sys/scsi/adapters/espcmd.h'\"
else
echo shar: Extracting \"'include/sys/scsi/adapters/espcmd.h'\" \(0 characters\)
sed "s/^X//" >'include/sys/scsi/adapters/espcmd.h' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'include/sys/scsi/adapters/espcmd.h'`; then
    echo shar: \"'include/sys/scsi/adapters/espcmd.h'\" unpacked with wrong size!
fi
# end of 'include/sys/scsi/adapters/espcmd.h'
fi
if test ! -d 'include/ptisp' ; then
    echo shar: Creating directory \"'include/ptisp'\"
    mkdir 'include/ptisp'
fi
if test -f 'include/ptisp/ispmail4.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/ptisp/ispmail4.h'\"
else
echo shar: Extracting \"'include/ptisp/ispmail4.h'\" \(5583 characters\)
sed "s/^X//" >'include/ptisp/ispmail4.h' <<'END_OF_FILE'
X
X/************************************************************************/
X/*																		*/
X/* ispmail.h: ptisp mailbox definitions									*/
X/*																		*/
X/* Copyright (c) 1993 by Sun Microsystems, Inc.							*/
X/*																		*/
X/* From: ispmail.h	1.9	93/08/24 SMI									*/
X/*																		*/
X/************************************************************************/
X
Xstatic char sccsid_ispmail_h[] = "@(#) ispmail.h 96/12/11 14.1.2.1	96/12/12	Copyright 1993,94 Performance Technologies, Inc.";
X
X/*
X * Mailbox Register 0 status bit definitions.
X */
X
X#define	ISP_MBOX_EVENT_MASK				0xF000
X#define	ISP_MBOX_EVENT_ASYNCH			0x8000
X#define	ISP_MBOX_EVENT_CMD				0x4000
X
X#define	ISP_MBOX_STATUS_MASK			0x00FF
X#define	ISP_MBOX_STATUS_OK				0x00
X#define	ISP_MBOX_STATUS_INVALID_CMD		0x01
X#define	ISP_MBOX_STATUS_INVALID_PARAMS	0x02
X#define	ISP_MBOX_STATUS_BOOT_ERR		0x03
X#define	ISP_MBOX_STATUS_FIRMWARE_ERR	0x04
X
X#define	ISP_MBOX_ASYNC_RESET			0x01
X#define	ISP_MBOX_ASYNC_ERR				0x02
X#define	ISP_MBOX_ASYNC_REQ_DMA_ERR		0x03
X#define	ISP_MBOX_ASYNC_RESP_DMA_ERR		0x04
X#define	ISP_MBOX_ASYNC_WAKEUP			0x05
X#define	ISP_MBOX_ASYNC_INT_RESET		0x06
X#define	ISP_MBOX_ASYNC_INT_DEV_RESET	0x07
X#define	ISP_MBOX_ASYNC_INT_ABORT		0x08
X
X#define	ISP_MBOX_BUSY					0x04
X
X#define	ISP_MBOX_EVENT_SBUS				0x01
X#define	ISP_MBOX_EVENT_REQUEST			0x02
X
X#define	ISP_GET_MBOX_STATUS(mailbox)	(mailbox & ISP_MBOX_STATUS_MASK)
X#define	ISP_GET_MBOX_EVENT(mailbox)		(mailbox & ISP_MBOX_STATUS_MASK)
X
X/* asynch event related defines */
X#define	ISP_AEN_RESET					-1
X#define	ISP_AEN_SUCCESS					1
X#define	ISP_AEN_FAILURE					0
X
X#define	ISP_MBOX_CMD_NOP				0x00
X#define	ISP_MBOX_CMD_ABOUT_PROM			0x08
X#define	ISP_MBOX_CMD_CHECKSUM_FIRMWARE	0x0E
X#define	ISP_MBOX_CMD_STOP_FW			0x14
X#define	ISP_MBOX_CMD_LOAD_RAM			0x01
X#define	ISP_MBOX_CMD_START_FW			0x02
X#define	ISP_MBOX_CMD_DUMP_RAM			0x03
X#define	ISP_MBOX_CMD_LOAD_WORD			0x04
X#define	ISP_MBOX_CMD_DUMP_WORD			0x05
X#define	ISP_MBOX_CMD_WRAP_MAILBOXES		0x06
X#define	ISP_MBOX_CMD_CHECKSUM			0x07
X#define	ISP_MBOX_CMD_INIT_RQST_QUEUE	0x10
X#define	ISP_MBOX_CMD_INIT_RSPN_QUEUE	0x11
X#define	ISP_MBOX_CMD_SCSI_CMD			0x12
X#define	ISP_MBOX_CMD_WAKE_UP			0x13
X#define	ISP_MBOX_CMD_ABORT_IOCB			0x15
X#define	ISP_MBOX_CMD_ABORT_DEVICE		0x16
X#define	ISP_MBOX_CMD_ABORT_TARGET		0x17
X#define	ISP_MBOX_CMD_BUS_RESET			0x18
X#define	ISP_MBOX_CMD_STOP_QUEUE			0x19
X#define	ISP_MBOX_CMD_START_QUEUE		0x1A
X#define	ISP_MBOX_CMD_STEP_QUEUE			0x1B
X#define	ISP_MBOX_CMD_ABORT_QUEUE		0x1C
X#define	ISP_MBOX_CMD_GET_DEV_Q_STATE	0x1D
X#define	ISP_MBOX_CMD_GET_FW_STATUS		0x1F
X#define	ISP_MBOX_CMD_GET_SXP_CONFIG		0x2F
X#define	ISP_MBOX_CMD_SET_SXP_CONFIG		0x3F
X#define	ISP_MBOX_CMD_GET_SCSI_ID		0x20
X#define	ISP_MBOX_CMD_SET_SCSI_ID		0x30
X#define	ISP_MBOX_CMD_GET_SEL_TIMEOUT	0x21
X#define	ISP_MBOX_CMD_SET_SEL_TIMEOUT	0x31
X#define	ISP_MBOX_CMD_GET_RETRY_ATTEMPTS	0x22
X#define	ISP_MBOX_CMD_SET_RETRY_ATTEMPTS	0x32
X#define	ISP_MBOX_CMD_GET_AGE_LIMIT		0x23
X#define	ISP_MBOX_CMD_SET_AGE_LIMIT		0x33
X#define	ISP_MBOX_CMD_GET_CLOCK_RATE		0x24
X#define	ISP_MBOX_CMD_SET_CLOCK_RATE		0x34
X#define	ISP_MBOX_CMD_GET_PULL_UPS		0x25
X#define	ISP_MBOX_CMD_SET_PULL_UPS		0x35
X#define	ISP_MBOX_CMD_GET_DAT_TRANS_TIME	0x26
X#define	ISP_MBOX_CMD_SET_DAT_TRANS_TIME	0x36
X#define	ISP_MBOX_CMD_GET_SBUS_INTERFACE	0x27
X#define	ISP_MBOX_CMD_SET_SBUS_INTERFACE	0x37
X#define	ISP_MBOX_SBUS_ENA_DMA_BURST		0x02
X#define	ISP_MBOX_CMD_GET_TARGET_CAP		0x28
X#define	ISP_MBOX_CMD_SET_TARGET_CAP		0x38
X#define	ISP_MBOX_CMD_GET_DEV_Q_PARAMS	0x29
X#define	ISP_MBOX_CMD_SET_DEV_Q_PARAMS	0x39
X
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#define	ISP_CAP_10M_SYNC_PERIOD			0x0019
X#define	ISP_CAP_10M_SYNC_OFFSET			0x000C
X#define	ISP_CAP_10M_SYNC_PARAMS			0x0C19	/* (OFFSET<<8) | PERIOD	*/
X#define	ISP_CAP_8M_SYNC_PERIOD			0x0025
X#define	ISP_CAP_8M_SYNC_OFFSET			0x000C
X#define	ISP_CAP_8M_SYNC_PARAMS			0x0C25	/* (OFFSET<<8) | PERIOD	*/
X#define	ISP_CAP_5M_SYNC_PERIOD			0x0032
X#define	ISP_CAP_5M_SYNC_OFFSET			0x000C
X#define	ISP_CAP_5M_SYNC_PARAMS			0x0C32	/* (OFFSET<<8) | PERIOD	*/
X#define	ISP_CAP_4M_SYNC_PERIOD			0x0041
X#define	ISP_CAP_4M_SYNC_OFFSET			0x000C
X#define	ISP_CAP_4M_SYNC_PARAMS			0x0C41	/* (OFFSET<<8) | PERIOD	*/
X
X#define ISP_CAP_GET_PERIOD(param)		(param & 0xFF)
X#define	ISP_CAP_SET_SYNC_PERIOD(oval,sval)	( (oval)<<8 | (sval))
X#define ISP_CAP_PERIOD_CLICK			6
X
X/* mailbox related structures and defines */
X#define	ISP_MAX_MBOX_REGS				6
X#define	ISP_MBOX_CMD_TIMEOUT			10
X#define	ISP_MBOX_CMD_RETRY_CNT			1
X#define	ISP_MBOX_CMD_FLAGS_COMPLETE		0x01
X
X/*
X * mailbox command struct
X *
X * sizeof(ptisp_mbox_cmd) = 4 + 6 * 2 + 6 * 2 + 4 = 32 bytes.
X */
X
Xstruct ptisp_mbox_cmd {
X	u_int		timeout;				/* timeout for cmd				*/
X	u_short		out[ISP_MAX_MBOX_REGS];	/* outgoing registers			*/
X	u_short		in[ISP_MAX_MBOX_REGS];	/* incoming registers			*/
X	u_char		retry_cnt;				/* retry count					*/
X	u_char		n_out;					/* no of mbox out regs wrt drv	*/
X	u_char		n_in;					/* no of mbox in  regs wrt drv	*/
X	u_char		not_used;
X};
X
X/*
X * ptisp mailbox struct
X */
X
Xstruct ptisp_mbox {
X	u_char		flags; 					/* mbox register flags			*/
X	struct ptisp_mbox_cmd cmd;			/* mbox command					*/
X};
X
X#define	ISP_MBOX_CMD_BUSY_WAIT_TIME		1    /* sec						*/
X#define	ISP_MBOX_CMD_BUSY_POLL_DELAY	100  /* usecs					*/
X
X/*........................... End of ispmail.h .........................*/
END_OF_FILE
if test 5583 -ne `wc -c <'include/ptisp/ispmail4.h'`; then
    echo shar: \"'include/ptisp/ispmail4.h'\" unpacked with wrong size!
fi
# end of 'include/ptisp/ispmail4.h'
fi
if test -f 'include/ptisp/ptisp4.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/ptisp/ptisp4.h'\"
else
echo shar: Extracting \"'include/ptisp/ptisp4.h'\" \(10773 characters\)
sed "s/^X//" >'include/ptisp/ptisp4.h' <<'END_OF_FILE'
X
X/************************************************************************/
X/*																		*/
X/* ptisp.h: Header file for ptisp.c										*/
X/*																		*/
X/* Copyright (c) 1993 by Sun Microsystems, Inc.							*/
X/*																		*/
X/* From: ispvar.h	1.25	93/07/29 PTI								*/
X/*																		*/
X/************************************************************************/
X
Xstatic char sccsid_ptisp_h[] = "@(#) ptisp.h 96/12/11 14.1.2.1 96/12/11     Copyright 1993,94 Performance Technologies, Inc."; 
X
X/*
X * Convenient short hand defines
X */
X
X#define	TRUE					1
X#define	FALSE					0
X#define	UNDEFINED				-1
X
X#define	MSW(x)					(short) (((long) x >> 16) & 0xFFFF)
X#define	LSW(x)					(short) ((long) x & 0xFFFF)
X
X#define	NPTISPBUS				8
X#ifdef NTARGETS
X#undef NTARGETS
X#endif
X#define	NTARGETS				16
X
X#define	TGT(sp)					((sp)->cmd_pkt.pkt_address.a_target)
X#define	LUN(sp)					((sp)->cmd_pkt.pkt_address.a_lun)
X
X#define	PTISP_RETRY_DELAY		5
X#define	PTISP_RETRIES			0
X
X/*
X * On-board Status Register offset from register attribute.
X */
X
X#define PTISP_OBSTAT_OFFSET		0x10000
X#define	PTISP_OBSTAT_ECOUNT		10		/* report err after 10 in a row	*/
X
X/* 
X * OBSTAT bit defines
X */
X
X#define PTISP_OBSTAT_TERMPWR	0x80	/* Termpwr state				*/
X#define PTISP_OBSTAT_FUSERR		0x40	/* Fuse Error (open)			*/
X#define PTISP_OBSTAT_PODIS		0x20	/* Power Up Disable State		*/
X#define PTISP_OBSTAT_DIFFSNS	0x10	/* Differential Sense			*/
X#define PTISP_OBSTAT_INTMSK		0x0c	/* Mask for interrupt level		*/
X#define PTISP_OBSTAT_SWMSK		0x03	/* Switch pack mask				*/
X
X/*
X * Interrupt actions returned by ptisp_i_flag_event()
X */
X
X#define	PTISP_ACTION_CONTINUE	0
X#define	PTISP_ACTION_RETURN		1
X#define	PTISP_ACTION_IGNORE		2
X
X/*
X * Reset actions for ptisp_i_reset_interface()
X */
X
X#define	PTISP_RESET_BUS_IF_BUSY	0x01	/* reset scsi bus if it is busy	*/
X#define	PTISP_FORCE_RESET_BUS	0x02	/* reset scsi bus on error reco */
X
X/*
X * timeout values
X */
X
X#define	PTISP_TIMEOUT_GRACE		50		/* Timeout margin (sec.)		*/
X#define	PTISP_TIMEOUT_DELAY(s, d)		(s * (1000000 / d))
X
X/*
X * delay time for polling loops
X */
X
X#define	PTISP_POLL_DELAY_TIME	1000	/* usecs						*/
X
X/*
X * busy wait delay time after chip reset
X */
X
X#define	PTISP_RESET_BSY_WAIT_TM	100		/* usecs						*/
X
X/*
X * timeout for ISP coming out of reset
X */
X
X#define	PTISP_RESET_WAIT_TIME	1000	/* ms							*/
X#define	PTISP_SOFT_RESET_TIME	1		/* second						*/
X
X/*
X * timeout for reading the response
X */
X
X#define	PTISP_RESPONSE_TIME		100
X
X/*
X * Size definitions for request and response queues.
X */
X
X#define	PTISP_MAX_REQUESTS		256
X#define	PTISP_MAX_RESPONSES		256
X
X/*
X * ISP request packet as defined by the Firmware Interface
X */
X
Xstruct ptisp_dataseg {
X	long		d_base;
X	long		d_count;
X};
X
X/*
X * The request/response header entry
X */
X
Xstruct ptisp_cq_header {
X	char		entry_count;
X	char		entry_type;
X	u_char		flags;
X	u_char		seqno;
X};
X
Xstruct ptisp_request {
X	struct ptisp_cq_header header;
X	opaque_t	token;
X	char		target;
X	char		lun_trn;
X	union {
X		short	cdblen;
X		short	modifier;
X	} cm;
X	short		flags;
X	short		reserved;
X	short		timeout;
X	short		seg_count;
X	u_char		cdb[12];
X	struct ptisp_dataseg dataseg[4];
X};
X
X/*
X * Header flags definitions
X */
X
X#define	PTISP_CQ_FLAG_CONT			0x01
X#define	PTISP_CQ_FLAG_FULL			0x02
X#define	PTISP_CQ_FLAG_BADHEADER		0x04
X#define	PTISP_CQ_FLAG_BADPACKET		0x08
X#define	PTISP_CQ_FLAG_ERR_MASK		0x0E
X
X/*
X * Header entry_type definitions
X */
X
X#define	PTISP_CQ_TYPE_REQUEST		1
X#define	PTISP_CQ_TYPE_DATASEG		2
X#define	PTISP_CQ_TYPE_RESPONSE		3
X#define	PTISP_CQ_TYPE_MARKER		4
X#define	PTISP_CQ_TYPE_CMDONLY		5
X
X#define	PTISP_CDBMAX				12
X
X/*
X * marker packet (req_modifier) values
X */
X
X#define	PTISP_SYNCHRONIZE_NEXUS		0
X#define	PTISP_SYNCHRONIZE_TARGET	1
X#define	PTISP_SYNCHRONIZE_ALL		2
X
X/*
X * request flag values
X */
X
X#define	PTISP_REQ_FLAG_NODISCON		0x0001
X#define	PTISP_REQ_FLAG_HEAD_TAG		0x0002
X#define	PTISP_REQ_FLAG_ORDERED_TAG	0x0004
X#define	PTISP_REQ_FLAG_SIMPLE_TAG	0x0008
X#define	PTISP_REQ_FLAG_USE_TRN		0x0010
X#define	PTISP_REQ_FLAG_DATA_READ	0x0020
X#define	PTISP_REQ_FLAG_DATA_WRITE	0x0040
X#define	PTISP_REQ_FLAG_MASK			0x00FF
X
X/*
X * throttle values for ISP request queue
X */
X#define	PTISP_SHUTDOWN_THROTTLE		-1		/* do not submit any reqs	*/
X#define	PTISP_CLEAR_THROTTLE		(PTISP_MAX_REQUESTS - 1)
X
X/*
X * ISP response packet as defined by the Firmware Interface
X */
X
Xstruct ptisp_response {
X	struct ptisp_cq_header header;
X	opaque_t	token;
X	short		scb;
X	short		reason;
X	short		state;
X	short		flags;
X	short		timeout;
X	short		rqs_count;
X	long		resid;
X	long		reserved[2];
X	long		sense[8];
X};
X
X#define	PTISP_STAT_NEGOTIATE		0x0080
X
X/*
X * ptisp softstate structure
X */
X
X/*
X * This struct is defined for saving time in computing the slot number
X * for a known target.
X */
X
Xstruct ptisp_slot {
X	struct scsi_cmd *cmds[PTISP_MAX_REQUESTS];
X};
X
X/*
X * ptisp_pkt_private: Private stuff for a SCSI packet.
X *
X * We use the pkt_ha_private as the pointer to such a struct.  The forw
X * field was in the SCSI packet in Solaris 2.x.  But now we don't have
X * that defined in SunOS 4.1.x.  So this forw has to be moved here.
X */
X
Xstruct ptisp_pkt_private {
X	struct ptisp_response	*rspn;
X	struct scsi_cmd			*forw;
X	u_short					deadbeef;
X	int						tag;
X	struct ptisp_pkt_private *next;
X	struct ptisp_pkt_private *prev;
X};
X
X/*
X * ptisp: Driver unit structure
X *
X * Each host adapter will export the address of this structure,
X * which defines function entry points
X * The library will use the address of this structure to form
X * SCSI device addresses- the address of this structure will
X * be encoded in the 'a_cookie' field of the SCSI device address.
X *
X * All requests are defined such that the SCSI address is either
X * a formal paramter, or contained within a formal parameter.
X *
X * Therefore, each function entry in the driver will know that
X * the 'a_cookie' field points to a transport structure, which
X * will then allow each function to retrieve a pointer to the
X * correct soft_state structure.
X */
X
Xstruct ptisp {
X	struct scsi_transport tran;		/* This one MUST be first			*/
X
X	struct ptisp_slot slots[NTARGETS];
X
X	struct dev_info *dev;			/* Pointer to devinfo structure		*/
X
X	struct ispregs	*reg;			/* ISP1000 register pointer			*/
X
X	struct ptisp_request *rqst_ptr;	/* Current request					*/
X	struct ptisp_request *rqst_base;/* Request Q base address			*/
X	u_long			rqst_dvma;		/* Request Q DVMA space				*/
X
X	struct ptisp_response *rspn_ptr;/* Current response Q pointer		*/
X	struct ptisp_response *rspn_base;
X    u_long			rspn_dvma;
X
X	int				qspace;			/* ISP request/response Q pointers	*/
X
X	u_long			burstsize;
X
X	caddr_t			ob_statreg;		/* Ptr to mapped in status register	*/
X
X	u_short			cap[NTARGETS];	/* Target capabilities				*/
X	u_short			sync[NTARGETS];
X
X	short			major_rev;		/* Major/minor firmware rev number	*/
X	short			minor_rev;
X
X	char			unit_no;		/* Unit number of this card			*/
X	char			scsi_id;		/* Host adapter SCSI ID				*/
X	u_char			shutdown;		/* HA can't do anything				*/
X
X	u_char			diffmode;		/* Differential mode flag			*/
X	u_char			ultramode;		/* Ultra SCSI-3 mode				*/
X	u_char			tmoncount;		/* report errors when down to 0		*/
X	u_char			display_rate[16];	
X									/* Display the rate of drives */
X	u_char			intr_level;		/* SBus interrupt level				*/
X
X	struct ptisp_mbox mbox;			/* Mbox values are stored here		*/
X
X	int				prev_tms;		/* TMON interface status			*/
X	int				chk_tms;
X
X	u_short			rqst_in;		/* Request/Response in/out counter	*/
X	u_short			rqst_out;
X	u_short			rspn_in;
X	u_short			rspn_out;
X
X	int				ncmds[NTARGETS];/* For ptispinfo only				*/
X	int				nreads[NTARGETS];
X	int				nwrites[NTARGETS];
X	int				kbytes[NTARGETS];
X	u_int			sync_told;		/* Bitmap for targets				*/
X
X	u_char			tags[NTARGETS];
X
X	struct buf		rqst_buf;		/* mb_mapalloc buf struct for rqst	*/
X	struct buf		rspn_buf;		/* mb_mapalloc buf struct for rspn	*/
X
X	int				npkt_avail;		/* Available private buffers		*/
X	int				npkt_used;		/* Used private buffers				*/
X	struct ptisp_pkt_private *pkt_head;
X	struct ptisp_pkt_private *pkt_free;
X	struct ptisp_pkt_private pkts[PTISP_MAX_REQUESTS];
X
X};
X
X/*
X * Handy definitions for the above fields.  They should be used the same
X * as TGT() and LUN() macros because this struct is part of a sp.
X */
X
X#define	PTISP_PKT_PRIVATE(sp) \
X	((struct ptisp_pkt_private *) ((sp)->cmd_pkt.pkt_ha_private))
X
X#define	RSPN(sp)	(PTISP_PKT_PRIVATE(sp)->rspn)
X#define	FORW(sp)	(PTISP_PKT_PRIVATE(sp)->forw)
X#define	TAG(sp)		(PTISP_PKT_PRIVATE(sp)->tag)
X
X/*
X * Cpu types for determine burst sizes
X */
X
X#define	CPU_TYPE_IPC		0x52
X#define	CPU_TYPE_IPX		0x57
X#define	CPU_TYPE_SPARC2		0x55
X#define	CPU_TYPE_SLC		0x54
X#define	CPU_TYPE_ELC		0x56
X#define	CPU_TYPE_SPARC10	0x72
X#define	CPU_TYPE_SPARCMP	0x71
X#define	CPU_TYPE_SPARC1P	0x53
X#define	CPU_TYPE_SYS5K		0xF7
X#define	CPU_TYPE_LX_OR_SPARC5			0x80
X
X/*
X * Speed to SCSI period conversion table.
X */
X
X/* ISP1000 fast wide scsi-2 */
Xunsigned char ptisp_speed2period_fast[] = {
X	0x0, 0x0, 0x0, 0x0, 0x38, 0x32, 0x2d, 0x2a, 0x25, 0x1e, 0x19,
X};
Xchar *ptisp_speed2rate_fast[] = {
X        "async", "async", "async", "async", "4.5" ,"5", "5.5","6","6.5","8","10"
X};
X
X/* ISP1000 ultra wide scsi-3 */
Xunsigned char ptisp_speed2period[] = {
X           0x0,0x42,0x3a,0x32,0x2a,0x21,0x1e,0x19,0x15,0x10,0xc 
X};
Xchar *ptisp_speed2rate[11] = {
X       "async", "3", "4", "5", "6", "7", "8","10","12","15","20" 
X};
X
X/*
X * Firmware download options.  For external variable ptisp_update_fw.
X */
X
X#define	PTISP_FW_UPDATE_OFF	0		/* Don't update firmware	*/
X#define	PTISP_FW_UPDATE_NEWER	1		/* Update if firmware is newer	*/
X#define	PTISP_FW_UPDATE_ALWAYS	2		/* Force firmware update	*/
X
X/*
X * Default SCSI Host Adapter ID
X */
X
X#define	PTISP_DEFAULT_HOSTID	7
X
X/*
X * Some flags are not defined in SunOS4.1.3.  Fortunately we still have
X * some bits to fake them by ourselves.
X */
X
X#define CFLAG_COMPLETED			0x2000
X#define	CFLAG_FINISHED			0x4000
X#define	CFLAG_IN_TRANSPORT		0x8000
X#define	STAT_BUS_RESET			0x8
X#define	STAT_TIMEOUT			0x10
X#define	SCSI_OPTIONS_TAG		0x80
X#define	SCSI_OPTIONS_WIDE		0x100
X#define	STATE_ARQ_DONE			0x20
X#define	SCMD_MODE_SENSE_G1		0x5A
X#define	SCMD_MODE_SELECT_G1		0x55
X
X/*
X * Unavailable SCSA variables.
X *
X * We need to figure out the initial values for them.
X */
X
Xint scsi_tag_age_limit = 100;
X
X/*
X * Our own stuff for onboard monitor.
X */
X
X#ifndef KEND
X#define PTISP_SBUS_INT_INSRAM			0xFF00
X#define PTISP_SBUS_ID_INSRAM			0xFF80
X#else
X#define PTISP_SBUS_INT_INSRAM			0xBFFE
X#define PTISP_SBUS_ID_INSRAM			0xFFFE
X#endif KEND
X
X
X/* Our additions for SCSI capabilities.  ie case: PTISP_CAP_VALUE + offset */
X
Xchar *ptisp_scsi_capstrings[] =
X{
X    "auto-rqsense",
X    0
X};
X
X#define PTISP_CAP_VALUE		0x8000
X
X#define PTISP_SCSI_CAP_ARQ	0x8000
X
X/*........................... End of ptisp.h ...........................*/
END_OF_FILE
if test 10773 -ne `wc -c <'include/ptisp/ptisp4.h'`; then
    echo shar: \"'include/ptisp/ptisp4.h'\" unpacked with wrong size!
fi
# end of 'include/ptisp/ptisp4.h'
fi
if test -f 'include/ptisp/ispmail5.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/ptisp/ispmail5.h'\"
else
echo shar: Extracting \"'include/ptisp/ispmail5.h'\" \(6107 characters\)
sed "s/^X//" >'include/ptisp/ispmail5.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1993 by Sun Microsystems, Inc.
X */
X
X#ifndef _SYS_SCSI_ADAPTERS_ISPMAIL_H
X#define	_SYS_SCSI_ADAPTERS_ISPMAIL_H
X
X#pragma ident  "@(#) ispmail.h 96/06/14 7.3       97/02/19     Copyright 1993,94,95,96 Performance Technologies, Inc."
X
X/*
X * isp mailbox definitions
X */
X
X#ifdef	__cplusplus
Xextern "C" {
X#endif
X
X/*
X * Mailbox Register 0 status bit definitions.
X */
X#define	ISP_MBOX_EVENT_MASK			0xF000
X#define	ISP_MBOX_EVENT_ASYNCH			0x8000
X#define	ISP_MBOX_EVENT_CMD			0x4000
X
X#define	ISP_MBOX_STATUS_MASK			0x00FF
X#define	ISP_MBOX_STATUS_OK			0x00
X#define	ISP_MBOX_STATUS_INVALID_CMD		0x01
X#define	ISP_MBOX_STATUS_INVALID_PARAMS		0x02
X#define	ISP_MBOX_STATUS_BOOT_ERR		0x03
X#define	ISP_MBOX_STATUS_FIRMWARE_ERR		0x04
X
X#define	ISP_MBOX_ASYNC_RESET			0x01
X#define	ISP_MBOX_ASYNC_ERR			0x02
X#define	ISP_MBOX_ASYNC_REQ_DMA_ERR		0x03
X#define	ISP_MBOX_ASYNC_RESP_DMA_ERR		0x04
X#define	ISP_MBOX_ASYNC_WAKEUP			0x05
X#define	ISP_MBOX_ASYNC_INT_RESET		0x06
X#define	ISP_MBOX_ASYNC_INT_DEV_RESET		0x07
X#define	ISP_MBOX_ASYNC_INT_ABORT		0x08
X
X#define	ISP_MBOX_BUSY				0x04
X
X#define	ISP_MBOX_EVENT_SBUS			0x01
X#define	ISP_MBOX_EVENT_REQUEST			0x02
X
X#define	ISP_GET_MBOX_STATUS(mailbox)		\
X	(mailbox & ISP_MBOX_STATUS_MASK)
X#define	ISP_GET_MBOX_EVENT(mailbox)		\
X	(mailbox & ISP_MBOX_STATUS_MASK)
X
X/* asynch event related defines */
X#define	ISP_AEN_RESET	-1
X#define	ISP_AEN_SUCCESS	1
X#define	ISP_AEN_FAILURE	0
X
X#define	ISP_MBOX_CMD_NOP				0x00
X#define	ISP_MBOX_CMD_ABOUT_PROM				0x08
X#define	ISP_MBOX_CMD_CHECKSUM_FIRMWARE			0x0E
X#define	ISP_MBOX_CMD_STOP_FW				0x14
X#define	ISP_MBOX_CMD_LOAD_RAM				0x01
X#define	ISP_MBOX_CMD_START_FW				0x02
X#define	ISP_MBOX_CMD_DUMP_RAM				0x03
X#define	ISP_MBOX_CMD_LOAD_WORD				0x04
X#define	ISP_MBOX_CMD_DUMP_WORD				0x05
X#define	ISP_MBOX_CMD_WRAP_MAILBOXES			0x06
X#define	ISP_MBOX_CMD_CHECKSUM				0x07
X#define	ISP_MBOX_CMD_INIT_REQUEST_QUEUE			0x10
X#define	ISP_MBOX_CMD_INIT_RESPONSE_QUEUE		0x11
X#define	ISP_MBOX_CMD_SCSI_CMD				0x12
X#define	ISP_MBOX_CMD_WAKE_UP				0x13
X#define	ISP_MBOX_CMD_ABORT_IOCB				0x15
X#define	ISP_MBOX_CMD_ABORT_DEVICE			0x16
X#define	ISP_MBOX_CMD_ABORT_TARGET			0x17
X#define	ISP_MBOX_CMD_BUS_RESET				0x18
X#define	ISP_MBOX_CMD_STOP_QUEUE				0x19
X#define	ISP_MBOX_CMD_START_QUEUE			0x1A
X#define	ISP_MBOX_CMD_STEP_QUEUE				0x1B
X#define	ISP_MBOX_CMD_ABORT_QUEUE			0x1C
X#define	ISP_MBOX_CMD_GET_DEVICE_QUEUE_STATE		0x1D
X#define	ISP_MBOX_CMD_GET_ISP_STAT			0x1E
X#define	ISP_MBOX_CMD_GET_FIRMWARE_STATUS		0x1F
X#define	ISP_MBOX_CMD_GET_SXP_CONFIG			0x2F
X#define	ISP_MBOX_CMD_SET_SXP_CONFIG			0x3F
X#define	ISP_MBOX_CMD_GET_SCSI_ID			0x20
X#define	ISP_MBOX_CMD_SET_SCSI_ID			0x30
X#define	ISP_MBOX_CMD_GET_SEL_TIMEOUT			0x21
X#define	ISP_MBOX_CMD_SET_SEL_TIMEOUT			0x31
X#define	ISP_MBOX_CMD_GET_RETRY_ATTEMPTS			0x22
X#define	ISP_MBOX_CMD_SET_RETRY_ATTEMPTS			0x32
X#define	ISP_MBOX_CMD_GET_AGE_LIMIT			0x23
X#define	ISP_MBOX_CMD_SET_AGE_LIMIT			0x33
X#define	ISP_MBOX_CMD_GET_CLOCK_RATE			0x24
X#define	ISP_MBOX_CMD_SET_CLOCK_RATE			0x34
X#define	ISP_MBOX_CMD_GET_PULL_UPS			0x25
X#define	ISP_MBOX_CMD_SET_PULL_UPS			0x35
X#define	ISP_MBOX_CMD_GET_DATA_TRANS_TIME		0x26
X#define	ISP_MBOX_CMD_SET_DATA_TRANS_TIME		0x36
X#define	ISP_MBOX_CMD_GET_SBUS_INTERFACE			0x27
X#define	ISP_MBOX_CMD_SET_SBUS_INTERFACE			0x37
X#define	ISP_MBOX_SBUS_INTERFACE_ENABLE_DMA_BURST	0x02
X#define	ISP_MBOX_CMD_GET_TARGET_CAP			0x28
X#define	ISP_MBOX_CMD_SET_TARGET_CAP			0x38
X#define	ISP_MBOX_CMD_GET_DEVICE_QUEUE_PARAMS		0x29
X#define	ISP_MBOX_CMD_SET_DEVICE_QUEUE_PARAMS		0x39
X#define	ISP_MBOX_CMD_GET_QFULL_RETRIES			0x2A
X#define	ISP_MBOX_CMD_SET_QFULL_RETRIES			0x3A
X#define	ISP_MBOX_CMD_GET_QFULL_RETRY_INTERVAL		0x2B
X#define	ISP_MBOX_CMD_SET_QFULL_RETRY_INTERVAL		0x3B
X
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#define	ISP_10M_SYNC_PERIOD	0x0019
X#define	ISP_10M_SYNC_OFFSET	0x000C
X#define	ISP_10M_SYNC_PARAMS	((ISP_10M_SYNC_OFFSET << 8) | \
X				ISP_10M_SYNC_PERIOD)
X#define	ISP_8M_SYNC_PERIOD	0x0025
X#define	ISP_8M_SYNC_OFFSET	0x000C
X#define	ISP_8M_SYNC_PARAMS	((ISP_8M_SYNC_OFFSET << 8) | \
X				ISP_8M_SYNC_PERIOD)
X#define	ISP_5M_SYNC_PERIOD	0x0032
X#define	ISP_5M_SYNC_OFFSET	0x000C
X#define	ISP_5M_SYNC_PARAMS	((ISP_5M_SYNC_OFFSET << 8) | \
X				ISP_5M_SYNC_PERIOD)
X#define	ISP_4M_SYNC_PERIOD	0x0041
X#define	ISP_4M_SYNC_OFFSET	0x000C
X#define	ISP_4M_SYNC_PARAMS	((ISP_4M_SYNC_OFFSET << 8) | \
X				ISP_4M_SYNC_PERIOD)
X
X/* mailbox related structures and defines */
X#define	ISP_MAX_MBOX_REGS		6
X#define	ISP_MBOX_CMD_TIMEOUT		10
X#define	ISP_MBOX_CMD_RETRY_CNT		1
X
X
X#define	ISP_MBOX_CMD_FLAGS_COMPLETE	0x01
X
X/* mailbox command struct */
Xstruct isp_mbox_cmd {
X	u_int		timeout;	/* timeout for cmd */
X	u_char		retry_cnt;	/* retry count */
X	u_char		n_mbox_out;	/* no of mbox out regs wrt driver */
X	u_char		n_mbox_in;	/* no of mbox in  regs wrt driver */
X	u_short		mbox_out [ISP_MAX_MBOX_REGS]; /* outgoing registers  */
X	u_short		mbox_in  [ISP_MAX_MBOX_REGS]; /* incoming registers  */
X};
X/* MEMBERS PROTECTED BY "Semaphore": timeout, retry_cnt		*/
X/* MEMBERS PROTECTED BY "Semaphore": n_mbox_out, n_mbox_in	*/
X/* MEMBERS PROTECTED BY "Semaphore": mbox_out, mbox_in		*/
X
X
X/* isp mailbox struct */
Xstruct isp_mbox {
X	ksema_t			mbox_sema;   /* sema to sequentialize access */
X	u_char			mbox_flags;  /* mbox register flags */
X	struct isp_mbox_cmd 	mbox_cmd;    /* mbox command */
X};
X
X
X#define	ISP_MBOX_CMD_BUSY_WAIT_TIME		1    /* sec */
X#define	ISP_MBOX_CMD_BUSY_POLL_DELAY_TIME	100  /* usecs */
X
X/* PTI added: */
X
X#define ISP_PRESENT_PERIOD(param)       (param & 0xff)
X#define ISP_SET_SYNC_PERIOD(sval)       ((ISP_10M_SYNC_OFFSET << 8) | sval)
X#define PCLICK 				6
X
X#ifndef KEND
X#define SBUS_INT_INSRAM 0xFF00
X#define SBUS_DIFF_INSRAM 0xFF80
X#else
X#define SBUS_INT_INSRAM 0xBFFE
X#define SBUS_DIFF_INSRAM 0xFFFE
X#endif KEND
X#define SBUSLEVEL3 3
X#define SBUSLEVEL2 2
X#define SBUSLEVEL5 5
X#define RATE_FIELD 0x00ff
X
X#ifdef	__cplusplus
X}
X#endif
X
X#endif	/* _SYS_SCSI_ADAPTERS_ISPMAIL_H */
END_OF_FILE
if test 6107 -ne `wc -c <'include/ptisp/ispmail5.h'`; then
    echo shar: \"'include/ptisp/ispmail5.h'\" unpacked with wrong size!
fi
# end of 'include/ptisp/ispmail5.h'
fi
if test -f 'include/ptisp/ispvar5.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'include/ptisp/ispvar5.h'\"
else
echo shar: Extracting \"'include/ptisp/ispvar5.h'\" \(17616 characters\)
sed "s/^X//" >'include/ptisp/ispvar5.h' <<'END_OF_FILE'
X/*
X * Copyright (c) 1993 by Sun Microsystems, Inc.
X */
X
X#ifndef _SYS_SCSI_ADAPTERS_ISPVAR_H
X#define	_SYS_SCSI_ADAPTERS_ISPVAR_H
X
X#pragma ident "@(#) ispvar.h 96/06/14 7.3       97/02/19     Copyright 1993,94,95,96 Performance Technologies, Inc."
X
X#ifdef	__cplusplus
Xextern "C" {
X#endif
X
X/*
X * Convenient short hand defines
X */
X#define	TRUE			 1
X#define	FALSE			 0
X#define	UNDEFINED		-1
X
X#define	CNUM(isp)		(ddi_get_instance(isp->isp_tran.tran_dev))
X
X#define	ISP_RETRY_DELAY		5
X#define	ISP_RETRIES		0	/* retry of selections */
X#define	ISP_INITIAL_SOFT_SPACE	5	/* Used for the softstate_init func */
X
X#define	MSW(x)			(short)(((long)x >> 16) & 0xFFFF)
X#define	LSW(x)			(short)((long)x & 0xFFFF)
X
X#define	TGT(sp)			(CMD2PKT(sp)->pkt_address.a_target)
X#define	LUN(sp)			(CMD2PKT(sp)->pkt_address.a_lun)
X
X#define	HW_REV(val)		(((val) >>8) & 0xff)
X#define	FW_REV(val)		((val) & 0xff)
X
X/*
X *  Use for Qfull Capability
X */
X#define	ISP_GET_QFULL_CAP	1
X#define	ISP_SET_QFULL_CAP	0
X
X/*
X *	Tag reject
X */
X#define	TAG_REJECT	28
X/*
X * Interrupt actions returned by ptisp_i_flag_event()
X */
X#define	ACTION_CONTINUE		0	/* Continue */
X#define	ACTION_RETURN		1	/* Exit */
X#define	ACTION_IGNORE		2	/* Ignore */
X
X/*
X * Reset actions for ptisp_i_reset_interface()
X */
X#define	ISP_RESET_BUS_IF_BUSY	0x01	/* reset scsi bus if it is busy */
X#define	ISP_FORCE_RESET_BUS	0x02	/* reset scsi bus on error reco */
X
X
X/*
X * firmware download options for ptisp_i_download_fw()
X */
X#define	ISP_DOWNLOAD_FW_OFF		0
X#define	ISP_DOWNLOAD_FW_IF_NEWER	1
X#define	ISP_DOWNLOAD_FW_ALWAYS		2
X
X/*
X * extracting period and offset from isp_synch
X */
X#define	PERIOD_MASK(val)	((val) & 0xff)
X#define	OFFSET_MASK(val)	(((val) >>8) & 0xff)
X
X/*
X * timeout values
X */
X#define	ISP_GRACE		10	/* Timeout margin (sec.) */
X#define	ISP_TIMEOUT_DELAY(secs, delay)	(secs * (1000000 / delay))
X
X/*
X * delay time for polling loops
X */
X#define	ISP_NOINTR_POLL_DELAY_TIME		1000	/* usecs */
X
X/*
X * busy wait delay time after chip reset
X */
X#define	ISP_CHIP_RESET_BUSY_WAIT_TIME		100	/* usecs */
X
X/*
X * timeout for ISP coming out of reset
X */
X#define	ISP_RESET_WAIT				1000	/* ms */
X#define	ISP_SOFT_RESET_TIME			1	/* second */
X
X
X/*
X * Debugging macros
X */
X#ifdef PTISPDEBUG
X
X#define	ISP_DEBUG	if (ptispdebug) ptisp_i_log
X#define	ISP_DEBUG2	if (ptispdebug > 1) ptisp_i_log
X
X#else	/* ISPDEBUG */
X
X#define	ptispdebug	(0)
X#define	INFORMATIVE	(0)
X#define	DEBUGGING	(0)
X#define	DEBUGGING_ALL	(0)
X
X#define	ISP_DEBUG	if (0) ptisp_i_log
X#define	ISP_DEBUG2	if (0) ptisp_i_log
X
X#endif /* PTISPDEBUG */
X
X/*
X * Size definitions for request and response queues.
X */
X#define	ISP_MAX_REQUESTS	256
X#define	ISP_MAX_RESPONSES	256
X#define	ISP_QUEUE_SIZE		\
X	(ISP_MAX_REQUESTS  * sizeof (struct isp_request) + \
X	    ISP_MAX_RESPONSES * sizeof (struct isp_response))
X
X/*
X * ISP request packet as defined by the Firmware Interface
X */
Xstruct isp_dataseg {
X	long	d_base;
X	long	d_count;
X};
X
X
Xstruct cq_header {
X	u_char	cq_entry_count;
X	u_char	cq_entry_type;
X	u_char	cq_flags;
X	u_char	cq_seqno;
X};
X
Xstruct isp_request {
X	struct cq_header	req_header;
X	opaque_t		req_token;
X
X	u_char			req_target;
X	u_char			req_lun_trn;
X	u_short			req_cdblen;
X#define	req_modifier		req_cdblen	/* marker packet */
X	u_short			req_flags;
X	u_short			req_reserved;
X	u_short			req_time;
X	u_short			req_seg_count;
X
X	u_long			req_cdb[3];
X	struct isp_dataseg	req_dataseg[4];
X};
X
X#define	ISP_UPDATE_QUEUE_SPACE(isp) \
X	isp->isp_request_out = ISP_GET_REQUEST_OUT(isp); \
X	if (isp->isp_request_in == isp->isp_request_out) { \
X		isp->isp_queue_space = ISP_MAX_REQUESTS - 1; \
X	} else if (isp->isp_request_in > isp->isp_request_out) { \
X		isp->isp_queue_space = ((ISP_MAX_REQUESTS - 1) - \
X		    (isp->isp_request_in - isp->isp_request_out)); \
X	} else { \
X		isp->isp_queue_space = isp->isp_request_out - \
X		    isp->isp_request_in - 1; \
X	}
X
X/*
X * Header flags definitions
X */
X#define	CQ_FLAG_CONTINUATION	0x01
X#define	CQ_FLAG_FULL		0x02
X#define	CQ_FLAG_BADHEADER	0x04
X#define	CQ_FLAG_BADPACKET	0x08
X#define	CQ_FLAG_ERR_MASK	\
X	(CQ_FLAG_FULL | CQ_FLAG_BADHEADER | CQ_FLAG_BADPACKET)
X
X/*
X * Header entry_type definitions
X */
X#define	CQ_TYPE_REQUEST		1
X#define	CQ_TYPE_DATASEG		2
X#define	CQ_TYPE_RESPONSE	3
X#define	CQ_TYPE_MARKER		4
X#define	CQ_TYPE_CMDONLY		5
X
X/*
X * Copy cdb into request using long word transfers to save time.
X */
X#define	ISP_CDBMAX	12
X#define	ISP_LOAD_REQUEST_CDB(req, sp, cdbsize) { \
X	register long *cdbp, *sp_cdbp; \
X	(req)->req_cdblen = (short)(cdbsize); \
X	cdbp = (long *)(req)->req_cdb; \
X	sp_cdbp = (long *)CMD2PKT(sp)->pkt_cdbp; \
X	*cdbp = *sp_cdbp, *(cdbp+1) = *(sp_cdbp+1), \
X	*(cdbp+2) = *(sp_cdbp+2); \
X}
X
X/*
X * marker packet (req_modifier) values
X */
X#define	SYNCHRONIZE_NEXUS	0
X#define	SYNCHRONIZE_TARGET	1
X#define	SYNCHRONIZE_ALL		2
X
X/*
X * request flag values
X */
X#define	ISP_REQ_FLAG_NODISCON		0x0001
X#define	ISP_REQ_FLAG_HEAD_TAG		0x0002
X#define	ISP_REQ_FLAG_ORDERED_TAG	0x0004
X#define	ISP_REQ_FLAG_SIMPLE_TAG		0x0008
X#define	ISP_REQ_FLAG_USE_TRN		0x0010
X#define	ISP_REQ_FLAG_DATA_READ		0x0020
X#define	ISP_REQ_FLAG_DATA_WRITE		0x0040
X#define	ISP_REQ_FLAG_DISARQ		0x0080
X#define	ISP_REQ_FLAG_MASK		0x00FF
X
X/*
X * translate scsi_pkt flags into ISP request packet flags
X * It would be illegal if two flags are set; the driver does not
X * check for this. Setting NODISCON and a tag flag is harmless.
X */
X#define	ISP_SET_PKT_FLAGS(scsa_flags, isp_flags) {		\
X	isp_flags = (scsa_flags >> 11) & 0xe; /* tags */ \
X	isp_flags |= (scsa_flags >> 1) & 0x1; /* no disconnect */  \
X}
X
X/*
X * isp_request size minus header.
X */
X#define	ISP_PAYLOAD		\
X	(sizeof (struct isp_request) - sizeof (struct cq_header))
X
X/*
X * throttle values for ISP request queue
X */
X#define	SHUTDOWN_THROTTLE	-1	/* do not submit any requests */
X#define	CLEAR_THROTTLE		(ISP_MAX_REQUESTS -1)
X
X/*
X * XXX: Note, this request queue macro *ASSUMES* that queue full cannot
X *	occur.
X */
X#define	ISP_GET_NEXT_REQUEST_IN(isp, ptr) { \
X	(ptr) = (isp)->isp_request_ptr; \
X	if ((isp)->isp_request_in == (ISP_MAX_REQUESTS - 1)) {	 \
X		(isp)->isp_request_in = 0; \
X		(isp)->isp_request_ptr = (isp)->isp_request_base; \
X	} else { \
X		(isp)->isp_request_in++; \
X		(isp)->isp_request_ptr++; \
X	} \
X}
X
X/*
X * slots queue for isp timeout handling
X * Must be a multiple of 8
X */
X#define	ISP_DISK_QUEUE_DEPTH	100
X#define	ISP_MAX_SLOTS		((NTARGETS_WIDE * ISP_DISK_QUEUE_DEPTH) + \
X				ISP_MAX_REQUESTS)
X
X/*
X * ISP response packet as defined by the Firmware Interface
X */
Xstruct isp_response {
X	struct cq_header	resp_header;
X	opaque_t		resp_token;
X
X	u_short			resp_scb;
X	u_short			resp_reason;
X	u_short			resp_state;
X	u_short			resp_status_flags;
X	u_short			resp_time;
X	u_short			resp_rqs_count;
X
X	u_long			resp_resid;
X	u_long			resp_reserved[2];
X	u_long			resp_request_sense[8];
X};
X
X#define	ISP_GET_NEXT_RESPONSE_OUT(isp, ptr) { \
X	(ptr) = (isp)->isp_response_ptr; \
X	if ((isp)->isp_response_out == (ISP_MAX_RESPONSES - 1)) {  \
X		(isp)->isp_response_out = 0; \
X		(isp)->isp_response_ptr = (isp)->isp_response_base; \
X	} else { \
X		(isp)->isp_response_out++; \
X		(isp)->isp_response_ptr++; \
X	} \
X}
X
X#define	ISP_IS_RESPONSE_INVALID(resp) \
X	((resp)->resp_header.cq_entry_type != CQ_TYPE_RESPONSE)
X
X
X#define	ISP_GET_PKT_STATE(state)	((u_long) (state >> 8))
X#define	ISP_GET_PKT_STATS(stats)	((u_long) (stats))
X
X#define	ISP_STAT_NEGOTIATE	0x0080
X
X#define	ISP_SET_REASON(sp, reason) { \
X	if ((sp) && CMD2PKT(sp)->pkt_reason == CMD_CMPLT) \
X		CMD2PKT(sp)->pkt_reason = (reason); \
X}
X
X/*
X * mutex and semaphore short hands
X */
X#define	ISP_MBOX_SEMA(isp)	(&isp->isp_mbox.mbox_sema)
X
X#define	ISP_REQ_MUTEX(isp)	(&isp->isp_request_mutex)
X#define	ISP_RESP_MUTEX(isp)	(&isp->isp_response_mutex)
X#define	ISP_WAITQ_MUTEX(isp)	(&isp->isp_waitq_mutex)
X
X
X#define	ISP_MUTEX_ENTER(isp)	mutex_enter(ISP_RESP_MUTEX(isp)),	\
X				mutex_enter(ISP_REQ_MUTEX(isp))
X#define	ISP_MUTEX_EXIT(isp)	mutex_exit(ISP_RESP_MUTEX(isp)),	\
X				mutex_exit(ISP_REQ_MUTEX(isp))
X
X
X/*
X * HBA interface macros
X */
X#define	SDEV2TRAN(sd)		((sd)->sd_address.a_hba_tran)
X#define	SDEV2ADDR(sd)		(&((sd)->sd_address))
X#define	PKT2TRAN(pkt)		((pkt)->pkt_address.a_hba_tran)
X#define	ADDR2TRAN(ap)		((ap)->a_hba_tran)
X
X#define	TRAN2ISP(tran)		((struct isp *)(tran)->tran_hba_private)
X#define	SDEV2ISP(sd)		(TRAN2ISP(SDEV2TRAN(sd)))
X#define	PKT2ISP(pkt)		(TRAN2ISP(PKT2TRAN(pkt)))
X#define	ADDR2ISP(ap)		(TRAN2ISP(ADDR2TRAN(ap)))
X
X#define	CMD2ADDR(cmd)		(&CMD2PKT(cmd)->pkt_address)
X#define	CMD2TRAN(cmd)		(CMD2PKT(cmd)->pkt_address.a_hba_tran)
X#define	CMD2ISP(cmd)		(TRAN2ISP(CMD2TRAN(cmd)))
X
X
X/*
X * ptisp softstate structure
X */
X
X/*
X * deadline slot structure for timeout handling
X */
Xstruct isp_slot {
X	struct isp_cmd *slot_cmd;
X#ifdef OLDTIMEOUT
X	clock_t		slot_deadline;
X#endif
X};
X
X
Xstruct ptisp {
X
X	/*
X	 * Transport structure for this instance of the hba
X	 */
X	scsi_hba_tran_t		*isp_tran;
X
X	/*
X	 * dev_info_t reference can be found in the transport structure
X	 */
X	dev_info_t		*isp_dip;
X
X	/*
X	 * Interrupt block cookie
X	 */
X	ddi_iblock_cookie_t	isp_iblock;
X
X	/*
X	 * linked list of all isp's for ptisp_intr_loop() and debugging
X	 */
X	struct isp		*isp_next;
X
X	/*
X	 * PTI added: ptr to mapped in status register
X	 */
X
X	caddr_t			ob_statreg;
X
X	/*
X	 * Firmware revision number
X	 */
X	u_short			isp_major_rev;
X	u_short			isp_minor_rev;
X
X	/*
X	 * scsi options, scsi_tag_age_limit  per isp
X	 */
X	int			isp_scsi_options;
X	int			isp_target_scsi_options[NTARGETS_WIDE];
X	int			isp_scsi_tag_age_limit;
X
X	/*
X	 * scsi_reset_delay per isp
X	 */
X	u_int			isp_scsi_reset_delay;
X
X	/*
X	 * current host ID
X	 */
X	u_char			isp_initiator_id;
X
X        /*
X         * PTI added: differential mode flag
X         */
X        u_char			ptisp_diffmode;
X
X        /*
X         * PTI added: Soft interrupt level (3 for Solaris 2.X,
X	 * 2 or 3 for sun4m/d, sun4c
X         */
X        u_char			sbus_int_level;
X
X	/*
X	 * suspended flag for power management
X	 */
X	u_char			isp_suspended;
X
X	/*
X	 * Host adapter capabilities and offset/period values per target
X	 */
X	u_short			isp_cap[NTARGETS_WIDE];
X	u_short			isp_synch[NTARGETS_WIDE];
X
X	/*
X	 * ISP Hardware register pointer.
X	 */
X	volatile struct ispregs		*isp_reg;
X
X	/*
X	 * mbox values are stored here before and after the mbox cmd
X	 * (protected by semaphore inside isp_mbox)
X	 */
X	struct isp_mbox		isp_mbox;
X
X	/*
X	 * shutdown flag if things get really confused
X	 */
X	u_char			isp_shutdown;
X
X        /*
X         * PTI added: tmon interface status
X         */
X 
X        int			prev_tms;
X        int			ptisp_chk_t;
X
X	/*
X	 * request and response queue dvma space
X	 */
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	/*
X	 * data access handle
X	 */
X	ddi_acc_handle_t	isp_acc_handle;
X
X	/*
X	 * ISP input request and output response queue pointers
X	 * and mutexes protecting request and response queue
X	 */
X	u_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
X	struct isp_request	*isp_request_ptr,
X				*isp_request_base;
X	struct isp_response	*isp_response_ptr,
X				*isp_response_base;
X	/*
X	 * waitQ (used for storing cmds in case request mutex is held)
X	 */
X	kmutex_t		isp_waitq_mutex;
X	struct	isp_cmd		*isp_waitf;
X	struct	isp_cmd		*isp_waitb;
X	int			isp_waitq_timeout;
X
X	int			isp_burst_size;
X	u_short			isp_conf1_burst_flag;
X
X
X#ifdef ISP_PERF
X	/*
X	 * performance counters
X	 */
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
X	/*
X	 * These are for handling cmd. timeouts.
X	 *
X	 * Because the ISP request queue is a round-robin, entries
X	 * in progress can be overwritten. In order to provide crash
X	 * recovery, we have to keep a list of requests in progress
X	 * here.
X	 */
X	u_short			isp_free_slot;
X#ifdef OLDTIMEOUT
X	u_short			isp_last_slot_watched;
X#else
X	u_short			isp_alive;
X#endif
X
X	/*
X	 * list of reset notification requests
X	 */
X	struct scsi_reset_notify_entry	*isp_reset_notify_listf;
X	struct kmem_cache		*isp_kmem_cache;
X
X	struct	isp_slot	isp_slots[ISP_MAX_SLOTS];
X};
X
X
X/* MEMBERS PROTECTED BY "Atomicity": isp_tran				*/
X/* MEMBERS PROTECTED BY "Atomicity": isp_major_rev, isp_minor_rev	*/
X/* MEMBERS PROTECTED BY "Properties": isp_initiator_id			*/
X/* MEMBERS PROTECTED BY "Failure Mode": isp_shutdown			*/
X
X/* MEMBERS PROTECTED BY "Set Once": isp_cmdarea, isp_dmahandle		*/
X/* MEMBERS PROTECTED BY "Set Once": isp_dmacookie			*/
X/* MEMBERS PROTECTED BY "Semaphore": isp_mbox				*/
X
X/* MEMBERS PROTECTED BY "Set Once": isp_request_base, isp_response_base */
X/* MEMBERS PROTECTED BY "Set Once": isp_request_dvma, isp_response_dvma */
X/* MEMBERS PROTECTED BY "Set Once": isp_request_dvma, isp_response_dvma */
X
X/* MEMBERS PROTECTED BY "HW Registers": isp_reg */
X
X/* MEMBERS PROTECTED BY isp::isp_request_mutex: isp_cap, isp_synch	*/
X/* MEMBERS PROTECTED BY isp::isp_response_mutex: isp_free_slot, isp_slots */
X
X/* MEMBERS PROTECTED BY isp::isp_waitq_mutex: isp_waitf, isp_waitb	*/
X
X/* MEMBERS PROTECTED BY isp::isp_request_mutex: isp_queue_space	*/
X/* MEMBERS PROTECTED BY isp::isp_request_mutex: isp_request_in	*/
X/* MEMBERS PROTECTED BY isp::isp_request_mutex: isp_request_out	*/
X/* MEMBERS PROTECTED BY isp::isp_request_mutex: isp_request_ptr	*/
X
X/* MEMBERS PROTECTED BY isp::isp_response_mutex: isp_response_in	*/
X/* MEMBERS PROTECTED BY "Sbus semaphore	\
X			or isp_response_mutex": isp_response_out	*/
X/* MEMBERS PROTECTED BY isp::isp_response_mutex: isp_response_ptr	*/
X
X/* MEMBERS PROTECTED BY "No Mutex Needed": isp_alive */
X
X#ifdef ISP_PERF
X/* MEMBERS PROTECTED BY "Perf Counters": isp_request_count, isp_intr_count */
X/* MEMBERS PROTECTED BY "Perf Counters": isp_rpio_count, isp_wpio_count */
X/* MEMBERS PROTECTED BY "Perf Counters": isp_mail_requests, isp_perf_ticks */
X#endif
X
X/*
X * Hardware  access definitions for ISP chip
X *
X */
X#ifdef ISP_PERF
X#define	ISP_REG_SET_HOST_INT(isp)				\
X	(isp)->isp_reg->isp_hccr = ISP_HCCR_CMD_SET_HOST_INT,	\
X	(isp)->isp_wpio_count++
X
X#define	ISP_REG_GET_HOST_INT(isp)				\
X	(isp)->isp_rpio_count++,				\
X	(isp)->isp_reg->isp_hccr & ISP_HCCR_HOST_INT
X
X#define	ISP_REG_GET_RISC_INT(isp)				\
X	(isp)->isp_rpio_count++,				\
X	(isp)->isp_reg->isp_sbus_isr & ISP_SBUS_ISR_RISC_INT
X
X#define	ISP_CLEAR_RISC_INT(isp)					\
X	(isp)->isp_reg->isp_hccr = ISP_HCCR_CMD_CLEAR_RISC_INT, \
X	(isp)->isp_wpio_count++
X
X#define	ISP_CLEAR_SEMAPHORE_LOCK(isp)				\
X	ip->isp_sbus_sema &= ~ISP_SBUS_SEMA_LOCK,		\
X	(isp)->isp_wpio_count++, (isp)->isp_rpio_count++
X
X#define	ISP_SET_REQUEST_IN(isp)					\
X	(isp)->isp_reg->isp_mailbox4 = (isp)->isp_request_in,	\
X	(isp)->isp_wpio_count++, (isp)->isp_request_count++
X
X#define	ISP_SET_RESPONSE_OUT(isp)				\
X	(isp)->isp_reg->isp_mailbox5 = isp->isp_response_out,	\
X	(isp)->isp_wpio_count++
X
X#define	ISP_GET_REQUEST_OUT(isp)				\
X	((isp)->isp_reg->isp_mailbox4),				\
X	(isp)->isp_rpio_count++
X
X#define	ISP_GET_RESPONSE_IN(isp)				\
X	((isp)->isp_reg->isp_mailbox5),				\
X	(isp)->isp_rpio_count++
X
X#define	ISP_INT_PENDING(isp)					\
X	(isp)->isp_rpio_count++,				\
X	((isp)->isp_reg->isp_sbus_isr & ISP_SBUS_ISR_RISC_INT)
X
X#define	ISP_CHECK_SEMAPHORE_LOCK(isp)				\
X	(isp)->isp_rpio_count++,				\
X	((isp)->isp_reg->isp_sbus_sema & ISP_SBUS_SEMA_LOCK)
X
X#else	/* ISP_PERF */
X
X#define	ISP_REG_SET_HOST_INT(isp)				\
X	(isp)->isp_reg->isp_hccr = ISP_HCCR_CMD_SET_HOST_INT
X
X#define	ISP_REG_GET_HOST_INT(isp)				\
X	(isp)->isp_reg->isp_hccr & ISP_HCCR_HOST_INT;
X
X#define	ISP_CLEAR_RISC_INT(isp)					\
X	(isp)->isp_reg->isp_hccr = ISP_HCCR_CMD_CLEAR_RISC_INT
X
X#define	ISP_REG_GET_RISC_INT(isp)				\
X	(isp)->isp_reg->isp_sbus_isr & ISP_SBUS_ISR_RISC_INT;
X
X#define	ISP_CLEAR_SEMAPHORE_LOCK(isp)				\
X	ip->isp_sbus_sema &= ~ISP_SBUS_SEMA_LOCK
X
X#define	ISP_SET_REQUEST_IN(isp)					\
X	(isp)->isp_reg->isp_mailbox4 = (isp)->isp_request_in	\
X
X#define	ISP_SET_RESPONSE_OUT(isp)				\
X	(isp)->isp_reg->isp_mailbox5 = isp->isp_response_out	\
X
X#define	ISP_GET_REQUEST_OUT(isp)	((isp)->isp_reg->isp_mailbox4)
X#define	ISP_GET_RESPONSE_IN(isp)	((isp)->isp_reg->isp_mailbox5)
X
X#define	ISP_INT_PENDING(isp)					\
X	((isp)->isp_reg->isp_sbus_isr & ISP_SBUS_ISR_RISC_INT)
X
X#define	ISP_CHECK_SEMAPHORE_LOCK(isp)				\
X	((isp)->isp_reg->isp_sbus_sema & ISP_SBUS_SEMA_LOCK)
X
X#endif /* ISP_PERF */
X
X/*
X * quick 64 byte byte copy
X */
X#define	B64COPY(source, dest) \
X	{ \
X		register long long *s, *d; \
X		s = (long long *) source; \
X		d = (long long *) dest; \
X		*d = *s; \
X		*(d+1) = *(s+1); \
X		*(d+2) = *(s+2); \
X		*(d+3) = *(s+3); \
X		*(d+4) = *(s+4); \
X		*(d+5) = *(s+5); \
X		*(d+6) = *(s+6); \
X		*(d+7) = *(s+7); \
X	}
X
X/*
X * quick 40 byte byte copy
X */
X#define	B40COPY(source, dest) \
X	{ \
X		register long long *s, *d; \
X		s = (long long *) source; \
X		d = (long long *) dest; \
X		*d = *s; \
X		*(d+1) = *(s+1); \
X		*(d+2) = *(s+2); \
X		*(d+3) = *(s+3); \
X		*(d+4) = *(s+4); \
X	}
X
X
X/*
X * quick 24 byte byte copy
X */
X#define	B24COPY(source, dest) \
X	{ \
X		register long long *s, *d; \
X		s = (long long *) source; \
X		d = (long long *) dest; \
X		*d = *s; \
X		*(d+1) = *(s+1); \
X		*(d+2) = *(s+2); \
X	}
X
X
X/* begin PTI additives */
X 
X/*
X * On-board Status Register
X */
X 
X#define OBSTAT_OFF 0x10000	/* Offset from reg attribute to reg */
X
X/*
X * bit defs for On-board Status Register
X */
X 
X#define ST_TERMPWR	0x80	/* Termpwr state */
X#define ST_FUSERR	0x40	/* Fuse Error (open) */
X#define ST_PODIS	0x20	/* Power Up Disable State */
X#define ST_DIFFSNS	0x10	/* Differential Sense */
X 
X#define ST_INTMSK	0x0c	/* Mask for interrupt level */
X#define ST_SWMSK	0x03	/* Switch pack mask */
X
X#ifdef	__cplusplus
X}
X#endif
X
X#endif	/* _SYS_SCSI_ADAPTERS_ISPVAR_H */
END_OF_FILE
if test 17616 -ne `wc -c <'include/ptisp/ispvar5.h'`; then
    echo shar: \"'include/ptisp/ispvar5.h'\" unpacked with wrong size!
fi
# end of 'include/ptisp/ispvar5.h'
fi
if test -f 'mkadapters' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mkadapters'\"
else
echo shar: Extracting \"'mkadapters'\" \(1157 characters\)
sed "s/^X//" >'mkadapters' <<'END_OF_FILE'
X#!/bin/sh
XPATH=/usr/ucb:/usr/bin; export PATH
X# Output an "ADAPTERS =" line for a Makefile.
X# Takes a list of adapter names (lower case) on the command line, and
X# for each adapter, checks to see if <adapter>.c contains any reference
X# to include files of the form [sys/]scsi/adapters/<adapter>*.h, and
X# if so, verifies those include files exist.  If they do (or if there
X# are no references to such include files), output a makefile define
X# for that adapter, of the form -D<ADAPTER>_SUPPORT, 
X
XADAPTERS=$*
Xtest `uname -r | awk -F. '{print $1}'` -lt 5 && \
X	INCDIR="<scsi/adapters/" || INCDIR="<sys/scsi/adapters/"
X
Xcheckadapter() {
X  test -f $1.c || return 1
X  CHECKDIR=` echo $INCDIR$1 | sed 's@/@\\\/@g'`
X  awk '$1=="#include" && $2~/'"$CHECKDIR"'[a-z]*\.h>/{
X	print "test -f /usr/include/"substr($2,2,length($2)-2), " || exit 1"
X  }' $1.c | sh
X}
X
Xecho "# Generated by mkadapters $*"
Xecho "# "$USER"@`uname -n` `uname -sr` `date`"
Xecho -n "ADAPTERS ="
Xfor i in $ADAPTERS; do
X  checkadapter $i && echo -n " -D`echo $i | tr a-z A-Z`_SUPPORT" \
X	|| echo "WARNING: Support for $i removed: the necessary include files are not installed." 1>&2 
Xdone
Xecho ""
END_OF_FILE
if test 1157 -ne `wc -c <'mkadapters'`; then
    echo shar: \"'mkadapters'\" unpacked with wrong size!
fi
chmod +x 'mkadapters'
# end of 'mkadapters'
fi
echo shar: End of shell archive.
exit 0
