1 1.53 rin /* $NetBSD: if_le_isa.c,v 1.53 2022/05/29 10:43:46 rin Exp $ */ 2 1.11 thorpej 3 1.11 thorpej /*- 4 1.23 mycroft * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 1.11 thorpej * All rights reserved. 6 1.11 thorpej * 7 1.11 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.23 mycroft * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace 9 1.23 mycroft * Simulation Facility, NASA Ames Research Center. 10 1.11 thorpej * 11 1.11 thorpej * Redistribution and use in source and binary forms, with or without 12 1.11 thorpej * modification, are permitted provided that the following conditions 13 1.11 thorpej * are met: 14 1.11 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.11 thorpej * notice, this list of conditions and the following disclaimer. 16 1.11 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.11 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.11 thorpej * documentation and/or other materials provided with the distribution. 19 1.11 thorpej * 20 1.11 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.11 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.11 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.11 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.11 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.11 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.11 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.11 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.11 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.11 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.11 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.11 thorpej */ 32 1.1 thorpej 33 1.1 thorpej /*- 34 1.1 thorpej * Copyright (c) 1992, 1993 35 1.1 thorpej * The Regents of the University of California. All rights reserved. 36 1.1 thorpej * 37 1.1 thorpej * This code is derived from software contributed to Berkeley by 38 1.1 thorpej * Ralph Campbell and Rick Macklem. 39 1.1 thorpej * 40 1.1 thorpej * Redistribution and use in source and binary forms, with or without 41 1.1 thorpej * modification, are permitted provided that the following conditions 42 1.1 thorpej * are met: 43 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 44 1.1 thorpej * notice, this list of conditions and the following disclaimer. 45 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 46 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 47 1.1 thorpej * documentation and/or other materials provided with the distribution. 48 1.35 agc * 3. Neither the name of the University nor the names of its contributors 49 1.1 thorpej * may be used to endorse or promote products derived from this software 50 1.1 thorpej * without specific prior written permission. 51 1.1 thorpej * 52 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 53 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 54 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 55 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 56 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 57 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 58 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 59 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 60 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 61 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 62 1.1 thorpej * SUCH DAMAGE. 63 1.1 thorpej * 64 1.1 thorpej * @(#)if_le.c 8.2 (Berkeley) 11/16/93 65 1.1 thorpej */ 66 1.28 lukem 67 1.28 lukem #include <sys/cdefs.h> 68 1.53 rin __KERNEL_RCSID(0, "$NetBSD: if_le_isa.c,v 1.53 2022/05/29 10:43:46 rin Exp $"); 69 1.1 thorpej 70 1.1 thorpej #include <sys/param.h> 71 1.1 thorpej #include <sys/systm.h> 72 1.1 thorpej #include <sys/mbuf.h> 73 1.1 thorpej #include <sys/syslog.h> 74 1.1 thorpej #include <sys/socket.h> 75 1.1 thorpej #include <sys/device.h> 76 1.1 thorpej 77 1.1 thorpej #include <net/if.h> 78 1.9 is #include <net/if_ether.h> 79 1.10 thorpej #include <net/if_media.h> 80 1.1 thorpej 81 1.45 ad #include <sys/cpu.h> 82 1.45 ad #include <sys/intr.h> 83 1.45 ad #include <sys/bus.h> 84 1.1 thorpej 85 1.1 thorpej #include <dev/isa/isareg.h> 86 1.1 thorpej #include <dev/isa/isavar.h> 87 1.1 thorpej #include <dev/isa/isadmavar.h> 88 1.1 thorpej 89 1.22 drochner #include <dev/ic/lancereg.h> 90 1.22 drochner #include <dev/ic/lancevar.h> 91 1.1 thorpej #include <dev/ic/am7990reg.h> 92 1.1 thorpej #include <dev/ic/am7990var.h> 93 1.1 thorpej 94 1.1 thorpej #include <dev/isa/if_levar.h> 95 1.1 thorpej 96 1.46 tsutsui int ne2100_isa_probe(device_t, cfdata_t, void *); 97 1.46 tsutsui int bicc_isa_probe(device_t, cfdata_t, void *); 98 1.46 tsutsui void le_dummyattach(device_t, device_t, void *); 99 1.46 tsutsui int le_dummyprobe(device_t, cfdata_t, void *); 100 1.46 tsutsui void le_ne2100_attach(device_t, device_t, void *); 101 1.46 tsutsui void le_bicc_attach(device_t, device_t, void *); 102 1.17 drochner 103 1.46 tsutsui CFATTACH_DECL_NEW(nele, 0, 104 1.33 thorpej ne2100_isa_probe, le_dummyattach, NULL, NULL); 105 1.33 thorpej 106 1.46 tsutsui CFATTACH_DECL_NEW(le_nele, sizeof(struct le_softc), 107 1.33 thorpej le_dummyprobe, le_ne2100_attach, NULL, NULL); 108 1.33 thorpej 109 1.46 tsutsui CFATTACH_DECL_NEW(bicc, 0, 110 1.33 thorpej bicc_isa_probe, le_dummyattach, NULL, NULL); 111 1.33 thorpej 112 1.46 tsutsui CFATTACH_DECL_NEW(le_bicc, sizeof(struct le_softc), 113 1.33 thorpej le_dummyprobe, le_bicc_attach, NULL, NULL); 114 1.1 thorpej 115 1.17 drochner struct le_isa_params { 116 1.39 christos const char *name; 117 1.17 drochner int iosize, rap, rdp; 118 1.17 drochner int macstart, macstride; 119 1.17 drochner } ne2100_params = { 120 1.17 drochner "NE2100", 121 1.17 drochner 24, NE2100_RAP, NE2100_RDP, 122 1.17 drochner 0, 1 123 1.17 drochner }, bicc_params = { 124 1.17 drochner "BICC Isolan", 125 1.17 drochner 16, BICC_RAP, BICC_RDP, 126 1.17 drochner 0, 2 127 1.1 thorpej }; 128 1.1 thorpej 129 1.37 perry int lance_isa_probe(struct isa_attach_args *, struct le_isa_params *, int); 130 1.48 cegger void le_isa_attach(device_t, struct le_softc *, 131 1.46 tsutsui struct isa_attach_args *, struct le_isa_params *); 132 1.1 thorpej 133 1.37 perry int le_isa_intredge(void *); 134 1.1 thorpej 135 1.26 mrg #if defined(_KERNEL_OPT) 136 1.22 drochner #include "opt_ddb.h" 137 1.22 drochner #endif 138 1.22 drochner 139 1.22 drochner #ifdef DDB 140 1.22 drochner #define integrate 141 1.22 drochner #define hide 142 1.22 drochner #else 143 1.41 perry #define integrate static inline 144 1.22 drochner #define hide static 145 1.22 drochner #endif 146 1.22 drochner 147 1.46 tsutsui hide void le_isa_wrcsr(struct lance_softc *, uint16_t, uint16_t); 148 1.46 tsutsui hide uint16_t le_isa_rdcsr(struct lance_softc *, uint16_t); 149 1.1 thorpej 150 1.11 thorpej #define LE_ISA_MEMSIZE 16384 151 1.11 thorpej 152 1.1 thorpej hide void 153 1.46 tsutsui le_isa_wrcsr(struct lance_softc *sc, uint16_t port, uint16_t val) 154 1.1 thorpej { 155 1.6 thorpej struct le_softc *lesc = (struct le_softc *)sc; 156 1.6 thorpej bus_space_tag_t iot = lesc->sc_iot; 157 1.6 thorpej bus_space_handle_t ioh = lesc->sc_ioh; 158 1.1 thorpej 159 1.6 thorpej bus_space_write_2(iot, ioh, lesc->sc_rap, port); 160 1.6 thorpej bus_space_write_2(iot, ioh, lesc->sc_rdp, val); 161 1.1 thorpej } 162 1.1 thorpej 163 1.46 tsutsui hide uint16_t 164 1.46 tsutsui le_isa_rdcsr(struct lance_softc *sc, uint16_t port) 165 1.1 thorpej { 166 1.6 thorpej struct le_softc *lesc = (struct le_softc *)sc; 167 1.6 thorpej bus_space_tag_t iot = lesc->sc_iot; 168 1.38 perry bus_space_handle_t ioh = lesc->sc_ioh; 169 1.46 tsutsui uint16_t val; 170 1.1 thorpej 171 1.6 thorpej bus_space_write_2(iot, ioh, lesc->sc_rap, port); 172 1.38 perry val = bus_space_read_2(iot, ioh, lesc->sc_rdp); 173 1.1 thorpej return (val); 174 1.1 thorpej } 175 1.1 thorpej 176 1.1 thorpej int 177 1.46 tsutsui ne2100_isa_probe(device_t parent, cfdata_t cf, void *aux) 178 1.1 thorpej { 179 1.46 tsutsui 180 1.46 tsutsui return (lance_isa_probe(aux, &ne2100_params, cf->cf_flags)); 181 1.17 drochner } 182 1.14 thorpej 183 1.17 drochner int 184 1.46 tsutsui bicc_isa_probe(device_t parent, cfdata_t cf, void *aux) 185 1.17 drochner { 186 1.46 tsutsui 187 1.46 tsutsui return (lance_isa_probe(aux, &bicc_params, cf->cf_flags)); 188 1.1 thorpej } 189 1.1 thorpej 190 1.17 drochner /* 191 1.17 drochner * Determine which chip is present on the card. 192 1.17 drochner */ 193 1.1 thorpej int 194 1.46 tsutsui lance_isa_probe(struct isa_attach_args *ia, struct le_isa_params *p, int flags) 195 1.1 thorpej { 196 1.6 thorpej bus_space_tag_t iot = ia->ia_iot; 197 1.6 thorpej bus_space_handle_t ioh; 198 1.17 drochner int rap, rdp; 199 1.17 drochner int rv = 0; 200 1.17 drochner 201 1.29 thorpej if (ia->ia_nio < 1) 202 1.29 thorpej return (0); 203 1.29 thorpej if (ia->ia_nirq < 1) 204 1.29 thorpej return (0); 205 1.29 thorpej if (ia->ia_ndrq < 1) 206 1.29 thorpej return (0); 207 1.29 thorpej 208 1.29 thorpej if (ISA_DIRECT_CONFIG(ia)) 209 1.29 thorpej return (0); 210 1.29 thorpej 211 1.17 drochner /* Disallow wildcarded i/o address. */ 212 1.36 drochner if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT) 213 1.29 thorpej return (0); 214 1.36 drochner if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) 215 1.29 thorpej return (0); 216 1.38 perry if ((flags & LANCEISA_FLAG_LOCALBUS) == 0 && 217 1.36 drochner ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ) 218 1.17 drochner return (0); 219 1.1 thorpej 220 1.6 thorpej /* Map i/o space. */ 221 1.29 thorpej if (bus_space_map(iot, ia->ia_io[0].ir_addr, p->iosize, 0, &ioh)) 222 1.17 drochner return (0); 223 1.6 thorpej 224 1.17 drochner rap = p->rap; 225 1.17 drochner rdp = p->rdp; 226 1.6 thorpej 227 1.17 drochner /* Stop the LANCE chip and put it in a known state. */ 228 1.17 drochner bus_space_write_2(iot, ioh, rap, LE_CSR0); 229 1.17 drochner bus_space_write_2(iot, ioh, rdp, LE_C0_STOP); 230 1.17 drochner delay(100); 231 1.12 mycroft 232 1.17 drochner bus_space_write_2(iot, ioh, rap, LE_CSR0); 233 1.17 drochner if (bus_space_read_2(iot, ioh, rdp) != LE_C0_STOP) 234 1.6 thorpej goto bad; 235 1.6 thorpej 236 1.17 drochner bus_space_write_2(iot, ioh, rap, LE_CSR3); 237 1.17 drochner bus_space_write_2(iot, ioh, rdp, 0); 238 1.6 thorpej 239 1.29 thorpej ia->ia_nio = 1; 240 1.29 thorpej ia->ia_io[0].ir_size = p->iosize; 241 1.29 thorpej 242 1.29 thorpej ia->ia_nirq = 1; 243 1.31 rafal 244 1.31 rafal if ((flags & LANCEISA_FLAG_LOCALBUS) != 0 && 245 1.36 drochner ia->ia_drq[0].ir_drq == ISA_UNKNOWN_DRQ) 246 1.31 rafal ia->ia_ndrq = 0; 247 1.31 rafal else 248 1.31 rafal ia->ia_ndrq = 1; 249 1.29 thorpej 250 1.29 thorpej ia->ia_niomem = 0; 251 1.29 thorpej 252 1.17 drochner rv = 1; 253 1.1 thorpej 254 1.17 drochner bad: 255 1.17 drochner bus_space_unmap(iot, ioh, p->iosize); 256 1.17 drochner return (rv); 257 1.17 drochner } 258 1.1 thorpej 259 1.17 drochner void 260 1.46 tsutsui le_dummyattach(device_t parent, device_t self, void *aux) 261 1.17 drochner { 262 1.46 tsutsui 263 1.46 tsutsui aprint_normal("\n"); 264 1.1 thorpej 265 1.51 thorpej config_found(self, aux, 0, CFARGS_NONE); 266 1.17 drochner } 267 1.1 thorpej 268 1.17 drochner int 269 1.46 tsutsui le_dummyprobe(device_t parent, cfdata_t cf, void *aux) 270 1.17 drochner { 271 1.46 tsutsui 272 1.17 drochner return (1); 273 1.17 drochner } 274 1.1 thorpej 275 1.17 drochner void 276 1.46 tsutsui le_ne2100_attach(device_t parent, device_t self, void *aux) 277 1.17 drochner { 278 1.46 tsutsui struct le_softc *lesc = device_private(self); 279 1.46 tsutsui struct lance_softc *sc = &lesc->sc_am7990.lsc; 280 1.46 tsutsui 281 1.46 tsutsui sc->sc_dev = self; 282 1.46 tsutsui le_isa_attach(parent, lesc, aux, &ne2100_params); 283 1.17 drochner } 284 1.1 thorpej 285 1.17 drochner void 286 1.46 tsutsui le_bicc_attach(device_t parent, device_t self, void *aux) 287 1.17 drochner { 288 1.46 tsutsui struct le_softc *lesc = device_private(self); 289 1.46 tsutsui struct lance_softc *sc = &lesc->sc_am7990.lsc; 290 1.46 tsutsui 291 1.46 tsutsui sc->sc_dev = self; 292 1.46 tsutsui le_isa_attach(parent, lesc, aux, &bicc_params); 293 1.1 thorpej } 294 1.1 thorpej 295 1.17 drochner void 296 1.48 cegger le_isa_attach(device_t parent, struct le_softc *lesc, 297 1.42 christos struct isa_attach_args *ia, struct le_isa_params *p) 298 1.1 thorpej { 299 1.22 drochner struct lance_softc *sc = &lesc->sc_am7990.lsc; 300 1.6 thorpej bus_space_tag_t iot = ia->ia_iot; 301 1.6 thorpej bus_space_handle_t ioh; 302 1.18 drochner bus_dma_tag_t dmat = ia->ia_dmat; 303 1.17 drochner bus_dma_segment_t seg; 304 1.20 thorpej int i, rseg, error; 305 1.1 thorpej 306 1.46 tsutsui aprint_normal(": %s Ethernet\n", p->name); 307 1.6 thorpej 308 1.30 rafal if (bus_space_map(iot, ia->ia_io[0].ir_addr, p->iosize, 0, &ioh)) 309 1.46 tsutsui panic("%s: can't map io", device_xname(sc->sc_dev)); 310 1.1 thorpej 311 1.1 thorpej /* 312 1.1 thorpej * Extract the physical MAC address from the ROM. 313 1.1 thorpej */ 314 1.9 is for (i = 0; i < sizeof(sc->sc_enaddr); i++) 315 1.17 drochner sc->sc_enaddr[i] = 316 1.17 drochner bus_space_read_1(iot, ioh, p->macstart + i * p->macstride); 317 1.6 thorpej 318 1.7 thorpej lesc->sc_iot = iot; 319 1.7 thorpej lesc->sc_ioh = ioh; 320 1.18 drochner lesc->sc_dmat = dmat; 321 1.17 drochner lesc->sc_rap = p->rap; 322 1.17 drochner lesc->sc_rdp = p->rdp; 323 1.1 thorpej 324 1.1 thorpej /* 325 1.17 drochner * Allocate a DMA area for the card. 326 1.1 thorpej */ 327 1.25 thorpej if (bus_dmamem_alloc(dmat, LE_ISA_MEMSIZE, PAGE_SIZE, 0, &seg, 1, 328 1.17 drochner &rseg, BUS_DMA_NOWAIT)) { 329 1.46 tsutsui aprint_error_dev(sc->sc_dev, 330 1.46 tsutsui "couldn't allocate memory for card\n"); 331 1.53 rin goto bad_bsunmap; 332 1.17 drochner } 333 1.17 drochner if (bus_dmamem_map(dmat, &seg, rseg, LE_ISA_MEMSIZE, 334 1.44 christos (void **)&sc->sc_mem, 335 1.17 drochner BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) { 336 1.46 tsutsui aprint_error_dev(sc->sc_dev, "couldn't map memory for card\n"); 337 1.53 rin goto bad_free; 338 1.17 drochner } 339 1.6 thorpej 340 1.6 thorpej /* 341 1.17 drochner * Create and load the DMA map for the DMA area. 342 1.6 thorpej */ 343 1.17 drochner if (bus_dmamap_create(dmat, LE_ISA_MEMSIZE, 1, 344 1.17 drochner LE_ISA_MEMSIZE, 0, BUS_DMA_NOWAIT, &lesc->sc_dmam)) { 345 1.46 tsutsui aprint_error_dev(sc->sc_dev, "couldn't create DMA map\n"); 346 1.53 rin goto bad_unmap; 347 1.17 drochner } 348 1.17 drochner if (bus_dmamap_load(dmat, lesc->sc_dmam, 349 1.17 drochner sc->sc_mem, LE_ISA_MEMSIZE, NULL, BUS_DMA_NOWAIT)) { 350 1.52 andvar aprint_error_dev(sc->sc_dev, "couldn't load DMA map\n"); 351 1.53 rin goto bad_destroy; 352 1.1 thorpej } 353 1.1 thorpej 354 1.17 drochner sc->sc_conf3 = 0; 355 1.17 drochner sc->sc_addr = lesc->sc_dmam->dm_segs[0].ds_addr; 356 1.17 drochner sc->sc_memsize = LE_ISA_MEMSIZE; 357 1.17 drochner 358 1.22 drochner sc->sc_copytodesc = lance_copytobuf_contig; 359 1.22 drochner sc->sc_copyfromdesc = lance_copyfrombuf_contig; 360 1.22 drochner sc->sc_copytobuf = lance_copytobuf_contig; 361 1.22 drochner sc->sc_copyfrombuf = lance_copyfrombuf_contig; 362 1.22 drochner sc->sc_zerobuf = lance_zerobuf_contig; 363 1.1 thorpej 364 1.1 thorpej sc->sc_rdcsr = le_isa_rdcsr; 365 1.1 thorpej sc->sc_wrcsr = le_isa_wrcsr; 366 1.1 thorpej sc->sc_hwinit = NULL; 367 1.1 thorpej 368 1.31 rafal if (ia->ia_ndrq > 0) { 369 1.38 perry if ((error = isa_dmacascade(ia->ia_ic, 370 1.31 rafal ia->ia_drq[0].ir_drq)) != 0) { 371 1.46 tsutsui aprint_error_dev(sc->sc_dev, 372 1.46 tsutsui "unable to cascade DRQ, error = %d\n", error); 373 1.53 rin goto bad_destroy; 374 1.31 rafal } 375 1.20 thorpej } 376 1.1 thorpej 377 1.29 thorpej lesc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq, 378 1.29 thorpej IST_EDGE, IPL_NET, le_isa_intredge, sc); 379 1.20 thorpej 380 1.46 tsutsui aprint_normal("%s", device_xname(sc->sc_dev)); 381 1.22 drochner am7990_config(&lesc->sc_am7990); 382 1.53 rin 383 1.53 rin return; 384 1.53 rin 385 1.53 rin bad_destroy: 386 1.53 rin bus_dmamap_destroy(dmat, lesc->sc_dmam); 387 1.53 rin bad_unmap: 388 1.53 rin bus_dmamem_unmap(dmat, sc->sc_mem, LE_ISA_MEMSIZE); 389 1.53 rin bad_free: 390 1.53 rin bus_dmamem_free(dmat, &seg, rseg); 391 1.53 rin bad_bsunmap: 392 1.53 rin bus_space_unmap(iot, ioh, p->iosize); 393 1.1 thorpej } 394 1.1 thorpej 395 1.1 thorpej /* 396 1.1 thorpej * Controller interrupt. 397 1.1 thorpej */ 398 1.3 thorpej int 399 1.46 tsutsui le_isa_intredge(void *arg) 400 1.1 thorpej { 401 1.1 thorpej 402 1.1 thorpej if (am7990_intr(arg) == 0) 403 1.1 thorpej return (0); 404 1.1 thorpej for (;;) 405 1.1 thorpej if (am7990_intr(arg) == 0) 406 1.1 thorpej return (1); 407 1.1 thorpej } 408