Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/um/drivers/tty.c
10817 views
1
/*
2
* Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3
* Licensed under the GPL
4
*/
5
6
#include <errno.h>
7
#include <fcntl.h>
8
#include <termios.h>
9
#include "chan_user.h"
10
#include "kern_constants.h"
11
#include "os.h"
12
#include "um_malloc.h"
13
#include "user.h"
14
15
struct tty_chan {
16
char *dev;
17
int raw;
18
struct termios tt;
19
};
20
21
static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
22
{
23
struct tty_chan *data;
24
25
if (*str != ':') {
26
printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify "
27
"a device\n");
28
return NULL;
29
}
30
str++;
31
32
data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
33
if (data == NULL)
34
return NULL;
35
*data = ((struct tty_chan) { .dev = str,
36
.raw = opts->raw });
37
38
return data;
39
}
40
41
static int tty_open(int input, int output, int primary, void *d,
42
char **dev_out)
43
{
44
struct tty_chan *data = d;
45
int fd, err, mode = 0;
46
47
if (input && output)
48
mode = O_RDWR;
49
else if (input)
50
mode = O_RDONLY;
51
else if (output)
52
mode = O_WRONLY;
53
54
fd = open(data->dev, mode);
55
if (fd < 0)
56
return -errno;
57
58
if (data->raw) {
59
CATCH_EINTR(err = tcgetattr(fd, &data->tt));
60
if (err)
61
return err;
62
63
err = raw(fd);
64
if (err)
65
return err;
66
}
67
68
*dev_out = data->dev;
69
return fd;
70
}
71
72
const struct chan_ops tty_ops = {
73
.type = "tty",
74
.init = tty_chan_init,
75
.open = tty_open,
76
.close = generic_close,
77
.read = generic_read,
78
.write = generic_write,
79
.console_write = generic_console_write,
80
.window_size = generic_window_size,
81
.free = generic_free,
82
.winch = 0,
83
};
84
85