1*c35aa225Smarx /*
2*c35aa225Smarx * CDDL HEADER START
3*c35aa225Smarx *
4*c35aa225Smarx * The contents of this file are subject to the terms of the
5*c35aa225Smarx * Common Development and Distribution License (the "License").
6*c35aa225Smarx * You may not use this file except in compliance with the License.
7*c35aa225Smarx *
8*c35aa225Smarx * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*c35aa225Smarx * or http://www.opensolaris.org/os/licensing.
10*c35aa225Smarx * See the License for the specific language governing permissions
11*c35aa225Smarx * and limitations under the License.
12*c35aa225Smarx *
13*c35aa225Smarx * When distributing Covered Code, include this CDDL HEADER in each
14*c35aa225Smarx * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*c35aa225Smarx * If applicable, add the following below this CDDL HEADER, with the
16*c35aa225Smarx * fields enclosed by brackets "[]" replaced with your own identifying
17*c35aa225Smarx * information: Portions Copyright [yyyy] [name of copyright owner]
18*c35aa225Smarx *
19*c35aa225Smarx * CDDL HEADER END
20*c35aa225Smarx */
21*c35aa225Smarx /*
22*c35aa225Smarx * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23*c35aa225Smarx * Use is subject to license terms.
24*c35aa225Smarx */
25*c35aa225Smarx
26*c35aa225Smarx /*
27*c35aa225Smarx * This is the Beep module for supporting keyboard beep for keyboards
28*c35aa225Smarx * that do not have the beeping feature within themselves
29*c35aa225Smarx *
30*c35aa225Smarx */
31*c35aa225Smarx
32*c35aa225Smarx #include <sys/types.h>
33*c35aa225Smarx #include <sys/conf.h>
34*c35aa225Smarx
35*c35aa225Smarx #include <sys/ddi.h>
36*c35aa225Smarx #include <sys/sunddi.h>
37*c35aa225Smarx #include <sys/modctl.h>
38*c35aa225Smarx #include <sys/ddi_impldefs.h>
39*c35aa225Smarx #include <sys/kmem.h>
40*c35aa225Smarx
41*c35aa225Smarx #include <sys/beep.h>
42*c35aa225Smarx #include <sys/inttypes.h>
43*c35aa225Smarx
44*c35aa225Smarx /*
45*c35aa225Smarx * Debug stuff
46*c35aa225Smarx * BEEP_DEBUG used for errors
47*c35aa225Smarx * BEEP_DEBUG1 prints when beep_debug > 1 and used for normal messages
48*c35aa225Smarx */
49*c35aa225Smarx #ifdef DEBUG
50*c35aa225Smarx int beep_debug = 0;
51*c35aa225Smarx #define BEEP_DEBUG(args) if (beep_debug) cmn_err args
52*c35aa225Smarx #define BEEP_DEBUG1(args) if (beep_debug > 1) cmn_err args
53*c35aa225Smarx #else
54*c35aa225Smarx #define BEEP_DEBUG(args)
55*c35aa225Smarx #define BEEP_DEBUG1(args)
56*c35aa225Smarx #endif
57*c35aa225Smarx
58*c35aa225Smarx int beep_queue_size = BEEP_QUEUE_SIZE;
59*c35aa225Smarx
60*c35aa225Smarx /*
61*c35aa225Smarx * Note that mutex_init is not called on the mutex in beep_state,
62*c35aa225Smarx * But assumes that zeroed memory does not need to call mutex_init,
63*c35aa225Smarx * as documented in mutex.c
64*c35aa225Smarx */
65*c35aa225Smarx
66*c35aa225Smarx beep_state_t beep_state;
67*c35aa225Smarx
68*c35aa225Smarx beep_params_t beep_params[] = {
69*c35aa225Smarx {BEEP_CONSOLE, 900, 200},
70*c35aa225Smarx {BEEP_TYPE4, 2000, 0},
71*c35aa225Smarx {BEEP_DEFAULT, 1000, 200}, /* Must be last */
72*c35aa225Smarx };
73*c35aa225Smarx
74*c35aa225Smarx
75*c35aa225Smarx /*
76*c35aa225Smarx * beep_init:
77*c35aa225Smarx * Allocate the beep_queue structure
78*c35aa225Smarx * Initialize beep_state structure
79*c35aa225Smarx * Called from beep driver attach routine
80*c35aa225Smarx */
81*c35aa225Smarx
82*c35aa225Smarx int
beep_init(void * arg,beep_on_func_t beep_on_func,beep_off_func_t beep_off_func,beep_freq_func_t beep_freq_func)83*c35aa225Smarx beep_init(void *arg,
84*c35aa225Smarx beep_on_func_t beep_on_func,
85*c35aa225Smarx beep_off_func_t beep_off_func,
86*c35aa225Smarx beep_freq_func_t beep_freq_func)
87*c35aa225Smarx {
88*c35aa225Smarx beep_entry_t *queue;
89*c35aa225Smarx
90*c35aa225Smarx BEEP_DEBUG1((CE_CONT,
91*c35aa225Smarx "beep_init(0x%lx, 0x%lx, 0x%lx, 0x%lx) : start.",
92*c35aa225Smarx (unsigned long) arg,
93*c35aa225Smarx (unsigned long) beep_on_func,
94*c35aa225Smarx (unsigned long) beep_off_func,
95*c35aa225Smarx (unsigned long) beep_freq_func));
96*c35aa225Smarx
97*c35aa225Smarx mutex_enter(&beep_state.mutex);
98*c35aa225Smarx
99*c35aa225Smarx if (beep_state.mode != BEEP_UNINIT) {
100*c35aa225Smarx mutex_exit(&beep_state.mutex);
101*c35aa225Smarx BEEP_DEBUG((CE_WARN,
102*c35aa225Smarx "beep_init : beep_state already initialized."));
103*c35aa225Smarx return (DDI_SUCCESS);
104*c35aa225Smarx }
105*c35aa225Smarx
106*c35aa225Smarx queue = kmem_zalloc(sizeof (beep_entry_t) * beep_queue_size,
107*c35aa225Smarx KM_SLEEP);
108*c35aa225Smarx
109*c35aa225Smarx BEEP_DEBUG1((CE_CONT,
110*c35aa225Smarx "beep_init : beep_queue kmem_zalloc(%d) = 0x%lx.",
111*c35aa225Smarx (int)sizeof (beep_entry_t) * beep_queue_size,
112*c35aa225Smarx (unsigned long)queue));
113*c35aa225Smarx
114*c35aa225Smarx if (queue == NULL) {
115*c35aa225Smarx BEEP_DEBUG((CE_WARN,
116*c35aa225Smarx "beep_init : kmem_zalloc of beep_queue failed."));
117*c35aa225Smarx return (DDI_FAILURE);
118*c35aa225Smarx }
119*c35aa225Smarx
120*c35aa225Smarx beep_state.arg = arg;
121*c35aa225Smarx beep_state.mode = BEEP_OFF;
122*c35aa225Smarx beep_state.beep_freq = beep_freq_func;
123*c35aa225Smarx beep_state.beep_on = beep_on_func;
124*c35aa225Smarx beep_state.beep_off = beep_off_func;
125*c35aa225Smarx beep_state.timeout_id = 0;
126*c35aa225Smarx
127*c35aa225Smarx beep_state.queue_head = 0;
128*c35aa225Smarx beep_state.queue_tail = 0;
129*c35aa225Smarx beep_state.queue_size = beep_queue_size;
130*c35aa225Smarx beep_state.queue = queue;
131*c35aa225Smarx
132*c35aa225Smarx mutex_exit(&beep_state.mutex);
133*c35aa225Smarx
134*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_init : done."));
135*c35aa225Smarx return (DDI_SUCCESS);
136*c35aa225Smarx }
137*c35aa225Smarx
138*c35aa225Smarx
139*c35aa225Smarx int
beep_fini(void)140*c35aa225Smarx beep_fini(void)
141*c35aa225Smarx {
142*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_fini() : start."));
143*c35aa225Smarx
144*c35aa225Smarx (void) beeper_off();
145*c35aa225Smarx
146*c35aa225Smarx mutex_enter(&beep_state.mutex);
147*c35aa225Smarx
148*c35aa225Smarx if (beep_state.mode == BEEP_UNINIT) {
149*c35aa225Smarx mutex_exit(&beep_state.mutex);
150*c35aa225Smarx BEEP_DEBUG((CE_WARN,
151*c35aa225Smarx "beep_fini : beep_state already uninitialized."));
152*c35aa225Smarx return (0);
153*c35aa225Smarx }
154*c35aa225Smarx
155*c35aa225Smarx if (beep_state.queue != NULL)
156*c35aa225Smarx kmem_free(beep_state.queue,
157*c35aa225Smarx sizeof (beep_entry_t) * beep_state.queue_size);
158*c35aa225Smarx
159*c35aa225Smarx beep_state.arg = (void *)NULL;
160*c35aa225Smarx beep_state.mode = BEEP_UNINIT;
161*c35aa225Smarx beep_state.beep_freq = (beep_freq_func_t)NULL;
162*c35aa225Smarx beep_state.beep_on = (beep_on_func_t)NULL;
163*c35aa225Smarx beep_state.beep_off = (beep_off_func_t)NULL;
164*c35aa225Smarx beep_state.timeout_id = 0;
165*c35aa225Smarx
166*c35aa225Smarx beep_state.queue_head = 0;
167*c35aa225Smarx beep_state.queue_tail = 0;
168*c35aa225Smarx beep_state.queue_size = 0;
169*c35aa225Smarx beep_state.queue = (beep_entry_t *)NULL;
170*c35aa225Smarx
171*c35aa225Smarx mutex_exit(&beep_state.mutex);
172*c35aa225Smarx
173*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_fini() : done."));
174*c35aa225Smarx
175*c35aa225Smarx return (0);
176*c35aa225Smarx }
177*c35aa225Smarx
178*c35aa225Smarx
179*c35aa225Smarx int
beeper_off(void)180*c35aa225Smarx beeper_off(void)
181*c35aa225Smarx {
182*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_off : start."));
183*c35aa225Smarx
184*c35aa225Smarx mutex_enter(&beep_state.mutex);
185*c35aa225Smarx
186*c35aa225Smarx if (beep_state.mode == BEEP_UNINIT) {
187*c35aa225Smarx mutex_exit(&beep_state.mutex);
188*c35aa225Smarx return (ENXIO);
189*c35aa225Smarx }
190*c35aa225Smarx
191*c35aa225Smarx if (beep_state.mode == BEEP_TIMED) {
192*c35aa225Smarx (void) untimeout(beep_state.timeout_id);
193*c35aa225Smarx beep_state.timeout_id = 0;
194*c35aa225Smarx }
195*c35aa225Smarx
196*c35aa225Smarx if (beep_state.mode != BEEP_OFF) {
197*c35aa225Smarx beep_state.mode = BEEP_OFF;
198*c35aa225Smarx
199*c35aa225Smarx if (beep_state.beep_off != NULL)
200*c35aa225Smarx (*beep_state.beep_off)(beep_state.arg);
201*c35aa225Smarx }
202*c35aa225Smarx
203*c35aa225Smarx beep_state.queue_head = 0;
204*c35aa225Smarx beep_state.queue_tail = 0;
205*c35aa225Smarx
206*c35aa225Smarx mutex_exit(&beep_state.mutex);
207*c35aa225Smarx
208*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_off : done."));
209*c35aa225Smarx
210*c35aa225Smarx return (0);
211*c35aa225Smarx }
212*c35aa225Smarx
213*c35aa225Smarx int
beeper_freq(enum beep_type type,int freq)214*c35aa225Smarx beeper_freq(enum beep_type type, int freq)
215*c35aa225Smarx {
216*c35aa225Smarx beep_params_t *bp;
217*c35aa225Smarx
218*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_freq(%d, %d) : start", type, freq));
219*c35aa225Smarx
220*c35aa225Smarx /*
221*c35aa225Smarx * The frequency value is limited to the range of [0 - 32767]
222*c35aa225Smarx */
223*c35aa225Smarx if (freq < 0 || freq > INT16_MAX)
224*c35aa225Smarx return (EINVAL);
225*c35aa225Smarx
226*c35aa225Smarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
227*c35aa225Smarx if (bp->type == type)
228*c35aa225Smarx break;
229*c35aa225Smarx }
230*c35aa225Smarx
231*c35aa225Smarx if (bp->type != type) {
232*c35aa225Smarx BEEP_DEBUG((CE_WARN, "beeper_freq : invalid type."));
233*c35aa225Smarx
234*c35aa225Smarx return (EINVAL);
235*c35aa225Smarx }
236*c35aa225Smarx
237*c35aa225Smarx bp->frequency = freq;
238*c35aa225Smarx
239*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_freq : done."));
240*c35aa225Smarx return (0);
241*c35aa225Smarx }
242*c35aa225Smarx
243*c35aa225Smarx /*
244*c35aa225Smarx * beep :
245*c35aa225Smarx * Start beeping for period specified by the type value,
246*c35aa225Smarx * from the value in the beep_param structure in milliseconds.
247*c35aa225Smarx */
248*c35aa225Smarx int
beep(enum beep_type type)249*c35aa225Smarx beep(enum beep_type type)
250*c35aa225Smarx {
251*c35aa225Smarx
252*c35aa225Smarx beep_params_t *bp;
253*c35aa225Smarx
254*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep(%d) : start.", type));
255*c35aa225Smarx
256*c35aa225Smarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
257*c35aa225Smarx if (bp->type == type)
258*c35aa225Smarx break;
259*c35aa225Smarx }
260*c35aa225Smarx
261*c35aa225Smarx if (bp->type != type) {
262*c35aa225Smarx
263*c35aa225Smarx BEEP_DEBUG((CE_WARN, "beep : invalid type."));
264*c35aa225Smarx
265*c35aa225Smarx /* If type doesn't match, return silently without beeping */
266*c35aa225Smarx return (EINVAL);
267*c35aa225Smarx }
268*c35aa225Smarx
269*c35aa225Smarx return (beep_mktone(bp->frequency, bp->duration));
270*c35aa225Smarx }
271*c35aa225Smarx
272*c35aa225Smarx
273*c35aa225Smarx /*ARGSUSED*/
274*c35aa225Smarx int
beep_polled(enum beep_type type)275*c35aa225Smarx beep_polled(enum beep_type type)
276*c35aa225Smarx {
277*c35aa225Smarx /*
278*c35aa225Smarx * No-op at this time.
279*c35aa225Smarx *
280*c35aa225Smarx * Don't think we can make this work in general, as tem_safe
281*c35aa225Smarx * has a requirement of no mutexes, but kbd sends messages
282*c35aa225Smarx * through streams.
283*c35aa225Smarx */
284*c35aa225Smarx
285*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_polled(%d)", type));
286*c35aa225Smarx
287*c35aa225Smarx return (0);
288*c35aa225Smarx }
289*c35aa225Smarx
290*c35aa225Smarx /*
291*c35aa225Smarx * beeper_on :
292*c35aa225Smarx * Turn the beeper on
293*c35aa225Smarx */
294*c35aa225Smarx int
beeper_on(enum beep_type type)295*c35aa225Smarx beeper_on(enum beep_type type)
296*c35aa225Smarx {
297*c35aa225Smarx beep_params_t *bp;
298*c35aa225Smarx int status = 0;
299*c35aa225Smarx
300*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_on(%d) : start.", type));
301*c35aa225Smarx
302*c35aa225Smarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
303*c35aa225Smarx if (bp->type == type)
304*c35aa225Smarx break;
305*c35aa225Smarx }
306*c35aa225Smarx
307*c35aa225Smarx if (bp->type != type) {
308*c35aa225Smarx
309*c35aa225Smarx BEEP_DEBUG((CE_WARN, "beeper_on : invalid type."));
310*c35aa225Smarx
311*c35aa225Smarx /* If type doesn't match, return silently without beeping */
312*c35aa225Smarx return (EINVAL);
313*c35aa225Smarx }
314*c35aa225Smarx
315*c35aa225Smarx mutex_enter(&beep_state.mutex);
316*c35aa225Smarx
317*c35aa225Smarx if (beep_state.mode == BEEP_UNINIT) {
318*c35aa225Smarx status = ENXIO;
319*c35aa225Smarx
320*c35aa225Smarx /* Start another beep only if the previous one is over */
321*c35aa225Smarx } else if (beep_state.mode == BEEP_OFF) {
322*c35aa225Smarx if (bp->frequency != 0) {
323*c35aa225Smarx beep_state.mode = BEEP_ON;
324*c35aa225Smarx
325*c35aa225Smarx if (beep_state.beep_freq != NULL)
326*c35aa225Smarx (*beep_state.beep_freq)(beep_state.arg,
327*c35aa225Smarx bp->frequency);
328*c35aa225Smarx
329*c35aa225Smarx if (beep_state.beep_on != NULL)
330*c35aa225Smarx (*beep_state.beep_on)(beep_state.arg);
331*c35aa225Smarx }
332*c35aa225Smarx } else {
333*c35aa225Smarx status = EBUSY;
334*c35aa225Smarx }
335*c35aa225Smarx
336*c35aa225Smarx mutex_exit(&beep_state.mutex);
337*c35aa225Smarx
338*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_on : done, status %d.", status));
339*c35aa225Smarx
340*c35aa225Smarx return (status);
341*c35aa225Smarx }
342*c35aa225Smarx
343*c35aa225Smarx
344*c35aa225Smarx int
beep_mktone(int frequency,int duration)345*c35aa225Smarx beep_mktone(int frequency, int duration)
346*c35aa225Smarx {
347*c35aa225Smarx int next;
348*c35aa225Smarx int status = 0;
349*c35aa225Smarx
350*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_mktone(%d, %d) : start.", frequency,
351*c35aa225Smarx duration));
352*c35aa225Smarx
353*c35aa225Smarx /*
354*c35aa225Smarx * The frequency value is limited to the range of [0 - 32767]
355*c35aa225Smarx */
356*c35aa225Smarx if (frequency < 0 || frequency > INT16_MAX)
357*c35aa225Smarx return (EINVAL);
358*c35aa225Smarx
359*c35aa225Smarx mutex_enter(&beep_state.mutex);
360*c35aa225Smarx
361*c35aa225Smarx if (beep_state.mode == BEEP_UNINIT) {
362*c35aa225Smarx status = ENXIO;
363*c35aa225Smarx
364*c35aa225Smarx } else if (beep_state.mode == BEEP_TIMED) {
365*c35aa225Smarx
366*c35aa225Smarx /* If already processing a beep, queue this one */
367*c35aa225Smarx
368*c35aa225Smarx if (frequency != 0) {
369*c35aa225Smarx next = beep_state.queue_tail + 1;
370*c35aa225Smarx if (next == beep_state.queue_size)
371*c35aa225Smarx next = 0;
372*c35aa225Smarx
373*c35aa225Smarx if (next != beep_state.queue_head) {
374*c35aa225Smarx /*
375*c35aa225Smarx * If there is room in the queue,
376*c35aa225Smarx * add this entry
377*c35aa225Smarx */
378*c35aa225Smarx
379*c35aa225Smarx beep_state.queue[beep_state.queue_tail].
380*c35aa225Smarx frequency = (unsigned short)frequency;
381*c35aa225Smarx
382*c35aa225Smarx beep_state.queue[beep_state.queue_tail].
383*c35aa225Smarx duration = (unsigned short)duration;
384*c35aa225Smarx
385*c35aa225Smarx beep_state.queue_tail = next;
386*c35aa225Smarx } else {
387*c35aa225Smarx status = EAGAIN;
388*c35aa225Smarx }
389*c35aa225Smarx }
390*c35aa225Smarx
391*c35aa225Smarx } else if (beep_state.mode == BEEP_OFF) {
392*c35aa225Smarx
393*c35aa225Smarx /* Start another beep only if the previous one is over */
394*c35aa225Smarx
395*c35aa225Smarx if (frequency != 0) {
396*c35aa225Smarx beep_state.mode = BEEP_TIMED;
397*c35aa225Smarx
398*c35aa225Smarx if (beep_state.beep_freq != NULL)
399*c35aa225Smarx (*beep_state.beep_freq)(beep_state.arg,
400*c35aa225Smarx frequency);
401*c35aa225Smarx
402*c35aa225Smarx if (beep_state.beep_on != NULL)
403*c35aa225Smarx (*beep_state.beep_on)(beep_state.arg);
404*c35aa225Smarx
405*c35aa225Smarx /*
406*c35aa225Smarx * Set timeout for ending the beep after the
407*c35aa225Smarx * specified time
408*c35aa225Smarx */
409*c35aa225Smarx
410*c35aa225Smarx beep_state.timeout_id = timeout(beep_timeout, NULL,
411*c35aa225Smarx drv_usectohz(duration * 1000));
412*c35aa225Smarx }
413*c35aa225Smarx } else {
414*c35aa225Smarx status = EBUSY;
415*c35aa225Smarx }
416*c35aa225Smarx
417*c35aa225Smarx mutex_exit(&beep_state.mutex);
418*c35aa225Smarx
419*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_mktone : done, status %d.", status));
420*c35aa225Smarx
421*c35aa225Smarx return (status);
422*c35aa225Smarx }
423*c35aa225Smarx
424*c35aa225Smarx
425*c35aa225Smarx /*
426*c35aa225Smarx * Turn the beeper off which had been turned on from beep()
427*c35aa225Smarx * for a specified period of time
428*c35aa225Smarx */
429*c35aa225Smarx /*ARGSUSED*/
430*c35aa225Smarx void
beep_timeout(void * arg)431*c35aa225Smarx beep_timeout(void *arg)
432*c35aa225Smarx {
433*c35aa225Smarx int frequency;
434*c35aa225Smarx int duration;
435*c35aa225Smarx int next;
436*c35aa225Smarx
437*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beeper_timeout : start."));
438*c35aa225Smarx
439*c35aa225Smarx mutex_enter(&beep_state.mutex);
440*c35aa225Smarx
441*c35aa225Smarx beep_state.timeout_id = 0;
442*c35aa225Smarx
443*c35aa225Smarx if (beep_state.mode == BEEP_UNINIT) {
444*c35aa225Smarx mutex_exit(&beep_state.mutex);
445*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_timeout : uninitialized."));
446*c35aa225Smarx return;
447*c35aa225Smarx }
448*c35aa225Smarx
449*c35aa225Smarx if ((beep_state.mode == BEEP_ON) ||
450*c35aa225Smarx (beep_state.mode == BEEP_TIMED)) {
451*c35aa225Smarx
452*c35aa225Smarx beep_state.mode = BEEP_OFF;
453*c35aa225Smarx
454*c35aa225Smarx if (beep_state.beep_off != NULL)
455*c35aa225Smarx (*beep_state.beep_off)(beep_state.arg);
456*c35aa225Smarx }
457*c35aa225Smarx
458*c35aa225Smarx if (beep_state.queue_head != beep_state.queue_tail) {
459*c35aa225Smarx
460*c35aa225Smarx next = beep_state.queue_head;
461*c35aa225Smarx
462*c35aa225Smarx frequency = beep_state.queue[next].frequency;
463*c35aa225Smarx
464*c35aa225Smarx duration = beep_state.queue[next].duration;
465*c35aa225Smarx
466*c35aa225Smarx next++;
467*c35aa225Smarx if (next == beep_state.queue_size)
468*c35aa225Smarx next = 0;
469*c35aa225Smarx
470*c35aa225Smarx beep_state.queue_head = next;
471*c35aa225Smarx
472*c35aa225Smarx beep_state.mode = BEEP_TIMED;
473*c35aa225Smarx
474*c35aa225Smarx if (frequency != 0) {
475*c35aa225Smarx if (beep_state.beep_freq != NULL)
476*c35aa225Smarx (*beep_state.beep_freq)(beep_state.arg,
477*c35aa225Smarx frequency);
478*c35aa225Smarx
479*c35aa225Smarx if (beep_state.beep_on != NULL)
480*c35aa225Smarx (*beep_state.beep_on)(beep_state.arg);
481*c35aa225Smarx }
482*c35aa225Smarx
483*c35aa225Smarx /* Set timeout for ending the beep after the specified time */
484*c35aa225Smarx
485*c35aa225Smarx beep_state.timeout_id = timeout(beep_timeout, NULL,
486*c35aa225Smarx drv_usectohz(duration * 1000));
487*c35aa225Smarx }
488*c35aa225Smarx
489*c35aa225Smarx mutex_exit(&beep_state.mutex);
490*c35aa225Smarx
491*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_timeout : done."));
492*c35aa225Smarx }
493*c35aa225Smarx
494*c35aa225Smarx
495*c35aa225Smarx /*
496*c35aa225Smarx * Return true (1) if we are sounding a tone.
497*c35aa225Smarx */
498*c35aa225Smarx int
beep_busy(void)499*c35aa225Smarx beep_busy(void)
500*c35aa225Smarx {
501*c35aa225Smarx int status;
502*c35aa225Smarx
503*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_busy : start."));
504*c35aa225Smarx
505*c35aa225Smarx mutex_enter(&beep_state.mutex);
506*c35aa225Smarx
507*c35aa225Smarx status = beep_state.mode != BEEP_UNINIT &&
508*c35aa225Smarx beep_state.mode != BEEP_OFF;
509*c35aa225Smarx
510*c35aa225Smarx mutex_exit(&beep_state.mutex);
511*c35aa225Smarx
512*c35aa225Smarx BEEP_DEBUG1((CE_CONT, "beep_busy : status %d.", status));
513*c35aa225Smarx
514*c35aa225Smarx return (status);
515*c35aa225Smarx }
516