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