summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrz201010 <none@none>2007-01-25 18:23:59 -0800
committerrz201010 <none@none>2007-01-25 18:23:59 -0800
commit8ffc942d5d69695c8690274a7a3649bf0a80d3fb (patch)
treecebeb7273566e5368e0bb259d7844aa9dbfc5381
parentff2aee480f8fc985fe6a84c8d593c7a13c7a0481 (diff)
downloadillumos-joyent-8ffc942d5d69695c8690274a7a3649bf0a80d3fb.tar.gz
4421990 allow changing keyboard bell frequency
-rw-r--r--usr/src/cmd/kbd/kbd.c142
-rw-r--r--usr/src/cmd/kbd/kbd.dfl15
-rw-r--r--usr/src/cmd/truss/codes.c1
-rw-r--r--usr/src/uts/common/io/conskbd.c65
-rw-r--r--usr/src/uts/common/sys/beep.h10
-rw-r--r--usr/src/uts/common/sys/kbio.h14
-rw-r--r--usr/src/uts/intel/io/beeper.c38
-rw-r--r--usr/src/uts/sun4/os/beep.c50
8 files changed, 289 insertions, 46 deletions
diff --git a/usr/src/cmd/kbd/kbd.c b/usr/src/cmd/kbd/kbd.c
index 6bb935147e..10a7582126 100644
--- a/usr/src/cmd/kbd/kbd.c
+++ b/usr/src/cmd/kbd/kbd.c
@@ -27,8 +27,12 @@
/*
- * Usage: kbd [-r] [-t] [-l] [-i] [-c on|off] [-a enable|disable|alternate]
- * [-d keyboard device]
+ * Usage: kbd [-r] [-t] [-l] [-c on|off] [-a enable|disable|alternate]
+ * [-d keyboard device] [-D autorepeat dealy] [-R autorepeat
+ * rate]
+ * kbd [-i] [-d keyboard device]
+ * kbd -s [language]
+ * kbd -b [keyboard|console] frequency
* -r reset the keyboard as if power-up
* -t return the type of the keyboard being used
* -l return the layout of the keyboard being used,
@@ -40,6 +44,8 @@
* -R autorepeat rate sets autorepeat rate, unit in ms
* -d keyboard device chooses the kbd device, default /dev/kbd.
* -s keyboard layout sets keyboard layout
+ * -b [keyboard| console] frequency
+ * sets keyboard or console beeper frequency
*/
#include <sys/types.h>
@@ -55,6 +61,8 @@
#include <stropts.h>
#include <libintl.h>
#include <locale.h>
+#include <errno.h>
+#include <inttypes.h>
#define KBD_DEVICE "/dev/kbd" /* default keyboard device */
#define DEF_FILE "/etc/default/kbd" /* kbd defaults file */
@@ -63,12 +71,15 @@
#define DEF_RPTDELAY "REPEAT_DELAY="
#define DEF_RPTRATE "REPEAT_RATE="
#define DEF_LAYOUT "LAYOUT="
+#define DEF_KBDFREQ "KBD_BEEPER_FREQ="
+#define DEF_CONSFREQ "CONSOLE_BEEPER_FREQ="
#define KBD_LAYOUT_FILE "/usr/share/lib/keytables/type_6/kbd_layouts"
#define MAX_LAYOUT_NUM 128
#define MAX_LINE_SIZE 256
#define DEFAULT_KBD_LAYOUT 33
+int errno;
char *layout_names[MAX_LAYOUT_NUM];
int layout_numbers[MAX_LAYOUT_NUM];
static int layout_count;
@@ -89,21 +100,22 @@ static int get_layout_number(char *);
static int set_layout(int, int);
static int get_layouts(void);
static int set_kbd_layout(int, char *);
+static int set_beep_freq(int, char *, int);
int
main(int argc, char **argv)
{
int c, error;
int rflag, tflag, lflag, cflag, dflag, aflag, iflag, errflag,
- Dflag, Rflag, rtlacDRflag, sflag;
- char *copt, *aopt, *delay, *rate, *layout_name;
- char *kbdname = KBD_DEVICE;
- int kbd;
+ Dflag, Rflag, rtlacDRflag, sflag, bflag;
+ char *copt, *aopt, *delay, *rate, *layout_name, *b_type, *freq_str;
+ char *kbdname = KBD_DEVICE, *endptr = NULL;
+ int kbd, freq_val;
extern char *optarg;
extern int optind;
rflag = tflag = cflag = dflag = aflag = iflag = errflag = lflag =
- Dflag = Rflag = sflag = 0;
+ Dflag = Rflag = sflag = bflag = 0;
copt = aopt = (char *)0;
(void) setlocale(LC_ALL, "");
@@ -112,7 +124,7 @@ main(int argc, char **argv)
#endif
(void) textdomain(TEXT_DOMAIN);
- while ((c = getopt(argc, argv, "rtlisc:a:d:D:R:")) != EOF) {
+ while ((c = getopt(argc, argv, "rtlisc:a:d:D:R:b:")) != EOF) {
switch (c) {
case 'r':
rflag++;
@@ -149,6 +161,9 @@ main(int argc, char **argv)
rate = optarg;
Rflag++;
break;
+ case 'b':
+ bflag++;
+ break;
case '?':
errflag++;
break;
@@ -159,22 +174,25 @@ main(int argc, char **argv)
* Check for valid arguments:
*
* If argument parsing failed or if there are left-over
- * command line arguments(except -s option), then we're done now.
+ * command line arguments(except -s and -b option),
+ * then we're done now.
*/
- if (errflag != 0 || ((sflag == 0) && (argc != optind))) {
+ if (errflag != 0 || (sflag == 0 && bflag == 0 && argc != optind)) {
usage();
exit(1);
}
/*
- * kbd requires that the user specify either "-i" or "-s" or at
- * least one of -[rtlacDR]. The "-d" option is, well, optional.
+ * kbd requires that the user specify either "-i" or "-s" or "-b" or
+ * at least one of -[rtlacDR]. The "-d" option is, well, optional.
* We don't care if it's there or not.
*/
rtlacDRflag = rflag + tflag + lflag + aflag + cflag + Dflag + Rflag;
- if (!((iflag != 0 && sflag == 0 && rtlacDRflag == 0) ||
- (iflag == 0 && sflag != 0 && dflag == 0 && rtlacDRflag == 0) ||
- (iflag == 0 && sflag == 0 && rtlacDRflag != 0))) {
+ if (!((iflag != 0 && sflag == 0 && bflag == 0 && rtlacDRflag == 0) ||
+ (iflag == 0 && sflag != 0 && bflag == 0 && dflag == 0 &&
+ rtlacDRflag == 0) ||
+ (iflag == 0 && sflag == 0 && bflag == 0 && rtlacDRflag != 0) ||
+ (iflag == 0 && sflag == 0 && bflag != 0 && rtlacDRflag == 0))) {
usage();
exit(1);
}
@@ -241,6 +259,41 @@ main(int argc, char **argv)
exit(error);
}
+ if (bflag) {
+ if (argc == optind) {
+ b_type = "keyboard";
+ } else if (argc == (optind + 1)) {
+ b_type = argv[argc - 2];
+ } else {
+ usage();
+ exit(1);
+ }
+
+ if (strcmp(b_type, "keyboard") && strcmp(b_type, "console")) {
+ usage();
+ exit(1);
+ }
+
+ freq_str = argv[argc - 1];
+ errno = 0;
+ freq_val = (int)strtol(freq_str, &endptr, 10);
+ if (errno != 0 || endptr[0] != '\0') {
+ usage();
+ exit(1);
+ }
+
+ if (freq_val < 0 || freq_val > INT16_MAX) {
+ (void) fprintf(stderr, "Invalid arguments: -b %s\n",
+ freq_str);
+ (void) fprintf(stderr, "Frequency range: [0 - %d]\n",
+ INT16_MAX);
+ exit(1);
+ }
+
+ if ((error = set_beep_freq(kbd, b_type, freq_val)) != 0)
+ exit(1);
+ }
+
return (0);
}
@@ -333,6 +386,26 @@ set_kbd_layout(int kbd, char *layout_name)
}
/*
+ * This routine sets keyboard or console beeper frequency
+ */
+static int
+set_beep_freq(int fd, char *type, int freq)
+{
+ struct freq_request fr_struct;
+
+ if (strcmp(type, "keyboard") == 0)
+ fr_struct.type = KBD_BEEP;
+ else if (strcmp(type, "console") == 0)
+ fr_struct.type = CONSOLE_BEEP;
+ else
+ return (EINVAL);
+
+ fr_struct.freq = (int16_t)freq;
+
+ return (ioctl(fd, KIOCSETFREQ, &fr_struct));
+}
+
+/*
* this routine resets the state of the keyboard as if power-up
*/
static void
@@ -542,8 +615,8 @@ set_repeat_rate(char *rate_str, int kbd)
static void
kbd_defaults(int kbd)
{
- char *p;
- int layout_num;
+ char *p, *endptr;
+ int layout_num, freq;
if (defopen(DEF_FILE) != 0) {
(void) fprintf(stderr, "Can't open default file: %s\n",
@@ -612,6 +685,36 @@ kbd_defaults(int kbd)
(void) set_layout(kbd, layout_num);
}
+
+ p = defread(DEF_KBDFREQ);
+ if (p != NULL) {
+ /*
+ * Keyboard beeper frequency unit in Hz
+ */
+ endptr = NULL;
+ errno = 0;
+ freq = (int)strtol(p, &endptr, 10);
+ if (errno == 0 && endptr[0] == '\0' &&
+ freq >= 0 && freq <= INT16_MAX)
+ (void) set_beep_freq(kbd, "keyboard", freq);
+ else
+ (void) fprintf(stderr, BAD_DEFAULT, DEF_KBDFREQ, p);
+ }
+
+ p = defread(DEF_CONSFREQ);
+ if (p != NULL) {
+ /*
+ * Console beeper frequency unit in Hz
+ */
+ endptr = NULL;
+ errno = 0;
+ freq = (int)strtol(p, &endptr, 10);
+ if (errno == 0 && endptr[0] == '\0' &&
+ freq >= 0 && freq <= INT16_MAX)
+ (void) set_beep_freq(kbd, "console", freq);
+ else
+ (void) fprintf(stderr, BAD_DEFAULT, DEF_CONSFREQ, p);
+ }
}
static int
@@ -687,10 +790,11 @@ static char *usage1 = "kbd [-r] [-t] [-l] [-a enable|disable|alternate]";
static char *usage2 = " [-c on|off][-D delay][-R rate][-d keyboard device]";
static char *usage3 = "kbd -i [-d keyboard device]";
static char *usage4 = "kbd -s [language]";
+static char *usage5 = "kbd -b [keyboard|console] frequency";
static void
usage(void)
{
- (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n", usage1, usage2,
- usage3, usage4);
+ (void) fprintf(stderr, "Usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", usage1,
+ usage2, usage3, usage4, usage5);
}
diff --git a/usr/src/cmd/kbd/kbd.dfl b/usr/src/cmd/kbd/kbd.dfl
index a0daf927d7..51399ade31 100644
--- a/usr/src/cmd/kbd/kbd.dfl
+++ b/usr/src/cmd/kbd/kbd.dfl
@@ -1,13 +1,12 @@
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -61,3 +60,11 @@
# The value will override the kbd-type value supplied in eeprom
# if it exists in eeprom when system boots.
#LAYOUT=
+
+# Uncomment the following line to set up the keyboard beeper
+# frequency. The valid frequency range is [0 - 32767], units in Hz
+#KBD_BEEPER_FREQ=2000
+
+# Uncomment the following line to set up the console beeper
+# frequency. The valid frequency range is [0 - 32767], units in Hz
+#CONSOLE_BEEPER_FREQ=900
diff --git a/usr/src/cmd/truss/codes.c b/usr/src/cmd/truss/codes.c
index 21caaea163..b3867d52ee 100644
--- a/usr/src/cmd/truss/codes.c
+++ b/usr/src/cmd/truss/codes.c
@@ -812,6 +812,7 @@ const struct ioc {
{ (uint_t)KIOCSRPTDELAY, "KIOCSRPTDELAY", NULL },
{ (uint_t)KIOCGRPTRATE, "KIOCGRPTRATE", NULL },
{ (uint_t)KIOCSRPTRATE, "KIOCSRPTRATE", NULL },
+ { (uint_t)KIOCSETFREQ, "KIOCSETFREQ", NULL },
/* ptm/pts driver I_STR ioctls */
{ (uint_t)ISPTM, "ISPTM", NULL},
diff --git a/usr/src/uts/common/io/conskbd.c b/usr/src/uts/common/io/conskbd.c
index da326ffc7a..663a29fc0f 100644
--- a/usr/src/uts/common/io/conskbd.c
+++ b/usr/src/uts/common/io/conskbd.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -78,6 +78,7 @@
#include <sys/promif.h>
#include <sys/vuid_event.h>
#include <sys/conskbd.h>
+#include <sys/beep.h>
extern struct keyboard *kbtrans_usbkb_maptab_init(void);
extern void kbtrans_usbkb_maptab_fini(struct keyboard **);
@@ -665,6 +666,9 @@ conskbduwsrv(queue_t *q)
mblk_t *mp;
queue_t *oldq;
enum kbtrans_message_response ret;
+ struct copyresp *csp;
+ struct freq_request *frqp;
+ int error;
while ((mp = getq(q)) != NULL) {
@@ -749,6 +753,51 @@ conskbduwsrv(queue_t *q)
}
break;
+ case M_IOCDATA:
+ /*
+ * Only deal with copyresp to KIOCSETFREQ
+ * transparent ioctl now
+ */
+ csp = (struct copyresp *)mp->b_rptr;
+ if (csp->cp_rval) {
+ miocnak(q, mp, 0, EINVAL);
+ break;
+ }
+
+ error = 0;
+ switch (csp->cp_cmd) {
+ case KIOCSETFREQ:
+ frqp = (struct freq_request *)mp->
+ b_cont->b_rptr;
+
+ switch (frqp->type) {
+ case CONSOLE_BEEP:
+ error = beeper_freq(BEEP_CONSOLE,
+ (int)frqp->freq);
+ break;
+
+ case KBD_BEEP:
+ error = beeper_freq(BEEP_TYPE4,
+ (int)frqp->freq);
+ break;
+
+ default:
+ error = 1;
+ } /* frqp->type */
+
+ break;
+
+ default:
+ error = 1;
+ } /* csp->cp_cmd */
+
+ if (error == 0)
+ miocack(q, mp, 0, 0);
+ else
+ miocnak(q, mp, 0, EINVAL);
+
+ break;
+
default:
/*
* Pass an error message up.
@@ -815,6 +864,20 @@ conskbd_ioctl(queue_t *q, mblk_t *mp)
miocack(q, mp, 0, 0);
break;
+ case KIOCSETFREQ:
+ if (iocp->ioc_count != TRANSPARENT) {
+ /*
+ * We don't support non-transparent ioctls,
+ * i.e. I_STR ioctls
+ */
+ miocnak(q, mp, 0, EINVAL);
+ } else {
+ /* Transparent ioctl */
+ mcopyin(mp, NULL, sizeof (struct freq_request), NULL);
+ qreply(q, mp);
+ }
+ break;
+
default:
if (conskbd.conskbd_bypassed == B_TRUE) {
conskbd_legacy_kbd_ioctl(q, mp);
diff --git a/usr/src/uts/common/sys/beep.h b/usr/src/uts/common/sys/beep.h
index 4e72798a3c..fbffbab9a0 100644
--- a/usr/src/uts/common/sys/beep.h
+++ b/usr/src/uts/common/sys/beep.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#ifndef _SYS_BEEP_H
@@ -46,6 +45,7 @@ void beep(enum beep_type);
void beep_polled(enum beep_type);
void beeper_on(enum beep_type);
void beeper_off(void);
+int beeper_freq(enum beep_type, int);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/sys/kbio.h b/usr/src/uts/common/sys/kbio.h
index 2164c97584..8bc9b761f0 100644
--- a/usr/src/uts/common/sys/kbio.h
+++ b/usr/src/uts/common/sys/kbio.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -212,6 +212,18 @@ struct kiockeymap {
#define KIOCGRPTRATE (KIOC|24)
#define KIOCSRPTRATE (KIOC|25)
+/* Set keyboard and console beeper frequencies */
+#define KIOCSETFREQ (KIOC|26)
+
+/* Beeper type for struct freq_request */
+enum fr_beep_type {CONSOLE_BEEP = 1, KBD_BEEP = 2};
+
+/* Frequency request structure */
+struct freq_request {
+ enum fr_beep_type type; /* Beeper type */
+ int16_t freq; /* Frequency */
+};
+
/* Used to control the AutoRepeat Min-delay and Min-Rate */
#define KIOCRPTDELAY_MIN (100)
#define KIOCRPTRATE_MIN (30)
diff --git a/usr/src/uts/intel/io/beeper.c b/usr/src/uts/intel/io/beeper.c
index dbd71c5f88..fff0a7a962 100644
--- a/usr/src/uts/intel/io/beeper.c
+++ b/usr/src/uts/intel/io/beeper.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -37,6 +36,8 @@
#include <sys/ksynch.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
+#include <sys/errno.h>
+#include <sys/inttypes.h>
#define NELEM(a) (sizeof (a) / sizeof ((a)[0]))
@@ -88,7 +89,7 @@ beep(enum beep_type type)
}
mutex_enter(&beep_state.mutex);
- if (beep_state.state == BEEP_OFF) {
+ if (beep_state.state == BEEP_OFF && bp->frequency != 0) {
beep_state.state = BEEP_TIMED;
beep_frequency(bp->frequency);
beep_on();
@@ -158,8 +159,10 @@ beeper_on(enum beep_type type)
mutex_enter(&beep_state.mutex);
if (beep_state.state == BEEP_OFF) {
beep_state.state = BEEP_ON;
- beep_frequency(bp->frequency);
- beep_on();
+ if (bp->frequency != 0) {
+ beep_frequency(bp->frequency);
+ beep_on();
+ }
}
mutex_exit(&beep_state.mutex);
}
@@ -174,3 +177,24 @@ beeper_off()
}
mutex_exit(&beep_state.mutex);
}
+
+int
+beeper_freq(enum beep_type type, int freq)
+{
+ struct beep_params *bp;
+
+ /*
+ * The frequency value is limited to the range of [0 - 32767]
+ */
+ if ((type != BEEP_CONSOLE && type != BEEP_TYPE4) || freq < 0 ||
+ freq > INT16_MAX)
+ return (EINVAL);
+
+ for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
+ if (bp->type == type)
+ break;
+ }
+
+ bp->frequency = freq;
+ return (0);
+}
diff --git a/usr/src/uts/sun4/os/beep.c b/usr/src/uts/sun4/os/beep.c
index ded15b9087..10d1221cfd 100644
--- a/usr/src/uts/sun4/os/beep.c
+++ b/usr/src/uts/sun4/os/beep.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,8 +19,8 @@
* CDDL HEADER END
*/
/*
- * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
@@ -43,7 +42,8 @@
#include <sys/devops.h>
#include <sys/beep.h>
-
+#include <sys/errno.h>
+#include <sys/inttypes.h>
/*
* Debug stuff
@@ -184,7 +184,7 @@ beep(enum beep_type type)
mutex_enter(&beep_statep->beep_state_mutex);
/* Beep only when no previous beep is in progress */
- if (beep_statep->beep_state_mode == BEEP_OFF) {
+ if (beep_statep->beep_state_mode == BEEP_OFF && bp->frequency != 0) {
beep_statep->beep_state_mode = BEEP_TIMED;
@@ -248,10 +248,12 @@ beeper_on(enum beep_type type)
beep_statep->beep_state_mode = BEEP_ON;
- (*beep_statep->beep_state_beep_freq)(beep_statep->
+ if (bp->frequency != 0) {
+ (*beep_statep->beep_state_beep_freq)(beep_statep->
beep_state_beep_dip, bp->frequency);
- (*beep_statep->beep_state_beep_on)(beep_statep->
+ (*beep_statep->beep_state_beep_on)(beep_statep->
beep_state_beep_dip);
+ }
}
mutex_exit(&beep_statep->beep_state_mutex);
@@ -313,3 +315,33 @@ beep_timeout()
BEEP_DEBUG1((CE_CONT, "beeper_timeout : Done"));
}
+
+/*
+ * Beeper_freq:
+ * Set beeper frequency
+ */
+int
+beeper_freq(enum beep_type type, int freq)
+{
+ struct beep_params *bp;
+
+ BEEP_DEBUG1((CE_CONT, "beeper_freq : Start"));
+
+ /*
+ * The frequency value is limited to the range of [0 - 32767]
+ */
+ if ((type != BEEP_CONSOLE && type != BEEP_TYPE4) || freq < 0 ||
+ freq > INT16_MAX)
+ return (EINVAL);
+
+ for (bp = beep_params; bp->type != BEEP_DEFAULT; bp++) {
+ if (bp->type == type)
+ break;
+ }
+
+ bp->frequency = freq;
+
+ BEEP_DEBUG1((CE_CONT, "beeper_freq : Done"));
+
+ return (0);
+}