diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 15:05:51 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-21 15:05:51 -0500 |
commit | 06991c28f37ad68e5c03777f5c3b679b56e3dac1 (patch) | |
tree | 4be75788e21c3c644fe6d39abf47693a171cf4f8 /lib | |
parent | 460dc1eecf37263c8e3b17685ef236f0d236facb (diff) | |
parent | 74fef7a8fd1d2bd94f925d6638bb4c3049e7c381 (diff) |
Merge tag 'driver-core-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core patches from Greg Kroah-Hartman:
"Here is the big driver core merge for 3.9-rc1
There are two major series here, both of which touch lots of drivers
all over the kernel, and will cause you some merge conflicts:
- add a new function called devm_ioremap_resource() to properly be
able to check return values.
- remove CONFIG_EXPERIMENTAL
Other than those patches, there's not much here, some minor fixes and
updates"
Fix up trivial conflicts
* tag 'driver-core-3.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: (221 commits)
base: memory: fix soft/hard_offline_page permissions
drivercore: Fix ordering between deferred_probe and exiting initcalls
backlight: fix class_find_device() arguments
TTY: mark tty_get_device call with the proper const values
driver-core: constify data for class_find_device()
firmware: Ignore abort check when no user-helper is used
firmware: Reduce ifdef CONFIG_FW_LOADER_USER_HELPER
firmware: Make user-mode helper optional
firmware: Refactoring for splitting user-mode helper code
Driver core: treat unregistered bus_types as having no devices
watchdog: Convert to devm_ioremap_resource()
thermal: Convert to devm_ioremap_resource()
spi: Convert to devm_ioremap_resource()
power: Convert to devm_ioremap_resource()
mtd: Convert to devm_ioremap_resource()
mmc: Convert to devm_ioremap_resource()
mfd: Convert to devm_ioremap_resource()
media: Convert to devm_ioremap_resource()
iommu: Convert to devm_ioremap_resource()
drm: Convert to devm_ioremap_resource()
...
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Kconfig | 2 | ||||
-rw-r--r-- | lib/Kconfig.debug | 2 | ||||
-rw-r--r-- | lib/Kconfig.kgdb | 2 | ||||
-rw-r--r-- | lib/devres.c | 58 | ||||
-rw-r--r-- | lib/dynamic_debug.c | 165 | ||||
-rw-r--r-- | lib/hexdump.c | 4 |
6 files changed, 148 insertions, 85 deletions
diff --git a/lib/Kconfig b/lib/Kconfig index 75cdb77fa49d..3958dc4389f9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig | |||
@@ -322,7 +322,7 @@ config CPUMASK_OFFSTACK | |||
322 | 322 | ||
323 | config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS | 323 | config DISABLE_OBSOLETE_CPUMASK_FUNCTIONS |
324 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS | 324 | bool "Disable obsolete cpumask functions" if DEBUG_PER_CPU_MAPS |
325 | depends on EXPERIMENTAL && BROKEN | 325 | depends on BROKEN |
326 | 326 | ||
327 | config CPU_RMAP | 327 | config CPU_RMAP |
328 | bool | 328 | bool |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index a1714c897e3f..bb8d9b136cf9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -455,7 +455,7 @@ config HAVE_DEBUG_KMEMLEAK | |||
455 | 455 | ||
456 | config DEBUG_KMEMLEAK | 456 | config DEBUG_KMEMLEAK |
457 | bool "Kernel memory leak detector" | 457 | bool "Kernel memory leak detector" |
458 | depends on DEBUG_KERNEL && EXPERIMENTAL && HAVE_DEBUG_KMEMLEAK | 458 | depends on DEBUG_KERNEL && HAVE_DEBUG_KMEMLEAK |
459 | select DEBUG_FS | 459 | select DEBUG_FS |
460 | select STACKTRACE if STACKTRACE_SUPPORT | 460 | select STACKTRACE if STACKTRACE_SUPPORT |
461 | select KALLSYMS | 461 | select KALLSYMS |
diff --git a/lib/Kconfig.kgdb b/lib/Kconfig.kgdb index 43cb93fa2651..77439eb8528d 100644 --- a/lib/Kconfig.kgdb +++ b/lib/Kconfig.kgdb | |||
@@ -5,7 +5,7 @@ config HAVE_ARCH_KGDB | |||
5 | menuconfig KGDB | 5 | menuconfig KGDB |
6 | bool "KGDB: kernel debugger" | 6 | bool "KGDB: kernel debugger" |
7 | depends on HAVE_ARCH_KGDB | 7 | depends on HAVE_ARCH_KGDB |
8 | depends on DEBUG_KERNEL && EXPERIMENTAL | 8 | depends on DEBUG_KERNEL |
9 | help | 9 | help |
10 | If you say Y here, it will be possible to remotely debug the | 10 | If you say Y here, it will be possible to remotely debug the |
11 | kernel using gdb. It is recommended but not required, that | 11 | kernel using gdb. It is recommended but not required, that |
diff --git a/lib/devres.c b/lib/devres.c index 80b9c76d436a..88ad75952a76 100644 --- a/lib/devres.c +++ b/lib/devres.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/err.h> | ||
1 | #include <linux/pci.h> | 2 | #include <linux/pci.h> |
2 | #include <linux/io.h> | 3 | #include <linux/io.h> |
3 | #include <linux/gfp.h> | 4 | #include <linux/gfp.h> |
@@ -86,22 +87,24 @@ void devm_iounmap(struct device *dev, void __iomem *addr) | |||
86 | EXPORT_SYMBOL(devm_iounmap); | 87 | EXPORT_SYMBOL(devm_iounmap); |
87 | 88 | ||
88 | /** | 89 | /** |
89 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | 90 | * devm_ioremap_resource() - check, request region, and ioremap resource |
90 | * @dev: Generic device to handle the resource for | 91 | * @dev: generic device to handle the resource for |
91 | * @res: resource to be handled | 92 | * @res: resource to be handled |
92 | * | 93 | * |
93 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | 94 | * Checks that a resource is a valid memory region, requests the memory region |
94 | * everything is undone on driver detach. Checks arguments, so you can feed | 95 | * and ioremaps it either as cacheable or as non-cacheable memory depending on |
95 | * it the result from e.g. platform_get_resource() directly. Returns the | 96 | * the resource's flags. All operations are managed and will be undone on |
96 | * remapped pointer or NULL on error. Usage example: | 97 | * driver detach. |
98 | * | ||
99 | * Returns a pointer to the remapped memory or an ERR_PTR() encoded error code | ||
100 | * on failure. Usage example: | ||
97 | * | 101 | * |
98 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 102 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
99 | * base = devm_request_and_ioremap(&pdev->dev, res); | 103 | * base = devm_ioremap_resource(&pdev->dev, res); |
100 | * if (!base) | 104 | * if (IS_ERR(base)) |
101 | * return -EADDRNOTAVAIL; | 105 | * return PTR_ERR(base); |
102 | */ | 106 | */ |
103 | void __iomem *devm_request_and_ioremap(struct device *dev, | 107 | void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res) |
104 | struct resource *res) | ||
105 | { | 108 | { |
106 | resource_size_t size; | 109 | resource_size_t size; |
107 | const char *name; | 110 | const char *name; |
@@ -111,7 +114,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
111 | 114 | ||
112 | if (!res || resource_type(res) != IORESOURCE_MEM) { | 115 | if (!res || resource_type(res) != IORESOURCE_MEM) { |
113 | dev_err(dev, "invalid resource\n"); | 116 | dev_err(dev, "invalid resource\n"); |
114 | return NULL; | 117 | return ERR_PTR(-EINVAL); |
115 | } | 118 | } |
116 | 119 | ||
117 | size = resource_size(res); | 120 | size = resource_size(res); |
@@ -119,7 +122,7 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
119 | 122 | ||
120 | if (!devm_request_mem_region(dev, res->start, size, name)) { | 123 | if (!devm_request_mem_region(dev, res->start, size, name)) { |
121 | dev_err(dev, "can't request region for resource %pR\n", res); | 124 | dev_err(dev, "can't request region for resource %pR\n", res); |
122 | return NULL; | 125 | return ERR_PTR(-EBUSY); |
123 | } | 126 | } |
124 | 127 | ||
125 | if (res->flags & IORESOURCE_CACHEABLE) | 128 | if (res->flags & IORESOURCE_CACHEABLE) |
@@ -130,10 +133,39 @@ void __iomem *devm_request_and_ioremap(struct device *dev, | |||
130 | if (!dest_ptr) { | 133 | if (!dest_ptr) { |
131 | dev_err(dev, "ioremap failed for resource %pR\n", res); | 134 | dev_err(dev, "ioremap failed for resource %pR\n", res); |
132 | devm_release_mem_region(dev, res->start, size); | 135 | devm_release_mem_region(dev, res->start, size); |
136 | dest_ptr = ERR_PTR(-ENOMEM); | ||
133 | } | 137 | } |
134 | 138 | ||
135 | return dest_ptr; | 139 | return dest_ptr; |
136 | } | 140 | } |
141 | EXPORT_SYMBOL(devm_ioremap_resource); | ||
142 | |||
143 | /** | ||
144 | * devm_request_and_ioremap() - Check, request region, and ioremap resource | ||
145 | * @dev: Generic device to handle the resource for | ||
146 | * @res: resource to be handled | ||
147 | * | ||
148 | * Takes all necessary steps to ioremap a mem resource. Uses managed device, so | ||
149 | * everything is undone on driver detach. Checks arguments, so you can feed | ||
150 | * it the result from e.g. platform_get_resource() directly. Returns the | ||
151 | * remapped pointer or NULL on error. Usage example: | ||
152 | * | ||
153 | * res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
154 | * base = devm_request_and_ioremap(&pdev->dev, res); | ||
155 | * if (!base) | ||
156 | * return -EADDRNOTAVAIL; | ||
157 | */ | ||
158 | void __iomem *devm_request_and_ioremap(struct device *device, | ||
159 | struct resource *res) | ||
160 | { | ||
161 | void __iomem *dest_ptr; | ||
162 | |||
163 | dest_ptr = devm_ioremap_resource(device, res); | ||
164 | if (IS_ERR(dest_ptr)) | ||
165 | return NULL; | ||
166 | |||
167 | return dest_ptr; | ||
168 | } | ||
137 | EXPORT_SYMBOL(devm_request_and_ioremap); | 169 | EXPORT_SYMBOL(devm_request_and_ioremap); |
138 | 170 | ||
139 | #ifdef CONFIG_HAS_IOPORT | 171 | #ifdef CONFIG_HAS_IOPORT |
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 1db1fc660538..5276b99ca650 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -59,7 +59,7 @@ struct ddebug_iter { | |||
59 | 59 | ||
60 | static DEFINE_MUTEX(ddebug_lock); | 60 | static DEFINE_MUTEX(ddebug_lock); |
61 | static LIST_HEAD(ddebug_tables); | 61 | static LIST_HEAD(ddebug_tables); |
62 | static int verbose = 0; | 62 | static int verbose; |
63 | module_param(verbose, int, 0644); | 63 | module_param(verbose, int, 0644); |
64 | 64 | ||
65 | /* Return the path relative to source root */ | 65 | /* Return the path relative to source root */ |
@@ -100,24 +100,32 @@ static char *ddebug_describe_flags(struct _ddebug *dp, char *buf, | |||
100 | return buf; | 100 | return buf; |
101 | } | 101 | } |
102 | 102 | ||
103 | #define vpr_info(fmt, ...) \ | 103 | #define vpr_info(fmt, ...) \ |
104 | if (verbose) do { pr_info(fmt, ##__VA_ARGS__); } while (0) | ||
105 | |||
106 | #define vpr_info_dq(q, msg) \ | ||
107 | do { \ | 104 | do { \ |
108 | /* trim last char off format print */ \ | 105 | if (verbose) \ |
109 | vpr_info("%s: func=\"%s\" file=\"%s\" " \ | 106 | pr_info(fmt, ##__VA_ARGS__); \ |
110 | "module=\"%s\" format=\"%.*s\" " \ | ||
111 | "lineno=%u-%u", \ | ||
112 | msg, \ | ||
113 | q->function ? q->function : "", \ | ||
114 | q->filename ? q->filename : "", \ | ||
115 | q->module ? q->module : "", \ | ||
116 | (int)(q->format ? strlen(q->format) - 1 : 0), \ | ||
117 | q->format ? q->format : "", \ | ||
118 | q->first_lineno, q->last_lineno); \ | ||
119 | } while (0) | 107 | } while (0) |
120 | 108 | ||
109 | static void vpr_info_dq(const struct ddebug_query *query, const char *msg) | ||
110 | { | ||
111 | /* trim any trailing newlines */ | ||
112 | int fmtlen = 0; | ||
113 | |||
114 | if (query->format) { | ||
115 | fmtlen = strlen(query->format); | ||
116 | while (fmtlen && query->format[fmtlen - 1] == '\n') | ||
117 | fmtlen--; | ||
118 | } | ||
119 | |||
120 | vpr_info("%s: func=\"%s\" file=\"%s\" module=\"%s\" format=\"%.*s\" lineno=%u-%u\n", | ||
121 | msg, | ||
122 | query->function ? query->function : "", | ||
123 | query->filename ? query->filename : "", | ||
124 | query->module ? query->module : "", | ||
125 | fmtlen, query->format ? query->format : "", | ||
126 | query->first_lineno, query->last_lineno); | ||
127 | } | ||
128 | |||
121 | /* | 129 | /* |
122 | * Search the tables for _ddebug's which match the given `query' and | 130 | * Search the tables for _ddebug's which match the given `query' and |
123 | * apply the `flags' and `mask' to them. Returns number of matching | 131 | * apply the `flags' and `mask' to them. Returns number of matching |
@@ -141,7 +149,7 @@ static int ddebug_change(const struct ddebug_query *query, | |||
141 | if (query->module && strcmp(query->module, dt->mod_name)) | 149 | if (query->module && strcmp(query->module, dt->mod_name)) |
142 | continue; | 150 | continue; |
143 | 151 | ||
144 | for (i = 0 ; i < dt->num_ddebugs ; i++) { | 152 | for (i = 0; i < dt->num_ddebugs; i++) { |
145 | struct _ddebug *dp = &dt->ddebugs[i]; | 153 | struct _ddebug *dp = &dt->ddebugs[i]; |
146 | 154 | ||
147 | /* match against the source filename */ | 155 | /* match against the source filename */ |
@@ -176,10 +184,10 @@ static int ddebug_change(const struct ddebug_query *query, | |||
176 | continue; | 184 | continue; |
177 | dp->flags = newflags; | 185 | dp->flags = newflags; |
178 | vpr_info("changed %s:%d [%s]%s =%s\n", | 186 | vpr_info("changed %s:%d [%s]%s =%s\n", |
179 | trim_prefix(dp->filename), dp->lineno, | 187 | trim_prefix(dp->filename), dp->lineno, |
180 | dt->mod_name, dp->function, | 188 | dt->mod_name, dp->function, |
181 | ddebug_describe_flags(dp, flagbuf, | 189 | ddebug_describe_flags(dp, flagbuf, |
182 | sizeof(flagbuf))); | 190 | sizeof(flagbuf))); |
183 | } | 191 | } |
184 | } | 192 | } |
185 | mutex_unlock(&ddebug_lock); | 193 | mutex_unlock(&ddebug_lock); |
@@ -213,19 +221,23 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) | |||
213 | /* find `end' of word, whitespace separated or quoted */ | 221 | /* find `end' of word, whitespace separated or quoted */ |
214 | if (*buf == '"' || *buf == '\'') { | 222 | if (*buf == '"' || *buf == '\'') { |
215 | int quote = *buf++; | 223 | int quote = *buf++; |
216 | for (end = buf ; *end && *end != quote ; end++) | 224 | for (end = buf; *end && *end != quote; end++) |
217 | ; | 225 | ; |
218 | if (!*end) | 226 | if (!*end) { |
227 | pr_err("unclosed quote: %s\n", buf); | ||
219 | return -EINVAL; /* unclosed quote */ | 228 | return -EINVAL; /* unclosed quote */ |
229 | } | ||
220 | } else { | 230 | } else { |
221 | for (end = buf ; *end && !isspace(*end) ; end++) | 231 | for (end = buf; *end && !isspace(*end); end++) |
222 | ; | 232 | ; |
223 | BUG_ON(end == buf); | 233 | BUG_ON(end == buf); |
224 | } | 234 | } |
225 | 235 | ||
226 | /* `buf' is start of word, `end' is one past its end */ | 236 | /* `buf' is start of word, `end' is one past its end */ |
227 | if (nwords == maxwords) | 237 | if (nwords == maxwords) { |
238 | pr_err("too many words, legal max <=%d\n", maxwords); | ||
228 | return -EINVAL; /* ran out of words[] before bytes */ | 239 | return -EINVAL; /* ran out of words[] before bytes */ |
240 | } | ||
229 | if (*end) | 241 | if (*end) |
230 | *end++ = '\0'; /* terminate the word */ | 242 | *end++ = '\0'; /* terminate the word */ |
231 | words[nwords++] = buf; | 243 | words[nwords++] = buf; |
@@ -235,7 +247,7 @@ static int ddebug_tokenize(char *buf, char *words[], int maxwords) | |||
235 | if (verbose) { | 247 | if (verbose) { |
236 | int i; | 248 | int i; |
237 | pr_info("split into words:"); | 249 | pr_info("split into words:"); |
238 | for (i = 0 ; i < nwords ; i++) | 250 | for (i = 0; i < nwords; i++) |
239 | pr_cont(" \"%s\"", words[i]); | 251 | pr_cont(" \"%s\"", words[i]); |
240 | pr_cont("\n"); | 252 | pr_cont("\n"); |
241 | } | 253 | } |
@@ -257,7 +269,11 @@ static inline int parse_lineno(const char *str, unsigned int *val) | |||
257 | return 0; | 269 | return 0; |
258 | } | 270 | } |
259 | *val = simple_strtoul(str, &end, 10); | 271 | *val = simple_strtoul(str, &end, 10); |
260 | return end == NULL || end == str || *end != '\0' ? -EINVAL : 0; | 272 | if (end == NULL || end == str || *end != '\0') { |
273 | pr_err("bad line-number: %s\n", str); | ||
274 | return -EINVAL; | ||
275 | } | ||
276 | return 0; | ||
261 | } | 277 | } |
262 | 278 | ||
263 | /* | 279 | /* |
@@ -286,11 +302,11 @@ static char *unescape(char *str) | |||
286 | in += 2; | 302 | in += 2; |
287 | continue; | 303 | continue; |
288 | } else if (isodigit(in[1]) && | 304 | } else if (isodigit(in[1]) && |
289 | isodigit(in[2]) && | 305 | isodigit(in[2]) && |
290 | isodigit(in[3])) { | 306 | isodigit(in[3])) { |
291 | *out++ = ((in[1] - '0')<<6) | | 307 | *out++ = (((in[1] - '0') << 6) | |
292 | ((in[2] - '0')<<3) | | 308 | ((in[2] - '0') << 3) | |
293 | (in[3] - '0'); | 309 | (in[3] - '0')); |
294 | in += 4; | 310 | in += 4; |
295 | continue; | 311 | continue; |
296 | } | 312 | } |
@@ -308,8 +324,8 @@ static int check_set(const char **dest, char *src, char *name) | |||
308 | 324 | ||
309 | if (*dest) { | 325 | if (*dest) { |
310 | rc = -EINVAL; | 326 | rc = -EINVAL; |
311 | pr_err("match-spec:%s val:%s overridden by %s", | 327 | pr_err("match-spec:%s val:%s overridden by %s\n", |
312 | name, *dest, src); | 328 | name, *dest, src); |
313 | } | 329 | } |
314 | *dest = src; | 330 | *dest = src; |
315 | return rc; | 331 | return rc; |
@@ -337,40 +353,46 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
337 | int rc; | 353 | int rc; |
338 | 354 | ||
339 | /* check we have an even number of words */ | 355 | /* check we have an even number of words */ |
340 | if (nwords % 2 != 0) | 356 | if (nwords % 2 != 0) { |
357 | pr_err("expecting pairs of match-spec <value>\n"); | ||
341 | return -EINVAL; | 358 | return -EINVAL; |
359 | } | ||
342 | memset(query, 0, sizeof(*query)); | 360 | memset(query, 0, sizeof(*query)); |
343 | 361 | ||
344 | if (modname) | 362 | if (modname) |
345 | /* support $modname.dyndbg=<multiple queries> */ | 363 | /* support $modname.dyndbg=<multiple queries> */ |
346 | query->module = modname; | 364 | query->module = modname; |
347 | 365 | ||
348 | for (i = 0 ; i < nwords ; i += 2) { | 366 | for (i = 0; i < nwords; i += 2) { |
349 | if (!strcmp(words[i], "func")) | 367 | if (!strcmp(words[i], "func")) { |
350 | rc = check_set(&query->function, words[i+1], "func"); | 368 | rc = check_set(&query->function, words[i+1], "func"); |
351 | else if (!strcmp(words[i], "file")) | 369 | } else if (!strcmp(words[i], "file")) { |
352 | rc = check_set(&query->filename, words[i+1], "file"); | 370 | rc = check_set(&query->filename, words[i+1], "file"); |
353 | else if (!strcmp(words[i], "module")) | 371 | } else if (!strcmp(words[i], "module")) { |
354 | rc = check_set(&query->module, words[i+1], "module"); | 372 | rc = check_set(&query->module, words[i+1], "module"); |
355 | else if (!strcmp(words[i], "format")) | 373 | } else if (!strcmp(words[i], "format")) { |
356 | rc = check_set(&query->format, unescape(words[i+1]), | 374 | rc = check_set(&query->format, unescape(words[i+1]), |
357 | "format"); | 375 | "format"); |
358 | else if (!strcmp(words[i], "line")) { | 376 | } else if (!strcmp(words[i], "line")) { |
359 | char *first = words[i+1]; | 377 | char *first = words[i+1]; |
360 | char *last = strchr(first, '-'); | 378 | char *last = strchr(first, '-'); |
361 | if (query->first_lineno || query->last_lineno) { | 379 | if (query->first_lineno || query->last_lineno) { |
362 | pr_err("match-spec:line given 2 times\n"); | 380 | pr_err("match-spec: line used 2x\n"); |
363 | return -EINVAL; | 381 | return -EINVAL; |
364 | } | 382 | } |
365 | if (last) | 383 | if (last) |
366 | *last++ = '\0'; | 384 | *last++ = '\0'; |
367 | if (parse_lineno(first, &query->first_lineno) < 0) | 385 | if (parse_lineno(first, &query->first_lineno) < 0) { |
386 | pr_err("line-number is <0\n"); | ||
368 | return -EINVAL; | 387 | return -EINVAL; |
388 | } | ||
369 | if (last) { | 389 | if (last) { |
370 | /* range <first>-<last> */ | 390 | /* range <first>-<last> */ |
371 | if (parse_lineno(last, &query->last_lineno) | 391 | if (parse_lineno(last, &query->last_lineno) |
372 | < query->first_lineno) { | 392 | < query->first_lineno) { |
373 | pr_err("last-line < 1st-line\n"); | 393 | pr_err("last-line:%d < 1st-line:%d\n", |
394 | query->last_lineno, | ||
395 | query->first_lineno); | ||
374 | return -EINVAL; | 396 | return -EINVAL; |
375 | } | 397 | } |
376 | } else { | 398 | } else { |
@@ -406,19 +428,22 @@ static int ddebug_parse_flags(const char *str, unsigned int *flagsp, | |||
406 | op = *str++; | 428 | op = *str++; |
407 | break; | 429 | break; |
408 | default: | 430 | default: |
431 | pr_err("bad flag-op %c, at start of %s\n", *str, str); | ||
409 | return -EINVAL; | 432 | return -EINVAL; |
410 | } | 433 | } |
411 | vpr_info("op='%c'\n", op); | 434 | vpr_info("op='%c'\n", op); |
412 | 435 | ||
413 | for ( ; *str ; ++str) { | 436 | for (; *str ; ++str) { |
414 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { | 437 | for (i = ARRAY_SIZE(opt_array) - 1; i >= 0; i--) { |
415 | if (*str == opt_array[i].opt_char) { | 438 | if (*str == opt_array[i].opt_char) { |
416 | flags |= opt_array[i].flag; | 439 | flags |= opt_array[i].flag; |
417 | break; | 440 | break; |
418 | } | 441 | } |
419 | } | 442 | } |
420 | if (i < 0) | 443 | if (i < 0) { |
444 | pr_err("unknown flag '%c' in \"%s\"\n", *str, str); | ||
421 | return -EINVAL; | 445 | return -EINVAL; |
446 | } | ||
422 | } | 447 | } |
423 | vpr_info("flags=0x%x\n", flags); | 448 | vpr_info("flags=0x%x\n", flags); |
424 | 449 | ||
@@ -450,16 +475,22 @@ static int ddebug_exec_query(char *query_string, const char *modname) | |||
450 | char *words[MAXWORDS]; | 475 | char *words[MAXWORDS]; |
451 | 476 | ||
452 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); | 477 | nwords = ddebug_tokenize(query_string, words, MAXWORDS); |
453 | if (nwords <= 0) | 478 | if (nwords <= 0) { |
479 | pr_err("tokenize failed\n"); | ||
454 | return -EINVAL; | 480 | return -EINVAL; |
455 | if (ddebug_parse_query(words, nwords-1, &query, modname)) | 481 | } |
482 | /* check flags 1st (last arg) so query is pairs of spec,val */ | ||
483 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) { | ||
484 | pr_err("flags parse failed\n"); | ||
456 | return -EINVAL; | 485 | return -EINVAL; |
457 | if (ddebug_parse_flags(words[nwords-1], &flags, &mask)) | 486 | } |
487 | if (ddebug_parse_query(words, nwords-1, &query, modname)) { | ||
488 | pr_err("query parse failed\n"); | ||
458 | return -EINVAL; | 489 | return -EINVAL; |
459 | 490 | } | |
460 | /* actually go and implement the change */ | 491 | /* actually go and implement the change */ |
461 | nfound = ddebug_change(&query, flags, mask); | 492 | nfound = ddebug_change(&query, flags, mask); |
462 | vpr_info_dq((&query), (nfound) ? "applied" : "no-match"); | 493 | vpr_info_dq(&query, nfound ? "applied" : "no-match"); |
463 | 494 | ||
464 | return nfound; | 495 | return nfound; |
465 | } | 496 | } |
@@ -488,8 +519,9 @@ static int ddebug_exec_queries(char *query, const char *modname) | |||
488 | if (rc < 0) { | 519 | if (rc < 0) { |
489 | errs++; | 520 | errs++; |
490 | exitcode = rc; | 521 | exitcode = rc; |
491 | } else | 522 | } else { |
492 | nfound += rc; | 523 | nfound += rc; |
524 | } | ||
493 | i++; | 525 | i++; |
494 | } | 526 | } |
495 | vpr_info("processed %d queries, with %d matches, %d errs\n", | 527 | vpr_info("processed %d queries, with %d matches, %d errs\n", |
@@ -765,7 +797,7 @@ static void *ddebug_proc_next(struct seq_file *m, void *p, loff_t *pos) | |||
765 | struct _ddebug *dp; | 797 | struct _ddebug *dp; |
766 | 798 | ||
767 | vpr_info("called m=%p p=%p *pos=%lld\n", | 799 | vpr_info("called m=%p p=%p *pos=%lld\n", |
768 | m, p, (unsigned long long)*pos); | 800 | m, p, (unsigned long long)*pos); |
769 | 801 | ||
770 | if (p == SEQ_START_TOKEN) | 802 | if (p == SEQ_START_TOKEN) |
771 | dp = ddebug_iter_first(iter); | 803 | dp = ddebug_iter_first(iter); |
@@ -791,14 +823,14 @@ static int ddebug_proc_show(struct seq_file *m, void *p) | |||
791 | 823 | ||
792 | if (p == SEQ_START_TOKEN) { | 824 | if (p == SEQ_START_TOKEN) { |
793 | seq_puts(m, | 825 | seq_puts(m, |
794 | "# filename:lineno [module]function flags format\n"); | 826 | "# filename:lineno [module]function flags format\n"); |
795 | return 0; | 827 | return 0; |
796 | } | 828 | } |
797 | 829 | ||
798 | seq_printf(m, "%s:%u [%s]%s =%s \"", | 830 | seq_printf(m, "%s:%u [%s]%s =%s \"", |
799 | trim_prefix(dp->filename), dp->lineno, | 831 | trim_prefix(dp->filename), dp->lineno, |
800 | iter->table->mod_name, dp->function, | 832 | iter->table->mod_name, dp->function, |
801 | ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); | 833 | ddebug_describe_flags(dp, flagsbuf, sizeof(flagsbuf))); |
802 | seq_escape(m, dp->format, "\t\r\n\""); | 834 | seq_escape(m, dp->format, "\t\r\n\""); |
803 | seq_puts(m, "\"\n"); | 835 | seq_puts(m, "\"\n"); |
804 | 836 | ||
@@ -845,7 +877,7 @@ static int ddebug_proc_open(struct inode *inode, struct file *file) | |||
845 | kfree(iter); | 877 | kfree(iter); |
846 | return err; | 878 | return err; |
847 | } | 879 | } |
848 | ((struct seq_file *) file->private_data)->private = iter; | 880 | ((struct seq_file *)file->private_data)->private = iter; |
849 | return 0; | 881 | return 0; |
850 | } | 882 | } |
851 | 883 | ||
@@ -1002,8 +1034,7 @@ static int __init dynamic_debug_init(void) | |||
1002 | int verbose_bytes = 0; | 1034 | int verbose_bytes = 0; |
1003 | 1035 | ||
1004 | if (__start___verbose == __stop___verbose) { | 1036 | if (__start___verbose == __stop___verbose) { |
1005 | pr_warn("_ddebug table is empty in a " | 1037 | pr_warn("_ddebug table is empty in a CONFIG_DYNAMIC_DEBUG build\n"); |
1006 | "CONFIG_DYNAMIC_DEBUG build"); | ||
1007 | return 1; | 1038 | return 1; |
1008 | } | 1039 | } |
1009 | iter = __start___verbose; | 1040 | iter = __start___verbose; |
@@ -1030,18 +1061,16 @@ static int __init dynamic_debug_init(void) | |||
1030 | goto out_err; | 1061 | goto out_err; |
1031 | 1062 | ||
1032 | ddebug_init_success = 1; | 1063 | ddebug_init_success = 1; |
1033 | vpr_info("%d modules, %d entries and %d bytes in ddebug tables," | 1064 | vpr_info("%d modules, %d entries and %d bytes in ddebug tables, %d bytes in (readonly) verbose section\n", |
1034 | " %d bytes in (readonly) verbose section\n", | 1065 | modct, entries, (int)(modct * sizeof(struct ddebug_table)), |
1035 | modct, entries, (int)( modct * sizeof(struct ddebug_table)), | 1066 | verbose_bytes + (int)(__stop___verbose - __start___verbose)); |
1036 | verbose_bytes + (int)(__stop___verbose - __start___verbose)); | ||
1037 | 1067 | ||
1038 | /* apply ddebug_query boot param, dont unload tables on err */ | 1068 | /* apply ddebug_query boot param, dont unload tables on err */ |
1039 | if (ddebug_setup_string[0] != '\0') { | 1069 | if (ddebug_setup_string[0] != '\0') { |
1040 | pr_warn("ddebug_query param name is deprecated," | 1070 | pr_warn("ddebug_query param name is deprecated, change it to dyndbg\n"); |
1041 | " change it to dyndbg\n"); | ||
1042 | ret = ddebug_exec_queries(ddebug_setup_string, NULL); | 1071 | ret = ddebug_exec_queries(ddebug_setup_string, NULL); |
1043 | if (ret < 0) | 1072 | if (ret < 0) |
1044 | pr_warn("Invalid ddebug boot param %s", | 1073 | pr_warn("Invalid ddebug boot param %s\n", |
1045 | ddebug_setup_string); | 1074 | ddebug_setup_string); |
1046 | else | 1075 | else |
1047 | pr_info("%d changes by ddebug_query\n", ret); | 1076 | pr_info("%d changes by ddebug_query\n", ret); |
diff --git a/lib/hexdump.c b/lib/hexdump.c index 6540d657dca4..3f0494c9d57a 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c | |||
@@ -227,6 +227,7 @@ void print_hex_dump(const char *level, const char *prefix_str, int prefix_type, | |||
227 | } | 227 | } |
228 | EXPORT_SYMBOL(print_hex_dump); | 228 | EXPORT_SYMBOL(print_hex_dump); |
229 | 229 | ||
230 | #if !defined(CONFIG_DYNAMIC_DEBUG) | ||
230 | /** | 231 | /** |
231 | * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params | 232 | * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params |
232 | * @prefix_str: string to prefix each line with; | 233 | * @prefix_str: string to prefix each line with; |
@@ -246,4 +247,5 @@ void print_hex_dump_bytes(const char *prefix_str, int prefix_type, | |||
246 | buf, len, true); | 247 | buf, len, true); |
247 | } | 248 | } |
248 | EXPORT_SYMBOL(print_hex_dump_bytes); | 249 | EXPORT_SYMBOL(print_hex_dump_bytes); |
249 | #endif | 250 | #endif /* !defined(CONFIG_DYNAMIC_DEBUG) */ |
251 | #endif /* defined(CONFIG_PRINTK) */ | ||