c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * CDDL HEADER START
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * The contents of this file are subject to the terms of the
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Common Development and Distribution License (the "License").
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * You may not use this file except in compliance with the License.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * or http://www.opensolaris.org/os/licensing.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * See the License for the specific language governing permissions
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * and limitations under the License.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * When distributing Covered Code, include this CDDL HEADER in each
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * If applicable, add the following below this CDDL HEADER, with the
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * fields enclosed by brackets "[]" replaced with your own identifying
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * information: Portions Copyright [yyyy] [name of copyright owner]
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * CDDL HEADER END
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Use is subject to license terms.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#pragma ident "%Z%%M% %I% %E% SMI"
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * This is the Beep module for supporting keyboard beep for keyboards
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * that do not have the beeping feature within themselves
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/types.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/conf.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/ddi.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/sunddi.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/modctl.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/ddi_impldefs.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/kmem.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/beep.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#include <sys/inttypes.h>
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Debug stuff
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * BEEP_DEBUG used for errors
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * BEEP_DEBUG1 prints when beep_debug > 1 and used for normal messages
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#ifdef DEBUG
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint beep_debug = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#define BEEP_DEBUG(args) if (beep_debug) cmn_err args
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#define BEEP_DEBUG1(args) if (beep_debug > 1) cmn_err args
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#else
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#define BEEP_DEBUG(args)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#define BEEP_DEBUG1(args)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx#endif
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint beep_queue_size = BEEP_QUEUE_SIZE;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Note that mutex_init is not called on the mutex in beep_state,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * But assumes that zeroed memory does not need to call mutex_init,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * as documented in mutex.c
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_state_t beep_state;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_params_t beep_params[] = {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx {BEEP_CONSOLE, 900, 200},
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx {BEEP_TYPE4, 2000, 0},
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx {BEEP_DEFAULT, 1000, 200}, /* Must be last */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx};
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * beep_init:
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Allocate the beep_queue structure
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Initialize beep_state structure
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Called from beep driver attach routine
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_init(void *arg,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_on_func_t beep_on_func,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_off_func_t beep_off_func,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_freq_func_t beep_freq_func)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_entry_t *queue;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx "beep_init(0x%lx, 0x%lx, 0x%lx, 0x%lx) : start.",
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (unsigned long) arg,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (unsigned long) beep_on_func,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (unsigned long) beep_off_func,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (unsigned long) beep_freq_func));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode != BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx "beep_init : beep_state already initialized."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (DDI_SUCCESS);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx queue = kmem_zalloc(sizeof (beep_entry_t) * beep_queue_size,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx KM_SLEEP);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx "beep_init : beep_queue kmem_zalloc(%d) = 0x%lx.",
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (int)sizeof (beep_entry_t) * beep_queue_size,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (unsigned long)queue));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (queue == NULL) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx "beep_init : kmem_zalloc of beep_queue failed."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (DDI_FAILURE);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.arg = arg;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_OFF;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_freq = beep_freq_func;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_on = beep_on_func;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_off = beep_off_func;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_head = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_tail = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_size = beep_queue_size;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue = queue;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_init : done."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (DDI_SUCCESS);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_fini(void)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_fini() : start."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (void) beeper_off();
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx "beep_fini : beep_state already uninitialized."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (0);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.queue != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx kmem_free(beep_state.queue,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx sizeof (beep_entry_t) * beep_state.queue_size);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.arg = (void *)NULL;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_UNINIT;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_freq = (beep_freq_func_t)NULL;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_on = (beep_on_func_t)NULL;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.beep_off = (beep_off_func_t)NULL;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_head = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_tail = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_size = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue = (beep_entry_t *)NULL;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_fini() : done."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (0);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeeper_off(void)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_off : start."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (ENXIO);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_TIMED) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (void) untimeout(beep_state.timeout_id);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode != BEEP_OFF) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_OFF;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_off != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_off)(beep_state.arg);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_head = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_tail = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_off : done."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (0);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeeper_freq(enum beep_type type, int freq)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_params_t *bp;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_freq(%d, %d) : start", type, freq));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * The frequency value is limited to the range of [0 - 32767]
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (freq < 0 || freq > INT16_MAX)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (EINVAL);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type == type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx break;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type != type) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN, "beeper_freq : invalid type."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (EINVAL);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx bp->frequency = freq;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_freq : done."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (0);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * beep :
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Start beeping for period specified by the type value,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * from the value in the beep_param structure in milliseconds.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep(enum beep_type type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_params_t *bp;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep(%d) : start.", type));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type == type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx break;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type != type) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN, "beep : invalid type."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* If type doesn't match, return silently without beeping */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (EINVAL);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (beep_mktone(bp->frequency, bp->duration));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*ARGSUSED*/
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_polled(enum beep_type type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * No-op at this time.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx *
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Don't think we can make this work in general, as tem_safe
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * has a requirement of no mutexes, but kbd sends messages
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * through streams.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_polled(%d)", type));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (0);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * beeper_on :
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Turn the beeper on
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeeper_on(enum beep_type type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_params_t *bp;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int status = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_on(%d) : start.", type));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type == type)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx break;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->type != type) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG((CE_WARN, "beeper_on : invalid type."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* If type doesn't match, return silently without beeping */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (EINVAL);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = ENXIO;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* Start another beep only if the previous one is over */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else if (beep_state.mode == BEEP_OFF) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (bp->frequency != 0) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_ON;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_freq != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_freq)(beep_state.arg,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx bp->frequency);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_on != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_on)(beep_state.arg);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = EBUSY;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_on : done, status %d.", status));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (status);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_mktone(int frequency, int duration)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int next;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int status = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_mktone(%d, %d) : start.", frequency,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx duration));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * The frequency value is limited to the range of [0 - 32767]
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (frequency < 0 || frequency > INT16_MAX)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (EINVAL);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = ENXIO;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else if (beep_state.mode == BEEP_TIMED) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* If already processing a beep, queue this one */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (frequency != 0) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx next = beep_state.queue_tail + 1;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (next == beep_state.queue_size)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx next = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (next != beep_state.queue_head) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * If there is room in the queue,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * add this entry
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue[beep_state.queue_tail].
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx frequency = (unsigned short)frequency;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue[beep_state.queue_tail].
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx duration = (unsigned short)duration;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_tail = next;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = EAGAIN;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else if (beep_state.mode == BEEP_OFF) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* Start another beep only if the previous one is over */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (frequency != 0) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_TIMED;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_freq != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_freq)(beep_state.arg,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx frequency);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_on != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_on)(beep_state.arg);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Set timeout for ending the beep after the
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * specified time
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = timeout(beep_timeout, NULL,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx drv_usectohz(duration * 1000));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx } else {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = EBUSY;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_mktone : done, status %d.", status));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (status);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Turn the beeper off which had been turned on from beep()
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * for a specified period of time
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*ARGSUSED*/
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxvoid
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_timeout(void *arg)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int frequency;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int duration;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int next;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beeper_timeout : start."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.mode == BEEP_UNINIT) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_timeout : uninitialized."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if ((beep_state.mode == BEEP_ON) ||
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (beep_state.mode == BEEP_TIMED)) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_OFF;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_off != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_off)(beep_state.arg);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.queue_head != beep_state.queue_tail) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx next = beep_state.queue_head;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx frequency = beep_state.queue[next].frequency;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx duration = beep_state.queue[next].duration;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx next++;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (next == beep_state.queue_size)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx next = 0;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.queue_head = next;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode = BEEP_TIMED;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (frequency != 0) {
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_freq != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_freq)(beep_state.arg,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx frequency);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx if (beep_state.beep_on != NULL)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx (*beep_state.beep_on)(beep_state.arg);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx /* Set timeout for ending the beep after the specified time */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.timeout_id = timeout(beep_timeout, NULL,
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx drv_usectohz(duration * 1000));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx }
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_timeout : done."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx/*
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx * Return true (1) if we are sounding a tone.
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx */
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxint
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarxbeep_busy(void)
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx{
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx int status;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_busy : start."));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_enter(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx status = beep_state.mode != BEEP_UNINIT &&
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx beep_state.mode != BEEP_OFF;
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx mutex_exit(&beep_state.mutex);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx BEEP_DEBUG1((CE_CONT, "beep_busy : status %d.", status));
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx return (status);
c35aa225b9ae500f1d14f0d39a94f1eb6cda333dmarx}