Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / sys / net / i4b / capi / iavc / iavc_isa.c
1 /*
2  * Copyright (c) 2001 Hellmuth Michaelis. All rights reserved.
3  *
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.
12  *
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.
24  *
25  * $FreeBSD: src/sys/i4b/capi/iavc/iavc_isa.c,v 1.1.2.1 2001/08/10 14:08:34 obrien Exp $
26  * $DragonFly: src/sys/net/i4b/capi/iavc/iavc_isa.c,v 1.2 2003/06/17 04:28:39 dillon Exp $
27  */
28
29 #include "iavc.h"
30 #include "i4bcapi.h"
31
32 #if (NIAVC > 0) && (NI4BCAPI > 0)
33
34 #include <sys/param.h>
35 #include <sys/kernel.h>
36 #include <sys/systm.h>
37 #include <sys/mbuf.h>
38 #include <sys/socket.h>
39 #include <net/if.h>
40
41 #include <machine/clock.h>
42
43 #include <machine/bus.h>
44 #include <machine/resource.h>
45 #include <sys/bus.h>
46 #include <sys/rman.h>
47 #include <vm/vm.h>
48 #include <vm/pmap.h>
49 #include <isa/isavar.h>
50
51 #include <machine/i4b_debug.h>
52 #include <machine/i4b_ioctl.h>
53 #include <machine/i4b_trace.h>
54
55 #include <i4b/include/i4b_global.h>
56 #include <i4b/include/i4b_l3l4.h>
57 #include <i4b/include/i4b_mbuf.h>
58
59 #include <i4b/capi/capi.h>
60
61 #include <i4b/capi/iavc/iavc.h>
62
63 /* ISA driver linkage */
64
65 static void iavc_isa_intr(iavc_softc_t *sc);
66 static int iavc_isa_probe(device_t dev);
67 static int iavc_isa_attach(device_t dev);
68
69 static device_method_t iavc_isa_methods[] =
70 {
71     DEVMETHOD(device_probe,     iavc_isa_probe),
72     DEVMETHOD(device_attach,    iavc_isa_attach),
73     { 0, 0 }
74 };
75
76 static driver_t iavc_isa_driver =
77 {
78     "iavc",
79     iavc_isa_methods,
80     0
81 };
82
83 static devclass_t iavc_isa_devclass;
84
85 DRIVER_MODULE(iavc, isa, iavc_isa_driver, iavc_isa_devclass, 0, 0);
86
87 #define B1_IOLENGTH     0x20
88
89 static int b1_irq_table[] =
90 {0, 0, 0, 192, 32, 160, 96, 224, 0, 64, 80, 208, 48, 0, 0, 112};
91 /*        3    4   5    6   7       9   10  11   12        15 */
92
93 /*---------------------------------------------------------------------------*
94  *      device probe
95  *---------------------------------------------------------------------------*/
96
97 static int
98 iavc_isa_probe(device_t dev)
99 {
100         struct iavc_softc *sc;
101         int ret = ENXIO;
102         int unit = device_get_unit(dev);
103         
104         if(isa_get_vendorid(dev))       /* no PnP probes here */
105                 return ENXIO;
106
107         /* check max unit range */
108         
109         if (unit >= IAVC_MAXUNIT)
110         {
111                 printf("iavc%d: too many units\n", unit);
112                 return(ENXIO);  
113         }
114
115         sc = iavc_find_sc(unit);        /* get softc */ 
116         
117         sc->sc_unit = unit;
118
119         if (!(sc->sc_resources.io_base[0] =
120                 bus_alloc_resource(dev, SYS_RES_IOPORT,
121                         &sc->sc_resources.io_rid[0],
122                         0UL, ~0UL, B1_IOLENGTH, RF_ACTIVE)))
123         {
124                 printf("iavc%d: can't allocate io region\n", unit);
125                 return(ENXIO);                                       
126         }
127
128         sc->sc_iobase = rman_get_start(sc->sc_resources.io_base[0]);
129
130         switch(sc->sc_iobase)
131         {
132                 case 0x150:
133                 case 0x250:
134                 case 0x300:
135                 case 0x340:
136                         break;
137                 default:
138                         printf("iavc%d: ERROR, invalid i/o base addr 0x%x configured!\n", sc->sc_unit, sc->sc_iobase);
139                         bus_release_resource(dev, SYS_RES_IOPORT,
140                                         sc->sc_resources.io_rid[0],
141                                         sc->sc_resources.io_base[0]);
142                 return(ENXIO);
143         }       
144         
145         sc->sc_io_bt = rman_get_bustag(sc->sc_resources.io_base[0]);
146         sc->sc_io_bh = rman_get_bushandle(sc->sc_resources.io_base[0]);
147
148         /* setup characteristics */
149
150         sc->sc_t1 = FALSE;
151         sc->sc_dma = FALSE;
152
153         sc->sc_capi.card_type = CARD_TYPEC_AVM_B1_ISA;
154         sc->sc_capi.sc_nbch = 2;
155
156         b1_reset(sc);
157         DELAY(100);
158
159         ret = b1_detect(sc);
160
161         if(ret)
162         {
163                 printf("iavc%d: no card ? b1_detect returns 0x02x\n", sc->sc_unit, ret);
164                 return(ENXIO);
165         }
166
167         DELAY(100);
168
169         b1_reset(sc);
170         
171         DELAY(100);
172
173         if(bootverbose)
174         {
175                 printf("iavc%d: class = 0x%02x, rev = 0x%02x\n", sc->sc_unit,
176                         iavc_read_port(sc, B1_ANALYSE),
177                         iavc_read_port(sc, B1_REVISION));
178         }
179
180         device_set_desc(dev, "AVM B1 ISA");
181         return(0);
182 }
183
184 /*---------------------------------------------------------------------------*
185  *      attach
186  *---------------------------------------------------------------------------*/
187 static int
188 iavc_isa_attach(device_t dev)
189 {
190         struct iavc_softc *sc;
191         void *ih = 0;
192         int unit = device_get_unit(dev);
193         int irq;
194         
195         sc = iavc_find_sc(unit);        /* get softc */ 
196         
197         sc->sc_resources.irq_rid = 0;
198         
199         if(!(sc->sc_resources.irq =
200                 bus_alloc_resource(dev, SYS_RES_IRQ,
201                         &sc->sc_resources.irq_rid,
202                         0UL, ~0UL, 1, RF_ACTIVE)))
203         {
204                 printf("iavc%d: can't allocate irq\n",unit);
205                 bus_release_resource(dev, SYS_RES_IOPORT,
206                                 sc->sc_resources.io_rid[0],
207                                 sc->sc_resources.io_base[0]);
208                 return(ENXIO);
209         }
210
211         irq = rman_get_start(sc->sc_resources.irq);
212
213         if(b1_irq_table[irq] == 0)
214         {
215                 printf("iavc%d: ERROR, illegal irq %d configured!\n",unit, irq);
216                 bus_release_resource(dev, SYS_RES_IOPORT,
217                                 sc->sc_resources.io_rid[0],
218                                 sc->sc_resources.io_base[0]);
219                 bus_release_resource(dev, SYS_RES_IRQ,
220                                 sc->sc_resources.irq_rid,
221                                 sc->sc_resources.irq);
222                 return(ENXIO);
223         }
224         
225         memset(&sc->sc_txq, 0, sizeof(struct ifqueue));
226         sc->sc_txq.ifq_maxlen = sc->sc_capi.sc_nbch * 4;
227
228 #if defined (__FreeBSD__) && __FreeBSD__ > 4
229         mtx_init(&sc->sc_txq.ifq_mtx, "i4b_ivac_isa", MTX_DEF);
230 #endif
231
232         sc->sc_intr = FALSE;
233         sc->sc_state = IAVC_DOWN;
234         sc->sc_blocked = FALSE;
235
236         /* setup capi link */
237         
238         sc->sc_capi.load = iavc_load;
239         sc->sc_capi.reg_appl = iavc_register;
240         sc->sc_capi.rel_appl = iavc_release;
241         sc->sc_capi.send = iavc_send;
242         sc->sc_capi.ctx = (void*) sc;
243
244         if (capi_ll_attach(&sc->sc_capi))
245         {
246                 printf("iavc%d: capi attach failed\n", unit);
247                 return(ENXIO);
248         }
249
250         /* setup the interrupt */
251
252         if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
253                       (void(*)(void*))iavc_isa_intr,
254                       sc, &ih))
255         {
256                 printf("iavc%d: irq setup failed\n", unit);
257                 bus_release_resource(dev, SYS_RES_IOPORT,
258                                 sc->sc_resources.io_rid[0],
259                                 sc->sc_resources.io_base[0]);
260                 bus_release_resource(dev, SYS_RES_IRQ,
261                                 sc->sc_resources.irq_rid,
262                                 sc->sc_resources.irq);
263                 return(ENXIO);
264         }
265
266         /* the board is now ready to be loaded */
267
268         return(0);
269 }
270
271 /*---------------------------------------------------------------------------*
272  *      setup interrupt
273  *---------------------------------------------------------------------------*/
274 void
275 b1isa_setup_irq(struct iavc_softc *sc)
276 {
277         int irq = rman_get_start(sc->sc_resources.irq);
278         
279         if(bootverbose)
280                 printf("iavc%d: using irq %d\n", sc->sc_unit, irq);
281
282         /* enable the interrupt */
283
284         b1io_outp(sc, B1_INSTAT, 0x00);
285         b1io_outp(sc, B1_RESET, b1_irq_table[irq]);
286         b1io_outp(sc, B1_INSTAT, 0x02);
287 }       
288
289 /*---------------------------------------------------------------------------*
290  *      IRQ handler
291  *---------------------------------------------------------------------------*/
292 static void
293 iavc_isa_intr(struct iavc_softc *sc)
294 {
295         iavc_handle_intr(sc);
296 }
297
298 #endif