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 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 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 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 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 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 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 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 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 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 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