@@ -570,54 +570,70 @@ static void console_init_owner(void)
console_set_owner(domid);
}
-static void __serial_rx(char c)
+static void handle_keypress_in_domain(struct domain *d, char c)
{
- switch ( console_owner )
+ int rc = 0;
+
+ /*
+ * Deliver input to the emulated UART.
+ */
+ if ( domain_has_vuart(d) )
{
- case DOMID_XEN:
- return handle_keypress(c, false);
-
- case 0:
- /*
- * Deliver input to the hardware domain buffer, unless it is
- * already full.
- */
- if ( (serial_rx_prod - serial_rx_cons) != SERIAL_RX_SIZE )
- serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
-
- /*
- * Always notify the hardware domain: prevents receive path from
- * getting stuck.
- */
- send_global_virq(VIRQ_CONSOLE);
- break;
-
-#ifdef CONFIG_SBSA_VUART_CONSOLE
- default:
- {
- struct domain *d = rcu_lock_domain_by_id(console_owner);
-
- /*
- * If we have a properly initialized vpl011 console for the
- * domain, without a full PV ring to Dom0 (in that case input
- * comes from the PV ring), then send the character to it.
- */
- if ( d != NULL )
- vpl011_rx_char_xen(d, c);
- else
- printk("Cannot send chars to Dom%d: no UART available\n",
- console_owner);
-
- if ( d != NULL )
- rcu_unlock_domain(d);
-
- break;
- }
+#if defined(CONFIG_SBSA_VUART_CONSOLE)
+ rc = vpl011_rx_char_xen(d, c);
#endif
}
+ /*
+ * Deliver input to the hardware domain buffer.
+ */
+ else if ( d == hardware_domain )
+ {
+ /*
+ * Deliver input to the PV shim console.
+ */
+ if ( consoled_is_enabled() )
+ rc = consoled_guest_tx(c);
+ else
+ {
+ /*
+ * Deliver input to the hardware domain buffer, unless it is
+ * already full.
+ */
+ if ( (serial_rx_prod - serial_rx_cons) != SERIAL_RX_SIZE )
+ serial_rx_ring[SERIAL_RX_MASK(serial_rx_prod++)] = c;
- if ( consoled_is_enabled() )
- consoled_guest_tx(c);
+ /*
+ * Always notify the hardware domain: prevents receive path from
+ * getting stuck.
+ */
+ send_global_virq(VIRQ_CONSOLE);
+ rc = 0;
+ }
+ }
+ /*
+ * Deliver input to the PV shim console.
+ */
+ else if ( consoled_is_enabled() )
+ rc = consoled_guest_tx(c);
+
+ if ( rc )
+ printk(KERN_WARNING "console input domain %d: not ready: %d\n",
+ d->domain_id, rc);
+
+}
+
+static void __serial_rx(char c)
+{
+ struct domain *d;
+
+ d = rcu_lock_domain_console_owner();
+ if ( d != NULL )
+ {
+ handle_keypress_in_domain(d, c);
+ rcu_unlock_domain(d);
+ }
+ else
+ handle_keypress(c, false);
}
static void cf_check serial_rx(char c)