1.\" $OpenBSD: evcount.9,v 1.3 2007/05/31 19:20:00 jmc Exp $ 2.\" Written by Jared Yanovich 3.\" This file belongs to the public domain, 11/02/2004. 4.Dd $Mdocdate: May 31 2007 $ 5.Dt EVCOUNT 9 6.Os 7.Sh NAME 8.Nm evcount , 9.Nm evcount_attach , 10.Nm evcount_detach 11.Nd generic interrupt and event counter kernel API 12.Sh SYNOPSIS 13.In sys/evcount.h 14.Ft void 15.Fn evcount_attach "struct evcount *ec" "const char *name" "void *data" \ 16 "struct evcount *parent" 17.Ft void 18.Fn evcount_detach "struct evcount *ec" 19.Sh DESCRIPTION 20The 21.Nm 22API provides an interface for generic event and interrupt counting, 23whose statistics are made available to machine-independent 24.Xr sysctl 3 25nodes. 26.Ss Overview 27With 28.Nm , 29an architecture can collect interrupt counting for any device and 30organize the counting hierarchy however it wants. 31All registered counters will be made available under the 32.Va kern.evcount 33.Xr sysctl 3 34node as a flat list. 35The following is a sample hierarchy for counters provided by some 36common architectures: 37.Pp 38.Bl -tag -width 8n -offset indent -compact 39.It clock 40Interrupt counter for the system clock 41.It stat 42Second-level interrupt decrementer counter 43.It rtc 44Real-time clock counter 45.It prof 46System profiler counter 47.It pciide0 48PCI IDE controller counter (see 49.Xr pciide 4 ) 50.It uhci0 51USB 1.0 controller counter (see 52.Xr usb 4 ) 53.El 54.Pp 55Event counters may be organized hierarchically, so a parent 56.Nm 57node that represents a bus may contain child nodes that represent 58devices attached to that bus. 59.Pp 60See 61.Xr intro 4 62for a list of devices for any of which 63.Nm 64may track interrupt counting. 65.Pp 66The 67.Xr systat 1 68and 69.Xr vmstat 8 70utilities can be used to view interrupts collected by 71.Nm . 72.Ss The API 73The 74.Vt evcount 75structure has the following definition: 76.Bd -literal -offset indent 77struct evcount { 78 u_int64_t ec_count; /* main counter */ 79 int ec_id; /* counter ID */ 80 const char *ec_name; /* counter name */ 81 struct evcount *ec_parent; /* parent */ 82 void *ec_data; /* user data */ 83 84 TAILQ_ENTRY(evcount) next; 85}; 86.Ed 87.Pp 88The 89.Fn evcount_attach ec name data parent 90function inserts the given event counter 91.Fa ec 92into the given 93.Fa parent Ns 's 94list of counters. 95.Fa name 96provides the counter name, which is modeled after a 97device, such as 98.Dq clock 99or 100.Dq pciide0 . 101.Fa data 102provides a chunk of data that will be made available through the 103.Xr sysctl 3 104call. 105.Pp 106The 107.Fn evcount_detach ec 108function removes the given event counter 109.Fa ec 110from its parent. 111.Sh EXAMPLES 112The following is an outline of code that provides routines to register 113and de-register interrupt handlers for devices, plugging the counting of 114interrupts generated by them during system operation into the 115.Nm 116framework. 117.Bd -literal 118#include <sys/evcount.h> 119#include <machine/intr.h> 120 121/* 122 * machine/intr.h provides a structure, intrhand, which is 123 * machine-dependent but is usually similar to this: 124 * 125 * struct intrhand { 126 * int (*ih_fun)(void *); 127 * void *ih_arg; 128 * int ih_level; 129 * struct intrhand *ih_next; 130 * int ih_irq; 131 * struct evcount ih_count; 132 * } 133 */ 134 135/* 136 * Register an interrupt handler. 137 */ 138void * 139intr_establish(void *lcv, int irq, int type, int level, 140 int (*ih_fun)(void *), void *ih_arg, char *name) 141{ 142 struct intrhand *ih, **p; 143 144 /* 145 * Allocate memory for the handler, sanity-check incoming 146 * values (IRQ#, etc.), and link the handler into 147 * machine-dependent data structures. 148 */ 149 150 /* 151 * Fill out the handler. 152 */ 153 ih->ih_fun = ih_fun; 154 ih->ih_arg = ih_arg; 155 ih->ih_next = NULL; 156 ih->ih_level = level; 157 ih->ih_irq = irq; 158 159 /* 160 * Attach it under the root event counter, evcount_intr. 161 */ 162 evcount_attach(&ih->ih_count, name, (void *)&ih->ih_irq, 163 &evcount_intr); 164 165 return (ih); 166} 167 168/* 169 * Deregister an interrupt handler. 170 */ 171void 172intr_disestablish(void *lcp, void *arg) 173{ 174 struct intrhand *ih = arg; 175 176 /* 177 * Sanity-check incoming values (IRQ, etc.) and remove 178 * the interrupt handler from machine-dependent data 179 * structures. 180 */ 181 182 evcount_detach(&ih->ih_count); 183 184 /* 185 * Free up memory and install a null interrupt handler. 186 */ 187} 188.Ed 189.Pp 190An interrupt handler for a device will be registered during 191.Xr autoconf 9 192with a call to the above 193.Fn intr_establish . 194.Pp 195The main external interrupt handler, which handles all system 196interrupts, will select the appropriate handler for the device 197that created the interrupt when an interrupt is generated. 198In this case, the handler is the routine assigned to 199.Va ih_fun , 200and 201.Nm 202will be made aware of interrupt occurrence. 203.Sh SEE ALSO 204.Xr systat 1 , 205.Xr queue 3 , 206.Xr sysctl 3 , 207.Xr intro 4 , 208.Xr vmstat 8 , 209.Xr autoconf 9 210.Sh AUTHORS 211The 212.Nm 213API was written by Artur Grabowski and Aaron Campbell for 214.Ox 3.6 . 215