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