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