aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/Kconfig.debug55
-rw-r--r--lib/Makefile2
-rw-r--r--lib/dynamic_printk.c418
-rw-r--r--lib/iommu-helper.c9
-rw-r--r--lib/kobject.c35
-rw-r--r--lib/vsprintf.c235
7 files changed, 637 insertions, 121 deletions
diff --git a/lib/Kconfig b/lib/Kconfig
index c7ad7a5b3535..85cf7ea978aa 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -8,10 +8,10 @@ config BITREVERSE
8 tristate 8 tristate
9 9
10config GENERIC_FIND_FIRST_BIT 10config GENERIC_FIND_FIRST_BIT
11 def_bool n 11 bool
12 12
13config GENERIC_FIND_NEXT_BIT 13config GENERIC_FIND_NEXT_BIT
14 def_bool n 14 bool
15 15
16config CRC_CCITT 16config CRC_CCITT
17 tristate "CRC-CCITT functions" 17 tristate "CRC-CCITT functions"
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index aa81d2848448..31d784dd80d0 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -807,6 +807,61 @@ menuconfig BUILD_DOCSRC
807 807
808 Say N if you are unsure. 808 Say N if you are unsure.
809 809
810config DYNAMIC_PRINTK_DEBUG
811 bool "Enable dynamic printk() call support"
812 default n
813 depends on PRINTK
814 select PRINTK_DEBUG
815 help
816
817 Compiles debug level messages into the kernel, which would not
818 otherwise be available at runtime. These messages can then be
819 enabled/disabled on a per module basis. This mechanism implicitly
820 enables all pr_debug() and dev_dbg() calls. The impact of this
821 compile option is a larger kernel text size of about 2%.
822
823 Usage:
824
825 Dynamic debugging is controlled by the debugfs file,
826 dynamic_printk/modules. This file contains a list of the modules that
827 can be enabled. The format of the file is the module name, followed
828 by a set of flags that can be enabled. The first flag is always the
829 'enabled' flag. For example:
830
831 <module_name> <enabled=0/1>
832 .
833 .
834 .
835
836 <module_name> : Name of the module in which the debug call resides
837 <enabled=0/1> : whether the messages are enabled or not
838
839 From a live system:
840
841 snd_hda_intel enabled=0
842 fixup enabled=0
843 driver enabled=0
844
845 Enable a module:
846
847 $echo "set enabled=1 <module_name>" > dynamic_printk/modules
848
849 Disable a module:
850
851 $echo "set enabled=0 <module_name>" > dynamic_printk/modules
852
853 Enable all modules:
854
855 $echo "set enabled=1 all" > dynamic_printk/modules
856
857 Disable all modules:
858
859 $echo "set enabled=0 all" > dynamic_printk/modules
860
861 Finally, passing "dynamic_printk" at the command line enables
862 debugging for all modules. This mode can be turned off via the above
863 disable command.
864
810source "samples/Kconfig" 865source "samples/Kconfig"
811 866
812source "lib/Kconfig.kgdb" 867source "lib/Kconfig.kgdb"
diff --git a/lib/Makefile b/lib/Makefile
index 44001af76a7d..16feaab057b2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -81,6 +81,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
81 81
82obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o 82obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
83 83
84obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
85
84hostprogs-y := gen_crc32table 86hostprogs-y := gen_crc32table
85clean-files := crc32table.h 87clean-files := crc32table.h
86 88
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
new file mode 100644
index 000000000000..d640f87bdc9e
--- /dev/null
+++ b/lib/dynamic_printk.c
@@ -0,0 +1,418 @@
1/*
2 * lib/dynamic_printk.c
3 *
4 * make pr_debug()/dev_dbg() calls runtime configurable based upon their
5 * their source module.
6 *
7 * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
8 */
9
10#include <linux/kernel.h>
11#include <linux/module.h>
12#include <linux/uaccess.h>
13#include <linux/seq_file.h>
14#include <linux/debugfs.h>
15#include <linux/fs.h>
16
17extern struct mod_debug __start___verbose[];
18extern struct mod_debug __stop___verbose[];
19
20struct debug_name {
21 struct hlist_node hlist;
22 struct hlist_node hlist2;
23 int hash1;
24 int hash2;
25 char *name;
26 int enable;
27 int type;
28};
29
30static int nr_entries;
31static int num_enabled;
32int dynamic_enabled = DYNAMIC_ENABLED_NONE;
33static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
34 { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
35static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
36 { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
37static DECLARE_MUTEX(debug_list_mutex);
38
39/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
40 * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
41 * use independent hash functions, to reduce the chance of false positives.
42 */
43long long dynamic_printk_enabled;
44EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
45long long dynamic_printk_enabled2;
46EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
47
48/* returns the debug module pointer. */
49static struct debug_name *find_debug_module(char *module_name)
50{
51 int i;
52 struct hlist_head *head;
53 struct hlist_node *node;
54 struct debug_name *element;
55
56 element = NULL;
57 for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
58 head = &module_table[i];
59 hlist_for_each_entry_rcu(element, node, head, hlist)
60 if (!strcmp(element->name, module_name))
61 return element;
62 }
63 return NULL;
64}
65
66/* returns the debug module pointer. */
67static struct debug_name *find_debug_module_hash(char *module_name, int hash)
68{
69 struct hlist_head *head;
70 struct hlist_node *node;
71 struct debug_name *element;
72
73 element = NULL;
74 head = &module_table[hash];
75 hlist_for_each_entry_rcu(element, node, head, hlist)
76 if (!strcmp(element->name, module_name))
77 return element;
78 return NULL;
79}
80
81/* caller must hold mutex*/
82static int __add_debug_module(char *mod_name, int hash, int hash2)
83{
84 struct debug_name *new;
85 char *module_name;
86 int ret = 0;
87
88 if (find_debug_module(mod_name)) {
89 ret = -EINVAL;
90 goto out;
91 }
92 module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
93 if (!module_name) {
94 ret = -ENOMEM;
95 goto out;
96 }
97 module_name = strcpy(module_name, mod_name);
98 module_name[strlen(mod_name)] = '\0';
99 new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
100 if (!new) {
101 kfree(module_name);
102 ret = -ENOMEM;
103 goto out;
104 }
105 INIT_HLIST_NODE(&new->hlist);
106 INIT_HLIST_NODE(&new->hlist2);
107 new->name = module_name;
108 new->hash1 = hash;
109 new->hash2 = hash2;
110 hlist_add_head_rcu(&new->hlist, &module_table[hash]);
111 hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
112 nr_entries++;
113out:
114 return ret;
115}
116
117int unregister_dynamic_debug_module(char *mod_name)
118{
119 struct debug_name *element;
120 int ret = 0;
121
122 down(&debug_list_mutex);
123 element = find_debug_module(mod_name);
124 if (!element) {
125 ret = -EINVAL;
126 goto out;
127 }
128 hlist_del_rcu(&element->hlist);
129 hlist_del_rcu(&element->hlist2);
130 synchronize_rcu();
131 kfree(element->name);
132 if (element->enable)
133 num_enabled--;
134 kfree(element);
135 nr_entries--;
136out:
137 up(&debug_list_mutex);
138 return 0;
139}
140EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
141
142int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
143 char *flags, int hash, int hash2)
144{
145 struct debug_name *elem;
146 int ret = 0;
147
148 down(&debug_list_mutex);
149 elem = find_debug_module(mod_name);
150 if (!elem) {
151 if (__add_debug_module(mod_name, hash, hash2))
152 goto out;
153 elem = find_debug_module(mod_name);
154 if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
155 !strcmp(mod_name, share_name)) {
156 elem->enable = true;
157 num_enabled++;
158 }
159 }
160 elem->type |= type;
161out:
162 up(&debug_list_mutex);
163 return ret;
164}
165EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
166
167int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
168{
169 struct debug_name *elem;
170 int ret = 0;
171
172 if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
173 return 1;
174 rcu_read_lock();
175 elem = find_debug_module_hash(mod_name, hash);
176 if (elem && elem->enable)
177 ret = 1;
178 rcu_read_unlock();
179 return ret;
180}
181EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
182
183static void set_all(bool enable)
184{
185 struct debug_name *e;
186 struct hlist_node *node;
187 int i;
188 long long enable_mask;
189
190 for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
191 if (module_table[i].first != NULL) {
192 hlist_for_each_entry(e, node, &module_table[i], hlist) {
193 e->enable = enable;
194 }
195 }
196 }
197 if (enable)
198 enable_mask = ULLONG_MAX;
199 else
200 enable_mask = 0;
201 dynamic_printk_enabled = enable_mask;
202 dynamic_printk_enabled2 = enable_mask;
203}
204
205static int disabled_hash(int i, bool first_table)
206{
207 struct debug_name *e;
208 struct hlist_node *node;
209
210 if (first_table) {
211 hlist_for_each_entry(e, node, &module_table[i], hlist) {
212 if (e->enable)
213 return 0;
214 }
215 } else {
216 hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
217 if (e->enable)
218 return 0;
219 }
220 }
221 return 1;
222}
223
224static ssize_t pr_debug_write(struct file *file, const char __user *buf,
225 size_t length, loff_t *ppos)
226{
227 char *buffer, *s, *value_str, *setting_str;
228 int err, value;
229 struct debug_name *elem = NULL;
230 int all = 0;
231
232 if (length > PAGE_SIZE || length < 0)
233 return -EINVAL;
234
235 buffer = (char *)__get_free_page(GFP_KERNEL);
236 if (!buffer)
237 return -ENOMEM;
238
239 err = -EFAULT;
240 if (copy_from_user(buffer, buf, length))
241 goto out;
242
243 err = -EINVAL;
244 if (length < PAGE_SIZE)
245 buffer[length] = '\0';
246 else if (buffer[PAGE_SIZE-1])
247 goto out;
248
249 err = -EINVAL;
250 down(&debug_list_mutex);
251
252 if (strncmp("set", buffer, 3))
253 goto out_up;
254 s = buffer + 3;
255 setting_str = strsep(&s, "=");
256 if (s == NULL)
257 goto out_up;
258 setting_str = strstrip(setting_str);
259 value_str = strsep(&s, " ");
260 if (s == NULL)
261 goto out_up;
262 s = strstrip(s);
263 if (!strncmp(s, "all", 3))
264 all = 1;
265 else
266 elem = find_debug_module(s);
267 if (!strncmp(setting_str, "enable", 6)) {
268 value = !!simple_strtol(value_str, NULL, 10);
269 if (all) {
270 if (value) {
271 set_all(true);
272 num_enabled = nr_entries;
273 dynamic_enabled = DYNAMIC_ENABLED_ALL;
274 } else {
275 set_all(false);
276 num_enabled = 0;
277 dynamic_enabled = DYNAMIC_ENABLED_NONE;
278 }
279 err = 0;
280 } else {
281 if (elem) {
282 if (value && (elem->enable == 0)) {
283 dynamic_printk_enabled |=
284 (1LL << elem->hash1);
285 dynamic_printk_enabled2 |=
286 (1LL << elem->hash2);
287 elem->enable = 1;
288 num_enabled++;
289 dynamic_enabled = DYNAMIC_ENABLED_SOME;
290 err = 0;
291 printk(KERN_DEBUG
292 "debugging enabled for module %s",
293 elem->name);
294 } else if (!value && (elem->enable == 1)) {
295 elem->enable = 0;
296 num_enabled--;
297 if (disabled_hash(elem->hash1, true))
298 dynamic_printk_enabled &=
299 ~(1LL << elem->hash1);
300 if (disabled_hash(elem->hash2, false))
301 dynamic_printk_enabled2 &=
302 ~(1LL << elem->hash2);
303 if (num_enabled)
304 dynamic_enabled =
305 DYNAMIC_ENABLED_SOME;
306 else
307 dynamic_enabled =
308 DYNAMIC_ENABLED_NONE;
309 err = 0;
310 printk(KERN_DEBUG
311 "debugging disabled for module "
312 "%s", elem->name);
313 }
314 }
315 }
316 }
317 if (!err)
318 err = length;
319out_up:
320 up(&debug_list_mutex);
321out:
322 free_page((unsigned long)buffer);
323 return err;
324}
325
326static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
327{
328 return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
329}
330
331static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
332{
333 (*pos)++;
334 if (*pos >= DEBUG_HASH_TABLE_SIZE)
335 return NULL;
336 return pos;
337}
338
339static void pr_debug_seq_stop(struct seq_file *s, void *v)
340{
341 /* Nothing to do */
342}
343
344static int pr_debug_seq_show(struct seq_file *s, void *v)
345{
346 struct hlist_head *head;
347 struct hlist_node *node;
348 struct debug_name *elem;
349 unsigned int i = *(loff_t *) v;
350
351 rcu_read_lock();
352 head = &module_table[i];
353 hlist_for_each_entry_rcu(elem, node, head, hlist) {
354 seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
355 seq_printf(s, "\n");
356 }
357 rcu_read_unlock();
358 return 0;
359}
360
361static struct seq_operations pr_debug_seq_ops = {
362 .start = pr_debug_seq_start,
363 .next = pr_debug_seq_next,
364 .stop = pr_debug_seq_stop,
365 .show = pr_debug_seq_show
366};
367
368static int pr_debug_open(struct inode *inode, struct file *filp)
369{
370 return seq_open(filp, &pr_debug_seq_ops);
371}
372
373static const struct file_operations pr_debug_operations = {
374 .open = pr_debug_open,
375 .read = seq_read,
376 .write = pr_debug_write,
377 .llseek = seq_lseek,
378 .release = seq_release,
379};
380
381static int __init dynamic_printk_init(void)
382{
383 struct dentry *dir, *file;
384 struct mod_debug *iter;
385 unsigned long value;
386
387 dir = debugfs_create_dir("dynamic_printk", NULL);
388 if (!dir)
389 return -ENOMEM;
390 file = debugfs_create_file("modules", 0644, dir, NULL,
391 &pr_debug_operations);
392 if (!file) {
393 debugfs_remove(dir);
394 return -ENOMEM;
395 }
396 for (value = (unsigned long)__start___verbose;
397 value < (unsigned long)__stop___verbose;
398 value += sizeof(struct mod_debug)) {
399 iter = (struct mod_debug *)value;
400 register_dynamic_debug_module(iter->modname,
401 iter->type,
402 iter->logical_modname,
403 iter->flag_names, iter->hash, iter->hash2);
404 }
405 return 0;
406}
407module_init(dynamic_printk_init);
408/* may want to move this earlier so we can get traces as early as possible */
409
410static int __init dynamic_printk_setup(char *str)
411{
412 if (str)
413 return -ENOENT;
414 set_all(true);
415 return 0;
416}
417/* Use early_param(), so we can get debug output as early as possible */
418early_param("dynamic_printk", dynamic_printk_setup);
diff --git a/lib/iommu-helper.c b/lib/iommu-helper.c
index 5d90074dca75..75dbda03f4fb 100644
--- a/lib/iommu-helper.c
+++ b/lib/iommu-helper.c
@@ -79,3 +79,12 @@ void iommu_area_free(unsigned long *map, unsigned long start, unsigned int nr)
79 } 79 }
80} 80}
81EXPORT_SYMBOL(iommu_area_free); 81EXPORT_SYMBOL(iommu_area_free);
82
83unsigned long iommu_num_pages(unsigned long addr, unsigned long len,
84 unsigned long io_page_size)
85{
86 unsigned long size = (addr & (io_page_size - 1)) + len;
87
88 return DIV_ROUND_UP(size, io_page_size);
89}
90EXPORT_SYMBOL(iommu_num_pages);
diff --git a/lib/kobject.c b/lib/kobject.c
index fbf0ae282376..0487d1f64806 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -387,11 +387,17 @@ EXPORT_SYMBOL_GPL(kobject_init_and_add);
387 * kobject_rename - change the name of an object 387 * kobject_rename - change the name of an object
388 * @kobj: object in question. 388 * @kobj: object in question.
389 * @new_name: object's new name 389 * @new_name: object's new name
390 *
391 * It is the responsibility of the caller to provide mutual
392 * exclusion between two different calls of kobject_rename
393 * on the same kobject and to ensure that new_name is valid and
394 * won't conflict with other kobjects.
390 */ 395 */
391int kobject_rename(struct kobject *kobj, const char *new_name) 396int kobject_rename(struct kobject *kobj, const char *new_name)
392{ 397{
393 int error = 0; 398 int error = 0;
394 const char *devpath = NULL; 399 const char *devpath = NULL;
400 const char *dup_name = NULL, *name;
395 char *devpath_string = NULL; 401 char *devpath_string = NULL;
396 char *envp[2]; 402 char *envp[2];
397 403
@@ -401,19 +407,6 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
401 if (!kobj->parent) 407 if (!kobj->parent)
402 return -EINVAL; 408 return -EINVAL;
403 409
404 /* see if this name is already in use */
405 if (kobj->kset) {
406 struct kobject *temp_kobj;
407 temp_kobj = kset_find_obj(kobj->kset, new_name);
408 if (temp_kobj) {
409 printk(KERN_WARNING "kobject '%s' cannot be renamed "
410 "to '%s' as '%s' is already in existence.\n",
411 kobject_name(kobj), new_name, new_name);
412 kobject_put(temp_kobj);
413 return -EINVAL;
414 }
415 }
416
417 devpath = kobject_get_path(kobj, GFP_KERNEL); 410 devpath = kobject_get_path(kobj, GFP_KERNEL);
418 if (!devpath) { 411 if (!devpath) {
419 error = -ENOMEM; 412 error = -ENOMEM;
@@ -428,15 +421,27 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
428 envp[0] = devpath_string; 421 envp[0] = devpath_string;
429 envp[1] = NULL; 422 envp[1] = NULL;
430 423
424 name = dup_name = kstrdup(new_name, GFP_KERNEL);
425 if (!name) {
426 error = -ENOMEM;
427 goto out;
428 }
429
431 error = sysfs_rename_dir(kobj, new_name); 430 error = sysfs_rename_dir(kobj, new_name);
431 if (error)
432 goto out;
433
434 /* Install the new kobject name */
435 dup_name = kobj->name;
436 kobj->name = name;
432 437
433 /* This function is mostly/only used for network interface. 438 /* This function is mostly/only used for network interface.
434 * Some hotplug package track interfaces by their name and 439 * Some hotplug package track interfaces by their name and
435 * therefore want to know when the name is changed by the user. */ 440 * therefore want to know when the name is changed by the user. */
436 if (!error) 441 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
437 kobject_uevent_env(kobj, KOBJ_MOVE, envp);
438 442
439out: 443out:
444 kfree(dup_name);
440 kfree(devpath_string); 445 kfree(devpath_string);
441 kfree(devpath); 446 kfree(devpath);
442 kobject_put(kobj); 447 kobject_put(kobj);
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index c399bc1093cb..cceecb6a963d 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -32,40 +32,48 @@
32/* Works only for digits and letters, but small and fast */ 32/* Works only for digits and letters, but small and fast */
33#define TOLOWER(x) ((x) | 0x20) 33#define TOLOWER(x) ((x) | 0x20)
34 34
35static unsigned int simple_guess_base(const char *cp)
36{
37 if (cp[0] == '0') {
38 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
39 return 16;
40 else
41 return 8;
42 } else {
43 return 10;
44 }
45}
46
35/** 47/**
36 * simple_strtoul - convert a string to an unsigned long 48 * simple_strtoul - convert a string to an unsigned long
37 * @cp: The start of the string 49 * @cp: The start of the string
38 * @endp: A pointer to the end of the parsed string will be placed here 50 * @endp: A pointer to the end of the parsed string will be placed here
39 * @base: The number base to use 51 * @base: The number base to use
40 */ 52 */
41unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) 53unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
42{ 54{
43 unsigned long result = 0,value; 55 unsigned long result = 0;
44 56
45 if (!base) { 57 if (!base)
46 base = 10; 58 base = simple_guess_base(cp);
47 if (*cp == '0') { 59
48 base = 8; 60 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
49 cp++; 61 cp += 2;
50 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 62
51 cp++; 63 while (isxdigit(*cp)) {
52 base = 16; 64 unsigned int value;
53 } 65
54 } 66 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
55 } else if (base == 16) { 67 if (value >= base)
56 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 68 break;
57 cp += 2; 69 result = result * base + value;
58 }
59 while (isxdigit(*cp) &&
60 (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
61 result = result*base + value;
62 cp++; 70 cp++;
63 } 71 }
72
64 if (endp) 73 if (endp)
65 *endp = (char *)cp; 74 *endp = (char *)cp;
66 return result; 75 return result;
67} 76}
68
69EXPORT_SYMBOL(simple_strtoul); 77EXPORT_SYMBOL(simple_strtoul);
70 78
71/** 79/**
@@ -74,13 +82,12 @@ EXPORT_SYMBOL(simple_strtoul);
74 * @endp: A pointer to the end of the parsed string will be placed here 82 * @endp: A pointer to the end of the parsed string will be placed here
75 * @base: The number base to use 83 * @base: The number base to use
76 */ 84 */
77long simple_strtol(const char *cp,char **endp,unsigned int base) 85long simple_strtol(const char *cp, char **endp, unsigned int base)
78{ 86{
79 if(*cp=='-') 87 if(*cp == '-')
80 return -simple_strtoul(cp+1,endp,base); 88 return -simple_strtoul(cp + 1, endp, base);
81 return simple_strtoul(cp,endp,base); 89 return simple_strtoul(cp, endp, base);
82} 90}
83
84EXPORT_SYMBOL(simple_strtol); 91EXPORT_SYMBOL(simple_strtol);
85 92
86/** 93/**
@@ -89,34 +96,30 @@ EXPORT_SYMBOL(simple_strtol);
89 * @endp: A pointer to the end of the parsed string will be placed here 96 * @endp: A pointer to the end of the parsed string will be placed here
90 * @base: The number base to use 97 * @base: The number base to use
91 */ 98 */
92unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) 99unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
93{ 100{
94 unsigned long long result = 0,value; 101 unsigned long long result = 0;
95 102
96 if (!base) { 103 if (!base)
97 base = 10; 104 base = simple_guess_base(cp);
98 if (*cp == '0') { 105
99 base = 8; 106 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
100 cp++; 107 cp += 2;
101 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 108
102 cp++; 109 while (isxdigit(*cp)) {
103 base = 16; 110 unsigned int value;
104 } 111
105 } 112 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
106 } else if (base == 16) { 113 if (value >= base)
107 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 114 break;
108 cp += 2; 115 result = result * base + value;
109 }
110 while (isxdigit(*cp)
111 && (value = isdigit(*cp) ? *cp-'0' : TOLOWER(*cp)-'a'+10) < base) {
112 result = result*base + value;
113 cp++; 116 cp++;
114 } 117 }
118
115 if (endp) 119 if (endp)
116 *endp = (char *)cp; 120 *endp = (char *)cp;
117 return result; 121 return result;
118} 122}
119
120EXPORT_SYMBOL(simple_strtoull); 123EXPORT_SYMBOL(simple_strtoull);
121 124
122/** 125/**
@@ -125,14 +128,13 @@ EXPORT_SYMBOL(simple_strtoull);
125 * @endp: A pointer to the end of the parsed string will be placed here 128 * @endp: A pointer to the end of the parsed string will be placed here
126 * @base: The number base to use 129 * @base: The number base to use
127 */ 130 */
128long long simple_strtoll(const char *cp,char **endp,unsigned int base) 131long long simple_strtoll(const char *cp, char **endp, unsigned int base)
129{ 132{
130 if(*cp=='-') 133 if(*cp=='-')
131 return -simple_strtoull(cp+1,endp,base); 134 return -simple_strtoull(cp + 1, endp, base);
132 return simple_strtoull(cp,endp,base); 135 return simple_strtoull(cp, endp, base);
133} 136}
134 137
135
136/** 138/**
137 * strict_strtoul - convert a string to an unsigned long strictly 139 * strict_strtoul - convert a string to an unsigned long strictly
138 * @cp: The string to be converted 140 * @cp: The string to be converted
@@ -155,7 +157,27 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
155 * simple_strtoul just ignores the successive invalid characters and 157 * simple_strtoul just ignores the successive invalid characters and
156 * return the converted value of prefix part of the string. 158 * return the converted value of prefix part of the string.
157 */ 159 */
158int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); 160int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
161{
162 char *tail;
163 unsigned long val;
164 size_t len;
165
166 *res = 0;
167 len = strlen(cp);
168 if (len == 0)
169 return -EINVAL;
170
171 val = simple_strtoul(cp, &tail, base);
172 if ((*tail == '\0') ||
173 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
174 *res = val;
175 return 0;
176 }
177
178 return -EINVAL;
179}
180EXPORT_SYMBOL(strict_strtoul);
159 181
160/** 182/**
161 * strict_strtol - convert a string to a long strictly 183 * strict_strtol - convert a string to a long strictly
@@ -169,7 +191,20 @@ int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
169 * It returns 0 if conversion is successful and *res is set to the converted 191 * It returns 0 if conversion is successful and *res is set to the converted
170 * value, otherwise it returns -EINVAL and *res is set to 0. 192 * value, otherwise it returns -EINVAL and *res is set to 0.
171 */ 193 */
172int strict_strtol(const char *cp, unsigned int base, long *res); 194int strict_strtol(const char *cp, unsigned int base, long *res)
195{
196 int ret;
197 if (*cp == '-') {
198 ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
199 if (!ret)
200 *res = -(*res);
201 } else {
202 ret = strict_strtoul(cp, base, (unsigned long *)res);
203 }
204
205 return ret;
206}
207EXPORT_SYMBOL(strict_strtol);
173 208
174/** 209/**
175 * strict_strtoull - convert a string to an unsigned long long strictly 210 * strict_strtoull - convert a string to an unsigned long long strictly
@@ -193,7 +228,27 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
193 * simple_strtoull just ignores the successive invalid characters and 228 * simple_strtoull just ignores the successive invalid characters and
194 * return the converted value of prefix part of the string. 229 * return the converted value of prefix part of the string.
195 */ 230 */
196int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res); 231int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
232{
233 char *tail;
234 unsigned long long val;
235 size_t len;
236
237 *res = 0;
238 len = strlen(cp);
239 if (len == 0)
240 return -EINVAL;
241
242 val = simple_strtoull(cp, &tail, base);
243 if ((*tail == '\0') ||
244 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
245 *res = val;
246 return 0;
247 }
248
249 return -EINVAL;
250}
251EXPORT_SYMBOL(strict_strtoull);
197 252
198/** 253/**
199 * strict_strtoll - convert a string to a long long strictly 254 * strict_strtoll - convert a string to a long long strictly
@@ -207,53 +262,20 @@ int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res);
207 * It returns 0 if conversion is successful and *res is set to the converted 262 * It returns 0 if conversion is successful and *res is set to the converted
208 * value, otherwise it returns -EINVAL and *res is set to 0. 263 * value, otherwise it returns -EINVAL and *res is set to 0.
209 */ 264 */
210int strict_strtoll(const char *cp, unsigned int base, long long *res); 265int strict_strtoll(const char *cp, unsigned int base, long long *res)
211 266{
212#define define_strict_strtoux(type, valtype) \ 267 int ret;
213int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\ 268 if (*cp == '-') {
214{ \ 269 ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
215 char *tail; \ 270 if (!ret)
216 valtype val; \ 271 *res = -(*res);
217 size_t len; \ 272 } else {
218 \ 273 ret = strict_strtoull(cp, base, (unsigned long long *)res);
219 *res = 0; \ 274 }
220 len = strlen(cp); \
221 if (len == 0) \
222 return -EINVAL; \
223 \
224 val = simple_strtou##type(cp, &tail, base); \
225 if ((*tail == '\0') || \
226 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\
227 *res = val; \
228 return 0; \
229 } \
230 \
231 return -EINVAL; \
232} \
233
234#define define_strict_strtox(type, valtype) \
235int strict_strto##type(const char *cp, unsigned int base, valtype *res) \
236{ \
237 int ret; \
238 if (*cp == '-') { \
239 ret = strict_strtou##type(cp+1, base, res); \
240 if (!ret) \
241 *res = -(*res); \
242 } else \
243 ret = strict_strtou##type(cp, base, res); \
244 \
245 return ret; \
246} \
247
248define_strict_strtoux(l, unsigned long)
249define_strict_strtox(l, long)
250define_strict_strtoux(ll, unsigned long long)
251define_strict_strtox(ll, long long)
252 275
253EXPORT_SYMBOL(strict_strtoul); 276 return ret;
254EXPORT_SYMBOL(strict_strtol); 277}
255EXPORT_SYMBOL(strict_strtoll); 278EXPORT_SYMBOL(strict_strtoll);
256EXPORT_SYMBOL(strict_strtoull);
257 279
258static int skip_atoi(const char **s) 280static int skip_atoi(const char **s)
259{ 281{
@@ -565,6 +587,10 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
565 * @fmt: The format string to use 587 * @fmt: The format string to use
566 * @args: Arguments for the format string 588 * @args: Arguments for the format string
567 * 589 *
590 * This function follows C99 vsnprintf, but has some extensions:
591 * %pS output the name of a text symbol
592 * %pF output the name of a function pointer
593 *
568 * The return value is the number of characters which would 594 * The return value is the number of characters which would
569 * be generated for the given input, excluding the trailing 595 * be generated for the given input, excluding the trailing
570 * '\0', as per ISO C99. If you want to have the exact 596 * '\0', as per ISO C99. If you want to have the exact
@@ -790,7 +816,6 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
790 /* the trailing null byte doesn't count towards the total */ 816 /* the trailing null byte doesn't count towards the total */
791 return str-buf; 817 return str-buf;
792} 818}
793
794EXPORT_SYMBOL(vsnprintf); 819EXPORT_SYMBOL(vsnprintf);
795 820
796/** 821/**
@@ -806,6 +831,8 @@ EXPORT_SYMBOL(vsnprintf);
806 * 831 *
807 * Call this function if you are already dealing with a va_list. 832 * Call this function if you are already dealing with a va_list.
808 * You probably want scnprintf() instead. 833 * You probably want scnprintf() instead.
834 *
835 * See the vsnprintf() documentation for format string extensions over C99.
809 */ 836 */
810int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) 837int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
811{ 838{
@@ -814,7 +841,6 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
814 i=vsnprintf(buf,size,fmt,args); 841 i=vsnprintf(buf,size,fmt,args);
815 return (i >= size) ? (size - 1) : i; 842 return (i >= size) ? (size - 1) : i;
816} 843}
817
818EXPORT_SYMBOL(vscnprintf); 844EXPORT_SYMBOL(vscnprintf);
819 845
820/** 846/**
@@ -828,6 +854,8 @@ EXPORT_SYMBOL(vscnprintf);
828 * generated for the given input, excluding the trailing null, 854 * generated for the given input, excluding the trailing null,
829 * as per ISO C99. If the return is greater than or equal to 855 * as per ISO C99. If the return is greater than or equal to
830 * @size, the resulting string is truncated. 856 * @size, the resulting string is truncated.
857 *
858 * See the vsnprintf() documentation for format string extensions over C99.
831 */ 859 */
832int snprintf(char * buf, size_t size, const char *fmt, ...) 860int snprintf(char * buf, size_t size, const char *fmt, ...)
833{ 861{
@@ -839,7 +867,6 @@ int snprintf(char * buf, size_t size, const char *fmt, ...)
839 va_end(args); 867 va_end(args);
840 return i; 868 return i;
841} 869}
842
843EXPORT_SYMBOL(snprintf); 870EXPORT_SYMBOL(snprintf);
844 871
845/** 872/**
@@ -877,12 +904,13 @@ EXPORT_SYMBOL(scnprintf);
877 * 904 *
878 * Call this function if you are already dealing with a va_list. 905 * Call this function if you are already dealing with a va_list.
879 * You probably want sprintf() instead. 906 * You probably want sprintf() instead.
907 *
908 * See the vsnprintf() documentation for format string extensions over C99.
880 */ 909 */
881int vsprintf(char *buf, const char *fmt, va_list args) 910int vsprintf(char *buf, const char *fmt, va_list args)
882{ 911{
883 return vsnprintf(buf, INT_MAX, fmt, args); 912 return vsnprintf(buf, INT_MAX, fmt, args);
884} 913}
885
886EXPORT_SYMBOL(vsprintf); 914EXPORT_SYMBOL(vsprintf);
887 915
888/** 916/**
@@ -894,6 +922,8 @@ EXPORT_SYMBOL(vsprintf);
894 * The function returns the number of characters written 922 * The function returns the number of characters written
895 * into @buf. Use snprintf() or scnprintf() in order to avoid 923 * into @buf. Use snprintf() or scnprintf() in order to avoid
896 * buffer overflows. 924 * buffer overflows.
925 *
926 * See the vsnprintf() documentation for format string extensions over C99.
897 */ 927 */
898int sprintf(char * buf, const char *fmt, ...) 928int sprintf(char * buf, const char *fmt, ...)
899{ 929{
@@ -905,7 +935,6 @@ int sprintf(char * buf, const char *fmt, ...)
905 va_end(args); 935 va_end(args);
906 return i; 936 return i;
907} 937}
908
909EXPORT_SYMBOL(sprintf); 938EXPORT_SYMBOL(sprintf);
910 939
911/** 940/**
@@ -1134,7 +1163,6 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
1134 1163
1135 return num; 1164 return num;
1136} 1165}
1137
1138EXPORT_SYMBOL(vsscanf); 1166EXPORT_SYMBOL(vsscanf);
1139 1167
1140/** 1168/**
@@ -1153,5 +1181,4 @@ int sscanf(const char * buf, const char * fmt, ...)
1153 va_end(args); 1181 va_end(args);
1154 return i; 1182 return i;
1155} 1183}
1156
1157EXPORT_SYMBOL(sscanf); 1184EXPORT_SYMBOL(sscanf);