kernel-ark/arch/m68k/emu/nfcon.c
Geert Uytterhoeven 55490050df m68k/atari: ARAnyM - Always use physical addresses in NatFeat calls
Pointers passed to ARAnyM NatFeat calls should be physical addresses,
not virtual addresses. This worked before because on Atari, physical and
virtual kernel addresses are the same, as long as normal kernel memory
is concerned.

Correct the few remaining places where virtual addresses were used.

Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
2013-08-23 12:49:01 +02:00

170 lines
3.4 KiB
C

/*
* ARAnyM console driver
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive
* for more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/console.h>
#include <linux/tty.h>
#include <linux/tty_driver.h>
#include <linux/tty_flip.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include <asm/natfeat.h>
static int stderr_id;
static struct tty_port nfcon_tty_port;
static struct tty_driver *nfcon_tty_driver;
static void nfputs(const char *str, unsigned int count)
{
char buf[68];
unsigned long phys = virt_to_phys(buf);
buf[64] = 0;
while (count > 64) {
memcpy(buf, str, 64);
nf_call(stderr_id, phys);
str += 64;
count -= 64;
}
memcpy(buf, str, count);
buf[count] = 0;
nf_call(stderr_id, phys);
}
static void nfcon_write(struct console *con, const char *str,
unsigned int count)
{
nfputs(str, count);
}
static struct tty_driver *nfcon_device(struct console *con, int *index)
{
*index = 0;
return (con->flags & CON_ENABLED) ? nfcon_tty_driver : NULL;
}
static struct console nf_console = {
.name = "nfcon",
.write = nfcon_write,
.device = nfcon_device,
.flags = CON_PRINTBUFFER,
.index = -1,
};
static int nfcon_tty_open(struct tty_struct *tty, struct file *filp)
{
return 0;
}
static void nfcon_tty_close(struct tty_struct *tty, struct file *filp)
{
}
static int nfcon_tty_write(struct tty_struct *tty, const unsigned char *buf,
int count)
{
nfputs(buf, count);
return count;
}
static int nfcon_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
char temp[2] = { ch, 0 };
nf_call(stderr_id, virt_to_phys(temp));
return 1;
}
static int nfcon_tty_write_room(struct tty_struct *tty)
{
return 64;
}
static const struct tty_operations nfcon_tty_ops = {
.open = nfcon_tty_open,
.close = nfcon_tty_close,
.write = nfcon_tty_write,
.put_char = nfcon_tty_put_char,
.write_room = nfcon_tty_write_room,
};
#ifndef MODULE
static int __init nf_debug_setup(char *arg)
{
if (strcmp(arg, "nfcon"))
return 0;
stderr_id = nf_get_id("NF_STDERR");
if (stderr_id) {
nf_console.flags |= CON_ENABLED;
register_console(&nf_console);
}
return 0;
}
early_param("debug", nf_debug_setup);
#endif /* !MODULE */
static int __init nfcon_init(void)
{
int res;
stderr_id = nf_get_id("NF_STDERR");
if (!stderr_id)
return -ENODEV;
nfcon_tty_driver = alloc_tty_driver(1);
if (!nfcon_tty_driver)
return -ENOMEM;
tty_port_init(&nfcon_tty_port);
nfcon_tty_driver->driver_name = "nfcon";
nfcon_tty_driver->name = "nfcon";
nfcon_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM;
nfcon_tty_driver->subtype = SYSTEM_TYPE_TTY;
nfcon_tty_driver->init_termios = tty_std_termios;
nfcon_tty_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(nfcon_tty_driver, &nfcon_tty_ops);
tty_port_link_device(&nfcon_tty_port, nfcon_tty_driver, 0);
res = tty_register_driver(nfcon_tty_driver);
if (res) {
pr_err("failed to register nfcon tty driver\n");
put_tty_driver(nfcon_tty_driver);
tty_port_destroy(&nfcon_tty_port);
return res;
}
if (!(nf_console.flags & CON_ENABLED))
register_console(&nf_console);
return 0;
}
static void __exit nfcon_exit(void)
{
unregister_console(&nf_console);
tty_unregister_driver(nfcon_tty_driver);
put_tty_driver(nfcon_tty_driver);
tty_port_destroy(&nfcon_tty_port);
}
module_init(nfcon_init);
module_exit(nfcon_exit);
MODULE_LICENSE("GPL");