Commit c4e00daaa96d3a0786f1f4fe6456281c60ef9a16
Committed by
Greg Kroah-Hartman
1 parent
e11fea92e1
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
driver-core: extend dev_printk() to pass structured data
Extends dev_printk() to attach a dictionary with a device identifier and the driver core subsystem name to logged messages, which makes dev_prink() reliable machine-readable. In addition to the printed plain text message, it creates these properties: SUBSYSTEM= - the driver-core subsytem name DEVICE= b12:8 - block dev_t c127:3 - char dev_t n8 - netdev ifindex +sound:card0 - subsystem:devname Tested-by: William Douglas <william.douglas@intel.com> Signed-off-by: Kay Sievers <kay@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Showing 1 changed file with 49 additions and 3 deletions Side-by-side Diff
drivers/base/core.c
... | ... | @@ -25,6 +25,7 @@ |
25 | 25 | #include <linux/mutex.h> |
26 | 26 | #include <linux/async.h> |
27 | 27 | #include <linux/pm_runtime.h> |
28 | +#include <linux/netdevice.h> | |
28 | 29 | |
29 | 30 | #include "base.h" |
30 | 31 | #include "power/power.h" |
31 | 32 | |
32 | 33 | |
... | ... | @@ -1843,15 +1844,60 @@ |
1843 | 1844 | */ |
1844 | 1845 | |
1845 | 1846 | #ifdef CONFIG_PRINTK |
1846 | - | |
1847 | 1847 | int __dev_printk(const char *level, const struct device *dev, |
1848 | 1848 | struct va_format *vaf) |
1849 | 1849 | { |
1850 | + char dict[128]; | |
1851 | + size_t dictlen = 0; | |
1852 | + const char *subsys; | |
1853 | + | |
1850 | 1854 | if (!dev) |
1851 | 1855 | return printk("%s(NULL device *): %pV", level, vaf); |
1852 | 1856 | |
1853 | - return printk("%s%s %s: %pV", | |
1854 | - level, dev_driver_string(dev), dev_name(dev), vaf); | |
1857 | + if (dev->class) | |
1858 | + subsys = dev->class->name; | |
1859 | + else if (dev->bus) | |
1860 | + subsys = dev->bus->name; | |
1861 | + else | |
1862 | + goto skip; | |
1863 | + | |
1864 | + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | |
1865 | + "SUBSYSTEM=%s", subsys); | |
1866 | + | |
1867 | + /* | |
1868 | + * Add device identifier DEVICE=: | |
1869 | + * b12:8 block dev_t | |
1870 | + * c127:3 char dev_t | |
1871 | + * n8 netdev ifindex | |
1872 | + * +sound:card0 subsystem:devname | |
1873 | + */ | |
1874 | + if (MAJOR(dev->devt)) { | |
1875 | + char c; | |
1876 | + | |
1877 | + if (strcmp(subsys, "block") == 0) | |
1878 | + c = 'b'; | |
1879 | + else | |
1880 | + c = 'c'; | |
1881 | + dictlen++; | |
1882 | + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | |
1883 | + "DEVICE=%c%u:%u", | |
1884 | + c, MAJOR(dev->devt), MINOR(dev->devt)); | |
1885 | + } else if (strcmp(subsys, "net") == 0) { | |
1886 | + struct net_device *net = to_net_dev(dev); | |
1887 | + | |
1888 | + dictlen++; | |
1889 | + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | |
1890 | + "DEVICE=n%u", net->ifindex); | |
1891 | + } else { | |
1892 | + dictlen++; | |
1893 | + dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen, | |
1894 | + "DEVICE=+%s:%s", subsys, dev_name(dev)); | |
1895 | + } | |
1896 | +skip: | |
1897 | + return printk_emit(0, level[1] - '0', | |
1898 | + dictlen ? dict : NULL, dictlen, | |
1899 | + "%s %s: %pV", | |
1900 | + dev_driver_string(dev), dev_name(dev), vaf); | |
1855 | 1901 | } |
1856 | 1902 | EXPORT_SYMBOL(__dev_printk); |
1857 | 1903 |