Skip to contentSkip to conversation

: disable pcspeaker kernel: 2.4.2 - 2.4.5

PATCH In review Nico Schottelius 3 participants 4 messages May 30, 2001

Subsystems (7)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 : disable pcspeaker kernel: 2.4.2 - 2.4.5

Hello!

As I read that Alan and Linus are more than busy, I just retry sending the patch to the list.

The patch allows you to switch off the builtin pc speaker with sysctl options. No program will then be able to beep under Linux, nor under X neither in the console.

Normally the speaker keeps enabled, unless you

echo 0 > /proc/sys/kernel/pcspeaker

With all values != 0 it is turned on (documented is 1).

The support is included for i386, ia64, alpha, mips and mips64.

It is tested under i386 with several kernels / machines. No problem occurs.
The code should not make any problems on the other processors, but I would be nice if I could get feedback from people using this on alpha,...

I (and maybe others ?) would be happy if someone applies the patch to 2.4.6.

Thank you,

Nico

P.S.: I also attached an init script. This is from the clinux distrubtion
and has to be changed to run without /etc/sys/combined and /etc/sys/boot/kernelsettings.
If somebody is interested, I can send him/her the /etc/sys/ files.

#!/bin/sh
#
# Author: Nico Schottelius <nico AT schottelius DOT org>
# Date: 15th of May 2k+1
# Last Changed: 15th of May 2k+1
# Comment: Sub script of kernel/ settings script. Set pcspeaker on/off #

. /etc/sys/combined
. /etc/sys/boot/kernelsettings

case "$1" in
on) $SYS_ECHO -n "$SET $PC_SPEAKER_TEXT $WILL_TEXT "
echo 1 > $PC_SPEAKER_FILE
$SYS_ECHO $ON
;;
off) $SYS_ECHO -n "$SET $PC_SPEAKER_TEXT $WILL_TEXT "
echo 0 > $PC_SPEAKER_FILE
$SYS_ECHO $OFF
;;

status) $SYS_ECHO -n "$STATUS $PC_SPEAKER_TEXT $IS_TEXT "
if [ cat $PC_SPEAKER_FILE -eq 0 ]; then
$SYS_ECHO $OFF
else
$SYS_ECHO $ON
fi
;;
*) $SYS_ECHO "$USAGE $0 {on|off|status}"
exit 1
esac

exit 0

Documentation/Configure.help +17 -0
diff -u --recursive linux-2.4.5/Documentation/Configure.help linux-2.4.5-nc/Documentation/Configure.help
@@ -333,6 +333,23 @@
 
   Most users will answer N here.
 
+Disables the PC or internal speaker
+CONFIG_DISABLE_PC_SPEAKER
+  Whenever you don't want your computer to be able to beep,
+  choose this option. Actually, choosing this will still not
+  disable the speaker, you have to use sysctl for this:
+
+     echo 0 > /proc/sys/kernel/pcspeaker # disable speaker
+
+     echo 1 > /proc/sys/kernel/pcspeaker # enable speaker (default)
+
+  Attention: This will not catch the beeps made directly by the
+  BIOS (mostly this happens when using a notebook and pressing
+  special key codes). To disable this "BIOS-beep" enter the
+  BIOS and change it there.
+
+  If you are unsure, say N.
+
 Network Block Device support
 CONFIG_BLK_DEV_NBD
   Saying Y here will allow your computer to be a client for network
arch/alpha/config.in +5 -0
diff -u --recursive linux-2.4.5/arch/alpha/config.in linux-2.4.5-nc/arch/alpha/config.in
@@ -240,6 +240,11 @@
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 tristate 'Kernel support for Linux/Intel ELF binaries' CONFIG_BINFMT_EM86
 source drivers/parport/Config.in
+
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 source drivers/mtd/Config.in
arch/arm/config.in +5 -0
diff -u --recursive linux-2.4.5/arch/arm/config.in linux-2.4.5-nc/arch/arm/config.in
@@ -372,6 +372,12 @@
    source net/ax25/Config.in
 
    source net/irda/Config.in
+
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 fi
 
 mainmenu_option next_comment
arch/i386/config.in +4 -0
diff -u --recursive linux-2.4.5/arch/i386/config.in linux-2.4.5-nc/arch/i386/config.in
@@ -258,6 +258,10 @@
    bool '    Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
 fi
 
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 source drivers/mtd/Config.in
arch/ia64/config.in +4 -0
diff -u --recursive linux-2.4.5/arch/ia64/config.in linux-2.4.5-nc/arch/ia64/config.in
@@ -137,6 +137,10 @@
 
 fi # !HP_SIM
 
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 if [ "$CONFIG_NET" = "y" ]; then
arch/mips/config.in +5 -0
diff -u --recursive linux-2.4.5/arch/mips/config.in linux-2.4.5-nc/arch/mips/config.in
@@ -180,6 +180,11 @@
 #	bool ' Access.Bus support' CONFIG_ACCESSBUS
 #    fi
 fi
