1 /* $NetBSD: arcbios_tty.c,v 1.19 2007/11/19 18:51:45 ad Exp $ */
4 * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
7 * Author: Chris G. Demetriou
9 * Permission to use, copy, modify and distribute this software and
10 * its documentation is hereby granted, provided that both the copyright
11 * notice and this permission notice appear in all copies of the
12 * software, derivative works or modified versions, and any portions
13 * thereof, and that both notices appear in supporting documentation.
15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
19 * Carnegie Mellon requests users of this software to return to
21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
22 * School of Computer Science
23 * Carnegie Mellon University
24 * Pittsburgh PA 15213-3890
26 * any improvements or extensions that they make and grant Carnegie the
27 * rights to redistribute these changes.
30 #include <sys/cdefs.h>
31 __KERNEL_RCSID(0, "$NetBSD: arcbios_tty.c,v 1.19 2007/11/19 18:51:45 ad Exp $");
33 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/callout.h>
37 #include <sys/kernel.h>
41 #include <sys/termios.h>
42 #include <sys/kauth.h>
46 #include <dev/arcbios/arcbios.h>
47 #include <dev/arcbios/arcbiosvar.h>
49 callout_t arcbios_tty_ch
;
51 static struct tty
*arcbios_tty
[1];
53 void arcbios_tty_start(struct tty
*);
54 void arcbios_tty_poll(void *);
55 int arcbios_tty_param(struct tty
*, struct termios
*);
57 dev_type_open(arcbios_ttyopen
);
58 dev_type_close(arcbios_ttyclose
);
59 dev_type_read(arcbios_ttyread
);
60 dev_type_write(arcbios_ttywrite
);
61 dev_type_ioctl(arcbios_ttyioctl
);
62 dev_type_stop(arcbios_ttystop
);
63 dev_type_tty(arcbios_ttytty
);
64 dev_type_poll(arcbios_ttypoll
);
66 const struct cdevsw arcbios_cdevsw
= {
67 arcbios_ttyopen
, arcbios_ttyclose
, arcbios_ttyread
, arcbios_ttywrite
,
68 arcbios_ttyioctl
, arcbios_ttystop
, arcbios_ttytty
, arcbios_ttypoll
,
69 nommap
, ttykqfilter
, D_TTY
,
73 arcbios_ttyopen(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
75 int unit
= minor(dev
);
77 int s
, error
= 0, setuptimeout
= 0;
79 if (!arcbios_ch_init
) {
80 arcbios_ch_init
= true;
81 callout_init(&arcbios_tty_ch
, 0);
89 if (arcbios_tty
[unit
] == NULL
) {
90 tp
= arcbios_tty
[unit
] = ttymalloc();
93 tp
= arcbios_tty
[unit
];
95 tp
->t_oproc
= arcbios_tty_start
;
96 tp
->t_param
= arcbios_tty_param
;
99 if (kauth_authorize_device_tty(l
->l_cred
, KAUTH_DEVICE_TTY_OPEN
, tp
)) {
104 if ((tp
->t_state
& TS_ISOPEN
) == 0) {
105 tp
->t_state
|= TS_CARR_ON
;
107 tp
->t_iflag
= TTYDEF_IFLAG
;
108 tp
->t_oflag
= TTYDEF_OFLAG
;
109 tp
->t_cflag
= TTYDEF_CFLAG
| CLOCAL
;
110 tp
->t_lflag
= TTYDEF_LFLAG
;
111 tp
->t_ispeed
= tp
->t_ospeed
= 9600;
119 error
= (*tp
->t_linesw
->l_open
)(dev
, tp
);
120 if (error
== 0 && setuptimeout
)
121 callout_reset(&arcbios_tty_ch
, 1, arcbios_tty_poll
, tp
);
127 arcbios_ttyclose(dev_t dev
, int flag
, int mode
, struct lwp
*l
)
129 int unit
= minor(dev
);
130 struct tty
*tp
= arcbios_tty
[unit
];
132 callout_stop(&arcbios_tty_ch
);
133 (*tp
->t_linesw
->l_close
)(tp
, flag
);
139 arcbios_ttyread(dev_t dev
, struct uio
*uio
, int flag
)
141 struct tty
*tp
= arcbios_tty
[minor(dev
)];
143 return ((*tp
->t_linesw
->l_read
)(tp
, uio
, flag
));
147 arcbios_ttywrite(dev_t dev
, struct uio
*uio
, int flag
)
149 struct tty
*tp
= arcbios_tty
[minor(dev
)];
151 return ((*tp
->t_linesw
->l_write
)(tp
, uio
, flag
));
155 arcbios_ttypoll(dev_t dev
, int events
, struct lwp
*l
)
157 struct tty
*tp
= arcbios_tty
[minor(dev
)];
159 return ((*tp
->t_linesw
->l_poll
)(tp
, events
, l
));
163 arcbios_ttyioctl(dev_t dev
, u_long cmd
, void *data
, int flag
, struct lwp
*l
)
165 int unit
= minor(dev
);
166 struct tty
*tp
= arcbios_tty
[unit
];
169 error
= (*tp
->t_linesw
->l_ioctl
)(tp
, cmd
, data
, flag
, l
);
170 if (error
!= EPASSTHROUGH
)
172 return (ttioctl(tp
, cmd
, data
, flag
, l
));
176 arcbios_tty_param(struct tty
*tp
, struct termios
*t
)
183 arcbios_tty_start(struct tty
*tp
)
189 if (tp
->t_state
& (TS_TTSTOP
| TS_BUSY
))
192 tp
->t_state
|= TS_BUSY
;
193 while (tp
->t_outq
.c_cc
!= 0) {
194 (*ARCBIOS
->Write
)(ARCBIOS_STDOUT
, tp
->t_outq
.c_cf
,
195 ndqb(&tp
->t_outq
, 0), &count
);
196 ndflush(&tp
->t_outq
, count
);
198 tp
->t_state
&= ~TS_BUSY
;
204 arcbios_ttystop(struct tty
*tp
, int flag
)
209 if (tp
->t_state
& TS_BUSY
)
210 if ((tp
->t_state
& TS_TTSTOP
) == 0)
211 tp
->t_state
|= TS_FLUSH
;
216 arcbios_tty_getchar(int *cp
)
222 q
= ARCBIOS
->GetReadStatus(ARCBIOS_STDIN
);
225 ARCBIOS
->Read(ARCBIOS_STDIN
, &c
, 1, &count
);
235 arcbios_tty_poll(void *v
)
240 while (arcbios_tty_getchar(&c
)) {
241 if (tp
->t_state
& TS_ISOPEN
)
242 l_r
= (*tp
->t_linesw
->l_rint
)(c
, tp
);
244 callout_reset(&arcbios_tty_ch
, 1, arcbios_tty_poll
, tp
);
248 arcbios_ttytty(dev_t dev
)
252 panic("arcbios_ttytty: bogus");
254 return (arcbios_tty
[0]);