Some drivers use macro pr_cont() for continuing a message sent via printk.
Hence if we want to convert printk messaging to using the logging system,
we must support continuation of log messages too.

As pr_cont() does not provide a message level we need a means of
remembering the last log level.

With the patch a pseudo log level LOGL_CONT as well as a pseudo log
category LOGC_CONT are introduced. Using these results in the application
of the same log level and category as in the previous log message.

Signed-off-by: Heinrich Schuchardt <xypron.g...@gmx.de>
---
 common/log.c            | 23 ++++++++++++++++++-----
 doc/develop/logging.rst |  6 ++++++
 include/log.h           |  2 ++
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/common/log.c b/common/log.c
index 9a5f100da3..bafc09f263 100644
--- a/common/log.c
+++ b/common/log.c
@@ -183,10 +183,12 @@ static bool log_passes_filters(struct log_device *ldev, 
struct log_rec *rec)
  * log_dispatch() - Send a log record to all log devices for processing
  *
  * The log record is sent to each log device in turn, skipping those which have
- * filters which block the record
+ * filters which block the record.
  *
- * @rec: Log record to dispatch
- * @return 0 (meaning success)
+ * All log messages created while processing log record @rec are ignored.
+ *
+ * @rec:       log record to dispatch
+ * Return:     0 msg sent, 1 msg not sent while already dispatching another msg
  */
 static int log_dispatch(struct log_rec *rec)
 {
@@ -199,7 +201,7 @@ static int log_dispatch(struct log_rec *rec)
         * as this might result in infinite recursion.
         */
        if (processing_msg)
-               return 0;
+               return 1;

        /* Emit message */
        processing_msg = 1;
@@ -214,10 +216,18 @@ static int log_dispatch(struct log_rec *rec)
 int _log(enum log_category_t cat, enum log_level_t level, const char *file,
         int line, const char *func, const char *fmt, ...)
 {
+       static enum log_category_t logc_prev = LOGC_NONE;
+       static enum log_level_t logl_prev = LOGL_INFO;
        char buf[CONFIG_SYS_CBSIZE];
        struct log_rec rec;
        va_list args;

+       /* Check for message continuation */
+       if (cat == LOGC_CONT)
+               cat = logc_prev;
+       if (level == LOGL_CONT)
+               level = logl_prev;
+
        rec.cat = cat;
        rec.level = level;
        rec.file = file;
@@ -232,7 +242,10 @@ int _log(enum log_category_t cat, enum log_level_t level, 
const char *file,
                        gd->log_drop_count++;
                return -ENOSYS;
        }
-       log_dispatch(&rec);
+       if (!log_dispatch(&rec)) {
+               logc_prev = cat;
+               logl_prev = level;
+       }

        return 0;
 }
diff --git a/doc/develop/logging.rst b/doc/develop/logging.rst
index 7ce8482ab6..c36f6bbbe4 100644
--- a/doc/develop/logging.rst
+++ b/doc/develop/logging.rst
@@ -38,6 +38,9 @@ There are a number logging levels available, in increasing 
order of verbosity:
 * LOGL_DEBUG_CONTENT - Debug message showing full message content
 * LOGL_DEBUG_IO - Debug message showing hardware I/O access

+To continue a log message in a separate call of function log() use
+
+* LOGL_CONT - Use same log level as in previous call

 Logging category
 ----------------
@@ -56,6 +59,9 @@ The following main categories are defined:
 * LOGC_DT - Related to device tree control
 * LOGC_EFI - Related to EFI implementation

+To continue a log message in a separate call of function log() use
+
+* LOGC_CONT - Use same category as in previous call

 Enabling logging
 ----------------
diff --git a/include/log.h b/include/log.h
index 2859ce1f2e..567cd32d34 100644
--- a/include/log.h
+++ b/include/log.h
@@ -35,6 +35,7 @@ enum log_level_t {

        LOGL_FIRST = LOGL_EMERG,
        LOGL_MAX = LOGL_DEBUG_IO,
+       LOGL_CONT = -1,         /* Use same log level as in previous call */
 };

 /**
@@ -60,6 +61,7 @@ enum log_category_t {

        LOGC_COUNT,     /* Number of log categories */
        LOGC_END,       /* Sentinel value for a list of log categories */
+       LOGC_CONT = -1, /* Use same category as in previous call */
 };

 /* Helper to cast a uclass ID to a log category */
--
2.28.0

Reply via email to