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