summaryrefslogtreecommitdiff
path: root/usr/src/cmd/busstat/busstat.h
blob: 48c0ecbac85b3d28f4f3db2593858627059394f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright (c) 1999 by Sun Microsystems, Inc.
 * All rights reserved.
 */

#ifndef	_BUSSTAT_H
#define	_BUSSTAT_H


#pragma ident	"%Z%%M%	%I%	%E% SMI"

/*
 * busstat works by reading and writing from/to kstat's which are
 * exported by drivers on the system.
 *
 * busstat parses the command line it is given and builds up a
 * pair of linked list's to represent the various options specified.
 * An example command line is given below..
 *
 * -w ac2,pic0=wio_pkts,pic1=rbio_pkts -w ac2,pic0=rto_pkts,pic1=rto_pkts -r ac5
 * =============================================================================
 *
 * ______
 * |    |
 * | ac2|->wio_pkts->rto_pkts
 * |pic0|    |            |
 * |    |    -------<------
 * ------
 *    |
 *    |
 * ______
 * |    |
 * | ac2|->rbio_pkts->rto_pkts
 * |pic1|     |            |
 * |    |     --------<-----
 * ------
 *    |
 *    |
 * ______
 * |    |
 * | ac5|->evt
 * |pic0|
 * |    |
 * ------
 *   |
 *   |
 * ______
 * |    |
 * | ac5|->evt
 * |pic1|
 * |    |
 * ------
 *
 * The above diagram shows the lists created after the initial parsing.
 *
 * Each device instance/pic is represented by a device node. Hanging off
 * that is at least one event node.
 *
 * Event nodes come in two different types. Nodes that are the result of a -r
 * operation will have the r_w field in their parent dev_node set to EVT_READ,
 * and most of their other fields set to zero or NULL. An event node that was
 * created because of a -w operation (r_w = EVT_WRITE) will have all it's fields
 * filled in. When a device node is created, an  event node is automatically
 * created and marked as EVT_READ. If the device node was created as the result
 * of a -r operation, nothing more happens. But if it was a -w operation, then
 * the event node is modified (r_w changed to EVT_WRITE, event pcr mask and
 * event name written if known).
 *
 * Setting events : work along the list of dev_nodes, for each device node check
 * the event node pointed to by evt_node, if it is marked as EVT_WRITE in the
 * corresponding r_w array, if so set the event stored in the node.
 *
 * Reading events : work along the list of dev_nodes, for each device node check
 * the event node pointed to by evt_node, if it is marked EVT_WRITE, just read
 * the event count from the appropiate PIC and store it in the node. If the node
 * is EVT_READ however, read the PCR, determine the event name, store it in the
 * node along with the event count.
 *
 * Multiplexing is handled by cycling through the event nodes. The event nodes
 * are on a circular list, which allows each pic to be multiplexing between
 * different numbers of events.
 */

#define	TRUE	1
#define	FALSE	0
#define	FAIL	-1

#define	READ_EVT	1
#define	WRITE_EVT	0

#define	EVT_READ	0x1
#define	EVT_WRITE	0x2
#define	ONE_INST_CALL	0x4
#define	ALL_INST_CALL	0x8

#define	STATE_INIT	0x10	/* Initial state of node when created */
#define	STATE_INST	0x20	/* Node was created by specific instance call */
#define	STATE_ALL	0x40	/* Node was created by call for all instances */

#define	NANO		1000000000	/* To convert from nanosecs to secs */

#define	PIC_STR_LEN	3

#define	EVT_STR		-1

typedef struct evt_node {
	char		evt_name[KSTAT_STRLEN];	/* The event name */
	uint64_t	prev_count;	/* The previous count for this evt */
	uint64_t	total;		/* Total count for this event */
	uint64_t	evt_pcr_mask;	/* PCR mask for this event */
	struct evt_node *next;
} evt_node_t;

typedef struct dev_node {
	char		name[KSTAT_STRLEN];	/* Device name e.g. ac */
	int		dev_inst;	/* Device instance number */
	int		pic_num;	/* PIC number. */
	kstat_t		*cnt_ksp;	/* "counters" kstat pointer */
	kstat_t		*pic_ksp;	/* pointer to picN kstat */
	int		r_w;		/* r_w flag */
	int		state;		/* state flag */
	struct evt_node	*evt_node;	/* ptr to current evt_node */
	struct dev_node	*next;
} dev_node_t;

#endif	/* _BUSSTAT_H */