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