[BACK]Return to if_fmv_isa.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / isa

Annotation of src/sys/dev/isa/if_fmv_isa.c, Revision 1.9.16.1

1.9.16.1! skrll       1: /*     $NetBSD: if_fmv_isa.c,v 1.9.2.1 2008/05/08 07:52:44 jdc Exp $   */
1.1       tsutsui     2:
                      3: /*
                      4:  * All Rights Reserved, Copyright (C) Fujitsu Limited 1995
                      5:  *
                      6:  * This software may be used, modified, copied, distributed, and sold, in
                      7:  * both source and binary form provided that the above copyright, these
                      8:  * terms and the following disclaimer are retained.  The name of the author
                      9:  * and/or the contributor may not be used to endorse or promote products
                     10:  * derived from this software without specific prior written permission.
                     11:  *
                     12:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND
                     13:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     14:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     15:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE
                     16:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     17:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     18:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION.
                     19:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     20:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     21:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     22:  * SUCH DAMAGE.
                     23:  */
                     24:
                     25: /*
                     26:  * Portions copyright (C) 1993, David Greenman.  This software may be used,
                     27:  * modified, copied, distributed, and sold, in both source and binary form
                     28:  * provided that the above copyright and these terms are retained.  Under no
                     29:  * circumstances is the author responsible for the proper functioning of this
                     30:  * software, nor does the author assume any responsibility for damages
                     31:  * incurred with its use.
                     32:  */
                     33:
                     34: #include <sys/cdefs.h>
1.9.16.1! skrll      35: __KERNEL_RCSID(0, "$NetBSD: if_fmv_isa.c,v 1.9.2.1 2008/05/08 07:52:44 jdc Exp $");
1.1       tsutsui    36:
                     37: #include <sys/param.h>
                     38: #include <sys/systm.h>
                     39: #include <sys/device.h>
                     40:
                     41: #include <net/if.h>
                     42: #include <net/if_ether.h>
                     43: #include <net/if_media.h>
                     44:
                     45: #include <machine/bus.h>
                     46: #include <machine/intr.h>
                     47:
                     48: #include <dev/ic/mb86960reg.h>
                     49: #include <dev/ic/mb86960var.h>
                     50: #include <dev/ic/fmvreg.h>
                     51: #include <dev/ic/fmvvar.h>
                     52:
                     53: #include <dev/isa/isavar.h>
                     54:
1.4       tsutsui    55: int    fmv_isa_match(struct device *, struct cfdata *, void *);
                     56: void   fmv_isa_attach(struct device *, struct device *, void *);
1.1       tsutsui    57:
                     58: struct fmv_isa_softc {
                     59:        struct  mb86960_softc sc_mb86960;       /* real "mb86960" softc */
                     60:
                     61:        /* ISA-specific goo. */
                     62:        void    *sc_ih;                         /* interrupt cookie */
                     63: };
                     64:
                     65: CFATTACH_DECL(fmv_isa, sizeof(struct fmv_isa_softc),
                     66:     fmv_isa_match, fmv_isa_attach, NULL, NULL);
                     67:
                     68: struct fe_simple_probe_struct {
1.4       tsutsui    69:        uint8_t port;   /* Offset from the base I/O address. */
                     70:        uint8_t mask;   /* Bits to be checked. */
                     71:        uint8_t bits;   /* Values to be compared against. */
1.1       tsutsui    72: };
                     73:
1.6       perry      74: static inline int fe_simple_probe(bus_space_tag_t, bus_space_handle_t,
1.4       tsutsui    75:     struct fe_simple_probe_struct const *);
                     76: static int fmv_find(bus_space_tag_t, bus_space_handle_t, int *, int *);
1.1       tsutsui    77:
                     78: static int const fmv_iomap[8] = {
                     79:        0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340
                     80: };
                     81: #define NFMV_IOMAP (sizeof (fmv_iomap) / sizeof (fmv_iomap[0]))
                     82: #define FMV_NPORTS 0x20
                     83:
1.4       tsutsui    84: #ifdef FMV_DEBUG
                     85: #define DPRINTF        printf
                     86: #else
                     87: #define DPRINTF        while (/* CONSTCOND */0) printf
                     88: #endif
                     89:
1.1       tsutsui    90: /*
                     91:  * Hardware probe routines.
                     92:  */
                     93:
                     94: /*
                     95:  * Determine if the device is present.
                     96:  */
                     97: int
