(Roman.Hodek@informatik.uni-erlangen.de):
Reading/writing the Intel I/O ports via /dev/port is not the
- English way... Such hardware dependant stuff can never work on
+ English way... Such hardware dependent stuff can never work on
other architectures.
Linux/68k has an new ioctl for setting the keyboard repeat rate
1999-03-17
Linux/SPARC modifications by Jeffrey Connell <ankh@canuck.gen.nz>:
It seems that the KDKBDREP ioctl is not available on this platform.
- However, Linux/SPARC has its own ioctl for this, with yet another
- different measurement system. Thus, try for KIOCSRATE, too.
+ However, Linux/SPARC has its own ioctl for this (since 2.1.30),
+ with yet another measurement system. Thus, try for KIOCSRATE, too.
*/
#include <errno.h>
#include <sys/file.h>
#include <sys/ioctl.h>
-
-#include "../defines.h"
-#ifdef HAVE_kd_h
#include <linux/kd.h>
-#endif
+
#ifdef __sparc__
#include <asm/param.h>
-#include <asm/kbio.h>
#endif
+#ifdef COMPAT_HEADERS
+#include "compat/linux-kd.h"
+#endif
+
+/* Equal to kernel version, but field names vary. */
+struct my_kbd_repeat {
+ int delay; /* in msec; <= 0: don't change */
+ int period; /* in msec; <= 0: don't change */
+ /* earlier this field was misnamed "rate" */
+};
+
+#include <signal.h>
+
#include "nls.h"
#include "version.h"
static int
KDKBDREP_ioctl_ok(double rate, int delay, int silent) {
-#ifdef KDKBDREP
- /* This ioctl is defined in <linux/kd.h> but is not
- implemented anywhere - must be in some m68k patches. */
- struct kbd_repeat kbdrep_s;
+ /*
+ * This ioctl is defined in <linux/kd.h> but is not
+ * implemented anywhere - must be in some m68k patches.
+ * Since 2.4.9 also on i386.
+ */
+ struct my_kbd_repeat kbdrep_s;
/* don't change, just test */
- kbdrep_s.rate = -1;
+ kbdrep_s.period = -1;
kbdrep_s.delay = -1;
if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
- if (errno == EINVAL)
+ if (errno == EINVAL || errno == ENOTTY)
return 0;
perror( "ioctl(KDKBDREP)" );
exit( 1 );
}
+#if 0
+ printf("old delay %d, period %d\n",
+ kbdrep_s.delay, kbdrep_s.period);
+#endif
+
/* do the change */
- if (rate == 0) /* switch repeat off */
- kbdrep_s.rate = 0;
+ if (rate == 0) /* switch repeat off */
+ kbdrep_s.period = 0;
else
- kbdrep_s.rate = 1000.0 / rate; /* convert cps to msec */
- if (kbdrep_s.rate < 1)
- kbdrep_s.rate = 1;
+ kbdrep_s.period = 1000.0 / rate; /* convert cps to msec */
+ if (kbdrep_s.period < 1)
+ kbdrep_s.period = 1;
kbdrep_s.delay = delay;
if (kbdrep_s.delay < 1)
kbdrep_s.delay = 1;
+ if (ioctl(0, KDKBDREP, &kbdrep_s)) {
+ perror("ioctl(KDKBDREP)");
+ exit(1);
+ }
+
+ /* report */
+ if (kbdrep_s.period == 0)
+ rate = 0;
+ else
+ rate = 1000.0 / (double) kbdrep_s.period;
+
+ if (!silent)
+ printf( _("Typematic Rate set to %.1f cps (delay = %d ms)\n"),
+ rate, kbdrep_s.delay );
+
+ kbdrep_s.period = -1;
+ kbdrep_s.delay = -1;
if (ioctl( 0, KDKBDREP, &kbdrep_s )) {
+ if (errno == EINVAL)
+ return 0;
perror( "ioctl(KDKBDREP)" );
exit( 1 );
}
-
- /* report */
- if (kbdrep_s.rate == 0)
+ printf("old delay %d, period %d\n",
+ kbdrep_s.delay, kbdrep_s.period);
+ if (kbdrep_s.period == 0)
rate = 0;
else
- rate = 1000.0 / (double) kbdrep_s.rate;
+ rate = 1000.0 / (double) kbdrep_s.period;
if (!silent)
printf( _("Typematic Rate set to %.1f cps (delay = %d ms)\n"),
rate, kbdrep_s.delay );
return 1; /* success! */
-
-#else /* no KDKBDREP */
- return 0;
-#endif /* KDKBDREP */
}
+#ifndef KIOCSRATE
+#define arg_state attr_unused
+#else
+#define arg_state
+#endif
+
static int
-KIOCSRATE_ioctl_ok(double rate, int delay, int silent) {
+KIOCSRATE_ioctl_ok(arg_state double rate, arg_state int delay, arg_state int silent) {
#ifdef KIOCSRATE
struct kbd_rate kbdrate_s;
int fd;
#endif /* KIOCSRATE */
}
+static void
+sigalrmhandler( attr_unused int sig ) {
+ fprintf( stderr, "kbdrate: Failed waiting for kbd controller!\n" );
+ raise( SIGINT );
+}
+
int
main( int argc, char **argv ) {
#ifdef __sparc__
int fd;
char data;
int c;
- int i;
+ unsigned int i;
extern char *optarg;
set_progname(argv[0]);
setlocale(LC_ALL, "");
- bindtextdomain(PACKAGE, LOCALEDIR);
- textdomain(PACKAGE);
+ bindtextdomain(PACKAGE_NAME, LOCALEDIR);
+ textdomain(PACKAGE_NAME);
if (argc == 2 &&
(!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version")))
exit( 1 );
}
+ signal( SIGALRM, sigalrmhandler );
+ alarm( 3 );
+
do {
lseek( fd, 0x64, 0 );
- read( fd, &data, 1 );
+ if (read( fd, &data, 1 ) == -1) {
+ perror( "read" );
+ exit( 1 );
+ }
} while ((data & 2) == 2 ); /* wait */
lseek( fd, 0x60, 0 );
data = 0xf3; /* set typematic rate */
- write( fd, &data, 1 );
+ if (write( fd, &data, 1 ) == -1) {
+ perror( "write" );
+ exit( 1 );
+ }
do {
lseek( fd, 0x64, 0 );
- read( fd, &data, 1 );
+ if (read( fd, &data, 1 ) == -1) {
+ perror( "read" );
+ exit( 1 );
+ }
} while ((data & 2) == 2 ); /* wait */
+ alarm( 0 );
+
lseek( fd, 0x60, 0 );
sleep( 1 );
- write( fd, &value, 1 );
+ if (write( fd, &value, 1 ) == -1) {
+ perror( "write" );
+ exit( 1 );
+ }
close( fd );