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