1 /* $OpenBSD: magma.c,v 1.35 2022/07/02 08:50:42 visa 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 const 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 const 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 const 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, 908 ttopen); 909 if (error != 0) { 910 splx(s); 911 CLR(tp->t_state, TS_WOPEN); 912 return (error); 913 } 914 } 915 } 916 917 splx(s); 918 919 return ((*linesw[tp->t_line].l_open)(dev, tp, p)); 920 } 921 922 /* 923 * close routine. returns zero if successful, else error code 924 */ 925 int 926 mttyclose(dev_t dev, int flag, int mode, struct proc *p) 927 { 928 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 929 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 930 struct tty *tp = mp->mp_tty; 931 int s; 932 933 (*linesw[tp->t_line].l_close)(tp, flag, p); 934 s = spltty(); 935 936 /* if HUPCL is set, and the tty is no longer open 937 * shut down the port 938 */ 939 if (ISSET(tp->t_cflag, HUPCL) || !ISSET(tp->t_state, TS_ISOPEN)) { 940 /* XXX wait until FIFO is empty before turning off the channel 941 struct cd1400 *cd = mp->mp_cd1400; 942 */ 943 944 /* drop DTR and RTS */ 945 (void)mtty_modem_control(mp, 0, DMSET); 946 947 /* turn off the channel 948 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 949 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); 950 */ 951 } 952 953 splx(s); 954 ttyclose(tp); 955 956 return (0); 957 } 958 959 /* 960 * Read routine 961 */ 962 int 963 mttyread(dev_t dev, struct uio *uio, int flags) 964 { 965 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 966 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 967 struct tty *tp = mp->mp_tty; 968 969 return ((*linesw[tp->t_line].l_read)(tp, uio, flags)); 970 } 971 972 /* 973 * Write routine 974 */ 975 int 976 mttywrite(dev_t dev, struct uio *uio, int flags) 977 { 978 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 979 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 980 struct tty *tp = mp->mp_tty; 981 982 return ((*linesw[tp->t_line].l_write)(tp, uio, flags)); 983 } 984 985 /* 986 * return tty pointer 987 */ 988 struct tty * 989 mttytty(dev_t dev) 990 { 991 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 992 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 993 994 return (mp->mp_tty); 995 } 996 997 /* 998 * ioctl routine 999 */ 1000 int 1001 mttyioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 1002 { 1003 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(dev)]; 1004 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1005 struct tty *tp = mp->mp_tty; 1006 int error; 1007 1008 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flags, p); 1009 if (error >= 0) 1010 return (error); 1011 1012 error = ttioctl(tp, cmd, data, flags, p); 1013 if (error >= 0) 1014 return (error); 1015 1016 error = 0; 1017 1018 switch(cmd) { 1019 case TIOCSBRK: /* set break */ 1020 SET(mp->mp_flags, MTTYF_SET_BREAK); 1021 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1022 break; 1023 1024 case TIOCCBRK: /* clear break */ 1025 SET(mp->mp_flags, MTTYF_CLR_BREAK); 1026 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1027 break; 1028 1029 case TIOCSDTR: /* set DTR */ 1030 mtty_modem_control(mp, TIOCM_DTR, DMBIS); 1031 break; 1032 1033 case TIOCCDTR: /* clear DTR */ 1034 mtty_modem_control(mp, TIOCM_DTR, DMBIC); 1035 break; 1036 1037 case TIOCMSET: /* set modem lines */ 1038 mtty_modem_control(mp, *((int *)data), DMSET); 1039 break; 1040 1041 case TIOCMBIS: /* bit set modem lines */ 1042 mtty_modem_control(mp, *((int *)data), DMBIS); 1043 break; 1044 1045 case TIOCMBIC: /* bit clear modem lines */ 1046 mtty_modem_control(mp, *((int *)data), DMBIC); 1047 break; 1048 1049 case TIOCMGET: /* get modem lines */ 1050 *((int *)data) = mtty_modem_control(mp, 0, DMGET); 1051 break; 1052 1053 case TIOCGFLAGS: 1054 *((int *)data) = mp->mp_openflags; 1055 break; 1056 1057 case TIOCSFLAGS: 1058 if (suser(p)) 1059 error = EPERM; 1060 else 1061 mp->mp_openflags = *((int *)data) & 1062 (TIOCFLAG_SOFTCAR | TIOCFLAG_CLOCAL | 1063 TIOCFLAG_CRTSCTS | TIOCFLAG_MDMBUF); 1064 break; 1065 1066 default: 1067 error = ENOTTY; 1068 } 1069 1070 return (error); 1071 } 1072 1073 /* 1074 * Stop output, e.g., for ^S or output flush. 1075 */ 1076 int 1077 mttystop(struct tty *tp, int flags) 1078 { 1079 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1080 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1081 int s; 1082 1083 s = spltty(); 1084 1085 if (ISSET(tp->t_state, TS_BUSY)) { 1086 if (!ISSET(tp->t_state, TS_TTSTOP)) 1087 SET(tp->t_state, TS_FLUSH); 1088 1089 /* 1090 * the transmit interrupt routine will disable transmit when it 1091 * notices that MTTYF_STOP has been set. 1092 */ 1093 SET(mp->mp_flags, MTTYF_STOP); 1094 } 1095 1096 splx(s); 1097 return (0); 1098 } 1099 1100 /* 1101 * Start output, after a stop. 1102 */ 1103 void 1104 mtty_start(struct tty *tp) 1105 { 1106 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1107 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1108 int s; 1109 1110 s = spltty(); 1111 1112 /* we only need to do something if we are not already busy 1113 * or delaying or stopped 1114 */ 1115 if (!ISSET(tp->t_state, TS_TTSTOP | TS_TIMEOUT | TS_BUSY)) { 1116 1117 /* if we are sleeping and output has drained below 1118 * low water mark, awaken 1119 */ 1120 ttwakeupwr(tp); 1121 1122 /* if something to send, start transmitting 1123 */ 1124 if (tp->t_outq.c_cc) { 1125 mp->mp_txc = ndqb(&tp->t_outq, 0); 1126 mp->mp_txp = tp->t_outq.c_cf; 1127 SET(tp->t_state, TS_BUSY); 1128 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1129 } 1130 } 1131 1132 splx(s); 1133 } 1134 1135 /* 1136 * set/get modem line status 1137 * 1138 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR 1139 * 1140 * note that DTR and RTS lines are exchanged, and that DSR is 1141 * not available on the LC2+1Sp card (used as CD) 1142 * 1143 * only let them fiddle with RTS if CRTSCTS is not enabled 1144 */ 1145 int 1146 mtty_modem_control(struct mtty_port *mp, int bits, int howto) 1147 { 1148 struct cd1400 *cd = mp->mp_cd1400; 1149 struct tty *tp = mp->mp_tty; 1150 int s, msvr; 1151 1152 s = spltty(); 1153 1154 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 1155 1156 switch(howto) { 1157 case DMGET: /* get bits */ 1158 bits = 0; 1159 1160 bits |= TIOCM_LE; 1161 1162 msvr = CD1400_READ_REG(cd, CD1400_MSVR1); 1163 if (msvr & CD1400_MSVR1_RTS) 1164 bits |= TIOCM_DTR; 1165 1166 msvr = CD1400_READ_REG(cd, CD1400_MSVR2); 1167 if (msvr & CD1400_MSVR2_DTR) 1168 bits |= TIOCM_RTS; 1169 if (msvr & CD1400_MSVR2_CTS) 1170 bits |= TIOCM_CTS; 1171 if (msvr & CD1400_MSVR2_RI) 1172 bits |= TIOCM_RI; 1173 if (msvr & CD1400_MSVR2_DSR) 1174 bits |= (cd->cd_parmode ? TIOCM_CD : TIOCM_DSR); 1175 if (msvr & CD1400_MSVR2_CD) 1176 bits |= (cd->cd_parmode ? 0 : TIOCM_CD); 1177 1178 break; 1179 1180 case DMSET: /* reset bits */ 1181 if (!ISSET(tp->t_cflag, CRTSCTS)) 1182 CD1400_WRITE_REG(cd, CD1400_MSVR2, 1183 ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0)); 1184 1185 CD1400_WRITE_REG(cd, CD1400_MSVR1, 1186 ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0)); 1187 1188 break; 1189 1190 case DMBIS: /* set bits */ 1191 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1192 CD1400_WRITE_REG(cd, CD1400_MSVR2, CD1400_MSVR2_DTR); 1193 1194 if (bits & TIOCM_DTR) 1195 CD1400_WRITE_REG(cd, CD1400_MSVR1, CD1400_MSVR1_RTS); 1196 1197 break; 1198 1199 case DMBIC: /* clear bits */ 1200 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1201 CD1400_WRITE_REG(cd, CD1400_MSVR2, 0); 1202 1203 if (bits & TIOCM_DTR) 1204 CD1400_WRITE_REG(cd, CD1400_MSVR1, 0); 1205 1206 break; 1207 } 1208 1209 splx(s); 1210 return (bits); 1211 } 1212 1213 /* 1214 * Set tty parameters, returns error or 0 on success 1215 */ 1216 int 1217 mtty_param(struct tty *tp, struct termios *t) 1218 { 1219 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1220 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1221 struct cd1400 *cd = mp->mp_cd1400; 1222 int rbpr, tbpr, rcor, tcor; 1223 u_char mcor1 = 0, mcor2 = 0; 1224 int s, opt; 1225 1226 if (t->c_ospeed && 1227 cd1400_compute_baud(t->c_ospeed, cd->cd_clock, &tcor, &tbpr)) 1228 return (EINVAL); 1229 1230 if (t->c_ispeed && 1231 cd1400_compute_baud(t->c_ispeed, cd->cd_clock, &rcor, &rbpr)) 1232 return (EINVAL); 1233 1234 s = spltty(); 1235 1236 /* hang up the line if ospeed is zero, else raise DTR */ 1237 (void)mtty_modem_control(mp, TIOCM_DTR, 1238 (t->c_ospeed == 0 ? DMBIC : DMBIS)); 1239 1240 /* select channel, done in mtty_modem_control() */ 1241 /* CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); */ 1242 1243 /* set transmit speed */ 1244 if (t->c_ospeed) { 1245 CD1400_WRITE_REG(cd, CD1400_TCOR, tcor); 1246 CD1400_WRITE_REG(cd, CD1400_TBPR, tbpr); 1247 } 1248 1249 /* set receive speed */ 1250 if (t->c_ispeed) { 1251 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1252 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1253 } 1254 1255 /* enable transmitting and receiving on this channel */ 1256 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN | CD1400_CCR_RCVEN; 1257 cd1400_write_ccr(cd, opt); 1258 1259 /* set parity, data and stop bits */ 1260 opt = 0; 1261 if (ISSET(t->c_cflag, PARENB)) 1262 opt |= (ISSET(t->c_cflag, PARODD) ? CD1400_COR1_PARODD : CD1400_COR1_PARNORMAL); 1263 1264 if (!ISSET(t->c_iflag, INPCK)) 1265 opt |= CD1400_COR1_NOINPCK; /* no parity checking */ 1266 1267 if (ISSET(t->c_cflag, CSTOPB)) 1268 opt |= CD1400_COR1_STOP2; 1269 1270 switch( t->c_cflag & CSIZE) { 1271 case CS5: 1272 opt |= CD1400_COR1_CS5; 1273 break; 1274 1275 case CS6: 1276 opt |= CD1400_COR1_CS6; 1277 break; 1278 1279 case CS7: 1280 opt |= CD1400_COR1_CS7; 1281 break; 1282 1283 default: 1284 opt |= CD1400_COR1_CS8; 1285 break; 1286 } 1287 1288 CD1400_WRITE_REG(cd, CD1400_COR1, opt); 1289 1290 /* 1291 * enable Embedded Transmit Commands (for breaks) 1292 * use the CD1400 automatic CTS flow control if CRTSCTS is set 1293 */ 1294 opt = CD1400_COR2_ETC; 1295 if (ISSET(t->c_cflag, CRTSCTS)) 1296 opt |= CD1400_COR2_CCTS_OFLOW; 1297 CD1400_WRITE_REG(cd, CD1400_COR2, opt); 1298 1299 CD1400_WRITE_REG(cd, CD1400_COR3, MTTY_RX_FIFO_THRESHOLD); 1300 1301 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3); 1302 1303 CD1400_WRITE_REG(cd, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION); 1304 CD1400_WRITE_REG(cd, CD1400_COR5, 0); 1305 1306 /* 1307 * if automatic RTS handshaking enabled, set DTR threshold 1308 * (RTS and DTR lines are switched, CD1400 thinks its DTR) 1309 */ 1310 if (ISSET(t->c_cflag, CRTSCTS)) 1311 mcor1 = MTTY_RX_DTR_THRESHOLD; 1312 1313 /* set up `carrier detect' interrupts */ 1314 if (cd->cd_parmode) { 1315 SET(mcor1, CD1400_MCOR1_DSRzd); 1316 SET(mcor2, CD1400_MCOR2_DSRod); 1317 } else { 1318 SET(mcor1, CD1400_MCOR1_CDzd); 1319 SET(mcor2, CD1400_MCOR2_CDod); 1320 } 1321 1322 CD1400_WRITE_REG(cd, CD1400_MCOR1, mcor1); 1323 CD1400_WRITE_REG(cd, CD1400_MCOR2, mcor2); 1324 1325 /* receive timeout 2ms */ 1326 CD1400_WRITE_REG(cd, CD1400_RTPR, 2); 1327 1328 splx(s); 1329 return (0); 1330 } 1331 1332 /************************************************************************ 1333 * 1334 * MBPP Routines 1335 * 1336 * mbpp_match match one mbpp device 1337 * mbpp_attach attach mbpp devices 1338 * mbppopen open mbpp device 1339 * mbppclose close mbpp device 1340 * mbppread read from mbpp 1341 * mbppwrite write to mbpp 1342 * mbppioctl do ioctl 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 int 1511 mbppkqfilter(dev_t dev, struct knote *kn) 1512 { 1513 return (seltrue_kqfilter(dev, kn)); 1514 } 1515 1516 int 1517 mbpp_rw(dev_t dev, struct uio *uio) 1518 { 1519 int card = MAGMA_CARD(dev); 1520 int port = MAGMA_PORT(dev); 1521 struct mbpp_softc *ms = mbpp_cd.cd_devs[card]; 1522 struct mbpp_port *mp = &ms->ms_port[port]; 1523 caddr_t buffer, ptr; 1524 size_t buflen, cnt, len; 1525 int s, error = 0; 1526 int gotdata = 0; 1527 1528 if (uio->uio_resid == 0) 1529 return (0); 1530 1531 buflen = ulmin(uio->uio_resid, mp->mp_burst); 1532 buffer = malloc(buflen, M_DEVBUF, M_WAITOK); 1533 1534 SET(mp->mp_flags, MBPPF_UIO); 1535 1536 /* 1537 * start timeout, if needed 1538 */ 1539 if (mp->mp_timeout > 0) { 1540 SET(mp->mp_flags, MBPPF_TIMEOUT); 1541 timeout_add_msec(&mp->mp_timeout_tmo, mp->mp_timeout); 1542 } 1543 1544 len = cnt = 0; 1545 while (uio->uio_resid > 0) { 1546 len = ulmin(buflen, uio->uio_resid); 1547 ptr = buffer; 1548 1549 if (uio->uio_rw == UIO_WRITE) { 1550 error = uiomove(ptr, len, uio); 1551 if (error) 1552 break; 1553 } 1554 again: /* goto bad */ 1555 /* timed out? */ 1556 if (!ISSET(mp->mp_flags, MBPPF_UIO)) 1557 break; 1558 1559 /* 1560 * perform the operation 1561 */ 1562 if (uio->uio_rw == UIO_WRITE) { 1563 cnt = mbpp_send(mp, ptr, len); 1564 } else { 1565 cnt = mbpp_recv(mp, ptr, len); 1566 } 1567 1568 if (uio->uio_rw == UIO_READ) { 1569 if (cnt) { 1570 error = uiomove(ptr, cnt, uio); 1571 if (error) 1572 break; 1573 gotdata++; 1574 } 1575 else if (gotdata) /* consider us done */ 1576 break; 1577 } 1578 1579 /* timed out? */ 1580 if (!ISSET(mp->mp_flags, MBPPF_UIO)) 1581 break; 1582 1583 /* 1584 * poll delay? 1585 */ 1586 if (mp->mp_delay > 0) { 1587 s = spltty(); /* XXX */ 1588 SET(mp->mp_flags, MBPPF_DELAY); 1589 timeout_add_msec(&mp->mp_start_tmo, mp->mp_delay); 1590 error = tsleep_nsec(mp, PCATCH | PZERO, "mbppdelay", 1591 INFSLP); 1592 splx(s); 1593 if (error) 1594 break; 1595 } 1596 1597 /* 1598 * don't call uiomove again until we used all the data we grabbed 1599 */ 1600 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1601 ptr += cnt; 1602 len -= cnt; 1603 cnt = 0; 1604 goto again; 1605 } 1606 } 1607 1608 /* 1609 * clear timeouts 1610 */ 1611 s = spltty(); /* XXX */ 1612 if (ISSET(mp->mp_flags, MBPPF_TIMEOUT)) { 1613 timeout_del(&mp->mp_timeout_tmo); 1614 CLR(mp->mp_flags, MBPPF_TIMEOUT); 1615 } 1616 if (ISSET(mp->mp_flags, MBPPF_DELAY)) { 1617 timeout_del(&mp->mp_start_tmo); 1618 CLR(mp->mp_flags, MBPPF_DELAY); 1619 } 1620 splx(s); 1621 1622 /* 1623 * adjust for those chars that we uiomoved but never actually wrote 1624 */ 1625 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1626 uio->uio_resid += (len - cnt); 1627 } 1628 1629 free(buffer, M_DEVBUF, 0); 1630 return (error); 1631 } 1632 1633 void 1634 mbpp_timeout(void *arg) 1635 { 1636 struct mbpp_port *mp = arg; 1637 1638 CLR(mp->mp_flags, MBPPF_UIO | MBPPF_TIMEOUT); 1639 wakeup(mp); 1640 } 1641 1642 void 1643 mbpp_start(void *arg) 1644 { 1645 struct mbpp_port *mp = arg; 1646 1647 CLR(mp->mp_flags, MBPPF_DELAY); 1648 wakeup(mp); 1649 } 1650 1651 int 1652 mbpp_send(struct mbpp_port *mp, caddr_t ptr, int len) 1653 { 1654 int s; 1655 struct cd1400 *cd = mp->mp_cd1400; 1656 1657 /* set up io information */ 1658 mp->mp_ptr = ptr; 1659 mp->mp_cnt = len; 1660 1661 /* start transmitting */ 1662 s = spltty(); 1663 if (cd) { 1664 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1665 1666 /* output strobe width ~1microsecond */ 1667 CD1400_WRITE_REG(cd, CD1400_TBPR, 10); 1668 1669 /* enable channel */ 1670 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN); 1671 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_TXRDY); 1672 } 1673 1674 /* ZZzzz... */ 1675 tsleep_nsec(mp, PCATCH | PZERO, "mbpp_send", INFSLP); 1676 1677 /* stop transmitting */ 1678 if (cd) { 1679 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1680 1681 /* disable transmitter */ 1682 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1683 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTDIS); 1684 1685 /* flush fifo */ 1686 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 1687 } 1688 splx(s); 1689 1690 /* return number of chars sent */ 1691 return (len - mp->mp_cnt); 1692 } 1693 1694 int 1695 mbpp_recv(struct mbpp_port *mp, caddr_t ptr, int len) 1696 { 1697 int s; 1698 struct cd1400 *cd = mp->mp_cd1400; 1699 1700 /* set up io information */ 1701 mp->mp_ptr = ptr; 1702 mp->mp_cnt = len; 1703 1704 /* start receiving */ 1705 s = spltty(); 1706 if (cd) { 1707 int rcor, rbpr; 1708 1709 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1710 1711 /* input strobe at 100kbaud (10microseconds) */ 1712 cd1400_compute_baud(100000, cd->cd_clock, &rcor, &rbpr); 1713 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1714 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1715 1716 /* rx threshold */ 1717 CD1400_WRITE_REG(cd, CD1400_COR3, MBPP_RX_FIFO_THRESHOLD); 1718 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3); 1719 1720 /* enable channel */ 1721 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVEN); 1722 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA); 1723 } 1724 1725 /* ZZzzz... */ 1726 tsleep_nsec(mp, PCATCH | PZERO, "mbpp_recv", INFSLP); 1727 1728 /* stop receiving */ 1729 if (cd) { 1730 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1731 1732 /* disable receiving */ 1733 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1734 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVDIS); 1735 } 1736 splx(s); 1737 1738 /* return number of chars received */ 1739 return (len - mp->mp_cnt); 1740 } 1741