Sun Jan 12 12:21:16 2014 UTC ()
Pull up following revision(s) (requested by tsutsui in ticket #1004):
	sys/arch/luna68k/dev/siotty.c: revision 1.35
	sys/arch/luna68k/dev/siotty.c: revision 1.36
	sys/arch/luna68k/dev/siotty.c: revision 1.37
	sys/arch/luna68k/dev/siotty.c: revision 1.38
	sys/arch/luna68k/dev/lunaws.c: revision 1.25
	sys/arch/luna68k/dev/lunaws.c: revision 1.26
	sys/arch/luna68k/dev/lunaws.c: revision 1.27
	sys/arch/luna68k/dev/siovar.h: revision 1.7
	sys/arch/luna68k/dev/siotty.c: revision 1.34
struct device * -> device_t, use device_xname()  (from chs@)
Whitespace cleanup.
Use softint(9) to pass received data into wskbd(9) and wsmouse(9) layers.
It might be problematic to call them from an interrupt handler at IPL_SERIAL.
Tab/space cleanup.
Use softint(9) properly to process TX/RX data between tty(4) layer.
It could cause possible locking issue to call tty(4) layer functions
from IPL_SERIAL interrupt handlers.
Changes details (mostly similar to com(4) and z8530tty(4)):
 - allocate RX buffer and put data and status into it in the interrupt handler
 - call t_linesw->l_rint from the software interrupt handler
 - set the only first byte in siottystart() and use t_outq buffer to send
   multiple TX data
 - call the next t_linesw->l_start on TX complete in the software interrupt
   handler
Also put more changes:
 - handle cnmagic(9) properly (now entering ddb(4) by console BREAK works)
 - allocate tty in the attach function as other drivers rather than first open
 - use proper variable types
Remove initialization of unused t_softc in struct tty (to make pullup easier).


(bouyer)
diff -r1.23.8.1 -r1.23.8.2 src/sys/arch/luna68k/dev/lunaws.c
diff -r1.33 -r1.33.4.1 src/sys/arch/luna68k/dev/siotty.c
diff -r1.6 -r1.6.8.1 src/sys/arch/luna68k/dev/siovar.h

cvs diff -r1.23.8.1 -r1.23.8.2 src/sys/arch/luna68k/dev/lunaws.c (expand / switch to unified diff)

--- src/sys/arch/luna68k/dev/lunaws.c 2012/07/25 21:30:35 1.23.8.1
+++ src/sys/arch/luna68k/dev/lunaws.c 2014/01/12 12:21:16 1.23.8.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lunaws.c,v 1.23.8.1 2012/07/25 21:30:35 martin Exp $ */ 1/* $NetBSD: lunaws.c,v 1.23.8.2 2014/01/12 12:21:16 bouyer Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura. 8 * by Tohru Nishimura.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,65 +21,73 @@ @@ -21,65 +21,73 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
33 33
34__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.23.8.1 2012/07/25 21:30:35 martin Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: lunaws.c,v 1.23.8.2 2014/01/12 12:21:16 bouyer Exp $");
35 35
36#include "wsmouse.h" 36#include "wsmouse.h"
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/conf.h> 40#include <sys/conf.h>
41#include <sys/device.h> 41#include <sys/device.h>
42 42
43#include <dev/wscons/wsconsio.h> 43#include <dev/wscons/wsconsio.h>
44#include <dev/wscons/wskbdvar.h> 44#include <dev/wscons/wskbdvar.h>
45#include <dev/wscons/wsksymdef.h> 45#include <dev/wscons/wsksymdef.h>
46#include <dev/wscons/wsksymvar.h> 46#include <dev/wscons/wsksymvar.h>
47#include <dev/wscons/wsmousevar.h> 47#include <dev/wscons/wsmousevar.h>
48 48
49#include <luna68k/dev/sioreg.h> 49#include <luna68k/dev/sioreg.h>
50#include <luna68k/dev/siovar.h> 50#include <luna68k/dev/siovar.h>
51 51
52#include "ioconf.h" 52#include "ioconf.h"
53 53
 54#define OMKBD_RXQ_LEN 64
 55#define OMKBD_RXQ_LEN_MASK (OMKBD_RXQ_LEN - 1)
 56#define OMKBD_NEXTRXQ(x) (((x) + 1) & OMKBD_RXQ_LEN_MASK)
 57
54static const uint8_t ch1_regs[6] = { 58static const uint8_t ch1_regs[6] = {
55 WR0_RSTINT, /* Reset E/S Interrupt */ 59 WR0_RSTINT, /* Reset E/S Interrupt */
56 WR1_RXALLS, /* Rx per char, No Tx */ 60 WR1_RXALLS, /* Rx per char, No Tx */
57 0, /* */ 61 0, /* */
58 WR3_RX8BIT | WR3_RXENBL, /* Rx */ 62 WR3_RX8BIT | WR3_RXENBL, /* Rx */
59 WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */ 63 WR4_BAUD96 | WR4_STOP1 | WR4_NPARITY, /* Tx/Rx */
60 WR5_TX8BIT | WR5_TXENBL, /* Tx */ 64 WR5_TX8BIT | WR5_TXENBL, /* Tx */
61}; 65};
62 66
63struct ws_softc { 67struct ws_softc {
64 device_t sc_dev; 68 device_t sc_dev;
65 struct sioreg *sc_ctl; 69 struct sioreg *sc_ctl;
66 uint8_t sc_wr[6]; 70 uint8_t sc_wr[6];
67 struct device *sc_wskbddev; 71 device_t sc_wskbddev;
 72 uint8_t sc_rxq[OMKBD_RXQ_LEN];
 73 u_int sc_rxqhead;
 74 u_int sc_rxqtail;
68#if NWSMOUSE > 0 75#if NWSMOUSE > 0
69 struct device *sc_wsmousedev; 76 device_t sc_wsmousedev;
70 int sc_msreport; 77 int sc_msreport;
71 int buttons, dx, dy; 78 int sc_msbuttons, sc_msdx, sc_msdy;
72#endif 79#endif
 80 void *sc_si;
73}; 81};
74 82
75static void omkbd_input(void *, int); 83static void omkbd_input(void *, int);
76static int omkbd_decode(void *, int, u_int *, int *); 84static int omkbd_decode(void *, int, u_int *, int *);
77static int omkbd_enable(void *, int); 85static int omkbd_enable(void *, int);
78static void omkbd_set_leds(void *, int); 86static void omkbd_set_leds(void *, int);
79static int omkbd_ioctl(void *, u_long, void *, int, struct lwp *); 87static int omkbd_ioctl(void *, u_long, void *, int, struct lwp *);
80 88
81struct wscons_keydesc omkbd_keydesctab[]; 89struct wscons_keydesc omkbd_keydesctab[];
82 90
83static const struct wskbd_mapdata omkbd_keymapdata = { 91static const struct wskbd_mapdata omkbd_keymapdata = {
84 omkbd_keydesctab, 92 omkbd_keydesctab,
85 KB_JP, 93 KB_JP,
@@ -101,26 +109,27 @@ static const struct wskbd_consops ws_con @@ -101,26 +109,27 @@ static const struct wskbd_consops ws_con
101#if NWSMOUSE > 0 109#if NWSMOUSE > 0
102static int omms_enable(void *); 110static int omms_enable(void *);
103static int omms_ioctl(void *, u_long, void *, int, struct lwp *); 111static int omms_ioctl(void *, u_long, void *, int, struct lwp *);
104static void omms_disable(void *); 112static void omms_disable(void *);
105 113
106static const struct wsmouse_accessops omms_accessops = { 114static const struct wsmouse_accessops omms_accessops = {
107 omms_enable, 115 omms_enable,
108 omms_ioctl, 116 omms_ioctl,
109 omms_disable, 117 omms_disable,
110}; 118};
111#endif 119#endif
112 120
113static void wsintr(int); 121static void wsintr(int);
 122static void wssoftintr(void *);
114 123
115static int wsmatch(device_t, cfdata_t, void *); 124static int wsmatch(device_t, cfdata_t, void *);
116static void wsattach(device_t, device_t, void *); 125static void wsattach(device_t, device_t, void *);
117 126
118CFATTACH_DECL_NEW(ws, sizeof(struct ws_softc), 127CFATTACH_DECL_NEW(ws, sizeof(struct ws_softc),
119 wsmatch, wsattach, NULL, NULL); 128 wsmatch, wsattach, NULL, NULL);
120 129
121extern int syscngetc(dev_t); 130extern int syscngetc(dev_t);
122extern void syscnputc(dev_t, int); 131extern void syscnputc(dev_t, int);
123 132
124static int 133static int
125wsmatch(device_t parent, cfdata_t cf, void *aux) 134wsmatch(device_t parent, cfdata_t cf, void *aux)
126{ 135{
@@ -133,165 +142,184 @@ wsmatch(device_t parent, cfdata_t cf, vo @@ -133,165 +142,184 @@ wsmatch(device_t parent, cfdata_t cf, vo
133 142
134static void 143static void
135wsattach(device_t parent, device_t self, void *aux) 144wsattach(device_t parent, device_t self, void *aux)
136{ 145{
137 struct ws_softc *sc = device_private(self); 146 struct ws_softc *sc = device_private(self);
138 struct sio_softc *scp = device_private(parent); 147 struct sio_softc *scp = device_private(parent);
139 struct sio_attach_args *args = aux; 148 struct sio_attach_args *args = aux;
140 struct wskbddev_attach_args a; 149 struct wskbddev_attach_args a;
141 150
142 sc->sc_dev = self; 151 sc->sc_dev = self;
143 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1; 152 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + 1;
144 memcpy(sc->sc_wr, ch1_regs, sizeof(ch1_regs)); 153 memcpy(sc->sc_wr, ch1_regs, sizeof(ch1_regs));
145 scp->scp_intr[1] = wsintr; 154 scp->scp_intr[1] = wsintr;
146  155
147 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 156 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
148 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]); 157 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
149 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]); 158 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
150 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]); 159 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
151 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 160 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
152 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); 161 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]);
153 162
154 syscnputc((dev_t)1, 0x20); /* keep quiet mouse */ 163 syscnputc((dev_t)1, 0x20); /* keep quiet mouse */
155 164
 165 sc->sc_rxqhead = 0;
 166 sc->sc_rxqtail = 0;
 167
 168 sc->sc_si = softint_establish(SOFTINT_SERIAL, wssoftintr, sc);
 169
