1 /* $OpenBSD: spif.c,v 1.13 2006/03/04 13:00:55 miod 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(); 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) && p->p_ucred->cr_uid != 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)); 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); 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 if (tp->t_outq.c_cc <= tp->t_lowat) { 744 if (ISSET(tp->t_state, TS_ASLEEP)) { 745 CLR(tp->t_state, TS_ASLEEP); 746 wakeup(&tp->t_outq); 747 } 748 selwakeup(&tp->t_wsel); 749 } 750 if (tp->t_outq.c_cc) { 751 sp->sp_txc = ndqb(&tp->t_outq, 0); 752 sp->sp_txp = tp->t_outq.c_cf; 753 SET(tp->t_state, TS_BUSY); 754 STC_WRITE(sc, STC_CAR, sp->sp_channel); 755 STC_WRITE(sc, STC_SRER, 756 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 757 } 758 } 759 760 splx(s); 761 } 762 763 int 764 spifstcintr_rxexception(sc, needsoftp) 765 struct spif_softc *sc; 766 int *needsoftp; 767 { 768 struct stty_port *sp; 769 u_int8_t channel, *ptr; 770 771 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 772 sp = &sc->sc_ttys->sc_port[channel]; 773 ptr = sp->sp_rput; 774 *ptr++ = STC_READ(sc, STC_RCSR); 775 *ptr++ = STC_READ(sc, STC_RDR); 776 if (ptr == sp->sp_rend) 777 ptr = sp->sp_rbuf; 778 if (ptr == sp->sp_rget) { 779 if (ptr == sp->sp_rbuf) 780 ptr = sp->sp_rend; 781 ptr -= 2; 782 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 783 } 784 STC_WRITE(sc, STC_EOSRR, 0); 785 *needsoftp = 1; 786 sp->sp_rput = ptr; 787 return (1); 788 } 789 790 int 791 spifstcintr_rx(sc, needsoftp) 792 struct spif_softc *sc; 793 int *needsoftp; 794 { 795 struct stty_port *sp; 796 u_int8_t channel, *ptr, cnt, rcsr; 797 int i; 798 799 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 800 sp = &sc->sc_ttys->sc_port[channel]; 801 ptr = sp->sp_rput; 802 cnt = STC_READ(sc, STC_RDCR); 803 for (i = 0; i < cnt; i++) { 804 *ptr++ = 0; 805 rcsr = STC_READ(sc, STC_RCSR); 806 *ptr++ = STC_READ(sc, STC_RDR); 807 if (ptr == sp->sp_rend) 808 ptr = sp->sp_rbuf; 809 if (ptr == sp->sp_rget) { 810 if (ptr == sp->sp_rbuf) 811 ptr = sp->sp_rend; 812 ptr -= 2; 813 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 814 break; 815 } 816 } 817 STC_WRITE(sc, STC_EOSRR, 0); 818 if (cnt) { 819 *needsoftp = 1; 820 sp->sp_rput = ptr; 821 } 822 return (1); 823 } 824 825 int 826 spifstcintr_tx(sc, needsoftp) 827 struct spif_softc *sc; 828 int *needsoftp; 829 { 830 struct stty_port *sp; 831 u_int8_t channel, ch; 832 int cnt = 0; 833 834 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 835 sp = &sc->sc_ttys->sc_port[channel]; 836 if (!ISSET(sp->sp_flags, STTYF_STOP)) { 837 if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) { 838 STC_WRITE(sc, STC_TDR, 0); 839 STC_WRITE(sc, STC_TDR, 0x81); 840 CLR(sp->sp_flags, STTYF_SET_BREAK); 841 cnt += 2; 842 } 843 if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) { 844 STC_WRITE(sc, STC_TDR, 0); 845 STC_WRITE(sc, STC_TDR, 0x83); 846 CLR(sp->sp_flags, STTYF_CLR_BREAK); 847 cnt += 2; 848 } 849 850 while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) { 851 ch = *sp->sp_txp; 852 sp->sp_txc--; 853 sp->sp_txp++; 854 855 if (ch == 0) { 856 STC_WRITE(sc, STC_TDR, ch); 857 cnt++; 858 } 859 STC_WRITE(sc, STC_TDR, ch); 860 cnt++; 861 } 862 } 863 864 if (sp->sp_txc == 0 || 865 ISSET(sp->sp_flags, STTYF_STOP)) { 866 STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) & 867 (~CD180_SRER_TXD)); 868 CLR(sp->sp_flags, STTYF_STOP); 869 SET(sp->sp_flags, STTYF_DONE); 870 *needsoftp = 1; 871 } 872 873 STC_WRITE(sc, STC_EOSRR, 0); 874 875 return (1); 876 } 877 878 int 879 spifstcintr_mx(sc, needsoftp) 880 struct spif_softc *sc; 881 int *needsoftp; 882 { 883 struct stty_port *sp; 884 u_int8_t channel, mcr; 885 886 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 887 sp = &sc->sc_ttys->sc_port[channel]; 888 mcr = STC_READ(sc, STC_MCR); 889 if (mcr & CD180_MCR_CD) { 890 SET(sp->sp_flags, STTYF_CDCHG); 891 *needsoftp = 1; 892 } 893 STC_WRITE(sc, STC_MCR, 0); 894 STC_WRITE(sc, STC_EOSRR, 0); 895 return (1); 896 } 897 898 int 899 spifstcintr(vsc) 900 void *vsc; 901 { 902 struct spif_softc *sc = (struct spif_softc *)vsc; 903 int needsoft = 0, r = 0, i; 904 u_int8_t ar; 905 906 for (i = 0; i < 8; i++) { 907 ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK; 908 if (ar == CD180_GSVR_RXGOOD) 909 r |= spifstcintr_rx(sc, &needsoft); 910 else if (ar == CD180_GSVR_RXEXCEPTION) 911 r |= spifstcintr_rxexception(sc, &needsoft); 912 } 913 914 for (i = 0; i < 8; i++) { 915 ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK; 916 if (ar == CD180_GSVR_TXDATA) 917 r |= spifstcintr_tx(sc, &needsoft); 918 } 919 920 for (i = 0; i < 8; i++) { 921 ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK; 922 if (ar == CD180_GSVR_STATCHG) 923 r |= spifstcintr_mx(sc, &needsoft); 924 } 925 926 if (needsoft) 927 softintr_schedule(sc->sc_softih); 928 return (r); 929 } 930 931 void 932 spifsoftintr(vsc) 933 void *vsc; 934 { 935 struct spif_softc *sc = (struct spif_softc *)vsc; 936 struct stty_softc *stc = sc->sc_ttys; 937 int r = 0, i, data, s, flags; 938 u_int8_t stat, msvr; 939 struct stty_port *sp; 940 struct tty *tp; 941 942 if (stc != NULL) { 943 for (i = 0; i < stc->sc_nports; i++) { 944 sp = &stc->sc_port[i]; 945 tp = sp->sp_tty; 946 947 if (!ISSET(tp->t_state, TS_ISOPEN)) 948 continue; 949 950 while (sp->sp_rget != sp->sp_rput) { 951 stat = sp->sp_rget[0]; 952 data = sp->sp_rget[1]; 953 sp->sp_rget += 2; 954 if (sp->sp_rget == sp->sp_rend) 955 sp->sp_rget = sp->sp_rbuf; 956 957 if (stat & (CD180_RCSR_BE | CD180_RCSR_FE)) 958 data |= TTY_FE; 959 960 if (stat & CD180_RCSR_PE) 961 data |= TTY_PE; 962 963 (*linesw[tp->t_line].l_rint)(data, tp); 964 r = 1; 965 } 966 967 s = splhigh(); 968 flags = sp->sp_flags; 969 CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG | 970 STTYF_RING_OVERFLOW); 971 splx(s); 972 973 if (ISSET(flags, STTYF_CDCHG)) { 974 s = spltty(); 975 STC_WRITE(sc, STC_CAR, i); 976 msvr = STC_READ(sc, STC_MSVR); 977 splx(s); 978 979 sp->sp_carrier = msvr & CD180_MSVR_CD; 980 (*linesw[tp->t_line].l_modem)(tp, 981 sp->sp_carrier); 982 r = 1; 983 } 984 985 if (ISSET(flags, STTYF_RING_OVERFLOW)) { 986 log(LOG_WARNING, "%s-%x: ring overflow\n", 987 stc->sc_dev.dv_xname, i); 988 r = 1; 989 } 990 991 if (ISSET(flags, STTYF_DONE)) { 992 ndflush(&tp->t_outq, 993 sp->sp_txp - tp->t_outq.c_cf); 994 CLR(tp->t_state, TS_BUSY); 995 (*linesw[tp->t_line].l_start)(tp); 996 r = 1; 997 } 998 } 999 } 1000 } 1001 1002 void 1003 stty_write_ccr(sc, val) 1004 struct spif_softc *sc; 1005 u_int8_t val; 1006 { 1007 int tries = 100000; 1008 1009 while (STC_READ(sc, STC_CCR) && tries--) 1010 /*EMPTY*/; 1011 if (tries == 0) 1012 printf("%s: ccr timeout\n", sc->sc_dev.dv_xname); 1013 STC_WRITE(sc, STC_CCR, val); 1014 } 1015 1016 int 1017 stty_compute_baud(speed, clock, bprlp, bprhp) 1018 speed_t speed; 1019 int clock; 1020 u_int8_t *bprlp, *bprhp; 1021 { 1022 u_int32_t rate; 1023 1024 rate = (2 * clock) / (16 * speed); 1025 if (rate & 1) 1026 rate = (rate >> 1) + 1; 1027 else 1028 rate = rate >> 1; 1029 1030 if (rate > 0xffff || rate == 0) 1031 return (1); 1032 1033 *bprlp = rate & 0xff; 1034 *bprhp = (rate >> 8) & 0xff; 1035 return (0); 1036 } 1037 1038 int 1039 sbppmatch(parent, vcf, aux) 1040 struct device *parent; 1041 void *vcf, *aux; 1042 { 1043 struct spif_softc *sc = (struct spif_softc *)parent; 1044 1045 return (aux == sbppmatch && sc->sc_bpps == NULL); 1046 } 1047 1048 void 1049 sbppattach(parent, dev, aux) 1050 struct device *parent, *dev; 1051 void *aux; 1052 { 1053 struct spif_softc *sc = (struct spif_softc *)parent; 1054 struct sbpp_softc *psc = (struct sbpp_softc *)dev; 1055 int port; 1056 1057 sc->sc_bpps = psc; 1058 1059 for (port = 0; port < sc->sc_npar; port++) { 1060 } 1061 1062 psc->sc_nports = port; 1063 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1064 } 1065 1066 int 1067 sbppopen(dev, flags, mode, p) 1068 dev_t dev; 1069 int flags; 1070 int mode; 1071 struct proc *p; 1072 { 1073 return (ENXIO); 1074 } 1075 1076 int 1077 sbppclose(dev, flags, mode, p) 1078 dev_t dev; 1079 int flags; 1080 int mode; 1081 struct proc *p; 1082 { 1083 return (ENXIO); 1084 } 1085 1086 int 1087 spifppcintr(v) 1088 void *v; 1089 { 1090 return (0); 1091 } 1092 1093 int 1094 sbppread(dev, uio, flags) 1095 dev_t dev; 1096 struct uio *uio; 1097 int flags; 1098 { 1099 return (sbpp_rw(dev, uio)); 1100 } 1101 1102 int 1103 sbppwrite(dev, uio, flags) 1104 dev_t dev; 1105 struct uio *uio; 1106 int flags; 1107 { 1108 return (sbpp_rw(dev, uio)); 1109 } 1110 1111 int 1112 sbpp_rw(dev, uio) 1113 dev_t dev; 1114 struct uio *uio; 1115 { 1116 return (ENXIO); 1117 } 1118 1119 int 1120 sbpppoll(dev, events, p) 1121 dev_t dev; 1122 int events; 1123 struct proc *p; 1124 { 1125 return (seltrue(dev, events, p)); 1126 } 1127 1128 int 1129 sbppioctl(dev, cmd, data, flags, p) 1130 dev_t dev; 1131 u_long cmd; 1132 caddr_t data; 1133 int flags; 1134 struct proc *p; 1135 { 1136 int error; 1137 1138 error = ENOTTY; 1139 1140 return (error); 1141 } 1142