Subject: port-sun3/2163: [dM] sun3 blinkenlights are boring
To: None <gnats-bugs@NetBSD.ORG>
From: der Mouse <mouse@Collatz.McRCIM.McGill.EDU>
List: netbsd-bugs
Date: 03/02/1996 19:25:32
>Number:         2163
>Category:       port-sun3
>Synopsis:       [dM] sun3 blinkenlights are boring
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Mar  2 19:35:02 1996
>Last-Modified:
>Originator:     der Mouse
>Organization:
	Dis-
>Release:        NetBSD/sun3 -current as of Feb 27 1996 sup
>Environment:
	Any Sun-3 (work done on -3/110)
>Description:
	The default heartbeat pattern on the back-of-machine diagnostic
	lights is rather boring.  This patch livens it up considerably.
	In my opinion this PR supersedes my PR #2144, which may now be
	closed at will.  This patch adds /dev/leds, which allows
	user-land to control the patterns scrolling past.  See the
	leds.4 manpage in the appended patches for details.
>How-To-Repeat:
	Look at the bank of lights.  Wish it were a little more
	interesting.
>Fix:
	Apply the following patches.

	If this is change adopted, I recommend that someone more
	familiar than I with the driving philosophy behind the way
	cdevsw[] is initialized fix up what I did there.  What I did
	works, but can hardly be called the Right Thing.  (I'm also not
	entirely happy with the tweak to files.sun3, but that there's
	less to get wrong.)

	I deliberately chose to put no kernel restrictions on who can
	do what to /dev/leds, since it doesn't affect anything
	important to system operation...so I let the permission bits on
	the special device node do the access control.  (Besides, it
	simplifies the /dev/leds driver somewhat. :-)

