1 /* $OpenBSD: magma.c,v 1.17 2008/11/29 05:56:41 deraadt 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/file.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(); 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) && p->p_ucred->cr_uid != 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", 0); 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)); 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); 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, 0)) 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 if (tp->t_outq.c_cc <= tp->t_lowat) { 1120 if (ISSET(tp->t_state, TS_ASLEEP)) { 1121 CLR(tp->t_state, TS_ASLEEP); 1122 wakeup(&tp->t_outq); 1123 } 1124 1125 selwakeup(&tp->t_wsel); 1126 } 1127 1128 /* if something to send, start transmitting 1129 */ 1130 if (tp->t_outq.c_cc) { 1131 mp->mp_txc = ndqb(&tp->t_outq, 0); 1132 mp->mp_txp = tp->t_outq.c_cf; 1133 SET(tp->t_state, TS_BUSY); 1134 cd1400_enable_transmitter(mp->mp_cd1400, mp->mp_channel); 1135 } 1136 } 1137 1138 splx(s); 1139 } 1140 1141 /* 1142 * set/get modem line status 1143 * 1144 * bits can be: TIOCM_DTR, TIOCM_RTS, TIOCM_CTS, TIOCM_CD, TIOCM_RI, TIOCM_DSR 1145 * 1146 * note that DTR and RTS lines are exchanged, and that DSR is 1147 * not available on the LC2+1Sp card (used as CD) 1148 * 1149 * only let them fiddle with RTS if CRTSCTS is not enabled 1150 */ 1151 int 1152 mtty_modem_control(struct mtty_port *mp, int bits, int howto) 1153 { 1154 struct cd1400 *cd = mp->mp_cd1400; 1155 struct tty *tp = mp->mp_tty; 1156 int s, msvr; 1157 1158 s = spltty(); 1159 1160 CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); 1161 1162 switch(howto) { 1163 case DMGET: /* get bits */ 1164 bits = 0; 1165 1166 bits |= TIOCM_LE; 1167 1168 msvr = CD1400_READ_REG(cd, CD1400_MSVR1); 1169 if (msvr & CD1400_MSVR1_RTS) 1170 bits |= TIOCM_DTR; 1171 1172 msvr = CD1400_READ_REG(cd, CD1400_MSVR2); 1173 if (msvr & CD1400_MSVR2_DTR) 1174 bits |= TIOCM_RTS; 1175 if (msvr & CD1400_MSVR2_CTS) 1176 bits |= TIOCM_CTS; 1177 if (msvr & CD1400_MSVR2_RI) 1178 bits |= TIOCM_RI; 1179 if (msvr & CD1400_MSVR2_DSR) 1180 bits |= (cd->cd_parmode ? TIOCM_CD : TIOCM_DSR); 1181 if (msvr & CD1400_MSVR2_CD) 1182 bits |= (cd->cd_parmode ? 0 : TIOCM_CD); 1183 1184 break; 1185 1186 case DMSET: /* reset bits */ 1187 if (!ISSET(tp->t_cflag, CRTSCTS)) 1188 CD1400_WRITE_REG(cd, CD1400_MSVR2, 1189 ((bits & TIOCM_RTS) ? CD1400_MSVR2_DTR : 0)); 1190 1191 CD1400_WRITE_REG(cd, CD1400_MSVR1, 1192 ((bits & TIOCM_DTR) ? CD1400_MSVR1_RTS : 0)); 1193 1194 break; 1195 1196 case DMBIS: /* set bits */ 1197 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1198 CD1400_WRITE_REG(cd, CD1400_MSVR2, CD1400_MSVR2_DTR); 1199 1200 if (bits & TIOCM_DTR) 1201 CD1400_WRITE_REG(cd, CD1400_MSVR1, CD1400_MSVR1_RTS); 1202 1203 break; 1204 1205 case DMBIC: /* clear bits */ 1206 if ((bits & TIOCM_RTS) && !ISSET(tp->t_cflag, CRTSCTS)) 1207 CD1400_WRITE_REG(cd, CD1400_MSVR2, 0); 1208 1209 if (bits & TIOCM_DTR) 1210 CD1400_WRITE_REG(cd, CD1400_MSVR1, 0); 1211 1212 break; 1213 } 1214 1215 splx(s); 1216 return (bits); 1217 } 1218 1219 /* 1220 * Set tty parameters, returns error or 0 on success 1221 */ 1222 int 1223 mtty_param(struct tty *tp, struct termios *t) 1224 { 1225 struct mtty_softc *ms = mtty_cd.cd_devs[MAGMA_CARD(tp->t_dev)]; 1226 struct mtty_port *mp = &ms->ms_port[MAGMA_PORT(tp->t_dev)]; 1227 struct cd1400 *cd = mp->mp_cd1400; 1228 int rbpr, tbpr, rcor, tcor; 1229 u_char mcor1 = 0, mcor2 = 0; 1230 int s, opt; 1231 1232 if (t->c_ospeed && 1233 cd1400_compute_baud(t->c_ospeed, cd->cd_clock, &tcor, &tbpr)) 1234 return (EINVAL); 1235 1236 if (t->c_ispeed && 1237 cd1400_compute_baud(t->c_ispeed, cd->cd_clock, &rcor, &rbpr)) 1238 return (EINVAL); 1239 1240 s = spltty(); 1241 1242 /* hang up the line if ospeed is zero, else raise DTR */ 1243 (void)mtty_modem_control(mp, TIOCM_DTR, 1244 (t->c_ospeed == 0 ? DMBIC : DMBIS)); 1245 1246 /* select channel, done in mtty_modem_control() */ 1247 /* CD1400_WRITE_REG(cd, CD1400_CAR, mp->mp_channel); */ 1248 1249 /* set transmit speed */ 1250 if (t->c_ospeed) { 1251 CD1400_WRITE_REG(cd, CD1400_TCOR, tcor); 1252 CD1400_WRITE_REG(cd, CD1400_TBPR, tbpr); 1253 } 1254 1255 /* set receive speed */ 1256 if (t->c_ispeed) { 1257 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1258 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1259 } 1260 1261 /* enable transmitting and receiving on this channel */ 1262 opt = CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN | CD1400_CCR_RCVEN; 1263 cd1400_write_ccr(cd, opt); 1264 1265 /* set parity, data and stop bits */ 1266 opt = 0; 1267 if (ISSET(t->c_cflag, PARENB)) 1268 opt |= (ISSET(t->c_cflag, PARODD) ? CD1400_COR1_PARODD : CD1400_COR1_PARNORMAL); 1269 1270 if (!ISSET(t->c_iflag, INPCK)) 1271 opt |= CD1400_COR1_NOINPCK; /* no parity checking */ 1272 1273 if (ISSET(t->c_cflag, CSTOPB)) 1274 opt |= CD1400_COR1_STOP2; 1275 1276 switch( t->c_cflag & CSIZE) { 1277 case CS5: 1278 opt |= CD1400_COR1_CS5; 1279 break; 1280 1281 case CS6: 1282 opt |= CD1400_COR1_CS6; 1283 break; 1284 1285 case CS7: 1286 opt |= CD1400_COR1_CS7; 1287 break; 1288 1289 default: 1290 opt |= CD1400_COR1_CS8; 1291 break; 1292 } 1293 1294 CD1400_WRITE_REG(cd, CD1400_COR1, opt); 1295 1296 /* 1297 * enable Embedded Transmit Commands (for breaks) 1298 * use the CD1400 automatic CTS flow control if CRTSCTS is set 1299 */ 1300 opt = CD1400_COR2_ETC; 1301 if (ISSET(t->c_cflag, CRTSCTS)) 1302 opt |= CD1400_COR2_CCTS_OFLOW; 1303 CD1400_WRITE_REG(cd, CD1400_COR2, opt); 1304 1305 CD1400_WRITE_REG(cd, CD1400_COR3, MTTY_RX_FIFO_THRESHOLD); 1306 1307 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR1 | CD1400_CCR_COR2 | CD1400_CCR_COR3); 1308 1309 CD1400_WRITE_REG(cd, CD1400_COR4, CD1400_COR4_PFO_EXCEPTION); 1310 CD1400_WRITE_REG(cd, CD1400_COR5, 0); 1311 1312 /* 1313 * if automatic RTS handshaking enabled, set DTR threshold 1314 * (RTS and DTR lines are switched, CD1400 thinks its DTR) 1315 */ 1316 if (ISSET(t->c_cflag, CRTSCTS)) 1317 mcor1 = MTTY_RX_DTR_THRESHOLD; 1318 1319 /* set up `carrier detect' interrupts */ 1320 if (cd->cd_parmode) { 1321 SET(mcor1, CD1400_MCOR1_DSRzd); 1322 SET(mcor2, CD1400_MCOR2_DSRod); 1323 } else { 1324 SET(mcor1, CD1400_MCOR1_CDzd); 1325 SET(mcor2, CD1400_MCOR2_CDod); 1326 } 1327 1328 CD1400_WRITE_REG(cd, CD1400_MCOR1, mcor1); 1329 CD1400_WRITE_REG(cd, CD1400_MCOR2, mcor2); 1330 1331 /* receive timeout 2ms */ 1332 CD1400_WRITE_REG(cd, CD1400_RTPR, 2); 1333 1334 splx(s); 1335 return (0); 1336 } 1337 1338 /************************************************************************ 1339 * 1340 * MBPP Routines 1341 * 1342 * mbpp_match match one mbpp device 1343 * mbpp_attach attach mbpp devices 1344 * mbppopen open mbpp device 1345 * mbppclose close mbpp device 1346 * mbppread read from mbpp 1347 * mbppwrite write to mbpp 1348 * mbppioctl do ioctl on mbpp 1349 * mbpppoll do poll on mbpp 1350 * mbpp_rw general rw routine 1351 * mbpp_timeout rw timeout 1352 * mbpp_start rw start after delay 1353 * mbpp_send send data 1354 * mbpp_recv recv data 1355 */ 1356 1357 int 1358 mbpp_match(struct device *parent, void *vcf, void *args) 1359 { 1360 struct magma_softc *sc = (struct magma_softc *)parent; 1361 1362 return (args == mbpp_match && sc->ms_board->mb_npar && 1363 sc->ms_mbpp == NULL); 1364 } 1365 1366 void 1367 mbpp_attach(struct device *parent, struct device *dev, void *args) 1368 { 1369 struct magma_softc *sc = (struct magma_softc *)parent; 1370 struct mbpp_softc *ms = (struct mbpp_softc *)dev; 1371 struct mbpp_port *mp; 1372 int port; 1373 1374 sc->ms_mbpp = ms; 1375 dprintf((" addr 0x%x", ms)); 1376 1377 for (port = 0 ; port < sc->ms_board->mb_npar ; port++) { 1378 mp = &ms->ms_port[port]; 1379 1380 if (sc->ms_ncd1190) 1381 mp->mp_cd1190 = &sc->ms_cd1190[port]; 1382 else 1383 mp->mp_cd1400 = &sc->ms_cd1400[0]; 1384 1385 timeout_set(&mp->mp_timeout_tmo, mbpp_timeout, mp); 1386 timeout_set(&mp->mp_start_tmo, mbpp_start, mp); 1387 } 1388 1389 ms->ms_nports = port; 1390 printf(": %d port%s\n", port, port == 1 ? "" : "s"); 1391 } 1392 1393 /* 1394 * open routine. returns zero if successful, else error code 1395 */ 1396 int 1397 mbppopen(dev_t dev, int flags, int mode, struct proc *p) 1398 { 1399 int card = MAGMA_CARD(dev); 1400 int port = MAGMA_PORT(dev); 1401 struct mbpp_softc *ms; 1402 struct mbpp_port *mp; 1403 int s; 1404 1405 if (card >= mbpp_cd.cd_ndevs || (ms = mbpp_cd.cd_devs[card]) == NULL || port >= ms->ms_nports) 1406 return (ENXIO); 1407 1408 mp = &ms->ms_port[port]; 1409 1410 s = spltty(); 1411 if (ISSET(mp->mp_flags, MBPPF_OPEN)) { 1412 splx(s); 1413 return (EBUSY); 1414 } 1415 SET(mp->mp_flags, MBPPF_OPEN); 1416 splx(s); 1417 1418 /* set defaults */ 1419 mp->mp_burst = BPP_BURST; 1420 mp->mp_timeout = mbpp_mstohz(BPP_TIMEOUT); 1421 mp->mp_delay = mbpp_mstohz(BPP_DELAY); 1422 1423 /* init chips */ 1424 if (mp->mp_cd1400) { /* CD1400 */ 1425 struct cd1400 *cd = mp->mp_cd1400; 1426 1427 /* set up CD1400 channel */ 1428 s = spltty(); 1429 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1430 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET); 1431 CD1400_WRITE_REG(cd, CD1400_LIVR, (1<<3)); 1432 splx(s); 1433 } else { /* CD1190 */ 1434 mp->mp_flags = 0; 1435 return (ENXIO); 1436 } 1437 1438 return (0); 1439 } 1440 1441 /* 1442 * close routine. returns zero if successful, else error code 1443 */ 1444 int 1445 mbppclose(dev_t dev, int flag, int mode, struct proc *p) 1446 { 1447 struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)]; 1448 struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1449 1450 mp->mp_flags = 0; 1451 return (0); 1452 } 1453 1454 /* 1455 * Read routine 1456 */ 1457 int 1458 mbppread(dev_t dev, struct uio *uio, int flags) 1459 { 1460 return (mbpp_rw(dev, uio)); 1461 } 1462 1463 /* 1464 * Write routine 1465 */ 1466 int 1467 mbppwrite(dev_t dev, struct uio *uio, int flags) 1468 { 1469 return (mbpp_rw(dev, uio)); 1470 } 1471 1472 /* 1473 * ioctl routine 1474 */ 1475 int 1476 mbppioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) 1477 { 1478 struct mbpp_softc *ms = mbpp_cd.cd_devs[MAGMA_CARD(dev)]; 1479 struct mbpp_port *mp = &ms->ms_port[MAGMA_PORT(dev)]; 1480 struct bpp_param *bp; 1481 int error = 0; 1482 int s; 1483 1484 switch(cmd) { 1485 case BPPIOCSPARAM: 1486 bp = (struct bpp_param *)data; 1487 if (bp->bp_burst < BPP_BURST_MIN || bp->bp_burst > BPP_BURST_MAX || 1488 bp->bp_delay < BPP_DELAY_MIN || bp->bp_delay > BPP_DELAY_MIN) { 1489 error = EINVAL; 1490 } else { 1491 mp->mp_burst = bp->bp_burst; 1492 mp->mp_timeout = mbpp_mstohz(bp->bp_timeout); 1493 mp->mp_delay = mbpp_mstohz(bp->bp_delay); 1494 } 1495 break; 1496 case BPPIOCGPARAM: 1497 bp = (struct bpp_param *)data; 1498 bp->bp_burst = mp->mp_burst; 1499 bp->bp_timeout = mbpp_hztoms(mp->mp_timeout); 1500 bp->bp_delay = mbpp_hztoms(mp->mp_delay); 1501 break; 1502 case BPPIOCGSTAT: 1503 /* XXX make this more generic */ 1504 s = spltty(); 1505 CD1400_WRITE_REG(mp->mp_cd1400, CD1400_CAR, 0); 1506 *(int *)data = CD1400_READ_REG(mp->mp_cd1400, CD1400_PSVR); 1507 splx(s); 1508 break; 1509 default: 1510 error = ENOTTY; 1511 } 1512 1513 return (error); 1514 } 1515 1516 /* 1517 * poll routine 1518 */ 1519 int 1520 mbpppoll(dev_t dev, int events, struct proc *p) 1521 { 1522 return (seltrue(dev, events, p)); 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 int 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 = min(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(&mp->mp_timeout_tmo, mp->mp_timeout); 1551 } 1552 1553 len = cnt = 0; 1554 while (uio->uio_resid > 0) { 1555 len = min(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(&mp->mp_start_tmo, mp->mp_delay); 1599 error = tsleep(mp, PCATCH | PZERO, "mbppdelay", 0); 1600 splx(s); 1601 if (error) 1602 break; 1603 } 1604 1605 /* 1606 * don't call uiomove again until we used all the data we grabbed 1607 */ 1608 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1609 ptr += cnt; 1610 len -= cnt; 1611 cnt = 0; 1612 goto again; 1613 } 1614 } 1615 1616 /* 1617 * clear timeouts 1618 */ 1619 s = spltty(); /* XXX */ 1620 if (ISSET(mp->mp_flags, MBPPF_TIMEOUT)) { 1621 timeout_del(&mp->mp_timeout_tmo); 1622 CLR(mp->mp_flags, MBPPF_TIMEOUT); 1623 } 1624 if (ISSET(mp->mp_flags, MBPPF_DELAY)) { 1625 timeout_del(&mp->mp_start_tmo); 1626 CLR(mp->mp_flags, MBPPF_DELAY); 1627 } 1628 splx(s); 1629 1630 /* 1631 * adjust for those chars that we uiomoved but never actually wrote 1632 */ 1633 if (uio->uio_rw == UIO_WRITE && cnt != len) { 1634 uio->uio_resid += (len - cnt); 1635 } 1636 1637 free(buffer, M_DEVBUF); 1638 return (error); 1639 } 1640 1641 void 1642 mbpp_timeout(void *arg) 1643 { 1644 struct mbpp_port *mp = arg; 1645 1646 CLR(mp->mp_flags, MBPPF_UIO | MBPPF_TIMEOUT); 1647 wakeup(mp); 1648 } 1649 1650 void 1651 mbpp_start(void *arg) 1652 { 1653 struct mbpp_port *mp = arg; 1654 1655 CLR(mp->mp_flags, MBPPF_DELAY); 1656 wakeup(mp); 1657 } 1658 1659 int 1660 mbpp_send(struct mbpp_port *mp, caddr_t ptr, int len) 1661 { 1662 int s; 1663 struct cd1400 *cd = mp->mp_cd1400; 1664 1665 /* set up io information */ 1666 mp->mp_ptr = ptr; 1667 mp->mp_cnt = len; 1668 1669 /* start transmitting */ 1670 s = spltty(); 1671 if (cd) { 1672 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1673 1674 /* output strobe width ~1microsecond */ 1675 CD1400_WRITE_REG(cd, CD1400_TBPR, 10); 1676 1677 /* enable channel */ 1678 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTEN); 1679 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_TXRDY); 1680 } 1681 1682 /* ZZzzz... */ 1683 tsleep(mp, PCATCH | PZERO, "mbpp_send", 0); 1684 1685 /* stop transmitting */ 1686 if (cd) { 1687 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1688 1689 /* disable transmitter */ 1690 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1691 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_XMTDIS); 1692 1693 /* flush fifo */ 1694 cd1400_write_ccr(cd, CD1400_CCR_CMDRESET | CD1400_CCR_FTF); 1695 } 1696 splx(s); 1697 1698 /* return number of chars sent */ 1699 return (len - mp->mp_cnt); 1700 } 1701 1702 int 1703 mbpp_recv(struct mbpp_port *mp, caddr_t ptr, int len) 1704 { 1705 int s; 1706 struct cd1400 *cd = mp->mp_cd1400; 1707 1708 /* set up io information */ 1709 mp->mp_ptr = ptr; 1710 mp->mp_cnt = len; 1711 1712 /* start receiving */ 1713 s = spltty(); 1714 if (cd) { 1715 int rcor, rbpr; 1716 1717 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1718 1719 /* input strobe at 100kbaud (10microseconds) */ 1720 cd1400_compute_baud(100000, cd->cd_clock, &rcor, &rbpr); 1721 CD1400_WRITE_REG(cd, CD1400_RCOR, rcor); 1722 CD1400_WRITE_REG(cd, CD1400_RBPR, rbpr); 1723 1724 /* rx threshold */ 1725 CD1400_WRITE_REG(cd, CD1400_COR3, MBPP_RX_FIFO_THRESHOLD); 1726 cd1400_write_ccr(cd, CD1400_CCR_CMDCORCHG | CD1400_CCR_COR3); 1727 1728 /* enable channel */ 1729 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVEN); 1730 CD1400_WRITE_REG(cd, CD1400_SRER, CD1400_SRER_RXDATA); 1731 } 1732 1733 /* ZZzzz... */ 1734 tsleep(mp, PCATCH | PZERO, "mbpp_recv", 0); 1735 1736 /* stop receiving */ 1737 if (cd) { 1738 CD1400_WRITE_REG(cd, CD1400_CAR, 0); 1739 1740 /* disable receiving */ 1741 CD1400_WRITE_REG(cd, CD1400_SRER, 0); 1742 cd1400_write_ccr(cd, CD1400_CCR_CMDCHANCTL | CD1400_CCR_RCVDIS); 1743 } 1744 splx(s); 1745 1746 /* return number of chars received */ 1747 return (len - mp->mp_cnt); 1748 } 1749 1750 int 1751 mbpp_hztoms(int h) 1752 { 1753 int m = h; 1754 1755 if (m > 0) 1756 m = m * 1000 / hz; 1757 return (m); 1758 } 1759 1760 int 1761 mbpp_mstohz(int m) 1762 { 1763 int h = m; 1764 1765 if (h > 0) { 1766 h = h * hz / 1000; 1767 if (h == 0) 1768 h = 1000 / hz; 1769 } 1770 return (h); 1771 } 1772