linux/arch/m68k/emu/nfcon.c
<<
>>
Prefs
   1/*
   2 * ARAnyM console driver
   3 *
   4 * This file is subject to the terms and conditions of the GNU General Public
   5 * License.  See the file COPYING in the main directory of this archive
   6 * for more details.
   7 */
   8
   9#include <linux/module.h>
  10#include <linux/init.h>
  11#include <linux/console.h>
  12#include <linux/tty.h>
  13#include <linux/tty_driver.h>
  14#include <linux/tty_flip.h>
  15#include <linux/slab.h>
  16#include <linux/err.h>
  17#include <linux/uaccess.h>
  18#include <linux/io.h>
  19
  20#include <asm/natfeat.h>
  21
  22static int stderr_id;
  23static struct tty_port nfcon_tty_port;
  24static struct tty_driver *nfcon_tty_driver;
  25
  26static void nfputs(const char *str, unsigned int count)
  27{
  28        char buf[68];
  29        unsigned long phys = virt_to_phys(buf);
  30
  31        buf[64] = 0;
  32        while (count > 64) {
  33                memcpy(buf, str, 64);
  34                nf_call(stderr_id, phys);
  35                str += 64;
  36                count -= 64;
  37        }
  38        memcpy(buf, str, count);
  39        buf[count] = 0;
  40        nf_call(stderr_id, phys);
  41}
  42
  43static void nfcon_write(struct console *con, const char *str,
  44                        unsigned int count)
  45{
  46        nfputs(str, count);
  47}
  48
  49static struct tty_driver *nfcon_device(struct console *con, int *index)
  50{
  51        *index = 0;
  52        return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
  53}
  54
  55static struct console nf_console = {
  56        .name   = "nfcon",
  57        .write  = nfcon_write,
  58        .device = nfcon_device,
  59        .flags  = CON_PRINTBUFFER,
  60        .index  = -1,
  61};
  62
  63
  64static int nfcon_tty_open(struct tty_struct *tty, struct file *filp)
  65{
  66        return 0;
  67}
  68
  69static void nfcon_tty_close(struct tty_struct *tty, struct file *filp)
  70{
  71}
  72
  73static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf,
  74                           int count)
  75{
  76        nfputs(buf, count);
  77        return count;
  78}
  79
  80static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch)
  81{
  82        char temp[2] = { ch, 0 };
  83
  84        nf_call(stderr_id, virt_to_phys(temp));
  85        return 1;
  86}
  87
  88static unsigned int nfcon_tty_write_room(struct tty_struct *tty)
  89{
  90        return 64;
  91}
  92
  93static const struct tty_operations nfcon_tty_ops = {
  94        .open           = nfcon_tty_open,
  95        .close          = nfcon_tty_close,
  96        .write          = nfcon_tty_write,
  97        .put_char       = nfcon_tty_put_char,
  98        .write_room     = nfcon_tty_write_room,
  99};
 100
 101#ifndef MODULE
 102
 103static int __init nf_debug_setup(char *arg)
 104{
 105        if (strcmp(arg, "nfcon"))
 106                return 0;
 107
 108        stderr_id = nf_get_id("NF_STDERR");
 109        if (stderr_id) {
 110                nf_console.flags |= CON_ENABLED;
 111                register_console(&nf_console);
 112        }
 113
 114        return 0;
 115}
 116
 117early_param("debug", nf_debug_setup);
 118
 119#endif /* !MODULE */
 120
 121static int __init nfcon_init(void)
 122{
 123        int res;
 124
 125        stderr_id = nf_get_id("NF_STDERR");
 126        if (!stderr_id)
 127                return -ENODEV;
 128
 129        nfcon_tty_driver = alloc_tty_driver(1);
 130        if (!nfcon_tty_driver)
 131                return -ENOMEM;
 132
 133        tty_port_init(&nfcon_tty_port);
 134
 135        nfcon_tty_driver->driver_name = "nfcon";
 136        nfcon_tty_driver->name = "nfcon";
 137        nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
 138        nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
 139        nfcon_tty_driver->init_termios = tty_std_termios;
 140        nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
 141
 142        tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
 143        tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0);
 144        res = tty_register_driver(nfcon_tty_driver);
 145        if (res) {
 146                pr_err("failed to register nfcon tty driver\n");
 147                put_tty_driver(nfcon_tty_driver);
 148                tty_port_destroy(&nfcon_tty_port);
 149                return res;
 150        }
 151
 152        if (!(nf_console.flags & CON_ENABLED))
 153                register_console(&nf_console);
 154
 155        return 0;
 156}
 157
 158static void __exit nfcon_exit(void)
 159{
 160        unregister_console(&nf_console);
 161        tty_unregister_driver(nfcon_tty_driver);
 162        put_tty_driver(nfcon_tty_driver);
 163        tty_port_destroy(&nfcon_tty_port);
 164}
 165
 166module_init(nfcon_init);
 167module_exit(nfcon_exit);
 168
 169MODULE_LICENSE("GPL");
 170