dz_ebus.c revision 1.2.4.2 1 1.2.4.2 jruoho /* $NetBSD: dz_ebus.c,v 1.2.4.2 2011/06/06 09:05:16 jruoho Exp $ */
2 1.2.4.2 jruoho
3 1.2.4.2 jruoho /*-
4 1.2.4.2 jruoho * Copyright (c) 2010 The NetBSD Foundation, Inc.
5 1.2.4.2 jruoho * All rights reserved.
6 1.2.4.2 jruoho *
7 1.2.4.2 jruoho * This code was written by Alessandro Forin and Neil Pittman
8 1.2.4.2 jruoho * at Microsoft Research and contributed to The NetBSD Foundation
9 1.2.4.2 jruoho * by Microsoft Corporation.
10 1.2.4.2 jruoho *
11 1.2.4.2 jruoho * Redistribution and use in source and binary forms, with or without
12 1.2.4.2 jruoho * modification, are permitted provided that the following conditions
13 1.2.4.2 jruoho * are met:
14 1.2.4.2 jruoho * 1. Redistributions of source code must retain the above copyright
15 1.2.4.2 jruoho * notice, this list of conditions and the following disclaimer.
16 1.2.4.2 jruoho * 2. Redistributions in binary form must reproduce the above copyright
17 1.2.4.2 jruoho * notice, this list of conditions and the following disclaimer in the
18 1.2.4.2 jruoho * documentation and/or other materials provided with the distribution.
19 1.2.4.2 jruoho *
20 1.2.4.2 jruoho * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 1.2.4.2 jruoho * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 1.2.4.2 jruoho * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 1.2.4.2 jruoho * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 1.2.4.2 jruoho * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 1.2.4.2 jruoho * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 1.2.4.2 jruoho * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 1.2.4.2 jruoho * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 1.2.4.2 jruoho * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 1.2.4.2 jruoho * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 1.2.4.2 jruoho * POSSIBILITY OF SUCH DAMAGE.
31 1.2.4.2 jruoho */
32 1.2.4.2 jruoho
33 1.2.4.2 jruoho #include <sys/cdefs.h>
34 1.2.4.2 jruoho __KERNEL_RCSID(0, "$NetBSD: dz_ebus.c,v 1.2.4.2 2011/06/06 09:05:16 jruoho Exp $");
35 1.2.4.2 jruoho
36 1.2.4.2 jruoho #include "opt_ddb.h"
37 1.2.4.2 jruoho
38 1.2.4.2 jruoho #include <sys/param.h>
39 1.2.4.2 jruoho #include <sys/systm.h>
40 1.2.4.2 jruoho #include <sys/callout.h>
41 1.2.4.2 jruoho #include <sys/ioctl.h>
42 1.2.4.2 jruoho #include <sys/tty.h>
43 1.2.4.2 jruoho #include <sys/proc.h>
44 1.2.4.2 jruoho #include <sys/buf.h>
45 1.2.4.2 jruoho #include <sys/conf.h>
46 1.2.4.2 jruoho #include <sys/file.h>
47 1.2.4.2 jruoho #include <sys/uio.h>
48 1.2.4.2 jruoho #include <sys/kernel.h>
49 1.2.4.2 jruoho #include <sys/syslog.h>
50 1.2.4.2 jruoho #include <sys/device.h>
51 1.2.4.2 jruoho #include <sys/kauth.h>
52 1.2.4.2 jruoho
53 1.2.4.2 jruoho #include <machine/bus.h>
54 1.2.4.2 jruoho #include <machine/emipsreg.h>
55 1.2.4.2 jruoho
56 1.2.4.2 jruoho #include <dev/cons.h>
57 1.2.4.2 jruoho
58 1.2.4.2 jruoho
59 1.2.4.2 jruoho #include <emips/ebus/ebusvar.h>
60 1.2.4.2 jruoho #include <emips/emips/cons.h>
61 1.2.4.2 jruoho //#include <emips/emips/machdep.h>
62 1.2.4.2 jruoho
63 1.2.4.2 jruoho #include "ioconf.h" /* for dz_cd */
64 1.2.4.2 jruoho
65 1.2.4.2 jruoho #define DZ_C2I(c) ((c)<<3) /* convert controller # to index */
66 1.2.4.2 jruoho #define DZ_I2C(c) ((c)>>3) /* convert minor to controller # */
67 1.2.4.2 jruoho #define DZ_PORT(u) ((u)&07) /* extract the port # */
68 1.2.4.2 jruoho
69 1.2.4.2 jruoho struct dz_softc {
70 1.2.4.2 jruoho struct device sc_dev; /* Autoconf blaha */
71 1.2.4.2 jruoho struct evcnt sc_rintrcnt; /* recevive interrupt counts */
72 1.2.4.2 jruoho struct evcnt sc_tintrcnt; /* transmit interrupt counts */
73 1.2.4.2 jruoho struct _Usart *sc_dr; /* reg pointers */
74 1.2.4.2 jruoho bus_space_tag_t sc_iot;
75 1.2.4.2 jruoho bus_space_handle_t sc_ioh;
76 1.2.4.2 jruoho int sc_consline; /* console line, or -1 */
77 1.2.4.2 jruoho int sc_rxint; /* Receive interrupt count XXX */
78 1.2.4.2 jruoho u_char sc_brk; /* Break asserted on some lines */
79 1.2.4.2 jruoho u_char sc_dsr; /* DSR set bits if no mdm ctrl */
80 1.2.4.2 jruoho struct dz_linestate {
81 1.2.4.2 jruoho struct dz_softc *dz_sc; /* backpointer to softc */
82 1.2.4.2 jruoho int dz_line; /* channel number */
83 1.2.4.2 jruoho struct tty * dz_tty; /* what we work on */
84 1.2.4.2 jruoho } sc_dz;
85 1.2.4.2 jruoho };
86 1.2.4.2 jruoho
87 1.2.4.2 jruoho void dzrint(struct dz_softc *, uint32_t);
88 1.2.4.2 jruoho void dzxint(struct dz_softc *, uint32_t);
89 1.2.4.2 jruoho
90 1.2.4.2 jruoho #ifndef TIOCM_BRK
91 1.2.4.2 jruoho #define TIOCM_BRK 0100000 /* no equivalent */
92 1.2.4.2 jruoho
93 1.2.4.2 jruoho static void dzstart(struct tty *);
94 1.2.4.2 jruoho static int dzparam(struct tty *, struct termios *);
95 1.2.4.2 jruoho static unsigned dzmctl(struct dz_softc *sc, int line,
96 1.2.4.2 jruoho int bits, /* one of the TIOCM_xx */
97 1.2.4.2 jruoho int how); /* one of the DMSET/BIS.. */
98 1.2.4.2 jruoho
99 1.2.4.2 jruoho #include <dev/dec/dzkbdvar.h>
100 1.2.4.2 jruoho #endif
101 1.2.4.2 jruoho
102 1.2.4.2 jruoho dev_type_open(dzopen);
103 1.2.4.2 jruoho dev_type_close(dzclose);
104 1.2.4.2 jruoho dev_type_read(dzread);
105 1.2.4.2 jruoho dev_type_write(dzwrite);
106 1.2.4.2 jruoho dev_type_ioctl(dzioctl);
107 1.2.4.2 jruoho dev_type_stop(dzstop);
108 1.2.4.2 jruoho dev_type_tty(dztty);
109 1.2.4.2 jruoho dev_type_poll(dzpoll);
110 1.2.4.2 jruoho
111 1.2.4.2 jruoho const struct cdevsw dz_cdevsw = {
112 1.2.4.2 jruoho dzopen, dzclose, dzread, dzwrite, dzioctl,
113 1.2.4.2 jruoho dzstop, dztty, dzpoll, nommap, ttykqfilter, D_TTY
114 1.2.4.2 jruoho };
115 1.2.4.2 jruoho
116 1.2.4.2 jruoho int
117 1.2.4.2 jruoho dzopen(dev_t dev, int flag, int mode, struct lwp *l)
118 1.2.4.2 jruoho {
119 1.2.4.2 jruoho struct tty *tp;
120 1.2.4.2 jruoho int unit, line;
121 1.2.4.2 jruoho struct dz_softc *sc;
122 1.2.4.2 jruoho int s, error = 0;
123 1.2.4.2 jruoho
124 1.2.4.2 jruoho unit = DZ_I2C(minor(dev));
125 1.2.4.2 jruoho line = DZ_PORT(minor(dev));
126 1.2.4.2 jruoho if (unit >= dz_cd.cd_ndevs || dz_cd.cd_devs[unit] == NULL)
127 1.2.4.2 jruoho return (ENXIO);
128 1.2.4.2 jruoho
129 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[unit];
130 1.2.4.2 jruoho
131 1.2.4.2 jruoho if (line > 0) /* FIXME fo rmore than one line */
132 1.2.4.2 jruoho return ENXIO;
133 1.2.4.2 jruoho
134 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
135 1.2.4.2 jruoho if (tp == NULL)
136 1.2.4.2 jruoho return (ENODEV);
137 1.2.4.2 jruoho tp->t_oproc = dzstart;
138 1.2.4.2 jruoho tp->t_param = dzparam;
139 1.2.4.2 jruoho tp->t_dev = dev;
140 1.2.4.2 jruoho
141 1.2.4.2 jruoho if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
142 1.2.4.2 jruoho return (EBUSY);
143 1.2.4.2 jruoho
144 1.2.4.2 jruoho if ((tp->t_state & TS_ISOPEN) == 0) {
145 1.2.4.2 jruoho ttychars(tp);
146 1.2.4.2 jruoho if (tp->t_ispeed == 0) {
147 1.2.4.2 jruoho tp->t_iflag = TTYDEF_IFLAG;
148 1.2.4.2 jruoho tp->t_oflag = TTYDEF_OFLAG;
149 1.2.4.2 jruoho tp->t_cflag = TTYDEF_CFLAG;
150 1.2.4.2 jruoho tp->t_lflag = TTYDEF_LFLAG;
151 1.2.4.2 jruoho tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
152 1.2.4.2 jruoho }
153 1.2.4.2 jruoho (void) dzparam(tp, &tp->t_termios);
154 1.2.4.2 jruoho ttsetwater(tp);
155 1.2.4.2 jruoho }
156 1.2.4.2 jruoho /* we have no modem control but..*/
157 1.2.4.2 jruoho if (dzmctl(sc, line, TIOCM_DTR, DMBIS) & TIOCM_CD)
158 1.2.4.2 jruoho tp->t_state |= TS_CARR_ON;
159 1.2.4.2 jruoho s = spltty();
160 1.2.4.2 jruoho while (!(flag & O_NONBLOCK) && !(tp->t_cflag & CLOCAL) &&
161 1.2.4.2 jruoho !(tp->t_state & TS_CARR_ON)) {
162 1.2.4.2 jruoho tp->t_wopen++;
163 1.2.4.2 jruoho error = ttysleep(tp, &tp->t_rawcv, true, 0);
164 1.2.4.2 jruoho tp->t_wopen--;
165 1.2.4.2 jruoho if (error)
166 1.2.4.2 jruoho break;
167 1.2.4.2 jruoho }
168 1.2.4.2 jruoho (void) splx(s);
169 1.2.4.2 jruoho if (error)
170 1.2.4.2 jruoho return (error);
171 1.2.4.2 jruoho return ((*tp->t_linesw->l_open)(dev, tp));
172 1.2.4.2 jruoho }
173 1.2.4.2 jruoho int
174 1.2.4.2 jruoho dzclose(dev_t dev, int flag, int mode, struct lwp *l)
175 1.2.4.2 jruoho {
176 1.2.4.2 jruoho struct dz_softc *sc;
177 1.2.4.2 jruoho struct tty *tp;
178 1.2.4.2 jruoho int unit, line;
179 1.2.4.2 jruoho
180 1.2.4.2 jruoho
181 1.2.4.2 jruoho unit = DZ_I2C(minor(dev));
182 1.2.4.2 jruoho line = DZ_PORT(minor(dev));
183 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[unit];
184 1.2.4.2 jruoho
185 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
186 1.2.4.2 jruoho
187 1.2.4.2 jruoho (*tp->t_linesw->l_close)(tp, flag);
188 1.2.4.2 jruoho
189 1.2.4.2 jruoho /* Make sure a BREAK state is not left enabled. */
190 1.2.4.2 jruoho (void) dzmctl(sc, line, TIOCM_BRK, DMBIC);
191 1.2.4.2 jruoho
192 1.2.4.2 jruoho /* Do a hangup if so required. */
193 1.2.4.2 jruoho if ((tp->t_cflag & HUPCL) || tp->t_wopen || !(tp->t_state & TS_ISOPEN))
194 1.2.4.2 jruoho (void) dzmctl(sc, line, 0, DMSET);
195 1.2.4.2 jruoho
196 1.2.4.2 jruoho return (ttyclose(tp));
197 1.2.4.2 jruoho }
198 1.2.4.2 jruoho int
199 1.2.4.2 jruoho dzread(dev_t dev, struct uio *uio, int flag)
200 1.2.4.2 jruoho {
201 1.2.4.2 jruoho struct tty *tp;
202 1.2.4.2 jruoho struct dz_softc *sc;
203 1.2.4.2 jruoho
204 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[DZ_I2C(minor(dev))];
205 1.2.4.2 jruoho
206 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
207 1.2.4.2 jruoho return ((*tp->t_linesw->l_read)(tp, uio, flag));
208 1.2.4.2 jruoho }
209 1.2.4.2 jruoho
210 1.2.4.2 jruoho int
211 1.2.4.2 jruoho dzwrite(dev_t dev, struct uio *uio, int flag)
212 1.2.4.2 jruoho {
213 1.2.4.2 jruoho struct tty *tp;
214 1.2.4.2 jruoho struct dz_softc *sc;
215 1.2.4.2 jruoho
216 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[DZ_I2C(minor(dev))];
217 1.2.4.2 jruoho
218 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
219 1.2.4.2 jruoho return ((*tp->t_linesw->l_write)(tp, uio, flag));
220 1.2.4.2 jruoho }
221 1.2.4.2 jruoho
222 1.2.4.2 jruoho /*ARGSUSED*/
223 1.2.4.2 jruoho int
224 1.2.4.2 jruoho dzioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
225 1.2.4.2 jruoho {
226 1.2.4.2 jruoho struct dz_softc *sc;
227 1.2.4.2 jruoho struct tty *tp;
228 1.2.4.2 jruoho int unit, line;
229 1.2.4.2 jruoho int error;
230 1.2.4.2 jruoho
231 1.2.4.2 jruoho unit = DZ_I2C(minor(dev));
232 1.2.4.2 jruoho line = 0;
233 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[unit];
234 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
235 1.2.4.2 jruoho
236 1.2.4.2 jruoho error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l);
237 1.2.4.2 jruoho if (error >= 0)
238 1.2.4.2 jruoho return (error);
239 1.2.4.2 jruoho
240 1.2.4.2 jruoho error = ttioctl(tp, cmd, data, flag, l);
241 1.2.4.2 jruoho if (error >= 0)
242 1.2.4.2 jruoho return (error);
243 1.2.4.2 jruoho
244 1.2.4.2 jruoho switch (cmd) {
245 1.2.4.2 jruoho
246 1.2.4.2 jruoho case TIOCSBRK:
247 1.2.4.2 jruoho (void) dzmctl(sc, line, TIOCM_BRK, DMBIS);
248 1.2.4.2 jruoho break;
249 1.2.4.2 jruoho
250 1.2.4.2 jruoho case TIOCCBRK:
251 1.2.4.2 jruoho (void) dzmctl(sc, line, TIOCM_BRK, DMBIC);
252 1.2.4.2 jruoho break;
253 1.2.4.2 jruoho
254 1.2.4.2 jruoho case TIOCSDTR:
255 1.2.4.2 jruoho (void) dzmctl(sc, line, TIOCM_DTR, DMBIS);
256 1.2.4.2 jruoho break;
257 1.2.4.2 jruoho
258 1.2.4.2 jruoho case TIOCCDTR:
259 1.2.4.2 jruoho (void) dzmctl(sc, line, TIOCM_DTR, DMBIC);
260 1.2.4.2 jruoho break;
261 1.2.4.2 jruoho
262 1.2.4.2 jruoho case TIOCMSET:
263 1.2.4.2 jruoho (void) dzmctl(sc, line, *(int *)data, DMSET);
264 1.2.4.2 jruoho break;
265 1.2.4.2 jruoho
266 1.2.4.2 jruoho case TIOCMBIS:
267 1.2.4.2 jruoho (void) dzmctl(sc, line, *(int *)data, DMBIS);
268 1.2.4.2 jruoho break;
269 1.2.4.2 jruoho
270 1.2.4.2 jruoho case TIOCMBIC:
271 1.2.4.2 jruoho (void) dzmctl(sc, line, *(int *)data, DMBIC);
272 1.2.4.2 jruoho break;
273 1.2.4.2 jruoho
274 1.2.4.2 jruoho case TIOCMGET:
275 1.2.4.2 jruoho *(int *)data = (dzmctl(sc, line, 0, DMGET) & ~TIOCM_BRK);
276 1.2.4.2 jruoho break;
277 1.2.4.2 jruoho
278 1.2.4.2 jruoho default:
279 1.2.4.2 jruoho return (EPASSTHROUGH);
280 1.2.4.2 jruoho }
281 1.2.4.2 jruoho return (0);
282 1.2.4.2 jruoho }
283 1.2.4.2 jruoho
284 1.2.4.2 jruoho /*ARGSUSED*/
285 1.2.4.2 jruoho void
286 1.2.4.2 jruoho dzstop(struct tty *tp, int flag)
287 1.2.4.2 jruoho {
288 1.2.4.2 jruoho if (tp->t_state & TS_BUSY)
289 1.2.4.2 jruoho if (!(tp->t_state & TS_TTSTOP))
290 1.2.4.2 jruoho tp->t_state |= TS_FLUSH;
291 1.2.4.2 jruoho }
292 1.2.4.2 jruoho
293 1.2.4.2 jruoho struct tty *
294 1.2.4.2 jruoho dztty(dev_t dev)
295 1.2.4.2 jruoho {
296 1.2.4.2 jruoho struct dz_softc *sc = (void *)dz_cd.cd_devs[DZ_I2C(minor(dev))];
297 1.2.4.2 jruoho struct tty *tp = sc->sc_dz.dz_tty;
298 1.2.4.2 jruoho
299 1.2.4.2 jruoho return (tp);
300 1.2.4.2 jruoho }
301 1.2.4.2 jruoho
302 1.2.4.2 jruoho int
303 1.2.4.2 jruoho dzpoll( dev_t dev, int events, struct lwp *l)
304 1.2.4.2 jruoho {
305 1.2.4.2 jruoho struct tty *tp;
306 1.2.4.2 jruoho struct dz_softc *sc;
307 1.2.4.2 jruoho
308 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[DZ_I2C(minor(dev))];
309 1.2.4.2 jruoho
310 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
311 1.2.4.2 jruoho return ((*tp->t_linesw->l_poll)(tp, events, l));
312 1.2.4.2 jruoho }
313 1.2.4.2 jruoho
314 1.2.4.2 jruoho void
315 1.2.4.2 jruoho dzstart(struct tty *tp)
316 1.2.4.2 jruoho {
317 1.2.4.2 jruoho struct dz_softc *sc;
318 1.2.4.2 jruoho struct clist *cl;
319 1.2.4.2 jruoho int unit, s;
320 1.2.4.2 jruoho
321 1.2.4.2 jruoho unit = DZ_I2C(minor(tp->t_dev));
322 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[unit];
323 1.2.4.2 jruoho
324 1.2.4.2 jruoho s = spltty();
325 1.2.4.2 jruoho if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
326 1.2.4.2 jruoho splx(s);
327 1.2.4.2 jruoho return;
328 1.2.4.2 jruoho }
329 1.2.4.2 jruoho cl = &tp->t_outq;
330 1.2.4.2 jruoho ttypull(tp);
331 1.2.4.2 jruoho if (cl->c_cc == 0) {
332 1.2.4.2 jruoho splx(s);
333 1.2.4.2 jruoho return;
334 1.2.4.2 jruoho }
335 1.2.4.2 jruoho
336 1.2.4.2 jruoho tp->t_state |= TS_BUSY;
337 1.2.4.2 jruoho
338 1.2.4.2 jruoho /* was idle, get it started */
339 1.2.4.2 jruoho dzxint(sc,USI_TXRDY);
340 1.2.4.2 jruoho splx(s);
341 1.2.4.2 jruoho }
342 1.2.4.2 jruoho
343 1.2.4.2 jruoho static int rclk = 25000000; /* BUGBUGBUGBUG */
344 1.2.4.2 jruoho
345 1.2.4.2 jruoho static int
346 1.2.4.2 jruoho dzdivisor(int baudrate)
347 1.2.4.2 jruoho {
348 1.2.4.2 jruoho int act_baud, divisor, error;
349 1.2.4.2 jruoho
350 1.2.4.2 jruoho if (baudrate <= 0)
351 1.2.4.2 jruoho return (0);
352 1.2.4.2 jruoho
353 1.2.4.2 jruoho divisor = (rclk/8)/(baudrate);
354 1.2.4.2 jruoho divisor = (divisor/2) + (divisor&1);
355 1.2.4.2 jruoho
356 1.2.4.2 jruoho if (divisor <= 0)
357 1.2.4.2 jruoho return (-1);
358 1.2.4.2 jruoho act_baud = rclk / (divisor * 16);
359 1.2.4.2 jruoho
360 1.2.4.2 jruoho /* 10 times error in percent: */
361 1.2.4.2 jruoho error = ((act_baud - baudrate) * 2000 / baudrate + 1) >> 1;
362 1.2.4.2 jruoho
363 1.2.4.2 jruoho /* 3.0% maximum error tolerance: */
364 1.2.4.2 jruoho if (error < -30 || error > 30)
365 1.2.4.2 jruoho return (-1);
366 1.2.4.2 jruoho
367 1.2.4.2 jruoho return (divisor);
368 1.2.4.2 jruoho }
369 1.2.4.2 jruoho
370 1.2.4.2 jruoho static int
371 1.2.4.2 jruoho dzparam(struct tty *tp, struct termios *t)
372 1.2.4.2 jruoho {
373 1.2.4.2 jruoho struct dz_softc *sc;
374 1.2.4.2 jruoho int cflag = t->c_cflag;
375 1.2.4.2 jruoho int unit, line;
376 1.2.4.2 jruoho int speed;
377 1.2.4.2 jruoho unsigned lpr;
378 1.2.4.2 jruoho int s;
379 1.2.4.2 jruoho struct _Usart *dzr;
380 1.2.4.2 jruoho
381 1.2.4.2 jruoho unit = DZ_I2C(minor(tp->t_dev));
382 1.2.4.2 jruoho line = DZ_PORT(minor(tp->t_dev));
383 1.2.4.2 jruoho sc = (void *)dz_cd.cd_devs[unit];
384 1.2.4.2 jruoho
385 1.2.4.2 jruoho /* check requested parameters */
386 1.2.4.2 jruoho if (t->c_ispeed != t->c_ospeed)
387 1.2.4.2 jruoho return (EINVAL);
388 1.2.4.2 jruoho speed = dzdivisor(t->c_ispeed);
389 1.2.4.2 jruoho if (speed < 0)
390 1.2.4.2 jruoho return (EINVAL);
391 1.2.4.2 jruoho
392 1.2.4.2 jruoho tp->t_ispeed = t->c_ispeed;
393 1.2.4.2 jruoho tp->t_ospeed = t->c_ospeed;
394 1.2.4.2 jruoho tp->t_cflag = cflag;
395 1.2.4.2 jruoho
396 1.2.4.2 jruoho { static int didit=0;
397 1.2.4.2 jruoho if (!didit && t->c_ispeed != 38400)
398 1.2.4.2 jruoho printf("dzparam: c_ispeed %d ignored, keeping 38400\n",t->c_ispeed);
399 1.2.4.2 jruoho didit = 1;
400 1.2.4.2 jruoho }
401 1.2.4.2 jruoho speed = dzdivisor(38400);
402 1.2.4.2 jruoho
403 1.2.4.2 jruoho if (speed == 0) {
404 1.2.4.2 jruoho (void) dzmctl(sc, line, 0, DMSET); /* hang up line */
405 1.2.4.2 jruoho return (0);
406 1.2.4.2 jruoho }
407 1.2.4.2 jruoho
408 1.2.4.2 jruoho switch (cflag & CSIZE)
409 1.2.4.2 jruoho {
410 1.2.4.2 jruoho case CS5:
411 1.2.4.2 jruoho lpr = USC_BPC_5;
412 1.2.4.2 jruoho break;
413 1.2.4.2 jruoho case CS6:
414 1.2.4.2 jruoho lpr = USC_BPC_6;
415 1.2.4.2 jruoho break;
416 1.2.4.2 jruoho case CS7:
417 1.2.4.2 jruoho lpr = USC_BPC_7;
418 1.2.4.2 jruoho break;
419 1.2.4.2 jruoho default:
420 1.2.4.2 jruoho lpr = USC_BPC_8;
421 1.2.4.2 jruoho break;
422 1.2.4.2 jruoho }
423 1.2.4.2 jruoho if (cflag & CSTOPB)
424 1.2.4.2 jruoho lpr |= USC_2STOP;
425 1.2.4.2 jruoho
426 1.2.4.2 jruoho if (cflag & PARENB) {
427 1.2.4.2 jruoho if (cflag & PARODD)
428 1.2.4.2 jruoho lpr |= USC_ODD;
429 1.2.4.2 jruoho else
430 1.2.4.2 jruoho lpr |= USC_EVEN;
431 1.2.4.2 jruoho } else
432 1.2.4.2 jruoho lpr |= USC_NONE;
433 1.2.4.2 jruoho
434 1.2.4.2 jruoho s = spltty();
435 1.2.4.2 jruoho
436 1.2.4.2 jruoho dzr = sc->sc_dr;
437 1.2.4.2 jruoho
438 1.2.4.2 jruoho dzr->Baud = speed;
439 1.2.4.2 jruoho dzr->Control = USC_CLKDIV_4 | USC_TXEN | USC_RXEN | lpr;
440 1.2.4.2 jruoho #define USI_INTRS (USI_RXRDY|USI_RXBRK|USI_OVRE|USI_FRAME|USI_PARE)
441 1.2.4.2 jruoho dzr->IntrEnable = USI_INTRS;
442 1.2.4.2 jruoho
443 1.2.4.2 jruoho (void) splx(s);
444 1.2.4.2 jruoho return (0);
445 1.2.4.2 jruoho }
446 1.2.4.2 jruoho
447 1.2.4.2 jruoho static unsigned
448 1.2.4.2 jruoho dzmctl(struct dz_softc *sc, int line, int bits, int how)
449 1.2.4.2 jruoho {
450 1.2.4.2 jruoho unsigned mbits;
451 1.2.4.2 jruoho int s;
452 1.2.4.2 jruoho struct _Usart *dzr;
453 1.2.4.2 jruoho
454 1.2.4.2 jruoho mbits = 0;
455 1.2.4.2 jruoho
456 1.2.4.2 jruoho s = spltty();
457 1.2.4.2 jruoho
458 1.2.4.2 jruoho dzr = sc->sc_dr;
459 1.2.4.2 jruoho
460 1.2.4.2 jruoho /* we have no modem control bits (CD,RI,DTR,DSR,..) */
461 1.2.4.2 jruoho mbits |= TIOCM_CD;
462 1.2.4.2 jruoho mbits |= TIOCM_DTR;
463 1.2.4.2 jruoho
464 1.2.4.2 jruoho if (dzr->ChannelStatus & USI_RXBRK)
465 1.2.4.2 jruoho mbits |= TIOCM_BRK;
466 1.2.4.2 jruoho
467 1.2.4.2 jruoho switch (how)
468 1.2.4.2 jruoho {
469 1.2.4.2 jruoho case DMSET:
470 1.2.4.2 jruoho mbits = bits;
471 1.2.4.2 jruoho break;
472 1.2.4.2 jruoho
473 1.2.4.2 jruoho case DMBIS:
474 1.2.4.2 jruoho mbits |= bits;
475 1.2.4.2 jruoho break;
476 1.2.4.2 jruoho
477 1.2.4.2 jruoho case DMBIC:
478 1.2.4.2 jruoho mbits &= ~bits;
479 1.2.4.2 jruoho break;
480 1.2.4.2 jruoho
481 1.2.4.2 jruoho case DMGET:
482 1.2.4.2 jruoho (void) splx(s);
483 1.2.4.2 jruoho return (mbits);
484 1.2.4.2 jruoho }
485 1.2.4.2 jruoho
486 1.2.4.2 jruoho /* BUGBUG work in progress */
487 1.2.4.2 jruoho if (mbits & TIOCM_BRK) {
488 1.2.4.2 jruoho sc->sc_brk |= (1 << line);
489 1.2.4.2 jruoho dzr->Control |= USC_STTBRK;
490 1.2.4.2 jruoho } else {
491 1.2.4.2 jruoho sc->sc_brk &= ~(1 << line);
492 1.2.4.2 jruoho dzr->Control |= USC_STPBRK;
493 1.2.4.2 jruoho }
494 1.2.4.2 jruoho
495 1.2.4.2 jruoho (void) splx(s);
496 1.2.4.2 jruoho return (mbits);
497 1.2.4.2 jruoho }
498 1.2.4.2 jruoho
499 1.2.4.2 jruoho
500 1.2.4.2 jruoho #if defined(DDB)
501 1.2.4.2 jruoho int dz_ddb = 0;
502 1.2.4.2 jruoho #endif
503 1.2.4.2 jruoho
504 1.2.4.2 jruoho /* Receiver Interrupt */
505 1.2.4.2 jruoho
506 1.2.4.2 jruoho void
507 1.2.4.2 jruoho dzrint(struct dz_softc *sc, uint32_t csr)
508 1.2.4.2 jruoho {
509 1.2.4.2 jruoho struct tty *tp;
510 1.2.4.2 jruoho int cc, mcc;
511 1.2.4.2 jruoho struct _Usart *dzr;
512 1.2.4.2 jruoho
513 1.2.4.2 jruoho sc->sc_rxint++;
514 1.2.4.2 jruoho dzr = sc->sc_dr;
515 1.2.4.2 jruoho
516 1.2.4.2 jruoho cc = dzr->RxData;
517 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
518 1.2.4.2 jruoho
519 1.2.4.2 jruoho if (csr & USI_RXBRK)
520 1.2.4.2 jruoho mcc = CNC_BREAK;
521 1.2.4.2 jruoho else
522 1.2.4.2 jruoho mcc = cc;
523 1.2.4.2 jruoho
524 1.2.4.2 jruoho /* clear errors before we print or bail out */
525 1.2.4.2 jruoho if (csr & (USI_OVRE|USI_FRAME|USI_PARE))
526 1.2.4.2 jruoho dzr->Control = USC_RSTSTA;
527 1.2.4.2 jruoho
528 1.2.4.2 jruoho if (!(tp->t_state & TS_ISOPEN)) {
529 1.2.4.2 jruoho wakeup(&tp->t_rawq);
530 1.2.4.2 jruoho return;
531 1.2.4.2 jruoho }
532 1.2.4.2 jruoho
533 1.2.4.2 jruoho if (csr & USI_OVRE) {
534 1.2.4.2 jruoho log(LOG_WARNING, "%s: silo overflow, line %d\n",
535 1.2.4.2 jruoho sc->sc_dev.dv_xname, 0);
536 1.2.4.2 jruoho }
537 1.2.4.2 jruoho
538 1.2.4.2 jruoho if (csr & USI_FRAME)
539 1.2.4.2 jruoho cc |= TTY_FE;
540 1.2.4.2 jruoho if (csr & USI_PARE)
541 1.2.4.2 jruoho cc |= TTY_PE;
542 1.2.4.2 jruoho
543 1.2.4.2 jruoho #if defined(DDB)
544 1.2.4.2 jruoho /* ^P drops into DDB */
545 1.2.4.2 jruoho if (dz_ddb && (cc == 0x10))
546 1.2.4.2 jruoho Debugger();
547 1.2.4.2 jruoho #endif
548 1.2.4.2 jruoho (*tp->t_linesw->l_rint)(cc, tp);
549 1.2.4.2 jruoho
550 1.2.4.2 jruoho }
551 1.2.4.2 jruoho
552 1.2.4.2 jruoho /* Transmitter Interrupt */
553 1.2.4.2 jruoho
554 1.2.4.2 jruoho void
555 1.2.4.2 jruoho dzxint(struct dz_softc *sc, uint32_t csr)
556 1.2.4.2 jruoho {
557 1.2.4.2 jruoho struct tty *tp;
558 1.2.4.2 jruoho struct clist *cl;
559 1.2.4.2 jruoho int ch;
560 1.2.4.2 jruoho struct _Usart *dzr;
561 1.2.4.2 jruoho
562 1.2.4.2 jruoho dzr = sc->sc_dr;
563 1.2.4.2 jruoho
564 1.2.4.2 jruoho tp = sc->sc_dz.dz_tty;
565 1.2.4.2 jruoho cl = &tp->t_outq;
566 1.2.4.2 jruoho tp->t_state &= ~TS_BUSY;
567 1.2.4.2 jruoho
568 1.2.4.2 jruoho /* Just send out a char if we have one */
569 1.2.4.2 jruoho if (cl->c_cc) {
570 1.2.4.2 jruoho tp->t_state |= TS_BUSY;
571 1.2.4.2 jruoho ch = getc(cl);
572 1.2.4.2 jruoho dzr->TxData = ch;
573 1.2.4.2 jruoho dzr->IntrEnable = USI_TXRDY;
574 1.2.4.2 jruoho return;
575 1.2.4.2 jruoho }
576 1.2.4.2 jruoho
577 1.2.4.2 jruoho /* Nothing to send; turn off intr */
578 1.2.4.2 jruoho dzr->IntrDisable = USI_TXRDY;
579 1.2.4.2 jruoho
580 1.2.4.2 jruoho if (tp->t_state & TS_FLUSH)
581 1.2.4.2 jruoho tp->t_state &= ~TS_FLUSH;
582 1.2.4.2 jruoho else
583 1.2.4.2 jruoho ndflush (&tp->t_outq, cl->c_cc);
584 1.2.4.2 jruoho
585 1.2.4.2 jruoho (*tp->t_linesw->l_start)(tp);
586 1.2.4.2 jruoho }
587 1.2.4.2 jruoho
588 1.2.4.2 jruoho /* Machdep part of the driver
589 1.2.4.2 jruoho */
590 1.2.4.2 jruoho int dz_ebus_match(struct device *, struct cfdata *, void *);
591 1.2.4.2 jruoho void dz_ebus_attach(struct device *, struct device *, void *);
592 1.2.4.2 jruoho int dz_ebus_intr(void *, void *);
593 1.2.4.2 jruoho
594 1.2.4.2 jruoho void dz_ebus_cnsetup(paddr_t);
595 1.2.4.2 jruoho void dz_ebus_cninit(struct consdev*);
596 1.2.4.2 jruoho int dz_ebus_cngetc(dev_t);
597 1.2.4.2 jruoho void dz_ebus_cnputc(dev_t, int);
598 1.2.4.2 jruoho void dz_ebus_cnpollc(dev_t, int);
599 1.2.4.2 jruoho
600 1.2.4.2 jruoho static int dz_ebus_getmajor(void);
601 1.2.4.2 jruoho
602 1.2.4.2 jruoho CFATTACH_DECL(dz_ebus, sizeof(struct dz_softc),
603 1.2.4.2 jruoho dz_ebus_match, dz_ebus_attach, NULL, NULL);
604 1.2.4.2 jruoho
605 1.2.4.2 jruoho struct consdev dz_ebus_consdev = {
606 1.2.4.2 jruoho NULL, dz_ebus_cninit, dz_ebus_cngetc, dz_ebus_cnputc,
607 1.2.4.2 jruoho dz_ebus_cnpollc, NULL, NULL, NULL, NODEV, CN_NORMAL,
608 1.2.4.2 jruoho };
609 1.2.4.2 jruoho
610 1.2.4.2 jruoho /* Points to the console regs. Special mapping until VM is turned on.
611 1.2.4.2 jruoho */
612 1.2.4.2 jruoho struct _Usart *dzcn;
613 1.2.4.2 jruoho
614 1.2.4.2 jruoho int
615 1.2.4.2 jruoho dz_ebus_match(struct device *parent, struct cfdata *cf, void *aux)
616 1.2.4.2 jruoho {
617 1.2.4.2 jruoho struct ebus_attach_args *iba;
618 1.2.4.2 jruoho struct _Usart *us;
619 1.2.4.2 jruoho
620 1.2.4.2 jruoho iba = aux;
621 1.2.4.2 jruoho
622 1.2.4.2 jruoho if (strcmp(iba->ia_name, "dz") != 0)
623 1.2.4.2 jruoho return (0);
624 1.2.4.2 jruoho
625 1.2.4.2 jruoho us = (struct _Usart *)iba->ia_vaddr;
626 1.2.4.2 jruoho if ((us == NULL) ||
627 1.2.4.2 jruoho (us->Tag != PMTTAG_USART))
628 1.2.4.2 jruoho return (0);
629 1.2.4.2 jruoho
630 1.2.4.2 jruoho return (1);
631 1.2.4.2 jruoho }
632 1.2.4.2 jruoho
633 1.2.4.2 jruoho void
634 1.2.4.2 jruoho dz_ebus_attach(struct device *parent, struct device *self, void *aux)
635 1.2.4.2 jruoho {
636 1.2.4.2 jruoho struct ebus_attach_args *iba;
637 1.2.4.2 jruoho struct dz_softc *sc;
638 1.2.4.2 jruoho
639 1.2.4.2 jruoho iba = aux;
640 1.2.4.2 jruoho sc = (struct dz_softc *)self;
641 1.2.4.2 jruoho
642 1.2.4.2 jruoho sc->sc_dr = (struct _Usart *)iba->ia_vaddr;
643 1.2.4.2 jruoho #if DEBUG
644 1.2.4.2 jruoho printf(" virt=%p ", (void *)sc->sc_dr);
645 1.2.4.2 jruoho #endif
646 1.2.4.2 jruoho
647 1.2.4.2 jruoho printf(": neilsart 1 line");
648 1.2.4.2 jruoho ebus_intr_establish(parent, (void *)iba->ia_cookie, IPL_TTY,
649 1.2.4.2 jruoho dz_ebus_intr, sc);
650 1.2.4.2 jruoho
651 1.2.4.2 jruoho sc->sc_rxint = sc->sc_brk = 0;
652 1.2.4.2 jruoho sc->sc_consline = 0;
653 1.2.4.2 jruoho
654 1.2.4.2 jruoho /* Initialize our softc structure. Should be done in open? */
655 1.2.4.2 jruoho
656 1.2.4.2 jruoho sc->sc_dz.dz_sc = sc;
657 1.2.4.2 jruoho sc->sc_dz.dz_line = 0;
658 1.2.4.2 jruoho sc->sc_dz.dz_tty = tty_alloc();
659 1.2.4.2 jruoho
660 1.2.4.2 jruoho evcnt_attach_dynamic(&sc->sc_rintrcnt, EVCNT_TYPE_INTR, NULL,
661 1.2.4.2 jruoho sc->sc_dev.dv_xname, "rintr");
662 1.2.4.2 jruoho evcnt_attach_dynamic(&sc->sc_tintrcnt, EVCNT_TYPE_INTR, NULL,
663 1.2.4.2 jruoho sc->sc_dev.dv_xname, "tintr");
664 1.2.4.2 jruoho
665 1.2.4.2 jruoho /* Initialize hw regs */
666 1.2.4.2 jruoho #if 0
667 1.2.4.2 jruoho DZ_WRITE_WORD(dr_csr, DZ_CSR_MSE | DZ_CSR_RXIE | DZ_CSR_TXIE);
668 1.2.4.2 jruoho DZ_WRITE_BYTE(dr_dtr, 0);
669 1.2.4.2 jruoho DZ_WRITE_BYTE(dr_break, 0);
670 1.2.4.2 jruoho #endif
671 1.2.4.2 jruoho
672 1.2.4.2 jruoho /* Switch the console to virtual mode */
673 1.2.4.2 jruoho dzcn = sc->sc_dr;
674 1.2.4.2 jruoho /* And test it */
675 1.2.4.2 jruoho printf("\n");
676 1.2.4.2 jruoho
677 1.2.4.2 jruoho }
678 1.2.4.2 jruoho
679 1.2.4.2 jruoho static int
680 1.2.4.2 jruoho dz_ebus_getmajor(void)
681 1.2.4.2 jruoho {
682 1.2.4.2 jruoho extern const struct cdevsw dz_cdevsw;
683 1.2.4.2 jruoho static int cache = -1;
684 1.2.4.2 jruoho
685 1.2.4.2 jruoho if (cache != -1)
686 1.2.4.2 jruoho return (cache);
687 1.2.4.2 jruoho
688 1.2.4.2 jruoho return (cache = cdevsw_lookup_major(&dz_cdevsw));
689 1.2.4.2 jruoho }
690 1.2.4.2 jruoho
691 1.2.4.2 jruoho int
692 1.2.4.2 jruoho dz_ebus_intr(void *cookie, void *f)
693 1.2.4.2 jruoho {
694 1.2.4.2 jruoho struct dz_softc *sc;
695 1.2.4.2 jruoho struct _Usart *dzr;
696 1.2.4.2 jruoho uint32_t csr;
697 1.2.4.2 jruoho
698 1.2.4.2 jruoho sc = cookie;
699 1.2.4.2 jruoho dzr = sc->sc_dr;
700 1.2.4.2 jruoho
701 1.2.4.2 jruoho #define USI_INTERRUPTS (USI_INTRS|USI_TXRDY)
702 1.2.4.2 jruoho
703 1.2.4.2 jruoho for (; ((csr = (dzr->ChannelStatus & dzr->IntrMask)) & USI_INTERRUPTS) != 0;) {
704 1.2.4.2 jruoho if ((csr & USI_INTRS) != 0)
705 1.2.4.2 jruoho dzrint(sc, csr);
706 1.2.4.2 jruoho if ((csr & USI_TXRDY) != 0)
707 1.2.4.2 jruoho dzxint(sc, csr);
708 1.2.4.2 jruoho }
709 1.2.4.2 jruoho
710 1.2.4.2 jruoho return (0);
711 1.2.4.2 jruoho }
712 1.2.4.2 jruoho
713 1.2.4.2 jruoho void
714 1.2.4.2 jruoho dz_ebus_cnsetup(paddr_t addr)
715 1.2.4.2 jruoho {
716 1.2.4.2 jruoho
717 1.2.4.2 jruoho dzcn = (struct _Usart *)addr;
718 1.2.4.2 jruoho
719 1.2.4.2 jruoho #if 0
720 1.2.4.2 jruoho /* Initialize enough to xmit/recv via polling.
721 1.2.4.2 jruoho * Bootloader might or might not have done it.
722 1.2.4.2 jruoho */
723 1.2.4.2 jruoho dzcn->Control = USC_RXEN|USC_TXEN|USC_BPC_8|USC_NONE|USC_1STOP|USC_CLKDIV_4;
724 1.2.4.2 jruoho dzcn->Baud = 0x29; /* 38400 */
725 1.2.4.2 jruoho #endif
726 1.2.4.2 jruoho
727 1.2.4.2 jruoho /*
728 1.2.4.2 jruoho * Point the console at us
729 1.2.4.2 jruoho */
730 1.2.4.2 jruoho cn_tab = &dz_ebus_consdev;
731 1.2.4.2 jruoho cn_tab->cn_pri = CN_NORMAL;/*CN_REMOTE?*/
732 1.2.4.2 jruoho cn_tab->cn_dev = makedev(dz_ebus_getmajor(), 0);
733 1.2.4.2 jruoho }
734 1.2.4.2 jruoho
735 1.2.4.2 jruoho void dz_ebus_cninit(struct consdev *cn)
736 1.2.4.2 jruoho {
737 1.2.4.2 jruoho }
738 1.2.4.2 jruoho
739 1.2.4.2 jruoho int
740 1.2.4.2 jruoho dz_ebus_cngetc(dev_t dev)
741 1.2.4.2 jruoho {
742 1.2.4.2 jruoho int c, s;
743 1.2.4.2 jruoho
744 1.2.4.2 jruoho c = 0;
745 1.2.4.2 jruoho s = spltty();
746 1.2.4.2 jruoho
747 1.2.4.2 jruoho while ((dzcn->ChannelStatus & USI_RXRDY) == 0)
748 1.2.4.2 jruoho DELAY(10);
749 1.2.4.2 jruoho c = dzcn->RxData;
750 1.2.4.2 jruoho
751 1.2.4.2 jruoho splx(s);
752 1.2.4.2 jruoho if (c == 13) /* map cr->ln */
753 1.2.4.2 jruoho c = 10;
754 1.2.4.2 jruoho return (c);
755 1.2.4.2 jruoho }
756 1.2.4.2 jruoho
757 1.2.4.2 jruoho int dzflipped = 0;
758 1.2.4.2 jruoho void
759 1.2.4.2 jruoho dz_ebus_cnputc(dev_t dev, int ch)
760 1.2.4.2 jruoho {
761 1.2.4.2 jruoho int timeout, s;
762 1.2.4.2 jruoho
763 1.2.4.2 jruoho /* Don't hang the machine! */
764 1.2.4.2 jruoho timeout = 1 << 15;
765 1.2.4.2 jruoho
766 1.2.4.2 jruoho s = spltty();
767 1.2.4.2 jruoho
768 1.2.4.2 jruoho #if 1
769 1.2.4.2 jruoho /* Keep wired to hunt for a bug */
770 1.2.4.2 jruoho if (dzcn && (dzcn != (struct _Usart *)0xfff90000)) {
771 1.2.4.2 jruoho dzcn = (struct _Usart *)0xfff90000;
772 1.2.4.2 jruoho dzflipped++;
773 1.2.4.2 jruoho }
774 1.2.4.2 jruoho #endif
775 1.2.4.2 jruoho
776 1.2.4.2 jruoho /* Wait until ready */
777 1.2.4.2 jruoho while ((dzcn->ChannelStatus & USI_TXRDY) == 0)
778 1.2.4.2 jruoho if (--timeout < 0)
779 1.2.4.2 jruoho break;
780 1.2.4.2 jruoho
781 1.2.4.2 jruoho /* Put the character */
782 1.2.4.2 jruoho dzcn->TxData = ch;
783 1.2.4.2 jruoho
784 1.2.4.2 jruoho splx(s);
785 1.2.4.2 jruoho }
786 1.2.4.2 jruoho
787 1.2.4.2 jruoho /* Called before/after going into poll mode
788 1.2.4.2 jruoho */
789 1.2.4.2 jruoho void
790 1.2.4.2 jruoho dz_ebus_cnpollc(dev_t dev, int on)
791 1.2.4.2 jruoho {
792 1.2.4.2 jruoho }
793 1.2.4.2 jruoho
794