xref: /illumos-gate/usr/src/uts/sun4u/mpxu/io/tsalarm.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate  */
26*7c478bd9Sstevel@tonic-gate 
27*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate 
29*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
30*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
31*7c478bd9Sstevel@tonic-gate #include <sys/conf.h>
32*7c478bd9Sstevel@tonic-gate #include <sys/modctl.h>
33*7c478bd9Sstevel@tonic-gate #include <sys/sunddi.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/callb.h>
35*7c478bd9Sstevel@tonic-gate #include <sys/strlog.h>
36*7c478bd9Sstevel@tonic-gate #include <sys/file.h>
37*7c478bd9Sstevel@tonic-gate #include <sys/lom_io.h>
38*7c478bd9Sstevel@tonic-gate #include <sys/ddi.h>
39*7c478bd9Sstevel@tonic-gate #include <sys/time.h>
40*7c478bd9Sstevel@tonic-gate 
41*7c478bd9Sstevel@tonic-gate #define	LOMIOCALCTL_OLD		_IOW('a', 4, ts_aldata_t)
42*7c478bd9Sstevel@tonic-gate #define	LOMIOCALSTATE_OLD	_IOWR('a', 5, ts_aldata_t)
43*7c478bd9Sstevel@tonic-gate 
44*7c478bd9Sstevel@tonic-gate struct tsalarm_softc {
45*7c478bd9Sstevel@tonic-gate 	dev_info_t *dip;
46*7c478bd9Sstevel@tonic-gate 	kmutex_t mutex;
47*7c478bd9Sstevel@tonic-gate };
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate #define	getsoftc(minor)	\
50*7c478bd9Sstevel@tonic-gate 		((struct tsalarm_softc *)ddi_get_soft_state(statep, (minor)))
51*7c478bd9Sstevel@tonic-gate /*
52*7c478bd9Sstevel@tonic-gate  * Driver entry points
53*7c478bd9Sstevel@tonic-gate  */
54*7c478bd9Sstevel@tonic-gate 
55*7c478bd9Sstevel@tonic-gate /* dev_ops and cb_ops entry point function declarations */
56*7c478bd9Sstevel@tonic-gate 
57*7c478bd9Sstevel@tonic-gate static int	tsalarm_attach(dev_info_t *, ddi_attach_cmd_t);
58*7c478bd9Sstevel@tonic-gate static int	tsalarm_detach(dev_info_t *, ddi_detach_cmd_t);
59*7c478bd9Sstevel@tonic-gate static int	tsalarm_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate static int	tsalarm_open(dev_t *, int, int, cred_t *);
62*7c478bd9Sstevel@tonic-gate static int	tsalarm_close(dev_t, int, int, cred_t *);
63*7c478bd9Sstevel@tonic-gate static int	tsalarm_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
64*7c478bd9Sstevel@tonic-gate 
65*7c478bd9Sstevel@tonic-gate static struct cb_ops tsalarm_cb_ops = {
66*7c478bd9Sstevel@tonic-gate 	tsalarm_open,	/* open */
67*7c478bd9Sstevel@tonic-gate 	tsalarm_close,	/* close */
68*7c478bd9Sstevel@tonic-gate 	nodev,		/* strategy() */
69*7c478bd9Sstevel@tonic-gate 	nodev,		/* print() */
70*7c478bd9Sstevel@tonic-gate 	nodev,		/* dump() */
71*7c478bd9Sstevel@tonic-gate 	nodev,		/* read() */
72*7c478bd9Sstevel@tonic-gate 	nodev,		/* write() */
73*7c478bd9Sstevel@tonic-gate 	tsalarm_ioctl,	/* ioctl() */
74*7c478bd9Sstevel@tonic-gate 	nodev,		/* devmap() */
75*7c478bd9Sstevel@tonic-gate 	nodev,		/* mmap() */
76*7c478bd9Sstevel@tonic-gate 	ddi_segmap,	/* segmap() */
77*7c478bd9Sstevel@tonic-gate 	nochpoll,	/* poll() */
78*7c478bd9Sstevel@tonic-gate 	ddi_prop_op,    /* prop_op() */
79*7c478bd9Sstevel@tonic-gate 	NULL,		/* cb_str */
80*7c478bd9Sstevel@tonic-gate 	D_NEW | D_MP	/* cb_flag */
81*7c478bd9Sstevel@tonic-gate };
82*7c478bd9Sstevel@tonic-gate 
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate static struct dev_ops tsalarm_ops = {
85*7c478bd9Sstevel@tonic-gate 	DEVO_REV,
86*7c478bd9Sstevel@tonic-gate 	0,			/* ref count */
87*7c478bd9Sstevel@tonic-gate 	tsalarm_getinfo,	/* getinfo() */
88*7c478bd9Sstevel@tonic-gate 	nulldev,		/* identify() */
89*7c478bd9Sstevel@tonic-gate 	nulldev,		/* probe() */
90*7c478bd9Sstevel@tonic-gate 	tsalarm_attach,		/* attach() */
91*7c478bd9Sstevel@tonic-gate 	tsalarm_detach,		/* detach */
92*7c478bd9Sstevel@tonic-gate 	nodev,			/* reset */
93*7c478bd9Sstevel@tonic-gate 	&tsalarm_cb_ops,		/* pointer to cb_ops structure */
94*7c478bd9Sstevel@tonic-gate 	(struct bus_ops *)NULL,
95*7c478bd9Sstevel@tonic-gate 	nulldev			/* power() */
96*7c478bd9Sstevel@tonic-gate };
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /*
99*7c478bd9Sstevel@tonic-gate  * Loadable module support.
100*7c478bd9Sstevel@tonic-gate  */
101*7c478bd9Sstevel@tonic-gate extern struct mod_ops mod_driverops;
102*7c478bd9Sstevel@tonic-gate static void    *statep;
103*7c478bd9Sstevel@tonic-gate 
104*7c478bd9Sstevel@tonic-gate static struct modldrv modldrv = {
105*7c478bd9Sstevel@tonic-gate 	&mod_driverops,			/* Type of module. This is a driver */
106*7c478bd9Sstevel@tonic-gate 	"tsalarm control driver v%I%",	/* Name of the module */
107*7c478bd9Sstevel@tonic-gate 	&tsalarm_ops			/* pointer to the dev_ops structure */
108*7c478bd9Sstevel@tonic-gate };
109*7c478bd9Sstevel@tonic-gate 
110*7c478bd9Sstevel@tonic-gate static struct modlinkage modlinkage = {
111*7c478bd9Sstevel@tonic-gate 	MODREV_1,
112*7c478bd9Sstevel@tonic-gate 	&modldrv,
113*7c478bd9Sstevel@tonic-gate 	NULL
114*7c478bd9Sstevel@tonic-gate };
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate extern int rmclomv_alarm_get(int alarm_type, int *alarm_state);
117*7c478bd9Sstevel@tonic-gate extern int rmclomv_alarm_set(int alarm_type, int new_state);
118*7c478bd9Sstevel@tonic-gate 
119*7c478bd9Sstevel@tonic-gate int
120*7c478bd9Sstevel@tonic-gate _init(void)
121*7c478bd9Sstevel@tonic-gate {
122*7c478bd9Sstevel@tonic-gate 	int    e;
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	if (e = ddi_soft_state_init(&statep,
125*7c478bd9Sstevel@tonic-gate 				sizeof (struct tsalarm_softc), 1)) {
126*7c478bd9Sstevel@tonic-gate 		return (e);
127*7c478bd9Sstevel@tonic-gate 	}
128*7c478bd9Sstevel@tonic-gate 
129*7c478bd9Sstevel@tonic-gate 	if ((e = mod_install(&modlinkage)) != 0) {
130*7c478bd9Sstevel@tonic-gate 		ddi_soft_state_fini(&statep);
131*7c478bd9Sstevel@tonic-gate 	}
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 	return (e);
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 
137*7c478bd9Sstevel@tonic-gate int
138*7c478bd9Sstevel@tonic-gate _fini(void)
139*7c478bd9Sstevel@tonic-gate {
140*7c478bd9Sstevel@tonic-gate 	int e;
141*7c478bd9Sstevel@tonic-gate 
142*7c478bd9Sstevel@tonic-gate 	if ((e = mod_remove(&modlinkage)) != 0) {
143*7c478bd9Sstevel@tonic-gate 		return (e);
144*7c478bd9Sstevel@tonic-gate 	}
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 	ddi_soft_state_fini(&statep);
147*7c478bd9Sstevel@tonic-gate 
148*7c478bd9Sstevel@tonic-gate 	return (DDI_SUCCESS);
149*7c478bd9Sstevel@tonic-gate }
150*7c478bd9Sstevel@tonic-gate 
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate int
153*7c478bd9Sstevel@tonic-gate _info(struct modinfo *modinfop)
154*7c478bd9Sstevel@tonic-gate {
155*7c478bd9Sstevel@tonic-gate 	return (mod_info(&modlinkage, modinfop));
156*7c478bd9Sstevel@tonic-gate }
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 
159*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
160*7c478bd9Sstevel@tonic-gate static int
161*7c478bd9Sstevel@tonic-gate tsalarm_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result)
162*7c478bd9Sstevel@tonic-gate {
163*7c478bd9Sstevel@tonic-gate 	int	inst = getminor((dev_t)arg);
164*7c478bd9Sstevel@tonic-gate 	int	retval = DDI_SUCCESS;
165*7c478bd9Sstevel@tonic-gate 	struct tsalarm_softc *softc;
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
168*7c478bd9Sstevel@tonic-gate 
169*7c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2DEVINFO:
170*7c478bd9Sstevel@tonic-gate 		if ((softc = getsoftc(inst)) == NULL) {
171*7c478bd9Sstevel@tonic-gate 			*result = (void *)NULL;
172*7c478bd9Sstevel@tonic-gate 			retval = DDI_FAILURE;
173*7c478bd9Sstevel@tonic-gate 		} else {
174*7c478bd9Sstevel@tonic-gate 			*result = (void *)softc->dip;
175*7c478bd9Sstevel@tonic-gate 		}
176*7c478bd9Sstevel@tonic-gate 		break;
177*7c478bd9Sstevel@tonic-gate 
178*7c478bd9Sstevel@tonic-gate 	case DDI_INFO_DEVT2INSTANCE:
179*7c478bd9Sstevel@tonic-gate 		*result = (void *)inst;
180*7c478bd9Sstevel@tonic-gate 		break;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 	default:
183*7c478bd9Sstevel@tonic-gate 		retval = DDI_FAILURE;
184*7c478bd9Sstevel@tonic-gate 	}
185*7c478bd9Sstevel@tonic-gate 
186*7c478bd9Sstevel@tonic-gate 	return (retval);
187*7c478bd9Sstevel@tonic-gate }
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate static int
190*7c478bd9Sstevel@tonic-gate tsalarm_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
191*7c478bd9Sstevel@tonic-gate {
192*7c478bd9Sstevel@tonic-gate 
193*7c478bd9Sstevel@tonic-gate 	int inst;
194*7c478bd9Sstevel@tonic-gate 	struct tsalarm_softc *softc = NULL;
195*7c478bd9Sstevel@tonic-gate 
196*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
197*7c478bd9Sstevel@tonic-gate 
198*7c478bd9Sstevel@tonic-gate 	case DDI_ATTACH:
199*7c478bd9Sstevel@tonic-gate 		inst = ddi_get_instance(dip);
200*7c478bd9Sstevel@tonic-gate 		/*
201*7c478bd9Sstevel@tonic-gate 		 * Allocate a soft state structure for this instance.
202*7c478bd9Sstevel@tonic-gate 		 */
203*7c478bd9Sstevel@tonic-gate 		if (ddi_soft_state_zalloc(statep, inst) != DDI_SUCCESS)
204*7c478bd9Sstevel@tonic-gate 			goto attach_failed;
205*7c478bd9Sstevel@tonic-gate 
206*7c478bd9Sstevel@tonic-gate 		softc = getsoftc(inst);
207*7c478bd9Sstevel@tonic-gate 		softc->dip = dip;
208*7c478bd9Sstevel@tonic-gate 		mutex_init(&softc->mutex, NULL, MUTEX_DRIVER, NULL);
209*7c478bd9Sstevel@tonic-gate 		/*
210*7c478bd9Sstevel@tonic-gate 		 * Create minor node.  The minor device number, inst, has no
211*7c478bd9Sstevel@tonic-gate 		 * meaning.  The model number above, which will be added to
212*7c478bd9Sstevel@tonic-gate 		 * the device's softc, is used to direct peculiar behavior.
213*7c478bd9Sstevel@tonic-gate 		 */
214*7c478bd9Sstevel@tonic-gate 		if (ddi_create_minor_node(dip, "lom", S_IFCHR, 0,
215*7c478bd9Sstevel@tonic-gate 				DDI_PSEUDO, NULL) == DDI_FAILURE)
216*7c478bd9Sstevel@tonic-gate 			goto attach_failed;
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 		ddi_report_dev(dip);
219*7c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
220*7c478bd9Sstevel@tonic-gate 
221*7c478bd9Sstevel@tonic-gate 	case DDI_RESUME:
222*7c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
223*7c478bd9Sstevel@tonic-gate 
224*7c478bd9Sstevel@tonic-gate 	default:
225*7c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
226*7c478bd9Sstevel@tonic-gate 	}
227*7c478bd9Sstevel@tonic-gate 
228*7c478bd9Sstevel@tonic-gate attach_failed:
229*7c478bd9Sstevel@tonic-gate 	/* Free soft state, if allocated. remove minor node if added earlier */
230*7c478bd9Sstevel@tonic-gate 	if (softc) {
231*7c478bd9Sstevel@tonic-gate 		mutex_destroy(&softc->mutex);
232*7c478bd9Sstevel@tonic-gate 		ddi_soft_state_free(statep, inst);
233*7c478bd9Sstevel@tonic-gate 	}
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 	ddi_remove_minor_node(dip, NULL);
236*7c478bd9Sstevel@tonic-gate 
237*7c478bd9Sstevel@tonic-gate 	return (DDI_FAILURE);
238*7c478bd9Sstevel@tonic-gate }
239*7c478bd9Sstevel@tonic-gate 
240*7c478bd9Sstevel@tonic-gate static int
241*7c478bd9Sstevel@tonic-gate tsalarm_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
242*7c478bd9Sstevel@tonic-gate {
243*7c478bd9Sstevel@tonic-gate 	int inst;
244*7c478bd9Sstevel@tonic-gate 	struct tsalarm_softc *softc;
245*7c478bd9Sstevel@tonic-gate 
246*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
247*7c478bd9Sstevel@tonic-gate 
248*7c478bd9Sstevel@tonic-gate 	case DDI_DETACH:
249*7c478bd9Sstevel@tonic-gate 		inst = ddi_get_instance(dip);
250*7c478bd9Sstevel@tonic-gate 		if ((softc = getsoftc(inst)) == NULL)
251*7c478bd9Sstevel@tonic-gate 			return (DDI_FAILURE);
252*7c478bd9Sstevel@tonic-gate 		/*
253*7c478bd9Sstevel@tonic-gate 		 * Free the soft state and remove minor node added earlier.
254*7c478bd9Sstevel@tonic-gate 		 */
255*7c478bd9Sstevel@tonic-gate 		ddi_remove_minor_node(dip, NULL);
256*7c478bd9Sstevel@tonic-gate 		mutex_destroy(&softc->mutex);
257*7c478bd9Sstevel@tonic-gate 		ddi_soft_state_free(statep, inst);
258*7c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
259*7c478bd9Sstevel@tonic-gate 
260*7c478bd9Sstevel@tonic-gate 	case DDI_SUSPEND:
261*7c478bd9Sstevel@tonic-gate 		return (DDI_SUCCESS);
262*7c478bd9Sstevel@tonic-gate 
263*7c478bd9Sstevel@tonic-gate 	default:
264*7c478bd9Sstevel@tonic-gate 		return (DDI_FAILURE);
265*7c478bd9Sstevel@tonic-gate 
266*7c478bd9Sstevel@tonic-gate 	}
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate 
269*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
270*7c478bd9Sstevel@tonic-gate static int
271*7c478bd9Sstevel@tonic-gate tsalarm_open(dev_t *devp, int flag, int otyp, cred_t *credp)
272*7c478bd9Sstevel@tonic-gate {
273*7c478bd9Sstevel@tonic-gate 	int	inst = getminor(*devp);
274*7c478bd9Sstevel@tonic-gate 
275*7c478bd9Sstevel@tonic-gate 	return (getsoftc(inst) == NULL ? ENXIO : 0);
276*7c478bd9Sstevel@tonic-gate }
277*7c478bd9Sstevel@tonic-gate 
278*7c478bd9Sstevel@tonic-gate 
279*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
280*7c478bd9Sstevel@tonic-gate static int
281*7c478bd9Sstevel@tonic-gate tsalarm_close(dev_t dev, int flag, int otyp, cred_t *credp)
282*7c478bd9Sstevel@tonic-gate {
283*7c478bd9Sstevel@tonic-gate 	int	inst = getminor(dev);
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 	return (getsoftc(inst) == NULL ? ENXIO : 0);
286*7c478bd9Sstevel@tonic-gate }
287*7c478bd9Sstevel@tonic-gate 
288*7c478bd9Sstevel@tonic-gate 
289*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
290*7c478bd9Sstevel@tonic-gate static int
291*7c478bd9Sstevel@tonic-gate tsalarm_ioctl(dev_t dev, int cmd, intptr_t arg, int mode,
292*7c478bd9Sstevel@tonic-gate 		cred_t *credp, int *rvalp)
293*7c478bd9Sstevel@tonic-gate {
294*7c478bd9Sstevel@tonic-gate 	int		inst = getminor(dev);
295*7c478bd9Sstevel@tonic-gate 	struct tsalarm_softc *softc;
296*7c478bd9Sstevel@tonic-gate 	int retval = 0;
297*7c478bd9Sstevel@tonic-gate 	ts_aldata_t ts_alinfo;
298*7c478bd9Sstevel@tonic-gate 	int alarm_type, alarm_state = 0;
299*7c478bd9Sstevel@tonic-gate 
300*7c478bd9Sstevel@tonic-gate 	if ((softc = getsoftc(inst)) == NULL)
301*7c478bd9Sstevel@tonic-gate 		return (ENXIO);
302*7c478bd9Sstevel@tonic-gate 
303*7c478bd9Sstevel@tonic-gate 	mutex_enter(&softc->mutex);
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 	switch (cmd) {
306*7c478bd9Sstevel@tonic-gate 
307*7c478bd9Sstevel@tonic-gate 	case LOMIOCALSTATE:
308*7c478bd9Sstevel@tonic-gate 	case LOMIOCALSTATE_OLD:
309*7c478bd9Sstevel@tonic-gate 		{
310*7c478bd9Sstevel@tonic-gate 			if (ddi_copyin((caddr_t)arg, (caddr_t)&ts_alinfo,
311*7c478bd9Sstevel@tonic-gate 				sizeof (ts_aldata_t), mode) != 0) {
312*7c478bd9Sstevel@tonic-gate 				retval = EFAULT;
313*7c478bd9Sstevel@tonic-gate 				goto end;
314*7c478bd9Sstevel@tonic-gate 			}
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate 			alarm_type = ts_alinfo.alarm_no;
317*7c478bd9Sstevel@tonic-gate 			if ((alarm_type < ALARM_CRITICAL) ||
318*7c478bd9Sstevel@tonic-gate 					(alarm_type > ALARM_USER)) {
319*7c478bd9Sstevel@tonic-gate 				retval = EINVAL;
320*7c478bd9Sstevel@tonic-gate 				goto end;
321*7c478bd9Sstevel@tonic-gate 			}
322*7c478bd9Sstevel@tonic-gate 
323*7c478bd9Sstevel@tonic-gate 			retval = rmclomv_alarm_get(alarm_type, &alarm_state);
324*7c478bd9Sstevel@tonic-gate 
325*7c478bd9Sstevel@tonic-gate 			if (retval != 0)
326*7c478bd9Sstevel@tonic-gate 				goto end;
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 			if ((alarm_state != 0) && (alarm_state != 1)) {
329*7c478bd9Sstevel@tonic-gate 				retval = EIO;
330*7c478bd9Sstevel@tonic-gate 				goto end;
331*7c478bd9Sstevel@tonic-gate 			}
332*7c478bd9Sstevel@tonic-gate 
333*7c478bd9Sstevel@tonic-gate 			ts_alinfo.alarm_state = alarm_state;
334*7c478bd9Sstevel@tonic-gate 			if (ddi_copyout((caddr_t)&ts_alinfo, (caddr_t)arg,
335*7c478bd9Sstevel@tonic-gate 				sizeof (ts_aldata_t), mode) != 0) {
336*7c478bd9Sstevel@tonic-gate 				retval = EFAULT;
337*7c478bd9Sstevel@tonic-gate 				goto end;
338*7c478bd9Sstevel@tonic-gate 			}
339*7c478bd9Sstevel@tonic-gate 
340*7c478bd9Sstevel@tonic-gate 		}
341*7c478bd9Sstevel@tonic-gate 		break;
342*7c478bd9Sstevel@tonic-gate 
343*7c478bd9Sstevel@tonic-gate 	case LOMIOCALCTL:
344*7c478bd9Sstevel@tonic-gate 	case LOMIOCALCTL_OLD:
345*7c478bd9Sstevel@tonic-gate 		{
346*7c478bd9Sstevel@tonic-gate 			if (ddi_copyin((caddr_t)arg, (caddr_t)&ts_alinfo,
347*7c478bd9Sstevel@tonic-gate 				sizeof (ts_aldata_t), mode) != 0) {
348*7c478bd9Sstevel@tonic-gate 				retval = EFAULT;
349*7c478bd9Sstevel@tonic-gate 				goto end;
350*7c478bd9Sstevel@tonic-gate 			}
351*7c478bd9Sstevel@tonic-gate 
352*7c478bd9Sstevel@tonic-gate 			alarm_type = ts_alinfo.alarm_no;
353*7c478bd9Sstevel@tonic-gate 			alarm_state = ts_alinfo.alarm_state;
354*7c478bd9Sstevel@tonic-gate 
355*7c478bd9Sstevel@tonic-gate 			if ((alarm_type < ALARM_CRITICAL) ||
356*7c478bd9Sstevel@tonic-gate 					(alarm_type > ALARM_USER)) {
357*7c478bd9Sstevel@tonic-gate 				retval = EINVAL;
358*7c478bd9Sstevel@tonic-gate 				goto end;
359*7c478bd9Sstevel@tonic-gate 			}
360*7c478bd9Sstevel@tonic-gate 			if ((alarm_state < ALARM_OFF) ||
361*7c478bd9Sstevel@tonic-gate 					(alarm_state > ALARM_ON)) {
362*7c478bd9Sstevel@tonic-gate 				retval = EINVAL;
363*7c478bd9Sstevel@tonic-gate 				goto end;
364*7c478bd9Sstevel@tonic-gate 			}
365*7c478bd9Sstevel@tonic-gate 
366*7c478bd9Sstevel@tonic-gate 			retval = rmclomv_alarm_set(alarm_type, alarm_state);
367*7c478bd9Sstevel@tonic-gate 		}
368*7c478bd9Sstevel@tonic-gate 		break;
369*7c478bd9Sstevel@tonic-gate 
370*7c478bd9Sstevel@tonic-gate 	default:
371*7c478bd9Sstevel@tonic-gate 		retval = EINVAL;
372*7c478bd9Sstevel@tonic-gate 		break;
373*7c478bd9Sstevel@tonic-gate 	}
374*7c478bd9Sstevel@tonic-gate 
375*7c478bd9Sstevel@tonic-gate end:
376*7c478bd9Sstevel@tonic-gate 	mutex_exit(&softc->mutex);
377*7c478bd9Sstevel@tonic-gate 
378*7c478bd9Sstevel@tonic-gate 	return (retval);
379*7c478bd9Sstevel@tonic-gate }
380