Sync usage with man page.
[netbsd-mini2440.git] / sys / dev / ic / isic.c
blobea6f8cbfbace862e85e7360a61e62a0f7386215b
1 /*
2 * Copyright (c) 1997, 2000 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
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.
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.
25 *---------------------------------------------------------------------------
27 * i4b_isic.c - global isic stuff
28 * ==============================
30 * $Id: isic.c,v 1.24 2008/04/08 12:07:26 cegger Exp $
32 * last edit-date: [Fri Jan 5 11:36:10 2001]
34 *---------------------------------------------------------------------------*/
36 #include <sys/cdefs.h>
37 __KERNEL_RCSID(0, "$NetBSD: isic.c,v 1.23 2007/10/19 11:59:54 ad Exp $");
39 #include <sys/param.h>
40 #include <sys/ioccom.h>
41 #include <sys/kernel.h>
42 #include <sys/systm.h>
43 #include <sys/mbuf.h>
44 #include <sys/socket.h>
45 #include <net/if.h>
46 #include <sys/callout.h>
47 #include <sys/device.h>
48 #include <sys/bus.h>
50 #include <netisdn/i4b_debug.h>
51 #include <netisdn/i4b_ioctl.h>
52 #include <netisdn/i4b_trace.h>
54 #include <netisdn/i4b_l2.h>
55 #include <netisdn/i4b_l1l2.h>
56 #include <netisdn/i4b_mbuf.h>
57 #include <netisdn/i4b_global.h>
59 #include <dev/ic/isic_l1.h>
60 #include <dev/ic/ipac.h>
61 #include <dev/ic/isac.h>
62 #include <dev/ic/hscx.h>
64 isdn_link_t *isic_ret_linktab(void*, int channel);
65 void isic_set_link(void*, int channel, const struct isdn_l4_driver_functions *l4_driver, void *l4_driver_softc);
66 void n_connect_request(struct call_desc *cd);
67 void n_connect_response(struct call_desc *cd, int response, int cause);
68 void n_disconnect_request(struct call_desc *cd, int cause);
69 void n_alert_request(struct call_desc *cd);
70 void n_mgmt_command(struct isdn_l3_driver *drv, int cmd, void *parm);
72 const struct isdn_l3_driver_functions
73 isic_l3_driver = {
74 isic_ret_linktab,
75 isic_set_link,
76 n_connect_request,
77 n_connect_response,
78 n_disconnect_request,
79 n_alert_request,
80 NULL,
81 NULL,
82 n_mgmt_command
85 /*---------------------------------------------------------------------------*
86 * isic - device driver interrupt routine
87 *---------------------------------------------------------------------------*/
88 int
89 isicintr(void *arg)
91 struct isic_softc *sc = arg;
93 /* could this be an interrupt for us? */
94 if (sc->sc_intr_valid == ISIC_INTR_DYING)
95 return 0; /* do not touch removed hardware */
97 if(sc->sc_ipac == 0) /* HSCX/ISAC interrupt routine */
99 u_char was_hscx_irq = 0;
100 u_char was_isac_irq = 0;
102 register u_char hscx_irq_stat;
103 register u_char isac_irq_stat;
105 for(;;)
107 /* get hscx irq status from hscx b ista */
108 hscx_irq_stat =
109 HSCX_READ(HSCX_CH_B, H_ISTA) & ~HSCX_B_IMASK;
111 /* get isac irq status */
112 isac_irq_stat = ISAC_READ(I_ISTA);
114 /* do as long as there are pending irqs in the chips */
115 if(!hscx_irq_stat && !isac_irq_stat)
116 break;
118 if(hscx_irq_stat & (HSCX_ISTA_RME | HSCX_ISTA_RPF |
119 HSCX_ISTA_RSC | HSCX_ISTA_XPR |
120 HSCX_ISTA_TIN | HSCX_ISTA_EXB))
122 isic_hscx_irq(sc, hscx_irq_stat,
123 HSCX_CH_B,
124 hscx_irq_stat & HSCX_ISTA_EXB);
125 was_hscx_irq = 1;
128 if(hscx_irq_stat & (HSCX_ISTA_ICA | HSCX_ISTA_EXA))
130 isic_hscx_irq(sc,
131 HSCX_READ(HSCX_CH_A, H_ISTA) & ~HSCX_A_IMASK,
132 HSCX_CH_A,
133 hscx_irq_stat & HSCX_ISTA_EXA);
134 was_hscx_irq = 1;
137 if(isac_irq_stat)
139 /* isac handler */
140 isic_isac_irq(sc, isac_irq_stat);
141 was_isac_irq = 1;
145 HSCX_WRITE(0, H_MASK, 0xff);
146 ISAC_WRITE(I_MASK, 0xff);
147 HSCX_WRITE(1, H_MASK, 0xff);
149 if (sc->clearirq)
151 DELAY(80);
152 sc->clearirq(sc);
153 } else
154 DELAY(100);
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 return(was_hscx_irq || was_isac_irq);
162 else /* IPAC interrupt routine */
164 register u_char ipac_irq_stat;
165 register u_char was_ipac_irq = 0;
167 for(;;)
169 /* get global irq status */
171 ipac_irq_stat = (IPAC_READ(IPAC_ISTA)) & 0x3f;
173 /* check hscx a */
175 if(ipac_irq_stat & (IPAC_ISTA_ICA | IPAC_ISTA_EXA))
177 /* HSCX A interrupt */
178 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_A, H_ISTA),
179 HSCX_CH_A,
180 ipac_irq_stat & IPAC_ISTA_EXA);
181 was_ipac_irq = 1;
183 if(ipac_irq_stat & (IPAC_ISTA_ICB | IPAC_ISTA_EXB))
185 /* HSCX B interrupt */
186 isic_hscx_irq(sc, HSCX_READ(HSCX_CH_B, H_ISTA),
187 HSCX_CH_B,
188 ipac_irq_stat & IPAC_ISTA_EXB);
189 was_ipac_irq = 1;
191 if(ipac_irq_stat & IPAC_ISTA_ICD)
193 /* ISAC interrupt, Obey ISAC-IPAC differences */
194 u_int8_t isac_ista = ISAC_READ(I_ISTA);
195 if (isac_ista & 0xfe)
196 isic_isac_irq(sc, isac_ista & 0xfe);
197 if (isac_ista & 0x01) /* unexpected */
198 aprint_error_dev(&sc->sc_dev, "unexpected ipac timer2 irq\n");
199 was_ipac_irq = 1;
201 if(ipac_irq_stat & IPAC_ISTA_EXD)
203 /* ISAC EXI interrupt */
204 isic_isac_irq(sc, ISAC_ISTA_EXI);
205 was_ipac_irq = 1;
208 /* do as long as there are pending irqs in the chip */
209 if(!ipac_irq_stat)
210 break;
213 #if 0
215 * This seems not to be necessary on IPACs - no idea why
216 * it is here - but due to limit range of test cards, leave
217 * it in for now, in case we have to resurrect it.
219 IPAC_WRITE(IPAC_MASK, 0xff);
220 DELAY(50);
221 IPAC_WRITE(IPAC_MASK, 0xc0);
222 #endif
224 return(was_ipac_irq);
229 isic_attach_bri(struct isic_softc *sc, const char *cardname, const struct isdn_layer1_isdnif_driver *dchan_driver)
231 struct isdn_l3_driver * drv;
233 drv = isdn_attach_isdnif(device_xname(&sc->sc_dev), cardname,
234 &sc->sc_l2, &isic_l3_driver, NBCH_BRI);
235 sc->sc_l3token = drv;
236 sc->sc_l2.driver = dchan_driver;
237 sc->sc_l2.l1_token = sc;
238 sc->sc_l2.drv = drv;
239 isdn_layer2_status_ind(&sc->sc_l2, drv, STI_ATTACH, 1);
240 isdn_isdnif_ready(drv->isdnif);
241 return 1;
245 isic_detach_bri(struct isic_softc *sc)
247 isdn_layer2_status_ind(&sc->sc_l2, sc->sc_l3token, STI_ATTACH, 0);
248 isdn_detach_isdnif(sc->sc_l3token);
249 sc->sc_l3token = NULL;
250 return 1;