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