156 aprint_normal("\n"); 170 aprint_normal("\n");
157 171
158 a.console = (args->hwflags == 1); 172 a.console = (args->hwflags == 1);
159 a.keymap = &omkbd_keymapdata; 173 a.keymap = &omkbd_keymapdata;
160 a.accessops = &omkbd_accessops; 174 a.accessops = &omkbd_accessops;
161 a.accesscookie = (void *)sc; 175 a.accesscookie = (void *)sc;
162 sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint); 176 sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint);
163 177
164#if NWSMOUSE > 0 178#if NWSMOUSE > 0
165 { 179 {
166 struct wsmousedev_attach_args b; 180 struct wsmousedev_attach_args b;
167 b.accessops = &omms_accessops; 181 b.accessops = &omms_accessops;
168 b.accesscookie = (void *)sc;  182 b.accesscookie = (void *)sc;
169 sc->sc_wsmousedev = 183 sc->sc_wsmousedev =
170 config_found_ia(self, "wsmousedev", &b, wsmousedevprint); 184 config_found_ia(self, "wsmousedev", &b, wsmousedevprint);
171 sc->sc_msreport = 0; 185 sc->sc_msreport = 0;
172 } 186 }
173#endif 187#endif
174} 188}
175 189
176/*ARGSUSED*/ 190/*ARGSUSED*/
177static void 191static void
178wsintr(int chan) 192wsintr(int chan)
179{ 193{
180 struct ws_softc *sc = device_lookup_private(&ws_cd, 0); 194 struct ws_softc *sc = device_lookup_private(&ws_cd, 0);
181 struct sioreg *sio = sc->sc_ctl; 195 struct sioreg *sio = sc->sc_ctl;
182 u_int code; 196 uint8_t code;
183 int rr; 197 int rr;
184 198
185 rr = getsiocsr(sio); 199 rr = getsiocsr(sio);
186 if (rr & RR_RXRDY) { 200 if (rr & RR_RXRDY) {
187 do { 201 do {
188 code = sio->sio_data; 202 code = sio->sio_data;
189 if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { 203 if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) {
190 sio->sio_cmd = WR0_ERRRST; 204 sio->sio_cmd = WR0_ERRRST;
191 continue; 205 continue;
192 } 206 }
193#if NWSMOUSE > 0 207 sc->sc_rxq[sc->sc_rxqtail] = code;
194 /* 208 sc->sc_rxqtail = OMKBD_NEXTRXQ(sc->sc_rxqtail);
195 * if (code >= 0x80 && code <= 0x87), then 
196 * it's the first byte of 3 byte long mouse report 
197 * code[0] & 07 -> LMR button condition 
198 * code[1], [2] -> x,y delta 
199 * otherwise, key press or release event. 
200 */ 
201 if (sc->sc_msreport == 0) { 
202 if (code < 0x80 || code > 0x87) { 
203 omkbd_input(sc, code); 
204 continue; 
205 } 
206 code = (code & 07) ^ 07; 
207 /* LMR->RML: wsevent counts 0 for leftmost */ 
208 sc->buttons = (code & 02); 
209 if (code & 01) 
210 sc->buttons |= 04; 
211 if (code & 04) 
212 sc->buttons |= 01; 
213 sc->sc_msreport = 1; 
214 } else if (sc->sc_msreport == 1) { 
215 sc->dx = (signed char)code; 
216 sc->sc_msreport = 2; 
217 } else if (sc->sc_msreport == 2) { 
218 sc->dy = (signed char)code; 
219 wsmouse_input(sc->sc_wsmousedev, 
220 sc->buttons, 
221 sc->dx, sc->dy, 0, 0, 
222 WSMOUSE_INPUT_DELTA); 
223 
224 sc->sc_msreport = 0; 
225 } 
226#else 
227 omkbd_input(sc, code); 
228#endif 
229 } while ((rr = getsiocsr(sio)) & RR_RXRDY); 209 } while ((rr = getsiocsr(sio)) & RR_RXRDY);
 210 softint_schedule(sc->sc_si);
230 } 211 }
231 if (rr & RR_TXRDY) 212 if (rr & RR_TXRDY)
232 sio->sio_cmd = WR0_RSTPEND; 213 sio->sio_cmd = WR0_RSTPEND;
233 /* not capable of transmit, yet */ 214 /* not capable of transmit, yet */
234} 215}
235 216
236static void 217static void
 218wssoftintr(void *arg)
 219{
 220 struct ws_softc *sc = arg;
 221 uint8_t code;
 222
 223 while (sc->sc_rxqhead != sc->sc_rxqtail) {
 224 code = sc->sc_rxq[sc->sc_rxqhead];
 225 sc->sc_rxqhead = OMKBD_NEXTRXQ(sc->sc_rxqhead);
 226#if NWSMOUSE > 0
 227 /*
 228 * if (code >= 0x80 && code <= 0x87), then
 229 * it's the first byte of 3 byte long mouse report
 230 * code[0] & 07 -> LMR button condition
 231 * code[1], [2] -> x,y delta
 232 * otherwise, key press or release event.
 233 */
 234 if (sc->sc_msreport == 0) {
 235 if (code < 0x80 || code > 0x87) {
 236 omkbd_input(sc, code);
 237 continue;
 238 }
 239 code = (code & 07) ^ 07;
 240 /* LMR->RML: wsevent counts 0 for leftmost */
 241 sc->sc_msbuttons = (code & 02);
 242 if (code & 01)
 243 sc->sc_msbuttons |= 04;
 244 if (code & 04)
 245 sc->sc_msbuttons |= 01;
 246 sc->sc_msreport = 1;
 247 } else if (sc->sc_msreport == 1) {
 248 sc->sc_msdx = (int8_t)code;
 249 sc->sc_msreport = 2;
 250 } else if (sc->sc_msreport == 2) {
 251 sc->sc_msdy = (int8_t)code;
 252 wsmouse_input(sc->sc_wsmousedev,
 253 sc->sc_msbuttons, sc->sc_msdx, sc->sc_msdy, 0, 0,
 254 WSMOUSE_INPUT_DELTA);
 255
 256 sc->sc_msreport = 0;
 257 }
 258#else
 259 omkbd_input(sc, code);
 260#endif
 261 }
 262}
 263
 264static void
