2003-07-29 15:18:14

by Philip Graham Willoughby

[permalink] [raw]
Subject: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi all,

This patch adds an abstraction layer for programmable LED devices,
hardware drivers for the Status LEDs found on some Intel PIIX4E based
server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
to the parallel port data lines.

It also includes a kernel-space heartbeat module and a module to monitor
a user-space program, both of which will flash an LED while the system
is happy.

I'm sorry for not involving all of you earlier, but I had to obtain the
permission of my boss to GPL this, and he was out of the country.

This patch is against the 2.4 series (specifically 2.4.21, but it should
apply against any 2.4) -- the code part of the patch is fine on 2.[56] but
the config stuff obviously needs changing.

The user-level software for this can be downloaded from
http://csgsoft.doc.ic.ac.uk/leds/

Please cc me on replies as I'm only on the digest list...

Regards,

Philip Willoughby
Systems Programmer, Department of Computing, Imperial College, London, UK


diff -uNr linux-2.4.21.vanilla/arch/i386/config.in linux-2.4.21.patched/arch/i386/config.in
--- linux-2.4.21.vanilla/arch/i386/config.in 2003-07-17 17:06:01.000000000 +0100
+++ linux-2.4.21.patched/arch/i386/config.in 2003-07-29 15:28:17.000000000 +0100
@@ -485,3 +485,4 @@
endmenu

source lib/Config.in
+source drivers/leds/Config.in
diff -uNr linux-2.4.21.vanilla/Documentation/Configure.help linux-2.4.21.patched/Documentation/Configure.help
--- linux-2.4.21.vanilla/Documentation/Configure.help 2003-07-17 17:07:00.000000000 +0100
+++ linux-2.4.21.patched/Documentation/Configure.help 2003-07-29 15:28:17.000000000 +0100
@@ -26649,6 +26649,53 @@
CONFIG_IPMI_WATCHDOG
This enables the IPMI watchdog timer.

