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 $
32 * last edit-date: [Wed Jan 24 09:29:42 2001]
34 *---------------------------------------------------------------------------*/
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/socket.h>
46 #include <machine/i4b_debug.h>
47 #include <machine/i4b_ioctl.h>
48 #include <machine/i4b_trace.h>
50 #include <i4b/layer1/i4b_l1.h>
52 #include <i4b/layer1/isic/i4b_isic.h>
53 #include <i4b/layer1/isic/i4b_isic_ext.h>
54 #include <i4b/layer1/isic/i4b_ipac.h>
55 #include <i4b/layer1/isic/i4b_isac.h>
56 #include <i4b/layer1/isic/i4b_hscx.h>
58 #include <i4b/include/i4b_global.h>
60 static char *ISACversion[] = {
61 "2085 Version A1/A2 or 2086/2186 Version 1.1",
64 "2085 Version V2.3 (B3)",
68 static char *HSCXversion[] = {
74 "82525 or 21525 Version 2.1",
78 /* jump table for multiplex routines */
79 struct i4b_l1mux_func isic_l1mux_func = {
87 /*---------------------------------------------------------------------------*
88 * isic - device driver interrupt routine
89 *---------------------------------------------------------------------------*/
91 isicintr(struct l1_softc *sc)
93 if(sc->sc_ipac == 0) /* HSCX/ISAC interupt routine */
95 u_char was_hscx_irq = 0;
96 u_char was_isac_irq = 0;
98 register u_char hscx_irq_stat;
99 register u_char isac_irq_stat;
103 /* get hscx irq status from hscx b ista */
105 HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK;
107 /* get isac irq status */
108 isac_irq_stat = ISAC_READ(I_ISTA);
110 /* do as long as there are pending irqs in the chips */
111 if(!hscx_irq_stat && !isac_irq_stat)
114 if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF |
115 HSCX_ISTA_RSC | HSCX_ISTA_XPR |
116 HSCX_ISTA_TIN | HSCX_ISTA_EXB))
118 isic_hscx_irq(sc, hscx_irq_stat,
120 hscx_irq_stat & HSCX_ISTA_EXB);
124 if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA))
127 HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK,
129 hscx_irq_stat & HSCX_ISTA_EXA);
135 isic_isac_irq(sc, isac_irq_stat); /* isac handler */
140 HSCX_WRITE(0, H_MASK, 0xff);
141 ISAC_WRITE(I_MASK, 0xff);
142 HSCX_WRITE(1, H_MASK, 0xff);
147 if((sc->sc_cardtyp == CARD_TYPEP_ELSAQS1ISA) && (sc->clearirq))
155 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
156 ISAC_WRITE(I_MASK, ISAC_IMASK);
157 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
159 else /* IPAC interrupt routine */
161 register u_char ipac_irq_stat;
162 register u_char was_ipac_irq = 0;
166 /* get global irq status */
168 ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f;
172 if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA))
174 /* HSCX A interrupt */
175 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA),
177 ipac_irq_stat & IPAC_ISTA_EXA);
180 if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB))
182 /* HSCX B interrupt */
183 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA),
185 ipac_irq_stat & IPAC_ISTA_EXB);
188 if(ipac_irq_stat & IPAC_ISTA_ICD)
191 isic_isac_irq(sc, ISAC_READ(I_ISTA));
194 if(ipac_irq_stat & IPAC_ISTA_EXD)
196 /* force ISAC interrupt handling */
197 isic_isac_irq(sc, ISAC_ISTA_EXI);
201 /* do as long as there are pending irqs in the chip */
206 IPAC_WRITE(IPAC_MASK, 0xff);
208 IPAC_WRITE(IPAC_MASK, 0xc0);
212 /*---------------------------------------------------------------------------*
213 * isic_recover - try to recover from irq lockup
214 *---------------------------------------------------------------------------*/
216 isic_recover(struct l1_softc *sc)
220 /* get hscx irq status from hscx b ista */
222 byte = HSCX_READ(HSCX_CH_B, H_ISTA);
224 NDBGL1(L1_ERROR, "HSCX B: ISTA = 0x%x", byte);
226 if(byte & HSCX_ISTA_ICA)
227 NDBGL1(L1_ERROR, "HSCX A: ISTA = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_ISTA));
229 if(byte & HSCX_ISTA_EXB)
230 NDBGL1(L1_ERROR, "HSCX B: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_B, H_EXIR));
232 if(byte & HSCX_ISTA_EXA)
233 NDBGL1(L1_ERROR, "HSCX A: EXIR = 0x%x", (u_char)HSCX_READ(HSCX_CH_A, H_EXIR));
235 /* get isac irq status */
237 byte = ISAC_READ(I_ISTA);
239 NDBGL1(L1_ERROR, " ISAC: ISTA = 0x%x", byte);
241 if(byte & ISAC_ISTA_EXI)
242 NDBGL1(L1_ERROR, " ISAC: EXIR = 0x%x", (u_char)ISAC_READ(I_EXIR));
244 if(byte & ISAC_ISTA_CISQ)
246 byte = ISAC_READ(I_CIRR);
248 NDBGL1(L1_ERROR, " ISAC: CISQ = 0x%x", byte);
250 if(byte & ISAC_CIRR_SQC)
251 NDBGL1(L1_ERROR, " ISAC: SQRR = 0x%x", (u_char)ISAC_READ(I_SQRR));
254 NDBGL1(L1_ERROR, "HSCX B: IMASK = 0x%x", HSCX_B_IMASK);
255 NDBGL1(L1_ERROR, "HSCX A: IMASK = 0x%x", HSCX_A_IMASK);
257 HSCX_WRITE(0, H_MASK, 0xff);
258 HSCX_WRITE(1, H_MASK, 0xff);
260 HSCX_WRITE(0, H_MASK, HSCX_A_IMASK);
261 HSCX_WRITE(1, H_MASK, HSCX_B_IMASK);
264 NDBGL1(L1_ERROR, " ISAC: IMASK = 0x%x", ISAC_IMASK);
266 ISAC_WRITE(I_MASK, 0xff);
268 ISAC_WRITE(I_MASK, ISAC_IMASK);
271 /*---------------------------------------------------------------------------*
272 * isic_attach_common - common attach routine for all busses
273 *---------------------------------------------------------------------------*/
275 isic_attach_common(device_t dev)
278 int unit = device_get_unit(dev);
279 struct l1_softc *sc = &l1_sc[unit];
283 sc->sc_isac_version = 0;
284 sc->sc_hscx_version = 0;
288 sc->sc_ipac_version = IPAC_READ(IPAC_ID);
290 switch(sc->sc_ipac_version)
297 printf("isic%d: Error, IPAC version %d unknown!\n",
298 unit, sc->sc_ipac_version);
305 sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
307 switch(sc->sc_isac_version)
316 printf("isic%d: Error, ISAC version %d unknown!\n",
317 unit, sc->sc_isac_version);
322 sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
324 switch(sc->sc_hscx_version)
333 printf("isic%d: Error, HSCX version %d unknown!\n",
334 unit, sc->sc_hscx_version);
340 isic_isac_init(sc); /* ISAC setup */
344 isic_bchannel_setup(sc->sc_unit, HSCX_CH_A, BPROT_NONE, 0);
346 isic_bchannel_setup(sc->sc_unit, HSCX_CH_B, BPROT_NONE, 0);
348 isic_init_linktab(sc); /* setup linktab */
350 sc->sc_trace = TRACE_OFF; /* set trace level */
352 sc->sc_state = ISAC_IDLE; /* set state */
354 sc->sc_ibuf = NULL; /* input buffering */
358 sc->sc_obuf = NULL; /* output buffering */
363 sc->sc_obuf2 = NULL; /* second output buffer */
364 sc->sc_freeflag2 = 0;
368 callout_handle_init(&sc->sc_T3_callout);
369 callout_handle_init(&sc->sc_T4_callout);
371 /* init higher protocol layers */
373 i4b_l1_mph_status_ind(L0ISICUNIT(sc->sc_unit), STI_ATTACH, sc->sc_cardtyp, &isic_l1mux_func);
375 /* announce manufacturer and card type for ISA cards */
377 switch(sc->sc_cardtyp)
380 drvid = "Teles S0/8 (or compatible)";
384 drvid = "Teles S0/16 (or compatible)";
387 case CARD_TYPEP_16_3:
388 drvid = "Teles S0/16.3";
391 case CARD_TYPEP_AVMA1:
392 drvid = "AVM A1 or Fritz!Card Classic";
395 case CARD_TYPEP_PCFRITZ:
396 drvid = "AVM Fritz!Card PCMCIA";
399 case CARD_TYPEP_USRTA:
400 drvid = "USRobotics Sportster ISDN TA intern";
403 case CARD_TYPEP_ITKIX1:
404 drvid = "ITK ix1 micro";
407 case CARD_TYPEP_PCC16:
408 drvid = "ELSA MicroLink ISDN/PCC-16";
412 drvid = NULL; /* pnp/pci cards announce themselves */
417 printf("isic%d: %s\n", unit, drvid);
421 /* announce chip versions */
425 if(sc->sc_ipac_version == IPAC_V11)
426 printf("isic%d: IPAC PSB2115 Version 1.1\n", unit);
428 printf("isic%d: IPAC PSB2115 Version 1.2\n", unit);
432 printf("isic%d: ISAC %s (IOM-%c)\n",
434 ISACversion[sc->sc_isac_version],
435 sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
437 printf("isic%d: HSCX %s\n",
439 HSCXversion[sc->sc_hscx_version]);
445 /*---------------------------------------------------------------------------*
446 * isic_detach_common - common detach routine for all busses
447 *---------------------------------------------------------------------------*/
449 isic_detach_common(device_t dev)
451 struct l1_softc *sc = &l1_sc[device_get_unit(dev)];
454 sc->sc_cardtyp = CARD_TYPEP_UNK;
456 /* free interrupt resources */
458 if(sc->sc_resources.irq)
460 /* tear down interupt handler */
461 bus_teardown_intr(dev, sc->sc_resources.irq,
462 (void(*)(void *))isicintr);
465 bus_release_resource(dev, SYS_RES_IRQ,
466 sc->sc_resources.irq_rid,
467 sc->sc_resources.irq);
468 sc->sc_resources.irq_rid = 0;
469 sc->sc_resources.irq = 0;
472 /* free memory resource */
474 if(sc->sc_resources.mem)
476 bus_release_resource(dev,SYS_RES_MEMORY,
477 sc->sc_resources.mem_rid,
478 sc->sc_resources.mem);
479 sc->sc_resources.mem_rid = 0;
480 sc->sc_resources.mem = 0;
485 for(i=0; i < INFO_IO_BASES ; i++)
487 if(sc->sc_resources.io_base[i])
489 bus_release_resource(dev, SYS_RES_IOPORT,
490 sc->sc_resources.io_rid[i],
491 sc->sc_resources.io_base[i]);
492 sc->sc_resources.io_rid[i] = 0;
493 sc->sc_resources.io_base[i] = 0;
498 #endif /* NISIC > 0 */