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 */ 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 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*/ 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*/ 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 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 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 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 */ 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*/ 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 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 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 */ 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 */ 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 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*/ 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 */ 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 */ 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 */ 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 */ 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 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 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 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 852 rs_enable(unit) 853 int unit; 854 { 855 856 scc_enable(scc_unit[unit]); 857 } 858 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 868 rsxint(scc) 869 int scc; 870 { 871 int unit = rs_unit[scc]; 872 873 _rsxint(unit, rslastcount[unit]); 874 } 875 876 rssint(scc, stat) 877 int scc; 878 int stat; 879 { 880 881 _rssint(rs_unit[scc], stat); 882 } 883 884 rs_start(unit) 885 int unit; 886 { 887 888 scc_start(scc_unit[unit]); 889 } 890 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 900 rs_stop(unit, flush) 901 int unit; 902 int flush; 903 { 904 905 if (flush) 906 scc_flush(scc_unit[unit]); 907 } 908 909 rs_reset(unit) 910 int unit; 911 { 912 913 scc_reset(scc_unit[unit]); 914 } 915 916 rs_get_param(unit) 917 int unit; 918 { 919 920 return (scc_get_param(scc_unit[unit])); 921 } 922 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 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 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 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 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 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 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 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 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 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 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 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