/* * 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 */