237omkbd_input(void *v, int data) 265omkbd_input(void *v, int data)
238{ 266{
239 struct ws_softc *sc = v; 267 struct ws_softc *sc = v;
240 u_int type; 268 u_int type;
241 int key; 269 int key;
242 270
243 if (omkbd_decode(v, data, &type, &key)) 271 if (omkbd_decode(v, data, &type, &key))
244 wskbd_input(sc->sc_wskbddev, type, key);  272 wskbd_input(sc->sc_wskbddev, type, key);
245} 273}
246 274
247static int 275static int
248omkbd_decode(void *v, int datain, u_int *type, int *dataout) 276omkbd_decode(void *v, int datain, u_int *type, int *dataout)
249{ 277{
250 278
251 *type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; 279 *type = (datain & 0x80) ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN;
252 *dataout = datain & 0x7f; 280 *dataout = datain & 0x7f;
253 return 1; 281 return 1;
254} 282}
255 283
256#define KC(n) KS_KEYCODE(n) 284#define KC(n) KS_KEYCODE(n)
257 285
258static const keysym_t omkbd_keydesc_1[] = { 286static const keysym_t omkbd_keydesc_1[] = {
259/* pos command normal shifted */ 287/* pos command normal shifted */
260 KC(0x9), KS_Tab, 288 KC(0x9), KS_Tab,
261 KC(0xa), KS_Control_L, 289 KC(0xa), KS_Control_L,
262 KC(0xb), KS_Mode_switch, /* Kana */ 290 KC(0xb), KS_Mode_switch, /* Kana */
263 KC(0xc), KS_Shift_R, 291 KC(0xc), KS_Shift_R,
264 KC(0xd), KS_Shift_L, 292 KC(0xd), KS_Shift_L,
265 KC(0xe), KS_Caps_Lock, 293 KC(0xe), KS_Caps_Lock,
266 KC(0xf), KS_Meta_L, /* Zenmen */ 294 KC(0xf), KS_Meta_L, /* Zenmen */
267 KC(0x10), KS_Escape, 295 KC(0x10), KS_Escape,
268 KC(0x11), KS_BackSpace, 296 KC(0x11), KS_BackSpace,
269 KC(0x12), KS_Return, 297 KC(0x12), KS_Return,
270 KC(0x14), KS_space, 298 KC(0x14), KS_space,
271 KC(0x15), KS_Delete, 299 KC(0x15), KS_Delete,
272 KC(0x16), KS_Alt_L, /* Henkan */ 300 KC(0x16), KS_Alt_L, /* Henkan */
273 KC(0x17), KS_Alt_R, /* Kakutei */ 301 KC(0x17), KS_Alt_R, /* Kakutei */
274 KC(0x18), KS_f11, /* Shokyo */ 302 KC(0x18), KS_f11, /* Shokyo */
275 KC(0x19), KS_f12, /* Yobidashi */ 303 KC(0x19), KS_f12, /* Yobidashi */
276 KC(0x1a), KS_f13, /* Bunsetsu L */ 304 KC(0x1a), KS_f13, /* Bunsetsu L */
277 KC(0x1b), KS_f14, /* Bunsetsu R */ 305 KC(0x1b), KS_f14, /* Bunsetsu R */
278 KC(0x1c), KS_KP_Up, 306 KC(0x1c), KS_KP_Up,
279 KC(0x1d), KS_KP_Left, 307 KC(0x1d), KS_KP_Left,
280 KC(0x1e), KS_KP_Right, 308 KC(0x1e), KS_KP_Right,
281 KC(0x1f), KS_KP_Down, 309 KC(0x1f), KS_KP_Down,
282 /* KC(0x20), KS_f11, */ 310 /* KC(0x20), KS_f11, */
283 /* KC(0x21), KS_f12, */ 311 /* KC(0x21), KS_f12, */
284 KC(0x22), KS_1, KS_exclam, 312 KC(0x22), KS_1, KS_exclam,
285 KC(0x23), KS_2, KS_quotedbl, 313 KC(0x23), KS_2, KS_quotedbl,
286 KC(0x24), KS_3, KS_numbersign, 314 KC(0x24), KS_3, KS_numbersign,
287 KC(0x25), KS_4, KS_dollar, 315 KC(0x25), KS_4, KS_dollar,
288 KC(0x26), KS_5, KS_percent, 316 KC(0x26), KS_5, KS_percent,
289 KC(0x27), KS_6, KS_ampersand, 317 KC(0x27), KS_6, KS_ampersand,
290 KC(0x28), KS_7, KS_apostrophe, 318 KC(0x28), KS_7, KS_apostrophe,
291 KC(0x29), KS_8, KS_parenleft, 319 KC(0x29), KS_8, KS_parenleft,
292 KC(0x2a), KS_9, KS_parenright, 320 KC(0x2a), KS_9, KS_parenright,
293 KC(0x2b), KS_0, 321 KC(0x2b), KS_0,
294 KC(0x2c), KS_minus, KS_equal, 322 KC(0x2c), KS_minus, KS_equal,
295 KC(0x2d), KS_asciicircum, KS_asciitilde, 323 KC(0x2d), KS_asciicircum, KS_asciitilde,
296 KC(0x2e), KS_backslash, KS_bar, 324 KC(0x2e), KS_backslash, KS_bar,
297 /* KC(0x30), KS_f13, */ 325 /* KC(0x30), KS_f13, */

cvs diff -r1.33 -r1.33.4.1 src/sys/arch/luna68k/dev/siotty.c (expand / switch to unified diff)

--- src/sys/arch/luna68k/dev/siotty.c 2011/11/26 04:40:50 1.33
+++ src/sys/arch/luna68k/dev/siotty.c 2014/01/12 12:21:16 1.33.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: siotty.c,v 1.33 2011/11/26 04:40:50 tsutsui Exp $ */ 1/* $NetBSD: siotty.c,v 1.33.4.1 2014/01/12 12:21:16 bouyer Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura. 8 * by Tohru Nishimura.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,225 +21,368 @@ @@ -21,225 +21,368 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 32#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
33 33
34__KERNEL_RCSID(0, "$NetBSD: siotty.c,v 1.33 2011/11/26 04:40:50 tsutsui Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: siotty.c,v 1.33.4.1 2014/01/12 12:21:16 bouyer Exp $");
35 35
36#include "opt_ddb.h" 36#include "opt_ddb.h"
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/systm.h> 39#include <sys/systm.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/conf.h> 41#include <sys/conf.h>
42#include <sys/ioctl.h> 42#include <sys/ioctl.h>
43#include <sys/proc.h> 43#include <sys/proc.h>
44#include <sys/tty.h> 44#include <sys/tty.h>
45#include <sys/uio.h> 45#include <sys/uio.h>
46#include <sys/callout.h> 46#include <sys/callout.h>
47#include <sys/fcntl.h> 47#include <sys/fcntl.h>
48#include <dev/cons.h> 48#include <dev/cons.h>
49#include <sys/kauth.h> 49#include <sys/kauth.h>
 50#include <sys/kmem.h>
50 51
51#include <machine/cpu.h> 52#include <machine/cpu.h>
52 53
53#include <luna68k/dev/sioreg.h> 54#include <luna68k/dev/sioreg.h>
54#include <luna68k/dev/siovar.h> 55#include <luna68k/dev/siovar.h>
55 56
56#include "ioconf.h" 57#include "ioconf.h"
57 58
58#define TIOCM_BREAK 01000 /* non standard use */ 59#define TIOCM_BREAK 01000 /* non standard use */
59 60
60static const uint8_t ch0_regs[6] = { 61static const uint8_t ch0_regs[6] = {
61 WR0_RSTINT, /* reset E/S interrupt */ 62 WR0_RSTINT, /* reset E/S interrupt */
62 WR1_RXALLS | WR1_TXENBL, /* Rx per char, Tx */ 63 WR1_RXALLS | WR1_TXENBL, /* Rx per char, Tx */
63 0, /* */ 64 0, /* */
64 WR3_RX8BIT | WR3_RXENBL, /* Rx */ 65 WR3_RX8BIT | WR3_RXENBL, /* Rx */
65 WR4_BAUD96 | WR4_STOP1, /* Tx/Rx */ 66 WR4_BAUD96 | WR4_STOP1, /* Tx/Rx */
66 WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS, /* Tx */ 67 WR5_TX8BIT | WR5_TXENBL | WR5_DTR | WR5_RTS, /* Tx */
67}; 68};
68 69
69static const struct speedtab siospeedtab[] = { 70static const struct speedtab siospeedtab[] = {
70 { 2400, WR4_BAUD24, }, 71 { 2400, WR4_BAUD24, },
71 { 4800, WR4_BAUD48, }, 72 { 4800, WR4_BAUD48, },
72 { 9600, WR4_BAUD96, }, 73 { 9600, WR4_BAUD96, },
73 { -1, 0, }, 74 { -1, 0, },
74}; 75};
75 76
76struct siotty_softc { 77struct siotty_softc {
77 device_t sc_dev; 78 device_t sc_dev;
78 struct tty *sc_tty; 79 struct tty *sc_tty;
79 struct sioreg *sc_ctl; 80 struct sioreg *sc_ctl;
80 u_int sc_flags; 81 u_int sc_flags;
81 uint8_t sc_wr[6]; 82 uint8_t sc_wr[6];
 83 void *sc_si; /* software interrupt handler */
 84 u_int sc_hwflags;
 85#define SIOTTY_HW_CONSOLE 0x0001
 86
 87 uint8_t *sc_rbuf;
 88 uint8_t *sc_rbufend;
 89 uint8_t * volatile sc_rbget;
 90 uint8_t * volatile sc_rbput;
 91 volatile u_int sc_rbavail;
 92
 93 uint8_t *sc_tba;
 94 u_int sc_tbc;
 95
 96 bool sc_rx_ready;
 97 bool sc_tx_busy;
 98 bool sc_tx_done;
82}; 99};
83 100
 101#define SIOTTY_RING_SIZE 2048
 102u_int siotty_rbuf_size = SIOTTY_RING_SIZE;
 103
 104static struct cnm_state siotty_cnm_state;
 105
84#include "siotty.h" 106#include "siotty.h"
85static void siostart(struct tty *); 107static void siostart(struct tty *);
86static int sioparam(struct tty *, struct termios *); 108static int sioparam(struct tty *, struct termios *);
87static void siottyintr(int); 109static void siottyintr(int);
 110static void siottysoft(void *);
 111static void siotty_rxsoft(struct siotty_softc *, struct tty *);
 112static void siotty_txsoft(struct siotty_softc *, struct tty *);
88static int siomctl(struct siotty_softc *, int, int); 113static int siomctl(struct siotty_softc *, int, int);
89 114
90static int siotty_match(device_t, cfdata_t, void *); 115static int siotty_match(device_t, cfdata_t, void *);
91static void siotty_attach(device_t, device_t, void *); 116static void siotty_attach(device_t, device_t, void *);
92 117
93CFATTACH_DECL_NEW(siotty, sizeof(struct siotty_softc), 118CFATTACH_DECL_NEW(siotty, sizeof(struct siotty_softc),
94 siotty_match, siotty_attach, NULL, NULL); 119 siotty_match, siotty_attach, NULL, NULL);
95 120
96dev_type_open(sioopen); 121dev_type_open(sioopen);
97dev_type_close(sioclose); 122dev_type_close(sioclose);
98dev_type_read(sioread); 123dev_type_read(sioread);
99dev_type_write(siowrite); 124dev_type_write(siowrite);
100dev_type_ioctl(sioioctl); 125dev_type_ioctl(sioioctl);
101dev_type_stop(siostop); 126dev_type_stop(siostop);
102dev_type_tty(siotty); 127dev_type_tty(siotty);
103dev_type_poll(siopoll); 128dev_type_poll(siopoll);
104 129
105const struct cdevsw siotty_cdevsw = { 130const struct cdevsw siotty_cdevsw = {
106 sioopen, sioclose, sioread, siowrite, sioioctl, 131 sioopen, sioclose, sioread, siowrite, sioioctl,
107 siostop, siotty, siopoll, nommap, ttykqfilter, D_TTY 132 siostop, siotty, siopoll, nommap, ttykqfilter, D_TTY
108}; 133};
109 134
110static int  135static int
111siotty_match(device_t parent, cfdata_t cf, void *aux) 136siotty_match(device_t parent, cfdata_t cf, void *aux)
112{ 137{
113 struct sio_attach_args *args = aux; 138 struct sio_attach_args *args = aux;
114 139
115 if (args->channel != 0) /* XXX allow tty on Ch.B XXX */ 140 if (args->channel != 0) /* XXX allow tty on Ch.B XXX */
116 return 0; 141 return 0;
117 return 1; 142 return 1;
118} 143}
119 144
120static void  145static void
121siotty_attach(struct device *parent, struct device *self, void *aux) 146siotty_attach(device_t parent, device_t self, void *aux)
122{ 147{
123 struct sio_softc *scp = device_private(parent); 148 struct sio_softc *scp = device_private(parent);
124 struct siotty_softc *sc = device_private(self); 149 struct siotty_softc *sc = device_private(self);
125 struct sio_attach_args *args = aux; 150 struct sio_attach_args *args = aux;
 151 struct tty *tp;
126 152
127 sc->sc_dev = self; 153 sc->sc_dev = self;
128 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel; 154 sc->sc_ctl = (struct sioreg *)scp->scp_ctl + args->channel;
129 memcpy(sc->sc_wr, ch0_regs, sizeof(ch0_regs)); 155 memcpy(sc->sc_wr, ch0_regs, sizeof(ch0_regs));
130 scp->scp_intr[args->channel] = siottyintr; 156 scp->scp_intr[args->channel] = siottyintr;
 157 if (args->hwflags == 1)
 158 sc->sc_hwflags |= SIOTTY_HW_CONSOLE;
131 159
132 if (args->hwflags == 1) { 160 if ((sc->sc_hwflags & SIOTTY_HW_CONSOLE) != 0) {
133 aprint_normal(" (console)"); 161 aprint_normal(" (console)");
134 sc->sc_flags = TIOCFLAG_SOFTCAR; 162 sc->sc_flags = TIOCFLAG_SOFTCAR;
135 } else { 163 } else {
136 setsioreg(sc->sc_ctl, WR0, WR0_CHANRST); 164 setsioreg(sc->sc_ctl, WR0, WR0_CHANRST);
137 setsioreg(sc->sc_ctl, WR2A, WR2_VEC86 | WR2_INTR_1); 165 setsioreg(sc->sc_ctl, WR2A, WR2_VEC86 | WR2_INTR_1);
138 setsioreg(sc->sc_ctl, WR2B, 0); 166 setsioreg(sc->sc_ctl, WR2B, 0);
139 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 167 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
140 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]); 168 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
141 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]); 169 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
142 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]); 170 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
143 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]); 171 setsioreg(sc->sc_ctl, WR0, sc->sc_wr[WR0]);
144 } 172 }
145 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */ 173 setsioreg(sc->sc_ctl, WR1, sc->sc_wr[WR1]); /* now interrupt driven */
146 174
147 aprint_normal("\n"); 175 aprint_normal("\n");
 176
 177 sc->sc_rbuf = kmem_alloc(siotty_rbuf_size * 2, KM_NOSLEEP);
 178 if (sc->sc_rbuf == NULL) {
 179 aprint_error_dev(self, "unable to allocate ring buffer\n");
 180 return;
 181 }
 182 sc->sc_rbufend = sc->sc_rbuf + (siotty_rbuf_size * 2);
 183 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
 184 sc->sc_rbavail = siotty_rbuf_size;
 185
 186 tp = tty_alloc();
 187 tp->t_oproc = siostart;
 188 tp->t_param = sioparam;
 189 tp->t_hwiflow = NULL /* XXX siohwiflow XXX */;
 190 if ((sc->sc_hwflags & SIOTTY_HW_CONSOLE) != 0)
 191 tp->t_dev = cn_tab->cn_dev;
 192 sc->sc_tty = tp;
 193
 194 tty_attach(tp);
 195
 196 sc->sc_si = softint_establish(SOFTINT_SERIAL, siottysoft, sc);