+LED Subsystem Support
+CONFIG_LEDS
+ Enables support for LED devices.
+
+Intel PIIX4E LED Support
+CONFIG_PIIX4E_LEDS
+ Enables support for the programmable LEDs on some Intel PIIX4E-based
+ mainboards. One such board is contained in the Intel ISP1100
+ server. If you don't have an Intel PIIX4E this driver will do
+ nothing. On boards with the LEDs unconnected, this driver _should_
+ do no harm, but I have not been able to test it on all such boards.
+ It should be safe to load this driver (Y or M) on all machines, if
+ you find a problem, please contact me:
+
+ Philip Willoughby <[email protected]>
+
+ Put "PIIX4E LED BUG" in the subject line please.
+
+Parallel Port LED Support
+CONFIG_PARPORT_LEDS
+ Enables support for a bank of 8 LEDs connected to the parallel port.
+ These devices are extremely simple and cannot be autodetected. I
+ recommend you do not load this driver unless you are sure you have
+ such a device attached. Say N here unless you really know what
+ you're doing.
+
+Kernel Heartbeat LED
+CONFIG_KBEAT_LED
+ Enables a kernel-resident piece of code which will toggle the status
+ of a LED twice per second. Useful as a liveness indicator. This
+ will do nothing if you do not have any LED hardware drivers loaded.
+
+ If you build this code as a module, you can tune the flash interval
+ with module parameters.
+
+User Heartbeat
+CONFIG_UBEAT
+ Enables a kernel-resident piece of code which monitors a user daemon
+ (ubeatd). While the user-level code is working fine, a LED will
+ flash. In the event of a failure, a message will be logged through
+ the normal kernel logging facilities.
+
+ If you have no LED hardware, this code will still work -- no LEDs
+ will flash, but the failure message will still work.
+
+ ubeatd can be downloaded from http://csgsoft.doc.ic.ac.uk/leds/
+
#
# A couple of things I keep forgetting:
# capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet,
diff -uNr linux-2.4.21.vanilla/drivers/leds/Config.in linux-2.4.21.patched/drivers/leds/Config.in
--- linux-2.4.21.vanilla/drivers/leds/Config.in 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/Config.in 2003-07-29 15:28:17.000000000 +0100
@@ -0,0 +1,21 @@
+#
+# LED device configuration
+#
+mainmenu_option next_comment
+comment 'LED Subsystem'
+
+tristate 'LED Subsystem Support' CONFIG_LEDS
+if [ "$CONFIG_LEDS" != "n" ]; then
+comment 'LED hardware drivers'
+ if [ "$CONFIG_X86" = "y" -a "$CONFIG_X86_64" != "y" ]; then
+ dep_tristate 'Intel PIIX4E LED Support' CONFIG_PIIX4E_LEDS $CONFIG_LEDS
+ fi
+ if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate 'Parallel Port LED Support (Read Help)' CONFIG_PARPORT_LEDS $CONFIG_LEDS $CONFIG_PARPORT
+ fi
+comment 'LED-using software'
+ dep_tristate 'Kernel Heartbeat LED' CONFIG_KBEAT_LED $CONFIG_LEDS
+ dep_tristate 'User Heartbeat' CONFIG_UBEAT $CONFIG_LEDS
+fi
+
+endmenu
diff -uNr linux-2.4.21.vanilla/drivers/leds/kbeat_led.c linux-2.4.21.patched/drivers/leds/kbeat_led.c
--- linux-2.4.21.vanilla/drivers/leds/kbeat_led.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/kbeat_led.c 2003-07-22 14:05:54.000000000 +0100
@@ -0,0 +1,58 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+
+static unsigned int kbeat_led;
+static unsigned char kbeat_state = 0;
+
+static struct timer_list kbeat_timer;
+static unsigned int kbeat_stps __initdata = 2;
+static unsigned int kbeat_interval = HZ/2;
+
+static void
+kbeat_beat (unsigned long GoOnGccWarnMeThen)
+{
+ kbeat_state = ~kbeat_state;
+ led_set (kbeat_led, kbeat_state, THIS_MODULE);
+ /* init_timer(&kbeat_timer); */
+ kbeat_timer.expires=jiffies + kbeat_interval;
+ kbeat_timer.function=kbeat_beat;
+ add_timer(&kbeat_timer);
+}
+
+void __exit
+kbeat_exit(void)
+{
+ del_timer_sync (&kbeat_timer);
+ led_release(kbeat_led, THIS_MODULE);
+}
+
+int __init
+kbeat_init(void)
+{
+ if (led_reserve(&kbeat_led, THIS_MODULE) == 0)
+ {
+ printk(KERN_INFO "kbeat_led: got LED %.8x\n", kbeat_led);
+ if ((kbeat_stps <= 0) || ((kbeat_interval = HZ/kbeat_stps) == 0))
+ kbeat_interval = HZ/2;
+ init_timer(&kbeat_timer);
+ kbeat_timer.expires=jiffies + kbeat_interval;
+ kbeat_timer.function=kbeat_beat;
+ add_timer(&kbeat_timer);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+module_init (kbeat_init);
+module_exit (kbeat_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
+MODULE_DESCRIPTION("Blinks a LED to indicate the kernel is alive and well");
+MODULE_PARM(kbeat_stps, "i");
+MODULE_PARM_DESC(kbeat_stps, "State changes per second for the kernel controlled LED.");
+EXPORT_NO_SYMBOLS;
diff -uNr linux-2.4.21.vanilla/drivers/leds/leds.c linux-2.4.21.patched/drivers/leds/leds.c
--- linux-2.4.21.vanilla/drivers/leds/leds.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/leds.c 2003-07-29 15:22:49.000000000 +0100
@@ -0,0 +1,595 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/leds.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/ioctl.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
+
+static struct list_head led_list;
+static rwlock_t led_list_lock = RW_LOCK_UNLOCKED;
+static unsigned int leds_major_num;
+static devfs_handle_t ledsdir;
+static devfs_handle_t ledsctl;
+static int have_devfs = 0;
+
+static void
+del_all_owned_by_pid (pid_t who, struct linux_leds_info *leds)
+{
+ int i;
+ if (leds->owners == NULL)
+ return;
+ for (i = 0 ; i < leds->count ; ++i)
+ if ((leds->owners[i].ownertype == leds_user) && (leds->owners[i].ownerdata.processdata.pid == who))
+ {
+ leds->owners[i].ownertype = leds_noone;
+ leds->release(leds->data);
+ }
+}
+
+static void
+release_all_owned_by_pid (pid_t pid)
+{
+ struct list_head *hd;
+ write_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ del_all_owned_by_pid (pid, (struct linux_leds_info *)hd);
+ }
+ write_unlock(&led_list_lock);
+}
+
+static void
+del_all_owned_by(struct led_owner *who, struct linux_leds_info *leds)
+{
+ int i;
+ if (leds->owners == NULL)
+ return;
+ for (i = 0 ; i < leds->count ; ++i)
+ {
+ switch (who->ownertype)
+ {
+ case leds_noone:
+ break;
+ case leds_kernel:
+ if (leds->owners[i].ownerdata.module == who->ownerdata.module)
+ {
+ leds->owners[i].ownertype = leds_noone;
+ leds->release(leds->data);
+ }
+ break;
+ case leds_user:
+ if ((leds->owners[i].ownerdata.processdata.pid == who->ownerdata.processdata.pid) && (leds->owners[i].ownerdata.processdata.uid == who->ownerdata.processdata.uid))
+ {
+ leds->owners[i].ownertype = leds_noone;
+ leds->release(leds->data);
+ }
+ }
+ }
+}
+
+static void
+release_all_owned_by(struct led_owner *pid)
+{
+ struct list_head *hd;
+ write_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ del_all_owned_by (pid, (struct linux_leds_info *)hd);
+ }
+ write_unlock(&led_list_lock);
+}
+
+int leds_read_proc (char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+ int len = 0;
+ int i;
+ int id;
+ struct list_head *hd;
+ *start=buf;
+ if (offset == 0)
+ {
+ len += sprintf (buf+len, "LED ID: PID/Module Name: UID: \n");
+ }
+ else
+ {
+ offset /= 55;
+ --offset; /* The header -- almost forgot ;-) */
+ }
+ read_lock(&led_list_lock);
+ hd = &led_list;
+ while ((hd->next != &led_list) && ( len + 55 <= count))
+ {
+ hd = hd->next;
+ if (((struct linux_leds_info *)hd)->count < offset)
+ {
+ offset -=((struct linux_leds_info *)hd)->count;
+ continue;
+ }
+ for (i=0 ; i < ((struct linux_leds_info *)hd)->count ; ++i)
+ {
+ if (i >= offset)
+ {
+ if ( len + 55 > count)
+ {
+ read_unlock(&led_list_lock);
+ return len;
+ }
+ id = ((struct linux_leds_info *)hd)->id;
+ id <<= 24;
+ id |= i;
+ len += sprintf (buf+len, "%.16X ", id);
+ if (((struct linux_leds_info *)hd)->owners == NULL)
+ {
+ len += sprintf (buf+len, "Not allocated \n");
+ }
+ else if (((struct linux_leds_info *)hd)->owners[i].ownertype == leds_noone)
+ {
+ len += sprintf (buf+len, "Not allocated \n");
+ }
+ else if (((struct linux_leds_info *)hd)->owners[i].ownertype == leds_kernel)
+ {
+ int c;
+ c = sprintf (buf+len, "%.36s", ((struct linux_leds_info *)hd)->owners[i].ownerdata.module->name);
+ len += c;
+ while (c < 36)
+ {
+ len += sprintf (buf+len, " ");
+ ++c;
+ }
+ len += sprintf (buf+len, "\n");
+ }
+ else if (((struct linux_leds_info *)hd)->owners[i].ownertype == leds_user)
+ {
+ int c;
+ c = sprintf (buf+len, "%-16u", ((struct linux_leds_info *)hd)->owners[i].ownerdata.processdata.pid);
+ len += c;
+ while (c < 18)
+ {
+ len += sprintf (buf+len, " ");
+ ++c;
+ }
+ c = sprintf (buf+len, "%-16u", ((struct linux_leds_info *)hd)->owners[i].ownerdata.processdata.uid);
+ len += c;
+ while (c < 18)
+ {
+ len += sprintf (buf+len, " ");
+ ++c;
+ }
+ len += sprintf (buf+len, "\n");
+ }
+ else
+ {
+ len += sprintf (buf+len,"Corrupted structure encountered \n");
+ }
+ }
+ }
+ offset = 0;
+ }
+ read_unlock(&led_list_lock);
+ *eof = 1;
+ return len;
+}
+
+int
+leds_add (struct linux_leds_info *leds)
+{
+ struct list_head *hd;
+ MOD_INC_USE_COUNT;
+ INIT_LIST_HEAD(&leds->list);
+ leds->owners=NULL;
+ leds->id=0;
+ write_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ if (leds->id < ((struct linux_leds_info *)hd)->id)
+ {
+ list_add_tail(&leds->list, hd);
+ write_unlock(&led_list_lock);
+ return 0;
+ }
+ ++leds->id;
+ }
+ list_add_tail(&leds->list, &led_list);
+ write_unlock(&led_list_lock);
+ return 0;
+}
+
+int
+leds_del (struct linux_leds_info *leds)
+{
+ MOD_DEC_USE_COUNT;
+ write_lock(&led_list_lock);
+ list_del (&leds->list);
+ write_unlock(&led_list_lock);
+ return 0;
+}
+
+unsigned int
+leds_count(void)
+{
+ unsigned int cnt = 0;
+ struct list_head *hd;
+ read_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ cnt += ((struct linux_leds_info *)hd)->count;
+ }
+ read_unlock(&led_list_lock);
+ return cnt;
+}
+
+static int
+del_led_owner(struct led_owner *who, unsigned int idx, struct linux_leds_info *leds)
+{
+ if (leds->owners == NULL)
+ return -EBUSY;
+ if (leds->owners[idx].ownertype == leds_noone)
+ return -EBUSY;
+ if (leds->owners[idx].ownertype != who->ownertype)
+ return -EPERM;
+ switch (who->ownertype)
+ {
+ case leds_noone:
+ return -EBADFD;
+ case leds_user:
+ if (leds->owners[idx].ownerdata.processdata.pid != who->ownerdata.processdata.pid)
+ return -EPERM;
+ leds->owners[idx].ownertype = leds_noone;
+ return 0;
+ case leds_kernel:
+ if (leds->owners[idx].ownerdata.module != who->ownerdata.module)
+ return -EPERM;
+ leds->owners[idx].ownertype = leds_noone;
+ return 0;
+ }
+ return -EBUSY;
+}
+
+static int
+add_led_owner(struct led_owner *who, unsigned int idx, struct linux_leds_info *leds)
+{
+ if (leds->owners == NULL)
+ {
+ int i;
+ leds->owners = kmalloc (leds->count * sizeof(struct led_owner), GFP_KERNEL);
+ if (leds->owners == NULL)
+ return -ENOMEM;
+ for (i = 0 ; i < leds->count ; ++i)
+ {
+ leds->owners[i].ownertype = leds_noone;
+ }
+ }
+ if (leds->owners[idx].ownertype == leds_noone)
+ {
+ leds->owners[idx].ownertype = who->ownertype;
+ switch (who->ownertype)
+ {
+ case leds_noone:
+ return -EBADFD;
+ break;
+ case leds_user:
+ leds->owners[idx].ownerdata.processdata.pid = who->ownerdata.processdata.pid;
+ leds->owners[idx].ownerdata.processdata.uid = who->ownerdata.processdata.uid;
+ return 0;
+ break;
+ case leds_kernel:
+ leds->owners[idx].ownerdata.module = who->ownerdata.module;
+ return 0;
+ }
+ }
+ return -EBUSY;
+}
+
+static int
+is_allowed(struct led_owner *who, unsigned int idx, struct linux_leds_info *leds)
+{
+ int ret = -EBUSY;
+ read_lock(&led_list_lock);
+ if (leds->owners == NULL)
+ ret = 0;
+ if (leds->owners[idx].ownertype == who->ownertype)
+ {
+ switch (who->ownertype)
+ {
+ case leds_noone:
+ break;
+ case leds_user:
+ if (leds->owners[idx].ownerdata.processdata.pid != who->ownerdata.processdata.pid)
+ break;
+ ret = 0;
+ break;
+ case leds_kernel:
+ if (leds->owners[idx].ownerdata.module != who->ownerdata.module)
+ break;
+ ret = 0;
+ }
+ }
+ read_unlock(&led_list_lock);
+ return ret;
+}
+
+static int
+led_release_real(struct led_owner *who, unsigned int which)
+{
+ struct list_head *hd;
+ int tmp;
+ write_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ if (((which >> 24) & 0xff) == ((struct linux_leds_info *)hd)->id)
+ {
+ if ((tmp = del_led_owner(who, which & 0xffffff, (struct linux_leds_info *)hd)) == 0)
+ {
+ ((struct linux_leds_info *)hd)->release(((struct linux_leds_info *)hd)->data);
+ }
+ write_unlock(&led_list_lock);
+ return tmp;
+ }
+ }
+ write_unlock(&led_list_lock);
+ return -ENODEV;
+}
+
+static int
+led_reserve_real(struct led_owner *who, unsigned int *which)
+{
+ struct list_head *hd;
+ int tmp;
+ write_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ int i;
+ hd = hd->next;
+ for (i=0 ; i < ((struct linux_leds_info *)hd)->count ; ++i)
+ {
+ if ((tmp = add_led_owner(who, i, (struct linux_leds_info *)hd)) == 0)
+ {
+ *which = ((struct linux_leds_info *)hd)->id;
+ *which <<= 24;
+ *which |= i;
+ ((struct linux_leds_info *)hd)->reserve(((struct linux_leds_info *)hd)->data);
+ write_unlock(&led_list_lock);
+ return tmp;
+ }
+ }
+ }
+ write_unlock(&led_list_lock);
+ return -ENODEV;
+}
+
+static int
+led_set_real (struct led_owner *who, unsigned int which, unsigned char state)
+{
+ struct list_head *hd;
+ int ret;
+ read_lock(&led_list_lock);
+ hd = &led_list;
+ if (state) state=~0;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ if (((which >> 24) & 0xff) == ((struct linux_leds_info *)hd)->id)
+ {
+ if ((which & 0xffffff) > ((struct linux_leds_info *)hd)->count)
+ {
+ read_unlock(&led_list_lock);
+ return -ENODEV;
+ }
+ if ((ret = is_allowed(who, which & 0xffffff, (struct linux_leds_info *)hd)) == 0)
+ ((struct linux_leds_info *)hd)->set_state(which & 0xffffff, state, ((struct linux_leds_info *)hd)->data);
+ read_unlock(&led_list_lock);
+ return ret;
+ }
+ }
+ read_unlock(&led_list_lock);
+ return -ENODEV;
+}
+
+int led_release (unsigned int idx, struct module *mod)
+{
+ struct led_owner a;
+ a.ownertype = leds_kernel;
+ a.ownerdata.module = mod;
+ return led_release_real(&a, idx);
+}
+
+int led_reserve (unsigned int *which, struct module *mod)
+{
+ struct led_owner a;
+ a.ownertype = leds_kernel;
+ a.ownerdata.module = mod;
+ return led_reserve_real(&a, which);
+}
+
+int
+led_set(unsigned int idx, unsigned char state, struct module *mod)
+{
+ struct led_owner a;
+ a.ownertype = leds_kernel;
+ a.ownerdata.module = mod;
+ return led_set_real(&a, idx, state);
+}
+
+int
+led_get(unsigned int which)
+{
+ struct list_head *hd;
+ unsigned char state;
+ read_lock(&led_list_lock);
+ hd = &led_list;
+ while (hd->next != &led_list)
+ {
+ hd = hd->next;
+ if (((which >> 24) & 0xff) == ((struct linux_leds_info *)hd)->id)
+ {
+ if ((which & 0xffffff) > ((struct linux_leds_info *)hd)->count)
+ {
+ read_unlock(&led_list_lock);
+ return -ENODEV;
+ }
+ state = ((struct linux_leds_info *)hd)->get_state(which & 0xffffff, ((struct linux_leds_info *)hd)->data);
+ read_unlock(&led_list_lock);
+ if (state) state=~0;
+ return state;
+ }
+ }
+ read_unlock(&led_list_lock);
+ return -ENODEV;
+}
+
+static int
+leds_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ unsigned int idx;
+ unsigned char state;
+ signed int tmp;
+ struct led_owner a;
+ pid_t pid;
+ if (MINOR(inode->i_rdev) != 0xff) {
+ return -ENOTTY;
+ }
+ if (_IOC_TYPE(cmd) != LINUX_LEDS_IOC_MAGIC) {
+ return -ENOTTY;
+ }
+ if (_IOC_NR(cmd) > LINUX_LEDS_IOC_MAX_NR) {
+ return -ENOTTY;
+ }
+ if ((_IOC_DIR(cmd) & _IOC_READ) && (!access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd))))
+ return -EFAULT;
+ else if ((_IOC_DIR(cmd) & _IOC_WRITE) && (!access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd))))
+ return -EFAULT;
+ a.ownertype = leds_user;
+ a.ownerdata.processdata.pid = current->tgid;
+ a.ownerdata.processdata.uid = current->uid;
+ switch (cmd)
+ {
+ case LINUX_LEDS_IOC_COUNT_LEDS:
+ idx = leds_count();
+ __put_user(idx, (unsigned int *)arg);
+ return 0;
+ case LINUX_LEDS_IOC_SET_LED:
+ __get_user (idx, &(((struct linux_leds *)arg)->idx));
+ __get_user (state, &(((struct linux_leds *)arg)->state));
+ return led_set_real (&a, idx, state);
+ case LINUX_LEDS_IOC_GET_LED:
+ __get_user (idx, &(((struct linux_leds *)arg)->idx));
+ tmp = led_get(idx);
+ if (tmp < 0)
+ return tmp;
+ state = ((unsigned int)tmp) &0xff;
+ __put_user (state, &(((struct linux_leds *)arg)->state));
+ return 0;
+ case LINUX_LEDS_IOC_RESERVE_LED:
+ tmp = led_reserve_real (&a, &idx);
+ __put_user (idx, (unsigned int *)arg);
+ return tmp;
+ case LINUX_LEDS_IOC_RELEASE_LED:
+ __get_user (idx, (unsigned int *)arg);
+ return led_release_real (&a, idx);
+ case LINUX_LEDS_IOC_BREAK_LOCK:
+ __get_user (pid, (pid_t *)arg);
+ if (!capable(CAP_DAC_OVERRIDE))
+ {
+ a.ownerdata.processdata.pid = pid;
+ release_all_owned_by (&a);
+ }
+ else
+ release_all_owned_by_pid(pid);
+ return 0;
+ }
+ /* Unreachable code */
+ return -ENOTTY;
+}
+
+static int
+leds_open (struct inode *inode, struct file *filp)
+{
+ if (MINOR(inode->i_rdev) != 0xff) return -ENODEV;
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int
+leds_release (struct inode *inode, struct file *filp)
+{
+ release_all_owned_by_pid (current->tgid);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+struct file_operations leds_fops = {
+open: leds_open,
+release: leds_release,
+ioctl: leds_ioctl,
+owner: THIS_MODULE,
+};
+
+void __exit
+leds_exit (void)
+{
+ remove_proc_entry("leds", NULL);
+ if (have_devfs)
+ {
+ devfs_unregister (ledsctl);
+ devfs_unregister (ledsdir);
+ }
+ unregister_chrdev(leds_major_num, "leds");
+}
+
+int __init
+leds_init (void)
+{
+ int maj;
+ maj = register_chrdev(0, "leds", &leds_fops);
+ if (maj < 0) return maj;
+ leds_major_num = maj;
+ printk(KERN_NOTICE "leds: assigned major number %u\n", leds_major_num);
+ write_lock(&led_list_lock);
+ INIT_LIST_HEAD(&led_list);
+ write_unlock(&led_list_lock);
+ ledsdir = devfs_mk_dir (NULL, "leds", NULL);
+ if (ledsdir != NULL)
+ {
+ have_devfs = 1;
+ ledsctl = devfs_register (ledsdir, "ctl", DEVFS_FL_DEFAULT, leds_major_num, 0xff, S_IFCHR | 0666 , &leds_fops, NULL);
+ if (ledsctl == NULL)
+ {
+ devfs_unregister (ledsdir);
+ unregister_chrdev(leds_major_num, "leds");
+ return -EBUSY;
+ }
+ }
+ create_proc_read_entry("leds", 0, NULL, leds_read_proc, NULL);
+ return 0;
+}
+
+module_init(leds_init);
+module_exit(leds_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
+MODULE_DESCRIPTION("Provides a generic kernel interface for LED control");
+EXPORT_SYMBOL(led_get);
+EXPORT_SYMBOL(led_set);
+EXPORT_SYMBOL(led_reserve);
+EXPORT_SYMBOL(led_release);
+EXPORT_SYMBOL(leds_count);
+EXPORT_SYMBOL(leds_add);
+EXPORT_SYMBOL(leds_del);
diff -uNr linux-2.4.21.vanilla/drivers/leds/Makefile linux-2.4.21.patched/drivers/leds/Makefile
--- linux-2.4.21.vanilla/drivers/leds/Makefile 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/Makefile 2003-07-29 15:29:31.000000000 +0100
@@ -0,0 +1,20 @@
+#
+# Makefile for the kernel LED device drivers.
+#
+
+obj-y:=
+
+obj-m:=
+
+# All of the (potential) objects that export symbols.
+# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
+
+export-objs:=leds.o
+
+obj-$(CONFIG_LEDS) += leds.o
+obj-$(CONFIG_PIIX4E_LEDS) += piix4e_leds.o
+obj-$(CONFIG_PARPORT_LEDS) += parport_leds.o
+obj-$(CONFIG_KBEAT_LED) += kbeat_led.o
+obj-$(CONFIG_UBEAT) += ubeat.o
+
+include $(TOPDIR)/Rules.make
diff -uNr linux-2.4.21.vanilla/drivers/leds/parport_leds.c linux-2.4.21.patched/drivers/leds/parport_leds.c
--- linux-2.4.21.vanilla/drivers/leds/parport_leds.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/parport_leds.c 2003-07-22 13:55:10.000000000 +0100
@@ -0,0 +1,144 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/parport.h>
+#include <linux/errno.h>
+#include <linux/leds.h>
+#include <linux/spinlock.h>
+
+static spinlock_t parled_lock= SPIN_LOCK_UNLOCKED;
+static unsigned char parled_state = 0;
+static int parled_parport = -1;
+static struct pardevice *parleds_dev = NULL;
+
+static void
+release (void *ignore)
+{
+ MOD_DEC_USE_COUNT;
+}
+
+static void
+reserve (void *ignore)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static void
+set_state (unsigned int idx, unsigned char state, void *ignore)
+{
+ spin_lock(&parled_lock);
+ parled_state &= ~(1 << idx);
+ parled_state |= state & (1 << idx);
+ parleds_dev->port->ops->write_data (parleds_dev->port, parled_state);
+ spin_unlock(&parled_lock);
+}
+
+static unsigned char
+get_state (unsigned int idx, void *ignore)
+{
+ unsigned char reg;
+ spin_lock(&parled_lock);
+ reg = parled_state;
+ spin_unlock(&parled_lock);
+ reg &= (1 << idx);
+ return reg;
+}
+
+static void
+attach (struct parport *thing)
+{
+ if (parled_parport >= 0)
+ return;
+ for (parled_parport = 0 ; parled_parport < PARPORT_MAX ; ++parled_parport)
+ {
+ if (thing == NULL)
+ {
+ printk (KERN_DEBUG "parport_leds: Moo %d\n", parled_parport);
+ continue;
+ }
+ if (thing->number == parled_parport)
+ {
+ struct pardevice *dev;
+ dev = parport_register_device (thing, "leds", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);
+ if (dev == NULL)
+ {
+ printk (KERN_DEBUG "parport_leds: Baa %d\n", parled_parport);
+ continue;
+ }
+ if (!parport_claim (dev) == 0)
+ {
+ parled_parport = -1;
+ }
+ else
+ {
+ parleds_dev = thing->devices;
+ }
+ return;
+ }
+ }
+ parled_parport = -1;
+ return;
+}
+
+static void
+detach (struct parport *thing)
+{
+}
+
+static struct linux_leds_info parleds = {
+get_state:get_state,
+set_state:set_state,
+reserve:reserve,
+release:release,
+count:8,
+drivername:THIS_MODULE,
+};
+
+static struct parport_driver parleds_driver = {
+name:"parleds",
+attach:attach,
+detach:detach,
+};
+
+int __init
+init_parallel_leds (void)
+{
+ int c;
+ if (parport_register_driver (&parleds_driver) != 0)
+ {
+ printk (KERN_INFO "parport_leds: parport_register_driver failed\n");
+ return -EIO;
+ }
+ if (parled_parport < 0)
+ {
+ parport_unregister_driver (&parleds_driver);
+ printk (KERN_INFO "parport_leds: couldn't claim a parallel port\n");
+ return -EIO;
+ }
+ c = leds_add (&parleds);
+ if (c != 0)
+ {
+ parport_unregister_driver (&parleds_driver);
+ printk (KERN_INFO "parport_leds: leds_add failed\n");
+ return -ENODEV;
+ }
+ return c;
+}
+
+void __exit
+cleanup_parallel_leds (void)
+{
+ leds_del (&parleds);
+ parport_release (parleds_dev);
+ parport_unregister_device (parleds_dev);
+ parport_unregister_driver (&parleds_driver);
+}
+
+module_init(init_parallel_leds);
+module_exit(cleanup_parallel_leds);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
+MODULE_DESCRIPTION("This module provides kernel control for programmable LEDs wired up to the parallel port");
+MODULE_SUPPORTED_DEVICE("Parallel port LED boxes");
+EXPORT_NO_SYMBOLS;
+
diff -uNr linux-2.4.21.vanilla/drivers/leds/piix4e_leds.c linux-2.4.21.patched/drivers/leds/piix4e_leds.c
--- linux-2.4.21.vanilla/drivers/leds/piix4e_leds.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/piix4e_leds.c 2003-07-22 13:54:46.000000000 +0100
@@ -0,0 +1,116 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/leds.h>
+#include <linux/spinlock.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+static const unsigned char bxled_mask[] = {0x01, 0x10};
+static const unsigned short bxled_port[] = {0x0435, 0x0437};
+static spinlock_t bxled_lock[] = {SPIN_LOCK_UNLOCKED, SPIN_LOCK_UNLOCKED};
+
+static void
+release (void * ignored)
+{
+ MOD_DEC_USE_COUNT;
+}
+
+static void
+reserve (void * ignored)
+{
+ MOD_INC_USE_COUNT;
+}
+
+static void
+set_state (unsigned int idx, unsigned char state, void *ignored)
+{
+ unsigned char reg;
+ spin_lock(&bxled_lock[idx]);
+ reg = inb(bxled_port[idx]);
+ reg &= ~bxled_mask[idx];
+ reg |= state & bxled_mask[idx];
+ outb (reg, bxled_port[idx]);
+ spin_unlock(&bxled_lock[idx]);
+}
+
+static unsigned char
+get_state (unsigned int idx, void * ignored)
+{
+ unsigned char reg;
+ spin_lock(&bxled_lock[idx]);
+ reg = inb(bxled_port[idx]);
+ spin_unlock(&bxled_lock[idx]);
+ reg &= bxled_mask[idx];
+ return reg;
+}
+
+static struct linux_leds_info bxleds = {
+get_state:get_state,
+set_state:set_state,
+reserve:reserve,
+release:release,
+count:2,
+data:NULL,
+drivername:THIS_MODULE,
+};
+
+int __init
+init_isp1100_lights (void)
+{
+ int c;
+ if (!pci_present())
+ return -ENODEV;
+ if (!(pci_find_device(PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_82371AB_3,NULL)))
+ return -ENODEV;
+ if (!request_region (bxled_port[0], 1, "Intel PIIX4E LED U1"))
+ return -EBUSY;
+ c = -EBUSY;
+ if (!request_region (bxled_port[1], 1, "Intel PIIX4E LED U2"))
+ goto cleanup_zero;
+ /* Now check if there are actually LEDs there. Boards with them unconnected
+ * seem to lose the status of the IO port -- I therefore assume, if the bit
+ * sticks, poke it
+ */
+ c = -ENODEV;
+ set_state (0, 0, NULL);
+ set_state (1, 0, NULL);
+ if (get_state (0, NULL))
+ goto cleanup_both;
+ if (get_state (1, NULL))
+ goto cleanup_both;
+ set_state (0, ~0, NULL);
+ set_state (1, ~0, NULL);
+ if (!get_state (0, NULL))
+ goto cleanup_both;
+ if (!get_state (1, NULL))
+ goto cleanup_both;
+ c = leds_add (&bxleds);
+ if (c != 0)
+ goto cleanup_both;
+ return c;
+cleanup_both:
+ release_region (bxled_port[1], 1);
+cleanup_zero:
+ release_region (bxled_port[0], 1);
+ return c;
+}
+
+void __exit
+cleanup_isp1100_lights (void)
+{
+ leds_del (&bxleds);
+ release_region (bxled_port[1], 1);
+ release_region (bxled_port[0], 1);
+}
+
+module_init(init_isp1100_lights);
+module_exit(cleanup_isp1100_lights);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
+MODULE_DESCRIPTION("This module provides kernel control for the programmable LEDs on Intel PIIX4E Systems");
+MODULE_SUPPORTED_DEVICE("Intel PIIX4E Chipset");
+EXPORT_NO_SYMBOLS;
+
diff -uNr linux-2.4.21.vanilla/drivers/leds/ubeat.c linux-2.4.21.patched/drivers/leds/ubeat.c
--- linux-2.4.21.vanilla/drivers/leds/ubeat.c 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/drivers/leds/ubeat.c 2003-07-22 14:06:38.000000000 +0100
@@ -0,0 +1,187 @@
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/ubeat.h>
+#include <linux/leds.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/timer.h>
+#include <linux/spinlock.h>
+#include <linux/fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/ioctl.h>
+
+static unsigned int ubeat_major_num;
+static volatile int ubeat_have_led = 0;
+static int have_devfs = 0;
+static unsigned int ubeat_led;
+static volatile unsigned char ubeat_state = 0;
+static struct timer_list ubeat_timer;
+static unsigned int ubeat_interval;
+static signed int ubeat_timeout __initdata = 2;
+static devfs_handle_t ubeatdir;
+static devfs_handle_t ubeatctl;
+static spinlock_t ubeat_use_lock = SPIN_LOCK_UNLOCKED;
+static volatile int inuse = 0;
+static atomic_t ubeat_carp;
+
+static void
+ubeat_timeup (unsigned long ignored)
+{
+ if (atomic_read(&ubeat_carp) == 0)
+ return;
+ atomic_set (&ubeat_carp, 0);
+ printk(KERN_ALERT "ubeat: User heartbeat not detected - FIX ME!!!!\n");
+}
+
+static int
+ubeat_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ if (MINOR(inode->i_rdev) != 0)
+ {
+ printk( KERN_DEBUG "ubeat: Minor number was %u\n", MINOR(inode->i_rdev));
+ return -ENODEV;
+ }
+ if (_IOC_TYPE(cmd) != LINUX_UBEAT_IOC_MAGIC)
+ {
+ printk( KERN_DEBUG "ubeat: Magic number was 0x%x\n", _IOC_TYPE(cmd));
+ return -ENOTTY;
+ }
+ if (_IOC_NR(cmd) > LINUX_UBEAT_IOC_MAX_NR)
+ {
+ printk( KERN_DEBUG "ubeat: Command number was %u\n", _IOC_NR(cmd));
+ return -ENOTTY;
+ }
+ switch (cmd)
+ {
+ case LINUX_UBEAT_IOC_POKE:
+ spin_lock(&ubeat_use_lock);
+ del_timer_sync(&ubeat_timer);
+ ubeat_timer.expires = jiffies + ubeat_interval;
+ add_timer(&ubeat_timer);
+ spin_unlock(&ubeat_use_lock);
+ if (ubeat_have_led)
+ {
+ led_set(ubeat_led, ubeat_state, THIS_MODULE);
+ ubeat_state = ~ubeat_state;
+ }
+ return 0;
+ case LINUX_UBEAT_IOC_FIXT:
+ spin_lock(&ubeat_use_lock);
+ del_timer_sync(&ubeat_timer);
+ ubeat_timer.expires = jiffies + ubeat_interval;
+ add_timer(&ubeat_timer);
+ spin_unlock(&ubeat_use_lock);
+ atomic_set (&ubeat_carp, 1);
+ return 0;
+ }
+ return -ENOTTY;
+}
+
+
+static int
+ubeat_open (struct inode *inode, struct file *filp)
+{
+ MOD_INC_USE_COUNT;
+ spin_lock(&ubeat_use_lock);
+ ++inuse;
+ del_timer_sync(&ubeat_timer);
+ ubeat_timer.expires = jiffies + ubeat_interval;
+ add_timer(&ubeat_timer);
+ spin_unlock(&ubeat_use_lock);
+ return 0;
+}
+
+static int
+ubeat_release (struct inode *inode, struct file *filp)
+{
+ MOD_DEC_USE_COUNT;
+ spin_lock(&ubeat_use_lock);
+ --inuse;
+ if (inuse == 0)
+ {
+ del_timer_sync(&ubeat_timer);
+ atomic_set (&ubeat_carp, 1);
+ }
+ spin_unlock(&ubeat_use_lock);
+ return 0;
+}
+
+
+static struct file_operations ubeat_fops = {
+open: ubeat_open,
+release: ubeat_release,
+ioctl: ubeat_ioctl,
+owner: THIS_MODULE,
+};
+
+void __exit
+ubeat_exit(void)
+{
+ del_timer_sync(&ubeat_timer);
+ if (ubeat_have_led)
+ led_release(ubeat_led, THIS_MODULE);
+ if (have_devfs)
+ {
+ devfs_unregister (ubeatctl);
+ devfs_unregister (ubeatdir);
+ }
+ unregister_chrdev(ubeat_major_num, "ubeat");
+}
+
+int __init
+ubeat_init(void)
+{
+ int maj;
+ atomic_set (&ubeat_carp, 1);
+ maj = register_chrdev(0, "ubeat", &ubeat_fops);
+ if (maj < 0) return maj;
+ ubeat_major_num = maj;
+ printk (KERN_NOTICE "ubeat: got major number %u\n", ubeat_major_num);
+ ubeatdir = devfs_mk_dir(NULL, "ubeat", NULL);
+ if (ubeatdir != NULL)
+ {
+ have_devfs = 1;
+ unregister_chrdev(ubeat_major_num, "ubeat");
+ ubeatctl = devfs_register (ubeatdir, "pokeme", DEVFS_FL_DEFAULT, ubeat_major_num, 0, S_IFCHR | 0660 , &ubeat_fops, NULL);
+ if (ubeatctl == NULL)
+ {
+ devfs_unregister (ubeatdir);
+ unregister_chrdev(ubeat_major_num, "ubeat");
+ return -EBUSY;
+ }
+ }
+ if (led_reserve(&ubeat_led, THIS_MODULE) == 0)
+ {
+ printk (KERN_INFO "ubeat_led: got led %.8x\n", ubeat_led);
+ ubeat_have_led = 1;
+ }
+ if (ubeat_timeout == 0)
+ {
+ printk (KERN_INFO "ubeat_led: timeout value '0' is invalid, using 2\n");
+ ubeat_timeout = 2;
+ }
+ if (ubeat_timeout < 0)
+ {
+ ubeat_interval = HZ / (-1 * ubeat_timeout);
+ } else {
+ ubeat_interval = HZ * ubeat_timeout;
+ }
+ if (ubeat_interval == 0)
+ {
+ printk (KERN_INFO "ubeat_led: timeout value out of range, using 2\n");
+ ubeat_interval = 2 * HZ;
+ }
+ init_timer (&ubeat_timer);
+ ubeat_timer.function = ubeat_timeup;
+ return 0;
+}
+
+module_init(ubeat_init);
+module_exit(ubeat_exit);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
+MODULE_DESCRIPTION("Provides kernel interface to keep an eye on user programs");
+EXPORT_NO_SYMBOLS;
+MODULE_PARM(ubeat_timeout, "i");
+MODULE_PARM_DESC(ubeat_timeout, "Seconds before the kernel should alert you, fractions below 1s can be specified with -ve numbers e.g. -2 means wait 1/2 a second.");
diff -uNr linux-2.4.21.vanilla/drivers/Makefile linux-2.4.21.patched/drivers/Makefile
--- linux-2.4.21.vanilla/drivers/Makefile 2003-07-17 17:04:35.000000000 +0100
+++ linux-2.4.21.patched/drivers/Makefile 2003-07-29 15:28:17.000000000 +0100
@@ -48,5 +48,6 @@
subdir-$(CONFIG_ACPI) += acpi

subdir-$(CONFIG_BLUEZ) += bluetooth
+subdir-$(CONFIG_LEDS) += leds

include $(TOPDIR)/Rules.make
diff -uNr linux-2.4.21.vanilla/include/linux/leds.h linux-2.4.21.patched/include/linux/leds.h
--- linux-2.4.21.vanilla/include/linux/leds.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/include/linux/leds.h 2003-07-22 14:07:52.000000000 +0100
@@ -0,0 +1,68 @@
+#ifndef LINUX_LEDS_H__
+#define LINUX_LEDS_H__
+
+#ifdef __KERNEL__
+
+#include <linux/list.h>
+
+enum ownertype
+{
+ leds_noone = 0,
+ leds_kernel,
+ leds_user,
+};
+
+struct led_owner
+{
+ enum ownertype ownertype;
+ union
+ {
+ struct module *module;
+ struct {
+ pid_t pid;
+ uid_t uid;
+ } processdata;
+ } ownerdata;
+};
+
+struct linux_leds_info
+{
+ struct list_head list;
+ unsigned int id:8;
+ unsigned int count:24;
+ unsigned char (*get_state)(unsigned int, void *);
+ void (*set_state)(unsigned int, unsigned char, void *);
+ void (*reserve)(void *);
+ void (*release)(void *);
+ void *data;
+ struct module *drivername;
+ struct led_owner *owners;
+};
+
+extern int led_get(unsigned int idx);
+extern int led_set(unsigned int idx, unsigned char state, struct module *mod);
+extern int led_reserve(unsigned int *idx, struct module *mod);
+extern int led_release(unsigned int idx, struct module *mod);
+extern unsigned int leds_count(void);
+extern int leds_add (struct linux_leds_info *);
+extern int leds_del (struct linux_leds_info *);
+
+#endif /* defined __KERNEL__ */
+
+#include <linux/ioctl.h>
+
+struct linux_leds {
+ unsigned int idx; /* LEDS are indexed from zero */
+ unsigned char state; /* 0 for off, ~0 for on */
+};
+
+#define LINUX_LEDS_IOC_MAGIC 0x81
+#define LINUX_LEDS_IOC_COUNT_LEDS _IOR(LINUX_LEDS_IOC_MAGIC, 0, unsigned int)
+#define LINUX_LEDS_IOC_SET_LED _IOW(LINUX_LEDS_IOC_MAGIC, 1, struct linux_leds)
+#define LINUX_LEDS_IOC_GET_LED _IOR(LINUX_LEDS_IOC_MAGIC, 2, struct linux_leds)
+#define LINUX_LEDS_IOC_RESERVE_LED _IOR(LINUX_LEDS_IOC_MAGIC, 3, unsigned int)
+#define LINUX_LEDS_IOC_RELEASE_LED _IOW(LINUX_LEDS_IOC_MAGIC, 4, unsigned int)
+#define LINUX_LEDS_IOC_BREAK_LOCK _IOW(LINUX_LEDS_IOC_MAGIC, 5, pid_t)
+#define LINUX_LEDS_IOC_MAX_NR 5
+
+#endif /* ! defined LINUX_LEDS_H__ */
diff -uNr linux-2.4.21.vanilla/include/linux/ubeat.h linux-2.4.21.patched/include/linux/ubeat.h
--- linux-2.4.21.vanilla/include/linux/ubeat.h 1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.21.patched/include/linux/ubeat.h 2003-07-10 21:31:31.000000000 +0100
@@ -0,0 +1,11 @@
+#ifndef LINUX_UBEAT_H__
+#define LINUX_UBEAT_H__
+
+#include <linux/ioctl.h>
+
+#define LINUX_UBEAT_IOC_MAGIC 0x75
+#define LINUX_UBEAT_IOC_POKE _IO(LINUX_UBEAT_IOC_MAGIC, 0)
+#define LINUX_UBEAT_IOC_FIXT _IO(LINUX_UBEAT_IOC_MAGIC, 1)
+#define LINUX_UBEAT_IOC_MAX_NR 1
+
+#endif /* ! defined LINUX_UBEAT_H__ */


2003-07-29 19:54:16

by John Bradford

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> This patch adds an abstraction layer for programmable LED devices,
> hardware drivers for the Status LEDs found on some Intel PIIX4E based
> server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
> to the parallel port data lines.

I haven't had chance to test this yet, but I really like the idea - by
an amasing co-incidence, I was actually thinking about the possibility
of doing a parallel port connected front panel earlier today!

Does anybody have any suggestions for recommended standard uses for
parallel port connected LEDs?

Disk spinning up/disk ready
Root login active

Any other suggestions?

John.

2003-07-29 20:10:12

by Joel Jaeggli

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, 29 Jul 2003, John Bradford wrote:

> > This patch adds an abstraction layer for programmable LED devices,
> > hardware drivers for the Status LEDs found on some Intel PIIX4E based
> > server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
> > to the parallel port data lines.
>
> I haven't had chance to test this yet, but I really like the idea - by
> an amasing co-incidence, I was actually thinking about the possibility
> of doing a parallel port connected front panel earlier today!
>
> Does anybody have any suggestions for recommended standard uses for
> parallel port connected LEDs?
>
> Disk spinning up/disk ready
> Root login active

provide a userspace interface and people will use it for all sorts of
strange things...

email deliverly notification, varying levels of log messages and output,
from lmsensors come to mind immediatly...

> Any other suggestions?
>
> John.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

--
--------------------------------------------------------------------------
Joel Jaeggli Academic User Services [email protected]
-- PGP Key Fingerprint: 1DE9 8FCA 51FB 4195 B42A 9C32 A30D 121E --
In Dr. Johnson's famous dictionary patriotism is defined as the last
resort of the scoundrel. With all due respect to an enlightened but
inferior lexicographer I beg to submit that it is the first.
-- Ambrose Bierce, "The Devil's Dictionary"


2003-07-29 20:08:25

by Tim Hockin

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> I haven't had chance to test this yet, but I really like the idea - by
> an amasing co-incidence, I was actually thinking about the possibility
> of doing a parallel port connected front panel earlier today!
>
> Does anybody have any suggestions for recommended standard uses for
> parallel port connected LEDs?
>
> Disk spinning up/disk ready
> Root login active

In the cobalt days we had a parallel port connected panel with an LCD (2
lines x 16 characters) 6 buttons (up, down, left, right, select, enter) and
LEDs (Disk, network activity, network link, 100 MB status, and web activity
[required a hacked apache, but it was cute]).

Our RaQXTR boxes had even more - and they were all software programmable.

2003-07-29 20:29:17

by John Bradford

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> > This patch adds an abstraction layer for programmable LED devices,
> > hardware drivers for the Status LEDs found on some Intel PIIX4E based
> > server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
> > to the parallel port data lines.
>
> I haven't had chance to test this yet, but I really like the idea - by
> an amasing co-incidence, I was actually thinking about the possibility
> of doing a parallel port connected front panel earlier today!
>
> Does anybody have any suggestions for recommended standard uses for
> parallel port connected LEDs?
>
> Disk spinning up/disk ready
> Root login active
>
> Any other suggestions?

Ah, I just thought, for debugging purposes we could have LEDs for:

* BKL taken
* Servicing interrupt
* Kernel stack usage > 2K

John.

2003-07-29 20:39:04

by Andries Brouwer

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, Jul 29, 2003 at 09:38:52PM +0100, John Bradford wrote:

> Ah, I just thought, for debugging purposes we could have LEDs for:
>
> * BKL taken
> * Servicing interrupt
> * Kernel stack usage > 2K

Ever tried keyboard.c:register_leds() ?


2003-07-29 20:40:57

by Randolph Bentson

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, Jul 29, 2003 at 09:38:52PM +0100, John Bradford wrote:
> Ah, I just thought, for debugging purposes we could have LEDs for:
>
> * BKL taken
> * Servicing interrupt
> * Kernel stack usage > 2K

In the way olden days we used the console lights for a realtime
display of buffer use on a PDP-11. This type of realtime display
can be most useful, especially if it's easily configurable.

--
Randolph Bentson
[email protected]

2003-07-29 20:43:28

by Eli Carter

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

John Bradford wrote:
>>>This patch adds an abstraction layer for programmable LED devices,
>>>hardware drivers for the Status LEDs found on some Intel PIIX4E based
>>>server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
>>>to the parallel port data lines.
>>
>>I haven't had chance to test this yet, but I really like the idea - by
>>an amasing co-incidence, I was actually thinking about the possibility
>>of doing a parallel port connected front panel earlier today!
>>
>>Does anybody have any suggestions for recommended standard uses for
>>parallel port connected LEDs?
>>
>>Disk spinning up/disk ready
>>Root login active
>>
>>Any other suggestions?
>
>
> Ah, I just thought, for debugging purposes we could have LEDs for:
>
> * BKL taken
> * Servicing interrupt
> * Kernel stack usage > 2K

Maybe also:
* 100% CPU usage
* Toggle each jiffie (help detect interrupts disabled)
* User control for things like cpu/harddrive temp...
* and of course, Morse code ;)

Have fun,

Eli
--------------------. "If it ain't broke now,
Eli Carter \ it will be soon." -- crypto-gram
eli.carter(a)inet.com `-------------------------------------------------

2003-07-29 21:21:27

by Ryan Flowers

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever



> On Tue, Jul 29, 2003 at 09:38:52PM +0100, John Bradford wrote:
> > Ah, I just thought, for debugging purposes we could have LEDs for:
> >
> > * BKL taken
> > * Servicing interrupt
> > * Kernel stack usage > 2K
>
> In the way olden days we used the console lights for a realtime
> display of buffer use on a PDP-11. This type of realtime display
> can be most useful, especially if it's easily configurable.
>
> --
> Randolph Bentson
> [email protected]
> -
These ideas based on my experience in a production server environment, in
web hosting:

Temperature (Red/Yellow/Green LED)
CPU load (Red/Yellow/Green LED)
Out of Memory (blinking red?)

Don't imagine it would be hard to make a red LED status also set off an
alarm via the PC speaker. Although really a proper system will alert you of
these things anyway, but it would be nice to see it at a glance too.

Ryan Flowers - Reno NV
http://www.ryanflowers.com

2003-07-29 21:38:34

by Philip Graham Willoughby

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On 2003-07-29 22:37:45 +0000, Andries Brouwer wrote:
> On Tue, Jul 29, 2003 at 09:38:52PM +0100, John Bradford wrote:
>
> > Ah, I just thought, for debugging purposes we could have LEDs for:
> >
> > * BKL taken
> > * Servicing interrupt
> > * Kernel stack usage > 2K
>
> Ever tried keyboard.c:register_leds() ?

Nope -- I have just hacked together a driver to expose the keyboard leds
vie my leds interface (see below), _but_ register_leds is not an exported
symbol, not is it declared in <linux/keyboard.h> (on 2.4.21 anyway), so
you'll need to make some modifications if you want to actually use it.

Also, I'm not sure if there is a way of unregistering leds you register
in this way -- I've done a bodge job thus far, but you take your life in
your hands when you unload this module (in other words, don't).

Regards,

Philip Willoughby

Systems Programmer, Department of Computing, Imperial College, London, UK
--
echo [email protected] | tr "bizndfohces" "pwgd9ociaku"
Why reinvent the wheel? Because we can make it rounder...

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/leds.h>
#include <linux/sched.h>
#include <linux/keyboard.h>
#include <linux/spinlock.h>
#include <asm/current.h>

static unsigned int keybleds;
static spinlock_t keybleds_lock = SPIN_LOCK_UNLOCKED;

static void
release (void * ignored)
{
MOD_DEC_USE_COUNT;
}

static void
reserve (void * ignored)
{
MOD_INC_USE_COUNT;
}

static void
set_state (unsigned int idx, unsigned char state, void *ignored)
{
spin_lock(&keybleds_lock);
keybleds &= ~(1 << idx);
keybleds |= state & (1<<idx);
spin_unlock(&keybleds_lock);
}

static unsigned char
get_state (unsigned int idx, void * ignored)
{
unsigned char rv;
spin_lock(&keybleds_lock);
rv = (unsigned char)(keybleds & (1 << idx));
spin_unlock(&keybleds_lock);
return rv;
}

static struct linux_leds_info kbleds = {
get_state:get_state,
set_state:set_state,
reserve:reserve,
release:release,
count:3,
data:NULL,
drivername:THIS_MODULE,
};

static int __init
init_keyb_leds (void)
{
register_leds(0, 0, &keybleds, 1);
register_leds(0, 1, &keybleds, 2);
register_leds(0, 2, &keybleds, 4);
return leds_add (&kbleds);
}

static void __exit
cleanup_keyb_leds (void)
{
register_leds(0, 3, NULL, 0);
register_leds(0, 1, NULL, 0);
register_leds(0, 2, NULL, 0);
register_leds(0, 2, NULL, 0);
}

module_init(init_keyb_leds);
module_exit(cleanup_keyb_leds);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Philip Graham Willoughby <[email protected]>");
MODULE_DESCRIPTION("This module exposes the keyboard LEDs through the generic LEDs interface");
MODULE_SUPPORTED_DEVICE("Keyboards");
EXPORT_NO_SYMBOLS;

2003-07-29 21:23:53

by Kent Borg

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, Jul 29, 2003 at 08:15:06PM +0100, John Bradford wrote:
> Does anybody have any suggestions for recommended standard uses for
> parallel port connected LEDs?

I think someone else mentioned notification of e-mail. Well, I get
too much e-mail for that (I am on the kernel list, after all) but that
suggestion make me think of a soft of "Check Engine" light.

In my Red Hat box there are various sanity checks that happen
regularly and they send me an e-mail when one of those items goes
wrong. For example, if a raid disk dies or a partition gets too full
(what are others?), I get an e-mail. It might be nice to have those
programs also light an LED.


-kb

2003-07-29 21:44:11

by Philip Graham Willoughby

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On 2003-07-29 17:20:35 +0000, Kent Borg wrote:
> On Tue, Jul 29, 2003 at 08:15:06PM +0100, John Bradford wrote:
> > Does anybody have any suggestions for recommended standard uses for
> > parallel port connected LEDs?
>
> I think someone else mentioned notification of e-mail. Well, I get
> too much e-mail for that (I am on the kernel list, after all) but that
> suggestion make me think of a soft of "Check Engine" light.
>
> In my Red Hat box there are various sanity checks that happen
> regularly and they send me an e-mail when one of those items goes
> wrong. For example, if a raid disk dies or a partition gets too full
> (what are others?), I get an e-mail. It might be nice to have those
> programs also light an LED.

Try libleds (hastily written just now ;-)) from
http://csgsoft.doc.ic.ac.uk/leds -- it should make the LED component of
those programs dead easy to write, and also protect you against any
changes anyone ever makes to the ioctls.

I guess you could also port libleds to some other system, but why would
you want to use anything other than linux?

There's no real documentation as yet, but the code is complete. sample
usage:

#include <libleds/libleds.h>
.
.
.
led_t myled;
char ledstatus;

if (reserve_led(&myled) !=0) /* You should similarly check the rc from
the other fns, but I shan't bother here */
{
perror ("Tried to reserve a LED");
exit (EXIT_FAILURE);
}
led_status (myled, &status);
/* status is now nonzero if LED is on, zero if off */
status = !status;
led_set (myled, status);
/* Just toggled it */
release_led (myled);
/* SIGSEGV comes to those who use a led_t after release_led */

V1.1 will have a man page. Woohoo.

Regards,

Philip Willoughby

Systems Programmer, Department of Computing, Imperial College, London, UK
--
echo [email protected] | tr "bizndfohces" "pwgd9ociaku"
Why reinvent the wheel? Because we can make it rounder...

2003-07-30 06:10:11

by Tomas Szepe

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> [[email protected]]
>
> Maybe also:
> ...
> * and of course, Morse code ;)

Provided the lowlevel LED support is hacked together as a module for
the 2.[56] input layer, the current morse code panics patch should work
"out of the box."

--
Tomas Szepe <[email protected]>

2003-07-30 06:28:13

by Pavel Machek

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi!

I'd not said this is so pointless... handhelds tend to have "new mail" led for example.
Better question is why it is not integrated with input subsystem (similar to kbd leds).
Pavel
--
Pavel
Written on sharp zaurus, because my Velo1 broke. If you have Velo you don't need...

2003-07-30 06:37:09

by CaT

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, Jul 29, 2003 at 04:17:03PM +0100, Philip Graham Willoughby wrote:
> Hi all,
>
> This patch adds an abstraction layer for programmable LED devices,

Would this (now or in the future) by any chance let one use the keyboard
leds for stuff without activating their num lock, caps lock and scroll
lock functionality? I'd like to use one of them (at least) as a network
traffic indicator but so far I get the sideffects of the functionality
being on also. Most annoying when typing. :/

--
"How can I not love the Americans? They helped me with a flat tire the
other day," he said.
- http://tinyurl.com/h6fo

2003-07-30 06:37:20

by Helge Deller

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tuesday 29 July 2003 22:43, Eli Carter wrote:
> Maybe also:
> * 100% CPU usage
> * Toggle each jiffie (help detect interrupts disabled)
> * User control for things like cpu/harddrive temp...
> * and of course, Morse code ;)

Older PA-RISC machines have at the front panel a LED
which shows machine load (4 LEDs), heartbeat (1 LED),
SCSI activity (1 LED) and network RX/TX (1 LED each).
This panel is programmable via software and a nice and
consistent linux kernel and userspace API across the
architectures is IMHO a good thing.

Helge

2003-07-30 11:52:57

by Jamey Hicks

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, 2003-07-29 at 14:00, Pavel Machek wrote:
> Hi!
>
> I'd not said this is so pointless... handhelds tend to have "new mail" led for example.
> Better question is why it is not integrated with input subsystem (similar to kbd leds).

I would have thought that leds are output? Why would output devices be
integrated into the input subsystem?

I do think that the Linux kernel should have a generic LED interface for
devices that have them available as indicators.

-Jamey


2003-07-30 12:30:12

by Pavel Machek

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi!

> I haven't had chance to test this yet, but I really like the idea - by
> an amasing co-incidence, I was actually thinking about the possibility
> of doing a parallel port connected front panel earlier today!
>
> Does anybody have any suggestions for recommended standard uses for
> parallel port connected LEDs?
>
> Disk spinning up/disk ready
> Root login active
>
> Any other suggestions?

At one point I had 12 LEDs on parport. LEDs were fast enough to be drive at interrupt entry/exit.
They were:
Yellow not idle task
Green interrupt
" bh
" pagefault
Red lowest 4 bits of PID
Red, low intensity serial i/o
" network i/o

It actually looked very good. Glow of interrupt led
told you interrupt load, pid LEDs told you about what kind of load
it is experiencing (you could tell shell script from make and from computation, and
if machine hard-died, you at least knew if it
was interrupt or process context).
But this kind of blinkenlights needed pretty fast LEDs. (At 486 time I decided that parport on ISA is fast enough..)
Pavel
--
Pavel
Written on sharp zaurus, because my Velo1 broke. If you have Velo you don't need...

2003-07-30 12:31:28

by Pavel Machek

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi!

> > I'd not said this is so pointless... handhelds tend to have "new mail" led for example.
> > Better question is why it is not integrated with input subsystem (similar to kbd leds).
>
> I would have thought that leds are output? Why would output devices be
> integrated into the input subsystem?
>
> I do think that the Linux kernel should have a generic LED interface for
> devices that have them available as indicators.

Most keyboards have leds, some of them even "new mail" led, and input already handles those.
We have that interface already. Its badly named...
--
Pavel
Written on sharp zaurus, because my Velo1 broke. If you have Velo you don't need...

2003-07-30 12:27:25

by Andrey Borzenkov

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever


> This patch adds an abstraction layer for programmable LED devices,
> hardware drivers for the Status LEDs found on some Intel PIIX4E based
> server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
> to the parallel port data lines.

Sorry for a bit OT but - anybody has experience with ASUS I-Panel?
It plugs into SM bus, has several buttons, diodes and LEDs. Some of
buttons are apparently programmable and LED can be used to cycle
through sensor information.

It should be accessible via normal i2c interface but I could not find
any description. Also pressing button when some sensor-aware program
runs gives funny results sometimes :)

TIA

-andrey

2003-07-30 13:00:22

by Andries Brouwer

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 04:36:57PM +1000, CaT wrote:

> Would this (now or in the future) by any chance let one use the keyboard
> leds for stuff without activating their num lock, caps lock and scroll
> lock functionality? I'd like to use one of them (at least) as a network
> traffic indicator but so far I get the sideffects of the functionality
> being on also. Most annoying when typing. :/

The use of LEDs as random lights instead of as keyboard status indicators
has been possible since very early times. See the kernel code, or setleds(1).

2003-07-30 13:19:15

by CaT

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 03:00:15PM +0200, Andries Brouwer wrote:
> On Wed, Jul 30, 2003 at 04:36:57PM +1000, CaT wrote:
>
> > Would this (now or in the future) by any chance let one use the keyboard
> > leds for stuff without activating their num lock, caps lock and scroll
> > lock functionality? I'd like to use one of them (at least) as a network
> > traffic indicator but so far I get the sideffects of the functionality
> > being on also. Most annoying when typing. :/
>
> The use of LEDs as random lights instead of as keyboard status indicators
> has been possible since very early times. See the kernel code, or setleds(1).

Yes. That works. Strange. Every util I tried that was to do what I want
failed because it also activated the functionality so I figured they
couldn't -all- be wrong. :) How wrong I was. Thanks for the heads-up.

--
"How can I not love the Americans? They helped me with a flat tire the
other day," he said.
- http://tinyurl.com/h6fo

2003-07-30 15:40:36

by John Bradford

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> > Would this (now or in the future) by any chance let one use the keyboard
> > leds for stuff without activating their num lock, caps lock and scroll
> > lock functionality? I'd like to use one of them (at least) as a network
> > traffic indicator but so far I get the sideffects of the functionality
> > being on also. Most annoying when typing. :/
>
> The use of LEDs as random lights instead of as keyboard status indicators
> has been possible since very early times. See the kernel code, or setleds(1).

The keyboard LEDs are far too slow to access to use for 'front-panel'
type applications, though.

John.

2003-07-30 15:58:56

by John Bradford

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> > Does anybody have any suggestions for recommended standard uses for
> > parallel port connected LEDs?

> At one point I had 12 LEDs on parport. LEDs were fast enough to be
> drive at interrupt entry/exit.
> They were:
> Yellow not idle task
> Green interrupt
> " bh
> " pagefault
> Red lowest 4 bits of PID
> Red, low intensity serial i/o
> " network i/o
>
> It actually looked very good. Glow of interrupt led told you
> interrupt load, pid LEDs told you about what kind of load it is
> experiencing (you could tell shell script from make and from
> computation, and if machine hard-died, you at least knew if it was
> interrupt or process context).

Sounds like exactly what we need. If we standardise on something like
the above, we could just have a CONFIG_FRONT_PANEL_MONITOR and ask
people to send in the LED status with bug reports.

> But this kind of blinkenlights needed pretty fast LEDs. (At 486 time
> I decided that parport on ISA is fast enough..)

I'll buy some LEDs and build a parallel port connected LED panel
tomorrow... Do you think the overhead of driving the LEDs would have
too much of a negative effect on system performance? If so, or if we
want more flexibility, maybe we could work out a design for a PCI
card, which could include more than 12 LEDs - 7-segment numeric
displays of pid, etc.

John.

2003-07-30 17:45:02

by Pavel Machek

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi!

> > But this kind of blinkenlights needed pretty fast LEDs. (At 486 time
> > I decided that parport on ISA is fast enough..)
>
> I'll buy some LEDs and build a parallel port connected LED panel
> tomorrow... Do you think the overhead of driving the LEDs would have
> too much of a negative effect on system performance? If so, or if
> we

I'm not sure. At 486 days I was pretty sure it did not matter. These
days you might get 10% slowdown on some microbenchmark, or something
like that. I do not think it can slow down common tasks.

My construction of LED lights is extremely flaky, and I'm afraid of
burning printer port. At 486 days ports were expected to survive such
abuse. Not sure if todays EPP/wtf ports can handle that.
Pavel

--
Horseback riding is like software...
...vgf orggre jura vgf serr.

2003-07-30 18:40:38

by John Bradford

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

> > > But this kind of blinkenlights needed pretty fast LEDs. (At 486 time
> > > I decided that parport on ISA is fast enough..)
> >
> > I'll buy some LEDs and build a parallel port connected LED panel
> > tomorrow... Do you think the overhead of driving the LEDs would have
> > too much of a negative effect on system performance? If so, or if
> > we
>
> I'm not sure. At 486 days I was pretty sure it did not matter. These
> days you might get 10% slowdown on some microbenchmark, or something
> like that. I do not think it can slow down common tasks.

OK, so no problems there...

> My construction of LED lights is extremely flaky, and I'm afraid of
> burning printer port. At 486 days ports were expected to survive such
> abuse. Not sure if todays EPP/wtf ports can handle that.

This could be a problem, though - now I've looked in to it, the
maximum recommended current drain on the parallel port seems to be
really low :-(.

I've CC'ed Alan - maybe he can offer some advice.

(Alan - basically we're thinking of using this LED-on-parallel-port
driver for a standardised 'front panel', showing things like interrupt
being serviced, BKL taken, etc, for debugging purposes.)

John.

2003-07-30 18:56:53

by Herbert Poetzl

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 07:44:57PM +0200, Pavel Machek wrote:
> Hi!
>
> > > But this kind of blinkenlights needed pretty fast LEDs. (At 486 time
> > > I decided that parport on ISA is fast enough..)
> >
> > I'll buy some LEDs and build a parallel port connected LED panel
> > tomorrow... Do you think the overhead of driving the LEDs would have
> > too much of a negative effect on system performance? If so, or if
> > we
>
> I'm not sure. At 486 days I was pretty sure it did not matter. These
> days you might get 10% slowdown on some microbenchmark, or something
> like that. I do not think it can slow down common tasks.
>
> My construction of LED lights is extremely flaky, and I'm afraid of
> burning printer port. At 486 days ports were expected to survive such
> abuse. Not sure if todays EPP/wtf ports can handle that.

parport uses 5V (actually a little less) so if you
use normal (not extra super duper bright) leds and
put a 1kOhm resistor in front of each led, then it
will drain 5mA per led, which gives a total of 40mA
for eight leds (for example)

now for the parport: depending on the technology
and the age of the circuit, it provides between
2 and 14mA output at >2.4V (the led usually requires
less than 1.5V to operate) so this would be within
the range ... but, if you want either extra brightness
or extra security, you could provide +5V and use
the outputlines as sink, which then is between
15 and 25mA ...

anyway, parport should be short circuit safe, so
the worst what could happen is, that the leds are
not working ;) ...

HTH,
Herbert

PS: I usually use 220Ohm and no external power ...

> --
> Horseback riding is like software...
> ...vgf orggre jura vgf serr.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2003-07-30 18:50:18

by Marc Giger

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi All,

On Wed, 30 Jul 2003 19:44:57 +0200
Pavel Machek <[email protected]> wrote:

> Hi!
>
> > > But this kind of blinkenlights needed pretty fast LEDs. (At 486
> > > time I decided that parport on ISA is fast enough..)
> >
> > I'll buy some LEDs and build a parallel port connected LED panel
> > tomorrow... Do you think the overhead of driving the LEDs would
> > have too much of a negative effect on system performance? If so, or
> > if we

Yesterday I connected 8 LED's to the parallelport datalines. Today I
read this thread. What for a coincidence...
The goal of this "project" was to show the current cpu load. It works
great now! I can see randomly the LED's lightening up while I am writing
this mail:-))

>
> I'm not sure. At 486 days I was pretty sure it did not matter. These
> days you might get 10% slowdown on some microbenchmark, or something
> like that. I do not think it can slow down common tasks.
>
> My construction of LED lights is extremely flaky, and I'm afraid of
> burning printer port. At 486 days ports were expected to survive such
> abuse. Not sure if todays EPP/wtf ports can handle that.
> Pavel

At beginning I had some fear to connect LEDS directly to the parport,
because its an onboard controller (like the most mainboards have).
I don't notice system performance slowdowns. (CPU Load code was borrowed
from xosview:-))

My personal goal would be to controll a Dot-Matrix Display. The
Display should show something like the actual CPU temperature,
CPU-load, processes, s.m.a.r.t state, etc etc etc etc..........But my
problem is how to beginn with that. I would prefer to controll it with a
PCI card. Also I looked today at 68HC11 microcontrollers, which I can
connect to the serial port and transmit the needed infos.

Are there suggestions / comments / questions?

If somebody is interested to develop such a card / controller with me, I
will be pleased to hear from you!

Thank you

Marc

2003-07-30 19:05:31

by Herbert Poetzl

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 08:50:02PM +0200, Marc Giger wrote:
> Hi All,
>
> On Wed, 30 Jul 2003 19:44:57 +0200
> Pavel Machek <[email protected]> wrote:
>
> > Hi!
> >
> > > > But this kind of blinkenlights needed pretty fast LEDs. (At 486
> > > > time I decided that parport on ISA is fast enough..)
> > >
> > > I'll buy some LEDs and build a parallel port connected LED panel
> > > tomorrow... Do you think the overhead of driving the LEDs would
> > > have too much of a negative effect on system performance? If so, or
> > > if we
>
> Yesterday I connected 8 LED's to the parallelport datalines. Today I
> read this thread. What for a coincidence...
> The goal of this "project" was to show the current cpu load. It works
> great now! I can see randomly the LED's lightening up while I am writing
> this mail:-))
>
> >
> > I'm not sure. At 486 days I was pretty sure it did not matter. These
> > days you might get 10% slowdown on some microbenchmark, or something
> > like that. I do not think it can slow down common tasks.
> >
> > My construction of LED lights is extremely flaky, and I'm afraid of
> > burning printer port. At 486 days ports were expected to survive such
> > abuse. Not sure if todays EPP/wtf ports can handle that.
> > Pavel
>
> At beginning I had some fear to connect LEDS directly to the parport,
> because its an onboard controller (like the most mainboards have).
> I don't notice system performance slowdowns. (CPU Load code was borrowed
> from xosview:-))
>
> My personal goal would be to controll a Dot-Matrix Display. The
> Display should show something like the actual CPU temperature,
> CPU-load, processes, s.m.a.r.t state, etc etc etc etc..........But my
> problem is how to beginn with that. I would prefer to controll it with a
> PCI card. Also I looked today at 68HC11 microcontrollers, which I can
> connect to the serial port and transmit the needed infos.

sounds interesting ...

> Are there suggestions / comments / questions?

http://www.ewal.net/lcd.php
http://patrick.wattle.id.au/cameron/information/lcd/

> If somebody is interested to develop such a card / controller with me, I
> will be pleased to hear from you!

I'm interested in discussions and willing to share my
knowledge (was working with embedded systems) on this
issue ...

best,
Herbert

> Thank you
>
> Marc
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2003-07-30 19:06:27

by Marc Giger

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, 30 Jul 2003 20:56:59 +0200
Herbert P?tzl <[email protected]> wrote:

> On Wed, Jul 30, 2003 at 07:44:57PM +0200, Pavel Machek wrote:
> > Hi!
> >
> > > > But this kind of blinkenlights needed pretty fast LEDs. (At 486
> > > > time I decided that parport on ISA is fast enough..)
> > >
> > > I'll buy some LEDs and build a parallel port connected LED panel
> > > tomorrow... Do you think the overhead of driving the LEDs would
> > > have too much of a negative effect on system performance? If so,
> > > or if we
> >
> > I'm not sure. At 486 days I was pretty sure it did not matter. These
> > days you might get 10% slowdown on some microbenchmark, or something
> > like that. I do not think it can slow down common tasks.
> >
> > My construction of LED lights is extremely flaky, and I'm afraid of
> > burning printer port. At 486 days ports were expected to survive
> > such abuse. Not sure if todays EPP/wtf ports can handle that.
>
> parport uses 5V (actually a little less) so if you
> use normal (not extra super duper bright) leds and
> put a 1kOhm resistor in front of each led, then it
> will drain 5mA per led, which gives a total of 40mA
> for eight leds (for example)

5mA per LED on the same line. 40mA if you connect all to the same
dataline or GND-line.

>
> now for the parport: depending on the technology
> and the age of the circuit, it provides between
> 2 and 14mA output at >2.4V (the led usually requires
> less than 1.5V to operate) so this would be within
> the range ... but, if you want either extra brightness
> or extra security, you could provide +5V and use
> the outputlines as sink, which then is between
> 15 and 25mA ...
>
> anyway, parport should be short circuit safe, so
> the worst what could happen is, that the leds are
> not working ;) ...

Are you sure?? I thought this is true for serial-port...

>
> HTH,
> Herbert
>
> PS: I usually use 220Ohm and no external power ...

The same here...

greets

Marc

2003-07-30 19:02:44

by Pavel Machek

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Hi!

> > My construction of LED lights is extremely flaky, and I'm afraid of
> > burning printer port. At 486 days ports were expected to survive such
> > abuse. Not sure if todays EPP/wtf ports can handle that.
>
> parport uses 5V (actually a little less) so if you
> use normal (not extra super duper bright) leds and
> put a 1kOhm resistor in front of each led, then it
> will drain 5mA per led, which gives a total of 40mA
> for eight leds (for example)
>
> now for the parport: depending on the technology
> and the age of the circuit, it provides between
> 2 and 14mA output at >2.4V (the led usually requires
> less than 1.5V to operate) so this would be within
> the range ... but, if you want either extra brightness
> or extra security, you could provide +5V and use
> the outputlines as sink, which then is between
> 15 and 25mA ...
>
> anyway, parport should be short circuit safe, so
> the worst what could happen is, that the leds are
> not working ;) ...

Really? Even for newer designs? I was afraid not to kill
southbridge...


> PS: I usually use 220Ohm and no external power ...

I used 330Ohm and no external power. 8leds were bright (those on data
pins), 4 dim (those on control pins). That was 486, through.

--
Horseback riding is like software...
...vgf orggre jura vgf serr.

2003-07-30 19:16:57

by Herbert Poetzl

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 09:06:18PM +0200, Marc Giger wrote:
> On Wed, 30 Jul 2003 20:56:59 +0200
> Herbert P?tzl <[email protected]> wrote:
> > On Wed, Jul 30, 2003 at 07:44:57PM +0200, Pavel Machek wrote:

[incredible useful info zapped here]

> > anyway, parport should be short circuit safe, so
> > the worst what could happen is, that the leds are
> > not working ;) ...
>
> Are you sure?? I thought this is true for serial-port...

I said 'should', for serial it would have been 'must' ;)

http://www.amontec.com/ieee1284_electrical.shtml
or search for the IEEE docs ...

modern chips work at ~15mA/2.5V ... according to spec

best,
Herbert

2003-07-30 21:44:37

by Mike Jagdis

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

Strangely (and perhaps sadly) enough a couple of years ago I wrote
an LED, um, "pattern generator" because, ah, someone insisted that
it would be "really cool" if the kit we were (going to) build had
a Knight Rider / Cylon "sweep"...

It had drivers for parport (I did initial development using LEDs
hanging off the back of a Thinkpad), a 5.25" SBC made by WinEnt
(LEDs on the PIIX4 GPO pins), an i2c I/O chip (used in the semi-custom
PC we eventually chose), and a test stub that just output bit patterns.

Since running patterns from user space is anti-social (and it's
difficult to get the timing good enough) there was a kernel space
"interpreter" that you could load scripts in to. Sweeps, scans,
blinks, ping-pong etc. Plus you could have multiple scripts with
LEDs "owned" by different scripts so you could do knock outs,
fill ins etc. And, of course, change scripts to reflect system
status on the fly :-)

Ok, it was a sunday afternoon hack so I got carried away a bit...

Like I say it was a couple of years ago so it probably needs some
work. But I'm quite happy to mail it to anyone that's curious. And
if any hardware manufacturers still think sweeping LEDs are cool
and trendy they're welcome to talk to me. Discreetly :-).

Mike

--
Mike Jagdis
Eris Associates Limited

2003-07-30 22:22:52

by Brian McGroarty

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 08:50:02PM +0200, Marc Giger wrote:
>
> My personal goal would be to controll a Dot-Matrix Display. The
> Display should show something like the actual CPU temperature,
> CPU-load, processes, s.m.a.r.t state, etc etc etc etc..........But my
> problem is how to beginn with that. I would prefer to controll it with a
> PCI card. Also I looked today at 68HC11 microcontrollers, which I can
> connect to the serial port and transmit the needed infos.
>
> Are there suggestions / comments / questions?
>
> If somebody is interested to develop such a card / controller with me, I
> will be pleased to hear from you!

I don't know if you're more after having a project or having the end
result, but if you just want the hardware then the end result is
already available here:

http://www.crystalfontz.com/


2003-07-30 23:31:20

by Greg KH

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Tue, Jul 29, 2003 at 04:17:03PM +0100, Philip Graham Willoughby wrote:
> Hi all,
>
> This patch adds an abstraction layer for programmable LED devices,
> hardware drivers for the Status LEDs found on some Intel PIIX4E based
> server hardware (notably the ISP1100 1U rackmount server) and LEDs wired
> to the parallel port data lines.

Some minor comments:
- read Documentation/CodingStyle and apply it to your code.
- fix up the usages of the MOD_* functions. Get rid of the ones
for the file_ops and have the core increment the count of the
drivers before the core calls them.
- please do not use ioctls. They are hell for 64bit kernels.
Use either a filesystem for your subsystem, or sysfs.
- try doing this for 2.6 first if you want any chance at all to
get it into the main kernel trees.

Good luck,

greg k-h

2003-07-31 08:31:43

by jw schultz

[permalink] [raw]
Subject: Re: PATCH : LEDs - possibly the most pointless kernel subsystem ever

On Wed, Jul 30, 2003 at 05:08:34PM +0100, John Bradford wrote:
> I'll buy some LEDs and build a parallel port connected LED panel
> tomorrow... Do you think the overhead of driving the LEDs would have
> too much of a negative effect on system performance? If so, or if we
> want more flexibility, maybe we could work out a design for a PCI
> card, which could include more than 12 LEDs - 7-segment numeric
> displays of pid, etc.

If you are going to talk special hardware i'd suggest making
it a USB device instead of a PCI card.

Most systems manufactured in the last five years or so ago
have USB but laptops don't and many servers don't have a
spare PCI slot. There is enough power specified by the
standard to make it a passive device in most cases. If you
want you could use a cable long enough to mount the display
on the wall outside the wiring closet or server room.

Sounds fun so have some.

--
________________________________________________________________
J.W. Schultz Pegasystems Technologies
email address: [email protected]

Remember Cernan and Schmitt