#! /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 'COPYRIGHT' <<'END_OF_FILE' X/* X * Copyright University of Toronto 1993. 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 911 -ne `wc -c <'COPYRIGHT'`; then echo shar: \"'COPYRIGHT'\" unpacked with wrong size! fi # end of 'COPYRIGHT' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(310 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' XCOPYRIGHT Copyright notice XMANIFEST This file XMakefile makefile XREADME Read this file first Xpatchlevel.h Patch level header file Xscsiinfo.1 scsiinfo manual page Xscsiinfo.c scsiinfo main source Xutils.c misc utilities Xutils.h header file for utils.c Xsundev/dmaga.h Empty file for fooling C compiler END_OF_FILE if test 310 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(2317 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XMay 17, 1993 X XSCSIINFO displays information about SCSI devices attached to a given Xsystem, as seen by the Sun ESP device driver. For each target known to the XSCSI host adapter, scsinfo reports whether it is synchronous or Xasynchronous, whether or not the tranfers to/from the target are clean or Xsusceptible to noise, and whether or not the target can disconnect and Xreconnect. When a target supports synchronous transfer, the negotiated maximum Xtransfer rate (in MB/sec) is reported. X XSCSI Notes: X XThe negotiated maxiumum synchronous transfer rate normally will be the Xlesser of the maximum rate supported by the adapter and the maximum rate Xsupported by the device, but it can be lower than this under various Xcircumstances. This rate is typically negotiated at reboot (SunOS 4.1 and X4.1.1 report it for each synchronous device), but it can also be Xrenegotiated during operations if necessary. X XSCSIINFO notes: X - runs on SunOS 4.1 through SunOS 5.x. X - "-s" option most useful for SunOS 4.1.2 and above, since in X these versions of the OS, the SCSI driver no longer reports the X transfer rates it negotiates with synchronous SCSI devices. X - Does nothing on suns without ESP host adapters. X - Supports multiple ESP host adapters X - SCSIINFO needs to be recompiled on any (even minor) OS releases that X changed the format of the esp structure. For example, a 4.1.1 X binary will not work on 4.1.2 or 4.1.3. X XInstallation: X 1. Edit the Makefile to taste. X 2. Compile. X 3. scsiinfo needs to be able to read /dev/kmem. For use by users X without read permissions on /dev/kmem, it can be made setgid X kmem or setgid sys. "make install" will install it setgid kmem. X XPorting notes: X - It will be almost impossible to port to 4.0.x without source, since X there are no suitable include files. X - The esp driver has tended to change quite a bit between releases; X the code is written to be as portable as possible, but future X (greater than 5.1) versions of SunOS 5.x may break something. X XBug reports, fixes, enhancements, etc. are welcome. X XJohn X-- XJohn DiMarco jdd@cdf.toronto.edu XComputing Disciplines Facility Systems Manager jdd@cdf.utoronto.ca XUniversity of Toronto EA201B,(416)978-1928 END_OF_FILE if test 2317 -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'\" \(71 characters\) sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE' X#ifndef lint Xstatic char patchlevel[] = "scsiinfo version 1.0"; X#endif END_OF_FILE if test 71 -ne `wc -c <'patchlevel.h'`; then echo shar: \"'patchlevel.h'\" unpacked with wrong size! fi # end of 'patchlevel.h' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(986 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# CC = cc XCC = cc XINCLUDEDIRS = -I. X X# Add -lelf for Solaris 2.x XLIBRARIES = -lkvm # -lelf X X# Add -DSUNOS4_1_0 if you're running SunOS 4.1 (not 4.1.1 or greater) XDEFS = X XCFLAGS = $(DEFS) -O $(INCLUDEDIRS) XLDFLAGS = XLINTFLAGS = $(DEFS) -ha $(INCLUDEDIRS) XSRCS = scsiinfo.c utils.c XOBJS = $(SRCS:.c=.o) XRM = /bin/rm -rf XINSTALL = /usr/bin/install # /usr/ucb/install for Solaris 2.x XETCDIR = /local/etc XMANDIR = /local/man/man1 XKMEMGRP = kmem # sys for Solaris 2.x X Xall:: scsiinfo X Xscsiinfo: $(OBJS) X $(RM) $@ X $(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBRARIES) Xlint: X lint $(LINTFLAGS) $(SRCS) Xlintport: X lint -p $(LINTFLAGS) $(SRCS) Xclean: X rm -f $(OBJS) scsiinfo Xdepend: X makedepend -- $(CFLAGS) -- $(SRCS) X Xinstall: scsiinfo X $(INSTALL) -s -m 2751 -g $(KMEMGRP) scsiinfo $(ETCDIR) X Xinstall.man: scsiinfo.1 X $(INSTALL) -m 644 scsiinfo.1 $(MANDIR) X Xshar: X shar COPYRIGHT MANIFEST README patchlevel.h Makefile scsiinfo.1 \ X scsiinfo.c utils.c utils.h sundev sundev/dmaga.h >scsiinfo.shar END_OF_FILE if test 986 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'scsiinfo.1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'scsiinfo.1'\" else echo shar: Extracting \"'scsiinfo.1'\" \(1133 characters\) sed "s/^X//" >'scsiinfo.1' <<'END_OF_FILE' X.TH scsiinfo 1 "May 17, 1993" X.SH scsiinfo Xscsiinfo \- obtain information about scsi devices attached to a machine X.SH SYNOPSIS X.B scsiinfo X[ X.B \-c X] X[ X.B \-s X] X.SH DESCRIPTION X.B scsiinfo Xdisplays information about SCSI devices attached to a given system, as seen Xby the Sun ESP device driver. For each target known to the SCSI host adapter, X.B scsinfo Xreports whether it is synchronous or asynchronous, whether or not the Xtranfers to/from the target are clean or susceptible to noise, and whether Xor not the target can disconnect and reconnect. When a target supports Xsynchronous transfer, the negotiated maximum transfer rate (in MB/sec) is Xreported. X.SH OPTIONS X.IP \fB\-c\fP XIn addition, provide type and speed (clock rate) information about the ESP Xcontrollers on the machine. X.IP \fB\-s\fP XReport "Target now Synchronous" messages for all synchronous devices in Xthe style of the SunOS 4.1 and 4.1.1 kernels at bootup. X.SH SEE ALSO XSunOS 4.x: devinfo(8S), SunOS 5.x: prtconf(1M) X.SH HISTORY XWritten by John DiMarco (jdd@cdf.toronto.edu) at the University of Toronto X.SH BUGS XOnly Sun ESP SCSI host adapters are supported. END_OF_FILE if test 1133 -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'\" \(5261 characters\) sed "s/^X//" >'scsiinfo.c' <<'END_OF_FILE' X/* X * scsiinfo.c - determine SCSI info. X * Only ESP SCSI host adapters are supported. X * X * Author: John DiMarco, University of Toronto, CDF X * jdd@cdf.toronto.edu X */ X X#ifndef lint Xstatic char rcsid[] = "$Header: /u/jdd/src/jdd/distrib/scsiinfo/RCS/scsiinfo.c,v 1.2 1993/05/17 22:39:26 jdd Exp $"; X#endif X X/* X * $Log: scsiinfo.c,v $ X * Revision 1.2 1993/05/17 22:39:26 jdd X * -v option is really -c. X * Added patchlevel.h X * X * Revision 1.1 1993/05/17 17:03:13 jdd X * Initial revision X * X * X */ X X#include "patchlevel.h" X#include X X#ifdef FILENAME_MAX /* defined in stdio.h only for SunOS >=5.x */ X#define SYSV X#endif X X#include X#include X#include X#include X#include X#include X#include "utils.h" X X#ifdef SYSV X#include X#include X#include X#include X#include Xstruct nlist nl[]={ X#define N_ESP_SOFTC 0 X { "esp_softc" }, X { "" }, X}; X Xstruct dev_info devi; X#define ddi_get_instance(a) ((struct dev_info *)a)->devi_instance X X#else /* SYSV */ X X#ifdef SUNOS4_1_0 X/* no espvar.h in SunOS 4.1 */ X#include X#else X#include X#endif Xstruct nlist nl[]={ X#define N_NESP 0 X { "_nesp" }, X#define N_ESP_SOFTC 1 X { "_esp_softc" }, X { "" }, X}; 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#endif /* SYSV */ X X#define MAXESP 255 X Xextern char *calloc(); X Xchar *progname; Xint d; X Xint controller=0, synch=0; X Xvoid usage() X{ X fprintf(stderr, "Usage: %s [-c][-s]\n", progname); X exit(2); X} X Xkvm_t *kd; X#define getkvm(a,b,l) kvm_read(kd,a,(char *)b,l) X Xchar *espType(typecode) Xint typecode; X{ X /* see /usr/include/[sys/]scsi/adapters/espreg.h */ X switch(typecode){ X case 0: return("ESP100/NCR53C90"); X break; X case 1: return("ESP100A/NCR53C90A"); X break; X case 2: return("ESP236"); X break; X case 3: return("FAS100/100A"); X break; X case 4: return("FAS236"); X break; X case 5: return("FAST"); X break; X default: return("unknown"); X break; X } X} X Xmain(argc, argv) Xint argc; Xchar *argv[]; X{ X int c, j, i; X int errflg = 0; X extern int optind; X extern char *optarg; X struct esp esp[1], *esp_p, *esp_softc; X u_long addr; X u_int nesp = MAXESP; X X progname = argv[0]; X while ((c = getopt(argc, argv, "dcs")) != EOF) X switch (c) { X case 'd': X ++d; X break; X case 'c': X controller++; X break; X case 's': X synch++; X break; X default: X errflg++; X break; X } X if (errflg) { X usage(); X } X X if(NULL==(kd=kvm_open(NULL, NULL, NULL, O_RDONLY, progname))){ X Error("kvm_open"); X } X if(0!=kvm_nlist(kd, nl)){ X Error("kvm_nlist: %d", kvm_nlist(kd, nl)); X } X if(-1==getkvm(nl[N_ESP_SOFTC].n_value, &addr, sizeof(addr))){ X Error("kvm_read: esp_softc"); X } X X if((u_long)NULL==addr) exit(0); /* no esp's */ X esp_softc=esp_p=(struct esp *)addr; X X if(-1==getkvm(addr, esp, sizeof(struct esp))){ X Error("kvm_read: initial esp"); X } X X#ifndef SYSV X if(-1==getkvm(nl[N_NESP].n_value, &nesp, sizeof(nesp))) { X Error("kvm_read: nesp"); X } X if(0==nesp) exit(0); X#endif /* !SYSV */ X X for(j=0;je_dev, &devi, sizeof(devi))){ X Error("kvm_read: #%d esp devinfo", j); X } X esp->e_dev=(dev_info_t)&devi; X#endif /* SYSV */ X if(controller){ 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 for(i=0;ie_targets & (1<e_sync_known & (1<e_period[i]) continue; X if(0==esp->e_clock_conv) continue; X } X X /* X * Synch cycle time in milliseconds is the X * number of ticks in the period multiplied X * by the tick rate. e_clock_conv is the X * esp's tick rate in units of 5MHz. X */ X cytime = esp->e_clock_conv?(esp->e_period[i] * X (1000/(5*esp->e_clock_conv))):0; X X /* X * Compute speed in thousanths of MBs/sec. X */ X speed = cytime?((((1000*1000*1000)/cytime)+999)/1000):0; X X if(synch){ X printf("esp%d:\tTarget %d now \ XSynchronous at %d.%d mb/s max transmit rate\n", X CNUM, i, speed/1000, speed%1000); X } else { X printf("esp%d:\tTarget %d:", CNUM, i); X if(speed && (esp->e_sync_known & (1<e_weak & (1<e_nodisc & (1<e_next; X#endif X X } X return(0); X} END_OF_FILE if test 5261 -ne `wc -c <'scsiinfo.c'`; then echo shar: \"'scsiinfo.c'\" unpacked with wrong size! fi # end of 'scsiinfo.c' fi if test -f 'utils.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'utils.c'\" else echo shar: Extracting \"'utils.c'\" \(4771 characters\) sed "s/^X//" >'utils.c' <<'END_OF_FILE' X/* X * John DiMarco University of Toronto, CSRI X */ X#include X#ifdef FILENAME_MAX X#include X#else X#include X#endif X#include X#include "utils.h" X X#ifdef lint X#undef va_arg(x,y) X#define va_arg(x,y) (y)NULL X#endif X Xextern char *progname; Xextern int d; X Xextern char *malloc(), *realloc(); X X/* X * Error(): behaves like fprintf(stderr, ...) followed by exit(2), 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 (void)exit(2); 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 while(1){ 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 while(1){ 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} X X/* X * getstr(): read a string of arbitrary length from the given file X * descriptor into malloc'ed memory, up to (but not including) X * the next newline. Return a pointer to the string; NULL if EOF. X */ Xchar *getstr(fd) XFILE *fd; X{ X unsigned int buffsize = 128; /* buffer size */ X char *result, *tmp; X unsigned int length = 0; /* length of string read */ X int last; X X result = mem(buffsize+1); X X loop{ X tmp = result+length; X if(NULL==fgets(tmp, buffsize+1, fd)){ X /* no more characters to read; EOF reached */ X if(tmp==result){ X /* we never read anything! */ X free(result); X return(NULL); X } X break; X } else { X last = strlen(tmp); X if('\n'==*(tmp+last-1)){ X /* found a newline */ X *(tmp+last-1)='\0'; X break; X } X /* still more to read */ X length += buffsize; X realloc(result, length+buffsize); X } X } X /* trim off excess buffer */ X rmem(result, strlen(result)+1); X return(result); X} END_OF_FILE if test 4771 -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'\" \(1608 characters\) sed "s/^X//" >'utils.h' <<'END_OF_FILE' 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 1608 -ne `wc -c <'utils.h'`; then echo shar: \"'utils.h'\" unpacked with wrong size! fi # end of 'utils.h' fi if test ! -d 'sundev' ; then echo shar: Creating directory \"'sundev'\" mkdir 'sundev' fi if test -f 'sundev/dmaga.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sundev/dmaga.h'\" else echo shar: Extracting \"'sundev/dmaga.h'\" \(0 characters\) sed "s/^X//" >'sundev/dmaga.h' <<'END_OF_FILE' END_OF_FILE if test 0 -ne `wc -c <'sundev/dmaga.h'`; then echo shar: \"'sundev/dmaga.h'\" unpacked with wrong size! fi # end of 'sundev/dmaga.h' fi echo shar: End of shell archive. exit 0