1/* 2 * Copyright (c) 1997, 2000 Hellmuth Michaelis. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23 * SUCH DAMAGE. 24 * 25 *--------------------------------------------------------------------------- 26 * 27 * i4b_isac.c - i4b siemens isdn chipset driver ISAC handler 28 * --------------------------------------------------------- 29 * 30 * $Id: isac.c,v 1.23 2011/07/17 20:54:51 joerg Exp $ 31 * 32 * last edit-date: [Fri Jan 5 11:36:10 2001] 33 * 34 *---------------------------------------------------------------------------*/ 35 36#include <sys/cdefs.h> 37__KERNEL_RCSID(0, "$NetBSD: isac.c,v 1.22 2008/04/08 12:07:26 cegger Exp $"); 38 39#ifdef __FreeBSD__ 40#include "opt_i4b.h" 41#endif 42#include <sys/param.h> 43#if defined(__FreeBSD__) && __FreeBSD__ >= 3 44#include <sys/ioccom.h> 45#else 46#include <sys/ioctl.h> 47#endif 48#include <sys/kernel.h> 49#include <sys/systm.h> 50#include <sys/mbuf.h> 51 52#ifdef __FreeBSD__ 53#include <machine/clock.h> 54#include <i386/isa/isa_device.h> 55#else 56#ifndef __bsdi__ 57#include <sys/bus.h> 58#endif 59#include <sys/device.h> 60#endif 61 62#include <sys/socket.h> 63#include <net/if.h> 64 65#if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000 66#include <sys/callout.h> 67#endif 68 69#ifdef __FreeBSD__ 70#include <machine/i4b_debug.h> 71#include <machine/i4b_ioctl.h> 72#include <machine/i4b_trace.h> 73#else 74#include <netisdn/i4b_debug.h> 75#include <netisdn/i4b_ioctl.h> 76#include <netisdn/i4b_trace.h> 77#endif 78 79#include <netisdn/i4b_global.h> 80#include <netisdn/i4b_l2.h> 81#include <netisdn/i4b_l1l2.h> 82#include <netisdn/i4b_mbuf.h> 83 84#include <dev/ic/isic_l1.h> 85#include <dev/ic/isac.h> 86#include <dev/ic/ipac.h> 87#include <dev/ic/hscx.h> 88 89static u_char isic_isac_exir_hdlr(register struct isic_softc *sc, u_char exir); 90static void isic_isac_ind_hdlr(register struct isic_softc *sc, int ind); 91 92/*---------------------------------------------------------------------------* 93 * ISAC interrupt service routine 94 *---------------------------------------------------------------------------*/ 95void 96isic_isac_irq(struct isic_softc *sc, int ista) 97{ 98 register u_char c = 0; 99 NDBGL1(L1_F_MSG, "%s: ista = 0x%02x", device_xname(&sc->sc_dev), ista); 100 101 if(ista & ISAC_ISTA_EXI) /* extended interrupt */ 102 { 103 u_int8_t exirstat = ISAC_READ(I_EXIR); 104 if (sc->sc_intr_valid == ISIC_INTR_VALID) 105 c |= isic_isac_exir_hdlr(sc, exirstat); 106 } 107 108 if(ista & ISAC_ISTA_RME) /* receive message end */ 109 { 110 register int rest; 111 u_char rsta; 112 113 /* get rx status register */ 114 115 rsta = ISAC_READ(I_RSTA); 116 117 if((rsta & ISAC_RSTA_MASK) != 0x20) 118 { 119 int error = 0; 120 121 if(!(rsta & ISAC_RSTA_CRC)) /* CRC error */ 122 { 123 error++; 124 NDBGL1(L1_I_ERR, "%s: CRC error", device_xname(&sc->sc_dev)); 125 } 126 127 if(rsta & ISAC_RSTA_RDO) /* ReceiveDataOverflow */ 128 { 129 error++; 130 NDBGL1(L1_I_ERR, "%s: Data Overrun error", device_xname(&sc->sc_dev)); 131 } 132 133 if(rsta & ISAC_RSTA_RAB) /* ReceiveABorted */ 134 { 135 error++; 136 NDBGL1(L1_I_ERR, "%s: Receive Aborted error", device_xname(&sc->sc_dev)); 137 } 138 139 if(error == 0) 140 { 141 NDBGL1(L1_I_ERR, "%s: RME unknown error, RSTA = 0x%02x!", device_xname(&sc->sc_dev), rsta); 142 } 143 144 i4b_Dfreembuf(sc->sc_ibuf); 145 146 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; 147 148 sc->sc_ibuf = NULL; 149 sc->sc_ib = NULL; 150 sc->sc_ilen = 0; 151 152 ISAC_WRITE(I_CMDR, ISAC_CMDR_RMC|ISAC_CMDR_RRES); 153 ISACCMDRWRDELAY(); 154 155 return; 156 } 157 158 rest = (ISAC_READ(I_RBCL) & (ISAC_FIFO_LEN-1)); 159 160 if(rest == 0) 161 rest = ISAC_FIFO_LEN; 162 163 if(sc->sc_ibuf == NULL) 164 { 165 if((sc->sc_ibuf = i4b_Dgetmbuf(rest)) != NULL) 166 sc->sc_ib = sc->sc_ibuf->m_data; 167 else 168 panic("isic_isac_irq: RME, i4b_Dgetmbuf returns NULL!"); 169 sc->sc_ilen = 0; 170 } 171 172 if(sc->sc_ilen <= (MAX_DFRAME_LEN - rest)) 173 { 174 ISAC_RDFIFO(sc->sc_ib, rest); 175 sc->sc_ilen += rest; 176 177 sc->sc_ibuf->m_pkthdr.len = 178 sc->sc_ibuf->m_len = sc->sc_ilen; 179 180 if(sc->sc_trace & TRACE_D_RX) 181 { 182 i4b_trace_hdr hdr; 183 memset(&hdr, 0, sizeof hdr); 184 hdr.type = TRC_CH_D; 185 hdr.dir = FROM_NT; 186 hdr.count = ++sc->sc_trace_dcount; 187 isdn_layer2_trace_ind(&sc->sc_l2, sc->sc_l3token, &hdr, sc->sc_ibuf->m_len, sc->sc_ibuf->m_data); 188 } 189 190 c |= ISAC_CMDR_RMC; 191 192 if(sc->sc_intr_valid == ISIC_INTR_VALID && 193 (((struct isdn_l3_driver*)sc->sc_l3token)->protocol != PROTOCOL_D64S)) 194 { 195 isdn_layer2_data_ind(&sc->sc_l2, sc->sc_l3token, sc->sc_ibuf); 196 } 197 else 198 { 199 i4b_Dfreembuf(sc->sc_ibuf); 200 } 201 } 202 else 203 { 204 NDBGL1(L1_I_ERR, "RME, input buffer overflow!"); 205 i4b_Dfreembuf(sc->sc_ibuf); 206 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; 207 } 208 209 sc->sc_ibuf = NULL; 210 sc->sc_ib = NULL; 211 sc->sc_ilen = 0; 212 } 213 214 if(ista & ISAC_ISTA_RPF) /* receive fifo full */ 215 { 216 if(sc->sc_ibuf == NULL) 217 { 218 if((sc->sc_ibuf = i4b_Dgetmbuf(MAX_DFRAME_LEN)) != NULL) 219 sc->sc_ib= sc->sc_ibuf->m_data; 220 else 221 panic("isic_isac_irq: RPF, i4b_Dgetmbuf returns NULL!"); 222 sc->sc_ilen = 0; 223 } 224 225 if(sc->sc_ilen <= (MAX_DFRAME_LEN - ISAC_FIFO_LEN)) 226 { 227 ISAC_RDFIFO(sc->sc_ib, ISAC_FIFO_LEN); 228 sc->sc_ilen += ISAC_FIFO_LEN; 229 sc->sc_ib += ISAC_FIFO_LEN; 230 c |= ISAC_CMDR_RMC; 231 } 232 else 233 { 234 NDBGL1(L1_I_ERR, "RPF, input buffer overflow!"); 235 i4b_Dfreembuf(sc->sc_ibuf); 236 sc->sc_ibuf = NULL; 237 sc->sc_ib = NULL; 238 sc->sc_ilen = 0; 239 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; 240 } 241 } 242 243 if(ista & ISAC_ISTA_XPR) /* transmit fifo empty (XPR bit set) */ 244 { 245 if((sc->sc_obuf2 != NULL) && (sc->sc_obuf == NULL)) 246 { 247 sc->sc_freeflag = sc->sc_freeflag2; 248 sc->sc_obuf = sc->sc_obuf2; 249 sc->sc_op = sc->sc_obuf->m_data; 250 sc->sc_ol = sc->sc_obuf->m_len; 251 sc->sc_obuf2 = NULL; 252#ifdef NOTDEF 253 printf("ob2=%x, op=%x, ol=%d, f=%d #", 254 sc->sc_obuf, 255 sc->sc_op, 256 sc->sc_ol, 257 sc->sc_state); 258#endif 259 } 260 else 261 { 262#ifdef NOTDEF 263 printf("ob=%x, op=%x, ol=%d, f=%d #", 264 sc->sc_obuf, 265 sc->sc_op, 266 sc->sc_ol, 267 sc->sc_state); 268#endif 269 } 270 271 if(sc->sc_obuf) 272 { 273 ISAC_WRFIFO(sc->sc_op, min(sc->sc_ol, ISAC_FIFO_LEN)); 274 275 if(sc->sc_ol > ISAC_FIFO_LEN) /* length > 32 ? */ 276 { 277 sc->sc_op += ISAC_FIFO_LEN; /* bufferptr+32 */ 278 sc->sc_ol -= ISAC_FIFO_LEN; /* length - 32 */ 279 c |= ISAC_CMDR_XTF; /* set XTF bit */ 280 } 281 else 282 { 283 if(sc->sc_freeflag) 284 { 285 i4b_Dfreembuf(sc->sc_obuf); 286 sc->sc_freeflag = 0; 287 } 288 sc->sc_obuf = NULL; 289 sc->sc_op = NULL; 290 sc->sc_ol = 0; 291 292 c |= ISAC_CMDR_XTF | ISAC_CMDR_XME; 293 } 294 } 295 else 296 { 297 sc->sc_state &= ~ISAC_TX_ACTIVE; 298 } 299 } 300 301 if(ista & ISAC_ISTA_CISQ) /* channel status change CISQ */ 302 { 303 register u_char ci; 304 305 /* get command/indication rx register*/ 306 307 ci = ISAC_READ(I_CIRR); 308 309 /* if S/Q IRQ, read SQC reg to clr SQC IRQ */ 310 311 if(ci & ISAC_CIRR_SQC) 312 (void) ISAC_READ(I_SQRR); 313 314 /* C/I code change IRQ (flag already cleared by CIRR read) */ 315 316 if(ci & ISAC_CIRR_CIC0) 317 isic_isac_ind_hdlr(sc, (ci >> 2) & 0xf); 318 } 319 320 if(c) 321 { 322 ISAC_WRITE(I_CMDR, c); 323 ISACCMDRWRDELAY(); 324 } 325} 326 327/*---------------------------------------------------------------------------* 328 * ISAC L1 Extended IRQ handler 329 *---------------------------------------------------------------------------*/ 330static u_char 331isic_isac_exir_hdlr(register struct isic_softc *sc, u_char exir) 332{ 333 u_char c = 0; 334 335 if(exir & ISAC_EXIR_XMR) 336 { 337 NDBGL1(L1_I_ERR, "EXIRQ Tx Message Repeat"); 338 339 c |= ISAC_CMDR_XRES; 340 } 341 342 if(exir & ISAC_EXIR_XDU) 343 { 344 NDBGL1(L1_I_ERR, "EXIRQ Tx Data Underrun"); 345 346 c |= ISAC_CMDR_XRES; 347 } 348 349 if(exir & ISAC_EXIR_PCE) 350 { 351 NDBGL1(L1_I_ERR, "EXIRQ Protocol Error"); 352 } 353 354 if(exir & ISAC_EXIR_RFO) 355 { 356 NDBGL1(L1_I_ERR, "EXIRQ Rx Frame Overflow"); 357 358 c |= ISAC_CMDR_RMC|ISAC_CMDR_RRES; 359 } 360 361 if(exir & ISAC_EXIR_SOV) 362 { 363 NDBGL1(L1_I_ERR, "EXIRQ Sync Xfer Overflow"); 364 } 365 366 if(exir & ISAC_EXIR_MOS) 367 { 368 NDBGL1(L1_I_ERR, "EXIRQ Monitor Status"); 369 } 370 371 if(exir & ISAC_EXIR_SAW) 372 { 373 /* cannot happen, STCR:TSF is set to 0 */ 374 375 NDBGL1(L1_I_ERR, "EXIRQ Subscriber Awake"); 376 } 377 378 if(exir & ISAC_EXIR_WOV) 379 { 380 /* cannot happen, STCR:TSF is set to 0 */ 381 382 NDBGL1(L1_I_ERR, "EXIRQ Watchdog Timer Overflow"); 383 } 384 385 return(c); 386} 387 388/*---------------------------------------------------------------------------* 389 * ISAC L1 Indication handler 390 *---------------------------------------------------------------------------*/ 391static void 392isic_isac_ind_hdlr(register struct isic_softc *sc, int ind) 393{ 394 register int event; 395 396 switch(ind) 397 { 398 case ISAC_CIRR_IAI8: 399 NDBGL1(L1_I_CICO, "rx AI8 in state %s", isic_printstate(sc)); 400 if(sc->sc_bustyp == BUS_TYPE_IOM2) 401 isic_isac_l1_cmd(sc, CMD_AR8); 402 event = EV_INFO48; 403 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE); 404 break; 405 406 case ISAC_CIRR_IAI10: 407 NDBGL1(L1_I_CICO, "rx AI10 in state %s", isic_printstate(sc)); 408 if(sc->sc_bustyp == BUS_TYPE_IOM2) 409 isic_isac_l1_cmd(sc, CMD_AR10); 410 event = EV_INFO410; 411 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_ACTIVE); 412 break; 413 414 case ISAC_CIRR_IRSY: 415 NDBGL1(L1_I_CICO, "rx RSY in state %s", isic_printstate(sc)); 416 event = EV_RSY; 417 break; 418 419 case ISAC_CIRR_IPU: 420 NDBGL1(L1_I_CICO, "rx PU in state %s", isic_printstate(sc)); 421 event = EV_PU; 422 break; 423 424 case ISAC_CIRR_IDR: 425 NDBGL1(L1_I_CICO, "rx DR in state %s", isic_printstate(sc)); 426 isic_isac_l1_cmd(sc, CMD_DIU); 427 event = EV_DR; 428 break; 429 430 case ISAC_CIRR_IDID: 431 NDBGL1(L1_I_CICO, "rx DID in state %s", isic_printstate(sc)); 432 event = EV_INFO0; 433 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_L1STAT, LAYER_IDLE); 434 break; 435 436 case ISAC_CIRR_IDIS: 437 NDBGL1(L1_I_CICO, "rx DIS in state %s", isic_printstate(sc)); 438 event = EV_DIS; 439 break; 440 441 case ISAC_CIRR_IEI: 442 NDBGL1(L1_I_CICO, "rx EI in state %s", isic_printstate(sc)); 443 isic_isac_l1_cmd(sc, CMD_DIU); 444 event = EV_EI; 445 break; 446 447 case ISAC_CIRR_IARD: 448 NDBGL1(L1_I_CICO, "rx ARD in state %s", isic_printstate(sc)); 449 event = EV_INFO2; 450 break; 451 452 case ISAC_CIRR_ITI: 453 NDBGL1(L1_I_CICO, "rx TI in state %s", isic_printstate(sc)); 454 event = EV_INFO0; 455 break; 456 457 case ISAC_CIRR_IATI: 458 NDBGL1(L1_I_CICO, "rx ATI in state %s", isic_printstate(sc)); 459 event = EV_INFO0; 460 break; 461 462 case ISAC_CIRR_ISD: 463 NDBGL1(L1_I_CICO, "rx SD in state %s", isic_printstate(sc)); 464 event = EV_INFO0; 465 break; 466 467 default: 468 NDBGL1(L1_I_ERR, "UNKNOWN Indication 0x%x in state %s", ind, isic_printstate(sc)); 469 event = EV_INFO0; 470 break; 471 } 472 isic_next_state(sc, event); 473} 474 475/*---------------------------------------------------------------------------* 476 * execute a layer 1 command 477 *---------------------------------------------------------------------------*/ 478void 479isic_isac_l1_cmd(struct isic_softc *sc, int command) 480{ 481 u_char cmd; 482 483#ifdef I4B_SMP_WORKAROUND 484 485 /* XXXXXXXXXXXXXXXXXXX */ 486 487 /* 488 * patch from Wolfgang Helbig: 489 * 490 * Here is a patch that makes i4b work on an SMP: 491 * The card (TELES 16.3) didn't interrupt on an SMP machine. 492 * This is a gross workaround, but anyway it works *and* provides 493 * some information as how to finally fix this problem. 494 */ 495 496 HSCX_WRITE(0, H_MASK, 0xff); 497 HSCX_WRITE(1, H_MASK, 0xff); 498 ISAC_WRITE(I_MASK, 0xff); 499 DELAY(100); 500 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); 501 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); 502 ISAC_WRITE(I_MASK, ISAC_IMASK); 503 504 /* XXXXXXXXXXXXXXXXXXX */ 505 506#endif /* I4B_SMP_WORKAROUND */ 507 508 if(command < 0 || command > CMD_ILL) 509 { 510 NDBGL1(L1_I_ERR, "illegal cmd 0x%x in state %s", command, isic_printstate(sc)); 511 return; 512 } 513 514 if(sc->sc_bustyp == BUS_TYPE_IOM2) 515 cmd = ISAC_CIX0_LOW; 516 else 517 cmd = 0; 518 519 switch(command) 520 { 521 case CMD_TIM: 522 NDBGL1(L1_I_CICO, "tx TIM in state %s", isic_printstate(sc)); 523 cmd |= (ISAC_CIXR_CTIM << 2); 524 break; 525 526 case CMD_RS: 527 NDBGL1(L1_I_CICO, "tx RS in state %s", isic_printstate(sc)); 528 cmd |= (ISAC_CIXR_CRS << 2); 529 break; 530 531 case CMD_AR8: 532 NDBGL1(L1_I_CICO, "tx AR8 in state %s", isic_printstate(sc)); 533 cmd |= (ISAC_CIXR_CAR8 << 2); 534 break; 535 536 case CMD_AR10: 537 NDBGL1(L1_I_CICO, "tx AR10 in state %s", isic_printstate(sc)); 538 cmd |= (ISAC_CIXR_CAR10 << 2); 539 break; 540 541 case CMD_DIU: 542 NDBGL1(L1_I_CICO, "tx DIU in state %s", isic_printstate(sc)); 543 cmd |= (ISAC_CIXR_CDIU << 2); 544 break; 545 } 546 ISAC_WRITE(I_CIXR, cmd); 547} 548 549/*---------------------------------------------------------------------------* 550 * L1 ISAC initialization 551 *---------------------------------------------------------------------------*/ 552int 553isic_isac_init(struct isic_softc *sc) 554{ 555 ISAC_IMASK = 0xff; /* disable all irqs */ 556 557 ISAC_WRITE(I_MASK, ISAC_IMASK); 558 559 if(sc->sc_bustyp != BUS_TYPE_IOM2) 560 { 561 NDBGL1(L1_I_SETUP, "configuring for IOM-1 mode"); 562 563 /* ADF2: Select mode IOM-1 */ 564 ISAC_WRITE(I_ADF2, 0x00); 565 566 /* SPCR: serial port control register: 567 * SPU - software power up = 0 568 * SAC - SIP port high Z 569 * SPM - timing mode 0 570 * TLP - test loop = 0 571 * C1C, C2C - B1 and B2 switched to/from SPa 572 */ 573 ISAC_WRITE(I_SPCR, ISAC_SPCR_C1C1|ISAC_SPCR_C2C1); 574 575 /* SQXR: S/Q channel xmit register: 576 * SQIE - S/Q IRQ enable = 0 577 * SQX1-4 - Fa bits = 1 578 */ 579 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); 580 581 /* ADF1: additional feature reg 1: 582 * WTC - watchdog = 0 583 * TEM - test mode = 0 584 * PFS - pre-filter = 0 585 * CFS - IOM clock/frame always active 586 * FSC1/2 - polarity of 8kHz strobe 587 * ITF - interframe fill = idle 588 */ 589 ISAC_WRITE(I_ADF1, ISAC_ADF1_FC2); /* ADF1 */ 590 591 /* STCR: sync transfer control reg: 592 * TSF - terminal secific functions = 0 593 * TBA - TIC bus address = 7 594 * STx/SCx = 0 595 */ 596 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); 597 } 598 else 599 { 600 NDBGL1(L1_I_SETUP, "configuring for IOM-2 mode"); 601 602 /* ADF2: Select mode IOM-2 */ 603 ISAC_WRITE(I_ADF2, ISAC_ADF2_IMS); 604 605 /* SPCR: serial port control register: 606 * SPU - software power up = 0 607 * SPM - timing mode 0 608 * TLP - test loop = 0 609 * C1C, C2C - B1 + C1 and B2 + IC2 monitoring 610 */ 611 ISAC_WRITE(I_SPCR, 0x00); 612 613 /* SQXR: S/Q channel xmit register: 614 * IDC - IOM direction = 0 (master) 615 * CFS - Config Select = 0 (clock always active) 616 * CI1E - C/I channel 1 IRQ enable = 0 617 * SQIE - S/Q IRQ enable = 0 618 * SQX1-4 - Fa bits = 1 619 */ 620 ISAC_WRITE(I_SQXR, ISAC_SQXR_SQX1|ISAC_SQXR_SQX2|ISAC_SQXR_SQX3|ISAC_SQXR_SQX4); 621 622 /* ADF1: additional feature reg 1: 623 * WTC - watchdog = 0 624 * TEM - test mode = 0 625 * PFS - pre-filter = 0 626 * IOF - IOM i/f off = 0 627 * ITF - interframe fill = idle 628 */ 629 ISAC_WRITE(I_ADF1, 0x00); 630 631 /* STCR: sync transfer control reg: 632 * TSF - terminal secific functions = 0 633 * TBA - TIC bus address = 7 634 * STx/SCx = 0 635 */ 636 ISAC_WRITE(I_STCR, ISAC_STCR_TBA2|ISAC_STCR_TBA1|ISAC_STCR_TBA0); 637 } 638 639 640 /* MODE: Mode Register: 641 * MDSx - transparent mode 2 642 * TMD - timer mode = external 643 * RAC - Receiver enabled 644 * DIMx - digital i/f mode 645 */ 646 ISAC_WRITE(I_MODE, ISAC_MODE_MDS2|ISAC_MODE_MDS1|ISAC_MODE_RAC|ISAC_MODE_DIM0); 647 648 /* enabled interrupts: 649 * =================== 650 * RME - receive message end 651 * RPF - receive pool full 652 * XPR - transmit pool ready 653 * CISQ - CI or S/Q channel change 654 * EXI - extended interrupt 655 */ 656 657 ISAC_IMASK = ISAC_MASK_RSC | /* auto mode only */ 658 ISAC_MASK_TIN | /* timer irq */ 659 ISAC_MASK_SIN; /* sync xfer irq */ 660 661 ISAC_WRITE(I_MASK, ISAC_IMASK); 662 663 ISAC_WRITE(I_CMDR, ISAC_CMDR_RRES|ISAC_CMDR_XRES); 664 ISACCMDRWRDELAY(); 665 666 return(0); 667} 668 669/*---------------------------------------------------------------------------* 670 * isic_recovery - try to recover from irq lockup 671 *---------------------------------------------------------------------------*/ 672void 673isic_recover(struct isic_softc *sc) 674{ 675 u_char byte; 676 677 /* get hscx irq status from hscx b ista */ 678 679 byte = HSCX_READ(HSCX_CH_B, H_ISTA); 680 681 NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte); 682 683 if(byte & HSCX_ISTA_ICA) 684 NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA)); 685 686 if(byte & HSCX_ISTA_EXB) 687 NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR)); 688 689 if(byte & HSCX_ISTA_EXA) 690 NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR)); 691 692 /* get isac irq status */ 693 694 byte = ISAC_READ(I_ISTA); 695 696 NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte); 697 698 if(byte & ISAC_ISTA_EXI) 699 NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR)); 700 701 if(byte & ISAC_ISTA_CISQ) 702 { 703 byte = ISAC_READ(I_CIRR); 704 705 NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte); 706 707 if(byte & ISAC_CIRR_SQC) 708 NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR)); 709 } 710 711 NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK); 712 NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK); 713 714 HSCX_WRITE(0, H_MASK, 0xff); 715 HSCX_WRITE(1, H_MASK, 0xff); 716 DELAY(100); 717 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK); 718 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK); 719 DELAY(100); 720 721 NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK); 722 723 ISAC_WRITE(I_MASK, 0xff); 724 DELAY(100); 725 ISAC_WRITE(I_MASK, ISAC_IMASK); 726} 727