n2piupc_kstats.c revision ea1a228c80597366447774aa1988868492330eb5
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "n2piupc_acc.h"
#include "n2piupc_tables.h"
#include "n2piupc.h"
#include "n2piupc_biterr.h"
int num_kstats);
/*
* One-time initialization for this module.
*/
int
{
N2PIUPC_DBG2("n2piupc: kstat_init: enter\n");
/*
* Initialize the name kstats for each group, drawing upon the table
* for values.
*/
/* Create basic pic event-type pair. */
N2PIUPC_DBG1("n2piupc: init: failure exit\n");
return (DDI_FAILURE);
}
}
N2PIUPC_DBG2("n2piupc: kstat_init: success exit\n");
return (DDI_SUCCESS);
}
/*
* Per-instance initialization for this module.
*/
int
{
int i;
N2PIUPC_DBG2("n2piupc: kstat_attach %d: enter\n",
/* Initialize biterr module. Save opaque result. */
goto err;
/* Set up kstats for each group. */
/*
* ksinfo_p keeps all info needed by n2piupc_kstat_update,
* which is fired off asynchronously on demand by the kstat
* framework.
*/
sizeof (n2piu_ksinfo_t), KM_SLEEP);
/* Also save in state structure, for later cleanup. */
/* Create counter kstats */
goto err;
}
N2PIUPC_DBG2("n2piupc: kstat_attach: success exit\n");
return (DDI_SUCCESS);
err:
N2PIUPC_DBG2("n2piupc: kstat_attach: failure exit\n");
return (DDI_FAILURE);
}
/*
* Create the name kstats for each group.
*/
static int
{
int i;
for (i = 0; i < grp_p->num_counters; i++) {
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
/*
* Create the picN kstat. Returns a pointer to the
* kstat which the driver must store to allow it
* to be deleted when necessary.
*/
static kstat_t *
{
int event;
char pic_name[PIC_STR_LEN];
struct kstat_named *pic_named_data;
return (NULL);
}
/* NOTE: Number of events is assumed to always be non-zero. */
/*
* Fill up data section of the kstat
* Write event names and their associated pcr masks.
* num_ev - 1 is because CLEAR_PIC is added separately.
*/
}
/*
* add the clear_pic entry
*/
return (picN_ksp);
}
/*
* Create the "counters" kstat.
*/
static kstat_t *
{
int i;
char pic_str[PIC_STR_LEN];
struct kstat *counters_ksp;
struct kstat_named *counters_named_data;
N2PIUPC_DBG2("n2piupc_create_cntr_kstat: name: %s instance: %d\n",
/*
* Size of kstat is num_pics + 1. extra one for pcr.
*/
return (NULL);
}
for (i = 0; i < num_pics; i++) {
}
/*
* Store the reg type and other info. in the kstat's private field
* so that they are available to the update function.
*/
return (counters_ksp);
}
/* Higher-level register write, hides SW abstractions. */
static int
{
switch (regid) {
case SW_N2PIU_BITERR_SEL:
case SW_N2PIU_BITERR_CLR:
break;
default:
break;
}
return (rval);
}
/* Higher-level register read, hides SW abstractions. */
static int
{
/* This "register" is a layered SW-implemented reg. */
switch (regid) {
case SW_N2PIU_BITERR_SEL:
break;
default:
break;
}
rval);
return (rval);
}
/*
* Program a performance counter.
*
* reggroup is which type of counter.
* counter is the counter number.
* event is the event to program for that counter.
*/
static int
{
int counter;
&old_events)) != SUCCESS) {
"Read of old event data failed, select reg offset:%ld\n",
goto done_pgm;
}
continue;
"grp:%s, counter:%d, zero_regoff:0x%lx, "
"new&mask:0x%lx\n",
new_events & event_mask);
if ((old_events & event_mask) ==
(new_events & event_mask))
continue;
goto done_pgm;
}
if (old_events != new_events) {
N2PIUPC_DBG1("old != new, setting event reg %ld to 0x%lx\n",
new_events)) != SUCCESS) {
"Write of new event data failed, "
"select reg offset: %ld\n",
goto done_pgm;
}
}
return (rval);
}
/*
*/
static int
{
struct kstat_named *data_p;
int counter;
if (rw == KSTAT_WRITE) {
N2PIUPC_DBG2("n2piupc_kstat_update: wr %ld\n",
/*
* Fields without programmable events won't be zeroed as
* n2piupc_perfcnt_program is what zeros them.
*/
/* This group has programmable events. */
N2PIUPC_DBG2("write: regoff has valid register\n");
return (EIO);
}
} else { /* Read the event register and all of the counters. */
/* This group has programmable events. */
N2PIUPC_DBG2("read: regoff has valid register\n");
return (EIO);
} else
N2PIUPC_DBG2("n2piupc_kstat_update: rd event %ld",
if (n2piupc_read(n2piupc_p,
return (EIO);
}
}
return (SUCCESS);
}
void
{
int j;
N2PIUPC_DBG2("n2piupc_kstat_fini called\n");
}
}
}
static void
{
int i;
if (name_kstats_pp != NULL) {
for (i = 0; i < num_kstats; i++) {
if (name_kstats_pp[i] != NULL)
}
}
}
void
{
int i;
N2PIUPC_DBG2("n2piupc_kstat_detach called\n");
sizeof (n2piu_ksinfo_t));
}
}
}