* [sparc32] Kernel module to control front LED
@ 2005-08-26 17:21 Metalhead
2005-09-27 20:28 ` David S. Miller
` (7 more replies)
0 siblings, 8 replies; 9+ messages in thread
From: Metalhead @ 2005-08-26 17:21 UTC (permalink / raw)
To: sparclinux
[-- Attachment #1: Type: text/plain, Size: 7114 bytes --]
Hi all,
I've written a kernel module that allows you to control the fron LED on
Sparcstations via /proc. It can also be compiled into the kernel, supporting
display of the system load (a la NetBSD and OpenBSD) then.
Please find the patch against a vanilla 2.4.30 tree included. The sources and
the patch can also be found at http://www.metalhead.ws/led.tar.gz.
diff -uprN linux-2.4.30-vanilla/Documentation/Configure.help linux-2.4.30-mod/Documentation/Configure.help
--- linux-2.4.30-vanilla/Documentation/Configure.help 2005-04-04 01:42:19.000000000 +0000
+++ linux-2.4.30-mod/Documentation/Configure.help 2005-08-25 20:32:22.000000000 +0000
@@ -23069,6 +23083,17 @@ CONFIG_SUN_OPENPROMFS
<file:Documentation/modules.txt>.
The module will be called openpromfs.o. If unsure, say M.
+Control front LED on sun4m machines via /proc/led (EXPERIMENTAL)
+CONFIG_SUN_LED
+ This allows you to control the front LED on sun4m machines via /proc/led. The
+ state of the LED can also be queried.
+
+ On, off and toggle do what their names suggest, an integer number makes the
+ LED blink at this interval seconds, load makes it blink according to the
+ system load (not available when compiled as a module).
+
+ If unsure, say N.
+
Kernel support for Linux/Sparc 32bit binary compatibility
CONFIG_SPARC32_COMPAT
This allows you to run 32-bit binaries on your Ultra.
diff -uprN linux-2.4.30-vanilla/arch/sparc/config.in linux-2.4.30-mod/arch/sparc/config.in
--- linux-2.4.30-vanilla/arch/sparc/config.in 2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/config.in 2005-08-25 20:32:38.000000000 +0000
@@ -64,6 +64,10 @@ else
define_bool CONFIG_PCI n
fi
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+ tristate 'Control front LED on sun4m machines via /proc/led (EXPERIMENTAL)' CONFIG_SUN_LED
+fi
+
tristate 'Openprom tree appears in /proc/openprom' CONFIG_SUN_OPENPROMFS
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
diff -uprN linux-2.4.30-vanilla/arch/sparc/kernel/Makefile linux-2.4.30-mod/arch/sparc/kernel/Makefile
--- linux-2.4.30-vanilla/arch/sparc/kernel/Makefile 2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/kernel/Makefile 2005-08-25 20:32:59.000000000 +0000
@@ -33,6 +33,7 @@ obj-$(CONFIG_SMP) += trampoline.o smp.o
obj-$(CONFIG_SUN_AUXIO) += auxio.o
obj-$(CONFIG_PCI) += ebus.o
obj-$(CONFIG_SUN_PM) += apc.o pmc.o
+obj-$(CONFIG_SUN_LED) += led.o
ifdef CONFIG_SUNOS_EMUL
obj-y += sys_sunos.o sunos_ioctl.o
diff -uprN linux-2.4.30-vanilla/arch/sparc/kernel/led.c linux-2.4.30-mod/arch/sparc/kernel/led.c
--- linux-2.4.30-vanilla/arch/sparc/kernel/led.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/kernel/led.c 2005-08-25 20:32:03.000000000 +0000
@@ -0,0 +1,170 @@
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <asm/auxio.h>
+#include <asm/uaccess.h>
+
+#define MODULE_VERSION "0.1"
+#define MODULE_NAME "led"
+
+MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>");
+MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+
+#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
+
+struct proc_dir_entry *led;
+struct timer_list led_blink_timer;
+
+inline void print_debug(const char *msg)
+{
+ printk(KERN_DEBUG "[%s] %s\n", MODULE_NAME, msg);
+}
+
+inline void led_toggle(void)
+{
+ /* set_auxio takes 2 arguments, first the bits to enable, second the
+ * bits to disable (huh?) */
+ set_auxio(get_auxio() ^ AUXIO_LED, get_auxio() & AUXIO_LED);
+}
+
+void led_blink(unsigned long timeout)
+{
+ led_toggle();
+
+ /* reschedule */
+#ifndef CONFIG_SUN_LED_MODULE
+ if(!timeout) { /* blink according to load */
+ led_blink_timer.expires = jiffies +
+ ((1 + (avenrun[0] >> FSHIFT)) * HZ);
+ /* avenrun isn't exported by the kernel, hence the ifndefs */
+ led_blink_timer.data = 0;
+ } else { /* blink at user specified interval */
+#endif
+ led_blink_timer.expires = jiffies + (timeout * HZ);
+ led_blink_timer.data = timeout;
+#ifndef CONFIG_SUN_LED_MODULE
+ }
+#endif
+ add_timer(&led_blink_timer);
+}
+
+int led_read_proc(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ int len = 0;
+
+ MOD_INC_USE_COUNT;
+
+ if(get_auxio() & AUXIO_LED) {
+ len = sprintf(buf, "on\n");
+ } else {
+ len = sprintf(buf, "off\n");
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ return len;
+}
+
+int led_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ char *buf = NULL;
+ unsigned long l = 0;
+
+ if(count > LED_MAX_LENGTH) {
+ count = LED_MAX_LENGTH;
+ }
+
+ buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL);
+ if(!buf) {
+ return -ENOMEM;
+ }
+
+ MOD_INC_USE_COUNT;
+
+ if(copy_from_user(buf, buffer, count)) {
+ MOD_DEC_USE_COUNT;
+ kfree(buf);
+ return -EFAULT;
+ }
+ buf[count] = '\0';
+
+ /* work around \n when echo'ing into proc */
+ if(buf[count - 1] == '\n') {
+ buf[count - 1] = '\0';
+ }
+
+ /* before we change anything we want to stop any running timers,
+ * otherwise calls such as on will have no persistent effect */
+ if(timer_pending(&led_blink_timer)) {
+ del_timer_sync(&led_blink_timer);
+ }
+
+ if(!strcmp(buf, "on")) {
+ print_debug("Turning LED on...");
+ auxio_set_led(AUXIO_LED_ON);
+ } else if(!strcmp(buf, "toggle")) {
+ print_debug("Toggling LED...");
+ led_toggle();
+ } else if((*buf > '0') && (*buf <= '9')) { /* 0 would cause division by
+ zero */
+ for(l = 0; *buf != '\0'; buf++) { /* convert to number */
+ l = 10 * l + (*buf - '0');
+ }
+ print_debug("Starting to blink...");
+ led_blink(l);
+#ifndef CONFIG_SUN_LED_MODULE
+ } else if(!strcmp(buf, "load")) {
+ print_debug("Starting to display load...");
+ led_blink(0);
+#endif
+ } else {
+ print_debug("Turning LED off...");
+ auxio_set_led(AUXIO_LED_OFF);
+ }
+
+ MOD_DEC_USE_COUNT;
+ kfree(buf);
+
+ return count;
+}
+
+static int __init init_led(void)
+{
+ led = create_proc_entry(MODULE_NAME,
+ 0, /* default mode */
+ NULL /* parent dir */);
+ if(!led) {
+ return -ENOMEM;
+ }
+
+ led->read_proc = led_read_proc; /* reader function */
+ led->write_proc = led_write_proc; /* writer function */
+ led->owner = THIS_MODULE;
+
+ /* initialize timer for blinking */
+ init_timer(&led_blink_timer);
+ led_blink_timer.function = led_blink; /* blinking function */
+
+ printk(KERN_INFO
+ "%s version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
+ MODULE_NAME, MODULE_VERSION);
+
+ return 0;
+}
+
+static void __exit cleanup_led(void)
+{
+ remove_proc_entry(MODULE_NAME, NULL);
+ if(timer_pending(&led_blink_timer)) { /* kill timer if necessary */
+ del_timer_sync(&led_blink_timer);
+ }
+}
+
+module_init(init_led);
+module_exit(cleanup_led);
--
They say that bandaging one's wounds helps to keep up one's appearance.
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
@ 2005-09-27 20:28 ` David S. Miller
2005-09-27 21:18 ` Arnaldo Carvalho de Melo
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2005-09-27 20:28 UTC (permalink / raw)
To: sparclinux
From: Metalhead <metalhead@metalhead.ws>
Date: Fri, 26 Aug 2005 19:21:13 +0200
> I've written a kernel module that allows you to control the fron
> LED on Sparcstations via /proc. It can also be compiled into the
> kernel, supporting display of the system load (a la NetBSD and
> OpenBSD) then.
>
> Please find the patch against a vanilla 2.4.30 tree included. The
> sources and the patch can also be found at
> http://www.metalhead.ws/led.tar.gz.
Thanks for the submission, looks cool.
Can I suggest one cleanup?
+ } else if((*buf > '0') && (*buf <= '9')) { /* 0 would cause division by
+ zero */
+ for(l = 0; *buf != '\0'; buf++) { /* convert to number */
+ l = 10 * l + (*buf - '0');
+ }
+ print_debug("Starting to blink...");
+ led_blink(l);
The kernel has a library function called simple_strtoul() which
you should probably use instead of this hand-crafted version.
Also, when you resubmit with this fixed, please provide a
"Signed-off-by: " for yourself so that I can apply your patch.
Thanks a lot.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
2005-09-27 20:28 ` David S. Miller
@ 2005-09-27 21:18 ` Arnaldo Carvalho de Melo
2005-09-27 22:09 ` David S. Miller
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2005-09-27 21:18 UTC (permalink / raw)
To: sparclinux
Em Tue, Sep 27, 2005 at 01:28:28PM -0700, David S. Miller escreveu:
> From: Metalhead <metalhead@metalhead.ws>
> Date: Fri, 26 Aug 2005 19:21:13 +0200
>
> > I've written a kernel module that allows you to control the fron
> > LED on Sparcstations via /proc. It can also be compiled into the
> > kernel, supporting display of the system load (a la NetBSD and
> > OpenBSD) then.
> >
> > Please find the patch against a vanilla 2.4.30 tree included. The
> > sources and the patch can also be found at
> > http://www.metalhead.ws/led.tar.gz.
>
> Thanks for the submission, looks cool.
>
> Can I suggest one cleanup?
>
> + } else if((*buf > '0') && (*buf <= '9')) { /* 0 would cause division by
> + zero */
> + for(l = 0; *buf != '\0'; buf++) { /* convert to number */
> + l = 10 * l + (*buf - '0');
> + }
> + print_debug("Starting to blink...");
> + led_blink(l);
>
> The kernel has a library function called simple_strtoul() which
> you should probably use instead of this hand-crafted version.
>
> Also, when you resubmit with this fixed, please provide a
> "Signed-off-by: " for yourself so that I can apply your patch.
>
> Thanks a lot.
Is this in any way similar to what the guardian service processor in
PARISC64 machines provide? I.e. one can see what the leds in the machine
front panel remotely :-)
- Arnaldo
GSP>
********** VIRTUAL FRONT PANEL **********
System Boot detected
*****************************************
LEDs: RUN ATTENTION FAULT REMOTE POWER
FLASH FLASH OFF ON ON
LED State: Running non-OS code. Non-critical error detected.
Check Chassis and Console Logs for error messages.
platform config
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
2005-09-27 20:28 ` David S. Miller
2005-09-27 21:18 ` Arnaldo Carvalho de Melo
@ 2005-09-27 22:09 ` David S. Miller
2005-09-28 0:39 ` Eric Brower
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2005-09-27 22:09 UTC (permalink / raw)
To: sparclinux
From: acme@ghostprotocols.net (Arnaldo Carvalho de Melo)
Date: Tue, 27 Sep 2005 18:18:59 -0300
> Is this in any way similar to what the guardian service processor in
> PARISC64 machines provide? I.e. one can see what the leds in the machine
> front panel remotely :-)
Nah, this is just a physical single LED on the front panel of
the machine that you can toggle on an off by flipping a bit
in an I/O register.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
` (2 preceding siblings ...)
2005-09-27 22:09 ` David S. Miller
@ 2005-09-28 0:39 ` Eric Brower
2005-09-28 0:48 ` Arnaldo Carvalho de Melo
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Eric Brower @ 2005-09-28 0:39 UTC (permalink / raw)
To: sparclinux
On 9/27/05, David S. Miller <davem@davemloft.net> wrote:
> From: acme@ghostprotocols.net (Arnaldo Carvalho de Melo)
> Date: Tue, 27 Sep 2005 18:18:59 -0300
>
> > Is this in any way similar to what the guardian service processor in
> > PARISC64 machines provide? I.e. one can see what the leds in the machine
> > front panel remotely :-)
>
> Nah, this is just a physical single LED on the front panel of
> the machine that you can toggle on an off by flipping a bit
> in an I/O register.
Arnaldo,
Certain Sun systems do have this sort of feature-- it has been called
Lights Out Management (LOM), Remote System Control (RSC) and the like.
Basically, proprietary, pre-IPMI management controllers of varying
functionality. As DaveM mentions, this isn't it, though... :)
There is ongoing work to support such controllers (e.g. on Sun E250
and E450 servers).
--
E
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
` (3 preceding siblings ...)
2005-09-28 0:39 ` Eric Brower
@ 2005-09-28 0:48 ` Arnaldo Carvalho de Melo
2005-09-28 4:38 ` David S. Miller
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Arnaldo Carvalho de Melo @ 2005-09-28 0:48 UTC (permalink / raw)
To: sparclinux
On 9/27/05, Eric Brower <ebrower@gmail.com> wrote:
> On 9/27/05, David S. Miller <davem@davemloft.net> wrote:
> > From: acme@ghostprotocols.net (Arnaldo Carvalho de Melo)
> > Date: Tue, 27 Sep 2005 18:18:59 -0300
> >
> > > Is this in any way similar to what the guardian service processor in
> > > PARISC64 machines provide? I.e. one can see what the leds in the machine
> > > front panel remotely :-)
> >
> > Nah, this is just a physical single LED on the front panel of
> > the machine that you can toggle on an off by flipping a bit
> > in an I/O register.
>
> Arnaldo,
>
> Certain Sun systems do have this sort of feature-- it has been called
> Lights Out Management (LOM), Remote System Control (RSC) and the like.
> Basically, proprietary, pre-IPMI management controllers of varying
> functionality. As DaveM mentions, this isn't it, though... :)
>
> There is ongoing work to support such controllers (e.g. on Sun E250
> and E450 servers).
Thanks for the information! I have to find time to get my SS 10 back to life and
use it to test my kernel hacks :-)
BTW, is 2.6.latest working well on Sparcstation 10s?
- Arnaldo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
` (4 preceding siblings ...)
2005-09-28 0:48 ` Arnaldo Carvalho de Melo
@ 2005-09-28 4:38 ` David S. Miller
2005-09-28 7:09 ` Christian Joensson
2005-09-28 14:28 ` Metalhead
7 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2005-09-28 4:38 UTC (permalink / raw)
To: sparclinux
From: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Date: Tue, 27 Sep 2005 21:48:47 -0300
> BTW, is 2.6.latest working well on Sparcstation 10s?
For some people yes, for some other folks no. Sparc32
doesn't get much tender love & care lately. :-/
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
` (5 preceding siblings ...)
2005-09-28 4:38 ` David S. Miller
@ 2005-09-28 7:09 ` Christian Joensson
2005-09-28 14:28 ` Metalhead
7 siblings, 0 replies; 9+ messages in thread
From: Christian Joensson @ 2005-09-28 7:09 UTC (permalink / raw)
To: sparclinux
On 9/28/05, David S. Miller <davem@davemloft.net> wrote:
> From: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
> Date: Tue, 27 Sep 2005 21:48:47 -0300
>
> > BTW, is 2.6.latest working well on Sparcstation 10s?
>
> For some people yes, for some other folks no. Sparc32
> doesn't get much tender love & care lately. :-/
(sorry dave for the duplicate...)
how about hyperSPARC? how about SMP on 32 bit?
I am merely interested in an update...
--
Cheers,
/ChJ
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [sparc32] Kernel module to control front LED
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
` (6 preceding siblings ...)
2005-09-28 7:09 ` Christian Joensson
@ 2005-09-28 14:28 ` Metalhead
7 siblings, 0 replies; 9+ messages in thread
From: Metalhead @ 2005-09-28 14:28 UTC (permalink / raw)
To: sparclinux
[-- Attachment #1: Type: text/plain, Size: 6962 bytes --]
Hi,
I've changed the patch to use simple_strtoul() and included a signed-off-by
line, thanks for the tip. Although this change was small, please be aware that I
didn't test this version, as I unfortunately don't have access to a sparcstation
right now.
Thanks.
Lars
diff -uprN linux-2.4.30-vanilla/Documentation/Configure.help linux-2.4.30-mod/Documentation/Configure.help
--- linux-2.4.30-vanilla/Documentation/Configure.help 2005-04-04 01:42:19.000000000 +0000
+++ linux-2.4.30-mod/Documentation/Configure.help 2005-08-25 20:32:22.000000000 +0000
@@ -23069,6 +23083,17 @@ CONFIG_SUN_OPENPROMFS
<file:Documentation/modules.txt>.
The module will be called openpromfs.o. If unsure, say M.
+Control front LED on sun4m machines via /proc/led (EXPERIMENTAL)
+CONFIG_SUN_LED
+ This allows you to control the front LED on sun4m machines via /proc/led. The
+ state of the LED can also be queried.
+
+ On, off and toggle do what their names suggest, an integer number makes the
+ LED blink at this interval seconds, load makes it blink according to the
+ system load (not available when compiled as a module).
+
+ If unsure, say N.
+
Kernel support for Linux/Sparc 32bit binary compatibility
CONFIG_SPARC32_COMPAT
This allows you to run 32-bit binaries on your Ultra.
diff -uprN linux-2.4.30-vanilla/arch/sparc/config.in linux-2.4.30-mod/arch/sparc/config.in
--- linux-2.4.30-vanilla/arch/sparc/config.in 2004-11-17 11:54:21.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/config.in 2005-08-25 20:32:38.000000000 +0000
@@ -64,6 +64,10 @@ else
define_bool CONFIG_PCI n
fi
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+ tristate 'Control front LED on sun4m machines via /proc/led (EXPERIMENTAL)' CONFIG_SUN_LED
+fi
+
tristate 'Openprom tree appears in /proc/openprom' CONFIG_SUN_OPENPROMFS
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
diff -uprN linux-2.4.30-vanilla/arch/sparc/kernel/Makefile linux-2.4.30-mod/arch/sparc/kernel/Makefile
--- linux-2.4.30-vanilla/arch/sparc/kernel/Makefile 2003-11-28 18:26:19.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/kernel/Makefile 2005-08-25 20:32:59.000000000 +0000
@@ -33,6 +33,7 @@ obj-$(CONFIG_SMP) += trampoline.o smp.o
obj-$(CONFIG_SUN_AUXIO) += auxio.o
obj-$(CONFIG_PCI) += ebus.o
obj-$(CONFIG_SUN_PM) += apc.o pmc.o
+obj-$(CONFIG_SUN_LED) += led.o
ifdef CONFIG_SUNOS_EMUL
obj-y += sys_sunos.o sunos_ioctl.o
diff -uprN linux-2.4.30-vanilla/arch/sparc/kernel/led.c linux-2.4.30-mod/arch/sparc/kernel/led.c
--- linux-2.4.30-vanilla/arch/sparc/kernel/led.c 1970-01-01 00:00:00.000000000 +0000
+++ linux-2.4.30-mod/arch/sparc/kernel/led.c 2005-08-25 20:32:03.000000000 +0000
@@ -0,0 +1,170 @@
+#include <linux/module.h>
+#include <linux/proc_fs.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <asm/auxio.h>
+#include <asm/uaccess.h>
+
+#define MODULE_VERSION "0.1"
+#define MODULE_NAME "led"
+
+MODULE_AUTHOR("Lars Kotthoff <metalhead@metalhead.ws>");
+MODULE_DESCRIPTION("Provides control of the front LED on SPARC systems.");
+MODULE_LICENSE("GPL");
+
+EXPORT_NO_SYMBOLS;
+
+#define LED_MAX_LENGTH 8 /* maximum chars written to proc file */
+
+struct proc_dir_entry *led;
+struct timer_list led_blink_timer;
+
+inline void print_debug(const char *msg)
+{
+ printk(KERN_DEBUG "[%s] %s\n", MODULE_NAME, msg);
+}
+
+inline void led_toggle(void)
+{
+ /* set_auxio takes 2 arguments, first the bits to enable, second the
+ * bits to disable (huh?) */
+ set_auxio(get_auxio() ^ AUXIO_LED, get_auxio() & AUXIO_LED);
+}
+
+void led_blink(unsigned long timeout)
+{
+ led_toggle();
+
+ /* reschedule */
+#ifndef CONFIG_SUN_LED_MODULE
+ if(!timeout) { /* blink according to load */
+ led_blink_timer.expires = jiffies +
+ ((1 + (avenrun[0] >> FSHIFT)) * HZ);
+ /* avenrun isn't exported by the kernel, hence the ifndefs */
+ led_blink_timer.data = 0;
+ } else { /* blink at user specified interval */
+#endif
+ led_blink_timer.expires = jiffies + (timeout * HZ);
+ led_blink_timer.data = timeout;
+#ifndef CONFIG_SUN_LED_MODULE
+ }
+#endif
+ add_timer(&led_blink_timer);
+}
+
+int led_read_proc(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ int len = 0;
+
+ MOD_INC_USE_COUNT;
+
+ if(get_auxio() & AUXIO_LED) {
+ len = sprintf(buf, "on\n");
+ } else {
+ len = sprintf(buf, "off\n");
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ return len;
+}
+
+int led_write_proc(struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ char *buf = NULL;
+ unsigned long l = 0;
+
+ if(count > LED_MAX_LENGTH) {
+ count = LED_MAX_LENGTH;
+ }
+
+ buf = kmalloc(sizeof(char) * (count + 1), GFP_KERNEL);
+ if(!buf) {
+ return -ENOMEM;
+ }
+
+ MOD_INC_USE_COUNT;
+
+ if(copy_from_user(buf, buffer, count)) {
+ MOD_DEC_USE_COUNT;
+ kfree(buf);
+ return -EFAULT;
+ }
+ buf[count] = '\0';
+
+ /* work around \n when echo'ing into proc */
+ if(buf[count - 1] == '\n') {
+ buf[count - 1] = '\0';
+ }
+
+ /* before we change anything we want to stop any running timers,
+ * otherwise calls such as on will have no persistent effect */
+ if(timer_pending(&led_blink_timer)) {
+ del_timer_sync(&led_blink_timer);
+ }
+
+ if(!strcmp(buf, "on")) {
+ print_debug("Turning LED on...");
+ auxio_set_led(AUXIO_LED_ON);
+ } else if(!strcmp(buf, "toggle")) {
+ print_debug("Toggling LED...");
+ led_toggle();
+ } else if((*buf > '0') && (*buf <= '9')) { /* 0 would cause division by
+ zero */
+ print_debug("Starting to blink...");
+ led_blink(simple_strtoul(buf, NULL, 10));
+#ifndef CONFIG_SUN_LED_MODULE
+ } else if(!strcmp(buf, "load")) {
+ print_debug("Starting to display load...");
+ led_blink(0);
+#endif
+ } else {
+ print_debug("Turning LED off...");
+ auxio_set_led(AUXIO_LED_OFF);
+ }
+
+ MOD_DEC_USE_COUNT;
+ kfree(buf);
+
+ return count;
+}
+
+static int __init init_led(void)
+{
+ led = create_proc_entry(MODULE_NAME,
+ 0, /* default mode */
+ NULL /* parent dir */);
+ if(!led) {
+ return -ENOMEM;
+ }
+
+ led->read_proc = led_read_proc; /* reader function */
+ led->write_proc = led_write_proc; /* writer function */
+ led->owner = THIS_MODULE;
+
+ /* initialize timer for blinking */
+ init_timer(&led_blink_timer);
+ led_blink_timer.function = led_blink; /* blinking function */
+
+ printk(KERN_INFO
+ "%s version %s, Lars Kotthoff <metalhead@metalhead.ws>\n",
+ MODULE_NAME, MODULE_VERSION);
+
+ return 0;
+}
+
+static void __exit cleanup_led(void)
+{
+ remove_proc_entry(MODULE_NAME, NULL);
+ if(timer_pending(&led_blink_timer)) { /* kill timer if necessary */
+ del_timer_sync(&led_blink_timer);
+ }
+}
+
+module_init(init_led);
+module_exit(cleanup_led);
Signed-off-by: Lars Kotthoff
--
Horses trust their riders, even when not so deserved.
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2005-09-28 14:28 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-26 17:21 [sparc32] Kernel module to control front LED Metalhead
2005-09-27 20:28 ` David S. Miller
2005-09-27 21:18 ` Arnaldo Carvalho de Melo
2005-09-27 22:09 ` David S. Miller
2005-09-28 0:39 ` Eric Brower
2005-09-28 0:48 ` Arnaldo Carvalho de Melo
2005-09-28 4:38 ` David S. Miller
2005-09-28 7:09 ` Christian Joensson
2005-09-28 14:28 ` Metalhead
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.