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 27 #include <sys/types.h> 28 #include <sys/byteorder.h> 29 #include <sys/systm.h> 30 #include <sys/ddi.h> 31 #include <sys/sunddi.h> 32 33 int pcs_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 34 int pcs_attach(dev_info_t *, ddi_attach_cmd_t); 35 int pcs_detach(dev_info_t *, ddi_detach_cmd_t); 36 dev_info_t *pcs_dip; 37 38 static struct dev_ops pcs_devops = { 39 DEVO_REV, 40 0, 41 pcs_getinfo, 42 nulldev, 43 nulldev, 44 pcs_attach, 45 pcs_detach, 46 nulldev, 47 NULL, 48 NULL, 49 NULL, 50 ddi_quiesce_not_needed, /* quiesce */ 51 }; 52 /* 53 * This is the loadable module wrapper. 54 */ 55 #include <sys/modctl.h> 56 57 extern struct mod_ops mod_driverops; 58 59 static struct modldrv modldrv = { 60 &mod_driverops, /* Type of module. This one is a driver */ 61 "PCMCIA Socket Driver", /* Name of the module. */ 62 &pcs_devops, /* driver ops */ 63 }; 64 65 static struct modlinkage modlinkage = { 66 MODREV_1, { (void *)&modldrv, NULL } 67 }; 68 69 struct pcs_inst { 70 dev_info_t *dip; 71 } *pcs_instances; 72 73 int 74 _init() 75 { 76 int ret; 77 if ((ret = ddi_soft_state_init((void **)&pcs_instances, 78 sizeof (struct pcs_inst), 1)) != 0) 79 return (ret); 80 if ((ret = mod_install(&modlinkage)) != 0) { 81 ddi_soft_state_fini((void **)&pcs_instances); 82 } 83 return (ret); 84 } 85 86 int 87 _fini() 88 { 89 int ret; 90 ret = mod_remove(&modlinkage); 91 if (ret == 0) { 92 ddi_soft_state_fini((void **)&pcs_instances); 93 } 94 return (ret); 95 } 96 97 int 98 _info(struct modinfo *modinfop) 99 { 100 return (mod_info(&modlinkage, modinfop)); 101 } 102 103 int 104 pcs_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 105 { 106 int error = DDI_SUCCESS; 107 int inum; 108 struct pcs_inst *inst; 109 #ifdef lint 110 dip = dip; 111 #endif 112 113 switch (cmd) { 114 case DDI_INFO_DEVT2DEVINFO: 115 inum = getminor((dev_t)arg); 116 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 117 inum); 118 if (inst == NULL) 119 error = DDI_FAILURE; 120 else 121 *result = inst->dip; 122 break; 123 case DDI_INFO_DEVT2INSTANCE: 124 inum = getminor((dev_t)arg); 125 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 126 inum); 127 if (inst == NULL) 128 error = DDI_FAILURE; 129 else 130 *result = (void *)(uintptr_t)inum; 131 break; 132 default: 133 error = DDI_FAILURE; 134 } 135 return (error); 136 } 137 138 int 139 pcs_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 140 { 141 int ret = DDI_SUCCESS; 142 int inum; 143 struct pcs_inst *inst; 144 145 switch (cmd) { 146 case DDI_RESUME: 147 return (DDI_SUCCESS); 148 case DDI_ATTACH: 149 break; 150 default: 151 return (DDI_FAILURE); 152 } 153 154 inum = ddi_get_instance(dip); 155 156 if (ddi_soft_state_zalloc(pcs_instances, inum) == DDI_SUCCESS) { 157 inst = (struct pcs_inst *)ddi_get_soft_state(pcs_instances, 158 inum); 159 if (inst == NULL) 160 ret = DDI_FAILURE; 161 else 162 inst->dip = dip; 163 } 164 165 return (ret); 166 } 167 168 int 169 pcs_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 170 { 171 switch (cmd) { 172 case DDI_DETACH: 173 ddi_soft_state_free(pcs_instances, ddi_get_instance(dip)); 174 return (DDI_SUCCESS); 175 176 case DDI_SUSPEND: 177 case DDI_PM_SUSPEND: 178 return (DDI_SUCCESS); 179 default: 180 break; 181 } 182 return (DDI_FAILURE); 183 }