1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License").  You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22/*
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
25 */
26
27#ifndef	_BUSSTAT_H
28#define	_BUSSTAT_H
29
30
31#pragma ident	"%Z%%M%	%I%	%E% SMI"
32
33/*
34 * busstat works by reading and writing from/to kstat's which are
35 * exported by drivers on the system.
36 *
37 * busstat parses the command line it is given and builds up a
38 * pair of linked list's to represent the various options specified.
39 * An example command line is given below..
40 *
41 * -w ac2,pic0=wio_pkts,pic1=rbio_pkts -w ac2,pic0=rto_pkts,pic1=rto_pkts -r ac5
42 * =============================================================================
43 *
44 * ______
45 * |    |
46 * | ac2|->wio_pkts->rto_pkts
47 * |pic0|    |            |
48 * |    |    -------<------
49 * ------
50 *    |
51 *    |
52 * ______
53 * |    |
54 * | ac2|->rbio_pkts->rto_pkts
55 * |pic1|     |            |
56 * |    |     --------<-----
57 * ------
58 *    |
59 *    |
60 * ______
61 * |    |
62 * | ac5|->evt
63 * |pic0|
64 * |    |
65 * ------
66 *   |
67 *   |
68 * ______
69 * |    |
70 * | ac5|->evt
71 * |pic1|
72 * |    |
73 * ------
74 *
75 * The above diagram shows the lists created after the initial parsing.
76 *
77 * Each device instance/pic is represented by a device node. Hanging off
78 * that is at least one event node.
79 *
80 * Event nodes come in two different types. Nodes that are the result of a -r
81 * operation will have the r_w field in their parent dev_node set to EVT_READ,
82 * and most of their other fields set to zero or NULL. An event node that was
83 * created because of a -w operation (r_w = EVT_WRITE) will have all it's fields
84 * filled in. When a device node is created, an  event node is automatically
85 * created and marked as EVT_READ. If the device node was created as the result
86 * of a -r operation, nothing more happens. But if it was a -w operation, then
87 * the event node is modified (r_w changed to EVT_WRITE, event pcr mask and
88 * event name written if known).
89 *
90 * Setting events : work along the list of dev_nodes, for each device node check
91 * the event node pointed to by evt_node, if it is marked as EVT_WRITE in the
92 * corresponding r_w array, if so set the event stored in the node.
93 *
94 * Reading events : work along the list of dev_nodes, for each device node check
95 * the event node pointed to by evt_node, if it is marked EVT_WRITE, just read
96 * the event count from the appropiate PIC and store it in the node. If the node
97 * is EVT_READ however, read the PCR, determine the event name, store it in the
98 * node along with the event count.
99 *
100 * Multiplexing is handled by cycling through the event nodes. The event nodes
101 * are on a circular list, which allows each pic to be multiplexing between
102 * different numbers of events.
103 */
104
105#define	TRUE	1
106#define	FALSE	0
107#define	FAIL	-1
108
109#define	READ_EVT	1
110#define	WRITE_EVT	0
111
112#define	EVT_READ	0x1
113#define	EVT_WRITE	0x2
114#define	ONE_INST_CALL	0x4
115#define	ALL_INST_CALL	0x8
116
117#define	STATE_INIT	0x10	/* Initial state of node when created */
118#define	STATE_INST	0x20	/* Node was created by specific instance call */
119#define	STATE_ALL	0x40	/* Node was created by call for all instances */
120
121#define	NANO		1000000000	/* To convert from nanosecs to secs */
122
123#define	PIC_STR_LEN	3
124
125#define	EVT_STR		-1
126
127typedef struct evt_node {
128	char		evt_name[KSTAT_STRLEN];	/* The event name */
129	uint64_t	prev_count;	/* The previous count for this evt */
130	uint64_t	total;		/* Total count for this event */
131	uint64_t	evt_pcr_mask;	/* PCR mask for this event */
132	struct evt_node *next;
133} evt_node_t;
134
135typedef struct dev_node {
136	char		name[KSTAT_STRLEN];	/* Device name e.g. ac */
137	int		dev_inst;	/* Device instance number */
138	int		pic_num;	/* PIC number. */
139	kstat_t		*cnt_ksp;	/* "counters" kstat pointer */
140	kstat_t		*pic_ksp;	/* pointer to picN kstat */
141	int		r_w;		/* r_w flag */
142	int		state;		/* state flag */
143	struct evt_node	*evt_node;	/* ptr to current evt_node */
144	struct dev_node	*next;
145} dev_node_t;
146
147#endif	/* _BUSSTAT_H */
148