diff options
| -rw-r--r-- | drivers/video/via/viafbdev.h | 3 | ||||
| -rw-r--r-- | include/linux/kernel.h | 70 | ||||
| -rw-r--r-- | lib/Kconfig.debug | 3 | ||||
| -rw-r--r-- | lib/Makefile | 2 | ||||
| -rw-r--r-- | lib/kstrtox.c | 227 | ||||
| -rw-r--r-- | lib/test-kstrtox.c | 739 | ||||
| -rw-r--r-- | lib/vsprintf.c | 141 | ||||
| -rwxr-xr-x | scripts/checkpatch.pl | 4 |
8 files changed, 1039 insertions, 150 deletions
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index d66f963e930e..137996dc547e 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h | |||
| @@ -94,9 +94,6 @@ extern int viafb_LCD_ON; | |||
| 94 | extern int viafb_DVI_ON; | 94 | extern int viafb_DVI_ON; |
| 95 | extern int viafb_hotplug; | 95 | extern int viafb_hotplug; |
| 96 | 96 | ||
| 97 | extern int strict_strtoul(const char *cp, unsigned int base, | ||
| 98 | unsigned long *res); | ||
| 99 | |||
| 100 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information | 97 | u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information |
| 101 | *plvds_setting_info, struct lvds_chip_information | 98 | *plvds_setting_info, struct lvds_chip_information |
| 102 | *plvds_chip_info, u8 index); | 99 | *plvds_chip_info, u8 index); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 2fe6e84894a4..00cec4dc0ae2 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
| @@ -187,14 +187,76 @@ NORET_TYPE void do_exit(long error_code) | |||
| 187 | ATTRIB_NORET; | 187 | ATTRIB_NORET; |
| 188 | NORET_TYPE void complete_and_exit(struct completion *, long) | 188 | NORET_TYPE void complete_and_exit(struct completion *, long) |
| 189 | ATTRIB_NORET; | 189 | ATTRIB_NORET; |
| 190 | |||
| 191 | /* Internal, do not use. */ | ||
| 192 | int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); | ||
| 193 | int __must_check _kstrtol(const char *s, unsigned int base, long *res); | ||
| 194 | |||
| 195 | int __must_check kstrtoull(const char *s, unsigned int base, unsigned long long *res); | ||
| 196 | int __must_check kstrtoll(const char *s, unsigned int base, long long *res); | ||
| 197 | static inline int __must_check kstrtoul(const char *s, unsigned int base, unsigned long *res) | ||
| 198 | { | ||
| 199 | /* | ||
| 200 | * We want to shortcut function call, but | ||
| 201 | * __builtin_types_compatible_p(unsigned long, unsigned long long) = 0. | ||
| 202 | */ | ||
| 203 | if (sizeof(unsigned long) == sizeof(unsigned long long) && | ||
| 204 | __alignof__(unsigned long) == __alignof__(unsigned long long)) | ||
| 205 | return kstrtoull(s, base, (unsigned long long *)res); | ||
| 206 | else | ||
| 207 | return _kstrtoul(s, base, res); | ||
| 208 | } | ||
| 209 | |||
| 210 | static inline int __must_check kstrtol(const char *s, unsigned int base, long *res) | ||
| 211 | { | ||
| 212 | /* | ||
| 213 | * We want to shortcut function call, but | ||
| 214 | * __builtin_types_compatible_p(long, long long) = 0. | ||
| 215 | */ | ||
| 216 | if (sizeof(long) == sizeof(long long) && | ||
| 217 | __alignof__(long) == __alignof__(long long)) | ||
| 218 | return kstrtoll(s, base, (long long *)res); | ||
| 219 | else | ||
| 220 | return _kstrtol(s, base, res); | ||
| 221 | } | ||
| 222 | |||
| 223 | int __must_check kstrtouint(const char *s, unsigned int base, unsigned int *res); | ||
| 224 | int __must_check kstrtoint(const char *s, unsigned int base, int *res); | ||
| 225 | |||
| 226 | static inline int __must_check kstrtou64(const char *s, unsigned int base, u64 *res) | ||
| 227 | { | ||
| 228 | return kstrtoull(s, base, res); | ||
| 229 | } | ||
| 230 | |||
| 231 | static inline int __must_check kstrtos64(const char *s, unsigned int base, s64 *res) | ||
| 232 | { | ||
| 233 | return kstrtoll(s, base, res); | ||
| 234 | } | ||
| 235 | |||
| 236 | static inline int __must_check kstrtou32(const char *s, unsigned int base, u32 *res) | ||
| 237 | { | ||
| 238 | return kstrtouint(s, base, res); | ||
| 239 | } | ||
| 240 | |||
| 241 | static inline int __must_check kstrtos32(const char *s, unsigned int base, s32 *res) | ||
| 242 | { | ||
| 243 | return kstrtoint(s, base, res); | ||
| 244 | } | ||
| 245 | |||
| 246 | int __must_check kstrtou16(const char *s, unsigned int base, u16 *res); | ||
| 247 | int __must_check kstrtos16(const char *s, unsigned int base, s16 *res); | ||
| 248 | int __must_check kstrtou8(const char *s, unsigned int base, u8 *res); | ||
| 249 | int __must_check kstrtos8(const char *s, unsigned int base, s8 *res); | ||
| 250 | |||
| 190 | extern unsigned long simple_strtoul(const char *,char **,unsigned int); | 251 | extern unsigned long simple_strtoul(const char *,char **,unsigned int); |
| 191 | extern long simple_strtol(const char *,char **,unsigned int); | 252 | extern long simple_strtol(const char *,char **,unsigned int); |
| 192 | extern unsigned long long simple_strtoull(const char *,char **,unsigned int); | 253 | extern unsigned long long simple_strtoull(const char *,char **,unsigned int); |
| 193 | extern long long simple_strtoll(const char *,char **,unsigned int); | 254 | extern long long simple_strtoll(const char *,char **,unsigned int); |
| 194 | extern int __must_check strict_strtoul(const char *, unsigned int, unsigned long *); | 255 | #define strict_strtoul kstrtoul |
| 195 | extern int __must_check strict_strtol(const char *, unsigned int, long *); | 256 | #define strict_strtol kstrtol |
| 196 | extern int __must_check strict_strtoull(const char *, unsigned int, unsigned long long *); | 257 | #define strict_strtoull kstrtoull |
| 197 | extern int __must_check strict_strtoll(const char *, unsigned int, long long *); | 258 | #define strict_strtoll kstrtoll |
| 259 | |||
| 198 | extern int sprintf(char * buf, const char * fmt, ...) | 260 | extern int sprintf(char * buf, const char * fmt, ...) |
| 199 | __attribute__ ((format (printf, 2, 3))); | 261 | __attribute__ ((format (printf, 2, 3))); |
| 200 | extern int vsprintf(char *buf, const char *, va_list) | 262 | extern int vsprintf(char *buf, const char *, va_list) |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index bef5faab660f..df9234c5f9d1 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
| @@ -1250,3 +1250,6 @@ source "samples/Kconfig" | |||
| 1250 | source "lib/Kconfig.kgdb" | 1250 | source "lib/Kconfig.kgdb" |
| 1251 | 1251 | ||
| 1252 | source "lib/Kconfig.kmemcheck" | 1252 | source "lib/Kconfig.kmemcheck" |
| 1253 | |||
| 1254 | config TEST_KSTRTOX | ||
| 1255 | tristate "Test kstrto*() family of functions at runtime" | ||
diff --git a/lib/Makefile b/lib/Makefile index ef7ed71a6ffd..8c9de027ebb1 100644 --- a/lib/Makefile +++ b/lib/Makefile | |||
| @@ -22,6 +22,8 @@ lib-y += kobject.o kref.o klist.o | |||
| 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ | 22 | obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ |
| 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ | 23 | bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ |
| 24 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o | 24 | string_helpers.o gcd.o lcm.o list_sort.o uuid.o flex_array.o |
| 25 | obj-y += kstrtox.o | ||
| 26 | obj-$(CONFIG_TEST_KSTRTOX) += test-kstrtox.o | ||
| 25 | 27 | ||
| 26 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) | 28 | ifeq ($(CONFIG_DEBUG_KOBJECT),y) |
| 27 | CFLAGS_kobject.o += -DDEBUG | 29 | CFLAGS_kobject.o += -DDEBUG |
diff --git a/lib/kstrtox.c b/lib/kstrtox.c new file mode 100644 index 000000000000..05672e819f8c --- /dev/null +++ b/lib/kstrtox.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* | ||
| 2 | * Convert integer string representation to an integer. | ||
| 3 | * If an integer doesn't fit into specified type, -E is returned. | ||
| 4 | * | ||
| 5 | * Integer starts with optional sign. | ||
| 6 | * kstrtou*() functions do not accept sign "-". | ||
| 7 | * | ||
| 8 | * Radix 0 means autodetection: leading "0x" implies radix 16, | ||
| 9 | * leading "0" implies radix 8, otherwise radix is 10. | ||
| 10 | * Autodetection hints work after optional sign, but not before. | ||
| 11 | * | ||
| 12 | * If -E is returned, result is not touched. | ||
| 13 | */ | ||
| 14 | #include <linux/ctype.h> | ||
| 15 | #include <linux/errno.h> | ||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/math64.h> | ||
| 18 | #include <linux/module.h> | ||
| 19 | #include <linux/types.h> | ||
| 20 | |||
| 21 | static inline char _tolower(const char c) | ||
| 22 | { | ||
| 23 | return c | 0x20; | ||
| 24 | } | ||
| 25 | |||
| 26 | static int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) | ||
| 27 | { | ||
| 28 | unsigned long long acc; | ||
| 29 | int ok; | ||
| 30 | |||
| 31 | if (base == 0) { | ||
| 32 | if (s[0] == '0') { | ||
| 33 | if (_tolower(s[1]) == 'x' && isxdigit(s[2])) | ||
| 34 | base = 16; | ||
| 35 | else | ||
| 36 | base = 8; | ||
| 37 | } else | ||
| 38 | base = 10; | ||
| 39 | } | ||
| 40 | if (base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') | ||
| 41 | s += 2; | ||
| 42 | |||
| 43 | acc = 0; | ||
| 44 | ok = 0; | ||
| 45 | while (*s) { | ||
| 46 | unsigned int val; | ||
| 47 | |||
| 48 | if ('0' <= *s && *s <= '9') | ||
| 49 | val = *s - '0'; | ||
| 50 | else if ('a' <= _tolower(*s) && _tolower(*s) <= 'f') | ||
| 51 | val = _tolower(*s) - 'a' + 10; | ||
| 52 | else if (*s == '\n') { | ||
| 53 | if (*(s + 1) == '\0') | ||
| 54 | break; | ||
| 55 | else | ||
| 56 | return -EINVAL; | ||
| 57 | } else | ||
| 58 | return -EINVAL; | ||
| 59 | |||
| 60 | if (val >= base) | ||
| 61 | return -EINVAL; | ||
| 62 | if (acc > div_u64(ULLONG_MAX - val, base)) | ||
| 63 | return -ERANGE; | ||
| 64 | acc = acc * base + val; | ||
| 65 | ok = 1; | ||
| 66 | |||
| 67 | s++; | ||
| 68 | } | ||
| 69 | if (!ok) | ||
| 70 | return -EINVAL; | ||
| 71 | *res = acc; | ||