148} 197}
149 198
150/*-------------------- low level routine --------------------*/ 199/*-------------------- low level routine --------------------*/
151 200
152static void 201static void
153siottyintr(int chan) 202siottyintr(int chan)
154{ 203{
155 struct siotty_softc *sc; 204 struct siotty_softc *sc;
156 struct sioreg *sio; 205 struct sioreg *sio;
157 struct tty *tp; 206 uint8_t *put, *end;
158 unsigned int code; 207 uint8_t c;
159 int rr; 208 uint16_t rr;
 209 int cc;
160 210
161 sc = device_lookup_private(&siotty_cd, chan); 211 sc = device_lookup_private(&siotty_cd, chan);
162 if (sc == NULL) 212 if (sc == NULL)
163 return; 213 return;
164 214
165 tp = sc->sc_tty; 215 end = sc->sc_rbufend;
 216 put = sc->sc_rbput;
 217 cc = sc->sc_rbavail;
 218
166 sio = sc->sc_ctl; 219 sio = sc->sc_ctl;
167 rr = getsiocsr(sio); 220 rr = getsiocsr(sio);
 221 if ((rr & RR_BREAK) != 0) {
 222 sio->sio_cmd = WR0_RSTINT;
 223 cn_check_magic(sc->sc_tty->t_dev, CNC_BREAK, siotty_cnm_state);
 224 }
168 if (rr & RR_RXRDY) { 225 if (rr & RR_RXRDY) {
169 do { 226 do {
170 code = sio->sio_data; 227 if (cc > 0) {
171 if (rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) { 228 c = sio->sio_data;
172 sio->sio_cmd = WR0_ERRRST; 229 cn_check_magic(sc->sc_tty->t_dev, c,
173 if (sio->sio_stat & RR_FRAMING) 230 siotty_cnm_state);
174 code |= TTY_FE; 231 put[0] = c;
175 else if (sio->sio_stat & RR_PARITY) 232 put[1] = rr & 0xff;
176 code |= TTY_PE; 233 put += 2;
177 } 234 if (put >= end)
178 if (tp == NULL || (tp->t_state & TS_ISOPEN) == 0) 235 put = sc->sc_rbuf;
179 continue; 236 cc--;
180#if 0 && defined(DDB) /* ?!?! fails to resume ?!?! */ 
181 if ((rr & RR_BREAK) && tp->t_dev == cn_tab->cn_dev) { 
182 cpu_Debugger(); 
183 return; 
184 } 237 }
185#endif 238 if ((rr & (RR_FRAMING | RR_OVERRUN | RR_PARITY)) != 0)
186 (*tp->t_linesw->l_rint)(code, tp); 239 sio->sio_cmd = WR0_ERRRST;
 240
 241 sc->sc_rbput = put;
 242 sc->sc_rbavail = cc;
 243 sc->sc_rx_ready = true;
187 } while ((rr = getsiocsr(sio)) & RR_RXRDY); 244 } while ((rr = getsiocsr(sio)) & RR_RXRDY);
188 } 245 }
189 if (rr & RR_TXRDY) { 246 if (rr & RR_TXRDY) {
190 sio->sio_cmd = WR0_RSTPEND; 247 sio->sio_cmd = WR0_RSTPEND;
191 if (tp != NULL) { 248 if (sc->sc_tbc > 0) {
192 tp->t_state &= ~(TS_BUSY|TS_FLUSH); 249 sio->sio_data = *sc->sc_tba;
193 (*tp->t_linesw->l_start)(tp); 250 sc->sc_tba++;
 251 sc->sc_tbc--;
 252 } else {
 253 if (sc->sc_tx_busy) {
 254 sc->sc_tx_busy = false;
 255 sc->sc_tx_done = true;
 256 }
194 } 257 }
195 } 258 }
 259 softint_schedule(sc->sc_si);
 260}
 261
 262static void
 263siottysoft(void *arg)
 264{
 265 struct siotty_softc *sc;
 266 struct tty *tp;
 267
 268 sc = arg;
 269 tp = sc->sc_tty;
 270
 271 if (sc->sc_rx_ready) {
 272 sc->sc_rx_ready = false;
 273 siotty_rxsoft(sc, tp);
 274 }
 275 if (sc->sc_tx_done) {
 276 sc->sc_tx_done = false;
 277 siotty_txsoft(sc, tp);
 278 }
 279}
 280
 281static void
 282siotty_rxsoft(struct siotty_softc *sc, struct tty *tp)
 283{
 284 uint8_t *get, *end;
 285 u_int cc, scc;
 286 unsigned int code;
 287 uint8_t stat;
 288 int s;
 289
 290 end = sc->sc_rbufend;
 291 get = sc->sc_rbget;
 292 scc = cc = siotty_rbuf_size - sc->sc_rbavail;
 293
 294 if (cc == siotty_rbuf_size) {
 295 printf("%s: rx buffer overflow\n", device_xname(sc->sc_dev));
 296 }
 297
 298 while (cc > 0) {
 299 code = get[0];
 300 stat = get[1];
 301 if ((stat & RR_FRAMING) != 0)
 302 code |= TTY_FE;
 303 else if ((stat & RR_PARITY) != 0)
 304 code |= TTY_PE;
 305
 306 (*tp->t_linesw->l_rint)(code, tp);
 307 get += 2;
 308 if (get >= end)
 309 get = sc->sc_rbuf;
 310 cc--;
 311 }
 312
 313 if (cc != scc) {
 314 s = splserial();
 315 sc->sc_rbget = get;
 316 sc->sc_rbavail += scc - cc;
 317 splx(s);
 318 }
 319}
 320
 321static void
 322siotty_txsoft(struct siotty_softc *sc, struct tty *tp)
 323{
 324
 325 tp->t_state &= ~TS_BUSY;
 326 if ((tp->t_state & TS_FLUSH) != 0)
 327 tp->t_state &= ~TS_FLUSH;
 328 else
 329 ndflush(&tp->t_outq, (int)(sc->sc_tba - tp->t_outq.c_cf));
 330 (*tp->t_linesw->l_start)(tp);
196} 331}
197 332
198static void 333static void
199siostart(struct tty *tp) 334siostart(struct tty *tp)
200{ 335{
201 struct siotty_softc *sc; 336 struct siotty_softc *sc;
202 int s, c; 337 int s;
203  338 uint8_t *tba;
 339 int tbc;
 340
204 sc = device_lookup_private(&siotty_cd, minor(tp->t_dev)); 341 sc = device_lookup_private(&siotty_cd, minor(tp->t_dev));
205 s = splserial(); 342 s = splserial();
206 if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP)) 343 if (tp->t_state & (TS_BUSY|TS_TIMEOUT|TS_TTSTOP))
207 goto out; 344 goto out;
208 if (!ttypull(tp)) 345 if (!ttypull(tp))
209 goto out; 346 goto out;
210 tp->t_state |= TS_BUSY; 347 tp->t_state |= TS_BUSY;
211 while (getsiocsr(sc->sc_ctl) & RR_TXRDY) { 348
212 if ((c = getc(&tp->t_outq)) == -1) 349 tba = tp->t_outq.c_cf;
213 break; 350 tbc = ndqb(&tp->t_outq, 0);
214 sc->sc_ctl->sio_data = c; 351
215 } 352 sc->sc_tba = tba;
 353 sc->sc_tbc = tbc;
 354 sc->sc_tx_busy = true;
 355
 356 sc->sc_ctl->sio_data = *sc->sc_tba;
 357 sc->sc_tba++;
 358 sc->sc_tbc--;
