From 9af7706492f985867d070861fe39fee0fe41326f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 3 Oct 2019 15:32:14 +0300 Subject: lib/vsprintf: Remove support for %pF and %pf in favour of %pS and %ps %pS and %ps are now the preferred conversion specifiers to print function names. The functionality is equivalent; remove the old, deprecated %pF and %pf support. Depends-on: commit 2d44d165e939 ("scsi: lpfc: Convert existing %pf users to %ps") Depends-on: commit b295c3e39c13 ("tools lib traceevent: Convert remaining %p[fF] users to %p[sS]") Signed-off-by: Sakari Ailus Reviewed-by: Andy Shevchenko Reviewed-by: Petr Mladek Signed-off-by: Rafael J. Wysocki --- lib/vsprintf.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e78017a3e1bd..7eb6417b3aae 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -918,7 +918,7 @@ char *symbol_string(char *buf, char *end, void *ptr, #ifdef CONFIG_KALLSYMS if (*fmt == 'B') sprint_backtrace(sym, value); - else if (*fmt != 'f' && *fmt != 's') + else if (*fmt != 's') sprint_symbol(sym, value); else sprint_symbol_no_offset(sym, value); @@ -2016,9 +2016,7 @@ static char *kobject_string(char *buf, char *end, void *ptr, * * - 'S' For symbolic direct pointers (or function descriptors) with offset * - 's' For symbolic direct pointers (or function descriptors) without offset - * - 'F' Same as 'S' - * - 'f' Same as 's' - * - '[FfSs]R' as above with __builtin_extract_return_addr() translation + * - '[Ss]R' as above with __builtin_extract_return_addr() translation * - 'B' For backtraced symbolic direct pointers with offset * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] @@ -2121,8 +2119,6 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, struct printf_spec spec) { switch (*fmt) { - case 'F': - case 'f': case 'S': case 's': ptr = dereference_symbol_descriptor(ptr); @@ -2819,8 +2815,6 @@ int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) /* Dereference of functions is still OK */ case 'S': case 's': - case 'F': - case 'f': case 'x': case 'K': save_arg(void *); -- cgit v1.2.3-70-g09d2 From 1586c5ae2f9310235b5e70abe712c73fc32eb98f Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 3 Oct 2019 15:32:15 +0300 Subject: lib/vsprintf: Add a note on re-using %pf or %pF Add a note warning of re-use of obsolete %pf or %pF extensions. Signed-off-by: Sakari Ailus Suggested-by: Steven Rostedt (VMware) Reviewed-by: Petr Mladek Signed-off-by: Rafael J. Wysocki --- lib/vsprintf.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7eb6417b3aae..ac9f3207a8d6 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -2017,6 +2017,8 @@ static char *kobject_string(char *buf, char *end, void *ptr, * - 'S' For symbolic direct pointers (or function descriptors) with offset * - 's' For symbolic direct pointers (or function descriptors) without offset * - '[Ss]R' as above with __builtin_extract_return_addr() translation + * - '[Ff]' %pf and %pF were obsoleted and later removed in favor of + * %ps and %pS. Be careful when re-using these specifiers. * - 'B' For backtraced symbolic direct pointers with offset * - 'R' For decoded struct resource, e.g., [mem 0x0-0x1f 64bit pref] * - 'r' For raw struct resource, e.g., [mem 0x0-0x1f flags 0x201] -- cgit v1.2.3-70-g09d2 From a92eb7621b9fb2c28a588ce333d226f56fab6a85 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 3 Oct 2019 15:32:16 +0300 Subject: lib/vsprintf: Make use of fwnode API to obtain node names and separators Instead of implementing our own means of discovering parent nodes, node names or counting how many parents a node has, use the newly added functions in the fwnode API to obtain that information. Signed-off-by: Sakari Ailus Reviewed-by: Andy Shevchenko Reviewed-by: Petr Mladek Signed-off-by: Rafael J. Wysocki --- lib/vsprintf.c | 39 +++++++++++++++++---------------------- 1 file changed, 17 insertions(+), 22 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index ac9f3207a8d6..6917d36f7ec9 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -38,6 +38,7 @@ #include #include #include +#include #ifdef CONFIG_BLOCK #include #endif @@ -1872,32 +1873,25 @@ char *flags_string(char *buf, char *end, void *flags_ptr, return format_flags(buf, end, flags, names); } -static const char *device_node_name_for_depth(const struct device_node *np, int depth) -{ - for ( ; np && depth; depth--) - np = np->parent; - - return kbasename(np->full_name); -} - static noinline_for_stack -char *device_node_gen_full_name(const struct device_node *np, char *buf, char *end) +char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf, + char *end) { int depth; - const struct device_node *parent = np->parent; - /* special case for root node */ - if (!parent) - return string_nocheck(buf, end, "/", default_str_spec); + /* Loop starting from the root node to the current node. */ + for (depth = fwnode_count_parents(fwnode); depth >= 0; depth--) { + struct fwnode_handle *__fwnode = + fwnode_get_nth_parent(fwnode, depth); - for (depth = 0; parent->parent; depth++) - parent = parent->parent; - - for ( ; depth >= 0; depth--) { - buf = string_nocheck(buf, end, "/", default_str_spec); - buf = string(buf, end, device_node_name_for_depth(np, depth), + buf = string(buf, end, fwnode_get_name_prefix(__fwnode), + default_str_spec); + buf = string(buf, end, fwnode_get_name(__fwnode), default_str_spec); + + fwnode_handle_put(__fwnode); } + return buf; } @@ -1942,10 +1936,11 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, switch (*fmt) { case 'f': /* full_name */ - buf = device_node_gen_full_name(dn, buf, end); + buf = fwnode_full_name_string(of_fwnode_handle(dn), buf, + end); break; case 'n': /* name */ - p = kbasename(of_node_full_name(dn)); + p = fwnode_get_name(of_fwnode_handle(dn)); precision = str_spec.precision; str_spec.precision = strchrnul(p, '@') - p; buf = string(buf, end, p, str_spec); @@ -1955,7 +1950,7 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, buf = number(buf, end, (unsigned int)dn->phandle, num_spec); break; case 'P': /* path-spec */ - p = kbasename(of_node_full_name(dn)); + p = fwnode_get_name(of_fwnode_handle(dn)); if (!p[1]) p = "/"; buf = string(buf, end, p, str_spec); -- cgit v1.2.3-70-g09d2 From 83abc5a77f3b028b8c845c39ce4053119e1de35b Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 3 Oct 2019 15:32:17 +0300 Subject: lib/vsprintf: OF nodes are first and foremost, struct device_nodes Factor out static kobject_string() function that simply calls device_node_string(), and thus remove references to kobjects (as these are struct device_node). Signed-off-by: Sakari Ailus Reviewed-by: Andy Shevchenko Reviewed-by: Petr Mladek Signed-off-by: Rafael J. Wysocki --- lib/vsprintf.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6917d36f7ec9..4b766ee00dea 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1915,6 +1915,9 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, struct printf_spec str_spec = spec; str_spec.field_width = -1; + if (fmt[0] != 'F') + return error_string(buf, end, "(%pO?)", spec); + if (!IS_ENABLED(CONFIG_OF)) return error_string(buf, end, "(%pOF?)", spec); @@ -1988,17 +1991,6 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, return widen_string(buf, buf - buf_start, end, spec); } -static char *kobject_string(char *buf, char *end, void *ptr, - struct printf_spec spec, const char *fmt) -{ - switch (fmt[1]) { - case 'F': - return device_node_string(buf, end, ptr, spec, fmt + 1); - } - - return error_string(buf, end, "(%pO?)", spec); -} - /* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format @@ -2177,7 +2169,7 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, case 'G': return flags_string(buf, end, ptr, spec, fmt); case 'O': - return kobject_string(buf, end, ptr, spec, fmt); + return device_node_string(buf, end, ptr, spec, fmt + 1); case 'x': return pointer_string(buf, end, ptr, spec); } -- cgit v1.2.3-70-g09d2 From 3bd32d6a2ee62db3c5b06caf7b163b6a4d459ea1 Mon Sep 17 00:00:00 2001 From: Sakari Ailus Date: Thu, 3 Oct 2019 15:32:18 +0300 Subject: lib/vsprintf: Add %pfw conversion specifier for printing fwnode names Add support for %pfw conversion specifier (with "f" and "P" modifiers) to support printing full path of the node, including its name ("f") and only the node's name ("P") in the printk family of functions. The two flags have equivalent functionality to existing %pOF with the same two modifiers ("f" and "P") on OF based systems. The ability to do the same on ACPI based systems is added by this patch. On ACPI based systems the resulting strings look like \_SB.PCI0.CIO2.port@1.endpoint@0 where the nodes are separated by a dot (".") and the first three are ACPI device nodes and the latter two ACPI data nodes. Signed-off-by: Sakari Ailus Reviewed-by: Andy Shevchenko Reviewed-by: Petr Mladek Signed-off-by: Rafael J. Wysocki --- Documentation/core-api/printk-formats.rst | 24 +++++++++++++++++++++ lib/vsprintf.c | 36 +++++++++++++++++++++++++++++++ scripts/checkpatch.pl | 8 +++++-- 3 files changed, 66 insertions(+), 2 deletions(-) (limited to 'lib/vsprintf.c') diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core-api/printk-formats.rst index 0c081edbe97e..a6df7e99e6c9 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -418,6 +418,30 @@ Examples:: Passed by reference. +Fwnode handles +-------------- + +:: + + %pfw[fP] + +For printing information on fwnode handles. The default is to print the full +node name, including the path. The modifiers are functionally equivalent to +%pOF above. + + - f - full name of the node, including the path + - P - the name of the node including an address (if there is one) + +Examples (ACPI):: + + %pfwf \_SB.PCI0.CIO2.port@1.endpoint@0 - Full node name + %pfwP endpoint@0 - Node name + +Examples (OF):: + + %pfwf /ocp@68000000/i2c@48072000/camera@10/port/endpoint - Full name + %pfwP endpoint - Node name + Time and date (struct rtc_time) ------------------------------- diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4b766ee00dea..65dd5804a93b 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1991,6 +1991,36 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, return widen_string(buf, buf - buf_start, end, spec); } +static noinline_for_stack +char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode, + struct printf_spec spec, const char *fmt) +{ + struct printf_spec str_spec = spec; + char *buf_start = buf; + + str_spec.field_width = -1; + + if (*fmt != 'w') + return error_string(buf, end, "(%pf?)", spec); + + if (check_pointer(&buf, end, fwnode, spec)) + return buf; + + fmt++; + + switch (*fmt) { + case 'P': /* name */ + buf = string(buf, end, fwnode_get_name(fwnode), str_spec); + break; + case 'f': /* full_name */ + default: + buf = fwnode_full_name_string(fwnode, buf, end); + break; + } + + return widen_string(buf, buf - buf_start, end, spec); +} + /* * Show a '%p' thing. A kernel extension is that the '%p' is followed * by an extra set of alphanumeric characters that are extended format @@ -2095,6 +2125,10 @@ char *device_node_string(char *buf, char *end, struct device_node *dn, * F device node flags * c major compatible string * C full compatible string + * - 'fw[fP]' For a firmware node (struct fwnode_handle) pointer + * Without an option prints the full name of the node + * f full name + * P node name, including a possible unit address * - 'x' For printing the address. Equivalent to "%lx". * * ** When making changes please also update: @@ -2170,6 +2204,8 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr, return flags_string(buf, end, ptr, spec, fmt); case 'O': return device_node_string(buf, end, ptr, spec, fmt + 1); + case 'f': + return fwnode_string(buf, end, ptr, spec, fmt + 1); case 'x': return pointer_string(buf, end, ptr, spec); } diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 03c574a49e1a..3d1f08fa091c 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6015,14 +6015,18 @@ sub process { for (my $count = $linenr; $count <= $lc; $count++) { my $specifier; my $extension; + my $qualifier; my $bad_specifier = ""; my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0)); $fmt =~ s/%%//g; - while ($fmt =~ /(\%[\*\d\.]*p(\w))/g) { + while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) { $specifier = $1; $extension = $2; - if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxt]/) { + $qualifier = $3; + if ($extension !~ /[SsBKRraEhMmIiUDdgVCbGNOxtf]/ || + ($extension eq "f" && + defined $qualifier && $qualifier !~ /^w/)) { $bad_specifier = $specifier; last; } -- cgit v1.2.3-70-g09d2