aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Kconfig4
-rw-r--r--lib/Kconfig.debug60
-rw-r--r--lib/Makefile2
-rw-r--r--lib/bitmap.c11
-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.c284
8 files changed, 685 insertions, 138 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..b0f239e443bc 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -652,6 +652,11 @@ config DEBUG_BLOCK_EXT_DEVT
652 depends on BLOCK 652 depends on BLOCK
653 default n 653 default n
654 help 654 help
655 BIG FAT WARNING: ENABLING THIS OPTION MIGHT BREAK BOOTING ON
656 SOME DISTRIBUTIONS. DO NOT ENABLE THIS UNLESS YOU KNOW WHAT
657 YOU ARE DOING. Distros, please enable this and fix whatever
658 is broken.
659
655 Conventionally, block device numbers are allocated from 660 Conventionally, block device numbers are allocated from
656 predetermined contiguous area. However, extended block area 661 predetermined contiguous area. However, extended block area
657 may introduce non-contiguous block device numbers. This 662 may introduce non-contiguous block device numbers. This
@@ -807,6 +812,61 @@ menuconfig BUILD_DOCSRC
807 812
808 Say N if you are unsure. 813 Say N if you are unsure.
809 814
815config DYNAMIC_PRINTK_DEBUG
816 bool "Enable dynamic printk() call support"
817 default n
818 depends on PRINTK
819 select PRINTK_DEBUG
820 help
821
822 Compiles debug level messages into the kernel, which would not
823 otherwise be available at runtime. These messages can then be
824 enabled/disabled on a per module basis. This mechanism implicitly
825 enables all pr_debug() and dev_dbg() calls. The impact of this
826 compile option is a larger kernel text size of about 2%.
827
828 Usage:
829
830 Dynamic debugging is controlled by the debugfs file,
831 dynamic_printk/modules. This file contains a list of the modules that
832 can be enabled. The format of the file is the module name, followed
833 by a set of flags that can be enabled. The first flag is always the
834 'enabled' flag. For example:
835
836 <module_name> <enabled=0/1>
837 .
838 .
839 .
840
841 <module_name> : Name of the module in which the debug call resides
842 <enabled=0/1> : whether the messages are enabled or not
843
844 From a live system:
845
846 snd_hda_intel enabled=0
847 fixup enabled=0
848 driver enabled=0
849
850 Enable a module:
851
852 $echo "set enabled=1 <module_name>" > dynamic_printk/modules
853
854 Disable a module:
855
856 $echo "set enabled=0 <module_name>" > dynamic_printk/modules
857
858 Enable all modules:
859
860 $echo "set enabled=1 all" > dynamic_printk/modules
861
862 Disable all modules:
863
864 $echo "set enabled=0 all" > dynamic_printk/modules
865
866 Finally, passing "dynamic_printk" at the command line enables
867 debugging for all modules. This mode can be turned off via the above
868 disable command.
869
810source "samples/Kconfig" 870source "samples/Kconfig"
811 871
812source "lib/Kconfig.kgdb" 872source "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/bitmap.c b/lib/bitmap.c
index 06fb57c86de0..482df94ea21e 100644
--- a/lib/bitmap.c
+++ b/lib/bitmap.c
@@ -316,17 +316,6 @@ int bitmap_scnprintf(char *buf, unsigned int buflen,
316EXPORT_SYMBOL(bitmap_scnprintf); 316EXPORT_SYMBOL(bitmap_scnprintf);
317 317
318/** 318/**
319 * bitmap_scnprintf_len - return buffer length needed to convert
320 * bitmap to an ASCII hex string
321 * @nr_bits: number of bits to be converted
322 */
323int bitmap_scnprintf_len(unsigned int nr_bits)
324{
325 unsigned int nr_nibbles = ALIGN(nr_bits, 4) / 4;
326 return nr_nibbles + ALIGN(nr_nibbles, CHUNKSZ / 4) / (CHUNKSZ / 4) - 1;
327}
328
329/**
330 * __bitmap_parse - convert an ASCII hex string into a bitmap. 319 * __bitmap_parse - convert an ASCII hex string into a bitmap.
331 * @buf: pointer to buffer containing string. 320 * @buf: pointer to buffer containing string.
332 * @buflen: buffer size in bytes. If string is smaller than this 321 * @buflen: buffer size in bytes. If string is smaller than this
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..a013bbc23717 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/kallsyms.h> 25#include <linux/kallsyms.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/ioport.h>
27 28
28#include <asm/page.h> /* for PAGE_SIZE */ 29#include <asm/page.h> /* for PAGE_SIZE */
29#include <asm/div64.h> 30#include <asm/div64.h>
@@ -32,40 +33,48 @@
32/* Works only for digits and letters, but small and fast */ 33/* Works only for digits and letters, but small and fast */
33#define TOLOWER(x) ((x) | 0x20) 34#define TOLOWER(x) ((x) | 0x20)
34 35
36static unsigned int simple_guess_base(const char *cp)
37{
38 if (cp[0] == '0') {
39 if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
40 return 16;
41 else
42 return 8;
43 } else {
44 return 10;
45 }
46}
47
35/** 48/**
36 * simple_strtoul - convert a string to an unsigned long 49 * simple_strtoul - convert a string to an unsigned long
37 * @cp: The start of the string 50 * @cp: The start of the string
38 * @endp: A pointer to the end of the parsed string will be placed here 51 * @endp: A pointer to the end of the parsed string will be placed here
39 * @base: The number base to use 52 * @base: The number base to use
40 */ 53 */
41unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) 54unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
42{ 55{
43 unsigned long result = 0,value; 56 unsigned long result = 0;
44 57
45 if (!base) { 58 if (!base)
46 base = 10; 59 base = simple_guess_base(cp);
47 if (*cp == '0') { 60
48 base = 8; 61 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
49 cp++; 62 cp += 2;
50 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 63
51 cp++; 64 while (isxdigit(*cp)) {
52 base = 16; 65 unsigned int value;
53 } 66
54 } 67 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
55 } else if (base == 16) { 68 if (value >= base)
56 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 69 break;
57 cp += 2; 70 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++; 71 cp++;
63 } 72 }
73
64 if (endp) 74 if (endp)
65 *endp = (char *)cp; 75 *endp = (char *)cp;
66 return result; 76 return result;
67} 77}
68
69EXPORT_SYMBOL(simple_strtoul); 78EXPORT_SYMBOL(simple_strtoul);
70 79
71/** 80/**
@@ -74,13 +83,12 @@ EXPORT_SYMBOL(simple_strtoul);
74 * @endp: A pointer to the end of the parsed string will be placed here 83 * @endp: A pointer to the end of the parsed string will be placed here
75 * @base: The number base to use 84 * @base: The number base to use
76 */ 85 */
77long simple_strtol(const char *cp,char **endp,unsigned int base) 86long simple_strtol(const char *cp, char **endp, unsigned int base)
78{ 87{
79 if(*cp=='-') 88 if(*cp == '-')
80 return -simple_strtoul(cp+1,endp,base); 89 return -simple_strtoul(cp + 1, endp, base);
81 return simple_strtoul(cp,endp,base); 90 return simple_strtoul(cp, endp, base);
82} 91}
83
84EXPORT_SYMBOL(simple_strtol); 92EXPORT_SYMBOL(simple_strtol);
85 93
86/** 94/**
@@ -89,34 +97,30 @@ EXPORT_SYMBOL(simple_strtol);
89 * @endp: A pointer to the end of the parsed string will be placed here 97 * @endp: A pointer to the end of the parsed string will be placed here
90 * @base: The number base to use 98 * @base: The number base to use
91 */ 99 */
92unsigned long long simple_strtoull(const char *cp,char **endp,unsigned int base) 100unsigned long long simple_strtoull(const char *cp, char **endp, unsigned int base)
93{ 101{
94 unsigned long long result = 0,value; 102 unsigned long long result = 0;
95 103
96 if (!base) { 104 if (!base)
97 base = 10; 105 base = simple_guess_base(cp);
98 if (*cp == '0') { 106
99 base = 8; 107 if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
100 cp++; 108 cp += 2;
101 if ((TOLOWER(*cp) == 'x') && isxdigit(cp[1])) { 109
102 cp++; 110 while (isxdigit(*cp)) {
103 base = 16; 111 unsigned int value;
104 } 112
105 } 113 value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
106 } else if (base == 16) { 114 if (value >= base)
107 if (cp[0] == '0' && TOLOWER(cp[1]) == 'x') 115 break;
108 cp += 2; 116 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++; 117 cp++;
114 } 118 }
119
115 if (endp) 120 if (endp)
116 *endp = (char *)cp; 121 *endp = (char *)cp;
117 return result; 122 return result;
118} 123}
119
120EXPORT_SYMBOL(simple_strtoull); 124EXPORT_SYMBOL(simple_strtoull);
121 125
122/** 126/**
@@ -125,14 +129,13 @@ EXPORT_SYMBOL(simple_strtoull);
125 * @endp: A pointer to the end of the parsed string will be placed here 129 * @endp: A pointer to the end of the parsed string will be placed here
126 * @base: The number base to use 130 * @base: The number base to use
127 */ 131 */
128long long simple_strtoll(const char *cp,char **endp,unsigned int base) 132long long simple_strtoll(const char *cp, char **endp, unsigned int base)
129{ 133{
130 if(*cp=='-') 134 if(*cp=='-')
131 return -simple_strtoull(cp+1,endp,base); 135 return -simple_strtoull(cp + 1, endp, base);
132 return simple_strtoull(cp,endp,base); 136 return simple_strtoull(cp, endp, base);
133} 137}
134 138
135
136/** 139/**
137 * strict_strtoul - convert a string to an unsigned long strictly 140 * strict_strtoul - convert a string to an unsigned long strictly
138 * @cp: The string to be converted 141 * @cp: The string to be converted
@@ -155,7 +158,27 @@ long long simple_strtoll(const char *cp,char **endp,unsigned int base)
155 * simple_strtoul just ignores the successive invalid characters and 158 * simple_strtoul just ignores the successive invalid characters and
156 * return the converted value of prefix part of the string. 159 * return the converted value of prefix part of the string.
157 */ 160 */
158int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); 161int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
162{
163 char *tail;
164 unsigned long val;
165 size_t len;
166
167 *res = 0;
168 len = strlen(cp);
169 if (len == 0)
170 return -EINVAL;
171
172 val = simple_strtoul(cp, &tail, base);
173 if ((*tail == '\0') ||
174 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
175 *res = val;
176 return 0;
177 }
178
179 return -EINVAL;
180}
181EXPORT_SYMBOL(strict_strtoul);
159 182
160/** 183/**
161 * strict_strtol - convert a string to a long strictly 184 * strict_strtol - convert a string to a long strictly
@@ -169,7 +192,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 192 * 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. 193 * value, otherwise it returns -EINVAL and *res is set to 0.
171 */ 194 */
172int strict_strtol(const char *cp, unsigned int base, long *res); 195int strict_strtol(const char *cp, unsigned int base, long *res)
196{
197 int ret;
198 if (*cp == '-') {
199 ret = strict_strtoul(cp + 1, base, (unsigned long *)res);
200 if (!ret)
201 *res = -(*res);
202 } else {
203 ret = strict_strtoul(cp, base, (unsigned long *)res);
204 }
205
206 return ret;
207}
208EXPORT_SYMBOL(strict_strtol);
173 209
174/** 210/**
175 * strict_strtoull - convert a string to an unsigned long long strictly 211 * strict_strtoull - convert a string to an unsigned long long strictly
@@ -193,7 +229,27 @@ int strict_strtol(const char *cp, unsigned int base, long *res);
193 * simple_strtoull just ignores the successive invalid characters and 229 * simple_strtoull just ignores the successive invalid characters and
194 * return the converted value of prefix part of the string. 230 * return the converted value of prefix part of the string.
195 */ 231 */
196int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res); 232int strict_strtoull(const char *cp, unsigned int base, unsigned long long *res)
233{
234 char *tail;
235 unsigned long long val;
236 size_t len;
237
238 *res = 0;
239 len = strlen(cp);
240 if (len == 0)
241 return -EINVAL;
242
243 val = simple_strtoull(cp, &tail, base);
244 if ((*tail == '\0') ||
245 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
246 *res = val;
247 return 0;
248 }
249
250 return -EINVAL;
251}
252EXPORT_SYMBOL(strict_strtoull);
197 253
198/** 254/**
199 * strict_strtoll - convert a string to a long long strictly 255 * strict_strtoll - convert a string to a long long strictly
@@ -207,53 +263,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 263 * 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. 264 * value, otherwise it returns -EINVAL and *res is set to 0.
209 */ 265 */
210int strict_strtoll(const char *cp, unsigned int base, long long *res); 266int strict_strtoll(const char *cp, unsigned int base, long long *res)
211 267{
212#define define_strict_strtoux(type, valtype) \ 268 int ret;
213int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\ 269 if (*cp == '-') {
214{ \ 270 ret = strict_strtoull(cp + 1, base, (unsigned long long *)res);
215 char *tail; \ 271 if (!ret)
216 valtype val; \ 272 *res = -(*res);
217 size_t len; \ 273 } else {
218 \ 274 ret = strict_strtoull(cp, base, (unsigned long long *)res);
219 *res = 0; \ 275 }
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 276
253EXPORT_SYMBOL(strict_strtoul); 277 return ret;
254EXPORT_SYMBOL(strict_strtol); 278}
255EXPORT_SYMBOL(strict_strtoll); 279EXPORT_SYMBOL(strict_strtoll);
256EXPORT_SYMBOL(strict_strtoull);
257 280
258static int skip_atoi(const char **s) 281static int skip_atoi(const char **s)
259{ 282{
@@ -528,18 +551,51 @@ static char *symbol_string(char *buf, char *end, void *ptr, int field_width, int
528#endif 551#endif
529} 552}
530 553
554static char *resource_string(char *buf, char *end, struct resource *res, int field_width, int precision, int flags)
555{
556#ifndef IO_RSRC_PRINTK_SIZE
557#define IO_RSRC_PRINTK_SIZE 4
558#endif
559
560#ifndef MEM_RSRC_PRINTK_SIZE
561#define MEM_RSRC_PRINTK_SIZE 8
562#endif
563
564 /* room for the actual numbers, the two "0x", -, [, ] and the final zero */
565 char sym[4*sizeof(resource_size_t) + 8];
566 char *p = sym, *pend = sym + sizeof(sym);
567 int size = -1;
568
569 if (res->flags & IORESOURCE_IO)
570 size = IO_RSRC_PRINTK_SIZE;
571 else if (res->flags & IORESOURCE_MEM)
572 size = MEM_RSRC_PRINTK_SIZE;
573
574 *p++ = '[';
575 p = number(p, pend, res->start, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
576 *p++ = '-';
577 p = number(p, pend, res->end, 16, size, -1, SPECIAL | SMALL | ZEROPAD);
578 *p++ = ']';
579 *p = 0;
580
581 return string(buf, end, sym, field_width, precision, flags);
582}
583
531/* 584/*
532 * Show a '%p' thing. A kernel extension is that the '%p' is followed 585 * Show a '%p' thing. A kernel extension is that the '%p' is followed
533 * by an extra set of alphanumeric characters that are extended format 586 * by an extra set of alphanumeric characters that are extended format
534 * specifiers. 587 * specifiers.
535 * 588 *
536 * Right now we just handle 'F' (for symbolic Function descriptor pointers) 589 * Right now we handle:
537 * and 'S' (for Symbolic direct pointers), but this can easily be 590 *
538 * extended in the future (network address types etc). 591 * - 'F' For symbolic function descriptor pointers
592 * - 'S' For symbolic direct pointers
593 * - 'R' For a struct resource pointer, it prints the range of
594 * addresses (not the name nor the flags)
539 * 595 *
540 * The difference between 'S' and 'F' is that on ia64 and ppc64 function 596 * Note: The difference between 'S' and 'F' is that on ia64 and ppc64
541 * pointers are really function descriptors, which contain a pointer the 597 * function pointers are really function descriptors, which contain a
542 * real address. 598 * pointer to the real address.
543 */ 599 */
544static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags) 600static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field_width, int precision, int flags)
545{ 601{
@@ -549,6 +605,8 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
549 /* Fallthrough */ 605 /* Fallthrough */
550 case 'S': 606 case 'S':
551 return symbol_string(buf, end, ptr, field_width, precision, flags); 607 return symbol_string(buf, end, ptr, field_width, precision, flags);
608 case 'R':
609 return resource_string(buf, end, ptr, field_width, precision, flags);
552 } 610 }
553 flags |= SMALL; 611 flags |= SMALL;
554 if (field_width == -1) { 612 if (field_width == -1) {
@@ -565,6 +623,11 @@ static char *pointer(const char *fmt, char *buf, char *end, void *ptr, int field
565 * @fmt: The format string to use 623 * @fmt: The format string to use
566 * @args: Arguments for the format string 624 * @args: Arguments for the format string
567 * 625 *
626 * This function follows C99 vsnprintf, but has some extensions:
627 * %pS output the name of a text symbol
628 * %pF output the name of a function pointer
629 * %pR output the address range in a struct resource
630 *
568 * The return value is the number of characters which would 631 * The return value is the number of characters which would
569 * be generated for the given input, excluding the trailing 632 * be generated for the given input, excluding the trailing
570 * '\0', as per ISO C99. If you want to have the exact 633 * '\0', as per ISO C99. If you want to have the exact
@@ -790,7 +853,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 */ 853 /* the trailing null byte doesn't count towards the total */
791 return str-buf; 854 return str-buf;
792} 855}
793
794EXPORT_SYMBOL(vsnprintf); 856EXPORT_SYMBOL(vsnprintf);
795 857
796/** 858/**
@@ -806,6 +868,8 @@ EXPORT_SYMBOL(vsnprintf);
806 * 868 *
807 * Call this function if you are already dealing with a va_list. 869 * Call this function if you are already dealing with a va_list.
808 * You probably want scnprintf() instead. 870 * You probably want scnprintf() instead.
871 *
872 * See the vsnprintf() documentation for format string extensions over C99.
809 */ 873 */
810int vscnprintf(char *buf, size_t size, const char *fmt, va_list args) 874int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
811{ 875{
@@ -814,7 +878,6 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
814 i=vsnprintf(buf,size,fmt,args); 878 i=vsnprintf(buf,size,fmt,args);
815 return (i >= size) ? (size - 1) : i; 879 return (i >= size) ? (size - 1) : i;
816} 880}
817
818EXPORT_SYMBOL(vscnprintf); 881EXPORT_SYMBOL(vscnprintf);
819 882
820/** 883/**
@@ -828,6 +891,8 @@ EXPORT_SYMBOL(vscnprintf);
828 * generated for the given input, excluding the trailing null, 891 * generated for the given input, excluding the trailing null,
829 * as per ISO C99. If the return is greater than or equal to 892 * as per ISO C99. If the return is greater than or equal to
830 * @size, the resulting string is truncated. 893 * @size, the resulting string is truncated.
894 *
895 * See the vsnprintf() documentation for format string extensions over C99.
831 */ 896 */
832int snprintf(char * buf, size_t size, const char *fmt, ...) 897int snprintf(char * buf, size_t size, const char *fmt, ...)
833{ 898{
@@ -839,7 +904,6 @@ int snprintf(char * buf, size_t size, const char *fmt, ...)
839 va_end(args); 904 va_end(args);
840 return i; 905 return i;
841} 906}
842
843EXPORT_SYMBOL(snprintf); 907EXPORT_SYMBOL(snprintf);
844 908
845/** 909/**
@@ -877,12 +941,13 @@ EXPORT_SYMBOL(scnprintf);
877 * 941 *
878 * Call this function if you are already dealing with a va_list. 942 * Call this function if you are already dealing with a va_list.
879 * You probably want sprintf() instead. 943 * You probably want sprintf() instead.
944 *
945 * See the vsnprintf() documentation for format string extensions over C99.
880 */ 946 */
881int vsprintf(char *buf, const char *fmt, va_list args) 947int vsprintf(char *buf, const char *fmt, va_list args)
882{ 948{
883 return vsnprintf(buf, INT_MAX, fmt, args); 949 return vsnprintf(buf, INT_MAX, fmt, args);
884} 950}
885
886EXPORT_SYMBOL(vsprintf); 951EXPORT_SYMBOL(vsprintf);
887 952
888/** 953/**
@@ -894,6 +959,8 @@ EXPORT_SYMBOL(vsprintf);
894 * The function returns the number of characters written 959 * The function returns the number of characters written
895 * into @buf. Use snprintf() or scnprintf() in order to avoid 960 * into @buf. Use snprintf() or scnprintf() in order to avoid
896 * buffer overflows. 961 * buffer overflows.
962 *
963 * See the vsnprintf() documentation for format string extensions over C99.
897 */ 964 */
898int sprintf(char * buf, const char *fmt, ...) 965int sprintf(char * buf, const char *fmt, ...)
899{ 966{
@@ -905,7 +972,6 @@ int sprintf(char * buf, const char *fmt, ...)
905 va_end(args); 972 va_end(args);
906 return i; 973 return i;
907} 974}
908
909EXPORT_SYMBOL(sprintf); 975EXPORT_SYMBOL(sprintf);
910 976
911/** 977/**
@@ -1134,7 +1200,6 @@ int vsscanf(const char * buf, const char * fmt, va_list args)
1134 1200
1135 return num; 1201 return num;
1136} 1202}
1137
1138EXPORT_SYMBOL(vsscanf); 1203EXPORT_SYMBOL(vsscanf);
1139 1204
1140/** 1205/**
@@ -1153,5 +1218,4 @@ int sscanf(const char * buf, const char * fmt, ...)
1153 va_end(args); 1218 va_end(args);
1154 return i; 1219 return i;
1155} 1220}
1156
1157EXPORT_SYMBOL(sscanf); 1221EXPORT_SYMBOL(sscanf);