+
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 if [ "$CONFIG_ISA" = "y" ]; then
arch/mips64/config.in +4 -0
diff -u --recursive linux-2.4.5/arch/mips64/config.in linux-2.4.5-nc/arch/mips64/config.in
@@ -113,6 +113,10 @@
 fi
 tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
 
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 mainmenu_option next_comment
arch/sh/config.in +4 -0
diff -u --recursive linux-2.4.5/arch/sh/config.in linux-2.4.5-nc/arch/sh/config.in
@@ -141,6 +141,10 @@
 
 source drivers/parport/Config.in
 
+if [ "$CONFIG_SYSCTL" = "y" ]; then
+   bool '  Disable the PC-Speaker' CONFIG_DISABLE_PC_SPEAKER
+fi
+
 endmenu
 
 source drivers/mtd/Config.in
drivers/char/vt.c +12 -1
diff -u --recursive linux-2.4.5/drivers/char/vt.c linux-2.4.5-nc/drivers/char/vt.c
@@ -7,6 +7,7 @@
  *  Dynamic keymap and string allocation - [email protected] - May 1994
  *  Restrict VT switching via ioctl() - [email protected] - Dec 1995
  *  Some code moved for less code duplication - Andi Kleen - Mar 1997
+ *  Added ability to disable the pc speaker - [email protected] - May 2001
  */
 
 #include <linux/config.h>
@@ -40,6 +41,10 @@
 #include <asm/vc_ioctl.h>
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 
+#ifdef CONFIG_DISABLE_PC_SPEAKER
+extern int pcspeaker_enabled; /* disable the pcspeaker */
+#endif
+
 char vt_dont_switch;
 extern struct tty_driver console_driver;
 
@@ -112,6 +117,12 @@
 	unsigned int count = 0;
 	unsigned long flags;
 
+#ifdef CONFIG_DISABLE_PC_SPEAKER
+	/* is the pcspeaker enabled or disabled ? 0=disabled,1=enabled */
+	if(!pcspeaker_enabled)
+		return;
+#endif
+
 	if (hz > 20 && hz < 32767)
 		count = 1193180 / hz;
 	
@@ -137,7 +148,7 @@
 	return;
 }
 
-#else
+#else /* else of machine check */
 
 void
 _kd_mksound(unsigned int hz, unsigned int ticks)
include/linux/sysctl.h +2 -1
diff -u --recursive linux-2.4.5/include/linux/sysctl.h linux-2.4.5-nc/include/linux/sysctl.h
@@ -118,7 +118,8 @@
 	KERN_SHMPATH=48,	/* string: path to shm fs */
 	KERN_HOTPLUG=49,	/* string: path to hotplug policy agent */
 	KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
-	KERN_S390_USER_DEBUG_LOGGING=51  /* int: dumps of user faults */
+	KERN_S390_USER_DEBUG_LOGGING=51,  /* int: dumps of user faults */
+	KERN_DISABLE_PC_SPEAKER=52 /* int: speaker on or off */
 };
 
 
kernel/sys.c +8 -0
diff -u --recursive linux-2.4.5/kernel/sys.c linux-2.4.5-nc/kernel/sys.c
@@ -40,6 +40,14 @@
 
 int C_A_D = 1;
 
+/*
+ * whether to enable or disable the pcspeaker. default is to enable it.
+ */
+
+#ifdef CONFIG_DISABLE_PC_SPEAKER
+int pcspeaker_enabled = 1;
+#endif 
+
 
 /*
  *	Notifier list for kernel code which wants to be called
kernel/sysctl.c +11 -0
diff -u --recursive linux-2.4.5/kernel/sysctl.c linux-2.4.5-nc/kernel/sysctl.c
@@ -16,6 +16,7 @@
  *  Wendling.
  * The list_for_each() macro wasn't appropriate for the sysctl loop.
  *  Removed it and replaced it with older style, 03/23/00, Bill Wendling
+ * disable pc_speaker support, 8th of May 2001, Nico Schottelius
  */
 
 #include <linux/config.h>
@@ -48,6 +49,10 @@
 extern int nr_queued_signals, max_queued_signals;
 extern int sysrq_enabled;
 
