1 /*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * from: $Hdr: rs.c,v 4.300 91/06/09 06:43:03 root Rel41 $ SONY
11 *
12 * @(#)rs.c 8.1 (Berkeley) 06/11/93
13 */
14
15 /* rs.c 6.1 83/07/29 */
16
17 #include "rs.h"
18 #if NRS > 0
19 /*
20 * RS driver
21 *
22 */
23 #if NBK > 0
24 #include "bk.h"
25 #endif
26 #include <sys/param.h>
27 #include <sys/conf.h>
28 #include <sys/proc.h>
29 #include <sys/user.h>
30 #include <sys/kernel.h>
31 #include <sys/ioctl.h>
32 #include <sys/tty.h>
33 #include <sys/buf.h>
34 #include <sys/malloc.h>
35
36 #ifdef CPU_SINGLE
37 #include <news3400/hbdev/hbvar.h>
38 #else
39 #include "../iop/iopvar.h"
40 #endif
41
42 #include <news3400/iop/rsreg.h>
43 #include <news3400/sio/sccparam.h>
44
45 #define RS_RXE RXE
46 #define RS_TXE TXE
47 #define RS_ON (RXE|TXE|RTS|DTR)
48 #define RS_OFF TXE
49 #define RS_RTS RTS
50 #define RS_DTR DTR
51 #define RS_CTS CTS
52 #define RS_DCD DCD
53 #define RS_DSR DSR
54 #define RS_RI RI
55 #define RS_BRK XBREAK
56
57 #ifdef AUTO_ENABLE
58 #define RS_AUTO_ENABLE AUTO_ENABLE
59 #endif
60
61 #ifdef CPU_SINGLE
62 #define iop_device hb_device
63 #define ii_unit hi_unit
64 #define ii_flags hi_flags
65 #define ii_alive hi_alive
66 #endif
67
68 /*
69 * Definition of the driver for the auto-configuration program.
70 */
71 int rsprobe(), rsattach(), rsrint(), rsxint(), rssint();
72 struct iop_device *rsinfo[NRS];
73
74 #ifdef CPU_SINGLE
75 struct hb_driver rsdriver = { rsprobe, 0, rsattach, 0, 0, "rs", rsinfo };
76 #else
77 struct iop_driver rsdriver = { rsprobe, 0, rsattach, 0, "rs", rsinfo };
78 #endif
79
80 /*
81 * Local variables for the driver
82 */
83
84 struct tty rs_tty[NRS*4];
85 char rssoftCAR[NRS];
86
87 int rs_flags[NRS*4];
88 int rs_param[NRS*4];
89 char rs_active[NRS*4];
90 char rs_stopped[NRS*4];
91
92 int rs_rate[NRS*4];
93 int rs_average[NRS*4];
94 char rs_timeout[NRS*4];
95 char rs_watch;
96
97 #ifndef lint
98 int nrs = NRS*4; /* used by iostat */
99 #endif
100
101 extern int tty00_is_console;
102 extern void rsstart();
103 extern void ttrstrt();
104 extern void rsctrl();
105
106 #define RS_CARR(unit) (rssoftCAR[(unit) >> 2] & (1 << ((unit) & 03)))
107 #define RS_FLAG(unit, flag) (rs_flags[unit] & (flag))
108
109 #define RF_FLOWCTL 0x0010 /* use H/W flow control */
110 #define RF_EXTCLK 0x0100 /* allow external clock */
111 #define RF_NODELAY 0x1000 /* disable interrupt delay */
112
113 /*
114 * Routine for configuration
115 */
116 /*ARGSUSED*/
117 rsprobe(ii)
118 struct iop_device *ii;
119 {
120
121 return (rs_probe(ii));
122 }
123
124 /*
125 * Routine called to attach a rs.
126 */
rsattach(ii)127 rsattach(ii)
128 register struct iop_device *ii;
129 {
130 int i;
131
132 rssoftCAR[ii->ii_unit] = ii->ii_flags;
133 for (i = 0; i < 4; i++)
134 rs_flags[ii->ii_unit * 4 + i] =
135 (ii->ii_flags >> i) & (RF_FLOWCTL|RF_EXTCLK|RF_NODELAY);
136 if (rs_watch == 0) {
137 rs_watchdog();
138 rs_watch = 1;
139 }
140 }
141
rs_watchdog()142 rs_watchdog()
143 {
144 register int unit, s;
145
146 for (unit = 0; unit < NRS*4; unit++) {
147 if (rs_active[unit] == 0)
148 continue;
149 s = spltty();
150 rs_average[unit] = (rs_average[unit] * 7 + rs_rate[unit]) >> 3;
151 rs_rate[unit] = 0;
152 (void) splx(s);
153 }
154 timeout(rs_watchdog, (caddr_t)0, hz / 10);
155 }
156
157 /*
158 * Open a RS line. Turn on this rs if this is the first use of it.
159 */
160 /*ARGSUSED*/
rsopen(dev,flag,mode,p)161 rsopen(dev, flag, mode, p)
162 dev_t dev;
163 int flag, mode;
164 struct proc *p;
165 {
166 register int unit;
167 register struct tty *tp;
168 register struct iop_device *ii;
169 int s;
170
171 unit = minor(dev);
172 if (unit >= NRS*4 || (ii = rsinfo[unit >> 2]) == 0 || ii->ii_alive == 0)
173 return (ENXIO);
174 if (rs_active[unit] == 0) {
175 if (rs_init(unit) < 0)
176 return (ENXIO);
177 rs_enable(unit);
178 rs_active[unit] = 1;
179 }
180 tp = &rs_tty[unit];
181 if (tp->t_state&TS_XCLUDE && curproc->p_ucred->cr_uid != 0)
182 return (EBUSY);
183 tp->t_addr = (caddr_t)0;
184 tp->t_oproc = rsstart;
185 #ifdef notyet /* KU:XXX */
186 tp->t_ctrlproc = rsctrl;
187 #endif
188 /*
189 * If this is first open, initialze tty state to default.
190 */
191 if ((tp->t_state & TS_ISOPEN) == 0) {
192 tp->t_state |= TS_WOPEN;
193 ttychars(tp);
194 if (tp->t_ispeed == 0) {
195 tp->t_iflag = TTYDEF_IFLAG;
196 tp->t_oflag = TTYDEF_OFLAG;
197 tp->t_cflag = TTYDEF_CFLAG;
198 tp->t_lflag = TTYDEF_LFLAG;
199 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
200 }
201 rsparam(tp, &tp->t_termios);
202 ttsetwater(tp);
203 }
204 /*
205 * Wait receiver and status interrupt
206 */
207 /*
208 * Wait for carrier, then process line discipline specific open.
209 */
210 rsmctl(dev, RS_ON, DMSET);
211 if (rs_param[unit] & DCD || RS_CARR(unit))
212 tp->t_state |= TS_CARR_ON;
213 s = spltty(); /* spl5 -> spltty, 90/02/28 sak */
214 while ((tp->t_state & TS_CARR_ON) == 0) {
215 tp->t_state |= TS_WOPEN;
216 sleep((caddr_t)&tp->t_rawq, TTIPRI);
217 }
218 #ifdef notyet /* KU:XXX */
219 if (RS_FLAG(unit, RF_FLOWCTL)) {
220 tp->t_state |= TS_HFLWCTL;
221 rsmctl(dev, RS_AUTO_ENABLE, DMBIS);
222 } else {
223 tp->t_state &= ~TS_HFLWCTL;
224 rsmctl(dev, RS_AUTO_ENABLE, DMBIC);
225 }
226 #endif
227 (void) splx(s);
228 return ((*linesw[tp->t_line].l_open)(dev, tp));
229 }
230
231 /*
232 * Close a RS line.
233 */
234 /*ARGSUSED*/
rsclose(dev,flag)235 rsclose(dev, flag)
236 dev_t dev;
237 int flag;
238 {
239 register struct tty *tp;
240 register unit;
241
242 unit = minor(dev);
243 tp = &rs_tty[unit];
244 (*linesw[tp->t_line].l_close)(tp);
245 (void) rsmctl(unit, RS_BRK, DMBIC);
246 if (tp->t_cflag & HUPCL || (tp->t_state & TS_ISOPEN) == 0)
247 (void) rsmctl(unit, RS_OFF, DMSET);
248 ttyclose(tp);
249
250 if (RS_FLAG(unit, RF_FLOWCTL))
251 (void)rsmctl(unit, RS_RTS, DMBIC);
252 }
253
rsread(dev,uio,flag)254 rsread(dev, uio, flag)
255 dev_t dev;
256 struct uio *uio;
257 int flag;
258 {
259 register struct tty *tp;
260
261 tp = &rs_tty[minor(dev)];
262 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
263 }
264
rswrite(dev,uio,flag)265 rswrite(dev, uio, flag)
266 dev_t dev;
267 struct uio *uio;
268 int flag;
269 {
270 register struct tty *tp;
271
272 tp = &rs_tty[minor(dev)];
273 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
274 }
275
rsenable(unit)276 rsenable(unit)
277 int unit;
278 {
279
280 rs_timeout[unit] = 0;
281 rs_enable(unit);
282 }
283
284 /*
285 * RS receiver interrupt.
286 */
_rsrint(unit,buf,n)287 _rsrint(unit, buf, n)
288 register int unit;
289 register char *buf;
290 register int n;
291 {
292 register struct iop_device *ii;
293 register struct tty *tp;
294 register int (*rint)();
295
296 #ifdef notyet /* KU:XXX */
297 intrcnt[INTR_RS0 + unit]++;
298 #endif
299 ii = rsinfo[unit >> 2];
300 if (ii == 0 || ii->ii_alive == 0)
301 return;
302 tp = &rs_tty[unit];
303 if ((tp->t_state & TS_ISOPEN) == 0) {
304 wakeup((caddr_t)&tp->t_rawq);
305 goto enable;
306 }
307 /*
308 * Loop fetching characters from the silo for this
309 * rs until there are no more in the silo.
310 */
311 rint = linesw[tp->t_line].l_rint;
312 while (--n >= 0) {
313 #if NBK > 0
314 if (tp->t_line == NETLDISC) {
315 c &= 0177;
316 BKINPUT(c, tp);
317 } else
318 #endif /* NBK > 0 */
319 (*rint)(*buf++, tp);
320 }
321 enable:
322 rs_rate[unit]++;
323 if (rs_average[unit] >= 10 && RS_FLAG(unit, RF_NODELAY) == 0) {
324 if (rs_timeout[unit] == 0) {
325 rs_timeout[unit] = 1;
326 timeout(rsenable, (caddr_t)unit, hz / 100);
327 }
328 } else
329 rs_enable(unit);
330 }
331
332 /*ARGSUSED*/
rsioctl(dev,cmd,data,flag)333 rsioctl(dev, cmd, data, flag)
334 dev_t dev;
335 caddr_t data;
336 {
337 register struct tty *tp;
338 register int unit = minor(dev);
339 int error;
340
341 tp = &rs_tty[unit];
342 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag);
343 if (error >= 0)
344 return (error);
345 error = ttioctl(tp, cmd, data, flag);
346 if (error >= 0)
347 return (error);
348
349 switch (cmd) {
350
351 case TIOCSBRK:
352 (void) rsmctl(dev, RS_BRK, DMBIS);
353 break;
354
355 case TIOCCBRK:
356 (void) rsmctl(dev, RS_BRK, DMBIC);
357 break;
358
359 case TIOCSDTR:
360 (void) rsmctl(dev, RS_DTR|RS_RTS, DMBIS);
361 break;
362
363 case TIOCCDTR:
364 if (curproc->p_ucred->cr_uid &&
365 curproc->p_session->s_ttyp != tp)
366 return (EACCES);
367 (void) rsmctl(dev, RS_DTR|RS_RTS, DMBIC);
368 break;
369
370 case TIOCMSET:
371 (void) rsmctl(dev, dmtors(*(int *)data), DMSET);
372 break;
373
374 case TIOCMBIS:
375 (void) rsmctl(dev, dmtors(*(int *)data), DMBIS);
376 break;
377
378 case TIOCMBIC:
379 (void) rsmctl(dev, dmtors(*(int *)data), DMBIC);
380 break;
381
382 case TIOCMGET:
383 *(int *)data = rstodm(rsmctl(dev, 0, DMGET));
384 break;
385
386 default:
387 return (ENOTTY);
388 }
389 return (0);
390 }
391
dmtors(bits)392 dmtors(bits)
393 register int bits;
394 {
395 register int b;
396
397 b = 0;
398 if (bits & DML_LE) b |= RS_TXE|RS_RXE;
399 if (bits & DML_DTR) b |= RS_DTR;
400 if (bits & DML_RTS) b |= RS_RTS;
401 if (bits & DML_CTS) b |= RS_CTS;
402 if (bits & DML_CAR) b |= RS_DCD;
403 if (bits & DML_RNG) b |= RS_RI;
404 if (bits & DML_DSR) b |= RS_DSR;
405 #ifdef AUTO_ENABLE
406 if (bits & DML_USR) b |= RS_AUTO_ENABLE;
407 #endif /* AUTO_ENABLE */
408 return(b);
409 }
410
rstodm(bits)411 rstodm(bits)
412 register int bits;
413 {
414 register int b;
415
416 b = 0;
417 if (bits & (RS_TXE|RS_RXE)) b |= DML_LE;
418 if (bits & RS_DTR) b |= DML_DTR;
419 if (bits & RS_RTS) b |= DML_RTS;
420 if (bits & RS_CTS) b |= DML_CTS;
421 if (bits & RS_DCD) b |= DML_CAR;
422 if (bits & RS_RI) b |= DML_RNG;
423 if (bits & RS_DSR) b |= DML_DSR;
424 #ifdef AUTO_ENABLE
425 if (bits & RS_AUTO_ENABLE) b |= DML_USR;
426 #endif
427 return(b);
428 }
429
430 /*
431 * compat table
432 */
433 struct speedtab rsspeedtab[] = {
434 0, 0,
435 50, 1,
436 75, 2,
437 110, 3,
438 134, 4,
439 150, 5,
440 200, 6,
441 300, 7,
442 600, 8,
443 1200, 9,
444 1800, 10,
445 2400, 11,
446 4800, 12,
447 9600, 13,
448 19200, 14,
449 38400, 15,
450 -1, -1
451 };
452
453 /*
454 * Set parameters from open or stty into the RS hardware
455 * registers.
456 */
rsparam(tp,t)457 rsparam(tp, t)
458 register struct tty *tp;
459 register struct termios *t;
460 {
461 register int param;
462 register int cflag = t->c_cflag;
463 int unit = minor(tp->t_dev);
464 int s;
465 int ospeed = ttspeedtab(t->c_ospeed, rsspeedtab);
466
467 /* check requested parameters */
468 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed) ||
469 (cflag & CSIZE) == CS5 || (cflag & CSIZE) == CS6)
470 return (EINVAL);
471 /* and copy to tty */
472 tp->t_ispeed = t->c_ispeed;
473 tp->t_ospeed = t->c_ospeed;
474 tp->t_cflag = cflag;
475
476 /*
477 * Block interrupts so parameters will be set
478 * before the line interrupts.
479 */
480 s = spltty();
481 if (tp->t_ospeed == 0) {
482 tp->t_cflag |= HUPCL;
483 (void) rsmctl(unit, RS_OFF, DMSET);
484 (void) splx(s);
485 return (0);
486 }
487
488 param = rs_get_param(unit) &
489 ~(CHAR_SIZE|PARITY|EVEN|STOPBIT|BAUD_RATE|NOCHECK);
490 if ((cflag & CREAD) == 0)
491 param &= ~RXE;
492 if (cflag & CS6)
493 param |= C6BIT;
494 if (cflag & CS7)
495 param |= C7BIT;
496 if (cflag & PARENB)
497 param |= PARITY;
498 if ((cflag & PARODD) == 0)
499 param |= EVEN;
500 if ((tp->t_iflag & INPCK) == 0)
501 param |= NOCHECK;
502 if (cflag & CSTOPB)
503 param |= STOP2;
504 else
505 param |= STOP1;
506
507 rs_param[unit] = param | ospeed;
508
509 if (RS_FLAG(unit, RF_EXTCLK))
510 rs_param[unit] |= EXTCLK_ENABLE;
511 else
512 rs_param[unit] &= ~EXTCLK_ENABLE;
513 rs_set_param(unit, rs_param[unit]);
514 (void) splx(s);
515
516 return (0);
517 }
518
519 /*
520 * RS transmitter interrupt.
521 * Restart the idle line.
522 */
_rsxint(unit,count)523 _rsxint(unit, count)
524 int unit;
525 int count;
526 {
527 register struct tty *tp;
528 register int s;
529
530 #ifdef notyet /* KU:XXX */
531 intrcnt[INTR_RS0 + unit]++;
532 #endif
533 rs_stopped[unit] = 0;
534 tp = &rs_tty[unit];
535 tp->t_state &= ~TS_BUSY;
536 s = spltty();
537 if (tp->t_state & TS_FLUSH)
538 tp->t_state &= ~TS_FLUSH;
539 else
540 ndflush(&tp->t_outq, count);
541 (void) splx(s);
542 if (tp->t_line)
543 (*linesw[tp->t_line].l_start)(tp);
544 else
545 rsstart(tp);
546 }
547
548 /*
549 * Start (restart) transmission on the given RS line.
550 */
551 void
rsstart(tp)552 rsstart(tp)
553 register struct tty *tp;
554 {
555 register int unit, nch;
556 int s;
557
558 unit = minor(tp->t_dev);
559
560 /*
561 * Must hold interrupts in following code to prevent
562 * state of the tp from changing.
563 */
564 s = spltty();
565 /*
566 * If it's currently active, or delaying, no need to do anything.
567 */
568 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP))
569 goto out;
570 /*
571 * If ther are still characters in the IOP,
572 * just reenable transmit.
573 */
574 if (rs_stopped[unit]) {
575 rs_start(unit);
576 rs_stopped[unit] = 0;
577 goto out;
578 }
579 /*
580 * If there are sleepers, and output has drained below low
581 * water mark, wake up the sleepers.
582 */
583 if (tp->t_outq.c_cc <= tp->t_lowat) {
584 if (tp->t_state & TS_ASLEEP) {
585 tp->t_state &= ~TS_ASLEEP;
586 wakeup((caddr_t)&tp->t_outq);
587 }
588 selwakeup(&tp->t_wsel);
589 }
590 /*
591 * Now restart transmission unless the output queue is
592 * empty.
593 */
594 if (tp->t_outq.c_cc == 0)
595 goto out;
596 if (tp->t_flags & (RAW|LITOUT))
597 nch = ndqb(&tp->t_outq, 0);
598 else {
599 nch = ndqb(&tp->t_outq, 0200);
600 /*
601 * If first thing on queue is a delay process it.
602 */
603 if (nch == 0) {
604 nch = getc(&tp->t_outq);
605 timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6);
606 tp->t_state |= TS_TIMEOUT;
607 goto out;
608 }
609 }
610 /*
611 * If characters to transmit, restart transmission.
612 */
613 if (nch) {
614 tp->t_state |= TS_BUSY;
615 rs_output(unit, nch);
616 }
617 out:
618 (void) splx(s);
619 }
620
621 /*
622 * Stop output on a line, e.g. for ^S/^Q or output flush.
623 */
624 /*ARGSUSED*/
rsstop(tp,flag)625 rsstop(tp, flag)
626 register struct tty *tp;
627 {
628 register int unit, s;
629
630 unit = minor(tp->t_dev);
631 s = spltty();
632 if (tp->t_state & TS_BUSY) {
633 rs_stop(unit, 0);
634 rs_stopped[unit] = 1;
635 if ((tp->t_state & TS_TTSTOP) == 0) {
636 tp->t_state |= TS_FLUSH;
637 rs_stop(unit, 1);
638 }
639 }
640 (void) splx(s);
641 }
642
643 /*
644 * RS modem control
645 */
rsmctl(dev,bits,how)646 rsmctl(dev, bits, how)
647 dev_t dev;
648 int bits, how;
649 {
650 register int unit, mbits;
651 int s;
652
653 #ifdef AUTO_ENABLE
654 bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK|RS_AUTO_ENABLE);
655 #else
656 bits &= (RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK);
657 #endif
658
659 unit = minor(dev);
660 s = spltty(); /* spl5 -> spltty, 90/02/28 sak */
661
662 mbits = rs_get_param(unit);
663 switch (how) {
664
665 case DMSET:
666 mbits = mbits & ~(RS_RXE|RS_TXE|RS_RTS|RS_DTR|RS_BRK) | bits;
667 break;
668
669 case DMBIS:
670 mbits |= bits;
671 break;
672
673 case DMBIC:
674 mbits &= ~bits;
675 break;
676
677 case DMGET:
678 (void) splx(s);
679 return(mbits);
680 }
681 rs_param[unit] = mbits;
682 rs_set_param(unit, rs_param[unit]);
683
684 (void) splx(s);
685 return(mbits);
686 }
687
688 /*
689 * Reset state of driver if IOP reset was necessary.
690 * Reset the parameter and status, and
691 * restart transmitters.
692 */
rsreset()693 rsreset()
694 {
695 register int unit;
696 register struct tty *tp;
697 register struct iop_device *ii;
698
699 for (unit = 0; unit < NRS * 4; unit++) {
700 ii = rsinfo[unit >> 2];
701 if (ii == 0 || ii->ii_alive == 0)
702 continue;
703 printf(" rs%d", unit);
704 tp = &rs_tty[unit];
705 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) {
706 rs_reset(unit);
707 rsparam(tp, &tp->t_termios);
708 (void) rsmctl(unit, RS_ON, DMSET);
709 tp->t_state &= ~TS_BUSY;
710 rsstart(tp);
711 }
712 }
713 }
714
715 /*
716 * RS status interrupt
717 */
_rssint(unit,stat)718 _rssint(unit, stat)
719 int unit;
720 int stat;
721 {
722 register struct tty *tp;
723
724 #ifdef notyet /* KU:XXX */
725 intrcnt[INTR_RS0 + unit]++;
726 #endif
727 tp = &rs_tty[unit];
728 if (stat & RS_DCD) {
729 rs_param[unit] |= RS_DCD;
730 (void)(*linesw[tp->t_line].l_modem)(tp, 1);
731 } else if (RS_CARR(unit) == 0 &&
732 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) {
733 rs_param[unit] &= ~(RS_DCD | RS_DTR);
734 rs_set_param(unit, rs_param[unit]);
735 }
736 if (stat & OVERRUN_ERROR) {
737 printf("rs%d: fifo overflow\n", unit);
738 rs_param[unit] &= ~OVERRUN_ERROR;
739 rs_set_param(unit, rs_param[unit]);
740 }
741 if (stat & RBREAK) {
742 rs_param[unit] &= ~RBREAK;
743 if (tp->t_state & TS_ISOPEN)
744 (*linesw[tp->t_line].l_rint)
745 (tp->t_flags & RAW ? '\0' : tp->t_cc[VINTR], tp);
746 }
747 }
748
749 /*
750 * RS control interrupt
751 */
rscint(rs)752 rscint(rs)
753 int rs;
754 {
755
756 printf("rscint: %d\n", rs);
757 }
758
759 /*
760 * RS H/W control
761 */
762 void
rsctrl(tp,cmd,arg)763 rsctrl(tp, cmd, arg)
764 struct tty *tp;
765 int cmd;
766 int arg;
767 {
768 #ifdef notyet /* KU:XXX */
769 int unit = minor(tp->t_dev);
770
771 switch (cmd) {
772
773 case TC_HBLOCK:
774 if (RS_FLAG(unit, RF_FLOWCTL))
775 rsflowctl(unit, arg);
776 break;
777
778 default:
779 break;
780 }
781
782 return (0);
783 #endif
784 }
785
rsflowctl(unit,block)786 rsflowctl(unit, block)
787 int unit;
788 int block;
789 {
790 int s;
791
792 s = spltty();
793 if (block)
794 rs_param[unit] &= ~RS_RTS;
795 else
796 rs_param[unit] |= RS_RTS;
797 rs_set_param(unit, rs_param[unit]);
798 (void) splx(s);
799 }
800
801 /*
802 * Machine dependent functions
803 *
804 * rs_probe()
805 * rs_init()
806 * rsrint()
807 * rsxint()
808 * rssint()
809 * rs_enable()
810 * rs_output()
811 * rs_start()
812 * rs_stop()
813 * rs_reset()
814 * rs_get_param()
815 * rs_set_param()
816 */
817 #ifdef CPU_SINGLE
818 #include <news3400/hbdev/hbvar.h>
819 #include <news3400/hbdev/rsreg.h>
820 #include <news3400/sio/scc.h>
821
822 int rslastcount[NRS*4];
823 int scc_unit[] = { 0, 1, -1, -1, 2, 3, 4, 5, 6, 7, 8, 9 };
824 int rs_unit[] = { 0, 1, 4, 5, 6, 7, 8, 9, 10, 11 };
825
826 rs_probe(hi)
827 struct hb_device *hi;
828 {
829 register int i, cmax;
830
831 for (i = (hi->hi_unit << 2), cmax = 4; cmax > 0; cmax--, i++) {
832 if (i == 2 || i == 3)
833 continue;
834 if (scc_probe(scc_unit[i]))
835 continue;
836 return (0);
837 }
838 return (1);
839 }
840
rs_init(unit)841 rs_init(unit)
842 int unit;
843 {
844
845 if (scc_open(scc_unit[unit])) {
846 printf("rs_init: chan %d open failed.\n", scc_unit[unit]);
847 return (-1);
848 }
849 return (0);
850 }
851
rs_enable(unit)852 rs_enable(unit)
853 int unit;
854 {
855
856 scc_enable(scc_unit[unit]);
857 }
858
rsrint(scc,buf,cnt)859 rsrint(scc, buf, cnt)
860 int scc;
861 char *buf;
862 int cnt;
863 {
864
865 _rsrint(rs_unit[scc], buf, cnt);
866 }
867
rsxint(scc)868 rsxint(scc)
869 int scc;
870 {
871 int unit = rs_unit[scc];
872
873 _rsxint(unit, rslastcount[unit]);
874 }
875
rssint(scc,stat)876 rssint(scc, stat)
877 int scc;
878 int stat;
879 {
880
881 _rssint(rs_unit[scc], stat);
882 }
883
rs_start(unit)884 rs_start(unit)
885 int unit;
886 {
887
888 scc_start(scc_unit[unit]);
889 }
890
rs_output(unit,n)891 rs_output(unit, n)
892 int unit;
893 int n;
894 {
895
896 rslastcount[unit] =
897 scc_write(scc_unit[unit], rs_tty[unit].t_outq.c_cf, n);
898 }
899
rs_stop(unit,flush)900 rs_stop(unit, flush)
901 int unit;
902 int flush;
903 {
904
905 if (flush)
906 scc_flush(scc_unit[unit]);
907 }
908
rs_reset(unit)909 rs_reset(unit)
910 int unit;
911 {
912
913 scc_reset(scc_unit[unit]);
914 }
915
rs_get_param(unit)916 rs_get_param(unit)
917 int unit;
918 {
919
920 return (scc_get_param(scc_unit[unit]));
921 }
922
rs_set_param(unit,param)923 rs_set_param(unit, param)
924 int unit;
925 int param;
926 {
927
928 scc_set_param(scc_unit[unit], param);
929 }
930 #endif /* CPU_SINGLE */
931
932 #ifdef IPC_MRX
933 #include "../ipc/newsipc.h"
934 #include "../mrx/h/scc.h"
935 #include "../mrx/h/cio.h"
936
937 int port_rsrecv[NRS*4];
938 int port_rsxmit[NRS*4];
939 int port_rsstat[NRS*4];
940 int port_rsctrl[NRS*4];
941 int port_recv_iop[NRS*4];
942 int port_xmit_iop[NRS*4];
943 int port_ctrl_iop[NRS*4];
944 int port_stat_iop[NRS*4];
945
946 /*
947 * minor No: 0 - 12 ----> SCC unit No : 0 - 9
948 */
949 int scc_unit[] = { 1, 0, -1, -1, 3, 2, 5, 4, 7, 6, 9, 8 };
950
951 rs_probe(ii)
952 struct iop_device *ii;
953 {
954 register int base = ii->ii_unit << 2;
955 register int i, j;
956 char buf[16];
957
958 #define PT_CREATE(buf, name, unit, func, arg) \
959 port_create(make_name(buf, name, unit), func, arg)
960 #define OB_QUERY(buf, name, unit) \
961 object_query(make_name(buf, name, unit))
962 for (i = base; i < base+4; i++) {
963 if ((j = scc_unit[i]) < 0)
964 continue;
965 port_recv_iop[i] = OB_QUERY(buf, "scc_inputX", j);
966 if (port_recv_iop[i] <= 0)
967 return (0);
968 port_xmit_iop[i] = OB_QUERY(buf, "scc_outputX", j);
969 port_ctrl_iop[i] = OB_QUERY(buf, "scc_ctrlX", j);
970 port_stat_iop[i] = OB_QUERY(buf, "scc_statX", j);
971
972 port_rsrecv[i] = PT_CREATE(buf, "@rsrecvX", j, rsrint, i);
973 port_rsxmit[i] = PT_CREATE(buf, "@rsxmitX", j, rsxint, i);
974 port_rsctrl[i] = PT_CREATE(buf, "@rsctrlX", j, NULL, 0);
975 port_rsstat[i] = PT_CREATE(buf, "@rsstatX", j, rssint, i);
976 }
977 return (1);
978 }
979
rs_init(unit)980 rs_init(unit)
981 int unit;
982 {
983 int len;
984
985 msg_send(port_stat_iop[unit], port_rsstat[unit], NULL, 0, 0);
986 return (0);
987 }
988
rs_enable(unit)989 rs_enable(unit)
990 int unit;
991 {
992 int len;
993
994 len = MAX_CIO;
995 msg_send(port_recv_iop[unit], port_rsrecv[unit], &len, sizeof(len), 0);
996 }
997
rsrint(unit)998 rsrint(unit)
999 register int unit;
1000 {
1001 char *addr;
1002 int from, len;
1003
1004 msg_recv(port_rsrecv[unit], &from, &addr, &len, 0);
1005 #ifdef mips
1006 clean_dcache(addr, len + 8);
1007 #endif
1008 _rsrint(unit, addr, len);
1009 }
1010
rsxint(unit)1011 rsxint(unit)
1012 register int unit;
1013 {
1014 int from, *len;
1015
1016 msg_recv(port_rsxmit[unit], &from, &len, NULL, 0);
1017 _rsxint(unit, *len);
1018 }
1019
rssint(unit)1020 rssint(unit)
1021 register int unit;
1022 {
1023 int from, *reply;
1024
1025 msg_recv(port_rsstat[unit], &from, &reply, NULL, 0);
1026 _rssint(unit, *reply);
1027 msg_send(from, port_rsstat[unit], NULL, 0, 0);
1028 }
1029
rs_start(unit)1030 rs_start(unit)
1031 int unit;
1032 {
1033 int func;
1034
1035 func = CIO_START;
1036 msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1037 }
1038
rs_output(unit,n)1039 rs_output(unit, n)
1040 int unit;
1041 int n;
1042 {
1043
1044 msg_send(port_xmit_iop[unit], port_rsxmit[unit],
1045 rs_tty[unit].t_outq.c_cf, min(n, MAX_CIO), 0);
1046 }
1047
rs_stop(unit,flush)1048 rs_stop(unit, flush)
1049 int unit;
1050 int flush;
1051 {
1052 int func;
1053
1054 func = flush ? CIO_FLUSH : CIO_STOP;
1055 msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1056 }
1057
rs_reset(unit)1058 rs_reset(unit)
1059 int unit;
1060 {
1061 int func;
1062
1063 func = CIO_RESET;
1064 msg_send(port_ctrl_iop[unit], 0, &func, sizeof(func), 0);
1065 }
1066
rs_get_param(unit)1067 rs_get_param(unit)
1068 register int unit;
1069 {
1070 register int port;
1071 struct scc_ctrl_req req;
1072 int param, *reply;
1073
1074 port = port_rsctrl[unit];
1075 req.scc_func = CIO_GETPARAMS;
1076
1077 /* message length 8 means 2 * sizeof(int) : func and status */
1078 msg_send(port_ctrl_iop[unit], port, &req, 8, 0);
1079 msg_recv(port, NULL, &reply, NULL, 0);
1080
1081 param = *reply;
1082 msg_free(port);
1083
1084 return (param);
1085 }
1086
rs_set_param(unit,param)1087 rs_set_param(unit, param)
1088 register int unit;
1089 int param;
1090 {
1091 struct scc_ctrl_req req;
1092
1093 req.scc_func = CIO_SETPARAMS;
1094 req.scc_arg = param;
1095
1096 /* message length 8 means 2 * sizeof(int) : func and param */
1097 msg_send(port_ctrl_iop[unit], 0, &req, 8, 0);
1098 }
1099 #endif /* IPC_MRX */
1100 #endif /* NRS > 0 */
1101