1.9       christos   98: fmv_isa_match(struct device *parent, struct cfdata *match,
1.8       christos   99:     void *aux)
1.1       tsutsui   100: {
                    101:        struct isa_attach_args *ia = aux;
                    102:        bus_space_tag_t iot = ia->ia_iot;
                    103:        bus_space_handle_t ioh;
                    104:        int i, iobase, irq, rv = 0;
1.4       tsutsui   105:        uint8_t myea[ETHER_ADDR_LEN];
1.1       tsutsui   106:
                    107:        if (ia->ia_nio < 1)
1.4       tsutsui   108:                return 0;
1.1       tsutsui   109:        if (ia->ia_nirq < 1)
1.4       tsutsui   110:                return 0;
1.1       tsutsui   111:
                    112:        if (ISA_DIRECT_CONFIG(ia))
1.4       tsutsui   113:                return 0;
1.1       tsutsui   114:
                    115:        /* Disallow wildcarded values. */
1.3       drochner  116:        if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.4       tsutsui   117:                return 0;
1.1       tsutsui   118:
                    119:        /*
                    120:         * See if the sepcified address is valid for FMV-180 series.
                    121:         */
                    122:        for (i = 0; i < NFMV_IOMAP; i++)
                    123:                if (fmv_iomap[i] == ia->ia_io[0].ir_addr)
                    124:                        break;
                    125:        if (i == NFMV_IOMAP) {
1.4       tsutsui   126:                DPRINTF("fmv_match: unknown iobase 0x%x\n",
1.1       tsutsui   127:                    ia->ia_io[0].ir_addr);
1.4       tsutsui   128:                return 0;
1.1       tsutsui   129:        }
                    130:
                    131:        /* Map i/o space. */
                    132:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, FMV_NPORTS, 0, &ioh)) {
1.4       tsutsui   133:                DPRINTF("fmv_match: couldn't map iospace 0x%x\n",
1.1       tsutsui   134:                    ia->ia_io[0].ir_addr);
1.4       tsutsui   135:                return 0;
1.1       tsutsui   136:        }
                    137:
                    138:        if (fmv_find(iot, ioh, &iobase, &irq) == 0) {
1.4       tsutsui   139:                DPRINTF("fmv_match: fmv_find failed\n");
1.1       tsutsui   140:                goto out;
                    141:        }
                    142:
                    143:        if (iobase != ia->ia_io[0].ir_addr) {
1.4       tsutsui   144:                DPRINTF("fmv_match: unexpected iobase in board: 0x%x\n",
1.1       tsutsui   145:                    iobase);
                    146:                goto out;
                    147:        }
                    148:
                    149:        if (fmv_detect(iot, ioh, myea) == 0) { /* XXX necessary? */
1.4       tsutsui   150:                DPRINTF("fmv_match: fmv_detect failed\n");
1.1       tsutsui   151:                goto out;
                    152:        }
                    153:
1.3       drochner  154:        if (ia->ia_irq[0].ir_irq != ISA_UNKNOWN_IRQ) {
1.1       tsutsui   155:                if (ia->ia_irq[0].ir_irq != irq) {
                    156:                        printf("fmv_match: irq mismatch; "
                    157:                            "kernel configured %d != board configured %d\n",
                    158:                            ia->ia_irq[0].ir_irq, irq);
                    159:                        goto out;
                    160:                }
                    161:        } else
                    162:                ia->ia_irq[0].ir_irq = irq;
                    163:
                    164:        ia->ia_nio = 1;
                    165:        ia->ia_io[0].ir_size = FMV_NPORTS;
                    166:
                    167:        ia->ia_nirq = 1;
                    168:
                    169:        ia->ia_niomem = 0;
                    170:        ia->ia_ndrq = 0;
                    171:
                    172:        rv = 1;
                    173:
                    174:  out:
                    175:        bus_space_unmap(iot, ioh, FMV_NPORTS);
1.4       tsutsui   176:        return rv;
1.1       tsutsui   177: }
                    178:
                    179: /*
                    180:  * Check for specific bits in specific registers have specific values.
                    181:  */
1.6       perry     182: static inline int
1.4       tsutsui   183: fe_simple_probe(bus_space_tag_t iot, bus_space_handle_t ioh,
                    184:     struct fe_simple_probe_struct const *sp)
1.1       tsutsui   185: {
1.4       tsutsui   186:        uint8_t val;
1.1       tsutsui   187:        struct fe_simple_probe_struct const *p;
                    188:
                    189:        for (p = sp; p->mask != 0; p++) {
                    190:                val = bus_space_read_1(iot, ioh, p->port);
                    191:                if ((val & p->mask) != p->bits) {
1.4       tsutsui   192:                        DPRINTF("fe_simple_probe: %x & %x != %x\n",
1.1       tsutsui   193:                            val, p->mask, p->bits);
1.4       tsutsui   194:                        return 0;
1.1       tsutsui   195:                }
                    196:        }
                    197:
1.4       tsutsui   198:        return 1;
1.1       tsutsui   199: }
                    200:
                    201: /*
                    202:  * Hardware (vendor) specific probe routines.
                    203:  */
                    204:
                    205: /*
                    206:  * Probe Fujitsu FMV-180 series boards and get iobase and irq from
                    207:  * board.
                    208:  */
                    209: static int