+#ifdef CONFIG_DISABLE_PC_SPEAKER
+extern int pcspeaker_enabled; /* don't waste ram unless really needed */
+#endif
+
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -212,6 +217,12 @@
 	 0444, NULL, &proc_dointvec},
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
+
+#ifdef CONFIG_DISABLE_PC_SPEAKER
+	{KERN_DISABLE_PC_SPEAKER, "pcspeaker", &pcspeaker_enabled, sizeof(int),
+	 0644, NULL, &proc_dointvec},
+#endif
+
 #ifdef CONFIG_SYSVIPC
 	{KERN_SHMMAX, "shmmax", &shm_ctlmax, sizeof (size_t),
 	 0644, NULL, &proc_doulongvec_minmax},
#1 lore raw

By making this (logical, and needed) feature unconditional, your patch's size and complexity is reduced by 80%. (see the attached pc_speaker.patch2)

Ingo

drivers/char/vt.c +4 -0
diff -u --recursive linux-2.4.5/drivers/char/vt.c linux-2.4.5-nc/drivers/char/vt.c
@@ -40,6 +41,7 @@
 #include <asm/vc_ioctl.h>
 #endif /* CONFIG_FB_COMPAT_XPMAC */
 
+extern int pcspeaker_enabled;
 char vt_dont_switch;
 extern struct tty_driver console_driver;
 
@@ -112,6 +117,9 @@
 	unsigned int count = 0;
 	unsigned long flags;
 
+	/* is the pcspeaker enabled or disabled ? 0=disabled,1=enabled */
+	if (!pcspeaker_enabled)
+		return;
 	if (hz > 20 && hz < 32767)
 		count = 1193180 / hz;
 	
include/linux/sysctl.h +2 -1
diff -u --recursive linux-2.4.5/include/linux/sysctl.h linux-2.4.5-nc/include/linux/sysctl.h
@@ -118,7 +118,8 @@
 	KERN_SHMPATH=48,	/* string: path to shm fs */
 	KERN_HOTPLUG=49,	/* string: path to hotplug policy agent */
 	KERN_IEEE_EMULATION_WARNINGS=50, /* int: unimplemented ieee instructions */
-	KERN_S390_USER_DEBUG_LOGGING=51  /* int: dumps of user faults */
+	KERN_S390_USER_DEBUG_LOGGING=51,  /* int: dumps of user faults */
+	KERN_DISABLE_PC_SPEAKER=52 /* int: speaker on or off */
 };
 
 
kernel/sysctl.c +3 -0
diff -u --recursive linux-2.4.5/kernel/sysctl.c linux-2.4.5-nc/kernel/sysctl.c
@@ -48,6 +49,7 @@
 extern int nr_queued_signals, max_queued_signals;
 extern int sysrq_enabled;
 
+int pcspeaker_enabled;
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
 static int minolduid;
@@ -212,6 +217,8 @@
 	 0444, NULL, &proc_dointvec},
 	{KERN_RTSIGMAX, "rtsig-max", &max_queued_signals, sizeof(int),
 	 0644, NULL, &proc_dointvec},
+	{KERN_DISABLE_PC_SPEAKER, "pcspeaker", &pcspeaker_enabled, sizeof(int),
+	 0644, NULL, &proc_dointvec},
 #ifdef CONFIG_SYSVIPC
 	{KERN_SHMMAX, "shmmax", &shm_ctlmax, sizeof (size_t),
 	 0644, NULL, &proc_doulongvec_minmax},
#2 lore raw

Hi!

Where did you put the config.in entries to ?
This way it would be enabled all the time... okay...
I like that, too.
In the version I set up, I used the config.in entries, because if you use disable pc_speaker, there is at least one more int in the kernel. This is surely now much, but as it is not needed all the time, I thought about choosing it from menuconfig/config/...

So in short:

less code / one int more in the kernel
or
more code and #ifs / one int less in the kernel

What do you think is better ? I agree that the above one is nicer code, but in fact I would prefer the second solution.

And what about the code from kernel/sys.c ? The version you provided doesn't take care of what's the default value of pcspeaker. This would make it undefined, which is not really good.

Regards,

Nico

#3 lore raw
In reply to Ingo Molnar

Hi!

Quoted 4 lines

And what about the code from kernel/sys.c ? The version you provided doesn't take care of what's the default value of pcspeaker. This would make it undefined, which is not really good.

Since the variable is global in kernel/sysctl.c (and not kernel/sys.c), and globals are set to zero when linking by GCC. (am I wrong?). cheers,

Masoud