2 * Copyright (c) 1999-2001, Ivan Sharov, Vitaly Belekhov.
3 * Copyright (c) 2004 Stanislav Svirid.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * $RISS: if_arl/dev/arl/if_arl_isa.c,v 1.7 2004/03/16 05:30:38 count Exp $
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/socket.h>
42 #include <sys/kernel.h>
43 #include <sys/malloc.h>
45 #include <sys/module.h>
47 #include <machine/bus.h>
48 #include <machine/resource.h>
51 #include <net/ethernet.h>
53 #include <net/if_arp.h>
54 #include <net/if_mib.h>
55 #include <net/if_media.h>
57 #include <isa/isavar.h>
58 #include <isa/pnpvar.h>
59 #include <isa/isa_common.h>
61 #include <machine/md_var.h>
64 #include <vm/vm_param.h>
66 #include <dev/arl/if_arlreg.h>
68 static void arl_isa_identify(driver_t *, device_t);
69 static int arl_isa_probe (device_t);
70 static int arl_isa_attach (device_t);
71 static int arl_isa_detach (device_t);
72 static char* arl_make_desc (u_int8_t, u_int8_t);
74 #define ARL_MAX_ATYPE_LEN 10
75 static struct arl_type {
91 #define ARL_MAX_RTYPE_LEN 10
95 } radio_type_list [] = {
112 arl_make_desc(hw_type, radio_mod)
116 static char desc[80];
117 char atype[ARL_MAX_ATYPE_LEN], rtype[ARL_MAX_RTYPE_LEN];
123 for(i = 0; arl_type_list[i].desc; i++) {
124 if (arl_type_list[i].type == hw_type)
128 if (arl_type_list[i].desc)
129 strncpy(atype, arl_type_list[i].desc, ARL_MAX_ATYPE_LEN);
131 snprintf(atype, ARL_MAX_ATYPE_LEN, "(0x%x)", hw_type);
134 for(i = 0; radio_type_list[i].desc; i++)
135 if (radio_type_list[i].type == radio_mod)
138 if (radio_type_list[i].desc)
139 strncpy(rtype, radio_type_list[i].desc, ARL_MAX_RTYPE_LEN);
141 snprintf(rtype, ARL_MAX_RTYPE_LEN, "(0x%x)", radio_mod);
143 snprintf(desc, 80, "ArLan type %s, radio module %s", atype, rtype);
148 #define ARL_ADDR2VEC(addr) (1 << ((addr - ARL_BASE_START) / ARL_BASE_STEP))
151 arl_isa_identify (driver_t *driver, device_t parent)
154 struct arl_softc *sc;
156 u_int16_t free_mem = 0xFFFF;
159 printf("arl: in identify\n");
161 /* Try avoid already added devices */
162 for (i = 0; (child = device_find_child(parent, "arl", i)) != NULL; i++) {
163 chunk = bus_get_resource_start(child, SYS_RES_MEMORY, 0);
165 device_printf(child, "found at iomem = 0x%0x\n", chunk);
166 if (chunk >= ARL_BASE_START && chunk <= ARL_BASE_END)
167 free_mem ^= ARL_ADDR2VEC(chunk);
171 printf("arl: free mem vector = 0x%x\n", free_mem);
173 for (chunk = ARL_BASE_START; chunk <= ARL_BASE_END; chunk += ARL_BASE_STEP) {
174 /* If device 'arl' with this chunk was found early - skip it */
175 if ( !(free_mem & ARL_ADDR2VEC(chunk)) )
179 child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "arl", -1);
180 device_set_driver(child, driver);
181 sc = device_get_softc(child);
182 bzero(sc, sizeof(*sc));
184 bus_set_resource(child, SYS_RES_MEMORY, sc->mem_rid, chunk,
187 if (arl_alloc_memory(child, sc->mem_rid, ARL_BASE_STEP) == 0) {
188 ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
189 if (!bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1))
194 device_printf(child, "%sfound at 0x%x\n",
195 !found ? "not " : "", chunk);
197 arl_release_resources(child);
199 bus_delete_resource(child, SYS_RES_MEMORY, sc->mem_rid);
200 device_delete_child(parent, child);
207 arl_isa_probe (device_t dev)
209 struct arl_softc *sc = device_get_softc(dev);
214 if (isa_get_vendorid(dev))
218 device_printf(dev, "in probe\n");
220 bzero(sc, sizeof(struct arl_softc));
222 sc->arl_unit = device_get_unit(dev);
224 error = arl_alloc_memory(dev, 0, ARL_BASE_STEP);
227 device_printf(dev, "Error allocating memory (%d)\n", error);
231 ar = (struct arl_private *) rman_get_virtual(sc->mem_res);
232 if (bcmp(ar->textRegion, ARLAN_SIGN, sizeof(ARLAN_SIGN) - 1)) {
234 device_printf(dev, "not found\n");
243 error = bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1);
247 error = arl_alloc_irq(dev, 0, 0);
250 device_printf(dev, "Can't allocate IRQ %d\n", irq);
254 ar->controlRegister = 1; /* freeze board */
257 for (ptr = (u_char *) ar;
258 ptr < ((u_char *) ar + ARL_BASE_STEP - 1); ptr++) {
261 c = *ptr; *ptr = ~(*ptr);
262 if (*ptr != (u_char)~c) {
263 device_printf(dev, "board memory failed at [%lx]\n",
264 rman_get_start(sc->mem_res) + (ptr - (u_char *)ar));
265 break; /* skip memory test */
269 bzero((void *) ar, ARL_BASE_STEP - 1); /* clear board ram */
271 if (arl_wait_reset(sc, 100, ARDELAY)) {
276 if (ar->diagnosticInfo == 0xFF) {
277 device_set_desc_copy(dev, arl_make_desc(ar->hardwareType,
282 device_printf(dev, "board self-test failed (0x%x)!\n",
288 arl_release_resources(dev);
294 arl_isa_attach (device_t dev)
296 struct arl_softc *sc = device_get_softc(dev);
300 device_printf(dev, "in attach\n");
302 arl_alloc_memory(dev, sc->mem_rid, ARL_BASE_STEP);
303 arl_alloc_irq(dev, sc->irq_rid, 0);
305 error = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET,
306 NULL, arl_intr, sc, &sc->irq_handle);
308 arl_release_resources(dev);
312 #if __FreeBSD_version < 502108
313 device_printf(dev, "Ethernet address %6D\n", IFP2ENADDR(sc->arl_ifp), ":");
316 return arl_attach(dev);
320 arl_isa_detach(device_t dev)
322 struct arl_softc *sc = device_get_softc(dev);
325 ifmedia_removeall(&sc->arl_ifmedia);
326 bus_teardown_intr(dev, sc->irq_res, sc->irq_handle);
327 #if __FreeBSD_version < 500100
328 ether_ifdetach(sc->arl_ifp, ETHER_BPF_SUPPORTED);
330 ether_ifdetach(sc->arl_ifp);
331 if_free(sc->arl_ifp);
333 arl_release_resources(dev);
338 static device_method_t arl_isa_methods[] = {
339 /* Device interface */
340 DEVMETHOD(device_identify, arl_isa_identify),
341 DEVMETHOD(device_probe, arl_isa_probe),
342 DEVMETHOD(device_attach, arl_isa_attach),
343 DEVMETHOD(device_detach, arl_isa_detach),
348 static driver_t arl_isa_driver = {
351 sizeof(struct arl_softc)
354 extern devclass_t arl_devclass;
356 DRIVER_MODULE(arl, isa, arl_isa_driver, arl_devclass, 0, 0);
357 MODULE_DEPEND(arl, isa, 1, 1, 1);
358 MODULE_DEPEND(arl, ether, 1, 1, 1);