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        struct tty_driver *driver;
 124        int res;
 125
 126        stderr_id = nf_get_id("NF_STDERR");
 127        if (!stderr_id)
 128                return -ENODEV;
 129
 130        driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW);
 131        if (IS_ERR(driver))
 132                return PTR_ERR(driver);
 133
 134        tty_port_init(&nfcon_tty_port);
 135
 136        driver->driver_name = "nfcon";
 137        driver->name = "nfcon";
 138        driver->type = TTY_DRIVER_TYPE_SYSTEM;
 139        driver->subtype = SYSTEM_TYPE_TTY;
 140        driver->init_termios = tty_std_termios;
 141
 142        tty_set_operations(driver, &nfcon_tty_ops);
 143        tty_port_link_device(&nfcon_tty_port, driver, 0);
 144        res = tty_register_driver(driver);
 145        if (res) {
 146                pr_err("failed to register nfcon tty driver\n");
 147                tty_driver_kref_put(driver);
 148                tty_port_destroy(&nfcon_tty_port);
 149                return res;
 150        }
 151
 152        nfcon_tty_driver = driver;
 153
 154        if (!(nf_console.flags & CON_ENABLED))
 155                register_console(&nf_console);
 156
 157        return 0;
 158}
 159
 160static void __exit nfcon_exit(void)
 161{
 162        unregister_console(&nf_console);
 163        tty_unregister_driver(nfcon_tty_driver);
 164        tty_driver_kref_put(nfcon_tty_driver);
 165        tty_port_destroy(&nfcon_tty_port);
 166}
 167
 168module_init(nfcon_init);
 169module_exit(nfcon_exit);
 170
 171MODULE_LICENSE("GPL");
 172