1 /* $NetBSD: spif.c,v 1.32 2019/11/10 21:16:37 chs Exp $ */ 2 /* $OpenBSD: spif.c,v 1.12 2003/10/03 16:44:51 miod Exp $ */ 3 4 /* 5 * Copyright (c) 1999-2002 Jason L. Wright (jason@thought.net) 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Effort sponsored in part by the Defense Advanced Research Projects 30 * Agency (DARPA) and Air Force Research Laboratory, Air Force 31 * Materiel Command, USAF, under agreement number F30602-01-2-0537. 32 * 33 */ 34 35 /* 36 * Driver for the SUNW,spif: 8 serial, 1 parallel sbus board 37 * based heavily on Iain Hibbert's driver for the MAGMA cards 38 */ 39 40 /* Ported to NetBSD 2.0 by Hauke Fath */ 41 42 43 #include <sys/cdefs.h> 44 __KERNEL_RCSID(0, "$NetBSD: spif.c,v 1.32 2019/11/10 21:16:37 chs Exp $"); 45 46 #include "spif.h" 47 #if NSPIF > 0 48 49 #include <sys/param.h> 50 #include <sys/systm.h> 51 #include <sys/proc.h> 52 #include <sys/device.h> 53 #include <sys/file.h> 54 #include <sys/ioctl.h> 55 #include <sys/malloc.h> 56 #include <sys/tty.h> 57 #include <sys/time.h> 58 #include <sys/kernel.h> 59 #include <sys/syslog.h> 60 #include <sys/conf.h> 61 #include <sys/errno.h> 62 #include <sys/kauth.h> 63 #include <sys/intr.h> 64 65 #include <sys/bus.h> 66 #include <machine/autoconf.h> 67 #include <machine/promlib.h> 68 69 #include <dev/sbus/sbusvar.h> 70 71 #include <dev/sbus/spifvar.h> 72 #include <dev/sbus/spifreg.h> 73 74 #include "ioconf.h" 75 76 /* Autoconfig stuff */ 77 78 CFATTACH_DECL_NEW(spif, sizeof(struct spif_softc), 79 spif_match, spif_attach, NULL, NULL); 80 81 CFATTACH_DECL_NEW(stty, sizeof(struct stty_softc), 82 stty_match, stty_attach, NULL, NULL); 83 84 CFATTACH_DECL_NEW(sbpp, sizeof(struct sbpp_softc), 85 sbpp_match, sbpp_attach, NULL, NULL); 86 87 dev_type_open(stty_open); 88 dev_type_close(stty_close); 89 dev_type_read(stty_read); 90 dev_type_write(stty_write); 91 dev_type_ioctl(stty_ioctl); 92 dev_type_stop(stty_stop); 93 dev_type_tty(stty_tty); 94 dev_type_poll(stty_poll); 95 96 const struct cdevsw stty_cdevsw = { 97 .d_open = stty_open, 98 .d_close = stty_close, 99 .d_read = stty_read, 100 .d_write = stty_write, 101 .d_ioctl = stty_ioctl, 102 .d_stop = stty_stop, 103 .d_tty = stty_tty, 104 .d_poll = stty_poll, 105 .d_mmap = nommap, 106 .d_kqfilter = ttykqfilter, 107 .d_discard = nodiscard, 108 .d_flag = D_TTY 109 }; 110 111 dev_type_open(sbpp_open); 112 dev_type_close(sbpp_close); 113 dev_type_read(sbpp_read); 114 dev_type_write(sbpp_write); 115 dev_type_ioctl(sbpp_ioctl); 116 dev_type_poll(sbpp_poll); 117 118 const struct cdevsw sbpp_cdevsw = { 119 .d_open = sbpp_open, 120 .d_close = sbpp_close, 121 .d_read = sbpp_read, 122 .d_write = sbpp_write, 123 .d_ioctl = sbpp_ioctl, 124 .d_stop = nostop, 125 .d_tty = notty, 126 .d_poll = sbpp_poll, 127 .d_mmap = nommap, 128 .d_kqfilter = nokqfilter, 129 .d_discard = nodiscard, 130 .d_flag = D_OTHER 131 }; 132 133 134 /* normal STC access */ 135 #define STC_WRITE(sc,r,v) \ 136 bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v)) 137 #define STC_READ(sc,r) \ 138 bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r)) 139 140 /* IACK STC access */ 141 #define ISTC_WRITE(sc,r,v) \ 142 bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v)) 143 #define ISTC_READ(sc,r) \ 144 bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r)) 145 146 /* PPC access */ 147 #define PPC_WRITE(sc,r,v) \ 148 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v)) 149 #define PPC_READ(sc,r) \ 150 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r)) 151 152 #define DTR_WRITE(sc,port,v) \ 153 do { \ 154 sc->sc_ttys->sc_port[(port)].sp_dtr = v; \ 155 bus_space_write_1((sc)->sc_bustag, \ 156 sc->sc_dtrh, port, (v == 0) ? 1 : 0); \ 157 } while (0) 158 159 #define DTR_READ(sc,port) ((sc)->sc_ttys->sc_port[(port)].sp_dtr) 160 161 162 int 163 spif_match(device_t parent, cfdata_t vcf, void *aux) 164 { 165 struct sbus_attach_args *sa = aux; 166 167 if (strcmp(vcf->cf_name, sa->sa_name) && 168 strcmp("SUNW,spif", sa->sa_name)) 169 return (0); 170 return (1); 171 } 172 173 void 174 spif_attach(device_t parent, device_t self, void *aux) 175 { 176 struct spif_softc *sc = device_private(self); 177 struct sbus_attach_args *sa = aux; 178 179 sc->sc_dev = self; 180 181 if (sa->sa_nintr != 2) { 182 printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr); 183 return; 184 } 185 186 if (sa->sa_nreg != 1) { 187 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); 188 return; 189 } 190 191 sc->sc_bustag = sa->sa_bustag; 192 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 193 sa->sa_offset, sa->sa_size, 194 0, &sc->sc_regh) != 0) { 195 printf(": can't map registers\n"); 196 return; 197 } 198 199 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 200 DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 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 STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) { 207 printf(": can't map dtr regs\n"); 208 goto fail_unmapregs; 209 } 210 211 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 212 ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) { 213 printf(": can't map dtr regs\n"); 214 goto fail_unmapregs; 215 } 216 217 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 218 PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) { 219 printf(": can't map dtr regs\n"); 220 goto fail_unmapregs; 221 } 222 223 sc->sc_ppcih = bus_intr_establish(sa->sa_bustag, 224 sa->sa_intr[PARALLEL_INTR].oi_pri, IPL_SERIAL, spif_ppcintr, sc); 225 if (sc->sc_ppcih == NULL) { 226 printf(": failed to establish ppc interrupt\n"); 227 goto fail_unmapregs; 228 } 229 230 sc->sc_stcih = bus_intr_establish(sa->sa_bustag, 231 sa->sa_intr[SERIAL_INTR].oi_pri, IPL_SERIAL, spif_stcintr, sc); 232 if (sc->sc_stcih == NULL) { 233 printf(": failed to establish stc interrupt\n"); 234 goto fail_unmapregs; 235 } 236 237 sc->sc_softih = softint_establish(SOFTINT_SERIAL, spif_softintr, sc); 238 if (sc->sc_softih == NULL) { 239 printf(": can't get soft intr\n"); 240 goto fail_unmapregs; 241 } 242 243 sc->sc_node = sa->sa_node; 244 245 sc->sc_rev = prom_getpropint(sc->sc_node, "revlev", 0); 246 247 sc->sc_osc = prom_getpropint(sc->sc_node, "verosc", 0); 248 switch (sc->sc_osc) { 249 case SPIF_OSC10: 250 sc->sc_osc = 10000000; 251 break; 252 case SPIF_OSC9: 253 default: 254 sc->sc_osc = 9830400; 255 break; 256 } 257 258 sc->sc_nser = 8; 259 sc->sc_npar = 1; 260 261 sc->sc_rev2 = STC_READ(sc, STC_GFRCR); 262 STC_WRITE(sc, STC_GSVR, 0); 263 264 stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL); 265 while (STC_READ(sc, STC_GSVR) != 0xff); 266 while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2); 267 268 STC_WRITE(sc, STC_PPRH, CD180_PPRH); 269 STC_WRITE(sc, STC_PPRL, CD180_PPRL); 270 STC_WRITE(sc, STC_MSMR, SPIF_MSMR); 271 STC_WRITE(sc, STC_TSMR, SPIF_TSMR); 272 STC_WRITE(sc, STC_RSMR, SPIF_RSMR); 273 STC_WRITE(sc, STC_GSVR, 0); 274 STC_WRITE(sc, STC_GSCR1, 0); 275 STC_WRITE(sc, STC_GSCR2, 0); 276 STC_WRITE(sc, STC_GSCR3, 0); 277 278 printf(": rev %x chiprev %x osc %sMHz\n", 279 sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc)); 280 281 (void)config_found(self, stty_match, NULL); 282 (void)config_found(self, sbpp_match, NULL); 283 284 return; 285 286 fail_unmapregs: 287 bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_size); 288 } 289 290 int 291 stty_match(device_t parent, cfdata_t vcf, void *aux) 292 { 293 struct spif_softc *sc = device_private(parent); 294 295 return (aux == stty_match && sc->sc_ttys == NULL); 296 } 297 298 void 299 stty_attach(device_t parent, device_t dev, void *aux) 300 { 301 struct spif_softc *sc = device_private(parent); 302 struct stty_softc *ssc = device_private(dev); 303 int port; 304 305 sc->sc_dev = dev; 306 sc->sc_ttys = ssc; 307 308 for (port = 0; port < sc->sc_nser; port++) { 309 struct stty_port *sp = &ssc->sc_port[port]; 310 struct tty *tp; 311 312 DTR_WRITE(sc, port, 0); 313 314 tp = tty_alloc(); 315 316 tp->t_oproc = stty_start; 317 tp->t_param = stty_param; 318 319 sp->sp_tty = tp; 320 sp->sp_sc = sc; 321 sp->sp_channel = port; 322 323 sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_WAITOK); 324 sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE; 325 } 326 327 ssc->sc_nports = port; 328 329 printf(": %d tty%s\n", port, port == 1 ? "" : "s"); 330 } 331 332 int 333 stty_open(dev_t dev, int flags, int mode, struct lwp *l) 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 342 sc = device_lookup_private(&stty_cd, card); 343 csc = device_lookup_private(&spif_cd, card); 344 if (sc == NULL || csc == NULL) 345 return (ENXIO); 346 347 if (port >= sc->sc_nports) 348 return (ENXIO); 349 350 sp = &sc->sc_port[port]; 351 tp = sp->sp_tty; 352 tp->t_dev = dev; 353 354 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 355 return (EBUSY); 356 357 mutex_spin_enter(&tty_lock); 358 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 359 ttychars(tp); 360 tp->t_iflag = TTYDEF_IFLAG; 361 tp->t_oflag = TTYDEF_OFLAG; 362 tp->t_cflag = TTYDEF_CFLAG; 363 if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL)) 364 SET(tp->t_cflag, CLOCAL); 365 if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS)) 366 SET(tp->t_cflag, CRTSCTS); 367 if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF)) 368 SET(tp->t_cflag, MDMBUF); 369 tp->t_lflag = TTYDEF_LFLAG; 370 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 371 372 sp->sp_rput = sp->sp_rget = sp->sp_rbuf; 373 374 STC_WRITE(csc, STC_CAR, sp->sp_channel); 375 stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 376 STC_WRITE(csc, STC_CAR, sp->sp_channel); 377 378 stty_param(tp, &tp->t_termios); 379 380 ttsetwater(tp); 381 382 STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD); 383 384 if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier) 385 SET(tp->t_state, TS_CARR_ON); 386 else 387 CLR(tp->t_state, TS_CARR_ON); 388 } 389 390 if (!ISSET(flags, O_NONBLOCK)) { 391 while (!ISSET(tp->t_cflag, CLOCAL) && 392 !ISSET(tp->t_state, TS_CARR_ON)) { 393 int error; 394 error = ttysleep(tp, &tp->t_rawcv, true, 0); 395 if (error != 0) { 396 mutex_spin_exit(&tty_lock); 397 return (error); 398 } 399 } 400 } 401 mutex_spin_exit(&tty_lock); 402 403 return ((*tp->t_linesw->l_open)(dev, tp)); 404 } 405 406 int 407 stty_close(dev_t dev, int flags, int mode, struct lwp *l) 408 { 409 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 410 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 411 struct spif_softc *csc = sp->sp_sc; 412 struct tty *tp = sp->sp_tty; 413 int port = SPIF_PORT(dev); 414 int s; 415 416 (*tp->t_linesw->l_close)(tp, flags); 417 s = spltty(); 418 419 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) { 420 stty_modem_control(sp, 0, DMSET); 421 STC_WRITE(csc, STC_CAR, port); 422 STC_WRITE(csc, STC_CCR, 423 CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 424 } 425 426 splx(s); 427 ttyclose(tp); 428 return (0); 429 } 430 431 int 432 stty_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 433 { 434 struct stty_softc *stc = device_lookup_private(&stty_cd, 435 SPIF_CARD(dev)); 436 struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)]; 437 struct spif_softc *sc = sp->sp_sc; 438 struct tty *tp = sp->sp_tty; 439 int error; 440 441 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); 442 if (error >= 0) 443 return (error); 444 445 error = ttioctl(tp, cmd, data, flags, l); 446 if (error >= 0) 447 return (error); 448 449 error = 0; 450 451 switch (cmd) { 452 case TIOCSBRK: 453 SET(sp->sp_flags, STTYF_SET_BREAK); 454 STC_WRITE(sc, STC_CAR, sp->sp_channel); 455 STC_WRITE(sc, STC_SRER, 456 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 457 break; 458 case TIOCCBRK: 459 SET(sp->sp_flags, STTYF_CLR_BREAK); 460 STC_WRITE(sc, STC_CAR, sp->sp_channel); 461 STC_WRITE(sc, STC_SRER, 462 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 463 break; 464 case TIOCSDTR: 465 stty_modem_control(sp, TIOCM_DTR, DMBIS); 466 break; 467 case TIOCCDTR: 468 stty_modem_control(sp, TIOCM_DTR, DMBIC); 469 break; 470 case TIOCMBIS: 471 stty_modem_control(sp, *((int *)data), DMBIS); 472 break; 473 case TIOCMBIC: 474 stty_modem_control(sp, *((int *)data), DMBIC); 475 break; 476 case TIOCMGET: 477 *((int *)data) = stty_modem_control(sp, 0, DMGET); 478 break; 479 case TIOCMSET: 480 stty_modem_control(sp, *((int *)data), DMSET); 481 break; 482 case TIOCGFLAGS: 483 *((int *)data) = sp->sp_openflags; 484 break; 485 case TIOCSFLAGS: 486 if (kauth_authorize_device_tty(l->l_cred, 487 KAUTH_DEVICE_TTY_PRIVSET, tp)) 488 error = EPERM; 489 else 490 sp->sp_openflags = *((int *)data) & 491 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 492 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 493 break; 494 default: 495 error = ENOTTY; 496 } 497 498 return (error); 499 } 500 501 int 502 stty_modem_control(struct stty_port *sp, int bits, int how) 503 { 504 struct spif_softc *csc = sp->sp_sc; 505 struct tty *tp = sp->sp_tty; 506 int s, msvr; 507 508 s = spltty(); 509 STC_WRITE(csc, STC_CAR, sp->sp_channel); 510 511 switch (how) { 512 case DMGET: 513 bits = TIOCM_LE; 514 if (DTR_READ(csc, sp->sp_channel)) 515 bits |= TIOCM_DTR; 516 msvr = STC_READ(csc, STC_MSVR); 517 if (ISSET(msvr, CD180_MSVR_DSR)) 518 bits |= TIOCM_DSR; 519 if (ISSET(msvr, CD180_MSVR_CD)) 520 bits |= TIOCM_CD; 521 if (ISSET(msvr, CD180_MSVR_CTS)) 522 bits |= TIOCM_CTS; 523 if (ISSET(msvr, CD180_MSVR_RTS)) 524 bits |= TIOCM_RTS; 525 break; 526 case DMSET: 527 DTR_WRITE(csc, sp->sp_channel, ISSET(bits, TIOCM_DTR) ? 1 : 0); 528 if (ISSET(bits, TIOCM_RTS)) 529 STC_WRITE(csc, STC_MSVR, 530 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS)); 531 else 532 STC_WRITE(csc, STC_MSVR, 533 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS); 534 break; 535 case DMBIS: 536 if (ISSET(bits, TIOCM_DTR)) 537 DTR_WRITE(csc, sp->sp_channel, 1); 538 if (ISSET(bits, TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 539 STC_WRITE(csc, STC_MSVR, 540 STC_READ(csc, STC_MSVR) & (~CD180_MSVR_RTS)); 541 break; 542 case DMBIC: 543 if (ISSET(bits, TIOCM_DTR)) 544 DTR_WRITE(csc, sp->sp_channel, 0); 545 if (ISSET(bits, TIOCM_RTS)) 546 STC_WRITE(csc, STC_MSVR, 547 STC_READ(csc, STC_MSVR) | CD180_MSVR_RTS); 548 break; 549 } 550 551 splx(s); 552 return (bits); 553 } 554 555 int 556 stty_param(struct tty *tp, struct termios *t) 557 { 558 struct stty_softc *st = device_lookup_private(&stty_cd, 559 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 uint8_t rbprl = 0, rbprh = 0, tbprl = 0, tbprh = 0; 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 stty_read(dev_t dev, struct uio *uio, int flags) 654 { 655 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 656 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 657 struct tty *tp = sp->sp_tty; 658 659 return ((*tp->t_linesw->l_read)(tp, uio, flags)); 660 } 661 662 int 663 stty_write(dev_t dev, struct uio *uio, int flags) 664 { 665 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 666 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 667 struct tty *tp = sp->sp_tty; 668 669 return ((*tp->t_linesw->l_write)(tp, uio, flags)); 670 } 671 672 int 673 stty_poll(dev_t dev, int events, struct lwp *l) 674 { 675 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 676 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 677 struct tty *tp = sp->sp_tty; 678 679 return ((*tp->t_linesw->l_poll)(tp, events, l)); 680 } 681 682 struct tty * 683 stty_tty(dev_t dev) 684 { 685 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 686 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 687 688 return (sp->sp_tty); 689 } 690 691 void 692 stty_stop(struct tty *tp, int flags) 693 { 694 struct stty_softc *sc = device_lookup_private(&stty_cd, 695 SPIF_CARD(tp->t_dev)); 696 struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)]; 697 int s; 698 699 s = spltty(); 700 if (ISSET(tp->t_state, TS_BUSY)) { 701 if (!ISSET(tp->t_state, TS_TTSTOP)) 702 SET(tp->t_state, TS_FLUSH); 703 SET(sp->sp_flags, STTYF_STOP); 704 } 705 splx(s); 706 } 707 708 void 709 stty_start(struct tty *tp) 710 { 711 struct stty_softc *stc = device_lookup_private(&stty_cd, 712 SPIF_CARD(tp->t_dev)); 713 struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)]; 714 struct spif_softc *sc = sp->sp_sc; 715 int s; 716 717 s = spltty(); 718 719 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 720 if (ttypull(tp)) { 721 sp->sp_txc = ndqb(&tp->t_outq, 0); 722 sp->sp_txp = tp->t_outq.c_cf; 723 SET(tp->t_state, TS_BUSY); 724 STC_WRITE(sc, STC_CAR, sp->sp_channel); 725 STC_WRITE(sc, STC_SRER, 726 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 727 } 728 } 729 730 splx(s); 731 } 732 733 int 734 spif_stcintr_rxexception(struct spif_softc *sc, int *needsoftp) 735 { 736 struct stty_port *sp; 737 uint8_t channel, *ptr; 738 739 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 740 sp = &sc->sc_ttys->sc_port[channel]; 741 ptr = sp->sp_rput; 742 *ptr++ = STC_READ(sc, STC_RCSR); 743 *ptr++ = STC_READ(sc, STC_RDR); 744 if (ptr == sp->sp_rend) 745 ptr = sp->sp_rbuf; 746 if (ptr == sp->sp_rget) { 747 if (ptr == sp->sp_rbuf) 748 ptr = sp->sp_rend; 749 ptr -= 2; 750 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 751 } 752 STC_WRITE(sc, STC_EOSRR, 0); 753 *needsoftp = 1; 754 sp->sp_rput = ptr; 755 return (1); 756 } 757 758 int 759 spif_stcintr_rx(struct spif_softc *sc, int *needsoftp) 760 { 761 struct stty_port *sp; 762 uint8_t channel, *ptr, cnt; 763 int i; 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 cnt = STC_READ(sc, STC_RDCR); 769 for (i = 0; i < cnt; i++) { 770 *ptr++ = 0; 771 (void)STC_READ(sc, STC_RCSR); 772 *ptr++ = STC_READ(sc, STC_RDR); 773 if (ptr == sp->sp_rend) 774 ptr = sp->sp_rbuf; 775 if (ptr == sp->sp_rget) { 776 if (ptr == sp->sp_rbuf) 777 ptr = sp->sp_rend; 778 ptr -= 2; 779 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 780 break; 781 } 782 } 783 STC_WRITE(sc, STC_EOSRR, 0); 784 if (cnt) { 785 *needsoftp = 1; 786 sp->sp_rput = ptr; 787 } 788 return (1); 789 } 790 791 int 792 spif_stcintr_tx(struct spif_softc *sc, int *needsoftp) 793 { 794 struct stty_port *sp; 795 uint8_t channel, ch; 796 int cnt = 0; 797 798 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 799 sp = &sc->sc_ttys->sc_port[channel]; 800 if (!ISSET(sp->sp_flags, STTYF_STOP)) { 801 if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) { 802 STC_WRITE(sc, STC_TDR, 0); 803 STC_WRITE(sc, STC_TDR, 0x81); 804 CLR(sp->sp_flags, STTYF_SET_BREAK); 805 cnt += 2; 806 } 807 if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) { 808 STC_WRITE(sc, STC_TDR, 0); 809 STC_WRITE(sc, STC_TDR, 0x83); 810 CLR(sp->sp_flags, STTYF_CLR_BREAK); 811 cnt += 2; 812 } 813 814 while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) { 815 ch = *sp->sp_txp; 816 sp->sp_txc--; 817 sp->sp_txp++; 818 819 if (ch == 0) { 820 STC_WRITE(sc, STC_TDR, ch); 821 cnt++; 822 } 823 STC_WRITE(sc, STC_TDR, ch); 824 cnt++; 825 } 826 } 827 828 if (sp->sp_txc == 0 || 829 ISSET(sp->sp_flags, STTYF_STOP)) { 830 STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) & 831 (~CD180_SRER_TXD)); 832 CLR(sp->sp_flags, STTYF_STOP); 833 SET(sp->sp_flags, STTYF_DONE); 834 *needsoftp = 1; 835 } 836 837 STC_WRITE(sc, STC_EOSRR, 0); 838 839 return (1); 840 } 841 842 int 843 spif_stcintr_mx(struct spif_softc *sc, int *needsoftp) 844 { 845 struct stty_port *sp; 846 uint8_t channel, mcr; 847 848 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 849 sp = &sc->sc_ttys->sc_port[channel]; 850 mcr = STC_READ(sc, STC_MCR); 851 if (mcr & CD180_MCR_CD) { 852 SET(sp->sp_flags, STTYF_CDCHG); 853 *needsoftp = 1; 854 } 855 STC_WRITE(sc, STC_MCR, 0); 856 STC_WRITE(sc, STC_EOSRR, 0); 857 return (1); 858 } 859 860 int 861 spif_stcintr(void *vsc) 862 { 863 struct spif_softc *sc = (struct spif_softc *)vsc; 864 int needsoft = 0, r = 0, i; 865 uint8_t ar; 866 867 for (i = 0; i < 8; i++) { 868 ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK; 869 if (ar == CD180_GSVR_RXGOOD) 870 r |= spif_stcintr_rx(sc, &needsoft); 871 else if (ar == CD180_GSVR_RXEXCEPTION) 872 r |= spif_stcintr_rxexception(sc, &needsoft); 873 } 874 875 for (i = 0; i < 8; i++) { 876 ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK; 877 if (ar == CD180_GSVR_TXDATA) 878 r |= spif_stcintr_tx(sc, &needsoft); 879 } 880 881 for (i = 0; i < 8; i++) { 882 ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK; 883 if (ar == CD180_GSVR_STATCHG) 884 r |= spif_stcintr_mx(sc, &needsoft); 885 } 886 887 if (needsoft) 888 softint_schedule(sc->sc_softih); 889 return (r); 890 } 891 892 void 893 spif_softintr(void *vsc) 894 { 895 struct spif_softc *sc = (struct spif_softc *)vsc; 896 struct stty_softc *stc = sc->sc_ttys; 897 int i, data, s, flags; 898 uint8_t stat, msvr; 899 struct stty_port *sp; 900 struct tty *tp; 901 902 if (stc != NULL) { 903 for (i = 0; i < stc->sc_nports; i++) { 904 sp = &stc->sc_port[i]; 905 tp = sp->sp_tty; 906 907 if (!ISSET(tp->t_state, TS_ISOPEN)) 908 continue; 909 910 while (sp->sp_rget != sp->sp_rput) { 911 stat = sp->sp_rget[0]; 912 data = sp->sp_rget[1]; 913 sp->sp_rget += 2; 914 if (sp->sp_rget == sp->sp_rend) 915 sp->sp_rget = sp->sp_rbuf; 916 917 if (stat & (CD180_RCSR_BE | CD180_RCSR_FE)) 918 data |= TTY_FE; 919 920 if (stat & CD180_RCSR_PE) 921 data |= TTY_PE; 922 923 (*tp->t_linesw->l_rint)(data, tp); 924 } 925 926 s = splhigh(); 927 flags = sp->sp_flags; 928 CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG | 929 STTYF_RING_OVERFLOW); 930 splx(s); 931 932 if (ISSET(flags, STTYF_CDCHG)) { 933 s = spltty(); 934 STC_WRITE(sc, STC_CAR, i); 935 msvr = STC_READ(sc, STC_MSVR); 936 splx(s); 937 938 sp->sp_carrier = msvr & CD180_MSVR_CD; 939 (*tp->t_linesw->l_modem)(tp, 940 sp->sp_carrier); 941 } 942 943 if (ISSET(flags, STTYF_RING_OVERFLOW)) { 944 log(LOG_WARNING, "%s-%x: ring overflow\n", 945 device_xname(stc->sc_dev), i); 946 } 947 948 if (ISSET(flags, STTYF_DONE)) { 949 ndflush(&tp->t_outq, 950 sp->sp_txp - tp->t_outq.c_cf); 951 CLR(tp->t_state, TS_BUSY); 952 (*tp->t_linesw->l_start)(tp); 953 } 954 } 955 } 956 } 957 958 void 959 stty_write_ccr(struct spif_softc *sc, uint8_t val) 960 { 961 int tries = 100000; 962 963 while (STC_READ(sc, STC_CCR) && tries--) 964 /*EMPTY*/; 965 if (tries == 0) 966 aprint_error_dev(sc->sc_dev, "ccr timeout\n"); 967 STC_WRITE(sc, STC_CCR, val); 968 } 969 970 int 971 stty_compute_baud(speed_t speed, int clock, uint8_t *bprlp, uint8_t *bprhp) 972 { 973 uint32_t rate; 974 975 rate = (2 * clock) / (16 * speed); 976 if (rate & 1) 977 rate = (rate >> 1) + 1; 978 else 979 rate = rate >> 1; 980 981 if (rate > 0xffff || rate == 0) 982 return (1); 983 984 *bprlp = rate & 0xff; 985 *bprhp = (rate >> 8) & 0xff; 986 return (0); 987 } 988 989 int 990 sbpp_match(device_t parent, cfdata_t vcf, void *aux) 991 { 992 struct spif_softc *sc = device_private(parent); 993 994 return (aux == sbpp_match && sc->sc_bpps == NULL); 995 } 996 997 void 998 sbpp_attach(device_t parent, device_t dev, void *aux) 999 { 1000 struct spif_softc *sc = device_private(parent); 1001 struct sbpp_softc *psc = device_private(dev); 1002 int port; 1003 1004 sc->sc_bpps = psc; 1005 1006 for (port = 0; port < sc->sc_npar; port++) { 1007 } 1008 1009 psc->sc_nports = port; 1010 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1011 } 1012 1013 int 1014 sbpp_open(dev_t dev, int flags, int mode, struct lwp *l) 1015 { 1016 return (ENXIO); 1017 } 1018 1019 int 1020 sbpp_close(dev_t dev, int flags, int mode, struct lwp *l) 1021 { 1022 return (ENXIO); 1023 } 1024 1025 int 1026 spif_ppcintr(void *v) 1027 { 1028 return (0); 1029 } 1030 1031 int 1032 sbpp_read(dev_t dev, struct uio *uio, int flags) 1033 { 1034 return (sbpp_rw(dev, uio)); 1035 } 1036 1037 int 1038 sbpp_write(dev_t dev, struct uio *uio, int flags) 1039 { 1040 return (sbpp_rw(dev, uio)); 1041 } 1042 1043 int 1044 sbpp_rw(dev_t dev, struct uio *uio) 1045 { 1046 return (ENXIO); 1047 } 1048 1049 int 1050 sbpp_poll(dev_t dev, int events, struct lwp *l) 1051 { 1052 return (seltrue(dev, events, l)); 1053 } 1054 1055 int 1056 sbpp_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 1057 { 1058 int error; 1059 1060 error = ENOTTY; 1061 1062 return (error); 1063 } 1064 1065 #endif /* NSPIF */ 1066