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