diff options
| author | Danilo Krummrich <dakr@kernel.org> | 2026-08-13 18:52:04 +0200 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2026-08-17 01:41:36 +0200 |
| commit | f146c7bc85a51f95c05e0f8173d484eb301ece78 (patch) | |
| tree | 07296ae54ed6551492b0c609dc0f5463f61f89ca /drivers/accessibility/speakup/genmap.c | |
| download | linux-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.c | 161 |
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); +} |
