diff options
| -rw-r--r-- | drivers/input/input.c | 86 |
1 files changed, 71 insertions, 15 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index ab060710688f..30b503b8d67b 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <linux/mutex.h> | 24 | #include <linux/mutex.h> |
| 25 | #include <linux/rcupdate.h> | 25 | #include <linux/rcupdate.h> |
| 26 | #include <linux/smp_lock.h> | 26 | #include <linux/smp_lock.h> |
| 27 | #include "input-compat.h" | ||
| 27 | 28 | ||
| 28 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); | 29 | MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>"); |
| 29 | MODULE_DESCRIPTION("Input core"); | 30 | MODULE_DESCRIPTION("Input core"); |
| @@ -764,6 +765,40 @@ static int input_attach_handler(struct input_dev *dev, struct input_handler *han | |||
| 764 | return error; | 765 | return error; |
| 765 | } | 766 | } |
| 766 | 767 | ||
| 768 | #ifdef CONFIG_COMPAT | ||
| 769 | |||
| 770 | static int input_bits_to_string(char *buf, int buf_size, | ||
| 771 | unsigned long bits, bool skip_empty) | ||
| 772 | { | ||
| 773 | int len = 0; | ||
| 774 | |||
| 775 | if (INPUT_COMPAT_TEST) { | ||
| 776 | u32 dword = bits >> 32; | ||
| 777 | if (dword || !skip_empty) | ||
| 778 | len += snprintf(buf, buf_size, "%x ", dword); | ||
| 779 | |||
| 780 | dword = bits & 0xffffffffUL; | ||
| 781 | if (dword || !skip_empty || len) | ||
| 782 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
| 783 | "%x", dword); | ||
| 784 | } else { | ||
| 785 | if (bits || !skip_empty) | ||
| 786 | len += snprintf(buf, buf_size, "%lx", bits); | ||
| 787 | } | ||
| 788 | |||
| 789 | return len; | ||
| 790 | } | ||
| 791 | |||
| 792 | #else /* !CONFIG_COMPAT */ | ||
| 793 | |||
| 794 | static int input_bits_to_string(char *buf, int buf_size, | ||
| 795 | unsigned long bits, bool skip_empty) | ||
| 796 | { | ||
| 797 | return bits || !skip_empty ? | ||
| 798 | snprintf(buf, buf_size, "%lx", bits) : 0; | ||
| 799 | } | ||
| 800 | |||
| 801 | #endif | ||
| 767 | 802 | ||
| 768 | #ifdef CONFIG_PROC_FS | 803 | #ifdef CONFIG_PROC_FS |
| 769 | 804 | ||
| @@ -832,14 +867,25 @@ static void input_seq_print_bitmap(struct seq_file *seq, const char *name, | |||
| 832 | unsigned long *bitmap, int max) | 867 | unsigned long *bitmap, int max) |
| 833 | { | 868 | { |
| 834 | int i; | 869 | int i; |
| 835 | 870 | bool skip_empty = true; | |
| 836 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 871 | char buf[18]; |
| 837 | if (bitmap[i]) | ||
| 838 | break; | ||
| 839 | 872 | ||
| 840 | seq_printf(seq, "B: %s=", name); | 873 | seq_printf(seq, "B: %s=", name); |
| 841 | for (; i >= 0; i--) | 874 | |
| 842 | seq_printf(seq, "%lx%s", bitmap[i], i > 0 ? " " : ""); | 875 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { |
| 876 | if (input_bits_to_string(buf, sizeof(buf), | ||
| 877 | bitmap[i], skip_empty)) { | ||
| 878 | skip_empty = false; | ||
| 879 | seq_printf(seq, "%s%s", buf, i > 0 ? " " : ""); | ||
| 880 | } | ||
| 881 | } | ||
| 882 | |||
| 883 | /* | ||
| 884 | * If no output was produced print a single 0. | ||
| 885 | */ | ||
| 886 | if (skip_empty) | ||
| 887 | seq_puts(seq, "0"); | ||
| 888 | |||
| 843 | seq_putc(seq, '\n'); | 889 | seq_putc(seq, '\n'); |
| 844 | } | 890 | } |
| 845 | 891 | ||
| @@ -1128,14 +1174,23 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, | |||
| 1128 | { | 1174 | { |
| 1129 | int i; | 1175 | int i; |
| 1130 | int len = 0; | 1176 | int len = 0; |
| 1177 | bool skip_empty = true; | ||
| 1178 | |||
| 1179 | for (i = BITS_TO_LONGS(max) - 1; i >= 0; i--) { | ||
| 1180 | len += input_bits_to_string(buf + len, max(buf_size - len, 0), | ||
| 1181 | bitmap[i], skip_empty); | ||
| 1182 | if (len) { | ||
| 1183 | skip_empty = false; | ||
| 1184 | if (i > 0) | ||
| 1185 | len += snprintf(buf + len, max(buf_size - len, 0), " "); | ||
| 1186 | } | ||
| 1187 | } | ||
| 1131 | 1188 | ||
| 1132 | for (i = BITS_TO_LONGS(max) - 1; i > 0; i--) | 1189 | /* |
| 1133 | if (bitmap[i]) | 1190 | * If no output was produced print a single 0. |
| 1134 | break; | 1191 | */ |
| 1135 | 1192 | if (len == 0) | |
| 1136 | for (; i >= 0; i--) | 1193 | len = snprintf(buf, buf_size, "%d", 0); |
| 1137 | len += snprintf(buf + len, max(buf_size - len, 0), | ||
| 1138 | "%lx%s", bitmap[i], i > 0 ? " " : ""); | ||
| 1139 | 1194 | ||
| 1140 | if (add_cr) | 1195 | if (add_cr) |
| 1141 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | 1196 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); |
| @@ -1150,7 +1205,8 @@ static ssize_t input_dev_show_cap_##bm(struct device *dev, \ | |||
| 1150 | { \ | 1205 | { \ |
| 1151 | struct input_dev *input_dev = to_input_dev(dev); \ | 1206 | struct input_dev *input_dev = to_input_dev(dev); \ |
| 1152 | int len = input_print_bitmap(buf, PAGE_SIZE, \ | 1207 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
| 1153 | input_dev->bm##bit, ev##_MAX, 1); \ | 1208 | input_dev->bm##bit, ev##_MAX, \ |
| 1209 | true); \ | ||
| 1154 | return min_t(int, len, PAGE_SIZE); \ | 1210 | return min_t(int, len, PAGE_SIZE); \ |
| 1155 | } \ | 1211 | } \ |
| 1156 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) | 1212 | static DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL) |
| @@ -1214,7 +1270,7 @@ static int input_add_uevent_bm_var(struct kobj_uevent_env *env, | |||
| 1214 | 1270 | ||
| 1215 | len = input_print_bitmap(&env->buf[env->buflen - 1], | 1271 | len = input_print_bitmap(&env->buf[env->buflen - 1], |
| 1216 | sizeof(env->buf) - env->buflen, | 1272 | sizeof(env->buf) - env->buflen, |
| 1217 | bitmap, max, 0); | 1273 | bitmap, max, false); |
| 1218 | if (len >= (sizeof(env->buf) - env->buflen)) | 1274 | if (len >= (sizeof(env->buf) - env->buflen)) |
| 1219 | return -ENOMEM; | 1275 | return -ENOMEM; |
| 1220 | 1276 | ||
