diff options
author | peter <peter@FreeBSD.org> | 2000-01-14 07:14:17 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 2000-01-14 07:14:17 +0000 |
commit | 2d989cd686df201901f4279380d0010fdae042ca (patch) | |
tree | 6993ef193f20615fddb4df0a445c90ede06a924e /sys | |
parent | f87edded2316615942b4344b5be1836d37ad377c (diff) | |
download | FreeBSD-src-2d989cd686df201901f4279380d0010fdae042ca.zip FreeBSD-src-2d989cd686df201901f4279380d0010fdae042ca.tar.gz |
Pre 4.0 tidy up.
Collect together the components of several drivers and export eisa from
the i386-only area (It's not, it's on some alphas too). The code hasn't
been updated to work on the Alpha yet, but that can come later.
Repository copies were done a while ago.
Moving these now keeps them in consistant place across the 4.x series
as the newbusification progresses.
Submitted by: mdodd
Diffstat (limited to 'sys')
34 files changed, 36 insertions, 10166 deletions
diff --git a/sys/conf/files b/sys/conf/files index 44e920c..354f3d7 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -93,9 +93,13 @@ ddb/db_trap.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb +dev/advansys/adv_eisa.c optional adv eisa +dev/advansys/adv_isa.c optional adv isa +dev/advansys/adv_pci.c optional adv pci dev/advansys/advansys.c optional adv dev/advansys/advlib.c optional adv dev/advansys/advmcode.c optional adv +dev/advansys/adw_pci.c optional adw pci dev/advansys/adwcam.c optional adw dev/advansys/adwlib.c optional adw dev/advansys/adwmcode.c optional adw @@ -105,8 +109,13 @@ dev/amr/amr.c optional amr dev/aha/aha.c optional aha dev/aha/aha_isa.c optional aha isa dev/aha/aha_mca.c optional aha mca +dev/ahb/ahb.c optional ahb eisa dev/aic/aic.c optional aic dev/aic/aic_isa.c optional aic isa +dev/aic7xxx/ahc_eisa.c optional ahc eisa \ + dependency "aic7xxx_reg.h $S/dev/aic7xxx/ahc_eisa.c" +dev/aic7xxx/ahc_pci.c optional ahc pci \ + dependency "aic7xxx_reg.h $S/dev/aic7xxx/ahc_pci.c" dev/aic7xxx/aic7xxx.c optional ahc \ dependency "aic7xxx_{reg,seq}.h" dev/aic7xxx/93cx6.c optional ahc @@ -128,6 +137,7 @@ dev/ep/if_ep_eisa.c optional ep eisa dev/ep/if_ep_mca.c optional ep mca dev/ep/if_ep_pccard.c optional ep card dev/en/midway.c optional en +dev/ex/if_ex.c optional ex dev/hea/eni.c optional hea dev/hea/eni_buffer.c optional hea dev/hea/eni_globals.c optional hea @@ -205,10 +215,12 @@ power_if.h optional pccard \ clean "power_if.h" dev/pcic/i82365.c optional pcic pccard dev/pcic/i82365_isa.c optional pcic pccard -dev/pdq/pdq.c optional fea -dev/pdq/pdq_ifsubr.c optional fea -dev/pdq/pdq.c optional fpa -dev/pdq/pdq_ifsubr.c optional fpa +dev/pdq/if_fea.c optional fea eisa +dev/pdq/if_fpa.c optional fea pci +dev/pdq/pdq.c optional fea eisa +dev/pdq/pdq_ifsubr.c optional fea eisa +dev/pdq/pdq.c optional fpa pci +dev/pdq/pdq_ifsubr.c optional fpa pci ppbus_if.o optional ppbus \ dependency "ppbus_if.c ppbus_if.h" \ compile-with "${NORMAL_C}" \ @@ -306,6 +318,8 @@ dev/vinum/vinumstate.c optional vinum dev/vinum/vinumutil.c optional vinum dev/vn/vn.c optional vn dev/vx/if_vx.c optional vx +dev/vx/if_vx_eisa.c optional vx eisa +dev/vx/if_vx_pci.c optional vx pci dev/xe/if_xe.c optional xe gnu/ext2fs/ext2_alloc.c optional ext2fs gnu/ext2fs/ext2_balloc.c optional ext2fs @@ -764,10 +778,6 @@ pccard/pccard_nbk.c optional card pccard/pcic.c optional pcic card pci/amd.c optional amd pci/pcic_p.c optional pcic pci -pci/adv_pci.c optional adv pci -pci/adw_pci.c optional adw pci -pci/ahc_pci.c optional ahc pci \ - dependency "aic7xxx_reg.h $S/pci/ahc_pci.c" dev/bktr/bktr_core.c optional bktr pci dev/bktr/bktr_i2c.c optional bktr pci dev/bktr/bktr_card.c optional bktr pci @@ -781,7 +791,6 @@ pci/if_ar_p.c optional ar pci pci/if_dc.c optional dc pci/if_de.c optional de pci/if_en_pci.c optional en pci -pci/if_fpa.c optional fpa pci pci/if_fxp.c optional fxp pci/if_lnc_p.c optional lnc pci pci/if_mn.c optional mn @@ -795,7 +804,6 @@ pci/if_ti.c optional ti pci/if_tl.c optional tl pci/if_tx.c optional tx pci/if_vr.c optional vr -pci/if_vx_pci.c optional vx pci pci/if_wb.c optional wb pci/if_wx.c optional wx pci/if_xl.c optional xl diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 18b060a..813aa93 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -72,6 +72,7 @@ dev/ata/atapi-tape.c optional atapist dev/ed/if_ed.c optional ed dev/ed/if_ed_isa.c optional ed isa dev/ed/if_ed_pccard.c optional ed card +dev/eisa/eisaconf.c optional eisa dev/fb/fb.c optional fb dev/fb/fb.c optional vga dev/fb/splash.c optional splash @@ -131,13 +132,6 @@ gnu/i386/isa/dgb.c optional dgb gnu/i386/isa/dgm.c optional dgm gnu/i386/isa/sound/awe_wave.c optional awe i386/apm/apm.c optional apm -i386/eisa/adv_eisa.c optional adv -i386/eisa/ahb.c optional ahb -i386/eisa/ahc_eisa.c optional eisa ahc \ - dependency "aic7xxx_reg.h $S/i386/eisa/ahc_eisa.c" -i386/eisa/eisaconf.c optional eisa -i386/eisa/if_fea.c optional fea -i386/eisa/if_vx_eisa.c optional vx i386/i386/atomic.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}" i386/i386/autoconf.c standard @@ -199,7 +193,6 @@ i386/ibcs2/ibcs2_util.c optional ibcs2 i386/ibcs2/ibcs2_xenix.c optional ibcs2 i386/ibcs2/ibcs2_xenix_sysent.c optional ibcs2 i386/ibcs2/imgact_coff.c optional ibcs2 -i386/isa/adv_isa.c optional adv i386/isa/asc.c optional asc i386/isa/atapi-cd.c optional wcd \ warning "The wcd driver is obsolete. Please use the atapicd driver!" @@ -219,9 +212,7 @@ i386/isa/if_ar.c optional ar i386/isa/if_cs.c optional cs i386/isa/if_cx.c optional cx i386/isa/if_el.c optional el -i386/isa/if_ex.c optional ex i386/isa/if_fe.c optional fe -i386/isa/if_ie.c optional ie i386/isa/if_le.c optional le i386/isa/if_lnc.c optional lnc i386/isa/if_rdp.c optional rdp diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 1ceebdd..e470be5 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -66,6 +66,7 @@ dev/ata/atapi-all.c optional atapist dev/ata/atapi-cd.c optional atapicd dev/ata/atapi-fd.c optional atapifd dev/ata/atapi-tape.c optional atapist +dev/eisa/eisaconf.c optional eisa dev/fb/fb.c optional fb dev/fb/fb.c optional gdc dev/fb/splash.c optional splash @@ -114,13 +115,6 @@ gnu/i386/isa/dgb.c optional dgb gnu/i386/isa/dgm.c optional dgm gnu/i386/isa/sound/awe_wave.c optional awe i386/apm/apm.c optional apm -#i386/eisa/adv_eisa.c optional adv -i386/eisa/ahb.c optional ahb -i386/eisa/ahc_eisa.c optional eisa ahc \ - dependency "aic7xxx_reg.h $S/i386/eisa/ahc_eisa.c" -i386/eisa/eisaconf.c optional eisa -i386/eisa/if_fea.c optional fea -i386/eisa/if_vx_eisa.c optional vx i386/i386/atomic.c standard \ compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} ${.IMPSRC}" i386/i386/autoconf.c standard @@ -187,7 +181,6 @@ i386/isa/bs/bs.c optional bs i386/isa/bs/bsfunc.c optional bs i386/isa/bs/bshw.c optional bs i386/isa/bs/bsif.c optional bs -#i386/isa/adv_isa.c optional adv i386/isa/asc.c optional asc i386/isa/atapi-cd.c optional wcd pc98/pc98/atapi.c optional wdc @@ -207,9 +200,7 @@ i386/isa/if_cs.c optional cs i386/isa/if_cx.c optional cx pc98/pc98/if_ed.c optional ed i386/isa/if_el.c optional el -i386/isa/if_ex.c optional ex i386/isa/if_fe.c optional fe -i386/isa/if_ie.c optional ie i386/isa/if_le.c optional le i386/isa/if_lnc.c optional lnc i386/isa/if_rdp.c optional rdp diff --git a/sys/dev/advansys/adv_eisa.c b/sys/dev/advansys/adv_eisa.c index ad9604e..9caf574 100644 --- a/sys/dev/advansys/adv_eisa.c +++ b/sys/dev/advansys/adv_eisa.c @@ -49,7 +49,7 @@ #include <machine/resource.h> #include <sys/rman.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <dev/advansys/advansys.h> diff --git a/sys/dev/ahb/ahb.c b/sys/dev/ahb/ahb.c index 67eead4..4b432a9 100644 --- a/sys/dev/ahb/ahb.c +++ b/sys/dev/ahb/ahb.c @@ -53,9 +53,9 @@ #include <cam/scsi/scsi_message.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> -#include <i386/eisa/ahbreg.h> +#include <dev/ahb/ahbreg.h> #define ccb_ecb_ptr spriv_ptr0 #define ccb_ahb_ptr spriv_ptr1 diff --git a/sys/dev/aic7xxx/ahc_eisa.c b/sys/dev/aic7xxx/ahc_eisa.c index e98be7d..c8805fe 100644 --- a/sys/dev/aic7xxx/ahc_eisa.c +++ b/sys/dev/aic7xxx/ahc_eisa.c @@ -43,7 +43,7 @@ #include <machine/resource.h> #include <sys/rman.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <cam/cam.h> #include <cam/cam_ccb.h> diff --git a/sys/dev/buslogic/bt_eisa.c b/sys/dev/buslogic/bt_eisa.c index 400b42b..e24409b 100644 --- a/sys/dev/buslogic/bt_eisa.c +++ b/sys/dev/buslogic/bt_eisa.c @@ -43,7 +43,7 @@ #include <machine/resource.h> #include <sys/rman.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <dev/buslogic/btreg.h> diff --git a/sys/dev/dpt/dpt_eisa.c b/sys/dev/dpt/dpt_eisa.c index 67b77d1..bd98bfa 100644 --- a/sys/dev/dpt/dpt_eisa.c +++ b/sys/dev/dpt/dpt_eisa.c @@ -58,7 +58,7 @@ #include <dev/dpt/dpt.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <machine/clock.h> diff --git a/sys/dev/eisa/eisaconf.c b/sys/dev/eisa/eisaconf.c index 59f553a..1e9dcda 100644 --- a/sys/dev/eisa/eisaconf.c +++ b/sys/dev/eisa/eisaconf.c @@ -46,7 +46,7 @@ #include <machine/resource.h> #include <sys/rman.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> typedef struct resvaddr { u_long addr; /* start address */ diff --git a/sys/dev/ep/if_ep_eisa.c b/sys/dev/ep/if_ep_eisa.c index ee1a50f..b8bc31d 100644 --- a/sys/dev/ep/if_ep_eisa.c +++ b/sys/dev/ep/if_ep_eisa.c @@ -40,7 +40,7 @@ #include <machine/clock.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <dev/ep/if_epreg.h> #include <dev/ep/if_epvar.h> diff --git a/sys/dev/ex/if_ex.c b/sys/dev/ex/if_ex.c index 6a09445..40ad5b5 100644 --- a/sys/dev/ex/if_ex.c +++ b/sys/dev/ex/if_ex.c @@ -68,7 +68,7 @@ #include <isa/isavar.h> #include <isa/pnpvar.h> -#include <i386/isa/if_exreg.h> +#include <dev/ex/if_exreg.h> #ifdef EXDEBUG # define Start_End 1 diff --git a/sys/dev/ie/if_ie.c b/sys/dev/ie/if_ie.c index fbbb801..dbb8f7e 100644 --- a/sys/dev/ie/if_ie.c +++ b/sys/dev/ie/if_ie.c @@ -136,9 +136,9 @@ iomem and and with 0xffff. #include <i386/isa/isa_device.h> #include <i386/isa/ic/i82586.h> #include <i386/isa/icu.h> -#include <i386/isa/if_iereg.h> -#include <i386/isa/if_ie507.h> -#include <i386/isa/if_iee16.h> +#include <dev/ie/if_iereg.h> +#include <dev/ie/if_ie507.h> +#include <dev/ie/if_iee16.h> #include <i386/isa/elink.h> #include <net/bpf.h> diff --git a/sys/dev/pdq/if_fea.c b/sys/dev/pdq/if_fea.c index 21c90d4..dc90631 100644 --- a/sys/dev/pdq/if_fea.c +++ b/sys/dev/pdq/if_fea.c @@ -43,7 +43,7 @@ #include <machine/bus.h> #include <machine/resource.h> #include <sys/rman.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <dev/pdq/pdqvar.h> #include <dev/pdq/pdqreg.h> diff --git a/sys/dev/vx/if_vx_eisa.c b/sys/dev/vx/if_vx_eisa.c index 150e573..c700eb3 100644 --- a/sys/dev/vx/if_vx_eisa.c +++ b/sys/dev/vx/if_vx_eisa.c @@ -26,6 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * $FreeBSD$ */ #include "eisa.h" @@ -48,7 +49,7 @@ #include <net/if.h> #include <net/if_arp.h> -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> #include <dev/vx/if_vxreg.h> diff --git a/sys/i386/eisa/adv_eisa.c b/sys/i386/eisa/adv_eisa.c deleted file mode 100644 index ad9604e..0000000 --- a/sys/i386/eisa/adv_eisa.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Device probe and attach routines for the following - * Advanced Systems Inc. SCSI controllers: - * - * Single Channel Products: - * ABP742 - Bus-Master EISA (240 CDB) - * - * Dual Channel Products: - * ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) - * - * Copyright (c) 1997 Justin Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "eisa.h" -#if NEISA > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus_pio.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <i386/eisa/eisaconf.h> - -#include <dev/advansys/advansys.h> - -#define EISA_DEVICE_ID_ADVANSYS_740 0x04507400 -#define EISA_DEVICE_ID_ADVANSYS_750 0x04507500 - -#define ADV_EISA_SLOT_OFFSET 0xc00 -#define ADV_EISA_OFFSET_CHAN1 0x30 -#define ADV_EISA_OFFSET_CHAN2 0x50 -#define ADV_EISA_IOSIZE 0x100 - -#define ADV_EISA_ROM_BIOS_ADDR_REG 0x86 -#define ADV_EISA_IRQ_BURST_LEN_REG 0x87 -#define ADV_EISA_IRQ_MASK 0x07 -#define ADV_EISA_IRQ_10 0x00 -#define ADV_EISA_IRQ_11 0x01 -#define ADV_EISA_IRQ_12 0x02 -#define ADV_EISA_IRQ_14 0x04 -#define ADV_EISA_IRQ_15 0x05 - -#define ADV_EISA_MAX_DMA_ADDR (0x07FFFFFFL) -#define ADV_EISA_MAX_DMA_COUNT (0x07FFFFFFL) - -/* - * The overrun buffer shared amongst all EISA adapters. - */ -static u_int8_t* overrun_buf; -static bus_dma_tag_t overrun_dmat; -static bus_dmamap_t overrun_dmamap; -static bus_addr_t overrun_physbase; - -static const char *adveisamatch(eisa_id_t type); - -static const char* -adveisamatch(eisa_id_t type) -{ - switch (type & ~0xF) { - case EISA_DEVICE_ID_ADVANSYS_740: - return ("AdvanSys ABP-740/742 SCSI adapter"); - break; - case EISA_DEVICE_ID_ADVANSYS_750: - return ("AdvanSys ABP-750/752 SCSI adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -adveisaprobe(device_t dev) -{ - const char *desc; - u_int32_t iobase; - u_int8_t irq; - - desc = adveisamatch(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) - + ADV_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, ADV_EISA_IOSIZE, RESVADDR_NONE); - irq = inb(iobase + ADV_EISA_IRQ_BURST_LEN_REG); - irq &= ADV_EISA_IRQ_MASK; - switch (irq) { - case 0: - case 1: - case 2: - case 4: - case 5: - break; - default: - printf("adv at slot %d: illegal " - "irq setting %d\n", eisa_get_slot(dev), - irq); - return ENXIO; - } - eisa_add_intr(dev, irq + 10, EISA_TRIGGER_LEVEL); - - return 0; -} - -static int -adveisaattach(device_t dev) -{ - struct adv_softc *adv; - struct adv_softc *adv_b; - struct resource *io; - struct resource *irq; - int unit = device_get_unit(dev); - int rid, error; - void *ih; - - adv_b = NULL; - - rid = 0; - io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - return ENOMEM; - } - - rid = 0; - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE); - if (!irq) { - device_printf(dev, "No irq?!\n"); - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - return ENOMEM; - - } - - switch (eisa_get_id(dev) & ~0xF) { - case EISA_DEVICE_ID_ADVANSYS_750: - adv_b = adv_alloc(unit, rman_get_bustag(io), - rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN2); - if (adv_b == NULL) - goto bad; - - /* - * Allocate a parent dmatag for all tags created - * by the MI portions of the advansys driver - */ - /* XXX Should be a child of the PCI bus dma tag */ - error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, - /*boundary*/0, - /*lowaddr*/ADV_EISA_MAX_DMA_ADDR, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/ADV_EISA_MAX_DMA_COUNT, - /*flags*/0, - &adv_b->parent_dmat); - - if (error != 0) { - printf("%s: Could not allocate DMA tag - error %d\n", - adv_name(adv_b), error); - adv_free(adv_b); - goto bad; - } - - adv_b->init_level++; - - /* FALLTHROUGH */ - case EISA_DEVICE_ID_ADVANSYS_740: - adv = adv_alloc(unit, rman_get_bustag(io), - rman_get_bushandle(io) + ADV_EISA_OFFSET_CHAN1); - if (adv == NULL) { - if (adv_b != NULL) - adv_free(adv_b); - goto bad; - } - - /* - * Allocate a parent dmatag for all tags created - * by the MI portions of the advansys driver - */ - /* XXX Should be a child of the PCI bus dma tag */ - error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, - /*boundary*/0, - /*lowaddr*/ADV_EISA_MAX_DMA_ADDR, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/ADV_EISA_MAX_DMA_COUNT, - /*flags*/0, - &adv->parent_dmat); - - if (error != 0) { - printf("%s: Could not allocate DMA tag - error %d\n", - adv_name(adv), error); - adv_free(adv); - goto bad; - } - - adv->init_level++; - break; - default: - printf("adveisaattach: Unknown device type!\n"); - goto bad; - break; - } - - if (overrun_buf == NULL) { - /* Need to allocate our overrun buffer */ - if (bus_dma_tag_create(adv->parent_dmat, - /*alignment*/8, - /*boundary*/0, - ADV_EISA_MAX_DMA_ADDR, - BUS_SPACE_MAXADDR, - /*filter*/NULL, - /*filterarg*/NULL, - ADV_OVERRUN_BSIZE, - /*nsegments*/1, - BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, - &overrun_dmat) != 0) { - adv_free(adv); - goto bad; - } - if (bus_dmamem_alloc(overrun_dmat, - (void **)&overrun_buf, - BUS_DMA_NOWAIT, - &overrun_dmamap) != 0) { - bus_dma_tag_destroy(overrun_dmat); - adv_free(adv); - goto bad; - } - /* And permanently map it in */ - bus_dmamap_load(overrun_dmat, overrun_dmamap, - overrun_buf, ADV_OVERRUN_BSIZE, - adv_map, &overrun_physbase, - /*flags*/0); - } - - /* - * Now that we know we own the resources we need, do the - * card initialization. - */ - - /* - * Stop the chip. - */ - ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); - ADV_OUTW(adv, ADV_CHIP_STATUS, 0); - - adv->chip_version = EISA_REVISION_ID(eisa_get_id(dev)) - + ADV_CHIP_MIN_VER_EISA - 1; - - if (adv_init(adv) != 0) { - adv_free(adv); - if (adv_b != NULL) - adv_free(adv_b); - return(-1); - } - - adv->max_dma_count = ADV_EISA_MAX_DMA_COUNT; - adv->max_dma_addr = ADV_EISA_MAX_DMA_ADDR; - - if (adv_b != NULL) { - /* - * Stop the chip. - */ - ADV_OUTB(adv_b, ADV_CHIP_CTRL, ADV_CC_HALT); - ADV_OUTW(adv_b, ADV_CHIP_STATUS, 0); - - adv_b->chip_version = EISA_REVISION_ID(eisa_get_id(dev)) - + ADV_CHIP_MIN_VER_EISA - 1; - - if (adv_init(adv_b) != 0) { - adv_free(adv_b); - } else { - adv_b->max_dma_count = ADV_EISA_MAX_DMA_COUNT; - adv_b->max_dma_addr = ADV_EISA_MAX_DMA_ADDR; - } - } - - /* - * Enable our interrupt handler. - */ - bus_setup_intr(dev, irq, INTR_TYPE_CAM, adv_intr, adv, &ih); - - /* Attach sub-devices - always succeeds */ - adv_attach(adv); - if (adv_b != NULL) - adv_attach(adv_b); - - return 0; - - bad: - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - return -1; -} - -static device_method_t adv_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, adveisaprobe), - DEVMETHOD(device_attach, adveisaattach), - - { 0, 0 } -}; - -static driver_t adv_eisa_driver = { - "adv", - adv_eisa_methods, - 1, /* unused */ -}; - -static devclass_t adv_devclass; - -DRIVER_MODULE(adv, eisa, adv_eisa_driver, adv_devclass, 0, 0); - -#endif /* NEISA > 0 */ diff --git a/sys/i386/eisa/ahb.c b/sys/i386/eisa/ahb.c deleted file mode 100644 index 67eead4..0000000 --- a/sys/i386/eisa/ahb.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * CAM SCSI device driver for the Adaptec 174X SCSI Host adapter - * - * Copyright (c) 1998 Justin T. Gibbs - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "eisa.h" -#if NEISA > 0 -#include <stddef.h> /* For offsetof() */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus_pio.h> -#include <machine/bus.h> -#include <machine/clock.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <cam/cam.h> -#include <cam/cam_ccb.h> -#include <cam/cam_sim.h> -#include <cam/cam_xpt_sim.h> -#include <cam/cam_debug.h> - -#include <cam/scsi/scsi_message.h> - -#include <i386/eisa/eisaconf.h> - -#include <i386/eisa/ahbreg.h> - -#define ccb_ecb_ptr spriv_ptr0 -#define ccb_ahb_ptr spriv_ptr1 - -#define MIN(a, b) ((a) < (b) ? (a) : (b)) - -#define ahb_inb(ahb, port) \ - bus_space_read_1((ahb)->tag, (ahb)->bsh, port) - -#define ahb_inl(ahb, port) \ - bus_space_read_4((ahb)->tag, (ahb)->bsh, port) - -#define ahb_outb(ahb, port, value) \ - bus_space_write_1((ahb)->tag, (ahb)->bsh, port, value) - -#define ahb_outl(ahb, port, value) \ - bus_space_write_4((ahb)->tag, (ahb)->bsh, port, value) - -static const char *ahbmatch(eisa_id_t type); -static struct ahb_softc *ahballoc(u_long unit, u_int iobase); -static void ahbfree(struct ahb_softc *ahb); -static int ahbreset(struct ahb_softc *ahb); -static void ahbmapecbs(void *arg, bus_dma_segment_t *segs, - int nseg, int error); -static int ahbxptattach(struct ahb_softc *ahb); -static void ahbhandleimmed(struct ahb_softc *ahb, - u_int32_t mbox, u_int intstat); -static void ahbcalcresid(struct ahb_softc *ahb, - struct ecb *ecb, union ccb *ccb); -static __inline void ahbdone(struct ahb_softc *ahb, u_int32_t mbox, - u_int intstat); -static void ahbintr(void *arg); -static bus_dmamap_callback_t ahbexecuteecb; -static void ahbaction(struct cam_sim *sim, union ccb *ccb); -static void ahbpoll(struct cam_sim *sim); - -/* Our timeout handler */ -static timeout_t ahbtimeout; - -static __inline struct ecb* ahbecbget(struct ahb_softc *ahb); -static __inline void ahbecbfree(struct ahb_softc* ahb, - struct ecb* ecb); -static __inline u_int32_t ahbecbvtop(struct ahb_softc *ahb, - struct ecb *ecb); -static __inline struct ecb* ahbecbptov(struct ahb_softc *ahb, - u_int32_t ecb_addr); -static __inline u_int32_t ahbstatuspaddr(u_int32_t ecb_paddr); -static __inline u_int32_t ahbsensepaddr(u_int32_t ecb_paddr); -static __inline u_int32_t ahbsgpaddr(u_int32_t ecb_paddr); -static __inline void ahbqueuembox(struct ahb_softc *ahb, - u_int32_t mboxval, - u_int attn_code); - -static __inline struct ecb* -ahbecbget(struct ahb_softc *ahb) -{ - struct ecb* ecb; - int s; - - s = splcam(); - if ((ecb = SLIST_FIRST(&ahb->free_ecbs)) != NULL) - SLIST_REMOVE_HEAD(&ahb->free_ecbs, links); - splx(s); - - return (ecb); -} - -static __inline void -ahbecbfree(struct ahb_softc* ahb, struct ecb* ecb) -{ - int s; - - s = splcam(); - ecb->state = ECB_FREE; - SLIST_INSERT_HEAD(&ahb->free_ecbs, ecb, links); - splx(s); -} - -static __inline u_int32_t -ahbecbvtop(struct ahb_softc *ahb, struct ecb *ecb) -{ - return (ahb->ecb_physbase - + (u_int32_t)((caddr_t)ecb - (caddr_t)ahb->ecb_array)); -} - -static __inline struct ecb* -ahbecbptov(struct ahb_softc *ahb, u_int32_t ecb_addr) -{ - return (ahb->ecb_array - + ((struct ecb*)ecb_addr - (struct ecb*)ahb->ecb_physbase)); -} - -static __inline u_int32_t -ahbstatuspaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, status)); -} - -static __inline u_int32_t -ahbsensepaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, sense)); -} - -static __inline u_int32_t -ahbsgpaddr(u_int32_t ecb_paddr) -{ - return (ecb_paddr + offsetof(struct ecb, sg_list)); -} - -static __inline void -ahbqueuembox(struct ahb_softc *ahb, u_int32_t mboxval, u_int attn_code) -{ - u_int loopmax = 300; - while (--loopmax) { - u_int status; - - status = ahb_inb(ahb, HOSTSTAT); - if ((status & (HOSTSTAT_MBOX_EMPTY|HOSTSTAT_BUSY)) - == HOSTSTAT_MBOX_EMPTY) - break; - DELAY(20); - } - if (loopmax == 0) - panic("ahb%ld: adapter not taking commands\n", ahb->unit); - - ahb_outl(ahb, MBOXOUT0, mboxval); - ahb_outb(ahb, ATTN, attn_code); -} - -static const char * -ahbmatch(eisa_id_t type) -{ - switch(type & 0xfffffe00) { - case EISA_DEVICE_ID_ADAPTEC_1740: - return ("Adaptec 174x SCSI host adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -ahbprobe(device_t dev) -{ - const char *desc; - u_int32_t iobase; - u_int32_t irq; - u_int8_t intdef; - int shared; - - desc = ahbmatch(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + - AHB_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE); - - intdef = inb(INTDEF + iobase); - switch (intdef & 0x7) { - case INT9: - irq = 9; - break; - case INT10: - irq = 10; - break; - case INT11: - irq = 11; - break; - case INT12: - irq = 12; - break; - case INT14: - irq = 14; - break; - case INT15: - irq = 15; - break; - default: - printf("Adaptec 174X at slot %d: illegal " - "irq setting %d\n", eisa_get_slot(dev), - (intdef & 0x7)); - irq = 0; - break; - } - if (irq == 0) - return ENXIO; - - shared = (inb(INTDEF + iobase) & INTLEVEL) ? - EISA_TRIGGER_LEVEL : EISA_TRIGGER_EDGE; - - eisa_add_intr(dev, irq, shared); - - return 0; -} - -static int -ahbattach(device_t dev) -{ - /* - * find unit and check we have that many defined - */ - struct ahb_softc *ahb; - struct ecb* next_ecb; - struct resource *io = 0; - struct resource *irq = 0; - int rid; - void *ih; - - rid = 0; - io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - return ENOMEM; - } - - if ((ahb = ahballoc(device_get_unit(dev), rman_get_start(io))) == NULL) { - goto error_exit2; - } - - if (ahbreset(ahb) != 0) - goto error_exit; - - rid = 0; - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!irq) { - device_printf(dev, "Can't allocate interrupt\n"); - goto error_exit; - } - - /* - * Create our DMA tags. These tags define the kinds of device - * accessable memory allocations and memory mappings we will - * need to perform during normal operation. - */ - /* DMA tag for mapping buffers into device visible space. */ - /* XXX Should be a child of the EISA bus dma tag */ - if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/MAXBSIZE, /*nsegments*/AHB_NSEG, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/BUS_DMA_ALLOCNOW, - &ahb->buffer_dmat) != 0) - goto error_exit; - - ahb->init_level++; - - /* DMA tag for our ccb structures and ha inquiry data */ - if (bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - (AHB_NECB * sizeof(struct ecb)) - + sizeof(*ahb->ha_inq_data), - /*nsegments*/1, - /*maxsegsz*/BUS_SPACE_MAXSIZE_32BIT, - /*flags*/0, &ahb->ecb_dmat) != 0) - goto error_exit; - - ahb->init_level++; - - /* Allocation for our ccbs */ - if (bus_dmamem_alloc(ahb->ecb_dmat, (void **)&ahb->ecb_array, - BUS_DMA_NOWAIT, &ahb->ecb_dmamap) != 0) - goto error_exit; - - ahb->ha_inq_data = (struct ha_inquiry_data *)&ahb->ecb_array[AHB_NECB]; - - ahb->init_level++; - - /* And permanently map them */ - bus_dmamap_load(ahb->ecb_dmat, ahb->ecb_dmamap, - ahb->ecb_array, AHB_NSEG * sizeof(struct ecb), - ahbmapecbs, ahb, /*flags*/0); - - ahb->init_level++; - - /* Allocate the buffer dmamaps for each of our ECBs */ - bzero(ahb->ecb_array, (AHB_NECB * sizeof(struct ecb)) - + sizeof(*ahb->ha_inq_data)); - next_ecb = ahb->ecb_array; - while (ahb->num_ecbs < AHB_NECB) { - u_int32_t ecb_paddr; - - if (bus_dmamap_create(ahb->buffer_dmat, /*flags*/0, - &next_ecb->dmamap)) - break; - ecb_paddr = ahbecbvtop(ahb, next_ecb); - next_ecb->hecb.status_ptr = ahbstatuspaddr(ecb_paddr); - next_ecb->hecb.sense_ptr = ahbsensepaddr(ecb_paddr); - ahb->num_ecbs++; - ahbecbfree(ahb, next_ecb); - next_ecb++; - } - - if (ahb->num_ecbs == 0) - goto error_exit; - - ahb->init_level++; - - /* - * Now that we know we own the resources we need, register - * our bus with the XPT. - */ - if (ahbxptattach(ahb)) - goto error_exit; - - /* Enable our interrupt */ - bus_setup_intr(dev, irq, INTR_TYPE_CAM, ahbintr, ahb, &ih); - return (0); - -error_exit: - /* - * The board's IRQ line will not be left enabled - * if we can't intialize correctly, so its safe - * to release the irq. - */ - ahbfree(ahb); -error_exit2: - if (io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - if (irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - return (-1); -} - -static struct ahb_softc * -ahballoc(u_long unit, u_int iobase) -{ - struct ahb_softc *ahb; - - /* - * Allocate a storage area for us - */ - ahb = malloc(sizeof(struct ahb_softc), M_DEVBUF, M_NOWAIT); - if (!ahb) { - printf("ahb%ld: cannot malloc!\n", unit); - return (NULL); - } - bzero(ahb, sizeof(struct ahb_softc)); - SLIST_INIT(&ahb->free_ecbs); - LIST_INIT(&ahb->pending_ccbs); - ahb->unit = unit; - ahb->tag = I386_BUS_SPACE_IO; - ahb->bsh = iobase; - ahb->disc_permitted = ~0; - ahb->tags_permitted = ~0; - - return (ahb); -} - -static void -ahbfree(struct ahb_softc *ahb) -{ - switch (ahb->init_level) { - default: - case 4: - bus_dmamap_unload(ahb->ecb_dmat, ahb->ecb_dmamap); - case 3: - bus_dmamem_free(ahb->ecb_dmat, ahb->ecb_array, - ahb->ecb_dmamap); - bus_dmamap_destroy(ahb->ecb_dmat, ahb->ecb_dmamap); - case 2: - bus_dma_tag_destroy(ahb->ecb_dmat); - case 1: - bus_dma_tag_destroy(ahb->buffer_dmat); - case 0: - } - free(ahb, M_DEVBUF); -} - -/* - * reset board, If it doesn't respond, return failure - */ -static int -ahbreset(struct ahb_softc *ahb) -{ - int wait = 1000; /* 1 sec enough? */ - int test; - - if ((ahb_inb(ahb, PORTADDR) & PORTADDR_ENHANCED) == 0) { - printf("ahb_reset: Controller not in enhanced mode\n"); - return (-1); - } - - ahb_outb(ahb, CONTROL, CNTRL_HARD_RST); - DELAY(1000); - ahb_outb(ahb, CONTROL, 0); - while (--wait) { - DELAY(1000); - if ((ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_BUSY) == 0) - break; - } - - if (wait == 0) { - printf("ahbreset: No answer from aha1742 board\n"); - return (-1); - } - if ((test = ahb_inb(ahb, MBOXIN0)) != 0) { - printf("ahb_reset: self test failed, val = 0x%x\n", test); - return (-1); - } - while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { - ahb_outb(ahb, CONTROL, CNTRL_CLRINT); - DELAY(10000); - } - return (0); -} - -static void -ahbmapecbs(void *arg, bus_dma_segment_t *segs, int nseg, int error) -{ - struct ahb_softc* ahb; - - ahb = (struct ahb_softc*)arg; - ahb->ecb_physbase = segs->ds_addr; - /* - * Space for adapter inquiry information is on the - * tail of the ecb array. - */ - ahb->ha_inq_physbase = ahbecbvtop(ahb, &ahb->ecb_array[AHB_NECB]); -} - -static int -ahbxptattach(struct ahb_softc *ahb) -{ - struct cam_devq *devq; - struct ecb *ecb; - u_int i; - - /* Remeber who are we on the scsi bus */ - ahb->scsi_id = ahb_inb(ahb, SCSIDEF) & HSCSIID; - - /* Use extended translation?? */ - ahb->extended_trans = ahb_inb(ahb, RESV1) & EXTENDED_TRANS; - - /* Fetch adapter inquiry data */ - ecb = ahbecbget(ahb); /* Always succeeds - no outstanding commands */ - ecb->hecb.opcode = ECBOP_READ_HA_INQDATA; - ecb->hecb.flag_word1 = FW1_SUPPRESS_URUN_ERR|FW1_ERR_STATUS_BLK_ONLY; - ecb->hecb.data_ptr = ahb->ha_inq_physbase; - ecb->hecb.data_len = sizeof(struct ha_inquiry_data); - ecb->hecb.sense_ptr = 0; - ecb->state = ECB_ACTIVE; - - /* Tell the adapter about this command */ - ahbqueuembox(ahb, ahbecbvtop(ahb, ecb), - ATTN_STARTECB|ahb->scsi_id); - - /* Poll for interrupt completion */ - for (i = 1000; ecb->state != ECB_FREE && i != 0; i--) { - ahbintr(ahb); - DELAY(1000); - } - - ahb->num_ecbs = MIN(ahb->num_ecbs, - ahb->ha_inq_data->scsi_data.reserved[1]); - printf("ahb%ld: %.8s %s SCSI Adapter, FW Rev. %.4s, ID=%d, %d ECBs\n", - ahb->unit, ahb->ha_inq_data->scsi_data.product, - (ahb->ha_inq_data->scsi_data.flags & 0x4) ? "Differential" - : "Single Ended", - ahb->ha_inq_data->scsi_data.revision, - ahb->scsi_id, ahb->num_ecbs); - - /* Restore sense paddr for future CCB clients */ - ecb->hecb.sense_ptr = ahbsensepaddr(ahbecbvtop(ahb, ecb)); - - ahbecbfree(ahb, ecb); - - /* - * Create the device queue for our SIM. - */ - devq = cam_simq_alloc(ahb->num_ecbs); - if (devq == NULL) - return (ENOMEM); - - /* - * Construct our SIM entry - */ - ahb->sim = cam_sim_alloc(ahbaction, ahbpoll, "ahb", ahb, ahb->unit, - 2, ahb->num_ecbs, devq); - if (ahb->sim == NULL) { - cam_simq_free(devq); - return (ENOMEM); - } - - if (xpt_bus_register(ahb->sim, 0) != CAM_SUCCESS) { - cam_sim_free(ahb->sim, /*free_devq*/TRUE); - return (ENXIO); - } - - if (xpt_create_path(&ahb->path, /*periph*/NULL, - cam_sim_path(ahb->sim), CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD) != CAM_REQ_CMP) { - xpt_bus_deregister(cam_sim_path(ahb->sim)); - cam_sim_free(ahb->sim, /*free_devq*/TRUE); - return (ENXIO); - } - - /* - * Allow the board to generate interrupts. - */ - ahb_outb(ahb, INTDEF, ahb_inb(ahb, INTDEF) | INTEN); - - return (0); -} - -static void -ahbhandleimmed(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) -{ - struct ccb_hdr *ccb_h; - u_int target_id; - - if (ahb->immed_cmd == 0) { - printf("ahb%ld: Immediate Command complete with no " - " pending command\n", ahb->unit); - return; - } - - target_id = intstat & INTSTAT_TARGET_MASK; - - ccb_h = LIST_FIRST(&ahb->pending_ccbs); - while (ccb_h != NULL) { - struct ecb *pending_ecb; - union ccb *ccb; - - pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; - ccb = pending_ecb->ccb; - ccb_h = LIST_NEXT(ccb_h, sim_links.le); - if (ccb->ccb_h.target_id == target_id - || target_id == ahb->scsi_id) { - untimeout(ahbtimeout, pending_ecb, - ccb->ccb_h.timeout_ch); - LIST_REMOVE(&ccb->ccb_h, sim_links.le); - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) - bus_dmamap_unload(ahb->buffer_dmat, - pending_ecb->dmamap); - if (pending_ecb == ahb->immed_ecb) - ccb->ccb_h.status = - CAM_CMD_TIMEOUT|CAM_RELEASE_SIMQ; - else if (target_id == ahb->scsi_id) - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - else - ccb->ccb_h.status = CAM_BDR_SENT; - ahbecbfree(ahb, pending_ecb); - xpt_done(ccb); - } else if (ahb->immed_ecb != NULL) { - /* Re-instate timeout */ - ccb->ccb_h.timeout_ch = - timeout(ahbtimeout, (caddr_t)pending_ecb, - (ccb->ccb_h.timeout * hz) / 1000); - } - } - - if (ahb->immed_ecb != NULL) { - ahb->immed_ecb = NULL; - printf("ahb%ld: No longer in timeout\n", ahb->unit); - } else if (target_id == ahb->scsi_id) - printf("ahb%ld: SCSI Bus Reset Delivered\n", ahb->unit); - else - printf("ahb%ld: Bus Device Reset Delibered to target %d\n", - ahb->unit, target_id); - - ahb->immed_cmd = 0; -} - -static void -ahbcalcresid(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) -{ - if (ecb->status.data_overrun != 0) { - /* - * Overrun Condition. The hardware doesn't - * provide a meaningful byte count in this case - * (the residual is always 0). Tell the XPT - * layer about the error. - */ - ccb->ccb_h.status = CAM_DATA_RUN_ERR; - } else { - ccb->csio.resid = ecb->status.resid_count; - - if ((ecb->hecb.flag_word1 & FW1_SG_ECB) != 0) { - /* - * For S/G transfers, the adapter provides a pointer - * to the address in the last S/G element used and a - * residual for that element. So, we need to sum up - * the elements that follow it in order to get a real - * residual number. If we have an overrun, the residual - * reported will be 0 and we already know that all S/G - * segments have been exhausted, so we can skip this - * step. - */ - ahb_sg_t *sg; - int num_sg; - - num_sg = ecb->hecb.data_len / sizeof(ahb_sg_t); - - /* Find the S/G the adapter was working on */ - for (sg = ecb->sg_list; - num_sg != 0 && sg->addr != ecb->status.resid_addr; - num_sg--, sg++) - ; - - /* Skip it */ - num_sg--; - sg++; - - /* Sum the rest */ - for (; num_sg != 0; num_sg--, sg++) - ccb->csio.resid += sg->len; - } - /* Underruns are not errors */ - ccb->ccb_h.status = CAM_REQ_CMP; - } -} - -static void -ahbprocesserror(struct ahb_softc *ahb, struct ecb *ecb, union ccb *ccb) -{ - struct hardware_ecb *hecb; - struct ecb_status *status; - - hecb = &ecb->hecb; - status = &ecb->status; - switch (status->ha_status) { - case HS_OK: - ccb->csio.scsi_status = status->scsi_status; - if (status->scsi_status != 0) { - ccb->ccb_h.status = CAM_SCSI_STATUS_ERROR; - if (status->sense_stored) { - ccb->ccb_h.status |= CAM_AUTOSNS_VALID; - ccb->csio.sense_resid = - ccb->csio.sense_len - status->sense_len; - bcopy(&ecb->sense, &ccb->csio.sense_data, - status->sense_len); - } - } - break; - case HS_TARGET_NOT_ASSIGNED: - ccb->ccb_h.status = CAM_PATH_INVALID; - break; - case HS_SEL_TIMEOUT: - ccb->ccb_h.status = CAM_SEL_TIMEOUT; - break; - case HS_DATA_RUN_ERR: - ahbcalcresid(ahb, ecb, ccb); - break; - case HS_UNEXPECTED_BUSFREE: - ccb->ccb_h.status = CAM_UNEXP_BUSFREE; - break; - case HS_INVALID_PHASE: - ccb->ccb_h.status = CAM_SEQUENCE_FAIL; - break; - case HS_REQUEST_SENSE_FAILED: - ccb->ccb_h.status = CAM_AUTOSENSE_FAIL; - break; - case HS_TAG_MSG_REJECTED: - { - struct ccb_trans_settings neg; - - xpt_print_path(ccb->ccb_h.path); - printf("refuses tagged commands. Performing " - "non-tagged I/O\n"); - neg.flags = 0; - neg.valid = CCB_TRANS_TQ_VALID; - xpt_setup_ccb(&neg.ccb_h, ccb->ccb_h.path, /*priority*/1); - xpt_async(AC_TRANSFER_NEG, ccb->ccb_h.path, &neg); - ahb->tags_permitted &= ~(0x01 << ccb->ccb_h.target_id); - ccb->ccb_h.status = CAM_MSG_REJECT_REC; - break; - } - case HS_FIRMWARE_LOAD_REQ: - case HS_HARDWARE_ERR: - /* - * Tell the system that the Adapter - * is no longer functional. - */ - ccb->ccb_h.status = CAM_NO_HBA; - break; - case HS_CMD_ABORTED_HOST: - case HS_CMD_ABORTED_ADAPTER: - case HS_ATN_TARGET_FAILED: - case HS_SCSI_RESET_ADAPTER: - case HS_SCSI_RESET_INCOMING: - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - break; - case HS_INVALID_ECB_PARAM: - printf("ahb%ld: opcode 0x%02x, flag_word1 0x%02x, flag_word2 0x%02x\n", - ahb->unit, hecb->opcode, hecb->flag_word1, hecb->flag_word2); - ccb->ccb_h.status = CAM_SCSI_BUS_RESET; - break; - case HS_DUP_TCB_RECEIVED: - case HS_INVALID_OPCODE: - case HS_INVALID_CMD_LINK: - case HS_PROGRAM_CKSUM_ERROR: - panic("ahb%ld: Can't happen host status %x occurred", - ahb->unit, status->ha_status); - break; - } - if (ccb->ccb_h.status != CAM_REQ_CMP) { - xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); - ccb->ccb_h.status |= CAM_DEV_QFRZN; - } -} - -static void -ahbdone(struct ahb_softc *ahb, u_int32_t mbox, u_int intstat) -{ - struct ecb *ecb; - union ccb *ccb; - - ecb = ahbecbptov(ahb, mbox); - - if ((ecb->state & ECB_ACTIVE) == 0) - panic("ecb not active"); - - ccb = ecb->ccb; - - if (ccb != NULL) { - untimeout(ahbtimeout, ecb, ccb->ccb_h.timeout_ch); - LIST_REMOVE(&ccb->ccb_h, sim_links.le); - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - bus_dmasync_op_t op; - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) - op = BUS_DMASYNC_POSTREAD; - else - op = BUS_DMASYNC_POSTWRITE; - bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); - bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); - } - - if ((intstat & INTSTAT_MASK) == INTSTAT_ECB_OK) { - ccb->ccb_h.status = CAM_REQ_CMP; - ccb->csio.resid = 0; - } else { - ahbprocesserror(ahb, ecb, ccb); - } - ahbecbfree(ahb, ecb); - xpt_done(ccb); - } else { - /* Non CCB Command */ - if ((intstat & INTSTAT_MASK) != INTSTAT_ECB_OK) { - printf("ahb%ld: Command 0%x Failed %x:%x:%x\n", - ahb->unit, ecb->hecb.opcode, - *((u_int16_t*)&ecb->status), - ecb->status.ha_status, ecb->status.resid_count); - } - /* Client owns this ECB and will release it. */ - } -} - -/* - * Catch an interrupt from the adaptor - */ -static void -ahbintr(void *arg) -{ - struct ahb_softc *ahb; - u_int intstat; - u_int32_t mbox; - - ahb = (struct ahb_softc *)arg; - - while (ahb_inb(ahb, HOSTSTAT) & HOSTSTAT_INTPEND) { - /* - * Fetch information about this interrupt. - */ - intstat = ahb_inb(ahb, INTSTAT); - mbox = ahb_inl(ahb, MBOXIN0); - - /* - * Reset interrupt latch. - */ - ahb_outb(ahb, CONTROL, CNTRL_CLRINT); - - /* - * Process the completed operation - */ - switch (intstat & INTSTAT_MASK) { - case INTSTAT_ECB_OK: - case INTSTAT_ECB_CMPWRETRY: - case INTSTAT_ECB_CMPWERR: - ahbdone(ahb, mbox, intstat); - break; - case INTSTAT_AEN_OCCURED: - if ((intstat & INTSTAT_TARGET_MASK) == ahb->scsi_id) { - /* Bus Reset */ - xpt_print_path(ahb->path); - switch (mbox) { - case HS_SCSI_RESET_ADAPTER: - printf("Host Adapter Initiated " - "Bus Reset occurred\n"); - break; - case HS_SCSI_RESET_INCOMING: - printf("Bus Reset Initiated " - "by another device occurred\n"); - break; - } - /* Notify the XPT */ - xpt_async(AC_BUS_RESET, ahb->path, NULL); - break; - } - printf("Unsupported initiator selection AEN occured\n"); - break; - case INTSTAT_IMMED_OK: - case INTSTAT_IMMED_ERR: - ahbhandleimmed(ahb, mbox, intstat); - break; - case INTSTAT_HW_ERR: - panic("Unrecoverable hardware Error Occurred\n"); - } - } -} - -static void -ahbexecuteecb(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error) -{ - struct ecb *ecb; - union ccb *ccb; - struct ahb_softc *ahb; - u_int32_t ecb_paddr; - int s; - - ecb = (struct ecb *)arg; - ccb = ecb->ccb; - ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; - - if (error != 0) { - if (error != EFBIG) - printf("ahb%ld: Unexepected error 0x%x returned from " - "bus_dmamap_load\n", ahb->unit, error); - if (ccb->ccb_h.status == CAM_REQ_INPROG) { - xpt_freeze_devq(ccb->ccb_h.path, /*count*/1); - ccb->ccb_h.status = CAM_REQ_TOO_BIG|CAM_DEV_QFRZN; - } - ahbecbfree(ahb, ecb); - xpt_done(ccb); - return; - } - - ecb_paddr = ahbecbvtop(ahb, ecb); - - if (nseg != 0) { - ahb_sg_t *sg; - bus_dma_segment_t *end_seg; - bus_dmasync_op_t op; - - end_seg = dm_segs + nseg; - - /* Copy the segments into our SG list */ - sg = ecb->sg_list; - while (dm_segs < end_seg) { - sg->addr = dm_segs->ds_addr; - sg->len = dm_segs->ds_len; - sg++; - dm_segs++; - } - - if (nseg > 1) { - ecb->hecb.flag_word1 |= FW1_SG_ECB; - ecb->hecb.data_ptr = ahbsgpaddr(ecb_paddr); - ecb->hecb.data_len = sizeof(ahb_sg_t) * nseg; - } else { - ecb->hecb.data_ptr = ecb->sg_list->addr; - ecb->hecb.data_len = ecb->sg_list->len; - } - - if ((ccb->ccb_h.flags & CAM_DIR_MASK) == CAM_DIR_IN) { -/* ecb->hecb.flag_word2 |= FW2_DATA_DIR_IN; */ - op = BUS_DMASYNC_PREREAD; - } else { - op = BUS_DMASYNC_PREWRITE; - } - /* ecb->hecb.flag_word2 |= FW2_CHECK_DATA_DIR; */ - - bus_dmamap_sync(ahb->buffer_dmat, ecb->dmamap, op); - - } else { - ecb->hecb.data_ptr = 0; - ecb->hecb.data_len = 0; - } - - s = splcam(); - - /* - * Last time we need to check if this CCB needs to - * be aborted. - */ - if (ccb->ccb_h.status != CAM_REQ_INPROG) { - if (nseg != 0) - bus_dmamap_unload(ahb->buffer_dmat, ecb->dmamap); - ahbecbfree(ahb, ecb); - xpt_done(ccb); - splx(s); - return; - } - - ecb->state = ECB_ACTIVE; - ccb->ccb_h.status |= CAM_SIM_QUEUED; - LIST_INSERT_HEAD(&ahb->pending_ccbs, &ccb->ccb_h, sim_links.le); - - /* Tell the adapter about this command */ - ahbqueuembox(ahb, ecb_paddr, ATTN_STARTECB|ccb->ccb_h.target_id); - - ccb->ccb_h.timeout_ch = timeout(ahbtimeout, (caddr_t)ecb, - (ccb->ccb_h.timeout * hz) / 1000); - splx(s); -} - -static void -ahbaction(struct cam_sim *sim, union ccb *ccb) -{ - struct ahb_softc *ahb; - - CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahbaction\n")); - - ahb = (struct ahb_softc *)cam_sim_softc(sim); - - switch (ccb->ccb_h.func_code) { - /* Common cases first */ - case XPT_SCSI_IO: /* Execute the requested I/O operation */ - { - struct ecb *ecb; - struct hardware_ecb *hecb; - - /* - * get an ecb to use. - */ - if ((ecb = ahbecbget(ahb)) == NULL) { - /* Should never occur */ - panic("Failed to get an ecb"); - } - - /* - * So we can find the ECB when an abort is requested - */ - ecb->ccb = ccb; - ccb->ccb_h.ccb_ecb_ptr = ecb; - ccb->ccb_h.ccb_ahb_ptr = ahb; - - /* - * Put all the arguments for the xfer in the ecb - */ - hecb = &ecb->hecb; - hecb->opcode = ECBOP_INITIATOR_SCSI_CMD; - hecb->flag_word1 = FW1_AUTO_REQUEST_SENSE - | FW1_ERR_STATUS_BLK_ONLY; - hecb->flag_word2 = ccb->ccb_h.target_lun - | FW2_NO_RETRY_ON_BUSY; - if ((ccb->ccb_h.flags & CAM_TAG_ACTION_VALID) != 0) { - hecb->flag_word2 |= FW2_TAG_ENB - | ((ccb->csio.tag_action & 0x3) - << FW2_TAG_TYPE_SHIFT); - } - if ((ccb->ccb_h.flags & CAM_DIS_DISCONNECT) != 0) - hecb->flag_word2 |= FW2_DISABLE_DISC; - hecb->sense_len = ccb->csio.sense_len; - hecb->cdb_len = ccb->csio.cdb_len; - if ((ccb->ccb_h.flags & CAM_CDB_POINTER) != 0) { - if ((ccb->ccb_h.flags & CAM_CDB_PHYS) == 0) { - bcopy(ccb->csio.cdb_io.cdb_ptr, - hecb->cdb, hecb->cdb_len); - } else { - /* I guess I could map it in... */ - ccb->ccb_h.status = CAM_REQ_INVALID; - ahbecbfree(ahb, ecb); - xpt_done(ccb); - return; - } - } else { - bcopy(ccb->csio.cdb_io.cdb_bytes, - hecb->cdb, hecb->cdb_len); - } - - /* - * If we have any data to send with this command, - * map it into bus space. - */ - if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) { - if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) { - /* - * We've been given a pointer - * to a single buffer. - */ - if ((ccb->ccb_h.flags & CAM_DATA_PHYS)==0) { - int s; - int error; - - s = splsoftvm(); - error = bus_dmamap_load( - ahb->buffer_dmat, - ecb->dmamap, - ccb->csio.data_ptr, - ccb->csio.dxfer_len, - ahbexecuteecb, - ecb, /*flags*/0); - if (error == EINPROGRESS) { - /* - * So as to maintain ordering, - * freeze the controller queue - * until our mapping is - * returned. - */ - xpt_freeze_simq(ahb->sim, 1); - ccb->ccb_h.status |= - CAM_RELEASE_SIMQ; - } - splx(s); - } else { - struct bus_dma_segment seg; - - /* Pointer to physical buffer */ - seg.ds_addr = - (bus_addr_t)ccb->csio.data_ptr; - seg.ds_len = ccb->csio.dxfer_len; - ahbexecuteecb(ecb, &seg, 1, 0); - } - } else { - struct bus_dma_segment *segs; - - if ((ccb->ccb_h.flags & CAM_DATA_PHYS) != 0) - panic("ahbaction - Physical segment " - "pointers unsupported"); - - if ((ccb->ccb_h.flags & CAM_SG_LIST_PHYS) == 0) - panic("btaction - Virtual segment " - "addresses unsupported"); - - /* Just use the segments provided */ - segs = (struct bus_dma_segment *) - ccb->csio.data_ptr; - ahbexecuteecb(ecb, segs, ccb->csio.sglist_cnt, - 0); - } - } else { - ahbexecuteecb(ecb, NULL, 0, 0); - } - break; - } - case XPT_EN_LUN: /* Enable LUN as a target */ - case XPT_TARGET_IO: /* Execute target I/O request */ - case XPT_ACCEPT_TARGET_IO: /* Accept Host Target Mode CDB */ - case XPT_CONT_TARGET_IO: /* Continue Host Target I/O Connection*/ - case XPT_ABORT: /* Abort the specified CCB */ - /* XXX Implement */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - case XPT_SET_TRAN_SETTINGS: - { - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - xpt_done(ccb); - break; - } - case XPT_GET_TRAN_SETTINGS: - /* Get default/user set transfer settings for the target */ - { - struct ccb_trans_settings *cts; - u_int target_mask; - - cts = &ccb->cts; - target_mask = 0x01 << ccb->ccb_h.target_id; - if ((cts->flags & CCB_TRANS_USER_SETTINGS) != 0) { - cts->flags = 0; - if ((ahb->disc_permitted & target_mask) != 0) - cts->flags |= CCB_TRANS_DISC_ENB; - if ((ahb->tags_permitted & target_mask) != 0) - cts->flags |= CCB_TRANS_TAG_ENB; - cts->bus_width = MSG_EXT_WDTR_BUS_8_BIT; - cts->sync_period = 25; /* 10MHz */ - - if (cts->sync_period != 0) - cts->sync_offset = 15; - - cts->valid = CCB_TRANS_SYNC_RATE_VALID - | CCB_TRANS_SYNC_OFFSET_VALID - | CCB_TRANS_BUS_WIDTH_VALID - | CCB_TRANS_DISC_VALID - | CCB_TRANS_TQ_VALID; - ccb->ccb_h.status = CAM_REQ_CMP; - } else { - ccb->ccb_h.status = CAM_FUNC_NOTAVAIL; - } - xpt_done(ccb); - break; - } - case XPT_RESET_DEV: /* Bus Device Reset the specified SCSI device */ - { - int i; - int s; - - s = splcam(); - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); - /* Poll for interrupt completion */ - for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) { - DELAY(1000); - ahbintr(cam_sim_softc(sim)); - } - splx(s); - break; - } - case XPT_CALC_GEOMETRY: - { - struct ccb_calc_geometry *ccg; - u_int32_t size_mb; - u_int32_t secs_per_cylinder; - - ccg = &ccb->ccg; - size_mb = ccg->volume_size - / ((1024L * 1024L) / ccg->block_size); - - if (size_mb > 1024 && (ahb->extended_trans != 0)) { - ccg->heads = 255; - ccg->secs_per_track = 63; - } else { - ccg->heads = 64; - ccg->secs_per_track = 32; - } - secs_per_cylinder = ccg->heads * ccg->secs_per_track; - ccg->cylinders = ccg->volume_size / secs_per_cylinder; - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - case XPT_RESET_BUS: /* Reset the specified SCSI bus */ - { - int i; - - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); - /* Poll for interrupt completion */ - for (i = 1000; ahb->immed_cmd != 0 && i != 0; i--) - DELAY(1000); - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - case XPT_TERM_IO: /* Terminate the I/O process */ - /* XXX Implement */ - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - case XPT_PATH_INQ: /* Path routing inquiry */ - { - struct ccb_pathinq *cpi = &ccb->cpi; - - cpi->version_num = 1; /* XXX??? */ - cpi->hba_inquiry = PI_SDTR_ABLE|PI_TAG_ABLE; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = 7; - cpi->max_lun = 7; - cpi->initiator_id = ahb->scsi_id; - cpi->bus_id = cam_sim_bus(sim); - cpi->base_transfer_speed = 3300; - strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN); - strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN); - cpi->unit_number = cam_sim_unit(sim); - cpi->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } -#if 0 - /* Need these??? */ - case XPT_IMMED_NOTIFY: /* Notify Host Target driver of event */ - case XPT_NOTIFY_ACK: /* Acknowledgement of event */ -#endif - default: - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - } -} - -static void -ahbpoll(struct cam_sim *sim) -{ - ahbintr(cam_sim_softc(sim)); -} - -static void -ahbtimeout(void *arg) -{ - struct ecb *ecb; - union ccb *ccb; - struct ahb_softc *ahb; - int s; - - ecb = (struct ecb *)arg; - ccb = ecb->ccb; - ahb = (struct ahb_softc *)ccb->ccb_h.ccb_ahb_ptr; - xpt_print_path(ccb->ccb_h.path); - printf("ECB %p - timed out\n", (void *)ecb); - - s = splcam(); - - if ((ecb->state & ECB_ACTIVE) == 0) { - xpt_print_path(ccb->ccb_h.path); - printf("ECB %p - timed out ECB already completed\n", - (void *)ecb); - splx(s); - return; - } - /* - * In order to simplify the recovery process, we ask the XPT - * layer to halt the queue of new transactions and we traverse - * the list of pending CCBs and remove their timeouts. This - * means that the driver attempts to clear only one error - * condition at a time. In general, timeouts that occur - * close together are related anyway, so there is no benefit - * in attempting to handle errors in parrallel. Timeouts will - * be reinstated when the recovery process ends. - */ - if ((ecb->state & ECB_DEVICE_RESET) == 0) { - struct ccb_hdr *ccb_h; - - if ((ecb->state & ECB_RELEASE_SIMQ) == 0) { - xpt_freeze_simq(ahb->sim, /*count*/1); - ecb->state |= ECB_RELEASE_SIMQ; - } - - ccb_h = LIST_FIRST(&ahb->pending_ccbs); - while (ccb_h != NULL) { - struct ecb *pending_ecb; - - pending_ecb = (struct ecb *)ccb_h->ccb_ecb_ptr; - untimeout(ahbtimeout, pending_ecb, ccb_h->timeout_ch); - ccb_h = LIST_NEXT(ccb_h, sim_links.le); - } - - /* Store for our interrupt handler */ - ahb->immed_ecb = ecb; - - /* - * Send a Bus Device Reset message: - * The target that is holding up the bus may not - * be the same as the one that triggered this timeout - * (different commands have different timeout lengths), - * but we have no way of determining this from our - * timeout handler. Our strategy here is to queue a - * BDR message to the target of the timed out command. - * If this fails, we'll get another timeout 2 seconds - * later which will attempt a bus reset. - */ - xpt_print_path(ccb->ccb_h.path); - printf("Queuing BDR\n"); - ecb->state |= ECB_DEVICE_RESET; - ccb->ccb_h.timeout_ch = - timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); - - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ccb->ccb_h.target_id); - } else if ((ecb->state & ECB_SCSIBUS_RESET) != 0) { - /* - * Try a SCSI bus reset. We do this only if we - * have already attempted to clear the condition with a BDR. - */ - xpt_print_path(ccb->ccb_h.path); - printf("Attempting SCSI Bus reset\n"); - ecb->state |= ECB_SCSIBUS_RESET; - ccb->ccb_h.timeout_ch = - timeout(ahbtimeout, (caddr_t)ecb, 2 * hz); - ahb->immed_cmd = IMMED_RESET; - ahbqueuembox(ahb, IMMED_RESET, ATTN_IMMED|ahb->scsi_id); - } else { - /* Bring out the hammer... */ - ahbreset(ahb); - - /* Simulate the reset complete interrupt */ - ahbhandleimmed(ahb, 0, ahb->scsi_id|INTSTAT_IMMED_OK); - } - - splx(s); -} - -static device_method_t ahb_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ahbprobe), - DEVMETHOD(device_attach, ahbattach), - - { 0, 0 } -}; - -static driver_t ahb_eisa_driver = { - "ahb", - ahb_eisa_methods, - 1, /* unused */ -}; - -static devclass_t ahb_devclass; - -DRIVER_MODULE(ahb, eisa, ahb_eisa_driver, ahb_devclass, 0, 0); - -#endif /* NEISA */ diff --git a/sys/i386/eisa/ahbreg.h b/sys/i386/eisa/ahbreg.h deleted file mode 100644 index c72f068..0000000 --- a/sys/i386/eisa/ahbreg.h +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Hardware structure definitions for the Adaptec 174X CAM SCSI device driver. - * - * Copyright (c) 1998 Justin T. Gibbs - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* Resource Constatns */ -#define AHB_NECB 64 -#define AHB_NSEG 32 - -/* AHA1740 EISA ID, IO port range size, and offset from slot base */ -#define EISA_DEVICE_ID_ADAPTEC_1740 0x04900000 -#define AHB_EISA_IOSIZE 0x100 -#define AHB_EISA_SLOT_OFFSET 0xc00 - -/* AHA1740 EISA board control registers (Offset from slot base) */ -#define EBCTRL 0x084 -#define CDEN 0x01 - -/* - * AHA1740 EISA board mode registers (Offset from slot base) - */ -#define PORTADDR 0x0C0 -#define PORTADDR_ENHANCED 0x80 - -#define BIOSADDR 0x0C1 - -#define INTDEF 0x0C2 -#define INT9 0x00 -#define INT10 0x01 -#define INT11 0x02 -#define INT12 0x03 -#define INT14 0x05 -#define INT15 0x06 -#define INTLEVEL 0x08 -#define INTEN 0x10 - -#define SCSIDEF 0x0C3 -#define HSCSIID 0x0F /* our SCSI ID */ -#define RSTBUS 0x10 - -#define BUSDEF 0x0C4 -#define B0uS 0x00 /* give up bus immediatly */ -#define B4uS 0x01 /* delay 4uSec. */ -#define B8uS 0x02 /* delay 8uSec. */ - -#define RESV0 0x0C5 - -#define RESV1 0x0C6 -#define EXTENDED_TRANS 0x01 - -#define RESV2 0x0C7 - -/* - * AHA1740 ENHANCED mode mailbox control regs (Offset from slot base) - */ -#define MBOXOUT0 0x0D0 -#define MBOXOUT1 0x0D1 -#define MBOXOUT2 0x0D2 -#define MBOXOUT3 0x0D3 - -#define ATTN 0x0D4 -#define ATTN_TARGMASK 0x0F -#define ATTN_IMMED 0x10 -#define ATTN_STARTECB 0x40 -#define ATTN_ABORTECB 0x50 -#define ATTN_TARG_RESET 0x80 - -#define CONTROL 0x0D5 -#define CNTRL_SET_HRDY 0x20 -#define CNTRL_CLRINT 0x40 -#define CNTRL_HARD_RST 0x80 - -#define INTSTAT 0x0D6 -#define INTSTAT_TARGET_MASK 0x0F -#define INTSTAT_MASK 0xF0 -#define INTSTAT_ECB_OK 0x10 /* ECB Completed w/out error */ -#define INTSTAT_ECB_CMPWRETRY 0x50 /* ECB Completed w/retries */ -#define INTSTAT_HW_ERR 0x70 /* Adapter Hardware Failure */ -#define INTSTAT_IMMED_OK 0xA0 /* Immediate command complete */ -#define INTSTAT_ECB_CMPWERR 0xC0 /* ECB Completed w/error */ -#define INTSTAT_AEN_OCCURED 0xD0 /* Async Event Notification */ -#define INTSTAT_IMMED_ERR 0xE0 /* Immediate command failed */ - -#define HOSTSTAT 0x0D7 -#define HOSTSTAT_MBOX_EMPTY 0x04 -#define HOSTSTAT_INTPEND 0x02 -#define HOSTSTAT_BUSY 0x01 - - -#define MBOXIN0 0x0D8 -#define MBOXIN1 0x0D9 -#define MBOXIN2 0x0DA -#define MBOXIN3 0x0DB - -#define STATUS2 0x0DC -#define STATUS2_HOST_READY 0x01 - -typedef enum { - IMMED_RESET = 0x000080, - IMMED_DEVICE_CLEAR_QUEUE = 0x000480, - IMMED_ADAPTER_CLEAR_QUEUE = 0x000880, - IMMED_RESUME = 0x200090 -} immed_cmd; - -struct ecb_status { - /* Status Flags */ - u_int16_t no_error :1, /* Completed with no error */ - data_underrun :1, - :1, - ha_queue_full :1, - spec_check :1, - data_overrun :1, - chain_halted :1, - intr_issued :1, - status_avail :1, /* status bytes 14-31 are valid */ - sense_stored :1, - :1, - init_requied :1, - major_error :1, - :1, - extended_ca :1, - :1; - /* Host Status */ - u_int8_t ha_status; - u_int8_t scsi_status; - int32_t resid_count; - u_int32_t resid_addr; - u_int16_t addit_status; - u_int8_t sense_len; - u_int8_t unused[9]; - u_int8_t cdb[6]; -}; - -typedef enum { - HS_OK = 0x00, - HS_CMD_ABORTED_HOST = 0x04, - HS_CMD_ABORTED_ADAPTER = 0x05, - HS_FIRMWARE_LOAD_REQ = 0x08, - HS_TARGET_NOT_ASSIGNED = 0x0A, - HS_SEL_TIMEOUT = 0x11, - HS_DATA_RUN_ERR = 0x12, - HS_UNEXPECTED_BUSFREE = 0x13, - HS_INVALID_PHASE = 0x14, - HS_INVALID_OPCODE = 0x16, - HS_INVALID_CMD_LINK = 0x17, - HS_INVALID_ECB_PARAM = 0x18, - HS_DUP_TCB_RECEIVED = 0x19, - HS_REQUEST_SENSE_FAILED = 0x1A, - HS_TAG_MSG_REJECTED = 0x1C, - HS_HARDWARE_ERR = 0x20, - HS_ATN_TARGET_FAILED = 0x21, - HS_SCSI_RESET_ADAPTER = 0x22, - HS_SCSI_RESET_INCOMING = 0x23, - HS_PROGRAM_CKSUM_ERROR = 0x80 -} host_status; - -typedef enum { - ECBOP_NOP = 0x00, - ECBOP_INITIATOR_SCSI_CMD = 0x01, - ECBOP_RUN_DIAGNOSTICS = 0x05, - ECBOP_INITIALIZE_SCSI = 0x06, /* Set syncrate/disc/parity */ - ECBOP_READ_SENSE = 0x08, - ECBOP_DOWNLOAD_FIRMWARE = 0x09, - ECBOP_READ_HA_INQDATA = 0x0a, - ECBOP_TARGET_SCSI_CMD = 0x10 -} ecb_op; - -struct ha_inquiry_data { - struct scsi_inquiry_data scsi_data; - u_int8_t release_date[8]; - u_int8_t release_time[8]; - u_int16_t firmware_cksum; - u_int16_t reserved; - u_int16_t target_data[16]; -}; - -struct hardware_ecb { - u_int16_t opcode; - u_int16_t flag_word1; -#define FW1_LINKED_CMD 0x0001 -#define FW1_DISABLE_INTR 0x0080 -#define FW1_SUPPRESS_URUN_ERR 0x0400 -#define FW1_SG_ECB 0x1000 -#define FW1_ERR_STATUS_BLK_ONLY 0x4000 -#define FW1_AUTO_REQUEST_SENSE 0x8000 - u_int16_t flag_word2; -#define FW2_LUN_MASK 0x0007 -#define FW2_TAG_ENB 0x0008 -#define FW2_TAG_TYPE 0x0030 -#define FW2_TAG_TYPE_SHIFT 4 -#define FW2_DISABLE_DISC 0x0040 -#define FW2_CHECK_DATA_DIR 0x0100 -#define FW2_DATA_DIR_IN 0x0200 -#define FW2_SUPRESS_TRANSFER 0x0400 -#define FW2_CALC_CKSUM 0x0800 -#define FW2_RECOVERY_ECB 0x4000 -#define FW2_NO_RETRY_ON_BUSY 0x8000 - u_int16_t reserved; - u_int32_t data_ptr; - u_int32_t data_len; - u_int32_t status_ptr; - u_int32_t link_ptr; - u_int32_t reserved2; - u_int32_t sense_ptr; - u_int8_t sense_len; - u_int8_t cdb_len; - u_int16_t cksum; - u_int8_t cdb[12]; -}; - -typedef struct { - u_int32_t addr; - u_int32_t len; -} ahb_sg_t; - -typedef enum { - ECB_FREE = 0x0, - ECB_ACTIVE = 0x1, - ECB_DEVICE_RESET = 0x2, - ECB_SCSIBUS_RESET = 0x4, - ECB_RELEASE_SIMQ = 0x8 -} ecb_state; - -struct ecb { - struct hardware_ecb hecb; - struct ecb_status status; - struct scsi_sense_data sense; - ahb_sg_t sg_list[AHB_NSEG]; - SLIST_ENTRY(ecb) links; - ecb_state state; - union ccb *ccb; - bus_dmamap_t dmamap; -}; - -struct ahb_softc { - bus_space_tag_t tag; - bus_space_handle_t bsh; - struct cam_sim *sim; - struct cam_path *path; - SLIST_HEAD(,ecb) free_ecbs; - LIST_HEAD(,ccb_hdr) pending_ccbs; - struct ecb *ecb_array; - u_int32_t ecb_physbase; - bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */ - bus_dma_tag_t ecb_dmat; /* dmat for our ecb array */ - bus_dmamap_t ecb_dmamap; - volatile u_int32_t immed_cmd; - struct ecb *immed_ecb; - struct ha_inquiry_data *ha_inq_data; - u_int32_t ha_inq_physbase; - u_long unit; - u_int init_level; - u_int scsi_id; - u_int num_ecbs; - u_int extended_trans; - u_int8_t disc_permitted; - u_int8_t tags_permitted; -}; diff --git a/sys/i386/eisa/ahc_eisa.c b/sys/i386/eisa/ahc_eisa.c deleted file mode 100644 index e98be7d..0000000 --- a/sys/i386/eisa/ahc_eisa.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - * Product specific probe and attach routines for: - * 27/284X and aic7770 motherboard SCSI controllers - * - * Copyright (c) 1994, 1995, 1996, 1997, 1998 Justin T. Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "eisa.h" -#if NEISA > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus_pio.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <i386/eisa/eisaconf.h> - -#include <cam/cam.h> -#include <cam/cam_ccb.h> -#include <cam/cam_sim.h> -#include <cam/cam_xpt_sim.h> -#include <cam/scsi/scsi_all.h> - -#include <dev/aic7xxx/aic7xxx.h> -#include <dev/aic7xxx/93cx6.h> - -#include <aic7xxx_reg.h> - -#define EISA_DEVICE_ID_ADAPTEC_AIC7770 0x04907770 -#define EISA_DEVICE_ID_ADAPTEC_274x 0x04907771 -#define EISA_DEVICE_ID_ADAPTEC_284xB 0x04907756 /* BIOS enabled */ -#define EISA_DEVICE_ID_ADAPTEC_284x 0x04907757 /* BIOS disabled*/ - -#define AHC_EISA_SLOT_OFFSET 0xc00 -#define AHC_EISA_IOSIZE 0x100 -#define INTDEF 0x5cul /* Interrupt Definition Register */ - -static void aha2840_load_seeprom(struct ahc_softc *ahc); - -static const char *aic7770_match(eisa_id_t type); - -static const char* -aic7770_match(eisa_id_t type) -{ - switch (type) { - case EISA_DEVICE_ID_ADAPTEC_AIC7770: - return ("Adaptec aic7770 SCSI host adapter"); - break; - case EISA_DEVICE_ID_ADAPTEC_274x: - return ("Adaptec 274X SCSI host adapter"); - break; - case EISA_DEVICE_ID_ADAPTEC_284xB: - case EISA_DEVICE_ID_ADAPTEC_284x: - return ("Adaptec 284X SCSI host adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -aic7770_probe(device_t dev) -{ - const char *desc; - u_int32_t iobase; - u_int32_t irq; - u_int8_t intdef; - u_int8_t hcntrl; - int shared; - - desc = aic7770_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - iobase = (eisa_get_slot(dev) * EISA_SLOT_SIZE) - + AHC_EISA_SLOT_OFFSET; - - /* Pause the card preseving the IRQ type */ - hcntrl = inb(iobase + HCNTRL) & IRQMS; - - outb(iobase + HCNTRL, hcntrl | PAUSE); - - eisa_add_iospace(dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE); - intdef = inb(INTDEF + iobase); - shared = (intdef & 0x80) ? EISA_TRIGGER_EDGE : EISA_TRIGGER_LEVEL; - irq = intdef & 0xf; - switch (irq) { - case 9: - case 10: - case 11: - case 12: - case 14: - case 15: - break; - default: - printf("aic7770 at slot %d: illegal " - "irq setting %d\n", eisa_get_slot(dev), - intdef); - irq = 0; - break; - } - if (irq == 0) - return ENXIO; - - eisa_add_intr(dev, irq, shared); - - return 0; -} - -static int -aic7770_attach(device_t dev) -{ - ahc_chip chip; - bus_dma_tag_t parent_dmat; - struct ahc_softc *ahc; - struct resource *io; - int error, rid; - - rid = 0; - io = NULL; - ahc = NULL; - switch (eisa_get_id(dev)) { - case EISA_DEVICE_ID_ADAPTEC_274x: - case EISA_DEVICE_ID_ADAPTEC_AIC7770: - chip = AHC_AIC7770|AHC_EISA; - break; - case EISA_DEVICE_ID_ADAPTEC_284xB: - case EISA_DEVICE_ID_ADAPTEC_284x: - chip = AHC_AIC7770|AHC_VL; - break; - default: - printf("aic7770_attach: Unknown device type!\n"); - goto bad; - } - - /* XXX Should be a child of the EISA bus dma tag */ - error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/MAXBSIZE, - /*nsegments*/AHC_NSEG, - /*maxsegsz*/AHC_MAXTRANSFER_SIZE, - /*flags*/BUS_DMA_ALLOCNOW, &parent_dmat); - - if (error != 0) { - printf("ahc_eisa_attach: Could not allocate DMA tag " - "- error %d\n", error); - goto bad; - } - - io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - return ENOMEM; - } - - if (!(ahc = ahc_alloc(dev, io, SYS_RES_IOPORT, rid, - parent_dmat, chip, AHC_AIC7770_FE, AHC_FNONE, - NULL))) - goto bad; - - io = NULL; - - ahc->channel = 'A'; - ahc->channel_b = 'B'; - if (ahc_reset(ahc) != 0) { - goto bad; - } - - /* - * The IRQMS bit enables level sensitive interrupts. Only allow - * IRQ sharing if it's set. - */ - rid = 0; - ahc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_ACTIVE); - if (ahc->irq == NULL) { - device_printf(dev, "Can't allocate interrupt\n"); - goto bad; - } - ahc->irq_res_type = SYS_RES_IRQ; - - /* - * Tell the user what type of interrupts we're using. - * usefull for debugging irq problems - */ - if (bootverbose) { - printf("%s: Using %s Interrupts\n", - ahc_name(ahc), - ahc->pause & IRQMS ? - "Level Sensitive" : "Edge Triggered"); - } - - /* - * Now that we know we own the resources we need, do the - * card initialization. - * - * First, the aic7770 card specific setup. - */ - switch (chip & (AHC_EISA|AHC_VL)) { - case AHC_EISA: - { - u_int biosctrl; - u_int scsiconf; - u_int scsiconf1; -#if DEBUG - int i; -#endif - - biosctrl = ahc_inb(ahc, HA_274_BIOSCTRL); - scsiconf = ahc_inb(ahc, SCSICONF); - scsiconf1 = ahc_inb(ahc, SCSICONF + 1); - -#if DEBUG - for (i = TARG_SCSIRATE; i <= HA_274_BIOSCTRL; i+=8) { - printf("0x%x, 0x%x, 0x%x, 0x%x, " - "0x%x, 0x%x, 0x%x, 0x%x\n", - ahc_inb(ahc, i), - ahc_inb(ahc, i+1), - ahc_inb(ahc, i+2), - ahc_inb(ahc, i+3), - ahc_inb(ahc, i+4), - ahc_inb(ahc, i+5), - ahc_inb(ahc, i+6), - ahc_inb(ahc, i+7)); - } -#endif - - /* Get the primary channel information */ - if ((biosctrl & CHANNEL_B_PRIMARY) != 0) - ahc->flags |= AHC_CHANNEL_B_PRIMARY; - - if ((biosctrl & BIOSMODE) == BIOSDISABLED) { - ahc->flags |= AHC_USEDEFAULTS; - } else { - if ((ahc->features & AHC_WIDE) != 0) { - ahc->our_id = scsiconf1 & HWSCSIID; - if (scsiconf & TERM_ENB) - ahc->flags |= AHC_TERM_ENB_A; - } else { - ahc->our_id = scsiconf & HSCSIID; - ahc->our_id_b = scsiconf1 & HSCSIID; - if (scsiconf & TERM_ENB) - ahc->flags |= AHC_TERM_ENB_A; - if (scsiconf1 & TERM_ENB) - ahc->flags |= AHC_TERM_ENB_B; - } - } - /* - * We have no way to tell, so assume extended - * translation is enabled. - */ - ahc->flags |= AHC_EXTENDED_TRANS_A|AHC_EXTENDED_TRANS_B; - break; - } - case AHC_VL: - { - aha2840_load_seeprom(ahc); - break; - } - default: - break; - } - - /* - * See if we have a Rev E or higher aic7770. Anything below a - * Rev E will have a R/O autoflush disable configuration bit. - */ - { - char *id_string; - u_int8_t sblkctl; - u_int8_t sblkctl_orig; - - sblkctl_orig = ahc_inb(ahc, SBLKCTL); - sblkctl = sblkctl_orig ^ AUTOFLUSHDIS; - ahc_outb(ahc, SBLKCTL, sblkctl); - sblkctl = ahc_inb(ahc, SBLKCTL); - if (sblkctl != sblkctl_orig) { - id_string = "aic7770 >= Rev E, "; - /* - * Ensure autoflush is enabled - */ - sblkctl &= ~AUTOFLUSHDIS; - ahc_outb(ahc, SBLKCTL, sblkctl); - - } else - id_string = "aic7770 <= Rev C, "; - - printf("%s: %s", ahc_name(ahc), id_string); - } - - /* Setup the FIFO threshold and the bus off time */ - { - u_int8_t hostconf = ahc_inb(ahc, HOSTCONF); - ahc_outb(ahc, BUSSPD, hostconf & DFTHRSH); - ahc_outb(ahc, BUSTIME, (hostconf << 2) & BOFF); - } - - /* - * Generic aic7xxx initialization. - */ - if (ahc_init(ahc)) { - /* - * The board's IRQ line is not yet enabled so it's safe - * to release the irq. - */ - goto bad; - } - - /* - * Enable the board's BUS drivers - */ - ahc_outb(ahc, BCTL, ENABLE); - - /* Attach sub-devices - always succeeds */ - ahc_attach(ahc); - - return 0; - - bad: - if (ahc != NULL) - ahc_free(ahc); - - if (io != NULL) - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - - return -1; -} - -/* - * Read the 284x SEEPROM. - */ -static void -aha2840_load_seeprom(struct ahc_softc *ahc) -{ - struct seeprom_descriptor sd; - struct seeprom_config sc; - u_int16_t checksum = 0; - u_int8_t scsi_conf; - int have_seeprom; - - sd.sd_tag = ahc->tag; - sd.sd_bsh = ahc->bsh; - sd.sd_control_offset = SEECTL_2840; - sd.sd_status_offset = STATUS_2840; - sd.sd_dataout_offset = STATUS_2840; - sd.sd_chip = C46; - sd.sd_MS = 0; - sd.sd_RDY = EEPROM_TF; - sd.sd_CS = CS_2840; - sd.sd_CK = CK_2840; - sd.sd_DO = DO_2840; - sd.sd_DI = DI_2840; - - if (bootverbose) - printf("%s: Reading SEEPROM...", ahc_name(ahc)); - have_seeprom = read_seeprom(&sd, - (u_int16_t *)&sc, - /*start_addr*/0, - sizeof(sc)/2); - - if (have_seeprom) { - /* Check checksum */ - int i; - int maxaddr = (sizeof(sc)/2) - 1; - u_int16_t *scarray = (u_int16_t *)≻ - - for (i = 0; i < maxaddr; i++) - checksum = checksum + scarray[i]; - if (checksum != sc.checksum) { - if(bootverbose) - printf ("checksum error\n"); - have_seeprom = 0; - } else if (bootverbose) { - printf("done.\n"); - } - } - - if (!have_seeprom) { - if (bootverbose) - printf("%s: No SEEPROM available\n", ahc_name(ahc)); - ahc->flags |= AHC_USEDEFAULTS; - } else { - /* - * Put the data we've collected down into SRAM - * where ahc_init will find it. - */ - int i; - int max_targ = (ahc->features & AHC_WIDE) != 0 ? 16 : 8; - u_int16_t discenable; - - discenable = 0; - for (i = 0; i < max_targ; i++){ - u_int8_t target_settings; - target_settings = (sc.device_flags[i] & CFXFER) << 4; - if (sc.device_flags[i] & CFSYNCH) - target_settings |= SOFS; - if (sc.device_flags[i] & CFWIDEB) - target_settings |= WIDEXFER; - if (sc.device_flags[i] & CFDISC) - discenable |= (0x01 << i); - ahc_outb(ahc, TARG_SCSIRATE + i, target_settings); - } - ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); - ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); - - ahc->our_id = sc.brtime_id & CFSCSIID; - - scsi_conf = (ahc->our_id & 0x7); - if (sc.adapter_control & CFSPARITY) - scsi_conf |= ENSPCHK; - if (sc.adapter_control & CFRESETB) - scsi_conf |= RESET_SCSI; - - if (sc.bios_control & CF284XEXTEND) - ahc->flags |= AHC_EXTENDED_TRANS_A; - /* Set SCSICONF info */ - ahc_outb(ahc, SCSICONF, scsi_conf); - - if (sc.adapter_control & CF284XSTERM) - ahc->flags |= AHC_TERM_ENB_A; - } -} - -static device_method_t ahc_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, aic7770_probe), - DEVMETHOD(device_attach, aic7770_attach), - - { 0, 0 } -}; - -static driver_t ahc_eisa_driver = { - "ahc", - ahc_eisa_methods, - 1, /* unused */ -}; - -static devclass_t ahc_devclass; - -DRIVER_MODULE(ahc, eisa, ahc_eisa_driver, ahc_devclass, 0, 0); - -#endif /* NEISA > 0 */ diff --git a/sys/i386/eisa/eisaconf.c b/sys/i386/eisa/eisaconf.c deleted file mode 100644 index 59f553a..0000000 --- a/sys/i386/eisa/eisaconf.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * EISA bus probe and attach routines - * - * Copyright (c) 1995, 1996 Justin T. Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "opt_eisa.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/queue.h> -#include <sys/malloc.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/limits.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <i386/eisa/eisaconf.h> - -typedef struct resvaddr { - u_long addr; /* start address */ - u_long size; /* size of reserved area */ - int flags; - struct resource *res; /* resource manager handle */ - LIST_ENTRY(resvaddr) links; /* List links */ -} resvaddr_t; - -LIST_HEAD(resvlist, resvaddr); - -struct irq_node { - int irq_no; - int irq_trigger; - void *idesc; - TAILQ_ENTRY(irq_node) links; -}; - -TAILQ_HEAD(irqlist, irq_node); - -struct eisa_ioconf { - int slot; - struct resvlist ioaddrs; /* list of reserved I/O ranges */ - struct resvlist maddrs; /* list of reserved memory ranges */ - struct irqlist irqs; /* list of reserved irqs */ -}; - -/* To be replaced by the "super device" generic device structure... */ -struct eisa_device { - eisa_id_t id; - struct eisa_ioconf ioconf; -}; - - -/* Global variable, so UserConfig can change it. */ -#define MAX_COL 79 -#ifndef EISA_SLOTS -#define EISA_SLOTS 10 /* PCI clashes with higher ones.. fix later */ -#endif -int num_eisa_slots = EISA_SLOTS; - -static devclass_t eisa_devclass; - -static void eisa_reg_print (device_t, char *, char *, int *); -static struct irq_node * eisa_find_irq(struct eisa_device *e_dev, int rid); -static struct resvaddr * eisa_find_maddr(struct eisa_device *e_dev, int rid); -static struct resvaddr * eisa_find_ioaddr(struct eisa_device *e_dev, int rid); - -static int -mainboard_probe(device_t dev) -{ - char *idstring; - eisa_id_t id = eisa_get_id(dev); - - if (eisa_get_slot(dev) != 0) - return (ENXIO); - - idstring = (char *)malloc(8 + sizeof(" (System Board)") + 1, - M_DEVBUF, M_NOWAIT); - if (idstring == NULL) { - panic("Eisa probe unable to malloc"); - } - sprintf(idstring, "%c%c%c%03x%01x (System Board)", - EISA_MFCTR_CHAR0(id), - EISA_MFCTR_CHAR1(id), - EISA_MFCTR_CHAR2(id), - EISA_PRODUCT_ID(id), - EISA_REVISION_ID(id)); - device_set_desc(dev, idstring); - - return (0); -} - -static int -mainboard_attach(device_t dev) -{ - return (0); -} - -static device_method_t mainboard_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, mainboard_probe), - DEVMETHOD(device_attach, mainboard_attach), - - { 0, 0 } -}; - -static driver_t mainboard_driver = { - "mainboard", - mainboard_methods, - 1, -}; - -static devclass_t mainboard_devclass; - -DRIVER_MODULE(mainboard, eisa, mainboard_driver, mainboard_devclass, 0, 0); - -/* -** probe for EISA devices -*/ -static int -eisa_probe(device_t dev) -{ - int i,slot; - struct eisa_device *e_dev; - device_t child; - int eisaBase = 0xc80; - eisa_id_t eisa_id; - int devices_found = 0; - - device_set_desc(dev, "EISA bus"); - - for (slot = 0; slot < num_eisa_slots; eisaBase+=0x1000, slot++) { - int id_size = sizeof(eisa_id); - eisa_id = 0; - for( i = 0; i < id_size; i++ ) { - outb(eisaBase,0x80 + i); /*Some cards require priming*/ - eisa_id |= inb(eisaBase+i) << ((id_size-i-1)*CHAR_BIT); - } - if (eisa_id & 0x80000000) - continue; /* no EISA card in slot */ - - devices_found++; - - /* Prepare an eisa_device_node for this slot */ - e_dev = (struct eisa_device *)malloc(sizeof(*e_dev), - M_DEVBUF, M_NOWAIT); - if (!e_dev) { - device_printf(dev, "cannot malloc eisa_device"); - break; /* Try to attach what we have already */ - } - bzero(e_dev, sizeof(*e_dev)); - - e_dev->id = eisa_id; - - e_dev->ioconf.slot = slot; - - /* Initialize our lists of reserved addresses */ - LIST_INIT(&(e_dev->ioconf.ioaddrs)); - LIST_INIT(&(e_dev->ioconf.maddrs)); - TAILQ_INIT(&(e_dev->ioconf.irqs)); - - child = device_add_child(dev, NULL, -1); - device_set_ivars(child, e_dev); - } - - /* - * EISA busses themselves are not easily detectable, the easiest way - * to tell if there is an eisa bus is if we found something - there - * should be a motherboard "card" there somewhere. - */ - return devices_found ? 0 : ENXIO; -} - -static void -eisa_probe_nomatch(device_t dev, device_t child) -{ - u_int32_t eisa_id = eisa_get_id(child); - u_int8_t slot = eisa_get_slot(child); - - device_printf(dev, "unknown card %c%c%c%03x%01x (0x%08x) at slot %d\n", - EISA_MFCTR_CHAR0(eisa_id), - EISA_MFCTR_CHAR1(eisa_id), - EISA_MFCTR_CHAR2(eisa_id), - EISA_PRODUCT_ID(eisa_id), - EISA_REVISION_ID(eisa_id), - eisa_id, - slot); - - return; -} - -static void -eisa_reg_print (dev, string, separator, column) - device_t dev; - char * string; - char * separator; - int * column; -{ - int length = strlen(string); - - length += (separator ? 2 : 1); - - if (((*column) + length) >= MAX_COL) { - printf("\n"); - (*column) = 0; - } else if ((*column) != 0) { - if (separator) { - printf("%c", *separator); - (*column)++; - } - printf(" "); - (*column)++; - } - - if ((*column) == 0) { - (*column) += device_printf(dev, "%s", string); - } else { - (*column) += printf("%s", string); - } - - return; -} - -static int -eisa_print_child(device_t dev, device_t child) -{ - char buf[81]; - struct eisa_device * e_dev = device_get_ivars(child); - int rid; - struct irq_node * irq; - struct resvaddr * resv; - char separator = ','; - int column = 0; - int retval = 0; - - if (device_get_desc(child)) { - snprintf(buf, sizeof(buf), "<%s>", device_get_desc(child)); - eisa_reg_print(child, buf, NULL, &column); - } - - rid = 0; - while ((resv = eisa_find_ioaddr(e_dev, rid++))) { - if ((resv->size == 1) || - (resv->flags & RESVADDR_BITMASK)) { - snprintf(buf, sizeof(buf), "%s%lx", - ((rid == 1) ? "at 0x" : "0x"), - resv->addr); - } else { - snprintf(buf, sizeof(buf), "%s%lx-0x%lx", - ((rid == 1) ? "at 0x" : "0x"), - resv->addr, - (resv->addr + (resv->size - 1))); - } - eisa_reg_print(child, buf, - ((rid == 2) ? &separator : NULL), &column); - } - - rid = 0; - while ((resv = eisa_find_maddr(e_dev, rid++))) { - if ((resv->size == 1) || - (resv->flags & RESVADDR_BITMASK)) { - snprintf(buf, sizeof(buf), "%s%lx", - ((rid == 1) ? "at 0x" : "0x"), - resv->addr); - } else { - snprintf(buf, sizeof(buf), "%s%lx-0x%lx", - ((rid == 1) ? "at 0x" : "0x"), - resv->addr, - (resv->addr + (resv->size - 1))); - } - eisa_reg_print(child, buf, - ((rid == 2) ? &separator : NULL), &column); - } - - rid = 0; - while ((irq = eisa_find_irq(e_dev, rid++)) != NULL) { - snprintf(buf, sizeof(buf), "irq %d (%s)", irq->irq_no, - (irq->irq_trigger ? "level" : "edge")); - eisa_reg_print(child, buf, - ((rid == 1) ? &separator : NULL), &column); - } - - snprintf(buf, sizeof(buf), "on %s slot %d\n", - device_get_nameunit(dev), eisa_get_slot(child)); - eisa_reg_print(child, buf, NULL, &column); - - return (retval); -} - -static struct irq_node * -eisa_find_irq(struct eisa_device *e_dev, int rid) -{ - int i; - struct irq_node *irq; - - for (i = 0, irq = TAILQ_FIRST(&e_dev->ioconf.irqs); - i < rid && irq; - i++, irq = TAILQ_NEXT(irq, links)) - ; - - if (irq) - return (irq); - else - return (NULL); -} - -static struct resvaddr * -eisa_find_maddr(struct eisa_device *e_dev, int rid) -{ - int i; - struct resvaddr *resv; - - for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.maddrs); - i < rid && resv; - i++, resv = LIST_NEXT(resv, links)) - ; - - return resv; -} - -static struct resvaddr * -eisa_find_ioaddr(struct eisa_device *e_dev, int rid) -{ - int i; - struct resvaddr *resv; - - for (i = 0, resv = LIST_FIRST(&e_dev->ioconf.ioaddrs); - i < rid && resv; - i++, resv = LIST_NEXT(resv, links)) - ; - - return resv; -} - -static int -eisa_read_ivar(device_t dev, device_t child, int which, u_long *result) -{ - struct eisa_device *e_dev = device_get_ivars(child); - struct irq_node *irq; - - switch (which) { - case EISA_IVAR_SLOT: - *result = e_dev->ioconf.slot; - break; - - case EISA_IVAR_ID: - *result = e_dev->id; - break; - - case EISA_IVAR_IRQ: - /* XXX only first irq */ - if ((irq = eisa_find_irq(e_dev, 0)) != NULL) { - *result = irq->irq_no; - } else { - *result = -1; - } - break; - - default: - return (ENOENT); - } - - return (0); -} - -static int -eisa_write_ivar(device_t dev, device_t child, int which, uintptr_t value) -{ - return (EINVAL); -} - -static struct resource * -eisa_alloc_resource(device_t dev, device_t child, int type, int *rid, - u_long start, u_long end, u_long count, u_int flags) -{ - int isdefault; - struct eisa_device *e_dev = device_get_ivars(child); - struct resource *rv, **rvp = 0; - - isdefault = (device_get_parent(child) == dev - && start == 0UL && end == ~0UL && count == 1); - - switch (type) { - case SYS_RES_IRQ: - if (isdefault) { - struct irq_node * irq = eisa_find_irq(e_dev, *rid); - if (irq == NULL) - return 0; - start = end = irq->irq_no; - count = 1; - if (irq->irq_trigger == EISA_TRIGGER_LEVEL) { - flags |= RF_SHAREABLE; - } else { - flags &= ~RF_SHAREABLE; - } - } - break; - - case SYS_RES_MEMORY: - if (isdefault) { - struct resvaddr *resv; - - resv = eisa_find_maddr(e_dev, *rid); - if (!resv) - return 0; - - start = resv->addr; - end = resv->addr + (resv->size - 1); - count = resv->size; - rvp = &resv->res; - } - break; - - case SYS_RES_IOPORT: - if (isdefault) { - struct resvaddr *resv; - - resv = eisa_find_ioaddr(e_dev, *rid); - if (!resv) - return 0; - - start = resv->addr; - end = resv->addr + (resv->size - 1); - count = resv->size; - rvp = &resv->res; - } - break; - - default: - return 0; - } - - rv = BUS_ALLOC_RESOURCE(device_get_parent(dev), child, - type, rid, start, end, count, flags); - if (rvp) - *rvp = rv; - - return rv; -} - -static int -eisa_release_resource(device_t dev, device_t child, int type, int rid, - struct resource *r) -{ - int rv; - struct eisa_device *e_dev = device_get_ivars(child); - struct resvaddr *resv = 0; - - switch (type) { - case SYS_RES_IRQ: - if (eisa_find_irq(e_dev, rid) == NULL) - return EINVAL; - break; - - case SYS_RES_MEMORY: - if (device_get_parent(child) == dev) - resv = eisa_find_maddr(e_dev, rid); - break; - - - case SYS_RES_IOPORT: - if (device_get_parent(child) == dev) - resv = eisa_find_ioaddr(e_dev, rid); - break; - - default: - return (ENOENT); - } - - rv = BUS_RELEASE_RESOURCE(device_get_parent(dev), child, type, rid, r); - - if (rv == 0) { - if (resv) - resv->res = 0; - } - - return rv; -} - -int -eisa_add_intr(device_t dev, int irq, int trigger) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - struct irq_node *irq_info; - - irq_info = (struct irq_node *)malloc(sizeof(*irq_info), M_DEVBUF, - M_NOWAIT); - if (irq_info == NULL) - return (1); - - irq_info->irq_no = irq; - irq_info->irq_trigger = trigger; - irq_info->idesc = NULL; - TAILQ_INSERT_TAIL(&e_dev->ioconf.irqs, irq_info, links); - return 0; -} - -static int -eisa_add_resvaddr(struct eisa_device *e_dev, struct resvlist *head, u_long base, - u_long size, int flags) -{ - resvaddr_t *reservation; - - reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t), - M_DEVBUF, M_NOWAIT); - if(!reservation) - return (ENOMEM); - - reservation->addr = base; - reservation->size = size; - reservation->flags = flags; - - if (!head->lh_first) { - LIST_INSERT_HEAD(head, reservation, links); - } - else { - resvaddr_t *node; - for(node = head->lh_first; node; node = node->links.le_next) { - if (node->addr > reservation->addr) { - /* - * List is sorted in increasing - * address order. - */ - LIST_INSERT_BEFORE(node, reservation, links); - break; - } - - if (node->addr == reservation->addr) { - /* - * If the entry we want to add - * matches any already in here, - * fail. - */ - free(reservation, M_DEVBUF); - return (EEXIST); - } - - if (!node->links.le_next) { - LIST_INSERT_AFTER(node, reservation, links); - break; - } - } - } - return (0); -} - -int -eisa_add_mspace(device_t dev, u_long mbase, u_long msize, int flags) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - - return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.maddrs), mbase, msize, - flags); -} - -int -eisa_add_iospace(device_t dev, u_long iobase, u_long iosize, int flags) -{ - struct eisa_device *e_dev = device_get_ivars(dev); - - return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), iobase, - iosize, flags); -} - -static device_method_t eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, eisa_probe), - DEVMETHOD(device_attach, bus_generic_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, eisa_print_child), - DEVMETHOD(bus_probe_nomatch, eisa_probe_nomatch), - DEVMETHOD(bus_read_ivar, eisa_read_ivar), - DEVMETHOD(bus_write_ivar, eisa_write_ivar), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_alloc_resource, eisa_alloc_resource), - DEVMETHOD(bus_release_resource, eisa_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - { 0, 0 } -}; - -static driver_t eisa_driver = { - "eisa", - eisa_methods, - 1, /* no softc */ -}; - -DRIVER_MODULE(eisa, isab, eisa_driver, eisa_devclass, 0, 0); -DRIVER_MODULE(eisa, nexus, eisa_driver, eisa_devclass, 0, 0); diff --git a/sys/i386/eisa/eisaconf.h b/sys/i386/eisa/eisaconf.h deleted file mode 100644 index 8330bb4..0000000 --- a/sys/i386/eisa/eisaconf.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * EISA bus device definitions - * - * Copyright (c) 1995, 1996 Justin T. Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice immediately at the beginning of the file, without modification, - * this list of conditions, and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _I386_EISA_EISACONF_H_ -#define _I386_EISA_EISACONF_H_ 1 - -#define EISA_SLOT_SIZE 0x1000 - -#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */ -#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */ -#define EISA_MFCTR_CHAR2(ID) (char)(((ID>>16) & 0x1F) | '@') /* Bits 16-20 */ -#define EISA_MFCTR_ID(ID) (short)((ID>>16) & 0xFF) /* Bits 16-31 */ -#define EISA_PRODUCT_ID(ID) (short)((ID>>4) & 0xFFF) /* Bits 4-15 */ -#define EISA_REVISION_ID(ID) (u_char)(ID & 0x0F) /* Bits 0-3 */ - -extern int num_eisa_slots; - -typedef u_int32_t eisa_id_t; - -enum eisa_device_ivars { - EISA_IVAR_SLOT, - EISA_IVAR_ID, - EISA_IVAR_IRQ -}; - -#define EISA_TRIGGER_EDGE 0x0 -#define EISA_TRIGGER_LEVEL 0x1 - -/* - * Simplified accessors for isa devices - */ -#define EISA_ACCESSOR(A, B, T) \ - \ -static __inline T eisa_get_ ## A(device_t dev) \ -{ \ - uintptr_t v; \ - BUS_READ_IVAR(device_get_parent(dev), dev, EISA_IVAR_ ## B, &v); \ - return (T) v; \ -} \ - \ -static __inline void eisa_set_ ## A(device_t dev, T t) \ -{ \ - u_long v = (u_long) t; \ - BUS_WRITE_IVAR(device_get_parent(dev), dev, EISA_IVAR_ ## B, v); \ -} - -EISA_ACCESSOR(slot, SLOT, int) -EISA_ACCESSOR(id, ID, eisa_id_t) -EISA_ACCESSOR(irq, IRQ, eisa_id_t) - -int eisa_add_intr __P((device_t, int, int)); - -#define RESVADDR_NONE 0x00 -#define RESVADDR_BITMASK 0x01 /* size is a mask of reserved - * bits at addr - */ -#define RESVADDR_RELOCATABLE 0x02 -int eisa_add_iospace __P((device_t, u_long, u_long, int)); -int eisa_add_mspace __P((device_t, u_long, u_long, int)); - -#endif /* _I386_EISA_EISACONF_H_ */ diff --git a/sys/i386/eisa/if_fea.c b/sys/i386/eisa/if_fea.c deleted file mode 100644 index 21c90d4..0000000 --- a/sys/i386/eisa/if_fea.c +++ /dev/null @@ -1,270 +0,0 @@ -/*- - * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * DEC PDQ FDDI Controller - * - * This module support the DEFEA EISA FDDI Controller. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_arp.h> - -#include <sys/module.h> -#include <sys/bus.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> -#include <i386/eisa/eisaconf.h> -#include <dev/pdq/pdqvar.h> -#include <dev/pdq/pdqreg.h> - -static void pdq_eisa_subprobe __P((pdq_bus_t, u_int32_t, u_int32_t *, u_int32_t *, u_int32_t *)); -static void pdq_eisa_devinit __P((pdq_softc_t *)); -static const char * pdq_eisa_match __P((eisa_id_t)); -static int pdq_eisa_probe __P((device_t)); -static int pdq_eisa_attach __P((device_t)); -void pdq_eisa_intr __P((void *)); -static int pdq_eisa_shutdown __P((device_t)); - -#define DEFEA_IRQS 0x0000FBA9U - -#define DEFEA_INTRENABLE 0x8 /* level interrupt */ -#define DEFEA_DECODE_IRQ(n) ((DEFEA_IRQS >> ((n) << 2)) & 0x0f) - -#define EISA_DEVICE_ID_DEC_DEC3001 0x10a33001 -#define EISA_DEVICE_ID_DEC_DEC3002 0x10a33002 -#define EISA_DEVICE_ID_DEC_DEC3003 0x10a33003 -#define EISA_DEVICE_ID_DEC_DEC3004 0x10a33004 - -static void -pdq_eisa_subprobe(bc, iobase, maddr, msize, irq) - pdq_bus_t bc; - u_int32_t iobase; - u_int32_t *maddr; - u_int32_t *msize; - u_int32_t *irq; -{ - if (irq != NULL) - *irq = DEFEA_DECODE_IRQ(PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_IO_CONFIG_STAT_0) & 3); - *maddr = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_0) << 8) - | (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_CMP_1) << 16); - *msize = (PDQ_OS_IORD_8(bc, iobase, PDQ_EISA_MEM_ADD_MASK_0) + 4) << 8; - - return; -} - -static void -pdq_eisa_devinit (sc) - pdq_softc_t *sc; -{ - pdq_uint8_t data; - - /* - * Do the standard initialization for the DEFEA registers. - */ - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_FUNCTION_CTRL, 0x23); - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_1_1, (sc->sc_iobase >> 8) & 0xF0); - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CMP_0_1, (sc->sc_iobase >> 8) & 0xF0); - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_SLOT_CTRL, 0x01); - data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF); -#if defined(PDQ_IOMAPPED) - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data & ~1); -#else - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_BURST_HOLDOFF, data | 1); -#endif - data = PDQ_OS_IORD_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0); - PDQ_OS_IOWR_8(sc->sc_bc, sc->sc_iobase, PDQ_EISA_IO_CONFIG_STAT_0, data | DEFEA_INTRENABLE); - - return; -} - -static const char * -pdq_eisa_match (type) - eisa_id_t type; -{ - switch (type) { - case EISA_DEVICE_ID_DEC_DEC3001: - case EISA_DEVICE_ID_DEC_DEC3002: - case EISA_DEVICE_ID_DEC_DEC3003: - case EISA_DEVICE_ID_DEC_DEC3004: - return ("DEC FDDIcontroller/EISA Adapter"); - break; - default: - break; - } - return (NULL); -} - -static int -pdq_eisa_probe (dev) - device_t dev; -{ - const char *desc; - u_int32_t iobase; - u_int32_t irq; - u_int32_t maddr; - u_int32_t msize; - - u_int32_t eisa_id = eisa_get_id(dev);; - - desc = pdq_eisa_match(eisa_id); - if (!desc) { - return (ENXIO); - } - - device_set_desc(dev, desc); - - iobase = eisa_get_slot(dev) * EISA_SLOT_SIZE; - pdq_eisa_subprobe(PDQ_BUS_EISA, iobase, &maddr, &msize, &irq); - - eisa_add_iospace(dev, iobase, 0x200, RESVADDR_NONE); - eisa_add_mspace(dev, maddr, msize, RESVADDR_NONE); - eisa_add_intr(dev, irq, EISA_TRIGGER_LEVEL); - - return (0); -} - -void -pdq_eisa_intr(xdev) - void *xdev; -{ - device_t dev = (device_t) xdev; - pdq_softc_t *sc = device_get_softc(dev); - (void) pdq_interrupt(sc->sc_pdq); - - return; -} - -static int -pdq_eisa_attach (dev) - device_t dev; -{ - pdq_softc_t *sc = device_get_softc(dev); - struct resource *io = 0; - struct resource *irq = 0; - struct resource *mspace = 0; - int rid; - void *ih; - u_int32_t m_addr, m_size; - - rid = 0; - io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (!io) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - - rid = 0; - mspace = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (!mspace) { - device_printf(dev, "No memory space?!\n"); - goto bad; - } - - rid = 0; - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (!irq) { - device_printf(dev, "No, irq?!\n"); - goto bad; - } - - m_addr = rman_get_start(mspace); - m_size = (rman_get_end(mspace) - rman_get_start(mspace)) + 1; - - sc->sc_iobase = (pdq_bus_ioport_t) rman_get_start(io); - sc->sc_membase = (pdq_bus_memaddr_t) pmap_mapdev(m_addr, m_size); - sc->sc_if.if_name = "fea"; - sc->sc_if.if_unit = device_get_unit(dev); - - pdq_eisa_devinit(sc); - sc->sc_pdq = pdq_initialize(PDQ_BUS_EISA, sc->sc_membase, - sc->sc_if.if_name, sc->sc_if.if_unit, - (void *) sc, PDQ_DEFEA); - if (sc->sc_pdq == NULL) { - device_printf(dev, "initialization failed\n"); - goto bad; - } - - if (bus_setup_intr(dev, irq, INTR_TYPE_NET, pdq_eisa_intr, dev, &ih)) { - goto bad; - } - - bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); - pdq_ifattach(sc, NULL); - - return (0); - -bad: - if (io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - if (irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - if (mspace) - bus_release_resource(dev, SYS_RES_MEMORY, 0, mspace); - - return (-1); -} - -static int -pdq_eisa_shutdown(dev) - device_t dev; -{ - pdq_softc_t *sc = device_get_softc(dev); - - pdq_hwreset(sc->sc_pdq); - - return (0); -} - -static device_method_t pdq_eisa_methods[] = { - DEVMETHOD(device_probe, pdq_eisa_probe), - DEVMETHOD(device_attach, pdq_eisa_attach), - DEVMETHOD(device_shutdown, pdq_eisa_shutdown), - - { 0, 0 } -}; - -static driver_t pdq_eisa_driver = { - "fea", - pdq_eisa_methods, - sizeof(pdq_softc_t), -}; - -static devclass_t pdq_devclass; - -DRIVER_MODULE(pdq, eisa, pdq_eisa_driver, pdq_devclass, 0, 0); diff --git a/sys/i386/eisa/if_vx_eisa.c b/sys/i386/eisa/if_vx_eisa.c deleted file mode 100644 index 150e573..0000000 --- a/sys/i386/eisa/if_vx_eisa.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 1996 Naoki Hamada <nao@tom-yam.or.jp> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include "eisa.h" -#if NEISA > 0 - -#include "vx.h" -#if NVX > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/if.h> -#include <net/if_arp.h> - -#include <i386/eisa/eisaconf.h> - -#include <dev/vx/if_vxreg.h> - -#define EISA_DEVICE_ID_3COM_3C592 0x506d5920 -#define EISA_DEVICE_ID_3COM_3C597_TX 0x506d5970 -#define EISA_DEVICE_ID_3COM_3C597_T4 0x506d5971 -#define EISA_DEVICE_ID_3COM_3C597_MII 0x506d5972 - - -#define VX_EISA_SLOT_OFFSET 0x0c80 -#define VX_EISA_IOSIZE 0x000a -#define VX_RESOURCE_CONFIG 0x0008 - - -static const char *vx_match __P((eisa_id_t type)); - -static const char* -vx_match(eisa_id_t type) -{ - switch (type) { - case EISA_DEVICE_ID_3COM_3C592: - return "3Com 3C592 Network Adapter"; - break; - case EISA_DEVICE_ID_3COM_3C597_TX: - return "3Com 3C597-TX Network Adapter"; - break; - case EISA_DEVICE_ID_3COM_3C597_T4: - return "3Com 3C597-T4 Network Adapter"; - break; - case EISA_DEVICE_ID_3COM_3C597_MII: - return "3Com 3C597-MII Network Adapter"; - break; - default: - break; - } - return (NULL); -} - -static int -vx_eisa_probe(device_t dev) -{ - const char *desc; - u_long iobase; - u_long port; - - desc = vx_match(eisa_get_id(dev)); - if (!desc) - return (ENXIO); - device_set_desc(dev, desc); - - port = eisa_get_slot(dev) * EISA_SLOT_SIZE; - iobase = port + VX_EISA_SLOT_OFFSET; - - eisa_add_iospace(dev, iobase, VX_EISA_IOSIZE, RESVADDR_NONE); - eisa_add_iospace(dev, port, VX_IOSIZE, RESVADDR_NONE); - - /* Set irq */ - eisa_add_intr(dev, inw(iobase + VX_RESOURCE_CONFIG) >> 12, - EISA_TRIGGER_EDGE); - - return (0); -} - -static int -vx_eisa_attach(device_t dev) -{ - struct vx_softc *sc; - int unit = device_get_unit(dev); - struct resource *io = 0; - struct resource *eisa_io = 0; - struct resource *irq = 0; - int rid; - void *ih; - - /* - * The addresses are sorted in increasing order - * so we know the port to pass to the core ep - * driver comes first. - */ - rid = 0; - io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!io) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - - rid = 1; - eisa_io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!eisa_io) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - - if ((sc = vxalloc(unit)) == NULL) - goto bad; - - sc->vx_io_addr = rman_get_start(io); - - rid = 0; - irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_ACTIVE); - if (!irq) { - device_printf(dev, "No irq?!\n"); - vxfree(sc); - goto bad; - } - - /* Now the registers are availible through the lower ioport */ - - vxattach(sc); - - if (bus_setup_intr(dev, irq, INTR_TYPE_NET, vxintr, sc, &ih)) { - vxfree(sc); - goto bad; - } - - return 0; - - bad: - if (io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, io); - if (eisa_io) - bus_release_resource(dev, SYS_RES_IOPORT, 0, eisa_io); - if (irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, irq); - return -1; -} - -static device_method_t vx_eisa_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, vx_eisa_probe), - DEVMETHOD(device_attach, vx_eisa_attach), - - { 0, 0 } -}; - -static driver_t vx_eisa_driver = { - "vx", - vx_eisa_methods, - 1, /* unused */ -}; - -static devclass_t vx_devclass; - -DRIVER_MODULE(vx, eisa, vx_eisa_driver, vx_devclass, 0, 0); - -#endif /* NVX > 0 */ -#endif /* NEISA > 0 */ diff --git a/sys/i386/i386/userconfig.c b/sys/i386/i386/userconfig.c index 376f049..bf981f3 100644 --- a/sys/i386/i386/userconfig.c +++ b/sys/i386/i386/userconfig.c @@ -2616,7 +2616,7 @@ static int lineno; #if NEISA > 0 -#include <i386/eisa/eisaconf.h> +#include <dev/eisa/eisaconf.h> static int set_num_eisa_slots(CmdParm *); diff --git a/sys/i386/isa/if_ex.c b/sys/i386/isa/if_ex.c deleted file mode 100644 index 6a09445..0000000 --- a/sys/i386/isa/if_ex.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * Copyright (c) 1996, Javier Martín Rueda (jmrueda@diatel.upm.es) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - * MAINTAINER: Matthew N. Dodd <winter@jurai.net> - * <mdodd@FreeBSD.org> - */ - -/* - * Intel EtherExpress Pro/10, Pro/10+ Ethernet driver - * - * Revision history: - * - * 30-Oct-1996: first beta version. Inet and BPF supported, but no multicast. - */ - -#include "ex.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/conf.h> -#include <sys/sockio.h> -#include <sys/mbuf.h> -#include <sys/socket.h> - -#include <sys/module.h> -#include <sys/bus.h> - -#include <machine/bus.h> -#include <machine/resource.h> -#include <sys/rman.h> - -#include <net/ethernet.h> -#include <net/if.h> - -#include <netinet/in.h> -#include <netinet/if_ether.h> - -#include <net/bpf.h> - -#include <machine/clock.h> - -#include <isa/isavar.h> -#include <isa/pnpvar.h> - -#include <i386/isa/if_exreg.h> - -#ifdef EXDEBUG -# define Start_End 1 -# define Rcvd_Pkts 2 -# define Sent_Pkts 4 -# define Status 8 -static int debug_mask = 0; -static int exintr_count = 0; -# define DODEBUG(level, action) if (level & debug_mask) action -#else -# define DODEBUG(level, action) -#endif - -#define Conn_BNC 1 -#define Conn_TPE 2 -#define Conn_AUI 3 - -#define CARD_TYPE_EX_10 1 -#define CARD_TYPE_EX_10_PLUS 2 - -struct ex_softc { - struct arpcom arpcom; /* Ethernet common data */ - - device_t dev; - struct resource *ioport; - struct resource *irq; - - u_int iobase; /* I/O base address. */ - u_short irq_no; /* IRQ number. */ - - char * irq2ee; /* irq <-> internal */ - u_char * ee2irq; /* representation conversion */ - - u_short connector; /* Connector type. */ - - u_int mem_size; /* Total memory size, in bytes. */ - u_int rx_mem_size; /* Rx memory size (by default, */ - /* first 3/4 of total memory). */ - - u_int rx_lower_limit; /* Lower and upper limits of */ - u_int rx_upper_limit; /* receive buffer. */ - - u_int rx_head; /* Head of receive ring buffer. */ - u_int tx_mem_size; /* Tx memory size (by default, */ - /* last quarter of total memory).*/ - - u_int tx_lower_limit; /* Lower and upper limits of */ - u_int tx_upper_limit; /* transmit buffer. */ - - u_int tx_head; /* Head and tail of */ - u_int tx_tail; /* transmit ring buffer. */ - - u_int tx_last; /* Pointer to beginning of last */ - /* frame in the chain. */ -}; - -static char irq2eemap[] = - { -1, -1, 0, 1, -1, 2, -1, -1, -1, 0, 3, 4, -1, -1, -1, -1 }; -static u_char ee2irqmap[] = - { 9, 3, 5, 10, 11, 0, 0, 0 }; - -static char plus_irq2eemap[] = - { -1, -1, -1, 0, 1, 2, -1, 3, -1, 4, 5, 6, 7, -1, -1, -1 }; -static u_char plus_ee2irqmap[] = - { 3, 4, 5, 7, 9, 10, 11, 12 }; - -/* Bus Front End Functions */ -static void ex_isa_identify __P((driver_t *, device_t)); -static int ex_isa_probe __P((device_t)); -static int ex_isa_attach __P((device_t)); - -/* Network Interface Functions */ -static void ex_init __P((void *)); -static void ex_start __P((struct ifnet *)); -static int ex_ioctl __P((struct ifnet *, u_long, caddr_t)); -static void ex_watchdog __P((struct ifnet *)); - -static void ex_stop __P((struct ex_softc *)); -static void ex_reset __P((struct ex_softc *)); - -static driver_intr_t ex_intr; -static void ex_tx_intr __P((struct ex_softc *)); -static void ex_rx_intr __P((struct ex_softc *)); - -static u_short eeprom_read __P((int, int)); - -static device_method_t ex_methods[] = { - /* Device interface */ - DEVMETHOD(device_identify, ex_isa_identify), - DEVMETHOD(device_probe, ex_isa_probe), - DEVMETHOD(device_attach, ex_isa_attach), - - { 0, 0 } -}; - -static driver_t ex_driver = { - "ex", - ex_methods, - sizeof(struct ex_softc), -}; - -static devclass_t ex_devclass; - -DRIVER_MODULE(ex, isa, ex_driver, ex_devclass, 0, 0); - -static struct isa_pnp_id ex_ids[] = { - { 0x3110d425, NULL }, /* INT1031 */ - { 0x3010d425, NULL }, /* INT1030 */ - { 0, NULL }, -}; - -static int -look_for_card (u_int iobase) -{ - int count1, count2; - - /* - * Check for the i82595 signature, and check that the round robin - * counter actually advances. - */ - if (((count1 = inb(iobase + ID_REG)) & Id_Mask) != Id_Sig) - return(0); - count2 = inb(iobase + ID_REG); - count2 = inb(iobase + ID_REG); - count2 = inb(iobase + ID_REG); - - return((count2 & Counter_bits) == ((count1 + 0xc0) & Counter_bits)); -} - -static int -ex_get_media (u_int32_t iobase) -{ - int tmp; - - outb(iobase + CMD_REG, Bank2_Sel); - tmp = inb(iobase + REG3); - outb(iobase + CMD_REG, Bank0_Sel); - - if (tmp & TPE_bit) - return(Conn_TPE); - if (tmp & BNC_bit) - return(Conn_BNC); - - return (Conn_AUI); -} - -static void -ex_get_address (u_int32_t iobase, u_char *enaddr) -{ - u_int16_t eaddr_tmp; - - eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Lo); - enaddr[5] = eaddr_tmp & 0xff; - enaddr[4] = eaddr_tmp >> 8; - eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Mid); - enaddr[3] = eaddr_tmp & 0xff; - enaddr[2] = eaddr_tmp >> 8; - eaddr_tmp = eeprom_read(iobase, EE_Eth_Addr_Hi); - enaddr[1] = eaddr_tmp & 0xff; - enaddr[0] = eaddr_tmp >> 8; - - return; -} - -static int -ex_card_type (u_char *enaddr) -{ - if ((enaddr[0] == 0x00) && (enaddr[1] == 0xA0) && (enaddr[2] == 0xC9)) - return (CARD_TYPE_EX_10_PLUS); - - return (CARD_TYPE_EX_10); -} - -/* - * Non-destructive identify. - */ -static void -ex_isa_identify (driver_t *driver, device_t parent) -{ - device_t child; - u_int32_t ioport; - u_char enaddr[6]; - u_int irq; - int tmp; - const char * desc; - - for (ioport = 0x200; ioport < 0x3a0; ioport += 0x10) { - - /* No board found at address */ - if (!look_for_card(ioport)) { - continue; - } - - /* Board in PnP mode */ - if (eeprom_read(ioport, 0) & 0x01) { - continue; - } - - bzero(enaddr, sizeof(enaddr)); - - /* Reset the card. */ - outb(ioport + CMD_REG, Reset_CMD); - DELAY(400); - - ex_get_address(ioport, enaddr); - tmp = eeprom_read(ioport, EE_IRQ_No) & IRQ_No_Mask; - - /* work out which set of irq <-> internal tables to use */ - if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { - irq = plus_ee2irqmap[tmp]; - desc = "Intel Pro/10+"; - } else { - irq = ee2irqmap[tmp]; - desc = "Intel Pro/10"; - } - - child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "ex", -1); - device_set_desc_copy(child, desc); - device_set_driver(child, driver); - bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); - bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, EX_IOSIZE); - } - - return; -} - -static int -ex_isa_probe(device_t dev) -{ - u_int iobase; - u_int irq; - char * irq2ee; - u_char * ee2irq; - u_char enaddr[6]; - int tmp; - int error; - - DODEBUG(Start_End, printf("ex_probe: start\n");); - - /* Check isapnp ids */ - error = ISA_PNP_PROBE(device_get_parent(dev), dev, ex_ids); - - /* If the card had a PnP ID that didn't match any we know about */ - if (error == ENXIO) { - return(error); - } - - /* If we had some other problem. */ - if (!(error == 0 || error == ENOENT)) { - return(error); - } - - iobase = bus_get_resource_start(dev, SYS_RES_IOPORT, 0); - if (iobase && !look_for_card(iobase)) { - printf("ex: no card found at 0x%03x\n", iobase); - return(ENXIO); - } - - /* - * Reset the card. - */ - outb(iobase + CMD_REG, Reset_CMD); - DELAY(400); - - ex_get_address(iobase, enaddr); - - /* work out which set of irq <-> internal tables to use */ - if (ex_card_type(enaddr) == CARD_TYPE_EX_10_PLUS) { - irq2ee = plus_irq2eemap; - ee2irq = plus_ee2irqmap; - } else { - irq2ee = irq2eemap; - ee2irq = ee2irqmap; - } - - tmp = eeprom_read(iobase, EE_IRQ_No) & IRQ_No_Mask; - irq = bus_get_resource_start(dev, SYS_RES_IRQ, 0); - - if (irq > 0) { - /* This will happen if board is in PnP mode. */ - if (ee2irq[tmp] != irq) { - printf("ex: WARNING: board's EEPROM is configured" - " for IRQ %d, using %d\n", - ee2irq[tmp], irq); - } - } else { - irq = ee2irq[tmp]; - bus_set_resource(dev, SYS_RES_IRQ, 0, irq, 1); - } - - if (irq == 0) { - printf("ex: invalid IRQ.\n"); - return(ENXIO); - } - - DODEBUG(Start_End, printf("ex_probe: finish\n");); - - return(0); -} - -static int -ex_isa_attach(device_t dev) -{ - struct ex_softc * sc = device_get_softc(dev); - struct ifnet * ifp = &sc->arpcom.ac_if; - int unit = device_get_unit(dev); - int error; - int rid; - void * ih; - - DODEBUG(Start_End, device_printf(dev, "start\n");); - - rid = 0; - sc->ioport = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (!sc->ioport) { - device_printf(dev, "No I/O space?!\n"); - goto bad; - } - - rid = 0; - sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, - 0, ~0, 1, RF_ACTIVE); - - if (!sc->irq) { - device_printf(dev, "No IRQ?!\n"); - goto bad; - } - - error = bus_setup_intr(dev, sc->irq, INTR_TYPE_NET, - ex_intr, (void *)sc, &ih); - - if (error) { - device_printf(dev, "bus_setup_intr() failed!\n"); - goto bad; - } - - /* - * Fill in several fields of the softc structure: - * - I/O base address. - * - Hardware Ethernet address. - * - IRQ number (if not supplied in config file, read it from EEPROM). - * - Connector type. - */ - sc->dev = dev; - sc->iobase = rman_get_start(sc->ioport); - sc->irq_no = rman_get_start(sc->irq); - - ex_get_address(sc->iobase, sc->arpcom.ac_enaddr); - - /* work out which set of irq <-> internal tables to use */ - if (ex_card_type(sc->arpcom.ac_enaddr) == CARD_TYPE_EX_10_PLUS) { - sc->irq2ee = plus_irq2eemap; - sc->ee2irq = plus_ee2irqmap; - } else { - sc->irq2ee = irq2eemap; - sc->ee2irq = ee2irqmap; - } - - sc->connector = ex_get_media(sc->iobase); - sc->mem_size = CARD_RAM_SIZE; /* XXX This should be read from the card itself. */ - - /* - * Initialize the ifnet structure. - */ - ifp->if_softc = sc; - ifp->if_unit = unit; - ifp->if_name = "ex"; - ifp->if_mtu = ETHERMTU; - ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST /* XXX not done yet. | IFF_MULTICAST */; - ifp->if_output = ether_output; - ifp->if_start = ex_start; - ifp->if_ioctl = ex_ioctl; - ifp->if_watchdog = ex_watchdog; - ifp->if_init = ex_init; - ifp->if_snd.ifq_maxlen = IFQ_MAXLEN; - - /* - * Attach the interface. - */ - if_attach(ifp); - ether_ifattach(ifp); - - device_printf(sc->dev, "Ethernet address %6D\n", - sc->arpcom.ac_enaddr, ":"); - - /* - * If BPF is in the kernel, call the attach for it - */ - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); - DODEBUG(Start_End, printf("ex_isa_attach%d: finish\n", unit);); - - return(0); -bad: - - if (sc->ioport) - bus_release_resource(dev, SYS_RES_IOPORT, 0, sc->ioport); - if (sc->irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq); - - return (-1); -} - - -static void -ex_init(void *xsc) -{ - struct ex_softc * sc = (struct ex_softc *) xsc; - struct ifnet * ifp = &sc->arpcom.ac_if; - int s; - int i; - register int iobase = sc->iobase; - unsigned short temp_reg; - - DODEBUG(Start_End, printf("ex_init%d: start\n", ifp->if_unit);); - - if (ifp->if_addrhead.tqh_first == NULL) { - return; - } - s = splimp(); - sc->arpcom.ac_if.if_timer = 0; - - /* - * Load the ethernet address into the card. - */ - outb(iobase + CMD_REG, Bank2_Sel); - temp_reg = inb(iobase + EEPROM_REG); - if (temp_reg & Trnoff_Enable) { - outb(iobase + EEPROM_REG, temp_reg & ~Trnoff_Enable); - } - for (i = 0; i < ETHER_ADDR_LEN; i++) { - outb(iobase + I_ADDR_REG0 + i, sc->arpcom.ac_enaddr[i]); - } - /* - * - Setup transmit chaining and discard bad received frames. - * - Match broadcast. - * - Clear test mode. - * - Set receiving mode. - * - Set IRQ number. - */ - outb(iobase + REG1, inb(iobase + REG1) | Tx_Chn_Int_Md | Tx_Chn_ErStp | Disc_Bad_Fr); - outb(iobase + REG2, inb(iobase + REG2) | No_SA_Ins | RX_CRC_InMem); - outb(iobase + REG3, inb(iobase + REG3) & 0x3f /* XXX constants. */ ); - outb(iobase + CMD_REG, Bank1_Sel); - outb(iobase + INT_NO_REG, (inb(iobase + INT_NO_REG) & 0xf8) | sc->irq2ee[sc->irq_no]); - - /* - * Divide the available memory in the card into rcv and xmt buffers. - * By default, I use the first 3/4 of the memory for the rcv buffer, - * and the remaining 1/4 of the memory for the xmt buffer. - */ - sc->rx_mem_size = sc->mem_size * 3 / 4; - sc->tx_mem_size = sc->mem_size - sc->rx_mem_size; - sc->rx_lower_limit = 0x0000; - sc->rx_upper_limit = sc->rx_mem_size - 2; - sc->tx_lower_limit = sc->rx_mem_size; - sc->tx_upper_limit = sc->mem_size - 2; - outb(iobase + RCV_LOWER_LIMIT_REG, sc->rx_lower_limit >> 8); - outb(iobase + RCV_UPPER_LIMIT_REG, sc->rx_upper_limit >> 8); - outb(iobase + XMT_LOWER_LIMIT_REG, sc->tx_lower_limit >> 8); - outb(iobase + XMT_UPPER_LIMIT_REG, sc->tx_upper_limit >> 8); - - /* - * Enable receive and transmit interrupts, and clear any pending int. - */ - outb(iobase + REG1, inb(iobase + REG1) | TriST_INT); - outb(iobase + CMD_REG, Bank0_Sel); - outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); - outb(iobase + STATUS_REG, All_Int); - - /* - * Initialize receive and transmit ring buffers. - */ - outw(iobase + RCV_BAR, sc->rx_lower_limit); - sc->rx_head = sc->rx_lower_limit; - outw(iobase + RCV_STOP_REG, sc->rx_upper_limit | 0xfe); - outw(iobase + XMT_BAR, sc->tx_lower_limit); - sc->tx_head = sc->tx_tail = sc->tx_lower_limit; - - ifp->if_flags |= IFF_RUNNING; - ifp->if_flags &= ~IFF_OACTIVE; - DODEBUG(Status, printf("OIDLE init\n");); - - /* - * Final reset of the board, and enable operation. - */ - outb(iobase + CMD_REG, Sel_Reset_CMD); - DELAY(2); - outb(iobase + CMD_REG, Rcv_Enable_CMD); - - ex_start(ifp); - splx(s); - - DODEBUG(Start_End, printf("ex_init%d: finish\n", ifp->if_unit);); -} - - -static void -ex_start(struct ifnet *ifp) -{ - struct ex_softc * sc = ifp->if_softc; - int iobase = sc->iobase; - int i, s, len, data_len, avail, dest, next; - unsigned char tmp16[2]; - struct mbuf * opkt; - struct mbuf * m; - - DODEBUG(Start_End, printf("ex_start%d: start\n", unit);); - - s = splimp(); - - /* - * Main loop: send outgoing packets to network card until there are no - * more packets left, or the card cannot accept any more yet. - */ - while (((opkt = ifp->if_snd.ifq_head) != NULL) && - !(ifp->if_flags & IFF_OACTIVE)) { - - /* - * Ensure there is enough free transmit buffer space for - * this packet, including its header. Note: the header - * cannot wrap around the end of the transmit buffer and - * must be kept together, so we allow space for twice the - * length of the header, just in case. - */ - - for (len = 0, m = opkt; m != NULL; m = m->m_next) { - len += m->m_len; - } - - data_len = len; - - DODEBUG(Sent_Pkts, printf("1. Sending packet with %d data bytes. ", data_len);); - - if (len & 1) { - len += XMT_HEADER_LEN + 1; - } else { - len += XMT_HEADER_LEN; - } - - if ((i = sc->tx_tail - sc->tx_head) >= 0) { - avail = sc->tx_mem_size - i; - } else { - avail = -i; - } - - DODEBUG(Sent_Pkts, printf("i=%d, avail=%d\n", i, avail);); - - if (avail >= len + XMT_HEADER_LEN) { - IF_DEQUEUE(&ifp->if_snd, opkt); - -#ifdef EX_PSA_INTR - /* - * Disable rx and tx interrupts, to avoid corruption - * of the host address register by interrupt service - * routines. - * XXX Is this necessary with splimp() enabled? - */ - outb(iobase + MASK_REG, All_Int); -#endif - - /* - * Compute the start and end addresses of this - * frame in the tx buffer. - */ - dest = sc->tx_tail; - next = dest + len; - - if (next > sc->tx_upper_limit) { - if ((sc->tx_upper_limit + 2 - sc->tx_tail) <= - XMT_HEADER_LEN) { - dest = sc->tx_lower_limit; - next = dest + len; - } else { - next = sc->tx_lower_limit + - next - sc->tx_upper_limit - 2; - } - } - - /* - * Build the packet frame in the card's ring buffer. - */ - DODEBUG(Sent_Pkts, printf("2. dest=%d, next=%d. ", dest, next);); - - outw(iobase + HOST_ADDR_REG, dest); - outw(iobase + IO_PORT_REG, Transmit_CMD); - outw(iobase + IO_PORT_REG, 0); - outw(iobase + IO_PORT_REG, next); - outw(iobase + IO_PORT_REG, data_len); - - /* - * Output the packet data to the card. Ensure all - * transfers are 16-bit wide, even if individual - * mbufs have odd length. - */ - - for (m = opkt, i = 0; m != NULL; m = m->m_next) { - DODEBUG(Sent_Pkts, printf("[%d]", m->m_len);); - if (i) { - tmp16[1] = *(mtod(m, caddr_t)); - outsw(iobase + IO_PORT_REG, tmp16, 1); - } - outsw(iobase + IO_PORT_REG, - mtod(m, caddr_t) + i, (m->m_len - i) / 2); - - if ((i = (m->m_len - i) & 1) != 0) { - tmp16[0] = *(mtod(m, caddr_t) + - m->m_len - 1); - } - } - if (i) { - outsw(iobase + IO_PORT_REG, tmp16, 1); - } - - /* - * If there were other frames chained, update the - * chain in the last one. - */ - if (sc->tx_head != sc->tx_tail) { - if (sc->tx_tail != dest) { - outw(iobase + HOST_ADDR_REG, - sc->tx_last + XMT_Chain_Point); - outw(iobase + IO_PORT_REG, dest); - } - outw(iobase + HOST_ADDR_REG, - sc->tx_last + XMT_Byte_Count); - i = inw(iobase + IO_PORT_REG); - outw(iobase + HOST_ADDR_REG, - sc->tx_last + XMT_Byte_Count); - outw(iobase + IO_PORT_REG, i | Ch_bit); - } - - /* - * Resume normal operation of the card: - * - Make a dummy read to flush the DRAM write - * pipeline. - * - Enable receive and transmit interrupts. - * - Send Transmit or Resume_XMT command, as - * appropriate. - */ - inw(iobase + IO_PORT_REG); -#ifdef EX_PSA_INTR - outb(iobase + MASK_REG, All_Int & ~(Rx_Int | Tx_Int)); -#endif - if (sc->tx_head == sc->tx_tail) { - outw(iobase + XMT_BAR, dest); - outb(iobase + CMD_REG, Transmit_CMD); - sc->tx_head = dest; - DODEBUG(Sent_Pkts, printf("Transmit\n");); - } else { - outb(iobase + CMD_REG, Resume_XMT_List_CMD); - DODEBUG(Sent_Pkts, printf("Resume\n");); - } - - sc->tx_last = dest; - sc->tx_tail = next; - - if (ifp->if_bpf != NULL) { - bpf_mtap(ifp, opkt); - } - - ifp->if_timer = 2; - ifp->if_opackets++; - m_freem(opkt); - } else { - ifp->if_flags |= IFF_OACTIVE; - DODEBUG(Status, printf("OACTIVE start\n");); - } - } - - splx(s); - - DODEBUG(Start_End, printf("ex_start%d: finish\n", unit);); -} - -static void -ex_stop(struct ex_softc *sc) -{ - int iobase = sc->iobase; - - DODEBUG(Start_End, printf("ex_stop%d: start\n", unit);); - - /* - * Disable card operation: - * - Disable the interrupt line. - * - Flush transmission and disable reception. - * - Mask and clear all interrupts. - * - Reset the 82595. - */ - outb(iobase + CMD_REG, Bank1_Sel); - outb(iobase + REG1, inb(iobase + REG1) & ~TriST_INT); - outb(iobase + CMD_REG, Bank0_Sel); - outb(iobase + CMD_REG, Rcv_Stop); - sc->tx_head = sc->tx_tail = sc->tx_lower_limit; - sc->tx_last = 0; /* XXX I think these two lines are not necessary, because ex_init will always be called again to reinit the interface. */ - outb(iobase + MASK_REG, All_Int); - outb(iobase + STATUS_REG, All_Int); - outb(iobase + CMD_REG, Reset_CMD); - DELAY(200); - - DODEBUG(Start_End, printf("ex_stop%d: finish\n", unit);); - - return; -} - - -static void -ex_intr(void *arg) -{ - struct ex_softc * sc = (struct ex_softc *)arg; - struct ifnet * ifp = &sc->arpcom.ac_if; - int iobase = sc->iobase; - int int_status, send_pkts; - - DODEBUG(Start_End, printf("ex_intr%d: start\n", unit);); - -#ifdef EXDEBUG - if (++exintr_count != 1) - printf("WARNING: nested interrupt (%d). Mail the author.\n", exintr_count); -#endif - - send_pkts = 0; - while ((int_status = inb(iobase + STATUS_REG)) & (Tx_Int | Rx_Int)) { - if (int_status & Rx_Int) { - outb(iobase + STATUS_REG, Rx_Int); - - ex_rx_intr(sc); - } else if (int_status & Tx_Int) { - outb(iobase + STATUS_REG, Tx_Int); - - ex_tx_intr(sc); - send_pkts = 1; - } - } - - /* - * If any packet has been transmitted, and there are queued packets to - * be sent, attempt to send more packets to the network card. - */ - - if (send_pkts && (ifp->if_snd.ifq_head != NULL)) { - ex_start(ifp); - } - -#ifdef EXDEBUG - exintr_count--; -#endif - - DODEBUG(Start_End, printf("ex_intr%d: finish\n", unit);); - - return; -} - -static void -ex_tx_intr(struct ex_softc *sc) -{ - struct ifnet * ifp = &sc->arpcom.ac_if; - int iobase = sc->iobase; - int tx_status; - - DODEBUG(Start_End, printf("ex_tx_intr%d: start\n", unit);); - - /* - * - Cancel the watchdog. - * For all packets transmitted since last transmit interrupt: - * - Advance chain pointer to next queued packet. - * - Update statistics. - */ - - ifp->if_timer = 0; - - while (sc->tx_head != sc->tx_tail) { - outw(iobase + HOST_ADDR_REG, sc->tx_head); - - if (! inw(iobase + IO_PORT_REG) & Done_bit) - break; - - tx_status = inw(iobase + IO_PORT_REG); - sc->tx_head = inw(iobase + IO_PORT_REG); - - if (tx_status & TX_OK_bit) { - ifp->if_opackets++; - } else { - ifp->if_oerrors++; - } - - ifp->if_collisions += tx_status & No_Collisions_bits; - } - - /* - * The card should be ready to accept more packets now. - */ - - ifp->if_flags &= ~IFF_OACTIVE; - - DODEBUG(Status, printf("OIDLE tx_intr\n");); - DODEBUG(Start_End, printf("ex_tx_intr%d: finish\n", unit);); - - return; -} - -static void -ex_rx_intr(struct ex_softc *sc) -{ - struct ifnet * ifp = &sc->arpcom.ac_if; - int iobase = sc->iobase; - int rx_status; - int pkt_len; - int QQQ; - struct mbuf * m; - struct mbuf * ipkt; - struct ether_header * eh; - - DODEBUG(Start_End, printf("ex_rx_intr%d: start\n", unit);); - - /* - * For all packets received since last receive interrupt: - * - If packet ok, read it into a new mbuf and queue it to interface, - * updating statistics. - * - If packet bad, just discard it, and update statistics. - * Finally, advance receive stop limit in card's memory to new location. - */ - - outw(iobase + HOST_ADDR_REG, sc->rx_head); - - while (inw(iobase + IO_PORT_REG) == RCV_Done) { - - rx_status = inw(iobase + IO_PORT_REG); - sc->rx_head = inw(iobase + IO_PORT_REG); - QQQ = pkt_len = inw(iobase + IO_PORT_REG); - - if (rx_status & RCV_OK_bit) { - MGETHDR(m, M_DONTWAIT, MT_DATA); - ipkt = m; - if (ipkt == NULL) { - ifp->if_iqdrops++; - } else { - ipkt->m_pkthdr.rcvif = ifp; - ipkt->m_pkthdr.len = pkt_len; - ipkt->m_len = MHLEN; - - while (pkt_len > 0) { - if (pkt_len > MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) { - m->m_len = MCLBYTES; - } else { - m_freem(ipkt); - ifp->if_iqdrops++; - goto rx_another; - } - } - m->m_len = min(m->m_len, pkt_len); - - /* - * NOTE: I'm assuming that all mbufs allocated are of even length, - * except for the last one in an odd-length packet. - */ - - insw(iobase + IO_PORT_REG, - mtod(m, caddr_t), m->m_len / 2); - - if (m->m_len & 1) { - *(mtod(m, caddr_t) + m->m_len - 1) = inb(iobase + IO_PORT_REG); - } - pkt_len -= m->m_len; - - if (pkt_len > 0) { - MGET(m->m_next, M_DONTWAIT, MT_DATA); - if (m->m_next == NULL) { - m_freem(ipkt); - ifp->if_iqdrops++; - goto rx_another; - } - m = m->m_next; - m->m_len = MLEN; - } - } - eh = mtod(ipkt, struct ether_header *); -#ifdef EXDEBUG - if (debug_mask & Rcvd_Pkts) { - if ((eh->ether_dhost[5] != 0xff) || (eh->ether_dhost[0] != 0xff)) { - printf("Receive packet with %d data bytes: %6D -> ", QQQ, eh->ether_shost, ":"); - printf("%6D\n", eh->ether_dhost, ":"); - } /* QQQ */ - } -#endif - if (ifp->if_bpf != NULL) { - bpf_mtap(ifp, ipkt); - - /* - * Note that the interface cannot be in promiscuous mode - * if there are no BPF listeners. And if we are in - * promiscuous mode, we have to check if this packet is - * really ours. - */ - if ((ifp->if_flags & IFF_PROMISC) && - (eh->ether_dhost[0] & 1) == 0 && - bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr, sizeof(eh->ether_dhost)) != 0 && - bcmp(eh->ether_dhost, etherbroadcastaddr, sizeof(eh->ether_dhost)) != 0) { - m_freem(ipkt); - goto rx_another; - } - } - m_adj(ipkt, sizeof(struct ether_header)); - ether_input(ifp, eh, ipkt); - ifp->if_ipackets++; - } - } else { - ifp->if_ierrors++; - } - outw(iobase + HOST_ADDR_REG, sc->rx_head); -rx_another: ; - } - - if (sc->rx_head < sc->rx_lower_limit + 2) - outw(iobase + RCV_STOP_REG, sc->rx_upper_limit); - else - outw(iobase + RCV_STOP_REG, sc->rx_head - 2); - - DODEBUG(Start_End, printf("ex_rx_intr%d: finish\n", unit);); - - return; -} - - -static int -ex_ioctl(register struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct ex_softc * sc = ifp->if_softc; - int s; - int error = 0; - - DODEBUG(Start_End, printf("ex_ioctl%d: start ", ifp->if_unit);); - - s = splimp(); - - switch(cmd) { - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, cmd, data); - break; - - case SIOCSIFFLAGS: - DODEBUG(Start_End, printf("SIOCSIFFLAGS");); - if ((ifp->if_flags & IFF_UP) == 0 && - (ifp->if_flags & IFF_RUNNING)) { - - ifp->if_flags &= ~IFF_RUNNING; - ex_stop(sc); - } else { - ex_init(sc); - } - break; -#ifdef NODEF - case SIOCGHWADDR: - DODEBUG(Start_End, printf("SIOCGHWADDR");); - bcopy((caddr_t)sc->sc_addr, (caddr_t)&ifr->ifr_data, - sizeof(sc->sc_addr)); - break; -#endif - case SIOCADDMULTI: - DODEBUG(Start_End, printf("SIOCADDMULTI");); - case SIOCDELMULTI: - DODEBUG(Start_End, printf("SIOCDELMULTI");); - /* XXX Support not done yet. */ - error = EINVAL; - break; - default: - DODEBUG(Start_End, printf("unknown");); - error = EINVAL; - } - - splx(s); - - DODEBUG(Start_End, printf("\nex_ioctl%d: finish\n", ifp->if_unit);); - - return(error); -} - - -static void -ex_reset(struct ex_softc *sc) -{ - int s; - - DODEBUG(Start_End, printf("ex_reset%d: start\n", unit);); - - s = splimp(); - - ex_stop(sc); - ex_init(sc); - - splx(s); - - DODEBUG(Start_End, printf("ex_reset%d: finish\n", unit);); - - return; -} - - -static void -ex_watchdog(struct ifnet *ifp) -{ - struct ex_softc * sc = ifp->if_softc; - - DODEBUG(Start_End, printf("ex_watchdog%d: start\n", ifp->if_unit);); - - ifp->if_flags &= ~IFF_OACTIVE; - - DODEBUG(Status, printf("OIDLE watchdog\n");); - - ifp->if_oerrors++; - ex_reset(sc); - ex_start(ifp); - - DODEBUG(Start_End, printf("ex_watchdog%d: finish\n", ifp->if_unit);); - - return; -} - - -static u_short -eeprom_read(int iobase, int location) -{ - int i; - u_short data = 0; - int ee_addr; - int read_cmd = location | EE_READ_CMD; - short ctrl_val = EECS; - - ee_addr = iobase + EEPROM_REG; - outb(iobase + CMD_REG, Bank2_Sel); - outb(ee_addr, EECS); - for (i = 8; i >= 0; i--) { - short outval = (read_cmd & (1 << i)) ? ctrl_val | EEDI : ctrl_val; - outb(ee_addr, outval); - outb(ee_addr, outval | EESK); - DELAY(3); - outb(ee_addr, outval); - DELAY(2); - } - outb(ee_addr, ctrl_val); - - for (i = 16; i > 0; i--) { - outb(ee_addr, ctrl_val | EESK); - DELAY(3); - data = (data << 1) | ((inb(ee_addr) & EEDO) ? 1 : 0); - outb(ee_addr, ctrl_val); - DELAY(2); - } - - ctrl_val &= ~EECS; - outb(ee_addr, ctrl_val | EESK); - DELAY(3); - outb(ee_addr, ctrl_val); - DELAY(2); - outb(iobase + CMD_REG, Bank0_Sel); - return(data); -} diff --git a/sys/i386/isa/if_exreg.h b/sys/i386/isa/if_exreg.h deleted file mode 100644 index 63b843f..0000000 --- a/sys/i386/isa/if_exreg.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 1996, Javier Martín Rueda (jmrueda@diatel.upm.es) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice unmodified, this list of conditions, and the following - * disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Intel EtherExpress Pro/10 Ethernet driver - */ - -/* - * Several constants. - */ - -/* Length of an ethernet address. */ -#define ETHER_ADDR_LEN 6 -/* Default RAM size in board. */ -#define CARD_RAM_SIZE 0x8000 -/* Number of I/O ports used. */ -#define EX_IOSIZE 16 - -/* - * Intel EtherExpress Pro (i82595 based) registers - */ - -/* Common registers to all banks. */ - -#define CMD_REG 0 -#define REG1 1 -#define REG2 2 -#define REG3 3 -#define REG4 4 -#define REG5 5 -#define REG6 6 -#define REG7 7 -#define REG8 8 -#define REG9 9 -#define REG10 10 -#define REG11 11 -#define REG12 12 -#define REG13 13 -#define REG14 14 -#define REG15 15 - -/* Definitions for command register (CMD_REG). */ - -#define Switch_Bank_CMD 0 -#define MC_Setup_CMD 3 -#define Transmit_CMD 4 -#define Diagnose_CMD 7 -#define Rcv_Enable_CMD 8 -#define Rcv_Stop 11 -#define Reset_CMD 14 -#define Resume_XMT_List_CMD 28 -#define Sel_Reset_CMD 30 -#define Abort 0x20 -#define Bank0_Sel 0x00 -#define Bank1_Sel 0x40 -#define Bank2_Sel 0x80 - -/* Bank 0 specific registers. */ - -#define STATUS_REG 1 -#define ID_REG 2 -#define Id_Mask 0x2c -#define Id_Sig 0x24 -#define Counter_bits 0xc0 -#define MASK_REG 3 -#define Exec_Int 0x08 -#define Tx_Int 0x04 -#define Rx_Int 0x02 -#define Rx_Stp_Int 0x01 -#define All_Int 0x0f -#define RCV_BAR 4 -#define RCV_BAR_Lo 4 -#define RCV_BAR_Hi 5 -#define RCV_STOP_REG 6 -#define XMT_BAR 10 -#define HOST_ADDR_REG 12 /* 16-bit register */ -#define IO_PORT_REG 14 /* 16-bit register */ - -/* Bank 1 specific registers. */ - -#define TriST_INT 0x80 -#define INT_NO_REG 2 -#define RCV_LOWER_LIMIT_REG 8 -#define RCV_UPPER_LIMIT_REG 9 -#define XMT_LOWER_LIMIT_REG 10 -#define XMT_UPPER_LIMIT_REG 11 - -/* Bank 2 specific registers. */ - -#define Disc_Bad_Fr 0x80 -#define Tx_Chn_ErStp 0x40 -#define Tx_Chn_Int_Md 0x20 -#define No_SA_Ins 0x10 -#define RX_CRC_InMem 0x04 -#define BNC_bit 0x20 -#define TPE_bit 0x04 -#define I_ADDR_REG0 4 -#define EEPROM_REG 10 -#define Trnoff_Enable 0x10 - -/* EEPROM memory positions (16-bit wide). */ - -#define EE_IRQ_No 1 -#define IRQ_No_Mask 0x07 -#define EE_Eth_Addr_Lo 2 -#define EE_Eth_Addr_Mid 3 -#define EE_Eth_Addr_Hi 4 - -/* EEPROM serial interface. */ - -#define EESK 0x01 -#define EECS 0x02 -#define EEDI 0x04 -#define EEDO 0x08 -#define EE_READ_CMD (6 << 6) - -/* Frame chain constants. */ - -/* Transmit header length (in board's ring buffer). */ -#define XMT_HEADER_LEN 8 -#define XMT_Chain_Point 4 -#define XMT_Byte_Count 6 -#define Done_bit 0x0080 -#define Ch_bit 0x8000 -/* Transmit result bits. */ -#define No_Collisions_bits 0x000f -#define TX_OK_bit 0x2000 -/* Receive result bits. */ -#define RCV_Done 8 -#define RCV_OK_bit 0x2000 diff --git a/sys/i386/isa/if_ie.c b/sys/i386/isa/if_ie.c deleted file mode 100644 index fbbb801..0000000 --- a/sys/i386/isa/if_ie.c +++ /dev/null @@ -1,2324 +0,0 @@ -/*- - * Copyright (c) 1992, 1993, University of Vermont and State - * Agricultural College. - * Copyright (c) 1992, 1993, Garrett A. Wollman. - * - * Portions: - * Copyright (c) 1990, 1991, William F. Jolitz - * Copyright (c) 1990, The Regents of the University of California - * - * 3Com 3C507 support: - * Copyright (c) 1993, 1994, Charles M. Hannum - * - * EtherExpress 16 support: - * Copyright (c) 1993, 1994, 1995, Rodney W. Grimes - * Copyright (c) 1997, Aaron C. Smith - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * Vermont and State Agricultural College and Garrett A. Wollman, by - * William F. Jolitz, by the University of California, Berkeley, - * Lawrence Berkeley Laboratory, and their contributors, by - * Charles M. Hannum, by Rodney W. Grimes, and by Aaron C. Smith. - * 4. Neither the names of the Universities nor the names of the authors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* - * Intel 82586 Ethernet chip - * Register, bit, and structure definitions. - * - * Written by GAW with reference to the Clarkson Packet Driver code for this - * chip written by Russ Nelson and others. - * - * Intel EtherExpress 16 support from if_ix.c, written by Rodney W. Grimes. - */ - -/* - * The i82586 is a very versatile chip, found in many implementations. - * Programming this chip is mostly the same, but certain details differ - * from card to card. This driver is written so that different cards - * can be automatically detected at run-time. - */ - -/* -Mode of operation: - -We run the 82586 in a standard Ethernet mode. We keep NFRAMES received -frame descriptors around for the receiver to use, and NRXBUFS associated -receive buffer descriptors, both in a circular list. Whenever a frame is -received, we rotate both lists as necessary. (The 586 treats both lists -as a simple queue.) We also keep a transmit command around so that packets -can be sent off quickly. - -We configure the adapter in AL-LOC = 1 mode, which means that the -Ethernet/802.3 MAC header is placed at the beginning of the receive buffer -rather than being split off into various fields in the RFD. This also -means that we must include this header in the transmit buffer as well. - -By convention, all transmit commands, and only transmit commands, shall -have the I (IE_CMD_INTR) bit set in the command. This way, when an -interrupt arrives at ieintr(), it is immediately possible to tell -what precisely caused it. ANY OTHER command-sending routines should -run at splimp(), and should post an acknowledgement to every interrupt -they generate. - -The 82586 has a 24-bit address space internally, and the adaptor's memory -is located at the top of this region. However, the value we are given in -configuration is normally the *bottom* of the adaptor RAM. So, we must go -through a few gyrations to come up with a kernel virtual address which -represents the actual beginning of the 586 address space. First, we -autosize the RAM by running through several possible sizes and trying to -initialize the adapter under the assumption that the selected size is -correct. Then, knowing the correct RAM size, we set up our pointers in -ie_softc[unit]. `iomem' represents the computed base of the 586 address -space. `iomembot' represents the actual configured base of adapter RAM. -Finally, `iosize' represents the calculated size of 586 RAM. Then, when -laying out commands, we use the interval [iomembot, iomembot + iosize); to -make 24-pointers, we subtract iomem, and to make 16-pointers, we subtract -iomem and and with 0xffff. - -*/ - -#include "ie.h" -#if NIE > 0 -#include "opt_inet.h" -#include "opt_ipx.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/eventhandler.h> -#include <sys/kernel.h> -#include <sys/malloc.h> -#include <sys/conf.h> -#include <sys/mbuf.h> -#include <sys/socket.h> -#include <sys/sockio.h> -#include <sys/syslog.h> - -#include <net/ethernet.h> -#include <net/if.h> -#include <net/if_types.h> -#include <net/if_dl.h> - -#include <netinet/in.h> -#include <netinet/if_ether.h> - -#include <machine/clock.h> -#include <machine/md_var.h> - -#include <i386/isa/isa_device.h> -#include <i386/isa/ic/i82586.h> -#include <i386/isa/icu.h> -#include <i386/isa/if_iereg.h> -#include <i386/isa/if_ie507.h> -#include <i386/isa/if_iee16.h> -#include <i386/isa/elink.h> - -#include <net/bpf.h> - -#ifdef DEBUG -#define IED_RINT 0x01 -#define IED_TINT 0x02 -#define IED_RNR 0x04 -#define IED_CNA 0x08 -#define IED_READFRAME 0x10 -static int ie_debug = IED_RNR; - -#endif - -#define IE_BUF_LEN ETHER_MAX_LEN /* length of transmit buffer */ - -/* Forward declaration */ -struct ie_softc; - -static struct mbuf *last_not_for_us; - -static int ieprobe(struct isa_device * dvp); -static int ieattach(struct isa_device * dvp); -static ointhand2_t ieintr; -static int sl_probe(struct isa_device * dvp); -static int el_probe(struct isa_device * dvp); -static int ni_probe(struct isa_device * dvp); -static int ee16_probe(struct isa_device * dvp); - -static int check_ie_present(int unit, caddr_t where, unsigned size); -static void ieinit(void *); -static void ie_stop(int unit); -static int ieioctl(struct ifnet * ifp, u_long command, caddr_t data); -static void iestart(struct ifnet * ifp); - -static void el_reset_586(int unit); -static void el_chan_attn(int unit); - -static void sl_reset_586(int unit); -static void sl_chan_attn(int unit); - -static void ee16_reset_586(int unit); -static void ee16_chan_attn(int unit); -static __inline void ee16_interrupt_enable(struct ie_softc * ie); -static void ee16_eeprom_outbits(struct ie_softc * ie, int edata, int cnt); -static void ee16_eeprom_clock(struct ie_softc * ie, int state); -static u_short ee16_read_eeprom(struct ie_softc * ie, int location); -static int ee16_eeprom_inbits(struct ie_softc * ie); -static void ee16_shutdown(void *sc, int howto); - -static void iereset(int unit); -static void ie_readframe(int unit, struct ie_softc * ie, int bufno); -static void ie_drop_packet_buffer(int unit, struct ie_softc * ie); -static void sl_read_ether(int unit, unsigned char addr[6]); -static void find_ie_mem_size(int unit); -static void chan_attn_timeout(void *rock); -static int command_and_wait(int unit, int command, - void volatile * pcmd, int); -static void run_tdr(int unit, volatile struct ie_tdr_cmd * cmd); -static int ierint(int unit, struct ie_softc * ie); -static int ietint(int unit, struct ie_softc * ie); -static int iernr(int unit, struct ie_softc * ie); -static void start_receiver(int unit); -static __inline int ieget(int, struct ie_softc *, struct mbuf **, - struct ether_header *, int *); -static v_caddr_t setup_rfa(v_caddr_t ptr, struct ie_softc * ie); -static int mc_setup(int, v_caddr_t, volatile struct ie_sys_ctl_block *); -static void ie_mc_reset(int unit); - -#ifdef DEBUG -static void print_rbd(volatile struct ie_recv_buf_desc * rbd); - -static int in_ierint = 0; -static int in_ietint = 0; - -#endif - -/* - * This tells the autoconf code how to set us up. - */ -struct isa_driver iedriver = { - ieprobe, ieattach, "ie", -}; - -enum ie_hardware { - IE_STARLAN10, - IE_EN100, - IE_SLFIBER, - IE_3C507, - IE_NI5210, - IE_EE16, - IE_UNKNOWN -}; - -static const char *ie_hardware_names[] = { - "StarLAN 10", - "EN100", - "StarLAN Fiber", - "3C507", - "NI5210", - "EtherExpress 16", - "Unknown" -}; - -/* -sizeof(iscp) == 1+1+2+4 == 8 -sizeof(scb) == 2+2+2+2+2+2+2+2 == 16 -NFRAMES * sizeof(rfd) == NFRAMES*(2+2+2+2+6+6+2+2) == NFRAMES*24 == 384 -sizeof(xmit_cmd) == 2+2+2+2+6+2 == 18 -sizeof(transmit buffer) == 1512 -sizeof(transmit buffer desc) == 8 ------ -1946 - -NRXBUFS * sizeof(rbd) == NRXBUFS*(2+2+4+2+2) == NRXBUFS*12 -NRXBUFS * IE_RBUF_SIZE == NRXBUFS*256 - -NRXBUFS should be (16384 - 1946) / (256 + 12) == 14438 / 268 == 53 - -With NRXBUFS == 48, this leaves us 1574 bytes for another command or -more buffers. Another transmit command would be 18+8+1512 == 1538 ----just barely fits! - -Obviously all these would have to be reduced for smaller memory sizes. -With a larger memory, it would be possible to roughly double the number of -both transmit and receive buffers. -*/ - -#define NFRAMES 8 /* number of receive frames */ -#define NRXBUFS 48 /* number of buffers to allocate */ -#define IE_RBUF_SIZE 256 /* size of each buffer, MUST BE POWER OF TWO */ -#define NTXBUFS 2 /* number of transmit commands */ -#define IE_TBUF_SIZE ETHER_MAX_LEN /* size of transmit buffer */ - -/* - * Ethernet status, per interface. - */ -static struct ie_softc { - struct arpcom arpcom; - void (*ie_reset_586) (int); - void (*ie_chan_attn) (int); - enum ie_hardware hard_type; - int hard_vers; - int unit; - - u_short port; /* i/o base address for this interface */ - caddr_t iomem; /* memory size */ - caddr_t iomembot; /* memory base address */ - unsigned iosize; - int bus_use; /* 0 means 16bit, 1 means 8 bit adapter */ - - int want_mcsetup; - int promisc; - int nframes; - int nrxbufs; - int ntxbufs; - volatile struct ie_int_sys_conf_ptr *iscp; - volatile struct ie_sys_ctl_block *scb; - volatile struct ie_recv_frame_desc **rframes; /* nframes worth */ - volatile struct ie_recv_buf_desc **rbuffs; /* nrxbufs worth */ - volatile u_char **cbuffs; /* nrxbufs worth */ - int rfhead, rftail, rbhead, rbtail; - - volatile struct ie_xmit_cmd **xmit_cmds; /* ntxbufs worth */ - volatile struct ie_xmit_buf **xmit_buffs; /* ntxbufs worth */ - volatile u_char **xmit_cbuffs; /* ntxbufs worth */ - int xmit_count; - - struct ie_en_addr mcast_addrs[MAXMCAST + 1]; - int mcast_count; - - u_short irq_encoded; /* encoded interrupt on IEE16 */ -} ie_softc[NIE]; - -#define MK_24(base, ptr) ((caddr_t)((uintptr_t)ptr - (uintptr_t)base)) -#define MK_16(base, ptr) ((u_short)(uintptr_t)MK_24(base, ptr)) - -#define PORT ie_softc[unit].port -#define MEM ie_softc[unit].iomem - -int -ieprobe(struct isa_device *dvp) -{ - int ret; - - ret = sl_probe(dvp); - if (!ret) - ret = el_probe(dvp); - if (!ret) - ret = ni_probe(dvp); - if (!ret) - ret = ee16_probe(dvp); - - return (ret); -} - -static int -sl_probe(struct isa_device *dvp) -{ - int unit = dvp->id_unit; - u_char c; - - ie_softc[unit].port = dvp->id_iobase; - ie_softc[unit].iomembot = dvp->id_maddr; - ie_softc[unit].iomem = 0; - ie_softc[unit].bus_use = 0; - - c = inb(PORT + IEATT_REVISION); - switch (SL_BOARD(c)) { - case SL10_BOARD: - ie_softc[unit].hard_type = IE_STARLAN10; - ie_softc[unit].ie_reset_586 = sl_reset_586; - ie_softc[unit].ie_chan_attn = sl_chan_attn; - break; - case EN100_BOARD: - ie_softc[unit].hard_type = IE_EN100; - ie_softc[unit].ie_reset_586 = sl_reset_586; - ie_softc[unit].ie_chan_attn = sl_chan_attn; - break; - case SLFIBER_BOARD: - ie_softc[unit].hard_type = IE_SLFIBER; - ie_softc[unit].ie_reset_586 = sl_reset_586; - ie_softc[unit].ie_chan_attn = sl_chan_attn; - break; - - /* - * Anything else is not recognized or cannot be used. - */ - default: - return (0); - } - - ie_softc[unit].hard_vers = SL_REV(c); - - /* - * Divine memory size on-board the card. Ususally 16k. - */ - find_ie_mem_size(unit); - - if (!ie_softc[unit].iosize) { - return (0); - } - dvp->id_msize = ie_softc[unit].iosize; - - switch (ie_softc[unit].hard_type) { - case IE_EN100: - case IE_STARLAN10: - case IE_SLFIBER: - sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr); - break; - - default: - if (bootverbose) - printf("ie%d: unknown AT&T board type code %d\n", unit, - ie_softc[unit].hard_type); - return (0); - } - - return (1); -} - - -static int -el_probe(struct isa_device *dvp) -{ - struct ie_softc *sc = &ie_softc[dvp->id_unit]; - u_char c; - int i; - u_char signature[] = "*3COM*"; - int unit = dvp->id_unit; - - sc->unit = unit; - sc->port = dvp->id_iobase; - sc->iomembot = dvp->id_maddr; - sc->bus_use = 0; - - /* Need this for part of the probe. */ - sc->ie_reset_586 = el_reset_586; - sc->ie_chan_attn = el_chan_attn; - - /* Reset and put card in CONFIG state without changing address. */ - elink_reset(); - outb(ELINK_ID_PORT, 0x00); - elink_idseq(ELINK_507_POLY); - elink_idseq(ELINK_507_POLY); - outb(ELINK_ID_PORT, 0xff); - - c = inb(PORT + IE507_MADDR); - if (c & 0x20) { -#ifdef DEBUG - printf("ie%d: can't map 3C507 RAM in high memory\n", unit); -#endif - return (0); - } - /* go to RUN state */ - outb(ELINK_ID_PORT, 0x00); - elink_idseq(ELINK_507_POLY); - outb(ELINK_ID_PORT, 0x00); - - outb(PORT + IE507_CTRL, EL_CTRL_NRST); - - for (i = 0; i < 6; i++) - if (inb(PORT + i) != signature[i]) - return (0); - - c = inb(PORT + IE507_IRQ) & 0x0f; - - if (dvp->id_irq != (1 << c)) { - printf("ie%d: kernel configured irq %d " - "doesn't match board configured irq %d\n", - unit, ffs(dvp->id_irq) - 1, c); - return (0); - } - c = (inb(PORT + IE507_MADDR) & 0x1c) + 0xc0; - - if (kvtop(dvp->id_maddr) != ((int) c << 12)) { - printf("ie%d: kernel configured maddr %lx " - "doesn't match board configured maddr %x\n", - unit, kvtop(dvp->id_maddr), (int) c << 12); - return (0); - } - outb(PORT + IE507_CTRL, EL_CTRL_NORMAL); - - sc->hard_type = IE_3C507; - sc->hard_vers = 0; /* 3C507 has no version number. */ - - /* - * Divine memory size on-board the card. - */ - find_ie_mem_size(unit); - - if (!sc->iosize) { - printf("ie%d: can't find shared memory\n", unit); - outb(PORT + IE507_CTRL, EL_CTRL_NRST); - return (0); - } - if (!dvp->id_msize) - dvp->id_msize = sc->iosize; - else if (dvp->id_msize != sc->iosize) { - printf("ie%d: kernel configured msize %d " - "doesn't match board configured msize %d\n", - unit, dvp->id_msize, sc->iosize); - outb(PORT + IE507_CTRL, EL_CTRL_NRST); - return (0); - } - sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr); - - /* Clear the interrupt latch just in case. */ - outb(PORT + IE507_ICTRL, 1); - - return (16); -} - - -static int -ni_probe(struct isa_device *dvp) -{ - int unit = dvp->id_unit; - int boardtype, c; - - ie_softc[unit].port = dvp->id_iobase; - ie_softc[unit].iomembot = dvp->id_maddr; - ie_softc[unit].iomem = 0; - ie_softc[unit].bus_use = 1; - - boardtype = inb(PORT + IEATT_REVISION); - c = inb(PORT + IEATT_REVISION + 1); - boardtype = boardtype + (c << 8); - switch (boardtype) { - case 0x5500: /* This is the magic cookie for the NI5210 */ - ie_softc[unit].hard_type = IE_NI5210; - ie_softc[unit].ie_reset_586 = sl_reset_586; - ie_softc[unit].ie_chan_attn = sl_chan_attn; - break; - - /* - * Anything else is not recognized or cannot be used. - */ - default: - return (0); - } - - ie_softc[unit].hard_vers = 0; - - /* - * Divine memory size on-board the card. Either 8 or 16k. - */ - find_ie_mem_size(unit); - - if (!ie_softc[unit].iosize) { - return (0); - } - if (!dvp->id_msize) - dvp->id_msize = ie_softc[unit].iosize; - else if (dvp->id_msize != ie_softc[unit].iosize) { - printf("ie%d: kernel configured msize %d " - "doesn't match board configured msize %d\n", - unit, dvp->id_msize, ie_softc[unit].iosize); - return (0); - } - sl_read_ether(unit, ie_softc[unit].arpcom.ac_enaddr); - - return (8); - -} - - -static void -ee16_shutdown(void *sc, int howto) -{ - struct ie_softc *ie = (struct ie_softc *)sc; - int unit = ie - &ie_softc[0]; - - ee16_reset_586(unit); - outb(PORT + IEE16_ECTRL, IEE16_RESET_ASIC); - outb(PORT + IEE16_ECTRL, 0); -} - - -/* Taken almost exactly from Rod's if_ix.c. */ - -int -ee16_probe(struct isa_device *dvp) -{ - struct ie_softc *sc = &ie_softc[dvp->id_unit]; - - int i; - int unit = dvp->id_unit; - u_short board_id, id_var1, id_var2, checksum = 0; - u_short eaddrtemp, irq; - u_short pg, adjust, decode, edecode; - u_char bart_config; - u_long bd_maddr; - - short irq_translate[] = {0, IRQ9, IRQ3, IRQ4, IRQ5, IRQ10, IRQ11, 0}; - char irq_encode[] = {0, 0, 0, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0}; - - /* Need this for part of the probe. */ - sc->ie_reset_586 = ee16_reset_586; - sc->ie_chan_attn = ee16_chan_attn; - - /* unsure if this is necessary */ - sc->bus_use = 0; - - /* reset any ee16 at the current iobase */ - outb(dvp->id_iobase + IEE16_ECTRL, IEE16_RESET_ASIC); - outb(dvp->id_iobase + IEE16_ECTRL, 0); - DELAY(240); - - /* now look for ee16. */ - board_id = id_var1 = id_var2 = 0; - for (i = 0; i < 4; i++) { - id_var1 = inb(dvp->id_iobase + IEE16_ID_PORT); - id_var2 = ((id_var1 & 0x03) << 2); - board_id |= ((id_var1 >> 4) << id_var2); - } - - if (board_id != IEE16_ID) { - if (bootverbose) - printf("ie%d: unknown board_id: %x\n", unit, board_id); - return (0); - } - /* need sc->port for ee16_read_eeprom */ - sc->port = dvp->id_iobase; - sc->hard_type = IE_EE16; - - /* - * The shared RAM location on the EE16 is encoded into bits 3-7 of - * EEPROM location 6. We zero the upper byte, and shift the 5 bits - * right 3. The resulting number tells us the RAM location. - * Because the EE16 supports either 16k or 32k of shared RAM, we - * only worry about the 32k locations. - * - * NOTE: if a 64k EE16 exists, it should be added to this switch. then - * the ia->ia_msize would need to be set per case statement. - * - * value msize location ===== ===== ======== 0x03 0x8000 - * 0xCC000 0x06 0x8000 0xD0000 0x0C 0x8000 0xD4000 0x18 - * 0x8000 0xD8000 - * - */ - - bd_maddr = 0; - i = (ee16_read_eeprom(sc, 6) & 0x00ff) >> 3; - switch (i) { - case 0x03: - bd_maddr = 0xCC000; - break; - case 0x06: - bd_maddr = 0xD0000; - break; - case 0x0c: - bd_maddr = 0xD4000; - break; - case 0x18: - bd_maddr = 0xD8000; - break; - default: - bd_maddr = 0; - break; - } - dvp->id_msize = 0x8000; - if (kvtop(dvp->id_maddr) != bd_maddr) { - printf("ie%d: kernel configured maddr %lx " - "doesn't match board configured maddr %lx\n", - unit, kvtop(dvp->id_maddr), bd_maddr); - } - sc->iomembot = dvp->id_maddr; - sc->iomem = 0; /* XXX some probes set this and some don't */ - sc->iosize = dvp->id_msize; - - /* need to put the 586 in RESET while we access the eeprom. */ - outb(PORT + IEE16_ECTRL, IEE16_RESET_586); - - /* read the eeprom and checksum it, should == IEE16_ID */ - for (i = 0; i < 0x40; i++) - checksum += ee16_read_eeprom(sc, i); - - if (checksum != IEE16_ID) { - printf("ie%d: invalid eeprom checksum: %x\n", unit, checksum); - return (0); - } - /* - * Size and test the memory on the board. The size of the memory - * can be one of 16k, 32k, 48k or 64k. It can be located in the - * address range 0xC0000 to 0xEFFFF on 16k boundaries. - * - * If the size does not match the passed in memory allocation size - * issue a warning, but continue with the minimum of the two sizes. - */ - - switch (dvp->id_msize) { - case 65536: - case 32768: /* XXX Only support 32k and 64k right now */ - break; - case 16384: - case 49512: - default: - printf("ie%d: mapped memory size %d not supported\n", unit, - dvp->id_msize); - return (0); - break; /* NOTREACHED */ - } - - if ((kvtop(dvp->id_maddr) < 0xC0000) || - (kvtop(dvp->id_maddr) + sc->iosize > 0xF0000)) { - printf("ie%d: mapped memory location %p out of range\n", unit, - (void *)dvp->id_maddr); - return (0); - } - pg = (kvtop(dvp->id_maddr) & 0x3C000) >> 14; - adjust = IEE16_MCTRL_FMCS16 | (pg & 0x3) << 2; - decode = ((1 << (sc->iosize / 16384)) - 1) << pg; - edecode = ((~decode >> 4) & 0xF0) | (decode >> 8); - - /* ZZZ This should be checked against eeprom location 6, low byte */ - outb(PORT + IEE16_MEMDEC, decode & 0xFF); - /* ZZZ This should be checked against eeprom location 1, low byte */ - outb(PORT + IEE16_MCTRL, adjust); - /* ZZZ Now if I could find this one I would have it made */ - outb(PORT + IEE16_MPCTRL, (~decode & 0xFF)); - /* ZZZ I think this is location 6, high byte */ - outb(PORT + IEE16_MECTRL, edecode); /* XXX disable Exxx */ - - (void) kvtop(dvp->id_maddr); - - /* - * first prime the stupid bart DRAM controller so that it works, - * then zero out all of memory. - */ - bzero(sc->iomembot, 32); - bzero(sc->iomembot, sc->iosize); - - /* - * Get the encoded interrupt number from the EEPROM, check it - * against the passed in IRQ. Issue a warning if they do not match. - * Always use the passed in IRQ, not the one in the EEPROM. - */ - irq = ee16_read_eeprom(sc, IEE16_EEPROM_CONFIG1); - irq = (irq & IEE16_EEPROM_IRQ) >> IEE16_EEPROM_IRQ_SHIFT; - irq = irq_translate[irq]; - if (dvp->id_irq > 0) { - if (irq != dvp->id_irq) { - printf("ie%d: WARNING: board configured " - "at irq %u, using %u\n", - dvp->id_unit, dvp->id_irq, irq); - irq = dvp->id_unit; - } - } else { - dvp->id_irq = irq; - } - sc->irq_encoded = irq_encode[ffs(irq) - 1]; - - /* - * Get the hardware ethernet address from the EEPROM and save it in - * the softc for use by the 586 setup code. - */ - eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_HIGH); - sc->arpcom.ac_enaddr[1] = eaddrtemp & 0xFF; - sc->arpcom.ac_enaddr[0] = eaddrtemp >> 8; - eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_MID); - sc->arpcom.ac_enaddr[3] = eaddrtemp & 0xFF; - sc->arpcom.ac_enaddr[2] = eaddrtemp >> 8; - eaddrtemp = ee16_read_eeprom(sc, IEE16_EEPROM_ENET_LOW); - sc->arpcom.ac_enaddr[5] = eaddrtemp & 0xFF; - sc->arpcom.ac_enaddr[4] = eaddrtemp >> 8; - - /* disable the board interrupts */ - outb(PORT + IEE16_IRQ, sc->irq_encoded); - - /* enable loopback to keep bad packets off the wire */ - if (sc->hard_type == IE_EE16) { - bart_config = inb(PORT + IEE16_CONFIG); - bart_config |= IEE16_BART_LOOPBACK; - bart_config |= IEE16_BART_MCS16_TEST;/* inb doesn't get bit! */ - outb(PORT + IEE16_CONFIG, bart_config); - bart_config = inb(PORT + IEE16_CONFIG); - } - /* take the board out of reset state */ - outb(PORT + IEE16_ECTRL, 0); - DELAY(100); - - if (!check_ie_present(unit, dvp->id_maddr, sc->iosize)) - return (0); - - return (16); /* return the number of I/O ports */ -} - -/* - * Taken almost exactly from Bill's if_is.c, then modified beyond recognition. - */ -int -ieattach(struct isa_device *dvp) -{ - int factor; - int unit = dvp->id_unit; - struct ie_softc *ie = &ie_softc[unit]; - struct ifnet *ifp = &ie->arpcom.ac_if; - size_t allocsize; - - dvp->id_ointr = ieintr; - - /* - * based on the amount of memory we have, allocate our tx and rx - * resources. - */ - factor = dvp->id_msize / 16384; - ie->nframes = factor * NFRAMES; - ie->nrxbufs = factor * NRXBUFS; - ie->ntxbufs = factor * NTXBUFS; - - /* - * Since all of these guys are arrays of pointers, allocate as one - * big chunk and dole out accordingly. - */ - allocsize = sizeof(void *) * (ie->nframes - + (ie->nrxbufs * 2) - + (ie->ntxbufs * 3)); - ie->rframes = (volatile struct ie_recv_frame_desc **) malloc(allocsize, - M_DEVBUF, - M_NOWAIT); - if (ie->rframes == NULL) - return (0); - ie->rbuffs = - (volatile struct ie_recv_buf_desc **)&ie->rframes[ie->nframes]; - ie->cbuffs = (volatile u_char **)&ie->rbuffs[ie->nrxbufs]; - ie->xmit_cmds = - (volatile struct ie_xmit_cmd **)&ie->cbuffs[ie->nrxbufs]; - ie->xmit_buffs = - (volatile struct ie_xmit_buf **)&ie->xmit_cmds[ie->ntxbufs]; - ie->xmit_cbuffs = (volatile u_char **)&ie->xmit_buffs[ie->ntxbufs]; - - ifp->if_softc = ie; - ifp->if_unit = unit; - ifp->if_name = iedriver.name; - ifp->if_mtu = ETHERMTU; - printf("ie%d: <%s R%d> address %6D\n", unit, - ie_hardware_names[ie->hard_type], - ie->hard_vers + 1, - ie->arpcom.ac_enaddr, ":"); - - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; - ifp->if_output = ether_output; - ifp->if_start = iestart; - ifp->if_ioctl = ieioctl; - ifp->if_init = ieinit; - ifp->if_type = IFT_ETHER; - ifp->if_addrlen = 6; - ifp->if_hdrlen = 14; - - if (ie->hard_type == IE_EE16) - EVENTHANDLER_REGISTER(shutdown_post_sync, ee16_shutdown, - ie, SHUTDOWN_PRI_DEFAULT); - - bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header)); - - if_attach(ifp); - ether_ifattach(ifp); - return (1); -} - -/* - * What to do upon receipt of an interrupt. - */ -static void -ieintr(int unit) -{ - register struct ie_softc *ie = &ie_softc[unit]; - register u_short status; - - /* Clear the interrupt latch on the 3C507. */ - if (ie->hard_type == IE_3C507 - && (inb(PORT + IE507_CTRL) & EL_CTRL_INTL)) - outb(PORT + IE507_ICTRL, 1); - - /* disable interrupts on the EE16. */ - if (ie->hard_type == IE_EE16) - outb(PORT + IEE16_IRQ, ie->irq_encoded); - - status = ie->scb->ie_status; - -loop: - - /* Don't ack interrupts which we didn't receive */ - ie_ack(ie->scb, IE_ST_WHENCE & status, unit, ie->ie_chan_attn); - - if (status & (IE_ST_RECV | IE_ST_RNR)) { -#ifdef DEBUG - in_ierint++; - if (ie_debug & IED_RINT) - printf("ie%d: rint\n", unit); -#endif - ierint(unit, ie); -#ifdef DEBUG - in_ierint--; -#endif - } - if (status & IE_ST_DONE) { -#ifdef DEBUG - in_ietint++; - if (ie_debug & IED_TINT) - printf("ie%d: tint\n", unit); -#endif - ietint(unit, ie); -#ifdef DEBUG - in_ietint--; -#endif - } - if (status & IE_ST_RNR) { -#ifdef DEBUG - if (ie_debug & IED_RNR) - printf("ie%d: rnr\n", unit); -#endif - iernr(unit, ie); - } -#ifdef DEBUG - if ((status & IE_ST_ALLDONE) - && (ie_debug & IED_CNA)) - printf("ie%d: cna\n", unit); -#endif - - if ((status = ie->scb->ie_status) & IE_ST_WHENCE) - goto loop; - - /* Clear the interrupt latch on the 3C507. */ - if (ie->hard_type == IE_3C507) - outb(PORT + IE507_ICTRL, 1); - - /* enable interrupts on the EE16. */ - if (ie->hard_type == IE_EE16) - outb(PORT + IEE16_IRQ, ie->irq_encoded | IEE16_IRQ_ENABLE); - -} - -/* - * Process a received-frame interrupt. - */ -static int -ierint(int unit, struct ie_softc *ie) -{ - int i, status; - static int timesthru = 1024; - - i = ie->rfhead; - while (1) { - status = ie->rframes[i]->ie_fd_status; - - if ((status & IE_FD_COMPLETE) && (status & IE_FD_OK)) { - ie->arpcom.ac_if.if_ipackets++; - if (!--timesthru) { - ie->arpcom.ac_if.if_ierrors += - ie->scb->ie_err_crc + - ie->scb->ie_err_align + - ie->scb->ie_err_resource + - ie->scb->ie_err_overrun; - ie->scb->ie_err_crc = 0; - ie->scb->ie_err_align = 0; - ie->scb->ie_err_resource = 0; - ie->scb->ie_err_overrun = 0; - timesthru = 1024; - } - ie_readframe(unit, ie, i); - } else { - if (status & IE_FD_RNR) { - if (!(ie->scb->ie_status & IE_RU_READY)) { - ie->rframes[0]->ie_fd_next = - MK_16(MEM, ie->rbuffs[0]); - ie->scb->ie_recv_list = - MK_16(MEM, ie->rframes[0]); - command_and_wait(unit, IE_RU_START, - 0, 0); - } - } - break; - } - i = (i + 1) % ie->nframes; - } - return (0); -} - -/* - * Process a command-complete interrupt. These are only generated by - * the transmission of frames. This routine is deceptively simple, since - * most of the real work is done by iestart(). - */ -static int -ietint(int unit, struct ie_softc *ie) -{ - int status; - int i; - - ie->arpcom.ac_if.if_timer = 0; - ie->arpcom.ac_if.if_flags &= ~IFF_OACTIVE; - - for (i = 0; i < ie->xmit_count; i++) { - status = ie->xmit_cmds[i]->ie_xmit_status; - - if (status & IE_XS_LATECOLL) { - printf("ie%d: late collision\n", unit); - ie->arpcom.ac_if.if_collisions++; - ie->arpcom.ac_if.if_oerrors++; - } else if (status & IE_XS_NOCARRIER) { - printf("ie%d: no carrier\n", unit); - ie->arpcom.ac_if.if_oerrors++; - } else if (status & IE_XS_LOSTCTS) { - printf("ie%d: lost CTS\n", unit); - ie->arpcom.ac_if.if_oerrors++; - } else if (status & IE_XS_UNDERRUN) { - printf("ie%d: DMA underrun\n", unit); - ie->arpcom.ac_if.if_oerrors++; - } else if (status & IE_XS_EXCMAX) { - printf("ie%d: too many collisions\n", unit); - ie->arpcom.ac_if.if_collisions += 16; - ie->arpcom.ac_if.if_oerrors++; - } else { - ie->arpcom.ac_if.if_opackets++; - ie->arpcom.ac_if.if_collisions += status & IE_XS_MAXCOLL; - } - } - ie->xmit_count = 0; - - /* - * If multicast addresses were added or deleted while we were - * transmitting, ie_mc_reset() set the want_mcsetup flag indicating - * that we should do it. - */ - if (ie->want_mcsetup) { - mc_setup(unit, (v_caddr_t) ie->xmit_cbuffs[0], ie->scb); - ie->want_mcsetup = 0; - } - /* Wish I knew why this seems to be necessary... */ - ie->xmit_cmds[0]->ie_xmit_status |= IE_STAT_COMPL; - - iestart(&ie->arpcom.ac_if); - return (0); /* shouldn't be necessary */ -} - -/* - * Process a receiver-not-ready interrupt. I believe that we get these - * when there aren't enough buffers to go around. For now (FIXME), we - * just restart the receiver, and hope everything's ok. - */ -static int -iernr(int unit, struct ie_softc *ie) -{ -#ifdef doesnt_work - setup_rfa((v_caddr_t) ie->rframes[0], ie); - - ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]); - command_and_wait(unit, IE_RU_START, 0, 0); -#else - /* This doesn't work either, but it doesn't hang either. */ - command_and_wait(unit, IE_RU_DISABLE, 0, 0); /* just in case */ - setup_rfa((v_caddr_t) ie->rframes[0], ie); /* ignore cast-qual */ - - ie->scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]); - command_and_wait(unit, IE_RU_START, 0, 0); /* was ENABLE */ - -#endif - ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn); - - ie->arpcom.ac_if.if_ierrors++; - return (0); -} - -/* - * Compare two Ether/802 addresses for equality, inlined and - * unrolled for speed. I'd love to have an inline assembler - * version of this... - */ -static __inline int -ether_equal(u_char * one, u_char * two) -{ - if (one[0] != two[0]) - return (0); - if (one[1] != two[1]) - return (0); - if (one[2] != two[2]) - return (0); - if (one[3] != two[3]) - return (0); - if (one[4] != two[4]) - return (0); - if (one[5] != two[5]) - return (0); - return 1; -} - -/* - * Check for a valid address. to_bpf is filled in with one of the following: - * 0 -> BPF doesn't get this packet - * 1 -> BPF does get this packet - * 2 -> BPF does get this packet, but we don't - * Return value is true if the packet is for us, and false otherwise. - * - * This routine is a mess, but it's also critical that it be as fast - * as possible. It could be made cleaner if we can assume that the - * only client which will fiddle with IFF_PROMISC is BPF. This is - * probably a good assumption, but we do not make it here. (Yet.) - */ -static __inline int -check_eh(struct ie_softc * ie, struct ether_header * eh, int *to_bpf) -{ - int i; - - switch (ie->promisc) { - case IFF_ALLMULTI: - /* - * Receiving all multicasts, but no unicasts except those - * destined for us. - */ - /* BPF gets this packet if anybody cares */ - *to_bpf = (ie->arpcom.ac_if.if_bpf != 0); - if (eh->ether_dhost[0] & 1) { - return (1); - } - if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr)) - return (1); - return (0); - - case IFF_PROMISC: - /* - * Receiving all packets. These need to be passed on to - * BPF. - */ - *to_bpf = (ie->arpcom.ac_if.if_bpf != 0); - /* If for us, accept and hand up to BPF */ - if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr)) - return (1); - - if (*to_bpf) - *to_bpf = 2; /* we don't need to see it */ - - /* - * Not a multicast, so BPF wants to see it but we don't. - */ - if (!(eh->ether_dhost[0] & 1)) - return (1); - - /* - * If it's one of our multicast groups, accept it and pass - * it up. - */ - for (i = 0; i < ie->mcast_count; i++) { - if (ether_equal(eh->ether_dhost, - (u_char *)&ie->mcast_addrs[i])) { - if (*to_bpf) - *to_bpf = 1; - return (1); - } - } - return (1); - - case IFF_ALLMULTI | IFF_PROMISC: - /* - * Acting as a multicast router, and BPF running at the same - * time. Whew! (Hope this is a fast machine...) - */ - *to_bpf = (ie->arpcom.ac_if.if_bpf != 0); - /* We want to see multicasts. */ - if (eh->ether_dhost[0] & 1) - return (1); - - /* We want to see our own packets */ - if (ether_equal(eh->ether_dhost, ie->arpcom.ac_enaddr)) - return (1); - - /* Anything else goes to BPF but nothing else. */ - if (*to_bpf) - *to_bpf = 2; - return (1); - - default: - /* - * Only accept unicast packets destined for us, or - * multicasts for groups that we belong to. For now, we - * assume that the '586 will only return packets that we - * asked it for. This isn't strictly true (it uses hashing - * for the multicast filter), but it will do in this case, - * and we want to get out of here as quickly as possible. - */ - *to_bpf = (ie->arpcom.ac_if.if_bpf != 0); - return (1); - } - return (0); -} - -/* - * We want to isolate the bits that have meaning... This assumes that - * IE_RBUF_SIZE is an even power of two. If somehow the act_len exceeds - * the size of the buffer, then we are screwed anyway. - */ -static __inline int -ie_buflen(struct ie_softc * ie, int head) -{ - return (ie->rbuffs[head]->ie_rbd_actual - & (IE_RBUF_SIZE | (IE_RBUF_SIZE - 1))); -} - -static __inline int -ie_packet_len(int unit, struct ie_softc * ie) -{ - int i; - int head = ie->rbhead; - int acc = 0; - - do { - if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) { -#ifdef DEBUG - print_rbd(ie->rbuffs[ie->rbhead]); -#endif - log(LOG_ERR, - "ie%d: receive descriptors out of sync at %d\n", - unit, ie->rbhead); - iereset(unit); - return (-1); - } - i = ie->rbuffs[head]->ie_rbd_actual & IE_RBD_LAST; - - acc += ie_buflen(ie, head); - head = (head + 1) % ie->nrxbufs; - } while (!i); - - return (acc); -} - -/* - * Read data off the interface, and turn it into an mbuf chain. - * - * This code is DRAMATICALLY different from the previous version; this - * version tries to allocate the entire mbuf chain up front, given the - * length of the data available. This enables us to allocate mbuf - * clusters in many situations where before we would have had a long - * chain of partially-full mbufs. This should help to speed up the - * operation considerably. (Provided that it works, of course.) - */ -static __inline int -ieget(int unit, struct ie_softc *ie, struct mbuf **mp, - struct ether_header *ehp, int *to_bpf) -{ - struct mbuf *m, *top, **mymp; - int i; - int offset; - int totlen, resid; - int thismboff; - int head; - - totlen = ie_packet_len(unit, ie); - if (totlen <= 0) - return (-1); - - i = ie->rbhead; - - /* - * Snarf the Ethernet header. - */ - bcopy((v_caddr_t) ie->cbuffs[i], (caddr_t) ehp, sizeof *ehp); - /* ignore cast-qual warning here */ - - /* - * As quickly as possible, check if this packet is for us. If not, - * don't waste a single cycle copying the rest of the packet in. - * This is only a consideration when FILTER is defined; i.e., when - * we are either running BPF or doing multicasting. - */ - if (!check_eh(ie, ehp, to_bpf)) { - ie_drop_packet_buffer(unit, ie); - ie->arpcom.ac_if.if_ierrors--; /* just this case, it's not an - * error - */ - return (-1); - } - totlen -= (offset = sizeof *ehp); - - MGETHDR(*mp, M_DONTWAIT, MT_DATA); - if (!*mp) { - ie_drop_packet_buffer(unit, ie); - return (-1); - } - m = *mp; - m->m_pkthdr.rcvif = &ie->arpcom.ac_if; - m->m_len = MHLEN; - resid = m->m_pkthdr.len = totlen; - top = 0; - mymp = ⊤ - - /* - * This loop goes through and allocates mbufs for all the data we - * will be copying in. It does not actually do the copying yet. - */ - do { /* while(resid > 0) */ - /* - * Try to allocate an mbuf to hold the data that we have. - * If we already allocated one, just get another one and - * stick it on the end (eventually). If we don't already - * have one, try to allocate an mbuf cluster big enough to - * hold the whole packet, if we think it's reasonable, or a - * single mbuf which may or may not be big enough. Got that? - */ - if (top) { - MGET(m, M_DONTWAIT, MT_DATA); - if (!m) { - m_freem(top); - ie_drop_packet_buffer(unit, ie); - return (-1); - } - m->m_len = MLEN; - } - if (resid >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - m->m_len = min(resid, MCLBYTES); - } else { - if (resid < m->m_len) { - if (!top && resid + max_linkhdr <= m->m_len) - m->m_data += max_linkhdr; - m->m_len = resid; - } - } - resid -= m->m_len; - *mymp = m; - mymp = &m->m_next; - } while (resid > 0); - - resid = totlen; - m = top; - thismboff = 0; - head = ie->rbhead; - - /* - * Now we take the mbuf chain (hopefully only one mbuf most of the - * time) and stuff the data into it. There are no possible failures - * at or after this point. - */ - while (resid > 0) { /* while there's stuff left */ - int thislen = ie_buflen(ie, head) - offset; - - /* - * If too much data for the current mbuf, then fill the - * current one up, go to the next one, and try again. - */ - if (thislen > m->m_len - thismboff) { - int newlen = m->m_len - thismboff; - - bcopy((v_caddr_t) (ie->cbuffs[head] + offset), - mtod(m, v_caddr_t) +thismboff, (unsigned) newlen); - /* ignore cast-qual warning */ - m = m->m_next; - thismboff = 0; /* new mbuf, so no offset */ - offset += newlen; /* we are now this far into - * the packet */ - resid -= newlen; /* so there is this much left - * to get */ - continue; - } - /* - * If there is more than enough space in the mbuf to hold - * the contents of this buffer, copy everything in, advance - * pointers, and so on. - */ - if (thislen < m->m_len - thismboff) { - bcopy((v_caddr_t) (ie->cbuffs[head] + offset), - mtod(m, caddr_t) +thismboff, (unsigned) thislen); - thismboff += thislen; /* we are this far into the - * mbuf */ - resid -= thislen; /* and this much is left */ - goto nextbuf; - } - /* - * Otherwise, there is exactly enough space to put this - * buffer's contents into the current mbuf. Do the - * combination of the above actions. - */ - bcopy((v_caddr_t) (ie->cbuffs[head] + offset), - mtod(m, caddr_t) + thismboff, (unsigned) thislen); - m = m->m_next; - thismboff = 0; /* new mbuf, start at the beginning */ - resid -= thislen; /* and we are this far through */ - - /* - * Advance all the pointers. We can get here from either of - * the last two cases, but never the first. - */ -nextbuf: - offset = 0; - ie->rbuffs[head]->ie_rbd_actual = 0; - ie->rbuffs[head]->ie_rbd_length |= IE_RBD_LAST; - ie->rbhead = head = (head + 1) % ie->nrxbufs; - ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; - ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs; - } - - /* - * Unless something changed strangely while we were doing the copy, - * we have now copied everything in from the shared memory. This - * means that we are done. - */ - return (0); -} - -/* - * Read frame NUM from unit UNIT (pre-cached as IE). - * - * This routine reads the RFD at NUM, and copies in the buffers from - * the list of RBD, then rotates the RBD and RFD lists so that the receiver - * doesn't start complaining. Trailers are DROPPED---there's no point - * in wasting time on confusing code to deal with them. Hopefully, - * this machine will never ARP for trailers anyway. - */ -static void -ie_readframe(int unit, struct ie_softc *ie, int num/* frame number to read */) -{ - struct ie_recv_frame_desc rfd; - struct mbuf *m = 0; - struct ether_header eh; - - int bpf_gets_it = 0; - - bcopy((v_caddr_t) (ie->rframes[num]), &rfd, - sizeof(struct ie_recv_frame_desc)); - - /* - * Immediately advance the RFD list, since we we have copied ours - * now. - */ - ie->rframes[num]->ie_fd_status = 0; - ie->rframes[num]->ie_fd_last |= IE_FD_LAST; - ie->rframes[ie->rftail]->ie_fd_last &= ~IE_FD_LAST; - ie->rftail = (ie->rftail + 1) % ie->nframes; - ie->rfhead = (ie->rfhead + 1) % ie->nframes; - - if (rfd.ie_fd_status & IE_FD_OK) { - if (ieget(unit, ie, &m, &eh, &bpf_gets_it)) { - ie->arpcom.ac_if.if_ierrors++; /* this counts as an - * error */ - return; - } - } -#ifdef DEBUG - if (ie_debug & IED_READFRAME) { - printf("ie%d: frame from ether %6D type %x\n", unit, - eh.ether_shost, ":", (unsigned) eh.ether_type); - } - if (ntohs(eh.ether_type) > ETHERTYPE_TRAIL - && ntohs(eh.ether_type) < (ETHERTYPE_TRAIL + ETHERTYPE_NTRAILER)) - printf("received trailer!\n"); -#endif - - if (!m) - return; - - if (last_not_for_us) { - m_freem(last_not_for_us); - last_not_for_us = 0; - } - /* - * Check for a BPF filter; if so, hand it up. Note that we have to - * stick an extra mbuf up front, because bpf_mtap expects to have - * the ether header at the front. It doesn't matter that this - * results in an ill-formatted mbuf chain, since BPF just looks at - * the data. (It doesn't try to free the mbuf, tho' it will make a - * copy for tcpdump.) - */ - if (bpf_gets_it) { - struct mbuf m0; - - m0.m_len = sizeof eh; - m0.m_data = (caddr_t)&eh; - m0.m_next = m; - - /* Pass it up */ - bpf_mtap(&ie->arpcom.ac_if, &m0); - } - /* - * A signal passed up from the filtering code indicating that the - * packet is intended for BPF but not for the protocol machinery. We - * can save a few cycles by not handing it off to them. - */ - if (bpf_gets_it == 2) { - last_not_for_us = m; - return; - } - /* - * In here there used to be code to check destination addresses upon - * receipt of a packet. We have deleted that code, and replaced it - * with code to check the address much earlier in the cycle, before - * copying the data in; this saves us valuable cycles when operating - * as a multicast router or when using BPF. - */ - - /* - * Finally pass this packet up to higher layers. - */ - ether_input(&ie->arpcom.ac_if, &eh, m); -} - -static void -ie_drop_packet_buffer(int unit, struct ie_softc * ie) -{ - int i; - - do { - /* - * This means we are somehow out of sync. So, we reset the - * adapter. - */ - if (!(ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_USED)) { -#ifdef DEBUG - print_rbd(ie->rbuffs[ie->rbhead]); -#endif - log(LOG_ERR, "ie%d: receive descriptors out of sync at %d\n", - unit, ie->rbhead); - iereset(unit); - return; - } - i = ie->rbuffs[ie->rbhead]->ie_rbd_actual & IE_RBD_LAST; - - ie->rbuffs[ie->rbhead]->ie_rbd_length |= IE_RBD_LAST; - ie->rbuffs[ie->rbhead]->ie_rbd_actual = 0; - ie->rbhead = (ie->rbhead + 1) % ie->nrxbufs; - ie->rbuffs[ie->rbtail]->ie_rbd_length &= ~IE_RBD_LAST; - ie->rbtail = (ie->rbtail + 1) % ie->nrxbufs; - } while (!i); -} - - -/* - * Start transmission on an interface. - */ -static void -iestart(struct ifnet *ifp) -{ - struct ie_softc *ie = ifp->if_softc; - struct mbuf *m0, *m; - volatile unsigned char *buffer; - u_short len; - - /* - * This is not really volatile, in this routine, but it makes gcc - * happy. - */ - volatile u_short *bptr = &ie->scb->ie_command_list; - - if (!(ifp->if_flags & IFF_RUNNING)) - return; - if (ifp->if_flags & IFF_OACTIVE) - return; - - do { - IF_DEQUEUE(&ie->arpcom.ac_if.if_snd, m); - if (!m) - break; - - buffer = ie->xmit_cbuffs[ie->xmit_count]; - len = 0; - - for (m0 = m; m && len < IE_BUF_LEN; m = m->m_next) { - bcopy(mtod(m, caddr_t), buffer, m->m_len); - buffer += m->m_len; - len += m->m_len; - } - - m_freem(m0); - len = max(len, ETHER_MIN_LEN); - - /* - * See if bpf is listening on this interface, let it see the - * packet before we commit it to the wire. - */ - if (ie->arpcom.ac_if.if_bpf) - bpf_tap(&ie->arpcom.ac_if, - (void *)ie->xmit_cbuffs[ie->xmit_count], len); - - ie->xmit_buffs[ie->xmit_count]->ie_xmit_flags = - IE_XMIT_LAST|len; - ie->xmit_buffs[ie->xmit_count]->ie_xmit_next = 0xffff; - ie->xmit_buffs[ie->xmit_count]->ie_xmit_buf = - MK_24(ie->iomem, ie->xmit_cbuffs[ie->xmit_count]); - - ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_cmd = IE_CMD_XMIT; - ie->xmit_cmds[ie->xmit_count]->ie_xmit_status = 0; - ie->xmit_cmds[ie->xmit_count]->ie_xmit_desc = - MK_16(ie->iomem, ie->xmit_buffs[ie->xmit_count]); - - *bptr = MK_16(ie->iomem, ie->xmit_cmds[ie->xmit_count]); - bptr = &ie->xmit_cmds[ie->xmit_count]->com.ie_cmd_link; - ie->xmit_count++; - } while (ie->xmit_count < ie->ntxbufs); - - /* - * If we queued up anything for transmission, send it. - */ - if (ie->xmit_count) { - ie->xmit_cmds[ie->xmit_count - 1]->com.ie_cmd_cmd |= - IE_CMD_LAST | IE_CMD_INTR; - - /* - * By passing the command pointer as a null, we tell - * command_and_wait() to pretend that this isn't an action - * command. I wish I understood what was happening here. - */ - command_and_wait(ifp->if_unit, IE_CU_START, 0, 0); - ifp->if_flags |= IFF_OACTIVE; - } - return; -} - -/* - * Check to see if there's an 82586 out there. - */ -static int -check_ie_present(int unit, caddr_t where, unsigned size) -{ - volatile struct ie_sys_conf_ptr *scp; - volatile struct ie_int_sys_conf_ptr *iscp; - volatile struct ie_sys_ctl_block *scb; - u_long realbase; - int s; - - s = splimp(); - - realbase = (uintptr_t) where + size - (1 << 24); - - scp = (volatile struct ie_sys_conf_ptr *) (uintptr_t) - (realbase + IE_SCP_ADDR); - bzero((volatile char *) scp, sizeof *scp); - - /* - * First we put the ISCP at the bottom of memory; this tests to make - * sure that our idea of the size of memory is the same as the - * controller's. This is NOT where the ISCP will be in normal - * operation. - */ - iscp = (volatile struct ie_int_sys_conf_ptr *) where; - bzero((volatile char *)iscp, sizeof *iscp); - - scb = (volatile struct ie_sys_ctl_block *) where; - bzero((volatile char *)scb, sizeof *scb); - - scp->ie_bus_use = ie_softc[unit].bus_use; /* 8-bit or 16-bit */ - scp->ie_iscp_ptr = (caddr_t) (uintptr_t) - ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase); - - iscp->ie_busy = 1; - iscp->ie_scb_offset = MK_16(realbase, scb) + 256; - - (*ie_softc[unit].ie_reset_586) (unit); - (*ie_softc[unit].ie_chan_attn) (unit); - - DELAY(100); /* wait a while... */ - - if (iscp->ie_busy) { - splx(s); - return (0); - } - /* - * Now relocate the ISCP to its real home, and reset the controller - * again. - */ - iscp = (void *) Align((caddr_t) (uintptr_t) - (realbase + IE_SCP_ADDR - - sizeof(struct ie_int_sys_conf_ptr))); - bzero((volatile char *) iscp, sizeof *iscp); /* ignore cast-qual */ - - scp->ie_iscp_ptr = (caddr_t) (uintptr_t) - ((volatile char *) iscp - (volatile char *) (uintptr_t) realbase); - - iscp->ie_busy = 1; - iscp->ie_scb_offset = MK_16(realbase, scb); - - (*ie_softc[unit].ie_reset_586) (unit); - (*ie_softc[unit].ie_chan_attn) (unit); - - DELAY(100); - - if (iscp->ie_busy) { - splx(s); - return (0); - } - ie_softc[unit].iosize = size; - ie_softc[unit].iomem = (caddr_t) (uintptr_t) realbase; - - ie_softc[unit].iscp = iscp; - ie_softc[unit].scb = scb; - - /* - * Acknowledge any interrupts we may have caused... - */ - ie_ack(scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn); - splx(s); - - return (1); -} - -/* - * Divine the memory size of ie board UNIT. - * Better hope there's nothing important hiding just below the ie card... - */ -static void -find_ie_mem_size(int unit) -{ - unsigned size; - - ie_softc[unit].iosize = 0; - - for (size = 65536; size >= 8192; size -= 8192) { - if (check_ie_present(unit, ie_softc[unit].iomembot, size)) { - return; - } - } - - return; -} - -void -el_reset_586(int unit) -{ - outb(PORT + IE507_CTRL, EL_CTRL_RESET); - DELAY(100); - outb(PORT + IE507_CTRL, EL_CTRL_NORMAL); - DELAY(100); -} - -void -sl_reset_586(int unit) -{ - outb(PORT + IEATT_RESET, 0); -} - -void -ee16_reset_586(int unit) -{ - outb(PORT + IEE16_ECTRL, IEE16_RESET_586); - DELAY(100); - outb(PORT + IEE16_ECTRL, 0); - DELAY(100); -} - -void -el_chan_attn(int unit) -{ - outb(PORT + IE507_ATTN, 1); -} - -void -sl_chan_attn(int unit) -{ - outb(PORT + IEATT_ATTN, 0); -} - -void -ee16_chan_attn(int unit) -{ - outb(PORT + IEE16_ATTN, 0); -} - -u_short -ee16_read_eeprom(struct ie_softc *sc, int location) -{ - int ectrl, edata; - - ectrl = inb(sc->port + IEE16_ECTRL); - ectrl &= IEE16_ECTRL_MASK; - ectrl |= IEE16_ECTRL_EECS; - outb(sc->port + IEE16_ECTRL, ectrl); - - ee16_eeprom_outbits(sc, IEE16_EEPROM_READ, IEE16_EEPROM_OPSIZE1); - ee16_eeprom_outbits(sc, location, IEE16_EEPROM_ADDR_SIZE); - edata = ee16_eeprom_inbits(sc); - ectrl = inb(sc->port + IEE16_ECTRL); - ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EEDI | IEE16_ECTRL_EECS); - outb(sc->port + IEE16_ECTRL, ectrl); - ee16_eeprom_clock(sc, 1); - ee16_eeprom_clock(sc, 0); - return edata; -} - -void -ee16_eeprom_outbits(struct ie_softc *sc, int edata, int count) -{ - int ectrl, i; - - ectrl = inb(sc->port + IEE16_ECTRL); - ectrl &= ~IEE16_RESET_ASIC; - for (i = count - 1; i >= 0; i--) { - ectrl &= ~IEE16_ECTRL_EEDI; - if (edata & (1 << i)) { - ectrl |= IEE16_ECTRL_EEDI; - } - outb(sc->port + IEE16_ECTRL, ectrl); - DELAY(1); /* eeprom data must be setup for 0.4 uSec */ - ee16_eeprom_clock(sc, 1); - ee16_eeprom_clock(sc, 0); - } - ectrl &= ~IEE16_ECTRL_EEDI; - outb(sc->port + IEE16_ECTRL, ectrl); - DELAY(1); /* eeprom data must be held for 0.4 uSec */ -} - -int -ee16_eeprom_inbits(struct ie_softc *sc) -{ - int ectrl, edata, i; - - ectrl = inb(sc->port + IEE16_ECTRL); - ectrl &= ~IEE16_RESET_ASIC; - for (edata = 0, i = 0; i < 16; i++) { - edata = edata << 1; - ee16_eeprom_clock(sc, 1); - ectrl = inb(sc->port + IEE16_ECTRL); - if (ectrl & IEE16_ECTRL_EEDO) { - edata |= 1; - } - ee16_eeprom_clock(sc, 0); - } - return (edata); -} - -void -ee16_eeprom_clock(struct ie_softc *sc, int state) -{ - int ectrl; - - ectrl = inb(sc->port + IEE16_ECTRL); - ectrl &= ~(IEE16_RESET_ASIC | IEE16_ECTRL_EESK); - if (state) { - ectrl |= IEE16_ECTRL_EESK; - } - outb(sc->port + IEE16_ECTRL, ectrl); - DELAY(9); /* EESK must be stable for 8.38 uSec */ -} - -static __inline void -ee16_interrupt_enable(struct ie_softc *sc) -{ - DELAY(100); - outb(sc->port + IEE16_IRQ, sc->irq_encoded | IEE16_IRQ_ENABLE); - DELAY(100); -} - -void -sl_read_ether(int unit, unsigned char addr[6]) -{ - int i; - - for (i = 0; i < 6; i++) - addr[i] = inb(PORT + i); -} - - -static void -iereset(int unit) -{ - int s = splimp(); - - if (unit >= NIE) { - splx(s); - return; - } - printf("ie%d: reset\n", unit); - ie_softc[unit].arpcom.ac_if.if_flags &= ~IFF_UP; - ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0); - - /* - * Stop i82586 dead in its tracks. - */ - if (command_and_wait(unit, IE_RU_ABORT | IE_CU_ABORT, 0, 0)) - printf("ie%d: abort commands timed out\n", unit); - - if (command_and_wait(unit, IE_RU_DISABLE | IE_CU_STOP, 0, 0)) - printf("ie%d: disable commands timed out\n", unit); - -#ifdef notdef - if (!check_ie_present(unit, ie_softc[unit].iomembot, - e_softc[unit].iosize)) - panic("ie disappeared!"); -#endif - - ie_softc[unit].arpcom.ac_if.if_flags |= IFF_UP; - ieioctl(&ie_softc[unit].arpcom.ac_if, SIOCSIFFLAGS, 0); - - splx(s); - return; -} - -/* - * This is called if we time out. - */ -static void -chan_attn_timeout(void *rock) -{ - *(int *) rock = 1; -} - -/* - * Send a command to the controller and wait for it to either - * complete or be accepted, depending on the command. If the - * command pointer is null, then pretend that the command is - * not an action command. If the command pointer is not null, - * and the command is an action command, wait for - * ((volatile struct ie_cmd_common *)pcmd)->ie_cmd_status & MASK - * to become true. - */ -static int -command_and_wait(int unit, int cmd, volatile void *pcmd, int mask) -{ - volatile struct ie_cmd_common *cc = pcmd; - volatile int timedout = 0; - struct callout_handle ch; - - ie_softc[unit].scb->ie_command = (u_short) cmd; - - if (IE_ACTION_COMMAND(cmd) && pcmd) { - (*ie_softc[unit].ie_chan_attn) (unit); - - /* - * According to the packet driver, the minimum timeout - * should be .369 seconds, which we round up to .37. - */ - ch = timeout(chan_attn_timeout, (caddr_t)&timedout, - 37 * hz / 100); - /* ignore cast-qual */ - - /* - * Now spin-lock waiting for status. This is not a very - * nice thing to do, but I haven't figured out how, or - * indeed if, we can put the process waiting for action to - * sleep. (We may be getting called through some other - * timeout running in the kernel.) - */ - while (1) { - if ((cc->ie_cmd_status & mask) || timedout) - break; - } - - untimeout(chan_attn_timeout, (caddr_t)&timedout, ch); - /* ignore cast-qual */ - - return (timedout); - } else { - - /* - * Otherwise, just wait for the command to be accepted. - */ - (*ie_softc[unit].ie_chan_attn) (unit); - - while (ie_softc[unit].scb->ie_command); /* spin lock */ - - return (0); - } -} - -/* - * Run the time-domain reflectometer... - */ -static void -run_tdr(int unit, volatile struct ie_tdr_cmd *cmd) -{ - int result; - - cmd->com.ie_cmd_status = 0; - cmd->com.ie_cmd_cmd = IE_CMD_TDR | IE_CMD_LAST; - cmd->com.ie_cmd_link = 0xffff; - cmd->ie_tdr_time = 0; - - ie_softc[unit].scb->ie_command_list = MK_16(MEM, cmd); - cmd->ie_tdr_time = 0; - - if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL)) - result = 0x2000; - else - result = cmd->ie_tdr_time; - - ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, - ie_softc[unit].ie_chan_attn); - - if (result & IE_TDR_SUCCESS) - return; - - if (result & IE_TDR_XCVR) { - printf("ie%d: transceiver problem\n", unit); - } else if (result & IE_TDR_OPEN) { - printf("ie%d: TDR detected an open %d clocks away\n", unit, - result & IE_TDR_TIME); - } else if (result & IE_TDR_SHORT) { - printf("ie%d: TDR detected a short %d clocks away\n", unit, - result & IE_TDR_TIME); - } else { - printf("ie%d: TDR returned unknown status %x\n", unit, result); - } -} - -static void -start_receiver(int unit) -{ - int s = splimp(); - - ie_softc[unit].scb->ie_recv_list = MK_16(MEM, ie_softc[unit].rframes[0]); - command_and_wait(unit, IE_RU_START, 0, 0); - - ie_ack(ie_softc[unit].scb, IE_ST_WHENCE, unit, ie_softc[unit].ie_chan_attn); - - splx(s); -} - -/* - * Here is a helper routine for iernr() and ieinit(). This sets up - * the RFA. - */ -static v_caddr_t -setup_rfa(v_caddr_t ptr, struct ie_softc * ie) -{ - volatile struct ie_recv_frame_desc *rfd = (volatile void *)ptr; - volatile struct ie_recv_buf_desc *rbd; - int i; - int unit = ie - &ie_softc[0]; - - /* First lay them out */ - for (i = 0; i < ie->nframes; i++) { - ie->rframes[i] = rfd; - bzero((volatile char *) rfd, sizeof *rfd); /* ignore cast-qual */ - rfd++; - } - - ptr = Alignvol(rfd); /* ignore cast-qual */ - - /* Now link them together */ - for (i = 0; i < ie->nframes; i++) { - ie->rframes[i]->ie_fd_next = - MK_16(MEM, ie->rframes[(i + 1) % ie->nframes]); - } - - /* Finally, set the EOL bit on the last one. */ - ie->rframes[ie->nframes - 1]->ie_fd_last |= IE_FD_LAST; - - /* - * Now lay out some buffers for the incoming frames. Note that we - * set aside a bit of slop in each buffer, to make sure that we have - * enough space to hold a single frame in every buffer. - */ - rbd = (volatile void *) ptr; - - for (i = 0; i < ie->nrxbufs; i++) { - ie->rbuffs[i] = rbd; - bzero((volatile char *)rbd, sizeof *rbd); - ptr = Alignvol(ptr + sizeof *rbd); - rbd->ie_rbd_length = IE_RBUF_SIZE; - rbd->ie_rbd_buffer = MK_24(MEM, ptr); - ie->cbuffs[i] = (volatile void *) ptr; - ptr += IE_RBUF_SIZE; - rbd = (volatile void *) ptr; - } - - /* Now link them together */ - for (i = 0; i < ie->nrxbufs; i++) { - ie->rbuffs[i]->ie_rbd_next = - MK_16(MEM, ie->rbuffs[(i + 1) % ie->nrxbufs]); - } - - /* Tag EOF on the last one */ - ie->rbuffs[ie->nrxbufs - 1]->ie_rbd_length |= IE_RBD_LAST; - - /* - * We use the head and tail pointers on receive to keep track of the - * order in which RFDs and RBDs are used. - */ - ie->rfhead = 0; - ie->rftail = ie->nframes - 1; - ie->rbhead = 0; - ie->rbtail = ie->nrxbufs - 1; - - ie->scb->ie_recv_list = MK_16(MEM, ie->rframes[0]); - ie->rframes[0]->ie_fd_buf_desc = MK_16(MEM, ie->rbuffs[0]); - - ptr = Alignvol(ptr); - return (ptr); -} - -/* - * Run the multicast setup command. - * Call at splimp(). - */ -static int -mc_setup(int unit, v_caddr_t ptr, - volatile struct ie_sys_ctl_block * scb) -{ - struct ie_softc *ie = &ie_softc[unit]; - volatile struct ie_mcast_cmd *cmd = (volatile void *) ptr; - - cmd->com.ie_cmd_status = 0; - cmd->com.ie_cmd_cmd = IE_CMD_MCAST | IE_CMD_LAST; - cmd->com.ie_cmd_link = 0xffff; - - /* ignore cast-qual */ - bcopy((v_caddr_t) ie->mcast_addrs, (v_caddr_t) cmd->ie_mcast_addrs, - ie->mcast_count * sizeof *ie->mcast_addrs); - - cmd->ie_mcast_bytes = ie->mcast_count * 6; /* grrr... */ - - scb->ie_command_list = MK_16(MEM, cmd); - if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL) - || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { - printf("ie%d: multicast address setup command failed\n", unit); - return (0); - } - return (1); -} - -/* - * This routine takes the environment generated by check_ie_present() - * and adds to it all the other structures we need to operate the adapter. - * This includes executing the CONFIGURE, IA-SETUP, and MC-SETUP commands, - * starting the receiver unit, and clearing interrupts. - * - * THIS ROUTINE MUST BE CALLED AT splimp() OR HIGHER. - */ -static void -ieinit(xsc) - void *xsc; -{ - struct ie_softc *ie = xsc; - volatile struct ie_sys_ctl_block *scb = ie->scb; - v_caddr_t ptr; - int i; - int unit = ie->unit; - - ptr = Alignvol((volatile char *) scb + sizeof *scb); - - /* - * Send the configure command first. - */ - { - volatile struct ie_config_cmd *cmd = (volatile void *) ptr; - - ie_setup_config(cmd, ie->promisc, - ie->hard_type == IE_STARLAN10); - cmd->com.ie_cmd_status = 0; - cmd->com.ie_cmd_cmd = IE_CMD_CONFIG | IE_CMD_LAST; - cmd->com.ie_cmd_link = 0xffff; - - scb->ie_command_list = MK_16(MEM, cmd); - - if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL) - || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { - printf("ie%d: configure command failed\n", unit); - return; - } - } - /* - * Now send the Individual Address Setup command. - */ - { - volatile struct ie_iasetup_cmd *cmd = (volatile void *) ptr; - - cmd->com.ie_cmd_status = 0; - cmd->com.ie_cmd_cmd = IE_CMD_IASETUP | IE_CMD_LAST; - cmd->com.ie_cmd_link = 0xffff; - - bcopy((volatile char *)ie_softc[unit].arpcom.ac_enaddr, - (volatile char *)&cmd->ie_address, sizeof cmd->ie_address); - scb->ie_command_list = MK_16(MEM, cmd); - if (command_and_wait(unit, IE_CU_START, cmd, IE_STAT_COMPL) - || !(cmd->com.ie_cmd_status & IE_STAT_OK)) { - printf("ie%d: individual address " - "setup command failed\n", unit); - return; - } - } - - /* - * Now run the time-domain reflectometer. - */ - run_tdr(unit, (volatile void *) ptr); - - /* - * Acknowledge any interrupts we have generated thus far. - */ - ie_ack(ie->scb, IE_ST_WHENCE, unit, ie->ie_chan_attn); - - /* - * Set up the RFA. - */ - ptr = setup_rfa(ptr, ie); - - /* - * Finally, the transmit command and buffer are the last little bit - * of work. - */ - - /* transmit command buffers */ - for (i = 0; i < ie->ntxbufs; i++) { - ie->xmit_cmds[i] = (volatile void *) ptr; - ptr += sizeof *ie->xmit_cmds[i]; - ptr = Alignvol(ptr); - ie->xmit_buffs[i] = (volatile void *)ptr; - ptr += sizeof *ie->xmit_buffs[i]; - ptr = Alignvol(ptr); - } - - /* transmit buffers */ - for (i = 0; i < ie->ntxbufs - 1; i++) { - ie->xmit_cbuffs[i] = (volatile void *)ptr; - ptr += IE_BUF_LEN; - ptr = Alignvol(ptr); - } - ie->xmit_cbuffs[ie->ntxbufs - 1] = (volatile void *) ptr; - - for (i = 1; i < ie->ntxbufs; i++) { - bzero((v_caddr_t) ie->xmit_cmds[i], sizeof *ie->xmit_cmds[i]); - bzero((v_caddr_t) ie->xmit_buffs[i], sizeof *ie->xmit_buffs[i]); - } - - /* - * This must be coordinated with iestart() and ietint(). - */ - ie->xmit_cmds[0]->ie_xmit_status = IE_STAT_COMPL; - - /* take the ee16 out of loopback */ - if (ie->hard_type == IE_EE16) { - u_int8_t bart_config; - - bart_config = inb(PORT + IEE16_CONFIG); - bart_config &= ~IEE16_BART_LOOPBACK; - /* inb doesn't get bit! */ - bart_config |= IEE16_BART_MCS16_TEST; - outb(PORT + IEE16_CONFIG, bart_config); - ee16_interrupt_enable(ie); - ee16_chan_attn(unit); - } - ie->arpcom.ac_if.if_flags |= IFF_RUNNING; /* tell higher levels - * we're here */ - start_receiver(unit); - - return; -} - -static void -ie_stop(int unit) -{ - command_and_wait(unit, IE_RU_DISABLE, 0, 0); -} - -static int -ieioctl(struct ifnet *ifp, u_long command, caddr_t data) -{ - int s, error = 0; - - s = splimp(); - - switch (command) { - case SIOCSIFADDR: - case SIOCGIFADDR: - case SIOCSIFMTU: - error = ether_ioctl(ifp, command, data); - break; - - case SIOCSIFFLAGS: - /* - * Note that this device doesn't have an "all multicast" - * mode, so we must turn on promiscuous mode and do the - * filtering manually. - */ - if ((ifp->if_flags & IFF_UP) == 0 && - (ifp->if_flags & IFF_RUNNING)) { - ifp->if_flags &= ~IFF_RUNNING; - ie_stop(ifp->if_unit); - } else if ((ifp->if_flags & IFF_UP) && - (ifp->if_flags & IFF_RUNNING) == 0) { - ie_softc[ifp->if_unit].promisc = - ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); - ieinit(ifp->if_softc); - } else if (ie_softc[ifp->if_unit].promisc ^ - (ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI))) { - ie_softc[ifp->if_unit].promisc = - ifp->if_flags & (IFF_PROMISC | IFF_ALLMULTI); - ieinit(ifp->if_softc); - } - break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - /* - * Update multicast listeners - */ - /* reset multicast filtering */ - ie_mc_reset(ifp->if_unit); - error = 0; - break; - - default: - error = EINVAL; - } - - splx(s); - return (error); -} - -static void -ie_mc_reset(int unit) -{ - struct ie_softc *ie = &ie_softc[unit]; - struct ifmultiaddr *ifma; - - /* - * Step through the list of addresses. - */ - ie->mcast_count = 0; - for (ifma = ie->arpcom.ac_if.if_multiaddrs.lh_first; ifma; - ifma = ifma->ifma_link.le_next) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - - /* XXX - this is broken... */ - if (ie->mcast_count >= MAXMCAST) { - ie->arpcom.ac_if.if_flags |= IFF_ALLMULTI; - ieioctl(&ie->arpcom.ac_if, SIOCSIFFLAGS, (void *) 0); - goto setflag; - } - bcopy(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), - &(ie->mcast_addrs[ie->mcast_count]), 6); - ie->mcast_count++; - } - -setflag: - ie->want_mcsetup = 1; -} - - -#ifdef DEBUG -static void -print_rbd(volatile struct ie_recv_buf_desc * rbd) -{ - printf("RBD at %p:\n" - "actual %04x, next %04x, buffer %p\n" - "length %04x, mbz %04x\n", - (volatile void *) rbd, - rbd->ie_rbd_actual, rbd->ie_rbd_next, - (void *) rbd->ie_rbd_buffer, - rbd->ie_rbd_length, rbd->mbz); -} - -#endif /* DEBUG */ -#endif /* NIE > 0 */ diff --git a/sys/i386/isa/if_ie507.h b/sys/i386/isa/if_ie507.h deleted file mode 100644 index 9be1396..0000000 --- a/sys/i386/isa/if_ie507.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * $FreeBSD$ - * Definitions for 3C507 - */ - -#define IE507_CTRL 6 /* control port */ -#define IE507_ICTRL 10 /* interrupt control */ -#define IE507_ATTN 11 /* any write here sends a chan attn */ -#define IE507_MADDR 14 /* shared memory configuration */ -#define IE507_IRQ 15 /* IRQ configuration */ - -#define EL_CTRL_BNK1 0x01 /* register bank 1 */ -#define EL_CTRL_IEN 0x04 /* interrupt enable */ -#define EL_CTRL_INTL 0x08 /* interrupt active latch */ -#define EL_CTRL_16BIT 0x10 /* bus width; clear = 8-bit, set = 16-bit */ -#define EL_CTRL_LOOP 0x20 /* loopback mode */ -#define EL_CTRL_NRST 0x80 /* turn off to reset */ -#define EL_CTRL_RESET (EL_CTRL_LOOP) -#define EL_CTRL_NORMAL (EL_CTRL_NRST | EL_CTRL_IEN | EL_CTRL_BNK1) diff --git a/sys/i386/isa/if_iee16.h b/sys/i386/isa/if_iee16.h deleted file mode 100644 index 27d0163..0000000 --- a/sys/i386/isa/if_iee16.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 1993, 1994, 1995 - * Rodney W. Grimes, Milwaukie, Oregon 97222. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer as - * the first lines of this file unmodified. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Rodney W. Grimes. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY RODNEY W. GRIMES ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL RODNEY W. GRIMES BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -/* - * Definitions for EtherExpress 16 - */ - -#define IEE16_ATTN 0x06 /* channel attention control */ -#define IEE16_IRQ 0x07 /* IRQ configuration */ -#define IEE16_IRQ_ENABLE 0x08 /* enable board interrupts */ - -#define IEE16_MEMDEC 0x0a /* memory decode */ -#define IEE16_MCTRL 0x0b /* memory control */ -#define IEE16_MCTRL_FMCS16 0x10 /* MEMCS16- for F000 */ - -#define IEE16_MPCTRL 0x0c /* memory page control */ -#define IEE16_CONFIG 0x0d /* config register */ -#define IEE16_BART_LOOPBACK 0x02 /* loopback, 0=none, 1=loopback */ -#define IEE16_BART_IOCHRDY_LATE 0x10 /* iochrdy late control bit */ -#define IEE16_BART_IO_TEST_EN 0x20 /* enable iochrdy timing test */ -#define IEE16_BART_IO_RESULT 0x40 /* result of the iochrdy test */ -#define IEE16_BART_MCS16_TEST 0x80 /* enable memcs16 select test */ - -#define IEE16_ECTRL 0x0e /* eeprom control */ -#define IEE16_ECTRL_EESK 0x01 /* EEPROM clock bit */ -#define IEE16_ECTRL_EECS 0x02 /* EEPROM chip select */ -#define IEE16_ECTRL_EEDI 0x04 /* EEPROM data in bit */ -#define IEE16_ECTRL_EEDO 0x08 /* EEPROM data out bit */ -#define IEE16_RESET_ASIC 0x40 /* reset ASIC (bart) pin */ -#define IEE16_RESET_586 0x80 /* reset 82586 pin */ -#define IEE16_ECTRL_MASK 0xb2 /* and'ed with ECTRL to enable read */ - -#define IEE16_MECTRL 0x0f /* memory control, 0xe000 seg 'W' */ -#define IEE16_ID_PORT 0x0f /* auto-id port 'R' */ - -#define IEE16_ID 0xbaba /* known id of EE16 */ - -#define IEE16_EEPROM_READ 0x06 /* EEPROM read opcode */ -#define IEE16_EEPROM_OPSIZE1 0x03 /* size of EEPROM opcodes */ -#define IEE16_EEPROM_ADDR_SIZE 0x06 /* size of EEPROM address */ - -/* Locations in the EEPROM */ -#define IEE16_EEPROM_CONFIG1 0x00 /* Configuration register 1 */ -#define IEE16_EEPROM_IRQ 0xE000 /* Encoded IRQ */ -#define IEE16_EEPROM_IRQ_SHIFT 13 /* To shift IRQ to lower bits */ -#define IEE16_EEPROM_LOCK_ADDR 0x01 /* contains the lock bit */ -#define IEE16_EEPROM_LOCKED 0x01 /* means that it is locked */ - -#define IEE16_EEPROM_ENET_LOW 0x02 /* Ethernet address, low word */ -#define IEE16_EEPROM_ENET_MID 0x03 /* Ethernet address, middle word */ -#define IEE16_EEPROM_ENET_HIGH 0x04 /* Ethernet address, high word */ diff --git a/sys/i386/isa/if_iereg.h b/sys/i386/isa/if_iereg.h deleted file mode 100644 index 875f63c..0000000 --- a/sys/i386/isa/if_iereg.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * $FreeBSD$ - * definitions for AT&T StarLAN 10 etc... - */ - -#define IEATT_RESET 0 /* any write here resets the 586 */ -#define IEATT_ATTN 1 /* any write here sends a Chan attn */ -#define IEATT_REVISION 6 /* read here to figure out this board */ -#define IEATT_ATTRIB 7 /* more information about this board */ - -#define SL_BOARD(x) ((x) & 0x0f) -#define SL_REV(x) ((x) >> 4) - -#define SL1_BOARD 0 -#define SL10_BOARD 1 -#define EN100_BOARD 2 -#define SLFIBER_BOARD 3 - -#define SL_ATTR_WIDTH 0x04 /* bus width: clear -> 8-bit */ -#define SL_ATTR_SPEED 0x08 /* medium speed: clear -> 10 Mbps */ -#define SL_ATTR_CODING 0x10 /* encoding: clear -> Manchester */ -#define SL_ATTR_HBW 0x20 /* host bus width: clear -> 16-bit */ -#define SL_ATTR_TYPE 0x40 /* medium type: clear -> Ethernet */ -#define SL_ATTR_BOOTROM 0x80 /* set -> boot ROM present */ diff --git a/sys/i386/isa/isa_compat.h b/sys/i386/isa/isa_compat.h index 98bf519..aadad05 100644 --- a/sys/i386/isa/isa_compat.h +++ b/sys/i386/isa/isa_compat.h @@ -35,7 +35,6 @@ #include "cx.h" #include "el.h" #include "fe.h" -#include "ie.h" #include "le.h" #include "lnc.h" #include "rdp.h" @@ -94,7 +93,6 @@ extern struct isa_driver csdriver; extern struct isa_driver cxdriver; extern struct isa_driver eldriver; extern struct isa_driver fedriver; -extern struct isa_driver iedriver; extern struct isa_driver ledriver; extern struct isa_driver lncdriver; extern struct isa_driver rdpdriver; @@ -229,9 +227,6 @@ static struct old_isa_driver old_drivers[] = { /* NET */ -#if NIE > 0 - { INTR_TYPE_NET, &iedriver }, -#endif #if NLE > 0 { INTR_TYPE_NET, &ledriver }, #endif diff --git a/sys/pci/adv_pci.c b/sys/pci/adv_pci.c deleted file mode 100644 index 8f8fc58..0000000 --- a/sys/pci/adv_pci.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Device probe and attach routines for the following - * Advanced Systems Inc. SCSI controllers: - * - * Connectivity Products: - * ABP920 - Bus-Master PCI (16 CDB) - * ABP930 - Bus-Master PCI (16 CDB) * - * ABP930U - Bus-Master PCI Ultra (16 CDB) - * ABP930UA - Bus-Master PCI Ultra (16 CDB) - * ABP960 - Bus-Master PCI MAC/PC (16 CDB) ** - * ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) - * - * Single Channel Products: - * ABP940 - Bus-Master PCI (240 CDB) - * ABP940U - Bus-Master PCI Ultra (240 CDB) - * ABP970 - Bus-Master PCI MAC/PC (240 CDB) - * ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) - * - * Dual Channel Products: - * ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) - * - * Footnotes: - * * This board has been sold by SIIG as the Fast SCSI Pro PCI. - * ** This board has been sold by Iomega as a Jaz Jet PCI adapter. - * - * Copyright (c) 1997 Justin Gibbs. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> - -#include <machine/bus_pio.h> -#include <machine/bus.h> - -#include <pci/pcireg.h> -#include <pci/pcivar.h> - -#include <dev/advansys/advansys.h> - -#define PCI_BASEADR0 PCI_MAP_REG_START /* I/O Address */ -#define PCI_BASEADR1 PCI_MAP_REG_START + 4 /* Mem I/O Address */ - -#define PCI_DEVICE_ID_ADVANSYS_1200A 0x110010CD -#define PCI_DEVICE_ID_ADVANSYS_1200B 0x120010CD -#define PCI_DEVICE_ID_ADVANSYS_ULTRA 0x130010CD -#define PCI_DEVICE_REV_ADVANSYS_3150 0x02 -#define PCI_DEVICE_REV_ADVANSYS_3050 0x03 - -#define ADV_PCI_MAX_DMA_ADDR (0xFFFFFFFFL) -#define ADV_PCI_MAX_DMA_COUNT (0xFFFFFFFFL) - -static const char* advpciprobe(pcici_t tag, pcidi_t type); -static void advpciattach(pcici_t config_id, int unit); - -/* - * The overrun buffer shared amongst all PCI adapters. - */ -static u_int8_t* overrun_buf; -static bus_dma_tag_t overrun_dmat; -static bus_dmamap_t overrun_dmamap; -static bus_addr_t overrun_physbase; - -static struct pci_device adv_pci_driver = { - "adv", - advpciprobe, - advpciattach, - &adv_unit, - NULL -}; - -COMPAT_PCI_DRIVER (adv_pci, adv_pci_driver); - -static const char* -advpciprobe(pcici_t tag, pcidi_t type) -{ - int rev = pci_conf_read(tag, PCI_CLASS_REG) & 0xff; - switch (type) { - case PCI_DEVICE_ID_ADVANSYS_1200A: - return ("AdvanSys ASC1200A SCSI controller"); - case PCI_DEVICE_ID_ADVANSYS_1200B: - return ("AdvanSys ASC1200B SCSI controller"); - case PCI_DEVICE_ID_ADVANSYS_ULTRA: - if (rev == PCI_DEVICE_REV_ADVANSYS_3150) - return ("AdvanSys ASC3150 Ultra SCSI controller"); - else - return ("AdvanSys ASC3050 Ultra SCSI controller"); - break; - default: - break; - } - return (NULL); -} - -static void -advpciattach(pcici_t config_id, int unit) -{ - u_int16_t io_port; - struct adv_softc *adv; - u_int32_t id; - u_int32_t command; - int error; - - /* - * Determine the chip version. - */ - id = pci_cfgread(config_id, PCI_ID_REG, /*bytes*/4); - command = pci_cfgread(config_id, PCIR_COMMAND, /*bytes*/1); - - /* - * These cards do not allow memory mapped accesses, so we must - * ensure that I/O accesses are available or we won't be able - * to talk to them. - */ - if ((command & (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) - != (PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN)) { - command |= PCIM_CMD_PORTEN|PCIM_CMD_BUSMASTEREN; - pci_cfgwrite(config_id, PCIR_COMMAND, command, /*bytes*/1); - } - - /* - * Early chips can't handle non-zero latency timer settings. - */ - if (id == PCI_DEVICE_ID_ADVANSYS_1200A - || id == PCI_DEVICE_ID_ADVANSYS_1200B) { - pci_cfgwrite(config_id, PCIR_LATTIMER, /*value*/0, /*bytes*/1); - } - - - if (pci_map_port(config_id, PCI_BASEADR0, &io_port) == 0) - return; - - if (adv_find_signature(I386_BUS_SPACE_IO, io_port) == 0) - return; - - adv = adv_alloc(unit, I386_BUS_SPACE_IO, io_port); - if (adv == NULL) - return; - - /* Allocate a dmatag for our transfer DMA maps */ - /* XXX Should be a child of the PCI bus dma tag */ - error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, - /*boundary*/0, - /*lowaddr*/ADV_PCI_MAX_DMA_ADDR, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/BUS_SPACE_MAXSIZE_32BIT, - /*nsegments*/BUS_SPACE_UNRESTRICTED, - /*maxsegsz*/ADV_PCI_MAX_DMA_COUNT, - /*flags*/0, - &adv->parent_dmat); - - if (error != 0) { - printf("%s: Could not allocate DMA tag - error %d\n", - adv_name(adv), error); - adv_free(adv); - return; - } - - adv->init_level++; - - if (overrun_buf == NULL) { - /* Need to allocate our overrun buffer */ - if (bus_dma_tag_create(adv->parent_dmat, - /*alignment*/8, /*boundary*/0, - ADV_PCI_MAX_DMA_ADDR, BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - ADV_OVERRUN_BSIZE, /*nsegments*/1, - BUS_SPACE_MAXSIZE_32BIT, /*flags*/0, - &overrun_dmat) != 0) { - bus_dma_tag_destroy(adv->parent_dmat); - adv_free(adv); - return; - } - if (bus_dmamem_alloc(overrun_dmat, - (void **)&overrun_buf, - BUS_DMA_NOWAIT, - &overrun_dmamap) != 0) { - bus_dma_tag_destroy(overrun_dmat); - bus_dma_tag_destroy(adv->parent_dmat); - adv_free(adv); - return; - } - /* And permanently map it in */ - bus_dmamap_load(overrun_dmat, overrun_dmamap, - overrun_buf, ADV_OVERRUN_BSIZE, - adv_map, &overrun_physbase, - /*flags*/0); - } - - adv->overrun_physbase = overrun_physbase; - - /* - * Stop the chip. - */ - ADV_OUTB(adv, ADV_CHIP_CTRL, ADV_CC_HALT); - ADV_OUTW(adv, ADV_CHIP_STATUS, 0); - - adv->chip_version = ADV_INB(adv, ADV_NONEISA_CHIP_REVISION); - adv->type = ADV_PCI; - - /* - * Setup active negation and signal filtering. - */ - { - u_int8_t extra_cfg; - - if (adv->chip_version >= ADV_CHIP_VER_PCI_ULTRA_3150) - adv->type |= ADV_ULTRA; - if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3150) - extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE; - else if (adv->chip_version == ADV_CHIP_VER_PCI_ULTRA_3050) - extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_WR_EN_FILTER; - else - extra_cfg = ADV_IFC_ACT_NEG | ADV_IFC_SLEW_RATE; - ADV_OUTB(adv, ADV_REG_IFC, extra_cfg); - } - - if (adv_init(adv) != 0) { - adv_free(adv); - return; - } - - adv->max_dma_count = ADV_PCI_MAX_DMA_COUNT; - adv->max_dma_addr = ADV_PCI_MAX_DMA_ADDR; - -#if CC_DISABLE_PCI_PARITY_INT - { - u_int16_t config_msw; - - config_msw = ADV_INW(adv, ADV_CONFIG_MSW); - config_msw &= 0xFFC0; - ADV_OUTW(adv, ADV_CONFIG_MSW, config_msw); - } -#endif - - if (id == PCI_DEVICE_ID_ADVANSYS_1200A - || id == PCI_DEVICE_ID_ADVANSYS_1200B) { - adv->bug_fix_control |= ADV_BUG_FIX_IF_NOT_DWB; - adv->bug_fix_control |= ADV_BUG_FIX_ASYN_USE_SYN; - adv->fix_asyn_xfer = ~0; - } - - if ((pci_map_int(config_id, adv_intr, (void *)adv, &cam_imask)) == 0) { - adv_free(adv); - return; - } - - adv_attach(adv); -} diff --git a/sys/pci/ahc_pci.c b/sys/pci/ahc_pci.c deleted file mode 100644 index 6e86839..0000000 --- a/sys/pci/ahc_pci.c +++ /dev/null @@ -1,1860 +0,0 @@ -/* - * Product specific probe and attach routines for: - * 3940, 2940, aic7895, aic7890, aic7880, - * aic7870, aic7860 and aic7850 SCSI controllers - * - * Copyright (c) 1995, 1996, 1997, 1998, 1999, 2000 Justin T. Gibbs - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions, and the following disclaimer, - * without modification, immediately at the beginning of the file. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * Where this Software is combined with software released under the terms of - * the GNU Public License ("GPL") and the terms of the GPL would require the - * combined work to also be released under the terms of the GPL, the terms - * and conditions of this License will apply in addition to those of the - * GPL with the exception of any terms or conditions of this License that - * conflict with, or are expressly prohibited by, the GPL. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <sys/bus.h> - -#include <pci/pcireg.h> -#include <pci/pcivar.h> - -#include <machine/bus_memio.h> -#include <machine/bus_pio.h> -#include <machine/bus.h> -#include <machine/resource.h> -#include <machine/clock.h> -#include <sys/rman.h> - -#include <cam/cam.h> -#include <cam/cam_ccb.h> -#include <cam/cam_sim.h> -#include <cam/cam_xpt_sim.h> - -#include <cam/scsi/scsi_all.h> - -#include <dev/aic7xxx/aic7xxx.h> -#include <dev/aic7xxx/93cx6.h> - -#include <aic7xxx_reg.h> - -#define AHC_PCI_IOADDR PCIR_MAPS /* I/O Address */ -#define AHC_PCI_MEMADDR (PCIR_MAPS + 4) /* Mem I/O Address */ - -static __inline u_int64_t -ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor) -{ - u_int64_t id; - - id = subvendor - | (subdevice << 16) - | ((u_int64_t)vendor << 32) - | ((u_int64_t)device << 48); - - return (id); -} - -#define ID_ALL_MASK 0xFFFFFFFFFFFFFFFFull -#define ID_DEV_VENDOR_MASK 0xFFFFFFFF00000000ull -#define ID_AIC7850 0x5078900400000000ull -#define ID_AHA_2910_15_20_30C 0x5078900478509004ull -#define ID_AIC7855 0x5578900400000000ull -#define ID_AIC7859 0x3860900400000000ull -#define ID_AHA_2930CU 0x3860900438699004ull -#define ID_AIC7860 0x6078900400000000ull -#define ID_AIC7860C 0x6078900478609004ull -#define ID_AHA_2940AU_0 0x6178900400000000ull -#define ID_AHA_2940AU_1 0x6178900478619004ull -#define ID_AHA_2940AU_CN 0x2178900478219004ull -#define ID_AHA_2930C_VAR 0x6038900438689004ull - -#define ID_AIC7870 0x7078900400000000ull -#define ID_AHA_2940 0x7178900400000000ull -#define ID_AHA_3940 0x7278900400000000ull -#define ID_AHA_398X 0x7378900400000000ull -#define ID_AHA_2944 0x7478900400000000ull -#define ID_AHA_3944 0x7578900400000000ull - -#define ID_AIC7880 0x8078900400000000ull -#define ID_AIC7880_B 0x8078900478809004ull -#define ID_AHA_2940U 0x8178900400000000ull -#define ID_AHA_3940U 0x8278900400000000ull -#define ID_AHA_2944U 0x8478900400000000ull -#define ID_AHA_3944U 0x8578900400000000ull -#define ID_AHA_398XU 0x8378900400000000ull -#define ID_AHA_4944U 0x8678900400000000ull -#define ID_AHA_2940UB 0x8178900478819004ull -#define ID_AHA_2930U 0x8878900478889004ull -#define ID_AHA_2940U_PRO 0x8778900478879004ull -#define ID_AHA_2940U_CN 0x0078900478009004ull - -#define ID_AIC7895 0x7895900478959004ull -#define ID_AIC7895_RAID_PORT 0x7893900478939004ull -#define ID_AHA_2940U_DUAL 0x7895900478919004ull -#define ID_AHA_3940AU 0x7895900478929004ull -#define ID_AHA_3944AU 0x7895900478949004ull - -#define ID_AIC7890 0x001F9005000F9005ull -#define ID_AHA_2930U2 0x0011900501819005ull -#define ID_AHA_2940U2B 0x00109005A1009005ull -#define ID_AHA_2940U2_OEM 0x0010900521809005ull -#define ID_AHA_2940U2 0x00109005A1809005ull -#define ID_AHA_2950U2B 0x00109005E1009005ull - -#define ID_AIC7892 0x008F9005FFFF9005ull -#define ID_AHA_29160 0x00809005E2A09005ull -#define ID_AHA_29160_CPQ 0x00809005E2A00E11ull -#define ID_AHA_29160N 0x0080900562A09005ull -#define ID_AHA_29160B 0x00809005E2209005ull -#define ID_AHA_19160B 0x0081900562A19005ull - -#define ID_AIC7896 0x005F9005FFFF9005ull -#define ID_AHA_3950U2B_0 0x00509005FFFF9005ull -#define ID_AHA_3950U2B_1 0x00509005F5009005ull -#define ID_AHA_3950U2D_0 0x00519005FFFF9005ull -#define ID_AHA_3950U2D_1 0x00519005B5009005ull - -#define ID_AIC7899 0x00CF9005FFFF9005ull -#define ID_AHA_3960D 0x00C09005F6209005ull /* AKA AHA-39160 */ -#define ID_AHA_3960D_CPQ 0x00C09005F6200E11ull - -#define ID_AIC7810 0x1078900400000000ull -#define ID_AIC7815 0x1578900400000000ull - -typedef int (ahc_device_setup_t)(device_t, char *, ahc_chip *, - ahc_feature *, ahc_flag *); - -static ahc_device_setup_t ahc_aic7850_setup; -static ahc_device_setup_t ahc_aic7855_setup; -static ahc_device_setup_t ahc_aic7859_setup; -static ahc_device_setup_t ahc_aic7860_setup; -static ahc_device_setup_t ahc_aic7870_setup; -static ahc_device_setup_t ahc_aha394X_setup; -static ahc_device_setup_t ahc_aha398X_setup; -static ahc_device_setup_t ahc_aic7880_setup; -static ahc_device_setup_t ahc_2940Pro_setup; -static ahc_device_setup_t ahc_aha394XU_setup; -static ahc_device_setup_t ahc_aha398XU_setup; -static ahc_device_setup_t ahc_aic7890_setup; -static ahc_device_setup_t ahc_aic7892_setup; -static ahc_device_setup_t ahc_aic7895_setup; -static ahc_device_setup_t ahc_aic7896_setup; -static ahc_device_setup_t ahc_aic7899_setup; -static ahc_device_setup_t ahc_raid_setup; -static ahc_device_setup_t ahc_aha394XX_setup; -static ahc_device_setup_t ahc_aha398XX_setup; - -struct ahc_pci_identity { - u_int64_t full_id; - u_int64_t id_mask; - char *name; - ahc_device_setup_t *setup; -}; - -struct ahc_pci_identity ahc_pci_ident_table [] = -{ - /* aic7850 based controllers */ - { - ID_AHA_2910_15_20_30C, - ID_ALL_MASK, - "Adaptec 2910/15/20/30C SCSI adapter", - ahc_aic7850_setup - }, - /* aic7859 based controllers */ - { - ID_AHA_2930CU, - ID_ALL_MASK, - "Adaptec 2930CU SCSI adapter", - ahc_aic7859_setup - }, - /* aic7860 based controllers */ - { - ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2940A Ultra SCSI adapter", - ahc_aic7860_setup - }, - { - ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2940A/CN Ultra SCSI adapter", - ahc_aic7860_setup - }, - { - ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2930C SCSI adapter (VAR)", - ahc_aic7860_setup - }, - /* aic7870 based controllers */ - { - ID_AHA_2940, - ID_ALL_MASK, - "Adaptec 2940 SCSI adapter", - ahc_aic7870_setup - }, - { - ID_AHA_3940, - ID_ALL_MASK, - "Adaptec 3940 SCSI adapter", - ahc_aha394X_setup - }, - { - ID_AHA_398X, - ID_ALL_MASK, - "Adaptec 398X SCSI RAID adapter", - ahc_aha398X_setup - }, - { - ID_AHA_2944, - ID_ALL_MASK, - "Adaptec 2944 SCSI adapter", - ahc_aic7870_setup - }, - { - ID_AHA_3944, - ID_ALL_MASK, - "Adaptec 3944 SCSI adapter", - ahc_aha394X_setup - }, - /* aic7880 based controllers */ - { - ID_AHA_2940U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2940 Ultra SCSI adapter", - ahc_aic7880_setup - }, - { - ID_AHA_3940U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 3940 Ultra SCSI adapter", - ahc_aha394XU_setup - }, - { - ID_AHA_2944U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2944 Ultra SCSI adapter", - ahc_aic7880_setup - }, - { - ID_AHA_3944U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 3944 Ultra SCSI adapter", - ahc_aha394XU_setup - }, - { - ID_AHA_398XU & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 398X Ultra SCSI RAID adapter", - ahc_aha398XU_setup - }, - { - /* - * XXX Don't know the slot numbers - * so we can't identify channels - */ - ID_AHA_4944U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 4944 Ultra SCSI adapter", - ahc_aic7880_setup - }, - { - ID_AHA_2930U & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2930 Ultra SCSI adapter", - ahc_aic7880_setup - }, - { - ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2940 Pro Ultra SCSI adapter", - ahc_2940Pro_setup - }, - { - ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec 2940/CN Ultra SCSI adapter", - ahc_aic7880_setup - }, - /* aic7890 based controllers */ - { - ID_AHA_2930U2, - ID_ALL_MASK, - "Adaptec 2930 Ultra2 SCSI adapter", - ahc_aic7890_setup - }, - { - ID_AHA_2940U2B, - ID_ALL_MASK, - "Adaptec 2940B Ultra2 SCSI adapter", - ahc_aic7890_setup - }, - { - ID_AHA_2940U2_OEM, - ID_ALL_MASK, - "Adaptec 2940 Ultra2 SCSI adapter (OEM)", - ahc_aic7890_setup - }, - { - ID_AHA_2940U2, - ID_ALL_MASK, - "Adaptec 2940 Ultra2 SCSI adapter", - ahc_aic7890_setup - }, - { - ID_AHA_2950U2B, - ID_ALL_MASK, - "Adaptec 2950 Ultra2 SCSI adapter", - ahc_aic7890_setup - }, - /* aic7892 based controllers */ - { - ID_AHA_29160, - ID_ALL_MASK, - "Adaptec 29160 Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - { - ID_AHA_29160_CPQ, - ID_ALL_MASK, - "Adaptec (Compaq OEM) 29160 Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - { - ID_AHA_29160N, - ID_ALL_MASK, - "Adaptec 29160N Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - { - ID_AHA_29160B, - ID_ALL_MASK, - "Adaptec 29160B Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - { - ID_AHA_19160B, - ID_ALL_MASK, - "Adaptec 19160B Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - /* aic7895 based controllers */ - { - ID_AHA_2940U_DUAL, - ID_ALL_MASK, - "Adaptec 2940/DUAL Ultra SCSI adapter", - ahc_aic7895_setup - }, - { - ID_AHA_3940AU, - ID_ALL_MASK, - "Adaptec 3940A Ultra SCSI adapter", - ahc_aic7895_setup - }, - { - ID_AHA_3944AU, - ID_ALL_MASK, - "Adaptec 3944A Ultra SCSI adapter", - ahc_aic7895_setup - }, - /* aic7896/97 based controllers */ - { - ID_AHA_3950U2B_0, - ID_ALL_MASK, - "Adaptec 3950B Ultra2 SCSI adapter", - ahc_aic7896_setup - }, - { - ID_AHA_3950U2B_1, - ID_ALL_MASK, - "Adaptec 3950B Ultra2 SCSI adapter", - ahc_aic7896_setup - }, - { - ID_AHA_3950U2D_0, - ID_ALL_MASK, - "Adaptec 3950D Ultra2 SCSI adapter", - ahc_aic7896_setup - }, - { - ID_AHA_3950U2D_1, - ID_ALL_MASK, - "Adaptec 3950D Ultra2 SCSI adapter", - ahc_aic7896_setup - }, - /* aic7899 based controllers */ - { - ID_AHA_3960D, - ID_ALL_MASK, - "Adaptec 3960D Ultra160 SCSI adapter", - ahc_aic7899_setup - }, - { - ID_AHA_3960D_CPQ, - ID_ALL_MASK, - "Adaptec (Compaq OEM) 3960D Ultra160 SCSI adapter", - ahc_aic7899_setup - }, - /* Generic chip probes for devices we don't know 'exactly' */ - { - ID_AIC7850 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7850 SCSI adapter", - ahc_aic7850_setup - }, - { - ID_AIC7855 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7855 SCSI adapter", - ahc_aic7855_setup - }, - { - ID_AIC7859 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7859 SCSI adapter", - ahc_aic7859_setup - }, - { - ID_AIC7860 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7860 SCSI adapter", - ahc_aic7860_setup - }, - { - ID_AIC7870 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7870 SCSI adapter", - ahc_aic7870_setup - }, - { - ID_AIC7880 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7880 Ultra SCSI adapter", - ahc_aic7880_setup - }, - { - ID_AIC7890 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7890/91 Ultra2 SCSI adapter", - ahc_aic7890_setup - }, - { - ID_AIC7892 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7892 Ultra160 SCSI adapter", - ahc_aic7892_setup - }, - { - ID_AIC7895 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7895 Ultra SCSI adapter", - ahc_aic7895_setup - }, - { - ID_AIC7895_RAID_PORT & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7895 Ultra SCSI adapter (RAID PORT)", - ahc_aic7895_setup - }, - { - ID_AIC7896 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7896/97 Ultra2 SCSI adapter", - ahc_aic7896_setup - }, - { - ID_AIC7899 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7899 Ultra160 SCSI adapter", - ahc_aic7899_setup - }, - { - ID_AIC7810 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7810 RAID memory controller", - ahc_raid_setup - }, - { - ID_AIC7815 & ID_DEV_VENDOR_MASK, - ID_DEV_VENDOR_MASK, - "Adaptec aic7815 RAID memory controller", - ahc_raid_setup - } -}; - -static const int ahc_num_pci_devs = - sizeof(ahc_pci_ident_table) / sizeof(*ahc_pci_ident_table); - -#define AHC_394X_SLOT_CHANNEL_A 4 -#define AHC_394X_SLOT_CHANNEL_B 5 - -#define AHC_398X_SLOT_CHANNEL_A 4 -#define AHC_398X_SLOT_CHANNEL_B 8 -#define AHC_398X_SLOT_CHANNEL_C 12 - -#define DEVCONFIG 0x40 -#define SCBSIZE32 0x00010000ul /* aic789X only */ -#define MPORTMODE 0x00000400ul /* aic7870 only */ -#define RAMPSM 0x00000200ul /* aic7870 only */ -#define VOLSENSE 0x00000100ul -#define SCBRAMSEL 0x00000080ul -#define MRDCEN 0x00000040ul -#define EXTSCBTIME 0x00000020ul /* aic7870 only */ -#define EXTSCBPEN 0x00000010ul /* aic7870 only */ -#define BERREN 0x00000008ul -#define DACEN 0x00000004ul -#define STPWLEVEL 0x00000002ul -#define DIFACTNEGEN 0x00000001ul /* aic7870 only */ - -#define CSIZE_LATTIME 0x0c -#define CACHESIZE 0x0000003ful /* only 5 bits */ -#define LATTIME 0x0000ff00ul - -static struct ahc_pci_identity *ahc_find_pci_device(device_t dev); -static int ahc_ext_scbram_present(struct ahc_softc *ahc); -static void ahc_ext_scbram_config(struct ahc_softc *ahc, int enable, - int pcheck, int fast); -static void ahc_probe_ext_scbram(struct ahc_softc *ahc); -static void check_extport(struct ahc_softc *ahc, u_int *sxfrctl1); -static void configure_termination(struct ahc_softc *ahc, - struct seeprom_descriptor *sd, - u_int adapter_control, - u_int *sxfrctl1); - -static void ahc_new_term_detect(struct ahc_softc *ahc, - int *enableSEC_low, - int *enableSEC_high, - int *enablePRI_low, - int *enablePRI_high, - int *eeprom_present); -static void aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, - int *internal68_present, - int *externalcable_present, - int *eeprom_present); -static void aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, - int *externalcable_present, - int *eeprom_present); -static int acquire_seeprom(struct ahc_softc *ahc, - struct seeprom_descriptor *sd); -static void release_seeprom(struct seeprom_descriptor *sd); -static void write_brdctl(struct ahc_softc *ahc, u_int8_t value); -static u_int8_t read_brdctl(struct ahc_softc *ahc); - -static struct ahc_softc *first_398X; - -static int ahc_pci_probe(device_t dev); -static int ahc_pci_attach(device_t dev); - -/* Exported for use in the ahc_intr routine */ -void ahc_pci_intr(struct ahc_softc *ahc); - -static device_method_t ahc_pci_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, ahc_pci_probe), - DEVMETHOD(device_attach, ahc_pci_attach), - { 0, 0 } -}; - -static driver_t ahc_pci_driver = { - "ahc", - ahc_pci_methods, - sizeof(struct ahc_softc) -}; - -static devclass_t ahc_devclass; - -DRIVER_MODULE(ahc, pci, ahc_pci_driver, ahc_devclass, 0, 0); - -static struct ahc_pci_identity * -ahc_find_pci_device(device_t dev) -{ - u_int64_t full_id; - struct ahc_pci_identity *entry; - u_int i; - - full_id = ahc_compose_id(pci_get_device(dev), - pci_get_vendor(dev), - pci_get_subdevice(dev), - pci_get_subvendor(dev)); - - for (i = 0; i < ahc_num_pci_devs; i++) { - entry = &ahc_pci_ident_table[i]; - if (entry->full_id == (full_id & entry->id_mask)) - return (entry); - } - return (NULL); -} - -static int -ahc_pci_probe(device_t dev) -{ - struct ahc_pci_identity *entry; - - entry = ahc_find_pci_device(dev); - if (entry != NULL) { - device_set_desc(dev, entry->name); - return (0); - } - return (ENXIO); -} - -static int -ahc_pci_attach(device_t dev) -{ - bus_dma_tag_t parent_dmat; - struct ahc_pci_identity *entry; - struct resource *regs; - struct ahc_softc *ahc; - u_int command; - struct scb_data *shared_scb_data; - ahc_chip ahc_t = AHC_NONE; - ahc_feature ahc_fe = AHC_FENONE; - ahc_flag ahc_f = AHC_FNONE; - int regs_type; - int regs_id; - u_int our_id = 0; - u_int sxfrctl1; - u_int scsiseq; - int error; - int zero; - char channel; - - shared_scb_data = NULL; - command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1); - entry = ahc_find_pci_device(dev); - if (entry == NULL) - return (ENXIO); - error = entry->setup(dev, &channel, &ahc_t, &ahc_fe, &ahc_f); - if (error != 0) - return (error); - - regs = NULL; - regs_type = 0; - regs_id = 0; -#ifdef AHC_ALLOW_MEMIO - if ((command & PCIM_CMD_MEMEN) != 0) { - regs_type = SYS_RES_MEMORY; - regs_id = AHC_PCI_MEMADDR; - regs = bus_alloc_resource(dev, regs_type, - ®s_id, 0, ~0, 1, RF_ACTIVE); - } -#endif - if (regs == NULL && (command & PCI_COMMAND_IO_ENABLE) != 0) { - regs_type = SYS_RES_IOPORT; - regs_id = AHC_PCI_IOADDR; - regs = bus_alloc_resource(dev, regs_type, - ®s_id, 0, ~0, 1, RF_ACTIVE); - } - - if (regs == NULL) { - device_printf(dev, "can't allocate register resources\n"); - return (ENOMEM); - } - - /* Ensure busmastering is enabled */ - command |= PCIM_CMD_BUSMASTEREN; - pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1); - - /* Allocate a dmatag for our SCB DMA maps */ - /* XXX Should be a child of the PCI bus dma tag */ - error = bus_dma_tag_create(/*parent*/NULL, /*alignment*/1, - /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, - /*filter*/NULL, /*filterarg*/NULL, - /*maxsize*/MAXBSIZE, /*nsegments*/AHC_NSEG, - /*maxsegsz*/AHC_MAXTRANSFER_SIZE, - /*flags*/BUS_DMA_ALLOCNOW, &parent_dmat); - - if (error != 0) { - printf("ahc_pci_attach: Could not allocate DMA tag " - "- error %d\n", error); - return (ENOMEM); - } - - /* On all PCI adapters, we allow SCB paging */ - ahc_f |= AHC_PAGESCBS; - if ((ahc = ahc_alloc(dev, regs, regs_type, regs_id, parent_dmat, - ahc_t|AHC_PCI, ahc_fe, ahc_f, - shared_scb_data)) == NULL) - return (ENOMEM); - - ahc->channel = channel; - - /* Store our PCI bus information for use in our PCI error handler */ - ahc->device = dev; - - /* Remeber how the card was setup in case there is no SEEPROM */ - ahc_outb(ahc, HCNTRL, ahc->pause); - if ((ahc->features & AHC_ULTRA2) != 0) - our_id = ahc_inb(ahc, SCSIID_ULTRA2) & OID; - else - our_id = ahc_inb(ahc, SCSIID) & OID; - sxfrctl1 = ahc_inb(ahc, SXFRCTL1) & STPWEN; - scsiseq = ahc_inb(ahc, SCSISEQ); - - if (ahc_reset(ahc) != 0) { - /* Failed */ - ahc_free(ahc); - return (ENXIO); - } - - if ((ahc->features & AHC_DT) != 0) { - u_int optionmode; - u_int sfunct; - - /* Perform ALT-Mode Setup */ - sfunct = ahc_inb(ahc, SFUNCT) & ~ALT_MODE; - ahc_outb(ahc, SFUNCT, sfunct | ALT_MODE); - optionmode = ahc_inb(ahc, OPTIONMODE); - printf("OptionMode = %x\n", optionmode); - ahc_outb(ahc, OPTIONMODE, OPTIONMODE_DEFAULTS); - /* Send CRC info in target mode every 4K */ - ahc_outb(ahc, TARGCRCCNT, 0); - ahc_outb(ahc, TARGCRCCNT + 1, 0x10); - ahc_outb(ahc, SFUNCT, sfunct); - - /* Normal mode setup */ - ahc_outb(ahc, CRCCONTROL1, CRCVALCHKEN|CRCENDCHKEN|CRCREQCHKEN - |TARGCRCENDEN|TARGCRCCNTEN); - } - zero = 0; - ahc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &zero, - 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE); - if (ahc->irq == NULL) { - ahc_free(ahc); - return (ENOMEM); - } - - ahc->irq_res_type = SYS_RES_IRQ; - - /* - * Do aic7880/aic7870/aic7860/aic7850 specific initialization - */ - { - u_int8_t sblkctl; - u_int dscommand0; - - dscommand0 = ahc_inb(ahc, DSCOMMAND0); - dscommand0 |= MPARCKEN; - if ((ahc->features & AHC_ULTRA2) != 0) { - - /* - * DPARCKEN doesn't work correctly on - * some MBs so don't use it. - */ - dscommand0 &= ~(USCBSIZE32|DPARCKEN); - dscommand0 |= CACHETHEN; - } - - ahc_outb(ahc, DSCOMMAND0, dscommand0); - - /* See if we have an SEEPROM and perform auto-term */ - check_extport(ahc, &sxfrctl1); - - /* - * Take the LED out of diagnostic mode - */ - sblkctl = ahc_inb(ahc, SBLKCTL); - ahc_outb(ahc, SBLKCTL, (sblkctl & ~(DIAGLEDEN|DIAGLEDON))); - - /* - * I don't know where this is set in the SEEPROM or by the - * BIOS, so we default to 100% on Ultra or slower controllers - * and 75% on ULTRA2 controllers. - */ - if ((ahc->features & AHC_ULTRA2) != 0) { - ahc_outb(ahc, DFF_THRSH, RD_DFTHRSH_75|WR_DFTHRSH_75); - } else { - ahc_outb(ahc, DSPCISTATUS, DFTHRSH_100); - } - - if (ahc->flags & AHC_USEDEFAULTS) { - /* - * PCI Adapter default setup - * Should only be used if the adapter does not have - * an SEEPROM. - */ - /* See if someone else set us up already */ - if (scsiseq != 0) { - printf("%s: Using left over BIOS settings\n", - ahc_name(ahc)); - ahc->flags &= ~AHC_USEDEFAULTS; - } else { - /* - * Assume only one connector and always turn - * on termination. - */ - our_id = 0x07; - sxfrctl1 = STPWEN; - } - ahc_outb(ahc, SCSICONF, our_id|ENSPCHK|RESET_SCSI); - - ahc->our_id = our_id; - } - } - - /* - * Take a look to see if we have external SRAM. - * We currently do not attempt to use SRAM that is - * shared among multiple controllers. - */ - ahc_probe_ext_scbram(ahc); - - - printf("%s: %s ", ahc_name(ahc), - ahc_chip_names[ahc->chip & AHC_CHIPID_MASK]); - - /* - * Record our termination setting for the - * generic initialization routine. - */ - if ((sxfrctl1 & STPWEN) != 0) - ahc->flags |= AHC_TERM_ENB_A; - - if (ahc_init(ahc)) { - ahc_free(ahc); - return (ENOMEM); - } - - /* XXX Crude hack - fix sometime */ - if (ahc->flags & AHC_SHARED_SRAM) { - /* Only set this once we've successfully probed */ - if (shared_scb_data == NULL) - first_398X = ahc; - } - - ahc_attach(ahc); - return (0); -} - -/* - * Test for the presense of external sram in an - * "unshared" configuration. - */ -static int -ahc_ext_scbram_present(struct ahc_softc *ahc) -{ - int ramps; - int single_user; - u_int32_t devconfig; - - devconfig = pci_read_config(ahc->device, DEVCONFIG, /*bytes*/4); - single_user = (devconfig & MPORTMODE) != 0; - - if ((ahc->features & AHC_ULTRA2) != 0) - ramps = (ahc_inb(ahc, DSCOMMAND0) & RAMPS) != 0; - else if ((ahc->chip & AHC_CHIPID_MASK) >= AHC_AIC7870) - ramps = (devconfig & RAMPSM) != 0; - else - ramps = 0; - - if (ramps && single_user) - return (1); - return (0); -} - -/* - * Enable external scbram. - */ -static void -ahc_ext_scbram_config(struct ahc_softc *ahc, int enable, int pcheck, int fast) -{ - u_int32_t devconfig; - - if (ahc->features & AHC_MULTI_FUNC) { - /* - * Set the SCB Base addr (highest address bit) - * depending on which channel we are. - */ - ahc_outb(ahc, SCBBADDR, pci_get_function(ahc->device)); - } - - devconfig = pci_read_config(ahc->device, DEVCONFIG, /*bytes*/4); - if ((ahc->features & AHC_ULTRA2) != 0) { - u_int dscommand0; - - dscommand0 = ahc_inb(ahc, DSCOMMAND0); - if (enable) - dscommand0 &= ~INTSCBRAMSEL; - else - dscommand0 |= INTSCBRAMSEL; - ahc_outb(ahc, DSCOMMAND0, dscommand0); - } else { - if (fast) - devconfig &= ~EXTSCBTIME; - else - devconfig |= EXTSCBTIME; - if (enable) - devconfig &= ~SCBRAMSEL; - else - devconfig |= SCBRAMSEL; - } - if (pcheck) - devconfig |= EXTSCBPEN; - else - devconfig &= ~EXTSCBPEN; - - pci_write_config(ahc->device, DEVCONFIG, devconfig, /*bytes*/4); -} - -/* - * Take a look to see if we have external SRAM. - * We currently do not attempt to use SRAM that is - * shared among multiple controllers. - */ -static void -ahc_probe_ext_scbram(struct ahc_softc *ahc) -{ - int num_scbs; - int test_num_scbs; - int enable; - int pcheck; - int fast; - - if (ahc_ext_scbram_present(ahc) == 0) - return; - - /* - * Probe for the best parameters to use. - */ - enable = FALSE; - pcheck = FALSE; - fast = FALSE; - ahc_ext_scbram_config(ahc, /*enable*/TRUE, pcheck, fast); - num_scbs = ahc_probe_scbs(ahc); - if (num_scbs == 0) { - /* The SRAM wasn't really present. */ - goto done; - } - enable = TRUE; - - /* Now see if we can do parity */ - ahc_ext_scbram_config(ahc, enable, /*pcheck*/TRUE, fast); - num_scbs = ahc_probe_scbs(ahc); - if ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 - || (ahc_inb(ahc, ERROR) & MPARERR) == 0) - pcheck = TRUE; - - /* Clear any resulting parity error */ - ahc_outb(ahc, CLRINT, CLRPARERR); - ahc_outb(ahc, CLRINT, CLRBRKADRINT); - - /* Now see if we can do fast timing */ - ahc_ext_scbram_config(ahc, enable, pcheck, /*fast*/TRUE); - test_num_scbs = ahc_probe_scbs(ahc); - if (test_num_scbs == num_scbs - && ((ahc_inb(ahc, INTSTAT) & BRKADRINT) == 0 - || (ahc_inb(ahc, ERROR) & MPARERR) == 0)) - fast = TRUE; - -done: - /* Clear any resulting parity error */ - ahc_outb(ahc, CLRINT, CLRPARERR); - ahc_outb(ahc, CLRINT, CLRBRKADRINT); - if (bootverbose && enable) { - printf("%s: External SRAM, %dns access%s\n", - ahc_name(ahc), fast ? 10 : 20, - pcheck ? ", parity checking enabled" : ""); - - } - ahc_ext_scbram_config(ahc, enable, pcheck, fast); -} - -/* - * Check the external port logic for a serial eeprom - * and termination/cable detection contrls. - */ -static void -check_extport(struct ahc_softc *ahc, u_int *sxfrctl1) -{ - struct seeprom_descriptor sd; - struct seeprom_config sc; - u_int scsi_conf; - u_int adapter_control; - int have_seeprom; - int have_autoterm; - - sd.sd_tag = ahc->tag; - sd.sd_bsh = ahc->bsh; - sd.sd_control_offset = SEECTL; - sd.sd_status_offset = SEECTL; - sd.sd_dataout_offset = SEECTL; - - /* - * For some multi-channel devices, the c46 is simply too - * small to work. For the other controller types, we can - * get our information from either SEEPROM type. Set the - * type to start our probe with accordingly. - */ - if (ahc->flags & AHC_LARGE_SEEPROM) - sd.sd_chip = C56_66; - else - sd.sd_chip = C46; - - sd.sd_MS = SEEMS; - sd.sd_RDY = SEERDY; - sd.sd_CS = SEECS; - sd.sd_CK = SEECK; - sd.sd_DO = SEEDO; - sd.sd_DI = SEEDI; - - have_seeprom = acquire_seeprom(ahc, &sd); - if (have_seeprom) { - - if (bootverbose) - printf("%s: Reading SEEPROM...", ahc_name(ahc)); - - for (;;) { - bus_size_t start_addr; - - start_addr = 32 * (ahc->channel - 'A'); - - have_seeprom = read_seeprom(&sd, (u_int16_t *)&sc, - start_addr, sizeof(sc)/2); - - if (have_seeprom) { - /* Check checksum */ - int i; - int maxaddr; - u_int32_t checksum; - u_int16_t *scarray; - - maxaddr = (sizeof(sc)/2) - 1; - checksum = 0; - scarray = (u_int16_t *)≻ - - for (i = 0; i < maxaddr; i++) - checksum = checksum + scarray[i]; - if (checksum == 0 - || (checksum & 0xFFFF) != sc.checksum) { - if (bootverbose && sd.sd_chip == C56_66) - printf ("checksum error\n"); - have_seeprom = 0; - } else { - if (bootverbose) - printf("done.\n"); - break; - } - } - - if (sd.sd_chip == C56_66) - break; - sd.sd_chip = C56_66; - } - } - - if (!have_seeprom) { - if (bootverbose) - printf("%s: No SEEPROM available.\n", ahc_name(ahc)); - ahc->flags |= AHC_USEDEFAULTS; - } else { - /* - * Put the data we've collected down into SRAM - * where ahc_init will find it. - */ - int i; - int max_targ = sc.max_targets & CFMAXTARG; - u_int16_t discenable; - u_int16_t ultraenb; - - discenable = 0; - ultraenb = 0; - if ((sc.adapter_control & CFULTRAEN) != 0) { - /* - * Determine if this adapter has a "newstyle" - * SEEPROM format. - */ - for (i = 0; i < max_targ; i++) { - if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0){ - ahc->flags |= AHC_NEWEEPROM_FMT; - break; - } - } - } - - for (i = 0; i < max_targ; i++) { - u_int scsirate; - u_int16_t target_mask; - - target_mask = 0x01 << i; - if (sc.device_flags[i] & CFDISC) - discenable |= target_mask; - if ((ahc->flags & AHC_NEWEEPROM_FMT) != 0) { - if ((sc.device_flags[i] & CFSYNCHISULTRA) != 0) - ultraenb |= target_mask; - } else if ((sc.adapter_control & CFULTRAEN) != 0) { - ultraenb |= target_mask; - } - if ((sc.device_flags[i] & CFXFER) == 0x04 - && (ultraenb & target_mask) != 0) { - /* Treat 10MHz as a non-ultra speed */ - sc.device_flags[i] &= ~CFXFER; - ultraenb &= ~target_mask; - } - if ((ahc->features & AHC_ULTRA2) != 0) { - u_int offset; - - if (sc.device_flags[i] & CFSYNCH) - offset = MAX_OFFSET_ULTRA2; - else - offset = 0; - ahc_outb(ahc, TARG_OFFSET + i, offset); - - scsirate = (sc.device_flags[i] & CFXFER) - | ((ultraenb & target_mask) - ? 0x8 : 0x0); - if (sc.device_flags[i] & CFWIDEB) - scsirate |= WIDEXFER; - } else { - scsirate = (sc.device_flags[i] & CFXFER) << 4; - if (sc.device_flags[i] & CFSYNCH) - scsirate |= SOFS; - if (sc.device_flags[i] & CFWIDEB) - scsirate |= WIDEXFER; - } - ahc_outb(ahc, TARG_SCSIRATE + i, scsirate); - } - ahc->our_id = sc.brtime_id & CFSCSIID; - - scsi_conf = (ahc->our_id & 0x7); - if (sc.adapter_control & CFSPARITY) - scsi_conf |= ENSPCHK; - if (sc.adapter_control & CFRESETB) - scsi_conf |= RESET_SCSI; - - if (sc.bios_control & CFEXTEND) - ahc->flags |= AHC_EXTENDED_TRANS_A; - if (ahc->features & AHC_ULTRA - && (ahc->flags & AHC_NEWEEPROM_FMT) == 0) { - /* Should we enable Ultra mode? */ - if (!(sc.adapter_control & CFULTRAEN)) - /* Treat us as a non-ultra card */ - ultraenb = 0; - } - /* Set SCSICONF info */ - ahc_outb(ahc, SCSICONF, scsi_conf); - ahc_outb(ahc, DISC_DSB, ~(discenable & 0xff)); - ahc_outb(ahc, DISC_DSB + 1, ~((discenable >> 8) & 0xff)); - ahc_outb(ahc, ULTRA_ENB, ultraenb & 0xff); - ahc_outb(ahc, ULTRA_ENB + 1, (ultraenb >> 8) & 0xff); - } - - /* - * Cards that have the external logic necessary to talk to - * a SEEPROM, are almost certain to have the remaining logic - * necessary for auto-termination control. This assumption - * hasn't failed yet... - */ - have_autoterm = have_seeprom; - if (have_seeprom) - adapter_control = sc.adapter_control; - else - adapter_control = CFAUTOTERM; - - /* - * Some low-cost chips have SEEPROM and auto-term control built - * in, instead of using a GAL. They can tell us directly - * if the termination logic is enabled. - */ - if ((ahc->features & AHC_SPIOCAP) != 0) { - if ((ahc_inb(ahc, SPIOCAP) & SSPIOCPS) != 0) - have_autoterm = TRUE; - else - have_autoterm = FALSE; - } - - if (have_autoterm) - configure_termination(ahc, &sd, adapter_control, sxfrctl1); - - release_seeprom(&sd); -} - -static void -configure_termination(struct ahc_softc *ahc, - struct seeprom_descriptor *sd, - u_int adapter_control, - u_int *sxfrctl1) -{ - u_int8_t brddat; - - brddat = 0; - - /* - * Update the settings in sxfrctl1 to match the - * termination settings - */ - *sxfrctl1 = 0; - - /* - * SEECS must be on for the GALS to latch - * the data properly. Be sure to leave MS - * on or we will release the seeprom. - */ - SEEPROM_OUTB(sd, sd->sd_MS | sd->sd_CS); - if ((adapter_control & CFAUTOTERM) != 0 - || (ahc->features & AHC_NEW_TERMCTL) != 0) { - int internal50_present; - int internal68_present; - int externalcable_present; - int eeprom_present; - int enableSEC_low; - int enableSEC_high; - int enablePRI_low; - int enablePRI_high; - - enableSEC_low = 0; - enableSEC_high = 0; - enablePRI_low = 0; - enablePRI_high = 0; - if ((ahc->features & AHC_NEW_TERMCTL) != 0) { - ahc_new_term_detect(ahc, &enableSEC_low, - &enableSEC_high, - &enablePRI_low, - &enablePRI_high, - &eeprom_present); - if ((adapter_control & CFSEAUTOTERM) == 0) { - if (bootverbose) - printf("%s: Manual SE Termination\n", - ahc_name(ahc)); - enableSEC_low = (adapter_control & CFSTERM); - enableSEC_high = (adapter_control & CFWSTERM); - } - if ((adapter_control & CFAUTOTERM) == 0) { - if (bootverbose) - printf("%s: Manual LVD Termination\n", - ahc_name(ahc)); - enablePRI_low = enablePRI_high = - (adapter_control & CFLVDSTERM); - } - /* Make the table calculations below happy */ - internal50_present = 0; - internal68_present = 1; - externalcable_present = 1; - } else if ((ahc->features & AHC_SPIOCAP) != 0) { - aic785X_cable_detect(ahc, &internal50_present, - &externalcable_present, - &eeprom_present); - } else { - aic787X_cable_detect(ahc, &internal50_present, - &internal68_present, - &externalcable_present, - &eeprom_present); - } - - if ((ahc->features & AHC_WIDE) == 0) - internal68_present = 0; - - if (bootverbose) { - if ((ahc->features & AHC_ULTRA2) == 0) { - printf("%s: internal 50 cable %s present, " - "internal 68 cable %s present\n", - ahc_name(ahc), - internal50_present ? "is":"not", - internal68_present ? "is":"not"); - - printf("%s: external cable %s present\n", - ahc_name(ahc), - externalcable_present ? "is":"not"); - } - printf("%s: BIOS eeprom %s present\n", - ahc_name(ahc), eeprom_present ? "is" : "not"); - } - - if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) { - /* - * The 50 pin connector is a separate bus, - * so force it to always be terminated. - * In the future, perform current sensing - * to determine if we are in the middle of - * a properly terminated bus. - */ - internal50_present = 0; - } - - /* - * Now set the termination based on what - * we found. - * Flash Enable = BRDDAT7 - * Secondary High Term Enable = BRDDAT6 - * Secondary Low Term Enable = BRDDAT5 (7890) - * Primary High Term Enable = BRDDAT4 (7890) - */ - if ((ahc->features & AHC_ULTRA2) == 0 - && (internal50_present != 0) - && (internal68_present != 0) - && (externalcable_present != 0)) { - printf("%s: Illegal cable configuration!!. " - "Only two connectors on the " - "adapter may be used at a " - "time!\n", ahc_name(ahc)); - } - - if ((ahc->features & AHC_WIDE) != 0 - && ((externalcable_present == 0) - || (internal68_present == 0) - || (enableSEC_high != 0))) { - brddat |= BRDDAT6; - if (bootverbose) { - if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) - printf("%s: 68 pin termination " - "Enabled\n", ahc_name(ahc)); - else - printf("%s: %sHigh byte termination " - "Enabled\n", ahc_name(ahc), - enableSEC_high ? "Secondary " - : ""); - } - } - - if (((internal50_present ? 1 : 0) - + (internal68_present ? 1 : 0) - + (externalcable_present ? 1 : 0)) <= 1 - || (enableSEC_low != 0)) { - if ((ahc->features & AHC_ULTRA2) != 0) - brddat |= BRDDAT5; - else - *sxfrctl1 |= STPWEN; - if (bootverbose) { - if ((ahc->flags & AHC_INT50_SPEEDFLEX) != 0) - printf("%s: 50 pin termination " - "Enabled\n", ahc_name(ahc)); - else - printf("%s: %sLow byte termination " - "Enabled\n", ahc_name(ahc), - enableSEC_low ? "Secondary " - : ""); - } - } - - if (enablePRI_low != 0) { - *sxfrctl1 |= STPWEN; - if (bootverbose) - printf("%s: Primary Low Byte termination " - "Enabled\n", ahc_name(ahc)); - } - - /* - * Setup STPWEN before setting up the rest of - * the termination per the tech note on the U160 cards. - */ - ahc_outb(ahc, SXFRCTL1, *sxfrctl1); - - if (enablePRI_high != 0) { - brddat |= BRDDAT4; - if (bootverbose) - printf("%s: Primary High Byte " - "termination Enabled\n", - ahc_name(ahc)); - } - - write_brdctl(ahc, brddat); - - } else { - if ((adapter_control & CFSTERM) != 0) { - *sxfrctl1 |= STPWEN; - - if (bootverbose) - printf("%s: %sLow byte termination Enabled\n", - ahc_name(ahc), - (ahc->features & AHC_ULTRA2) ? "Primary " - : ""); - } - - if ((adapter_control & CFWSTERM) != 0) { - brddat |= BRDDAT6; - if (bootverbose) - printf("%s: %sHigh byte termination Enabled\n", - ahc_name(ahc), - (ahc->features & AHC_ULTRA2) - ? "Secondary " : ""); - } - - /* - * Setup STPWEN before setting up the rest of - * the termination per the tech note on the U160 cards. - */ - ahc_outb(ahc, SXFRCTL1, *sxfrctl1); - - write_brdctl(ahc, brddat); - } - SEEPROM_OUTB(sd, sd->sd_MS); /* Clear CS */ -} - -static void -ahc_new_term_detect(struct ahc_softc *ahc, int *enableSEC_low, - int *enableSEC_high, int *enablePRI_low, - int *enablePRI_high, int *eeprom_present) -{ - u_int8_t brdctl; - - /* - * BRDDAT7 = Eeprom - * BRDDAT6 = Enable Secondary High Byte termination - * BRDDAT5 = Enable Secondary Low Byte termination - * BRDDAT4 = Enable Primary high byte termination - * BRDDAT3 = Enable Primary low byte termination - */ - brdctl = read_brdctl(ahc); - *eeprom_present = brdctl & BRDDAT7; - *enableSEC_high = (brdctl & BRDDAT6); - *enableSEC_low = (brdctl & BRDDAT5); - *enablePRI_high = (brdctl & BRDDAT4); - *enablePRI_low = (brdctl & BRDDAT3); -} - -static void -aic787X_cable_detect(struct ahc_softc *ahc, int *internal50_present, - int *internal68_present, int *externalcable_present, - int *eeprom_present) -{ - u_int8_t brdctl; - - /* - * First read the status of our cables. - * Set the rom bank to 0 since the - * bank setting serves as a multiplexor - * for the cable detection logic. - * BRDDAT5 controls the bank switch. - */ - write_brdctl(ahc, 0); - - /* - * Now read the state of the internal - * connectors. BRDDAT6 is INT50 and - * BRDDAT7 is INT68. - */ - brdctl = read_brdctl(ahc); - *internal50_present = !(brdctl & BRDDAT6); - *internal68_present = !(brdctl & BRDDAT7); - - /* - * Set the rom bank to 1 and determine - * the other signals. - */ - write_brdctl(ahc, BRDDAT5); - - /* - * Now read the state of the external - * connectors. BRDDAT6 is EXT68 and - * BRDDAT7 is EPROMPS. - */ - brdctl = read_brdctl(ahc); - *externalcable_present = !(brdctl & BRDDAT6); - *eeprom_present = brdctl & BRDDAT7; -} - -static void -aic785X_cable_detect(struct ahc_softc *ahc, int *internal50_present, - int *externalcable_present, int *eeprom_present) -{ - u_int8_t brdctl; - - ahc_outb(ahc, BRDCTL, BRDRW|BRDCS); - ahc_outb(ahc, BRDCTL, 0); - brdctl = ahc_inb(ahc, BRDCTL); - *internal50_present = !(brdctl & BRDDAT5); - *externalcable_present = !(brdctl & BRDDAT6); - - *eeprom_present = (ahc_inb(ahc, SPIOCAP) & EEPROM) != 0; -} - -static int -acquire_seeprom(struct ahc_softc *ahc, struct seeprom_descriptor *sd) -{ - int wait; - - if ((ahc->features & AHC_SPIOCAP) != 0 - && (ahc_inb(ahc, SPIOCAP) & SEEPROM) == 0) - return (0); - - /* - * Request access of the memory port. When access is - * granted, SEERDY will go high. We use a 1 second - * timeout which should be near 1 second more than - * is needed. Reason: after the chip reset, there - * should be no contention. - */ - SEEPROM_OUTB(sd, sd->sd_MS); - wait = 1000; /* 1 second timeout in msec */ - while (--wait && ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0)) { - DELAY(1000); /* delay 1 msec */ - } - if ((SEEPROM_STATUS_INB(sd) & sd->sd_RDY) == 0) { - SEEPROM_OUTB(sd, 0); - return (0); - } - return(1); -} - -static void -release_seeprom(sd) - struct seeprom_descriptor *sd; -{ - /* Release access to the memory port and the serial EEPROM. */ - SEEPROM_OUTB(sd, 0); -} - -static void -write_brdctl(ahc, value) - struct ahc_softc *ahc; - u_int8_t value; -{ - u_int8_t brdctl; - - if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { - brdctl = BRDSTB; - if (ahc->channel == 'B') - brdctl |= BRDCS; - } else if ((ahc->features & AHC_ULTRA2) != 0) { - brdctl = 0; - } else { - brdctl = BRDSTB|BRDCS; - } - ahc_outb(ahc, BRDCTL, brdctl); - DELAY(20); - brdctl |= value; - ahc_outb(ahc, BRDCTL, brdctl); - DELAY(20); - if ((ahc->features & AHC_ULTRA2) != 0) - brdctl |= BRDSTB_ULTRA2; - else - brdctl &= ~BRDSTB; - ahc_outb(ahc, BRDCTL, brdctl); - DELAY(20); - if ((ahc->features & AHC_ULTRA2) != 0) - brdctl = 0; - else - brdctl &= ~BRDCS; - ahc_outb(ahc, BRDCTL, brdctl); -} - -static u_int8_t -read_brdctl(ahc) - struct ahc_softc *ahc; -{ - u_int8_t brdctl; - u_int8_t value; - - if ((ahc->chip & AHC_CHIPID_MASK) == AHC_AIC7895) { - brdctl = BRDRW; - if (ahc->channel == 'B') - brdctl |= BRDCS; - } else if ((ahc->features & AHC_ULTRA2) != 0) { - brdctl = BRDRW_ULTRA2; - } else { - brdctl = BRDRW|BRDCS; - } - ahc_outb(ahc, BRDCTL, brdctl); - DELAY(20); - value = ahc_inb(ahc, BRDCTL); - ahc_outb(ahc, BRDCTL, 0); - return (value); -} - -#define DPE 0x80 -#define SSE 0x40 -#define RMA 0x20 -#define RTA 0x10 -#define STA 0x08 -#define DPR 0x01 - -void -ahc_pci_intr(struct ahc_softc *ahc) -{ - u_int8_t status1; - - status1 = pci_read_config(ahc->device, PCIR_STATUS + 1, /*bytes*/1); - - if (status1 & DPE) { - printf("%s: Data Parity Error Detected during address " - "or write data phase\n", ahc_name(ahc)); - } - if (status1 & SSE) { - printf("%s: Signal System Error Detected\n", ahc_name(ahc)); - } - if (status1 & RMA) { - printf("%s: Received a Master Abort\n", ahc_name(ahc)); - } - if (status1 & RTA) { - printf("%s: Received a Target Abort\n", ahc_name(ahc)); - } - if (status1 & STA) { - printf("%s: Signaled a Target Abort\n", ahc_name(ahc)); - } - if (status1 & DPR) { - printf("%s: Data Parity Error has been reported via PERR#\n", - ahc_name(ahc)); - } - if ((status1 & (DPE|SSE|RMA|RTA|STA|DPR)) == 0) { - printf("%s: Latched PCIERR interrupt with " - "no status bits set\n", ahc_name(ahc)); - } - pci_write_config(ahc->device, PCIR_STATUS + 1, status1, /*bytes*/1); - - if (status1 & (DPR|RMA|RTA)) { - ahc_outb(ahc, CLRINT, CLRPARERR); - } -} - -static int -ahc_aic7850_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7850; - *features = AHC_AIC7850_FE; - return (0); -} - -static int -ahc_aic7855_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7855; - *features = AHC_AIC7855_FE; - return (0); -} - -static int -ahc_aic7859_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7859; - *features = AHC_AIC7859_FE; - return (0); -} - -static int -ahc_aic7860_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7860; - *features = AHC_AIC7860_FE; - return (0); -} - -static int -ahc_aic7870_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7870; - *features = AHC_AIC7870_FE; - return (0); -} - -static int -ahc_aha394X_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - int error; - - error = ahc_aic7870_setup(dev, channel, chip, features, flags); - if (error == 0) - error = ahc_aha394XX_setup(dev, channel, chip, features, flags); - return (error); -} - -static int -ahc_aha398X_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - int error; - - error = ahc_aic7870_setup(dev, channel, chip, features, flags); - if (error == 0) - error = ahc_aha398XX_setup(dev, channel, chip, features, flags); - return (error); -} - -static int -ahc_aic7880_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7880; - *features = AHC_AIC7880_FE; - return (0); -} - -static int -ahc_2940Pro_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - int error; - - *flags |= AHC_INT50_SPEEDFLEX; - error = ahc_aic7880_setup(dev, channel, chip, features, flags); - return (0); -} - -static int -ahc_aha394XU_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - int error; - - error = ahc_aic7880_setup(dev, channel, chip, features, flags); - if (error == 0) - error = ahc_aha394XX_setup(dev, channel, chip, features, flags); - return (error); -} - -static int -ahc_aha398XU_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - int error; - - error = ahc_aic7880_setup(dev, channel, chip, features, flags); - if (error == 0) - error = ahc_aha398XX_setup(dev, channel, chip, features, flags); - return (error); -} - -static int -ahc_aic7890_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7890; - *features = AHC_AIC7890_FE; - *flags |= AHC_NEWEEPROM_FMT; - return (0); -} - -static int -ahc_aic7892_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = 'A'; - *chip = AHC_AIC7892; - *features = AHC_AIC7892_FE; - *flags |= AHC_NEWEEPROM_FMT; - return (0); -} - -static int -ahc_aic7895_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - u_int32_t devconfig; - - *channel = pci_get_function(dev) == 1 ? 'B' : 'A'; - *chip = AHC_AIC7895; - /* The 'C' revision of the aic7895 has a few additional features */ - if (pci_get_revid(dev) >= 4) - *features = AHC_AIC7895C_FE; - else - *features = AHC_AIC7895_FE; - *flags |= AHC_NEWEEPROM_FMT; - devconfig = pci_read_config(dev, DEVCONFIG, /*bytes*/4); - devconfig &= ~SCBSIZE32; - pci_write_config(dev, DEVCONFIG, devconfig, /*bytes*/4); - return (0); -} - -static int -ahc_aic7896_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = pci_get_function(dev) == 1 ? 'B' : 'A'; - *chip = AHC_AIC7896; - *features = AHC_AIC7896_FE; - *flags |= AHC_NEWEEPROM_FMT; - return (0); -} - -static int -ahc_aic7899_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - *channel = pci_get_function(dev) == 1 ? 'B' : 'A'; - *chip = AHC_AIC7899; - *features = AHC_AIC7899_FE; - *flags |= AHC_NEWEEPROM_FMT; - return (0); -} - -static int -ahc_raid_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - printf("RAID functionality unsupported\n"); - return (ENXIO); -} - -static int -ahc_aha394XX_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - switch (pci_get_slot(dev)) { - case AHC_394X_SLOT_CHANNEL_A: - *channel = 'A'; - break; - case AHC_394X_SLOT_CHANNEL_B: - *channel = 'B'; - break; - default: - printf("adapter at unexpected slot %d\n" - "unable to map to a channel\n", - pci_get_slot(dev)); - *channel = 'A'; - } - return (0); -} - -static int -ahc_aha398XX_setup(device_t dev, char *channel, ahc_chip *chip, - ahc_feature *features, ahc_flag *flags) -{ - switch (pci_get_slot(dev)) { - case AHC_398X_SLOT_CHANNEL_A: - *channel = 'A'; - break; - case AHC_398X_SLOT_CHANNEL_B: - *channel = 'B'; - break; - case AHC_398X_SLOT_CHANNEL_C: - *channel = 'C'; - break; - default: - printf("adapter at unexpected slot %d\n" - "unable to map to a channel\n", - pci_get_slot(dev)); - *channel = 'A'; - } - *flags |= AHC_LARGE_SEEPROM; - return (0); -} diff --git a/sys/pci/if_fpa.c b/sys/pci/if_fpa.c deleted file mode 100644 index d70628a..0000000 --- a/sys/pci/if_fpa.c +++ /dev/null @@ -1,441 +0,0 @@ -/*- - * Copyright (c) 1995, 1996 Matt Thomas <matt@3am-software.com> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. The name of the author may not be used to endorse or promote products - * derived from this software withough specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - * - */ - -/* - * DEC PDQ FDDI Controller; code for BSD derived operating systems - * - * This module supports the DEC DEFPA PCI FDDI Controller - */ - -#include <sys/param.h> -#include <sys/kernel.h> -#include <sys/socket.h> -#if defined(__bsdi__) || defined(__NetBSD__) -#include <sys/device.h> -#endif - -#include <net/if.h> - -#if defined(__FreeBSD__) -#include "fpa.h" -#include <sys/eventhandler.h> -#include <net/ethernet.h> -#include <net/if_arp.h> -#include <pci/pcivar.h> -#include <dev/pdq/pdqvar.h> -#include <dev/pdq/pdqreg.h> -#elif defined(__bsdi__) -#include <i386/isa/isavar.h> -#include <i386/isa/icu.h> -#ifndef DRQNONE -#define DRQNONE 0 -#endif -#if _BSDI_VERSION < 199401 -#define IRQSHARE 0 -#endif -#elif defined(__NetBSD__) -#include <dev/pci/pcivar.h> -#include <dev/ic/pdqvar.h> -#include <dev/ic/pdqreg.h> -#endif /* __NetBSD__ */ - - -#define DEC_VENDORID 0x1011 -#define DEFPA_CHIPID 0x000F -#define PCI_VENDORID(x) ((x) & 0xFFFF) -#define PCI_CHIPID(x) (((x) >> 16) & 0xFFFF) - -#define DEFPA_LATENCY 0x88 - -#define PCI_CFLT 0x0C /* Configuration Latency */ -#define PCI_CBMA 0x10 /* Configuration Base Memory Address */ -#define PCI_CBIO 0x14 /* Configuration Base I/O Address */ - -#if defined(__FreeBSD__) -#if NFPA < 4 -#undef NFPA -#define NFPA 4 -#endif -static pdq_softc_t *pdqs_pci[NFPA]; -#define PDQ_PCI_UNIT_TO_SOFTC(unit) (pdqs_pci[unit]) -#if BSD >= 199506 -#define pdq_pci_ifwatchdog NULL -#endif - -#elif defined(__bsdi__) -extern struct cfdriver fpacd; -#define PDQ_PCI_UNIT_TO_SOFTC(unit) ((pdq_softc_t *)fpacd.cd_devs[unit]) - -#elif defined(__NetBSD__) -extern struct cfattach fpa_ca; -extern struct cfdriver fpa_cd; -#define PDQ_PCI_UNIT_TO_SOFTC(unit) ((pdq_softc_t *)fpa_cd.cd_devs[unit]) -#define pdq_pci_ifwatchdog NULL -#endif - -#ifndef pdq_pci_ifwatchdog -static ifnet_ret_t -pdq_pci_ifwatchdog( - int unit) -{ - pdq_ifwatchdog(&PDQ_PCI_UNIT_TO_SOFTC(unit)->sc_if); -} -#endif - -#if defined(__FreeBSD__) && BSD >= 199506 -static void -pdq_pci_ifintr( - void *arg) -{ - (void) pdq_interrupt(((pdq_softc_t *) arg)->sc_pdq); -} -#else -static int -pdq_pci_ifintr( - void *arg) -{ - pdq_softc_t * const sc = (pdq_softc_t *) arg; -#ifdef __FreeBSD__ - return pdq_interrupt(sc->sc_pdq); -#elif defined(__bsdi__) || defined(__NetBSD__) - (void) pdq_interrupt(sc->sc_pdq); - return 1; -#endif -} -#endif /* __FreeBSD && BSD */ - -#if defined(__FreeBSD__) -static void pdq_pci_shutdown(void *, int); - -/* - * This is the PCI configuration support. Since the PDQ is available - * on both EISA and PCI boards, one must be careful in how defines the - * PDQ in the config file. - */ -static const char * -pdq_pci_probe( - pcici_t config_id, - pcidi_t device_id) -{ - if (PCI_VENDORID(device_id) == DEC_VENDORID && - PCI_CHIPID(device_id) == DEFPA_CHIPID) - return "Digital DEFPA PCI FDDI Controller"; - return NULL; -} - -static void -pdq_pci_attach( - pcici_t config_id, - int unit) -{ - pdq_softc_t *sc; - vm_offset_t va_csrs, pa_csrs; - pdq_uint32_t data; - - if (unit == NFPA) { - printf("fpa%d: not configured; kernel is built for only %d device%s.\n", - unit, NFPA, NFPA == 1 ? "" : "s"); - return; - } - - data = pci_conf_read(config_id, PCI_CFLT); - if ((data & 0xFF00) < (DEFPA_LATENCY << 8)) { - data &= ~0xFF00; - data |= DEFPA_LATENCY << 8; - pci_conf_write(config_id, PCI_CFLT, data); - } - - sc = (pdq_softc_t *) malloc(sizeof(*sc), M_DEVBUF, M_NOWAIT); - if (sc == NULL) - return; - - bzero(sc, sizeof(pdq_softc_t)); /* Zero out the softc*/ - if (!pci_map_mem(config_id, PCI_CBMA, &va_csrs, &pa_csrs)) { - free((void *) sc, M_DEVBUF); - return; - } - - sc->sc_if.if_name = "fpa"; - sc->sc_if.if_unit = unit; - sc->sc_membase = (pdq_bus_memaddr_t) va_csrs; - sc->sc_pdq = pdq_initialize(PDQ_BUS_PCI, sc->sc_membase, - sc->sc_if.if_name, sc->sc_if.if_unit, - (void *) sc, PDQ_DEFPA); - if (sc->sc_pdq == NULL) { - free((void *) sc, M_DEVBUF); - return; - } - bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); - pdqs_pci[unit] = sc; - pdq_ifattach(sc, pdq_pci_ifwatchdog); - pci_map_int(config_id, pdq_pci_ifintr, (void*) sc, &net_imask); - EVENTHANDLER_REGISTER(shutdown_post_sync, pdq_pci_shutdown, sc, - SHUTDOWN_PRI_DEFAULT); - -} - -static void -pdq_pci_shutdown( - void *sc, - int howto) -{ - pdq_hwreset(((pdq_softc_t *)sc)->sc_pdq); -} - -static u_long pdq_pci_count; - -static struct pci_device fpadevice = { - "fpa", - pdq_pci_probe, - pdq_pci_attach, - &pdq_pci_count, - NULL -}; - -COMPAT_PCI_DRIVER (fpa, fpadevice); - -#elif defined(__bsdi__) - -static int -pdq_pci_match( - pci_devaddr_t *pa) -{ - int irq; - int id; - - id = pci_inl(pa, PCI_VENDOR_ID); - if (PCI_VENDORID(id) != DEC_VENDORID || PCI_CHIPID(id) != DEFPA_CHIPID) - return 0; - - irq = pci_inl(pa, PCI_I_LINE) & 0xFF; - if (irq == 0 || irq >= 16) - return 0; - - return 1; -} - -int -pdq_pci_probe( - struct device *parent, - struct cfdata *cf, - void *aux) -{ - struct isa_attach_args *ia = (struct isa_attach_args *) aux; - pdq_uint32_t irq, data; - pci_devaddr_t *pa; - - pa = pci_scan(pdq_pci_match); - if (pa == NULL) - return 0; - - irq = (1 << (pci_inl(pa, PCI_I_LINE) & 0xFF)); - - if (ia->ia_irq != IRQUNK && irq != ia->ia_irq) { - printf("fpa%d: error: desired IRQ of %d does not match device's actual IRQ of %d\n", - cf->cf_unit, - ffs(ia->ia_irq) - 1, ffs(irq) - 1); - return 0; - } - if (ia->ia_irq == IRQUNK) { - (void) isa_irqalloc(irq); - ia->ia_irq = irq; - } - - /* PCI bus masters don't use host DMA channels */ - ia->ia_drq = DRQNONE; - - /* Get the memory base address; assume the BIOS set it up correctly */ - ia->ia_maddr = (caddr_t) (pci_inl(pa, PCI_CBMA) & ~7); - pci_outl(pa, PCI_CBMA, 0xFFFFFFFF); - ia->ia_msize = ((~pci_inl(pa, PCI_CBMA)) | 7) + 1; - pci_outl(pa, PCI_CBMA, (int) ia->ia_maddr); - - /* Disable I/O space access */ - pci_outl(pa, PCI_COMMAND, pci_inl(pa, PCI_COMMAND) & ~1); - ia->ia_iobase = 0; - ia->ia_iosize = 0; - - /* Make sure the latency timer is what the DEFPA likes */ - data = pci_inl(pa, PCI_CFLT); - if ((data & 0xFF00) < (DEFPA_LATENCY << 8)) { - data &= ~0xFF00; - data |= DEFPA_LATENCY << 8; - pci_outl(pa, PCI_CFLT, data); - } - ia->ia_irq |= IRQSHARE; - - return 1; -} - -void -pdq_pci_attach( - struct device *parent, - struct device *self, - void *aux) -{ - pdq_softc_t *sc = (pdq_softc_t *) self; - register struct isa_attach_args *ia = (struct isa_attach_args *) aux; - register struct ifnet *ifp = &sc->sc_if; - int i; - - sc->sc_if.if_unit = sc->sc_dev.dv_unit; - sc->sc_if.if_name = "fpa"; - sc->sc_if.if_flags = 0; - sc->sc_membase = (pdq_bus_memaddr_t) mapphys((vm_offset_t)ia->ia_maddr, ia->ia_msize); - - sc->sc_pdq = pdq_initialize(PDQ_BUS_PCI, sc->sc_membase, - sc->sc_if.if_name, sc->sc_if.if_unit, - (void *) sc, PDQ_DEFPA); - if (sc->sc_pdq == NULL) { - printf("fpa%d: initialization failed\n", sc->sc_if.if_unit); - return; - } - - bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); - - pdq_ifattach(sc, pdq_pci_ifwatchdog); - - isa_establish(&sc->sc_id, &sc->sc_dev); - - sc->sc_ih.ih_fun = pdq_pci_ifintr; - sc->sc_ih.ih_arg = (void *)sc; - intr_establish(ia->ia_irq, &sc->sc_ih, DV_NET); - - sc->sc_ats.func = (void (*)(void *)) pdq_hwreset; - sc->sc_ats.arg = (void *) sc->sc_pdq; - atshutdown(&sc->sc_ats, ATSH_ADD); -} - -struct cfdriver fpacd = { - 0, "fpa", pdq_pci_probe, pdq_pci_attach, -#if _BSDI_VERSION >= 199401 - DV_IFNET, -#endif - sizeof(pdq_softc_t) -}; - -#elif defined(__NetBSD__) - -static int -pdq_pci_match( - struct device *parent, - void *match, - void *aux) -{ - struct pci_attach_args *pa = (struct pci_attach_args *) aux; - - if (PCI_VENDORID(pa->pa_id) != DEC_VENDORID) - return 0; - if (PCI_CHIPID(pa->pa_id) == DEFPA_CHIPID) - return 1; - - return 0; -} - -static void -pdq_pci_attach( - struct device * const parent, - struct device * const self, - void * const aux) -{ - pdq_softc_t * const sc = (pdq_softc_t *) self; - struct pci_attach_args * const pa = (struct pci_attach_args *) aux; - pdq_uint32_t data; - pci_intr_handle_t intrhandle; - const char *intrstr; -#ifdef PDQ_IOMAPPED - bus_io_addr_t iobase; - bus_io_size_t iosize; -#else - bus_mem_addr_t membase; - bus_mem_size_t memsize; -#endif - - data = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_CFLT); - if ((data & 0xFF00) < (DEFPA_LATENCY << 8)) { - data &= ~0xFF00; - data |= DEFPA_LATENCY << 8; - pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_CFLT, data); - } - - sc->sc_bc = pa->pa_bc; - bcopy(sc->sc_dev.dv_xname, sc->sc_if.if_xname, IFNAMSIZ); - sc->sc_if.if_flags = 0; - sc->sc_if.if_softc = sc; - -#ifdef PDQ_IOMAPPED - if (pci_io_find(pa->pa_pc, pa->pa_tag, PCI_CBIO, &iobase, &iosize) - || bus_io_map(pa->pa_bc, iobase, iosize, &sc->sc_iobase)) - return; -#else - if (pci_mem_find(pa->pa_pc, pa->pa_tag, PCI_CBMA, &membase, &memsize, NULL) - || bus_mem_map(pa->pa_bc, membase, memsize, 0, &sc->sc_membase)) - return; -#endif - - sc->sc_pdq = pdq_initialize(sc->sc_bc, sc->sc_membase, - sc->sc_if.if_xname, 0, - (void *) sc, PDQ_DEFPA); - if (sc->sc_pdq == NULL) { - printf("%s: initialization failed\n", sc->sc_dev.dv_xname); - return; - } - - bcopy((caddr_t) sc->sc_pdq->pdq_hwaddr.lanaddr_bytes, sc->sc_ac.ac_enaddr, 6); - pdq_ifattach(sc, pdq_pci_ifwatchdog); - - if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, - pa->pa_intrline, &intrhandle)) { - printf("%s: couldn't map interrupt\n", self->dv_xname); - return; - } - intrstr = pci_intr_string(pa->pa_pc, intrhandle); - sc->sc_ih = pci_intr_establish(pa->pa_pc, intrhandle, IPL_NET, pdq_pci_ifintr, sc); - if (sc->sc_ih == NULL) { - printf("%s: couldn't establish interrupt", self->dv_xname); - if (intrstr != NULL) - printf(" at %s", intrstr); - printf("\n"); - return; - } - - sc->sc_ats = shutdownhook_establish((void (*)(void *)) pdq_hwreset, sc->sc_pdq); - if (sc->sc_ats == NULL) - printf("%s: warning: couldn't establish shutdown hook\n", self->dv_xname); - if (intrstr != NULL) - printf("%s: interrupting at %s\n", self->dv_xname, intrstr); -} - -struct cfattach fpa_ca = { - sizeof(pdq_softc_t), pdq_pci_match, pdq_pci_attach -}; - -struct cfdriver fpa_cd = { - 0, "fpa", DV_IFNET -}; - -#endif /* __NetBSD__ */ diff --git a/sys/pci/if_vx_pci.c b/sys/pci/if_vx_pci.c deleted file mode 100644 index e4910ad..0000000 --- a/sys/pci/if_vx_pci.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 1996 Naoki Hamada <nao@tom-yam.or.jp> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "vx.h" -#if NVX > 0 - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/eventhandler.h> -#include <sys/kernel.h> -#include <sys/socket.h> - -#include <net/if.h> -#include <net/if_arp.h> - -#include <pci/pcivar.h> - -#include <dev/vx/if_vxreg.h> - -static void vx_pci_shutdown(void *, int); -static const char *vx_pci_probe(pcici_t, pcidi_t); -static void vx_pci_attach(pcici_t, int unit); - -static void -vx_pci_shutdown( - void *sc, - int howto) -{ - vxstop(sc); - vxfree(sc); -} - -static const char* -vx_pci_probe( - pcici_t config_id, - pcidi_t device_id) -{ - if(device_id == 0x590010b7ul) - return "3COM 3C590 Etherlink III PCI"; - if(device_id == 0x595010b7ul || device_id == 0x595110b7ul || - device_id == 0x595210b7ul) - return "3COM 3C595 Fast Etherlink III PCI"; - /* - * The (Fast) Etherlink XL adapters are now supported by - * the xl driver, which uses bus master DMA and is much - * faster. (And which also supports the 3c905B. - */ -#ifdef VORTEX_ETHERLINK_XL - if(device_id == 0x900010b7ul || device_id == 0x900110b7ul) - return "3COM 3C900 Etherlink XL PCI"; - if(device_id == 0x905010b7ul || device_id == 0x905110b7ul) - return "3COM 3C905 Fast Etherlink XL PCI"; -#endif - return NULL; -} - -static void -vx_pci_attach( - pcici_t config_id, - int unit) -{ - struct vx_softc *sc; - - if (unit >= NVX) { - printf("vx%d: not configured; kernel is built for only %d device%s.\n", - unit, NVX, NVX == 1 ? "" : "s"); - return; - } - - if ((sc = vxalloc(unit)) == NULL) { - return; - } - - sc->vx_io_addr = pci_conf_read(config_id, 0x10) & 0xffffffe0; - - if (vxattach(sc) == 0) { - return; - } - - /* defect check for 3C590 */ - if ((pci_conf_read(config_id, 0) >> 16) == 0x5900) { - GO_WINDOW(0); - if (vxbusyeeprom(sc)) - return; - outw(BASE + VX_W0_EEPROM_COMMAND, EEPROM_CMD_RD | EEPROM_SOFT_INFO_2); - if (vxbusyeeprom(sc)) - return; - if (!(inw(BASE + VX_W0_EEPROM_DATA) & NO_RX_OVN_ANOMALY)) { - printf("Warning! Defective early revision adapter!\n"); - } - } - - /* - * Add shutdown hook so that DMA is disabled prior to reboot. Not - * doing do could allow DMA to corrupt kernel memory during the - * reboot before the driver initializes. - */ - EVENTHANDLER_REGISTER(shutdown_post_sync, vx_pci_shutdown, sc, - SHUTDOWN_PRI_DEFAULT); - - pci_map_int(config_id, vxintr, (void *) sc, &net_imask); -} - -static struct pci_device vxdevice = { - "vx", - vx_pci_probe, - vx_pci_attach, - &vx_count, - NULL -}; - -COMPAT_PCI_DRIVER (vx, vxdevice); - -#endif /* NVX */ |