Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
41bc4d9b
Commit
41bc4d9b
authored
Dec 16, 2002
by
Jeff Dike
Browse files
Options
Browse Files
Download
Plain Diff
Merge jdike.wstearns.org:/home/jdike/linux/linus-2.5
into jdike.wstearns.org:/home/jdike/linux/mconfig-2.5
parents
91ec8aa9
e414458d
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
371 additions
and
31 deletions
+371
-31
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_kern.c
+64
-2
arch/um/drivers/fd.c
arch/um/drivers/fd.c
+5
-1
arch/um/drivers/line.c
arch/um/drivers/line.c
+81
-10
arch/um/drivers/mconsole_kern.c
arch/um/drivers/mconsole_kern.c
+59
-3
arch/um/drivers/null.c
arch/um/drivers/null.c
+4
-1
arch/um/drivers/port_user.c
arch/um/drivers/port_user.c
+7
-2
arch/um/drivers/pty.c
arch/um/drivers/pty.c
+14
-3
arch/um/drivers/ssl.c
arch/um/drivers/ssl.c
+31
-1
arch/um/drivers/stdio_console.c
arch/um/drivers/stdio_console.c
+29
-1
arch/um/drivers/tty.c
arch/um/drivers/tty.c
+6
-2
arch/um/drivers/ubd_kern.c
arch/um/drivers/ubd_kern.c
+39
-0
arch/um/drivers/xterm.c
arch/um/drivers/xterm.c
+3
-1
arch/um/include/chan_kern.h
arch/um/include/chan_kern.h
+3
-0
arch/um/include/chan_user.h
arch/um/include/chan_user.h
+2
-1
arch/um/include/line.h
arch/um/include/line.h
+9
-2
arch/um/include/mconsole_kern.h
arch/um/include/mconsole_kern.h
+15
-1
No files found.
arch/um/drivers/chan_kern.c
View file @
41bc4d9b
...
@@ -24,7 +24,8 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
...
@@ -24,7 +24,8 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts)
return
(
NULL
);
return
(
NULL
);
}
}
static
int
not_configged_open
(
int
input
,
int
output
,
int
primary
,
void
*
data
)
static
int
not_configged_open
(
int
input
,
int
output
,
int
primary
,
void
*
data
,
char
**
dev_out
)
{
{
printk
(
KERN_ERR
"Using a channel type which is configured out of "
printk
(
KERN_ERR
"Using a channel type which is configured out of "
"UML
\n
"
);
"UML
\n
"
);
...
@@ -112,7 +113,8 @@ static int open_one_chan(struct chan *chan, int input, int output, int primary)
...
@@ -112,7 +113,8 @@ static int open_one_chan(struct chan *chan, int input, int output, int primary)
if
(
chan
->
opened
)
return
(
0
);
if
(
chan
->
opened
)
return
(
0
);
if
(
chan
->
ops
->
open
==
NULL
)
fd
=
0
;
if
(
chan
->
ops
->
open
==
NULL
)
fd
=
0
;
else
fd
=
(
*
chan
->
ops
->
open
)(
input
,
output
,
primary
,
chan
->
data
);
else
fd
=
(
*
chan
->
ops
->
open
)(
input
,
output
,
primary
,
chan
->
data
,
&
chan
->
dev
);
if
(
fd
<
0
)
return
(
fd
);
if
(
fd
<
0
)
return
(
fd
);
chan
->
fd
=
fd
;
chan
->
fd
=
fd
;
...
@@ -258,6 +260,66 @@ void free_chan(struct list_head *chans)
...
@@ -258,6 +260,66 @@ void free_chan(struct list_head *chans)
}
}
}
}
static
int
one_chan_config_string
(
struct
chan
*
chan
,
char
*
str
,
int
size
,
char
**
error_out
)
{
int
n
=
0
;
CONFIG_CHUNK
(
str
,
size
,
n
,
chan
->
ops
->
type
,
0
);
if
(
chan
->
dev
==
NULL
){
CONFIG_CHUNK
(
str
,
size
,
n
,
""
,
1
);
return
(
n
);
}
CONFIG_CHUNK
(
str
,
size
,
n
,
":"
,
0
);
CONFIG_CHUNK
(
str
,
size
,
n
,
chan
->
dev
,
0
);
return
(
n
);
}
static
int
chan_pair_config_string
(
struct
chan
*
in
,
struct
chan
*
out
,
char
*
str
,
int
size
,
char
**
error_out
)
{
int
n
;
n
=
one_chan_config_string
(
in
,
str
,
size
,
error_out
);
str
+=
n
;
size
-=
n
;
if
(
in
==
out
){
CONFIG_CHUNK
(
str
,
size
,
n
,
""
,
1
);
return
(
n
);
}
CONFIG_CHUNK
(
str
,
size
,
n
,
","
,
1
);
n
=
one_chan_config_string
(
out
,
str
,
size
,
error_out
);
str
+=
n
;
size
-=
n
;
CONFIG_CHUNK
(
str
,
size
,
n
,
""
,
1
);
return
(
n
);
}
int
chan_config_string
(
struct
list_head
*
chans
,
char
*
str
,
int
size
,
char
**
error_out
)
{
struct
list_head
*
ele
;
struct
chan
*
chan
,
*
in
=
NULL
,
*
out
=
NULL
;
list_for_each
(
ele
,
chans
){
chan
=
list_entry
(
ele
,
struct
chan
,
list
);
if
(
!
chan
->
primary
)
continue
;
if
(
chan
->
input
)
in
=
chan
;
if
(
chan
->
output
)
out
=
chan
;
}
return
(
chan_pair_config_string
(
in
,
out
,
str
,
size
,
error_out
));
}
struct
chan_type
{
struct
chan_type
{
char
*
key
;
char
*
key
;
struct
chan_ops
*
ops
;
struct
chan_ops
*
ops
;
...
...
arch/um/drivers/fd.c
View file @
41bc4d9b
...
@@ -15,6 +15,7 @@ struct fd_chan {
...
@@ -15,6 +15,7 @@ struct fd_chan {
int
fd
;
int
fd
;
int
raw
;
int
raw
;
struct
termios
tt
;
struct
termios
tt
;
char
str
[
sizeof
(
"1234567890
\0
"
)];
};
};
void
*
fd_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
void
*
fd_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
...
@@ -40,7 +41,7 @@ void *fd_init(char *str, int device, struct chan_opts *opts)
...
@@ -40,7 +41,7 @@ void *fd_init(char *str, int device, struct chan_opts *opts)
return
(
data
);
return
(
data
);
}
}
int
fd_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
fd_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
fd_chan
*
data
=
d
;
struct
fd_chan
*
data
=
d
;
...
@@ -48,6 +49,8 @@ int fd_open(int input, int output, int primary, void *d)
...
@@ -48,6 +49,8 @@ int fd_open(int input, int output, int primary, void *d)
tcgetattr
(
data
->
fd
,
&
data
->
tt
);
tcgetattr
(
data
->
fd
,
&
data
->
tt
);
raw
(
data
->
fd
,
0
);
raw
(
data
->
fd
,
0
);
}
}
sprintf
(
data
->
str
,
"%d"
,
data
->
fd
);
*
dev_out
=
data
->
str
;
return
(
data
->
fd
);
return
(
data
->
fd
);
}
}
...
@@ -69,6 +72,7 @@ int fd_console_write(int fd, const char *buf, int n, void *d)
...
@@ -69,6 +72,7 @@ int fd_console_write(int fd, const char *buf, int n, void *d)
}
}
struct
chan_ops
fd_ops
=
{
struct
chan_ops
fd_ops
=
{
type:
"fd"
,
init:
fd_init
,
init:
fd_init
,
open:
fd_open
,
open:
fd_open
,
close:
fd_close
,
close:
fd_close
,
...
...
arch/um/drivers/line.c
View file @
41bc4d9b
...
@@ -8,11 +8,13 @@
...
@@ -8,11 +8,13 @@
#include "linux/list.h"
#include "linux/list.h"
#include "linux/devfs_fs_kernel.h"
#include "linux/devfs_fs_kernel.h"
#include "asm/irq.h"
#include "asm/irq.h"
#include "asm/uaccess.h"
#include "chan_kern.h"
#include "chan_kern.h"
#include "irq_user.h"
#include "irq_user.h"
#include "line.h"
#include "line.h"
#include "kern.h"
#include "kern.h"
#include "user_util.h"
#include "user_util.h"
#include "kern_util.h"
#include "os.h"
#include "os.h"
#define LINE_BUFSIZE 4096
#define LINE_BUFSIZE 4096
...
@@ -281,7 +283,7 @@ void close_lines(struct line *lines, int nlines)
...
@@ -281,7 +283,7 @@ void close_lines(struct line *lines, int nlines)
close_chan
(
&
lines
[
i
].
chan_list
);
close_chan
(
&
lines
[
i
].
chan_list
);
}
}
void
line_setup
(
struct
line
*
lines
,
int
num
,
char
*
init
)
int
line_setup
(
struct
line
*
lines
,
int
num
,
char
*
init
,
int
all_allowed
)
{
{
int
i
,
n
;
int
i
,
n
;
char
*
end
;
char
*
end
;
...
@@ -292,12 +294,36 @@ void line_setup(struct line *lines, int num, char *init)
...
@@ -292,12 +294,36 @@ void line_setup(struct line *lines, int num, char *init)
if
(
*
end
!=
'='
){
if
(
*
end
!=
'='
){
printk
(
KERN_ERR
"line_setup failed to parse
\"
%s
\"\n
"
,
printk
(
KERN_ERR
"line_setup failed to parse
\"
%s
\"\n
"
,
init
);
init
);
return
;
return
(
1
)
;
}
}
init
=
end
;
init
=
end
;
}
}
init
++
;
init
++
;
if
(
n
==
-
1
){
if
((
n
>=
0
)
&&
(
n
>=
num
)){
printk
(
"line_setup - %d out of range ((0 ... %d) allowed)
\n
"
,
n
,
num
);
return
(
1
);
}
else
if
(
n
>=
0
){
if
(
lines
[
n
].
count
>
0
){
printk
(
"line_setup - device %d is open
\n
"
,
n
);
return
(
1
);
}
if
(
lines
[
n
].
init_pri
<=
INIT_ONE
){
lines
[
n
].
init_pri
=
INIT_ONE
;
if
(
!
strcmp
(
init
,
"none"
))
lines
[
n
].
valid
=
0
;
else
{
lines
[
n
].
init_str
=
init
;
lines
[
n
].
valid
=
1
;
}
}
}
else
if
(
!
all_allowed
){
printk
(
"line_setup - can't configure all devices from "
"mconsole
\n
"
);
return
(
1
);
}
else
{
for
(
i
=
0
;
i
<
num
;
i
++
){
for
(
i
=
0
;
i
<
num
;
i
++
){
if
(
lines
[
i
].
init_pri
<=
INIT_ALL
){
if
(
lines
[
i
].
init_pri
<=
INIT_ALL
){
lines
[
i
].
init_pri
=
INIT_ALL
;
lines
[
i
].
init_pri
=
INIT_ALL
;
...
@@ -309,14 +335,57 @@ void line_setup(struct line *lines, int num, char *init)
...
@@ -309,14 +335,57 @@ void line_setup(struct line *lines, int num, char *init)
}
}
}
}
}
}
else
if
(
lines
[
n
].
init_pri
<=
INIT_ONE
){
return
(
0
);
lines
[
n
].
init_pri
=
INIT_ONE
;
}
if
(
!
strcmp
(
init
,
"none"
))
lines
[
n
].
valid
=
0
;
else
{
int
line_config
(
struct
line
*
lines
,
int
num
,
char
*
str
)
lines
[
n
].
init_str
=
init
;
{
lines
[
n
].
valid
=
1
;
char
*
new
=
uml_strdup
(
str
);
}
if
(
new
==
NULL
){
printk
(
"line_config - uml_strdup failed
\n
"
);
return
(
-
ENOMEM
);
}
return
(
line_setup
(
lines
,
num
,
new
,
0
));
}
int
line_get_config
(
char
*
name
,
struct
line
*
lines
,
int
num
,
char
*
str
,
int
size
,
char
**
error_out
)
{
struct
line
*
line
;
char
*
end
;
int
dev
,
n
=
0
;
dev
=
simple_strtoul
(
name
,
&
end
,
0
);
if
((
*
end
!=
'\0'
)
||
(
end
==
name
)){
*
error_out
=
"line_setup failed to parse device number"
;
return
(
0
);
}
}
if
((
dev
<
0
)
||
(
dev
>=
num
)){
*
error_out
=
"device number of of range"
;
return
(
0
);
}
line
=
&
lines
[
dev
];
down
(
&
line
->
sem
);
if
(
!
line
->
valid
)
CONFIG_CHUNK
(
str
,
size
,
n
,
"none"
,
1
);
else
if
(
line
->
count
==
0
)
CONFIG_CHUNK
(
str
,
size
,
n
,
line
->
init_str
,
1
);
else
n
=
chan_config_string
(
&
line
->
chan_list
,
str
,
size
,
error_out
);
up
(
&
line
->
sem
);
return
(
n
);
}
int
line_remove
(
struct
line
*
lines
,
int
num
,
char
*
str
)
{
char
config
[
sizeof
(
"conxxxx=none
\0
"
)];
sprintf
(
config
,
"%s=none"
,
str
);
return
(
line_setup
(
lines
,
num
,
config
,
0
));
}
}
void
line_register_devfs
(
struct
lines
*
set
,
struct
line_driver
*
line_driver
,
void
line_register_devfs
(
struct
lines
*
set
,
struct
line_driver
*
line_driver
,
...
@@ -366,6 +435,8 @@ void line_register_devfs(struct lines *set, struct line_driver *line_driver,
...
@@ -366,6 +435,8 @@ void line_register_devfs(struct lines *set, struct line_driver *line_driver,
if
(
!
lines
[
i
].
valid
)
if
(
!
lines
[
i
].
valid
)
tty_unregister_devfs
(
driver
,
driver
->
minor_start
+
i
);
tty_unregister_devfs
(
driver
,
driver
->
minor_start
+
i
);
}
}
mconsole_register_dev
(
&
line_driver
->
mc
);
}
}
void
lines_init
(
struct
line
*
lines
,
int
nlines
)
void
lines_init
(
struct
line
*
lines
,
int
nlines
)
...
...
arch/um/drivers/mconsole_kern.c
View file @
41bc4d9b
...
@@ -108,6 +108,7 @@ void mconsole_version(struct mc_request *req)
...
@@ -108,6 +108,7 @@ void mconsole_version(struct mc_request *req)
reboot
-
Reboot
UML
reboot
-
Reboot
UML
config
<
dev
>=<
config
>
-
Add
a
new
device
to
UML
;
config
<
dev
>=<
config
>
-
Add
a
new
device
to
UML
;
same
syntax
as
command
line
same
syntax
as
command
line
config
<
dev
>
-
Query
the
configuration
of
a
device
remove
<
dev
>
-
Remove
a
device
from
UML
remove
<
dev
>
-
Remove
a
device
from
UML
sysrq
<
letter
>
-
Performs
the
SysRq
action
controlled
by
the
letter
sysrq
<
letter
>
-
Performs
the
SysRq
action
controlled
by
the
letter
cad
-
invoke
the
Ctl
-
Alt
-
Del
handler
cad
-
invoke
the
Ctl
-
Alt
-
Del
handler
...
@@ -181,10 +182,56 @@ static struct mc_device *mconsole_find_dev(char *name)
...
@@ -181,10 +182,56 @@ static struct mc_device *mconsole_find_dev(char *name)
return(NULL);
return(NULL);
}
}
#define CONFIG_BUF_SIZE 64
static void mconsole_get_config(int (*get_config)(char *, char *, int,
char **),
struct mc_request *req, char *name)
{
char default_buf[CONFIG_BUF_SIZE], *error, *buf;
int n, size;
if(get_config == NULL){
mconsole_reply(req, "
No
get_config
routine
defined
", 1, 0);
return;
}
error = NULL;
size = sizeof(default_buf)/sizeof(default_buf[0]);
buf = default_buf;
while(1){
n = (*get_config)(name, buf, size, &error);
if(error != NULL){
mconsole_reply(req, error, 1, 0);
goto out;
}
if(n <= size){
mconsole_reply(req, buf, 0, 0);
goto out;
}
if(buf != default_buf)
kfree(buf);
size = n;
buf = kmalloc(size, GFP_KERNEL);
if(buf == NULL){
mconsole_reply(req, "
Failed
to
allocate
buffer
", 1, 0);
return;
}
}
out:
if(buf != default_buf)
kfree(buf);
}
void mconsole_config(struct mc_request *req)
void mconsole_config(struct mc_request *req)
{
{
struct mc_device *dev;
struct mc_device *dev;
char *ptr = req->request.data;
char *ptr = req->request.data
, *name
;
int err;
int err;
ptr += strlen("
config
");
ptr += strlen("
config
");
...
@@ -194,8 +241,17 @@ void mconsole_config(struct mc_request *req)
...
@@ -194,8 +241,17 @@ void mconsole_config(struct mc_request *req)
mconsole_reply(req, "
Bad
configuration
option
", 1, 0);
mconsole_reply(req, "
Bad
configuration
option
", 1, 0);
return;
return;
}
}
err = (*dev->config)(&ptr[strlen(dev->name)]);
mconsole_reply(req, "", err, 0);
name = &ptr[strlen(dev->name)];
ptr = name;
while((*ptr != '=') && (*ptr != '
\0
'))
ptr++;
if(*ptr == '='){
err = (*dev->config)(name);
mconsole_reply(req, "", err, 0);
}
else mconsole_get_config(dev->get_config, req, name);
}
}
void mconsole_remove(struct mc_request *req)
void mconsole_remove(struct mc_request *req)
...
...
arch/um/drivers/null.c
View file @
41bc4d9b
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
* Licensed under the GPL
* Licensed under the GPL
*/
*/
#include <stdlib.h>
#include <errno.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include "chan_user.h"
#include "chan_user.h"
...
@@ -15,8 +16,9 @@ void *null_init(char *str, int device, struct chan_opts *opts)
...
@@ -15,8 +16,9 @@ void *null_init(char *str, int device, struct chan_opts *opts)
return
(
&
null_chan
);
return
(
&
null_chan
);
}
}
int
null_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
null_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
*
dev_out
=
NULL
;
return
(
os_open_file
(
DEV_NULL
,
of_rdwr
(
OPENFLAGS
()),
0
));
return
(
os_open_file
(
DEV_NULL
,
of_rdwr
(
OPENFLAGS
()),
0
));
}
}
...
@@ -30,6 +32,7 @@ void null_free(void *data)
...
@@ -30,6 +32,7 @@ void null_free(void *data)
}
}
struct
chan_ops
null_ops
=
{
struct
chan_ops
null_ops
=
{
type:
"null"
,
init:
null_init
,
init:
null_init
,
open:
null_open
,
open:
null_open
,
close:
generic_close
,
close:
generic_close
,
...
...
arch/um/drivers/port_user.c
View file @
41bc4d9b
...
@@ -3,11 +3,12 @@
...
@@ -3,11 +3,12 @@
* Licensed under the GPL
* Licensed under the GPL
*/
*/
#include <stdio.h>
#include <stddef.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <errno.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <termios.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/un.h>
...
@@ -24,6 +25,7 @@ struct port_chan {
...
@@ -24,6 +25,7 @@ struct port_chan {
int
raw
;
int
raw
;
struct
termios
tt
;
struct
termios
tt
;
void
*
kernel_data
;
void
*
kernel_data
;
char
dev
[
sizeof
(
"32768
\0
"
)];
};
};
void
*
port_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
void
*
port_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
...
@@ -50,11 +52,12 @@ void *port_init(char *str, int device, struct chan_opts *opts)
...
@@ -50,11 +52,12 @@ void *port_init(char *str, int device, struct chan_opts *opts)
if
((
data
=
um_kmalloc
(
sizeof
(
*
data
)))
==
NULL
)
return
(
NULL
);
if
((
data
=
um_kmalloc
(
sizeof
(
*
data
)))
==
NULL
)
return
(
NULL
);
*
data
=
((
struct
port_chan
)
{
raw
:
opts
->
raw
,
*
data
=
((
struct
port_chan
)
{
raw
:
opts
->
raw
,
kernel_data
:
kern_data
});
kernel_data
:
kern_data
});
sprintf
(
data
->
dev
,
"%d"
,
port
);
return
(
data
);
return
(
data
);
}
}
int
port_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
port_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
port_chan
*
data
=
d
;
struct
port_chan
*
data
=
d
;
int
fd
;
int
fd
;
...
@@ -64,6 +67,7 @@ int port_open(int input, int output, int primary, void *d)
...
@@ -64,6 +67,7 @@ int port_open(int input, int output, int primary, void *d)
tcgetattr
(
fd
,
&
data
->
tt
);
tcgetattr
(
fd
,
&
data
->
tt
);
raw
(
fd
,
0
);
raw
(
fd
,
0
);
}
}
*
dev_out
=
data
->
dev
;
return
(
fd
);
return
(
fd
);
}
}
...
@@ -91,6 +95,7 @@ void port_free(void *d)
...
@@ -91,6 +95,7 @@ void port_free(void *d)
}
}
struct
chan_ops
port_ops
=
{
struct
chan_ops
port_ops
=
{
type:
"port"
,
init:
port_init
,
init:
port_init
,
open:
port_open
,
open:
port_open
,
close:
port_close
,
close:
port_close
,
...
...
arch/um/drivers/pty.c
View file @
41bc4d9b
...
@@ -19,6 +19,7 @@ struct pty_chan {
...
@@ -19,6 +19,7 @@ struct pty_chan {
int
dev
;
int
dev
;
int
raw
;
int
raw
;
struct
termios
tt
;
struct
termios
tt
;
char
dev_name
[
sizeof
(
"/dev/pts/0123456
\0
"
)];
};
};
void
*
pty_chan_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
void
*
pty_chan_init
(
char
*
str
,
int
device
,
struct
chan_opts
*
opts
)
...
@@ -32,9 +33,10 @@ void *pty_chan_init(char *str, int device, struct chan_opts *opts)
...
@@ -32,9 +33,10 @@ void *pty_chan_init(char *str, int device, struct chan_opts *opts)
return
(
data
);
return
(
data
);
}
}
int
pts_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
pts_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
pty_chan
*
data
=
d
;
struct
pty_chan
*
data
=
d
;
char
*
dev
;
int
fd
;
int
fd
;
if
((
fd
=
get_pty
())
<
0
){
if
((
fd
=
get_pty
())
<
0
){
...
@@ -45,7 +47,11 @@ int pts_open(int input, int output, int primary, void *d)
...
@@ -45,7 +47,11 @@ int pts_open(int input, int output, int primary, void *d)
tcgetattr
(
fd
,
&
data
->
tt
);
tcgetattr
(
fd
,
&
data
->
tt
);
raw
(
fd
,
0
);
raw
(
fd
,
0
);
}
}
if
(
data
->
announce
)
(
*
data
->
announce
)(
ptsname
(
fd
),
data
->
dev
);
dev
=
ptsname
(
fd
);
sprintf
(
data
->
dev_name
,
"%s"
,
dev
);
*
dev_out
=
data
->
dev_name
;
if
(
data
->
announce
)
(
*
data
->
announce
)(
dev
,
data
->
dev
);
return
(
fd
);
return
(
fd
);
}
}
...
@@ -94,7 +100,7 @@ static void grantpt_cb(void *arg)
...
@@ -94,7 +100,7 @@ static void grantpt_cb(void *arg)
info
->
err
=
errno
;
info
->
err
=
errno
;
}
}
int
pty_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
pty_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
pty_chan
*
data
=
d
;
struct
pty_chan
*
data
=
d
;
int
fd
;
int
fd
;
...
@@ -110,6 +116,9 @@ int pty_open(int input, int output, int primary, void *d)
...
@@ -110,6 +116,9 @@ int pty_open(int input, int output, int primary, void *d)
if
(
data
->
raw
)
raw
(
fd
,
0
);
if
(
data
->
raw
)
raw
(
fd
,
0
);
if
(
data
->
announce
)
(
*
data
->
announce
)(
dev
,
data
->
dev
);
if
(
data
->
announce
)
(
*
data
->
announce
)(
dev
,
data
->
dev
);
sprintf
(
data
->
dev_name
,
"%s"
,
dev
);
*
dev_out
=
data
->
dev_name
;
return
(
fd
);
return
(
fd
);
}
}
...
@@ -121,6 +130,7 @@ int pty_console_write(int fd, const char *buf, int n, void *d)
...
@@ -121,6 +130,7 @@ int pty_console_write(int fd, const char *buf, int n, void *d)
}
}
struct
chan_ops
pty_ops
=
{
struct
chan_ops
pty_ops
=
{
type:
"pty"
,
init:
pty_chan_init
,
init:
pty_chan_init
,
open:
pty_open
,
open:
pty_open
,
close:
generic_close
,
close:
generic_close
,
...
@@ -133,6 +143,7 @@ struct chan_ops pty_ops = {
...
@@ -133,6 +143,7 @@ struct chan_ops pty_ops = {
};
};
struct
chan_ops
pts_ops
=
{
struct
chan_ops
pts_ops
=
{
type:
"pts"
,
init:
pty_chan_init
,
init:
pty_chan_init
,
open:
pts_open
,
open:
pts_open
,
close:
generic_close
,
close:
generic_close
,
...
...
arch/um/drivers/ssl.c
View file @
41bc4d9b
...
@@ -20,6 +20,7 @@
...
@@ -20,6 +20,7 @@
#include "kern.h"
#include "kern.h"
#include "init.h"
#include "init.h"
#include "irq_user.h"
#include "irq_user.h"
#include "mconsole_kern.h"
#include "2_5compat.h"
#include "2_5compat.h"
static
int
ssl_version
=
1
;
static
int
ssl_version
=
1
;
...
@@ -47,6 +48,10 @@ static struct chan_opts opts = {
...
@@ -47,6 +48,10 @@ static struct chan_opts opts = {
in_kernel
:
1
,
in_kernel
:
1
,
};
};
static
int
ssl_config
(
char
*
str
);
static
int
ssl_get_config
(
char
*
dev
,
char
*
str
,
int
size
,
char
**
error_out
);
static
int
ssl_remove
(
char
*
str
);
static
struct
line_driver
driver
=
{
static
struct
line_driver
driver
=
{
name
:
"UML serial line"
,
name
:
"UML serial line"
,
devfs_name
:
"tts/%d"
,
devfs_name
:
"tts/%d"
,
...
@@ -60,6 +65,12 @@ static struct line_driver driver = {
...
@@ -60,6 +65,12 @@ static struct line_driver driver = {
write_irq_name
:
"ssl-write"
,
write_irq_name
:
"ssl-write"
,
symlink_from
:
"serial"
,
symlink_from
:
"serial"
,
symlink_to
:
"tts"
,
symlink_to
:
"tts"
,
mc
:
{
name
:
"ssl"
,
config
:
ssl_config
,
get_config
:
ssl_get_config
,
remove
:
ssl_remove
,
},
};
};
/* The array is initialized by line_init, which is an initcall. The
/* The array is initialized by line_init, which is an initcall. The
...
@@ -70,6 +81,25 @@ static struct line serial_lines[NR_PORTS] =
...
@@ -70,6 +81,25 @@ static struct line serial_lines[NR_PORTS] =
static
struct
lines
lines
=
LINES_INIT
(
NR_PORTS
);
static
struct
lines
lines
=
LINES_INIT
(
NR_PORTS
);
static
int
ssl_config
(
char
*
str
)
{
return
(
line_config
(
serial_lines
,
sizeof
(
serial_lines
)
/
sizeof
(
serial_lines
[
0
]),
str
));
}
static
int
ssl_get_config
(
char
*
dev
,
char
*
str
,
int
size
,
char
**
error_out
)
{
return
(
line_get_config
(
dev
,
serial_lines
,
sizeof
(
serial_lines
)
/
sizeof
(
serial_lines
[
0
]),
str
,
size
,
error_out
));
}
static
int
ssl_remove
(
char
*
str
)
{
return
(
line_remove
(
serial_lines
,
sizeof
(
serial_lines
)
/
sizeof
(
serial_lines
[
0
]),
str
));
}
int
ssl_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
int
ssl_open
(
struct
tty_struct
*
tty
,
struct
file
*
filp
)
{
{
return
(
line_open
(
serial_lines
,
tty
,
&
opts
));
return
(
line_open
(
serial_lines
,
tty
,
&
opts
));
...
@@ -207,7 +237,7 @@ __initcall(ssl_init);
...
@@ -207,7 +237,7 @@ __initcall(ssl_init);
static
int
ssl_chan_setup
(
char
*
str
)
static
int
ssl_chan_setup
(
char
*
str
)
{
{
line_setup
(
serial_lines
,
sizeof
(
serial_lines
)
/
sizeof
(
serial_lines
[
0
]),
line_setup
(
serial_lines
,
sizeof
(
serial_lines
)
/
sizeof
(
serial_lines
[
0
]),
str
);
str
,
1
);
return
(
1
);
return
(
1
);
}
}
...
...
arch/um/drivers/stdio_console.c
View file @
41bc4d9b
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include "user_util.h"
#include "user_util.h"
#include "kern_util.h"
#include "kern_util.h"
#include "irq_user.h"
#include "irq_user.h"
#include "mconsole_kern.h"
#include "init.h"
#include "init.h"
#include "2_5compat.h"
#include "2_5compat.h"
...
@@ -41,6 +42,7 @@ static struct tty_driver console_driver;
...
@@ -41,6 +42,7 @@ static struct tty_driver console_driver;
static
int
console_refcount
=
0
;
static
int
console_refcount
=
0
;
static
struct
chan_ops
init_console_ops
=
{
static
struct
chan_ops
init_console_ops
=
{
type:
"you shouldn't see this"
,
init
:
NULL
,
init
:
NULL
,
open
:
NULL
,
open
:
NULL
,
close
:
NULL
,
close
:
NULL
,
...
@@ -78,6 +80,10 @@ static struct chan_opts opts = {
...
@@ -78,6 +80,10 @@ static struct chan_opts opts = {
in_kernel
:
1
,
in_kernel
:
1
,
};
};
static
int
con_config
(
char
*
str
);
static
int
con_get_config
(
char
*
dev
,
char
*
str
,
int
size
,
char
**
error_out
);
static
int
con_remove
(
char
*
str
);
static
struct
line_driver
driver
=
{
static
struct
line_driver
driver
=
{
name
:
"UML console"
,
name
:
"UML console"
,
devfs_name
:
"vc/%d"
,
devfs_name
:
"vc/%d"
,
...
@@ -91,6 +97,12 @@ static struct line_driver driver = {
...
@@ -91,6 +97,12 @@ static struct line_driver driver = {
write_irq_name
:
"console-write"
,
write_irq_name
:
"console-write"
,
symlink_from
:
"ttys"
,
symlink_from
:
"ttys"
,
symlink_to
:
"vc"
,
symlink_to
:
"vc"
,
mc
:
{
name
:
"con"
,
config
:
con_config
,
get_config
:
con_get_config
,
remove
:
con_remove
,
},
};
};
static
struct
lines
console_lines
=
LINES_INIT
(
MAX_TTYS
);
static
struct
lines
console_lines
=
LINES_INIT
(
MAX_TTYS
);
...
@@ -102,6 +114,22 @@ struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
...
@@ -102,6 +114,22 @@ struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver),
[
1
...
MAX_TTYS
-
1
]
=
[
1
...
MAX_TTYS
-
1
]
=
LINE_INIT
(
CONFIG_CON_CHAN
,
&
driver
)
};
LINE_INIT
(
CONFIG_CON_CHAN
,
&
driver
)
};
static
int
con_config
(
char
*
str
)
{
return
(
line_config
(
vts
,
sizeof
(
vts
)
/
sizeof
(
vts
[
0
]),
str
));
}
static
int
con_get_config
(
char
*
dev
,
char
*
str
,
int
size
,
char
**
error_out
)
{
return
(
line_get_config
(
dev
,
vts
,
sizeof
(
vts
)
/
sizeof
(
vts
[
0
]),
str
,
size
,
error_out
));
}
static
int
con_remove
(
char
*
str
)
{
return
(
line_remove
(
vts
,
sizeof
(
vts
)
/
sizeof
(
vts
[
0
]),
str
));
}
static
int
open_console
(
struct
tty_struct
*
tty
)
static
int
open_console
(
struct
tty_struct
*
tty
)
{
{
return
(
line_open
(
vts
,
tty
,
&
opts
));
return
(
line_open
(
vts
,
tty
,
&
opts
));
...
@@ -195,7 +223,7 @@ void stdio_console_init(void)
...
@@ -195,7 +223,7 @@ void stdio_console_init(void)
static
int
console_chan_setup
(
char
*
str
)
static
int
console_chan_setup
(
char
*
str
)
{
{
line_setup
(
vts
,
sizeof
(
vts
)
/
sizeof
(
vts
[
0
]),
str
);
line_setup
(
vts
,
sizeof
(
vts
)
/
sizeof
(
vts
[
0
]),
str
,
1
);
return
(
1
);
return
(
1
);
}
}
...
...
arch/um/drivers/tty.c
View file @
41bc4d9b
...
@@ -30,14 +30,15 @@ void *tty_chan_init(char *str, int device, struct chan_opts *opts)
...
@@ -30,14 +30,15 @@ void *tty_chan_init(char *str, int device, struct chan_opts *opts)
}
}
str
++
;
str
++
;
if
((
data
=
um_kmalloc
(
sizeof
(
*
data
)))
==
NULL
)
return
(
NULL
);
if
((
data
=
um_kmalloc
(
sizeof
(
*
data
)))
==
NULL
)
return
(
NULL
);
*
data
=
((
struct
tty_chan
)
{
dev
:
str
,
*
data
=
((
struct
tty_chan
)
{
dev
:
str
,
raw
:
opts
->
raw
});
raw
:
opts
->
raw
});
return
(
data
);
return
(
data
);
}
}
int
tty_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
tty_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
tty_chan
*
data
=
d
;
struct
tty_chan
*
data
=
d
;
int
fd
;
int
fd
;
...
@@ -48,6 +49,8 @@ int tty_open(int input, int output, int primary, void *d)
...
@@ -48,6 +49,8 @@ int tty_open(int input, int output, int primary, void *d)
tcgetattr
(
fd
,
&
data
->
tt
);
tcgetattr
(
fd
,
&
data
->
tt
);
raw
(
fd
,
0
);
raw
(
fd
,
0
);
}
}
*
dev_out
=
data
->
dev
;
return
(
fd
);
return
(
fd
);
}
}
...
@@ -59,6 +62,7 @@ int tty_console_write(int fd, const char *buf, int n, void *d)
...
@@ -59,6 +62,7 @@ int tty_console_write(int fd, const char *buf, int n, void *d)
}
}
struct
chan_ops
tty_ops
=
{
struct
chan_ops
tty_ops
=
{
type:
"tty"
,
init:
tty_chan_init
,
init:
tty_chan_init
,
open:
tty_open
,
open:
tty_open
,
close:
generic_close
,
close:
generic_close
,
...
...
arch/um/drivers/ubd_kern.c
View file @
41bc4d9b
...
@@ -574,6 +574,44 @@ static int ubd_config(char *str)
...
@@ -574,6 +574,44 @@ static int ubd_config(char *str)
return
(
err
);
return
(
err
);
}
}
static
int
ubd_get_config
(
char
*
dev
,
char
*
str
,
int
size
,
char
**
error_out
)
{
struct
ubd
*
ubd
;
char
*
end
;
int
major
,
n
=
0
;
major
=
simple_strtoul
(
dev
,
&
end
,
0
);
if
((
*
end
!=
'\0'
)
||
(
end
==
dev
)){
*
error_out
=
"ubd_get_config : didn't parse major number"
;
return
(
-
1
);
}
if
((
major
>=
MAX_DEV
)
||
(
major
<
0
)){
*
error_out
=
"ubd_get_config : major number out of range"
;
return
(
-
1
);
}
ubd
=
&
ubd_dev
[
major
];
spin_lock
(
&
ubd_lock
);
if
(
ubd
->
file
==
NULL
){
CONFIG_CHUNK
(
str
,
size
,
n
,
""
,
1
);
goto
out
;
}
CONFIG_CHUNK
(
str
,
size
,
n
,
ubd
->
file
,
0
);
if
(
ubd
->
cow
.
file
!=
NULL
){
CONFIG_CHUNK
(
str
,
size
,
n
,
","
,
0
);
CONFIG_CHUNK
(
str
,
size
,
n
,
ubd
->
cow
.
file
,
1
);
}
else
CONFIG_CHUNK
(
str
,
size
,
n
,
""
,
1
);
out:
spin_unlock
(
&
ubd_lock
);
return
(
n
);
}
static
int
ubd_remove
(
char
*
str
)
static
int
ubd_remove
(
char
*
str
)
{
{
struct
ubd
*
dev
;
struct
ubd
*
dev
;
...
@@ -620,6 +658,7 @@ static int ubd_remove(char *str)
...
@@ -620,6 +658,7 @@ static int ubd_remove(char *str)
static
struct
mc_device
ubd_mc
=
{
static
struct
mc_device
ubd_mc
=
{
.
name
=
"ubd"
,
.
name
=
"ubd"
,
.
config
=
ubd_config
,
.
config
=
ubd_config
,
.
get_config
=
ubd_get_config
,
.
remove
=
ubd_remove
,
.
remove
=
ubd_remove
,
};
};
...
...
arch/um/drivers/xterm.c
View file @
41bc4d9b
...
@@ -83,7 +83,7 @@ __uml_setup("xterm=", xterm_setup,
...
@@ -83,7 +83,7 @@ __uml_setup("xterm=", xterm_setup,
" are 'xterm=gnome-terminal,-t,-x'.
\n\n
"
" are 'xterm=gnome-terminal,-t,-x'.
\n\n
"
);
);
int
xterm_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
)
int
xterm_open
(
int
input
,
int
output
,
int
primary
,
void
*
d
,
char
**
dev_out
)
{
{
struct
xterm_chan
*
data
=
d
;
struct
xterm_chan
*
data
=
d
;
unsigned
long
stack
;
unsigned
long
stack
;
...
@@ -141,6 +141,7 @@ int xterm_open(int input, int output, int primary, void *d)
...
@@ -141,6 +141,7 @@ int xterm_open(int input, int output, int primary, void *d)
if
(
data
->
raw
)
raw
(
new
,
0
);
if
(
data
->
raw
)
raw
(
new
,
0
);
data
->
pid
=
pid
;
data
->
pid
=
pid
;
*
dev_out
=
NULL
;
return
(
new
);
return
(
new
);
}
}
...
@@ -168,6 +169,7 @@ int xterm_console_write(int fd, const char *buf, int n, void *d)
...
@@ -168,6 +169,7 @@ int xterm_console_write(int fd, const char *buf, int n, void *d)
}
}
struct
chan_ops
xterm_ops
=
{
struct
chan_ops
xterm_ops
=
{
type:
"xterm"
,
init:
xterm_init
,
init:
xterm_init
,
open:
xterm_open
,
open:
xterm_open
,
close:
xterm_close
,
close:
xterm_close
,
...
...
arch/um/include/chan_kern.h
View file @
41bc4d9b
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
struct
chan
{
struct
chan
{
struct
list_head
list
;
struct
list_head
list
;
char
*
dev
;
unsigned
int
primary
:
1
;
unsigned
int
primary
:
1
;
unsigned
int
input
:
1
;
unsigned
int
input
:
1
;
unsigned
int
output
:
1
;
unsigned
int
output
:
1
;
...
@@ -38,6 +39,8 @@ extern int chan_window_size(struct list_head *chans,
...
@@ -38,6 +39,8 @@ extern int chan_window_size(struct list_head *chans,
unsigned
short
*
rows_out
,
unsigned
short
*
rows_out
,
unsigned
short
*
cols_out
);
unsigned
short
*
cols_out
);
extern
int
chan_out_fd
(
struct
list_head
*
chans
);
extern
int
chan_out_fd
(
struct
list_head
*
chans
);
extern
int
chan_config_string
(
struct
list_head
*
chans
,
char
*
str
,
int
size
,
char
**
error_out
);
#endif
#endif
...
...
arch/um/include/chan_user.h
View file @
41bc4d9b
...
@@ -19,8 +19,9 @@ struct chan_opts {
...
@@ -19,8 +19,9 @@ struct chan_opts {
enum
chan_init_pri
{
INIT_STATIC
,
INIT_ALL
,
INIT_ONE
};
enum
chan_init_pri
{
INIT_STATIC
,
INIT_ALL
,
INIT_ONE
};
struct
chan_ops
{
struct
chan_ops
{
char
*
type
;
void
*
(
*
init
)(
char
*
,
int
,
struct
chan_opts
*
);
void
*
(
*
init
)(
char
*
,
int
,
struct
chan_opts
*
);
int
(
*
open
)(
int
,
int
,
int
,
void
*
);
int
(
*
open
)(
int
,
int
,
int
,
void
*
,
char
**
);
void
(
*
close
)(
int
,
void
*
);
void
(
*
close
)(
int
,
void
*
);
int
(
*
read
)(
int
,
char
*
,
void
*
);
int
(
*
read
)(
int
,
char
*
,
void
*
);
int
(
*
write
)(
int
,
const
char
*
,
int
,
void
*
);
int
(
*
write
)(
int
,
const
char
*
,
int
,
void
*
);
...
...
arch/um/include/line.h
View file @
41bc4d9b
...
@@ -11,6 +11,7 @@
...
@@ -11,6 +11,7 @@
#include "linux/tty.h"
#include "linux/tty.h"
#include "asm/semaphore.h"
#include "asm/semaphore.h"
#include "chan_user.h"
#include "chan_user.h"
#include "mconsole_kern.h"
struct
line_driver
{
struct
line_driver
{
char
*
name
;
char
*
name
;
...
@@ -25,6 +26,7 @@ struct line_driver {
...
@@ -25,6 +26,7 @@ struct line_driver {
char
*
write_irq_name
;
char
*
write_irq_name
;
char
*
symlink_from
;
char
*
symlink_from
;
char
*
symlink_to
;
char
*
symlink_to
;
struct
mc_device
mc
;
};
};
struct
line
{
struct
line
{
...
@@ -70,8 +72,9 @@ extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
...
@@ -70,8 +72,9 @@ extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
extern
void
line_close
(
struct
line
*
lines
,
struct
tty_struct
*
tty
);
extern
void
line_close
(
struct
line
*
lines
,
struct
tty_struct
*
tty
);
extern
int
line_open
(
struct
line
*
lines
,
struct
tty_struct
*
tty
,
extern
int
line_open
(
struct
line
*
lines
,
struct
tty_struct
*
tty
,
struct
chan_opts
*
opts
);
struct
chan_opts
*
opts
);
extern
void
line_setup
(
struct
line
*
lines
,
int
num
,
char
*
init
);
extern
int
line_setup
(
struct
line
*
lines
,
int
num
,
char
*
init
,
extern
int
line_write
(
struct
line
*
line
,
struct
tty_struct
*
tty
,
int
all_allowed
);
extern
int
line_write
(
struct
line
*
line
,
struct
tty_struct
*
tty
,
const
char
*
buf
,
int
len
);
const
char
*
buf
,
int
len
);
extern
int
line_write_room
(
struct
tty_struct
*
tty
);
extern
int
line_write_room
(
struct
tty_struct
*
tty
);
extern
char
*
add_xterm_umid
(
char
*
base
);
extern
char
*
add_xterm_umid
(
char
*
base
);
...
@@ -84,6 +87,10 @@ extern void line_register_devfs(struct lines *set,
...
@@ -84,6 +87,10 @@ extern void line_register_devfs(struct lines *set,
int
nlines
);
int
nlines
);
extern
void
lines_init
(
struct
line
*
lines
,
int
nlines
);
extern
void
lines_init
(
struct
line
*
lines
,
int
nlines
);
extern
void
close_lines
(
struct
line
*
lines
,
int
nlines
);
extern
void
close_lines
(
struct
line
*
lines
,
int
nlines
);
extern
int
line_config
(
struct
line
*
lines
,
int
num
,
char
*
str
);
extern
int
line_remove
(
struct
line
*
lines
,
int
num
,
char
*
str
);
extern
int
line_get_config
(
char
*
dev
,
struct
line
*
lines
,
int
num
,
char
*
str
,
int
size
,
char
**
error_out
);
#endif
#endif
...
...
arch/um/include/mconsole_kern.h
View file @
41bc4d9b
/*
/*
* Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
* Copyright (C) 2001
, 2002
Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
* Licensed under the GPL
*/
*/
...
@@ -19,9 +19,23 @@ struct mc_device {
...
@@ -19,9 +19,23 @@ struct mc_device {
struct
list_head
list
;
struct
list_head
list
;
char
*
name
;
char
*
name
;
int
(
*
config
)(
char
*
);
int
(
*
config
)(
char
*
);
int
(
*
get_config
)(
char
*
,
char
*
,
int
,
char
**
);
int
(
*
remove
)(
char
*
);
int
(
*
remove
)(
char
*
);
};
};
#define CONFIG_CHUNK(str, size, current, chunk, end) \
do { \
current += strlen(chunk); \
if(current >= size) \
str = NULL; \
if(str != NULL){ \
strcpy(str, chunk); \
str += strlen(chunk); \
} \
if(end) \
current++; \
} while(0)
#ifdef CONFIG_MCONSOLE
#ifdef CONFIG_MCONSOLE
extern
void
mconsole_register_dev
(
struct
mc_device
*
new
);
extern
void
mconsole_register_dev
(
struct
mc_device
*
new
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment