162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Convert integer string representation to an integer. 462306a36Sopenharmony_ci * If an integer doesn't fit into specified type, -E is returned. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Integer starts with optional sign. 762306a36Sopenharmony_ci * kstrtou*() functions do not accept sign "-". 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Radix 0 means autodetection: leading "0x" implies radix 16, 1062306a36Sopenharmony_ci * leading "0" implies radix 8, otherwise radix is 10. 1162306a36Sopenharmony_ci * Autodetection hints work after optional sign, but not before. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * If -E is returned, result is not touched. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci#include <linux/ctype.h> 1662306a36Sopenharmony_ci#include <linux/errno.h> 1762306a36Sopenharmony_ci#include <linux/export.h> 1862306a36Sopenharmony_ci#include <linux/kstrtox.h> 1962306a36Sopenharmony_ci#include <linux/math64.h> 2062306a36Sopenharmony_ci#include <linux/types.h> 2162306a36Sopenharmony_ci#include <linux/uaccess.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci#include "kstrtox.h" 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_cinoinline 2662306a36Sopenharmony_ciconst char *_parse_integer_fixup_radix(const char *s, unsigned int *base) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci if (*base == 0) { 2962306a36Sopenharmony_ci if (s[0] == '0') { 3062306a36Sopenharmony_ci if (_tolower(s[1]) == 'x' && isxdigit(s[2])) 3162306a36Sopenharmony_ci *base = 16; 3262306a36Sopenharmony_ci else 3362306a36Sopenharmony_ci *base = 8; 3462306a36Sopenharmony_ci } else 3562306a36Sopenharmony_ci *base = 10; 3662306a36Sopenharmony_ci } 3762306a36Sopenharmony_ci if (*base == 16 && s[0] == '0' && _tolower(s[1]) == 'x') 3862306a36Sopenharmony_ci s += 2; 3962306a36Sopenharmony_ci return s; 4062306a36Sopenharmony_ci} 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci/* 4362306a36Sopenharmony_ci * Convert non-negative integer string representation in explicitly given radix 4462306a36Sopenharmony_ci * to an integer. A maximum of max_chars characters will be converted. 4562306a36Sopenharmony_ci * 4662306a36Sopenharmony_ci * Return number of characters consumed maybe or-ed with overflow bit. 4762306a36Sopenharmony_ci * If overflow occurs, result integer (incorrect) is still returned. 4862306a36Sopenharmony_ci * 4962306a36Sopenharmony_ci * Don't you dare use this function. 5062306a36Sopenharmony_ci */ 5162306a36Sopenharmony_cinoinline 5262306a36Sopenharmony_ciunsigned int _parse_integer_limit(const char *s, unsigned int base, unsigned long long *p, 5362306a36Sopenharmony_ci size_t max_chars) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci unsigned long long res; 5662306a36Sopenharmony_ci unsigned int rv; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci res = 0; 5962306a36Sopenharmony_ci rv = 0; 6062306a36Sopenharmony_ci while (max_chars--) { 6162306a36Sopenharmony_ci unsigned int c = *s; 6262306a36Sopenharmony_ci unsigned int lc = _tolower(c); 6362306a36Sopenharmony_ci unsigned int val; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if ('0' <= c && c <= '9') 6662306a36Sopenharmony_ci val = c - '0'; 6762306a36Sopenharmony_ci else if ('a' <= lc && lc <= 'f') 6862306a36Sopenharmony_ci val = lc - 'a' + 10; 6962306a36Sopenharmony_ci else 7062306a36Sopenharmony_ci break; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci if (val >= base) 7362306a36Sopenharmony_ci break; 7462306a36Sopenharmony_ci /* 7562306a36Sopenharmony_ci * Check for overflow only if we are within range of 7662306a36Sopenharmony_ci * it in the max base we support (16) 7762306a36Sopenharmony_ci */ 7862306a36Sopenharmony_ci if (unlikely(res & (~0ull << 60))) { 7962306a36Sopenharmony_ci if (res > div_u64(ULLONG_MAX - val, base)) 8062306a36Sopenharmony_ci rv |= KSTRTOX_OVERFLOW; 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci res = res * base + val; 8362306a36Sopenharmony_ci rv++; 8462306a36Sopenharmony_ci s++; 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci *p = res; 8762306a36Sopenharmony_ci return rv; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cinoinline 9162306a36Sopenharmony_ciunsigned int _parse_integer(const char *s, unsigned int base, unsigned long long *p) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci return _parse_integer_limit(s, base, p, INT_MAX); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic int _kstrtoull(const char *s, unsigned int base, unsigned long long *res) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci unsigned long long _res; 9962306a36Sopenharmony_ci unsigned int rv; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci s = _parse_integer_fixup_radix(s, &base); 10262306a36Sopenharmony_ci rv = _parse_integer(s, base, &_res); 10362306a36Sopenharmony_ci if (rv & KSTRTOX_OVERFLOW) 10462306a36Sopenharmony_ci return -ERANGE; 10562306a36Sopenharmony_ci if (rv == 0) 10662306a36Sopenharmony_ci return -EINVAL; 10762306a36Sopenharmony_ci s += rv; 10862306a36Sopenharmony_ci if (*s == '\n') 10962306a36Sopenharmony_ci s++; 11062306a36Sopenharmony_ci if (*s) 11162306a36Sopenharmony_ci return -EINVAL; 11262306a36Sopenharmony_ci *res = _res; 11362306a36Sopenharmony_ci return 0; 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci/** 11762306a36Sopenharmony_ci * kstrtoull - convert a string to an unsigned long long 11862306a36Sopenharmony_ci * @s: The start of the string. The string must be null-terminated, and may also 11962306a36Sopenharmony_ci * include a single newline before its terminating null. The first character 12062306a36Sopenharmony_ci * may also be a plus sign, but not a minus sign. 12162306a36Sopenharmony_ci * @base: The number base to use. The maximum supported base is 16. If base is 12262306a36Sopenharmony_ci * given as 0, then the base of the string is automatically detected with the 12362306a36Sopenharmony_ci * conventional semantics - If it begins with 0x the number will be parsed as a 12462306a36Sopenharmony_ci * hexadecimal (case insensitive), if it otherwise begins with 0, it will be 12562306a36Sopenharmony_ci * parsed as an octal number. Otherwise it will be parsed as a decimal. 12662306a36Sopenharmony_ci * @res: Where to write the result of the conversion on success. 12762306a36Sopenharmony_ci * 12862306a36Sopenharmony_ci * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. 12962306a36Sopenharmony_ci * Preferred over simple_strtoull(). Return code must be checked. 13062306a36Sopenharmony_ci */ 13162306a36Sopenharmony_cinoinline 13262306a36Sopenharmony_ciint kstrtoull(const char *s, unsigned int base, unsigned long long *res) 13362306a36Sopenharmony_ci{ 13462306a36Sopenharmony_ci if (s[0] == '+') 13562306a36Sopenharmony_ci s++; 13662306a36Sopenharmony_ci return _kstrtoull(s, base, res); 13762306a36Sopenharmony_ci} 13862306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtoull); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci/** 14162306a36Sopenharmony_ci * kstrtoll - convert a string to a long long 14262306a36Sopenharmony_ci * @s: The start of the string. The string must be null-terminated, and may also 14362306a36Sopenharmony_ci * include a single newline before its terminating null. The first character 14462306a36Sopenharmony_ci * may also be a plus sign or a minus sign. 14562306a36Sopenharmony_ci * @base: The number base to use. The maximum supported base is 16. If base is 14662306a36Sopenharmony_ci * given as 0, then the base of the string is automatically detected with the 14762306a36Sopenharmony_ci * conventional semantics - If it begins with 0x the number will be parsed as a 14862306a36Sopenharmony_ci * hexadecimal (case insensitive), if it otherwise begins with 0, it will be 14962306a36Sopenharmony_ci * parsed as an octal number. Otherwise it will be parsed as a decimal. 15062306a36Sopenharmony_ci * @res: Where to write the result of the conversion on success. 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. 15362306a36Sopenharmony_ci * Preferred over simple_strtoll(). Return code must be checked. 15462306a36Sopenharmony_ci */ 15562306a36Sopenharmony_cinoinline 15662306a36Sopenharmony_ciint kstrtoll(const char *s, unsigned int base, long long *res) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci unsigned long long tmp; 15962306a36Sopenharmony_ci int rv; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci if (s[0] == '-') { 16262306a36Sopenharmony_ci rv = _kstrtoull(s + 1, base, &tmp); 16362306a36Sopenharmony_ci if (rv < 0) 16462306a36Sopenharmony_ci return rv; 16562306a36Sopenharmony_ci if ((long long)-tmp > 0) 16662306a36Sopenharmony_ci return -ERANGE; 16762306a36Sopenharmony_ci *res = -tmp; 16862306a36Sopenharmony_ci } else { 16962306a36Sopenharmony_ci rv = kstrtoull(s, base, &tmp); 17062306a36Sopenharmony_ci if (rv < 0) 17162306a36Sopenharmony_ci return rv; 17262306a36Sopenharmony_ci if ((long long)tmp < 0) 17362306a36Sopenharmony_ci return -ERANGE; 17462306a36Sopenharmony_ci *res = tmp; 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci return 0; 17762306a36Sopenharmony_ci} 17862306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtoll); 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci/* Internal, do not use. */ 18162306a36Sopenharmony_ciint _kstrtoul(const char *s, unsigned int base, unsigned long *res) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci unsigned long long tmp; 18462306a36Sopenharmony_ci int rv; 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci rv = kstrtoull(s, base, &tmp); 18762306a36Sopenharmony_ci if (rv < 0) 18862306a36Sopenharmony_ci return rv; 18962306a36Sopenharmony_ci if (tmp != (unsigned long)tmp) 19062306a36Sopenharmony_ci return -ERANGE; 19162306a36Sopenharmony_ci *res = tmp; 19262306a36Sopenharmony_ci return 0; 19362306a36Sopenharmony_ci} 19462306a36Sopenharmony_ciEXPORT_SYMBOL(_kstrtoul); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci/* Internal, do not use. */ 19762306a36Sopenharmony_ciint _kstrtol(const char *s, unsigned int base, long *res) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci long long tmp; 20062306a36Sopenharmony_ci int rv; 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_ci rv = kstrtoll(s, base, &tmp); 20362306a36Sopenharmony_ci if (rv < 0) 20462306a36Sopenharmony_ci return rv; 20562306a36Sopenharmony_ci if (tmp != (long)tmp) 20662306a36Sopenharmony_ci return -ERANGE; 20762306a36Sopenharmony_ci *res = tmp; 20862306a36Sopenharmony_ci return 0; 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ciEXPORT_SYMBOL(_kstrtol); 21162306a36Sopenharmony_ci 21262306a36Sopenharmony_ci/** 21362306a36Sopenharmony_ci * kstrtouint - convert a string to an unsigned int 21462306a36Sopenharmony_ci * @s: The start of the string. The string must be null-terminated, and may also 21562306a36Sopenharmony_ci * include a single newline before its terminating null. The first character 21662306a36Sopenharmony_ci * may also be a plus sign, but not a minus sign. 21762306a36Sopenharmony_ci * @base: The number base to use. The maximum supported base is 16. If base is 21862306a36Sopenharmony_ci * given as 0, then the base of the string is automatically detected with the 21962306a36Sopenharmony_ci * conventional semantics - If it begins with 0x the number will be parsed as a 22062306a36Sopenharmony_ci * hexadecimal (case insensitive), if it otherwise begins with 0, it will be 22162306a36Sopenharmony_ci * parsed as an octal number. Otherwise it will be parsed as a decimal. 22262306a36Sopenharmony_ci * @res: Where to write the result of the conversion on success. 22362306a36Sopenharmony_ci * 22462306a36Sopenharmony_ci * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. 22562306a36Sopenharmony_ci * Preferred over simple_strtoul(). Return code must be checked. 22662306a36Sopenharmony_ci */ 22762306a36Sopenharmony_cinoinline 22862306a36Sopenharmony_ciint kstrtouint(const char *s, unsigned int base, unsigned int *res) 22962306a36Sopenharmony_ci{ 23062306a36Sopenharmony_ci unsigned long long tmp; 23162306a36Sopenharmony_ci int rv; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci rv = kstrtoull(s, base, &tmp); 23462306a36Sopenharmony_ci if (rv < 0) 23562306a36Sopenharmony_ci return rv; 23662306a36Sopenharmony_ci if (tmp != (unsigned int)tmp) 23762306a36Sopenharmony_ci return -ERANGE; 23862306a36Sopenharmony_ci *res = tmp; 23962306a36Sopenharmony_ci return 0; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtouint); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci/** 24462306a36Sopenharmony_ci * kstrtoint - convert a string to an int 24562306a36Sopenharmony_ci * @s: The start of the string. The string must be null-terminated, and may also 24662306a36Sopenharmony_ci * include a single newline before its terminating null. The first character 24762306a36Sopenharmony_ci * may also be a plus sign or a minus sign. 24862306a36Sopenharmony_ci * @base: The number base to use. The maximum supported base is 16. If base is 24962306a36Sopenharmony_ci * given as 0, then the base of the string is automatically detected with the 25062306a36Sopenharmony_ci * conventional semantics - If it begins with 0x the number will be parsed as a 25162306a36Sopenharmony_ci * hexadecimal (case insensitive), if it otherwise begins with 0, it will be 25262306a36Sopenharmony_ci * parsed as an octal number. Otherwise it will be parsed as a decimal. 25362306a36Sopenharmony_ci * @res: Where to write the result of the conversion on success. 25462306a36Sopenharmony_ci * 25562306a36Sopenharmony_ci * Returns 0 on success, -ERANGE on overflow and -EINVAL on parsing error. 25662306a36Sopenharmony_ci * Preferred over simple_strtol(). Return code must be checked. 25762306a36Sopenharmony_ci */ 25862306a36Sopenharmony_cinoinline 25962306a36Sopenharmony_ciint kstrtoint(const char *s, unsigned int base, int *res) 26062306a36Sopenharmony_ci{ 26162306a36Sopenharmony_ci long long tmp; 26262306a36Sopenharmony_ci int rv; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci rv = kstrtoll(s, base, &tmp); 26562306a36Sopenharmony_ci if (rv < 0) 26662306a36Sopenharmony_ci return rv; 26762306a36Sopenharmony_ci if (tmp != (int)tmp) 26862306a36Sopenharmony_ci return -ERANGE; 26962306a36Sopenharmony_ci *res = tmp; 27062306a36Sopenharmony_ci return 0; 27162306a36Sopenharmony_ci} 27262306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtoint); 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cinoinline 27562306a36Sopenharmony_ciint kstrtou16(const char *s, unsigned int base, u16 *res) 27662306a36Sopenharmony_ci{ 27762306a36Sopenharmony_ci unsigned long long tmp; 27862306a36Sopenharmony_ci int rv; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci rv = kstrtoull(s, base, &tmp); 28162306a36Sopenharmony_ci if (rv < 0) 28262306a36Sopenharmony_ci return rv; 28362306a36Sopenharmony_ci if (tmp != (u16)tmp) 28462306a36Sopenharmony_ci return -ERANGE; 28562306a36Sopenharmony_ci *res = tmp; 28662306a36Sopenharmony_ci return 0; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtou16); 28962306a36Sopenharmony_ci 29062306a36Sopenharmony_cinoinline 29162306a36Sopenharmony_ciint kstrtos16(const char *s, unsigned int base, s16 *res) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci long long tmp; 29462306a36Sopenharmony_ci int rv; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci rv = kstrtoll(s, base, &tmp); 29762306a36Sopenharmony_ci if (rv < 0) 29862306a36Sopenharmony_ci return rv; 29962306a36Sopenharmony_ci if (tmp != (s16)tmp) 30062306a36Sopenharmony_ci return -ERANGE; 30162306a36Sopenharmony_ci *res = tmp; 30262306a36Sopenharmony_ci return 0; 30362306a36Sopenharmony_ci} 30462306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtos16); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_cinoinline 30762306a36Sopenharmony_ciint kstrtou8(const char *s, unsigned int base, u8 *res) 30862306a36Sopenharmony_ci{ 30962306a36Sopenharmony_ci unsigned long long tmp; 31062306a36Sopenharmony_ci int rv; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci rv = kstrtoull(s, base, &tmp); 31362306a36Sopenharmony_ci if (rv < 0) 31462306a36Sopenharmony_ci return rv; 31562306a36Sopenharmony_ci if (tmp != (u8)tmp) 31662306a36Sopenharmony_ci return -ERANGE; 31762306a36Sopenharmony_ci *res = tmp; 31862306a36Sopenharmony_ci return 0; 31962306a36Sopenharmony_ci} 32062306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtou8); 32162306a36Sopenharmony_ci 32262306a36Sopenharmony_cinoinline 32362306a36Sopenharmony_ciint kstrtos8(const char *s, unsigned int base, s8 *res) 32462306a36Sopenharmony_ci{ 32562306a36Sopenharmony_ci long long tmp; 32662306a36Sopenharmony_ci int rv; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_ci rv = kstrtoll(s, base, &tmp); 32962306a36Sopenharmony_ci if (rv < 0) 33062306a36Sopenharmony_ci return rv; 33162306a36Sopenharmony_ci if (tmp != (s8)tmp) 33262306a36Sopenharmony_ci return -ERANGE; 33362306a36Sopenharmony_ci *res = tmp; 33462306a36Sopenharmony_ci return 0; 33562306a36Sopenharmony_ci} 33662306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtos8); 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci/** 33962306a36Sopenharmony_ci * kstrtobool - convert common user inputs into boolean values 34062306a36Sopenharmony_ci * @s: input string 34162306a36Sopenharmony_ci * @res: result 34262306a36Sopenharmony_ci * 34362306a36Sopenharmony_ci * This routine returns 0 iff the first character is one of 'YyTt1NnFf0', or 34462306a36Sopenharmony_ci * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL. Value 34562306a36Sopenharmony_ci * pointed to by res is updated upon finding a match. 34662306a36Sopenharmony_ci */ 34762306a36Sopenharmony_cinoinline 34862306a36Sopenharmony_ciint kstrtobool(const char *s, bool *res) 34962306a36Sopenharmony_ci{ 35062306a36Sopenharmony_ci if (!s) 35162306a36Sopenharmony_ci return -EINVAL; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci switch (s[0]) { 35462306a36Sopenharmony_ci case 'y': 35562306a36Sopenharmony_ci case 'Y': 35662306a36Sopenharmony_ci case 't': 35762306a36Sopenharmony_ci case 'T': 35862306a36Sopenharmony_ci case '1': 35962306a36Sopenharmony_ci *res = true; 36062306a36Sopenharmony_ci return 0; 36162306a36Sopenharmony_ci case 'n': 36262306a36Sopenharmony_ci case 'N': 36362306a36Sopenharmony_ci case 'f': 36462306a36Sopenharmony_ci case 'F': 36562306a36Sopenharmony_ci case '0': 36662306a36Sopenharmony_ci *res = false; 36762306a36Sopenharmony_ci return 0; 36862306a36Sopenharmony_ci case 'o': 36962306a36Sopenharmony_ci case 'O': 37062306a36Sopenharmony_ci switch (s[1]) { 37162306a36Sopenharmony_ci case 'n': 37262306a36Sopenharmony_ci case 'N': 37362306a36Sopenharmony_ci *res = true; 37462306a36Sopenharmony_ci return 0; 37562306a36Sopenharmony_ci case 'f': 37662306a36Sopenharmony_ci case 'F': 37762306a36Sopenharmony_ci *res = false; 37862306a36Sopenharmony_ci return 0; 37962306a36Sopenharmony_ci default: 38062306a36Sopenharmony_ci break; 38162306a36Sopenharmony_ci } 38262306a36Sopenharmony_ci break; 38362306a36Sopenharmony_ci default: 38462306a36Sopenharmony_ci break; 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci return -EINVAL; 38862306a36Sopenharmony_ci} 38962306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtobool); 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci/* 39262306a36Sopenharmony_ci * Since "base" would be a nonsense argument, this open-codes the 39362306a36Sopenharmony_ci * _from_user helper instead of using the helper macro below. 39462306a36Sopenharmony_ci */ 39562306a36Sopenharmony_ciint kstrtobool_from_user(const char __user *s, size_t count, bool *res) 39662306a36Sopenharmony_ci{ 39762306a36Sopenharmony_ci /* Longest string needed to differentiate, newline, terminator */ 39862306a36Sopenharmony_ci char buf[4]; 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci count = min(count, sizeof(buf) - 1); 40162306a36Sopenharmony_ci if (copy_from_user(buf, s, count)) 40262306a36Sopenharmony_ci return -EFAULT; 40362306a36Sopenharmony_ci buf[count] = '\0'; 40462306a36Sopenharmony_ci return kstrtobool(buf, res); 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ciEXPORT_SYMBOL(kstrtobool_from_user); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci#define kstrto_from_user(f, g, type) \ 40962306a36Sopenharmony_ciint f(const char __user *s, size_t count, unsigned int base, type *res) \ 41062306a36Sopenharmony_ci{ \ 41162306a36Sopenharmony_ci /* sign, base 2 representation, newline, terminator */ \ 41262306a36Sopenharmony_ci char buf[1 + sizeof(type) * 8 + 1 + 1]; \ 41362306a36Sopenharmony_ci \ 41462306a36Sopenharmony_ci count = min(count, sizeof(buf) - 1); \ 41562306a36Sopenharmony_ci if (copy_from_user(buf, s, count)) \ 41662306a36Sopenharmony_ci return -EFAULT; \ 41762306a36Sopenharmony_ci buf[count] = '\0'; \ 41862306a36Sopenharmony_ci return g(buf, base, res); \ 41962306a36Sopenharmony_ci} \ 42062306a36Sopenharmony_ciEXPORT_SYMBOL(f) 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cikstrto_from_user(kstrtoull_from_user, kstrtoull, unsigned long long); 42362306a36Sopenharmony_cikstrto_from_user(kstrtoll_from_user, kstrtoll, long long); 42462306a36Sopenharmony_cikstrto_from_user(kstrtoul_from_user, kstrtoul, unsigned long); 42562306a36Sopenharmony_cikstrto_from_user(kstrtol_from_user, kstrtol, long); 42662306a36Sopenharmony_cikstrto_from_user(kstrtouint_from_user, kstrtouint, unsigned int); 42762306a36Sopenharmony_cikstrto_from_user(kstrtoint_from_user, kstrtoint, int); 42862306a36Sopenharmony_cikstrto_from_user(kstrtou16_from_user, kstrtou16, u16); 42962306a36Sopenharmony_cikstrto_from_user(kstrtos16_from_user, kstrtos16, s16); 43062306a36Sopenharmony_cikstrto_from_user(kstrtou8_from_user, kstrtou8, u8); 43162306a36Sopenharmony_cikstrto_from_user(kstrtos8_from_user, kstrtos8, s8); 432