xref: /titanic_52/usr/src/cmd/sa/sadp.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 1994 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*7c478bd9Sstevel@tonic-gate 
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate /*	sadp.c 1.14.1.12 of 8/9/89	*/
33*7c478bd9Sstevel@tonic-gate /*	sadp.c - For VAX and PDP11 machines,
34*7c478bd9Sstevel@tonic-gate 		disk profiler profiles rp06, rm05 and general disk drives.
35*7c478bd9Sstevel@tonic-gate 		It reads system buffer header pool, physical buffer header
36*7c478bd9Sstevel@tonic-gate 		pool and swap buffer header pool once every second,
37*7c478bd9Sstevel@tonic-gate 		to examine disk drive's I/O queue.
38*7c478bd9Sstevel@tonic-gate 		For 3b20s system, it profiles the regular disk drives,
39*7c478bd9Sstevel@tonic-gate 		it reads the circular output queue for each drive
40*7c478bd9Sstevel@tonic-gate 		once every second.
41*7c478bd9Sstevel@tonic-gate 	usage : sadp [-th][-d device[-drive]] s [n]
42*7c478bd9Sstevel@tonic-gate */
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate #include <stdio.h>
45*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
46*7c478bd9Sstevel@tonic-gate #include <sys/param.h>
47*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
48*7c478bd9Sstevel@tonic-gate #include <sys/buf.h>
49*7c478bd9Sstevel@tonic-gate #include <sys/elog.h>
50*7c478bd9Sstevel@tonic-gate #include <nlist.h>
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate #include <string.h>
53*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
54*7c478bd9Sstevel@tonic-gate #include <sys/dkio.h>
55*7c478bd9Sstevel@tonic-gate #ifdef FIXME
56*7c478bd9Sstevel@tonic-gate #include <sys/dk.h>
57*7c478bd9Sstevel@tonic-gate #endif
58*7c478bd9Sstevel@tonic-gate 
59*7c478bd9Sstevel@tonic-gate #include <time.h>
60*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
61*7c478bd9Sstevel@tonic-gate #include <sys/var.h>
62*7c478bd9Sstevel@tonic-gate #include <ctype.h>
63*7c478bd9Sstevel@tonic-gate #include <sys/sysinfo.h>
64*7c478bd9Sstevel@tonic-gate #include <kvm.h>
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate /*
67*7c478bd9Sstevel@tonic-gate  * These includes are for dealing with scsi targets.
68*7c478bd9Sstevel@tonic-gate  */
69*7c478bd9Sstevel@tonic-gate #include <sys/dditypes.h>
70*7c478bd9Sstevel@tonic-gate #include <sys/scsi/scsi.h>
71*7c478bd9Sstevel@tonic-gate #include <sys/scsi/conf/device.h>
72*7c478bd9Sstevel@tonic-gate #include <sys/scsi/targets/sddef.h>
73*7c478bd9Sstevel@tonic-gate 
74*7c478bd9Sstevel@tonic-gate 
75*7c478bd9Sstevel@tonic-gate /* cylinder profiling */
76*7c478bd9Sstevel@tonic-gate #define	BLANK ' '
77*7c478bd9Sstevel@tonic-gate #define	BLOB '*'
78*7c478bd9Sstevel@tonic-gate #define	TRACE '.'
79*7c478bd9Sstevel@tonic-gate #define	BRK '='
80*7c478bd9Sstevel@tonic-gate #define	FOOT '-'
81*7c478bd9Sstevel@tonic-gate #define	CYLNO   1
82*7c478bd9Sstevel@tonic-gate #define	SEEKD   2
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate struct dk_geom	dk_geom;
85*7c478bd9Sstevel@tonic-gate #define	CHUNK		16
86*7c478bd9Sstevel@tonic-gate #define	CHUNKSHIFT	4
87*7c478bd9Sstevel@tonic-gate #define	PHYS_CYL	dk_geom.dkg_pcyl
88*7c478bd9Sstevel@tonic-gate #define	CHPERCYL	(int)(PHYS_CYL/CHUNK)	/*
89*7c478bd9Sstevel@tonic-gate 						 * the number of CHUNK cylinder
90*7c478bd9Sstevel@tonic-gate 						 * chunks on a disk
91*7c478bd9Sstevel@tonic-gate 						 */
92*7c478bd9Sstevel@tonic-gate #define	SECTPERTRK	(int)(dk_geom.dkg_nsect)	/* sectors per track */
93*7c478bd9Sstevel@tonic-gate #define	SECTPERCYL	(SECTPERTRK * (int)(dk_geom.dkg_nhead))
94*7c478bd9Sstevel@tonic-gate #define	ERR_BAD_DEV	"Device %s is not defined, valid devices are: "
95*7c478bd9Sstevel@tonic-gate #define	ERR_BAD_UNIT \
96*7c478bd9Sstevel@tonic-gate 		"Invalid drive specified for device %s, valid drives are: "
97*7c478bd9Sstevel@tonic-gate #define	ERR_NO_DEV	"Please specify a device type, valid devices are: "
98*7c478bd9Sstevel@tonic-gate #define	DRVNUM(devname)	strpbrk(devname, "0123456789")
99*7c478bd9Sstevel@tonic-gate 
100*7c478bd9Sstevel@tonic-gate #define	cylin b_resid
101*7c478bd9Sstevel@tonic-gate #define	NDRIVE  10
102*7c478bd9Sstevel@tonic-gate #define	SNDRIVE NDRIVE		/* Not used */
103*7c478bd9Sstevel@tonic-gate #define	MAX_HDISK_REP	NDRIVE
104*7c478bd9Sstevel@tonic-gate #define	MAXDRIVE	20	/* maximum number of configured disks */
105*7c478bd9Sstevel@tonic-gate #define	NAMESIZE	10	/* size of device names */
106*7c478bd9Sstevel@tonic-gate 
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate struct nlist setup[] = {
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate #define	X1_V		0
111*7c478bd9Sstevel@tonic-gate 	{"v"},
112*7c478bd9Sstevel@tonic-gate #define	X1_BUF		1
113*7c478bd9Sstevel@tonic-gate 	{"buf"},
114*7c478bd9Sstevel@tonic-gate #define	X1_PBUF		2
115*7c478bd9Sstevel@tonic-gate 	{"pbuf"},
116*7c478bd9Sstevel@tonic-gate #define	X1_SDUNITS	3
117*7c478bd9Sstevel@tonic-gate 	{"sdunits"},
118*7c478bd9Sstevel@tonic-gate #ifdef FIXME
119*7c478bd9Sstevel@tonic-gate #define	X1_DK_NDRIVE	4
120*7c478bd9Sstevel@tonic-gate 	{"dk_ndrive"},
121*7c478bd9Sstevel@tonic-gate #define	X1_DK_BUSY	5
122*7c478bd9Sstevel@tonic-gate 	{"dk_busy"},
123*7c478bd9Sstevel@tonic-gate #define	X1_DK_TIME	6
124*7c478bd9Sstevel@tonic-gate 	{"dk_time"},
125*7c478bd9Sstevel@tonic-gate #define	X1_DK_SEEK	7
126*7c478bd9Sstevel@tonic-gate 	{"dk_seek"},
127*7c478bd9Sstevel@tonic-gate #define	X1_DK_XFER	8
128*7c478bd9Sstevel@tonic-gate 	{"dk_xfer"},
129*7c478bd9Sstevel@tonic-gate #define	X1_DK_WDS	9
130*7c478bd9Sstevel@tonic-gate 	{"dk_wds"},
131*7c478bd9Sstevel@tonic-gate #define	X1_DK_BPS	10
132*7c478bd9Sstevel@tonic-gate 	{"dk_bps"},
133*7c478bd9Sstevel@tonic-gate #define	X1_DK_READ	11
134*7c478bd9Sstevel@tonic-gate 	{"dk_read"},
135*7c478bd9Sstevel@tonic-gate #define	X1_DK_IVEC	12
136*7c478bd9Sstevel@tonic-gate 	{"dk_ivec"},
137*7c478bd9Sstevel@tonic-gate #define	X1_NUMSYMBOLS	13
138*7c478bd9Sstevel@tonic-gate #else
139*7c478bd9Sstevel@tonic-gate #define	X1_NUMSYMBOLS	4
140*7c478bd9Sstevel@tonic-gate #endif
141*7c478bd9Sstevel@tonic-gate 	{0}
142*7c478bd9Sstevel@tonic-gate };
143*7c478bd9Sstevel@tonic-gate 
144*7c478bd9Sstevel@tonic-gate void	do_disk_stats ();
145*7c478bd9Sstevel@tonic-gate void	usage ();
146*7c478bd9Sstevel@tonic-gate void	prthist ();
147*7c478bd9Sstevel@tonic-gate void	pline ();
148*7c478bd9Sstevel@tonic-gate void	cylhdr ();
149*7c478bd9Sstevel@tonic-gate void	cylftr ();
150*7c478bd9Sstevel@tonic-gate void	cylhist ();
151*7c478bd9Sstevel@tonic-gate void	validate_device ();
152*7c478bd9Sstevel@tonic-gate void	validate_drive ();
153*7c478bd9Sstevel@tonic-gate void	init_geom ();
154*7c478bd9Sstevel@tonic-gate void	bad_device ();
155*7c478bd9Sstevel@tonic-gate void	read_devinfo_names ();
156*7c478bd9Sstevel@tonic-gate void	fail ();
157*7c478bd9Sstevel@tonic-gate void	init_disk ();
158*7c478bd9Sstevel@tonic-gate void	safe_kvm_read ();
159*7c478bd9Sstevel@tonic-gate 
160*7c478bd9Sstevel@tonic-gate #undef n_name			/* to resolve conflict with <syms.h> */
161*7c478bd9Sstevel@tonic-gate #define	MAXINTSIZE	12	/* sizeof "-2147483648" + 1 */
162*7c478bd9Sstevel@tonic-gate 
163*7c478bd9Sstevel@tonic-gate int debug = 1;
164*7c478bd9Sstevel@tonic-gate 
165*7c478bd9Sstevel@tonic-gate #define	Debug		if (debug)
166*7c478bd9Sstevel@tonic-gate #define	dfprintf	if (debug) fprintf
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate /*
169*7c478bd9Sstevel@tonic-gate  * FETCH_XYZ naming convention:
170*7c478bd9Sstevel@tonic-gate  * X = I for nlist index, A for actual address
171*7c478bd9Sstevel@tonic-gate  * Y = V for regular variable, A for array variable
172*7c478bd9Sstevel@tonic-gate  * Z = L if length explicitly specified
173*7c478bd9Sstevel@tonic-gate  */
174*7c478bd9Sstevel@tonic-gate 
175*7c478bd9Sstevel@tonic-gate #define	FETCH_AAL(addr, var, len, vname)\
176*7c478bd9Sstevel@tonic-gate 	safe_kvm_read(kd, (unsigned long) addr, \
177*7c478bd9Sstevel@tonic-gate 		(char *) var, len, vname)
178*7c478bd9Sstevel@tonic-gate 
179*7c478bd9Sstevel@tonic-gate #define	FETCH_IV(index, var)\
180*7c478bd9Sstevel@tonic-gate 	safe_kvm_read(kd, (unsigned long) setup[index].n_value, \
181*7c478bd9Sstevel@tonic-gate 		(char *) &var, sizeof (var), setup[index].n_name)
182*7c478bd9Sstevel@tonic-gate 
183*7c478bd9Sstevel@tonic-gate #define	FETCH_IAL(index, var, len)\
184*7c478bd9Sstevel@tonic-gate 	safe_kvm_read(kd, (unsigned long)setup[index].n_value, \
185*7c478bd9Sstevel@tonic-gate 		(char *) var, len, setup[index].n_name)
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate int	dk_ndrive;
188*7c478bd9Sstevel@tonic-gate int	ndrives;
189*7c478bd9Sstevel@tonic-gate int	all = 0;	/*
190*7c478bd9Sstevel@tonic-gate 			 * indicate whether all drives
191*7c478bd9Sstevel@tonic-gate 			 * are implicitly specified
192*7c478bd9Sstevel@tonic-gate 			 */
193*7c478bd9Sstevel@tonic-gate char    *cmdname = "sadp";
194*7c478bd9Sstevel@tonic-gate char	device[NAMESIZE];
195*7c478bd9Sstevel@tonic-gate char	dr_name[NDRIVE][NAMESIZE];
196*7c478bd9Sstevel@tonic-gate long	dk_bps[NDRIVE];
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate struct {
199*7c478bd9Sstevel@tonic-gate 	long	dk_busy[NDRIVE];
200*7c478bd9Sstevel@tonic-gate 	long	dk_time[NDRIVE];
201*7c478bd9Sstevel@tonic-gate 	long	dk_wds[NDRIVE];
202*7c478bd9Sstevel@tonic-gate 	long	dk_seek[NDRIVE];
203*7c478bd9Sstevel@tonic-gate 	long	dk_xfer[NDRIVE];
204*7c478bd9Sstevel@tonic-gate 	long	dk_read[NDRIVE];
205*7c478bd9Sstevel@tonic-gate } dk;
206*7c478bd9Sstevel@tonic-gate 
207*7c478bd9Sstevel@tonic-gate struct var 	tbl;
208*7c478bd9Sstevel@tonic-gate char 		*sbuf, *phybuf;
209*7c478bd9Sstevel@tonic-gate struct buf 	bp[2];		/*  for swap buffers  */
210*7c478bd9Sstevel@tonic-gate int 		nonblk;
211*7c478bd9Sstevel@tonic-gate int 		index;
212*7c478bd9Sstevel@tonic-gate int 		index1;
213*7c478bd9Sstevel@tonic-gate unsigned 	temp1;
214*7c478bd9Sstevel@tonic-gate #define devnm dr_name
215*7c478bd9Sstevel@tonic-gate 
216*7c478bd9Sstevel@tonic-gate int fflg, dflg, tflg, hflg, errflg;
217*7c478bd9Sstevel@tonic-gate int s, n, ct;
218*7c478bd9Sstevel@tonic-gate static int ub = 8;
219*7c478bd9Sstevel@tonic-gate int sdist;
220*7c478bd9Sstevel@tonic-gate int m;
221*7c478bd9Sstevel@tonic-gate int dev;
222*7c478bd9Sstevel@tonic-gate int temp;
223*7c478bd9Sstevel@tonic-gate int f;
224*7c478bd9Sstevel@tonic-gate int i;
225*7c478bd9Sstevel@tonic-gate int n1, dleng, dashb, k, devlen;
226*7c478bd9Sstevel@tonic-gate int dashf;
227*7c478bd9Sstevel@tonic-gate int dn;
228*7c478bd9Sstevel@tonic-gate int drvlist[NDRIVE];
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate int Sdrvlist[SNDRIVE];	/* SCSI */
231*7c478bd9Sstevel@tonic-gate 
232*7c478bd9Sstevel@tonic-gate struct HISTDATA {
233*7c478bd9Sstevel@tonic-gate 	long	hdata[1];
234*7c478bd9Sstevel@tonic-gate };
235*7c478bd9Sstevel@tonic-gate struct utsname name;
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate char	*nopt;
238*7c478bd9Sstevel@tonic-gate char	empty[30];
239*7c478bd9Sstevel@tonic-gate char	drive[30];
240*7c478bd9Sstevel@tonic-gate char	*malloc();
241*7c478bd9Sstevel@tonic-gate 
242*7c478bd9Sstevel@tonic-gate int	SCSI;	/* SCSI */
243*7c478bd9Sstevel@tonic-gate int	ALL;
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate long	lseek();
246*7c478bd9Sstevel@tonic-gate long	**dkcyl;
247*7c478bd9Sstevel@tonic-gate long	**skcyl;
248*7c478bd9Sstevel@tonic-gate long	*iocnt;
249*7c478bd9Sstevel@tonic-gate static kvm_t	*kd = NULL;
250*7c478bd9Sstevel@tonic-gate struct scsi_device	*sdunits[SD_MAXUNIT];
251*7c478bd9Sstevel@tonic-gate struct scsi_device	sdunit[NDRIVE];
252*7c478bd9Sstevel@tonic-gate int			cyl_no, prev_cyl_no;
253*7c478bd9Sstevel@tonic-gate int			cyl_bk, prev_cyl_bk;
254*7c478bd9Sstevel@tonic-gate int			seek_dist, seek_bk;
255*7c478bd9Sstevel@tonic-gate int			max_cyl_no = 0;
256*7c478bd9Sstevel@tonic-gate int			max_seek_dist = 0;
257*7c478bd9Sstevel@tonic-gate 
258*7c478bd9Sstevel@tonic-gate main(argc, argv)
259*7c478bd9Sstevel@tonic-gate int argc;
260*7c478bd9Sstevel@tonic-gate char **argv;
261*7c478bd9Sstevel@tonic-gate {
262*7c478bd9Sstevel@tonic-gate 	unsigned sleep();
263*7c478bd9Sstevel@tonic-gate 	extern int	optind;
264*7c478bd9Sstevel@tonic-gate 	extern char	*optarg;
265*7c478bd9Sstevel@tonic-gate 	int c, j;
266*7c478bd9Sstevel@tonic-gate 	char *ctime(), *stime;
267*7c478bd9Sstevel@tonic-gate 	long curt;
268*7c478bd9Sstevel@tonic-gate 	extern time_t time();
269*7c478bd9Sstevel@tonic-gate 	long *skdist;
270*7c478bd9Sstevel@tonic-gate 	long *disk;
271*7c478bd9Sstevel@tonic-gate 
272*7c478bd9Sstevel@tonic-gate 	fail("sadp does not work yet -- no disk statistics in the kernel", 0);
273*7c478bd9Sstevel@tonic-gate 
274*7c478bd9Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "thd:")) != EOF)
275*7c478bd9Sstevel@tonic-gate 		switch (c) {
276*7c478bd9Sstevel@tonic-gate 		case 't':
277*7c478bd9Sstevel@tonic-gate 			tflg++;
278*7c478bd9Sstevel@tonic-gate 			break;
279*7c478bd9Sstevel@tonic-gate 		case 'h':
280*7c478bd9Sstevel@tonic-gate 			hflg++;
281*7c478bd9Sstevel@tonic-gate 			break;
282*7c478bd9Sstevel@tonic-gate 		case 'd':
283*7c478bd9Sstevel@tonic-gate 			dleng = strlen(optarg);
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 			/*
286*7c478bd9Sstevel@tonic-gate 			 * Controller types can be arbitrary length.
287*7c478bd9Sstevel@tonic-gate 			 */
288*7c478bd9Sstevel@tonic-gate 			devlen =  strchr(optarg, '-') ?
289*7c478bd9Sstevel@tonic-gate 					strchr(optarg, '-') - optarg : dleng;
290*7c478bd9Sstevel@tonic-gate 			SCSI = 0;
291*7c478bd9Sstevel@tonic-gate 			strncpy(device, optarg, devlen);
292*7c478bd9Sstevel@tonic-gate 
293*7c478bd9Sstevel@tonic-gate 			if (dleng == (devlen+1)) {
294*7c478bd9Sstevel@tonic-gate 				errflg++;
295*7c478bd9Sstevel@tonic-gate 				break;
296*7c478bd9Sstevel@tonic-gate 			}
297*7c478bd9Sstevel@tonic-gate 			if (dleng > devlen) {
298*7c478bd9Sstevel@tonic-gate 			for (i = (devlen+1), n1 = (devlen+1); i < dleng; i++){
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 				if (optarg[i] == ','){
301*7c478bd9Sstevel@tonic-gate 					if (n1 == i){
302*7c478bd9Sstevel@tonic-gate 					errflg++;
303*7c478bd9Sstevel@tonic-gate 					break;
304*7c478bd9Sstevel@tonic-gate 					}
305*7c478bd9Sstevel@tonic-gate 					if (getdrvn() != 0) {
306*7c478bd9Sstevel@tonic-gate 						errflg++;
307*7c478bd9Sstevel@tonic-gate 						break;
308*7c478bd9Sstevel@tonic-gate 					}
309*7c478bd9Sstevel@tonic-gate 					if (dashf != 0) {
310*7c478bd9Sstevel@tonic-gate 						if (dashb >= dn){
311*7c478bd9Sstevel@tonic-gate 							errflg++;
312*7c478bd9Sstevel@tonic-gate 							break;
313*7c478bd9Sstevel@tonic-gate 						}
314*7c478bd9Sstevel@tonic-gate 						for (j = dashb; j < dn+1; j++){
315*7c478bd9Sstevel@tonic-gate 							if (SCSI) /*  SCSI */
316*7c478bd9Sstevel@tonic-gate 								Sdrvlist[j] = 1;
317*7c478bd9Sstevel@tonic-gate 							else
318*7c478bd9Sstevel@tonic-gate 								drvlist[j] = 1;
319*7c478bd9Sstevel@tonic-gate 						}
320*7c478bd9Sstevel@tonic-gate 						dashb = 0;
321*7c478bd9Sstevel@tonic-gate 						dashf = 0;
322*7c478bd9Sstevel@tonic-gate 					}
323*7c478bd9Sstevel@tonic-gate 					else
324*7c478bd9Sstevel@tonic-gate 					{
325*7c478bd9Sstevel@tonic-gate 						if (SCSI)
326*7c478bd9Sstevel@tonic-gate 							Sdrvlist[dn] = 1;
327*7c478bd9Sstevel@tonic-gate 						else
328*7c478bd9Sstevel@tonic-gate 							drvlist[dn] = 1;
329*7c478bd9Sstevel@tonic-gate 					}
330*7c478bd9Sstevel@tonic-gate 					n1 = i+1;
331*7c478bd9Sstevel@tonic-gate 				} else {
332*7c478bd9Sstevel@tonic-gate 				if (optarg[i] == '-'){
333*7c478bd9Sstevel@tonic-gate 					if (dashf != 0) {
334*7c478bd9Sstevel@tonic-gate 						errflg++;
335*7c478bd9Sstevel@tonic-gate 						break;
336*7c478bd9Sstevel@tonic-gate 					}
337*7c478bd9Sstevel@tonic-gate 					if (getdrvn() != 0) {
338*7c478bd9Sstevel@tonic-gate 						errflg++;
339*7c478bd9Sstevel@tonic-gate 						break;
340*7c478bd9Sstevel@tonic-gate 					}
341*7c478bd9Sstevel@tonic-gate 					if (SCSI)
342*7c478bd9Sstevel@tonic-gate 						Sdrvlist[dn] = 1;
343*7c478bd9Sstevel@tonic-gate 					else
344*7c478bd9Sstevel@tonic-gate 						drvlist[dn] = 1;
345*7c478bd9Sstevel@tonic-gate 					dashb = dn;
346*7c478bd9Sstevel@tonic-gate 					dashf = 1;
347*7c478bd9Sstevel@tonic-gate 					n1 = i+1;
348*7c478bd9Sstevel@tonic-gate 				} else {
349*7c478bd9Sstevel@tonic-gate 					if (i == dleng-1){
350*7c478bd9Sstevel@tonic-gate 					i++;
351*7c478bd9Sstevel@tonic-gate 					if (getdrvn() != 0) {
352*7c478bd9Sstevel@tonic-gate 						errflg++;
353*7c478bd9Sstevel@tonic-gate 						break;
354*7c478bd9Sstevel@tonic-gate 					}
355*7c478bd9Sstevel@tonic-gate 					if (dashf != 0)
356*7c478bd9Sstevel@tonic-gate 						for (j = dashb; j < dn+1; j++){
357*7c478bd9Sstevel@tonic-gate 							if (SCSI)
358*7c478bd9Sstevel@tonic-gate 								Sdrvlist[j] = 1;
359*7c478bd9Sstevel@tonic-gate 							else
360*7c478bd9Sstevel@tonic-gate 								drvlist[j] = 1;
361*7c478bd9Sstevel@tonic-gate 						}
362*7c478bd9Sstevel@tonic-gate 					else
363*7c478bd9Sstevel@tonic-gate 					{
364*7c478bd9Sstevel@tonic-gate 						if (SCSI)
365*7c478bd9Sstevel@tonic-gate 							Sdrvlist[dn] = 1;
366*7c478bd9Sstevel@tonic-gate 						else
367*7c478bd9Sstevel@tonic-gate 							drvlist[dn] = 1;
368*7c478bd9Sstevel@tonic-gate 					}
369*7c478bd9Sstevel@tonic-gate 					}
370*7c478bd9Sstevel@tonic-gate 				}
371*7c478bd9Sstevel@tonic-gate 				}
372*7c478bd9Sstevel@tonic-gate 			}
373*7c478bd9Sstevel@tonic-gate 			} else {
374*7c478bd9Sstevel@tonic-gate 				if (dleng != devlen){
375*7c478bd9Sstevel@tonic-gate 					errflg++;
376*7c478bd9Sstevel@tonic-gate 					break;
377*7c478bd9Sstevel@tonic-gate 				}
378*7c478bd9Sstevel@tonic-gate 				all++;
379*7c478bd9Sstevel@tonic-gate 				if (SCSI)
380*7c478bd9Sstevel@tonic-gate 					ALL++;
381*7c478bd9Sstevel@tonic-gate 				else
382*7c478bd9Sstevel@tonic-gate 					for (i = 0; i < MAX_HDISK_REP; i++)
383*7c478bd9Sstevel@tonic-gate 						drvlist[i] = 1;
384*7c478bd9Sstevel@tonic-gate 			}
385*7c478bd9Sstevel@tonic-gate 			if (errflg)
386*7c478bd9Sstevel@tonic-gate 				break;
387*7c478bd9Sstevel@tonic-gate 			dflg++;
388*7c478bd9Sstevel@tonic-gate 			break;
389*7c478bd9Sstevel@tonic-gate 		case '?':
390*7c478bd9Sstevel@tonic-gate 			errflg++;
391*7c478bd9Sstevel@tonic-gate 			break;
392*7c478bd9Sstevel@tonic-gate 		}
393*7c478bd9Sstevel@tonic-gate 	if (errflg) {
394*7c478bd9Sstevel@tonic-gate 		fprintf (stderr, "%s: errors in arguments\n", cmdname);
395*7c478bd9Sstevel@tonic-gate 		usage();
396*7c478bd9Sstevel@tonic-gate 	}
397*7c478bd9Sstevel@tonic-gate 
398*7c478bd9Sstevel@tonic-gate 	/*
399*7c478bd9Sstevel@tonic-gate 	 * If no frequency arguments present, exit.
400*7c478bd9Sstevel@tonic-gate 	 */
401*7c478bd9Sstevel@tonic-gate 	if (optind == argc)
402*7c478bd9Sstevel@tonic-gate 		usage();
403*7c478bd9Sstevel@tonic-gate 	/*
404*7c478bd9Sstevel@tonic-gate 	 * If a non-dash field is presented as an argument,
405*7c478bd9Sstevel@tonic-gate 	 * check if it is a numerical arg.
406*7c478bd9Sstevel@tonic-gate 	 */
407*7c478bd9Sstevel@tonic-gate 	nopt = argv[optind];
408*7c478bd9Sstevel@tonic-gate 	if (tstdigit(nopt) != 0)
409*7c478bd9Sstevel@tonic-gate 		usage();
410*7c478bd9Sstevel@tonic-gate 	/*
411*7c478bd9Sstevel@tonic-gate 	 * For frequency arguments, if only s is presented , set n to 1
412*7c478bd9Sstevel@tonic-gate 	 */
413*7c478bd9Sstevel@tonic-gate 	if ((optind +1) == argc) {
414*7c478bd9Sstevel@tonic-gate 		s = atoi(argv[optind]);
415*7c478bd9Sstevel@tonic-gate 		n = 1;
416*7c478bd9Sstevel@tonic-gate 	}
417*7c478bd9Sstevel@tonic-gate 	/*
418*7c478bd9Sstevel@tonic-gate 	 * If both s and n are specified, check if
419*7c478bd9Sstevel@tonic-gate 	 * arg n is numeric.
420*7c478bd9Sstevel@tonic-gate 	 */
421*7c478bd9Sstevel@tonic-gate 	if ((optind +1) < argc) {
422*7c478bd9Sstevel@tonic-gate 		nopt = argv[optind + 1];
423*7c478bd9Sstevel@tonic-gate 		if (tstdigit(nopt) != 0)
424*7c478bd9Sstevel@tonic-gate 			usage();
425*7c478bd9Sstevel@tonic-gate 		s = atoi(argv[optind]);
426*7c478bd9Sstevel@tonic-gate 		n = atoi(argv[optind+1]);
427*7c478bd9Sstevel@tonic-gate 	}
428*7c478bd9Sstevel@tonic-gate 	if (s <= 0)
429*7c478bd9Sstevel@tonic-gate 		fail("bad value of s", 0);
430*7c478bd9Sstevel@tonic-gate 	if (n <= 0)
431*7c478bd9Sstevel@tonic-gate 		fail("bad value of n", 0);
432*7c478bd9Sstevel@tonic-gate 	ct = s;
433*7c478bd9Sstevel@tonic-gate 	/*
434*7c478bd9Sstevel@tonic-gate 	 * Get entries defined in setup from /stand/unix
435*7c478bd9Sstevel@tonic-gate 	 */
436*7c478bd9Sstevel@tonic-gate 	if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY, "Bad kvm open"))
437*7c478bd9Sstevel@tonic-gate 		== NULL)
438*7c478bd9Sstevel@tonic-gate 		fail("kvm_open failed", 1);
439*7c478bd9Sstevel@tonic-gate 
440*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "main: successful kvm_open\n");
441*7c478bd9Sstevel@tonic-gate 	/*
442*7c478bd9Sstevel@tonic-gate 	 * Search name list to get offsets.
443*7c478bd9Sstevel@tonic-gate 	 */
444*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "main: about to kvm_nlist\n");
445*7c478bd9Sstevel@tonic-gate 	if (kvm_nlist(kd, setup) == -1) {
446*7c478bd9Sstevel@tonic-gate 		fail("kvm_nlist failed", 1);
447*7c478bd9Sstevel@tonic-gate 	}
448*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "main: good nlist\n");
449*7c478bd9Sstevel@tonic-gate 	Debug dump_nlist (setup, "main");
450*7c478bd9Sstevel@tonic-gate 
451*7c478bd9Sstevel@tonic-gate 	/*
452*7c478bd9Sstevel@tonic-gate 	 * Initialize buffers and get disk info.
453*7c478bd9Sstevel@tonic-gate 	 */
454*7c478bd9Sstevel@tonic-gate 	init_disk();
455*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "init_disk\n");
456*7c478bd9Sstevel@tonic-gate 	skdist = (long *)calloc(dk_ndrive, sizeof (long));
457*7c478bd9Sstevel@tonic-gate 	disk = (long *)calloc(dk_ndrive, sizeof (long));
458*7c478bd9Sstevel@tonic-gate 
459*7c478bd9Sstevel@tonic-gate 	/*
460*7c478bd9Sstevel@tonic-gate 	 * Make sure device and drive specified is legitimate.
461*7c478bd9Sstevel@tonic-gate 	 */
462*7c478bd9Sstevel@tonic-gate 	validate_device();
463*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "validate_device\n");
464*7c478bd9Sstevel@tonic-gate 	validate_drive();
465*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "validate_drive\n");
466*7c478bd9Sstevel@tonic-gate 
467*7c478bd9Sstevel@tonic-gate 	/*
468*7c478bd9Sstevel@tonic-gate 	 * Get storage from memory for sysbuf pool and physical buf pool
469*7c478bd9Sstevel@tonic-gate 	 */
470*7c478bd9Sstevel@tonic-gate 	FETCH_IV (X1_V, tbl);
471*7c478bd9Sstevel@tonic-gate 	Debug dump_v_struct (&tbl);
472*7c478bd9Sstevel@tonic-gate 	sbuf = malloc(sizeof (struct buf) * tbl.v_buf);
473*7c478bd9Sstevel@tonic-gate 	if (sbuf == NULL)
474*7c478bd9Sstevel@tonic-gate 		fail("malloc of sbuf failed", 1);
475*7c478bd9Sstevel@tonic-gate 	phybuf = malloc(sizeof (struct buf) * tbl.v_pbuf);
476*7c478bd9Sstevel@tonic-gate 	if (phybuf == NULL)
477*7c478bd9Sstevel@tonic-gate 		fail("malloc of physbuf failed", 1);
478*7c478bd9Sstevel@tonic-gate 
479*7c478bd9Sstevel@tonic-gate 	/*
480*7c478bd9Sstevel@tonic-gate 	 * Determine the number of CHUNK cylinder chunks on the disk.
481*7c478bd9Sstevel@tonic-gate 	 * This will be referenced as CHPERCYL.
482*7c478bd9Sstevel@tonic-gate 	 */
483*7c478bd9Sstevel@tonic-gate 	init_geom();
484*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "init_geom\n");
485*7c478bd9Sstevel@tonic-gate 
486*7c478bd9Sstevel@tonic-gate 	ub = dk_ndrive;
487*7c478bd9Sstevel@tonic-gate #ifdef FIXME
488*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_DK_XFER, dk.dk_xfer, dk_ndrive*sizeof (long));
489*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_DK_READ, dk.dk_read, dk_ndrive*sizeof (long));
490*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_DK_SEEK, dk.dk_seek, dk_ndrive*sizeof (long));
491*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_DK_WDS, dk.dk_wds, dk_ndrive*sizeof (long));
492*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_DK_TIME, dk.dk_time, dk_ndrive*sizeof (long));
493*7c478bd9Sstevel@tonic-gate #endif
494*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "%s: ub %d\n", cmdname, ub);
495*7c478bd9Sstevel@tonic-gate 	/*
496*7c478bd9Sstevel@tonic-gate 	 * Get the list of scsi device pointers from kernel space.
497*7c478bd9Sstevel@tonic-gate 	 */
498*7c478bd9Sstevel@tonic-gate 	FETCH_IAL(X1_SDUNITS, sdunits, SD_MAXUNIT);
499*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < SD_MAXUNIT; i++) {
500*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "sdunits[%d] 0x%x ", i, (int)sdunits[i]);
501*7c478bd9Sstevel@tonic-gate 	}
502*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "\n");
503*7c478bd9Sstevel@tonic-gate 	for (k = 0, i = 0; k < ub; k++) {
504*7c478bd9Sstevel@tonic-gate 		if (drvlist[k] == 0)
505*7c478bd9Sstevel@tonic-gate 			continue;
506*7c478bd9Sstevel@tonic-gate 		/*
507*7c478bd9Sstevel@tonic-gate 		 * Make sure that there is a scsi_device struct for
508*7c478bd9Sstevel@tonic-gate 		 * the chosen device.
509*7c478bd9Sstevel@tonic-gate 		 */
510*7c478bd9Sstevel@tonic-gate 		if (!sdunits[k]) {
511*7c478bd9Sstevel@tonic-gate 			fprintf (stderr, "%s: no valid scsi_device struct\n",
512*7c478bd9Sstevel@tonic-gate 				cmdname);
513*7c478bd9Sstevel@tonic-gate 		}
514*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "%s: read unit %d\n", cmdname, k);
515*7c478bd9Sstevel@tonic-gate 		/*
516*7c478bd9Sstevel@tonic-gate 		 * Read the scsi_device struct for the device.
517*7c478bd9Sstevel@tonic-gate 		 */
518*7c478bd9Sstevel@tonic-gate 		FETCH_AAL(sdunits[k], &sdunit[k],
519*7c478bd9Sstevel@tonic-gate 			sizeof (struct scsi_device), "sdunits");
520*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "%s: sd_private 0x%x\n",
521*7c478bd9Sstevel@tonic-gate 			cmdname, (int)sdunit[k].sd_private);
522*7c478bd9Sstevel@tonic-gate 	}
523*7c478bd9Sstevel@tonic-gate 
524*7c478bd9Sstevel@tonic-gate 	/*
525*7c478bd9Sstevel@tonic-gate 	 * Get current I/O count for each drive.
526*7c478bd9Sstevel@tonic-gate 	 */
527*7c478bd9Sstevel@tonic-gate 	for (;;) {
528*7c478bd9Sstevel@tonic-gate 		s = ct;
529*7c478bd9Sstevel@tonic-gate 		for (k = 0, i = 0; k < ub; k++) {
530*7c478bd9Sstevel@tonic-gate 			if (drvlist[k] == 0)
531*7c478bd9Sstevel@tonic-gate 				continue;
532*7c478bd9Sstevel@tonic-gate 			for (j = 0; j < CHPERCYL; j++) {
533*7c478bd9Sstevel@tonic-gate 				dkcyl[i][j] = 0;
534*7c478bd9Sstevel@tonic-gate 				skcyl[i][j] = 0;
535*7c478bd9Sstevel@tonic-gate 			}
536*7c478bd9Sstevel@tonic-gate 			iocnt[i] = 0;
537*7c478bd9Sstevel@tonic-gate 			disk[i] = 0;
538*7c478bd9Sstevel@tonic-gate 			skdist[i] = 0;
539*7c478bd9Sstevel@tonic-gate 			i++;
540*7c478bd9Sstevel@tonic-gate 		}
541*7c478bd9Sstevel@tonic-gate 		/*
542*7c478bd9Sstevel@tonic-gate 		 * If no drives are selected or illegal drive number
543*7c478bd9Sstevel@tonic-gate 		 * is specified, exit.
544*7c478bd9Sstevel@tonic-gate 		 */
545*7c478bd9Sstevel@tonic-gate 		if (i == 0)
546*7c478bd9Sstevel@tonic-gate 			usage();
547*7c478bd9Sstevel@tonic-gate 
548*7c478bd9Sstevel@tonic-gate 		/*
549*7c478bd9Sstevel@tonic-gate 		 * Get i/o count for each disk.
550*7c478bd9Sstevel@tonic-gate 		 */
551*7c478bd9Sstevel@tonic-gate 
552*7c478bd9Sstevel@tonic-gate 		for (k = 0, i = 0; k < ub; k++) {
553*7c478bd9Sstevel@tonic-gate 			if (drvlist[k] == 0)
554*7c478bd9Sstevel@tonic-gate 				continue;
555*7c478bd9Sstevel@tonic-gate 			iocnt[i] = dk.dk_xfer[k];
556*7c478bd9Sstevel@tonic-gate 			i++;
557*7c478bd9Sstevel@tonic-gate 		}
558*7c478bd9Sstevel@tonic-gate 
559*7c478bd9Sstevel@tonic-gate 	cyl_no = 0; prev_cyl_no = 0; cyl_bk = 0; prev_cyl_bk = 0; seek_dist = 0;
560*7c478bd9Sstevel@tonic-gate 	for (;;) {
561*7c478bd9Sstevel@tonic-gate 
562*7c478bd9Sstevel@tonic-gate 		/*
563*7c478bd9Sstevel@tonic-gate 		 * Take a snapshot of buffer header pool, swap
564*7c478bd9Sstevel@tonic-gate 		 * buffer pool and physical buffer header.
565*7c478bd9Sstevel@tonic-gate 		 */
566*7c478bd9Sstevel@tonic-gate 
567*7c478bd9Sstevel@tonic-gate 		/*
568*7c478bd9Sstevel@tonic-gate 		 * read system buffer header pool.
569*7c478bd9Sstevel@tonic-gate 		 */
570*7c478bd9Sstevel@tonic-gate 		FETCH_IAL(X1_BUF, sbuf, tbl.v_buf*sizeof (struct buf));
571*7c478bd9Sstevel@tonic-gate 
572*7c478bd9Sstevel@tonic-gate 		/*
573*7c478bd9Sstevel@tonic-gate 		 * Read physical buffer header pool.
574*7c478bd9Sstevel@tonic-gate 		 */
575*7c478bd9Sstevel@tonic-gate 		FETCH_IAL(X1_PBUF, phybuf, tbl.v_pbuf*sizeof (struct buf));
576*7c478bd9Sstevel@tonic-gate 
577*7c478bd9Sstevel@tonic-gate 		for (k = 0, i = 0; k < ub; k++) {
578*7c478bd9Sstevel@tonic-gate 			if (drvlist[k] == 0)
579*7c478bd9Sstevel@tonic-gate 				continue;
580*7c478bd9Sstevel@tonic-gate 			do_disk_stats (i, k);
581*7c478bd9Sstevel@tonic-gate 		i++;
582*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "%s: i %d\n", cmdname, i);
583*7c478bd9Sstevel@tonic-gate 		}
584*7c478bd9Sstevel@tonic-gate 
585*7c478bd9Sstevel@tonic-gate 	/* TBD - get more samples */
586*7c478bd9Sstevel@tonic-gate 
587*7c478bd9Sstevel@tonic-gate 		if (--s)
588*7c478bd9Sstevel@tonic-gate 			sleep(1);
589*7c478bd9Sstevel@tonic-gate 		else {
590*7c478bd9Sstevel@tonic-gate 
591*7c478bd9Sstevel@tonic-gate 			/*
592*7c478bd9Sstevel@tonic-gate 			 * At the end of sampling, get the present I/O
593*7c478bd9Sstevel@tonic-gate 			 * count, and system name.
594*7c478bd9Sstevel@tonic-gate 			 */
595*7c478bd9Sstevel@tonic-gate 			uname(&name);
596*7c478bd9Sstevel@tonic-gate 
597*7c478bd9Sstevel@tonic-gate 			/*
598*7c478bd9Sstevel@tonic-gate 			 * Print the report, there are two parts:
599*7c478bd9Sstevel@tonic-gate 			 * cylinder profile, seeking distance profile.
600*7c478bd9Sstevel@tonic-gate 			 */
601*7c478bd9Sstevel@tonic-gate 			curt = time((long *) 0);
602*7c478bd9Sstevel@tonic-gate 			stime = ctime (&curt);
603*7c478bd9Sstevel@tonic-gate 			printf("\n\n%s\n", stime);
604*7c478bd9Sstevel@tonic-gate 			printf("%s %s %s %s %s\n",
605*7c478bd9Sstevel@tonic-gate 				name.sysname,
606*7c478bd9Sstevel@tonic-gate 				name.nodename,
607*7c478bd9Sstevel@tonic-gate 				name.release,
608*7c478bd9Sstevel@tonic-gate 				name.version,
609*7c478bd9Sstevel@tonic-gate 				name.machine);
610*7c478bd9Sstevel@tonic-gate 			for (k = 0, i = 0; k < ub; k++) {
611*7c478bd9Sstevel@tonic-gate 				if (drvlist[k] == 0)
612*7c478bd9Sstevel@tonic-gate 					continue;
613*7c478bd9Sstevel@tonic-gate 				for (j = 0; j < CHPERCYL; j++) {
614*7c478bd9Sstevel@tonic-gate 					disk[i] = disk[i] +dkcyl[i][j];
615*7c478bd9Sstevel@tonic-gate 					skdist[i] = skdist[i] + skcyl[i][j];
616*7c478bd9Sstevel@tonic-gate 
617*7c478bd9Sstevel@tonic-gate 				}
618*7c478bd9Sstevel@tonic-gate 				i++;
619*7c478bd9Sstevel@tonic-gate 			}
620*7c478bd9Sstevel@tonic-gate 			if ((tflg == 0) && (hflg == 0))
621*7c478bd9Sstevel@tonic-gate 				tflg = 1;
622*7c478bd9Sstevel@tonic-gate 			if (tflg){
623*7c478bd9Sstevel@tonic-gate 				printf("\nCYLINDER ACCESS PROFILE\n");
624*7c478bd9Sstevel@tonic-gate 				for (k = 0, i = 0; k < ub; k++) {
625*7c478bd9Sstevel@tonic-gate 					if (drvlist[k] == 0)
626*7c478bd9Sstevel@tonic-gate 						continue;
627*7c478bd9Sstevel@tonic-gate 					if (disk[i] != 0){
628*7c478bd9Sstevel@tonic-gate 						iocnt[i] = dk.dk_xfer[k] - iocnt[i];
629*7c478bd9Sstevel@tonic-gate 						printf("\n%s-%d:\n",
630*7c478bd9Sstevel@tonic-gate 							device, k);
631*7c478bd9Sstevel@tonic-gate 						printf("Cylinders\tTransfers\n");
632*7c478bd9Sstevel@tonic-gate 						for (j = 0; j < CHPERCYL; j++) {
633*7c478bd9Sstevel@tonic-gate 							if (dkcyl[i][j] > 0)
634*7c478bd9Sstevel@tonic-gate 								printf("%3d - %3d\t%ld\n",
635*7c478bd9Sstevel@tonic-gate 								j*8, j*8+7, dkcyl[i][j]);
636*7c478bd9Sstevel@tonic-gate 						}
637*7c478bd9Sstevel@tonic-gate 						printf("\nSampled I/O = %ld, Actual I/O = %ld\n",
638*7c478bd9Sstevel@tonic-gate 						disk[i], iocnt[i]);
639*7c478bd9Sstevel@tonic-gate 						if (iocnt[i] > 0)
640*7c478bd9Sstevel@tonic-gate 						printf("Percentage of I/O sampled = %2.2f\n",
641*7c478bd9Sstevel@tonic-gate 						((float)disk[i] /(float)iocnt[i]) * 100.0);
642*7c478bd9Sstevel@tonic-gate 					}
643*7c478bd9Sstevel@tonic-gate 					i++;
644*7c478bd9Sstevel@tonic-gate 				}
645*7c478bd9Sstevel@tonic-gate 
646*7c478bd9Sstevel@tonic-gate 				printf("\n\n\nSEEK DISTANCE PROFILE\n");
647*7c478bd9Sstevel@tonic-gate 				for (k = 0, i = 0; k < ub; k++) {
648*7c478bd9Sstevel@tonic-gate 					if (drvlist[k] == 0)
649*7c478bd9Sstevel@tonic-gate 						continue;
650*7c478bd9Sstevel@tonic-gate 					if (skdist[i] != 0){
651*7c478bd9Sstevel@tonic-gate 						printf("\n%s-%d:\n",
652*7c478bd9Sstevel@tonic-gate 							device, k);
653*7c478bd9Sstevel@tonic-gate 						printf("Seek Distance\tSeeks\n");
654*7c478bd9Sstevel@tonic-gate 						for (j = 0; j < CHPERCYL; j++)
655*7c478bd9Sstevel@tonic-gate 
656*7c478bd9Sstevel@tonic-gate 							if (skcyl[i][j] > 0){
657*7c478bd9Sstevel@tonic-gate 								if (j == 0)
658*7c478bd9Sstevel@tonic-gate 									printf("        0\t%ld\n",
659*7c478bd9Sstevel@tonic-gate 									skcyl[i][j]);
660*7c478bd9Sstevel@tonic-gate 								else
661*7c478bd9Sstevel@tonic-gate 									printf("%3d - %3d\t%ld\n",
662*7c478bd9Sstevel@tonic-gate 								j*8-7, j*8, skcyl[i][j]);
663*7c478bd9Sstevel@tonic-gate 							}
664*7c478bd9Sstevel@tonic-gate 						printf("Total Seeks = %ld\n", skdist[i]);
665*7c478bd9Sstevel@tonic-gate 					}
666*7c478bd9Sstevel@tonic-gate 					i++;
667*7c478bd9Sstevel@tonic-gate 				}
668*7c478bd9Sstevel@tonic-gate 			}
669*7c478bd9Sstevel@tonic-gate 			if (hflg){
670*7c478bd9Sstevel@tonic-gate 				for (k = 0, i = 0; k < ub; k++) {
671*7c478bd9Sstevel@tonic-gate 					if (drvlist[k] == 0)
672*7c478bd9Sstevel@tonic-gate 						continue;
673*7c478bd9Sstevel@tonic-gate 					if (disk[i] != 0) {
674*7c478bd9Sstevel@tonic-gate 						cylhdr(CYLNO, disk[i]);
675*7c478bd9Sstevel@tonic-gate 						cylhist(disk[i], dkcyl[i]);
676*7c478bd9Sstevel@tonic-gate 						cylftr(CYLNO);
677*7c478bd9Sstevel@tonic-gate 					}
678*7c478bd9Sstevel@tonic-gate 					i++;
679*7c478bd9Sstevel@tonic-gate 				}
680*7c478bd9Sstevel@tonic-gate 				for (k = 0, i = 0; k < ub; k++) {
681*7c478bd9Sstevel@tonic-gate 					if (drvlist[k] == 0)
682*7c478bd9Sstevel@tonic-gate 						continue;
683*7c478bd9Sstevel@tonic-gate 					if (skdist[i] != 0){
684*7c478bd9Sstevel@tonic-gate 						cylhdr(SEEKD, skdist[i]);
685*7c478bd9Sstevel@tonic-gate 						cylhist(skdist[i], skcyl[i]);
686*7c478bd9Sstevel@tonic-gate 						cylftr(SEEKD);
687*7c478bd9Sstevel@tonic-gate 					}
688*7c478bd9Sstevel@tonic-gate 					i++;
689*7c478bd9Sstevel@tonic-gate 				}
690*7c478bd9Sstevel@tonic-gate 			}
691*7c478bd9Sstevel@tonic-gate 
692*7c478bd9Sstevel@tonic-gate 			break;
693*7c478bd9Sstevel@tonic-gate 		}
694*7c478bd9Sstevel@tonic-gate 	}
695*7c478bd9Sstevel@tonic-gate 	if (--n)
696*7c478bd9Sstevel@tonic-gate 		continue;
697*7c478bd9Sstevel@tonic-gate 	exit(0);
698*7c478bd9Sstevel@tonic-gate 	}
699*7c478bd9Sstevel@tonic-gate }
700*7c478bd9Sstevel@tonic-gate 
701*7c478bd9Sstevel@tonic-gate void
702*7c478bd9Sstevel@tonic-gate do_disk_stats (i, k)
703*7c478bd9Sstevel@tonic-gate {
704*7c478bd9Sstevel@tonic-gate #ifdef	fixed
705*7c478bd9Sstevel@tonic-gate 	struct scsi_disk	sddisk[NDRIVE];
706*7c478bd9Sstevel@tonic-gate 	struct diskhd		*dp;
707*7c478bd9Sstevel@tonic-gate 	struct buf		buffer, *bp;
708*7c478bd9Sstevel@tonic-gate 	struct buf		*last_bp = 0;
709*7c478bd9Sstevel@tonic-gate 
710*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "do_disk_stats (i %d, k %d)\n", i, k);
711*7c478bd9Sstevel@tonic-gate 	/*
712*7c478bd9Sstevel@tonic-gate 	 * In each scsi_device struct there is a sd_private
713*7c478bd9Sstevel@tonic-gate 	 * pointer to a specialised scsi_disk struct which
714*7c478bd9Sstevel@tonic-gate 	 * describes the disk.
715*7c478bd9Sstevel@tonic-gate 	 */
716*7c478bd9Sstevel@tonic-gate 	do {
717*7c478bd9Sstevel@tonic-gate 		FETCH_AAL(sdunit[k].sd_private, &sddisk[k],
718*7c478bd9Sstevel@tonic-gate 			sizeof (struct scsi_disk), "sdunit");
719*7c478bd9Sstevel@tonic-gate 		/*
720*7c478bd9Sstevel@tonic-gate 		 * The diskhd struct describing the active and waiting
721*7c478bd9Sstevel@tonic-gate 		 * queues is embedded in the scsi_disk struct.
722*7c478bd9Sstevel@tonic-gate 		 */
723*7c478bd9Sstevel@tonic-gate 		dp = &sddisk[k].un_utab;
724*7c478bd9Sstevel@tonic-gate 		Debug dump_diskhd (dp);
725*7c478bd9Sstevel@tonic-gate 		/*
726*7c478bd9Sstevel@tonic-gate 		 * The current SunOS sd.c driver uses the b_forw
727*7c478bd9Sstevel@tonic-gate 		 * pointer for the currently active buffer, and the
728*7c478bd9Sstevel@tonic-gate 		 * b_actf (av_forw) pointer for the waiting queue
729*7c478bd9Sstevel@tonic-gate 		 * of buffers.
730*7c478bd9Sstevel@tonic-gate 		 */
731*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "%s: b_forw 0x%x\n", cmdname, (int)dp->b_forw);
732*7c478bd9Sstevel@tonic-gate 		/*
733*7c478bd9Sstevel@tonic-gate 		 * Trace disk queue for I/O location, seek distance.
734*7c478bd9Sstevel@tonic-gate 		 */
735*7c478bd9Sstevel@tonic-gate 		if (dp->b_forw) {
736*7c478bd9Sstevel@tonic-gate 			if (dp->b_forw == last_bp) {
737*7c478bd9Sstevel@tonic-gate 				continue;
738*7c478bd9Sstevel@tonic-gate 			} else {
739*7c478bd9Sstevel@tonic-gate 				last_bp = dp->b_forw;
740*7c478bd9Sstevel@tonic-gate 			}
741*7c478bd9Sstevel@tonic-gate 			dfprintf (stderr, "%s: b_forw 0x%x\n",
742*7c478bd9Sstevel@tonic-gate 				cmdname, (int)dp->b_forw);
743*7c478bd9Sstevel@tonic-gate 			FETCH_AAL(dp->b_forw, &buffer, sizeof (struct buf),
744*7c478bd9Sstevel@tonic-gate 				"b_forw");
745*7c478bd9Sstevel@tonic-gate 			bp = &buffer;
746*7c478bd9Sstevel@tonic-gate 			dfprintf (stderr, "%s: b_lblkno 0x%x b_blkno 0x%x\n",
747*7c478bd9Sstevel@tonic-gate 				cmdname, bp->b_lblkno, bp->b_blkno);
748*7c478bd9Sstevel@tonic-gate 			cyl_no = bp->b_blkno / SECTPERCYL;
749*7c478bd9Sstevel@tonic-gate 			cyl_bk = cyl_no >> CHUNKSHIFT;
750*7c478bd9Sstevel@tonic-gate 			seek_dist = prev_cyl_no - cyl_no;
751*7c478bd9Sstevel@tonic-gate 			if (seek_dist < 0)
752*7c478bd9Sstevel@tonic-gate 				seek_dist = -seek_dist;
753*7c478bd9Sstevel@tonic-gate 			seek_bk = prev_cyl_bk - cyl_bk;
754*7c478bd9Sstevel@tonic-gate 			if (seek_bk < 0)
755*7c478bd9Sstevel@tonic-gate 				seek_bk = -seek_bk;
756*7c478bd9Sstevel@tonic-gate 			prev_cyl_no = cyl_no;
757*7c478bd9Sstevel@tonic-gate 			prev_cyl_bk = cyl_bk;
758*7c478bd9Sstevel@tonic-gate 			if (cyl_no > max_cyl_no) {
759*7c478bd9Sstevel@tonic-gate 				max_cyl_no = cyl_no;
760*7c478bd9Sstevel@tonic-gate 			}
761*7c478bd9Sstevel@tonic-gate 			if (seek_dist > max_seek_dist) {
762*7c478bd9Sstevel@tonic-gate 				max_seek_dist = seek_dist;
763*7c478bd9Sstevel@tonic-gate 			}
764*7c478bd9Sstevel@tonic-gate 			skcyl[i][seek_bk]++;
765*7c478bd9Sstevel@tonic-gate 			dkcyl[i][cyl_bk]++;
766*7c478bd9Sstevel@tonic-gate 		}
767*7c478bd9Sstevel@tonic-gate 	} while (dp->b_forw);
768*7c478bd9Sstevel@tonic-gate #endif
769*7c478bd9Sstevel@tonic-gate }
770*7c478bd9Sstevel@tonic-gate 
771*7c478bd9Sstevel@tonic-gate 
772*7c478bd9Sstevel@tonic-gate /*
773*7c478bd9Sstevel@tonic-gate  * Determine if the I/O is from system buffer pool,
774*7c478bd9Sstevel@tonic-gate  * or swap buffer pool or physical buffer.
775*7c478bd9Sstevel@tonic-gate  */
776*7c478bd9Sstevel@tonic-gate 
777*7c478bd9Sstevel@tonic-gate int
778*7c478bd9Sstevel@tonic-gate testbuf()
779*7c478bd9Sstevel@tonic-gate {
780*7c478bd9Sstevel@tonic-gate 	if ((temp1 < setup[X1_BUF].n_value) || (index > tbl.v_buf)){
781*7c478bd9Sstevel@tonic-gate 		index = (int)(temp1 -setup[X1_PBUF].n_value)/
782*7c478bd9Sstevel@tonic-gate 			(sizeof (struct buf));
783*7c478bd9Sstevel@tonic-gate 		if (index < tbl.v_pbuf){
784*7c478bd9Sstevel@tonic-gate 			nonblk = 1;
785*7c478bd9Sstevel@tonic-gate 			return (0);
786*7c478bd9Sstevel@tonic-gate 
787*7c478bd9Sstevel@tonic-gate 		}
788*7c478bd9Sstevel@tonic-gate /* TBD - Is it possible to access swap buffers on Sun? */
789*7c478bd9Sstevel@tonic-gate #ifndef sun
790*7c478bd9Sstevel@tonic-gate 		index = (int)(temp1 -setup[SWP].n_value)/
791*7c478bd9Sstevel@tonic-gate 			(sizeof (struct buf));
792*7c478bd9Sstevel@tonic-gate 		if (index < NSWP) {
793*7c478bd9Sstevel@tonic-gate 			m = index;
794*7c478bd9Sstevel@tonic-gate 			nonblk = 2;
795*7c478bd9Sstevel@tonic-gate 			return (0);
796*7c478bd9Sstevel@tonic-gate 		}
797*7c478bd9Sstevel@tonic-gate #endif
798*7c478bd9Sstevel@tonic-gate 		return (-1);
799*7c478bd9Sstevel@tonic-gate 	}
800*7c478bd9Sstevel@tonic-gate 	return (0);
801*7c478bd9Sstevel@tonic-gate }
802*7c478bd9Sstevel@tonic-gate 
803*7c478bd9Sstevel@tonic-gate /*
804*7c478bd9Sstevel@tonic-gate  * Verify the I/O, get the cylinder number.
805*7c478bd9Sstevel@tonic-gate  */
806*7c478bd9Sstevel@tonic-gate 
807*7c478bd9Sstevel@tonic-gate ckbits(x)
808*7c478bd9Sstevel@tonic-gate 	register struct buf *x;
809*7c478bd9Sstevel@tonic-gate {
810*7c478bd9Sstevel@tonic-gate 	register p;
811*7c478bd9Sstevel@tonic-gate 	for (p = 0; p < index; p++, x++)
812*7c478bd9Sstevel@tonic-gate 		continue;
813*7c478bd9Sstevel@tonic-gate 	if ((x->b_flags & B_BUSY) &&
814*7c478bd9Sstevel@tonic-gate 	    ((x->b_flags & B_DONE) == 0)){
815*7c478bd9Sstevel@tonic-gate 		temp = x->cylin;
816*7c478bd9Sstevel@tonic-gate 		temp1 = (unsigned)x->av_forw;
817*7c478bd9Sstevel@tonic-gate 		return (0);
818*7c478bd9Sstevel@tonic-gate 	}
819*7c478bd9Sstevel@tonic-gate 	else
820*7c478bd9Sstevel@tonic-gate 		return (-1);
821*7c478bd9Sstevel@tonic-gate 
822*7c478bd9Sstevel@tonic-gate }
823*7c478bd9Sstevel@tonic-gate int
824*7c478bd9Sstevel@tonic-gate testdev()
825*7c478bd9Sstevel@tonic-gate {
826*7c478bd9Sstevel@tonic-gate 	if ((nonblk == 0) && (ckbits((struct buf *)sbuf) != -1))
827*7c478bd9Sstevel@tonic-gate 		goto endtest;
828*7c478bd9Sstevel@tonic-gate 	else {
829*7c478bd9Sstevel@tonic-gate 		if ((nonblk == 1) && (ckbits((struct buf *)phybuf) != -1))
830*7c478bd9Sstevel@tonic-gate 			goto endtest;
831*7c478bd9Sstevel@tonic-gate 
832*7c478bd9Sstevel@tonic-gate 		else {
833*7c478bd9Sstevel@tonic-gate 
834*7c478bd9Sstevel@tonic-gate 			if ((nonblk == 2) &&
835*7c478bd9Sstevel@tonic-gate 			    ((bp[m].b_flags & B_BUSY) &&
836*7c478bd9Sstevel@tonic-gate 			    ((bp[m].b_flags & B_DONE) == 0))){
837*7c478bd9Sstevel@tonic-gate 				temp = bp[m].cylin;
838*7c478bd9Sstevel@tonic-gate 				temp1 = (unsigned)bp[m].av_forw;
839*7c478bd9Sstevel@tonic-gate 			} else {
840*7c478bd9Sstevel@tonic-gate 				dfprintf (stderr, "testdev -1\n");
841*7c478bd9Sstevel@tonic-gate 				return (-1);
842*7c478bd9Sstevel@tonic-gate 			}
843*7c478bd9Sstevel@tonic-gate 		}
844*7c478bd9Sstevel@tonic-gate 	}
845*7c478bd9Sstevel@tonic-gate endtest:
846*7c478bd9Sstevel@tonic-gate 	dkcyl[i][temp >> 3]++;
847*7c478bd9Sstevel@tonic-gate 	return (0);
848*7c478bd9Sstevel@tonic-gate }
849*7c478bd9Sstevel@tonic-gate 
850*7c478bd9Sstevel@tonic-gate 
851*7c478bd9Sstevel@tonic-gate 
852*7c478bd9Sstevel@tonic-gate /*
853*7c478bd9Sstevel@tonic-gate  * Get drive number routine.
854*7c478bd9Sstevel@tonic-gate  */
855*7c478bd9Sstevel@tonic-gate getdrvn()
856*7c478bd9Sstevel@tonic-gate {
857*7c478bd9Sstevel@tonic-gate 	extern char *optarg;
858*7c478bd9Sstevel@tonic-gate 	char *strcpy();
859*7c478bd9Sstevel@tonic-gate 	char *strncat();
860*7c478bd9Sstevel@tonic-gate 
861*7c478bd9Sstevel@tonic-gate 	strcpy(drive, empty);
862*7c478bd9Sstevel@tonic-gate 	strncat(drive, &optarg[n1], i-n1);
863*7c478bd9Sstevel@tonic-gate 	if (tstdigit(drive) != 0)
864*7c478bd9Sstevel@tonic-gate 		return (-1);
865*7c478bd9Sstevel@tonic-gate 	dn = atoi(drive);
866*7c478bd9Sstevel@tonic-gate 	if (SCSI) {
867*7c478bd9Sstevel@tonic-gate 		if (dn >= SNDRIVE)
868*7c478bd9Sstevel@tonic-gate 			return (-1);
869*7c478bd9Sstevel@tonic-gate 	} else {
870*7c478bd9Sstevel@tonic-gate 		if (dn >= NDRIVE)
871*7c478bd9Sstevel@tonic-gate 			return (-1);
872*7c478bd9Sstevel@tonic-gate 	}
873*7c478bd9Sstevel@tonic-gate 	return (0);
874*7c478bd9Sstevel@tonic-gate }
875*7c478bd9Sstevel@tonic-gate 
876*7c478bd9Sstevel@tonic-gate void
877*7c478bd9Sstevel@tonic-gate usage()
878*7c478bd9Sstevel@tonic-gate {
879*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "usage:  sadp [-th][-d device[-drive]] s [n]\n");
880*7c478bd9Sstevel@tonic-gate 	exit(1);
881*7c478bd9Sstevel@tonic-gate }
882*7c478bd9Sstevel@tonic-gate 
883*7c478bd9Sstevel@tonic-gate int tstdigit(ss)
884*7c478bd9Sstevel@tonic-gate char *ss;
885*7c478bd9Sstevel@tonic-gate {
886*7c478bd9Sstevel@tonic-gate 	int kk, cc;
887*7c478bd9Sstevel@tonic-gate 	kk = 0;
888*7c478bd9Sstevel@tonic-gate 	while ((cc = ss[kk]) != '\0'){
889*7c478bd9Sstevel@tonic-gate 		if (isdigit(cc) == 0)
890*7c478bd9Sstevel@tonic-gate 			return (-1);
891*7c478bd9Sstevel@tonic-gate 		kk++;
892*7c478bd9Sstevel@tonic-gate 	}
893*7c478bd9Sstevel@tonic-gate 	return (0);
894*7c478bd9Sstevel@tonic-gate }
895*7c478bd9Sstevel@tonic-gate 
896*7c478bd9Sstevel@tonic-gate /*
897*7c478bd9Sstevel@tonic-gate  * The following routines are obtained from iostat.
898*7c478bd9Sstevel@tonic-gate  *
899*7c478bd9Sstevel@tonic-gate  * Output Cylinder Histogram.
900*7c478bd9Sstevel@tonic-gate  */
901*7c478bd9Sstevel@tonic-gate void
902*7c478bd9Sstevel@tonic-gate cylhist(at, dp)
903*7c478bd9Sstevel@tonic-gate long at;
904*7c478bd9Sstevel@tonic-gate register struct HISTDATA *dp;
905*7c478bd9Sstevel@tonic-gate {
906*7c478bd9Sstevel@tonic-gate 	register ii;
907*7c478bd9Sstevel@tonic-gate 	int maxrow;
908*7c478bd9Sstevel@tonic-gate 	long *graph = (long *)calloc(CHPERCYL, sizeof (long));
909*7c478bd9Sstevel@tonic-gate 	long    max, max2;
910*7c478bd9Sstevel@tonic-gate 	long    data;
911*7c478bd9Sstevel@tonic-gate 	long    scale;
912*7c478bd9Sstevel@tonic-gate 
913*7c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < CHPERCYL; ii++) {
914*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "(%d %d) ", ii, (int)dp->hdata[ii]);
915*7c478bd9Sstevel@tonic-gate 	}
916*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "\n");
917*7c478bd9Sstevel@tonic-gate 	max = 0;
918*7c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < CHPERCYL; ii++) {
919*7c478bd9Sstevel@tonic-gate 		if (data = dp->hdata[ii]) {
920*7c478bd9Sstevel@tonic-gate 			maxrow = ii;
921*7c478bd9Sstevel@tonic-gate 			if (data > max) {
922*7c478bd9Sstevel@tonic-gate 				max2 = max;
923*7c478bd9Sstevel@tonic-gate 				max = data;
924*7c478bd9Sstevel@tonic-gate 			} else if (data > max2 && data != max)
925*7c478bd9Sstevel@tonic-gate 				max2 = data;
926*7c478bd9Sstevel@tonic-gate 		}
927*7c478bd9Sstevel@tonic-gate 	}
928*7c478bd9Sstevel@tonic-gate 	maxrow++;
929*7c478bd9Sstevel@tonic-gate 
930*7c478bd9Sstevel@tonic-gate 	/* determine scaling */
931*7c478bd9Sstevel@tonic-gate 	scale = 1;
932*7c478bd9Sstevel@tonic-gate 	if (max2) {
933*7c478bd9Sstevel@tonic-gate 		scale = at / (max2 * 2);
934*7c478bd9Sstevel@tonic-gate 		if (scale > 48)
935*7c478bd9Sstevel@tonic-gate 			scale = 48;
936*7c478bd9Sstevel@tonic-gate 		}
937*7c478bd9Sstevel@tonic-gate 
938*7c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < maxrow; ii++) {
939*7c478bd9Sstevel@tonic-gate 		if (dp->hdata[ii])
940*7c478bd9Sstevel@tonic-gate 			graph[ii] = (scale * 100 * dp->hdata[ii]) / at;
941*7c478bd9Sstevel@tonic-gate 		else
942*7c478bd9Sstevel@tonic-gate 			graph[ii] = -1;
943*7c478bd9Sstevel@tonic-gate 	}
944*7c478bd9Sstevel@tonic-gate 
945*7c478bd9Sstevel@tonic-gate 	prthist(graph, maxrow, scale, (long) (max*100*scale/at));
946*7c478bd9Sstevel@tonic-gate }
947*7c478bd9Sstevel@tonic-gate /*
948*7c478bd9Sstevel@tonic-gate  * Print Histogram.
949*7c478bd9Sstevel@tonic-gate  */
950*7c478bd9Sstevel@tonic-gate void
951*7c478bd9Sstevel@tonic-gate prthist(array, mrow, scale, gmax)
952*7c478bd9Sstevel@tonic-gate 	long array[], scale, gmax;
953*7c478bd9Sstevel@tonic-gate register mrow;
954*7c478bd9Sstevel@tonic-gate {
955*7c478bd9Sstevel@tonic-gate 	long    line;
956*7c478bd9Sstevel@tonic-gate 
957*7c478bd9Sstevel@tonic-gate 	line = 50;
958*7c478bd9Sstevel@tonic-gate 	/* handle overflow in scaling */
959*7c478bd9Sstevel@tonic-gate 	if (gmax > 51) {
960*7c478bd9Sstevel@tonic-gate 		line = 52;
961*7c478bd9Sstevel@tonic-gate 		printf("\n%2ld%% -|", gmax/scale);
962*7c478bd9Sstevel@tonic-gate 		pline(line--, array, mrow, BLOB);
963*7c478bd9Sstevel@tonic-gate 		printf("\n     %c", BRK);
964*7c478bd9Sstevel@tonic-gate 		pline(line--, array, mrow, BRK);
965*7c478bd9Sstevel@tonic-gate 	} else if (gmax = 51)
966*7c478bd9Sstevel@tonic-gate 		line = 51;
967*7c478bd9Sstevel@tonic-gate 	while (line > 0) {
968*7c478bd9Sstevel@tonic-gate 		if ((line & 07) == 0) {
969*7c478bd9Sstevel@tonic-gate 			printf("\n%2ld%% -|", line/scale);
970*7c478bd9Sstevel@tonic-gate 		} else {
971*7c478bd9Sstevel@tonic-gate 			printf("\n     |");
972*7c478bd9Sstevel@tonic-gate 		}
973*7c478bd9Sstevel@tonic-gate 		pline(line--, array, mrow, BLOB);
974*7c478bd9Sstevel@tonic-gate 	}
975*7c478bd9Sstevel@tonic-gate 	printf("\n 0%% -+");
976*7c478bd9Sstevel@tonic-gate 	line = -1;
977*7c478bd9Sstevel@tonic-gate 	pline(line, array, mrow, FOOT);
978*7c478bd9Sstevel@tonic-gate }
979*7c478bd9Sstevel@tonic-gate 
980*7c478bd9Sstevel@tonic-gate /*
981*7c478bd9Sstevel@tonic-gate  * Print Histogram Line.
982*7c478bd9Sstevel@tonic-gate  */
983*7c478bd9Sstevel@tonic-gate void
984*7c478bd9Sstevel@tonic-gate pline(line, array, mrow, dot)
985*7c478bd9Sstevel@tonic-gate 	long line, array[];
986*7c478bd9Sstevel@tonic-gate int mrow;
987*7c478bd9Sstevel@tonic-gate char dot;
988*7c478bd9Sstevel@tonic-gate {
989*7c478bd9Sstevel@tonic-gate 	register ii;
990*7c478bd9Sstevel@tonic-gate 	register char *lp;
991*7c478bd9Sstevel@tonic-gate 	char lbuff[132];
992*7c478bd9Sstevel@tonic-gate 
993*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr,
994*7c478bd9Sstevel@tonic-gate 		"pline(line 0x%x, array 0x%x, mrow 0x%x, dot 0x%x)\n",
995*7c478bd9Sstevel@tonic-gate 		line, array, mrow, dot);
996*7c478bd9Sstevel@tonic-gate 	lp = lbuff;
997*7c478bd9Sstevel@tonic-gate 	for (ii = 0; ii < mrow; ii++)
998*7c478bd9Sstevel@tonic-gate 		if (array[ii] < line)
999*7c478bd9Sstevel@tonic-gate 			if (line == 1 && array[ii] == 0)
1000*7c478bd9Sstevel@tonic-gate 				*lp++ = TRACE;
1001*7c478bd9Sstevel@tonic-gate 			else
1002*7c478bd9Sstevel@tonic-gate 				*lp++ = BLANK;
1003*7c478bd9Sstevel@tonic-gate 		else
1004*7c478bd9Sstevel@tonic-gate 			*lp++ = dot;
1005*7c478bd9Sstevel@tonic-gate 	*lp++ = 0;
1006*7c478bd9Sstevel@tonic-gate 	printf("%s", lbuff);
1007*7c478bd9Sstevel@tonic-gate }
1008*7c478bd9Sstevel@tonic-gate /*
1009*7c478bd9Sstevel@tonic-gate  * Print Cylinder Profiling Headers.
1010*7c478bd9Sstevel@tonic-gate  */
1011*7c478bd9Sstevel@tonic-gate void
1012*7c478bd9Sstevel@tonic-gate cylhdr(flag, total)
1013*7c478bd9Sstevel@tonic-gate 	long total;
1014*7c478bd9Sstevel@tonic-gate {
1015*7c478bd9Sstevel@tonic-gate 
1016*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "cylhdr(flag 0x%x, total 0x%x)\n", flag, total);
1017*7c478bd9Sstevel@tonic-gate 	if (fflg)
1018*7c478bd9Sstevel@tonic-gate 		printf("\014\n");
1019*7c478bd9Sstevel@tonic-gate 	if (flag == CYLNO)
1020*7c478bd9Sstevel@tonic-gate 		printf("\nCYLINDER ACCESS HISTOGRAM\n");
1021*7c478bd9Sstevel@tonic-gate 	if (flag == SEEKD)
1022*7c478bd9Sstevel@tonic-gate 		printf("\nSEEK DISTANCE HISTOGRAM\n");
1023*7c478bd9Sstevel@tonic-gate 	printf("\n%s-%d:\n",
1024*7c478bd9Sstevel@tonic-gate 		device, k);
1025*7c478bd9Sstevel@tonic-gate 	printf("Total %s = %ld\n",
1026*7c478bd9Sstevel@tonic-gate 		flag == CYLNO ? "transfers" : "seeks", total);
1027*7c478bd9Sstevel@tonic-gate }
1028*7c478bd9Sstevel@tonic-gate 
1029*7c478bd9Sstevel@tonic-gate #define	MAXCOL	80
1030*7c478bd9Sstevel@tonic-gate /* Print Histogram Footers */
1031*7c478bd9Sstevel@tonic-gate void
1032*7c478bd9Sstevel@tonic-gate cylftr(flag)
1033*7c478bd9Sstevel@tonic-gate {
1034*7c478bd9Sstevel@tonic-gate 	int		i;
1035*7c478bd9Sstevel@tonic-gate 	int		chunk_mult = 1;
1036*7c478bd9Sstevel@tonic-gate 	int		col;
1037*7c478bd9Sstevel@tonic-gate 	char		footer[4][MAXCOL];
1038*7c478bd9Sstevel@tonic-gate 	char		digits[] = "0123456789";
1039*7c478bd9Sstevel@tonic-gate 	int		significant = 0;
1040*7c478bd9Sstevel@tonic-gate 
1041*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "cylftr(flag 0x%x)\n", flag);
1042*7c478bd9Sstevel@tonic-gate 	if (flag == CYLNO)
1043*7c478bd9Sstevel@tonic-gate 		printf("\n      \t\t\tCylinder number, granularity=%d", CHUNK);
1044*7c478bd9Sstevel@tonic-gate 	else
1045*7c478bd9Sstevel@tonic-gate 		printf("\n      =<< ");
1046*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < 4; i++) {
1047*7c478bd9Sstevel@tonic-gate 		for (col = 0; col < MAXCOL - 1; col++) {
1048*7c478bd9Sstevel@tonic-gate 			footer[i][col] = ' ';
1049*7c478bd9Sstevel@tonic-gate 		}
1050*7c478bd9Sstevel@tonic-gate 		footer[i][MAXCOL - 1] = '\0';
1051*7c478bd9Sstevel@tonic-gate 	}
1052*7c478bd9Sstevel@tonic-gate 	for (i = 0, col = 0; i < (int)PHYS_CYL;
1053*7c478bd9Sstevel@tonic-gate 		i += (chunk_mult * CHUNK), col += chunk_mult, significant = 0) {
1054*7c478bd9Sstevel@tonic-gate 		if ((i / 1000) > 0) {
1055*7c478bd9Sstevel@tonic-gate 			footer[0][col] = digits[(i / 1000)];
1056*7c478bd9Sstevel@tonic-gate 			significant = 1;
1057*7c478bd9Sstevel@tonic-gate 		}
1058*7c478bd9Sstevel@tonic-gate 		if ((significant) || (((i % 1000) / 100) > 0)) {
1059*7c478bd9Sstevel@tonic-gate 			footer[1][col] = digits[((i % 1000) / 100)];
1060*7c478bd9Sstevel@tonic-gate 			significant = 1;
1061*7c478bd9Sstevel@tonic-gate 		}
1062*7c478bd9Sstevel@tonic-gate 		if ((significant) || (((i % 100) / 10) > 0)) {
1063*7c478bd9Sstevel@tonic-gate 			footer[2][col] = digits[((i % 100) / 10)];
1064*7c478bd9Sstevel@tonic-gate 			significant = 1;
1065*7c478bd9Sstevel@tonic-gate 		}
1066*7c478bd9Sstevel@tonic-gate 		if ((i == 0) || (significant) || ((i % 10) > 0)) {
1067*7c478bd9Sstevel@tonic-gate 			footer[3][col] = digits[(i % 10)];
1068*7c478bd9Sstevel@tonic-gate 		}
1069*7c478bd9Sstevel@tonic-gate 		if (i > CHUNK) {
1070*7c478bd9Sstevel@tonic-gate 			chunk_mult = 2;
1071*7c478bd9Sstevel@tonic-gate 		}
1072*7c478bd9Sstevel@tonic-gate 		if (i > (3 * CHUNK)) {
1073*7c478bd9Sstevel@tonic-gate 			chunk_mult = 4;
1074*7c478bd9Sstevel@tonic-gate 			if (flag != CYLNO)
1075*7c478bd9Sstevel@tonic-gate 				printf ("<   ");
1076*7c478bd9Sstevel@tonic-gate 		}
1077*7c478bd9Sstevel@tonic-gate 	}
1078*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < 4; i++) {
1079*7c478bd9Sstevel@tonic-gate 		printf ("      %s\n", footer[i]);
1080*7c478bd9Sstevel@tonic-gate 	}
1081*7c478bd9Sstevel@tonic-gate 	printf ("\n");
1082*7c478bd9Sstevel@tonic-gate }
1083*7c478bd9Sstevel@tonic-gate 
1084*7c478bd9Sstevel@tonic-gate void
1085*7c478bd9Sstevel@tonic-gate validate_device()
1086*7c478bd9Sstevel@tonic-gate {
1087*7c478bd9Sstevel@tonic-gate 	int	i;
1088*7c478bd9Sstevel@tonic-gate 	char	tempdev[NAMESIZE];
1089*7c478bd9Sstevel@tonic-gate 
1090*7c478bd9Sstevel@tonic-gate 	if (dflg == 0) {
1091*7c478bd9Sstevel@tonic-gate 
1092*7c478bd9Sstevel@tonic-gate 		/*
1093*7c478bd9Sstevel@tonic-gate 		 * No device specified, so default to the first
1094*7c478bd9Sstevel@tonic-gate 		 * one if it is the only one, otherwise prompt
1095*7c478bd9Sstevel@tonic-gate 		 * user to enter one.
1096*7c478bd9Sstevel@tonic-gate 		 */
1097*7c478bd9Sstevel@tonic-gate 		strcpy(device, devnm[0]);
1098*7c478bd9Sstevel@tonic-gate 		*DRVNUM(device) = NULL;
1099*7c478bd9Sstevel@tonic-gate 		devlen = strlen(device);
1100*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < dk_ndrive; i++)
1101*7c478bd9Sstevel@tonic-gate 			drvlist[i] = 1;
1102*7c478bd9Sstevel@tonic-gate 		if (dk_ndrive > 1)
1103*7c478bd9Sstevel@tonic-gate 			bad_device(device, ERR_NO_DEV);
1104*7c478bd9Sstevel@tonic-gate 		dev = 0;
1105*7c478bd9Sstevel@tonic-gate 	} else {
1106*7c478bd9Sstevel@tonic-gate 
1107*7c478bd9Sstevel@tonic-gate 		/*
1108*7c478bd9Sstevel@tonic-gate 		 * Device was specified.  Make sure it matches
1109*7c478bd9Sstevel@tonic-gate 		 * one that is configured in the system.
1110*7c478bd9Sstevel@tonic-gate 		 */
1111*7c478bd9Sstevel@tonic-gate 		for (i = 0; i < dk_ndrive; i++) {
1112*7c478bd9Sstevel@tonic-gate 			strncpy(tempdev, devnm[i], DRVNUM(devnm[i])-devnm[i]);
1113*7c478bd9Sstevel@tonic-gate 			tempdev[DRVNUM(devnm[i])-devnm[i]] = NULL;
1114*7c478bd9Sstevel@tonic-gate 			if (strcmp(device, tempdev) == 0)
1115*7c478bd9Sstevel@tonic-gate 				break;
1116*7c478bd9Sstevel@tonic-gate 		}
1117*7c478bd9Sstevel@tonic-gate 		if (i == dk_ndrive)
1118*7c478bd9Sstevel@tonic-gate 			bad_device(device, ERR_BAD_DEV);
1119*7c478bd9Sstevel@tonic-gate 		dev = i;
1120*7c478bd9Sstevel@tonic-gate 	}
1121*7c478bd9Sstevel@tonic-gate }
1122*7c478bd9Sstevel@tonic-gate 
1123*7c478bd9Sstevel@tonic-gate void
1124*7c478bd9Sstevel@tonic-gate validate_drive()
1125*7c478bd9Sstevel@tonic-gate {
1126*7c478bd9Sstevel@tonic-gate 	int	i, j, c;
1127*7c478bd9Sstevel@tonic-gate 
1128*7c478bd9Sstevel@tonic-gate 	/*
1129*7c478bd9Sstevel@tonic-gate 	 * For each controller number specified, make sure it exists
1130*7c478bd9Sstevel@tonic-gate 	 * in the configured device list.
1131*7c478bd9Sstevel@tonic-gate 	 */
1132*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < dk_ndrive; i++) {
1133*7c478bd9Sstevel@tonic-gate 		if (drvlist[i] == 0)
1134*7c478bd9Sstevel@tonic-gate 			continue;
1135*7c478bd9Sstevel@tonic-gate 
1136*7c478bd9Sstevel@tonic-gate 		/*
1137*7c478bd9Sstevel@tonic-gate 		 * Since this controller number (i) was specified,
1138*7c478bd9Sstevel@tonic-gate 		 * find the corresponding entry (j) in the device list.
1139*7c478bd9Sstevel@tonic-gate 		 * If found, save the device list index in drvlist[].
1140*7c478bd9Sstevel@tonic-gate 		 */
1141*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < dk_ndrive; j++) {
1142*7c478bd9Sstevel@tonic-gate 			if (strncmp(device, devnm[j], devlen) != 0)
1143*7c478bd9Sstevel@tonic-gate 				continue;
1144*7c478bd9Sstevel@tonic-gate 			c = atoi(DRVNUM(devnm[j]));
1145*7c478bd9Sstevel@tonic-gate 			if (c == i) {
1146*7c478bd9Sstevel@tonic-gate 				/*
1147*7c478bd9Sstevel@tonic-gate 				 * NOTE: saved value actual index+1
1148*7c478bd9Sstevel@tonic-gate 				 * as entries with 0 imply don't care.
1149*7c478bd9Sstevel@tonic-gate 				 */
1150*7c478bd9Sstevel@tonic-gate 				drvlist[i] = j+1;  /* not a flag anymore! */
1151*7c478bd9Sstevel@tonic-gate 
1152*7c478bd9Sstevel@tonic-gate 				break;
1153*7c478bd9Sstevel@tonic-gate 			}
1154*7c478bd9Sstevel@tonic-gate 		}
1155*7c478bd9Sstevel@tonic-gate 
1156*7c478bd9Sstevel@tonic-gate 		/*
1157*7c478bd9Sstevel@tonic-gate 		 * If not found, output error, except if all drives
1158*7c478bd9Sstevel@tonic-gate 		 * were implied by only specifying controller type.
1159*7c478bd9Sstevel@tonic-gate 		 * In this case, flag it as don't care.
1160*7c478bd9Sstevel@tonic-gate 		 */
1161*7c478bd9Sstevel@tonic-gate 		if (j == dk_ndrive) {
1162*7c478bd9Sstevel@tonic-gate 			if (all)
1163*7c478bd9Sstevel@tonic-gate 				drvlist[i] = 0;
1164*7c478bd9Sstevel@tonic-gate 			else
1165*7c478bd9Sstevel@tonic-gate 				bad_device(device, ERR_BAD_UNIT);
1166*7c478bd9Sstevel@tonic-gate 			}
1167*7c478bd9Sstevel@tonic-gate 	}
1168*7c478bd9Sstevel@tonic-gate }
1169*7c478bd9Sstevel@tonic-gate 
1170*7c478bd9Sstevel@tonic-gate void
1171*7c478bd9Sstevel@tonic-gate init_geom()
1172*7c478bd9Sstevel@tonic-gate {
1173*7c478bd9Sstevel@tonic-gate 	char	tempdev[NAMESIZE];
1174*7c478bd9Sstevel@tonic-gate 	int	i, fd;
1175*7c478bd9Sstevel@tonic-gate /*
1176*7c478bd9Sstevel@tonic-gate  * When the new device naming convention is in effect, switch to it
1177*7c478bd9Sstevel@tonic-gate  */
1178*7c478bd9Sstevel@tonic-gate #ifdef NEW_DEVICE_NAMES
1179*7c478bd9Sstevel@tonic-gate #define	DEV_PREFIX	"/dev/rdsk/"
1180*7c478bd9Sstevel@tonic-gate #else
1181*7c478bd9Sstevel@tonic-gate #define	DEV_PREFIX	"/dev/r"
1182*7c478bd9Sstevel@tonic-gate #endif
1183*7c478bd9Sstevel@tonic-gate 
1184*7c478bd9Sstevel@tonic-gate 	for (i = 0; drvlist[i] == 0; i++);
1185*7c478bd9Sstevel@tonic-gate 	sprintf(tempdev, "%s%s%da", DEV_PREFIX, device, i);
1186*7c478bd9Sstevel@tonic-gate 	if ((fd = open(tempdev, O_RDONLY)) == -1)
1187*7c478bd9Sstevel@tonic-gate 		fail("open failed", 1);
1188*7c478bd9Sstevel@tonic-gate 	if (ioctl(fd, DKIOCGGEOM, &dk_geom) == -1) {
1189*7c478bd9Sstevel@tonic-gate 		close(fd);
1190*7c478bd9Sstevel@tonic-gate 		fail("ioctl failed", 1);
1191*7c478bd9Sstevel@tonic-gate 	}
1192*7c478bd9Sstevel@tonic-gate 	close(fd);
1193*7c478bd9Sstevel@tonic-gate 
1194*7c478bd9Sstevel@tonic-gate 	/*
1195*7c478bd9Sstevel@tonic-gate 	 * dk_geom structure now has data, and the number
1196*7c478bd9Sstevel@tonic-gate 	 * of 8 cylinder chunks on the disk can now be
1197*7c478bd9Sstevel@tonic-gate 	 * referenced via the CHPERCYL macro.  So allocate
1198*7c478bd9Sstevel@tonic-gate 	 * appropriate buffers based on this value.
1199*7c478bd9Sstevel@tonic-gate 	 */
1200*7c478bd9Sstevel@tonic-gate 	iocnt = (long *)calloc(dk_ndrive, sizeof (long));
1201*7c478bd9Sstevel@tonic-gate 	dkcyl = (long **)calloc(dk_ndrive, sizeof (long *));
1202*7c478bd9Sstevel@tonic-gate 	skcyl = (long **)calloc(dk_ndrive, sizeof (long *));
1203*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < dk_ndrive; i++) {
1204*7c478bd9Sstevel@tonic-gate 		dkcyl[i] = (long *)calloc(CHPERCYL, sizeof (long));
1205*7c478bd9Sstevel@tonic-gate 		skcyl[i] = (long *)calloc(CHPERCYL, sizeof (long));
1206*7c478bd9Sstevel@tonic-gate 	}
1207*7c478bd9Sstevel@tonic-gate }
1208*7c478bd9Sstevel@tonic-gate 
1209*7c478bd9Sstevel@tonic-gate /*
1210*7c478bd9Sstevel@tonic-gate  * General routine for printing out an error message
1211*7c478bd9Sstevel@tonic-gate  * when the specified device/drive is insufficient.
1212*7c478bd9Sstevel@tonic-gate  */
1213*7c478bd9Sstevel@tonic-gate void
1214*7c478bd9Sstevel@tonic-gate bad_device(device, errmsg)
1215*7c478bd9Sstevel@tonic-gate 	char	*device;
1216*7c478bd9Sstevel@tonic-gate 	char	*errmsg;
1217*7c478bd9Sstevel@tonic-gate {
1218*7c478bd9Sstevel@tonic-gate 	int	i, j;
1219*7c478bd9Sstevel@tonic-gate 	int	unique = 0;
1220*7c478bd9Sstevel@tonic-gate 	char	*p, *p1, **buf;
1221*7c478bd9Sstevel@tonic-gate 	char	s[NAMESIZE];
1222*7c478bd9Sstevel@tonic-gate 	char	*msg;
1223*7c478bd9Sstevel@tonic-gate 
1224*7c478bd9Sstevel@tonic-gate 
1225*7c478bd9Sstevel@tonic-gate 	/*
1226*7c478bd9Sstevel@tonic-gate 	 * Print usage statement if no device is specified.
1227*7c478bd9Sstevel@tonic-gate 	 */
1228*7c478bd9Sstevel@tonic-gate 	if (device[0] == NULL)
1229*7c478bd9Sstevel@tonic-gate 		usage();
1230*7c478bd9Sstevel@tonic-gate 
1231*7c478bd9Sstevel@tonic-gate 	/*
1232*7c478bd9Sstevel@tonic-gate 	 * Compose a list of unique device controller types, or
1233*7c478bd9Sstevel@tonic-gate 	 * unit numbers for a specified controller type, from
1234*7c478bd9Sstevel@tonic-gate 	 * the complete device list.
1235*7c478bd9Sstevel@tonic-gate 	 */
1236*7c478bd9Sstevel@tonic-gate 	buf = (char **)calloc(dk_ndrive, sizeof (char *));
1237*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < dk_ndrive; i++) {
1238*7c478bd9Sstevel@tonic-gate 
1239*7c478bd9Sstevel@tonic-gate 		/*
1240*7c478bd9Sstevel@tonic-gate 		 * Get controller type or unit
1241*7c478bd9Sstevel@tonic-gate 		 */
1242*7c478bd9Sstevel@tonic-gate 		p = devnm[i];
1243*7c478bd9Sstevel@tonic-gate 		p1 = DRVNUM(devnm[i]);
1244*7c478bd9Sstevel@tonic-gate 		if (!strcmp(errmsg, ERR_BAD_UNIT)) {
1245*7c478bd9Sstevel@tonic-gate 			if (strncmp(devnm[i], device, devlen))
1246*7c478bd9Sstevel@tonic-gate 				continue;
1247*7c478bd9Sstevel@tonic-gate 			p = p1;
1248*7c478bd9Sstevel@tonic-gate 			p1++;
1249*7c478bd9Sstevel@tonic-gate 		}
1250*7c478bd9Sstevel@tonic-gate 		strncpy(s, p, p1-p);
1251*7c478bd9Sstevel@tonic-gate 		s[p1-p] = NULL;
1252*7c478bd9Sstevel@tonic-gate 
1253*7c478bd9Sstevel@tonic-gate 		/*
1254*7c478bd9Sstevel@tonic-gate 		 * Have we already logged this one as unique?
1255*7c478bd9Sstevel@tonic-gate 		 * If not, then do so now.
1256*7c478bd9Sstevel@tonic-gate 		 */
1257*7c478bd9Sstevel@tonic-gate 		for (j = 0; j < unique; j++)
1258*7c478bd9Sstevel@tonic-gate 			if (!strcmp(s, buf[j]))
1259*7c478bd9Sstevel@tonic-gate 				break;
1260*7c478bd9Sstevel@tonic-gate 		if (j == unique)
1261*7c478bd9Sstevel@tonic-gate 			buf[unique++] = strdup(s);
1262*7c478bd9Sstevel@tonic-gate 	}
1263*7c478bd9Sstevel@tonic-gate 
1264*7c478bd9Sstevel@tonic-gate 	/*
1265*7c478bd9Sstevel@tonic-gate 	 * Invalid device was specified.  Compose message containing
1266*7c478bd9Sstevel@tonic-gate 	 * list of valid devices.
1267*7c478bd9Sstevel@tonic-gate 	 */
1268*7c478bd9Sstevel@tonic-gate 	msg = (char *)malloc(strlen(errmsg) +
1269*7c478bd9Sstevel@tonic-gate 			strlen(device) + unique*(NAMESIZE+1) + 1);
1270*7c478bd9Sstevel@tonic-gate 	sprintf(msg, errmsg, device);
1271*7c478bd9Sstevel@tonic-gate 	for (p = msg + strlen(msg), i = 0; i < unique; i++) {
1272*7c478bd9Sstevel@tonic-gate 		sprintf(p, "%s ", buf[i]);
1273*7c478bd9Sstevel@tonic-gate 		p += (strlen(buf[i])+ 1);
1274*7c478bd9Sstevel@tonic-gate 	}
1275*7c478bd9Sstevel@tonic-gate 
1276*7c478bd9Sstevel@tonic-gate 	/*
1277*7c478bd9Sstevel@tonic-gate 	 * Output the message and exit.
1278*7c478bd9Sstevel@tonic-gate 	 */
1279*7c478bd9Sstevel@tonic-gate 	fail(msg, 0);
1280*7c478bd9Sstevel@tonic-gate }
1281*7c478bd9Sstevel@tonic-gate 
1282*7c478bd9Sstevel@tonic-gate /*
1283*7c478bd9Sstevel@tonic-gate  * Code below here was taken from the SunOS 5.0 iostat command.
1284*7c478bd9Sstevel@tonic-gate  */
1285*7c478bd9Sstevel@tonic-gate 
1286*7c478bd9Sstevel@tonic-gate #ifdef FIXME
1287*7c478bd9Sstevel@tonic-gate 
1288*7c478bd9Sstevel@tonic-gate void
1289*7c478bd9Sstevel@tonic-gate read_devinfo_names()
1290*7c478bd9Sstevel@tonic-gate {
1291*7c478bd9Sstevel@tonic-gate 	int i;
1292*7c478bd9Sstevel@tonic-gate 	struct dk_ivec dkivec[NDRIVE];
1293*7c478bd9Sstevel@tonic-gate 
1294*7c478bd9Sstevel@tonic-gate 	safe_kvm_read (kd, nl_4c[X1_DK_IVEC].n_value, dkivec, sizeof dkivec,
1295*7c478bd9Sstevel@tonic-gate 		"dk_ivec");
1296*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDRIVE; i++) {
1297*7c478bd9Sstevel@tonic-gate 		if (dkivec[i].dk_name) {
1298*7c478bd9Sstevel@tonic-gate 			safe_kvm_read (kd, dkivec[i].dk_name, dr_name[i], 2,
1299*7c478bd9Sstevel@tonic-gate 				"dk_name");
1300*7c478bd9Sstevel@tonic-gate 			sprintf(dr_name[i] + 2, "%d", dkivec[i].dk_unit);
1301*7c478bd9Sstevel@tonic-gate 		}
1302*7c478bd9Sstevel@tonic-gate 	}
1303*7c478bd9Sstevel@tonic-gate }
1304*7c478bd9Sstevel@tonic-gate 
1305*7c478bd9Sstevel@tonic-gate #endif
1306*7c478bd9Sstevel@tonic-gate 
1307*7c478bd9Sstevel@tonic-gate void
1308*7c478bd9Sstevel@tonic-gate init_disk()
1309*7c478bd9Sstevel@tonic-gate {
1310*7c478bd9Sstevel@tonic-gate #ifdef FIXME
1311*7c478bd9Sstevel@tonic-gate 	int i;
1312*7c478bd9Sstevel@tonic-gate 
1313*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < NDRIVE; i++) {
1314*7c478bd9Sstevel@tonic-gate 		dr_select[i] = 0;
1315*7c478bd9Sstevel@tonic-gate 		dk_bps[i] = 0;
1316*7c478bd9Sstevel@tonic-gate 	}
1317*7c478bd9Sstevel@tonic-gate 
1318*7c478bd9Sstevel@tonic-gate 	/*
1319*7c478bd9Sstevel@tonic-gate 	 * The default device names: dk#
1320*7c478bd9Sstevel@tonic-gate 	 */
1321*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < dk_ndrive; i++) {
1322*7c478bd9Sstevel@tonic-gate 		dr_name[i] = buf;
1323*7c478bd9Sstevel@tonic-gate 		(void) sprintf(buf, "dk%d", i);
1324*7c478bd9Sstevel@tonic-gate 		buf += NAMESIZE;
1325*7c478bd9Sstevel@tonic-gate 	}
1326*7c478bd9Sstevel@tonic-gate 
1327*7c478bd9Sstevel@tonic-gate 	/*
1328*7c478bd9Sstevel@tonic-gate 	 * Device names must be discovered in this program, and output
1329*7c478bd9Sstevel@tonic-gate 	 * with its io data via the "sa" structure.
1330*7c478bd9Sstevel@tonic-gate 	 */
1331*7c478bd9Sstevel@tonic-gate 
1332*7c478bd9Sstevel@tonic-gate 	read_devinfo_names();
1333*7c478bd9Sstevel@tonic-gate #else
1334*7c478bd9Sstevel@tonic-gate 	return;
1335*7c478bd9Sstevel@tonic-gate #endif
1336*7c478bd9Sstevel@tonic-gate }
1337*7c478bd9Sstevel@tonic-gate 
1338*7c478bd9Sstevel@tonic-gate /*
1339*7c478bd9Sstevel@tonic-gate  * issue failure message and exit
1340*7c478bd9Sstevel@tonic-gate  */
1341*7c478bd9Sstevel@tonic-gate void
1342*7c478bd9Sstevel@tonic-gate fail(message, doperror)
1343*7c478bd9Sstevel@tonic-gate char *message;
1344*7c478bd9Sstevel@tonic-gate int doperror;
1345*7c478bd9Sstevel@tonic-gate {
1346*7c478bd9Sstevel@tonic-gate 	if (kd != NULL)
1347*7c478bd9Sstevel@tonic-gate 		(void) kvm_close(kd);
1348*7c478bd9Sstevel@tonic-gate 
1349*7c478bd9Sstevel@tonic-gate 	if (doperror) {
1350*7c478bd9Sstevel@tonic-gate 		fprintf(stderr, "%s: ", cmdname);
1351*7c478bd9Sstevel@tonic-gate 		perror(message);
1352*7c478bd9Sstevel@tonic-gate 	}
1353*7c478bd9Sstevel@tonic-gate 	fprintf(stderr, "%s: %s\n", cmdname, message);
1354*7c478bd9Sstevel@tonic-gate 	exit(2);
1355*7c478bd9Sstevel@tonic-gate }
1356*7c478bd9Sstevel@tonic-gate 
1357*7c478bd9Sstevel@tonic-gate void
1358*7c478bd9Sstevel@tonic-gate safe_kvm_read(kd, addr, buf, size, who)
1359*7c478bd9Sstevel@tonic-gate kvm_t *kd;
1360*7c478bd9Sstevel@tonic-gate unsigned long addr;
1361*7c478bd9Sstevel@tonic-gate char *buf;
1362*7c478bd9Sstevel@tonic-gate unsigned size;
1363*7c478bd9Sstevel@tonic-gate {
1364*7c478bd9Sstevel@tonic-gate 	int ret_code;
1365*7c478bd9Sstevel@tonic-gate 	char errmsg[100];
1366*7c478bd9Sstevel@tonic-gate 
1367*7c478bd9Sstevel@tonic-gate 	if (addr == 0) {
1368*7c478bd9Sstevel@tonic-gate 		sprintf(errmsg, "kvm_read of %s failed -- no address", who);
1369*7c478bd9Sstevel@tonic-gate 		fail(errmsg, 0);
1370*7c478bd9Sstevel@tonic-gate 	}
1371*7c478bd9Sstevel@tonic-gate 
1372*7c478bd9Sstevel@tonic-gate 	ret_code = kvm_read(kd, addr, buf, size);
1373*7c478bd9Sstevel@tonic-gate 	if (ret_code != size) {
1374*7c478bd9Sstevel@tonic-gate 		sprintf(errmsg, "kvm_read of %s failed with code %d",
1375*7c478bd9Sstevel@tonic-gate 			who, ret_code);
1376*7c478bd9Sstevel@tonic-gate 		fail(errmsg, 0);
1377*7c478bd9Sstevel@tonic-gate 	}
1378*7c478bd9Sstevel@tonic-gate }
1379*7c478bd9Sstevel@tonic-gate 
1380*7c478bd9Sstevel@tonic-gate /*
1381*7c478bd9Sstevel@tonic-gate  * code for debugging dumps
1382*7c478bd9Sstevel@tonic-gate  */
1383*7c478bd9Sstevel@tonic-gate 
1384*7c478bd9Sstevel@tonic-gate #include <sys/tuneable.h>
1385*7c478bd9Sstevel@tonic-gate #include <sys/var.h>
1386*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
1387*7c478bd9Sstevel@tonic-gate #include <sys/vnode.h>
1388*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
1389*7c478bd9Sstevel@tonic-gate #include <sys/buf.h>
1390*7c478bd9Sstevel@tonic-gate #include <sys/fs/rf_acct.h>
1391*7c478bd9Sstevel@tonic-gate 
1392*7c478bd9Sstevel@tonic-gate int	dump_iodev ();
1393*7c478bd9Sstevel@tonic-gate 
1394*7c478bd9Sstevel@tonic-gate dump_diskhd (dp)
1395*7c478bd9Sstevel@tonic-gate 	struct diskhd	*dp;
1396*7c478bd9Sstevel@tonic-gate {
1397*7c478bd9Sstevel@tonic-gate 
1398*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "dump_diskhd: dp 0x%x\n", (int)dp);
1399*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "flags\tb_forw\tb_back\tav_forw\tav_back\tb_bcount\n0x%x\t0x%x\t0x%x\t0x%x\t0x%x\t%d\n",
1400*7c478bd9Sstevel@tonic-gate 		(int)dp->b_flags, (int)dp->b_forw, (int)dp->b_back,
1401*7c478bd9Sstevel@tonic-gate 		(int)dp->av_forw, (int)dp->av_back, (int)dp->b_bcount);
1402*7c478bd9Sstevel@tonic-gate 
1403*7c478bd9Sstevel@tonic-gate return (0);
1404*7c478bd9Sstevel@tonic-gate }
1405*7c478bd9Sstevel@tonic-gate 
1406*7c478bd9Sstevel@tonic-gate dump_nlist (nlist, str)
1407*7c478bd9Sstevel@tonic-gate 	struct nlist    nlist[];
1408*7c478bd9Sstevel@tonic-gate 	char            *str;
1409*7c478bd9Sstevel@tonic-gate {
1410*7c478bd9Sstevel@tonic-gate 	int             i;
1411*7c478bd9Sstevel@tonic-gate 
1412*7c478bd9Sstevel@tonic-gate 	for (i = 0; nlist[i].n_name; i++) {
1413*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "%s: i %d n_name '%s' n_value 0x%x\n",
1414*7c478bd9Sstevel@tonic-gate 			str, i, nlist[i].n_name, (int)nlist[i].n_value);
1415*7c478bd9Sstevel@tonic-gate 	}
1416*7c478bd9Sstevel@tonic-gate 
1417*7c478bd9Sstevel@tonic-gate return (0);
1418*7c478bd9Sstevel@tonic-gate }
1419*7c478bd9Sstevel@tonic-gate 
1420*7c478bd9Sstevel@tonic-gate dump_v_struct (tbl)
1421*7c478bd9Sstevel@tonic-gate 	struct var *tbl;
1422*7c478bd9Sstevel@tonic-gate {
1423*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "dump_v_struct: tbl 0x%x\n", (int)tbl);
1424*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "v_buf\tv_call\tv_proc\tv_nglobpris\n%d\t%d\t%d\t%d\n",
1425*7c478bd9Sstevel@tonic-gate 		tbl->v_buf, tbl->v_call, tbl->v_proc, tbl->v_nglobpris);
1426*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "v_maxsyspri\tv_clist\tv_maxup\tv_hbuf\n%d\t\t%d\t%d\t%d\n",
1427*7c478bd9Sstevel@tonic-gate 		tbl->v_maxsyspri, tbl->v_clist, tbl->v_maxup, tbl->v_hbuf);
1428*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "v_hmask\tv_pbuf\tv_sptmap\tv_maxpmem\n0x%x\t%d\t%d\t\t%d\n",
1429*7c478bd9Sstevel@tonic-gate 		tbl->v_hmask, tbl->v_pbuf, tbl->v_sptmap, tbl->v_maxpmem);
1430*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "v_autoup\tv_bufhwm\n%d\t\t%d\n",
1431*7c478bd9Sstevel@tonic-gate 		tbl->v_autoup, tbl->v_bufhwm);
1432*7c478bd9Sstevel@tonic-gate 
1433*7c478bd9Sstevel@tonic-gate return (0);
1434*7c478bd9Sstevel@tonic-gate }
1435*7c478bd9Sstevel@tonic-gate 
1436*7c478bd9Sstevel@tonic-gate dump_tblmap (tbl, size)
1437*7c478bd9Sstevel@tonic-gate 	int	*tbl;
1438*7c478bd9Sstevel@tonic-gate 	int	size;
1439*7c478bd9Sstevel@tonic-gate {
1440*7c478bd9Sstevel@tonic-gate 	int	i;
1441*7c478bd9Sstevel@tonic-gate 
1442*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "tblmap size %d/4 = %d ", size, size/4);
1443*7c478bd9Sstevel@tonic-gate 	for (i = 0; i < size/4; i++) {
1444*7c478bd9Sstevel@tonic-gate 		dfprintf (stderr, "tblmap[%d] %d ", i, tbl[i]);
1445*7c478bd9Sstevel@tonic-gate 	}
1446*7c478bd9Sstevel@tonic-gate 	dfprintf (stderr, "\n");
1447*7c478bd9Sstevel@tonic-gate 
1448*7c478bd9Sstevel@tonic-gate return (0);
1449*7c478bd9Sstevel@tonic-gate }
1450