pcs.c revision 7656:2621e50fdf4a
1178479Sjb/* 2178479Sjb * CDDL HEADER START 3178479Sjb * 4178479Sjb * The contents of this file are subject to the terms of the 5178479Sjb * Common Development and Distribution License (the "License"). 6178479Sjb * You may not use this file except in compliance with the License. 7178479Sjb * 8178479Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9178479Sjb * or http://www.opensolaris.org/os/licensing. 10178479Sjb * See the License for the specific language governing permissions 11178479Sjb * and limitations under the License. 12178479Sjb * 13178479Sjb * When distributing Covered Code, include this CDDL HEADER in each 14178479Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15178479Sjb * If applicable, add the following below this CDDL HEADER, with the 16178479Sjb * fields enclosed by brackets "[]" replaced with your own identifying 17178479Sjb * information: Portions Copyright [yyyy] [name of copyright owner] 18178479Sjb * 19178479Sjb * CDDL HEADER END 20178479Sjb */ 21178479Sjb/* 22178479Sjb * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23178573Sjb * Use is subject to license terms. 24178479Sjb */ 25178479Sjb 26178479Sjb 27178479Sjb#include <sys/types.h> 28178479Sjb#include <sys/byteorder.h> 29178479Sjb#include <sys/systm.h> 30178479Sjb#include <sys/ddi.h> 31178479Sjb#include <sys/sunddi.h> 32178479Sjb 33178573Sjbint pcs_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 34178479Sjbint pcs_attach(dev_info_t *, ddi_attach_cmd_t); 35178573Sjbint pcs_detach(dev_info_t *, ddi_detach_cmd_t); 36178573Sjbdev_info_t *pcs_dip; 37178573Sjb 38178479Sjbstatic struct dev_ops pcs_devops = { 39178479Sjb DEVO_REV, 40178479Sjb 0, 41178573Sjb pcs_getinfo, 42178479Sjb nulldev, 43178573Sjb nulldev, 44178479Sjb pcs_attach, 45178479Sjb pcs_detach, 46178479Sjb nulldev, 47178479Sjb NULL, 48178479Sjb NULL, 49178479Sjb NULL, 50178573Sjb ddi_quiesce_not_needed, /* quiesce */ 51178479Sjb}; 52178573Sjb/* 53178573Sjb * This is the loadable module wrapper. 54211554Srpaulo */ 55211554Srpaulo#include <sys/modctl.h> 56211554Srpaulo 57178573Sjbextern struct mod_ops mod_driverops; 58178479Sjb 59178479Sjbstatic struct modldrv modldrv = { 60178479Sjb &mod_driverops, /* Type of module. This one is a driver */ 61178479Sjb "PCMCIA Socket Driver", /* Name of the module. */ 62178479Sjb &pcs_devops, /* driver ops */ 63178479Sjb}; 64178479Sjb 65178479Sjbstatic struct modlinkage modlinkage = { 66178479Sjb MODREV_1, (void *)&modldrv, NULL 67178479Sjb}; 68178479Sjb 69178479Sjbstruct pcs_inst { 70178479Sjb dev_info_t *dip; 71178479Sjb} *pcs_instances; 72178479Sjb 73178479Sjbint 74178479Sjb_init() 75178479Sjb{ 76178479Sjb int ret; 77178479Sjb if ((ret = ddi_soft_state_init((void **)&pcs_instances, 78178479Sjb sizeof (struct pcs_inst), 1)) != 0) 79178479Sjb return (ret); 80178479Sjb if ((ret = mod_install(&modlinkage)) != 0) { 81178479Sjb ddi_soft_state_fini((void **)&pcs_instances); 82178479Sjb } 83178479Sjb return (ret); 84178479Sjb} 85178479Sjb 86178479Sjbint 87178479Sjb_fini() 88178479Sjb{ 89178479Sjb int ret; 90178479Sjb ret = mod_remove(&modlinkage); 91178479Sjb if (ret == 0) { 92178479Sjb ddi_soft_state_fini((void **)&pcs_instances); 93178479Sjb } 94178479Sjb return (ret); 95178479Sjb} 96178479Sjb 97178479Sjbint 98178479Sjb_info(struct modinfo *modinfop) 99178479Sjb{ 100178479Sjb return (mod_info(&modlinkage, modinfop)); 101178479Sjb} 102178479Sjb 103178479Sjbint 104178479Sjbpcs_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 105178479Sjb{ 106178479Sjb int error = DDI_SUCCESS; 107178479Sjb int inum; 108178479Sjb struct pcs_inst *inst; 109178479Sjb#ifdef lint 110178479Sjb dip = dip; 111178479Sjb#endif 112178479Sjb 113178479Sjb switch (cmd) { 114178479Sjb case DDI_INFO_DEVT2DEVINFO: 115178479Sjb inum = getminor((dev_t)arg); 116178479Sjb inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 117178479Sjb inum); 118178479Sjb if (inst == NULL) 119178479Sjb error = DDI_FAILURE; 120178479Sjb else 121178479Sjb *result = inst->dip; 122178479Sjb break; 123178479Sjb case DDI_INFO_DEVT2INSTANCE: 124178479Sjb inum = getminor((dev_t)arg); 125178479Sjb inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 126178479Sjb inum); 127178479Sjb if (inst == NULL) 128178479Sjb error = DDI_FAILURE; 129178479Sjb else 130178479Sjb *result = (void *)(uintptr_t)inum; 131178479Sjb break; 132178479Sjb default: 133178479Sjb error = DDI_FAILURE; 134178479Sjb } 135178479Sjb return (error); 136178479Sjb} 137178479Sjb 138178479Sjbint 139178479Sjbpcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 140178479Sjb{ 141178479Sjb int ret = DDI_SUCCESS; 142178479Sjb int inum; 143178479Sjb struct pcs_inst *inst; 144178479Sjb 145178479Sjb switch (cmd) { 146178479Sjb case DDI_RESUME: 147178479Sjb return (DDI_SUCCESS); 148178479Sjb case DDI_ATTACH: 149178479Sjb break; 150178479Sjb default: 151178479Sjb return (DDI_FAILURE); 152178479Sjb } 153178479Sjb 154178479Sjb inum = ddi_get_instance(dip); 155178479Sjb 156178479Sjb if (ddi_soft_state_zalloc(pcs_instances, inum) == DDI_SUCCESS) { 157178479Sjb inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 158178479Sjb inum); 159178479Sjb if (inst == NULL) 160178479Sjb ret = DDI_FAILURE; 161178479Sjb else 162178479Sjb inst->dip = dip; 163178479Sjb } 164178479Sjb 165178479Sjb return (ret); 166178479Sjb} 167178479Sjb 168178479Sjbint 169178479Sjbpcs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 170178479Sjb{ 171178479Sjb switch (cmd) { 172178479Sjb case DDI_DETACH: 173178479Sjb ddi_soft_state_free(pcs_instances, ddi_get_instance(dip)); 174178479Sjb return (DDI_SUCCESS); 175178479Sjb 176178479Sjb case DDI_SUSPEND: 177178479Sjb case DDI_PM_SUSPEND: 178178479Sjb return (DDI_SUCCESS); 179178479Sjb default: 180178479Sjb break; 181178479Sjb } 182178479Sjb return (DDI_FAILURE); 183178479Sjb} 184178479Sjb