From ce98ef8d2131945c3432059b757dc5390d081674 Mon Sep 17 00:00:00 2001 From: Packit Date: Sep 29 2020 11:28:27 +0000 Subject: Apply patch kbd-1.15-sparc.patch patch_name: kbd-1.15-sparc.patch present_in_specfile: true --- diff --git a/docs/man/man8/kbdrate.8 b/docs/man/man8/kbdrate.8 index d16b7c9..e5d2006 100644 --- a/docs/man/man8/kbdrate.8 +++ b/docs/man/man8/kbdrate.8 @@ -22,7 +22,7 @@ Using without any options will reset the repeat rate to 10.9 characters per second (cps) and the delay to 250 milliseconds (ms) for Intel- and M68K-based systems. These are the IBM defaults. On SPARC-based systems it will reset the repeat rate -to 5 cps and the delay to 200 ms. +to 20 cps and the delay to 200 ms. .SH OPTIONS .TP diff --git a/docs/man/man8/kbdrate.8.sparc b/docs/man/man8/kbdrate.8.sparc new file mode 100644 index 0000000..d16b7c9 --- /dev/null +++ b/docs/man/man8/kbdrate.8.sparc @@ -0,0 +1,71 @@ +.\" Copyright 1992, 1994 Rickard E. Faith (faith@cs.unc.edu) +.\" May be distributed under the GNU General Public License +.\" Updated Wed Jun 22 21:09:43 1994, faith@cs.unc.edu +.\" +.TH KBDRATE 8 "22 June 1994" "Linux 1.1.19" "Linux Programmer's Manual" +.SH NAME +kbdrate \- reset the keyboard repeat rate and delay time +.SH SYNOPSIS +.B "kbdrate [ \-s ] [ \-r" +rate +.B "] [ \-d" +delay +.B ] +.SH DESCRIPTION +.B kbdrate +is used to change the keyboard repeat rate and delay time. The delay +is the amount of time that a key must be depressed before it will start to +repeat. + +Using +.B kbdrate +without any options will reset the repeat rate to 10.9 characters per second (cps) +and the delay to 250 milliseconds (ms) for Intel- and M68K-based systems. +These are the IBM defaults. On SPARC-based systems it will reset the repeat rate +to 5 cps and the delay to 200 ms. + +.SH OPTIONS +.TP +.B \-s +Silent. No messages are printed. +.TP +.BI \-r " rate" +Change the keyboard repeat rate to +.I rate +cps. For Intel-based systems, the allowable range is from 2.0 to 30.0 cps. +Only certain, specific values are possible, and the program will select the +nearest possible value to the one specified. The possible values are given, +in characters per second, as follows: 2.0, 2.1, 2.3, 2.5, 2.7, 3.0, 3.3, 3.7, +4.0, 4.3, 4.6, 5.0, 5.5, 6.0, 6.7, 7.5, 8.0, 8.6, 9.2, 10.0, 10.9, 12.0, 13.3, +15.0, 16.0, 17.1, 18.5, 20.0, 21.8, 24.0, 26.7, 30.0. +For SPARC-based systems, the allowable range is from 0 (no repeat) to 50 cps. +.TP +.BI \-d " delay" +Change the delay to +.I delay +milliseconds. +For Intel-based systems, the allowable range is from 250 to 1000 ms, +in 250 ms steps. For SPARC systems, possible values are between 10 ms and 1440 ms, +in 10 ms steps. +.TP +.B \-V \-\-version +Display a version number and exit. +.SH BUGS +Not all keyboards support all rates. +.PP +Not all keyboards have the rates mapped in the same way. +.PP +Setting the repeat rate on the Gateway AnyKey keyboard does not work. If +someone with a Gateway figures out how to program the keyboard, please send +mail to util-linux@math.uio.no. +.PP +All this is very architecture dependent. +Nowadays +.B kbdrate +first tries the KDKBDREP and KIOCSRATE ioctls. +(The former usually works on an m68k machine, the latter for SPARC.) +When these ioctls fail an ioport interface as on i386 is assumed. +.SH FILES +.I /etc/rc.local +.br +.I /dev/port diff --git a/src/kbdrate.c b/src/kbdrate.c index 834855c..f8ef0e9 100644 --- a/src/kbdrate.c +++ b/src/kbdrate.c @@ -111,9 +111,12 @@ static int valid_delays[] = { 250, 500, 750, 1000 }; static int KDKBDREP_ioctl_ok(double rate, int delay, int silent) { +#if defined(KDKBDREP) && !defined(__sparc__) /* * This ioctl is defined in but is not * implemented anywhere - must be in some m68k patches. + * We cannot blindly try unimplemented ioctls on sparc64 - + * the 32<->64bit transition layer does not like it. * Since 2.4.9 also on i386. */ struct my_kbd_repeat kbdrep_s; @@ -176,6 +179,9 @@ KDKBDREP_ioctl_ok(double rate, int delay, int silent) rate, kbdrep_s.delay); return 1; /* success! */ +#else /* no KDKBDREP or __sparc__ */ + return 0; +#endif /* KDKBDREP */ } #ifndef KIOCSRATE @@ -226,7 +232,7 @@ sigalrmhandler(int sig __attribute__((unused))) int main(int argc, char **argv) { #ifdef __sparc__ - double rate = 5.0; /* Default rate */ + double rate = 20.0; /* Default rate */ int delay = 200; /* Default delay */ #else double rate = 10.9; /* Default rate */ @@ -275,8 +281,9 @@ int main(int argc, char **argv) if (KIOCSRATE_ioctl_ok(rate, delay, silent)) /* sparc? */ return 0; - /* The ioport way */ + /* The ioport way - will crash on sparc */ +#ifndef __sparc__ for (i = 0; i < RATE_COUNT; i++) if (rate * 10 >= valid_rates[i]) { value &= 0x60; @@ -333,5 +340,6 @@ int main(int argc, char **argv) valid_rates[value & 0x1f] / 10.0, valid_delays[(value & 0x60) >> 5]); +#endif return EXIT_SUCCESS; } diff --git a/src/kbdrate.c.sparc b/src/kbdrate.c.sparc new file mode 100644 index 0000000..834855c --- /dev/null +++ b/src/kbdrate.c.sparc @@ -0,0 +1,337 @@ +/* +From: faith@cs.unc.edu (Rik Faith) +Subject: User mode keyboard rate changer +Date: 27 Apr 92 13:44:26 GMT + +I put together this program, called kbdrate.c, which will reset the keyboard +repeat rate and delay in user mode. The program must have read/write +access to /dev/port, so if /dev/port is only read/writeable by group port, +then kbdrate must run setgid to group port (for example). + +The "rate" is the rate in characters per second + +The "delay" is the amount of time the key must remain depressed before it +will start to repeat. + +Usage examples: + +kbdrate set rate to IBM default (10.9 cps, 250ms delay) +kbdrate -r 30.0 set rate to 30 cps and delay to 250ms +kbdrate -r 20.0 -s set rate to 20 cps (delay 250ms) -- don't print message +kbdrate -r 0 -d 0 set rate to 2.0 cps and delay to 250 ms + +I find it useful to put kbdrate in my /etc/rc file so that the keyboard +rate is set to something that I find comfortable at boot time. This sure +beats rebuilding the kernel! + + + kbdrate.c -- Set keyboard typematic rate (and delay) + Created: Thu Apr 23 12:24:30 1992 + Author: Rickard E. Faith, faith@cs.unc.edu + + Copyright 1992 Rickard E. Faith. Distributed under the GPL. + This program comes with ABSOLUTELY NO WARRANTY. + Usage: kbdrate [-r rate] [-d delay] [-s] + Rate can range from 2.0 to 30.0 (units are characters per second) + Delay can range from 250 to 1000 (units are milliseconds) + -s suppressed message + Compiles under gcc 2.1 for Linux (tested with the pre-0.96 kernel) + + Wed Jun 22 21:35:43 1994, faith@cs.unc.edu: + Changed valid_rates per suggestion by Andries.Brouwer@cwi.nl. + Wed Jun 22 22:18:29 1994, faith@cs.unc.edu: + Added patch for AUSTIN notebooks from John Bowman + (bowman@hagar.ph.utexas.edu) + + Linux/68k modifications by Roman Hodek + (Roman.Hodek@informatik.uni-erlangen.de): + + Reading/writing the Intel I/O ports via /dev/port is not the + English way... Such hardware dependent stuff can never work on + other architectures. + + Linux/68k has an new ioctl for setting the keyboard repeat rate + and delay. Both values are counted in msecs, the kernel will do + any rounding to values possible with the underlying hardware. + + kbdrate now first tries if the KDKBDREP ioctl is available. If it + is, it is used, else the old method is applied. + + 1999-02-22 Arkadiusz Miƛkiewicz + - added Native Language Support + + 1999-03-17 + Linux/SPARC modifications by Jeffrey Connell : + It seems that the KDKBDREP ioctl is not available on this platform. + However, Linux/SPARC has its own ioctl for this (since 2.1.30), + with yet another measurement system. Thus, try for KIOCSRATE, too. + +*/ +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __sparc__ +#include +#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 + +#include "nls.h" +#include "version.h" +#include "kbd_error.h" + +static int valid_rates[] = { 300, 267, 240, 218, 200, 185, 171, 160, 150, + 133, 120, 109, 100, 92, 86, 80, 75, 67, + 60, 55, 50, 46, 43, 40, 37, 33, 30, 27, + 25, 23, 21, 20 }; +#define RATE_COUNT (sizeof(valid_rates) / sizeof(int)) + +static int valid_delays[] = { 250, 500, 750, 1000 }; +#define DELAY_COUNT (sizeof(valid_delays) / sizeof(int)) + +static int +KDKBDREP_ioctl_ok(double rate, int delay, int silent) +{ + /* + * This ioctl is defined in 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.period = -1; + kbdrep_s.delay = -1; + if (ioctl(0, KDKBDREP, &kbdrep_s)) { + if (errno == EINVAL || errno == ENOTTY) + return 0; + kbd_error(EXIT_FAILURE, errno, "ioctl KDKBDREP"); + } + +#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.period = 0; + else + 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)) { + kbd_error(EXIT_FAILURE, errno, "ioctl KDKBDREP"); + } + + /* 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; + kbd_error(EXIT_FAILURE, errno, "ioctl KDKBDREP"); + } + 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.period; + + if (!silent) + printf(_("Typematic Rate set to %.1f cps (delay = %d ms)\n"), + rate, kbdrep_s.delay); + + return 1; /* success! */ +} + +#ifndef KIOCSRATE +#define arg_state __attribute__((unused)) +#else +#define arg_state +#endif + +static int +KIOCSRATE_ioctl_ok(arg_state double rate, arg_state int delay, arg_state int silent) +{ +#ifdef KIOCSRATE + struct kbd_rate kbdrate_s; + int fd; + + fd = open("/dev/kbd", O_RDONLY); + if (fd == -1) { + kbd_error(EXIT_FAILURE, errno, "open /dev/kbd"); + } + + kbdrate_s.rate = (int)(rate + 0.5); /* round up */ + kbdrate_s.delay = delay * HZ / 1000; /* convert ms to Hz */ + if (kbdrate_s.rate > 50) + kbdrate_s.rate = 50; + + if (ioctl(fd, KIOCSRATE, &kbdrate_s)) { + kbd_error(EXIT_FAILURE, errno, "ioctl KIOCSRATE"); + } + close(fd); + + if (!silent) + printf("Typematic Rate set to %d cps (delay = %d ms)\n", + kbdrate_s.rate, kbdrate_s.delay * 1000 / HZ); + + return 1; +#else /* no KIOCSRATE */ + return 0; +#endif /* KIOCSRATE */ +} + +static void +sigalrmhandler(int sig __attribute__((unused))) +{ + kbd_warning(0, "Failed waiting for kbd controller!\n"); + raise(SIGINT); +} + +int main(int argc, char **argv) +{ +#ifdef __sparc__ + double rate = 5.0; /* Default rate */ + int delay = 200; /* Default delay */ +#else + double rate = 10.9; /* Default rate */ + int delay = 250; /* Default delay */ +#endif + int value = 0x7f; /* Maximum delay with slowest rate */ + /* DO NOT CHANGE this value */ + int silent = 0; + int fd; + char data; + int c; + unsigned int i; + extern char *optarg; + + set_progname(argv[0]); + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE_NAME, LOCALEDIR); + textdomain(PACKAGE_NAME); + + if (argc == 2 && + (!strcmp(argv[1], "-V") || !strcmp(argv[1], "--version"))) + print_version_and_exit(); + + while ((c = getopt(argc, argv, "r:d:s")) != EOF) { + switch (c) { + case 'r': + rate = atof(optarg); + break; + case 'd': + delay = atoi(optarg); + break; + case 's': + silent = 1; + break; + default: + fprintf(stderr, + _("Usage: kbdrate [-V | --version] [-s] [-r rate] [-d delay]\n")); + exit(EXIT_FAILURE); + } + } + + if (KDKBDREP_ioctl_ok(rate, delay, silent)) /* m68k? */ + return 0; + + if (KIOCSRATE_ioctl_ok(rate, delay, silent)) /* sparc? */ + return 0; + + /* The ioport way */ + + for (i = 0; i < RATE_COUNT; i++) + if (rate * 10 >= valid_rates[i]) { + value &= 0x60; + value |= i; + break; + } + + for (i = 0; i < DELAY_COUNT; i++) + if (delay <= valid_delays[i]) { + value &= 0x1f; + value |= i << 5; + break; + } + + if ((fd = open("/dev/port", O_RDWR)) < 0) { + kbd_error(EXIT_FAILURE, errno, _("Cannot open /dev/port")); + } + + signal(SIGALRM, sigalrmhandler); + alarm(3); + + do { + lseek(fd, 0x64, 0); + if (read(fd, &data, 1) == -1) { + kbd_error(EXIT_FAILURE, errno, "read"); + } + } while ((data & 2) == 2); /* wait */ + + lseek(fd, 0x60, 0); + data = 0xf3; /* set typematic rate */ + if (write(fd, &data, 1) == -1) { + kbd_error(EXIT_FAILURE, errno, "write"); + } + + do { + lseek(fd, 0x64, 0); + if (read(fd, &data, 1) == -1) { + kbd_error(EXIT_FAILURE, errno, "read"); + } + } while ((data & 2) == 2); /* wait */ + + alarm(0); + + lseek(fd, 0x60, 0); + sleep(1); + if (write(fd, &value, 1) == -1) { + kbd_error(EXIT_FAILURE, errno, "write"); + } + + close(fd); + + if (!silent) + printf(_("Typematic Rate set to %.1f cps (delay = %d ms)\n"), + valid_rates[value & 0x1f] / 10.0, + valid_delays[(value & 0x60) >> 5]); + + return EXIT_SUCCESS; +}