1 /* $NetBSD: spif.c,v 1.30 2014/03/16 05:20:29 dholland 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.30 2014/03/16 05:20:29 dholland 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_flag = D_TTY 108 }; 109 110 dev_type_open(sbpp_open); 111 dev_type_close(sbpp_close); 112 dev_type_read(sbpp_read); 113 dev_type_write(sbpp_write); 114 dev_type_ioctl(sbpp_ioctl); 115 dev_type_poll(sbpp_poll); 116 117 const struct cdevsw sbpp_cdevsw = { 118 .d_open = sbpp_open, 119 .d_close = sbpp_close, 120 .d_read = sbpp_read, 121 .d_write = sbpp_write, 122 .d_ioctl = sbpp_ioctl, 123 .d_stop = nostop, 124 .d_tty = notty, 125 .d_poll = sbpp_poll, 126 .d_mmap = nommap, 127 .d_kqfilter = nokqfilter, 128 .d_flag = D_OTHER 129 }; 130 131 132 /* normal STC access */ 133 #define STC_WRITE(sc,r,v) \ 134 bus_space_write_1((sc)->sc_bustag, (sc)->sc_stch, (r), (v)) 135 #define STC_READ(sc,r) \ 136 bus_space_read_1((sc)->sc_bustag, (sc)->sc_stch, (r)) 137 138 /* IACK STC access */ 139 #define ISTC_WRITE(sc,r,v) \ 140 bus_space_write_1((sc)->sc_bustag, (sc)->sc_istch, (r), (v)) 141 #define ISTC_READ(sc,r) \ 142 bus_space_read_1((sc)->sc_bustag, (sc)->sc_istch, (r)) 143 144 /* PPC access */ 145 #define PPC_WRITE(sc,r,v) \ 146 bus_space_write_1((sc)->sc_bustag, (sc)->sc_ppch, (r), (v)) 147 #define PPC_READ(sc,r) \ 148 bus_space_read_1((sc)->sc_bustag, (sc)->sc_ppch, (r)) 149 150 #define DTR_WRITE(sc,port,v) \ 151 do { \ 152 sc->sc_ttys->sc_port[(port)].sp_dtr = v; \ 153 bus_space_write_1((sc)->sc_bustag, \ 154 sc->sc_dtrh, port, (v == 0) ? 1 : 0); \ 155 } while (0) 156 157 #define DTR_READ(sc,port) ((sc)->sc_ttys->sc_port[(port)].sp_dtr) 158 159 160 int 161 spif_match(device_t parent, cfdata_t vcf, void *aux) 162 { 163 struct sbus_attach_args *sa = aux; 164 165 if (strcmp(vcf->cf_name, sa->sa_name) && 166 strcmp("SUNW,spif", sa->sa_name)) 167 return (0); 168 return (1); 169 } 170 171 void 172 spif_attach(device_t parent, device_t self, void *aux) 173 { 174 struct spif_softc *sc = device_private(self); 175 struct sbus_attach_args *sa = aux; 176 177 sc->sc_dev = self; 178 179 if (sa->sa_nintr != 2) { 180 printf(": expected %d interrupts, got %d\n", 2, sa->sa_nintr); 181 return; 182 } 183 184 if (sa->sa_nreg != 1) { 185 printf(": expected %d registers, got %d\n", 1, sa->sa_nreg); 186 return; 187 } 188 189 sc->sc_bustag = sa->sa_bustag; 190 if (sbus_bus_map(sa->sa_bustag, sa->sa_slot, 191 sa->sa_offset, sa->sa_size, 192 0, &sc->sc_regh) != 0) { 193 printf(": can't map registers\n"); 194 return; 195 } 196 197 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 198 DTR_REG_OFFSET, DTR_REG_LEN, &sc->sc_dtrh) != 0) { 199 printf(": can't map dtr regs\n"); 200 goto fail_unmapregs; 201 } 202 203 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 204 STC_REG_OFFSET, STC_REG_LEN, &sc->sc_stch) != 0) { 205 printf(": can't map dtr regs\n"); 206 goto fail_unmapregs; 207 } 208 209 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 210 ISTC_REG_OFFSET, ISTC_REG_LEN, &sc->sc_istch) != 0) { 211 printf(": can't map dtr regs\n"); 212 goto fail_unmapregs; 213 } 214 215 if (bus_space_subregion(sc->sc_bustag, sc->sc_regh, 216 PPC_REG_OFFSET, PPC_REG_LEN, &sc->sc_ppch) != 0) { 217 printf(": can't map dtr regs\n"); 218 goto fail_unmapregs; 219 } 220 221 sc->sc_ppcih = bus_intr_establish(sa->sa_bustag, 222 sa->sa_intr[PARALLEL_INTR].oi_pri, IPL_SERIAL, spif_ppcintr, sc); 223 if (sc->sc_ppcih == NULL) { 224 printf(": failed to establish ppc interrupt\n"); 225 goto fail_unmapregs; 226 } 227 228 sc->sc_stcih = bus_intr_establish(sa->sa_bustag, 229 sa->sa_intr[SERIAL_INTR].oi_pri, IPL_SERIAL, spif_stcintr, sc); 230 if (sc->sc_stcih == NULL) { 231 printf(": failed to establish stc interrupt\n"); 232 goto fail_unmapregs; 233 } 234 235 sc->sc_softih = softint_establish(SOFTINT_SERIAL, spif_softintr, sc); 236 if (sc->sc_softih == NULL) { 237 printf(": can't get soft intr\n"); 238 goto fail_unmapregs; 239 } 240 241 sc->sc_node = sa->sa_node; 242 243 sc->sc_rev = prom_getpropint(sc->sc_node, "revlev", 0); 244 245 sc->sc_osc = prom_getpropint(sc->sc_node, "verosc", 0); 246 switch (sc->sc_osc) { 247 case SPIF_OSC10: 248 sc->sc_osc = 10000000; 249 break; 250 case SPIF_OSC9: 251 default: 252 sc->sc_osc = 9830400; 253 break; 254 } 255 256 sc->sc_nser = 8; 257 sc->sc_npar = 1; 258 259 sc->sc_rev2 = STC_READ(sc, STC_GFRCR); 260 STC_WRITE(sc, STC_GSVR, 0); 261 262 stty_write_ccr(sc, CD180_CCR_CMD_RESET | CD180_CCR_RESETALL); 263 while (STC_READ(sc, STC_GSVR) != 0xff); 264 while (STC_READ(sc, STC_GFRCR) != sc->sc_rev2); 265 266 STC_WRITE(sc, STC_PPRH, CD180_PPRH); 267 STC_WRITE(sc, STC_PPRL, CD180_PPRL); 268 STC_WRITE(sc, STC_MSMR, SPIF_MSMR); 269 STC_WRITE(sc, STC_TSMR, SPIF_TSMR); 270 STC_WRITE(sc, STC_RSMR, SPIF_RSMR); 271 STC_WRITE(sc, STC_GSVR, 0); 272 STC_WRITE(sc, STC_GSCR1, 0); 273 STC_WRITE(sc, STC_GSCR2, 0); 274 STC_WRITE(sc, STC_GSCR3, 0); 275 276 printf(": rev %x chiprev %x osc %sMHz\n", 277 sc->sc_rev, sc->sc_rev2, clockfreq(sc->sc_osc)); 278 279 (void)config_found(self, stty_match, NULL); 280 (void)config_found(self, sbpp_match, NULL); 281 282 return; 283 284 fail_unmapregs: 285 bus_space_unmap(sa->sa_bustag, sc->sc_regh, sa->sa_size); 286 } 287 288 int 289 stty_match(device_t parent, cfdata_t vcf, void *aux) 290 { 291 struct spif_softc *sc = device_private(parent); 292 293 return (aux == stty_match && sc->sc_ttys == NULL); 294 } 295 296 void 297 stty_attach(device_t parent, device_t dev, void *aux) 298 { 299 struct spif_softc *sc = device_private(parent); 300 struct stty_softc *ssc = device_private(dev); 301 int port; 302 303 sc->sc_dev = dev; 304 sc->sc_ttys = ssc; 305 306 for (port = 0; port < sc->sc_nser; port++) { 307 struct stty_port *sp = &ssc->sc_port[port]; 308 struct tty *tp; 309 310 DTR_WRITE(sc, port, 0); 311 312 tp = tty_alloc(); 313 314 tp->t_oproc = stty_start; 315 tp->t_param = stty_param; 316 317 sp->sp_tty = tp; 318 sp->sp_sc = sc; 319 sp->sp_channel = port; 320 321 sp->sp_rbuf = malloc(STTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT); 322 if(sp->sp_rbuf == NULL) 323 break; 324 325 sp->sp_rend = sp->sp_rbuf + STTY_RBUF_SIZE; 326 } 327 328 ssc->sc_nports = port; 329 330 printf(": %d tty%s\n", port, port == 1 ? "" : "s"); 331 } 332 333 int 334 stty_open(dev_t dev, int flags, int mode, struct lwp *l) 335 { 336 struct spif_softc *csc; 337 struct stty_softc *sc; 338 struct stty_port *sp; 339 struct tty *tp; 340 int card = SPIF_CARD(dev); 341 int port = SPIF_PORT(dev); 342 343 sc = device_lookup_private(&stty_cd, card); 344 csc = device_lookup_private(&spif_cd, card); 345 if (sc == NULL || csc == NULL) 346 return (ENXIO); 347 348 if (port >= sc->sc_nports) 349 return (ENXIO); 350 351 sp = &sc->sc_port[port]; 352 tp = sp->sp_tty; 353 tp->t_dev = dev; 354 355 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) 356 return (EBUSY); 357 358 mutex_spin_enter(&tty_lock); 359 if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { 360 ttychars(tp); 361 tp->t_iflag = TTYDEF_IFLAG; 362 tp->t_oflag = TTYDEF_OFLAG; 363 tp->t_cflag = TTYDEF_CFLAG; 364 if (ISSET(sp->sp_openflags, TIOCFLAG_CLOCAL)) 365 SET(tp->t_cflag, CLOCAL); 366 if (ISSET(sp->sp_openflags, TIOCFLAG_CRTSCTS)) 367 SET(tp->t_cflag, CRTSCTS); 368 if (ISSET(sp->sp_openflags, TIOCFLAG_MDMBUF)) 369 SET(tp->t_cflag, MDMBUF); 370 tp->t_lflag = TTYDEF_LFLAG; 371 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 372 373 sp->sp_rput = sp->sp_rget = sp->sp_rbuf; 374 375 STC_WRITE(csc, STC_CAR, sp->sp_channel); 376 stty_write_ccr(csc, CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 377 STC_WRITE(csc, STC_CAR, sp->sp_channel); 378 379 stty_param(tp, &tp->t_termios); 380 381 ttsetwater(tp); 382 383 STC_WRITE(csc, STC_SRER, CD180_SRER_CD | CD180_SRER_RXD); 384 385 if (ISSET(sp->sp_openflags, TIOCFLAG_SOFTCAR) || sp->sp_carrier) 386 SET(tp->t_state, TS_CARR_ON); 387 else 388 CLR(tp->t_state, TS_CARR_ON); 389 } 390 391 if (!ISSET(flags, O_NONBLOCK)) { 392 while (!ISSET(tp->t_cflag, CLOCAL) && 393 !ISSET(tp->t_state, TS_CARR_ON)) { 394 int error; 395 error = ttysleep(tp, &tp->t_rawcv, true, 0); 396 if (error != 0) { 397 mutex_spin_exit(&tty_lock); 398 return (error); 399 } 400 } 401 } 402 mutex_spin_exit(&tty_lock); 403 404 return ((*tp->t_linesw->l_open)(dev, tp)); 405 } 406 407 int 408 stty_close(dev_t dev, int flags, int mode, struct lwp *l) 409 { 410 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 411 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 412 struct spif_softc *csc = sp->sp_sc; 413 struct tty *tp = sp->sp_tty; 414 int port = SPIF_PORT(dev); 415 int s; 416 417 (*tp->t_linesw->l_close)(tp, flags); 418 s = spltty(); 419 420 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) { 421 stty_modem_control(sp, 0, DMSET); 422 STC_WRITE(csc, STC_CAR, port); 423 STC_WRITE(csc, STC_CCR, 424 CD180_CCR_CMD_RESET|CD180_CCR_RESETCHAN); 425 } 426 427 splx(s); 428 ttyclose(tp); 429 return (0); 430 } 431 432 int 433 stty_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 434 { 435 struct stty_softc *stc = device_lookup_private(&stty_cd, 436 SPIF_CARD(dev)); 437 struct stty_port *sp = &stc->sc_port[SPIF_PORT(dev)]; 438 struct spif_softc *sc = sp->sp_sc; 439 struct tty *tp = sp->sp_tty; 440 int error; 441 442 error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flags, l); 443 if (error >= 0) 444 return (error); 445 446 error = ttioctl(tp, cmd, data, flags, l); 447 if (error >= 0) 448 return (error); 449 450 error = 0; 451 452 switch (cmd) { 453 case TIOCSBRK: 454 SET(sp->sp_flags, STTYF_SET_BREAK); 455 STC_WRITE(sc, STC_CAR, sp->sp_channel); 456 STC_WRITE(sc, STC_SRER, 457 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 458 break; 459 case TIOCCBRK: 460 SET(sp->sp_flags, STTYF_CLR_BREAK); 461 STC_WRITE(sc, STC_CAR, sp->sp_channel); 462 STC_WRITE(sc, STC_SRER, 463 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 464 break; 465 case TIOCSDTR: 466 stty_modem_control(sp, TIOCM_DTR, DMBIS); 467 break; 468 case TIOCCDTR: 469 stty_modem_control(sp, TIOCM_DTR, DMBIC); 470 break; 471 case TIOCMBIS: 472 stty_modem_control(sp, *((int *)data), DMBIS); 473 break; 474 case TIOCMBIC: 475 stty_modem_control(sp, *((int *)data), DMBIC); 476 break; 477 case TIOCMGET: 478 *((int *)data) = stty_modem_control(sp, 0, DMGET); 479 break; 480 case TIOCMSET: 481 stty_modem_control(sp, *((int *)data), DMSET); 482 break; 483 case TIOCGFLAGS: 484 *((int *)data) = sp->sp_openflags; 485 break; 486 case TIOCSFLAGS: 487 if (kauth_authorize_device_tty(l->l_cred, 488 KAUTH_DEVICE_TTY_PRIVSET, tp)) 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 = device_lookup_private(&stty_cd, 560 SPIF_CARD(tp->t_dev)); 561 struct stty_port *sp = &st->sc_port[SPIF_PORT(tp->t_dev)]; 562 struct spif_softc *sc = sp->sp_sc; 563 uint8_t rbprl = 0, rbprh = 0, tbprl = 0, tbprh = 0; 564 int s, opt; 565 566 if (t->c_ospeed && 567 stty_compute_baud(t->c_ospeed, sc->sc_osc, &tbprl, &tbprh)) 568 return (EINVAL); 569 570 if (t->c_ispeed && 571 stty_compute_baud(t->c_ispeed, sc->sc_osc, &rbprl, &rbprh)) 572 return (EINVAL); 573 574 s = spltty(); 575 576 /* hang up line if ospeed is zero, otherwise raise DTR */ 577 stty_modem_control(sp, TIOCM_DTR, 578 (t->c_ospeed == 0 ? DMBIC : DMBIS)); 579 580 STC_WRITE(sc, STC_CAR, sp->sp_channel); 581 582 opt = 0; 583 if (ISSET(t->c_cflag, PARENB)) { 584 opt |= CD180_COR1_PARMODE_NORMAL; 585 opt |= (ISSET(t->c_cflag, PARODD) ? 586 CD180_COR1_ODDPAR : 587 CD180_COR1_EVENPAR); 588 } 589 else 590 opt |= CD180_COR1_PARMODE_NO; 591 592 if (!ISSET(t->c_iflag, INPCK)) 593 opt |= CD180_COR1_IGNPAR; 594 595 if (ISSET(t->c_cflag, CSTOPB)) 596 opt |= CD180_COR1_STOP2; 597 598 switch (t->c_cflag & CSIZE) { 599 case CS5: 600 opt |= CD180_COR1_CS5; 601 break; 602 case CS6: 603 opt |= CD180_COR1_CS6; 604 break; 605 case CS7: 606 opt |= CD180_COR1_CS7; 607 break; 608 default: 609 opt |= CD180_COR1_CS8; 610 break; 611 } 612 STC_WRITE(sc, STC_COR1, opt); 613 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG1); 614 615 opt = CD180_COR2_ETC; 616 if (ISSET(t->c_cflag, CRTSCTS)) 617 opt |= CD180_COR2_CTSAE; 618 STC_WRITE(sc, STC_COR2, opt); 619 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG2); 620 621 STC_WRITE(sc, STC_COR3, STTY_RX_FIFO_THRESHOLD); 622 stty_write_ccr(sc, CD180_CCR_CMD_COR|CD180_CCR_CORCHG3); 623 624 STC_WRITE(sc, STC_SCHR1, 0x11); 625 STC_WRITE(sc, STC_SCHR2, 0x13); 626 STC_WRITE(sc, STC_SCHR3, 0x11); 627 STC_WRITE(sc, STC_SCHR4, 0x13); 628 STC_WRITE(sc, STC_RTPR, 0x12); 629 630 STC_WRITE(sc, STC_MCOR1, CD180_MCOR1_CDZD | STTY_RX_DTR_THRESHOLD); 631 STC_WRITE(sc, STC_MCOR2, CD180_MCOR2_CDOD); 632 STC_WRITE(sc, STC_MCR, 0); 633 634 if (t->c_ospeed) { 635 STC_WRITE(sc, STC_TBPRH, tbprh); 636 STC_WRITE(sc, STC_TBPRL, tbprl); 637 } 638 639 if (t->c_ispeed) { 640 STC_WRITE(sc, STC_RBPRH, rbprh); 641 STC_WRITE(sc, STC_RBPRL, rbprl); 642 } 643 644 stty_write_ccr(sc, CD180_CCR_CMD_CHAN | 645 CD180_CCR_CHAN_TXEN | CD180_CCR_CHAN_RXEN); 646 647 sp->sp_carrier = STC_READ(sc, STC_MSVR) & CD180_MSVR_CD; 648 649 splx(s); 650 return (0); 651 } 652 653 int 654 stty_read(dev_t dev, struct uio *uio, int flags) 655 { 656 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 657 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 658 struct tty *tp = sp->sp_tty; 659 660 return ((*tp->t_linesw->l_read)(tp, uio, flags)); 661 } 662 663 int 664 stty_write(dev_t dev, struct uio *uio, int flags) 665 { 666 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 667 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 668 struct tty *tp = sp->sp_tty; 669 670 return ((*tp->t_linesw->l_write)(tp, uio, flags)); 671 } 672 673 int 674 stty_poll(dev_t dev, int events, struct lwp *l) 675 { 676 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 677 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 678 struct tty *tp = sp->sp_tty; 679 680 return ((*tp->t_linesw->l_poll)(tp, events, l)); 681 } 682 683 struct tty * 684 stty_tty(dev_t dev) 685 { 686 struct stty_softc *sc = device_lookup_private(&stty_cd, SPIF_CARD(dev)); 687 struct stty_port *sp = &sc->sc_port[SPIF_PORT(dev)]; 688 689 return (sp->sp_tty); 690 } 691 692 void 693 stty_stop(struct tty *tp, int flags) 694 { 695 struct stty_softc *sc = device_lookup_private(&stty_cd, 696 SPIF_CARD(tp->t_dev)); 697 struct stty_port *sp = &sc->sc_port[SPIF_PORT(tp->t_dev)]; 698 int s; 699 700 s = spltty(); 701 if (ISSET(tp->t_state, TS_BUSY)) { 702 if (!ISSET(tp->t_state, TS_TTSTOP)) 703 SET(tp->t_state, TS_FLUSH); 704 SET(sp->sp_flags, STTYF_STOP); 705 } 706 splx(s); 707 } 708 709 void 710 stty_start(struct tty *tp) 711 { 712 struct stty_softc *stc = device_lookup_private(&stty_cd, 713 SPIF_CARD(tp->t_dev)); 714 struct stty_port *sp = &stc->sc_port[SPIF_PORT(tp->t_dev)]; 715 struct spif_softc *sc = sp->sp_sc; 716 int s; 717 718 s = spltty(); 719 720 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 721 if (ttypull(tp)) { 722 sp->sp_txc = ndqb(&tp->t_outq, 0); 723 sp->sp_txp = tp->t_outq.c_cf; 724 SET(tp->t_state, TS_BUSY); 725 STC_WRITE(sc, STC_CAR, sp->sp_channel); 726 STC_WRITE(sc, STC_SRER, 727 STC_READ(sc, STC_SRER) | CD180_SRER_TXD); 728 } 729 } 730 731 splx(s); 732 } 733 734 int 735 spif_stcintr_rxexception(struct spif_softc *sc, int *needsoftp) 736 { 737 struct stty_port *sp; 738 uint8_t channel, *ptr; 739 740 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 741 sp = &sc->sc_ttys->sc_port[channel]; 742 ptr = sp->sp_rput; 743 *ptr++ = STC_READ(sc, STC_RCSR); 744 *ptr++ = STC_READ(sc, STC_RDR); 745 if (ptr == sp->sp_rend) 746 ptr = sp->sp_rbuf; 747 if (ptr == sp->sp_rget) { 748 if (ptr == sp->sp_rbuf) 749 ptr = sp->sp_rend; 750 ptr -= 2; 751 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 752 } 753 STC_WRITE(sc, STC_EOSRR, 0); 754 *needsoftp = 1; 755 sp->sp_rput = ptr; 756 return (1); 757 } 758 759 int 760 spif_stcintr_rx(struct spif_softc *sc, int *needsoftp) 761 { 762 struct stty_port *sp; 763 uint8_t channel, *ptr, cnt; 764 int i; 765 766 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 767 sp = &sc->sc_ttys->sc_port[channel]; 768 ptr = sp->sp_rput; 769 cnt = STC_READ(sc, STC_RDCR); 770 for (i = 0; i < cnt; i++) { 771 *ptr++ = 0; 772 (void)STC_READ(sc, STC_RCSR); 773 *ptr++ = STC_READ(sc, STC_RDR); 774 if (ptr == sp->sp_rend) 775 ptr = sp->sp_rbuf; 776 if (ptr == sp->sp_rget) { 777 if (ptr == sp->sp_rbuf) 778 ptr = sp->sp_rend; 779 ptr -= 2; 780 SET(sp->sp_flags, STTYF_RING_OVERFLOW); 781 break; 782 } 783 } 784 STC_WRITE(sc, STC_EOSRR, 0); 785 if (cnt) { 786 *needsoftp = 1; 787 sp->sp_rput = ptr; 788 } 789 return (1); 790 } 791 792 int 793 spif_stcintr_tx(struct spif_softc *sc, int *needsoftp) 794 { 795 struct stty_port *sp; 796 uint8_t channel, ch; 797 int cnt = 0; 798 799 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 800 sp = &sc->sc_ttys->sc_port[channel]; 801 if (!ISSET(sp->sp_flags, STTYF_STOP)) { 802 if (ISSET(sp->sp_flags, STTYF_SET_BREAK)) { 803 STC_WRITE(sc, STC_TDR, 0); 804 STC_WRITE(sc, STC_TDR, 0x81); 805 CLR(sp->sp_flags, STTYF_SET_BREAK); 806 cnt += 2; 807 } 808 if (ISSET(sp->sp_flags, STTYF_CLR_BREAK)) { 809 STC_WRITE(sc, STC_TDR, 0); 810 STC_WRITE(sc, STC_TDR, 0x83); 811 CLR(sp->sp_flags, STTYF_CLR_BREAK); 812 cnt += 2; 813 } 814 815 while (sp->sp_txc > 0 && cnt < (CD180_TX_FIFO_SIZE-1)) { 816 ch = *sp->sp_txp; 817 sp->sp_txc--; 818 sp->sp_txp++; 819 820 if (ch == 0) { 821 STC_WRITE(sc, STC_TDR, ch); 822 cnt++; 823 } 824 STC_WRITE(sc, STC_TDR, ch); 825 cnt++; 826 } 827 } 828 829 if (sp->sp_txc == 0 || 830 ISSET(sp->sp_flags, STTYF_STOP)) { 831 STC_WRITE(sc, STC_SRER, STC_READ(sc, STC_SRER) & 832 (~CD180_SRER_TXD)); 833 CLR(sp->sp_flags, STTYF_STOP); 834 SET(sp->sp_flags, STTYF_DONE); 835 *needsoftp = 1; 836 } 837 838 STC_WRITE(sc, STC_EOSRR, 0); 839 840 return (1); 841 } 842 843 int 844 spif_stcintr_mx(struct spif_softc *sc, int *needsoftp) 845 { 846 struct stty_port *sp; 847 uint8_t channel, mcr; 848 849 channel = CD180_GSCR_CHANNEL(STC_READ(sc, STC_GSCR1)); 850 sp = &sc->sc_ttys->sc_port[channel]; 851 mcr = STC_READ(sc, STC_MCR); 852 if (mcr & CD180_MCR_CD) { 853 SET(sp->sp_flags, STTYF_CDCHG); 854 *needsoftp = 1; 855 } 856 STC_WRITE(sc, STC_MCR, 0); 857 STC_WRITE(sc, STC_EOSRR, 0); 858 return (1); 859 } 860 861 int 862 spif_stcintr(void *vsc) 863 { 864 struct spif_softc *sc = (struct spif_softc *)vsc; 865 int needsoft = 0, r = 0, i; 866 uint8_t ar; 867 868 for (i = 0; i < 8; i++) { 869 ar = ISTC_READ(sc, STC_RRAR) & CD180_GSVR_IMASK; 870 if (ar == CD180_GSVR_RXGOOD) 871 r |= spif_stcintr_rx(sc, &needsoft); 872 else if (ar == CD180_GSVR_RXEXCEPTION) 873 r |= spif_stcintr_rxexception(sc, &needsoft); 874 } 875 876 for (i = 0; i < 8; i++) { 877 ar = ISTC_READ(sc, STC_TRAR) & CD180_GSVR_IMASK; 878 if (ar == CD180_GSVR_TXDATA) 879 r |= spif_stcintr_tx(sc, &needsoft); 880 } 881 882 for (i = 0; i < 8; i++) { 883 ar = ISTC_READ(sc, STC_MRAR) & CD180_GSVR_IMASK; 884 if (ar == CD180_GSVR_STATCHG) 885 r |= spif_stcintr_mx(sc, &needsoft); 886 } 887 888 if (needsoft) 889 softint_schedule(sc->sc_softih); 890 return (r); 891 } 892 893 void 894 spif_softintr(void *vsc) 895 { 896 struct spif_softc *sc = (struct spif_softc *)vsc; 897 struct stty_softc *stc = sc->sc_ttys; 898 int i, data, s, flags; 899 uint8_t stat, msvr; 900 struct stty_port *sp; 901 struct tty *tp; 902 903 if (stc != NULL) { 904 for (i = 0; i < stc->sc_nports; i++) { 905 sp = &stc->sc_port[i]; 906 tp = sp->sp_tty; 907 908 if (!ISSET(tp->t_state, TS_ISOPEN)) 909 continue; 910 911 while (sp->sp_rget != sp->sp_rput) { 912 stat = sp->sp_rget[0]; 913 data = sp->sp_rget[1]; 914 sp->sp_rget += 2; 915 if (sp->sp_rget == sp->sp_rend) 916 sp->sp_rget = sp->sp_rbuf; 917 918 if (stat & (CD180_RCSR_BE | CD180_RCSR_FE)) 919 data |= TTY_FE; 920 921 if (stat & CD180_RCSR_PE) 922 data |= TTY_PE; 923 924 (*tp->t_linesw->l_rint)(data, tp); 925 } 926 927 s = splhigh(); 928 flags = sp->sp_flags; 929 CLR(sp->sp_flags, STTYF_DONE | STTYF_CDCHG | 930 STTYF_RING_OVERFLOW); 931 splx(s); 932 933 if (ISSET(flags, STTYF_CDCHG)) { 934 s = spltty(); 935 STC_WRITE(sc, STC_CAR, i); 936 msvr = STC_READ(sc, STC_MSVR); 937 splx(s); 938 939 sp->sp_carrier = msvr & CD180_MSVR_CD; 940 (*tp->t_linesw->l_modem)(tp, 941 sp->sp_carrier); 942 } 943 944 if (ISSET(flags, STTYF_RING_OVERFLOW)) { 945 log(LOG_WARNING, "%s-%x: ring overflow\n", 946 device_xname(stc->sc_dev), i); 947 } 948 949 if (ISSET(flags, STTYF_DONE)) { 950 ndflush(&tp->t_outq, 951 sp->sp_txp - tp->t_outq.c_cf); 952 CLR(tp->t_state, TS_BUSY); 953 (*tp->t_linesw->l_start)(tp); 954 } 955 } 956 } 957 } 958 959 void 960 stty_write_ccr(struct spif_softc *sc, uint8_t val) 961 { 962 int tries = 100000; 963 964 while (STC_READ(sc, STC_CCR) && tries--) 965 /*EMPTY*/; 966 if (tries == 0) 967 aprint_error_dev(sc->sc_dev, "ccr timeout\n"); 968 STC_WRITE(sc, STC_CCR, val); 969 } 970 971 int 972 stty_compute_baud(speed_t speed, int clock, uint8_t *bprlp, uint8_t *bprhp) 973 { 974 uint32_t rate; 975 976 rate = (2 * clock) / (16 * speed); 977 if (rate & 1) 978 rate = (rate >> 1) + 1; 979 else 980 rate = rate >> 1; 981 982 if (rate > 0xffff || rate == 0) 983 return (1); 984 985 *bprlp = rate & 0xff; 986 *bprhp = (rate >> 8) & 0xff; 987 return (0); 988 } 989 990 int 991 sbpp_match(device_t parent, cfdata_t vcf, void *aux) 992 { 993 struct spif_softc *sc = device_private(parent); 994 995 return (aux == sbpp_match && sc->sc_bpps == NULL); 996 } 997 998 void 999 sbpp_attach(device_t parent, device_t dev, void *aux) 1000 { 1001 struct spif_softc *sc = device_private(parent); 1002 struct sbpp_softc *psc = device_private(dev); 1003 int port; 1004 1005 sc->sc_bpps = psc; 1006 1007 for (port = 0; port < sc->sc_npar; port++) { 1008 } 1009 1010 psc->sc_nports = port; 1011 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1012 } 1013 1014 int 1015 sbpp_open(dev_t dev, int flags, int mode, struct lwp *l) 1016 { 1017 return (ENXIO); 1018 } 1019 1020 int 1021 sbpp_close(dev_t dev, int flags, int mode, struct lwp *l) 1022 { 1023 return (ENXIO); 1024 } 1025 1026 int 1027 spif_ppcintr(void *v) 1028 { 1029 return (0); 1030 } 1031 1032 int 1033 sbpp_read(dev_t dev, struct uio *uio, int flags) 1034 { 1035 return (sbpp_rw(dev, uio)); 1036 } 1037 1038 int 1039 sbpp_write(dev_t dev, struct uio *uio, int flags) 1040 { 1041 return (sbpp_rw(dev, uio)); 1042 } 1043 1044 int 1045 sbpp_rw(dev_t dev, struct uio *uio) 1046 { 1047 return (ENXIO); 1048 } 1049 1050 int 1051 sbpp_poll(dev_t dev, int events, struct lwp *l) 1052 { 1053 return (seltrue(dev, events, l)); 1054 } 1055 1056 int 1057 sbpp_ioctl(dev_t dev, u_long cmd, void *data, int flags, struct lwp *l) 1058 { 1059 int error; 1060 1061 error = ENOTTY; 1062 1063 return (error); 1064 } 1065 1066 #endif /* NSPIF */ 1067