216out: 359out:
217 splx(s); 360 splx(s);
218} 361}
219 362
220void 363void
221siostop(struct tty *tp, int flag) 364siostop(struct tty *tp, int flag)
222{ 365{
223 int s; 366 int s;
224 367
225 s = splserial(); 368 s = splserial();
226 if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) { 369 if (TS_BUSY == (tp->t_state & (TS_BUSY|TS_TTSTOP))) {
227 /* 370 /*
228 * Device is transmitting; must stop it. 371 * Device is transmitting; must stop it.
229 */ 372 */
230 tp->t_state |= TS_FLUSH; 373 tp->t_state |= TS_FLUSH;
231 } 374 }
232 splx(s); 375 splx(s);
233} 376}
234 377
235static int 378static int
236sioparam(struct tty *tp, struct termios *t) 379sioparam(struct tty *tp, struct termios *t)
237{ 380{
238 struct siotty_softc *sc; 381 struct siotty_softc *sc;
239 int wr4, s; 382 int wr4, s;
240 383
241 sc = device_lookup_private(&siotty_cd, minor(tp->t_dev)); 384 sc = device_lookup_private(&siotty_cd, minor(tp->t_dev));
242 if (t->c_ispeed && t->c_ispeed != t->c_ospeed) 385 if (t->c_ispeed && t->c_ispeed != t->c_ospeed)
243 return EINVAL; 386 return EINVAL;
244 wr4 = ttspeedtab(t->c_ospeed, siospeedtab); 387 wr4 = ttspeedtab(t->c_ospeed, siospeedtab);
245 if (wr4 < 0) 388 if (wr4 < 0)
@@ -269,42 +412,44 @@ sioparam(struct tty *tp, struct termios  @@ -269,42 +412,44 @@ sioparam(struct tty *tp, struct termios
269 switch (tp->t_cflag & CSIZE) { 412 switch (tp->t_cflag & CSIZE) {
270 case CS7: 413 case CS7:
271 sc->sc_wr[WR3] |= WR3_RX7BIT; sc->sc_wr[WR5] |= WR5_TX7BIT; 414 sc->sc_wr[WR3] |= WR3_RX7BIT; sc->sc_wr[WR5] |= WR5_TX7BIT;
272 break; 415 break;
273 case CS8: 416 case CS8:
274 sc->sc_wr[WR3] |= WR3_RX8BIT; sc->sc_wr[WR5] |= WR5_TX8BIT; 417 sc->sc_wr[WR3] |= WR3_RX8BIT; sc->sc_wr[WR5] |= WR5_TX8BIT;
275 break; 418 break;
276 } 419 }
277 if (tp->t_cflag & PARENB) { 420 if (tp->t_cflag & PARENB) {
278 wr4 |= WR4_PARENAB; 421 wr4 |= WR4_PARENAB;
279 if ((tp->t_cflag & PARODD) == 0) 422 if ((tp->t_cflag & PARODD) == 0)
280 wr4 |= WR4_EPARITY; 423 wr4 |= WR4_EPARITY;
281 } 424 }
282 wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;  425 wr4 |= (tp->t_cflag & CSTOPB) ? WR4_STOP2 : WR4_STOP1;
283 sc->sc_wr[WR4] = wr4; 426 sc->sc_wr[WR4] = wr4;
284 427
285 s = splserial(); 428 s = splserial();
286 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]); 429 setsioreg(sc->sc_ctl, WR4, sc->sc_wr[WR4]);
287 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]); 430 setsioreg(sc->sc_ctl, WR3, sc->sc_wr[WR3]);
288 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]); 431 setsioreg(sc->sc_ctl, WR5, sc->sc_wr[WR5]);
289 splx(s); 432 splx(s);
290 433
291 return 0; 434 return 0;
292} 435}
293 436
294static int 437static int
295siomctl(struct siotty_softc *sc, int control, int op) 438siomctl(struct siotty_softc *sc, int control, int op)
296{ 439{
297 int val, s, wr5, rr; 440 int val, s;
 441 uint8_t wr5;
 442 uint16_t rr;
298 443
299 val = 0; 444 val = 0;
300 if (control & TIOCM_BREAK) 445 if (control & TIOCM_BREAK)
301 val |= WR5_BREAK; 446 val |= WR5_BREAK;
302 if (control & TIOCM_DTR) 447 if (control & TIOCM_DTR)
303 val |= WR5_DTR; 448 val |= WR5_DTR;
304 if (control & TIOCM_RTS) 449 if (control & TIOCM_RTS)
305 val |= WR5_RTS; 450 val |= WR5_RTS;
306 s = splserial(); 451 s = splserial();
307 wr5 = sc->sc_wr[WR5]; 452 wr5 = sc->sc_wr[WR5];
308 switch (op) { 453 switch (op) {
309 case DMSET: 454 case DMSET:
310 wr5 &= ~(WR5_BREAK|WR5_DTR|WR5_RTS); 455 wr5 &= ~(WR5_BREAK|WR5_DTR|WR5_RTS);
@@ -321,138 +466,139 @@ siomctl(struct siotty_softc *sc, int con @@ -321,138 +466,139 @@ siomctl(struct siotty_softc *sc, int con
321 if (wr5 & WR5_DTR) 466 if (wr5 & WR5_DTR)
322 val |= TIOCM_DTR; 467 val |= TIOCM_DTR;
323 if (wr5 & WR5_RTS) 468 if (wr5 & WR5_RTS)
324 val |= TIOCM_RTS; 469 val |= TIOCM_RTS;
325 if (rr & RR_CTS) 470 if (rr & RR_CTS)
326 val |= TIOCM_CTS; 471 val |= TIOCM_CTS;
327 if (rr & RR_DCD) 472 if (rr & RR_DCD)
328 val |= TIOCM_CD; 473 val |= TIOCM_CD;
329 goto done; 474 goto done;
330 } 475 }
331 sc->sc_wr[WR5] = wr5; 476 sc->sc_wr[WR5] = wr5;
332 setsioreg(sc->sc_ctl, WR5, wr5); 477 setsioreg(sc->sc_ctl, WR5, wr5);
333 val = 0; 478 val = 0;
334 done: 479 done:
335 splx(s); 480 splx(s);
336 return val; 481 return val;
337} 482}
338 483
339/*-------------------- cdevsw[] interface --------------------*/ 484/*-------------------- cdevsw[] interface --------------------*/
340 485
341int 486int
342sioopen(dev_t dev, int flag, int mode, struct lwp *l) 487sioopen(dev_t dev, int flag, int mode, struct lwp *l)
343{ 488{
344 struct siotty_softc *sc; 489 struct siotty_softc *sc;
345 struct tty *tp; 490 struct tty *tp;
346 int error; 491 int error;
 492 int s;
347 493
348 sc = device_lookup_private(&siotty_cd, minor(dev)); 494 sc = device_lookup_private(&siotty_cd, minor(dev));
349 if (sc == NULL) 495 if (sc == NULL)
350 return ENXIO; 496 return ENXIO;
351 if ((tp = sc->sc_tty) == NULL) { 
352 tp = sc->sc_tty = tty_alloc(); 
353 tty_attach(tp); 
354 } 
355 497
356 tp->t_oproc = siostart; 498 tp = sc->sc_tty;
357 tp->t_param = sioparam; 
358 tp->t_hwiflow = NULL /* XXX siohwiflow XXX */; 
359 tp->t_dev = dev; 
360 499
361 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 500 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
362 return EBUSY; 501 return EBUSY;
363 502
364 if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) { 503 if ((tp->t_state & TS_ISOPEN) == 0 && tp->t_wopen == 0) {
365 struct termios t; 504 struct termios t;
366 505
 506 tp->t_dev = dev;
367 t.c_ispeed = t.c_ospeed = TTYDEF_SPEED; 507 t.c_ispeed = t.c_ospeed = TTYDEF_SPEED;
368 t.c_cflag = TTYDEF_CFLAG; 508 t.c_cflag = TTYDEF_CFLAG;
369 tp->t_ospeed = 0; /* force register update */ 509 tp->t_ospeed = 0; /* force register update */
370 (void)sioparam(tp, &t); 510 (void)sioparam(tp, &t);
371 tp->t_iflag = TTYDEF_IFLAG; 511 tp->t_iflag = TTYDEF_IFLAG;
372 tp->t_oflag = TTYDEF_OFLAG; 512 tp->t_oflag = TTYDEF_OFLAG;
373 tp->t_lflag = TTYDEF_LFLAG; 513 tp->t_lflag = TTYDEF_LFLAG;
374 ttychars(tp); 514 ttychars(tp);
375 ttsetwater(tp); 515 ttsetwater(tp);
376 /* raise RTS and DTR here; but, DTR lead is not wired */ 516 /* raise RTS and DTR here; but, DTR lead is not wired */
377 /* then check DCD condition; but, DCD lead is not wired */ 517 /* then check DCD condition; but, DCD lead is not wired */
378 tp->t_state |= TS_CARR_ON; /* assume detected all the time */ 
379#if 0 518#if 0
380 if ((sc->sc_flags & TIOCFLAG_SOFTCAR) 519 if ((sc->sc_flags & TIOCFLAG_SOFTCAR)
381 || (tp->t_cflag & MDMBUF) 520 || (tp->t_cflag & MDMBUF)
382 || (getsiocsr(sc->sc_ctl) & RR_DCD)) 521 || (getsiocsr(sc->sc_ctl) & RR_DCD))
383 tp->t_state |= TS_CARR_ON; 522 tp->t_state |= TS_CARR_ON;
384 else 523 else
385 tp->t_state &= ~TS_CARR_ON; 524 tp->t_state &= ~TS_CARR_ON;
 525#else
 526 tp->t_state |= TS_CARR_ON; /* assume detected all the time */
386#endif 527#endif
 528
 529 s = splserial();
 530 sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
 531 sc->sc_rbavail = siotty_rbuf_size;
 532 splx(s);
387 } 533 }
388 534
389 error = ttyopen(tp, 0, (flag & O_NONBLOCK)); 535 error = ttyopen(tp, 0, (flag & O_NONBLOCK));
390 if (error > 0) 536 if (error > 0)
391 return error; 537 return error;
392 return (*tp->t_linesw->l_open)(dev, tp); 538 return (*tp->t_linesw->l_open)(dev, tp);
393} 539}
394  540
395int 541int
396sioclose(dev_t dev, int flag, int mode, struct lwp *l) 542sioclose(dev_t dev, int flag, int mode, struct lwp *l)
397{ 543{
398 struct siotty_softc *sc = device_lookup_private(&siotty_cd,minor(dev)); 544 struct siotty_softc *sc = device_lookup_private(&siotty_cd,minor(dev));
399 struct tty *tp = sc->sc_tty; 545 struct tty *tp = sc->sc_tty;
400 int s; 546 int s;
401 547
402 (*tp->t_linesw->l_close)(tp, flag); 548 (*tp->t_linesw->l_close)(tp, flag);
403 549
404 s = splserial(); 550 s = splserial();
405 siomctl(sc, TIOCM_BREAK, DMBIC); 551 siomctl(sc, TIOCM_BREAK, DMBIC);
406#if 0 /* because unable to feed DTR signal */ 552#if 0 /* because unable to feed DTR signal */
407 if ((tp->t_cflag & HUPCL) 553 if ((tp->t_cflag & HUPCL)
408 || tp->t_wopen || (tp->t_state & TS_ISOPEN) == 0) { 554 || tp->t_wopen || (tp->t_state & TS_ISOPEN) == 0) {
409 siomctl(sc, TIOCM_DTR, DMBIC); 555 siomctl(sc, TIOCM_DTR, DMBIC);
410 /* Yield CPU time to others for 1 second, then ... */ 556 /* Yield CPU time to others for 1 second, then ... */
411 siomctl(sc, TIOCM_DTR, DMBIS); 557 siomctl(sc, TIOCM_DTR, DMBIS);
412 } 558 }
413#endif 559#endif
414 splx(s); 560 splx(s);
415 return ttyclose(tp); 561 return ttyclose(tp);
416} 562}
417  563
418int 564int
419sioread(dev_t dev, struct uio *uio, int flag) 565sioread(dev_t dev, struct uio *uio, int flag)
420{ 566{
421 struct siotty_softc *sc; 567 struct siotty_softc *sc;
422 struct tty *tp; 568 struct tty *tp;
423  569
424 sc = device_lookup_private(&siotty_cd, minor(dev)); 570 sc = device_lookup_private(&siotty_cd, minor(dev));
425 tp = sc->sc_tty; 571 tp = sc->sc_tty;
426 return (*tp->t_linesw->l_read)(tp, uio, flag); 572 return (*tp->t_linesw->l_read)(tp, uio, flag);
427} 573}
428  574
429int 575int
430siowrite(dev_t dev, struct uio *uio, int flag) 576siowrite(dev_t dev, struct uio *uio, int flag)
431{ 577{
432 struct siotty_softc *sc; 578 struct siotty_softc *sc;
433 struct tty *tp; 579 struct tty *tp;
434  580
435 sc = device_lookup_private(&siotty_cd, minor(dev)); 581 sc = device_lookup_private(&siotty_cd, minor(dev));
436 tp = sc->sc_tty; 582 tp = sc->sc_tty;
437 return (*tp->t_linesw->l_write)(tp, uio, flag); 583 return (*tp->t_linesw->l_write)(tp, uio, flag);
438} 584}
439 585
440int 586int
441siopoll(dev_t dev, int events, struct lwp *l) 587siopoll(dev_t dev, int events, struct lwp *l)
442{ 588{
443 struct siotty_softc *sc; 589 struct siotty_softc *sc;
444 struct tty *tp; 590 struct tty *tp;
445  591
446 sc = device_lookup_private(&siotty_cd, minor(dev)); 592 sc = device_lookup_private(&siotty_cd, minor(dev));
447 tp = sc->sc_tty; 593 tp = sc->sc_tty;
448 return ((*tp->t_linesw->l_poll)(tp, events, l)); 594 return ((*tp->t_linesw->l_poll)(tp, events, l));
449} 595}
450 596
451int 597int
452sioioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) 598sioioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
453{ 599{
454 struct siotty_softc *sc; 600 struct siotty_softc *sc;
455 struct tty *tp; 601 struct tty *tp;
456 int error; 602 int error;
457 603
458 sc = device_lookup_private(&siotty_cd, minor(dev)); 604 sc = device_lookup_private(&siotty_cd, minor(dev));
@@ -498,43 +644,43 @@ sioioctl(dev_t dev, u_long cmd, void *da @@ -498,43 +644,43 @@ sioioctl(dev_t dev, u_long cmd, void *da
498 *(int *)data = sc->sc_flags; 644 *(int *)data = sc->sc_flags;
499 break; 645 break;
500 default: 646 default:
501 return EPASSTHROUGH; 647 return EPASSTHROUGH;
502 } 648 }
503 return 0; 649 return 0;
504} 650}
505 651
506/* ARSGUSED */ 652/* ARSGUSED */
507struct tty * 653struct tty *
508siotty(dev_t dev) 654siotty(dev_t dev)
509{ 655{
510 struct siotty_softc *sc; 656 struct siotty_softc *sc;
511  657
512 sc = device_lookup_private(&siotty_cd, minor(dev)); 658 sc = device_lookup_private(&siotty_cd, minor(dev));
513 return sc->sc_tty; 659 return sc->sc_tty;
514} 660}
515 661
516/*-------------------- miscelleneous routine --------------------*/ 662/*-------------------- miscelleneous routine --------------------*/
517 663
518/* EXPORT */ void 664/* EXPORT */ void
519setsioreg(struct sioreg *sio, int regno, int val) 665setsioreg(struct sioreg *sio, int regno, int val)
520{ 666{
521 667
522 if (regno != 0) 668 if (regno != 0)
523 sio->sio_cmd = regno; /* DELAY(); */ 669 sio->sio_cmd = regno; /* DELAY(); */
524 sio->sio_cmd = val; /* DELAY(); */ 670 sio->sio_cmd = val; /* DELAY(); */
525} 671}
526 672
527/* EXPORT */ int 673/* EXPORT */ uint16_t
528getsiocsr(struct sioreg *sio) 674getsiocsr(struct sioreg *sio)
529{ 675{
530 int val; 676 int val;
531 677
532 val = sio->sio_stat << 8; /* DELAY(); */ 678 val = sio->sio_stat << 8; /* DELAY(); */
533 sio->sio_cmd = 1; /* DELAY(); */ 679 sio->sio_cmd = 1; /* DELAY(); */
534 val |= sio->sio_stat; /* DELAY(); */ 680 val |= sio->sio_stat; /* DELAY(); */
535 return val; 681 return val;
536} 682}
537 683
538/*--------------------- console interface ----------------------*/ 684/*--------------------- console interface ----------------------*/
539 685
540void syscnattach(int); 686void syscnattach(int);
@@ -557,26 +703,28 @@ struct consdev syscons = { @@ -557,26 +703,28 @@ struct consdev syscons = {
557/* EXPORT */ void 703/* EXPORT */ void
558syscnattach(int channel) 704syscnattach(int channel)
559{ 705{
560/* 706/*
561 * Channel A is immediately initialized with 9600N1 right after cold 707 * Channel A is immediately initialized with 9600N1 right after cold
562 * boot/reset/poweron. ROM monitor emits one line message on CH.A. 708 * boot/reset/poweron. ROM monitor emits one line message on CH.A.
563 */ 709 */
564 struct sioreg *sio; 710 struct sioreg *sio;
565 sio = (struct sioreg *)0x51000000 + channel; 711 sio = (struct sioreg *)0x51000000 + channel;
566 712
567 syscons.cn_dev = makedev(cdevsw_lookup_major(&siotty_cdevsw), 713 syscons.cn_dev = makedev(cdevsw_lookup_major(&siotty_cdevsw),
568 channel); 714 channel);
569 cn_tab = &syscons; 715 cn_tab = &syscons;
 716 cn_init_magic(&siotty_cnm_state);
 717 cn_set_magic("\047\001");
570 718
571 setsioreg(sio, WR0, WR0_CHANRST); 719 setsioreg(sio, WR0, WR0_CHANRST);
572 setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1); 720 setsioreg(sio, WR2A, WR2_VEC86 | WR2_INTR_1);
573 setsioreg(sio, WR2B, 0); 721 setsioreg(sio, WR2B, 0);
574 setsioreg(sio, WR0, ch0_regs[WR0]); 722 setsioreg(sio, WR0, ch0_regs[WR0]);
575 setsioreg(sio, WR4, ch0_regs[WR4]); 723 setsioreg(sio, WR4, ch0_regs[WR4]);
576 setsioreg(sio, WR3, ch0_regs[WR3]); 724 setsioreg(sio, WR3, ch0_regs[WR3]);
577 setsioreg(sio, WR5, ch0_regs[WR5]); 725 setsioreg(sio, WR5, ch0_regs[WR5]);
578 setsioreg(sio, WR0, ch0_regs[WR0]); 726 setsioreg(sio, WR0, ch0_regs[WR0]);
579} 727}
580 728
581/* EXPORT */ int 729/* EXPORT */ int
582syscngetc(dev_t dev) 730syscngetc(dev_t dev)

cvs diff -r1.6 -r1.6.8.1 src/sys/arch/luna68k/dev/siovar.h (expand / switch to unified diff)

--- src/sys/arch/luna68k/dev/siovar.h 2011/07/27 14:17:55 1.6
+++ src/sys/arch/luna68k/dev/siovar.h 2014/01/12 12:21:16 1.6.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: siovar.h,v 1.6 2011/07/27 14:17:55 tsutsui Exp $ */ 1/* $NetBSD: siovar.h,v 1.6.8.1 2014/01/12 12:21:16 bouyer Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Tohru Nishimura. 8 * by Tohru Nishimura.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -38,15 +38,15 @@ struct sio_softc { @@ -38,15 +38,15 @@ struct sio_softc {
38struct sio_attach_args { 38struct sio_attach_args {
39 int channel; 39 int channel;
40 int hwflags; 40 int hwflags;
41}; 41};
42 42
43struct sioreg { 43struct sioreg {
44 volatile uint8_t sio_data; 44 volatile uint8_t sio_data;
45 uint8_t pad0; 45 uint8_t pad0;
46 volatile uint8_t sio_cmd; 46 volatile uint8_t sio_cmd;
47 uint8_t pad1; 47 uint8_t pad1;
48#define sio_stat sio_cmd 48#define sio_stat sio_cmd
49}; 49};
50 50
51int getsiocsr(struct sioreg *); 51uint16_t getsiocsr(struct sioreg *);
52void setsioreg(struct sioreg *, int, int); 52void setsioreg(struct sioreg *, int, int);