2 * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
25 *---------------------------------------------------------------------------
27 * i4b_isic.c - global isic stuff
28 * ==============================
30 * $FreeBSD: src/sys/i4b/layer1/isic/i4b_isic.c,v 1.4.2.1 2001/08/10 14:08:38 obrien Exp $
31 * $DragonFly: src/sys/net/i4b/layer1/isic/i4b_isic.c,v 1.6 2006/12/22 23:44:56 swildner Exp $
33 * last edit-date: [Wed Jan 24 09:29:42 2001]
35 *---------------------------------------------------------------------------*/
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/socket.h>
47 #include <net/i4b/include/machine/i4b_debug.h>
48 #include <net/i4b/include/machine/i4b_ioctl.h>
49 #include <net/i4b/include/machine/i4b_trace.h>
51 #include "../i4b_l1.h"
54 #include "i4b_isic_ext.h"
59 #include "../../include/i4b_global.h"
61 static char *ISACversion[] = {
62 "2085 Version A1/A2 or 2086/2186 Version 1.1",
65 "2085 Version V2.3 (B3)",
69 static char *HSCXversion[] = {
75 "82525 or 21525 Version 2.1",
79 /* jump table for multiplex routines */
80 struct i4b_l1mux_func isic_l1mux_func = {
88 /*---------------------------------------------------------------------------*
89 * isic - device driver interrupt routine
90 *---------------------------------------------------------------------------*/
92 isicintr(struct l1_softc *sc)
94 if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */
96 u_char was_hscx_irq = 0;
97 u_char was_isac_irq = 0;
100 u_char isac_irq_stat;
104 /* get hscx irq status from hscx b ista */
106 HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK;
108 /* get isac irq status */
109 isac_irq_stat = ISAC_READ(I_ISTA);
111 /* do as long as there are pending irqs in the chips */
112 if(!hscx_irq_stat && !isac_irq_stat)
115 if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF |
116 HSCX_ISTA_RSC | HSCX_ISTA_XPR |
117 HSCX_ISTA_TIN | HSCX_ISTA_EXB))
119 isic_hscx_irq(sc, hscx_irq_stat,
121 hscx_irq_stat & HSCX_ISTA_EXB);
125 if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA))
128 HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK,
130 hscx_irq_stat & HSCX_ISTA_EXA);
136 isic_isac_irq(sc, isac_irq_stat); /* isac handler */
141 HSCX_WRITE(0, H_MASK, 0xff);
142 ISAC_WRITE(I_MASK, 0xff);
143 HSCX_WRITE(1, H_MASK, 0xff);
148 if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq))
156 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
157 ISAC_WRITE(I_MASK, ISAC_IMASK);
158 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
160 else /* IPAC interrupt routine */
162 u_char ipac_irq_stat;
163 u_char was_ipac_irq = 0;
167 /* get global irq status */
169 ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f;
173 if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA))
175 /* HSCX A interrupt */
176 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA),
178 ipac_irq_stat & IPAC_ISTA_EXA);
181 if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB))
183 /* HSCX B interrupt */
184 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA),
186 ipac_irq_stat & IPAC_ISTA_EXB);
189 if(ipac_irq_stat & IPAC_ISTA_ICD)
192 isic_isac_irq(sc, ISAC_READ(I_ISTA));
195 if(ipac_irq_stat & IPAC_ISTA_EXD)
197 /* force ISAC interrupt handling */
198 isic_isac_irq(sc, ISAC_ISTA_EXI);
202 /* do as long as there are pending irqs in the chip */
207 IPAC_WRITE(IPAC_MASK, 0xff);
209 IPAC_WRITE(IPAC_MASK, 0xc0);
213 /*---------------------------------------------------------------------------*
214 * isic_recover - try to recover from irq lockup
215 *---------------------------------------------------------------------------*/
217 isic_recover(struct l1_softc *sc)
221 /* get hscx irq status from hscx b ista */
223 byte = HSCX_READ(HSCX_CH_B, H_ISTA);
225 NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte);
227 if(byte & HSCX_ISTA_ICA)
228 NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA));
230 if(byte & HSCX_ISTA_EXB)
231 NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR));
233 if(byte & HSCX_ISTA_EXA)
234 NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR));
236 /* get isac irq status */
238 byte = ISAC_READ(I_ISTA);
240 NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
242 if(byte & ISAC_ISTA_EXI)
243 NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
245 if(byte & ISAC_ISTA_CISQ)
247 byte = ISAC_READ(I_CIRR);
249 NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
251 if(byte & ISAC_CIRR_SQC)
252 NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
255 NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK);
256 NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK);
258 HSCX_WRITE(0, H_MASK, 0xff);
259 HSCX_WRITE(1, H_MASK, 0xff);
261 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
262 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
265 NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
267 ISAC_WRITE(I_MASK, 0xff);
269 ISAC_WRITE(I_MASK, ISAC_IMASK);
272 /*---------------------------------------------------------------------------*
273 * isic_attach_common - common attach routine for all busses
274 *---------------------------------------------------------------------------*/
276 isic_attach_common(device_t dev)
279 int unit = device_get_unit(dev);
280 struct l1_softc *sc = &l1_sc[unit];
284 sc->sc_isac_version = 0;
285 sc->sc_hscx_version = 0;
289 sc->sc_ipac_version = IPAC_READ(IPAC_ID);
291 switch(sc->sc_ipac_version)
298 kprintf("isic%d: Error, IPAC version %d unknown!\n",
299 unit, sc->sc_ipac_version);
306 sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
308 switch(sc->sc_isac_version)
317 kprintf("isic%d: Error, ISAC version %d unknown!\n",
318 unit, sc->sc_isac_version);
323 sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
325 switch(sc->sc_hscx_version)
334 kprintf("isic%d: Error, HSCX version %d unknown!\n",
335 unit, sc->sc_hscx_version);
341 isic_isac_init(sc); /* ISAC setup */
345 isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
347 isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
349 isic_init_linktab(sc); /* setup linktab */
351 sc->sc_trace = TRACE_OFF; /* set trace level */
353 sc->sc_state = ISAC_IDLE; /* set state */
355 sc->sc_ibuf = NULL; /* input buffering */
359 sc->sc_obuf = NULL; /* output buffering */
364 sc->sc_obuf2 = NULL; /* second output buffer */
365 sc->sc_freeflag2 = 0;
369 callout_init(&sc->sc_T3_timeout);
370 callout_init(&sc->sc_T4_timeout);
372 /* init higher protocol layers */
374 i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &isic_l1mux_func);
376 /* announce manufacturer and card type for ISA cards */
378 switch(sc->sc_cardtyp)
381 drvid = "Teles S0/8 (or compatible)";
385 drvid = "Teles S0/16 (or compatible)";
388 case CARD_TYPEP_16_3:
389 drvid = "Teles S0/16.3";
392 case CARD_TYPEP_AVMA1:
393 drvid = "AVM A1 or Fritz!Card Classic";
396 case CARD_TYPEP_PCFRITZ:
397 drvid = "AVM Fritz!Card PCMCIA";
400 case CARD_TYPEP_USRTA:
401 drvid = "USRobotics Sportster ISDN TA intern";
404 case CARD_TYPEP_ITKIX1:
405 drvid = "ITK ix1 micro";
408 case CARD_TYPEP_PCC16:
409 drvid = "ELSA MicroLink ISDN/PCC-16";
413 drvid = NULL; /* pnp/pci cards announce themselves */
418 kprintf("isic%d: %s\n", unit, drvid);
422 /* announce chip versions */
426 if(sc->sc_ipac_version == IPAC_V11)
427 kprintf("isic%d: IPAC PSB2115 Version 1.1\n", unit);
429 kprintf("isic%d: IPAC PSB2115 Version 1.2\n", unit);
433 kprintf("isic%d: ISAC %s (IOM-%c)\n",
435 ISACversion[sc->sc_isac_version],
436 sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
438 kprintf("isic%d: HSCX %s\n",
440 HSCXversion[sc->sc_hscx_version]);
446 /*---------------------------------------------------------------------------*
447 * isic_detach_common - common detach routine for all busses
448 *---------------------------------------------------------------------------*/
450 isic_detach_common(device_t dev)
452 struct l1_softc *sc = &l1_sc[device_get_unit(dev)];
455 sc->sc_cardtyp = CARD_TYPEP_UNK;
457 /* free interrupt resources */
459 if(sc->sc_resources.irq)
461 /* tear down interupt handler */
462 bus_teardown_intr(dev, sc->sc_resources.irq,
463 (void(*)(void *))isicintr);
466 bus_release_resource(dev, SYS_RES_IRQ,
467 sc->sc_resources.irq_rid,
468 sc->sc_resources.irq);
469 sc->sc_resources.irq_rid = 0;
470 sc->sc_resources.irq = 0;
473 /* free memory resource */
475 if(sc->sc_resources.mem)
477 bus_release_resource(dev,SYS_RES_MEMORY,
478 sc->sc_resources.mem_rid,
479 sc->sc_resources.mem);
480 sc->sc_resources.mem_rid = 0;
481 sc->sc_resources.mem = 0;
486 for(i=0; i < INFO_IO_BASES ; i++)
488 if(sc->sc_resources.io_base[i])
490 bus_release_resource(dev, SYS_RES_IOPORT,
491 sc->sc_resources.io_rid[i],
492 sc->sc_resources.io_base[i]);
493 sc->sc_resources.io_rid[i] = 0;
494 sc->sc_resources.io_base[i] = 0;
499 #endif /* NISIC > 0 */