| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: wsbell.c,v 1.6 2017/06/13 00:49:05 nat Exp $ */ | | 1 | /* $NetBSD: wsbell.c,v 1.7 2017/06/13 00:54:37 nat Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2017 Nathanial Sloss <nathanialsloss@yahoo.com.au> | | 4 | * Copyright (c) 2017 Nathanial Sloss <nathanialsloss@yahoo.com.au> |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * Copyright (c) 2006 The NetBSD Foundation, Inc. | | 7 | * Copyright (c) 2006 The NetBSD Foundation, Inc. |
8 | * All rights reserved. | | 8 | * All rights reserved. |
9 | * | | 9 | * |
10 | * This code is derived from software contributed to The NetBSD Foundation | | 10 | * This code is derived from software contributed to The NetBSD Foundation |
11 | * by Julio M. Merino Vidal. | | 11 | * by Julio M. Merino Vidal. |
12 | * | | 12 | * |
13 | * Redistribution and use in source and binary forms, with or without | | 13 | * Redistribution and use in source and binary forms, with or without |
14 | * modification, are permitted provided that the following conditions | | 14 | * modification, are permitted provided that the following conditions |
| @@ -97,27 +97,27 @@ | | | @@ -97,27 +97,27 @@ |
97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 97 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 98 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 99 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
100 | * SUCH DAMAGE. | | 100 | * SUCH DAMAGE. |
101 | * | | 101 | * |
102 | * @(#)ms.c 8.1 (Berkeley) 6/11/93 | | 102 | * @(#)ms.c 8.1 (Berkeley) 6/11/93 |
103 | */ | | 103 | */ |
104 | | | 104 | |
105 | /* | | 105 | /* |
106 | * Keyboard Bell driver. | | 106 | * Keyboard Bell driver. |
107 | */ | | 107 | */ |
108 | | | 108 | |
109 | #include <sys/cdefs.h> | | 109 | #include <sys/cdefs.h> |
110 | __KERNEL_RCSID(0, "$NetBSD: wsbell.c,v 1.6 2017/06/13 00:49:05 nat Exp $"); | | 110 | __KERNEL_RCSID(0, "$NetBSD: wsbell.c,v 1.7 2017/06/13 00:54:37 nat Exp $"); |
111 | | | 111 | |
112 | #if defined(_KERNEL_OPT) | | 112 | #if defined(_KERNEL_OPT) |
113 | #include "wsmux.h" | | 113 | #include "wsmux.h" |
114 | #endif | | 114 | #endif |
115 | | | 115 | |
116 | #include <sys/param.h> | | 116 | #include <sys/param.h> |
117 | #include <sys/conf.h> | | 117 | #include <sys/conf.h> |
118 | #include <sys/ioctl.h> | | 118 | #include <sys/ioctl.h> |
119 | #include <sys/poll.h> | | 119 | #include <sys/poll.h> |
120 | #include <sys/fcntl.h> | | 120 | #include <sys/fcntl.h> |
121 | #include <sys/kernel.h> | | 121 | #include <sys/kernel.h> |
122 | #include <sys/condvar.h> | | 122 | #include <sys/condvar.h> |
123 | #include <sys/mutex.h> | | 123 | #include <sys/mutex.h> |
| @@ -210,26 +210,27 @@ wsbell_match(device_t parent, cfdata_t m | | | @@ -210,26 +210,27 @@ wsbell_match(device_t parent, cfdata_t m |
210 | | | 210 | |
211 | void | | 211 | void |
212 | wsbell_attach(device_t parent, device_t self, void *aux) | | 212 | wsbell_attach(device_t parent, device_t self, void *aux) |
213 | { | | 213 | { |
214 | struct wsbell_softc *sc = device_private(self); | | 214 | struct wsbell_softc *sc = device_private(self); |
215 | struct wsbelldev_attach_args *ap = aux; | | 215 | struct wsbelldev_attach_args *ap = aux; |
216 | #if NWSMUX > 0 | | 216 | #if NWSMUX > 0 |
217 | int mux, error; | | 217 | int mux, error; |
218 | #endif | | 218 | #endif |
219 | | | 219 | |
220 | sc->sc_base.me_dv = self; | | 220 | sc->sc_base.me_dv = self; |
221 | sc->sc_accesscookie = ap->accesscookie; | | 221 | sc->sc_accesscookie = ap->accesscookie; |
222 | | | 222 | |
| | | 223 | sc->sc_dying = false; |
223 | sc->sc_spkr = device_unit(parent); | | 224 | sc->sc_spkr = device_unit(parent); |
224 | sc->sc_bell_data = wskbd_default_bell_data; | | 225 | sc->sc_bell_data = wskbd_default_bell_data; |
225 | #if NWSMUX > 0 | | 226 | #if NWSMUX > 0 |
226 | sc->sc_base.me_ops = &wsbell_srcops; | | 227 | sc->sc_base.me_ops = &wsbell_srcops; |
227 | mux = device_cfdata(self)->wsbelldevcf_mux; | | 228 | mux = device_cfdata(self)->wsbelldevcf_mux; |
228 | if (mux >= 0) { | | 229 | if (mux >= 0) { |
229 | error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base); | | 230 | error = wsmux_attach_sc(wsmux_getmux(mux), &sc->sc_base); |
230 | if (error) | | 231 | if (error) |
231 | aprint_error(" attach error=%d", error); | | 232 | aprint_error(" attach error=%d", error); |
232 | else | | 233 | else |
233 | aprint_normal(" mux %d", mux); | | 234 | aprint_normal(" mux %d", mux); |
234 | } | | 235 | } |
235 | #else | | 236 | #else |
| @@ -246,27 +247,27 @@ wsbell_attach(device_t parent, device_t | | | @@ -246,27 +247,27 @@ wsbell_attach(device_t parent, device_t |
246 | mutex_init(&sc->sc_bellock, MUTEX_DEFAULT, IPL_SCHED); | | 247 | mutex_init(&sc->sc_bellock, MUTEX_DEFAULT, IPL_SCHED); |
247 | cv_init(&sc->sc_bellcv, "bellcv"); | | 248 | cv_init(&sc->sc_bellcv, "bellcv"); |
248 | | | 249 | |
249 | kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, | | 250 | kthread_create(PRI_BIO, KTHREAD_MPSAFE | KTHREAD_MUSTJOIN, NULL, |
250 | bell_thread, sc, &sc->sc_bellthread, "%s", device_xname(self)); | | 251 | bell_thread, sc, &sc->sc_bellthread, "%s", device_xname(self)); |
251 | } | | 252 | } |
252 | | | 253 | |
253 | int | | 254 | int |
254 | wsbell_activate(device_t self, enum devact act) | | 255 | wsbell_activate(device_t self, enum devact act) |
255 | { | | 256 | { |
256 | struct wsbell_softc *sc = device_private(self); | | 257 | struct wsbell_softc *sc = device_private(self); |
257 | | | 258 | |
258 | if (act == DVACT_DEACTIVATE) | | 259 | if (act == DVACT_DEACTIVATE) |
259 | sc->sc_dying = 1; | | 260 | sc->sc_dying = true; |
260 | return (0); | | 261 | return (0); |
261 | } | | 262 | } |
262 | | | 263 | |
263 | int | | 264 | int |
264 | wsbell_detach(device_t self, int flags) | | 265 | wsbell_detach(device_t self, int flags) |
265 | { | | 266 | { |
266 | struct wsbell_softc *sc = device_private(self); | | 267 | struct wsbell_softc *sc = device_private(self); |
267 | struct wseventvar *evar; | | 268 | struct wseventvar *evar; |
268 | int maj, mn; | | 269 | int maj, mn; |
269 | int s; | | 270 | int s; |
270 | | | 271 | |
271 | #if NWSMUX > 0 | | 272 | #if NWSMUX > 0 |
272 | /* Tell parent mux we're leaving. */ | | 273 | /* Tell parent mux we're leaving. */ |
| @@ -295,27 +296,27 @@ wsbell_detach(device_t self, int flags) | | | @@ -295,27 +296,27 @@ wsbell_detach(device_t self, int flags) |
295 | device_xname(self)); | | 296 | device_xname(self)); |
296 | } | | 297 | } |
297 | splx(s); | | 298 | splx(s); |
298 | } | | 299 | } |
299 | | | 300 | |
300 | /* locate the major number */ | | 301 | /* locate the major number */ |
301 | maj = cdevsw_lookup_major(&wsbell_cdevsw); | | 302 | maj = cdevsw_lookup_major(&wsbell_cdevsw); |
302 | | | 303 | |
303 | /* Nuke the vnodes for any open instances (calls close). */ | | 304 | /* Nuke the vnodes for any open instances (calls close). */ |
304 | mn = device_unit(self); | | 305 | mn = device_unit(self); |
305 | vdevgone(maj, mn, mn, VCHR); | | 306 | vdevgone(maj, mn, mn, VCHR); |
306 | | | 307 | |
307 | mutex_enter(&sc->sc_bellock); | | 308 | mutex_enter(&sc->sc_bellock); |
308 | sc->sc_dying = 1; | | 309 | sc->sc_dying = true; |
309 | | | 310 | |
310 | cv_broadcast(&sc->sc_bellcv); | | 311 | cv_broadcast(&sc->sc_bellcv); |
311 | mutex_exit(&sc->sc_bellock); | | 312 | mutex_exit(&sc->sc_bellock); |
312 | | | 313 | |
313 | kthread_join(sc->sc_bellthread); | | 314 | kthread_join(sc->sc_bellthread); |
314 | cv_destroy(&sc->sc_bellcv); | | 315 | cv_destroy(&sc->sc_bellcv); |
315 | mutex_destroy(&sc->sc_bellock); | | 316 | mutex_destroy(&sc->sc_bellock); |
316 | | | 317 | |
317 | return (0); | | 318 | return (0); |
318 | } | | 319 | } |
319 | | | 320 | |
320 | #if NWSMUX > 0 | | 321 | #if NWSMUX > 0 |
321 | int | | 322 | int |
| @@ -334,27 +335,27 @@ wsbelldoioctl(device_t dv, u_long cmd, v | | | @@ -334,27 +335,27 @@ wsbelldoioctl(device_t dv, u_long cmd, v |
334 | | | 335 | |
335 | sc->sc_refcnt++; | | 336 | sc->sc_refcnt++; |
336 | error = wsbell_do_ioctl(sc, cmd, data, flag, l); | | 337 | error = wsbell_do_ioctl(sc, cmd, data, flag, l); |
337 | if (--sc->sc_refcnt < 0) | | 338 | if (--sc->sc_refcnt < 0) |
338 | wakeup(sc); | | 339 | wakeup(sc); |
339 | return (error); | | 340 | return (error); |
340 | } | | 341 | } |
341 | | | 342 | |
342 | int | | 343 | int |
343 | wsbell_do_ioctl(struct wsbell_softc *sc, u_long cmd, void *data, | | 344 | wsbell_do_ioctl(struct wsbell_softc *sc, u_long cmd, void *data, |
344 | int flag, struct lwp *l) | | 345 | int flag, struct lwp *l) |
345 | { | | 346 | { |
346 | struct wskbd_bell_data *ubdp, *kbdp; | | 347 | struct wskbd_bell_data *ubdp, *kbdp; |
347 | if (sc->sc_dying) | | 348 | if (sc->sc_dying == true) |
348 | return (EIO); | | 349 | return (EIO); |
349 | | | 350 | |
350 | /* | | 351 | /* |
351 | * Try the wsbell specific ioctls. | | 352 | * Try the wsbell specific ioctls. |
352 | */ | | 353 | */ |
353 | switch (cmd) { | | 354 | switch (cmd) { |
354 | case WSKBDIO_SETBELL: | | 355 | case WSKBDIO_SETBELL: |
355 | if ((flag & FWRITE) == 0) | | 356 | if ((flag & FWRITE) == 0) |
356 | return (EACCES); | | 357 | return (EACCES); |
357 | kbdp = &sc->sc_bell_data; | | 358 | kbdp = &sc->sc_bell_data; |
358 | ubdp = (struct wskbd_bell_data *)data; | | 359 | ubdp = (struct wskbd_bell_data *)data; |
359 | SETBELL(kbdp, ubdp, kbdp); | | 360 | SETBELL(kbdp, ubdp, kbdp); |
360 | return (0); | | 361 | return (0); |
| @@ -390,27 +391,27 @@ wsbell_do_ioctl(struct wsbell_softc *sc, | | | @@ -390,27 +391,27 @@ wsbell_do_ioctl(struct wsbell_softc *sc, |
390 | | | 391 | |
391 | static void | | 392 | static void |
392 | bell_thread(void *arg) | | 393 | bell_thread(void *arg) |
393 | { | | 394 | { |
394 | struct wsbell_softc *sc = arg; | | 395 | struct wsbell_softc *sc = arg; |
395 | struct vbell_args *vb = &sc->sc_bell_args; | | 396 | struct vbell_args *vb = &sc->sc_bell_args; |
396 | tone_t tone; | | 397 | tone_t tone; |
397 | u_int vol; | | 398 | u_int vol; |
398 | | | 399 | |
399 | for (;;) { | | 400 | for (;;) { |
400 | mutex_enter(&sc->sc_bellock); | | 401 | mutex_enter(&sc->sc_bellock); |
401 | cv_wait_sig(&sc->sc_bellcv, &sc->sc_bellock); | | 402 | cv_wait_sig(&sc->sc_bellcv, &sc->sc_bellock); |
402 | | | 403 | |
403 | if (sc->sc_dying) { | | 404 | if (sc->sc_dying == true) { |
404 | mutex_exit(&sc->sc_bellock); | | 405 | mutex_exit(&sc->sc_bellock); |
405 | kthread_exit(0); | | 406 | kthread_exit(0); |
406 | } | | 407 | } |
407 | | | 408 | |
408 | tone.frequency = vb->pitch; | | 409 | tone.frequency = vb->pitch; |
409 | tone.duration = vb->period; | | 410 | tone.duration = vb->period; |
410 | vol = vb->volume; | | 411 | vol = vb->volume; |
411 | mutex_exit(&sc->sc_bellock); | | 412 | mutex_exit(&sc->sc_bellock); |
412 | | | 413 | |
413 | if (spkropen(sc->sc_spkr, FWRITE, 0, NULL) != 0) | | 414 | if (spkropen(sc->sc_spkr, FWRITE, 0, NULL) != 0) |
414 | continue; | | 415 | continue; |
415 | spkrioctl(sc->sc_spkr, SPKRSETVOL, &vol, 0, curlwp); | | 416 | spkrioctl(sc->sc_spkr, SPKRSETVOL, &vol, 0, curlwp); |
416 | spkrioctl(sc->sc_spkr, SPKRTONE, &tone, 0, curlwp); | | 417 | spkrioctl(sc->sc_spkr, SPKRTONE, &tone, 0, curlwp); |