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.
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.
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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
28 * generic mpxio leaf driver
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/errno.h>
35 #include <sys/modctl.h>
39 #include <sys/cmn_err.h>
42 #include <sys/sunddi.h>
43 #include <sys/sunndi.h>
46 static int tcli_open(dev_t
*, int, int, cred_t
*);
47 static int tcli_close(dev_t
, int, int, cred_t
*);
48 static int tcli_read(dev_t
, struct uio
*, cred_t
*);
49 static int tcli_write(dev_t
, struct uio
*, cred_t
*);
50 static int tcli_ioctl(dev_t
, int, intptr_t, int, cred_t
*, int *);
51 static int tcli_attach(dev_info_t
*, ddi_attach_cmd_t
);
52 static int tcli_detach(dev_info_t
*, ddi_detach_cmd_t
);
54 static int tcli_info(dev_info_t
*, ddi_info_cmd_t
, void *, void **);
63 #define INST_TO_MINOR(i) (i)
64 #define MINOR_TO_INST(mn) (mn)
66 static struct cb_ops tcli_cb_ops
= {
68 tcli_close
, /* close */
73 tcli_write
, /* write */
74 tcli_ioctl
, /* ioctl */
79 ddi_prop_op
, /* prop_op */
81 D_NEW
| D_MP
| D_HOTPLUG
, /* flag */
88 static struct dev_ops tcli_ops
= {
89 DEVO_REV
, /* devo_rev */
91 tcli_info
, /* getinfo */
92 nulldev
, /* identify */
94 tcli_attach
, /* attach */
95 tcli_detach
, /* detach */
97 &tcli_cb_ops
, /* driver ops */
100 ddi_quiesce_not_needed
, /* quiesce */
103 static struct modldrv modldrv
= {
105 "vhci client test driver",
109 static struct modlinkage modlinkage
= {
110 MODREV_1
, &modldrv
, NULL
118 if ((e
= ddi_soft_state_init(&dstates
,
119 sizeof (struct dstate
), 0)) != 0) {
123 if ((e
= mod_install(&modlinkage
)) != 0) {
124 ddi_soft_state_fini(&dstates
);
135 if ((e
= mod_remove(&modlinkage
)) != 0) {
138 ddi_soft_state_fini(&dstates
);
143 _info(struct modinfo
*modinfop
)
145 return (mod_info(&modlinkage
, modinfop
));
150 tcli_attach(dev_info_t
*devi
, ddi_attach_cmd_t cmd
)
152 int instance
= ddi_get_instance(devi
);
153 struct dstate
*dstatep
;
156 if (cmd
!= DDI_ATTACH
)
157 return (DDI_SUCCESS
);
159 if (ddi_soft_state_zalloc(dstates
, instance
) != DDI_SUCCESS
) {
160 cmn_err(CE_CONT
, "%s%d: can't allocate state\n",
161 ddi_get_name(devi
), instance
);
162 return (DDI_FAILURE
);
165 dstatep
= ddi_get_soft_state(dstates
, instance
);
168 rval
= ddi_create_minor_node(devi
, "client", S_IFCHR
,
169 (INST_TO_MINOR(instance
)), DDI_PSEUDO
, 0);
170 if (rval
== DDI_FAILURE
) {
171 ddi_remove_minor_node(devi
, NULL
);
172 ddi_soft_state_free(dstates
, instance
);
173 cmn_err(CE_WARN
, "%s%d: can't create minor nodes",
174 ddi_get_name(devi
), instance
);
175 return (DDI_FAILURE
);
178 ddi_report_dev(devi
);
179 return (DDI_SUCCESS
);
184 tcli_detach(dev_info_t
*devi
, ddi_detach_cmd_t cmd
)
188 if (cmd
!= DDI_DETACH
)
189 return (DDI_SUCCESS
);
191 ddi_remove_minor_node(devi
, NULL
);
192 instance
= ddi_get_instance(devi
);
193 ddi_soft_state_free(dstates
, instance
);
194 return (DDI_SUCCESS
);
199 tcli_info(dev_info_t
*dip
, ddi_info_cmd_t infocmd
, void *arg
, void **result
)
204 if (infocmd
!= DDI_INFO_DEVT2INSTANCE
)
205 return (DDI_FAILURE
);
208 instance
= MINOR_TO_INST(getminor(dev
));
209 *result
= (void *)(uintptr_t)instance
;
210 return (DDI_SUCCESS
);
216 tcli_open(dev_t
*devp
, int flag
, int otyp
, cred_t
*cred
)
219 struct dstate
*dstatep
;
221 if (otyp
!= OTYP_BLK
&& otyp
!= OTYP_CHR
)
224 minor
= getminor(*devp
);
225 if ((dstatep
= ddi_get_soft_state(dstates
,
226 MINOR_TO_INST(minor
))) == NULL
)
236 tcli_close(dev_t dev
, int flag
, int otyp
, cred_t
*cred
)
238 struct dstate
*dstatep
;
239 minor_t minor
= getminor(dev
);
241 if (otyp
!= OTYP_BLK
&& otyp
!= OTYP_CHR
)
244 dstatep
= ddi_get_soft_state(dstates
, MINOR_TO_INST(minor
));
256 tcli_ioctl(dev_t dev
, int cmd
, intptr_t arg
, int mode
, cred_t
*credp
,
259 struct dstate
*dstatep
;
262 instance
= MINOR_TO_INST(getminor(dev
));
263 dstatep
= ddi_get_soft_state(dstates
, instance
);
273 tcli_read(dev_t dev
, struct uio
*uiop
, cred_t
*credp
)
280 tcli_write(dev_t dev
, struct uio
*uiop
, cred_t
*credp
)