int beeper_freq(enum beep_type type, int freq) { beep_params_t *bp; BEEP_DEBUG1((CE_CONT, "beeper_freq(%d, %d) : start", type, freq)); /* * The frequency value is limited to the range of [0 - 32767] */ if (freq < 0 || freq > INT16_MAX) return (EINVAL); for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) { if (bp->type == type) break; } if (bp->type != type) { BEEP_DEBUG((CE_WARN, "beeper_freq : invalid type.")); return (EINVAL); } bp->frequency = freq; BEEP_DEBUG1((CE_CONT, "beeper_freq : done.")); return (0); }
int beeper_off(void) { BEEP_DEBUG1((CE_CONT, "beeper_off : start.")); mutex_enter(&beep_state.mutex); if (beep_state.mode == BEEP_UNINIT) { mutex_exit(&beep_state.mutex); return (ENXIO); } if (beep_state.mode == BEEP_TIMED) { (void) untimeout(beep_state.timeout_id); beep_state.timeout_id = 0; } if (beep_state.mode != BEEP_OFF) { beep_state.mode = BEEP_OFF; if (beep_state.beep_off != NULL) (*beep_state.beep_off)(beep_state.arg); } beep_state.queue_head = 0; beep_state.queue_tail = 0; mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beeper_off : done.")); return (0); }
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) { beep_entry_t *queue; BEEP_DEBUG1((CE_CONT, "beep_init(0x%lx, 0x%lx, 0x%lx, 0x%lx) : start.", (unsigned long) arg, (unsigned long) beep_on_func, (unsigned long) beep_off_func, (unsigned long) beep_freq_func)); mutex_enter(&beep_state.mutex); if (beep_state.mode != BEEP_UNINIT) { mutex_exit(&beep_state.mutex); BEEP_DEBUG((CE_WARN, "beep_init : beep_state already initialized.")); return (DDI_SUCCESS); } queue = kmem_zalloc(sizeof (beep_entry_t) * beep_queue_size, KM_SLEEP); BEEP_DEBUG1((CE_CONT, "beep_init : beep_queue kmem_zalloc(%d) = 0x%lx.", (int)sizeof (beep_entry_t) * beep_queue_size, (unsigned long)queue)); if (queue == NULL) { BEEP_DEBUG((CE_WARN, "beep_init : kmem_zalloc of beep_queue failed.")); return (DDI_FAILURE); } beep_state.arg = arg; beep_state.mode = BEEP_OFF; beep_state.beep_freq = beep_freq_func; beep_state.beep_on = beep_on_func; beep_state.beep_off = beep_off_func; beep_state.timeout_id = 0; beep_state.queue_head = 0; beep_state.queue_tail = 0; beep_state.queue_size = beep_queue_size; beep_state.queue = queue; mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_init : done.")); return (DDI_SUCCESS); }
/* * beeper_on : * Turn the beeper on */ int beeper_on(enum beep_type type) { beep_params_t *bp; int status = 0; BEEP_DEBUG1((CE_CONT, "beeper_on(%d) : start.", type)); for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) { if (bp->type == type) break; } if (bp->type != type) { BEEP_DEBUG((CE_WARN, "beeper_on : invalid type.")); /* If type doesn't match, return silently without beeping */ return (EINVAL); } mutex_enter(&beep_state.mutex); if (beep_state.mode == BEEP_UNINIT) { status = ENXIO; /* Start another beep only if the previous one is over */ } else if (beep_state.mode == BEEP_OFF) { if (bp->frequency != 0) { beep_state.mode = BEEP_ON; if (beep_state.beep_freq != NULL) (*beep_state.beep_freq)(beep_state.arg, bp->frequency); if (beep_state.beep_on != NULL) (*beep_state.beep_on)(beep_state.arg); } } else { status = EBUSY; } mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beeper_on : done, status %d.", status)); return (status); }
/* * beep : * Start beeping for period specified by 'time' (in microsecond) */ void beep(enum beep_type type) { struct beep_params *bp; BEEP_DEBUG1((CE_CONT, "beep : Start")); if (beep_statep == NULL) { return; } for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) { if (bp->type == type) break; } if (bp->type != type) { /* If type doesn't match, return silently without beeping */ return; } mutex_enter(&beep_statep->beep_state_mutex); /* Beep only when no previous beep is in progress */ if (beep_statep->beep_state_mode == BEEP_OFF) { beep_statep->beep_state_mode = BEEP_TIMED; (*beep_statep->beep_state_beep_freq)(beep_statep-> beep_state_beep_dip, bp->frequency); (*beep_statep->beep_state_beep_on)(beep_statep-> beep_state_beep_dip); /* Set timeout for ending the beep after the specified time */ beep_statep->beep_state_timeout_id = timeout(beep_timeout, NULL, drv_usectohz(bp->duration*1000)); } mutex_exit(&beep_statep->beep_state_mutex); BEEP_DEBUG1((CE_CONT, "beep : Done")); }
/* * Return true (1) if we are sounding a tone. */ int beep_busy(void) { int status; BEEP_DEBUG1((CE_CONT, "beep_busy : start.")); mutex_enter(&beep_state.mutex); status = beep_state.mode != BEEP_UNINIT && beep_state.mode != BEEP_OFF; mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_busy : status %d.", status)); return (status); }
/* * Turn the beeper off which had been turned on from beep() * for a specified period of time */ void beep_timeout() { BEEP_DEBUG1((CE_CONT, "beeper_timeout : Start")); beep_statep->beep_state_timeout_id = 0; mutex_enter(&beep_statep->beep_state_mutex); if ((beep_statep->beep_state_mode == BEEP_ON) || (beep_statep->beep_state_mode == BEEP_TIMED)) { beep_statep->beep_state_mode = BEEP_OFF; (*beep_statep->beep_state_beep_off)(beep_statep-> beep_state_beep_dip); } mutex_exit(&beep_statep->beep_state_mutex); BEEP_DEBUG1((CE_CONT, "beeper_timeout : Done")); }
/* * beeper_on : * Turn the beeper on */ void beeper_on(enum beep_type type) { struct beep_params *bp; BEEP_DEBUG1((CE_CONT, "beeper_on : Start")); if (beep_statep == NULL) { return; } for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) { if (bp->type == type) break; } if (bp->type != type) { /* If type doesn't match, return silently */ return; } mutex_enter(&beep_statep->beep_state_mutex); /* Start another beep only if the previous one is over */ if (beep_statep->beep_state_mode == BEEP_OFF) { beep_statep->beep_state_mode = BEEP_ON; (*beep_statep->beep_state_beep_freq)(beep_statep-> beep_state_beep_dip, bp->frequency); (*beep_statep->beep_state_beep_on)(beep_statep-> beep_state_beep_dip); } mutex_exit(&beep_statep->beep_state_mutex); BEEP_DEBUG1((CE_CONT, "beeper_on : Done")); }
int beep_fini(void) { BEEP_DEBUG1((CE_CONT, "beep_fini() : start.")); (void) beeper_off(); mutex_enter(&beep_state.mutex); if (beep_state.mode == BEEP_UNINIT) { mutex_exit(&beep_state.mutex); BEEP_DEBUG((CE_WARN, "beep_fini : beep_state already uninitialized.")); return (0); } if (beep_state.queue != NULL) kmem_free(beep_state.queue, sizeof (beep_entry_t) * beep_state.queue_size); beep_state.arg = (void *)NULL; beep_state.mode = BEEP_UNINIT; beep_state.beep_freq = (beep_freq_func_t)NULL; beep_state.beep_on = (beep_on_func_t)NULL; beep_state.beep_off = (beep_off_func_t)NULL; beep_state.timeout_id = 0; beep_state.queue_head = 0; beep_state.queue_tail = 0; beep_state.queue_size = 0; beep_state.queue = (beep_entry_t *)NULL; mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_fini() : done.")); return (0); }
/* * beep_init : * Alloc beep_state structure * called from the beep driver attach routine */ int beep_init(dev_info_t *dip, void (*hwbeep_beep_on)(dev_info_t *), void (*hwbeep_beep_off)(dev_info_t *), void (*hwbeep_beep_freq)(dev_info_t *, int)) { BEEP_DEBUG1((CE_CONT, "beep_init : start")); if (dip == NULL) { return (DDI_FAILURE); } if ((hwbeep_beep_on == NULL) || (hwbeep_beep_off == NULL) || (hwbeep_beep_freq == NULL)) { BEEP_DEBUG((CE_WARN, "beep_init : Null routines passed for registration.")); return (DDI_FAILURE); } beep_statep = kmem_zalloc(sizeof (beep_state_t), KM_SLEEP); if (beep_statep == NULL) { BEEP_DEBUG((CE_WARN, "beep_init : kmem_zalloc failed.")); return (DDI_FAILURE); } beep_statep->beep_state_beep_dip = dip; beep_statep->beep_state_beep_on = hwbeep_beep_on; beep_statep->beep_state_beep_off = hwbeep_beep_off; beep_statep->beep_state_beep_freq = hwbeep_beep_freq; beep_statep->beep_state_mode = BEEP_OFF; mutex_init(&beep_statep->beep_state_mutex, NULL, MUTEX_DRIVER, NULL); BEEP_DEBUG1((CE_CONT, "beep_init : Done.")); return (DDI_SUCCESS); }
/* * beeper_off : * Turn the beeper off */ void beeper_off() { BEEP_DEBUG1((CE_CONT, "beeper_off : Start")); if (beep_statep == NULL) { return; } mutex_enter(&beep_statep->beep_state_mutex); if (beep_statep->beep_state_mode == BEEP_ON) { beep_statep->beep_state_mode = BEEP_OFF; (*beep_statep->beep_state_beep_off)(beep_statep-> beep_state_beep_dip); } mutex_exit(&beep_statep->beep_state_mutex); BEEP_DEBUG1((CE_CONT, "beeper_off : Done")); }
/*ARGSUSED*/ int beep_polled(enum beep_type type) { /* * No-op at this time. * * Don't think we can make this work in general, as tem_safe * has a requirement of no mutexes, but kbd sends messages * through streams. */ BEEP_DEBUG1((CE_CONT, "beep_polled(%d)", type)); return (0); }
/* * beep : * Start beeping for period specified by the type value, * from the value in the beep_param structure in milliseconds. */ int beep(enum beep_type type) { beep_params_t *bp; BEEP_DEBUG1((CE_CONT, "beep(%d) : start.", type)); for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) { if (bp->type == type) break; } if (bp->type != type) { BEEP_DEBUG((CE_WARN, "beep : invalid type.")); /* If type doesn't match, return silently without beeping */ return (EINVAL); } return (beep_mktone(bp->frequency, bp->duration)); }
/*ARGSUSED*/ void beep_timeout(void *arg) { int frequency; int duration; int next; BEEP_DEBUG1((CE_CONT, "beeper_timeout : start.")); mutex_enter(&beep_state.mutex); beep_state.timeout_id = 0; if (beep_state.mode == BEEP_UNINIT) { mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_timeout : uninitialized.")); return; } if ((beep_state.mode == BEEP_ON) || (beep_state.mode == BEEP_TIMED)) { beep_state.mode = BEEP_OFF; if (beep_state.beep_off != NULL) (*beep_state.beep_off)(beep_state.arg); } if (beep_state.queue_head != beep_state.queue_tail) { next = beep_state.queue_head; frequency = beep_state.queue[next].frequency; duration = beep_state.queue[next].duration; next++; if (next == beep_state.queue_size) next = 0; beep_state.queue_head = next; beep_state.mode = BEEP_TIMED; if (frequency != 0) { if (beep_state.beep_freq != NULL) (*beep_state.beep_freq)(beep_state.arg, frequency); if (beep_state.beep_on != NULL) (*beep_state.beep_on)(beep_state.arg); } /* Set timeout for ending the beep after the specified time */ beep_state.timeout_id = timeout(beep_timeout, NULL, drv_usectohz(duration * 1000)); } mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_timeout : done.")); }
int beep_mktone(int frequency, int duration) { int next; int status = 0; BEEP_DEBUG1((CE_CONT, "beep_mktone(%d, %d) : start.", frequency, duration)); /* * The frequency value is limited to the range of [0 - 32767] */ if (frequency < 0 || frequency > INT16_MAX) return (EINVAL); mutex_enter(&beep_state.mutex); if (beep_state.mode == BEEP_UNINIT) { status = ENXIO; } else if (beep_state.mode == BEEP_TIMED) { /* If already processing a beep, queue this one */ if (frequency != 0) { next = beep_state.queue_tail + 1; if (next == beep_state.queue_size) next = 0; if (next != beep_state.queue_head) { /* * If there is room in the queue, * add this entry */ beep_state.queue[beep_state.queue_tail]. frequency = (unsigned short)frequency; beep_state.queue[beep_state.queue_tail]. duration = (unsigned short)duration; beep_state.queue_tail = next; } else { status = EAGAIN; } } } else if (beep_state.mode == BEEP_OFF) { /* Start another beep only if the previous one is over */ if (frequency != 0) { beep_state.mode = BEEP_TIMED; if (beep_state.beep_freq != NULL) (*beep_state.beep_freq)(beep_state.arg, frequency); if (beep_state.beep_on != NULL) (*beep_state.beep_on)(beep_state.arg); /* * Set timeout for ending the beep after the * specified time */ beep_state.timeout_id = timeout(beep_timeout, NULL, drv_usectohz(duration * 1000)); } } else { status = EBUSY; } mutex_exit(&beep_state.mutex); BEEP_DEBUG1((CE_CONT, "beep_mktone : done, status %d.", status)); return (status); }