FreeBSD/Linux Kernel Cross Reference
sys/dev/pci/isic_pci.c
1 /* $NetBSD: isic_pci.c,v 1.20 2003/12/04 13:57:31 keihan Exp $ */
2
3 /*-
4 * Copyright (c) 2002 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Martin Husemann <martin@NetBSD.org>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: isic_pci.c,v 1.20 2003/12/04 13:57:31 keihan Exp $");
41
42 #include <sys/param.h>
43 #include <sys/errno.h>
44 #include <sys/syslog.h>
45 #include <sys/device.h>
46 #include <sys/socket.h>
47 #include <net/if.h>
48 #include <sys/systm.h>
49 #include <sys/malloc.h>
50 #include <sys/callout.h>
51
52 #include <machine/cpu.h>
53 #include <machine/intr.h>
54 #include <machine/bus.h>
55
56
57 #include <machine/bus.h>
58 #include <machine/intr.h>
59 #include <dev/pci/pcireg.h>
60 #include <dev/pci/pcivar.h>
61 #include <dev/pci/pcidevs.h>
62
63 #include <netisdn/i4b_ioctl.h>
64 #include <netisdn/i4b_global.h>
65 #include <netisdn/i4b_debug.h>
66 #include <netisdn/i4b_trace.h>
67 #include <netisdn/i4b_l2.h>
68 #include <netisdn/i4b_l1l2.h>
69
70 #include <dev/ic/isic_l1.h>
71 #include <dev/ic/ipac.h>
72 #include <dev/ic/isac.h>
73 #include <dev/ic/hscx.h>
74 #include <dev/pci/isic_pci.h>
75
76 extern const struct isdn_layer1_isdnif_driver isic_std_driver;
77
78 static int isic_pci_match __P((struct device *, struct cfdata *, void *));
79 static void isic_pci_attach __P((struct device *, struct device *, void *));
80 static const struct isic_pci_product * find_matching_card __P((struct pci_attach_args *pa));
81
82 static void isic_pci_isdn_attach __P((struct pci_isic_softc *psc, struct pci_attach_args *pa, const char *cardname));
83 static int isic_pci_detach(struct device *self, int flags);
84 static int isic_pci_activate(struct device *self, enum devact act);
85
86 CFATTACH_DECL(isic_pci, sizeof(struct pci_isic_softc),
87 isic_pci_match, isic_pci_attach, isic_pci_detach, isic_pci_activate);
88
89 static const struct isic_pci_product {
90 pci_vendor_id_t npp_vendor;
91 pci_product_id_t npp_product;
92 int cardtype;
93 const char * name;
94 void (*attach)(struct pci_isic_softc *psc, struct pci_attach_args *pa);
95 void (*pciattach)(struct pci_isic_softc *psc, struct pci_attach_args *pa, const char *cardname);
96 } isic_pci_products[] = {
97 { PCI_VENDOR_ELSA, PCI_PRODUCT_ELSA_QS1PCI,
98 CARD_TYPEP_ELSAQS1PCI,
99 "ELSA QuickStep 1000pro/PCI",
100 isic_attach_Eqs1pp, /* card specific initialization */
101 isic_pci_isdn_attach /* generic setup for ISAC/HSCX or IPAC boards */
102 },
103 { 0, 0, 0, NULL, NULL },
104 };
105
106 static const struct isic_pci_product * find_matching_card(pa)
107 struct pci_attach_args *pa;
108 {
109 const struct isic_pci_product * pp = NULL;
110
111 for (pp = isic_pci_products; pp->npp_vendor; pp++)
112 if (PCI_VENDOR(pa->pa_id) == pp->npp_vendor &&
113 PCI_PRODUCT(pa->pa_id) == pp->npp_product)
114 return pp;
115
116 return NULL;
117 }
118
119 /*
120 * Match card
121 */
122 static int
123 isic_pci_match(parent, match, aux)
124 struct device *parent;
125 struct cfdata *match;
126 void *aux;
127 {
128 struct pci_attach_args *pa = aux;
129
130 if (!find_matching_card(pa))
131 return 0;
132
133 return 1;
134 }
135
136 /*
137 * Attach the card
138 */
139 static void
140 isic_pci_attach(parent, self, aux)
141 struct device *parent, *self;
142 void *aux;
143 {
144 struct pci_isic_softc *psc = (void*) self;
145 struct isic_softc *sc = &psc->sc_isic;
146 struct pci_attach_args *pa = aux;
147 const struct isic_pci_product * prod;
148
149 /* Redo probe */
150 prod = find_matching_card(pa);
151 if (prod == NULL) return; /* oops - not found?!? */
152
153 printf(": %s\n", prod->name);
154
155 callout_init(&sc->sc_T3_callout);
156 callout_init(&sc->sc_T4_callout);
157
158 /* card initilization and sc setup */
159 prod->attach(psc, pa);
160
161 /* generic setup, if needed for this card */
162 if (prod->pciattach) prod->pciattach(psc, pa, prod->name);
163 }
164
165 /*---------------------------------------------------------------------------*
166 * isic - pci device driver attach routine
167 *---------------------------------------------------------------------------*/
168 static void
169 isic_pci_isdn_attach(psc, pa, cardname)
170 struct pci_isic_softc *psc;
171 struct pci_attach_args *pa;
172 const char *cardname;
173 {
174 struct isic_softc *sc = &psc->sc_isic;
175 pci_chipset_tag_t pc = pa->pa_pc;
176 pci_intr_handle_t ih;
177 const char *intrstr;
178
179 static char *ISACversion[] = {
180 "2085 Version A1/A2 or 2086/2186 Version 1.1",
181 "2085 Version B1",
182 "2085 Version B2",
183 "2085 Version V2.3 (B3)",
184 "Unknown Version"
185 };
186
187 static char *HSCXversion[] = {
188 "82525 Version A1",
189 "Unknown (0x01)",
190 "82525 Version A2",
191 "Unknown (0x03)",
192 "82525 Version A3",
193 "82525 or 21525 Version 2.1",
194 "Unknown Version"
195 };
196
197 sc->sc_isac_version = 0;
198 sc->sc_hscx_version = 0;
199
200 if(sc->sc_ipac)
201 {
202 u_int ret = IPAC_READ(IPAC_ID);
203
204 switch(ret)
205 {
206 case 0x01:
207 printf("%s: IPAC PSB2115 Version 1.1\n", sc->sc_dev.dv_xname);
208 break;
209
210 case 0x02:
211 printf("%s: IPAC PSB2115 Version 1.2\n", sc->sc_dev.dv_xname);
212 break;
213
214 default:
215 printf("%s: Error, IPAC version %d unknown!\n",
216 sc->sc_dev.dv_xname, ret);
217 return;
218 }
219 }
220 else
221 {
222 sc->sc_isac_version = ((ISAC_READ(I_RBCH)) >> 5) & 0x03;
223
224 switch(sc->sc_isac_version)
225 {
226 case ISAC_VA:
227 case ISAC_VB1:
228 case ISAC_VB2:
229 case ISAC_VB3:
230 printf("%s: ISAC %s (IOM-%c)\n",
231 sc->sc_dev.dv_xname,
232 ISACversion[sc->sc_isac_version],
233 sc->sc_bustyp == BUS_TYPE_IOM1 ? '1' : '2');
234 break;
235
236 default:
237 printf("%s: Error, ISAC version %d unknown!\n",
238 sc->sc_dev.dv_xname, sc->sc_isac_version);
239 return;
240 }
241
242 sc->sc_hscx_version = HSCX_READ(0, H_VSTR) & 0xf;
243
244 switch(sc->sc_hscx_version)
245 {
246 case HSCX_VA1:
247 case HSCX_VA2:
248 case HSCX_VA3:
249 case HSCX_V21:
250 printf("%s: HSCX %s\n",
251 sc->sc_dev.dv_xname,
252 HSCXversion[sc->sc_hscx_version]);
253 break;
254
255 default:
256 printf("%s: Error, HSCX version %d unknown!\n",
257 sc->sc_dev.dv_xname, sc->sc_hscx_version);
258 return;
259 }
260 }
261
262 /* Map and establish the interrupt. */
263 if (pci_intr_map(pa, &ih)) {
264 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
265 return;
266 }
267 intrstr = pci_intr_string(pc, ih);
268 psc->sc_ih = pci_intr_establish(pc, ih, IPL_NET, isic_intr_qs1p, psc);
269 if (psc->sc_ih == NULL) {
270 printf("%s: couldn't establish interrupt",
271 sc->sc_dev.dv_xname);
272 if (intrstr != NULL)
273 printf(" at %s", intrstr);
274 printf("\n");
275 return;
276 }
277 psc->sc_pc = pc;
278 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
279
280 sc->sc_intr_valid = ISIC_INTR_DISABLED;
281
282 /* HSCX setup */
283
284 isic_bchannel_setup(sc, HSCX_CH_A, BPROT_NONE, 0);
285
286 isic_bchannel_setup(sc, HSCX_CH_B, BPROT_NONE, 0);
287
288 /* setup linktab */
289
290 isic_init_linktab(sc);
291
292 /* set trace level */
293
294 sc->sc_trace = TRACE_OFF;
295
296 sc->sc_state = ISAC_IDLE;
297
298 sc->sc_ibuf = NULL;
299 sc->sc_ib = NULL;
300 sc->sc_ilen = 0;
301
302 sc->sc_obuf = NULL;
303 sc->sc_op = NULL;
304 sc->sc_ol = 0;
305 sc->sc_freeflag = 0;
306
307 sc->sc_obuf2 = NULL;
308 sc->sc_freeflag2 = 0;
309
310 /* init higher protocol layers */
311 isic_attach_bri(sc, cardname, &isic_std_driver);
312 }
313
314
315 static int
316 isic_pci_detach(self, flags)
317 struct device *self;
318 int flags;
319 {
320 struct pci_isic_softc *psc = (struct pci_isic_softc *)self;
321
322 bus_space_unmap(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
323 bus_space_free(psc->sc_isic.sc_maps[0].t, psc->sc_isic.sc_maps[0].h, psc->sc_size);
324 pci_intr_disestablish(psc->sc_pc, psc->sc_ih);
325
326 return (0);
327 }
328
329 static int
330 isic_pci_activate(self, act)
331 struct device *self;
332 enum devact act;
333 {
334 struct pci_isic_softc *psc = (struct pci_isic_softc *)self;
335 int error = 0, s;
336
337 s = splnet();
338 switch (act) {
339 case DVACT_ACTIVATE:
340 error = EOPNOTSUPP;
341 break;
342
343 case DVACT_DEACTIVATE:
344 psc->sc_isic.sc_intr_valid = ISIC_INTR_DYING;
345 isic_detach_bri(&psc->sc_isic);
346 break;
347 }
348 splx(s);
349 return (error);
350 }
Cache object: 98adfea10aac47b119aa996f7e46c636
|