All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.