Annotation of sys/dev/eisa/if_fea.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: if_fea.c,v 1.17 2004/05/12 06:35:10 tedu Exp $ */
! 2: /* $NetBSD: if_fea.c,v 1.9 1996/10/21 22:31:05 thorpej Exp $ */
! 3:
! 4: /*-
! 5: * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com>
! 6: * All rights reserved.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. The name of the author may not be used to endorse or promote products
! 14: * derived from this software without specific prior written permission
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 26: *
! 27: * Id: if_fea.c,v 1.6 1996/06/07 20:02:25 thomas Exp
! 28: */
! 29:
! 30: /*
! 31: * DEC PDQ FDDI Controller
! 32: *
! 33: * This module support the DEFEA EISA FDDI Controller.
! 34: */
! 35:
! 36:
! 37: #include <sys/param.h>
! 38: #include <sys/kernel.h>
! 39: #include <sys/mbuf.h>
! 40: #include <sys/protosw.h>
! 41: #include <sys/socket.h>
! 42: #include <sys/ioctl.h>
! 43: #include <sys/errno.h>
! 44: #include <sys/malloc.h>
! 45: #include <sys/device.h>
! 46:
! 47: #include <net/if.h>
! 48: #include <net/if_types.h>
! 49: #include <net/if_dl.h>
! 50: #include <net/route.h>
! 51:
! 52: #include "bpfilter.h"
! 53: #if NBPFILTER > 0
! 54: #include <net/bpf.h>
! 55: #endif
! 56:
! 57: #ifdef INET
! 58: #include <netinet/in.h>
! 59: #include <netinet/in_systm.h>
! 60: #include <netinet/in_var.h>
! 61: #include <netinet/ip.h>
! 62: #include <netinet/if_ether.h>
! 63: #endif
! 64:
! 65: #include <net/if_fddi.h>
! 66:
! 67: #include <machine/cpu.h>
! 68: #include <machine/bus.h>
! 69:
! 70: #include <dev/ic/pdqvar.h>
! 71: #include <dev/ic/pdqreg.h>
! 72:
! 73: #include <dev/eisa/eisareg.h>
! 74: #include <dev/eisa/eisavar.h>
! 75: #include <dev/eisa/eisadevs.h>
! 76:
! 77: /*
! 78: *
! 79: */
! 80:
! 81: void pdq_eisa_subprobe(bus_space_tag_t, bus_space_handle_t,
! 82: u_int32_t *, u_int32_t *, u_int32_t *);
! 83: void pdq_eisa_devinit(pdq_softc_t *);
! 84: int pdq_eisa_match(struct device *, void *, void *);
! 85: void pdq_eisa_attach(struct device *, struct device *, void *);
! 86:
! 87: #define DEFEA_INTRENABLE 0x8 /* level interrupt */
! 88: static int pdq_eisa_irqs[4] = { 9, 10, 11, 15 };
! 89:
! 90: void
! 91: pdq_eisa_subprobe(bc, iobase, maddr, msize, irq)
! 92: bus_space_tag_t bc;
! 93: bus_space_handle_t iobase;
! 94: u_int32_t *maddr;
! 95: u_int32_t *msize;
! 96: u_int32_t *irq;
! 97: {
! 98: if (irq != NULL)
! 99: *irq = pdq_eisa_irqs[PDQ_OS_IORD_8(bc, iobase,
! 100: PDQ_EISA_IO_CONFIG_STAT_0) & 3];
! 101:
! 102: *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8)
! 103: | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16);
! 104: *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8;
! 105: }
! 106:
! 107: void
! 108: pdq_eisa_devinit(sc)
! 109: pdq_softc_t *sc;
! 110: {
! 111: u_int8_t data;
! 112: bus_space_tag_t tag;
! 113:
! 114: tag = sc->sc_bc;
! 115:
! 116: /*
! 117: * Do the standard initialization for the DEFEA registers.
! 118: */
! 119: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23);
! 120: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1,
! 121: (sc->sc_iobase >> 8) & 0xF0);
! 122: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1,
! 123: (sc->sc_iobase >> 8) & 0xF0);
! 124: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01);
! 125: data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF);
! 126: #if defined(PDQ_IOMAPPED)
! 127: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1);
! 128: #else
! 129: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1);
! 130: #endif
! 131: data = PDQ_OS_IORD_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0);
! 132: PDQ_OS_IOWR_8(tag, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0,
! 133: data | DEFEA_INTRENABLE);
! 134: }
! 135:
! 136: int
! 137: pdq_eisa_match(parent, match, aux)
! 138: struct device *parent;
! 139: void *match;
! 140: void *aux;
! 141: {
! 142: struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
! 143:
! 144: if (strncmp(ea->ea_idstring, "DEC300", 6) == 0)
! 145: return (1);
! 146: return (0);
! 147: }
! 148:
! 149: void
! 150: pdq_eisa_attach(parent, self, aux)
! 151: struct device *parent;
! 152: struct device *self;
! 153: void *aux;
! 154: {
! 155: pdq_softc_t *sc = (pdq_softc_t *) self;
! 156: struct eisa_attach_args *ea = (struct eisa_attach_args *) aux;
! 157: u_int32_t irq, maddr, msize;
! 158: eisa_intr_handle_t ih;
! 159: const char *intrstr;
! 160:
! 161: sc->sc_iotag = ea->ea_iot;
! 162: bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ);
! 163: sc->sc_if.if_flags = 0;
! 164: sc->sc_if.if_softc = sc;
! 165:
! 166: /*
! 167: * NOTE: sc_bc is an alias for sc_csrtag and sc_membase is
! 168: * an alias for sc_csrhandle. sc_iobase is used here to
! 169: * check the card's configuration.
! 170: */
! 171:
! 172: if (bus_space_map(sc->sc_iotag, EISA_SLOT_ADDR(ea->ea_slot),
! 173: EISA_SLOT_SIZE, 0, &sc->sc_iobase)) {
! 174: printf("\n%s: failed to map I/O!\n", sc->sc_dev.dv_xname);
! 175: return;
! 176: }
! 177:
! 178: pdq_eisa_subprobe(sc->sc_iotag, sc->sc_iobase, &maddr, &msize, &irq);
! 179:
! 180: #if defined(PDQ_IOMAPPED)
! 181: sc->sc_csrtag = sc->sc_iotag;
! 182: sc->sc_csrhandle = sc->sc_iobase;
! 183: #else
! 184: if (maddr == 0 || msize == 0) {
! 185: printf("\n%s: error: memory not enabled! ECU reconfiguration"
! 186: " required\n", sc->sc_dev.dv_xname);
! 187: return;
! 188: }
! 189:
! 190: if (bus_space_map(sc->sc_csrtag, maddr, msize, 0, &sc->sc_csrhandle)) {
! 191: bus_space_unmap(sc->sc_iotag, sc->sc_iobase, EISA_SLOT_SIZE);
! 192: printf("\n%s: failed to map memory (0x%x-0x%x)!\n",
! 193: sc->sc_dev.dv_xname, maddr, maddr + msize - 1);
! 194: return;
! 195: }
! 196: #endif
! 197: pdq_eisa_devinit(sc);
! 198: sc->sc_pdq = pdq_initialize(sc->sc_bc, sc->sc_membase,
! 199: sc->sc_if.if_xname, 0, (void *) sc, PDQ_DEFEA);
! 200: if (sc->sc_pdq == NULL) {
! 201: printf("%s: initialization failed\n", sc->sc_dev.dv_xname);
! 202: return;
! 203: }
! 204:
! 205: if (eisa_intr_map(ea->ea_ec, irq, &ih)) {
! 206: printf("%s: couldn't map interrupt (%d)\n",
! 207: sc->sc_dev.dv_xname, irq);
! 208: return;
! 209: }
! 210: intrstr = eisa_intr_string(ea->ea_ec, ih);
! 211: sc->sc_ih = eisa_intr_establish(ea->ea_ec, ih, IST_LEVEL, IPL_NET,
! 212: (int (*)(void *)) pdq_interrupt, sc->sc_pdq, sc->sc_dev.dv_xname);
! 213: if (sc->sc_ih == NULL) {
! 214: printf("%s: couldn't establish interrupt", sc->sc_dev.dv_xname);
! 215: if (intrstr != NULL)
! 216: printf(" at %s", intrstr);
! 217: printf("\n");
! 218: return;
! 219: }
! 220: if (intrstr != NULL)
! 221: printf(": interrupting at %s\n", intrstr);
! 222:
! 223: bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes,
! 224: sc->sc_arpcom.ac_enaddr, 6);
! 225:
! 226: pdq_ifattach(sc, NULL);
! 227:
! 228: sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset,
! 229: sc->sc_pdq);
! 230: if (sc->sc_ats == NULL)
! 231: printf("%s: warning: couldn't establish shutdown hook\n",
! 232: self->dv_xname);
! 233: #if !defined(PDQ_IOMAPPED)
! 234: printf("%s: using iomem 0x%x-0x%x\n", sc->sc_dev.dv_xname, maddr,
! 235: maddr + msize - 1);
! 236: #endif
! 237: }
! 238:
! 239: struct cfattach fea_ca = {
! 240: sizeof(pdq_softc_t), pdq_eisa_match, pdq_eisa_attach
! 241: };
! 242:
! 243: struct cfdriver fea_cd = {
! 244: 0, "fea", DV_IFNET
! 245: };
CVSweb