1.4       tsutsui   210: fmv_find(bus_space_tag_t iot, bus_space_handle_t ioh, int *iobase, int *irq)
1.1       tsutsui   211: {
1.4       tsutsui   212:        uint8_t config;
1.1       tsutsui   213:        static int const fmv_irqmap[4] = { 3, 7, 10, 15 };
                    214:        static struct fe_simple_probe_struct const probe_table[] = {
                    215:                { FE_DLCR2, 0x70, 0x00 },
                    216:                { FE_DLCR4, 0x08, 0x00 },
                    217:            /*  { FE_DLCR5, 0x80, 0x00 },       Doesn't work. */
                    218:
                    219:                { FE_FMV0, FE_FMV0_MAGIC_MASK, FE_FMV0_MAGIC_VALUE },
                    220:                { FE_FMV1, FE_FMV1_MAGIC_MASK, FE_FMV1_MAGIC_VALUE },
                    221:                { FE_FMV3, FE_FMV3_EXTRA_MASK, FE_FMV3_EXTRA_VALUE },
                    222: #if 1
                    223:        /*
                    224:         * Test *vendor* part of the station address for Fujitsu.
                    225:         * The test will gain reliability of probe process, but
                    226:         * it rejects FMV-180 clone boards manufactured by other vendors.
                    227:         * We have to turn the test off when such cards are made available.
                    228:         */
                    229:                { FE_FMV4, 0xFF, 0x00 },
                    230:                { FE_FMV5, 0xFF, 0x00 },
                    231:                { FE_FMV6, 0xFF, 0x0E },
                    232: #else
                    233:        /*
                    234:         * We can always verify the *first* 2 bits (in Ehternet
                    235:         * bit order) are "no multicast" and "no local" even for
                    236:         * unknown vendors.
                    237:         */
                    238:                { FE_FMV4, 0x03, 0x00 },
                    239: #endif
1.7       christos  240:                { 0,       0x00, 0x00 },
1.1       tsutsui   241:        };
                    242:
                    243:        /* Simple probe. */
1.9.16.1! skrll     244:        if (fe_simple_probe(iot, ioh, probe_table) == 0)
1.4       tsutsui   245:                return 0;
1.1       tsutsui   246:
                    247:        /* Check if our I/O address matches config info on EEPROM. */
                    248:        config = bus_space_read_1(iot, ioh, FE_FMV2);
                    249:        *iobase = fmv_iomap[(config & FE_FMV2_ADDR) >> FE_FMV2_ADDR_SHIFT];
                    250:
                    251:        /*
                    252:         * Determine which IRQ to be used.
                    253:         *
                    254:         * In this version, we always get an IRQ assignment from the
                    255:         * FMV-180's configuration EEPROM, ignoring that specified in
                    256:         * config file.
                    257:         */
                    258:        *irq = fmv_irqmap[(config & FE_FMV2_IRQ) >> FE_FMV2_IRQ_SHIFT];
                    259:
1.4       tsutsui   260:        return 1;
1.1       tsutsui   261: }
                    262:
                    263: void
1.9       christos  264: fmv_isa_attach(struct device *parent, struct device *self,
1.8       christos  265:     void *aux)
1.1       tsutsui   266: {
                    267:        struct fmv_isa_softc *isc = (struct fmv_isa_softc *)self;
                    268:        struct mb86960_softc *sc = &isc->sc_mb86960;
                    269:        struct isa_attach_args *ia = aux;
                    270:        bus_space_tag_t iot = ia->ia_iot;
                    271:        bus_space_handle_t ioh;
                    272:
                    273:        /* Map i/o space. */
                    274:        if (bus_space_map(iot, ia->ia_io[0].ir_addr, FMV_NPORTS, 0, &ioh)) {
                    275:                printf("%s: can't map i/o space\n", sc->sc_dev.dv_xname);
                    276:                return;
                    277:        }
                    278:
                    279:        sc->sc_bst = iot;
                    280:        sc->sc_bsh = ioh;
                    281:
                    282:        fmv_attach(sc);
                    283:
                    284:        /* Establish the interrupt handler. */
                    285:        isc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq[0].ir_irq,
                    286:            IST_EDGE, IPL_NET, mb86960_intr, sc);
                    287:        if (isc->sc_ih == NULL)
                    288:                printf("%s: couldn't establish interrupt handler\n",
                    289:                    sc->sc_dev.dv_xname);
                    290: }

CVSweb <webmaster@jp.NetBSD.org>