aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2008-06-13 14:15:00 +0100
committerKeir Fraser <keir.fraser@citrix.com>2008-06-13 14:15:00 +0100
commit2754857001634a58e6e9066e8e10ebd0e09ed26b (patch)
treeefd5ea1614e20c6b9951f7839ec86876c6180f96
parent8b53284ae782507050de2a10280b52122677b2d9 (diff)
downloadxen-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.c13
-rw-r--r--xen/drivers/char/console.c12
-rw-r--r--xen/drivers/char/serial.c61
-rw-r--r--xen/include/xen/console.h3
-rw-r--r--xen/include/xen/serial.h5
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);