#! /bin/sh
#
# Shar: Shell Archiver
#
# This archive created Sat Mar  2 19:15:43 1996
# Run this through sh to create:
#	apply-script
#	patch-etc-etc.sun3-MAKEDEV
#	patch-share-man-man4-man4.sun3-Makefile
#	patch-share-man-man4-man4.sun3-leds.4
#	patch-sys-arch-sun3-conf-files.sun3
#	patch-sys-arch-sun3-sun3-clock.c
#	patch-sys-arch-sun3-sun3-conf.c
#	patch-sys-arch-sun3-sun3-leds-extern.h
#	patch-sys-arch-sun3-sun3-leds.c
echo x - apply-script \(740 characters\)
sed 's/^X//' > apply-script << \EOF
X#!/bin/sh
Xcase $# in
X	1)	;;
X	*)	echo "Usage: $0 base-directory-to-patch" 1>&2
X		echo "eg:    $0 /usr/src" 1>&2
X		exit 1
X		;;
Xesac
Xpatch "$1"/etc/etc.sun3/MAKEDEV < patch-etc-etc.sun3-MAKEDEV
Xpatch "$1"/share/man/man4/man4.sun3/Makefile < patch-share-man-man4-man4.sun3-Makefile
Xpatch "$1"/share/man/man4/man4.sun3/leds.4 < patch-share-man-man4-man4.sun3-leds.4
Xpatch "$1"/sys/arch/sun3/conf/files.sun3 < patch-sys-arch-sun3-conf-files.sun3
Xpatch "$1"/sys/arch/sun3/sun3/clock.c < patch-sys-arch-sun3-sun3-clock.c
Xpatch "$1"/sys/arch/sun3/sun3/conf.c < patch-sys-arch-sun3-sun3-conf.c
Xpatch "$1"/sys/arch/sun3/sun3/leds-extern.h < patch-sys-arch-sun3-sun3-leds-extern.h
Xpatch "$1"/sys/arch/sun3/sun3/leds.c < patch-sys-arch-sun3-sun3-leds.c
EOF
if test 740 -ne "`wc -c apply-script`"
then
echo shar: error transmitting apply-script \(should have been 740 characters\)
fi
echo x - patch-etc-etc.sun3-MAKEDEV \(254 characters\)
sed 's/^X//' > patch-etc-etc.sun3-MAKEDEV << \EOF
X+++ NEW/etc/etc.sun3/MAKEDEV	Thu Jan  1 00:00:00 1970
X@@ -105,6 +105,7 @@
X 	mk stdin	c 23 0
X 	mk stdout	c 23 1
X 	mk stderr	c 23 2
X+	mk leds		c 72 0 644
X 	;;
X 
X fd)
X@@ -210,4 +211,3 @@
X 
X esac
X done
X-
EOF
if test 254 -ne "`wc -c patch-etc-etc.sun3-MAKEDEV`"
then
echo shar: error transmitting patch-etc-etc.sun3-MAKEDEV \(should have been 254 characters\)
fi
echo x - patch-share-man-man4-man4.sun3-Makefile \(401 characters\)
sed 's/^X//' > patch-share-man-man4-man4.sun3-Makefile << \EOF
X+++ NEW/share/man/man4/man4.sun3/Makefile	Thu Jan  1 00:00:00 1970
X@@ -1,7 +1,7 @@
X # 	from: @(#)Makefile	8.2 (Berkeley) 2/16/94
X #	$NetBSD: Makefile,v 1.1.1.1 1995/08/08 20:18:53 gwr Exp $
X 
X-MAN=	bwtwo.4 cgtwo.4 cgfour.4 ie.4 le.4 mem.4
X+MAN=	bwtwo.4 cgtwo.4 cgfour.4 ie.4 le.4 leds.4 mem.4
X MLINKS=	mem.4 kmem.4
X MANSUBDIR=/sun3
X 
EOF
if test 401 -ne "`wc -c patch-share-man-man4-man4.sun3-Makefile`"
then
echo shar: error transmitting patch-share-man-man4-man4.sun3-Makefile \(should have been 401 characters\)
fi
echo x - patch-share-man-man4-man4.sun3-leds.4 \(2217 characters\)
sed 's/^X//' > patch-share-man-man4-man4.sun3-leds.4 << \EOF
X+++ NEW/share/man/man4/man4.sun3/leds.4	Thu Jan  1 00:00:00 1970
X@@ -0,0 +1,57 @@
X+.Dd March 2, 1996
X+.Dt LEDS 4 sun3
X+.Os NetBSD 1.1a
X+.Sh NAME
X+.Nm leds
X+.Nd back-panel LEDs
X+.Sh DESCRIPTION
X+The file
X+.Nm /dev/leds
X+is an interface to the diagnostic array of 8 light-emitting diodes on
X+the back of the computer.
X+.Pp
X+This file contains two
X+.Sy unsigned int Ns s
X+(in native byte order, as would be written by passing the address of an
X+.Sy unsigned int
X+to
X+.Xr write 2 ,
X+which on a Sun-3 means big-endian), followed by a string of bytes.  The
X+string of bytes gives the successive patterns to be displayed on the
X+LEDs; each byte's bits are taken and used to drive the LEDs.  A 0 bit
X+illuminates the corresponding LED; a 1 bit leaves the corresponding LED
X+dark.  The first
X+.Sy unsigned int
X+gives the number of clock ticks that are skipped after each pattern is
X+loaded before the next is loaded.  For example, if this value is 0, a
X+new pattern is loaded each clock tick; if it is 3, a new pattern will
X+be loaded every fourth clock tick (ie, three ticks will be skipped
X+between loads).  The second
X+.Sy unsigned int
X+gives the number of patterns in the list, that is, the number of bytes
X+following the two
X+.Sy unsigned int Ns s.
X+.Pp
X+There are limits on the two integer values; attempting a write that
X+would cause either of them to take on too large a value causes the
X+write to return EIO without affecting anything.  The limits are
X+compiled into the kernel; as of this writing, the first one can be at
X+most 128, the second at most 10240.
X+.Sh EXAMPLES
X+This example displays a single lit LED scrolling from one end of the
X+display to the other, over and over, moving every six clock ticks.  The
X+first eight bytes supply the two
X+.Sy unsigned int Ns s
X+mentioned above; the other eight specify the patterns.  (Convert them
X+to binary, and remember that 0 bits mean lit LEDs.)
X+.Bd -ragged -offset -ident
X+# echo 0 0 0 5 0 0 0 8 254 253 250 247 239 223 175 127 |
X+  awk '{ for (i=1;i<=NF;i++) printf("%c",$i+0); }' > /dev/leds
X+.Ed
X+.Sh FILES
X+.Bl -tag -width /dev/leds -compact
X+.It Pa /dev/leds
X+.El
X+.Sh HISTORY
X+.Nm /dev/leds
X+appeared in post-1.1 NetBSD.
EOF
if test 2217 -ne "`wc -c patch-share-man-man4-man4.sun3-leds.4`"
then
echo shar: error transmitting patch-share-man-man4-man4.sun3-leds.4 \(should have been 2217 characters\)
fi
echo x - patch-sys-arch-sun3-conf-files.sun3 \(309 characters\)
sed 's/^X//' > patch-sys-arch-sun3-conf-files.sun3 << \EOF
X+++ NEW/sys/arch/sun3/conf/files.sun3	Thu Jan  1 00:00:00 1970
X@@ -30,6 +30,7 @@
X file arch/sun3/sun3/trap.c		
X file arch/sun3/sun3/vector.c		
X file arch/sun3/sun3/vm_machdep.c	
X+file arch/sun3/sun3/leds.c
X 
X include "../../m68k/fpe/files.fpe"
X 
EOF
if test 309 -ne "`wc -c patch-sys-arch-sun3-conf-files.sun3`"
then
echo shar: error transmitting patch-sys-arch-sun3-conf-files.sun3 \(should have been 309 characters\)
fi
echo x - patch-sys-arch-sun3-sun3-clock.c \(1069 characters\)
sed 's/^X//' > patch-sys-arch-sun3-sun3-clock.c << \EOF
X+++ NEW/sys/arch/sun3/sun3/clock.c	Thu Jan  1 00:00:00 1970
X@@ -241,11 +241,12 @@
X  * This is is called by the "custom" interrupt handler
X  * after it has reset the pending bit in the clock.
X  */
X-int clock_count = 0;
X+/* Communication with the /dev/leds driver (leds.c)... */
X+#include "leds-extern.h"
X void clock_intr(frame)
X 	struct clockframe *frame;
X {
X-	static unsigned char led_pattern = 0xFE;
X+	unsigned int i;
X 
X #ifdef	DIAGNOSTIC
X 	if (!clk_intr_ready)
X@@ -253,13 +254,16 @@
X #endif
X 
X 	/* XXX - Move this LED frobbing to the idle loop? */
X-	clock_count++;
X-	if ((clock_count & 7) == 0) {
X-		led_pattern = (led_pattern << 1) | 1;
X-		if (led_pattern == 0xFF)
X-			led_pattern = 0xFE;
X-		set_control_byte((char *) DIAG_REG, led_pattern);
X-	}
X+	i = led_countdown;
X+	if (i == 0) {
X+		led_countdown = led_countmax;
X+		i = led_px;
X+		set_control_byte((char *) DIAG_REG, led_patterns[i]);
X+		if (i == 0)
X+			i = led_n_patterns;
X+		led_px = i - 1;
X+	} else
X+		led_countdown = i - 1;
X 	hardclock(frame);
X }
X 
EOF
if test 1069 -ne "`wc -c patch-sys-arch-sun3-sun3-clock.c`"
then
echo shar: error transmitting patch-sys-arch-sun3-sun3-clock.c \(should have been 1069 characters\)
fi
echo x - patch-sys-arch-sun3-sun3-conf.c \(1538 characters\)
sed 's/^X//' > patch-sys-arch-sun3-sun3-conf.c << \EOF
X+++ NEW/sys/arch/sun3/sun3/conf.c	Thu Jan  1 00:00:00 1970
X@@ -157,6 +157,7 @@
X 
X cdev_decl(log);
X cdev_decl(fd);
X+int ledrw __P((dev_t, struct uio *, int)); /* no "dev_type_rw()" macro */
X 
X #include "bpfilter.h"
X cdev_decl(bpf);
X@@ -168,13 +169,13 @@
X struct cdevsw	cdevsw[] =
X {
X 	cdev_cn_init(1,cn),		/* 0: virtual console */
X+	cdev_tty_init(NKD,kd),		/* 1: Sun keyboard/display */
X 	cdev_ctty_init(1,ctty),		/* 2: controlling terminal */
X 	cdev_mm_init(1,mm),		/* 3: /dev/{null,mem,kmem,...} */
X 	cdev_notdef(),			/* 4: was PROM console */
X 	cdev_notdef(),			/* 5: tapemaster tape */
X 	cdev_notdef(),			/* 6: systech/versatec */
X+	cdev_swap_init(1,sw),		/* 7: /dev/drum (swap pseudo-device) */
X 	cdev_notdef(),			/* 8: Archive QIC-11 tape */
X 	cdev_disk_init(NXY,xy),		/* 9: SMD disk on Xylogics 450/451 */
X 	cdev_notdef(),			/* 10: systech multi-terminal board */
X@@ -239,6 +240,9 @@
X 	cdev_notdef(),			/* 69: /dev/audio */
X 	cdev_notdef(),			/* 70: open prom */
X 	cdev_notdef(),			/* 71: (sg?) */
X+#define ledread ledrw
X+#define ledwrite ledrw
X+	cdev_swap_init(1,led),		/* 72: /dev/led - XXX to _swap_init */
X };
X int	nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
X 
X@@ -350,6 +354,7 @@
X 	/* 69 */	NODEV,
X 	/* 70 */	NODEV,
X 	/* 71 */	NODEV,
X+	/* 72 */	NODEV,
X };
X 
X /*
X@@ -367,4 +372,3 @@
X 		return (NODEV);
X 	return (makedev(blkmaj, minor(dev)));
X }
X-
EOF
if test 1538 -ne "`wc -c patch-sys-arch-sun3-sun3-conf.c`"
then
echo shar: error transmitting patch-sys-arch-sun3-sun3-conf.c \(should have been 1538 characters\)
fi
echo x - patch-sys-arch-sun3-sun3-leds-extern.h \(353 characters\)
sed 's/^X//' > patch-sys-arch-sun3-sun3-leds-extern.h << \EOF
X+++ NEW/sys/arch/sun3/sun3/leds-extern.h	Thu Jan  1 00:00:00 1970
X@@ -0,0 +1,5 @@
X+extern volatile unsigned int led_n_patterns;
X+extern volatile unsigned int led_countmax;
X+extern volatile const unsigned char * volatile led_patterns;
X+extern volatile unsigned int led_countdown;
X+extern volatile unsigned int led_px;
EOF
if test 353 -ne "`wc -c patch-sys-arch-sun3-sun3-leds-extern.h`"
then
echo shar: error transmitting patch-sys-arch-sun3-sun3-leds-extern.h \(should have been 353 characters\)
fi
echo x - patch-sys-arch-sun3-sun3-leds.c \(1522 characters\)
sed 's/^X//' > patch-sys-arch-sun3-sun3-leds.c << \EOF
X+++ NEW/sys/arch/sun3/sun3/leds.c	Thu Jan  1 00:00:00 1970
X@@ -0,0 +1,57 @@
X+#include <sys/types.h>
X+#include <sys/uio.h>
X+#include <sys/systm.h>
X+#include <sys/errno.h>
X+#include <machine/psl.h>
X+
X+#include "leds-extern.h"
X+
X+#define MAXPVLEN 10240
X+#define MAXCDOWN 128
X+
X+static volatile unsigned char pattern[MAXPVLEN] =
X+	{ 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80,
X+	  0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
X+	};
X+
X+volatile unsigned int led_n_patterns = 16;
X+volatile const unsigned char * volatile led_patterns = &pattern[0];
X+volatile unsigned int led_countmax = 5;
X+volatile unsigned int led_countdown = 0;
X+volatile unsigned int led_px = 0;
X+
X+int ledrw(dev_t dev, struct uio *uio)
X+{
X+ unsigned int v[2];
X+ int s;
X+ unsigned int o;
X+ int err;
X+
X+ if (uio->uio_offset > MAXPVLEN+sizeof(v)) return(0);
X+ s = splhigh();
X+ v[0] = led_countmax;
X+ v[1] = led_n_patterns;
X+ splx(s);
X+ o = uio->uio_offset;
X+ if (o < sizeof(v))
X+  { err = uiomove(((char *)&v[0])+o,sizeof(v)-o,uio);
X+    if (err) return(err);
X+    o = sizeof(v);
X+    if (uio->uio_rw == UIO_WRITE)
X+     { if ((v[0] > MAXCDOWN) || (v[1] < 1) || (v[1] > MAXPVLEN)) return(EIO);
X+       s = splhigh();
X+       led_countmax = v[0];
X+       led_n_patterns = v[1];
X+       led_countdown = 0;
X+       led_px = 0;
X+       splx(s);
X+     }
X+  }
X+ o -= sizeof(v);
X+ if (o >= v[1]) return(0);
X+ if (uio->uio_resid > 0)
X+  { err = uiomove(&pattern[o],v[1]-o,uio);
X+    if (err) return(err);
X+  }
X+ return(0);
X+}
EOF
if test 1522 -ne "`wc -c patch-sys-arch-sun3-sun3-leds.c`"
then
echo shar: error transmitting patch-sys-arch-sun3-sun3-leds.c \(should have been 1522 characters\)
fi
exit 0
# end of shell archive

					der Mouse

			    mouse@collatz.mcrcim.mcgill.edu
>Audit-Trail:
>Unformatted: