1 /* 2 * Copyright (c) 1985, 1986 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 * 6 * @(#)dhu.c 7.2 (Berkeley) 12/19/86 7 */ 8 9 /* 10 * based on dh.c 6.3 84/03/15 11 * and on dmf.c 6.2 84/02/16 12 * 13 * Dave Johnson, Brown University Computer Science 14 * ddj%brown@csnet-relay 15 */ 16 17 #include "dhu.h" 18 #if NDHU > 0 19 /* 20 * DHU-11 driver 21 */ 22 #include "../machine/pte.h" 23 24 #include "bk.h" 25 #include "param.h" 26 #include "conf.h" 27 #include "dir.h" 28 #include "user.h" 29 #include "proc.h" 30 #include "ioctl.h" 31 #include "tty.h" 32 #include "map.h" 33 #include "buf.h" 34 #include "vm.h" 35 #include "kernel.h" 36 #include "syslog.h" 37 38 #include "uba.h" 39 #include "ubareg.h" 40 #include "ubavar.h" 41 #include "dhureg.h" 42 43 #include "bkmac.h" 44 #include "clist.h" 45 #include "file.h" 46 #include "uio.h" 47 48 /* 49 * Definition of the driver for the auto-configuration program. 50 */ 51 int dhuprobe(), dhuattach(), dhurint(), dhuxint(); 52 struct uba_device *dhuinfo[NDHU]; 53 u_short dhustd[] = { 160440, 160500, 0 }; /* some common addresses */ 54 struct uba_driver dhudriver = 55 { dhuprobe, 0, dhuattach, 0, dhustd, "dhu", dhuinfo }; 56 57 #define NDHULINE (NDHU*16) 58 59 #define UNIT(x) (minor(x)) 60 61 #ifndef PORTSELECTOR 62 #define ISPEED B9600 63 #define IFLAGS (EVENP|ODDP|ECHO) 64 #else 65 #define ISPEED B4800 66 #define IFLAGS (EVENP|ODDP) 67 #endif 68 69 /* 70 * default receive silo timeout value -- valid values are 2..255 71 * number of ms. to delay between first char received and receive interrupt 72 * 73 * A value of 20 gives same response as ABLE dh/dm with silo alarm = 0 74 */ 75 #define DHU_DEF_TIMO 20 76 77 /* 78 * Other values for silo timeout register defined here but not used: 79 * receive interrupt only on modem control or silo alarm (3/4 full) 80 */ 81 #define DHU_POLL_TIMO 0 82 /* 83 * receive interrupt immediately on receive character 84 */ 85 #define DHU_NO_TIMO 1 86 87 /* 88 * Local variables for the driver 89 */ 90 /* 91 * Baud rates: no 50, 200, or 38400 baud; all other rates are from "Group B". 92 * EXTA => 19200 baud 93 * EXTB => 2000 baud 94 */ 95 char dhu_speeds[] = 96 { 0, 0, 1, 2, 3, 4, 0, 5, 6, 7, 8, 10, 11, 13, 14, 9 }; 97 98 short dhusoftCAR[NDHU]; 99 100 struct tty dhu_tty[NDHULINE]; 101 int ndhu = NDHULINE; 102 int dhuact; /* mask of active dhu's */ 103 int dhustart(), ttrstrt(); 104 105 /* 106 * The clist space is mapped by one terminal driver onto each UNIBUS. 107 * The identity of the board which allocated resources is recorded, 108 * so the process may be repeated after UNIBUS resets. 109 * The UBACVT macro converts a clist space address for unibus uban 110 * into an i/o space address for the DMA routine. 111 */ 112 int dhu_uballoc[NUBA]; /* which dhu (if any) allocated unibus map */ 113 int cbase[NUBA]; /* base address of clists in unibus map */ 114 #define UBACVT(x, uban) (cbase[uban] + ((x)-(char *)cfree)) 115 116 /* 117 * Routine for configuration to force a dhu to interrupt. 118 */ 119 /*ARGSUSED*/ 120 dhuprobe(reg) 121 caddr_t reg; 122 { 123 register int br, cvec; /* these are ``value-result'' */ 124 register struct dhudevice *dhuaddr = (struct dhudevice *)reg; 125 int i; 126 127 #ifdef lint 128 br = 0; cvec = br; br = cvec; 129 if (ndhu == 0) ndhu = 1; 130 dhurint(0); dhuxint(0); 131 #endif 132 /* 133 * The basic idea here is: 134 * do a self-test by setting the Master-Reset bit 135 * if this fails, then return 136 * if successful, there will be 8 diagnostic codes in RX FIFO 137 * therefore ask for a Received-Data-Available interrupt 138 * wait for it... 139 * reset the interrupt-enable bit and flush out the diag. codes 140 */ 141 dhuaddr->dhucsr = DHU_CS_MCLR; 142 for (i = 0; i < 1000; i++) { 143 DELAY(10000); 144 if ((dhuaddr->dhucsr&DHU_CS_MCLR) == 0) 145 break; 146 } 147 if (dhuaddr->dhucsr&DHU_CS_MCLR) 148 return(0); 149 if (dhuaddr->dhucsr&DHU_CS_DFAIL) 150 return(0); 151 dhuaddr->dhucsr = DHU_CS_RIE; 152 DELAY(1000); 153 dhuaddr->dhucsr = 0; 154 while (dhuaddr->dhurbuf < 0) 155 /* void */; 156 return (sizeof(struct dhudevice)); 157 } 158 159 /* 160 * Routine called to attach a dhu. 161 */ 162 dhuattach(ui) 163 struct uba_device *ui; 164 { 165 166 dhusoftCAR[ui->ui_unit] = ui->ui_flags; 167 cbase[ui->ui_ubanum] = -1; 168 dhu_uballoc[ui->ui_unit] = -1; 169 } 170 171 /* 172 * Open a DHU11 line, mapping the clist onto the uba if this 173 * is the first dhu on this uba. Turn on this dhu if this is 174 * the first use of it. 175 */ 176 /*ARGSUSED*/ 177 dhuopen(dev, flag) 178 dev_t dev; 179 { 180 register struct tty *tp; 181 register int unit, dhu; 182 register struct dhudevice *addr; 183 register struct uba_device *ui; 184 int s; 185 186 unit = UNIT(dev); 187 dhu = unit >> 4; 188 if (unit >= NDHULINE || (ui = dhuinfo[dhu])== 0 || ui->ui_alive == 0) 189 return (ENXIO); 190 tp = &dhu_tty[unit]; 191 if (tp->t_state & TS_XCLUDE && u.u_uid != 0) 192 return (EBUSY); 193 addr = (struct dhudevice *)ui->ui_addr; 194 tp->t_addr = (caddr_t)addr; 195 tp->t_oproc = dhustart; 196 /* 197 * While setting up state for this uba and this dhu, 198 * block uba resets which can clear the state. 199 */ 200 s = spl5(); 201 if (cbase[ui->ui_ubanum] == -1) { 202 dhu_uballoc[ui->ui_ubanum] = dhu; 203 cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, 204 (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); 205 } 206 if ((dhuact&(1<<dhu)) == 0) { 207 addr->dhucsr = DHU_SELECT(0) | DHU_IE; 208 addr->dhutimo = DHU_DEF_TIMO; 209 dhuact |= (1<<dhu); 210 /* anything else to configure whole board */ 211 } 212 (void) splx(s); 213 /* 214 * If this is first open, initialize tty state to default. 215 */ 216 if ((tp->t_state&TS_ISOPEN) == 0) { 217 ttychars(tp); 218 #ifndef PORTSELECTOR 219 if (tp->t_ispeed == 0) { 220 #else 221 tp->t_state |= TS_HUPCLS; 222 #endif PORTSELECTOR 223 tp->t_ispeed = ISPEED; 224 tp->t_ospeed = ISPEED; 225 tp->t_flags = IFLAGS; 226 #ifndef PORTSELECTOR 227 } 228 #endif PORTSELECTOR 229 tp->t_dev = dev; 230 dhuparam(unit); 231 } 232 /* 233 * Wait for carrier, then process line discipline specific open. 234 */ 235 s = spl5(); 236 if ((dhumctl(dev, DHU_ON, DMSET) & DHU_CAR) || 237 (dhusoftCAR[dhu] & (1<<(unit&0xf)))) 238 tp->t_state |= TS_CARR_ON; 239 while ((tp->t_state & TS_CARR_ON) == 0) { 240 tp->t_state |= TS_WOPEN; 241 sleep((caddr_t)&tp->t_rawq, TTIPRI); 242 } 243 (void) splx(s); 244 return ((*linesw[tp->t_line].l_open)(dev, tp)); 245 } 246 247 /* 248 * Close a DHU11 line, turning off the modem control. 249 */ 250 /*ARGSUSED*/ 251 dhuclose(dev, flag) 252 dev_t dev; 253 int flag; 254 { 255 register struct tty *tp; 256 register unit; 257 258 unit = UNIT(dev); 259 tp = &dhu_tty[unit]; 260 (*linesw[tp->t_line].l_close)(tp); 261 (void) dhumctl(unit, DHU_BRK, DMBIC); 262 if ((tp->t_state&(TS_HUPCLS|TS_WOPEN)) || (tp->t_state&TS_ISOPEN)==0) 263 #ifdef PORTSELECTOR 264 { 265 extern int wakeup(); 266 267 (void) dhumctl(unit, DHU_OFF, DMSET); 268 /* Hold DTR low for 0.5 seconds */ 269 timeout(wakeup, (caddr_t) &tp->t_dev, hz/2); 270 sleep((caddr_t) &tp->t_dev, PZERO); 271 } 272 #else 273 (void) dhumctl(unit, DHU_OFF, DMSET); 274 #endif PORTSELECTOR 275 ttyclose(tp); 276 } 277 278 dhuread(dev, uio) 279 dev_t dev; 280 struct uio *uio; 281 { 282 register struct tty *tp = &dhu_tty[UNIT(dev)]; 283 284 return ((*linesw[tp->t_line].l_read)(tp, uio)); 285 } 286 287 dhuwrite(dev, uio) 288 dev_t dev; 289 struct uio *uio; 290 { 291 register struct tty *tp = &dhu_tty[UNIT(dev)]; 292 293 return ((*linesw[tp->t_line].l_write)(tp, uio)); 294 } 295 296 /* 297 * DHU11 receiver interrupt. 298 */ 299 dhurint(dhu) 300 int dhu; 301 { 302 register struct tty *tp; 303 register c; 304 register struct dhudevice *addr; 305 register struct tty *tp0; 306 register struct uba_device *ui; 307 register line; 308 int overrun = 0; 309 310 #ifdef VAX630 311 (void) spl5(); 312 #endif 313 ui = dhuinfo[dhu]; 314 if (ui == 0 || ui->ui_alive == 0) 315 return; 316 addr = (struct dhudevice *)ui->ui_addr; 317 tp0 = &dhu_tty[dhu<<4]; 318 /* 319 * Loop fetching characters from the silo for this 320 * dhu until there are no more in the silo. 321 */ 322 while ((c = addr->dhurbuf) < 0) { /* (c & DHU_RB_VALID) == on */ 323 line = DHU_RX_LINE(c); 324 tp = tp0 + line; 325 if ((c & DHU_RB_STAT) == DHU_RB_STAT) { 326 /* 327 * modem changed or diag info 328 */ 329 if (c & DHU_RB_DIAG) { 330 /* decode diagnostic messages */ 331 continue; 332 } 333 if (c & DHU_ST_DCD) 334 (void)(*linesw[tp->t_line].l_modem)(tp, 1); 335 else if ((dhusoftCAR[dhu] & (1<<line)) == 0 && 336 (*linesw[tp->t_line].l_modem)(tp, 0) == 0) 337 (void) dhumctl((dhu<<4)|line, DHU_OFF, DMSET); 338 continue; 339 } 340 if ((tp->t_state&TS_ISOPEN) == 0) { 341 wakeup((caddr_t)&tp->t_rawq); 342 #ifdef PORTSELECTOR 343 if ((tp->t_state&TS_WOPEN) == 0) 344 #endif 345 continue; 346 } 347 if (c & DHU_RB_PE) 348 if ((tp->t_flags&(EVENP|ODDP)) == EVENP || 349 (tp->t_flags&(EVENP|ODDP)) == ODDP) 350 continue; 351 if ((c & DHU_RB_DO) && overrun == 0) { 352 log(LOG_WARNING, "dhu%d: silo overflow\n", dhu); 353 overrun = 1; 354 } 355 if (c & DHU_RB_FE) 356 /* 357 * At framing error (break) generate 358 * a null (in raw mode, for getty), or a 359 * interrupt (in cooked/cbreak mode). 360 */ 361 if (tp->t_flags&RAW) 362 c = 0; 363 else 364 c = tp->t_intrc; 365 #if NBK > 0 366 if (tp->t_line == NETLDISC) { 367 c &= 0x7f; 368 BKINPUT(c, tp); 369 } else 370 #endif 371 (*linesw[tp->t_line].l_rint)(c, tp); 372 } 373 } 374 375 /* 376 * Ioctl for DHU11. 377 */ 378 /*ARGSUSED*/ 379 dhuioctl(dev, cmd, data, flag) 380 caddr_t data; 381 { 382 register struct tty *tp; 383 register int unit = UNIT(dev); 384 int error; 385 386 tp = &dhu_tty[unit]; 387 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag); 388 if (error >= 0) 389 return (error); 390 error = ttioctl(tp, cmd, data, flag); 391 if (error >= 0) { 392 if (cmd == TIOCSETP || cmd == TIOCSETN || cmd == TIOCLSET || 393 cmd == TIOCLBIC || cmd == TIOCLBIS) 394 dhuparam(unit); 395 return (error); 396 } 397 398 switch (cmd) { 399 case TIOCSBRK: 400 (void) dhumctl(unit, DHU_BRK, DMBIS); 401 break; 402 403 case TIOCCBRK: 404 (void) dhumctl(unit, DHU_BRK, DMBIC); 405 break; 406 407 case TIOCSDTR: 408 (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIS); 409 break; 410 411 case TIOCCDTR: 412 (void) dhumctl(unit, DHU_DTR|DHU_RTS, DMBIC); 413 break; 414 415 case TIOCMSET: 416 (void) dhumctl(dev, dmtodhu(*(int *)data), DMSET); 417 break; 418 419 case TIOCMBIS: 420 (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIS); 421 break; 422 423 case TIOCMBIC: 424 (void) dhumctl(dev, dmtodhu(*(int *)data), DMBIC); 425 break; 426 427 case TIOCMGET: 428 *(int *)data = dhutodm(dhumctl(dev, 0, DMGET)); 429 break; 430 default: 431 return (ENOTTY); 432 } 433 return (0); 434 } 435 436 dmtodhu(bits) 437 register int bits; 438 { 439 register int b = 0; 440 441 if (bits & DML_RTS) b |= DHU_RTS; 442 if (bits & DML_DTR) b |= DHU_DTR; 443 if (bits & DML_LE) b |= DHU_LE; 444 return(b); 445 } 446 447 dhutodm(bits) 448 register int bits; 449 { 450 register int b = 0; 451 452 if (bits & DHU_DSR) b |= DML_DSR; 453 if (bits & DHU_RNG) b |= DML_RNG; 454 if (bits & DHU_CAR) b |= DML_CAR; 455 if (bits & DHU_CTS) b |= DML_CTS; 456 if (bits & DHU_RTS) b |= DML_RTS; 457 if (bits & DHU_DTR) b |= DML_DTR; 458 if (bits & DHU_LE) b |= DML_LE; 459 return(b); 460 } 461 462 463 /* 464 * Set parameters from open or stty into the DHU hardware 465 * registers. 466 */ 467 dhuparam(unit) 468 register int unit; 469 { 470 register struct tty *tp; 471 register struct dhudevice *addr; 472 register int lpar; 473 int s; 474 475 tp = &dhu_tty[unit]; 476 addr = (struct dhudevice *)tp->t_addr; 477 /* 478 * Block interrupts so parameters will be set 479 * before the line interrupts. 480 */ 481 s = spl5(); 482 if ((tp->t_ispeed) == 0) { 483 tp->t_state |= TS_HUPCLS; 484 (void)dhumctl(unit, DHU_OFF, DMSET); 485 splx(s); 486 return; 487 } 488 lpar = (dhu_speeds[tp->t_ospeed]<<12) | (dhu_speeds[tp->t_ispeed]<<8); 489 if ((tp->t_ispeed) == B134) 490 lpar |= DHU_LP_BITS6|DHU_LP_PENABLE; 491 else if (tp->t_flags & (RAW|LITOUT|PASS8)) 492 lpar |= DHU_LP_BITS8; 493 else 494 lpar |= DHU_LP_BITS7|DHU_LP_PENABLE; 495 if (tp->t_flags&EVENP) 496 lpar |= DHU_LP_EPAR; 497 if ((tp->t_ospeed) == B110) 498 lpar |= DHU_LP_TWOSB; 499 addr->dhucsr = DHU_SELECT(unit) | DHU_IE; 500 addr->dhulpr = lpar; 501 splx(s); 502 } 503 504 /* 505 * DHU11 transmitter interrupt. 506 * Restart each line which used to be active but has 507 * terminated transmission since the last interrupt. 508 */ 509 dhuxint(dhu) 510 int dhu; 511 { 512 register struct tty *tp; 513 register struct dhudevice *addr; 514 register struct tty *tp0; 515 register struct uba_device *ui; 516 register int line, t; 517 u_short cntr; 518 519 #ifdef VAX630 520 (void) spl5(); 521 #endif 522 ui = dhuinfo[dhu]; 523 tp0 = &dhu_tty[dhu<<4]; 524 addr = (struct dhudevice *)ui->ui_addr; 525 while ((t = addr->dhucsrh) & DHU_CSH_TI) { 526 line = DHU_TX_LINE(t); 527 tp = tp0 + line; 528 tp->t_state &= ~TS_BUSY; 529 if (t & DHU_CSH_NXM) { 530 printf("dhu(%d,%d): NXM fault\n", dhu, line); 531 /* SHOULD RESTART OR SOMETHING... */ 532 } 533 if (tp->t_state&TS_FLUSH) 534 tp->t_state &= ~TS_FLUSH; 535 else { 536 addr->dhucsrl = DHU_SELECT(line) | DHU_IE; 537 /* 538 * Do arithmetic in a short to make up 539 * for lost 16&17 bits. 540 */ 541 cntr = addr->dhubar1 - 542 UBACVT(tp->t_outq.c_cf, ui->ui_ubanum); 543 ndflush(&tp->t_outq, (int)cntr); 544 } 545 if (tp->t_line) 546 (*linesw[tp->t_line].l_start)(tp); 547 else 548 dhustart(tp); 549 } 550 } 551 552 /* 553 * Start (restart) transmission on the given DHU11 line. 554 */ 555 dhustart(tp) 556 register struct tty *tp; 557 { 558 register struct dhudevice *addr; 559 register int car, dhu, unit, nch; 560 int s; 561 562 unit = minor(tp->t_dev); 563 dhu = unit >> 4; 564 unit &= 0xf; 565 addr = (struct dhudevice *)tp->t_addr; 566 567 /* 568 * Must hold interrupts in following code to prevent 569 * state of the tp from changing. 570 */ 571 s = spl5(); 572 /* 573 * If it's currently active, or delaying, no need to do anything. 574 */ 575 if (tp->t_state&(TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) 576 goto out; 577 /* 578 * If there are sleepers, and output has drained below low 579 * water mark, wake up the sleepers.. 580 */ 581 if (tp->t_outq.c_cc<=TTLOWAT(tp)) { 582 if (tp->t_state&TS_ASLEEP) { 583 tp->t_state &= ~TS_ASLEEP; 584 wakeup((caddr_t)&tp->t_outq); 585 } 586 if (tp->t_wsel) { 587 selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL); 588 tp->t_wsel = 0; 589 tp->t_state &= ~TS_WCOLL; 590 } 591 } 592 /* 593 * Now restart transmission unless the output queue is 594 * empty. 595 */ 596 if (tp->t_outq.c_cc == 0) 597 goto out; 598 if (tp->t_flags & (RAW|LITOUT)) 599 nch = ndqb(&tp->t_outq, 0); 600 else { 601 nch = ndqb(&tp->t_outq, 0200); 602 /* 603 * If first thing on queue is a delay process it. 604 */ 605 if (nch == 0) { 606 nch = getc(&tp->t_outq); 607 timeout(ttrstrt, (caddr_t)tp, (nch&0x7f)+6); 608 tp->t_state |= TS_TIMEOUT; 609 goto out; 610 } 611 } 612 /* 613 * If characters to transmit, restart transmission. 614 */ 615 if (nch) { 616 car = UBACVT(tp->t_outq.c_cf, dhuinfo[dhu]->ui_ubanum); 617 addr->dhucsrl = DHU_SELECT(unit) | DHU_IE; 618 addr->dhulcr &= ~DHU_LC_TXABORT; 619 addr->dhubcr = nch; 620 addr->dhubar1 = car; 621 addr->dhubar2 = ((car >> DHU_XBA_SHIFT) & DHU_BA2_XBA) | 622 DHU_BA2_DMAGO; 623 tp->t_state |= TS_BUSY; 624 } 625 out: 626 splx(s); 627 } 628 629 /* 630 * Stop output on a line, e.g. for ^S/^Q or output flush. 631 */ 632 /*ARGSUSED*/ 633 dhustop(tp, flag) 634 register struct tty *tp; 635 { 636 register struct dhudevice *addr; 637 register int unit, s; 638 639 addr = (struct dhudevice *)tp->t_addr; 640 /* 641 * Block input/output interrupts while messing with state. 642 */ 643 s = spl5(); 644 if (tp->t_state & TS_BUSY) { 645 /* 646 * Device is transmitting; stop output 647 * by selecting the line and setting the 648 * abort xmit bit. We will get an xmit interrupt, 649 * where we will figure out where to continue the 650 * next time the transmitter is enabled. If 651 * TS_FLUSH is set, the outq will be flushed. 652 * In either case, dhustart will clear the TXABORT bit. 653 */ 654 unit = minor(tp->t_dev); 655 addr->dhucsrl = DHU_SELECT(unit) | DHU_IE; 656 addr->dhulcr |= DHU_LC_TXABORT; 657 if ((tp->t_state&TS_TTSTOP)==0) 658 tp->t_state |= TS_FLUSH; 659 } 660 (void) splx(s); 661 } 662 663 /* 664 * DHU11 modem control 665 */ 666 dhumctl(dev, bits, how) 667 dev_t dev; 668 int bits, how; 669 { 670 register struct dhudevice *dhuaddr; 671 register int unit, mbits; 672 int s; 673 674 unit = UNIT(dev); 675 dhuaddr = (struct dhudevice *)(dhu_tty[unit].t_addr); 676 unit &= 0xf; 677 s = spl5(); 678 dhuaddr->dhucsr = DHU_SELECT(unit) | DHU_IE; 679 /* 680 * combine byte from stat register (read only, bits 16..23) 681 * with lcr register (read write, bits 0..15). 682 */ 683 mbits = dhuaddr->dhulcr | (dhuaddr->dhustat << 16); 684 switch (how) { 685 case DMSET: 686 mbits = (mbits & 0xff0000) | bits; 687 break; 688 689 case DMBIS: 690 mbits |= bits; 691 break; 692 693 case DMBIC: 694 mbits &= ~bits; 695 break; 696 697 case DMGET: 698 (void) splx(s); 699 return(mbits); 700 } 701 dhuaddr->dhulcr = (mbits & 0xffff) | DHU_LC_RXEN; 702 dhuaddr->dhulcr2 = DHU_LC2_TXEN; 703 (void) splx(s); 704 return(mbits); 705 } 706 707 /* 708 * Reset state of driver if UBA reset was necessary. 709 * Reset the line and modem control registers. 710 * restart transmitters. 711 */ 712 dhureset(uban) 713 int uban; 714 { 715 register int dhu, unit; 716 register struct tty *tp; 717 register struct uba_device *ui; 718 register struct dhudevice *addr; 719 int i; 720 721 for (dhu = 0; dhu < NDHU; dhu++) { 722 ui = dhuinfo[dhu]; 723 if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) 724 continue; 725 printf(" dhu%d", dhu); 726 if (dhu_uballoc[uban] == dhu) { 727 int info; 728 729 info = uballoc(uban, (caddr_t)cfree, 730 nclist * sizeof(struct cblock), UBA_CANTWAIT); 731 if (info) 732 cbase[uban] = UBAI_ADDR(info); 733 else { 734 printf(" [can't get uba map]"); 735 cbase[uban] = -1; 736 } 737 } 738 addr = (struct dhudevice *)ui->ui_addr; 739 addr->dhucsr = DHU_SELECT(0) | DHU_IE; 740 addr->dhutimo = DHU_DEF_TIMO; 741 unit = dhu * 16; 742 for (i = 0; i < 16; i++) { 743 tp = &dhu_tty[unit]; 744 if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { 745 dhuparam(unit); 746 (void)dhumctl(unit, DHU_ON, DMSET); 747 tp->t_state &= ~TS_BUSY; 748 dhustart(tp); 749 } 750 unit++; 751 } 752 } 753 } 754 #endif 755