1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/byteorder.h> 30 #include <sys/systm.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 34 int pcs_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 35 int pcs_attach(dev_info_t *, ddi_attach_cmd_t); 36 int pcs_detach(dev_info_t *, ddi_detach_cmd_t); 37 dev_info_t *pcs_dip; 38 39 static struct dev_ops pcs_devops = { 40 DEVO_REV, 41 0, 42 pcs_getinfo, 43 nulldev, 44 nulldev, 45 pcs_attach, 46 pcs_detach, 47 nulldev, 48 NULL, 49 NULL 50 }; 51 /* 52 * This is the loadable module wrapper. 53 */ 54 #include <sys/modctl.h> 55 56 extern struct mod_ops mod_driverops; 57 58 static struct modldrv modldrv = { 59 &mod_driverops, /* Type of module. This one is a driver */ 60 "PCMCIA Socket Driver %I%", /* Name of the module. */ 61 &pcs_devops, /* driver ops */ 62 }; 63 64 static struct modlinkage modlinkage = { 65 MODREV_1, (void *)&modldrv, NULL 66 }; 67 68 struct pcs_inst { 69 dev_info_t *dip; 70 } *pcs_instances; 71 72 int 73 _init() 74 { 75 int ret; 76 if ((ret = ddi_soft_state_init((void **)&pcs_instances, 77 sizeof (struct pcs_inst), 1)) != 0) 78 return (ret); 79 if ((ret = mod_install(&modlinkage)) != 0) { 80 ddi_soft_state_fini((void **)&pcs_instances); 81 } 82 return (ret); 83 } 84 85 int 86 _fini() 87 { 88 int ret; 89 ret = mod_remove(&modlinkage); 90 if (ret == 0) { 91 ddi_soft_state_fini((void **)&pcs_instances); 92 } 93 return (ret); 94 } 95 96 int 97 _info(struct modinfo *modinfop) 98 { 99 return (mod_info(&modlinkage, modinfop)); 100 } 101 102 int 103 pcs_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 104 { 105 int error = DDI_SUCCESS; 106 int inum; 107 struct pcs_inst *inst; 108 #ifdef lint 109 dip = dip; 110 #endif 111 112 switch (cmd) { 113 case DDI_INFO_DEVT2DEVINFO: 114 inum = getminor((dev_t)arg); 115 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 116 inum); 117 if (inst == NULL) 118 error = DDI_FAILURE; 119 else 120 *result = inst->dip; 121 break; 122 case DDI_INFO_DEVT2INSTANCE: 123 inum = getminor((dev_t)arg); 124 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 125 inum); 126 if (inst == NULL) 127 error = DDI_FAILURE; 128 else 129 *result = (void *)(uintptr_t)inum; 130 break; 131 default: 132 error = DDI_FAILURE; 133 } 134 return (error); 135 } 136 137 int 138 pcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 139 { 140 int ret = DDI_SUCCESS; 141 int inum; 142 struct pcs_inst *inst; 143 144 switch (cmd) { 145 case DDI_RESUME: 146 return (DDI_SUCCESS); 147 case DDI_ATTACH: 148 break; 149 default: 150 return (DDI_FAILURE); 151 } 152 153 inum = ddi_get_instance(dip); 154 155 if (ddi_soft_state_zalloc(pcs_instances, inum) == DDI_SUCCESS) { 156 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 157 inum); 158 if (inst == NULL) 159 ret = DDI_FAILURE; 160 else 161 inst->dip = dip; 162 } 163 164 return (ret); 165 } 166 167 int 168 pcs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 169 { 170 switch (cmd) { 171 case DDI_DETACH: 172 ddi_soft_state_free(pcs_instances, ddi_get_instance(dip)); 173 return (DDI_SUCCESS); 174 175 case DDI_SUSPEND: 176 case DDI_PM_SUSPEND: 177 return (DDI_SUCCESS); 178 default: 179 break; 180 } 181 return (DDI_FAILURE); 182 } 183