summaryrefslogtreecommitdiffstats
path: root/drivers/input/input.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/input.c')
-rw-r--r--drivers/input/input.c120
1 files changed, 22 insertions, 98 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 3212c63dc..711485437 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);