summaryrefslogtreecommitdiffstats
path: root/drivers/accessibility/speakup/genmap.c
diff options
context:
space:
mode:
authorDanilo Krummrich <dakr@kernel.org>2026-08-13 18:52:04 +0200
committerDanilo Krummrich <dakr@kernel.org>2026-08-17 01:41:36 +0200
commitf146c7bc85a51f95c05e0f8173d484eb301ece78 (patch)
tree07296ae54ed6551492b0c609dc0f5463f61f89ca /drivers/accessibility/speakup/genmap.c
downloadlinux-stable-f146c7bc85a51f95c05e0f8173d484eb301ece78.tar.gz
linux-stable-f146c7bc85a51f95c05e0f8173d484eb301ece78.zip
PCI: Add pci_irq_type() to query the allocated interrupt typegrafted
Add a helper that returns PCI_IRQ_MSIX, PCI_IRQ_MSI, or PCI_IRQ_INTX based on the interrupt type the PCI core selected after pci_alloc_irq_vectors(). Several drivers already open-code this check against pdev->msix_enabled and pdev->msi_enabled, or even open code this helper [1]. A common helper avoids the duplication and keeps drivers from accessing the bitfield directly (see also [2]). Acked-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: John Hubbard <jhubbard@nvidia.com> Link: https://elixir.bootlin.com/linux/v7.1/source/drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c#L196 [1] Inspired-by: John Hubbard <jhubbard@nvidia.com> Link: https://lore.kernel.org/all/DKKG2QM3YJYB.Z2H2B2UXJ75N@kernel.org/ [2] Reviewed-by: Gary Guo <gary@garyguo.net> Link: https://patch.msgid.link/20260813165234.620555-5-dakr@kernel.org [ Add missing pci_irq_type() stub for CONFIG_PCI=n. ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Diffstat (limited to 'drivers/accessibility/speakup/genmap.c')
-rw-r--r--drivers/accessibility/speakup/genmap.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/drivers/accessibility/speakup/genmap.c b/drivers/accessibility/speakup/genmap.c
new file mode 100644
index 000000000..0882bab10
--- /dev/null
+++ b/drivers/accessibility/speakup/genmap.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0+
+/* genmap.c
+ * originally written by: Kirk Reiser.
+ *
+ ** Copyright (C) 2002 Kirk Reiser.
+ * Copyright (C) 2003 David Borowski.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <libgen.h>
+#include <string.h>
+#include <ctype.h>
+#include "utils.h"
+
+struct st_key_init {
+ char *name;
+ int value, shift;
+};
+
+static unsigned char key_data[MAXKEYVAL][16], *kp;
+
+#include "mapdata.h"
+
+static const char delims[] = "\t\n ";
+static char *cp;
+static int map_ver = 119; /* an arbitrary number so speakup can check */
+static int shift_table[17];
+static int max_states = 1, flags;
+/* flags reserved for later, maybe for individual console maps */
+
+static int get_shift_value(int state)
+{
+ int i;
+
+ for (i = 0; shift_table[i] != state; i++) {
+ if (shift_table[i] == -1) {
+ if (i >= 16)
+ oops("too many shift states", NULL);
+ shift_table[i] = state;
+ max_states = i+1;
+ break;
+ }
+ }
+ return i;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int value, shift_state, i, spk_val = 0, lock_val = 0;
+ int max_key_used = 0, num_keys_used = 0;
+ struct st_key *this;
+ struct st_key_init *p_init;
+ char buffer[256];
+
+ bzero(key_table, sizeof(key_table));
+ bzero(key_data, sizeof(key_data));
+
+ shift_table[0] = 0;
+ for (i = 1; i <= 16; i++)
+ shift_table[i] = -1;
+
+ if (argc < 2) {
+ fputs("usage: genmap filename\n", stderr);
+ exit(1);
+ }
+
+ for (p_init = init_key_data; p_init->name[0] != '.'; p_init++)
+ add_key(p_init->name, p_init->value, p_init->shift);
+
+ open_input(NULL, argv[1]);
+ while (fgets(buffer, sizeof(buffer), infile)) {
+ lc++;
+ value = shift_state = 0;
+
+ cp = strtok(buffer, delims);
+ if (*cp == '#')
+ continue;
+
+ while (cp) {
+ if (*cp == '=')
+ break;
+ this = find_key(cp);
+ if (this == NULL)
+ oops("unknown key/modifier", cp);
+ if (this->shift == is_shift) {
+ if (value)
+ oops("modifiers must come first", cp);
+ shift_state += this->value;
+ } else if (this->shift == is_input)
+ value = this->value;
+ else
+ oops("bad modifier or key", cp);
+ cp = strtok(0, delims);
+ }
+ if (!cp)
+ oops("no = found", NULL);
+
+ cp = strtok(0, delims);
+ if (!cp)
+ oops("no speakup function after =", NULL);
+
+ this = find_key(cp);
+ if (this == NULL || this->shift != is_spk)
+ oops("invalid speakup function", cp);
+
+ i = get_shift_value(shift_state);
+ if (key_data[value][i]) {
+ while (--cp > buffer)
+ if (!*cp)
+ *cp = ' ';
+ oops("two functions on same key combination", cp);
+ }
+ key_data[value][i] = (char)this->value;
+ if (value > max_key_used)
+ max_key_used = value;
+ }
+ fclose(infile);
+
+ this = find_key("spk_key");
+ if (this)
+ spk_val = this->value;
+
+ this = find_key("spk_lock");
+ if (this)
+ lock_val = this->value;
+
+ for (lc = 1; lc <= max_key_used; lc++) {
+ kp = key_data[lc];
+ if (!memcmp(key_data[0], kp, 16))
+ continue;
+ num_keys_used++;
+ for (i = 0; i < max_states; i++) {
+ if (kp[i] != spk_val && kp[i] != lock_val)
+ continue;
+ shift_state = shift_table[i];
+ if (shift_state&16)
+ continue;
+ shift_state = get_shift_value(shift_state+16);
+ kp[shift_state] = kp[i];
+ /* fill in so we can process the key up, as spk bit will be set */
+ }
+ }
+
+ printf("\t%d, %d, %d,\n\t", map_ver, num_keys_used, max_states);
+ for (i = 0; i < max_states; i++)
+ printf("%d, ", shift_table[i]);
+ printf("%d,", flags);
+ for (lc = 1; lc <= max_key_used; lc++) {
+ kp = key_data[lc];
+ if (!memcmp(key_data[0], kp, 16))
+ continue;
+ printf("\n\t%d,", lc);
+ for (i = 0; i < max_states; i++)
+ printf(" %d,", (unsigned int)kp[i]);
+ }
+ printf("\n\t0, %d\n", map_ver);
+
+ exit(0);
+}