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