fix for loss of USB console printk output on boot up.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, I have a patch here which I used to get the full console output on
a USB tty. On my system it on the BIOS address stuff at the very start
was
being printed out and the rest was lost up to the current messages.
The problem appears to be the USB printing code drops the output once
it's buffer is full as the current
code doesn't perform any waiting or buffering.

I am submitting it here for others that may have hit the same issue
and to find out if there is a better way to tackle this issue. When
large chunks are written to the console
it just delays a hard coded amount (established by trial and error and
likely would need to be changed for different console speeds...).

Obvious suggestions are - kernel parameter based on console speed (of
ttyUSB) with the default of off?

There is also a small patch that makes usb_console_write() handle
writes which are truncated (presently it ignores the returned value).

 I have to move on to other items but thought it worth sharing this
info for the benefit of others and in case people have better
solutions/ideas.

Andrew
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c
index 1ee6b2a..61f20bf 100644
--- a/drivers/usb/serial/console.c
+++ b/drivers/usb/serial/console.c
@@ -237,7 +237,9 @@ static void usb_console_write(struct console *co,
 		else
 			retval = usb_serial_generic_write(NULL, port, buf, i);
 		dbg("%s - return value : %d", __func__, retval);
-		if (lf) {
+		if ((retval > 0) && (retval < i))
+			i = retval;
+		else if (lf) {
 			/* append CR after LF */
 			unsigned char cr = 13;
 			if (serial->type->write)
diff --git a/kernel/printk.c b/kernel/printk.c
index 2ddbdc7..99a4e81 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -1121,6 +1121,7 @@ void console_unlock(void)
 	unsigned long flags;
 	unsigned _con_start, _log_end;
 	unsigned wake_klogd = 0;
+	int	delay_flag = 0;
 
 	if (console_suspended) {
 		up(&console_sem);
@@ -1130,13 +1131,29 @@ void console_unlock(void)
 	console_may_schedule = 0;
 
 	for ( ; ; ) {
+		if (delay_flag)
+			udelay(delay_flag);
 		spin_lock_irqsave(&logbuf_lock, flags);
 		wake_klogd |= log_start - log_end;
 		if (con_start == log_end)
 			break;			/* Nothing to print */
 		_con_start = con_start;
 		_log_end = log_end;
-		con_start = log_end;		/* Flush */
+#define CONSOLE_CHUNK_SIZE (512-128)
+#define CONSOLE_DELAY		83000
+		if (_log_end - _con_start > CONSOLE_CHUNK_SIZE) {
+			/* too big to swallow in one go */
+			_log_end = _con_start + CONSOLE_CHUNK_SIZE;
+			while (_log_end < log_end) {
+				_log_end++;
+				if (LOG_BUF(_log_end) == '\n')
+					break;
+			}
+			_log_end++;
+			con_start = _log_end;
+			delay_flag = CONSOLE_DELAY;
+		} else
+			con_start = log_end;		/* Flush */
 		spin_unlock(&logbuf_lock);
 		stop_critical_timings();	/* don't trace print latency */
 		call_console_drivers(_con_start, _log_end);

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux