root/usr/src/cmd/busstat/busstat.h
/*
 * 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

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