1 /* $OpenBSD: magma.c,v 1.32 2020/05/23 09:44:20 mpi Exp $ */ 2 3 /*- 4 * Copyright (c) 1998 Iain Hibbert 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 WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 /* #define MAGMA_DEBUG */ 29 30 /* 31 * Driver for Magma SBus Serial/Parallel cards using the Cirrus Logic 32 * CD1400 & CD1190 chips 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/proc.h> 38 #include <sys/device.h> 39 #include <sys/fcntl.h> 40 #include <sys/ioctl.h> 41 #include <sys/malloc.h> 42 #include <sys/tty.h> 43 #include <sys/time.h> 44 #include <sys/kernel.h> 45 #include <sys/syslog.h> 46 #include <sys/conf.h> 47 #include <sys/errno.h> 48 49 #include <machine/autoconf.h> 50 #include <machine/conf.h> 51 #include <machine/bus.h> 52 #include <machine/bppioctl.h> 53 54 #include <dev/sbus/sbusvar.h> 55 #include <dev/ic/cd1400reg.h> 56 #include <dev/ic/cd1190reg.h> 57 58 #include <dev/sbus/magmareg.h> 59 60 /* supported cards 61 * 62 * The table below lists the cards that this driver is likely to 63 * be able to support. 64 * 65 * Cards with parallel ports: except for the LC2+1Sp, they all use 66 * the CD1190 chip which I know nothing about. I've tried to leave 67 * hooks for it so it shouldn't be too hard to add support later. 68 * (I think somebody is working on this separately) 69 * 70 * Thanks to Bruce at Magma for telling me the hardware offsets. 71 */ 72 static const struct magma_board_info supported_cards[] = { 73 { 74 "MAGMA_Sp", "MAGMA,4_Sp", "Magma 4 Sp", 4, 0, 75 1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 }, 76 0, { 0, 0 } 77 }, 78 { 79 "MAGMA_Sp", "MAGMA,8_Sp", "Magma 8 Sp", 8, 0, 80 2, 0xa000, 0xc000, 0xe000, { 0x4000, 0x6000, 0, 0 }, 81 0, { 0, 0 } 82 }, 83 { 84 "MAGMA_Sp", "MAGMA,_8HS_Sp", "Magma Fast 8 Sp", 8, 0, 85 2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 }, 86 0, { 0, 0 } 87 }, 88 { 89 "MAGMA_Sp", "MAGMA,_8SP_422", "Magma 8 Sp - 422", 8, 0, 90 2, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0, 0 }, 91 0, { 0, 0 } 92 }, 93 { 94 "MAGMA_Sp", "MAGMA,12_Sp", "Magma 12 Sp", 12, 0, 95 3, 0xa000, 0xc000, 0xe000, { 0x2000, 0x4000, 0x6000, 0 }, 96 0, { 0, 0 } 97 }, 98 { 99 "MAGMA_Sp", "MAGMA,16_Sp", "Magma 16 Sp", 16, 0, 100 4, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0xa000, 0xb000 }, 101 0, { 0, 0 } 102 }, 103 { 104 "MAGMA_Sp", "MAGMA,16_Sp_2", "Magma 16 Sp", 16, 0, 105 4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 }, 106 0, { 0, 0 } 107 }, 108 { 109 "MAGMA_Sp", "MAGMA,16HS_Sp", "Magma Fast 16 Sp", 16, 0, 110 4, 0x2000, 0x4000, 0x6000, { 0x8000, 0xa000, 0xc000, 0xe000 }, 111 0, { 0, 0 } 112 }, 113 { 114 "MAGMA_Sp", "MAGMA,21_Sp", "Magma LC 2+1 Sp", 2, 1, 115 1, 0xa000, 0xc000, 0xe000, { 0x8000, 0, 0, 0 }, 116 0, { 0, 0 } 117 }, 118 { 119 "MAGMA_Sp", "MAGMA,21HS_Sp", "Magma 2+1 Sp", 2, 1, 120 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 }, 121 1, { 0x6000, 0 } 122 }, 123 { 124 "MAGMA_Sp", "MAGMA,41_Sp", "Magma 4+1 Sp", 4, 1, 125 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 }, 126 1, { 0x6000, 0 } 127 }, 128 { 129 "MAGMA_Sp", "MAGMA,82_Sp", "Magma 8+2 Sp", 8, 2, 130 2, 0xd000, 0xe000, 0xf000, { 0x8000, 0x9000, 0, 0 }, 131 2, { 0xa000, 0xb000 } 132 }, 133 { 134 "MAGMA_Sp", "MAGMA,P1_Sp", "Magma P1 Sp", 0, 1, 135 0, 0, 0, 0, { 0, 0, 0, 0 }, 136 1, { 0x8000, 0 } 137 }, 138 { 139 "MAGMA_Sp", "MAGMA,P2_Sp", "Magma P2 Sp", 0, 2, 140 0, 0, 0, 0, { 0, 0, 0, 0 }, 141 2, { 0x4000, 0x8000 } 142 }, 143 { 144 "MAGMA 2+1HS Sp", "", "Magma 2+1HS Sp", 2, 0, 145 1, 0xa000, 0xc000, 0xe000, { 0x4000, 0, 0, 0 }, 146 1, { 0x8000, 0 } 147 }, 148 { 149 NULL, NULL, NULL, 0, 0, 150 0, 0, 0, 0, { 0, 0, 0, 0 }, 151 0, { 0, 0 } 152 } 153 }; 154 155 /************************************************************************ 156 * 157 * Autoconfig Stuff 158 */ 159 160 struct cfattach magma_ca = { 161 sizeof(struct magma_softc), magma_match, magma_attach 162 }; 163 164 struct cfdriver magma_cd = { 165 NULL, "magma", DV_DULL 166 }; 167 168 struct cfattach mtty_ca = { 169 sizeof(struct mtty_softc), mtty_match, mtty_attach 170 }; 171 172 struct cfdriver mtty_cd = { 173 NULL, "mtty", DV_TTY 174 }; 175 176 struct cfattach mbpp_ca = { 177 sizeof(struct mbpp_softc), mbpp_match, mbpp_attach 178 }; 179 180 struct cfdriver mbpp_cd = { 181 NULL, "mbpp", DV_DULL 182 }; 183 184 /************************************************************************ 185 * 186 * CD1400 Routines 187 * 188 * cd1400_compute_baud calculate COR/BPR register values 189 * cd1400_write_ccr write a value to CD1400 ccr 190 * cd1400_read_reg read from a CD1400 register 191 * cd1400_write_reg write to a CD1400 register 192 * cd1400_enable_transmitter enable transmitting on CD1400 channel 193 */ 194 195 /* 196 * compute the bpr/cor pair for any baud rate 197 * returns 0 for success, 1 for failure 198 */ 199 int 200 cd1400_compute_baud(speed_t speed, int clock, int *cor, int *bpr) 201 { 202 int c, co, br; 203 204 if (speed < 50 || speed > 150000) 205 return (1); 206 207 for (c = 0, co = 8 ; co <= 2048 ; co <<= 2, c++) { 208 br = ((clock * 1000000) + (co * speed) / 2) / (co * speed); 209 if (br < 0x100) { 210 *bpr = br; 211 *cor = c; 212 return (0); 213 } 214 } 215 216 return (1); 217 } 218 219 #define CD1400_READ_REG(cd,reg) \ 220 bus_space_read_1((cd)->cd_regt, (cd)->cd_regh, (reg)) 221 #define CD1400_WRITE_REG(cd,reg,value) \ 222 bus_space_write_1((cd)->cd_regt, (cd)->cd_regh, (reg), (value)) 223 224 /* 225 * Write a CD1400 channel command, should have a timeout? 226 */ 227 __inline void 228 cd1400_write_ccr(struct cd1400 *cd, u_char cmd) 229 { 230 while (CD1400_READ_REG(cd, CD1400_CCR)) 231 /*EMPTY*/; 232 233 CD1400_WRITE_REG(cd, CD1400_CCR, cmd); 234 } 235 236 /* 237 * enable transmit service requests for cd1400 channel 238 */ 239 void 240 cd1400_enable_transmitter(struct cd1400 *cd, int channel) 241 { 242 int s, srer; 243 244 s = spltty(); 245 CD1400_WRITE_REG(cd, CD1400_CAR, channel); 246 srer = CD1400_READ_REG(cd, CD1400_SRER); 247 SET(srer, CD1400_SRER_TXRDY); 248 CD1400_WRITE_REG(cd, CD1400_SRER, srer); 249 splx(s); 250 } 251 252 /************************************************************************ 253 * 254 * CD1190 Routines 255 */ 256 257 /* well, there are none yet */ 258 259 /************************************************************************ 260 * 261 * Magma Routines 262 * 263 * magma_match reports if we have a magma board available 264 * magma_attach attaches magma boards to the sbus 265 * magma_hard hardware level interrupt routine 266 * magma_soft software level interrupt routine 267 */ 268 269 int 270 magma_match(struct device *parent, void *vcf, void *aux) 271 { 272 struct sbus_attach_args *sa = aux; 273 const struct magma_board_info *card; 274 275 /* See if we support this device */ 276 for (card = supported_cards; ; card++) { 277 if (card->mb_sbusname == NULL) 278 /* End of table: no match */ 279 return (0); 280 if (strcmp(sa->sa_name, card->mb_sbusname) == 0) 281 break; 282 } 283 return (1); 284 } 285 286 void 287 magma_attach(struct device *parent, struct device *dev, void *aux) 288 { 289 struct sbus_attach_args *sa = aux; 290 struct magma_softc *sc = (struct magma_softc *)dev; 291 const struct magma_board_info *card; 292 char magma_prom[40], *clockstr; 293 int chip, cd_clock; 294 295 getpropstringA(sa->sa_node, "magma_prom", magma_prom); 296 for (card = supported_cards; card->mb_name != NULL; card++) { 297 if (strcmp(sa->sa_name, card->mb_sbusname) != 0) 298 continue; 299 if (strcmp(magma_prom, card->mb_name) == 0) 300 break; 301 } 302 if (card->mb_name == NULL) { 303 printf(": %s (unsupported)\n", magma_prom); 304 return; 305 } 306 307 sc->sc_bustag = sa->sa_bustag; 308 309 clockstr = getpropstring(sa->sa_node, "clock"); 310 if (strlen(clockstr) == 0) 311 cd_clock = 25; 312 else { 313 cd_clock = 0; 314 while (*clockstr != '\0') 315 cd_clock = cd_clock * 10 + *clockstr++ - '0'; 316 } 317 318 if (sbus_bus_map(sa->sa_bustag, sa->sa_reg[0].sbr_slot, 319 sa->sa_reg[0].sbr_offset, sa->sa_reg[0].sbr_size, 320 0, 0, &sc->sc_iohandle) != 0) { 321 printf(": can't map registers\n"); 322 return; 323 } 324 325 if (sa->sa_nintr < 1) { 326 printf(": can't find interrupt\n"); 327 return; 328 } 329 sc->sc_ih = bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_TTY, 0, 330 magma_hard, sc, dev->dv_xname); 331 if (sc->sc_ih == NULL) { 332 printf(": couldn't establish interrupt, pri %d\n", 333 INTLEV(sa->sa_pri)); 334 bus_space_unmap(sc->sc_bustag, sc->sc_iohandle, 335 sa->sa_reg[0].sbr_size); 336 return; 337 } 338 339 sc->sc_sih = softintr_establish(IPL_TTY, magma_soft, sc); 340 if (sc->sc_sih == NULL) { 341 printf(": can't get soft intr\n"); 342 bus_space_unmap(sc->sc_bustag, sc->sc_iohandle, 343 sa->sa_reg[0].sbr_size); 344 return; 345 } 346 347 printf(": %s\n", card->mb_realname); 348 349 sc->ms_board = card; 350 sc->ms_ncd1400 = card->mb_ncd1400; 351 sc->ms_ncd1190 = card->mb_ncd1190; 352 353 /* the SVCACK* lines are daisychained */ 354 if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle, 355 card->mb_svcackr, 1, &sc->sc_svcackrh)) { 356 printf(": failed to map svcackr\n"); 357 return; 358 } 359 if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle, 360 card->mb_svcackt, 1, &sc->sc_svcackth)) { 361 printf(": failed to map svcackt\n"); 362 return; 363 } 364 if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle, 365 card->mb_svcackm, 1, &sc->sc_svcackmh)) { 366 printf(": failed to map svcackm\n"); 367 return; 368 } 369 370 /* init the cd1400 chips */ 371 for (chip = 0 ; chip < card->mb_ncd1400 ; chip++) { 372 struct cd1400 *cd = &sc->ms_cd1400[chip]; 373 374 cd->cd_clock = cd_clock; 375 376 if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle, 377 card->mb_cd1400[chip], CD1400_REGMAPSIZE, &cd->cd_regh)) { 378 printf(": failed to map cd1400 regs\n"); 379 return; 380 } 381 cd->cd_regt = sc->sc_bustag; 382 383 /* getpropstring(sa->sa_node, "chiprev"); */ 384 /* seemingly the Magma drivers just ignore the propstring */ 385 cd->cd_chiprev = CD1400_READ_REG(cd, CD1400_GFRCR); 386 387 dprintf(("%s attach CD1400 %d addr 0x%x rev %x clock %dMHz\n", 388 sc->ms_dev.dv_xname, chip, cd->cd_reg, 389 cd->cd_chiprev, cd->cd_clock)); 390 391 /* clear GFRCR */ 392 CD1400_WRITE_REG(cd, CD1400_GFRCR, 0x00); 393 394 /* reset whole chip */ 395 cd1400_write_ccr(cd, 396 CD1400_CCR_CMDRESET | CD1400_CCR_FULLRESET); 397 398 /* wait for revision code to be restored */ 399 while (CD1400_READ_REG(cd, CD1400_GFRCR) != cd->cd_chiprev) 400 ; 401 402 /* set the Prescaler Period Register to tick at 1ms */ 403 CD1400_WRITE_REG(cd, CD1400_PPR, 404 ((cd->cd_clock * 1000000 / CD1400_PPR_PRESCALER + 500) 405 / 1000)); 406 407 /* 408 * The LC2+1Sp card is the only card that doesn't have a 409 * CD1190 for the parallel port, but uses channel 0 of the 410 * CD1400, so we make a note of it for later and set up the 411 * CD1400 for parallel mode operation. 412 */ 413 if (card->mb_npar && card->mb_ncd1190 == 0) { 414 CD1400_WRITE_REG(cd, CD1400_GCR, CD1400_GCR_PARALLEL); 415 cd->cd_parmode = 1; 416 } 417 } 418 419 /* init the cd1190 chips */ 420 for (chip = 0 ; chip < card->mb_ncd1190 ; chip++) { 421 struct cd1190 *cd = &sc->ms_cd1190[chip]; 422 423 if (bus_space_subregion(sc->sc_bustag, sc->sc_iohandle, 424 card->mb_cd1190[chip], CD1190_REGMAPSIZE, &cd->cd_regh)) { 425 printf(": failed to map cd1190 regs\n"); 426 return; 427 } 428 cd->cd_regt = sc->sc_bustag; 429 dprintf(("%s attach CD1190 %d addr 0x%x (failed)\n", 430 sc->ms_dev.dv_xname, chip, cd->cd_reg)); 431 /* XXX don't know anything about these chips yet */ 432 } 433 434 /* configure the children */ 435 (void)config_found(dev, mtty_match, NULL); 436 (void)config_found(dev, mbpp_match, NULL); 437 } 438 439 /* 440 * hard interrupt routine 441 * 442 * returns 1 if it handled it, otherwise 0 443 * 444 * runs at interrupt priority 445 */ 446 int 447 magma_hard(void *arg) 448 { 449 struct magma_softc *sc = arg; 450 struct cd1400 *cd; 451 int chip, status = 0; 452 int serviced = 0; 453 int needsoftint = 0; 454 455 /* 456 * check status of all the CD1400 chips 457 */ 458 for (chip = 0 ; chip < sc->ms_ncd1400 ; chip++) 459 status |= CD1400_READ_REG(&sc->ms_cd1400[chip], CD1400_SVRR); 460 461 if (ISSET(status, CD1400_SVRR_RXRDY)) { 462 /* enter rx service context */ 463 u_int8_t rivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackrh, 0); 464 int port = rivr >> 4; 465 466 if (rivr & (1<<3)) { /* parallel port */ 467 struct mbpp_port *mbpp; 468 int n_chars; 469 470 mbpp = &sc->ms_mbpp->ms_port[port]; 471 cd = mbpp->mp_cd1400; 472 473 /* don't think we have to handle exceptions */ 474 n_chars = CD1400_READ_REG(cd, CD1400_RDCR); 475 while (n_chars--) { 476 if (mbpp->mp_cnt == 0) { 477 SET(mbpp->mp_flags, MBPPF_WAKEUP); 478 needsoftint = 1; 479 break; 480 } 481 *mbpp->mp_ptr = CD1400_READ_REG(cd, CD1400_RDSR); 482 mbpp->mp_ptr++; 483 mbpp->mp_cnt--; 484 } 485 } else { /* serial port */ 486 struct mtty_port *mtty; 487 u_char *ptr, n_chars, line_stat; 488 489 mtty = &sc->ms_mtty->ms_port[port]; 490 cd = mtty->mp_cd1400; 491 492 if (ISSET(rivr, CD1400_RIVR_EXCEPTION)) { 493 line_stat = CD1400_READ_REG(cd, CD1400_RDSR); 494 n_chars = 1; 495 } else { /* no exception, received data OK */ 496 line_stat = 0; 497 n_chars = CD1400_READ_REG(cd, CD1400_RDCR); 498 } 499 500 ptr = mtty->mp_rput; 501 while (n_chars--) { 502 *ptr++ = line_stat; 503 *ptr++ = CD1400_READ_REG(cd, CD1400_RDSR); 504 if (ptr == mtty->mp_rend) 505 ptr = mtty->mp_rbuf; 506 if (ptr == mtty->mp_rget) { 507 if (ptr == mtty->mp_rbuf) 508 ptr = mtty->mp_rend; 509 ptr -= 2; 510 SET(mtty->mp_flags, 511 MTTYF_RING_OVERFLOW); 512 break; 513 } 514 } 515 mtty->mp_rput = ptr; 516 517 needsoftint = 1; 518 } 519 520 CD1400_WRITE_REG(cd, CD1400_EOSRR, 0); /* end service context */ 521 serviced = 1; 522 } /* if(rx_service...) */ 523 524 if (ISSET(status, CD1400_SVRR_MDMCH)) { 525 u_int8_t mivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackmh, 0); 526 int port = mivr >> 4; 527 struct mtty_port *mtty; 528 int carrier; 529 u_char msvr; 530 531 /* 532 * Handle CD (LC2+1Sp = DSR) changes. 533 */ 534 mtty = &sc->ms_mtty->ms_port[port]; 535 cd = mtty->mp_cd1400; 536 msvr = CD1400_READ_REG(cd, CD1400_MSVR2); 537 carrier = ISSET(msvr, cd->cd_parmode ? CD1400_MSVR2_DSR : CD1400_MSVR2_CD); 538 539 if (mtty->mp_carrier != carrier) { 540 SET(mtty->mp_flags, MTTYF_CARRIER_CHANGED); 541 mtty->mp_carrier = carrier; 542 needsoftint = 1; 543 } 544 545 CD1400_WRITE_REG(cd, CD1400_EOSRR, 0); /* end service context */ 546 serviced = 1; 547 } /* if(mdm_service...) */ 548 549 if (ISSET(status, CD1400_SVRR_TXRDY)) { 550 /* enter tx service context */ 551 u_int8_t tivr = bus_space_read_1(sc->sc_bustag, sc->sc_svcackth, 0); 552 int port = tivr >> 4; 553 554 if (tivr & (1<<3)) { /* parallel port */ 555 struct mbpp_port *mbpp; 556 557 mbpp = &sc->ms_mbpp->ms_port[port]; 558 cd = mbpp->mp_cd1400; 559 560 if (mbpp->mp_cnt) { 561 int count = 0; 562 563 /* fill the fifo */ 564 while (mbpp->mp_cnt && count++ < CD1400_PAR_FIFO_SIZE) { 565 CD1400_WRITE_REG(cd, CD1400_TDR, *mbpp->mp_ptr); 566 mbpp->mp_ptr++; 567 mbpp->mp_cnt--; 568 } 569 } else { 570 /* fifo is empty and we got no more data to send, so shut 571 * off interrupts and signal for a wakeup, which can't be 572 * done here in case we beat mbpp_send to the tsleep call 573 * (we are running at >spltty) 574 */ 575 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 576 SET(mbpp->mp_flags, MBPPF_WAKEUP); 577 needsoftint = 1; 578 } 579 } else { /* serial port */ 580 struct mtty_port *mtty; 581 struct tty *tp; 582 583 mtty = &sc->ms_mtty->ms_port[port]; 584 cd = mtty->mp_cd1400; 585 tp = mtty->mp_tty; 586 587 if (!ISSET(mtty->mp_flags, MTTYF_STOP)) { 588 int count = 0; 589 590 /* check if we should start/stop a break */ 591 if (ISSET(mtty->mp_flags, MTTYF_SET_BREAK)) { 592 CD1400_WRITE_REG(cd, CD1400_TDR, 0); 593 CD1400_WRITE_REG(cd, CD1400_TDR, 0x81); 594 /* should we delay too? */ 595 CLR(mtty->mp_flags, MTTYF_SET_BREAK); 596 count += 2; 597 } 598 599 if (ISSET(mtty->mp_flags, MTTYF_CLR_BREAK)) { 600 CD1400_WRITE_REG(cd, CD1400_TDR, 0); 601 CD1400_WRITE_REG(cd, CD1400_TDR, 0x83); 602 CLR(mtty->mp_flags, MTTYF_CLR_BREAK); 603 count += 2; 604 } 605 606 /* I don't quite fill the fifo in case the last one is a 607 * NULL which I have to double up because its the escape 608 * code for embedded transmit characters. 609 */ 610 while (mtty->mp_txc > 0 && count < CD1400_TX_FIFO_SIZE - 1) { 611 u_char ch; 612 613 ch = *mtty->mp_txp; 614 615 mtty->mp_txc--; 616 mtty->mp_txp++; 617 618 if (ch == 0) { 619 CD1400_WRITE_REG(cd, CD1400_TDR, ch); 620 count++; 621 } 622 623 CD1400_WRITE_REG(cd, CD1400_TDR, ch); 624 count++; 625 } 626 } 627 628 /* if we ran out of work or are requested to STOP then 629 * shut off the txrdy interrupts and signal DONE to flush 630 * out the chars we have sent. 631 */ 632 if (mtty->mp_txc == 0 || ISSET(mtty->mp_flags, MTTYF_STOP)) { 633 int srer; 634 635 srer = CD1400_READ_REG(cd, CD1400_SRER); 636 CLR(srer, CD1400_SRER_TXRDY); 637 CD1400_WRITE_REG(cd, CD1400_SRER, srer); 638 CLR(mtty->mp_flags, MTTYF_STOP); 639 640 SET(mtty->mp_flags, MTTYF_DONE); 641 needsoftint = 1; 642 } 643 } 644 645 CD1400_WRITE_REG(cd, CD1400_EOSRR, 0); /* end service context */ 646 serviced = 1; 647 } /* if(tx_service...) */ 648 649 /* XXX service CD1190 interrupts too 650 for (chip = 0 ; chip < sc->ms_ncd1190 ; chip++) { 651 } 652 */ 653 654 if (needsoftint) 655 softintr_schedule(sc->sc_sih); 656 657 return (serviced); 658 } 659 660 /* 661 * magma soft interrupt handler 662 * 663 * returns 1 if it handled it, 0 otherwise 664 * 665 * runs at spltty() 666 */ 667 void 668 magma_soft(void *arg) 669 { 670 struct magma_softc *sc = arg; 671 struct mtty_softc *mtty = sc->ms_mtty; 672 struct mbpp_softc *mbpp = sc->ms_mbpp; 673 int port; 674 int serviced = 0; 675 int s, flags; 676 677 /* 678 * check the tty ports (if any) to see what needs doing 679 */ 680 if (mtty) { 681 for (port = 0 ; port < mtty->ms_nports ; port++) { 682 struct mtty_port *mp = &mtty->ms_port[port]; 683 struct tty *tp = mp->mp_tty; 684 685 if (!ISSET(tp->t_state, TS_ISOPEN)) 686 continue; 687 688 /* 689 * handle any received data 690 */ 691 while (mp->mp_rget != mp->mp_rput) { 692 u_char stat; 693 int data; 694 695 stat = mp->mp_rget[0]; 696 data = mp->mp_rget[1]; 697 mp->mp_rget = ((mp->mp_rget + 2) == mp->mp_rend) ? mp->mp_rbuf : (mp->mp_rget + 2); 698 699 if (stat & (CD1400_RDSR_BREAK | CD1400_RDSR_FE)) 700 data |= TTY_FE; 701 if (stat & CD1400_RDSR_PE) 702 data |= TTY_PE; 703 704 if (stat & CD1400_RDSR_OE) 705 log(LOG_WARNING, "%s%x: fifo overflow\n", mtty->ms_dev.dv_xname, port); 706 707 (*linesw[tp->t_line].l_rint)(data, tp); 708 serviced = 1; 709 } 710 711 s = splhigh(); /* block out hard interrupt routine */ 712 flags = mp->mp_flags; 713 CLR(mp->mp_flags, MTTYF_DONE | MTTYF_CARRIER_CHANGED | MTTYF_RING_OVERFLOW); 714 splx(s); /* ok */ 715 716 if (ISSET(flags, MTTYF_CARRIER_CHANGED)) { 717 dprintf(("%s%x: cd %s\n", mtty->ms_dev.dv_xname, port, mp->mp_carrier ? "on" : "off")); 718 (*linesw[tp->t_line].l_modem)(tp, mp->mp_carrier); 719 serviced = 1; 720 } 721 722 if (ISSET(flags, MTTYF_RING_OVERFLOW)) { 723 log(LOG_WARNING, "%s%x: ring buffer overflow\n", mtty->ms_dev.dv_xname, port); 724 serviced = 1; 725 } 726 727 if (ISSET(flags, MTTYF_DONE)) { 728 ndflush(&tp->t_outq, mp->mp_txp - tp->t_outq.c_cf); 729 CLR(tp->t_state, TS_BUSY); 730 (*linesw[tp->t_line].l_start)(tp); /* might be some more */ 731 serviced = 1; 732 } 733 } /* for (each mtty...) */ 734 } 735 736 /* 737 * check the bpp ports (if any) to see what needs doing 738 */ 739 if (mbpp) { 740 for (port = 0 ; port < mbpp->ms_nports ; port++) { 741 struct mbpp_port *mp = &mbpp->ms_port[port]; 742 743 if (!ISSET(mp->mp_flags, MBPPF_OPEN)) 744 continue; 745 746 s = splhigh(); /* block out hard intr routine */ 747 flags = mp->mp_flags; 748 CLR(mp->mp_flags, MBPPF_WAKEUP); 749 splx(s); 750 751 if (ISSET(flags, MBPPF_WAKEUP)) { 752 wakeup(mp); 753 serviced = 1; 754 } 755 } /* for (each mbpp...) */ 756 } 757 } 758 759 /************************************************************************ 760 * 761 * MTTY Routines 762 * 763 * mtty_match match one mtty device 764 * mtty_attach attach mtty devices 765 * mttyopen open mtty device 766 * mttyclose close mtty device 767 * mttyread read from mtty 768 * mttywrite write to mtty 769 * mttyioctl do ioctl on mtty 770 * mttytty return tty pointer for mtty 771 * mttystop stop mtty device 772 * mtty_start start mtty device 773 * mtty_param set mtty parameters 774 * mtty_modem_control set modem control lines 775 */ 776 777 int 778 mtty_match(struct device *parent, void *vcf, void *args) 779 { 780 struct magma_softc *sc = (struct magma_softc *)parent; 781 782 return (args == mtty_match && sc->ms_board->mb_nser && 783 sc->ms_mtty == NULL); 784 } 785 786 void 787 mtty_attach(struct device *parent, struct device *dev, void *args) 788 { 789 struct magma_softc *sc = (struct magma_softc *)parent; 790 struct mtty_softc *ms = (struct mtty_softc *)dev; 791 int port, chip, chan; 792 793 sc->ms_mtty = ms; 794 dprintf((" addr 0x%x", ms)); 795 796 for (port = 0, chip = 0, chan = 0; 797 port < sc->ms_board->mb_nser; port++) { 798 struct mtty_port *mp = &ms->ms_port[port]; 799 struct tty *tp; 800 801 mp->mp_cd1400 = &sc->ms_cd1400[chip]; 802 if (mp->mp_cd1400->cd_parmode && chan == 0) { 803 /* skip channel 0 if parmode */ 804 chan = 1; 805 } 806 mp->mp_channel = chan; 807 808 tp = ttymalloc(0); 809 tp->t_oproc = mtty_start; 810 tp->t_param = mtty_param; 811 812 mp->mp_tty = tp; 813 814 mp->mp_rbuf = malloc(MTTY_RBUF_SIZE, M_DEVBUF, M_NOWAIT); 815 if (mp->mp_rbuf == NULL) 816 break; 817 818 mp->mp_rend = mp->mp_rbuf + MTTY_RBUF_SIZE; 819 820 chan = (chan + 1) % CD1400_NO_OF_CHANNELS; 821 if (chan == 0) 822 chip++; 823 } 824 825 ms->ms_nports = port; 826 printf(": %d tty%s\n", port, port == 1 ? "" : "s"); 827 } 828 829 /* 830 * open routine. returns zero if successful, else error code 831 */ 832 int 833 mttyopen(dev_t dev, int flags, int mode, struct proc *p) 834 { 835 int card = MAGMA_CARD(dev); 836 int port = MAGMA_PORT(dev); 837 struct mtty_softc *ms; 838 struct mtty_port *mp; 839 struct tty *tp; 840 struct cd1400 *cd; 841 int s; 842 843 if (card >= mtty_cd.cd_ndevs || (ms = mtty_cd.cd_devs[card]) == NULL 844 || port >= ms->ms_nports) 845 return (ENXIO); /* device not configured */ 846 847 mp = &ms->ms_port[port]; 848 tp = mp->mp_tty; 849 tp->t_dev = dev; 850 851 if (!ISSET(tp->t_state, TS_ISOPEN)) { 852 SET(tp->t_state, TS_WOPEN); 853 854 /* set defaults */ 855 ttychars(tp); 856 tp->t_iflag = TTYDEF_IFLAG; 857 tp->t_oflag = TTYDEF_OFLAG; 858 tp->t_cflag = TTYDEF_CFLAG; 859 if (ISSET(mp->mp_openflags, TIOCFLAG_CLOCAL)) 860 SET(tp->t_cflag, CLOCAL); 861 if (ISSET(mp->mp_openflags, TIOCFLAG_CRTSCTS)) 862 SET(tp->t_cflag, CRTSCTS); 863 if (ISSET(mp->mp_openflags, TIOCFLAG_MDMBUF)) 864 SET(tp->t_cflag, MDMBUF); 865 tp->t_lflag = TTYDEF_LFLAG; 866 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 867 868 /* init ring buffer */ 869 mp->mp_rput = mp->mp_rget = mp->mp_rbuf; 870 871 s = spltty(); 872 873 /* reset CD1400 channel */ 874 cd = mp->mp_cd1400; 875 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 876 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); 877 878 /* encode the port number in top half of LIVR */ 879 CD1400_WRITE_REG(cd, CD1400_LIVR, port << 4); 880 881 /* sets parameters and raises DTR */ 882 (void)mtty_param(tp, &tp->t_termios); 883 884 /* set tty watermarks */ 885 ttsetwater(tp); 886 887 /* enable service requests */ 888 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA | CD1400_SRER_MDMCH); 889 890 /* tell the tty about the carrier status */ 891 if (ISSET(mp->mp_openflags, TIOCFLAG_SOFTCAR) || mp->mp_carrier) 892 SET(tp->t_state, TS_CARR_ON); 893 else 894 CLR(tp->t_state, TS_CARR_ON); 895 } else if (ISSET(tp->t_state, TS_XCLUDE) && suser(p) != 0) { 896 return (EBUSY); /* superuser can break exclusive access */ 897 } else { 898 s = spltty(); 899 } 900 901 /* wait for carrier if necessary */ 902 if (!ISSET(flags, O_NONBLOCK)) { 903 while (!ISSET(tp->t_cflag, CLOCAL) && !ISSET(tp->t_state, TS_CARR_ON)) { 904 int error; 905 906 SET(tp->t_state, TS_WOPEN); 907 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH, "mttydcd"); 908 if (error != 0) { 909 splx(s); 910 CLR(tp->t_state, TS_WOPEN); 911 return (error); 912 } 913 } 914 } 915 916 splx(s); 917 918 return ((*linesw[tp->t_line].l_open)(dev, tp, p)); 919 } 920 921 /* 922 * close routine. returns zero if successful, else error code 923 */ 924 int 925 mttyclose(dev_t dev, int flag, int mode, struct proc *p) 926 { 927 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 928 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 929 struct tty *tp = mp->mp_tty; 930 int s; 931 932 (*linesw[tp->t_line].l_close)(tp, flag, p); 933 s = spltty(); 934 935 /* if HUPCL is set, and the tty is no longer open 936 * shut down the port 937 */ 938 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) { 939 /* XXX wait until FIFO is empty before turning off the channel 940 struct cd1400 *cd = mp->mp_cd1400; 941 */ 942 943 /* drop DTR and RTS */ 944 (void)mtty_modem_control(mp, 0, DMSET); 945 946 /* turn off the channel 947 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 948 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); 949 */ 950 } 951 952 splx(s); 953 ttyclose(tp); 954 955 return (0); 956 } 957 958 /* 959 * Read routine 960 */ 961 int 962 mttyread(dev_t dev, struct uio *uio, int flags) 963 { 964 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 965 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 966 struct tty *tp = mp->mp_tty; 967 968 return ((*linesw[tp->t_line].l_read)(tp, uio, flags)); 969 } 970 971 /* 972 * Write routine 973 */ 974 int 975 mttywrite(dev_t dev, struct uio *uio, int flags) 976 { 977 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 978 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 979 struct tty *tp = mp->mp_tty; 980 981 return ((*linesw[tp->t_line].l_write)(tp, uio, flags)); 982 } 983 984 /* 985 * return tty pointer 986 */ 987 struct tty * 988 mttytty(dev_t dev) 989 { 990 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 991 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 992 993 return (mp->mp_tty); 994 } 995 996 /* 997 * ioctl routine 998 */ 999 int 1000 mttyioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 1001 { 1002 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 1003 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1004 struct tty *tp = mp->mp_tty; 1005 int error; 1006 1007 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p); 1008 if (error >= 0) 1009 return (error); 1010 1011 error = ttioctl(tp, cmd, data, flags, p); 1012 if (error >= 0) 1013 return (error); 1014 1015 error = 0; 1016 1017 switch(cmd) { 1018 case TIOCSBRK: /* set break */ 1019 SET(mp->mp_flags, MTTYF_SET_BREAK); 1020 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1021 break; 1022 1023 case TIOCCBRK: /* clear break */ 1024 SET(mp->mp_flags, MTTYF_CLR_BREAK); 1025 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1026 break; 1027 1028 case TIOCSDTR: /* set DTR */ 1029 mtty_modem_control(mp, TIOCM_DTR, DMBIS); 1030 break; 1031 1032 case TIOCCDTR: /* clear DTR */ 1033 mtty_modem_control(mp, TIOCM_DTR, DMBIC); 1034 break; 1035 1036 case TIOCMSET: /* set modem lines */ 1037 mtty_modem_control(mp, *((int *)data), DMSET); 1038 break; 1039 1040 case TIOCMBIS: /* bit set modem lines */ 1041 mtty_modem_control(mp, *((int *)data), DMBIS); 1042 break; 1043 1044 case TIOCMBIC: /* bit clear modem lines */ 1045 mtty_modem_control(mp, *((int *)data), DMBIC); 1046 break; 1047 1048 case TIOCMGET: /* get modem lines */ 1049 *((int *)data) = mtty_modem_control(mp, 0, DMGET); 1050 break; 1051 1052 case TIOCGFLAGS: 1053 *((int *)data) = mp->mp_openflags; 1054 break; 1055 1056 case TIOCSFLAGS: 1057 if (suser(p)) 1058 error = EPERM; 1059 else 1060 mp->mp_openflags = *((int *)data) & 1061 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 1062 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 1063 break; 1064 1065 default: 1066 error = ENOTTY; 1067 } 1068 1069 return (error); 1070 } 1071 1072 /* 1073 * Stop output, e.g., for ^S or output flush. 1074 */ 1075 int 1076 mttystop(struct tty *tp, int flags) 1077 { 1078 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1079 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1080 int s; 1081 1082 s = spltty(); 1083 1084 if (ISSET(tp->t_state, TS_BUSY)) { 1085 if (!ISSET(tp->t_state, TS_TTSTOP)) 1086 SET(tp->t_state, TS_FLUSH); 1087 1088 /* 1089 * the transmit interrupt routine will disable transmit when it 1090 * notices that MTTYF_STOP has been set. 1091 */ 1092 SET(mp->mp_flags, MTTYF_STOP); 1093 } 1094 1095 splx(s); 1096 return (0); 1097 } 1098 1099 /* 1100 * Start output, after a stop. 1101 */ 1102 void 1103 mtty_start(struct tty *tp) 1104 { 1105 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1106 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1107 int s; 1108 1109 s = spltty(); 1110 1111 /* we only need to do something if we are not already busy 1112 * or delaying or stopped 1113 */ 1114 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 1115 1116 /* if we are sleeping and output has drained below 1117 * low water mark, awaken 1118 */ 1119 ttwakeupwr(tp); 1120 1121 /* if something to send, start transmitting 1122 */ 1123 if (tp->t_outq.c_cc) { 1124 mp->mp_txc = ndqb(&tp->t_outq, 0); 1125 mp->mp_txp = tp->t_outq.c_cf; 1126 SET(tp->t_state, TS_BUSY); 1127 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1128 } 1129 } 1130 1131 splx(s); 1132 } 1133 1134 /* 1135 * set/get modem line status 1136 * 1137 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR 1138 * 1139 * note that DTR and RTS lines are exchanged, and that DSR is 1140 * not available on the LC2+1Sp card (used as CD) 1141 * 1142 * only let them fiddle with RTS if CRTSCTS is not enabled 1143 */ 1144 int 1145 mtty_modem_control(struct mtty_port *mp, int bits, int howto) 1146 { 1147 struct cd1400 *cd = mp->mp_cd1400; 1148 struct tty *tp = mp->mp_tty; 1149 int s, msvr; 1150 1151 s = spltty(); 1152 1153 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 1154 1155 switch(howto) { 1156 case DMGET: /* get bits */ 1157 bits = 0; 1158 1159 bits |= TIOCM_LE; 1160 1161 msvr = CD1400_READ_REG(cd, CD1400_MSVR1); 1162 if (msvr & CD1400_MSVR1_RTS) 1163 bits |= TIOCM_DTR; 1164 1165 msvr = CD1400_READ_REG(cd, CD1400_MSVR2); 1166 if (msvr & CD1400_MSVR2_DTR) 1167 bits |= TIOCM_RTS; 1168 if (msvr & CD1400_MSVR2_CTS) 1169 bits |= TIOCM_CTS; 1170 if (msvr & CD1400_MSVR2_RI) 1171 bits |= TIOCM_RI; 1172 if (msvr & CD1400_MSVR2_DSR) 1173 bits |= (cd->cd_parmode ? TIOCM_CD : TIOCM_DSR); 1174 if (msvr & CD1400_MSVR2_CD) 1175 bits |= (cd->cd_parmode ? 0 : TIOCM_CD); 1176 1177 break; 1178 1179 case DMSET: /* reset bits */ 1180 if (!ISSET(tp->t_cflag, CRTSCTS)) 1181 CD1400_WRITE_REG(cd, CD1400_MSVR2, 1182 ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0)); 1183 1184 CD1400_WRITE_REG(cd, CD1400_MSVR1, 1185 ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0)); 1186 1187 break; 1188 1189 case DMBIS: /* set bits */ 1190 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1191 CD1400_WRITE_REG(cd, CD1400_MSVR2, CD1400_MSVR2_DTR); 1192 1193 if (bits & TIOCM_DTR) 1194 CD1400_WRITE_REG(cd, CD1400_MSVR1, CD1400_MSVR1_RTS); 1195 1196 break; 1197 1198 case DMBIC: /* clear bits */ 1199 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1200 CD1400_WRITE_REG(cd, CD1400_MSVR2, 0); 1201 1202 if (bits & TIOCM_DTR) 1203 CD1400_WRITE_REG(cd, CD1400_MSVR1, 0); 1204 1205 break; 1206 } 1207 1208 splx(s); 1209 return (bits); 1210 } 1211 1212 /* 1213 * Set tty parameters, returns error or 0 on success 1214 */ 1215 int 1216 mtty_param(struct tty *tp, struct termios *t) 1217 { 1218 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1219 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1220 struct cd1400 *cd = mp->mp_cd1400; 1221 int rbpr, tbpr, rcor, tcor; 1222 u_char mcor1 = 0, mcor2 = 0; 1223 int s, opt; 1224 1225 if (t->c_ospeed && 1226 cd1400_compute_baud(t->c_ospeed, cd->cd_clock, &tcor, &tbpr)) 1227 return (EINVAL); 1228 1229 if (t->c_ispeed && 1230 cd1400_compute_baud(t->c_ispeed, cd->cd_clock, &rcor, &rbpr)) 1231 return (EINVAL); 1232 1233 s = spltty(); 1234 1235 /* hang up the line if ospeed is zero, else raise DTR */ 1236 (void)mtty_modem_control(mp, TIOCM_DTR, 1237 (t->c_ospeed == 0 ? DMBIC : DMBIS)); 1238 1239 /* select channel, done in mtty_modem_control() */ 1240 /* CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); */ 1241 1242 /* set transmit speed */ 1243 if (t->c_ospeed) { 1244 CD1400_WRITE_REG(cd, CD1400_TCOR, tcor); 1245 CD1400_WRITE_REG(cd, CD1400_TBPR, tbpr); 1246 } 1247 1248 /* set receive speed */ 1249 if (t->c_ispeed) { 1250 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1251 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1252 } 1253 1254 /* enable transmitting and receiving on this channel */ 1255 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN | CD1400_CCR_RCVEN; 1256 cd1400_write_ccr(cd, opt); 1257 1258 /* set parity, data and stop bits */ 1259 opt = 0; 1260 if (ISSET(t->c_cflag, PARENB)) 1261 opt |= (ISSET(t->c_cflag, PARODD) ? CD1400_COR1_PARODD : CD1400_COR1_PARNORMAL); 1262 1263 if (!ISSET(t->c_iflag, INPCK)) 1264 opt |= CD1400_COR1_NOINPCK; /* no parity checking */ 1265 1266 if (ISSET(t->c_cflag, CSTOPB)) 1267 opt |= CD1400_COR1_STOP2; 1268 1269 switch( t->c_cflag & CSIZE) { 1270 case CS5: 1271 opt |= CD1400_COR1_CS5; 1272 break; 1273 1274 case CS6: 1275 opt |= CD1400_COR1_CS6; 1276 break; 1277 1278 case CS7: 1279 opt |= CD1400_COR1_CS7; 1280 break; 1281 1282 default: 1283 opt |= CD1400_COR1_CS8; 1284 break; 1285 } 1286 1287 CD1400_WRITE_REG(cd, CD1400_COR1, opt); 1288 1289 /* 1290 * enable Embedded Transmit Commands (for breaks) 1291 * use the CD1400 automatic CTS flow control if CRTSCTS is set 1292 */ 1293 opt = CD1400_COR2_ETC; 1294 if (ISSET(t->c_cflag, CRTSCTS)) 1295 opt |= CD1400_COR2_CCTS_OFLOW; 1296 CD1400_WRITE_REG(cd, CD1400_COR2, opt); 1297 1298 CD1400_WRITE_REG(cd, CD1400_COR3, MTTY_RX_FIFO_THRESHOLD); 1299 1300 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3); 1301 1302 CD1400_WRITE_REG(cd, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION); 1303 CD1400_WRITE_REG(cd, CD1400_COR5, 0); 1304 1305 /* 1306 * if automatic RTS handshaking enabled, set DTR threshold 1307 * (RTS and DTR lines are switched, CD1400 thinks its DTR) 1308 */ 1309 if (ISSET(t->c_cflag, CRTSCTS)) 1310 mcor1 = MTTY_RX_DTR_THRESHOLD; 1311 1312 /* set up `carrier detect' interrupts */ 1313 if (cd->cd_parmode) { 1314 SET(mcor1, CD1400_MCOR1_DSRzd); 1315 SET(mcor2, CD1400_MCOR2_DSRod); 1316 } else { 1317 SET(mcor1, CD1400_MCOR1_CDzd); 1318 SET(mcor2, CD1400_MCOR2_CDod); 1319 } 1320 1321 CD1400_WRITE_REG(cd, CD1400_MCOR1, mcor1); 1322 CD1400_WRITE_REG(cd, CD1400_MCOR2, mcor2); 1323 1324 /* receive timeout 2ms */ 1325 CD1400_WRITE_REG(cd, CD1400_RTPR, 2); 1326 1327 splx(s); 1328 return (0); 1329 } 1330 1331 /************************************************************************ 1332 * 1333 * MBPP Routines 1334 * 1335 * mbpp_match match one mbpp device 1336 * mbpp_attach attach mbpp devices 1337 * mbppopen open mbpp device 1338 * mbppclose close mbpp device 1339 * mbppread read from mbpp 1340 * mbppwrite write to mbpp 1341 * mbppioctl do ioctl on mbpp 1342 * mbpppoll do poll on mbpp 1343 * mbppkqfilter kqueue on mbpp 1344 * mbpp_rw general rw routine 1345 * mbpp_timeout rw timeout 1346 * mbpp_start rw start after delay 1347 * mbpp_send send data 1348 * mbpp_recv recv data 1349 */ 1350 1351 int 1352 mbpp_match(struct device *parent, void *vcf, void *args) 1353 { 1354 struct magma_softc *sc = (struct magma_softc *)parent; 1355 1356 return (args == mbpp_match && sc->ms_board->mb_npar && 1357 sc->ms_mbpp == NULL); 1358 } 1359 1360 void 1361 mbpp_attach(struct device *parent, struct device *dev, void *args) 1362 { 1363 struct magma_softc *sc = (struct magma_softc *)parent; 1364 struct mbpp_softc *ms = (struct mbpp_softc *)dev; 1365 struct mbpp_port *mp; 1366 int port; 1367 1368 sc->ms_mbpp = ms; 1369 dprintf((" addr 0x%x", ms)); 1370 1371 for (port = 0 ; port < sc->ms_board->mb_npar ; port++) { 1372 mp = &ms->ms_port[port]; 1373 1374 if (sc->ms_ncd1190) 1375 mp->mp_cd1190 = &sc->ms_cd1190[port]; 1376 else 1377 mp->mp_cd1400 = &sc->ms_cd1400[0]; 1378 1379 timeout_set(&mp->mp_timeout_tmo, mbpp_timeout, mp); 1380 timeout_set(&mp->mp_start_tmo, mbpp_start, mp); 1381 } 1382 1383 ms->ms_nports = port; 1384 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1385 } 1386 1387 /* 1388 * open routine. returns zero if successful, else error code 1389 */ 1390 int 1391 mbppopen(dev_t dev, int flags, int mode, struct proc *p) 1392 { 1393 int card = MAGMA_CARD(dev); 1394 int port = MAGMA_PORT(dev); 1395 struct mbpp_softc *ms; 1396 struct mbpp_port *mp; 1397 int s; 1398 1399 if (card >= mbpp_cd.cd_ndevs || (ms = mbpp_cd.cd_devs[card]) == NULL || port >= ms->ms_nports) 1400 return (ENXIO); 1401 1402 mp = &ms->ms_port[port]; 1403 1404 s = spltty(); 1405 if (ISSET(mp->mp_flags, MBPPF_OPEN)) { 1406 splx(s); 1407 return (EBUSY); 1408 } 1409 SET(mp->mp_flags, MBPPF_OPEN); 1410 splx(s); 1411 1412 /* set defaults */ 1413 mp->mp_burst = BPP_BURST; 1414 mp->mp_timeout = BPP_TIMEOUT; 1415 mp->mp_delay = BPP_DELAY; 1416 1417 /* init chips */ 1418 if (mp->mp_cd1400) { /* CD1400 */ 1419 struct cd1400 *cd = mp->mp_cd1400; 1420 1421 /* set up CD1400 channel */ 1422 s = spltty(); 1423 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1424 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); 1425 CD1400_WRITE_REG(cd, CD1400_LIVR, (1<<3)); 1426 splx(s); 1427 } else { /* CD1190 */ 1428 mp->mp_flags = 0; 1429 return (ENXIO); 1430 } 1431 1432 return (0); 1433 } 1434 1435 /* 1436 * close routine. returns zero if successful, else error code 1437 */ 1438 int 1439 mbppclose(dev_t dev, int flag, int mode, struct proc *p) 1440 { 1441 struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)]; 1442 struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1443 1444 mp->mp_flags = 0; 1445 return (0); 1446 } 1447 1448 /* 1449 * Read routine 1450 */ 1451 int 1452 mbppread(dev_t dev, struct uio *uio, int flags) 1453 { 1454 return (mbpp_rw(dev, uio)); 1455 } 1456 1457 /* 1458 * Write routine 1459 */ 1460 int 1461 mbppwrite(dev_t dev, struct uio *uio, int flags) 1462 { 1463 return (mbpp_rw(dev, uio)); 1464 } 1465 1466 /* 1467 * ioctl routine 1468 */ 1469 int 1470 mbppioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 1471 { 1472 struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)]; 1473 struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1474 struct bpp_param *bp; 1475 int error = 0; 1476 int s; 1477 1478 switch(cmd) { 1479 case BPPIOCSPARAM: 1480 bp = (struct bpp_param *)data; 1481 if (bp->bp_burst < BPP_BURST_MIN || bp->bp_burst > BPP_BURST_MAX || 1482 bp->bp_delay < BPP_DELAY_MIN || bp->bp_delay > BPP_DELAY_MIN) { 1483 error = EINVAL; 1484 } else { 1485 mp->mp_burst = bp->bp_burst; 1486 mp->mp_timeout = bp->bp_timeout; 1487 mp->mp_delay = bp->bp_delay; 1488 } 1489 break; 1490 case BPPIOCGPARAM: 1491 bp = (struct bpp_param *)data; 1492 bp->bp_burst = mp->mp_burst; 1493 bp->bp_timeout = mp->mp_timeout; 1494 bp->bp_delay = mp->mp_delay; 1495 break; 1496 case BPPIOCGSTAT: 1497 /* XXX make this more generic */ 1498 s = spltty(); 1499 CD1400_WRITE_REG(mp->mp_cd1400, CD1400_CAR, 0); 1500 *(int *)data = CD1400_READ_REG(mp->mp_cd1400, CD1400_PSVR); 1501 splx(s); 1502 break; 1503 default: 1504 error = ENOTTY; 1505 } 1506 1507 return (error); 1508 } 1509 1510 /* 1511 * poll routine 1512 */ 1513 int 1514 mbpppoll(dev_t dev, int events, struct proc *p) 1515 { 1516 return (seltrue(dev, events, p)); 1517 } 1518 1519 int 1520 mbppkqfilter(dev_t dev, struct knote *kn) 1521 { 1522 return (seltrue_kqfilter(dev, kn)); 1523 } 1524 1525 int 1526 mbpp_rw(dev_t dev, struct uio *uio) 1527 { 1528 int card = MAGMA_CARD(dev); 1529 int port = MAGMA_PORT(dev); 1530 struct mbpp_softc *ms = mbpp_cd.cd_devs[card]; 1531 struct mbpp_port *mp = &ms->ms_port[port]; 1532 caddr_t buffer, ptr; 1533 size_t buflen, cnt, len; 1534 int s, error = 0; 1535 int gotdata = 0; 1536 1537 if (uio->uio_resid == 0) 1538 return (0); 1539 1540 buflen = ulmin(uio->uio_resid, mp->mp_burst); 1541 buffer = malloc(buflen, M_DEVBUF, M_WAITOK); 1542 1543 SET(mp->mp_flags, MBPPF_UIO); 1544 1545 /* 1546 * start timeout, if needed 1547 */ 1548 if (mp->mp_timeout > 0) { 1549 SET(mp->mp_flags, MBPPF_TIMEOUT); 1550 timeout_add_msec(&mp->mp_timeout_tmo, mp->mp_timeout); 1551 } 1552 1553 len = cnt = 0; 1554 while (uio->uio_resid > 0) { 1555 len = ulmin(buflen, uio->uio_resid); 1556 ptr = buffer; 1557 1558 if (uio->uio_rw == UIO_WRITE) { 1559 error = uiomove(ptr, len, uio); 1560 if (error) 1561 break; 1562 } 1563 again: /* goto bad */ 1564 /* timed out? */ 1565 if (!ISSET(mp->mp_flags, MBPPF_UIO)) 1566 break; 1567 1568 /* 1569 * perform the operation 1570 */ 1571 if (uio->uio_rw == UIO_WRITE) { 1572 cnt = mbpp_send(mp, ptr, len); 1573 } else { 1574 cnt = mbpp_recv(mp, ptr, len); 1575 } 1576 1577 if (uio->uio_rw == UIO_READ) { 1578 if (cnt) { 1579 error = uiomove(ptr, cnt, uio); 1580 if (error) 1581 break; 1582 gotdata++; 1583 } 1584 else if (gotdata) /* consider us done */ 1585 break; 1586 } 1587 1588 /* timed out? */ 1589 if (!ISSET(mp->mp_flags, MBPPF_UIO)) 1590 break; 1591 1592 /* 1593 * poll delay? 1594 */ 1595 if (mp->mp_delay > 0) { 1596 s = spltty(); /* XXX */ 1597 SET(mp->mp_flags, MBPPF_DELAY); 1598 timeout_add_msec(&mp->mp_start_tmo, mp->mp_delay); 1599 error = tsleep_nsec(mp, PCATCH | PZERO, "mbppdelay", 1600 INFSLP); 1601 splx(s); 1602 if (error) 1603 break; 1604 } 1605 1606 /* 1607 * don't call uiomove again until we used all the data we grabbed 1608 */ 1609 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1610 ptr += cnt; 1611 len -= cnt; 1612 cnt = 0; 1613 goto again; 1614 } 1615 } 1616 1617 /* 1618 * clear timeouts 1619 */ 1620 s = spltty(); /* XXX */ 1621 if (ISSET(mp->mp_flags, MBPPF_TIMEOUT)) { 1622 timeout_del(&mp->mp_timeout_tmo); 1623 CLR(mp->mp_flags, MBPPF_TIMEOUT); 1624 } 1625 if (ISSET(mp->mp_flags, MBPPF_DELAY)) { 1626 timeout_del(&mp->mp_start_tmo); 1627 CLR(mp->mp_flags, MBPPF_DELAY); 1628 } 1629 splx(s); 1630 1631 /* 1632 * adjust for those chars that we uiomoved but never actually wrote 1633 */ 1634 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1635 uio->uio_resid += (len - cnt); 1636 } 1637 1638 free(buffer, M_DEVBUF, 0); 1639 return (error); 1640 } 1641 1642 void 1643 mbpp_timeout(void *arg) 1644 { 1645 struct mbpp_port *mp = arg; 1646 1647 CLR(mp->mp_flags, MBPPF_UIO | MBPPF_TIMEOUT); 1648 wakeup(mp); 1649 } 1650 1651 void 1652 mbpp_start(void *arg) 1653 { 1654 struct mbpp_port *mp = arg; 1655 1656 CLR(mp->mp_flags, MBPPF_DELAY); 1657 wakeup(mp); 1658 } 1659 1660 int 1661 mbpp_send(struct mbpp_port *mp, caddr_t ptr, int len) 1662 { 1663 int s; 1664 struct cd1400 *cd = mp->mp_cd1400; 1665 1666 /* set up io information */ 1667 mp->mp_ptr = ptr; 1668 mp->mp_cnt = len; 1669 1670 /* start transmitting */ 1671 s = spltty(); 1672 if (cd) { 1673 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1674 1675 /* output strobe width ~1microsecond */ 1676 CD1400_WRITE_REG(cd, CD1400_TBPR, 10); 1677 1678 /* enable channel */ 1679 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN); 1680 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_TXRDY); 1681 } 1682 1683 /* ZZzzz... */ 1684 tsleep_nsec(mp, PCATCH | PZERO, "mbpp_send", INFSLP); 1685 1686 /* stop transmitting */ 1687 if (cd) { 1688 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1689 1690 /* disable transmitter */ 1691 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1692 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTDIS); 1693 1694 /* flush fifo */ 1695 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 1696 } 1697 splx(s); 1698 1699 /* return number of chars sent */ 1700 return (len - mp->mp_cnt); 1701 } 1702 1703 int 1704 mbpp_recv(struct mbpp_port *mp, caddr_t ptr, int len) 1705 { 1706 int s; 1707 struct cd1400 *cd = mp->mp_cd1400; 1708 1709 /* set up io information */ 1710 mp->mp_ptr = ptr; 1711 mp->mp_cnt = len; 1712 1713 /* start receiving */ 1714 s = spltty(); 1715 if (cd) { 1716 int rcor, rbpr; 1717 1718 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1719 1720 /* input strobe at 100kbaud (10microseconds) */ 1721 cd1400_compute_baud(100000, cd->cd_clock, &rcor, &rbpr); 1722 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1723 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1724 1725 /* rx threshold */ 1726 CD1400_WRITE_REG(cd, CD1400_COR3, MBPP_RX_FIFO_THRESHOLD); 1727 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3); 1728 1729 /* enable channel */ 1730 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVEN); 1731 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA); 1732 } 1733 1734 /* ZZzzz... */ 1735 tsleep_nsec(mp, PCATCH | PZERO, "mbpp_recv", INFSLP); 1736 1737 /* stop receiving */ 1738 if (cd) { 1739 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1740 1741 /* disable receiving */ 1742 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1743 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVDIS); 1744 } 1745 splx(s); 1746 1747 /* return number of chars received */ 1748 return (len - mp->mp_cnt); 1749 } 1750