xref: /onnv-gate/usr/src/uts/sun4/io/fpc/fpc.c (revision 1370:c1bce5cec2ac)
1*1370Sschwartz /*
2*1370Sschwartz  * CDDL HEADER START
3*1370Sschwartz  *
4*1370Sschwartz  * The contents of this file are subject to the terms of the
5*1370Sschwartz  * Common Development and Distribution License (the "License").
6*1370Sschwartz  * You may not use this file except in compliance with the License.
7*1370Sschwartz  *
8*1370Sschwartz  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1370Sschwartz  * or http://www.opensolaris.org/os/licensing.
10*1370Sschwartz  * See the License for the specific language governing permissions
11*1370Sschwartz  * and limitations under the License.
12*1370Sschwartz  *
13*1370Sschwartz  * When distributing Covered Code, include this CDDL HEADER in each
14*1370Sschwartz  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1370Sschwartz  * If applicable, add the following below this CDDL HEADER, with the
16*1370Sschwartz  * fields enclosed by brackets "[]" replaced with your own identifying
17*1370Sschwartz  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1370Sschwartz  *
19*1370Sschwartz  * CDDL HEADER END
20*1370Sschwartz  */
21*1370Sschwartz 
22*1370Sschwartz /*
23*1370Sschwartz  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*1370Sschwartz  * Use is subject to license terms.
25*1370Sschwartz  */
26*1370Sschwartz 
27*1370Sschwartz #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*1370Sschwartz 
29*1370Sschwartz #include <sys/types.h>
30*1370Sschwartz #include <sys/sunddi.h>
31*1370Sschwartz #include <sys/sunndi.h>
32*1370Sschwartz #include <sys/conf.h>
33*1370Sschwartz #include <sys/modctl.h>
34*1370Sschwartz #include <sys/stat.h>
35*1370Sschwartz #include <fpc.h>
36*1370Sschwartz 
37*1370Sschwartz static int fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
38*1370Sschwartz static int fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd);
39*1370Sschwartz 
40*1370Sschwartz static struct dev_ops fpc_ops = {
41*1370Sschwartz 	DEVO_REV,
42*1370Sschwartz 	0,
43*1370Sschwartz 	nulldev,
44*1370Sschwartz 	nulldev,
45*1370Sschwartz 	nulldev,
46*1370Sschwartz 	fpc_attach,
47*1370Sschwartz 	fpc_detach,
48*1370Sschwartz 	nodev,
49*1370Sschwartz 	NULL,
50*1370Sschwartz 	NULL,
51*1370Sschwartz 	nodev
52*1370Sschwartz };
53*1370Sschwartz 
54*1370Sschwartz extern struct mod_ops mod_driverops;
55*1370Sschwartz 
56*1370Sschwartz static struct modldrv md = {
57*1370Sschwartz 	&mod_driverops,
58*1370Sschwartz 	"IO Chip Perf Counter %I%",
59*1370Sschwartz 	&fpc_ops,
60*1370Sschwartz };
61*1370Sschwartz 
62*1370Sschwartz static struct modlinkage ml = {
63*1370Sschwartz 	MODREV_1,
64*1370Sschwartz 	(void *)&md,
65*1370Sschwartz 	NULL
66*1370Sschwartz };
67*1370Sschwartz 
68*1370Sschwartz int
69*1370Sschwartz _init(void)
70*1370Sschwartz {
71*1370Sschwartz 	return (mod_install(&ml));
72*1370Sschwartz }
73*1370Sschwartz 
74*1370Sschwartz int
75*1370Sschwartz _info(struct modinfo *modinfop)
76*1370Sschwartz {
77*1370Sschwartz 	return (mod_info(&ml, modinfop));
78*1370Sschwartz }
79*1370Sschwartz 
80*1370Sschwartz int
81*1370Sschwartz _fini(void)
82*1370Sschwartz {
83*1370Sschwartz 	return (mod_remove(&ml));
84*1370Sschwartz }
85*1370Sschwartz 
86*1370Sschwartz static int
87*1370Sschwartz fpc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
88*1370Sschwartz {
89*1370Sschwartz 	switch (cmd) {
90*1370Sschwartz 	/*
91*1370Sschwartz 	 * Since the driver saves no state between calls, we can fully detach
92*1370Sschwartz 	 * on suspend and fully attach on resume.
93*1370Sschwartz 	 *
94*1370Sschwartz 	 * An RFE might be to save event register states for restore.
95*1370Sschwartz 	 * The result of not doing this is that the kstat reader (busstat)
96*1370Sschwartz 	 * may quit upon resume, seeing that the events have changed out from
97*1370Sschwartz 	 * underneath it (since the registers were powered off upon suspend).
98*1370Sschwartz 	 */
99*1370Sschwartz 	case DDI_RESUME:
100*1370Sschwartz 	case DDI_ATTACH:
101*1370Sschwartz 		if (fpc_kstat_init(dip) != DDI_SUCCESS) {
102*1370Sschwartz 			(void) fpc_detach(dip, DDI_DETACH);
103*1370Sschwartz 			return (DDI_FAILURE);
104*1370Sschwartz 		}
105*1370Sschwartz 		return (DDI_SUCCESS);
106*1370Sschwartz 	default:
107*1370Sschwartz 		return (DDI_FAILURE);
108*1370Sschwartz 	}
109*1370Sschwartz }
110*1370Sschwartz 
111*1370Sschwartz static int
112*1370Sschwartz fpc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
113*1370Sschwartz {
114*1370Sschwartz 	switch (cmd) {
115*1370Sschwartz 	case DDI_SUSPEND:
116*1370Sschwartz 	case DDI_DETACH:
117*1370Sschwartz 		fpc_kstat_fini(dip);
118*1370Sschwartz 		return (DDI_SUCCESS);
119*1370Sschwartz 	default:
120*1370Sschwartz 		return (DDI_FAILURE);
121*1370Sschwartz 	}
122*1370Sschwartz }
123