aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/base/core.c
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2012-05-02 20:29:59 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-07 20:12:03 -0400
commitc4e00daaa96d3a0786f1f4fe6456281c60ef9a16 (patch)
tree802b018c8ee8280db04b03224e4d2d61e232d94b /drivers/base/core.c
parente11fea92e13fb91c50bacca799a6131c81929986 (diff)
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>
Diffstat (limited to 'drivers/base/core.c')
-rw-r--r--drivers/base/core.c52
1 files changed, 49 insertions, 3 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 33461ec35d8..346be8b78b2 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -25,6 +25,7 @@
25#include <linux/mutex.h> 25#include <linux/mutex.h>
26#include <linux/async.h> 26#include <linux/async.h>
27#include <linux/pm_runtime.h> 27#include <linux/pm_runtime.h>
28#include <linux/netdevice.h>
28 29
29#include "base.h" 30#include "base.h"
30#include "power/power.h" 31#include "power/power.h"
@@ -1843,15 +1844,60 @@ void device_shutdown(void)
1843 */ 1844 */
1844 1845
1845#ifdef CONFIG_PRINTK 1846#ifdef CONFIG_PRINTK
1846
1847int __dev_printk(const char *level, const struct device *dev, 1847int __dev_printk(const char *level, const struct device *dev,
1848 struct va_format *vaf) 1848 struct va_format *vaf)
1849{ 1849{
1850 char dict[128];
1851 size_t dictlen = 0;
1852 const char *subsys;
1853
1850 if (!dev) 1854 if (!dev)
1851 return printk("%s(NULL device *): %pV", level, vaf); 1855 return printk("%s(NULL device *): %pV", level, vaf);
1852 1856
1853 return printk("%s%s %s: %pV", 1857 if (dev->class)
1854 level, dev_driver_string(dev), dev_name(dev), vaf); 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 }
1896skip:
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}
1856EXPORT_SYMBOL(__dev_printk); 1902EXPORT_SYMBOL(__dev_printk);
1857 1903