Home | History | Annotate | Line # | Download | only in isa
if_ai.c revision 1.9
      1  1.9     bjh21 /*	$NetBSD: if_ai.c,v 1.9 2001/01/22 22:28:46 bjh21 Exp $	*/
      2  1.1        pk 
      3  1.1        pk /*-
      4  1.1        pk  * Copyright (c) 1998 The NetBSD Foundation, Inc.
      5  1.1        pk  * All rights reserved.
      6  1.1        pk  *
      7  1.1        pk  * This code is derived from software contributed to The NetBSD Foundation
      8  1.1        pk  * by Rafal K. Boni.
      9  1.1        pk  *
     10  1.1        pk  * Redistribution and use in source and binary forms, with or without
     11  1.1        pk  * modification, are permitted provided that the following conditions
     12  1.1        pk  * are met:
     13  1.1        pk  * 1. Redistributions of source code must retain the above copyright
     14  1.1        pk  *    notice, this list of conditions and the following disclaimer.
     15  1.1        pk  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1        pk  *    notice, this list of conditions and the following disclaimer in the
     17  1.1        pk  *    documentation and/or other materials provided with the distribution.
     18  1.1        pk  * 3. All advertising materials mentioning features or use of this software
     19  1.1        pk  *    must display the following acknowledgement:
     20  1.1        pk  *	This product includes software developed by the NetBSD
     21  1.1        pk  *	Foundation, Inc. and its contributors.
     22  1.1        pk  * 4. Neither the name of The NetBSD Foundation nor the names of its
     23  1.1        pk  *    contributors may be used to endorse or promote products derived
     24  1.1        pk  *    from this software without specific prior written permission.
     25  1.1        pk  *
     26  1.1        pk  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     27  1.1        pk  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     28  1.1        pk  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     29  1.1        pk  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     30  1.1        pk  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     31  1.1        pk  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     32  1.1        pk  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     33  1.1        pk  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     34  1.1        pk  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     35  1.1        pk  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     36  1.1        pk  * POSSIBILITY OF SUCH DAMAGE.
     37  1.1        pk  */
     38  1.1        pk 
     39  1.1        pk #include <sys/param.h>
     40  1.1        pk #include <sys/systm.h>
     41  1.1        pk #include <sys/mbuf.h>
     42  1.1        pk #include <sys/errno.h>
     43  1.1        pk #include <sys/device.h>
     44  1.1        pk #include <sys/protosw.h>
     45  1.1        pk #include <sys/socket.h>
     46  1.1        pk 
     47  1.1        pk #include <net/if.h>
     48  1.1        pk #include <net/if_dl.h>
     49  1.1        pk #include <net/if_types.h>
     50  1.1        pk #include <net/if_media.h>
     51  1.1        pk #include <net/if_ether.h>
     52  1.1        pk 
     53  1.1        pk #include <machine/cpu.h>
     54  1.1        pk #include <machine/bus.h>
     55  1.1        pk #include <machine/intr.h>
     56  1.1        pk 
     57  1.1        pk #include <dev/isa/isareg.h>
     58  1.1        pk #include <dev/isa/isavar.h>
     59  1.1        pk 
     60  1.1        pk #include <dev/ic/i82586reg.h>
     61  1.1        pk #include <dev/ic/i82586var.h>
     62  1.1        pk #include <dev/isa/if_aireg.h>
     63  1.1        pk 
     64  1.1        pk #ifdef AI_DEBUG
     65  1.1        pk #define DPRINTF(x)	printf x
     66  1.1        pk #else
     67  1.2        pk #define DPRINTF(x)
     68  1.1        pk #endif
     69  1.1        pk 
     70  1.1        pk struct ai_softc {
     71  1.1        pk 	struct ie_softc sc_ie;
     72  1.1        pk 
     73  1.1        pk 	bus_space_tag_t sc_regt;	/* space tag for registers */
     74  1.1        pk 	bus_space_handle_t sc_regh;	/* space handle for registers */
     75  1.1        pk 
     76  1.1        pk 	u_int8_t	card_rev;
     77  1.1        pk 	u_int8_t	card_type;
     78  1.1        pk 
     79  1.2        pk 	void		*sc_ih;		/* interrupt handle */
     80  1.1        pk };
     81  1.1        pk 
     82  1.1        pk const char *ai_names[] = {
     83  1.1        pk         "StarLAN 10",
     84  1.1        pk         "EN100",
     85  1.1        pk         "StarLAN Fiber",
     86  1.1        pk };
     87  1.1        pk 
     88  1.1        pk /* Functions required by the i82586 MI driver */
     89  1.1        pk static void 	ai_reset __P((struct ie_softc *, int));
     90  1.1        pk static void 	ai_atten __P((struct ie_softc *));
     91  1.1        pk 
     92  1.2        pk static void	ai_copyin __P((struct ie_softc *, void *, int, size_t));
     93  1.1        pk static void	ai_copyout __P((struct ie_softc *, const void *, int, size_t));
     94  1.2        pk 
     95  1.1        pk static u_int16_t ai_read_16 __P((struct ie_softc *, int));
     96  1.1        pk static void	ai_write_16 __P((struct ie_softc *, int, u_int16_t));
     97  1.1        pk static void	ai_write_24 __P((struct ie_softc *, int, int));
     98  1.2        pk 
     99  1.1        pk /* Local support functions */
    100  1.1        pk static int 	check_ie_present __P((struct ie_softc*, bus_space_tag_t,
    101  1.1        pk 					bus_space_handle_t, bus_size_t));
    102  1.2        pk static int	ai_find_mem_size __P((struct ai_softc*, bus_space_tag_t,
    103  1.1        pk 					bus_size_t));
    104  1.1        pk 
    105  1.1        pk int ai_match __P((struct device *, struct cfdata *, void *));
    106  1.1        pk void ai_attach __P((struct device *, struct device *, void *));
    107  1.1        pk 
    108  1.1        pk /*
    109  1.1        pk  * AT&T StarLan support routines
    110  1.1        pk  */
    111  1.1        pk static void
    112  1.1        pk ai_reset(sc, why)
    113  1.1        pk 	struct ie_softc *sc;
    114  1.1        pk 	int why;
    115  1.1        pk {
    116  1.2        pk 	struct ai_softc* asc = (struct ai_softc *) sc;
    117  1.1        pk 
    118  1.2        pk 	switch (why) {
    119  1.2        pk 	case CHIP_PROBE:
    120  1.2        pk 		/* reset to chip to see if it responds */
    121  1.2        pk 		bus_space_write_1(asc->sc_regt, asc->sc_regh, AI_RESET, 0);
    122  1.2        pk 		DELAY(100);
    123  1.2        pk 		break;
    124  1.2        pk 
    125  1.2        pk 	case CARD_RESET:
    126  1.2        pk 		/*
    127  1.2        pk 		 * this takes around 10sec, and we can get
    128  1.2        pk 		 * by quite well w/out it...
    129  1.2        pk 		 */
    130  1.2        pk 		break;
    131  1.2        pk 	}
    132  1.1        pk }
    133  1.1        pk 
    134  1.1        pk static void
    135  1.1        pk ai_atten(sc)
    136  1.1        pk 	struct ie_softc *sc;
    137  1.1        pk {
    138  1.1        pk     struct ai_softc* asc = (struct ai_softc *) sc;
    139  1.1        pk     bus_space_write_1(asc->sc_regt, asc->sc_regh, AI_ATTN, 0);
    140  1.1        pk }
    141  1.1        pk 
    142  1.1        pk static void
    143  1.1        pk ai_copyin (sc, dst, offset, size)
    144  1.1        pk         struct ie_softc *sc;
    145  1.1        pk         void *dst;
    146  1.1        pk         int offset;
    147  1.1        pk         size_t size;
    148  1.1        pk {
    149  1.2        pk 	int dribble;
    150  1.2        pk 	u_int8_t* bptr = dst;
    151  1.1        pk 
    152  1.2        pk 	bus_space_barrier(sc->bt, sc->bh, offset, size,
    153  1.2        pk 			  BUS_SPACE_BARRIER_READ);
    154  1.1        pk 
    155  1.2        pk 	if (offset % 2) {
    156  1.2        pk 		*bptr = bus_space_read_1(sc->bt, sc->bh, offset);
    157  1.2        pk 		offset++; bptr++; size--;
    158  1.2        pk 	}
    159  1.2        pk 
    160  1.2        pk 	dribble = size % 2;
    161  1.2        pk 	bus_space_read_region_2(sc->bt, sc->bh, offset, (u_int16_t *) bptr,
    162  1.2        pk 				size >> 1);
    163  1.2        pk 
    164  1.2        pk 	if (dribble) {
    165  1.2        pk 		bptr += size - 1;
    166  1.2        pk 		offset += size - 1;
    167  1.2        pk 		*bptr = bus_space_read_1(sc->bt, sc->bh, offset);
    168  1.2        pk 	}
    169  1.1        pk }
    170  1.1        pk 
    171  1.1        pk static void
    172  1.2        pk ai_copyout (sc, src, offset, size)
    173  1.1        pk         struct ie_softc *sc;
    174  1.1        pk         const void *src;
    175  1.1        pk         int offset;
    176  1.1        pk         size_t size;
    177  1.1        pk {
    178  1.2        pk 	int dribble;
    179  1.2        pk 	int osize = size;
    180  1.2        pk 	int ooffset = offset;
    181  1.2        pk 	const u_int8_t* bptr = src;
    182  1.2        pk 
    183  1.2        pk 	if (offset % 2) {
    184  1.2        pk 		bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
    185  1.2        pk 		offset++; bptr++; size--;
    186  1.2        pk 	}
    187  1.2        pk 
    188  1.2        pk 	dribble = size % 2;
    189  1.2        pk 	bus_space_write_region_2(sc->bt, sc->bh, offset, (u_int16_t *)bptr,
    190  1.2        pk 				 size >> 1);
    191  1.2        pk 	if (dribble) {
    192  1.2        pk 		bptr += size - 1;
    193  1.2        pk 		offset += size - 1;
    194  1.2        pk 		bus_space_write_1(sc->bt, sc->bh, offset, *bptr);
    195  1.2        pk 	}
    196  1.1        pk 
    197  1.2        pk 	bus_space_barrier(sc->bt, sc->bh, ooffset, osize,
    198  1.2        pk 			  BUS_SPACE_BARRIER_WRITE);
    199  1.1        pk }
    200  1.1        pk 
    201  1.1        pk static u_int16_t
    202  1.1        pk ai_read_16 (sc, offset)
    203  1.1        pk         struct ie_softc *sc;
    204  1.1        pk         int offset;
    205  1.1        pk {
    206  1.1        pk 	bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_READ);
    207  1.1        pk         return bus_space_read_2(sc->bt, sc->bh, offset);
    208  1.1        pk }
    209  1.1        pk 
    210  1.1        pk static void
    211  1.2        pk ai_write_16 (sc, offset, value)
    212  1.1        pk         struct ie_softc *sc;
    213  1.1        pk         int offset;
    214  1.1        pk         u_int16_t value;
    215  1.1        pk {
    216  1.1        pk         bus_space_write_2(sc->bt, sc->bh, offset, value);
    217  1.1        pk 	bus_space_barrier(sc->bt, sc->bh, offset, 2, BUS_SPACE_BARRIER_WRITE);
    218  1.1        pk }
    219  1.1        pk 
    220  1.1        pk static void
    221  1.1        pk ai_write_24 (sc, offset, addr)
    222  1.1        pk         struct ie_softc *sc;
    223  1.1        pk         int offset, addr;
    224  1.1        pk {
    225  1.1        pk         bus_space_write_4(sc->bt, sc->bh, offset, addr +
    226  1.1        pk                                 (u_long) sc->sc_maddr - (u_long) sc->sc_iobase);
    227  1.1        pk 	bus_space_barrier(sc->bt, sc->bh, offset, 4, BUS_SPACE_BARRIER_WRITE);
    228  1.1        pk }
    229  1.1        pk 
    230  1.1        pk int
    231  1.1        pk ai_match(parent, cf, aux)
    232  1.1        pk 	struct device *parent;
    233  1.1        pk 	struct cfdata *cf;
    234  1.1        pk 	void *aux;
    235  1.1        pk {
    236  1.2        pk 	int rv = 0;
    237  1.2        pk 	u_int8_t val, type;
    238  1.2        pk 	bus_size_t memsize;
    239  1.3        pk 	bus_space_tag_t iot;
    240  1.2        pk 	bus_space_handle_t ioh;
    241  1.2        pk 	struct isa_attach_args * const ia = aux;
    242  1.3        pk 	struct ai_softc asc;
    243  1.2        pk 
    244  1.2        pk 
    245  1.2        pk 	/* Punt if wildcarded port, IRQ or memory address */
    246  1.2        pk 	if (ia->ia_irq == ISACF_IRQ_DEFAULT ||
    247  1.2        pk 	    ia->ia_maddr == ISACF_IOMEM_DEFAULT  ||
    248  1.2        pk             ia->ia_iobase == ISACF_PORT_DEFAULT) {
    249  1.2        pk 		DPRINTF((
    250  1.2        pk 		 "ai_match: wildcarded IRQ, IOAddr, or memAddr, skipping\n"));
    251  1.2        pk 		return (0);
    252  1.2        pk 	}
    253  1.2        pk 
    254  1.3        pk 	iot = ia->ia_iot;
    255  1.3        pk 
    256  1.2        pk 	/*
    257  1.2        pk 	 * This probe is horribly bad, but I have no info on this card other
    258  1.2        pk 	 * than the former driver, and it was just as bad!
    259  1.2        pk 	 */
    260  1.3        pk 	if (bus_space_map(iot, ia->ia_iobase,
    261  1.2        pk 			  AI_IOSIZE, 0, &ioh) != 0) {
    262  1.2        pk 
    263  1.2        pk 		DPRINTF(("ai_match: cannot map %d IO ports @ 0x%x\n",
    264  1.2        pk 			 AI_IOSIZE, ia->ia_iobase));
    265  1.2        pk 		return (0);
    266  1.2        pk 	}
    267  1.2        pk 
    268  1.3        pk 	val = bus_space_read_1(iot, ioh, AI_REVISION);
    269  1.2        pk 
    270  1.2        pk 	type = SL_BOARD(val);
    271  1.5        pk 	if (type != SL10_BOARD && type != EN100_BOARD &&
    272  1.2        pk 	    type != SLFIBER_BOARD) {
    273  1.2        pk 		DPRINTF(("ai_match: unknown board code 0x%02x @ 0x%x\n",
    274  1.2        pk 			 type, ia->ia_iobase));
    275  1.2        pk 		goto out;
    276  1.2        pk 	}
    277  1.1        pk 
    278  1.3        pk 	/*
    279  1.3        pk 	 * Fill in just about enough of our local `ai_softc' for
    280  1.3        pk 	 * ai_find_mem_size() to do its job.
    281  1.3        pk 	 */
    282  1.3        pk 	bzero(&asc, sizeof asc);
    283  1.3        pk 	asc.sc_regt = iot;
    284  1.3        pk 	asc.sc_regh = ioh;
    285  1.1        pk 
    286  1.3        pk 	if ((memsize = ai_find_mem_size(&asc,ia->ia_memt,ia->ia_maddr)) == 0) {
    287  1.2        pk 		DPRINTF(("ai_match: cannot size memory of board @ 0x%x\n",
    288  1.2        pk 			 ia->ia_iobase));
    289  1.3        pk 		goto out;
    290  1.2        pk 	}
    291  1.1        pk 
    292  1.2        pk 	if (!ia->ia_msize)
    293  1.2        pk 		ia->ia_msize = memsize;
    294  1.2        pk 	else if (ia->ia_msize != memsize) {
    295  1.2        pk 		DPRINTF((
    296  1.2        pk 		   "ai_match: memsize of board @ 0x%x doesn't match config\n",
    297  1.2        pk 		   ia->ia_iobase));
    298  1.2        pk 		goto out;
    299  1.2        pk 	}
    300  1.2        pk 
    301  1.2        pk 	rv = 1;
    302  1.1        pk 	ia->ia_msize = memsize;
    303  1.2        pk 	ia->ia_iosize = AI_IOSIZE;
    304  1.2        pk 	DPRINTF(("ai_match: found board @ 0x%x\n", ia->ia_iobase));
    305  1.1        pk 
    306  1.1        pk out:
    307  1.3        pk 	bus_space_unmap(iot, ioh, AI_IOSIZE);
    308  1.2        pk 	return rv;
    309  1.1        pk }
    310  1.1        pk 
    311  1.1        pk void
    312  1.1        pk ai_attach(parent, self, aux)
    313  1.1        pk 	struct device *parent;
    314  1.1        pk 	struct device *self;
    315  1.1        pk 	void   *aux;
    316  1.1        pk {
    317  1.2        pk 	struct ai_softc *asc = (void *)self;
    318  1.2        pk 	struct ie_softc *sc = &asc->sc_ie;
    319  1.2        pk 	struct isa_attach_args *ia = aux;
    320  1.2        pk 
    321  1.2        pk 	u_int8_t val = 0;
    322  1.2        pk 	bus_space_handle_t ioh, memh;
    323  1.2        pk 	u_int8_t ethaddr[ETHER_ADDR_LEN];
    324  1.5        pk 	char name[80];
    325  1.2        pk 
    326  1.2        pk 	if (bus_space_map(ia->ia_iot, ia->ia_iobase,
    327  1.2        pk 			  ia->ia_iosize, 0, &ioh) != 0) {
    328  1.2        pk 		DPRINTF(("\n%s: can't map i/o space 0x%x-0x%x\n",
    329  1.2        pk 			 sc->sc_dev.dv_xname,
    330  1.2        pk 		         ia->ia_iobase, ia->ia_iobase + ia->ia_iosize - 1));
    331  1.2        pk 		return;
    332  1.2        pk 	}
    333  1.2        pk 
    334  1.2        pk 	if (bus_space_map(ia->ia_memt, ia->ia_maddr,
    335  1.2        pk 			  ia->ia_msize, 0, &memh) != 0) {
    336  1.2        pk 		DPRINTF(("\n%s: can't map iomem space 0x%x-0x%x\n",
    337  1.2        pk 			 sc->sc_dev.dv_xname,
    338  1.2        pk 			 ia->ia_maddr, ia->ia_maddr + ia->ia_msize - 1));
    339  1.2        pk 		bus_space_unmap(ia->ia_iot, ioh, ia->ia_iosize);
    340  1.2        pk 		return;
    341  1.2        pk 	}
    342  1.2        pk 
    343  1.2        pk 	asc->sc_regt = ia->ia_iot;
    344  1.2        pk 	asc->sc_regh = ioh;
    345  1.2        pk 
    346  1.2        pk 	sc->hwinit = NULL;
    347  1.2        pk 	sc->intrhook = NULL;
    348  1.2        pk 	sc->hwreset = ai_reset;
    349  1.2        pk 	sc->chan_attn = ai_atten;
    350  1.9     bjh21 
    351  1.9     bjh21 	sc->ie_bus_barrier = NULL;
    352  1.2        pk 
    353  1.2        pk 	sc->memcopyin = ai_copyin;
    354  1.2        pk 	sc->memcopyout = ai_copyout;
    355  1.2        pk 	sc->ie_bus_read16 = ai_read_16;
    356  1.2        pk 	sc->ie_bus_write16 = ai_write_16;
    357  1.2        pk 	sc->ie_bus_write24 = ai_write_24;
    358  1.2        pk 
    359  1.2        pk 	sc->do_xmitnopchain = 0;
    360  1.2        pk 
    361  1.2        pk 	sc->sc_mediachange = NULL;
    362  1.2        pk 	sc->sc_mediastatus = NULL;
    363  1.2        pk 
    364  1.2        pk 	sc->bt = ia->ia_memt;
    365  1.2        pk 	sc->bh = memh;
    366  1.2        pk 
    367  1.2        pk 	/* Map i/o space. */
    368  1.2        pk 	sc->sc_msize = ia->ia_msize;
    369  1.7  augustss 	sc->sc_maddr = (void *)memh;
    370  1.7  augustss 	sc->sc_iobase = (char *)sc->sc_maddr + sc->sc_msize - (1 << 24);
    371  1.2        pk 
    372  1.2        pk 	/* set up pointers to important on-card control structures */
    373  1.2        pk 	sc->iscp = 0;
    374  1.2        pk 	sc->scb = IE_ISCP_SZ;
    375  1.2        pk 	sc->scp = sc->sc_msize + IE_SCP_ADDR - (1 << 24);
    376  1.2        pk 
    377  1.2        pk 	sc->buf_area = sc->scb + IE_SCB_SZ;
    378  1.2        pk 	sc->buf_area_sz = sc->sc_msize - IE_ISCP_SZ - IE_SCB_SZ - IE_SCP_SZ;
    379  1.2        pk 
    380  1.2        pk 	/* zero card memory */
    381  1.2        pk 	bus_space_set_region_1(sc->bt, sc->bh, 0, 0, sc->sc_msize);
    382  1.2        pk 
    383  1.2        pk 	/* set card to 16-bit bus mode */
    384  1.2        pk 	bus_space_write_1(sc->bt, sc->bh, IE_SCP_BUS_USE((u_long)sc->scp), 0);
    385  1.2        pk 
    386  1.2        pk 	/* set up pointers to key structures */
    387  1.2        pk 	ai_write_24(sc, IE_SCP_ISCP((u_long)sc->scp), (u_long) sc->iscp);
    388  1.2        pk 	ai_write_16(sc, IE_ISCP_SCB((u_long)sc->iscp), (u_long) sc->scb);
    389  1.2        pk 	ai_write_24(sc, IE_ISCP_BASE((u_long)sc->iscp), (u_long) sc->iscp);
    390  1.2        pk 
    391  1.2        pk 	/* flush setup of pointers, check if chip answers */
    392  1.2        pk 	bus_space_barrier(sc->bt, sc->bh, 0, sc->sc_msize,
    393  1.2        pk 			  BUS_SPACE_BARRIER_WRITE);
    394  1.2        pk 	if (!i82586_proberam(sc)) {
    395  1.2        pk 		DPRINTF(("\n%s: can't talk to i82586!\n",
    396  1.2        pk 			sc->sc_dev.dv_xname));
    397  1.2        pk 		bus_space_unmap(ia->ia_iot, ioh, ia->ia_iosize);
    398  1.2        pk 		bus_space_unmap(ia->ia_memt, memh, ia->ia_msize);
    399  1.2        pk 		return;
    400  1.2        pk 	}
    401  1.2        pk 
    402  1.2        pk 	val = bus_space_read_1(asc->sc_regt, asc->sc_regh, AI_REVISION);
    403  1.2        pk 	asc->card_rev = SL_REV(val);
    404  1.2        pk 	asc->card_type = SL_BOARD(val) - 1;
    405  1.5        pk 	sprintf(name, "%s, rev. %d",
    406  1.2        pk 		ai_names[asc->card_type], asc->card_rev);
    407  1.2        pk 
    408  1.5        pk 	i82586_attach(sc, name, ethaddr, NULL, 0, 0);
    409  1.2        pk 
    410  1.2        pk 	asc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
    411  1.2        pk 					IPL_NET, i82586_intr, sc);
    412  1.2        pk 	if (asc->sc_ih == NULL) {
    413  1.2        pk 		DPRINTF(("\n%s: can't establish interrupt\n",
    414  1.2        pk 			sc->sc_dev.dv_xname));
    415  1.2        pk 	}
    416  1.1        pk }
    417  1.1        pk 
    418  1.1        pk /*
    419  1.1        pk  * Divine the memory size of this board.
    420  1.1        pk  * Better hope there's nothing important hiding just below the card...
    421  1.1        pk  */
    422  1.1        pk static int
    423  1.1        pk ai_find_mem_size(asc, memt, maddr)
    424  1.1        pk 	struct ai_softc* asc;
    425  1.1        pk 	bus_space_tag_t memt;
    426  1.1        pk 	bus_size_t maddr;
    427  1.1        pk {
    428  1.1        pk 	int size;
    429  1.1        pk 	bus_space_handle_t memh;
    430  1.1        pk 	struct ie_softc* sc = &asc->sc_ie;
    431  1.1        pk 
    432  1.1        pk 	for (size = 65536; size >= 16384; size -= 16384) {
    433  1.2        pk 		if (bus_space_map(memt, maddr, size, 0, &memh) == 0) {
    434  1.2        pk 			size = check_ie_present(sc, memt, maddr, size);
    435  1.2        pk 			bus_space_unmap(memt, memh, size);
    436  1.2        pk 
    437  1.2        pk 			if (size != 0)
    438  1.2        pk 				return size;
    439  1.2        pk 		}
    440  1.1        pk 	}
    441  1.1        pk 
    442  1.2        pk 	return (0);
    443  1.1        pk }
    444  1.1        pk 
    445  1.1        pk /*
    446  1.1        pk  * Check to see if there's an 82586 out there.
    447  1.1        pk  */
    448  1.1        pk static int
    449  1.1        pk check_ie_present(sc, memt, memh, size)
    450  1.1        pk 	struct ie_softc* sc;
    451  1.1        pk 	bus_space_tag_t memt;
    452  1.1        pk 	bus_space_handle_t memh;
    453  1.1        pk 	bus_size_t size;
    454  1.1        pk {
    455  1.2        pk 	sc->hwreset = ai_reset;
    456  1.2        pk 	sc->chan_attn = ai_atten;
    457  1.2        pk 	sc->ie_bus_read16 = ai_read_16;
    458  1.2        pk 	sc->ie_bus_write16 = ai_write_16;
    459  1.2        pk 
    460  1.2        pk 	sc->bt = memt;
    461  1.2        pk 	sc->bh = memh;
    462  1.7  augustss 	sc->sc_iobase = (char *)memh + size - (1 << 24);
    463  1.2        pk 
    464  1.2        pk 	sc->scp = size + IE_SCP_ADDR - (1 << 24);
    465  1.2        pk 	bus_space_set_region_1(memt, memh, (u_long) sc->scp, 0, IE_SCP_SZ);
    466  1.2        pk 
    467  1.2        pk 	sc->iscp = 0;
    468  1.2        pk 	bus_space_set_region_1(memt, memh, (u_long) sc->iscp, 0, IE_ISCP_SZ);
    469  1.2        pk 
    470  1.2        pk 	sc->scb = IE_ISCP_SZ;
    471  1.2        pk 	bus_space_set_region_1(memt, memh, sc->scb, 0, IE_SCB_SZ);
    472  1.2        pk 
    473  1.2        pk 	/* set card to 16-bit bus mode */
    474  1.2        pk 	bus_space_write_1(sc->bt, sc->bh, IE_SCP_BUS_USE((u_long)sc->scp), 0);
    475  1.2        pk 
    476  1.2        pk 	/* set up pointers to key structures */
    477  1.2        pk 	ai_write_24(sc, IE_SCP_ISCP((u_long)sc->scp), (u_long) sc->iscp);
    478  1.2        pk 	ai_write_16(sc, IE_ISCP_SCB((u_long)sc->iscp), (u_long) sc->scb);
    479  1.2        pk 	ai_write_24(sc, IE_ISCP_BASE((u_long)sc->iscp), (u_long) sc->iscp);
    480  1.2        pk 
    481  1.2        pk 	/* flush setup of pointers, check if chip answers */
    482  1.2        pk 	bus_space_barrier(sc->bt, sc->bh, 0, sc->sc_msize,
    483  1.2        pk 			  BUS_SPACE_BARRIER_WRITE);
    484  1.2        pk 
    485  1.2        pk 	if (!i82586_proberam(sc))
    486  1.2        pk 		return (0);
    487  1.1        pk 
    488  1.2        pk 	return (size);
    489  1.1        pk }
    490  1.1        pk 
    491  1.1        pk struct cfattach ai_ca = {
    492  1.1        pk 	sizeof(struct ai_softc), ai_match, ai_attach
    493  1.1        pk };
    494