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);