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
26 /*---------------------------------------------------------------------------
28 * i4b_isic.c - global isic stuff
29 * ==============================
30 * last edit-date: [Wed Jan 24 09:29:42 2001]
32 *---------------------------------------------------------------------------*/
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/socket.h>
44 #include <i4b/include/i4b_debug.h>
45 #include <i4b/include/i4b_ioctl.h>
46 #include <i4b/include/i4b_trace.h>
48 #include <i4b/layer1/i4b_l1.h>
50 #include <i4b/layer1/isic/i4b_isic.h>
51 #include <i4b/layer1/isic/i4b_isic_ext.h>
52 #include <i4b/layer1/isic/i4b_ipac.h>
53 #include <i4b/layer1/isic/i4b_isac.h>
54 #include <i4b/layer1/isic/i4b_hscx.h>
56 #include <i4b/include/i4b_global.h>
58 static char *ISACversion[] = {
59 "2085 Version A1/A2 or 2086/2186 Version 1.1",
62 "2085 Version V2.3 (B3)",
66 static char *HSCXversion[] = {
72 "82525 or 21525 Version 2.1",
76 /* jump table for multiplex routines */
77 struct i4b_l1mux_func isic_l1mux_func = {
85 /*---------------------------------------------------------------------------*
86 * isic - device driver interrupt routine
87 *---------------------------------------------------------------------------*/
89 isicintr(struct l1_softc *sc)
91 if(sc->sc_ipac == 0) /* HSCX/ISAC interrupt routine */
93 u_char was_hscx_irq = 0;
94 u_char was_isac_irq = 0;
96 register u_char hscx_irq_stat;
97 register u_char isac_irq_stat;
101 /* get hscx irq status from hscx b ista */
103 HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK;
105 /* get isac irq status */
106 isac_irq_stat = ISAC_READ(I_ISTA);
108 /* do as long as there are pending irqs in the chips */
109 if(!hscx_irq_stat && !isac_irq_stat)
112 if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF |
113 HSCX_ISTA_RSC | HSCX_ISTA_XPR |
114 HSCX_ISTA_TIN | HSCX_ISTA_EXB))
116 isic_hscx_irq(sc, hscx_irq_stat,
118 hscx_irq_stat & HSCX_ISTA_EXB);
122 if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA))
125 HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK,
127 hscx_irq_stat & HSCX_ISTA_EXA);
133 isic_isac_irq(sc, isac_irq_stat); /* isac handler */
138 HSCX_WRITE(0, H_MASK, 0xff);
139 ISAC_WRITE(I_MASK, 0xff);
140 HSCX_WRITE(1, H_MASK, 0xff);
145 if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq))
153 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
154 ISAC_WRITE(I_MASK, ISAC_IMASK);
155 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
157 else /* IPAC interrupt routine */
159 register u_char ipac_irq_stat;
160 register u_char was_ipac_irq = 0;
164 /* get global irq status */
166 ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f;
170 if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA))
172 /* HSCX A interrupt */
173 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA),
175 ipac_irq_stat & IPAC_ISTA_EXA);
178 if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB))
180 /* HSCX B interrupt */
181 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA),
183 ipac_irq_stat & IPAC_ISTA_EXB);
186 if(ipac_irq_stat & IPAC_ISTA_ICD)
189 isic_isac_irq(sc, ISAC_READ(I_ISTA));
192 if(ipac_irq_stat & IPAC_ISTA_EXD)
194 /* force ISAC interrupt handling */
195 isic_isac_irq(sc, ISAC_ISTA_EXI);
199 /* do as long as there are pending irqs in the chip */
204 IPAC_WRITE(IPAC_MASK, 0xff);
206 IPAC_WRITE(IPAC_MASK, 0xc0);
210 /*---------------------------------------------------------------------------*
211 * isic_recover - try to recover from irq lockup
212 *---------------------------------------------------------------------------*/
214 isic_recover(struct l1_softc *sc)
218 /* get hscx irq status from hscx b ista */
220 byte = HSCX_READ(HSCX_CH_B, H_ISTA);
222 NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte);
224 if(byte & HSCX_ISTA_ICA)
225 NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA));
227 if(byte & HSCX_ISTA_EXB)
228 NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR));
230 if(byte & HSCX_ISTA_EXA)
231 NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR));
233 /* get isac irq status */
235 byte = ISAC_READ(I_ISTA);
237 NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
239 if(byte & ISAC_ISTA_EXI)
240 NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
242 if(byte & ISAC_ISTA_CISQ)
244 byte = ISAC_READ(I_CIRR);
246 NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
248 if(byte & ISAC_CIRR_SQC)
249 NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
252 NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK);
253 NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK);
255 HSCX_WRITE(0, H_MASK, 0xff);
256 HSCX_WRITE(1, H_MASK, 0xff);
258 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
259 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
262 NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
264 ISAC_WRITE(I_MASK, 0xff);
266 ISAC_WRITE(I_MASK, ISAC_IMASK);
269 /*---------------------------------------------------------------------------*
270 * isic_attach_common - common attach routine for all busses
271 *---------------------------------------------------------------------------*/
273 isic_attach_common(device_t dev)
276 int unit = device_get_unit(dev);
277 struct l1_softc *sc = &l1_sc[unit];
281 sc->sc_isac_version = 0;
282 sc->sc_hscx_version = 0;
286 sc->sc_ipac_version = IPAC_READ(IPAC_ID);
288 switch(sc->sc_ipac_version)
295 printf("isic%d: Error, IPAC version %d unknown!\n",
296 unit, sc->sc_ipac_version);
303 sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
305 switch(sc->sc_isac_version)
314 printf("isic%d: Error, ISAC version %d unknown!\n",
315 unit, sc->sc_isac_version);
320 sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
322 switch(sc->sc_hscx_version)
331 printf("isic%d: Error, HSCX version %d unknown!\n",
332 unit, sc->sc_hscx_version);
338 isic_isac_init(sc); /* ISAC setup */
342 isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
344 isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
346 isic_init_linktab(sc); /* setup linktab */
348 sc->sc_trace = TRACE_OFF; /* set trace level */
350 sc->sc_state = ISAC_IDLE; /* set state */
352 sc->sc_ibuf = NULL; /* input buffering */
356 sc->sc_obuf = NULL; /* output buffering */
361 sc->sc_obuf2 = NULL; /* second output buffer */
362 sc->sc_freeflag2 = 0;
366 callout_handle_init(&sc->sc_T3_callout);
367 callout_handle_init(&sc->sc_T4_callout);
369 /* init higher protocol layers */
371 i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &isic_l1mux_func);
373 /* announce manufacturer and card type for ISA cards */
375 switch(sc->sc_cardtyp)
378 drvid = "Teles S0/8 (or compatible)";
382 drvid = "Teles S0/16 (or compatible)";
385 case CARD_TYPEP_16_3:
386 drvid = "Teles S0/16.3";
389 case CARD_TYPEP_AVMA1:
390 drvid = "AVM A1 or Fritz!Card Classic";
393 case CARD_TYPEP_PCFRITZ:
394 drvid = "AVM Fritz!Card PCMCIA";
397 case CARD_TYPEP_USRTA:
398 drvid = "USRobotics Sportster ISDN TA intern";
401 case CARD_TYPEP_ITKIX1:
402 drvid = "ITK ix1 micro";
405 case CARD_TYPEP_PCC16:
406 drvid = "ELSA MicroLink ISDN/PCC-16";
410 drvid = NULL; /* pnp/pci cards announce themselves */
415 printf("isic%d: %s\n", unit, drvid);
419 /* announce chip versions */
423 if(sc->sc_ipac_version == IPAC_V11)
424 printf("isic%d: IPAC PSB2115 Version 1.1\n", unit);
426 printf("isic%d: IPAC PSB2115 Version 1.2\n", unit);
430 printf("isic%d: ISAC %s (IOM-%c)\n",
432 ISACversion[sc->sc_isac_version],
433 sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
435 printf("isic%d: HSCX %s\n",
437 HSCXversion[sc->sc_hscx_version]);
443 /*---------------------------------------------------------------------------*
444 * isic_detach_common - common detach routine for all busses
445 *---------------------------------------------------------------------------*/
447 isic_detach_common(device_t dev)
449 struct l1_softc *sc = &l1_sc[device_get_unit(dev)];
452 sc->sc_cardtyp = CARD_TYPEP_UNK;
454 /* free interrupt resources */
456 if(sc->sc_resources.irq)
458 /* tear down interrupt handler */
459 bus_teardown_intr(dev, sc->sc_resources.irq,
460 (void(*)(void *))isicintr);
463 bus_release_resource(dev, SYS_RES_IRQ,
464 sc->sc_resources.irq_rid,
465 sc->sc_resources.irq);
466 sc->sc_resources.irq_rid = 0;
467 sc->sc_resources.irq = 0;
470 /* free memory resource */
472 if(sc->sc_resources.mem)
474 bus_release_resource(dev,SYS_RES_MEMORY,
475 sc->sc_resources.mem_rid,
476 sc->sc_resources.mem);
477 sc->sc_resources.mem_rid = 0;
478 sc->sc_resources.mem = 0;
483 for(i=0; i < INFO_IO_BASES ; i++)
485 if(sc->sc_resources.io_base[i])
487 bus_release_resource(dev, SYS_RES_IOPORT,
488 sc->sc_resources.io_rid[i],
489 sc->sc_resources.io_base[i]);
490 sc->sc_resources.io_rid[i] = 0;
491 sc->sc_resources.io_base[i] = 0;