1 /* 2 * Copyright (c) 1988 University of Utah. 3 * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. 4 * All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * the Systems Programming Group of the University of Utah Computer 8 * Science Department. 9 * 10 * %sccs.include.redist.c% 11 * 12 * from: $Hdr: dcm.c 1.26 91/01/21$ 13 * 14 * @(#)dcm.c 7.14 (Berkeley) 06/27/91 15 */ 16 17 /* 18 * TODO: 19 * Timeouts 20 * Test console support. 21 */ 22 23 #include "dcm.h" 24 #if NDCM > 0 25 /* 26 * 98642/MUX 27 */ 28 #include "sys/param.h" 29 #include "sys/systm.h" 30 #include "sys/ioctl.h" 31 #include "sys/tty.h" 32 #include "sys/proc.h" 33 #include "sys/conf.h" 34 #include "sys/file.h" 35 #include "sys/uio.h" 36 #include "sys/kernel.h" 37 #include "sys/syslog.h" 38 #include "sys/time.h" 39 40 #include "device.h" 41 #include "dcmreg.h" 42 #include "machine/cpu.h" 43 #include "../hp300/isr.h" 44 45 #ifndef DEFAULT_BAUD_RATE 46 #define DEFAULT_BAUD_RATE 9600 47 #endif 48 49 int ttrstrt(); 50 int dcmprobe(), dcmstart(), dcmintr(), dcmparam(); 51 52 struct driver dcmdriver = { 53 dcmprobe, "dcm", 54 }; 55 56 #define NDCMLINE (NDCM*4) 57 58 struct tty dcm_tty[NDCMLINE]; 59 struct modemreg *dcm_modem[NDCMLINE]; 60 char mcndlast[NDCMLINE]; /* XXX last modem status for line */ 61 int ndcm = NDCMLINE; 62 63 int dcm_active; 64 int dcmsoftCAR[NDCM]; 65 struct dcmdevice *dcm_addr[NDCM]; 66 struct isr dcmisr[NDCM]; 67 68 struct speedtab dcmspeedtab[] = { 69 0, BR_0, 70 50, BR_50, 71 75, BR_75, 72 110, BR_110, 73 134, BR_134, 74 150, BR_150, 75 300, BR_300, 76 600, BR_600, 77 1200, BR_1200, 78 1800, BR_1800, 79 2400, BR_2400, 80 4800, BR_4800, 81 9600, BR_9600, 82 19200, BR_19200, 83 38400, BR_38400, 84 -1, -1 85 }; 86 87 /* u-sec per character based on baudrate (assumes 1 start/8 data/1 stop bit) */ 88 #define DCM_USPERCH(s) (10000000 / (s)) 89 90 /* 91 * Per board interrupt scheme. 16.7ms is the polling interrupt rate 92 * (16.7ms is about 550 baud, 38.4k is 72 chars in 16.7ms). 93 */ 94 #define DIS_TIMER 0 95 #define DIS_PERCHAR 1 96 #define DIS_RESET 2 97 98 int dcmistype = -1; /* -1 == dynamic, 0 == timer, 1 == perchar */ 99 int dcminterval = 5; /* interval (secs) between checks */ 100 struct dcmischeme { 101 int dis_perchar; /* non-zero if interrupting per char */ 102 long dis_time; /* last time examined */ 103 int dis_intr; /* recv interrupts during last interval */ 104 int dis_char; /* characters read during last interval */ 105 } dcmischeme[NDCM]; 106 107 /* 108 * Console support 109 */ 110 #ifdef DCMCONSOLE 111 int dcmconsole = DCMCONSOLE; 112 #else 113 int dcmconsole = -1; 114 #endif 115 int dcmconsinit; 116 int dcmdefaultrate = DEFAULT_BAUD_RATE; 117 int dcmconbrdbusy = 0; 118 int dcmmajor; 119 extern struct tty *constty; 120 121 #ifdef KGDB 122 /* 123 * Kernel GDB support 124 */ 125 #include "machine/remote-sl.h" 126 127 extern dev_t kgdb_dev; 128 extern int kgdb_rate; 129 extern int kgdb_debug_init; 130 #endif 131 132 /* #define IOSTATS */ 133 134 #ifdef DEBUG 135 int dcmdebug = 0x0; 136 #define DDB_SIOERR 0x01 137 #define DDB_PARAM 0x02 138 #define DDB_INPUT 0x04 139 #define DDB_OUTPUT 0x08 140 #define DDB_INTR 0x10 141 #define DDB_IOCTL 0x20 142 #define DDB_INTSCHM 0x40 143 #define DDB_MODEM 0x80 144 #define DDB_OPENCLOSE 0x100 145 #endif 146 147 #ifdef IOSTATS 148 #define DCMRBSIZE 94 149 #define DCMXBSIZE 24 150 151 struct dcmstats { 152 long xints; /* # of xmit ints */ 153 long xchars; /* # of xmit chars */ 154 long xempty; /* times outq is empty in dcmstart */ 155 long xrestarts; /* times completed while xmitting */ 156 long rints; /* # of recv ints */ 157 long rchars; /* # of recv chars */ 158 long xsilo[DCMXBSIZE+2]; /* times this many chars xmit on one int */ 159 long rsilo[DCMRBSIZE+2]; /* times this many chars read on one int */ 160 } dcmstats[NDCM]; 161 #endif 162 163 #define UNIT(x) minor(x) 164 #define BOARD(x) (((x) >> 2) & 0x3f) 165 #define PORT(x) ((x) & 3) 166 #define MKUNIT(b,p) (((b) << 2) | (p)) 167 168 /* 169 * Conversion from "HP DCE" to almost-normal DCE: on the 638 8-port mux, 170 * the distribution panel uses "HP DCE" conventions. If requested via 171 * the device flags, we swap the inputs to something closer to normal DCE, 172 * allowing a straight-through cable to a DTE or a reversed cable 173 * to a DCE (reversing 2-3, 4-5, 8-20 and leaving 6 unconnected; 174 * this gets "DCD" on pin 20 and "CTS" on 4, but doesn't connect 175 * DSR or make RTS work, though). The following gives the full 176 * details of a cable from this mux panel to a modem: 177 * 178 * HP modem 179 * name pin pin name 180 * HP inputs: 181 * "Rx" 2 3 Tx 182 * CTS 4 5 CTS (only needed for CCTS_OFLOW) 183 * DCD 20 8 DCD 184 * "DSR" 9 6 DSR (unneeded) 185 * RI 22 22 RI (unneeded) 186 * 187 * HP outputs: 188 * "Tx" 3 2 Rx 189 * "DTR" 6 not connected 190 * "RTS" 8 20 DTR 191 * "SR" 23 4 RTS (often not needed) 192 */ 193 #define FLAG_STDDCE 0x10 /* map inputs if this bit is set in flags */ 194 #define hp2dce_in(ibits) (iconv[(ibits) & 0xf]) 195 static char iconv[16] = { 196 0, MI_DM, MI_CTS, MI_CTS|MI_DM, 197 MI_CD, MI_CD|MI_DM, MI_CD|MI_CTS, MI_CD|MI_CTS|MI_DM, 198 MI_RI, MI_RI|MI_DM, MI_RI|MI_CTS, MI_RI|MI_CTS|MI_DM, 199 MI_RI|MI_CD, MI_RI|MI_CD|MI_DM, MI_RI|MI_CD|MI_CTS, 200 MI_RI|MI_CD|MI_CTS|MI_DM 201 }; 202 203 dcmprobe(hd) 204 register struct hp_device *hd; 205 { 206 register struct dcmdevice *dcm; 207 register int i; 208 register int timo = 0; 209 int s, brd, isconsole, mbits; 210 211 dcm = (struct dcmdevice *)hd->hp_addr; 212 if ((dcm->dcm_rsid & 0x1f) != DCMID) 213 return (0); 214 brd = hd->hp_unit; 215 isconsole = (brd == BOARD(dcmconsole)); 216 /* 217 * XXX selected console device (CONSUNIT) as determined by 218 * dcmcnprobe does not agree with logical numbering imposed 219 * by the config file (i.e. lowest address DCM is not unit 220 * CONSUNIT). Don't recognize this card. 221 */ 222 if (isconsole && dcm != dcm_addr[BOARD(dcmconsole)]) 223 return (0); 224 225 /* 226 * Empirically derived self-test magic 227 */ 228 s = spltty(); 229 dcm->dcm_rsid = DCMRS; 230 DELAY(50000); /* 5000 is not long enough */ 231 dcm->dcm_rsid = 0; 232 dcm->dcm_ic = IC_IE; 233 dcm->dcm_cr = CR_SELFT; 234 while ((dcm->dcm_ic & IC_IR) == 0) 235 if (++timo == 20000) 236 return (0); 237 DELAY(50000) /* XXX why is this needed ???? */ 238 while ((dcm->dcm_iir & IIR_SELFT) == 0) 239 if (++timo == 400000) 240 return (0); 241 DELAY(50000) /* XXX why is this needed ???? */ 242 if (dcm->dcm_stcon != ST_OK) { 243 if (!isconsole) 244 printf("dcm%d: self test failed: %x\n", 245 brd, dcm->dcm_stcon); 246 return (0); 247 } 248 dcm->dcm_ic = IC_ID; 249 splx(s); 250 251 hd->hp_ipl = DCMIPL(dcm->dcm_ic); 252 dcm_addr[brd] = dcm; 253 dcm_active |= 1 << brd; 254 dcmsoftCAR[brd] = hd->hp_flags; 255 dcmisr[brd].isr_ipl = hd->hp_ipl; 256 dcmisr[brd].isr_arg = brd; 257 dcmisr[brd].isr_intr = dcmintr; 258 isrlink(&dcmisr[brd]); 259 #ifdef KGDB 260 if (major(kgdb_dev) == dcmmajor && BOARD(kgdb_dev) == brd) { 261 if (dcmconsole == UNIT(kgdb_dev)) 262 kgdb_dev = NODEV; /* can't debug over console port */ 263 #ifndef KGDB_CHEAT 264 /* 265 * The following could potentially be replaced 266 * by the corresponding code in dcmcnprobe. 267 */ 268 else { 269 (void) dcminit(kgdb_dev, kgdb_rate); 270 if (kgdb_debug_init) { 271 printf("dcm%d: ", UNIT(kgdb_dev)); 272 kgdb_connect(1); 273 } else 274 printf("dcm%d: kgdb enabled\n", UNIT(kgdb_dev)); 275 } 276 /* end could be replaced */ 277 #endif 278 } 279 #endif 280 if (dcmistype == DIS_TIMER) 281 dcmsetischeme(brd, DIS_RESET|DIS_TIMER); 282 else 283 dcmsetischeme(brd, DIS_RESET|DIS_PERCHAR); 284 285 /* load pointers to modem control */ 286 dcm_modem[MKUNIT(brd, 0)] = &dcm->dcm_modem0; 287 dcm_modem[MKUNIT(brd, 1)] = &dcm->dcm_modem1; 288 dcm_modem[MKUNIT(brd, 2)] = &dcm->dcm_modem2; 289 dcm_modem[MKUNIT(brd, 3)] = &dcm->dcm_modem3; 290 /* set DCD (modem) and CTS (flow control) on all ports */ 291 if (dcmsoftCAR[brd] & FLAG_STDDCE) 292 mbits = hp2dce_in(MI_CD|MI_CTS); 293 else 294 mbits = MI_CD|MI_CTS; 295 for (i = 0; i < 4; i++) 296 dcm_modem[MKUNIT(brd, i)]->mdmmsk = mbits; 297 298 dcm->dcm_ic = IC_IE; /* turn all interrupts on */ 299 /* 300 * Need to reset baud rate, etc. of next print so reset dcmconsole. 301 * Also make sure console is always "hardwired" 302 */ 303 if (isconsole) { 304 dcmconsinit = 0; 305 dcmsoftCAR[brd] |= (1 << PORT(dcmconsole)); 306 } 307 return (1); 308 } 309 310 /* ARGSUSED */ 311 #ifdef __STDC__ 312 dcmopen(dev_t dev, int flag, int mode, struct proc *p) 313 #else 314 dcmopen(dev, flag, mode, p) 315 dev_t dev; 316 int flag, mode; 317 struct proc *p; 318 #endif 319 { 320 register struct tty *tp; 321 register int unit, brd; 322 int error = 0, mbits; 323 324 unit = UNIT(dev); 325 brd = BOARD(unit); 326 if (unit >= NDCMLINE || (dcm_active & (1 << brd)) == 0) 327 return (ENXIO); 328 tp = &dcm_tty[unit]; 329 tp->t_oproc = dcmstart; 330 tp->t_param = dcmparam; 331 tp->t_dev = dev; 332 if ((tp->t_state & TS_ISOPEN) == 0) { 333 tp->t_state |= TS_WOPEN; 334 ttychars(tp); 335 if (tp->t_ispeed == 0) { 336 tp->t_iflag = TTYDEF_IFLAG; 337 tp->t_oflag = TTYDEF_OFLAG; 338 tp->t_cflag = TTYDEF_CFLAG; 339 tp->t_lflag = TTYDEF_LFLAG; 340 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; 341 } 342 (void) dcmparam(tp, &tp->t_termios); 343 ttsetwater(tp); 344 } else if (tp->t_state&TS_XCLUDE && p->p_ucred->cr_uid != 0) 345 return (EBUSY); 346 mbits = MO_ON; 347 if (dcmsoftCAR[brd] & FLAG_STDDCE) 348 mbits |= MO_SR; /* pin 23, could be used as RTS */ 349 (void) dcmmctl(dev, mbits, DMSET); /* enable port */ 350 if ((dcmsoftCAR[brd] & (1 << PORT(unit))) || 351 (dcmmctl(dev, MO_OFF, DMGET) & MI_CD)) 352 tp->t_state |= TS_CARR_ON; 353 #ifdef DEBUG 354 if (dcmdebug & DDB_MODEM) 355 printf("dcm%d: dcmopen port %d softcarr %c\n", 356 brd, unit, (tp->t_state & TS_CARR_ON) ? '1' : '0'); 357 #endif 358 (void) spltty(); 359 while ((flag&O_NONBLOCK) == 0 && (tp->t_cflag&CLOCAL) == 0 && 360 (tp->t_state & TS_CARR_ON) == 0) { 361 tp->t_state |= TS_WOPEN; 362 if (error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, 363 ttopen, 0)) 364 break; 365 } 366 (void) spl0(); 367 368 #ifdef DEBUG 369 if (dcmdebug & DDB_OPENCLOSE) 370 printf("dcmopen: u %x st %x fl %x\n", 371 unit, tp->t_state, tp->t_flags); 372 #endif 373 if (error == 0) 374 error = (*linesw[tp->t_line].l_open)(dev, tp); 375 return (error); 376 } 377 378 /*ARGSUSED*/ 379 dcmclose(dev, flag, mode, p) 380 dev_t dev; 381 int flag, mode; 382 struct proc *p; 383 { 384 register struct tty *tp; 385 int unit; 386 387 unit = UNIT(dev); 388 tp = &dcm_tty[unit]; 389 (*linesw[tp->t_line].l_close)(tp, flag); 390 if (tp->t_cflag&HUPCL || tp->t_state&TS_WOPEN || 391 (tp->t_state&TS_ISOPEN) == 0) 392 (void) dcmmctl(dev, MO_OFF, DMSET); 393 #ifdef DEBUG 394 if (dcmdebug & DDB_OPENCLOSE) 395 printf("dcmclose: u %x st %x fl %x\n", 396 unit, tp->t_state, tp->t_flags); 397 #endif 398 ttyclose(tp); 399 return (0); 400 } 401 402 dcmread(dev, uio, flag) 403 dev_t dev; 404 struct uio *uio; 405 { 406 register struct tty *tp; 407 408 tp = &dcm_tty[UNIT(dev)]; 409 return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); 410 } 411 412 dcmwrite(dev, uio, flag) 413 dev_t dev; 414 struct uio *uio; 415 { 416 int unit = UNIT(dev); 417 register struct tty *tp; 418 419 tp = &dcm_tty[unit]; 420 /* 421 * XXX we disallow virtual consoles if the physical console is 422 * a serial port. This is in case there is a display attached that 423 * is not the console. In that situation we don't need/want the X 424 * server taking over the console. 425 */ 426 if (constty && unit == dcmconsole) 427 constty = NULL; 428 return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); 429 } 430 431 dcmintr(brd) 432 register int brd; 433 { 434 register struct dcmdevice *dcm = dcm_addr[brd]; 435 register struct dcmischeme *dis; 436 register int unit = MKUNIT(brd, 0); 437 register int code, i; 438 int pcnd[4], mcode, mcnd[4]; 439 440 /* 441 * Do all guarded register accesses right off to minimize 442 * block out of hardware. 443 */ 444 SEM_LOCK(dcm); 445 if ((dcm->dcm_ic & IC_IR) == 0) { 446 SEM_UNLOCK(dcm); 447 return (0); 448 } 449 for (i = 0; i < 4; i++) { 450 pcnd[i] = dcm->dcm_icrtab[i].dcm_data; 451 dcm->dcm_icrtab[i].dcm_data = 0; 452 code = dcm_modem[unit+i]->mdmin; 453 if (dcmsoftCAR[brd] & FLAG_STDDCE) 454 code = hp2dce_in(code); 455 mcnd[i] = code; 456 } 457 code = dcm->dcm_iir & IIR_MASK; 458 dcm->dcm_iir = 0; /* XXX doc claims read clears interrupt?! */ 459 mcode = dcm->dcm_modemintr; 460 dcm->dcm_modemintr = 0; 461 SEM_UNLOCK(dcm); 462 463 #ifdef DEBUG 464 if (dcmdebug & DDB_INTR) { 465 printf("dcmintr(%d): iir %x pc %x/%x/%x/%x ", 466 brd, code, pcnd[0], pcnd[1], pcnd[2], pcnd[3]); 467 printf("miir %x mc %x/%x/%x/%x\n", 468 mcode, mcnd[0], mcnd[1], mcnd[2], mcnd[3]); 469 } 470 #endif 471 if (code & IIR_TIMEO) 472 dcmrint(brd, dcm); 473 if (code & IIR_PORT0) 474 dcmpint(unit+0, pcnd[0], dcm); 475 if (code & IIR_PORT1) 476 dcmpint(unit+1, pcnd[1], dcm); 477 if (code & IIR_PORT2) 478 dcmpint(unit+2, pcnd[2], dcm); 479 if (code & IIR_PORT3) 480 dcmpint(unit+3, pcnd[3], dcm); 481 if (code & IIR_MODM) { 482 if (mcode == 0 || mcode & 0x1) /* mcode==0 -> 98642 board */ 483 dcmmint(unit+0, mcnd[0], dcm); 484 if (mcode & 0x2) 485 dcmmint(unit+1, mcnd[1], dcm); 486 if (mcode & 0x4) 487 dcmmint(unit+2, mcnd[2], dcm); 488 if (mcode & 0x8) 489 dcmmint(unit+3, mcnd[3], dcm); 490 } 491 492 dis = &dcmischeme[brd]; 493 /* 494 * Chalk up a receiver interrupt if the timer running or one of 495 * the ports reports a special character interrupt. 496 */ 497 if ((code & IIR_TIMEO) || 498 ((pcnd[0]|pcnd[1]|pcnd[2]|pcnd[3]) & IT_SPEC)) 499 dis->dis_intr++; 500 /* 501 * See if it is time to check/change the interrupt rate. 502 */ 503 if (dcmistype < 0 && 504 (i = time.tv_sec - dis->dis_time) >= dcminterval) { 505 /* 506 * If currently per-character and averaged over 70 interrupts 507 * per-second (66 is threshold of 600 baud) in last interval, 508 * switch to timer mode. 509 * 510 * XXX decay counts ala load average to avoid spikes? 511 */ 512 if (dis->dis_perchar && dis->dis_intr > 70 * i) 513 dcmsetischeme(brd, DIS_TIMER); 514 /* 515 * If currently using timer and had more interrupts than 516 * received characters in the last interval, switch back 517 * to per-character. Note that after changing to per-char 518 * we must process any characters already in the queue 519 * since they may have arrived before the bitmap was setup. 520 * 521 * XXX decay counts? 522 */ 523 else if (!dis->dis_perchar && dis->dis_intr > dis->dis_char) { 524 dcmsetischeme(brd, DIS_PERCHAR); 525 dcmrint(brd, dcm); 526 } 527 dis->dis_intr = dis->dis_char = 0; 528 dis->dis_time = time.tv_sec; 529 } 530 return (1); 531 } 532 533 /* 534 * Port interrupt. Can be two things: 535 * First, it might be a special character (exception interrupt); 536 * Second, it may be a buffer empty (transmit interrupt); 537 */ 538 dcmpint(unit, code, dcm) 539 int unit, code; 540 struct dcmdevice *dcm; 541 { 542 struct tty *tp = &dcm_tty[unit]; 543 544 if (code & IT_SPEC) 545 dcmreadbuf(unit, dcm, tp); 546 if (code & IT_TX) 547 dcmxint(unit, dcm, tp); 548 } 549 550 dcmrint(brd, dcm) 551 int brd; 552 register struct dcmdevice *dcm; 553 { 554 register int i, unit; 555 register struct tty *tp; 556 557 unit = MKUNIT(brd, 0); 558 tp = &dcm_tty[unit]; 559 for (i = 0; i < 4; i++, tp++, unit++) 560 dcmreadbuf(unit, dcm, tp); 561 } 562 563 dcmreadbuf(unit, dcm, tp) 564 int unit; 565 register struct dcmdevice *dcm; 566 register struct tty *tp; 567 { 568 int port = PORT(unit); 569 register struct dcmpreg *pp = dcm_preg(dcm, port); 570 register struct dcmrfifo *fifo; 571 register int c, stat; 572 register unsigned head; 573 int nch = 0; 574 #ifdef IOSTATS 575 struct dcmstats *dsp = &dcmstats[BOARD(unit)]; 576 577 dsp->rints++; 578 #endif 579 if ((tp->t_state & TS_ISOPEN) == 0) { 580 #ifdef KGDB 581 if ((makedev(dcmmajor, unit) == kgdb_dev) && 582 (head = pp->r_head & RX_MASK) != (pp->r_tail & RX_MASK) && 583 dcm->dcm_rfifos[3-port][head>>1].data_char == FRAME_END) { 584 pp->r_head = (head + 2) & RX_MASK; 585 kgdb_connect(0); /* trap into kgdb */ 586 return; 587 } 588 #endif /* KGDB */ 589 pp->r_head = pp->r_tail & RX_MASK; 590 return; 591 } 592 593 head = pp->r_head & RX_MASK; 594 fifo = &dcm->dcm_rfifos[3-port][head>>1]; 595 /* 596 * XXX upper bound on how many chars we will take in one swallow? 597 */ 598 while (head != (pp->r_tail & RX_MASK)) { 599 /* 600 * Get character/status and update head pointer as fast 601 * as possible to make room for more characters. 602 */ 603 c = fifo->data_char; 604 stat = fifo->data_stat; 605 head = (head + 2) & RX_MASK; 606 pp->r_head = head; 607 fifo = head ? fifo+1 : &dcm->dcm_rfifos[3-port][0]; 608 nch++; 609 610 #ifdef DEBUG 611 if (dcmdebug & DDB_INPUT) 612 printf("dcmreadbuf(%d): c%x('%c') s%x f%x h%x t%x\n", 613 unit, c&0xFF, c, stat&0xFF, 614 tp->t_flags, head, pp->r_tail); 615 #endif 616 /* 617 * Check for and handle errors 618 */ 619 if (stat & RD_MASK) { 620 #ifdef DEBUG 621 if (dcmdebug & (DDB_INPUT|DDB_SIOERR)) 622 printf("dcmreadbuf(%d): err: c%x('%c') s%x\n", 623 unit, stat, c&0xFF, c); 624 #endif 625 if (stat & (RD_BD | RD_FE)) 626 c |= TTY_FE; 627 else if (stat & RD_PE) 628 c |= TTY_PE; 629 else if (stat & RD_OVF) 630 log(LOG_WARNING, 631 "dcm%d: silo overflow\n", unit); 632 else if (stat & RD_OE) 633 log(LOG_WARNING, 634 "dcm%d: uart overflow\n", unit); 635 } 636 (*linesw[tp->t_line].l_rint)(c, tp); 637 } 638 dcmischeme[BOARD(unit)].dis_char += nch; 639 #ifdef IOSTATS 640 dsp->rchars += nch; 641 if (nch <= DCMRBSIZE) 642 dsp->rsilo[nch]++; 643 else 644 dsp->rsilo[DCMRBSIZE+1]++; 645 #endif 646 } 647 648 dcmxint(unit, dcm, tp) 649 int unit; 650 struct dcmdevice *dcm; 651 register struct tty *tp; 652 { 653 tp->t_state &= ~TS_BUSY; 654 if (tp->t_state & TS_FLUSH) 655 tp->t_state &= ~TS_FLUSH; 656 (*linesw[tp->t_line].l_start)(tp); 657 } 658 659 dcmmint(unit, mcnd, dcm) 660 register int unit; 661 register struct dcmdevice *dcm; 662 int mcnd; 663 { 664 register struct tty *tp; 665 int delta; 666 667 #ifdef DEBUG 668 if (dcmdebug & DDB_MODEM) 669 printf("dcmmint: port %d mcnd %x mcndlast %x\n", 670 unit, mcnd, mcndlast[unit]); 671 #endif 672 tp = &dcm_tty[unit]; 673 delta = mcnd ^ mcndlast[unit]; 674 mcndlast[unit] = mcnd; 675 if ((delta & MI_CTS) && (tp->t_state & TS_ISOPEN) && 676 (tp->t_flags & CCTS_OFLOW)) { 677 if (mcnd & MI_CTS) { 678 tp->t_state &= ~TS_TTSTOP; 679 ttstart(tp); 680 } else 681 tp->t_state |= TS_TTSTOP; /* inline dcmstop */ 682 } 683 if (delta & MI_CD) { 684 if (mcnd & MI_CD) 685 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 686 else if ((dcmsoftCAR[BOARD(unit)] & (1 << PORT(unit))) == 0 && 687 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) { 688 dcm_modem[unit]->mdmout = MO_OFF; 689 SEM_LOCK(dcm); 690 dcm->dcm_modemchng |= 1<<(unit & 3); 691 dcm->dcm_cr |= CR_MODM; 692 SEM_UNLOCK(dcm); 693 DELAY(10); /* time to change lines */ 694 } 695 } 696 } 697 698 dcmioctl(dev, cmd, data, flag) 699 dev_t dev; 700 caddr_t data; 701 { 702 register struct tty *tp; 703 register int unit = UNIT(dev); 704 register struct dcmdevice *dcm; 705 register int port; 706 int error, s; 707 708 #ifdef DEBUG 709 if (dcmdebug & DDB_IOCTL) 710 printf("dcmioctl: unit %d cmd %x data %x flag %x\n", 711 unit, cmd, *data, flag); 712 #endif 713 tp = &dcm_tty[unit]; 714 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 715 if (error >= 0) 716 return (error); 717 error = ttioctl(tp, cmd, data, flag); 718 if (error >= 0) 719 return (error); 720 721 port = PORT(unit); 722 dcm = dcm_addr[BOARD(unit)]; 723 switch (cmd) { 724 case TIOCSBRK: 725 /* 726 * Wait for transmitter buffer to empty 727 */ 728 s = spltty(); 729 while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr) 730 DELAY(DCM_USPERCH(tp->t_ospeed)); 731 SEM_LOCK(dcm); 732 dcm->dcm_cmdtab[port].dcm_data |= CT_BRK; 733 dcm->dcm_cr |= (1 << port); /* start break */ 734 SEM_UNLOCK(dcm); 735 splx(s); 736 break; 737 738 case TIOCCBRK: 739 SEM_LOCK(dcm); 740 dcm->dcm_cmdtab[port].dcm_data |= CT_BRK; 741 dcm->dcm_cr |= (1 << port); /* end break */ 742 SEM_UNLOCK(dcm); 743 break; 744 745 case TIOCSDTR: 746 (void) dcmmctl(dev, MO_ON, DMBIS); 747 break; 748 749 case TIOCCDTR: 750 (void) dcmmctl(dev, MO_ON, DMBIC); 751 break; 752 753 case TIOCMSET: 754 (void) dcmmctl(dev, *(int *)data, DMSET); 755 break; 756 757 case TIOCMBIS: 758 (void) dcmmctl(dev, *(int *)data, DMBIS); 759 break; 760 761 case TIOCMBIC: 762 (void) dcmmctl(dev, *(int *)data, DMBIC); 763 break; 764 765 case TIOCMGET: 766 *(int *)data = dcmmctl(dev, 0, DMGET); 767 break; 768 769 default: 770 return (ENOTTY); 771 } 772 return (0); 773 } 774 775 dcmparam(tp, t) 776 register struct tty *tp; 777 register struct termios *t; 778 { 779 register struct dcmdevice *dcm; 780 register int port, mode, cflag = t->c_cflag; 781 int ospeed = ttspeedtab(t->c_ospeed, dcmspeedtab); 782 783 /* check requested parameters */ 784 if (ospeed < 0 || (t->c_ispeed && t->c_ispeed != t->c_ospeed)) 785 return (EINVAL); 786 /* and copy to tty */ 787 tp->t_ispeed = t->c_ispeed; 788 tp->t_ospeed = t->c_ospeed; 789 tp->t_cflag = cflag; 790 if (ospeed == 0) { 791 (void) dcmmctl(UNIT(tp->t_dev), MO_OFF, DMSET); 792 return (0); 793 } 794 795 mode = 0; 796 switch (cflag&CSIZE) { 797 case CS5: 798 mode = LC_5BITS; break; 799 case CS6: 800 mode = LC_6BITS; break; 801 case CS7: 802 mode = LC_7BITS; break; 803 case CS8: 804 mode = LC_8BITS; break; 805 } 806 if (cflag&PARENB) { 807 if (cflag&PARODD) 808 mode |= LC_PODD; 809 else 810 mode |= LC_PEVEN; 811 } 812 if (cflag&CSTOPB) 813 mode |= LC_2STOP; 814 else 815 mode |= LC_1STOP; 816 #ifdef DEBUG 817 if (dcmdebug & DDB_PARAM) 818 printf("dcmparam(%d): cflag %x mode %x speed %d uperch %d\n", 819 UNIT(tp->t_dev), cflag, mode, tp->t_ospeed, 820 DCM_USPERCH(tp->t_ospeed)); 821 #endif 822 823 port = PORT(tp->t_dev); 824 dcm = dcm_addr[BOARD(tp->t_dev)]; 825 /* 826 * Wait for transmitter buffer to empty. 827 */ 828 while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr) 829 DELAY(DCM_USPERCH(tp->t_ospeed)); 830 /* 831 * Make changes known to hardware. 832 */ 833 dcm->dcm_data[port].dcm_baud = ospeed; 834 dcm->dcm_data[port].dcm_conf = mode; 835 SEM_LOCK(dcm); 836 dcm->dcm_cmdtab[port].dcm_data |= CT_CON; 837 dcm->dcm_cr |= (1 << port); 838 SEM_UNLOCK(dcm); 839 /* 840 * Delay for config change to take place. Weighted by baud. 841 * XXX why do we do this? 842 */ 843 DELAY(16 * DCM_USPERCH(tp->t_ospeed)); 844 return (0); 845 } 846 847 dcmstart(tp) 848 register struct tty *tp; 849 { 850 register struct dcmdevice *dcm; 851 register struct dcmpreg *pp; 852 register struct dcmtfifo *fifo; 853 register char *bp; 854 register unsigned tail, next; 855 register int port, nch; 856 unsigned head; 857 char buf[16]; 858 int s; 859 #ifdef IOSTATS 860 struct dcmstats *dsp = &dcmstats[BOARD(tp->t_dev)]; 861 int tch = 0; 862 #endif 863 864 s = spltty(); 865 #ifdef IOSTATS 866 dsp->xints++; 867 #endif 868 #ifdef DEBUG 869 if (dcmdebug & DDB_OUTPUT) 870 printf("dcmstart(%d): state %x flags %x outcc %d\n", 871 UNIT(tp->t_dev), tp->t_state, tp->t_flags, 872 tp->t_outq.c_cc); 873 #endif 874 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 875 goto out; 876 if (tp->t_outq.c_cc <= tp->t_lowat) { 877 if (tp->t_state&TS_ASLEEP) { 878 tp->t_state &= ~TS_ASLEEP; 879 wakeup((caddr_t)&tp->t_outq); 880 } 881 if (tp->t_wsel) { 882 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 883 tp->t_wsel = 0; 884 tp->t_state &= ~TS_WCOLL; 885 } 886 } 887 if (tp->t_outq.c_cc == 0) { 888 #ifdef IOSTATS 889 dsp->xempty++; 890 #endif 891 goto out; 892 } 893 894 dcm = dcm_addr[BOARD(tp->t_dev)]; 895 port = PORT(tp->t_dev); 896 pp = dcm_preg(dcm, port); 897 tail = pp->t_tail & TX_MASK; 898 next = (tail + 1) & TX_MASK; 899 head = pp->t_head & TX_MASK; 900 if (head == next) 901 goto out; 902 fifo = &dcm->dcm_tfifos[3-port][tail]; 903 again: 904 nch = q_to_b(&tp->t_outq, buf, (head - next) & TX_MASK); 905 #ifdef IOSTATS 906 tch += nch; 907 #endif 908 #ifdef DEBUG 909 if (dcmdebug & DDB_OUTPUT) 910 printf("\thead %x tail %x nch %d\n", head, tail, nch); 911 #endif 912 /* 913 * Loop transmitting all the characters we can. 914 */ 915 for (bp = buf; --nch >= 0; bp++) { 916 fifo->data_char = *bp; 917 pp->t_tail = next; 918 /* 919 * If this is the first character, 920 * get the hardware moving right now. 921 */ 922 if (bp == buf) { 923 tp->t_state |= TS_BUSY; 924 SEM_LOCK(dcm); 925 dcm->dcm_cmdtab[port].dcm_data |= CT_TX; 926 dcm->dcm_cr |= (1 << port); 927 SEM_UNLOCK(dcm); 928 } 929 tail = next; 930 fifo = tail ? fifo+1 : &dcm->dcm_tfifos[3-port][0]; 931 next = (next + 1) & TX_MASK; 932 } 933 /* 934 * Head changed while we were loading the buffer, 935 * go back and load some more if we can. 936 */ 937 if (tp->t_outq.c_cc && head != (pp->t_head & TX_MASK)) { 938 #ifdef IOSTATS 939 dsp->xrestarts++; 940 #endif 941 head = pp->t_head & TX_MASK; 942 goto again; 943 } 944 945 /* 946 * Kick it one last time in case it finished while we were 947 * loading the last bunch. 948 */ 949 if (bp > &buf[1]) { 950 tp->t_state |= TS_BUSY; 951 SEM_LOCK(dcm); 952 dcm->dcm_cmdtab[port].dcm_data |= CT_TX; 953 dcm->dcm_cr |= (1 << port); 954 SEM_UNLOCK(dcm); 955 } 956 #ifdef DEBUG 957 if (dcmdebug & DDB_INTR) 958 printf("dcmstart(%d): head %x tail %x outqcc %d\n", 959 UNIT(tp->t_dev), head, tail, tp->t_outq.c_cc); 960 #endif 961 out: 962 #ifdef IOSTATS 963 dsp->xchars += tch; 964 if (tch <= DCMXBSIZE) 965 dsp->xsilo[tch]++; 966 else 967 dsp->xsilo[DCMXBSIZE+1]++; 968 #endif 969 splx(s); 970 } 971 972 /* 973 * Stop output on a line. 974 */ 975 dcmstop(tp, flag) 976 register struct tty *tp; 977 { 978 int s; 979 980 s = spltty(); 981 if (tp->t_state & TS_BUSY) { 982 /* XXX is there some way to safely stop transmission? */ 983 if ((tp->t_state&TS_TTSTOP) == 0) 984 tp->t_state |= TS_FLUSH; 985 } 986 splx(s); 987 } 988 989 /* 990 * Modem control 991 */ 992 dcmmctl(dev, bits, how) 993 dev_t dev; 994 int bits, how; 995 { 996 register struct dcmdevice *dcm; 997 int s, unit, brd, hit = 0; 998 999 unit = UNIT(dev); 1000 #ifdef DEBUG 1001 if (dcmdebug & DDB_MODEM) 1002 printf("dcmmctl(%d) unit %d bits 0x%x how %x\n", 1003 BOARD(unit), unit, bits, how); 1004 #endif 1005 1006 brd = BOARD(unit); 1007 dcm = dcm_addr[brd]; 1008 s = spltty(); 1009 switch (how) { 1010 1011 case DMSET: 1012 dcm_modem[unit]->mdmout = bits; 1013 hit++; 1014 break; 1015 1016 case DMBIS: 1017 dcm_modem[unit]->mdmout |= bits; 1018 hit++; 1019 break; 1020 1021 case DMBIC: 1022 dcm_modem[unit]->mdmout &= ~bits; 1023 hit++; 1024 break; 1025 1026 case DMGET: 1027 bits = dcm_modem[unit]->mdmin; 1028 if (dcmsoftCAR[brd] & FLAG_STDDCE) 1029 bits = hp2dce_in(bits); 1030 break; 1031 } 1032 if (hit) { 1033 SEM_LOCK(dcm); 1034 dcm->dcm_modemchng |= 1<<(unit & 3); 1035 dcm->dcm_cr |= CR_MODM; 1036 SEM_UNLOCK(dcm); 1037 DELAY(10); /* delay until done */ 1038 (void) splx(s); 1039 } 1040 return (bits); 1041 } 1042 1043 /* 1044 * Set board to either interrupt per-character or at a fixed interval. 1045 */ 1046 dcmsetischeme(brd, flags) 1047 int brd, flags; 1048 { 1049 register struct dcmdevice *dcm = dcm_addr[brd]; 1050 register struct dcmischeme *dis = &dcmischeme[brd]; 1051 register int i; 1052 u_char mask; 1053 int perchar = flags & DIS_PERCHAR; 1054 1055 #ifdef DEBUG 1056 if (dcmdebug & DDB_INTSCHM) 1057 printf("dcmsetischeme(%d, %d): cur %d, ints %d, chars %d\n", 1058 brd, perchar, dis->dis_perchar, 1059 dis->dis_intr, dis->dis_char); 1060 if ((flags & DIS_RESET) == 0 && perchar == dis->dis_perchar) { 1061 printf("dcmsetischeme(%d): redundent request %d\n", 1062 brd, perchar); 1063 return; 1064 } 1065 #endif 1066 /* 1067 * If perchar is non-zero, we enable interrupts on all characters 1068 * otherwise we disable perchar interrupts and use periodic 1069 * polling interrupts. 1070 */ 1071 dis->dis_perchar = perchar; 1072 mask = perchar ? 0xf : 0x0; 1073 for (i = 0; i < 256; i++) 1074 dcm->dcm_bmap[i].data_data = mask; 1075 /* 1076 * Don't slow down tandem mode, interrupt on flow control 1077 * chars for any port on the board. 1078 */ 1079 if (!perchar) { 1080 register struct tty *tp = &dcm_tty[MKUNIT(brd, 0)]; 1081 int c; 1082 1083 for (i = 0; i < 4; i++, tp++) { 1084 if ((c = tp->t_cc[VSTART]) != _POSIX_VDISABLE) 1085 dcm->dcm_bmap[c].data_data |= (1 << i); 1086 if ((c = tp->t_cc[VSTOP]) != _POSIX_VDISABLE) 1087 dcm->dcm_bmap[c].data_data |= (1 << i); 1088 } 1089 } 1090 /* 1091 * Board starts with timer disabled so if first call is to 1092 * set perchar mode then we don't want to toggle the timer. 1093 */ 1094 if (flags == (DIS_RESET|DIS_PERCHAR)) 1095 return; 1096 /* 1097 * Toggle card 16.7ms interrupts (we first make sure that card 1098 * has cleared the bit so it will see the toggle). 1099 */ 1100 while (dcm->dcm_cr & CR_TIMER) 1101 ; 1102 SEM_LOCK(dcm); 1103 dcm->dcm_cr |= CR_TIMER; 1104 SEM_UNLOCK(dcm); 1105 } 1106 1107 /* 1108 * Following are all routines needed for DCM to act as console 1109 */ 1110 #include "../hp300/cons.h" 1111 1112 dcmcnprobe(cp) 1113 struct consdev *cp; 1114 { 1115 register struct hp_hw *hw; 1116 int unit; 1117 1118 /* locate the major number */ 1119 for (dcmmajor = 0; dcmmajor < nchrdev; dcmmajor++) 1120 if (cdevsw[dcmmajor].d_open == dcmopen) 1121 break; 1122 1123 /* 1124 * Implicitly assigns the lowest select code DCM card found to be 1125 * logical unit 0 (actually CONUNIT). If your config file does 1126 * anything different, you're screwed. 1127 */ 1128 for (hw = sc_table; hw->hw_type; hw++) 1129 if (HW_ISDEV(hw, D_COMMDCM) && !badaddr((short *)hw->hw_kva)) 1130 break; 1131 if (!HW_ISDEV(hw, D_COMMDCM)) { 1132 cp->cn_pri = CN_DEAD; 1133 return; 1134 } 1135 unit = CONUNIT; 1136 dcm_addr[BOARD(CONUNIT)] = (struct dcmdevice *)hw->hw_kva; 1137 1138 /* initialize required fields */ 1139 cp->cn_dev = makedev(dcmmajor, unit); 1140 cp->cn_tp = &dcm_tty[unit]; 1141 switch (dcm_addr[BOARD(unit)]->dcm_rsid) { 1142 case DCMID: 1143 cp->cn_pri = CN_NORMAL; 1144 break; 1145 case DCMID|DCMCON: 1146 cp->cn_pri = CN_REMOTE; 1147 break; 1148 default: 1149 cp->cn_pri = CN_DEAD; 1150 return; 1151 } 1152 /* 1153 * If dcmconsole is initialized, raise our priority. 1154 */ 1155 if (dcmconsole == UNIT(unit)) 1156 cp->cn_pri = CN_REMOTE; 1157 #ifdef KGDB_CHEAT 1158 /* 1159 * This doesn't currently work, at least not with ite consoles; 1160 * the console hasn't been initialized yet. 1161 */ 1162 if (major(kgdb_dev) == dcmmajor && BOARD(kgdb_dev) == BOARD(unit)) { 1163 (void) dcminit(kgdb_dev, kgdb_rate); 1164 if (kgdb_debug_init) { 1165 /* 1166 * We assume that console is ready for us... 1167 * this assumes that a dca or ite console 1168 * has been selected already and will init 1169 * on the first putc. 1170 */ 1171 printf("dcm%d: ", UNIT(kgdb_dev)); 1172 kgdb_connect(1); 1173 } 1174 } 1175 #endif 1176 } 1177 1178 dcmcninit(cp) 1179 struct consdev *cp; 1180 { 1181 dcminit(cp->cn_dev, dcmdefaultrate); 1182 dcmconsinit = 1; 1183 dcmconsole = UNIT(cp->cn_dev); 1184 } 1185 1186 dcminit(dev, rate) 1187 dev_t dev; 1188 int rate; 1189 { 1190 register struct dcmdevice *dcm = dcm_addr[BOARD(dev)]; 1191 int s, mode, port; 1192 1193 port = PORT(dev); 1194 mode = LC_8BITS | LC_1STOP; 1195 s = splhigh(); 1196 /* 1197 * Wait for transmitter buffer to empty. 1198 */ 1199 while (dcm->dcm_thead[port].ptr != dcm->dcm_ttail[port].ptr) 1200 DELAY(DCM_USPERCH(rate)); 1201 /* 1202 * Make changes known to hardware. 1203 */ 1204 dcm->dcm_data[port].dcm_baud = ttspeedtab(rate, dcmspeedtab); 1205 dcm->dcm_data[port].dcm_conf = mode; 1206 SEM_LOCK(dcm); 1207 dcm->dcm_cmdtab[port].dcm_data |= CT_CON; 1208 dcm->dcm_cr |= (1 << port); 1209 SEM_UNLOCK(dcm); 1210 /* 1211 * Delay for config change to take place. Weighted by baud. 1212 * XXX why do we do this? 1213 */ 1214 DELAY(16 * DCM_USPERCH(rate)); 1215 splx(s); 1216 } 1217 1218 dcmcngetc(dev) 1219 dev_t dev; 1220 { 1221 register struct dcmdevice *dcm = dcm_addr[BOARD(dev)]; 1222 register struct dcmrfifo *fifo; 1223 register struct dcmpreg *pp; 1224 register unsigned head; 1225 int s, c, stat, port; 1226 1227 port = PORT(dev); 1228 pp = dcm_preg(dcm, port); 1229 s = splhigh(); 1230 head = pp->r_head & RX_MASK; 1231 fifo = &dcm->dcm_rfifos[3-port][head>>1]; 1232 while (head == (pp->r_tail & RX_MASK)) 1233 ; 1234 /* 1235 * If board interrupts are enabled, just let our received char 1236 * interrupt through in case some other port on the board was 1237 * busy. Otherwise we must clear the interrupt. 1238 */ 1239 SEM_LOCK(dcm); 1240 if ((dcm->dcm_ic & IC_IE) == 0) 1241 stat = dcm->dcm_iir; 1242 SEM_UNLOCK(dcm); 1243 c = fifo->data_char; 1244 stat = fifo->data_stat; 1245 pp->r_head = (head + 2) & RX_MASK; 1246 splx(s); 1247 return (c); 1248 } 1249 1250 /* 1251 * Console kernel output character routine. 1252 */ 1253 dcmcnputc(dev, c) 1254 dev_t dev; 1255 int c; 1256 { 1257 register struct dcmdevice *dcm = dcm_addr[BOARD(dev)]; 1258 register struct dcmpreg *pp; 1259 unsigned tail; 1260 int s, port, stat; 1261 1262 port = PORT(dev); 1263 pp = dcm_preg(dcm, port); 1264 s = splhigh(); 1265 #ifdef KGDB 1266 if (dev != kgdb_dev) 1267 #endif 1268 if (dcmconsinit == 0) { 1269 (void) dcminit(dev, dcmdefaultrate); 1270 dcmconsinit = 1; 1271 } 1272 tail = pp->t_tail & TX_MASK; 1273 while (tail != (pp->t_head & TX_MASK)) 1274 ; 1275 dcm->dcm_tfifos[3-port][tail].data_char = c; 1276 pp->t_tail = tail = (tail + 1) & TX_MASK; 1277 SEM_LOCK(dcm); 1278 dcm->dcm_cmdtab[port].dcm_data |= CT_TX; 1279 dcm->dcm_cr |= (1 << port); 1280 SEM_UNLOCK(dcm); 1281 while (tail != (pp->t_head & TX_MASK)) 1282 ; 1283 /* 1284 * If board interrupts are enabled, just let our completion 1285 * interrupt through in case some other port on the board 1286 * was busy. Otherwise we must clear the interrupt. 1287 */ 1288 if ((dcm->dcm_ic & IC_IE) == 0) { 1289 SEM_LOCK(dcm); 1290 stat = dcm->dcm_iir; 1291 SEM_UNLOCK(dcm); 1292 } 1293 splx(s); 1294 } 1295 #endif 1296