diff options
| -rw-r--r-- | arch/m68k/Kconfig | 8 | ||||
| -rw-r--r-- | arch/m68k/emu/Makefile | 1 | ||||
| -rw-r--r-- | arch/m68k/emu/natfeat.c | 38 | ||||
| -rw-r--r-- | arch/m68k/emu/nfcon.c | 162 |
4 files changed, 171 insertions, 38 deletions
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 2c890b56c96e..6719c5629c5d 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
| @@ -255,6 +255,14 @@ config NFBLOCK | |||
| 255 | which allows direct access to the hard drives without using | 255 | which allows direct access to the hard drives without using |
| 256 | the hardware emulation. | 256 | the hardware emulation. |
| 257 | 257 | ||
| 258 | config NFCON | ||
| 259 | tristate "NatFeat console driver" | ||
| 260 | depends on NATFEAT | ||
| 261 | help | ||
| 262 | Say Y to include support for the ARAnyM NatFeat console driver | ||
| 263 | which allows the console output to be redirected to the stderr | ||
| 264 | output of ARAnyM. | ||
| 265 | |||
| 258 | comment "Processor type" | 266 | comment "Processor type" |
| 259 | 267 | ||
| 260 | config M68020 | 268 | config M68020 |
diff --git a/arch/m68k/emu/Makefile b/arch/m68k/emu/Makefile index fc4f77a3d35c..a83ef1e497b3 100644 --- a/arch/m68k/emu/Makefile +++ b/arch/m68k/emu/Makefile | |||
| @@ -5,3 +5,4 @@ | |||
| 5 | obj-y += natfeat.o | 5 | obj-y += natfeat.o |
| 6 | 6 | ||
| 7 | obj-$(CONFIG_NFBLOCK) += nfblock.o | 7 | obj-$(CONFIG_NFBLOCK) += nfblock.o |
| 8 | obj-$(CONFIG_NFCON) += nfcon.o | ||
diff --git a/arch/m68k/emu/natfeat.c b/arch/m68k/emu/natfeat.c index 987d77322178..2291a7d69d49 100644 --- a/arch/m68k/emu/natfeat.c +++ b/arch/m68k/emu/natfeat.c | |||
| @@ -35,24 +35,6 @@ asm("\n" | |||
| 35 | EXPORT_SYMBOL_GPL(nf_get_id); | 35 | EXPORT_SYMBOL_GPL(nf_get_id); |
| 36 | EXPORT_SYMBOL_GPL(nf_call); | 36 | EXPORT_SYMBOL_GPL(nf_call); |
| 37 | 37 | ||
| 38 | static int stderr_id; | ||
| 39 | |||
| 40 | static void nf_write(struct console *co, const char *str, unsigned int count) | ||
| 41 | { | ||
| 42 | char buf[68]; | ||
| 43 | |||
| 44 | buf[64] = 0; | ||
| 45 | while (count > 64) { | ||
| 46 | memcpy(buf, str, 64); | ||
| 47 | nf_call(stderr_id, buf); | ||
| 48 | str += 64; | ||
| 49 | count -= 64; | ||
| 50 | } | ||
| 51 | memcpy(buf, str, count); | ||
| 52 | buf[count] = 0; | ||
| 53 | nf_call(stderr_id, buf); | ||
| 54 | } | ||
| 55 | |||
| 56 | void nfprint(const char *fmt, ...) | 38 | void nfprint(const char *fmt, ...) |
| 57 | { | 39 | { |
| 58 | static char buf[256]; | 40 | static char buf[256]; |
| @@ -65,26 +47,6 @@ void nfprint(const char *fmt, ...) | |||
| 65 | va_end(ap); | 47 | va_end(ap); |
| 66 | } | 48 | } |
| 67 | 49 | ||
| 68 | static struct console nf_console_driver = { | ||
| 69 | .name = "debug", | ||
| 70 | .write = nf_write, | ||
| 71 | .flags = CON_PRINTBUFFER, | ||
| 72 | .index = -1, | ||
| 73 | }; | ||
| 74 | |||
| 75 | static int __init nf_debug_setup(char *arg) | ||
| 76 | { | ||
| 77 | if (strcmp(arg, "emu")) | ||
| 78 | return 0; | ||
| 79 | |||
| 80 | stderr_id = nf_get_id("NF_STDERR"); | ||
| 81 | if (stderr_id) | ||
| 82 | register_console(&nf_console_driver); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | early_param("debug", nf_debug_setup); | ||
| 87 | |||
| 88 | static void nf_poweroff(void) | 50 | static void nf_poweroff(void) |
| 89 | { | 51 | { |
| 90 | long id = nf_get_id("NF_SHUTDOWN"); | 52 | long id = nf_get_id("NF_SHUTDOWN"); |
diff --git a/arch/m68k/emu/nfcon.c b/arch/m68k/emu/nfcon.c new file mode 100644 index 000000000000..ab20dc0ff63b --- /dev/null +++ b/arch/m68k/emu/nfcon.c | |||
| @@ -0,0 +1,162 @@ | |||
| 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 | |||
| 19 | #include <asm/natfeat.h> | ||
| 20 | |||
| 21 | static int stderr_id; | ||
| 22 | static struct tty_driver *nfcon_tty_driver; | ||
| 23 | |||
| 24 | static void nfputs(const char *str, unsigned int count) | ||
| 25 | { | ||
| 26 | char buf[68]; | ||
| 27 | |||
| 28 | buf[64] = 0; | ||
| 29 | while (count > 64) { | ||
| 30 | memcpy(buf, str, 64); | ||
| 31 | nf_call(stderr_id, buf); | ||
| 32 | str += 64; | ||
| 33 | count -= 64; | ||
| 34 | } | ||
| 35 | memcpy(buf, str, count); | ||
| 36 | buf[count] = 0; | ||
| 37 | nf_call(stderr_id, buf); | ||
| 38 | } | ||
| 39 | |||
| 40 | static void nfcon_write(struct console *con, const char *str, | ||
| 41 | unsigned int count) | ||
| 42 | { | ||
| 43 | nfputs(str, count); | ||
| 44 | } | ||
| 45 | |||
| 46 | static struct tty_driver *nfcon_device(struct console *con, int *index) | ||
| 47 | { | ||
| 48 | *index = 0; | ||
| 49 | return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL; | ||
| 50 | } | ||
| 51 | |||
| 52 | static struct console nf_console = { | ||
| 53 | .name = "nfcon", | ||
| 54 | .write = nfcon_write, | ||
| 55 | .device = nfcon_device, | ||
| 56 | .flags = CON_PRINTBUFFER, | ||
| 57 | .index = -1, | ||
| 58 | }; | ||
| 59 | |||
| 60 | |||
| 61 | static int nfcon_tty_open(struct tty_struct *tty, struct file *filp) | ||
| 62 | { | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | static void nfcon_tty_close(struct tty_struct *tty, struct file *filp) | ||
| 67 | { | ||
| 68 | } | ||
| 69 | |||
| 70 | static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf, | ||
| 71 | int count) | ||
| 72 | { | ||
| 73 | nfputs(buf, count); | ||
| 74 | return count; | ||
| 75 | } | ||
| 76 | |||
| 77 | static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch) | ||
| 78 | { | ||
| 79 | char temp[2] = { ch, 0 }; | ||
| 80 | |||
| 81 | nf_call(stderr_id, temp); | ||
| 82 | return 1; | ||
| 83 | } | ||
| 84 | |||
| 85 | static int nfcon_tty_write_room(struct tty_struct *tty) | ||
| 86 | { | ||
| 87 | return 64; | ||
| 88 | } | ||
| 89 | |||
| 90 | static const struct tty_operations nfcon_tty_ops = { | ||
| 91 | .open = nfcon_tty_open, | ||
| 92 | .close = nfcon_tty_close, | ||
| 93 | .write = nfcon_tty_write, | ||
| 94 | .put_char = nfcon_tty_put_char, | ||
| 95 | .write_room = nfcon_tty_write_room, | ||
| 96 | }; | ||
| 97 | |||
| 98 | #ifndef MODULE | ||
| 99 | |||
| 100 | static int __init nf_debug_setup(char *arg) | ||
| 101 | { | ||
| 102 | if (strcmp(arg, "nfcon")) | ||
| 103 | return 0; | ||
| 104 | |||
| 105 | stderr_id = nf_get_id("NF_STDERR"); | ||
| 106 | if (stderr_id) { | ||
| 107 | nf_console.flags |= CON_ENABLED; | ||
| 108 | register_console(&nf_console); | ||
| 109 | } | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | } | ||
| 113 | |||
| 114 | early_param("debug", nf_debug_setup); | ||
| 115 | |||
| 116 | #endif /* !MODULE */ | ||
| 117 | |||
| 118 | static int __init nfcon_init(void) | ||
| 119 | { | ||
| 120 | int res; | ||
| 121 | |||
| 122 | stderr_id = nf_get_id("NF_STDERR"); | ||
| 123 | if (!stderr_id) | ||
| 124 | return -ENODEV; | ||
| 125 | |||
| 126 | nfcon_tty_driver = alloc_tty_driver(1); | ||
| 127 | if (!nfcon_tty_driver) | ||
| 128 | return -ENOMEM; | ||
| 129 | |||
| 130 | nfcon_tty_driver->owner = THIS_MODULE; | ||
| 131 | nfcon_tty_driver->driver_name = "nfcon"; | ||
| 132 | nfcon_tty_driver->name = "nfcon"; | ||
| 133 | nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; | ||
| 134 | nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY; | ||
| 135 | nfcon_tty_driver->init_termios = tty_std_termios; | ||
| 136 | nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW; | ||
| 137 | |||
| 138 | tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops); | ||
| 139 | res = tty_register_driver(nfcon_tty_driver); | ||
| 140 | if (res) { | ||
| 141 | pr_err("failed to register nfcon tty driver\n"); | ||
| 142 | put_tty_driver(nfcon_tty_driver); | ||
| 143 | return res; | ||
| 144 | } | ||
| 145 | |||
| 146 | if (!(nf_console.flags & CON_ENABLED)) | ||
| 147 | register_console(&nf_console); | ||
| 148 | |||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | static void __exit nfcon_exit(void) | ||
| 153 | { | ||
| 154 | unregister_console(&nf_console); | ||
| 155 | tty_unregister_driver(nfcon_tty_driver); | ||
| 156 | put_tty_driver(nfcon_tty_driver); | ||
| 157 | } | ||
| 158 | |||
| 159 | module_init(nfcon_init); | ||
| 160 | module_exit(nfcon_exit); | ||
| 161 | |||
| 162 | MODULE_LICENSE("GPL"); | ||
