Home | History | Annotate | Download | only in busstat
      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 
    127 typedef 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 
    135 typedef 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