log: allow for message continuation
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.glpk@gmx.de> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
		
							parent
							
								
									993a06b614
								
							
						
					
					
						commit
						d094a0734c
					
				
							
								
								
									
										23
									
								
								common/log.c
								
								
								
								
							
							
						
						
									
										23
									
								
								common/log.c
								
								
								
								
							|  | @ -191,10 +191,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 |  * 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 |  * 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 |  * All log messages created while processing log record @rec are ignored. | ||||||
|  * @return 0 (meaning success) |  * | ||||||
|  |  * @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) | static int log_dispatch(struct log_rec *rec) | ||||||
| { | { | ||||||
|  | @ -206,7 +208,7 @@ static int log_dispatch(struct log_rec *rec) | ||||||
| 	 * as this might result in infinite recursion. | 	 * as this might result in infinite recursion. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (gd->processing_msg) | 	if (gd->processing_msg) | ||||||
| 		return 0; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	/* Emit message */ | 	/* Emit message */ | ||||||
| 	gd->processing_msg = true; | 	gd->processing_msg = true; | ||||||
|  | @ -226,6 +228,12 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, | ||||||
| 	struct log_rec rec; | 	struct log_rec rec; | ||||||
| 	va_list args; | 	va_list args; | ||||||
| 
 | 
 | ||||||
|  | 	/* Check for message continuation */ | ||||||
|  | 	if (cat == LOGC_CONT) | ||||||
|  | 		cat = gd->logc_prev; | ||||||
|  | 	if (level == LOGL_CONT) | ||||||
|  | 		level = gd->logl_prev; | ||||||
|  | 
 | ||||||
| 	rec.cat = cat; | 	rec.cat = cat; | ||||||
| 	rec.level = level & LOGL_LEVEL_MASK; | 	rec.level = level & LOGL_LEVEL_MASK; | ||||||
| 	rec.force_debug = level & LOGL_FORCE_DEBUG; | 	rec.force_debug = level & LOGL_FORCE_DEBUG; | ||||||
|  | @ -241,7 +249,10 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, | ||||||
| 			gd->log_drop_count++; | 			gd->log_drop_count++; | ||||||
| 		return -ENOSYS; | 		return -ENOSYS; | ||||||
| 	} | 	} | ||||||
| 	log_dispatch(&rec); | 	if (!log_dispatch(&rec)) { | ||||||
|  | 		gd->logc_prev = cat; | ||||||
|  | 		gd->logl_prev = level; | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  | @ -381,6 +392,8 @@ int log_init(void) | ||||||
| 	if (!gd->default_log_level) | 	if (!gd->default_log_level) | ||||||
| 		gd->default_log_level = CONFIG_LOG_DEFAULT_LEVEL; | 		gd->default_log_level = CONFIG_LOG_DEFAULT_LEVEL; | ||||||
| 	gd->log_fmt = log_get_default_format(); | 	gd->log_fmt = log_get_default_format(); | ||||||
|  | 	gd->logc_prev = LOGC_NONE; | ||||||
|  | 	gd->logl_prev = LOGL_INFO; | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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_CONTENT - Debug message showing full message content | ||||||
| * LOGL_DEBUG_IO - Debug message showing hardware I/O access | * 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 | Logging category | ||||||
| ---------------- | ---------------- | ||||||
|  | @ -56,6 +59,9 @@ The following main categories are defined: | ||||||
| * LOGC_DT - Related to device tree control | * LOGC_DT - Related to device tree control | ||||||
| * LOGC_EFI - Related to EFI implementation | * 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 | Enabling logging | ||||||
| ---------------- | ---------------- | ||||||
|  |  | ||||||
|  | @ -371,6 +371,18 @@ struct global_data { | ||||||
| 	 * while another message is being processed. | 	 * while another message is being processed. | ||||||
| 	 */ | 	 */ | ||||||
| 	bool processing_msg; | 	bool processing_msg; | ||||||
|  | 	/**
 | ||||||
|  | 	 * @logc_prev: logging category of previous message | ||||||
|  | 	 * | ||||||
|  | 	 * This value is used as logging category for continuation messages. | ||||||
|  | 	 */ | ||||||
|  | 	int logc_prev; | ||||||
|  | 	/**
 | ||||||
|  | 	 * @logl_pref: logging level of the previous message | ||||||
|  | 	 * | ||||||
|  | 	 * This value is used as logging level for continuation messages. | ||||||
|  | 	 */ | ||||||
|  | 	int logl_prev; | ||||||
| #endif | #endif | ||||||
| #if CONFIG_IS_ENABLED(BLOBLIST) | #if CONFIG_IS_ENABLED(BLOBLIST) | ||||||
| 	/**
 | 	/**
 | ||||||
|  |  | ||||||
|  | @ -38,6 +38,7 @@ enum log_level_t { | ||||||
| 
 | 
 | ||||||
| 	LOGL_FIRST = LOGL_EMERG, | 	LOGL_FIRST = LOGL_EMERG, | ||||||
| 	LOGL_MAX = LOGL_DEBUG_IO, | 	LOGL_MAX = LOGL_DEBUG_IO, | ||||||
|  | 	LOGL_CONT = -1,		/* Use same log level as in previous call */ | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -65,6 +66,7 @@ enum log_category_t { | ||||||
| 
 | 
 | ||||||
| 	LOGC_COUNT,	/* Number of log categories */ | 	LOGC_COUNT,	/* Number of log categories */ | ||||||
| 	LOGC_END,	/* Sentinel value for a list 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 */ | /* Helper to cast a uclass ID to a log category */ | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue