diff options
author | Keir Fraser <keir.fraser@citrix.com> | 2008-06-13 14:15:00 +0100 |
---|---|---|
committer | Keir Fraser <keir.fraser@citrix.com> | 2008-06-13 14:15:00 +0100 |
commit | 2754857001634a58e6e9066e8e10ebd0e09ed26b (patch) | |
tree | efd5ea1614e20c6b9951f7839ec86876c6180f96 | |
parent | 8b53284ae782507050de2a10280b52122677b2d9 (diff) | |
download | xen-2754857001634a58e6e9066e8e10ebd0e09ed26b.tar.gz xen-2754857001634a58e6e9066e8e10ebd0e09ed26b.tar.bz2 xen-2754857001634a58e6e9066e8e10ebd0e09ed26b.zip |
Bring back console_start_log_everything() as a milder alternative to
console_start_sync(). Revert keyhandler logic to use it. The
difference now is that serial logic is updated to not drop characters
if inb a log_everything region. Still this is milder than a sync
region since the async buffer must be filled before we start to
busy-wait on each character.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
-rw-r--r-- | xen/common/keyhandler.c | 13 | ||||
-rw-r--r-- | xen/drivers/char/console.c | 12 | ||||
-rw-r--r-- | xen/drivers/char/serial.c | 61 | ||||
-rw-r--r-- | xen/include/xen/console.h | 3 | ||||
-rw-r--r-- | xen/include/xen/serial.h | 5 |
5 files changed, 77 insertions, 17 deletions
diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index db57e5a9af..2acd17ae7b 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -36,10 +36,10 @@ static void keypress_action(unsigned long unused) { keyhandler_t *h; unsigned char key = keypress_key; - console_start_sync(); + console_start_log_everything(); if ( (h = key_table[key].u.handler) != NULL ) (*h)(key); - console_end_sync(); + console_end_log_everything(); } static DECLARE_TASKLET(keypress_tasklet, keypress_action, 0); @@ -50,10 +50,10 @@ void handle_keypress(unsigned char key, struct cpu_user_regs *regs) if ( !in_irq() || (key_table[key].flags & KEYHANDLER_IRQ_CALLBACK) ) { - console_start_sync(); + console_start_log_everything(); if ( (h = key_table[key].u.irq_handler) != NULL ) (*h)(key, regs); - console_end_sync(); + console_end_log_everything(); } else { @@ -105,6 +105,9 @@ static void dump_registers(unsigned char key, struct cpu_user_regs *regs) { unsigned int cpu; + /* We want to get everything out that we possibly can. */ + console_start_sync(); + printk("'%c' pressed -> dumping registers\n", key); /* Get local execution state out immediately, in case we get stuck. */ @@ -120,6 +123,8 @@ static void dump_registers(unsigned char key, struct cpu_user_regs *regs) } printk("\n"); + + console_end_sync(); } static void dump_dom0_registers(unsigned char key) diff --git a/xen/drivers/char/console.c b/xen/drivers/char/console.c index 1007e3e628..31e73c3201 100644 --- a/xen/drivers/char/console.c +++ b/xen/drivers/char/console.c @@ -635,6 +635,18 @@ int console_has(const char *device) return 0; } +void console_start_log_everything(void) +{ + serial_start_log_everything(sercon_handle); + atomic_inc(&print_everything); +} + +void console_end_log_everything(void) +{ + serial_end_log_everything(sercon_handle); + atomic_dec(&print_everything); +} + void console_force_unlock(void) { spin_lock_init(&console_lock); diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index c76a025047..2d0dcd5351 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -108,19 +108,23 @@ static void __serial_putc(struct serial_port *port, char c) if ( (port->txbufp - port->txbufc) == serial_txbufsz ) { -#ifdef SERIAL_NEVER_DROP_CHARS - /* Buffer is full: we spin waiting for space to appear. */ - int i; - while ( !port->driver->tx_empty(port) ) - cpu_relax(); - for ( i = 0; i < port->tx_fifo_size; i++ ) - port->driver->putc( - port, port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]); - port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c; -#else - /* Buffer is full: drop characters until buffer is half empty. */ - port->tx_quench = 1; -#endif + if ( port->tx_log_everything ) + { + /* Buffer is full: we spin waiting for space to appear. */ + int i; + while ( !port->driver->tx_empty(port) ) + cpu_relax(); + for ( i = 0; i < port->tx_fifo_size; i++ ) + port->driver->putc( + port, + port->txbuf[mask_serial_txbuf_idx(port->txbufc++)]); + port->txbuf[mask_serial_txbuf_idx(port->txbufp++)] = c; + } + else + { + /* Buffer is full: drop chars until buffer is half empty. */ + port->tx_quench = 1; + } return; } @@ -388,6 +392,37 @@ void serial_end_sync(int handle) spin_unlock_irqrestore(&port->tx_lock, flags); } +void serial_start_log_everything(int handle) +{ + struct serial_port *port; + unsigned long flags; + + if ( handle == -1 ) + return; + + port = &com[handle & SERHND_IDX]; + + spin_lock_irqsave(&port->tx_lock, flags); + port->tx_log_everything++; + port->tx_quench = 0; + spin_unlock_irqrestore(&port->tx_lock, flags); +} + +void serial_end_log_everything(int handle) +{ + struct serial_port *port; + unsigned long flags; + + if ( handle == -1 ) + return; + + port = &com[handle & SERHND_IDX]; + + spin_lock_irqsave(&port->tx_lock, flags); + port->tx_log_everything--; + spin_unlock_irqrestore(&port->tx_lock, flags); +} + int serial_tx_space(int handle) { struct serial_port *port; diff --git a/xen/include/xen/console.h b/xen/include/xen/console.h index f5e8be9815..5817f74958 100644 --- a/xen/include/xen/console.h +++ b/xen/include/xen/console.h @@ -26,6 +26,9 @@ void console_force_lock(void); void console_start_sync(void); void console_end_sync(void); +void console_start_log_everything(void); +void console_end_log_everything(void); + /* * Steal output from the console. Returns +ve identifier, else -ve error. * Takes the handle of the serial line to steal, and steal callback function. diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index b926672dfc..91fd30bcec 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -33,6 +33,7 @@ struct serial_port { char *txbuf; unsigned int txbufp, txbufc; bool_t tx_quench; + int tx_log_everything; /* Force synchronous transmit. */ int sync; /* Receiver callback functions (asynchronous receivers). */ @@ -97,6 +98,10 @@ void serial_force_unlock(int handle); void serial_start_sync(int handle); void serial_end_sync(int handle); +/* Start/end a region where we will wait rather than drop characters. */ +void serial_start_log_everything(int handle); +void serial_end_log_everything(int handle); + /* Return number of bytes headroom in transmit buffer. */ int serial_tx_space(int handle); |