xref: /onnv-gate/usr/src/uts/common/io/bl.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Blacklist special file
31*0Sstevel@tonic-gate  */
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #include <sys/types.h>
34*0Sstevel@tonic-gate #include <sys/conf.h>
35*0Sstevel@tonic-gate #include <sys/stat.h>
36*0Sstevel@tonic-gate #include <sys/modctl.h>
37*0Sstevel@tonic-gate #include <sys/kmem.h>
38*0Sstevel@tonic-gate #include <sys/ddi.h>
39*0Sstevel@tonic-gate #include <sys/sunddi.h>
40*0Sstevel@tonic-gate #include <sys/open.h>
41*0Sstevel@tonic-gate #include <sys/policy.h>
42*0Sstevel@tonic-gate #include <sys/fm/protocol.h>
43*0Sstevel@tonic-gate #include <sys/bl.h>
44*0Sstevel@tonic-gate 
45*0Sstevel@tonic-gate static dev_info_t *bl_dip;	/* private copy of devinfo pointer */
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate static int
48*0Sstevel@tonic-gate bl_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
49*0Sstevel@tonic-gate {
50*0Sstevel@tonic-gate 	switch (cmd) {
51*0Sstevel@tonic-gate 	case DDI_ATTACH:
52*0Sstevel@tonic-gate 		break;
53*0Sstevel@tonic-gate 	case DDI_RESUME:
54*0Sstevel@tonic-gate 		return (DDI_SUCCESS);
55*0Sstevel@tonic-gate 	default:
56*0Sstevel@tonic-gate 		return (DDI_FAILURE);
57*0Sstevel@tonic-gate 	}
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate 	if (ddi_create_minor_node(dip, ddi_get_name(dip), S_IFCHR,
60*0Sstevel@tonic-gate 	    ddi_get_instance(dip), DDI_PSEUDO, 0) != DDI_SUCCESS)
61*0Sstevel@tonic-gate 		return (DDI_FAILURE);
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate 	bl_dip = dip;
64*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
65*0Sstevel@tonic-gate }
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate /*ARGSUSED*/
68*0Sstevel@tonic-gate static int
69*0Sstevel@tonic-gate bl_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
70*0Sstevel@tonic-gate {
71*0Sstevel@tonic-gate 	switch (cmd) {
72*0Sstevel@tonic-gate 	case DDI_DETACH:
73*0Sstevel@tonic-gate 		break;
74*0Sstevel@tonic-gate 	case DDI_SUSPEND:
75*0Sstevel@tonic-gate 		return (DDI_SUCCESS);
76*0Sstevel@tonic-gate 	default:
77*0Sstevel@tonic-gate 		return (DDI_FAILURE);
78*0Sstevel@tonic-gate 	}
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate 	ddi_remove_minor_node(bl_dip, NULL);
81*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
82*0Sstevel@tonic-gate }
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate /*ARGSUSED*/
85*0Sstevel@tonic-gate static int
86*0Sstevel@tonic-gate bl_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
87*0Sstevel@tonic-gate {
88*0Sstevel@tonic-gate 	int rc = DDI_SUCCESS;
89*0Sstevel@tonic-gate 
90*0Sstevel@tonic-gate 	switch (infocmd) {
91*0Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
92*0Sstevel@tonic-gate 		*result = bl_dip;
93*0Sstevel@tonic-gate 		break;
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
96*0Sstevel@tonic-gate 		*result = (void *)(uintptr_t)getminor((dev_t)arg);
97*0Sstevel@tonic-gate 		break;
98*0Sstevel@tonic-gate 
99*0Sstevel@tonic-gate 	default:
100*0Sstevel@tonic-gate 		*result = NULL;
101*0Sstevel@tonic-gate 		rc = DDI_FAILURE;
102*0Sstevel@tonic-gate 	}
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	return (rc);
105*0Sstevel@tonic-gate }
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate /*ARGSUSED*/
108*0Sstevel@tonic-gate static int
109*0Sstevel@tonic-gate bl_open(dev_t *devp, int flag, int otyp, struct cred *credp)
110*0Sstevel@tonic-gate {
111*0Sstevel@tonic-gate 	if (otyp != OTYP_CHR)
112*0Sstevel@tonic-gate 		return (EINVAL);
113*0Sstevel@tonic-gate 
114*0Sstevel@tonic-gate 	if (secpolicy_blacklist(credp) != 0)
115*0Sstevel@tonic-gate 		return (EPERM);
116*0Sstevel@tonic-gate 
117*0Sstevel@tonic-gate 	return (0);
118*0Sstevel@tonic-gate }
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate /*ARGSUSED*/
121*0Sstevel@tonic-gate static int
122*0Sstevel@tonic-gate bl_ioctl(dev_t dev, int cmd, intptr_t data, int flag, cred_t *cred, int *rvalp)
123*0Sstevel@tonic-gate {
124*0Sstevel@tonic-gate 	bl_req_t blr;
125*0Sstevel@tonic-gate 	nvlist_t *fmri;
126*0Sstevel@tonic-gate 	const char *scheme;
127*0Sstevel@tonic-gate 	char class[128];
128*0Sstevel@tonic-gate 	char *buf;
129*0Sstevel@tonic-gate 	int err;
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate #ifdef _SYSCALL32
132*0Sstevel@tonic-gate 	if (get_udatamodel() != DATAMODEL_NATIVE) {
133*0Sstevel@tonic-gate 		bl_req32_t blr32;
134*0Sstevel@tonic-gate 
135*0Sstevel@tonic-gate 		if (copyin((void *)data, &blr32, sizeof (bl_req32_t)) != 0)
136*0Sstevel@tonic-gate 			return (EFAULT);
137*0Sstevel@tonic-gate 
138*0Sstevel@tonic-gate 		blr.bl_fmri = (caddr_t)(uintptr_t)blr32.bl_fmri;
139*0Sstevel@tonic-gate 		blr.bl_fmrisz = blr32.bl_fmrisz;
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 		blr.bl_class = (caddr_t)(uintptr_t)blr32.bl_class;
142*0Sstevel@tonic-gate 	} else
143*0Sstevel@tonic-gate #endif
144*0Sstevel@tonic-gate 	{
145*0Sstevel@tonic-gate 		if (copyin((void *)data, &blr, sizeof (bl_req_t)) != 0)
146*0Sstevel@tonic-gate 			return (EFAULT);
147*0Sstevel@tonic-gate 	}
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate 	if (blr.bl_fmri == NULL || blr.bl_fmrisz > BL_FMRI_MAX_BUFSIZE ||
150*0Sstevel@tonic-gate 	    blr.bl_class == NULL)
151*0Sstevel@tonic-gate 		return (EINVAL);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	if (copyinstr(blr.bl_class, class, sizeof (class), NULL) != 0)
154*0Sstevel@tonic-gate 		return (EFAULT);
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate 	buf = kmem_zalloc(blr.bl_fmrisz, KM_SLEEP);
157*0Sstevel@tonic-gate 	if (copyin(blr.bl_fmri, buf, blr.bl_fmrisz) != 0) {
158*0Sstevel@tonic-gate 		kmem_free(buf, blr.bl_fmrisz);
159*0Sstevel@tonic-gate 		return (EFAULT);
160*0Sstevel@tonic-gate 	}
161*0Sstevel@tonic-gate 
162*0Sstevel@tonic-gate 	err = nvlist_unpack(buf, blr.bl_fmrisz, &fmri, KM_SLEEP);
163*0Sstevel@tonic-gate 	kmem_free(buf, blr.bl_fmrisz);
164*0Sstevel@tonic-gate 	if (err != 0)
165*0Sstevel@tonic-gate 		return (err);
166*0Sstevel@tonic-gate 
167*0Sstevel@tonic-gate 	if (nvlist_lookup_string(fmri, FM_FMRI_SCHEME, (char **)&scheme) != 0) {
168*0Sstevel@tonic-gate 		nvlist_free(fmri);
169*0Sstevel@tonic-gate 		return (EINVAL);
170*0Sstevel@tonic-gate 	}
171*0Sstevel@tonic-gate 
172*0Sstevel@tonic-gate 	switch (cmd) {
173*0Sstevel@tonic-gate 	case BLIOC_INSERT:
174*0Sstevel@tonic-gate 	case BLIOC_DELETE:
175*0Sstevel@tonic-gate 		err = blacklist(cmd, scheme, fmri, class);
176*0Sstevel@tonic-gate 		break;
177*0Sstevel@tonic-gate 	default:
178*0Sstevel@tonic-gate 		err = ENOTSUP;
179*0Sstevel@tonic-gate 	}
180*0Sstevel@tonic-gate 
181*0Sstevel@tonic-gate 	nvlist_free(fmri);
182*0Sstevel@tonic-gate 	return (err);
183*0Sstevel@tonic-gate 
184*0Sstevel@tonic-gate }
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate static struct cb_ops bl_cb_ops = {
187*0Sstevel@tonic-gate 	bl_open,		/* open */
188*0Sstevel@tonic-gate 	nulldev,		/* close */
189*0Sstevel@tonic-gate 	nodev,			/* strategy */
190*0Sstevel@tonic-gate 	nodev,			/* print */
191*0Sstevel@tonic-gate 	nodev,			/* dump */
192*0Sstevel@tonic-gate 	nodev,			/* read */
193*0Sstevel@tonic-gate 	nodev,			/* write */
194*0Sstevel@tonic-gate 	bl_ioctl,		/* ioctl */
195*0Sstevel@tonic-gate 	nodev,			/* devmap */
196*0Sstevel@tonic-gate 	nodev,			/* mmap */
197*0Sstevel@tonic-gate 	nodev,			/* segmap */
198*0Sstevel@tonic-gate 	nochpoll,		/* poll */
199*0Sstevel@tonic-gate 	ddi_prop_op,		/* cb_prop_op */
200*0Sstevel@tonic-gate 	0,			/* streamtab  */
201*0Sstevel@tonic-gate 	D_NEW | D_MP | D_64BIT	/* Driver compatibility flag */
202*0Sstevel@tonic-gate };
203*0Sstevel@tonic-gate 
204*0Sstevel@tonic-gate static struct dev_ops bl_ops = {
205*0Sstevel@tonic-gate 	DEVO_REV,		/* devo_rev */
206*0Sstevel@tonic-gate 	0,			/* devo_refcnt  */
207*0Sstevel@tonic-gate 	bl_getinfo,		/* devo_getinfo */
208*0Sstevel@tonic-gate 	nulldev,		/* devo_identify */
209*0Sstevel@tonic-gate 	nulldev,		/* devo_probe */
210*0Sstevel@tonic-gate 	bl_attach,		/* devo_attach */
211*0Sstevel@tonic-gate 	bl_detach,		/* devo_detach */
212*0Sstevel@tonic-gate 	nodev,			/* devo_reset */
213*0Sstevel@tonic-gate 	&bl_cb_ops,		/* devo_cb_ops */
214*0Sstevel@tonic-gate 	(struct bus_ops *)0,	/* devo_bus_ops */
215*0Sstevel@tonic-gate 	NULL			/* devo_power */
216*0Sstevel@tonic-gate };
217*0Sstevel@tonic-gate 
218*0Sstevel@tonic-gate static struct modldrv modldrv = {
219*0Sstevel@tonic-gate 	&mod_driverops, "blacklist driver %I%", &bl_ops,
220*0Sstevel@tonic-gate };
221*0Sstevel@tonic-gate 
222*0Sstevel@tonic-gate static struct modlinkage modlinkage = {
223*0Sstevel@tonic-gate 	MODREV_1, &modldrv, NULL
224*0Sstevel@tonic-gate };
225*0Sstevel@tonic-gate 
226*0Sstevel@tonic-gate int
227*0Sstevel@tonic-gate _init(void)
228*0Sstevel@tonic-gate {
229*0Sstevel@tonic-gate 	return (mod_install(&modlinkage));
230*0Sstevel@tonic-gate }
231*0Sstevel@tonic-gate 
232*0Sstevel@tonic-gate int
233*0Sstevel@tonic-gate _info(struct modinfo *modinfop)
234*0Sstevel@tonic-gate {
235*0Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
236*0Sstevel@tonic-gate }
237*0Sstevel@tonic-gate 
238*0Sstevel@tonic-gate int
239*0Sstevel@tonic-gate _fini(void)
240*0Sstevel@tonic-gate {
241*0Sstevel@tonic-gate 	return (mod_remove(&modlinkage));
242*0Sstevel@tonic-gate }
243