* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include <linux/config.h>
#include <linux/console.h>
#include <linux/cpumask.h>
#include <linux/init.h>
* console interfaces but can still be used as a tty device. This has to be
* static because kmalloc will not work during early console init.
*/
-static uint32_t vtermnos[MAX_NR_HVC_CONSOLES];
-
-/* Used for accounting purposes */
-static int num_vterms = 0;
+static uint32_t vtermnos[MAX_NR_HVC_CONSOLES] =
+ {[0 ... MAX_NR_HVC_CONSOLES - 1] = -1};
/*
* Console APIs, NOT TTY. These APIs are available immediately when
static struct tty_driver *hvc_console_device(struct console *c, int *index)
{
+ if (vtermnos[c->index] == -1)
+ return NULL;
+
*index = c->index;
return hvc_driver;
}
static int __init hvc_console_setup(struct console *co, char *options)
{
+ if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
+ return -ENODEV;
+
+ if (vtermnos[co->index] == -1)
+ return -ENODEV;
+
return 0;
}
/* Early console initialization. Preceeds driver initialization. */
static int __init hvc_console_init(void)
{
- int i;
-
- for (i=0; i<MAX_NR_HVC_CONSOLES; i++)
- vtermnos[i] = -1;
- num_vterms = hvc_find_vtys();
+ hvc_find_vtys();
register_console(&hvc_con_driver);
return 0;
}
*/
int hvc_instantiate(uint32_t vtermno, int index)
{
+ struct hvc_struct *hp;
+
if (index < 0 || index >= MAX_NR_HVC_CONSOLES)
return -1;
if (vtermnos[index] != -1)
return -1;
+ /* make sure no no tty has been registerd in this index */
+ hp = hvc_get_by_index(index);
+ if (hp) {
+ kobject_put(&hp->kobj);
+ return -1;
+ }
+
vtermnos[index] = vtermno;
/* reserve all indices upto and including this index */
wake_up_process(hvc_task);
}
+static int hvc_poll(struct hvc_struct *hp);
+
/*
* NOTE: This API isn't used if the console adapter doesn't support interrupts.
* In this case the console is poll driven.
*/
static irqreturn_t hvc_handle_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
- hvc_kick();
+ /* if hvc_poll request a repoll, then kick the hvcd thread */
+ if (hvc_poll(dev_instance))
+ hvc_kick();
return IRQ_HANDLED;
}
}
for (i = 0; i < n; ++i) {
#ifdef CONFIG_MAGIC_SYSRQ
- /* Handle the SysRq Hack */
- if (buf[i] == '\x0f') { /* ^O -- should support a sequence */
- sysrq_pressed = 1;
- continue;
- } else if (sysrq_pressed) {
- handle_sysrq(buf[i], NULL, tty);
- sysrq_pressed = 0;
- continue;
+ if (hp->index == hvc_con_driver.index) {
+ /* Handle the SysRq Hack */
+ /* XXX should support a sequence */
+ if (buf[i] == '\x0f') { /* ^O */
+ sysrq_pressed = 1;
+ continue;
+ } else if (sysrq_pressed) {
+ handle_sysrq(buf[i], NULL, tty);
+ sysrq_pressed = 0;
+ continue;
+ }
}
#endif /* CONFIG_MAGIC_SYSRQ */
tty_insert_flip_char(tty, buf[i], 0);
/*
* Account for the total amount read in one loop, and if above
- * 64 bytes, we do a quick schedule loop to let the tty grok the
- * data and eventually throttle us.
+ * 64 bytes, we do a quick schedule loop to let the tty grok
+ * the data and eventually throttle us.
*/
read_total += n;
if (read_total >= 64) {
if (cpus_empty(cpus_in_xmon)) {
spin_lock(&hvc_structs_lock);
list_for_each_entry(hp, &hvc_structs, next) {
- /*hp = list_entry(node, struct hvc_struct, * next); */
poll_mask |= hvc_poll(hp);
}
spin_unlock(&hvc_structs_lock);
{
int rc;
- /* We need more than num_vterms adapters due to hotplug additions. */
+ /* We need more than hvc_count adapters due to hotplug additions. */
hvc_driver = alloc_tty_driver(HVC_ALLOC_TTY_ADAPTERS);
- /* hvc_driver = alloc_tty_driver(num_vterms); */
if (!hvc_driver)
return -ENOMEM;
}
module_init(hvc_init);
-/* This isn't particularily necessary due to this being a console driver but it
- * is nice to be thorough */
+/* This isn't particularily necessary due to this being a console driver
+ * but it is nice to be thorough.
+ */
static void __exit hvc_exit(void)
{
kthread_stop(hvc_task);
tty_unregister_driver(hvc_driver);
/* return tty_struct instances allocated in hvc_init(). */
put_tty_driver(hvc_driver);
+ unregister_console(&hvc_con_driver);
}
module_exit(hvc_exit);