This source file includes following definitions.
- spifmatch
- spifattach
- sttymatch
- sttyattach
- sttyopen
- sttyclose
- sttyioctl
- stty_modem_control
- stty_param
- sttyread
- sttywrite
- sttytty
- sttystop
- stty_start
- spifstcintr_rxexception
- spifstcintr_rx
- spifstcintr_tx
- spifstcintr_mx
- spifstcintr
- spifsoftintr
- stty_write_ccr
- stty_compute_baud
- sbppmatch
- sbppattach
- sbppopen
- sbppclose
- spifppcintr
- sbppread
- sbppwrite
- sbpp_rw
- sbpppoll
- sbppioctl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/proc.h>
42 #include <sys/device.h>
43 #include <sys/kernel.h>
44 #include <sys/file.h>
45 #include <sys/errno.h>
46 #include <sys/ioctl.h>
47 #include <sys/mbuf.h>
48 #include <sys/socket.h>
49 #include <sys/syslog.h>
50 #include <sys/malloc.h>
51 #include <sys/tty.h>
52 #include <sys/conf.h>
53
54 #include <machine/autoconf.h>
55 #include <dev/sbus/sbusvar.h>
56 #include <dev/sbus/spifreg.h>
57 #include <dev/sbus/spifvar.h>
58
59 int spifmatch(struct device *, void *, void *);
60 void spifattach(struct device *, struct device *, void *);
61
62 int sttymatch(struct device *, void *, void *);
63 void sttyattach(struct device *, struct device *, void *);
64 int sttyopen(dev_t, int, int, struct proc *);
65 int sttyclose(dev_t, int, int, struct proc *);
66 int sttyread(dev_t, struct uio *, int);
67 int sttywrite(dev_t, struct uio *, int);
68 int sttyioctl(dev_t, u_long, caddr_t, int, struct proc *);
69 int sttystop(struct tty *, int);
70
71 int spifstcintr(void *);
72 int spifstcintr_mx(struct spif_softc *, int *);
73 int spifstcintr_tx(struct spif_softc *, int *);
74 int spifstcintr_rx(struct spif_softc *, int *);
75 int spifstcintr_rxexception(struct spif_softc *, int *);
76 void spifsoftintr(void *);
77
78 int stty_param(struct tty *, struct termios *);
79 struct tty *sttytty(dev_t);
80 int stty_modem_control(struct stty_port *, int, int);
81 void stty_write_ccr(struct spif_softc *, u_int8_t);
82 int stty_compute_baud(speed_t, int, u_int8_t *, u_int8_t *);
83 void stty_start(struct tty *);
84
85 int sbppmatch(struct device *, void *, void *);
86 void sbppattach(struct device *, struct device *, void *);
87 int sbppopen(dev_t, int, int, struct proc *);
88 int sbppclose(dev_t, int, int, struct proc *);
89 int sbppread(dev_t, struct uio *, int);
90 int sbppwrite(dev_t, struct uio *, int);
91 int sbpp_rw(dev_t, struct uio *);
92 int spifppcintr(void *);
93 int sbpppoll(dev_t, int, struct proc *);
94 int sbppioctl(dev_t, u_long, caddr_t, int, struct proc *);
95
96 struct cfattach spif_ca = {
97 sizeof (struct spif_softc), spifmatch, spifattach
98 };
99
100 struct cfdriver spif_cd = {
101 NULL, "spif", DV_DULL
102 };
103
104 struct cfattach stty_ca = {
105 sizeof(struct stty_softc), sttymatch, sttyattach
106 };
107
108 struct cfdriver stty_cd = {
109 NULL, "stty", DV_TTY
110 };
111
112 struct cfattach sbpp_ca = {
113 sizeof(struct sbpp_softc), sbppmatch, sbppattach
114 };
115
116 struct cfdriver sbpp_cd = {
117 NULL, "sbpp", DV_DULL
118 };
119
120
121 #define STC_WRITE(sc,r,v) \
122 bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v))
123 #define STC_READ(sc,r) \
124 bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r))
125
126
127 #define ISTC_WRITE(sc,r,v) \
128 bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v))
129 #define ISTC_READ(sc,r) \
130 bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r))
131
132
133 #define PPC_WRITE(sc,r,v) \
134 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v))
135 #define PPC_READ(sc,r) \
136 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r))
137
138 #define DTR_WRITE(sc,port,v) \
139 do { \
140 sc->sc_ttys->sc_port[(port)].sp_dtr = v; \
141 bus_space_write_1((sc)->sc_bustag, \
142 sc->sc_dtrh, port, (v == 0) ? 1 : 0); \
143 } while (0)
144
145 #define DTR_READ(sc,port) ((sc)->sc_ttys->sc_port[(port)].sp_dtr)
146
147 int
148 spifmatch(parent, vcf, aux)
149 struct device *parent;
150 void *vcf, *aux;
151 {
152 struct cfdata *cf = vcf;
153 struct sbus_attach_args *sa = aux;
154
155 if (strcmp(cf->cf_driver->cd_name, sa->sa_name) &&
156 strcmp("SUNW,spif", sa->sa_name))
157 return (0);
158 return (1);
159 }
160
161 void
162 spifattach(parent, self, aux)
163 struct device *parent, *self;
164 void *aux;
165 {
166 struct spif_softc *sc = (struct spif_softc *)self;
167 struct sbus_attach_args *sa = aux;
168
169 if (sa->sa_nintr != 2) {
170 printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr);
171 return;
172 }
173
174 if (sa->sa_nreg != 1) {
175 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg);
176 return;
177 }
178
179 sc->sc_bustag = sa->sa_bustag;
180 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot,
181 sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size,
182 0, 0, &sc->sc_regh) != 0) {
183 printf(": can't map registers\n");
184 return;
185 }
186
187 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
188 DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 0) {
189 printf(": can't map dtr regs\n");
190 goto fail_unmapregs;
191 }
192
193 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
194 STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) {
195 printf(": can't map dtr regs\n");
196 goto fail_unmapregs;
197 }
198
199 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
200 ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) {
201 printf(": can't map dtr regs\n");
202 goto fail_unmapregs;
203 }
204
205 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh,
206 PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) {
207 printf(": can't map dtr regs\n");
208 goto fail_unmapregs;
209 }
210
211 sc->sc_ppcih = bus_intr_establish(sa->sa_bustag,
212 sa->sa_intr[PARALLEL_INTR].sbi_pri, IPL_TTY, 0, spifppcintr, sc,
213 self->dv_xname);
214 if (sc->sc_ppcih == NULL) {
215 printf(": failed to establish ppc interrupt\n");
216 goto fail_unmapregs;
217 }
218
219 sc->sc_stcih = bus_intr_establish(sa->sa_bustag,
220 sa->sa_intr[SERIAL_INTR].sbi_pri, IPL_TTY, 0, spifstcintr, sc,
221 self->dv_xname);
222 if (sc->sc_stcih == NULL) {
223 printf(": failed to establish stc interrupt\n");
224 goto fail_unmapregs;
225 }
226
227 sc->sc_softih = softintr_establish(IPL_TTY, spifsoftintr, sc);
228 if (sc->sc_softih == NULL) {
229 printf(": can't get soft intr\n");
230 goto fail_unmapregs;
231 }
232
233 sc->sc_node = sa->sa_node;
234
235 sc->sc_rev = getpropint(sc->sc_node, "revlev", 0);
236
237 sc->sc_osc = getpropint(sc->sc_node, "verosc", 0);
238 switch (sc->sc_osc) {
239 case SPIF_OSC10:
240 sc->sc_osc = 10000000;
241 break;
242 case SPIF_OSC9:
243 default:
244 sc->sc_osc = 9830400;
245 break;
246 }
247
248 sc->sc_nser = 8;
249 sc->sc_npar = 1;
250
251 sc->sc_rev2 = STC_READ(sc, STC_GFRCR);
252 STC_WRITE(sc, STC_GSVR, 0);
253
254 stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL);
255 while (STC_READ(sc, STC_GSVR) != 0xff);
256 while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2);
257
258 STC_WRITE(sc, STC_PPRH, CD180_PPRH);
259 STC_WRITE(sc, STC_PPRL, CD180_PPRL);
260 STC_WRITE(sc, STC_MSMR, SPIF_MSMR);
261 STC_WRITE(sc, STC_TSMR, SPIF_TSMR);
262 STC_WRITE(sc, STC_RSMR, SPIF_RSMR);
263 STC_WRITE(sc, STC_GSVR, 0);
264 STC_WRITE(sc, STC_GSCR1, 0);
265 STC_WRITE(sc, STC_GSCR2, 0);
266 STC_WRITE(sc, STC_GSCR3, 0);
267
268 printf(": rev %x chiprev %x osc %sMHz\n",
269 sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc));
270
271 (void)config_found(self, sttymatch, NULL);
272 (void)config_found(self, sbppmatch, NULL);
273
274 return;
275
276 fail_unmapregs:
277 bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_reg[0].sbr_size);
278 }
279
280 int
281 sttymatch(parent, vcf, aux)
282 struct device *parent;
283 void *vcf, *aux;
284 {
285 struct spif_softc *sc = (struct spif_softc *)parent;
286
287 return (aux == sttymatch && sc->sc_ttys == NULL);
288 }
289
290 void
291 sttyattach(parent, dev, aux)
292 struct device *parent, *dev;
293 void *aux;
294 {
295 struct spif_softc *sc = (struct spif_softc *)parent;
296 struct stty_softc *ssc = (struct stty_softc *)dev;
297 int port;
298
299 sc->sc_ttys = ssc;
300
301 for (port = 0; port < sc->sc_nser; port++) {
302 struct stty_port *sp = &ssc->sc_port[port];
303 struct tty *tp;
304
305 DTR_WRITE(sc, port, 0);
306
307 tp = ttymalloc();
308
309 tp->t_oproc = stty_start;
310 tp->t_param = stty_param;
311
312 sp->sp_tty = tp;
313 sp->sp_sc = sc;
314 sp->sp_channel = port;
315
316 sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT);
317 if(sp->sp_rbuf == NULL)
318 break;
319
320 sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE;
321 }
322
323 ssc->sc_nports = port;
324
325 printf(": %d tty%s\n", port, port == 1 ? "" : "s");
326 }
327
328 int
329 sttyopen(dev, flags, mode, p)
330 dev_t dev;
331 int flags;
332 int mode;
333 struct proc *p;
334 {
335 struct spif_softc *csc;
336 struct stty_softc *sc;
337 struct stty_port *sp;
338 struct tty *tp;
339 int card = SPIF_CARD(dev);
340 int port = SPIF_PORT(dev);
341 int s;
342
343 if (card >= stty_cd.cd_ndevs || card >= spif_cd.cd_ndevs)
344 return (ENXIO);
345
346 sc = stty_cd.cd_devs[card];
347 csc = spif_cd.cd_devs[card];
348 if (sc == NULL || csc == NULL)
349 return (ENXIO);
350
351 if (port >= sc->sc_nports)
352 return (ENXIO);
353
354 sp = &sc->sc_port[port];
355 tp = sp->sp_tty;
356 tp->t_dev = dev;
357
358 if (!ISSET(tp->t_state, TS_ISOPEN)) {
359 SET(tp->t_state, TS_WOPEN);
360
361 ttychars(tp);
362 tp->t_iflag = TTYDEF_IFLAG;
363 tp->t_oflag = TTYDEF_OFLAG;
364 tp->t_cflag = TTYDEF_CFLAG;
365 if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL))
366 SET(tp->t_cflag, CLOCAL);
367 if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS))
368 SET(tp->t_cflag, CRTSCTS);
369 if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF))
370 SET(tp->t_cflag, MDMBUF);
371 tp->t_lflag = TTYDEF_LFLAG;
372 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
373
374 sp->sp_rput = sp->sp_rget = sp->sp_rbuf;
375
376 s = spltty();
377
378 STC_WRITE(csc, STC_CAR, sp->sp_channel);
379 stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
380 STC_WRITE(csc, STC_CAR, sp->sp_channel);
381
382 stty_param(tp, &tp->t_termios);
383
384 ttsetwater(tp);
385
386 STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD);
387
388 if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier)
389 SET(tp->t_state, TS_CARR_ON);
390 else
391 CLR(tp->t_state, TS_CARR_ON);
392 }
393 else if (ISSET(tp->t_state, TS_XCLUDE) && p->p_ucred->cr_uid != 0) {
394 return (EBUSY);
395 } else {
396 s = spltty();
397 }
398
399 if (!ISSET(flags, O_NONBLOCK)) {
400 while (!ISSET(tp->t_cflag, CLOCAL) &&
401 !ISSET(tp->t_state, TS_CARR_ON)) {
402 int error;
403
404 SET(tp->t_state, TS_WOPEN);
405 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
406 "sttycd", 0);
407 if (error != 0) {
408 splx(s);
409 CLR(tp->t_state, TS_WOPEN);
410 return (error);
411 }
412 }
413 }
414
415 splx(s);
416
417 return ((*linesw[tp->t_line].l_open)(dev, tp));
418 }
419
420 int
421 sttyclose(dev, flags, mode, p)
422 dev_t dev;
423 int flags;
424 int mode;
425 struct proc *p;
426 {
427 struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
428 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
429 struct spif_softc *csc = sp->sp_sc;
430 struct tty *tp = sp->sp_tty;
431 int port = SPIF_PORT(dev);
432 int s;
433
434 (*linesw[tp->t_line].l_close)(tp, flags);
435 s = spltty();
436
437 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) {
438 stty_modem_control(sp, 0, DMSET);
439 STC_WRITE(csc, STC_CAR, port);
440 STC_WRITE(csc, STC_CCR,
441 CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN);
442 }
443
444 splx(s);
445 ttyclose(tp);
446 return (0);
447 }
448
449 int
450 sttyioctl(dev, cmd, data, flags, p)
451 dev_t dev;
452 u_long cmd;
453 caddr_t data;
454 int flags;
455 struct proc *p;
456 {
457 struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(dev)];
458 struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)];
459 struct spif_softc *sc = sp->sp_sc;
460 struct tty *tp = sp->sp_tty;
461 int error;
462
463 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p);
464 if (error >= 0)
465 return (error);
466
467 error = ttioctl(tp, cmd, data, flags, p);
468 if (error >= 0)
469 return (error);
470
471 error = 0;
472
473 switch (cmd) {
474 case TIOCSBRK:
475 SET(sp->sp_flags, STTYF_SET_BREAK);
476 STC_WRITE(sc, STC_CAR, sp->sp_channel);
477 STC_WRITE(sc, STC_SRER,
478 STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
479 break;
480 case TIOCCBRK:
481 SET(sp->sp_flags, STTYF_CLR_BREAK);
482 STC_WRITE(sc, STC_CAR, sp->sp_channel);
483 STC_WRITE(sc, STC_SRER,
484 STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
485 break;
486 case TIOCSDTR:
487 stty_modem_control(sp, TIOCM_DTR, DMBIS);
488 break;
489 case TIOCCDTR:
490 stty_modem_control(sp, TIOCM_DTR, DMBIC);
491 break;
492 case TIOCMBIS:
493 stty_modem_control(sp, *((int *)data), DMBIS);
494 break;
495 case TIOCMBIC:
496 stty_modem_control(sp, *((int *)data), DMBIC);
497 break;
498 case TIOCMGET:
499 *((int *)data) = stty_modem_control(sp, 0, DMGET);
500 break;
501 case TIOCMSET:
502 stty_modem_control(sp, *((int *)data), DMSET);
503 break;
504 case TIOCGFLAGS:
505 *((int *)data) = sp->sp_openflags;
506 break;
507 case TIOCSFLAGS:
508 if (suser(p, 0))
509 error = EPERM;
510 else
511 sp->sp_openflags = *((int *)data) &
512 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL |
513 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF);
514 break;
515 default:
516 error = ENOTTY;
517 }
518
519 return (error);
520 }
521
522 int
523 stty_modem_control(sp, bits, how)
524 struct stty_port *sp;
525 int bits, how;
526 {
527 struct spif_softc *csc = sp->sp_sc;
528 struct tty *tp = sp->sp_tty;
529 int s, msvr;
530
531 s = spltty();
532 STC_WRITE(csc, STC_CAR, sp->sp_channel);
533
534 switch (how) {
535 case DMGET:
536 bits = TIOCM_LE;
537 if (DTR_READ(csc, sp->sp_channel))
538 bits |= TIOCM_DTR;
539 msvr = STC_READ(csc, STC_MSVR);
540 if (ISSET(msvr, CD180_MSVR_DSR))
541 bits |= TIOCM_DSR;
542 if (ISSET(msvr, CD180_MSVR_CD))
543 bits |= TIOCM_CD;
544 if (ISSET(msvr, CD180_MSVR_CTS))
545 bits |= TIOCM_CTS;
546 if (ISSET(msvr, CD180_MSVR_RTS))
547 bits |= TIOCM_RTS;
548 break;
549 case DMSET:
550 DTR_WRITE(csc, sp->sp_channel, ISSET(bits, TIOCM_DTR) ? 1 : 0);
551 if (ISSET(bits, TIOCM_RTS))
552 STC_WRITE(csc, STC_MSVR,
553 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
554 else
555 STC_WRITE(csc, STC_MSVR,
556 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
557 break;
558 case DMBIS:
559 if (ISSET(bits, TIOCM_DTR))
560 DTR_WRITE(csc, sp->sp_channel, 1);
561 if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS))
562 STC_WRITE(csc, STC_MSVR,
563 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS));
564 break;
565 case DMBIC:
566 if (ISSET(bits, TIOCM_DTR))
567 DTR_WRITE(csc, sp->sp_channel, 0);
568 if (ISSET(bits, TIOCM_RTS))
569 STC_WRITE(csc, STC_MSVR,
570 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS);
571 break;
572 }
573
574 splx(s);
575 return (bits);
576 }
577
578 int
579 stty_param(tp, t)
580 struct tty *tp;
581 struct termios *t;
582 {
583 struct stty_softc *st = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
584 struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)];
585 struct spif_softc *sc = sp->sp_sc;
586 u_int8_t rbprl, rbprh, tbprl, tbprh;
587 int s, opt;
588
589 if (t->c_ospeed &&
590 stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh))
591 return (EINVAL);
592
593 if (t->c_ispeed &&
594 stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh))
595 return (EINVAL);
596
597 s = spltty();
598
599
600 stty_modem_control(sp, TIOCM_DTR,
601 (t->c_ospeed == 0 ? DMBIC : DMBIS));
602
603 STC_WRITE(sc, STC_CAR, sp->sp_channel);
604
605 opt = 0;
606 if (ISSET(t->c_cflag, PARENB)) {
607 opt |= CD180_COR1_PARMODE_NORMAL;
608 opt |= (ISSET(t->c_cflag, PARODD) ?
609 CD180_COR1_ODDPAR :
610 CD180_COR1_EVENPAR);
611 }
612 else
613 opt |= CD180_COR1_PARMODE_NO;
614
615 if (!ISSET(t->c_iflag, INPCK))
616 opt |= CD180_COR1_IGNPAR;
617
618 if (ISSET(t->c_cflag, CSTOPB))
619 opt |= CD180_COR1_STOP2;
620
621 switch (t->c_cflag & CSIZE) {
622 case CS5:
623 opt |= CD180_COR1_CS5;
624 break;
625 case CS6:
626 opt |= CD180_COR1_CS6;
627 break;
628 case CS7:
629 opt |= CD180_COR1_CS7;
630 break;
631 default:
632 opt |= CD180_COR1_CS8;
633 break;
634 }
635 STC_WRITE(sc, STC_COR1, opt);
636 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1);
637
638 opt = CD180_COR2_ETC;
639 if (ISSET(t->c_cflag, CRTSCTS))
640 opt |= CD180_COR2_CTSAE;
641 STC_WRITE(sc, STC_COR2, opt);
642 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2);
643
644 STC_WRITE(sc, STC_COR3, STTY_RX_FIFO_THRESHOLD);
645 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3);
646
647 STC_WRITE(sc, STC_SCHR1, 0x11);
648 STC_WRITE(sc, STC_SCHR2, 0x13);
649 STC_WRITE(sc, STC_SCHR3, 0x11);
650 STC_WRITE(sc, STC_SCHR4, 0x13);
651 STC_WRITE(sc, STC_RTPR, 0x12);
652
653 STC_WRITE(sc, STC_MCOR1, CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD);
654 STC_WRITE(sc, STC_MCOR2, CD180_MCOR2_CDOD);
655 STC_WRITE(sc, STC_MCR, 0);
656
657 if (t->c_ospeed) {
658 STC_WRITE(sc, STC_TBPRH, tbprh);
659 STC_WRITE(sc, STC_TBPRL, tbprl);
660 }
661
662 if (t->c_ispeed) {
663 STC_WRITE(sc, STC_RBPRH, rbprh);
664 STC_WRITE(sc, STC_RBPRL, rbprl);
665 }
666
667 stty_write_ccr(sc, CD180_CCR_CMD_CHAN |
668 CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN);
669
670 sp->sp_carrier = STC_READ(sc, STC_MSVR) & CD180_MSVR_CD;
671
672 splx(s);
673 return (0);
674 }
675
676 int
677 sttyread(dev, uio, flags)
678 dev_t dev;
679 struct uio *uio;
680 int flags;
681 {
682 struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
683 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
684 struct tty *tp = sp->sp_tty;
685
686 return ((*linesw[tp->t_line].l_read)(tp, uio, flags));
687 }
688
689 int
690 sttywrite(dev, uio, flags)
691 dev_t dev;
692 struct uio *uio;
693 int flags;
694 {
695 struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
696 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
697 struct tty *tp = sp->sp_tty;
698
699 return ((*linesw[tp->t_line].l_write)(tp, uio, flags));
700 }
701
702 struct tty *
703 sttytty(dev)
704 dev_t dev;
705 {
706 struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(dev)];
707 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)];
708
709 return (sp->sp_tty);
710 }
711
712 int
713 sttystop(tp, flags)
714 struct tty *tp;
715 int flags;
716 {
717 struct stty_softc *sc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
718 struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)];
719 int s;
720
721 s = spltty();
722 if (ISSET(tp->t_state, TS_BUSY)) {
723 if (!ISSET(tp->t_state, TS_TTSTOP))
724 SET(tp->t_state, TS_FLUSH);
725 SET(sp->sp_flags, STTYF_STOP);
726 }
727 splx(s);
728 return (0);
729 }
730
731 void
732 stty_start(tp)
733 struct tty *tp;
734 {
735 struct stty_softc *stc = stty_cd.cd_devs[SPIF_CARD(tp->t_dev)];
736 struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)];
737 struct spif_softc *sc = sp->sp_sc;
738 int s;
739
740 s = spltty();
741
742 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) {
743 if (tp->t_outq.c_cc <= tp->t_lowat) {
744 if (ISSET(tp->t_state, TS_ASLEEP)) {
745 CLR(tp->t_state, TS_ASLEEP);
746 wakeup(&tp->t_outq);
747 }
748 selwakeup(&tp->t_wsel);
749 }
750 if (tp->t_outq.c_cc) {
751 sp->sp_txc = ndqb(&tp->t_outq, 0);
752 sp->sp_txp = tp->t_outq.c_cf;
753 SET(tp->t_state, TS_BUSY);
754 STC_WRITE(sc, STC_CAR, sp->sp_channel);
755 STC_WRITE(sc, STC_SRER,
756 STC_READ(sc, STC_SRER) | CD180_SRER_TXD);
757 }
758 }
759
760 splx(s);
761 }
762
763 int
764 spifstcintr_rxexception(sc, needsoftp)
765 struct spif_softc *sc;
766 int *needsoftp;
767 {
768 struct stty_port *sp;
769 u_int8_t channel, *ptr;
770
771 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
772 sp = &sc->sc_ttys->sc_port[channel];
773 ptr = sp->sp_rput;
774 *ptr++ = STC_READ(sc, STC_RCSR);
775 *ptr++ = STC_READ(sc, STC_RDR);
776 if (ptr == sp->sp_rend)
777 ptr = sp->sp_rbuf;
778 if (ptr == sp->sp_rget) {
779 if (ptr == sp->sp_rbuf)
780 ptr = sp->sp_rend;
781 ptr -= 2;
782 SET(sp->sp_flags, STTYF_RING_OVERFLOW);
783 }
784 STC_WRITE(sc, STC_EOSRR, 0);
785 *needsoftp = 1;
786 sp->sp_rput = ptr;
787 return (1);
788 }
789
790 int
791 spifstcintr_rx(sc, needsoftp)
792 struct spif_softc *sc;
793 int *needsoftp;
794 {
795 struct stty_port *sp;
796 u_int8_t channel, *ptr, cnt, rcsr;
797 int i;
798
799 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
800 sp = &sc->sc_ttys->sc_port[channel];
801 ptr = sp->sp_rput;
802 cnt = STC_READ(sc, STC_RDCR);
803 for (i = 0; i < cnt; i++) {
804 *ptr++ = 0;
805 rcsr = STC_READ(sc, STC_RCSR);
806 *ptr++ = STC_READ(sc, STC_RDR);
807 if (ptr == sp->sp_rend)
808 ptr = sp->sp_rbuf;
809 if (ptr == sp->sp_rget) {
810 if (ptr == sp->sp_rbuf)
811 ptr = sp->sp_rend;
812 ptr -= 2;
813 SET(sp->sp_flags, STTYF_RING_OVERFLOW);
814 break;
815 }
816 }
817 STC_WRITE(sc, STC_EOSRR, 0);
818 if (cnt) {
819 *needsoftp = 1;
820 sp->sp_rput = ptr;
821 }
822 return (1);
823 }
824
825 int
826 spifstcintr_tx(sc, needsoftp)
827 struct spif_softc *sc;
828 int *needsoftp;
829 {
830 struct stty_port *sp;
831 u_int8_t channel, ch;
832 int cnt = 0;
833
834 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
835 sp = &sc->sc_ttys->sc_port[channel];
836 if (!ISSET(sp->sp_flags, STTYF_STOP)) {
837 if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) {
838 STC_WRITE(sc, STC_TDR, 0);
839 STC_WRITE(sc, STC_TDR, 0x81);
840 CLR(sp->sp_flags, STTYF_SET_BREAK);
841 cnt += 2;
842 }
843 if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) {
844 STC_WRITE(sc, STC_TDR, 0);
845 STC_WRITE(sc, STC_TDR, 0x83);
846 CLR(sp->sp_flags, STTYF_CLR_BREAK);
847 cnt += 2;
848 }
849
850 while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) {
851 ch = *sp->sp_txp;
852 sp->sp_txc--;
853 sp->sp_txp++;
854
855 if (ch == 0) {
856 STC_WRITE(sc, STC_TDR, ch);
857 cnt++;
858 }
859 STC_WRITE(sc, STC_TDR, ch);
860 cnt++;
861 }
862 }
863
864 if (sp->sp_txc == 0 ||
865 ISSET(sp->sp_flags, STTYF_STOP)) {
866 STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) &
867 (~CD180_SRER_TXD));
868 CLR(sp->sp_flags, STTYF_STOP);
869 SET(sp->sp_flags, STTYF_DONE);
870 *needsoftp = 1;
871 }
872
873 STC_WRITE(sc, STC_EOSRR, 0);
874
875 return (1);
876 }
877
878 int
879 spifstcintr_mx(sc, needsoftp)
880 struct spif_softc *sc;
881 int *needsoftp;
882 {
883 struct stty_port *sp;
884 u_int8_t channel, mcr;
885
886 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1));
887 sp = &sc->sc_ttys->sc_port[channel];
888 mcr = STC_READ(sc, STC_MCR);
889 if (mcr & CD180_MCR_CD) {
890 SET(sp->sp_flags, STTYF_CDCHG);
891 *needsoftp = 1;
892 }
893 STC_WRITE(sc, STC_MCR, 0);
894 STC_WRITE(sc, STC_EOSRR, 0);
895 return (1);
896 }
897
898 int
899 spifstcintr(vsc)
900 void *vsc;
901 {
902 struct spif_softc *sc = (struct spif_softc *)vsc;
903 int needsoft = 0, r = 0, i;
904 u_int8_t ar;
905
906 for (i = 0; i < 8; i++) {
907 ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK;
908 if (ar == CD180_GSVR_RXGOOD)
909 r |= spifstcintr_rx(sc, &needsoft);
910 else if (ar == CD180_GSVR_RXEXCEPTION)
911 r |= spifstcintr_rxexception(sc, &needsoft);
912 }
913
914 for (i = 0; i < 8; i++) {
915 ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK;
916 if (ar == CD180_GSVR_TXDATA)
917 r |= spifstcintr_tx(sc, &needsoft);
918 }
919
920 for (i = 0; i < 8; i++) {
921 ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK;
922 if (ar == CD180_GSVR_STATCHG)
923 r |= spifstcintr_mx(sc, &needsoft);
924 }
925
926 if (needsoft)
927 softintr_schedule(sc->sc_softih);
928 return (r);
929 }
930
931 void
932 spifsoftintr(vsc)
933 void *vsc;
934 {
935 struct spif_softc *sc = (struct spif_softc *)vsc;
936 struct stty_softc *stc = sc->sc_ttys;
937 int r = 0, i, data, s, flags;
938 u_int8_t stat, msvr;
939 struct stty_port *sp;
940 struct tty *tp;
941
942 if (stc != NULL) {
943 for (i = 0; i < stc->sc_nports; i++) {
944 sp = &stc->sc_port[i];
945 tp = sp->sp_tty;
946
947 if (!ISSET(tp->t_state, TS_ISOPEN))
948 continue;
949
950 while (sp->sp_rget != sp->sp_rput) {
951 stat = sp->sp_rget[0];
952 data = sp->sp_rget[1];
953 sp->sp_rget += 2;
954 if (sp->sp_rget == sp->sp_rend)
955 sp->sp_rget = sp->sp_rbuf;
956
957 if (stat & (CD180_RCSR_BE | CD180_RCSR_FE))
958 data |= TTY_FE;
959
960 if (stat & CD180_RCSR_PE)
961 data |= TTY_PE;
962
963 (*linesw[tp->t_line].l_rint)(data, tp);
964 r = 1;
965 }
966
967 s = splhigh();
968 flags = sp->sp_flags;
969 CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG |
970 STTYF_RING_OVERFLOW);
971 splx(s);
972
973 if (ISSET(flags, STTYF_CDCHG)) {
974 s = spltty();
975 STC_WRITE(sc, STC_CAR, i);
976 msvr = STC_READ(sc, STC_MSVR);
977 splx(s);
978
979 sp->sp_carrier = msvr & CD180_MSVR_CD;
980 (*linesw[tp->t_line].l_modem)(tp,
981 sp->sp_carrier);
982 r = 1;
983 }
984
985 if (ISSET(flags, STTYF_RING_OVERFLOW)) {
986 log(LOG_WARNING, "%s-%x: ring overflow\n",
987 stc->sc_dev.dv_xname, i);
988 r = 1;
989 }
990
991 if (ISSET(flags, STTYF_DONE)) {
992 ndflush(&tp->t_outq,
993 sp->sp_txp - tp->t_outq.c_cf);
994 CLR(tp->t_state, TS_BUSY);
995 (*linesw[tp->t_line].l_start)(tp);
996 r = 1;
997 }
998 }
999 }
1000 }
1001
1002 void
1003 stty_write_ccr(sc, val)
1004 struct spif_softc *sc;
1005 u_int8_t val;
1006 {
1007 int tries = 100000;
1008
1009 while (STC_READ(sc, STC_CCR) && tries--)
1010 ;
1011 if (tries == 0)
1012 printf("%s: ccr timeout\n", sc->sc_dev.dv_xname);
1013 STC_WRITE(sc, STC_CCR, val);
1014 }
1015
1016 int
1017 stty_compute_baud(speed, clock, bprlp, bprhp)
1018 speed_t speed;
1019 int clock;
1020 u_int8_t *bprlp, *bprhp;
1021 {
1022 u_int32_t rate;
1023
1024 rate = (2 * clock) / (16 * speed);
1025 if (rate & 1)
1026 rate = (rate >> 1) + 1;
1027 else
1028 rate = rate >> 1;
1029
1030 if (rate > 0xffff || rate == 0)
1031 return (1);
1032
1033 *bprlp = rate & 0xff;
1034 *bprhp = (rate >> 8) & 0xff;
1035 return (0);
1036 }
1037
1038 int
1039 sbppmatch(parent, vcf, aux)
1040 struct device *parent;
1041 void *vcf, *aux;
1042 {
1043 struct spif_softc *sc = (struct spif_softc *)parent;
1044
1045 return (aux == sbppmatch && sc->sc_bpps == NULL);
1046 }
1047
1048 void
1049 sbppattach(parent, dev, aux)
1050 struct device *parent, *dev;
1051 void *aux;
1052 {
1053 struct spif_softc *sc = (struct spif_softc *)parent;
1054 struct sbpp_softc *psc = (struct sbpp_softc *)dev;
1055 int port;
1056
1057 sc->sc_bpps = psc;
1058
1059 for (port = 0; port < sc->sc_npar; port++) {
1060 }
1061
1062 psc->sc_nports = port;
1063 printf(": %d port%s\n", port, port == 1 ? "" : "s");
1064 }
1065
1066 int
1067 sbppopen(dev, flags, mode, p)
1068 dev_t dev;
1069 int flags;
1070 int mode;
1071 struct proc *p;
1072 {
1073 return (ENXIO);
1074 }
1075
1076 int
1077 sbppclose(dev, flags, mode, p)
1078 dev_t dev;
1079 int flags;
1080 int mode;
1081 struct proc *p;
1082 {
1083 return (ENXIO);
1084 }
1085
1086 int
1087 spifppcintr(v)
1088 void *v;
1089 {
1090 return (0);
1091 }
1092
1093 int
1094 sbppread(dev, uio, flags)
1095 dev_t dev;
1096 struct uio *uio;
1097 int flags;
1098 {
1099 return (sbpp_rw(dev, uio));
1100 }
1101
1102 int
1103 sbppwrite(dev, uio, flags)
1104 dev_t dev;
1105 struct uio *uio;
1106 int flags;
1107 {
1108 return (sbpp_rw(dev, uio));
1109 }
1110
1111 int
1112 sbpp_rw(dev, uio)
1113 dev_t dev;
1114 struct uio *uio;
1115 {
1116 return (ENXIO);
1117 }
1118
1119 int
1120 sbpppoll(dev, events, p)
1121 dev_t dev;
1122 int events;
1123 struct proc *p;
1124 {
1125 return (seltrue(dev, events, p));
1126 }
1127
1128 int
1129 sbppioctl(dev, cmd, data, flags, p)
1130 dev_t dev;
1131 u_long cmd;
1132 caddr_t data;
1133 int flags;
1134 struct proc *p;
1135 {
1136 int error;
1137
1138 error = ENOTTY;
1139
1140 return (error);
1141 }