diff --git a/include/sys/sunddi.h b/include/sys/sunddi.h index dea09d171c..cf9c8ebc79 100644 --- a/include/sys/sunddi.h +++ b/include/sys/sunddi.h @@ -200,6 +200,11 @@ extern void __ddi_remove_minor_node(dev_info_t *dip, char *name); extern int __mod_install(struct modlinkage *modlp); extern int __mod_remove(struct modlinkage *modlp); +extern int ddi_strtoul(const char *, char **, int, unsigned long *); +extern int ddi_strtol(const char *, char **, int, long *); +extern int ddi_strtoull(const char *, char **, int, unsigned long long *); +extern int ddi_strtoll(const char *, char **, int, long long *); + static __inline__ void ddi_report_dev(dev_info_t *d) { } static __inline__ void ddi_prop_remove_all(dev_info_t *dip) { } diff --git a/modules/spl/spl-generic.c b/modules/spl/spl-generic.c index 944d70e72d..58b5951700 100644 --- a/modules/spl/spl-generic.c +++ b/modules/spl/spl-generic.c @@ -125,13 +125,60 @@ uint64_t __umoddi3(uint64_t dividend, uint64_t divisor) EXPORT_SYMBOL(__umoddi3); #endif -int -ddi_strtoul(const char *str, char **nptr, int base, unsigned long *result) -{ - char *end; - return (*result = simple_strtoul(str, &end, base)); -} +int ddi_strtoul(const char *, char **, int, unsigned long *); +int ddi_strtol(const char *, char **, int, long *); +int ddi_strtoull(const char *, char **, int, unsigned long long *); +int ddi_strtoll(const char *, char **, int, long long *); + +#define define_ddi_strtoux(type, valtype) \ +int ddi_strtou##type(const char *str, char **endptr, \ + int base, valtype *result) \ +{ \ + valtype val; \ + size_t len; \ + \ + len = strlen(str); \ + if (len == 0) \ + return -EINVAL; \ + \ + val = simple_strtoul(str, endptr, (unsigned int)base); \ + if ((**endptr == '\0') || \ + ((len == (size_t)(*endptr-str) + 1) && (**endptr == '\n'))) {\ + *result = val; \ + return 0; \ + } \ + \ + return -EINVAL; \ +} \ + +#define define_ddi_strtox(type, valtype) \ +int ddi_strto##type(const char *str, char **endptr, \ + int base, valtype *result) \ +{ \ + int ret; \ + \ + if (*str == '-') { \ + ret = ddi_strtou##type(str+1, endptr, \ + (unsigned int)base, result); \ + if (!ret) \ + *result = -(*result); \ + } else { \ + ret = ddi_strtou##type(str, endptr, \ + (unsigned int)base, result); \ + } \ + \ + return ret; \ +} \ + +define_ddi_strtoux(l, unsigned long) +define_ddi_strtox(l, long) +define_ddi_strtoux(ll, unsigned long long) +define_ddi_strtox(ll, long long) + EXPORT_SYMBOL(ddi_strtoul); +EXPORT_SYMBOL(ddi_strtol); +EXPORT_SYMBOL(ddi_strtoll); +EXPORT_SYMBOL(ddi_strtoull); struct new_utsname *__utsname(void) {