xref: /netbsd-src/sys/dev/ir/irframe.c (revision f9228f42259a421502f04b1ddb2df91c2ecbc519)
1*f9228f42Sdholland /*	$NetBSD: irframe.c,v 1.46 2014/07/25 08:10:37 dholland Exp $	*/
2b5409597Saugustss 
3b5409597Saugustss /*
4b5409597Saugustss  * Copyright (c) 2001 The NetBSD Foundation, Inc.
5b5409597Saugustss  * All rights reserved.
6b5409597Saugustss  *
7b5409597Saugustss  * This code is derived from software contributed to The NetBSD Foundation
8b5409597Saugustss  * by Lennart Augustsson (lennart@augustsson.net).
9b5409597Saugustss  *
10b5409597Saugustss  * Redistribution and use in source and binary forms, with or without
11b5409597Saugustss  * modification, are permitted provided that the following conditions
12b5409597Saugustss  * are met:
13b5409597Saugustss  * 1. Redistributions of source code must retain the above copyright
14b5409597Saugustss  *    notice, this list of conditions and the following disclaimer.
15b5409597Saugustss  * 2. Redistributions in binary form must reproduce the above copyright
16b5409597Saugustss  *    notice, this list of conditions and the following disclaimer in the
17b5409597Saugustss  *    documentation and/or other materials provided with the distribution.
18b5409597Saugustss  *
19b5409597Saugustss  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20b5409597Saugustss  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21b5409597Saugustss  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b5409597Saugustss  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23b5409597Saugustss  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24b5409597Saugustss  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25b5409597Saugustss  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26b5409597Saugustss  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27b5409597Saugustss  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28b5409597Saugustss  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29b5409597Saugustss  * POSSIBILITY OF SUCH DAMAGE.
30b5409597Saugustss  */
31b5409597Saugustss 
32365cbd94Slukem #include <sys/cdefs.h>
33*f9228f42Sdholland __KERNEL_RCSID(0, "$NetBSD: irframe.c,v 1.46 2014/07/25 08:10:37 dholland Exp $");
34365cbd94Slukem 
355f99a984Saugustss #include "irframe.h"
365f99a984Saugustss 
37b5409597Saugustss #include <sys/param.h>
38b5409597Saugustss #include <sys/systm.h>
39b5409597Saugustss #include <sys/ioctl.h>
40b5409597Saugustss #include <sys/kernel.h>
41b5409597Saugustss #include <sys/device.h>
42b5409597Saugustss #include <sys/conf.h>
43b5409597Saugustss #include <sys/malloc.h>
44b5409597Saugustss #include <sys/poll.h>
45b5409597Saugustss #include <sys/select.h>
46b5409597Saugustss #include <sys/vnode.h>
47b5409597Saugustss 
48b5409597Saugustss #include <dev/ir/ir.h>
49b5409597Saugustss #include <dev/ir/irdaio.h>
50b5409597Saugustss #include <dev/ir/irframevar.h>
51b5409597Saugustss 
523df38cc5Saugustss #ifdef IRFRAME_DEBUG
533df38cc5Saugustss #define DPRINTF(x)	if (irframedebug) printf x
543df38cc5Saugustss #define Static
553df38cc5Saugustss int irframedebug = 0;
563df38cc5Saugustss #else
573df38cc5Saugustss #define DPRINTF(x)
583df38cc5Saugustss #define Static static
593df38cc5Saugustss #endif
603df38cc5Saugustss 
6177a6b82bSgehenna dev_type_open(irframeopen);
6277a6b82bSgehenna dev_type_close(irframeclose);
6377a6b82bSgehenna dev_type_read(irframeread);
6477a6b82bSgehenna dev_type_write(irframewrite);
6577a6b82bSgehenna dev_type_ioctl(irframeioctl);
6677a6b82bSgehenna dev_type_poll(irframepoll);
67e0cc03a0Sjdolecek dev_type_kqfilter(irframekqfilter);
6877a6b82bSgehenna 
6977a6b82bSgehenna const struct cdevsw irframe_cdevsw = {
70a68f9396Sdholland 	.d_open = irframeopen,
71a68f9396Sdholland 	.d_close = irframeclose,
72a68f9396Sdholland 	.d_read = irframeread,
73a68f9396Sdholland 	.d_write = irframewrite,
74a68f9396Sdholland 	.d_ioctl = irframeioctl,
75a68f9396Sdholland 	.d_stop = nostop,
76a68f9396Sdholland 	.d_tty = notty,
77a68f9396Sdholland 	.d_poll = irframepoll,
78a68f9396Sdholland 	.d_mmap = nommap,
79a68f9396Sdholland 	.d_kqfilter = irframekqfilter,
80*f9228f42Sdholland 	.d_discard = nodiscard,
81a68f9396Sdholland 	.d_flag = D_OTHER
8277a6b82bSgehenna };
83b5409597Saugustss 
84a6b5eb2bScube int irframe_match(device_t parent, cfdata_t match, void *aux);
85b5409597Saugustss 
867f50d17cSaugustss Static int irf_set_params(struct irframe_softc *sc, struct irda_params *p);
873df38cc5Saugustss Static int irf_reset_params(struct irframe_softc *sc);
88b81ddff1Saugustss 
895f99a984Saugustss #if NIRFRAME == 0
905f99a984Saugustss /* In case we just have tty attachment. */
918043c2cbSthorpej CFDRIVER_DECL(irframe, DV_DULL, NULL);
925f99a984Saugustss #endif
935f99a984Saugustss 
94a6b5eb2bScube CFATTACH_DECL_NEW(irframe, sizeof(struct irframe_softc),
95de0ad504Sdyoung     irframe_match, irframe_attach, irframe_detach, NULL);
96b5409597Saugustss 
97b5409597Saugustss extern struct cfdriver irframe_cd;
98b5409597Saugustss 
99b5409597Saugustss #define IRFRAMEUNIT(dev) (minor(dev))
100b5409597Saugustss 
101b5409597Saugustss int
irframe_match(device_t parent,cfdata_t match,void * aux)102a6b5eb2bScube irframe_match(device_t parent, cfdata_t match, void *aux)
103b5409597Saugustss {
104b5409597Saugustss 	struct ir_attach_args *ia = aux;
105b5409597Saugustss 
106b5409597Saugustss 	return (ia->ia_type == IR_TYPE_IRFRAME);
107b5409597Saugustss }
108b5409597Saugustss 
109b5409597Saugustss void
irframe_attach(device_t parent,device_t self,void * aux)110a6b5eb2bScube irframe_attach(device_t parent, device_t self, void *aux)
111b5409597Saugustss {
1128fc35725Sthorpej 	struct irframe_softc *sc = device_private(self);
113b5409597Saugustss 	struct ir_attach_args *ia = aux;
114b5409597Saugustss 	const char *delim;
115b5409597Saugustss 	int speeds = 0;
116b5409597Saugustss 
117a6b5eb2bScube 	sc->sc_dev = self;
118b5409597Saugustss 	sc->sc_methods = ia->ia_methods;
119b5409597Saugustss 	sc->sc_handle = ia->ia_handle;
120b5409597Saugustss 
121b5409597Saugustss #ifdef DIAGNOSTIC
122b5409597Saugustss 	if (sc->sc_methods->im_read == NULL ||
123b5409597Saugustss 	    sc->sc_methods->im_write == NULL ||
1245f99a984Saugustss 	    sc->sc_methods->im_poll == NULL ||
125e0cc03a0Sjdolecek 	    sc->sc_methods->im_kqfilter == NULL ||
126b5409597Saugustss 	    sc->sc_methods->im_set_params == NULL ||
127b5409597Saugustss 	    sc->sc_methods->im_get_speeds == NULL ||
128b5409597Saugustss 	    sc->sc_methods->im_get_turnarounds == NULL)
129a6b5eb2bScube 		panic("%s: missing methods", device_xname(self));
130b5409597Saugustss #endif
131b5409597Saugustss 
132b5409597Saugustss 	(void)sc->sc_methods->im_get_speeds(sc->sc_handle, &speeds);
133090d1a62Saugustss 	sc->sc_speedmask = speeds;
134b5409597Saugustss 	delim = ":";
135b5409597Saugustss 	if (speeds & IRDA_SPEEDS_SIR) {
136b5409597Saugustss 		printf("%s SIR", delim);
137b5409597Saugustss 		delim = ",";
138b5409597Saugustss 	}
139b5409597Saugustss 	if (speeds & IRDA_SPEEDS_MIR) {
140b5409597Saugustss 		printf("%s MIR", delim);
141b5409597Saugustss 		delim = ",";
142b5409597Saugustss 	}
143b5409597Saugustss 	if (speeds & IRDA_SPEEDS_FIR) {
144b5409597Saugustss 		printf("%s FIR", delim);
145b5409597Saugustss 		delim = ",";
146b5409597Saugustss 	}
147b5409597Saugustss 	if (speeds & IRDA_SPEEDS_VFIR) {
148b5409597Saugustss 		printf("%s VFIR", delim);
149b5409597Saugustss 		delim = ",";
150b5409597Saugustss 	}
151b5409597Saugustss 	printf("\n");
1521c2f2889Smlelstv 
1531c2f2889Smlelstv 	if (!pmf_device_register(self, NULL, NULL))
1541c2f2889Smlelstv 		aprint_error_dev(self, "couldn't establish power handler\n");
155b5409597Saugustss }
156b5409597Saugustss 
157b5409597Saugustss int
irframe_detach(device_t self,int flags)158a6b5eb2bScube irframe_detach(device_t self, int flags)
159b5409597Saugustss {
1608fc35725Sthorpej 	/*struct irframe_softc *sc = device_private(self);*/
161b5409597Saugustss 	int maj, mn;
162b5409597Saugustss 
1631c2f2889Smlelstv 	pmf_device_deregister(self);
1641c2f2889Smlelstv 
1659cef2a3dSaugustss 	/* XXX needs reference count */
1669cef2a3dSaugustss 
167b5409597Saugustss 	/* locate the major number */
16877a6b82bSgehenna 	maj = cdevsw_lookup_major(&irframe_cdevsw);
169b5409597Saugustss 
170b5409597Saugustss 	/* Nuke the vnodes for any open instances (calls close). */
17139cd836eSthorpej 	mn = device_unit(self);
172b5409597Saugustss 	vdevgone(maj, mn, mn, VCHR);
173b5409597Saugustss 
174b5409597Saugustss 	return (0);
175b5409597Saugustss }
176b5409597Saugustss 
177b5409597Saugustss int
irframeopen(dev_t dev,int flag,int mode,struct lwp * l)17895e1ffb1Schristos irframeopen(dev_t dev, int flag, int mode, struct lwp *l)
179b5409597Saugustss {
180b5409597Saugustss 	struct irframe_softc *sc;
181b5409597Saugustss 	int error;
182b5409597Saugustss 
183fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
184b5409597Saugustss 	if (sc == NULL)
185b5409597Saugustss 		return (ENXIO);
186a6b5eb2bScube 	if (!device_is_active(sc->sc_dev))
187b5409597Saugustss 		return (EIO);
188b5409597Saugustss 	if (sc->sc_open)
189b5409597Saugustss 		return (EBUSY);
190b5409597Saugustss 	if (sc->sc_methods->im_open != NULL) {
19195e1ffb1Schristos 		error = sc->sc_methods->im_open(sc->sc_handle, flag, mode, l);
192b5409597Saugustss 		if (error)
193b5409597Saugustss 			return (error);
194b5409597Saugustss 	}
195b5409597Saugustss 	sc->sc_open = 1;
196090d1a62Saugustss #ifdef DIAGNOSTIC
197090d1a62Saugustss 	sc->sc_speed = IRDA_DEFAULT_SPEED;
198090d1a62Saugustss #endif
1998c2cf4c7Saugustss 	(void)irf_reset_params(sc);
200b5409597Saugustss 	return (0);
201b5409597Saugustss }
202b5409597Saugustss 
203b5409597Saugustss int
irframeclose(dev_t dev,int flag,int mode,struct lwp * l)20495e1ffb1Schristos irframeclose(dev_t dev, int flag, int mode, struct lwp *l)
205b5409597Saugustss {
206b5409597Saugustss 	struct irframe_softc *sc;
207b5409597Saugustss 	int error;
208b5409597Saugustss 
209fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
210b5409597Saugustss 	if (sc == NULL)
211b5409597Saugustss 		return (ENXIO);
212996d5c6cSaugustss 	sc->sc_open = 0;
213b5409597Saugustss 	if (sc->sc_methods->im_close != NULL)
21495e1ffb1Schristos 		error = sc->sc_methods->im_close(sc->sc_handle, flag, mode, l);
215b5409597Saugustss 	else
216b5409597Saugustss 		error = 0;
217b5409597Saugustss 	return (error);
218b5409597Saugustss }
219b5409597Saugustss 
220b5409597Saugustss int
irframeread(dev_t dev,struct uio * uio,int flag)221b5409597Saugustss irframeread(dev_t dev, struct uio *uio, int flag)
222b5409597Saugustss {
223b5409597Saugustss 	struct irframe_softc *sc;
224b5409597Saugustss 
225fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
226b5409597Saugustss 	if (sc == NULL)
227b5409597Saugustss 		return (ENXIO);
228a6b5eb2bScube 	if (!device_is_active(sc->sc_dev) || !sc->sc_open)
229b5409597Saugustss 		return (EIO);
2303df38cc5Saugustss 	if (uio->uio_resid < sc->sc_params.maxsize) {
2313df38cc5Saugustss #ifdef DIAGNOSTIC
232097bf36eSfvdl 		printf("irframeread: short read %ld < %d\n",
233097bf36eSfvdl 		       (long)uio->uio_resid, sc->sc_params.maxsize);
2343df38cc5Saugustss #endif
235090d1a62Saugustss 		return (EINVAL);
2363df38cc5Saugustss 	}
237b5409597Saugustss 	return (sc->sc_methods->im_read(sc->sc_handle, uio, flag));
238b5409597Saugustss }
239b5409597Saugustss 
240b5409597Saugustss int
irframewrite(dev_t dev,struct uio * uio,int flag)241b5409597Saugustss irframewrite(dev_t dev, struct uio *uio, int flag)
242b5409597Saugustss {
243b5409597Saugustss 	struct irframe_softc *sc;
244b5409597Saugustss 
245fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
246b5409597Saugustss 	if (sc == NULL)
247b5409597Saugustss 		return (ENXIO);
248a6b5eb2bScube 	if (!device_is_active(sc->sc_dev) || !sc->sc_open)
249b5409597Saugustss 		return (EIO);
2503df38cc5Saugustss 	if (uio->uio_resid > sc->sc_params.maxsize) {
2513df38cc5Saugustss #ifdef DIAGNOSTIC
252097bf36eSfvdl 		printf("irframeread: long write %ld > %d\n",
253097bf36eSfvdl 		       (long)uio->uio_resid, sc->sc_params.maxsize);
2543df38cc5Saugustss #endif
255090d1a62Saugustss 		return (EINVAL);
2563df38cc5Saugustss 	}
257cf8a8cbeSaugustss 	return (sc->sc_methods->im_write(sc->sc_handle, uio, flag));
258b5409597Saugustss }
259b5409597Saugustss 
260b5409597Saugustss int
irf_set_params(struct irframe_softc * sc,struct irda_params * p)2617f50d17cSaugustss irf_set_params(struct irframe_softc *sc, struct irda_params *p)
2627f50d17cSaugustss {
2637f50d17cSaugustss 	int error;
2647f50d17cSaugustss 
2657f50d17cSaugustss 	DPRINTF(("irf_set_params: set params speed=%u ebofs=%u maxsize=%u "
2667f50d17cSaugustss 		 "speedmask=0x%x\n", p->speed, p->ebofs, p->maxsize,
2677f50d17cSaugustss 		 sc->sc_speedmask));
2687f50d17cSaugustss 
2697f50d17cSaugustss 	if (p->maxsize > IRDA_MAX_FRAME_SIZE) {
2707f50d17cSaugustss #ifdef IRFRAME_DEBUG
2717f50d17cSaugustss 		printf("irf_set_params: bad maxsize=%u\n", p->maxsize);
2727f50d17cSaugustss #endif
2737f50d17cSaugustss 		return (EINVAL);
2747f50d17cSaugustss 	}
2757f50d17cSaugustss 
2767f50d17cSaugustss 	if (p->ebofs > IRDA_MAX_EBOFS) {
2777f50d17cSaugustss #ifdef IRFRAME_DEBUG
2787f50d17cSaugustss 		printf("irf_set_params: bad maxsize=%u\n", p->maxsize);
2797f50d17cSaugustss #endif
2807f50d17cSaugustss 		return (EINVAL);
2817f50d17cSaugustss 	}
2827f50d17cSaugustss 
2837f50d17cSaugustss #define CONC(x,y) x##y
2847f50d17cSaugustss #define CASE(s) case s: if (!(sc->sc_speedmask & CONC(IRDA_SPEED_,s))) return (EINVAL); break
2857f50d17cSaugustss 	switch (p->speed) {
2867f50d17cSaugustss 	CASE(2400);
2877f50d17cSaugustss 	CASE(9600);
2887f50d17cSaugustss 	CASE(19200);
2897f50d17cSaugustss 	CASE(38400);
2907f50d17cSaugustss 	CASE(57600);
2917f50d17cSaugustss 	CASE(115200);
2927f50d17cSaugustss 	CASE(576000);
2937f50d17cSaugustss 	CASE(1152000);
2947f50d17cSaugustss 	CASE(4000000);
2957f50d17cSaugustss 	CASE(16000000);
2967f50d17cSaugustss 	default: return (EINVAL);
2977f50d17cSaugustss 	}
2987f50d17cSaugustss #undef CONC
2997f50d17cSaugustss #undef CASE
3007f50d17cSaugustss 
3017f50d17cSaugustss 	error = sc->sc_methods->im_set_params(sc->sc_handle, p);
3027f50d17cSaugustss 	if (!error) {
3037f50d17cSaugustss 		sc->sc_params = *p;
3047f50d17cSaugustss 		DPRINTF(("irf_set_params: ok\n"));
3057f50d17cSaugustss #ifdef DIAGNOSTIC
3067f50d17cSaugustss 		if (p->speed != sc->sc_speed) {
3077f50d17cSaugustss 			sc->sc_speed = p->speed;
308a6b5eb2bScube 			aprint_verbose_dev(sc->sc_dev, "set speed %u\n",
3097f50d17cSaugustss 			       sc->sc_speed);
3107f50d17cSaugustss 		}
3117f50d17cSaugustss #endif
3127f50d17cSaugustss 	} else {
3137f50d17cSaugustss #ifdef IRFRAME_DEBUG
3147f50d17cSaugustss 		printf("irf_set_params: error=%d\n", error);
3157f50d17cSaugustss #endif
3167f50d17cSaugustss 	}
3177f50d17cSaugustss 	return (error);
3187f50d17cSaugustss }
3197f50d17cSaugustss 
3207f50d17cSaugustss int
irf_reset_params(struct irframe_softc * sc)321b81ddff1Saugustss irf_reset_params(struct irframe_softc *sc)
322b81ddff1Saugustss {
323b81ddff1Saugustss 	struct irda_params params;
324b81ddff1Saugustss 
325b81ddff1Saugustss 	params.speed = IRDA_DEFAULT_SPEED;
326b81ddff1Saugustss 	params.ebofs = IRDA_DEFAULT_EBOFS;
327b81ddff1Saugustss 	params.maxsize = IRDA_DEFAULT_SIZE;
3287f50d17cSaugustss 	return (irf_set_params(sc, &params));
329b81ddff1Saugustss }
330b81ddff1Saugustss 
331b81ddff1Saugustss int
irframeioctl(dev_t dev,u_long cmd,void * addr,int flag,struct lwp * l)33253524e44Schristos irframeioctl(dev_t dev, u_long cmd, void *addr, int flag,
333168cd830Schristos     struct lwp *l)
334b5409597Saugustss {
335b5409597Saugustss 	struct irframe_softc *sc;
336cf8a8cbeSaugustss 	void *vaddr = addr;
337b5409597Saugustss 	int error;
338b5409597Saugustss 
339fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
340b5409597Saugustss 	if (sc == NULL)
341b5409597Saugustss 		return (ENXIO);
342a6b5eb2bScube 	if (!device_is_active(sc->sc_dev) || !sc->sc_open)
343b5409597Saugustss 		return (EIO);
344b5409597Saugustss 
345b5409597Saugustss 	switch (cmd) {
346b5409597Saugustss 	case FIONBIO:
347b5409597Saugustss 		/* All handled in the upper FS layer. */
348b5409597Saugustss 		error = 0;
349b5409597Saugustss 		break;
350b5409597Saugustss 
351b5409597Saugustss 	case IRDA_SET_PARAMS:
3527f50d17cSaugustss 		error = irf_set_params(sc, vaddr);
353b5409597Saugustss 		break;
354b5409597Saugustss 
355b5409597Saugustss 	case IRDA_RESET_PARAMS:
3560913a897Saugustss 		error = irf_reset_params(sc);
357b5409597Saugustss 		break;
358b5409597Saugustss 
359b5409597Saugustss 	case IRDA_GET_SPEEDMASK:
360cf8a8cbeSaugustss 		error = sc->sc_methods->im_get_speeds(sc->sc_handle, vaddr);
361b5409597Saugustss 		break;
362b5409597Saugustss 
363b5409597Saugustss 	case IRDA_GET_TURNAROUNDMASK:
364cf8a8cbeSaugustss 		error = sc->sc_methods->im_get_turnarounds(sc->sc_handle,vaddr);
365b5409597Saugustss 		break;
366b5409597Saugustss 
367b5409597Saugustss 	default:
368b5409597Saugustss 		error = EINVAL;
369b5409597Saugustss 		break;
370b5409597Saugustss 	}
371b5409597Saugustss 	return (error);
372b5409597Saugustss }
373b5409597Saugustss 
374b5409597Saugustss int
irframepoll(dev_t dev,int events,struct lwp * l)37595e1ffb1Schristos irframepoll(dev_t dev, int events, struct lwp *l)
376b5409597Saugustss {
377b5409597Saugustss 	struct irframe_softc *sc;
378b5409597Saugustss 
379fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
380b5409597Saugustss 	if (sc == NULL)
3819d78e0cfSws 		return (POLLHUP);
382a6b5eb2bScube 	if (!device_is_active(sc->sc_dev) || !sc->sc_open)
3839d78e0cfSws 		return (POLLHUP);
384b5409597Saugustss 
38595e1ffb1Schristos 	return (sc->sc_methods->im_poll(sc->sc_handle, events, l));
386b5409597Saugustss }
387b5409597Saugustss 
388e0cc03a0Sjdolecek int
irframekqfilter(dev_t dev,struct knote * kn)389e0cc03a0Sjdolecek irframekqfilter(dev_t dev, struct knote *kn)
390e0cc03a0Sjdolecek {
391e0cc03a0Sjdolecek 	struct irframe_softc *sc;
392e0cc03a0Sjdolecek 
393fc8fd752Scegger 	sc = device_lookup_private(&irframe_cd, IRFRAMEUNIT(dev));
394a6b5eb2bScube 	if (!device_is_active(sc->sc_dev) || !sc->sc_open)
395e0cc03a0Sjdolecek 		return (1);
396e0cc03a0Sjdolecek 
397e0cc03a0Sjdolecek 	return (sc->sc_methods->im_kqfilter(sc->sc_handle, kn));
398e0cc03a0Sjdolecek }
399