From 94ac2ab3fff96814d7460a27a0e9d004abbd4128 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 19 Jun 2024 23:00:37 +0200 Subject: Merging upstream version 6.9.2. Signed-off-by: Daniel Baumann --- drivers/input/input.c | 120 +++++++++----------------------------------------- 1 file changed, 22 insertions(+), 98 deletions(-) (limited to 'drivers/input/input.c') diff --git a/drivers/input/input.c b/drivers/input/input.c index 3212c63dcf..7114854375 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -1378,19 +1378,19 @@ static int input_print_modalias_bits(char *buf, int size, char name, const unsigned long *bm, unsigned int min_bit, unsigned int max_bit) { - int bit = min_bit; - int len = 0; + int len = 0, i; len += snprintf(buf, max(size, 0), "%c", name); - for_each_set_bit_from(bit, bm, max_bit) - len += snprintf(buf + len, max(size - len, 0), "%X,", bit); + for (i = min_bit; i < max_bit; i++) + if (bm[BIT_WORD(i)] & BIT_MASK(i)) + len += snprintf(buf + len, max(size - len, 0), "%X,", i); return len; } -static int input_print_modalias_parts(char *buf, int size, int full_len, - const struct input_dev *id) +static int input_print_modalias(char *buf, int size, const struct input_dev *id, + int add_cr) { - int len, klen, remainder, space; + int len; len = snprintf(buf, max(size, 0), "input:b%04Xv%04Xp%04Xe%04X-", @@ -1399,48 +1399,8 @@ static int input_print_modalias_parts(char *buf, int size, int full_len, len += input_print_modalias_bits(buf + len, size - len, 'e', id->evbit, 0, EV_MAX); - - /* - * Calculate the remaining space in the buffer making sure we - * have place for the terminating 0. - */ - space = max(size - (len + 1), 0); - - klen = input_print_modalias_bits(buf + len, size - len, + len += input_print_modalias_bits(buf + len, size - len, 'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX); - len += klen; - - /* - * If we have more data than we can fit in the buffer, check - * if we can trim key data to fit in the rest. We will indicate - * that key data is incomplete by adding "+" sign at the end, like - * this: * "k1,2,3,45,+,". - * - * Note that we shortest key info (if present) is "k+," so we - * can only try to trim if key data is longer than that. - */ - if (full_len && size < full_len + 1 && klen > 3) { - remainder = full_len - len; - /* - * We can only trim if we have space for the remainder - * and also for at least "k+," which is 3 more characters. - */ - if (remainder <= space - 3) { - /* - * We are guaranteed to have 'k' in the buffer, so - * we need at least 3 additional bytes for storing - * "+," in addition to the remainder. - */ - for (int i = size - 1 - remainder - 3; i >= 0; i--) { - if (buf[i] == 'k' || buf[i] == ',') { - strcpy(buf + i + 1, "+,"); - len = i + 3; /* Not counting '\0' */ - break; - } - } - } - } - len += input_print_modalias_bits(buf + len, size - len, 'r', id->relbit, 0, REL_MAX); len += input_print_modalias_bits(buf + len, size - len, @@ -1456,23 +1416,10 @@ static int input_print_modalias_parts(char *buf, int size, int full_len, len += input_print_modalias_bits(buf + len, size - len, 'w', id->swbit, 0, SW_MAX); - return len; -} - -static int input_print_modalias(char *buf, int size, const struct input_dev *id) -{ - int full_len; + if (add_cr) + len += snprintf(buf + len, max(size - len, 0), "\n"); - /* - * Printing is done in 2 passes: first one figures out total length - * needed for the modalias string, second one will try to trim key - * data in case when buffer is too small for the entire modalias. - * If the buffer is too small regardless, it will fill as much as it - * can (without trimming key data) into the buffer and leave it to - * the caller to figure out what to do with the result. - */ - full_len = input_print_modalias_parts(NULL, 0, 0, id); - return input_print_modalias_parts(buf, size, full_len, id); + return len; } static ssize_t input_dev_show_modalias(struct device *dev, @@ -1482,9 +1429,7 @@ static ssize_t input_dev_show_modalias(struct device *dev, struct input_dev *id = to_input_dev(dev); ssize_t len; - len = input_print_modalias(buf, PAGE_SIZE, id); - if (len < PAGE_SIZE - 2) - len += snprintf(buf + len, PAGE_SIZE - len, "\n"); + len = input_print_modalias(buf, PAGE_SIZE, id, 1); return min_t(int, len, PAGE_SIZE); } @@ -1696,23 +1641,6 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, return 0; } -/* - * This is a pretty gross hack. When building uevent data the driver core - * may try adding more environment variables to kobj_uevent_env without - * telling us, so we have no idea how much of the buffer we can use to - * avoid overflows/-ENOMEM elsewhere. To work around this let's artificially - * reduce amount of memory we will use for the modalias environment variable. - * - * The potential additions are: - * - * SEQNUM=18446744073709551615 - (%llu - 28 bytes) - * HOME=/ (6 bytes) - * PATH=/sbin:/bin:/usr/sbin:/usr/bin (34 bytes) - * - * 68 bytes total. Allow extra buffer - 96 bytes - */ -#define UEVENT_ENV_EXTRA_LEN 96 - static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, const struct input_dev *dev) { @@ -1722,11 +1650,9 @@ static int input_add_uevent_modalias_var(struct kobj_uevent_env *env, return -ENOMEM; len = input_print_modalias(&env->buf[env->buflen - 1], - (int)sizeof(env->buf) - env->buflen - - UEVENT_ENV_EXTRA_LEN, - dev); - if (len >= ((int)sizeof(env->buf) - env->buflen - - UEVENT_ENV_EXTRA_LEN)) + sizeof(env->buf) - env->buflen, + dev, 0); + if (len >= (sizeof(env->buf) - env->buflen)) return -ENOMEM; env->buflen += len; @@ -1992,7 +1918,7 @@ static char *input_devnode(const struct device *dev, umode_t *mode) return kasprintf(GFP_KERNEL, "input/%s", dev_name(dev)); } -struct class input_class = { +const struct class input_class = { .name = "input", .devnode = input_devnode, }; @@ -2703,17 +2629,15 @@ int input_get_new_minor(int legacy_base, unsigned int legacy_num, * locking is needed here. */ if (legacy_base >= 0) { - int minor = ida_simple_get(&input_ida, - legacy_base, - legacy_base + legacy_num, - GFP_KERNEL); + int minor = ida_alloc_range(&input_ida, legacy_base, + legacy_base + legacy_num - 1, + GFP_KERNEL); if (minor >= 0 || !allow_dynamic) return minor; } - return ida_simple_get(&input_ida, - INPUT_FIRST_DYNAMIC_DEV, INPUT_MAX_CHAR_DEVICES, - GFP_KERNEL); + return ida_alloc_range(&input_ida, INPUT_FIRST_DYNAMIC_DEV, + INPUT_MAX_CHAR_DEVICES - 1, GFP_KERNEL); } EXPORT_SYMBOL(input_get_new_minor); @@ -2726,7 +2650,7 @@ EXPORT_SYMBOL(input_get_new_minor); */ void input_free_minor(unsigned int minor) { - ida_simple_remove(&input_ida, minor); + ida_free(&input_ida, minor); } EXPORT_SYMBOL(input_free_minor); -- cgit v1.2.3