-/* $OpenBSD: conf.c,v 1.4 1996/03/30 22:18:06 niklas Exp $ */
+/* $OpenBSD: conf.c,v 1.5 1996/04/27 18:38:45 niklas Exp $ */
/* $NetBSD: conf.c,v 1.33 1996/03/14 21:22:23 christos Exp $ */
/*-
dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
0, (dev_type_select((*))) enodev, (dev_type_mmap((*))) enodev }
+/* open, close, write, ioctl */
+#define cdev_lpt_init(c,n) { \
+ dev_init(c,n,open), dev_init(c,n,close), (dev_type_read((*))) enodev, \
+ dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \
+ 0, seltrue, (dev_type_mmap((*))) enodev }
+
cdev_decl(cn);
cdev_decl(ctty);
#define mmread mmrw
#define NIPF 0
#endif
+#include "com.h"
+cdev_decl(com);
+#include "lpt.h"
+cdev_decl(lpt);
+
struct cdevsw cdevsw[] =
{
cdev_cn_init(1,cn), /* 0: virtual console */
cdev_lkm_dummy(), /* 29 */
cdev_lkm_dummy(), /* 30 */
cdev_tty_init(NMSC,msc), /* 31: A2232 MSC Multiport serial */
- cdev_gen_ipf(NIPF,ipl), /* 32: IP filter log */
+ cdev_tty_init(NCOM,com), /* 32: ISA serial port */
+ cdev_lpt_init(NLPT,lpt), /* 33: ISA parallel printer */
+ cdev_gen_ipf(NIPF,ipl), /* 34: IP filter log */
};
int nchrdev = sizeof(cdevsw) / sizeof(cdevsw[0]);
*/
cons_decl(ser);
cons_decl(ite);
+cons_decl(com);
struct consdev constab[] = {
#if NSER > 0
#endif
#if NITE > 0
cons_init(ite),
+#endif
+#ifdef notyet
+#if NCOM > 0
+ cons_init(com),
+#endif
#endif
{ 0 },
};
+/* $OpenBSD: machdep.c,v 1.7 1996/04/27 18:38:46 niklas Exp $ */
/* $NetBSD: machdep.c,v 1.59 1995/10/09 04:33:58 chopps Exp $ */
/*
int ending_psw;
{
int i;
- int handled = 0;
- for (i = start_ipl; !handled && i >= isr_exter_lowipl; i--) {
+ for (i = start_ipl; i >= isr_exter_lowipl; i--) {
register int psw = i << 8 | PSL_S;
struct isr *isr;
return;
}
__asm __volatile("movew %0,sr" : : "d" (psw) : "cc");
- for (isr = isr_exter[i]; !handled && isr; isr = isr->isr_forw)
- handled = (*isr->isr_intr)(isr->isr_arg);
+ for (isr = isr_exter[i]; isr; isr = isr->isr_forw)
+ (*isr->isr_intr)(isr->isr_arg);
}
isr_exter_ipl = 0;
__asm __volatile("movew %0,sr" : : "di" (PSL_S|PSL_IPL6) : "cc");
-# $OpenBSD: FILIPPA,v 1.2 1996/02/26 23:07:41 niklas Exp $
+# $OpenBSD: FILIPPA,v 1.3 1996/04/27 18:38:48 niklas Exp $
#
# GENERIC AMIGA
# scsi stuff, all possible
-gvpbus* at zbus0
-gtsc0 at gvpbus? # GVP series II scsi
+#gvpbus* at zbus0
+#gtsc0 at gvpbus? # GVP series II scsi
#ahsc0 at mainbus0 # A3000 scsi
#atzsc0 at zbus0
#wstsc0 at zbus0 # Wordsync II scsi
cd0 at scsibus0 target 6 lun ? # scsi cd's
cd* at scsibus? target ? lun ? # scsi cd's
-ggbus0 at zbus0 # Goldengate bridge
-isa* at ggbus0
+ggbus* at zbus0 # Goldengate bridge
+isa* at ggbus?
-cross0 at zbus0 # CrossLink bridge
-isa* at cross0
+cross* at zbus0 # CrossLink bridge
+isa* at cross?
com0 at isa? port 0x3f8 irq 4 # Standard PC serial ports
com1 at isa? port 0x2f8 irq 3
com2 at isa? port 0x3e8 irq 5
com3 at isa? port 0x2e8 irq 9
-#com0 at isa? port 0x0f0 irq 11 # Crosslink builtin ports
-#com1 at isa? port 0x0f8 irq 10
-
ast0 at isa? port 0x1a0 irq 3 # AST 4-port serial cards
#com* at ast? slave ? flags 1
com4 at ast? slave ? flags 1
com6 at ast? slave ? flags 1
com7 at ast? slave ? flags 1
+com8 at isa? port 0x0f0 irq 11 # Crosslink builtin ports
+com9 at isa? port 0x0f8 irq 10
+
lpt0 at isa? port 0x378 irq 7 # Standard PC parallel ports
lpt1 at isa? port 0x278
lpt2 at isa? port 0x3bc
-# XXX should be ed0
+# XXX should be ed0 but clashes with Zorro ed device
isaed0 at isa? port 0x300 iomem 0xcc000 irq 10 # WD/SMC, 3C503, and NE[12]000
# ethernetcards
fd* at fdc0 unit ?
pseudo-device sl # slip
-pseudo-device ppp # ppp
+#pseudo-device ppp # ppp
pseudo-device view 10 # views
pseudo-device pty 32 # pseudo terminals
pseudo-device loop # network loopback
-# $OpenBSD: files.amiga,v 1.9 1996/04/21 22:14:53 deraadt Exp $
+# $OpenBSD: files.amiga,v 1.10 1996/04/27 18:38:49 niklas Exp $
# $NetBSD: files.amiga,v 1.41 1996/03/28 18:41:55 is Exp $
# maxpartitions must be first item in files.${ARCH}
define bridge {}
# GoldenGate bridge
-device ggbus at zbus: bridge
+device ggbus: isabus
+attach ggbus at zbus
file arch/amiga/isa/ggbus.c ggbus needs-flag
-file arch/amiga/isa/ggbus_pio.c ggbus
# CrossLink bridge
-device cross at zbus: bridge
+device cross: isabus
+attach cross at zbus
file arch/amiga/isa/cross.c cross needs-flag
-file arch/amiga/isa/cross_pio.c cross
-
-device isa at bridge {[port = -1], [size = 0], # XXX
- [iomem = -1], [iosiz = 0],
- [irq = -1], [drq = -1]}
# XXX Dummy busses needed for some multi-homed devices specified in files.isa
define pci { }
-device pcmciabus at isa {}
-file arch/amiga/conf/files.amiga pcmciabus needs-flag
include "../../../dev/isa/files.isa"
-file arch/amiga/isa/isa_machdep.c isa needs-flag # XXX
-# XXX should really use if_ed instead
-device isaed at isa: ifnet, ether
+# XXX should really use if_ed instead, but can't for the moment due to
+# name clashes with the amiga variant.
+device isaed: ifnet, ether
+attach isaed at isa
file arch/amiga/isa/if_isaed.c isaed
# list of standard files...
-/* $OpenBSD: clock.c,v 1.4 1996/04/21 22:15:01 deraadt Exp $ */
+/* $OpenBSD: clock.c,v 1.5 1996/04/27 18:38:50 niklas Exp $ */
/* $NetBSD: clock.c,v 1.12 1996/03/17 05:58:30 mhitch Exp $ */
/*
#include <sys/device.h>
#include <machine/psl.h>
#include <machine/cpu.h>
+#include <machine/intr.h>
#include <amiga/amiga/device.h>
#include <amiga/amiga/custom.h>
#include <amiga/amiga/cia.h>
-/* $OpenBSD: zssc.c,v 1.5 1996/04/21 22:15:51 deraadt Exp $ */
+/* $OpenBSD: zssc.c,v 1.6 1996/04/27 18:38:51 niklas Exp $ */
/* $NetBSD: zssc.c,v 1.15 1996/03/17 01:18:00 thorpej Exp $ */
/*
#include <sys/kernel.h>
#include <sys/device.h>
#include <machine/psl.h>
+#include <machine/intr.h>
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <amiga/amiga/custom.h>
--- /dev/null
+/* $OpenBSD: bus.h,v 1.1 1996/04/27 18:38:52 niklas Exp $ */
+
+/*
+ * Copyright (c) 1996 Niklas Hallqvist.
+ * 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 Niklas Hallqvist.
+ * 4. Neither the name of the University nor the names of its contributors
+ * 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 REGENTS 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.
+ */
+
+#ifndef _MACHINE_BUS_H_
+#define _MACHINE_BUS_H_
+
+/* I/O access types. */
+typedef u_long bus_io_addr_t;
+typedef u_long bus_io_size_t;
+typedef u_long bus_io_handle_t;
+
+/* Memory access types. */
+typedef u_long bus_mem_addr_t;
+typedef u_long bus_mem_size_t;
+typedef u_long bus_mem_handle_t;
+
+/*
+ * The big switch, that delegates each bus operation to the right
+ * implementation.
+ */
+typedef struct amiga_bus_chipset *bus_chipset_tag_t;
+
+struct amiga_bus_chipset {
+ void *bc_data;
+
+ int (*bc_io_map)(bus_chipset_tag_t, bus_io_addr_t, bus_io_size_t,
+ bus_io_handle_t *);
+ int (*bc_io_unmap)(bus_io_handle_t, bus_io_size_t);
+
+ u_int8_t (*bc_io_read_1)(bus_io_handle_t, bus_io_size_t);
+ u_int16_t (*bc_io_read_2)(bus_io_handle_t, bus_io_size_t);
+ u_int32_t (*bc_io_read_4)(bus_io_handle_t, bus_io_size_t);
+ u_int64_t (*bc_io_read_8)(bus_io_handle_t, bus_io_size_t);
+
+ void (*bc_io_read_multi_1)(bus_io_handle_t, bus_io_size_t,
+ u_int8_t *, bus_io_size_t);
+ void (*bc_io_read_multi_2)(bus_io_handle_t, bus_io_size_t,
+ u_int16_t *, bus_io_size_t);
+ void (*bc_io_read_multi_4)(bus_io_handle_t, bus_io_size_t,
+ u_int32_t *, bus_io_size_t);
+ void (*bc_io_read_multi_8)(bus_io_handle_t, bus_io_size_t,
+ u_int64_t *, bus_io_size_t);
+
+ void (*bc_io_write_1)(bus_io_handle_t, bus_io_size_t, u_int8_t);
+ void (*bc_io_write_2)(bus_io_handle_t, bus_io_size_t, u_int16_t);
+ void (*bc_io_write_4)(bus_io_handle_t, bus_io_size_t, u_int32_t);
+ void (*bc_io_write_8)(bus_io_handle_t, bus_io_size_t, u_int64_t);
+
+ void (*bc_io_write_multi_1)(bus_io_handle_t, bus_io_size_t,
+ const u_int8_t *, bus_io_size_t);
+ void (*bc_io_write_multi_2)(bus_io_handle_t, bus_io_size_t,
+ const u_int16_t *, bus_io_size_t);
+ void (*bc_io_write_multi_4)(bus_io_handle_t, bus_io_size_t,
+ const u_int32_t *, bus_io_size_t);
+ void (*bc_io_write_multi_8)(bus_io_handle_t, bus_io_size_t,
+ const u_int64_t *, bus_io_size_t);
+
+ int (*bc_mem_map)(bus_chipset_tag_t, bus_mem_addr_t,
+ bus_mem_size_t, int, bus_mem_handle_t *);
+ int (*bc_mem_unmap)(bus_mem_handle_t, bus_mem_size_t);
+
+ u_int8_t (*bc_mem_read_1)(bus_mem_handle_t, bus_mem_size_t);
+ u_int16_t (*bc_mem_read_2)(bus_mem_handle_t, bus_mem_size_t);
+ u_int32_t (*bc_mem_read_4)(bus_mem_handle_t, bus_mem_size_t);
+ u_int64_t (*bc_mem_read_8)(bus_mem_handle_t, bus_mem_size_t);
+
+ void (*bc_mem_write_1)(bus_mem_handle_t, bus_mem_size_t, u_int8_t);
+ void (*bc_mem_write_2)(bus_mem_handle_t, bus_mem_size_t, u_int16_t);
+ void (*bc_mem_write_4)(bus_mem_handle_t, bus_mem_size_t, u_int32_t);
+ void (*bc_mem_write_8)(bus_mem_handle_t, bus_mem_size_t, u_int64_t);
+
+ /* These are extensions to the general NetBSD bus interface. */
+ u_int16_t (*bc_to_host_2)(u_int16_t);
+ u_int32_t (*bc_to_host_4)(u_int32_t);
+ u_int64_t (*bc_to_host_8)(u_int64_t);
+
+ u_int16_t (*bc_from_host_2)(u_int16_t);
+ u_int32_t (*bc_from_host_4)(u_int32_t);
+ u_int64_t (*bc_from_host_8)(u_int64_t);
+};
+
+#define bus_io_map(t, port, size, iohp) \
+ (*(t)->bc_io_map)((t), (port), (size), (iohp))
+#define bus_io_unmap(t, iohp, size) \
+ (*(t)->bc_io_unmap)((iohp), (size))
+
+#define bus_io_read_1(t, h, o) \
+ (*(t)->bc_io_read_1)((h), (o))
+#define bus_io_read_2(t, h, o) \
+ (*(t)->bc_io_read_2)((h), (o))
+#define bus_io_read_4(t, h, o) \
+ (*(t)->bc_io_read_4)((h), (o))
+#define bus_io_read_8(t, h, o) \
+ (*(t)->bc_io_read_8)((h), (o))
+
+#define bus_io_read_multi_1(t, h, o, a, s) \
+ (*(t)->bc_io_read_multi_1)((h), (o), (a), (s))
+#define bus_io_read_multi_2(t, h, o, a, s) \
+ (*(t)->bc_io_read_multi_2)((h), (o), (a), (s))
+#define bus_io_read_multi_4(t, h, o, a, s) \
+ (*(t)->bc_io_read_multi_4)((h), (o), (a), (s))
+#define bus_io_read_multi_8(t, h, o, a, s) \
+ (*(t)->bc_io_read_multi_8)((h), (o), (a), (s))
+
+#define bus_io_write_1(t, h, o, v) \
+ (*(t)->bc_io_write_1)((h), (o), (v))
+#define bus_io_write_2(t, h, o, v) \
+ (*(t)->bc_io_write_2)((h), (o), (v))
+#define bus_io_write_4(t, h, o, v) \
+ (*(t)->bc_io_write_4)((h), (o), (v))
+#define bus_io_write_8(t, h, o, v) \
+ (*(t)->bc_io_write_8)((h), (o), (v))
+
+#define bus_io_write_multi_1(t, h, o, a, s) \
+ (*(t)->bc_io_write_multi_1)((h), (o), (a), (s))
+#define bus_io_write_multi_2(t, h, o, a, s) \
+ (*(t)->bc_io_write_multi_2)((h), (o), (a), (s))
+#define bus_io_write_multi_4(t, h, o, a, s) \
+ (*(t)->bc_io_write_multi_4)((h), (o), (a), (s))
+#define bus_io_write_multi_8(t, h, o, a, s) \
+ (*(t)->bc_io_write_multi_8)((h), (o), (a), (s))
+
+#define bus_mem_map(t, port, size, cacheable, mhp) \
+ (*(t)->bc_mem_map)((t), (port), (size), (cacheable), (mhp))
+#define bus_mem_unmap(t, mhp, size) \
+ (*(t)->bc_mem_unmap)((mhp), (size))
+
+#define bus_mem_read_1(t, h, o) \
+ (*(t)->bc_mem_read_1)((h), (o))
+#define bus_mem_read_2(t, h, o) \
+ (*(t)->bc_mem_read_2)((h), (o))
+#define bus_mem_read_4(t, h, o) \
+ (*(t)->bc_mem_read_4)((h), (o))
+#define bus_mem_read_8(t, h, o) \
+ (*(t)->bc_mem_read_8)((h), (o))
+
+#define bus_mem_write_1(t, h, o, v) \
+ (*(t)->bc_mem_write_1)((h), (o), (v))
+#define bus_mem_write_2(t, h, o, v) \
+ (*(t)->bc_mem_write_2)((h), (o), (v))
+#define bus_mem_write_4(t, h, o, v) \
+ (*(t)->bc_mem_write_4)((h), (o), (v))
+#define bus_mem_write_8(t, h, o, v) \
+ (*(t)->bc_mem_write_8)((h), (o), (v))
+
+/* These are extensions to the general NetBSD bus interface. */
+#define bus_to_host_2(t, v) (*(t)->bc_to_host_2)(v)
+#define bus_to_host_4(t, v) (*(t)->bc_to_host_4)(v)
+#define bus_to_host_8(t, v) (*(t)->bc_to_host_8)(v)
+
+#define bus_from_host_2(t, v) (*(t)->bc_from_host_2)(v)
+#define bus_from_host_4(t, v) (*(t)->bc_from_host_4)(v)
+#define bus_from_host_8(t, v) (*(t)->bc_from_host_8)(v)
+
+#endif /* _MACHINE_BUS_H_ */
--- /dev/null
+/* $OpenBSD: intr.h,v 1.1 1996/04/27 18:38:53 niklas Exp $ */
+
+/*
+ * Copyright (c) 1996 Niklas Hallqvist
+ * 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 Niklas Hallqvist.
+ * 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 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.
+ */
+
+#ifndef _MACHINE_INTR_H_
+#define _MACHINE_INTR_H_
+
+/* Interrupt priority `levels'; not mutually exclusive. */
+#define IPL_NONE -1
+#define IPL_BIO 3 /* block I/O */
+#define IPL_NET 3 /* network */
+#define IPL_TTY 4 /* terminal */
+#define IPL_CLOCK 4 /* clock */
+#define IPL_IMP 4 /* memory allocation */
+
+/* Interrupt sharing types. */
+#define IST_NONE 0 /* none */
+#define IST_PULSE 1 /* pulsed */
+#define IST_EDGE 2 /* edge-triggered */
+#define IST_LEVEL 3 /* level-triggered */
+
+#endif /* _MACHINE_INTR_H_ */
#ifndef _MACHINE_PSL_H_
#define _MACHINE_PSL_H_
-/* Interrupt priority `levels'; not mutually exclusive. */
-#define IPL_NONE -1
-#define IPL_BIO 3 /* block I/O */
-#define IPL_NET 3 /* network */
-#define IPL_TTY 4 /* terminal */
-#define IPL_CLOCK 4 /* clock */
-#define IPL_IMP 4 /* memory allocation */
-
-/* Interrupt sharing types. */
-#define IST_NONE 0 /* none */
-#define IST_PULSE 1 /* pulsed */
-#define IST_EDGE 2 /* edge-triggered */
-#define IST_LEVEL 3 /* level-triggered */
-
#include <m68k/psl.h>
#endif
-/* $OpenBSD: cross.c,v 1.2 1996/02/27 15:40:54 niklas Exp $ */
-/* $NetBSD: cross.c,v 1.0 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: cross.c,v 1.3 1996/04/27 18:38:55 niklas Exp $ */
/*
- * Copyright (c) 1994 Niklas Hallqvist, Carsten Hammer
+ * Copyright (c) 1994, 1996 Niklas Hallqvist, Carsten Hammer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* 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 Christian E. Hopps.
+ * This product includes software developed by Niklas Hallqvist.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* (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 <sys/param.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/pio.h>
+#include <machine/intr.h>
#include <dev/isa/isavar.h>
#include <amiga/amiga/isr.h>
#include <amiga/dev/zbusvar.h>
#include <amiga/isa/isa_machdep.h>
-#include <amiga/isa/isa_intr.h>
#include <amiga/isa/crossvar.h>
#include <amiga/isa/crossreg.h>
+extern int cold;
+
int crossdebug = 0;
-/* This static is OK because we only allow one ISA bus. */
-struct cross_device *crossp;
-
-void crossattach __P((struct device *, struct device *, void *));
-int crossmatch __P((struct device *, void *, void *));
-int crossprint __P((void *auxp, char *));
-void crossstb __P((struct device *, int, u_char));
-u_char crossldb __P((struct device *, int));
-void crossstw __P((struct device *, int, u_short));
-u_short crossldw __P((struct device *, int));
-void *cross_establish_intr __P((int intr, int type, int level,
- int (*ih_fun) (void *), void *ih_arg,
- char *ih_what));
-void cross_disestablish_intr __P((void *handler));
-
-struct isa_intr_fcns cross_intr_fcns = {
- 0 /* cross_intr_setup */, cross_establish_intr,
- cross_disestablish_intr, 0 /* cross_iointr */
+void crossattach __P((struct device *, struct device *, void *));
+int crossmatch __P((struct device *, void *, void *));
+int crossprint __P((void *, char *));
+
+int cross_io_map(bus_chipset_tag_t, bus_io_addr_t, bus_io_size_t,
+ bus_io_handle_t *);
+int cross_mem_map(bus_chipset_tag_t, bus_mem_addr_t, bus_mem_size_t, int,
+ bus_mem_handle_t *);
+
+void cross_io_read_multi_1(bus_io_handle_t, bus_io_size_t, u_int8_t *,
+ bus_io_size_t);
+void cross_io_read_multi_2(bus_io_handle_t, bus_io_size_t, u_int16_t *,
+ bus_io_size_t);
+
+void cross_io_write_multi_1(bus_io_handle_t, bus_io_size_t,
+ const u_int8_t *, bus_io_size_t);
+void cross_io_write_multi_2(bus_io_handle_t, bus_io_size_t,
+ const u_int16_t *, bus_io_size_t);
+
+/*
+ * Note that the following unified access functions are prototyped for the
+ * I/O access case. We use casts to get type correctness.
+ */
+int cross_unmap(bus_io_handle_t, bus_io_size_t);
+
+__inline u_int8_t cross_read_1(bus_io_handle_t, bus_io_size_t);
+__inline u_int16_t cross_read_2(bus_io_handle_t, bus_io_size_t);
+
+__inline void cross_write_1(bus_io_handle_t, bus_io_size_t, u_int8_t);
+__inline void cross_write_2(bus_io_handle_t, bus_io_size_t, u_int16_t);
+
+/*
+ * In order to share the access function implementations for I/O and memory
+ * access we cast the functions for the memory access case. These typedefs
+ * make that casting look nicer.
+ */
+typedef int (*bus_mem_unmap_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef u_int8_t (*bus_mem_read_1_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef u_int16_t (*bus_mem_read_2_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef void (*bus_mem_write_1_t)(bus_mem_handle_t, bus_mem_size_t, u_int8_t);
+typedef void (*bus_mem_write_2_t)(bus_mem_handle_t, bus_mem_size_t, u_int16_t);
+
+void cross_attach_hook(struct device *, struct device *,
+ struct isabus_attach_args *);
+void *cross_intr_establish __P((void *, int, int, int, int (*)(void *),
+ void *, char *));
+void cross_intr_disestablish __P((void *, void *));
+
+static u_int16_t swap __P((u_int16_t));
+
+struct amiga_bus_chipset cross_chipset = {
+ 0 /* bc_data */,
+
+ cross_io_map, cross_unmap,
+ cross_read_1, cross_read_2,
+ 0 /* bc_io_read_4 */, 0 /* bc_io_read_8 */,
+ cross_io_read_multi_1, cross_io_read_multi_2,
+ 0 /* bc_io_multi_4 */, 0 /* bc_io_multi_8 */,
+ cross_write_1, cross_write_2,
+ 0 /* bc_io_write_4 */, 0 /* bc_io_write_8 */,
+ cross_io_write_multi_1, cross_io_write_multi_2,
+ 0 /* bc_io_write_multi_4 */, 0 /* bc_io_write_multi_8 */,
+
+ cross_mem_map, (bus_mem_unmap_t)cross_unmap,
+ (bus_mem_read_1_t)cross_read_1, (bus_mem_read_2_t)cross_read_2,
+ 0 /* bc_mem_read_4 */, 0 /* bc_mem_read_8 */,
+ (bus_mem_write_1_t)cross_write_1, (bus_mem_write_2_t)cross_write_2,
+ 0 /* bc_mem_write_4 */, 0 /* bc_mem_write_8 */,
+
+ /* These are extensions to the general NetBSD bus interface. */
+ swap, 0 /* bc_to_host_4 */, 0 /* bc_to_host_8 */,
+ swap, 0 /* bc_from_host_4 */, 0 /* bc_from_host_8 */,
+};
+
+struct cfattach cross_ca = {
+ sizeof(struct cross_softc), crossmatch, crossattach
};
-struct cfdriver crosscd = {
- NULL, "cross", crossmatch, crossattach,
- DV_DULL, sizeof(struct cross_device), 0
+struct cfdriver cross_cd = {
+ NULL, "cross", DV_DULL, 0
};
int
}
void
-crossattach(pdp, dp, auxp)
- struct device *pdp, *dp;
- void *auxp;
+crossattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
{
- struct zbus_args *zap = auxp;
- struct cross_device *cdp = (struct cross_device *)dp;
-
- crossp = cdp;
- bcopy(zap, &cdp->cd_zargs, sizeof(struct zbus_args));
- cdp->cd_link.il_dev = dp;
- cdp->cd_link.il_ldb = crossldb;
- cdp->cd_link.il_stb = crossstb;
- cdp->cd_link.il_ldw = crossldw;
- cdp->cd_link.il_stw = crossstw;
- cdp->cd_imask = 1 << CROSS_MASTER;
-
- isa_intr_fcns = &cross_intr_fcns;
- isa_pio_fcns = &cross_pio_fcns;
-
- /* Enable interrupts lazily in crossaddint. */
+ struct cross_softc *sc = (struct cross_softc *)self;
+ struct zbus_args *zap = aux;
+ struct isabus_attach_args iba;
+
+ bcopy(zap, &sc->sc_zargs, sizeof(struct zbus_args));
+ bcopy(&cross_chipset, &sc->sc_bc, sizeof(struct amiga_bus_chipset));
+ sc->sc_bc.bc_data = sc;
+ sc->sc_status = CROSS_STATUS_ADDR(zap->va);
+ sc->sc_imask = 1 << CROSS_MASTER;
+
+ /* Enable interrupts lazily in cross_intr_establish. */
CROSS_ENABLE_INTS(zap->va, 0);
/* Default 16 bit tranfer */
- *(volatile u_short *)(cdp->cd_zargs.va + CROSS_XLP_LATCH) = CROSS_SBHE;
-
+ *CROSS_HANDLE_TO_XLP_LATCH((bus_io_handle_t)zap->va) = CROSS_SBHE;
printf(": pa 0x%08x va 0x%08x size 0x%x\n", zap->pa, zap->va,
- zap->size);
+ zap->size);
+ sc->sc_ic.ic_data = sc;
+ sc->sc_ic.ic_attach_hook = cross_attach_hook;
+ sc->sc_ic.ic_intr_establish = cross_intr_establish;
+ sc->sc_ic.ic_intr_disestablish = cross_intr_disestablish;
- /*
- * attempt to configure the board.
- */
- config_found(dp, &cdp->cd_link, crossprint);
+ iba.iba_busname = "isa";
+ iba.iba_bc = &sc->sc_bc;
+ iba.iba_ic = &sc->sc_ic;
+ config_found(self, &iba, crossprint);
}
int
}
-void
-crossstb(dev, ia, b)
- struct device *dev;
- int ia;
- u_char b;
+int
+cross_io_map(bct, addr, sz, handle)
+ bus_chipset_tag_t bct;
+ bus_io_addr_t addr;
+ bus_io_size_t sz;
+ bus_io_handle_t *handle;
+{
+ *handle = (bus_io_handle_t)
+ ((struct cross_softc *)bct->bc_data)->sc_zargs.va + 2 * addr;
+#if 0
+ printf("io_map %x %d -> %x\n", addr, sz, *handle);
+#endif
+ return 0;
+}
+
+int
+cross_mem_map(bct, addr, sz, cacheable, handle)
+ bus_chipset_tag_t bct;
+ bus_mem_addr_t addr;
+ bus_mem_size_t sz;
+ int cacheable;
+ bus_mem_handle_t *handle;
+{
+ *handle = (bus_mem_handle_t)
+ ((struct cross_softc *)bct->bc_data)->sc_zargs.va + 2 * addr +
+ CROSS_MEMORY_OFFSET;
+#if 0
+ printf("mem_map %x %d -> %x\n", addr, sz, *handle);
+#endif
+ return 0;
+}
+
+int
+cross_unmap(handle, sz)
+ bus_io_handle_t handle;
+ bus_io_size_t sz;
+{
+ return 0;
+}
+
+__inline u_int8_t
+cross_read_1(handle, addr)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
{
+ u_int8_t val;
+
/* generate A13-A19 for correct page */
- u_short upper_addressbits = ia >> 13;
- struct cross_device *cd = (struct cross_device *)dev;
+ *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE;
+ val = *(volatile u_int8_t *)(handle + 2 * addr);
- *(volatile u_short *)(cd->cd_zargs.va + CROSS_XLP_LATCH) =
- upper_addressbits | CROSS_SBHE;
- *(volatile u_char *)(cd->cd_zargs.va + CROSS_MEMORY_OFFSET + 2 * ia) =
- b;
+#if 0
+ printf("read_1 @%x handle %x -> %d\n", addr, handle, val);
+#endif
+ return val;
}
-u_char
-crossldb(dev, ia)
- struct device *dev;
- int ia;
+__inline u_int16_t
+cross_read_2(handle, addr)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
{
/* generate A13-A19 for correct page */
- u_short upper_addressbits = ia >> 13;
- struct cross_device *cd = (struct cross_device *)dev;
+ *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE;
+ return *(volatile u_int16_t *)(handle + 2 * addr);
+}
- *(volatile u_short *)(cd->cd_zargs.va + CROSS_XLP_LATCH) =
- upper_addressbits | CROSS_SBHE;
- return *(volatile u_char *)(cd->cd_zargs.va + CROSS_MEMORY_OFFSET +
- 2 * ia);
+void
+cross_io_read_multi_1(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int8_t *buf;
+ bus_io_size_t cnt;
+{
+ while (cnt--)
+ *buf++ = cross_read_1(handle, addr);
}
void
-crossstw(dev, ia, w)
- struct device *dev;
- int ia;
- u_short w;
+cross_io_read_multi_2(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int16_t *buf;
+ bus_io_size_t cnt;
{
- /* generate A13-A19 for correct page */
- u_short upper_addressbits = ia >> 13;
- struct cross_device *cd = (struct cross_device *)dev;
-
- *(volatile u_short *)(cd->cd_zargs.va + CROSS_XLP_LATCH) =
- upper_addressbits | CROSS_SBHE;
-#ifdef DEBUG
- if (crossdebug)
- printf("outw 0x%x,0x%x\n", ia, w);
-#endif
- *(volatile u_short *)(cd->cd_zargs.va + CROSS_MEMORY_OFFSET + 2 * ia) =
- w;
+ while (cnt--)
+ *buf++ = cross_read_2(handle, addr);
}
-u_short
-crossldw(dev, ia)
- struct device *dev;
- int ia;
+__inline void
+cross_write_1(handle, addr, val)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int8_t val;
{
/* generate A13-A19 for correct page */
- u_short upper_addressbits = ia >> 13;
- struct cross_device *cd = (struct cross_device *)dev;
- u_short retval;
-
- *(volatile u_short *)(cd->cd_zargs.va + CROSS_XLP_LATCH) =
- upper_addressbits | CROSS_SBHE;
- retval = *(volatile u_short *)(cd->cd_zargs.va + CROSS_MEMORY_OFFSET +
- 2 * ia);
-#ifdef DEBUG
- if (crossdebug)
- printf("ldw 0x%x => 0x%x\n", ia, retval);
+ *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE;
+#if 0
+ printf("write_1 @%x handle %x: %d\n", addr, handle, val);
#endif
- return retval;
+ *(volatile u_int8_t *)(handle + 2 * addr + 1) = val;
}
-static cross_int_map[] = {
- 0, 0, 0, 0, CROSS_IRQ3, CROSS_IRQ4, CROSS_IRQ5, CROSS_IRQ6, CROSS_IRQ7, 0,
- CROSS_IRQ9, CROSS_IRQ10, CROSS_IRQ11, CROSS_IRQ12, 0, CROSS_IRQ14,
- CROSS_IRQ15
-};
+__inline void
+cross_write_2(handle, addr, val)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int16_t val;
+{
+ /* generate A13-A19 for correct page */
+ *CROSS_HANDLE_TO_XLP_LATCH(handle) = addr >> 13 | CROSS_SBHE;
+ *(volatile u_int16_t *)(handle + 2 * addr) = val;
+}
-#if 0
-/* XXX We don't care about the priority yet, although we ought to. */
void
-crossaddint(dev, irq, func, arg, pri)
- struct device *dev;
- int irq;
- int (*func)();
- void *arg;
- int pri;
+cross_io_write_multi_1(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ const u_int8_t *buf;
+ bus_io_size_t cnt;
{
- struct cross_device *cd = (struct cross_device *)dev;
- int s = splhigh();
- int bit = cross_int_map[irq + 1];
-
- if (!bit) {
- log(LOG_WARNING, "Registration of unknown ISA interrupt %d\n",
- irq);
- goto out;
- }
- if (cd->cd_imask & 1 << bit) {
- log(LOG_WARNING, "ISA interrupt %d already handled\n", irq);
- goto out;
- }
- cd->cd_imask |= (1 << bit);
- CROSS_ENABLE_INTS (cd->cd_zargs.va, cd->cd_imask);
- cd->cd_ifunc[bit] = func;
- cd->cd_ipri[bit] = pri;
- cd->cd_iarg[bit] = arg;
-out:
- splx(s);
+ while (cnt--)
+ cross_write_1(handle, addr, *buf++);
}
void
-crossremint(dev, irq)
- struct device *dev;
- int irq;
+cross_io_write_multi_2(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ const u_int16_t *buf;
+ bus_io_size_t cnt;
{
- struct cross_device *cd = (struct cross_device *)dev;
- int s = splhigh();
- int bit = cross_int_map[irq + 1];
-
- cd->cd_imask &= ~(1 << bit);
- CROSS_ENABLE_INTS (cd->cd_zargs.va, cd->cd_imask);
- splx(s);
+ while (cnt--)
+ cross_write_2(handle, addr, *buf++);
}
-#endif
-struct crossintr_desc {
- struct isr cid_isr;
- int cid_mask;
- int (*cid_fun)(void *);
- void *cid_arg;
-};
-static struct crossintr_desc *crid[16]; /* XXX */
+static cross_int_map[] = {
+ 0, 0, 0, 0, CROSS_IRQ3, CROSS_IRQ4, CROSS_IRQ5, CROSS_IRQ6, CROSS_IRQ7, 0,
+ CROSS_IRQ9, CROSS_IRQ10, CROSS_IRQ11, CROSS_IRQ12, 0, CROSS_IRQ14,
+ CROSS_IRQ15
+};
int
-crossintr(cid)
- struct crossintr_desc *cid;
+crossintr(v)
+ void *v;
+{
+ struct intrhand *ih = (struct intrhand *)v;
+ int handled;
+
+ if (!(*ih->ih_status & ih->ih_mask))
+ return 0;
+ for (handled = 0; ih; ih = ih->ih_next)
+ if ((*ih->ih_fun)(ih->ih_arg))
+ handled = 1;
+ return handled;
+}
+
+void
+cross_attach_hook(parent, self, iba)
+ struct device *parent, *self;
+ struct isabus_attach_args *iba;
{
- return (CROSS_GET_STATUS (crossp->cd_zargs.va) & cid->cid_mask) ?
- (*cid->cid_fun)(cid->cid_arg) : 0;
}
void *
-cross_establish_intr(intr, type, level, ih_fun, ih_arg, ih_what)
- int intr;
- int type;
- int level;
- int (*ih_fun)(void *);
- void *ih_arg;
+cross_intr_establish(ic, irq, type, level, ih_fun, ih_arg, ih_what)
+ void *ic;
+ int irq;
+ int type;
+ int level;
+ int (*ih_fun)(void *);
+ void *ih_arg;
char *ih_what;
{
- if (crid[intr]) {
- log(LOG_WARNING, "ISA interrupt %d already handled\n", intr);
- return 0;
- }
- MALLOC(crid[intr], struct crossintr_desc *,
- sizeof(struct crossintr_desc), M_DEVBUF, M_WAITOK);
- crid[intr]->cid_isr.isr_intr = crossintr;
- crid[intr]->cid_isr.isr_arg = crid[intr];
- crid[intr]->cid_isr.isr_ipl = 6;
- crid[intr]->cid_isr.isr_mapped_ipl = level;
- crid[intr]->cid_mask = 1 << cross_int_map[intr + 1];
- crid[intr]->cid_fun = ih_fun;
- crid[intr]->cid_arg = ih_arg;
- add_isr (&crid[intr]->cid_isr);
- crossp->cd_imask |= 1 << cross_int_map[intr + 1];
- CROSS_ENABLE_INTS (crossp->cd_zargs.va, crossp->cd_imask);
- return &crid[intr];
+ struct intrhand **p, *c, *ih;
+ struct cross_softc *sc = (struct cross_softc *)ic;
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("cross_intr_establish: can't malloc handler info");
+
+ if (irq > ICU_LEN || type == IST_NONE)
+ panic("cross_intr_establish: bogus irq or type");
+
+ switch (sc->sc_intrsharetype[irq]) {
+ case IST_EDGE:
+ case IST_LEVEL:
+ if (type == sc->sc_intrsharetype[irq])
+ break;
+ case IST_PULSE:
+ if (type != IST_NONE)
+ panic("cross_intr_establish: can't share %s with %s",
+ isa_intr_typename(sc->sc_intrsharetype[irq]),
+ isa_intr_typename(type));
+ break;
+ }
+
+ /*
+ * Figure out where to put the handler.
+ * This is O(N^2), but we want to preserve the order, and N is
+ * generally small.
+ */
+ for (p = &sc->sc_ih[irq]; (c = *p) != NULL; p = &c->ih_next)
+ ;
+
+ /*
+ * Poke the real handler in now.
+ */
+ ih->ih_fun = ih_fun;
+ ih->ih_arg = ih_arg;
+ ih->ih_count = 0;
+ ih->ih_next = NULL;
+ ih->ih_irq = irq;
+ ih->ih_what = ih_what;
+ ih->ih_mask = 1 << cross_int_map[irq + 1];
+ ih->ih_status = sc->sc_status;
+ ih->ih_isr.isr_intr = crossintr;
+ ih->ih_isr.isr_arg = ih;
+ ih->ih_isr.isr_ipl = 6;
+ ih->ih_isr.isr_mapped_ipl = level;
+ *p = ih;
+ add_isr(&ih->ih_isr);
+
+ sc->sc_imask |= 1 << cross_int_map[irq + 1];
+ CROSS_ENABLE_INTS(sc->sc_zargs.va, sc->sc_imask);
+
+ return ih;
}
void
-cross_disestablish_intr(handler)
- void *handler;
+cross_intr_disestablish(ic, arg)
+ void *ic;
+ void *arg;
{
- struct crossintr_desc **cid = handler;
+ struct intrhand *ih = arg;
+ struct cross_softc *sc = (struct cross_softc *)ic;
+ int irq = ih->ih_irq;
+ struct intrhand **p, *q;
+
+ if (irq > ICU_LEN)
+ panic("cross_intr_establish: bogus irq");
+
+ sc->sc_imask &= ~ih->ih_mask;
+ CROSS_ENABLE_INTS (sc->sc_zargs.va, sc->sc_imask);
+ remove_isr(&ih->ih_isr);
- remove_isr(&(*cid)->cid_isr);
- crossp->cd_imask &= ~(*cid)->cid_mask;
- FREE(*cid, M_DEVBUF);
- *cid = 0;
- CROSS_ENABLE_INTS (crossp->cd_zargs.va, crossp->cd_imask);
+ /*
+ * Remove the handler from the chain.
+ * This is O(n^2), too.
+ */
+ for (p = &sc->sc_ih[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
+ ;
+ if (q)
+ *p = q->ih_next;
+ else
+ panic("cross_intr_disestablish: handler not registered");
+ free(ih, M_DEVBUF);
+
+ if (sc->sc_intrsharetype[irq] == NULL)
+ sc->sc_intrsharetype[irq] = IST_NONE;
+}
+
+/* Swap bytes in a short word. */
+static u_short
+swap(u_short x)
+{
+ __asm("rolw #8,%0" : "=r" (x) : "0" (x));
+ return x;
}
+++ /dev/null
-/* $NetBSD: cross_pio.c,v 1.1 1995/08/04 14:32:17 niklas Exp $ */
-
-/*
- * Copyright (c) 1995 Niklas Hallqvist
- * 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 Niklas Hallqvist.
- * 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 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.
- */
-#include <sys/types.h>
-#include <sys/device.h>
-
-#include <machine/pio.h>
-
-#include <dev/isa/isavar.h>
-
-#include <amiga/amiga/isr.h>
-#include <amiga/dev/zbusvar.h>
-#include <amiga/isa/isa_machdep.h>
-#include <amiga/isa/crossreg.h>
-#include <amiga/isa/crossvar.h>
-
-extern struct cross_device *crossp;
-
-void cross_outb __P((int, u_int8_t));
-u_int8_t cross_inb __P((int));
-void cross_outw __P((int, u_int16_t));
-u_int16_t cross_inw __P((int));
-
-struct isa_pio_fcns cross_pio_fcns = {
- cross_inb, isa_insb,
- cross_inw, isa_insw,
- 0 /* cross_inl */, 0 /* cross_insl */,
- cross_outb, isa_outsb,
- cross_outw, isa_outsw,
- 0 /* cross_outl */, 0 /* cross_outsl */,
-};
-
-void
-cross_outb(ia, b)
- int ia;
- u_int8_t b;
-{
-#ifdef DEBUG
- if (crossdebug)
- printf("outb 0x%x,0x%x\n", ia, b);
-#endif
- *(volatile u_int8_t *)(crossp->cd_zargs.va + 2 * ia) = b;
-}
-
-u_int8_t
-cross_inb(ia)
- int ia;
-{
- u_int8_t retval =
- *(volatile u_int8_t *)(crossp->cd_zargs.va + 2 * ia);
-
-
-#ifdef DEBUG
- if (crossdebug)
- printf("inb 0x%x => 0x%x\n", ia, retval);
-#endif
- return retval;
-}
-
-void
-cross_outw(ia, w)
- int ia;
- u_int16_t w;
-{
-#ifdef DEBUG
- if (crossdebug)
- printf("outw 0x%x,0x%x\n", ia, w);
-#endif
- *(volatile u_int16_t *)(crossp->cd_zargs.va + 2 * ia) = w;
-}
-
-u_int16_t
-cross_inw(ia)
- int ia;
-{
- u_int16_t retval =
- *(volatile u_int16_t *)(crossp->cd_zargs.va + 2 * ia);
-
-
-#ifdef DEBUG
- if (crossdebug)
- printf("inw 0x%x => 0x%x\n", ia, retval);
-#endif
- return retval;
-}
-
-/* $NetBSD: crossreg.h,v 1.1 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: crossreg.h,v 1.2 1996/04/27 18:38:56 niklas Exp $ */
/*
- * Copyright (c) 1994 Niklas Hallqvist, Carsten Hammer
+ * Copyright (c) 1994, 1996 Niklas Hallqvist, Carsten Hammer
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* 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 Christian E. Hopps.
+ * This product includes software developed by Niklas Hallqvist.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef _CROSSREG_H_
#define _CROSSREG_H_
+
/***
*
*
* about this register. However, it can be also used to
* determine which interrupt a board is connected to.
**/
+
/* hardware offsets from config address */
#define CROSS_XL_ROM 0x8000
#define CROSS_XLP_INTSTAT 0
#define CROSS_XLP_INTABLE 0
#define CROSS_XLP_LATCH 2
+#define CROSS_HANDLE_TO_XLP_LATCH(va) \
+ ((volatile u_int16_t *)((va) & 0xffff | CROSS_XLP_LATCH))
#define CROSS_MEMORY_OFFSET (CROSS_XL_MEM - 2 * 0x90000)
#define CROSS_SBHE 0x40
-#define CROSS_GET_STATUS(va) \
- (*(volatile u_short *)((va) + CROSS_XLP_INTSTAT))
+#define CROSS_STATUS_ADDR(va) \
+ ((volatile u_int16_t *)((va) + CROSS_XLP_INTSTAT))
#define CROSS_MASTER 5
-/* From what I understand IRQ2 is really IRQ9 -NH */
-#define CROSS_IRQ9 10
+
+#define CROSS_IRQ9 10 /* IRQ9 is an alias of IRQ2 */
#define CROSS_IRQ3 11
#define CROSS_IRQ4 12
#define CROSS_IRQ5 13
#define CROSS_GET_INT_STATUS(va) (CROSS_GET_STATUS(va) & CROSS_IRQMASK)
#define CROSS_ENABLE_INTS(va, ints) \
- (*(volatile u_short *)((va) + CROSS_XLP_INTABLE) = ints)
+ (*(volatile u_int16_t *)((va) + CROSS_XLP_INTABLE) = ints)
#endif
-/* $NetBSD: crossvar.h,v 1.1 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: crossvar.h,v 1.2 1996/04/27 18:38:57 niklas Exp $ */
/*
- * Copyright (c) 1994 Niklas Hallqvist
+ * Copyright (c) 1994, 1996 Niklas Hallqvist
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* 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 Christian E. Hopps.
+ * This product includes software developed by Niklas Hallqvist.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef _CROSSVAR_H_
#define _CROSSVAR_H_
-struct cross_device {
- struct device cd_dev;
- struct zbus_args cd_zargs;
- struct isa_link cd_link;
- int (*cd_ifunc[16])();
- void *cd_iarg[16];
- int cd_ipri[16];
- int cd_imask;
- struct isr cd_isr;
+/*
+ * Interrupt handler chains. cross_intr_establish() inserts a handler into
+ * the list. The handler is called with its (single) argument.
+ */
+struct intrhand {
+ struct intrhand *ih_next;
+ int (*ih_fun)();
+ void *ih_arg;
+ u_long ih_count;
+ int ih_irq;
+ char *ih_what;
+
+ struct isr ih_isr;
+ u_int16_t ih_mask;
+ volatile u_int16_t *ih_status;
+};
+
+#define ICU_LEN 16 /* number of ISA IRQs (XXX) */
+
+struct cross_softc {
+ struct device sc_dev;
+
+ struct zbus_args sc_zargs;
+ struct intrhand *sc_ih[ICU_LEN];
+ int sc_intrsharetype[ICU_LEN];
+ u_int16_t sc_imask;
+ volatile u_int16_t *sc_status;
+
+ struct amiga_bus_chipset sc_bc;
+ struct amiga_isa_chipset sc_ic;
};
extern int crossdebug;
-/* $OpenBSD: ggbus.c,v 1.2 1996/02/27 15:40:56 niklas Exp $ */
-/* $NetBSD: ggbus.c,v 1.1 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: ggbus.c,v 1.3 1996/04/27 18:38:58 niklas Exp $ */
/*
- * Copyright (c) 1994, 1995 Niklas Hallqvist
+ * Copyright (c) 1994, 1995, 1996 Niklas Hallqvist
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (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 <sys/param.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
+#include <machine/bus.h>
#include <machine/cpu.h>
-#include <machine/pio.h>
+#include <machine/intr.h>
#include <dev/isa/isavar.h>
#include <amiga/amiga/isr.h>
#include <amiga/dev/zbusvar.h>
#include <amiga/isa/isa_machdep.h>
-#include <amiga/isa/isa_intr.h>
#include <amiga/isa/ggbusvar.h>
#include <amiga/isa/ggbusreg.h>
+extern int cold;
+
int ggdebug = 0;
int ggstrayints = 0;
-/* This is OK because we only allow one ISA bus. */
-struct ggbus_device *ggbusp;
-
void ggbusattach __P((struct device *, struct device *, void *));
int ggbusmatch __P((struct device *, void *, void *));
-int ggbusprint __P((void *auxp, char *));
-void ggbusstb __P((struct device *, int, u_char));
-u_char ggbusldb __P((struct device *, int));
-void ggbusstw __P((struct device *, int, u_short));
-u_short ggbusldw __P((struct device *, int));
-void *ggbus_establish_intr __P((int intr, int type, int level,
- int (*ih_fun) (void *), void *ih_arg,
- char *ih_what));
-void ggbus_disestablish_intr __P((void *handler));
-
-struct isa_intr_fcns ggbus_intr_fcns = {
- 0 /* ggbus_intr_setup */, ggbus_establish_intr,
- ggbus_disestablish_intr, 0 /* ggbus_iointr */
+int ggbusprint __P((void *, char *));
+
+int ggbus_io_map(bus_chipset_tag_t, bus_io_addr_t, bus_io_size_t,
+ bus_io_handle_t *);
+int ggbus_mem_map(bus_chipset_tag_t, bus_mem_addr_t, bus_mem_size_t, int,
+ bus_mem_handle_t *);
+
+void ggbus_io_read_multi_1(bus_io_handle_t, bus_io_size_t, u_int8_t *,
+ bus_io_size_t);
+void ggbus_io_read_multi_2(bus_io_handle_t, bus_io_size_t, u_int16_t *,
+ bus_io_size_t);
+
+void ggbus_io_write_multi_1(bus_io_handle_t, bus_io_size_t,
+ const u_int8_t *, bus_io_size_t);
+void ggbus_io_write_multi_2(bus_io_handle_t, bus_io_size_t,
+ const u_int16_t *, bus_io_size_t);
+
+/*
+ * Note that the following unified access functions are prototyped for the
+ * I/O access case. We use casts to get type correctness.
+ */
+int ggbus_unmap(bus_io_handle_t, bus_io_size_t);
+
+__inline u_int8_t ggbus_read_1(bus_io_handle_t, bus_io_size_t);
+__inline u_int16_t ggbus_read_2(bus_io_handle_t, bus_io_size_t);
+
+__inline void ggbus_write_1(bus_io_handle_t, bus_io_size_t, u_int8_t);
+__inline void ggbus_write_2(bus_io_handle_t, bus_io_size_t, u_int16_t);
+
+/*
+ * In order to share the access function implementations for I/O and memory
+ * access we cast the functions for the memory access case. These typedefs
+ * make that casting look nicer.
+ */
+typedef int (*bus_mem_unmap_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef u_int8_t (*bus_mem_read_1_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef u_int16_t (*bus_mem_read_2_t)(bus_mem_handle_t, bus_mem_size_t);
+typedef void (*bus_mem_write_1_t)(bus_mem_handle_t, bus_mem_size_t, u_int8_t);
+typedef void (*bus_mem_write_2_t)(bus_mem_handle_t, bus_mem_size_t, u_int16_t);
+
+void ggbus_attach_hook(struct device *, struct device *,
+ struct isabus_attach_args *);
+void *ggbus_intr_establish __P((void *, int, int, int, int (*)(void *),
+ void *, char *));
+void ggbus_intr_disestablish __P((void *, void *));
+
+static u_int16_t swap __P((u_int16_t));
+
+/* Golden Gate I. */
+struct amiga_bus_chipset ggbus1_chipset = {
+ 0 /* bc_data */,
+
+ ggbus_io_map, ggbus_unmap,
+ ggbus_read_1, ggbus_read_2,
+ 0 /* bc_io_read_4 */, 0 /* bc_io_read_8 */,
+ ggbus_io_read_multi_1, ggbus_io_read_multi_2,
+ 0 /* bc_io_multi_4 */, 0 /* bc_io_multi_8 */,
+ ggbus_write_1, ggbus_write_2,
+ 0 /* bc_io_write_4 */, 0 /* bc_io_write_8 */,
+ ggbus_io_write_multi_1, ggbus_io_write_multi_2,
+ 0 /* bc_io_write_multi_4 */, 0 /* bc_io_write_multi_8 */,
+
+ 0 /* bc_mem_map */, 0 /* bc_mem_unmap */,
+ 0 /* bc_mem_read_1 */, 0 /* bc_mem_read_2 */,
+ 0 /* bc_mem_read_4 */, 0 /* bc_mem_read_8 */,
+ 0 /* bc_mem_write_1 */, 0 /* bc_mem_write_2 */,
+ 0 /* bc_mem_write_4 */, 0 /* bc_mem_write_8 */,
+
+ /* These are extensions to the general NetBSD bus interface. */
+ swap, 0 /* bc_to_host_4 */, 0 /* bc_to_host_8 */,
+ swap, 0 /* bc_from_host_4 */, 0 /* bc_from_host_8 */,
+};
+
+/* Golden Gate II. */
+struct amiga_bus_chipset ggbus2_chipset = {
+ 0 /* bc_data */,
+
+ ggbus_io_map, ggbus_unmap,
+ ggbus_read_1, ggbus_read_2,
+ 0 /* bc_io_read_4 */, 0 /* bc_io_read_8 */,
+ ggbus_io_read_multi_1, ggbus_io_read_multi_2,
+ 0 /* bc_io_multi_4 */, 0 /* bc_io_multi_8 */,
+ ggbus_write_1, ggbus_write_2,
+ 0 /* bc_io_write_4 */, 0 /* bc_io_write_8 */,
+ ggbus_io_write_multi_1, ggbus_io_write_multi_2,
+ 0 /* bc_io_write_multi_4 */, 0 /* bc_io_write_multi_8 */,
+
+ ggbus_mem_map, (bus_mem_unmap_t)ggbus_unmap,
+ (bus_mem_read_1_t)ggbus_read_1, (bus_mem_read_2_t)ggbus_read_2,
+ 0 /* bc_mem_read_4 */, 0 /* bc_mem_read_8 */,
+ (bus_mem_write_1_t)ggbus_write_1, (bus_mem_write_2_t)ggbus_write_2,
+ 0 /* bc_mem_write_4 */, 0 /* bc_mem_write_8 */,
+
+ /* These are extensions to the general NetBSD bus interface. */
+ swap, 0 /* bc_to_host_4 */, 0 /* bc_to_host_8 */,
+ swap, 0 /* bc_from_host_4 */, 0 /* bc_from_host_8 */,
+};
+
+struct cfattach ggbus_ca = {
+ sizeof(struct ggbus_softc), ggbusmatch, ggbusattach
};
-struct cfdriver ggbuscd = {
- NULL, "ggbus", ggbusmatch, ggbusattach,
- DV_DULL, sizeof(struct ggbus_device), 0
+struct cfdriver ggbus_cd = {
+ NULL, "ggbus", DV_DULL, 0
};
int
}
void
-ggbusattach(pdp, dp, auxp)
- struct device *pdp, *dp;
- void *auxp;
+ggbusattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
{
- struct zbus_args *zap = auxp;
- struct ggbus_device *gdp = (struct ggbus_device *)dp;
-
- ggbusp = gdp;
- bcopy(zap, &gdp->gd_zargs, sizeof(struct zbus_args));
- gdp->gd_link.il_dev = dp;
- if (gdp->gd_zargs.serno >= 2)
- {
- gdp->gd_link.il_ldb = ggbusldb;
- gdp->gd_link.il_stb = ggbusstb;
- gdp->gd_link.il_ldw = ggbusldw;
- gdp->gd_link.il_stw = ggbusstw;
- }
- else
- {
- gdp->gd_link.il_ldb = 0;
- gdp->gd_link.il_stb = 0;
- gdp->gd_link.il_ldw = 0;
- gdp->gd_link.il_stw = 0;
- }
- gdp->gd_imask = 0;
-
- isa_intr_fcns = &ggbus_intr_fcns;
- isa_pio_fcns = &ggbus_pio_fcns;
-
- if (gdp->gd_zargs.serno >= 2)
- {
- /* XXX turn on wait states unconditionally for now. */
- GG2_ENABLE_WAIT(zap->va);
- GG2_ENABLE_INTS(zap->va);
- }
-
- printf(": pa 0x%08x va 0x%08x size 0x%x\n", zap->pa, zap->va, zap->size);
+ struct ggbus_softc *sc = (struct ggbus_softc *)self;
+ struct zbus_args *zap = aux;
+ struct isabus_attach_args iba;
+
+ bcopy(zap, &sc->sc_zargs, sizeof(struct zbus_args));
+ /* XXX Is serno reliable? */
+ bcopy(zap->serno < 2 ? &ggbus1_chipset : &ggbus2_chipset,
+ &sc->sc_bc, sizeof(struct amiga_bus_chipset));
+ sc->sc_bc.bc_data = sc;
+ sc->sc_status = GG2_STATUS_ADDR(sc->sc_zargs.va);
+
+ if (sc->sc_zargs.serno >= 2) {
+ /* XXX turn on wait states unconditionally for now. */
+ GG2_ENABLE_WAIT(zap->va);
+ GG2_ENABLE_INTS(zap->va);
+ }
- /*
- * attempt to configure the board.
- */
- config_found(dp, &gdp->gd_link, ggbusprint);
+ printf(": pa 0x%08x va 0x%08x size 0x%x\n", zap->pa, zap->va,
+ zap->size);
+
+ sc->sc_ic.ic_data = sc;
+ sc->sc_ic.ic_attach_hook = ggbus_attach_hook;
+ sc->sc_ic.ic_intr_establish = ggbus_intr_establish;
+ sc->sc_ic.ic_intr_disestablish = ggbus_intr_disestablish;
+
+ iba.iba_busname = "isa";
+ iba.iba_bc = &sc->sc_bc;
+ iba.iba_ic = &sc->sc_ic;
+ config_found(self, &iba, ggbusprint);
}
int
return(UNCONF);
}
+int
+ggbus_io_map(bct, addr, sz, handle)
+ bus_chipset_tag_t bct;
+ bus_io_addr_t addr;
+ bus_io_size_t sz;
+ bus_io_handle_t *handle;
+{
+ *handle = (bus_io_handle_t)
+ ((struct ggbus_softc *)bct->bc_data)->sc_zargs.va + 2 * addr;
+#if 0
+ printf("io_map %x %d -> %x\n", addr, sz, *handle);
+#endif
+ return 0;
+}
-void
-ggbusstb(dev, ia, b)
- struct device *dev;
- int ia;
- u_char b;
+int
+ggbus_mem_map(bct, addr, sz, cacheable, handle)
+ bus_chipset_tag_t bct;
+ bus_mem_addr_t addr;
+ bus_mem_size_t sz;
+ int cacheable;
+ bus_mem_handle_t *handle;
{
- struct ggbus_device *gd = (struct ggbus_device *)dev;
+ *handle = (bus_mem_handle_t)
+ ((struct ggbus_softc *)bct->bc_data)->sc_zargs.va + 2 * addr +
+ GG2_MEMORY_OFFSET;
+#if 0
+ printf("mem_map %x %d -> %x\n", addr, sz, *handle);
+#endif
+ return 0;
+}
- *(volatile u_char *)(gd->gd_zargs.va + GG2_MEMORY_OFFSET + 2 * ia + 1) = b;
+int
+ggbus_unmap(handle, sz)
+ bus_io_handle_t handle;
+ bus_io_size_t sz;
+{
+ return 0;
}
-u_char
-ggbusldb(dev, ia)
- struct device *dev;
- int ia;
+__inline u_int8_t
+ggbus_read_1(handle, addr)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
{
- struct ggbus_device *gd = (struct ggbus_device *)dev;
- u_char retval =
- *(volatile u_char *)(gd->gd_zargs.va + GG2_MEMORY_OFFSET + 2 * ia + 1);
+ u_int8_t val = *(volatile u_int8_t *)(handle + 2 * addr + 1);
-#ifdef DEBUG
- if (ggdebug)
- printf("ldb 0x%x => 0x%x\n", ia, retval);
+#if 0
+ printf("read_1 @%x handle %x -> %d\n", addr, handle, val);
#endif
- return retval;
+ return val;
}
-void
-ggbusstw(dev, ia, w)
- struct device *dev;
- int ia;
- u_short w;
+__inline u_int16_t
+ggbus_read_2(handle, addr)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
{
- struct ggbus_device *gd = (struct ggbus_device *)dev;
+ return swap(*(volatile u_int16_t *)(handle + 2 * addr));
+}
- *(volatile u_short *)(gd->gd_zargs.va + GG2_MEMORY_OFFSET + 2 * ia) = swap(w);
+void
+ggbus_io_read_multi_1(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int8_t *buf;
+ bus_io_size_t cnt;
+{
+ while (cnt--)
+ *buf++ = ggbus_read_1(handle, addr);
}
-u_short
-ggbusldw(dev, ia)
- struct device *dev;
- int ia;
+void
+ggbus_io_read_multi_2(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int16_t *buf;
+ bus_io_size_t cnt;
{
- struct ggbus_device *gd = (struct ggbus_device *)dev;
- u_short retval =
- swap(*(volatile u_short *)(gd->gd_zargs.va + GG2_MEMORY_OFFSET + 2 * ia));
+ while (cnt--)
+ *buf++ = ggbus_read_2(handle, addr);
+}
-#ifdef DEBUG
- if (ggdebug)
- printf("ldw 0x%x => 0x%x\n", ia, retval);
+__inline void
+ggbus_write_1(handle, addr, val)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int8_t val;
+{
+#if 0
+ printf("write_1 @%x handle %x: %d\n", addr, handle, val);
#endif
- return retval;
+ *(volatile u_int8_t *)(handle + 2 * addr + 1) = val;
+}
+
+__inline void
+ggbus_write_2(handle, addr, val)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ u_int16_t val;
+{
+ *(volatile u_int16_t *)(handle + 2 * addr) = swap(val);
+}
+
+void
+ggbus_io_write_multi_1(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ const u_int8_t *buf;
+ bus_io_size_t cnt;
+{
+ while (cnt--)
+ ggbus_write_1(handle, addr, *buf++);
+}
+
+void
+ggbus_io_write_multi_2(handle, addr, buf, cnt)
+ bus_io_handle_t handle;
+ bus_io_size_t addr;
+ const u_int16_t *buf;
+ bus_io_size_t cnt;
+{
+ while (cnt--)
+ ggbus_write_2(handle, addr, *buf++);
}
static ggbus_int_map[] = {
GG2_IRQ9, GG2_IRQ10, GG2_IRQ11, GG2_IRQ12, 0, GG2_IRQ14, GG2_IRQ15
};
-struct ggintr_desc {
- struct isr gid_isr;
- int gid_mask;
- int (*gid_fun)(void *);
- void *gid_arg;
-};
+int
+ggbusintr(v)
+ void *v;
+{
+ struct intrhand *ih = (struct intrhand *)v;
+ int handled;
-static struct ggintr_desc *ggid[16]; /* XXX */
+ if (!(*ih->ih_status & ih->ih_mask))
+ return 0;
+ for (handled = 0; ih; ih = ih->ih_next)
+ if ((*ih->ih_fun)(ih->ih_arg))
+ handled = 1;
+ return handled;
+}
-int
-ggbusintr(gid)
- struct ggintr_desc *gid;
+void
+ggbus_attach_hook(parent, self, iba)
+ struct device *parent, *self;
+ struct isabus_attach_args *iba;
{
- return (GG2_GET_STATUS (ggbusp->gd_zargs.va) & gid->gid_mask) ?
- (*gid->gid_fun)(gid->gid_arg) : 0;
}
void *
-ggbus_establish_intr(intr, type, level, ih_fun, ih_arg, ih_what)
- int intr;
+ggbus_intr_establish(ic, irq, type, level, ih_fun, ih_arg, ih_what)
+ void *ic;
+ int irq;
int type;
int level;
int (*ih_fun)(void *);
void *ih_arg;
char *ih_what;
{
- if (ggid[intr]) {
- log(LOG_WARNING, "ISA interrupt %d already handled\n", intr);
- return 0;
- }
- MALLOC(ggid[intr], struct ggintr_desc *, sizeof(struct ggintr_desc),
- M_DEVBUF, M_WAITOK);
- ggid[intr]->gid_isr.isr_intr = ggbusintr;
- ggid[intr]->gid_isr.isr_arg = ggid[intr];
- ggid[intr]->gid_isr.isr_ipl = 6;
- ggid[intr]->gid_isr.isr_mapped_ipl = level;
- ggid[intr]->gid_mask = 1 << ggbus_int_map[intr + 1];
- ggid[intr]->gid_fun = ih_fun;
- ggid[intr]->gid_arg = ih_arg;
- add_isr(&ggid[intr]->gid_isr);
- return &ggid[intr];
+ struct intrhand **p, *c, *ih;
+ struct ggbus_softc *sc = (struct ggbus_softc *)ic;
+
+ /* no point in sleeping unless someone can free memory. */
+ ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
+ if (ih == NULL)
+ panic("ggbus_intr_establish: can't malloc handler info");
+
+ if (irq > ICU_LEN || type == IST_NONE)
+ panic("ggbus_intr_establish: bogus irq or type");
+
+ switch (sc->sc_intrsharetype[irq]) {
+ case IST_EDGE:
+ case IST_LEVEL:
+ if (type == sc->sc_intrsharetype[irq])
+ break;
+ case IST_PULSE:
+ if (type != IST_NONE)
+ panic("ggbus_intr_establish: can't share %s with %s",
+ isa_intr_typename(sc->sc_intrsharetype[irq]),
+ isa_intr_typename(type));
+ break;
+ }
+
+ /*
+ * Figure out where to put the handler.
+ * This is O(N^2), but we want to preserve the order, and N is
+ * generally small.
+ */
+ for (p = &sc->sc_ih[irq]; (c = *p) != NULL; p = &c->ih_next)
+ ;
+
+ /*
+ * Poke the real handler in now.
+ */
+ ih->ih_fun = ih_fun;
+ ih->ih_arg = ih_arg;
+ ih->ih_count = 0;
+ ih->ih_next = NULL;
+ ih->ih_irq = irq;
+ ih->ih_what = ih_what;
+ ih->ih_mask = 1 << ggbus_int_map[irq + 1];
+ ih->ih_status = sc->sc_status;
+ ih->ih_isr.isr_intr = ggbusintr;
+ ih->ih_isr.isr_arg = ih;
+ ih->ih_isr.isr_ipl = 6;
+ ih->ih_isr.isr_mapped_ipl = level;
+ *p = ih;
+
+ add_isr(&ih->ih_isr);
+ return ih;
}
void
-ggbus_disestablish_intr(handler)
- void *handler;
+ggbus_intr_disestablish(ic, arg)
+ void *ic;
+ void *arg;
{
- struct ggintr_desc **gid = handler;
+ struct intrhand *ih = arg;
+ struct ggbus_softc *sc = (struct ggbus_softc *)ic;
+ int irq = ih->ih_irq;
+ struct intrhand **p, *q;
- remove_isr(&(*gid)->gid_isr);
- FREE(*gid, M_DEVBUF);
- *gid = 0;
+ if (irq > ICU_LEN)
+ panic("ggbus_intr_establish: bogus irq");
+
+ remove_isr(&ih->ih_isr);
+
+ /*
+ * Remove the handler from the chain.
+ * This is O(n^2), too.
+ */
+ for (p = &sc->sc_ih[irq]; (q = *p) != NULL && q != ih; p = &q->ih_next)
+ ;
+ if (q)
+ *p = q->ih_next;
+ else
+ panic("ggbus_intr_disestablish: handler not registered");
+ free(ih, M_DEVBUF);
+
+ if (sc->sc_intrsharetype[irq] == NULL)
+ sc->sc_intrsharetype[irq] = IST_NONE;
+}
+
+/* Swap bytes in a short word. */
+static u_int16_t
+swap(u_int16_t x)
+{
+ __asm("rolw #8,%0" : "=r" (x) : "0" (x));
+ return x;
}
+++ /dev/null
-/* $NetBSD: ggbus_pio.c,v 1.1 1995/08/04 14:32:17 niklas Exp $ */
-
-/*
- * Copyright (c) 1995 Niklas Hallqvist
- * 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 Niklas Hallqvist.
- * 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 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.
- */
-#include <sys/types.h>
-#include <sys/device.h>
-
-#include <machine/pio.h>
-
-#include <dev/isa/isavar.h>
-
-#include <amiga/amiga/isr.h>
-#include <amiga/dev/zbusvar.h>
-#include <amiga/isa/isa_machdep.h>
-#include <amiga/isa/ggbusreg.h>
-#include <amiga/isa/ggbusvar.h>
-
-extern struct ggbus_device *ggbusp;
-
-void ggbus_outb __P((int, u_int8_t));
-u_int8_t ggbus_inb __P((int));
-void ggbus_outw __P((int, u_int16_t));
-u_int16_t ggbus_inw __P((int));
-
-struct isa_pio_fcns ggbus_pio_fcns = {
- ggbus_inb, isa_insb,
- ggbus_inw, isa_insw,
- 0 /* ggbus_inl */, 0 /* ggbus_insl */,
- ggbus_outb, isa_outsb,
- ggbus_outw, isa_outsw,
- 0 /* ggbus_outl */, 0 /* ggbus_outsl */,
-};
-
-void
-ggbus_outb(ia, b)
- int ia;
- u_int8_t b;
-{
-#ifdef DEBUG
- if (ggdebug)
- printf("outb 0x%x,0x%x\n", ia, b);
-#endif
- *(volatile u_int8_t *)(ggbusp->gd_zargs.va + 2 * ia + 1) = b;
-}
-
-u_int8_t
-ggbus_inb(ia)
- int ia;
-{
- u_int8_t retval =
- *(volatile u_int8_t *)(ggbusp->gd_zargs.va + 2 * ia + 1);
-
-
-#ifdef DEBUG
- if (ggdebug)
- printf("inb 0x%x => 0x%x\n", ia, retval);
-#endif
- return retval;
-}
-
-void
-ggbus_outw(ia, w)
- int ia;
- u_int16_t w;
-{
-#ifdef DEBUG
- if (ggdebug)
- printf("outw 0x%x,0x%x\n", ia, w);
-#endif
- *(volatile u_int16_t *)(ggbusp->gd_zargs.va + 2 * ia) = swap (w);
-}
-
-u_int16_t
-ggbus_inw(ia)
- int ia;
-{
- u_int16_t retval =
- swap(*(volatile u_int16_t *)(ggbusp->gd_zargs.va + 2 * ia));
-
-
-#ifdef DEBUG
- if (ggdebug)
- printf("inw 0x%x => 0x%x\n", ia, retval);
-#endif
- return retval;
-}
-
-/* $NetBSD: ggbusreg.h,v 1.1 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: ggbusreg.h,v 1.2 1996/04/27 18:38:59 niklas Exp $ */
/*
- * Copyright (c) 1994 Niklas Hallqvist
+ * Copyright (c) 1994, 1996 Niklas Hallqvist
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef _GGBUSREG_H_
#define _GGBUSREG_H_
#define GG2_MEMORY_OFFSET (0x20000 - 2 * 0x90000)
#define GG2_STATUS 0x18000
-#define GG2_GET_STATUS(va) (*(volatile u_short *)((va) + GG2_STATUS))
+#define GG2_STATUS_ADDR(va) (volatile u_int16_t *)((va) + GG2_STATUS)
#define GG2_MASTER 0
#define GG2_WAIT 1
#define GG2_GET_INT_STATUS(va) (GG2_GET_STATUS(va) & GG2_IRQ_MASK)
#define GG2_INT_CTRL 0x18002
-#define GG2_DISABLE_INTS(va) (*(volatile u_short *)((va) + GG2_INT_CTRL))
-#define GG2_ENABLE_INTS(va) (*(volatile u_short *)((va) + GG2_INT_CTRL) = 0)
+#define GG2_DISABLE_INTS(va) (*(volatile u_int16_t *)((va) + GG2_INT_CTRL))
+#define GG2_ENABLE_INTS(va) (*(volatile u_int16_t *)((va) + GG2_INT_CTRL) = 0)
#define GG2_WAIT_CTRL 0x18004
-#define GG2_TOGGLE_WAIT(va) (*(volatile u_char *)((va) + GG2_WAIT_CTRL))
+#define GG2_TOGGLE_WAIT(va) (*(volatile u_int8_t *)((va) + GG2_WAIT_CTRL))
#define GG2_ENABLE_WAIT(va) \
while ((GG2_GET_STATUS(va) & 1 << GG2_WAIT) == 0) GG2_TOGGLE_WAIT(va)
#define GG2_DISABLE_WAIT(va) \
-/* $NetBSD: ggbusvar.h,v 1.1 1994/07/08 23:32:17 niklas Exp $ */
+/* $OpenBSD: ggbusvar.h,v 1.2 1996/04/27 18:39:00 niklas Exp $ */
/*
- * Copyright (c) 1994, 1995 Niklas Hallqvist
+ * Copyright (c) 1994, 1995, 1996 Niklas Hallqvist
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+
#ifndef _GGBUSVAR_H_
#define _GGBUSVAR_H_
-struct ggbus_device {
- struct device gd_dev;
- struct zbus_args gd_zargs;
- struct isa_link gd_link;
- int (*gd_ifunc[16])();
- void *gd_iarg[16];
- int gd_ipri[16];
- int gd_imask;
- struct isr gd_isr;
+/*
+ * Interrupt handler chains. ggbus_intr_establish() inserts a handler into
+ * the list. The handler is called with its (single) argument.
+ */
+struct intrhand {
+ struct intrhand *ih_next;
+ int (*ih_fun)();
+ void *ih_arg;
+ u_long ih_count;
+ int ih_irq;
+ char *ih_what;
+
+ struct isr ih_isr;
+ u_int16_t ih_mask;
+ volatile u_int16_t *ih_status;
};
-extern int ggdebug;
+#define ICU_LEN 16 /* number of ISA IRQs (XXX) */
-#endif
+struct ggbus_softc {
+ struct device sc_dev;
+ struct zbus_args sc_zargs;
+ struct intrhand *sc_ih[ICU_LEN];
+ int sc_intrsharetype[ICU_LEN];
+ volatile u_int16_t *sc_status;
+ struct amiga_bus_chipset sc_bc;
+ struct amiga_isa_chipset sc_ic;
+};
+
+extern int ggdebug;
+
+#endif
-/* $OpenBSD: if_isaed.c,v 1.2 1996/02/27 15:40:57 niklas Exp $ */
-/* $NetBSD: if_isaed.c,v 1.7 1994/11/28 21:47:38 root Exp $ */
+/* $OpenBSD: if_isaed.c,v 1.3 1996/04/27 18:39:00 niklas Exp $ */
/*
- * Copyright (c) 1994, 1995 Niklas Hallqvist.
- * All rights reserved.
- *
- * Amiga adaptation based on:
- *
* Device driver for National Semiconductor DS8390/WD83C690 based ethernet
* adapters.
*
- * Copyright (c) 1994, 1995 Charles Hannum.
- * All rights reserved.
+ * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
*
* Copyright (C) 1993, David Greenman. This software may be used, modified,
* copied, distributed, and sold, in both source and binary form provided that
#endif
#include <machine/cpu.h>
-#include <machine/pio.h>
+#include <machine/bus.h>
+#include <machine/intr.h>
#include <dev/isa/isareg.h>
#include <dev/isa/isavar.h>
-#include <dev/isa/if_edreg.h>
-
#define ED_BYTE_ORDER LITTLE_ENDIAN
#include <dev/ic/dp8390reg.h>
-
-#include <amiga/isa/isa_machdep.h> /* XXX USES ISA HOLE DIRECTLY */
+#include <dev/isa/if_edreg.h>
/*
- * isaed_softc: per line info and status
+ * ed_softc: per line info and status
*/
-struct isaed_softc {
+struct ed_softc {
struct device sc_dev;
void *sc_ih;
struct arpcom sc_arpcom; /* ethernet common */
+ void *sc_sh; /* shutdown hook */
char *type_str; /* pointer to type string */
u_char vendor; /* interface vendor */
u_char type; /* interface type code */
+ u_short spec_flags;
+#define ED_REATTACH 0x0001 /* Reattach */
+#define ED_NOTPRESENT 0x0002 /* card not present; do not allow
+ reconfiguration */
+
+ bus_chipset_tag_t sc_bc; /* bus identifier */
+ bus_io_handle_t sc_ioh; /* io handle */
+ bus_mem_handle_t sc_memh; /* bus memory handle */
- int asic_addr; /* ASIC I/O bus address */
- int nic_addr; /* NIC (DS8390) I/O bus address */
+ bus_io_size_t asic_base; /* offset of ASIC I/O port */
+ bus_io_size_t nic_base; /* offset of NIC (DS8390) I/O port */
/*
* The following 'proto' variable is part of a work-around for 8013EBT asics
u_char isa16bit; /* width of access to card 0=8 or 1=16 */
u_char is790; /* set by probe if NIC is a 790 */
- caddr_t mem_start; /* NIC memory start address */
- caddr_t mem_end; /* NIC memory end address */
- u_long mem_size; /* total NIC memory size */
- caddr_t mem_ring; /* start of RX ring-buffer (in NIC mem) */
+ int mem_start; /* offset of NIC memory */
+ int mem_end; /* offset of NIC memory end */
+ int mem_size; /* total NIC memory size */
+ int mem_ring; /* offset of RX ring-buffer (in NIC mem) */
u_char mem_shared; /* NIC memory is shared with host */
u_char txb_cnt; /* number of transmit buffers */
u_char next_packet; /* pointer to next unread RX packet */
};
-int isaedprobe __P((struct device *, void *, void *));
-void isaedattach __P((struct device *, struct device *, void *));
-int isaedintr __P((void *));
-int isaedioctl __P((struct ifnet *, u_long, caddr_t));
-void isaedstart __P((struct ifnet *));
-void isaedwatchdog __P((int));
-void isaedreset __P((struct isaed_softc *));
-void isaedinit __P((struct isaed_softc *));
-void isaedstop __P((struct isaed_softc *));
+int edprobe __P((struct device *, void *, void *));
+void edattach __P((struct device *, struct device *, void *));
+int ed_find __P((struct ed_softc *, struct cfdata *,
+ struct isa_attach_args *ia));
+int ed_probe_generic8390 __P((bus_chipset_tag_t, bus_io_handle_t, int));
+int ed_find_WD80x3 __P((struct ed_softc *, struct cfdata *,
+ struct isa_attach_args *ia));
+int ed_find_3Com __P((struct ed_softc *, struct cfdata *,
+ struct isa_attach_args *ia));
+int ed_find_Novell __P((struct ed_softc *, struct cfdata *,
+ struct isa_attach_args *ia));
+int edintr __P((void *));
+int edioctl __P((struct ifnet *, u_long, caddr_t));
+void edstart __P((struct ifnet *));
+void edwatchdog __P((int));
+void edreset __P((struct ed_softc *));
+void edinit __P((struct ed_softc *));
+void edstop __P((struct ed_softc *));
+
+void ed_shared_writemem __P((struct ed_softc *, caddr_t, int, int));
+void ed_shared_readmem __P((struct ed_softc *, int, caddr_t, int));
#define inline /* XXX for debugging porpoises */
-void isaed_getmcaf __P((struct arpcom *, u_long *));
-void isaedread __P((struct isaed_softc *, caddr_t, int));
-struct mbuf *isaedget __P((struct isaed_softc *, caddr_t, int));
-static inline void isaed_rint __P((struct isaed_softc *));
-static inline void isaed_xmit __P((struct isaed_softc *));
-static inline caddr_t isaed_ring_copy __P((struct isaed_softc *, caddr_t,
- caddr_t, u_short));
+void ed_getmcaf __P((struct arpcom *, u_long *));
+void edread __P((struct ed_softc *, int, int));
+struct mbuf *edget __P((struct ed_softc *, int, int));
+static inline void ed_rint __P((struct ed_softc *));
+static inline void ed_xmit __P((struct ed_softc *));
+static inline int ed_ring_copy __P((struct ed_softc *, int, caddr_t,
+ u_short));
-void isaed_pio_readmem __P((struct isaed_softc *, u_short, caddr_t, u_short));
-void isaed_pio_writemem __P((struct isaed_softc *, caddr_t, u_short, u_short));
-u_short isaed_pio_write_mbufs __P((struct isaed_softc *, struct mbuf *, u_short));
+void ed_pio_readmem __P((struct ed_softc *, u_short, caddr_t, u_short));
+void ed_pio_writemem __P((struct ed_softc *, caddr_t, u_short, u_short));
+u_short ed_pio_write_mbufs __P((struct ed_softc *, struct mbuf *, u_short));
-#ifdef ISAED_DEBUG
-int isaeddebug = 0;
-#endif
-int isaedprobes = 7;
+struct cfattach isaed_ca = {
+ sizeof(struct ed_softc), edprobe, edattach
+};
-struct cfdriver isaedcd = {
- NULL, "isaed", isaedprobe, isaedattach, DV_IFNET, sizeof(struct isaed_softc)
+struct cfdriver isaed_cd = {
+ NULL, "isaed", DV_IFNET
};
#define ETHER_MIN_LEN 64
#define ETHER_MAX_LEN 1518
#define ETHER_ADDR_LEN 6
-#define NIC_PUT(sc, off, val) outb(sc->nic_addr + off, val)
-#define NIC_GET(sc, off) inb(sc->nic_addr + off)
+#define NIC_PUT(bc, ioh, nic, reg, val) \
+ bus_io_write_1((bc), (ioh), ((nic) + (reg)), (val))
+#define NIC_GET(bc, ioh, nic, reg) \
+ bus_io_read_1((bc), (ioh), ((nic) + (reg)))
+
+/*#include "pcmciabus.h"*/
+#if NPCMCIABUS > 0
+
+#include <dev/pcmcia/pcmciabus.h>
+static int ed_probe_pcmcia_ne __P((struct device *, void *,
+ void *, struct pcmcia_link *));
+
+static int edmod __P((struct pcmcia_link *, struct device *,
+ struct pcmcia_conf *, struct cfdata *cf));
+
+static int ed_remove __P((struct pcmcia_link *, struct device *));
+
+/* additional setup needed for pcmcia devices */
+static int
+ed_probe_pcmcia_ne(parent, match, aux, pc_link)
+ struct device *parent;
+ void *match;
+ void *aux;
+ struct pcmcia_link *pc_link;
+{
+ struct ed_softc *sc = match;
+ struct cfdata *cf = sc->sc_dev.dv_cfdata;
+ struct isa_attach_args *ia = aux;
+ struct pcmciadevs *dev=pc_link->device;
+ int err;
+ extern int ifqmaxlen;
+ u_char enaddr[ETHER_ADDR_LEN];
+
+ if ((int)dev->param >= 0)
+ err = pcmcia_read_cis(pc_link, enaddr,
+ (int) dev->param, ETHER_ADDR_LEN);
+ else
+ err = 0;
+ if (err)
+ printf("Cannot read cis info %d\n", err);
+
+ if (ed_probe_Novell(sc, cf, ia)) {
+ delay(100);
+ if ((int)dev->param >= 0) {
+ err = pcmcia_read_cis(pc_link, sc->sc_arpcom.ac_enaddr,
+ (int) dev->param, ETHER_ADDR_LEN);
+ if (err) {
+ printf("Cannot read cis info %d\n", err);
+ return 0;
+ }
+ if(bcmp(enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN)) {
+ printf("ENADDR MISMATCH %s ",
+ ether_sprintf(sc->sc_arpcom.ac_enaddr));
+ printf("- %s\n", ether_sprintf(enaddr));
+ bcopy(enaddr,sc->sc_arpcom.ac_enaddr,
+ ETHER_ADDR_LEN);
+ }
+ }
+ /* clear ED_NOTPRESENT, set ED_REATTACH if needed */
+ sc->spec_flags=pc_link->flags&PCMCIA_REATTACH?ED_REATTACH:0;
+ sc->type_str = dev->model;
+ sc->sc_arpcom.ac_if.if_snd.ifq_maxlen=ifqmaxlen;
+ return 1;
+ }
+ return 0;
+}
+
+/* modify config entry */
+static int
+edmod(pc_link, self, pc_cf, cf)
+ struct pcmcia_link *pc_link;
+ struct device *self;
+ struct pcmcia_conf *pc_cf;
+ struct cfdata *cf;
+{
+ int err;
+ struct pcmciadevs *dev=pc_link->device;
+ struct ed_softc *sc = (void *)self;
+ int svec_card = strcmp(dev->manufacturer, "SVEC") == 0;
+ int de650_0 = (pc_cf->memwin != 0) && !svec_card;
+ err = pc_link->adapter->bus_link->bus_config(pc_link, self, pc_cf, cf);
+ if (err)
+ return err;
+
+ if (svec_card) {
+ pc_cf->memwin = 0;
+ }
+ if (de650_0) {
+ pc_cf->io[0].flags =
+ (pc_cf->io[0].flags&~PCMCIA_MAP_16)|PCMCIA_MAP_8;
+ pc_cf->memwin = 0;
+ pc_cf->cfgtype = DOSRESET|1;
+ }
+ else {
+ /* still wrong in CIS; fix it here */
+ pc_cf->io[0].flags = PCMCIA_MAP_8|PCMCIA_MAP_16;
+ pc_cf->cfgtype = 1;
+ }
+
+ return err;
+}
+
+
+static int
+ed_remove(pc_link,self)
+ struct pcmcia_link *pc_link;
+ struct device *self;
+{
+ struct ed_softc *sc = (void *)self;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ if_down(ifp);
+ edstop(sc);
+ shutdownhook_disestablish(sc->sc_sh);
+ ifp->if_flags &= ~(IFF_RUNNING|IFF_UP);
+ sc->spec_flags |= ED_NOTPRESENT;
+ return pc_link->adapter->bus_link->bus_unconfig(pc_link);
+}
+
+static struct pcmcia_dlink {
+ struct pcmcia_device pcd;
+} pcmcia_dlink= {
+ "PCMCIA Novell compatible", edmod, ed_probe_pcmcia_ne, NULL, ed_remove
+};
+
+struct pcmciadevs pcmcia_ed_devs[]={
+ { "ed", 0, "D-Link", "DE-650", "Ver 01.00", NULL, (void *) -1,
+ (void *)&pcmcia_dlink },
+ { "ed", 0, "D-Link", "DE-650", "", NULL, (void *) 0x40,
+ (void *)&pcmcia_dlink },
+ { "ed", 0, "LINKSYS", "E-CARD", "Ver 01.00", NULL, (void *)-1,
+ (void *)&pcmcia_dlink },
+ { "ed", 0, "IBM Corp.", "Ethernet", "0933495", NULL, (void *) 0xff0,
+ (void *)&pcmcia_dlink },
+ { "ed", 0, "Socket Communications Inc",
+ "Socket EA PCMCIA LAN Adapter Revision D", "Ethernet ID 000000000000",
+ NULL, (void *) -1,
+ (void *)&pcmcia_dlink },
+ /* probably not right for ethernet address--card does not seem to
+ have it anywhere. */
+ { "ed", 0, "SVEC", "FD605 PCMCIA EtherNet Card", "V1-1", NULL,
+ (void *)0xb4, (void *)&pcmcia_dlink },
+ { "ed", 0, "PMX ", "PE-200", "ETHERNET", "R01", (void *) 0x110,
+ (void *)&pcmcia_dlink }, /* 0x110 is a guess */
+ { NULL }
+};
+#endif
+
/*
* Determine if the device is present.
*/
int
-isaedprobe(parent, match, aux)
+edprobe(parent, match, aux)
struct device *parent;
void *match, *aux;
{
- struct isaed_softc *sc = match;
+ struct ed_softc *sc = match;
struct cfdata *cf = sc->sc_dev.dv_cfdata;
struct isa_attach_args *ia = aux;
- if ((isaedprobes & 1) && isaed_probe_WD80x3(sc, cf, ia))
+ return (ed_find(match, sc->sc_dev.dv_cfdata, aux));
+}
+
+/*
+ * Fill in softc (if given), based on device type, cfdata and attach args.
+ * Return 1 if successful, 0 otherwise.
+ */
+int
+ed_find(sc, cf, ia)
+ struct ed_softc *sc;
+ struct cfdata *cf;
+ struct isa_attach_args *ia;
+{
+ if (ed_find_Novell(sc, cf, ia))
return (1);
- if ((isaedprobes & 2) && isaed_probe_3Com(sc, cf, ia))
+ if (ed_find_WD80x3(sc, cf, ia))
return (1);
- if ((isaedprobes & 4) && isaed_probe_Novell(sc, cf, ia))
+ if (ed_find_3Com(sc, cf, ia))
return (1);
return (0);
}
* Return 1 if 8390 was found, 0 if not.
*/
int
-isaed_probe_generic8390(sc)
- struct isaed_softc *sc;
+ed_probe_generic8390(bc, ioh, nicbase)
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ int nicbase;
{
- if ((NIC_GET(sc, ED_P0_CR) &
+ if ((NIC_GET(bc, ioh, nicbase, ED_P0_CR) &
(ED_CR_RD2 | ED_CR_TXP | ED_CR_STA | ED_CR_STP)) !=
(ED_CR_RD2 | ED_CR_STP))
return (0);
- if ((NIC_GET(sc, ED_P0_ISR) & ED_ISR_RST) != ED_ISR_RST)
+ if ((NIC_GET(bc, ioh, nicbase, ED_P0_ISR) & ED_ISR_RST) != ED_ISR_RST)
return (0);
return (1);
}
-int isaed_wd584_irq[] = { 9, 3, 5, 7, 10, 11, 15, 4 };
-int isaed_wd790_irq[] = { IRQUNK, 9, 3, 5, 7, 10, 11, 15 };
+int ed_wd584_irq[] = { 9, 3, 5, 7, 10, 11, 15, 4 };
+int ed_wd790_irq[] = { IRQUNK, 9, 3, 5, 7, 10, 11, 15 };
/*
* Probe and vendor-specific initialization routine for SMC/WD80x3 boards.
*/
int
-isaed_probe_WD80x3(sc, cf, ia)
- struct isaed_softc *sc;
+ed_find_WD80x3(sc, cf, ia)
+ struct ed_softc *sc;
struct cfdata *cf;
struct isa_attach_args *ia;
{
- int i;
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ bus_mem_handle_t memh;
u_int memsize;
u_char iptr, isa16bit, sum;
+ int i, rv, mapped_mem = 0;
+ int asicbase, nicbase;
- sc->asic_addr = ia->ia_iobase;
- sc->nic_addr = sc->asic_addr + ED_WD_NIC_OFFSET;
+ bc = ia->ia_bc;
+ rv = 0;
+
+ if (bus_io_map(bc, ia->ia_iobase, ED_WD_IO_PORTS, &ioh))
+ return (0);
+
+ sc->asic_base = asicbase = 0;
+ sc->nic_base = nicbase = asicbase + ED_WD_NIC_OFFSET;
sc->is790 = 0;
#ifdef TOSH_ETHER
- outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_POW);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR, ED_WD_MSR_POW);
delay(10000);
#endif
* this, though: some clone WD boards don't pass the checksum test.
* Danpex boards for one.
*/
- for (sum = 0, i = 0; i < 8; ++i) {
- u_char c = inb(sc->asic_addr + ED_WD_PROM + i);
-
- sum += c;
-#ifdef ISAED_DEBUG
- if (isaeddebug)
- printf("inb(0x%x) = 0x%02x -> sum = %d\n",
- sc->asic_addr + ED_WD_PROM + i, c, sum);
-#endif
- }
+ for (sum = 0, i = 0; i < 8; ++i)
+ sum += bus_io_read_1(bc, ioh, asicbase + ED_WD_PROM + i);
if (sum != ED_WD_ROM_CHECKSUM_TOTAL) {
/*
* clones. In this case, the checksum byte (the eighth byte)
* seems to always be zero.
*/
- if (inb(sc->asic_addr + ED_WD_CARD_ID) != ED_TYPE_WD8003E ||
- inb(sc->asic_addr + ED_WD_PROM + 7) != 0)
- return (0);
+ if (bus_io_read_1(bc, ioh, asicbase + ED_WD_CARD_ID) !=
+ ED_TYPE_WD8003E ||
+ bus_io_read_1(bc, ioh, asicbase + ED_WD_PROM + 7) != 0)
+ goto out;
}
/* Reset card to force it into a known state. */
#ifdef TOSH_ETHER
- outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST | ED_WD_MSR_POW);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
+ ED_WD_MSR_RST | ED_WD_MSR_POW);
#else
- outb(sc->asic_addr + ED_WD_MSR, ED_WD_MSR_RST);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR, ED_WD_MSR_RST);
#endif
delay(100);
- outb(sc->asic_addr + ED_WD_MSR,
- inb(sc->asic_addr + ED_WD_MSR) & ~ED_WD_MSR_RST);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
+ bus_io_read_1(bc, ioh, asicbase + ED_WD_MSR) & ~ED_WD_MSR_RST);
/* Wait in the case this card is reading it's EEROM. */
delay(5000);
sc->vendor = ED_VENDOR_WD_SMC;
- sc->type = inb(sc->asic_addr + ED_WD_CARD_ID);
+ sc->type = bus_io_read_1(bc, ioh, asicbase + ED_WD_CARD_ID);
/* Set initial values for width/size. */
memsize = 8192;
isa16bit = 1;
break;
case ED_TYPE_WD8013EP: /* also WD8003EP */
- if (inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) {
+ if (bus_io_read_1(bc, ioh, asicbase + ED_WD_ICR) &
+ ED_WD_ICR_16BIT) {
isa16bit = 1;
memsize = 16384;
sc->type_str = "WD8013EP";
isa16bit = 1;
break;
case ED_TYPE_SMC8216C:
- sc->type_str = "SMC8216/SMC8216C";
- memsize = 16384;
- isa16bit = 1;
- sc->is790 = 1;
- break;
case ED_TYPE_SMC8216T:
- sc->type_str = "SMC8216T";
- memsize = 16384;
+ sc->type_str = (sc->type == ED_TYPE_SMC8216C) ?
+ "SMC8216/SMC8216C" : "SMC8216T";
+ bus_io_write_1(bc, ioh, asicbase + ED_WD790_HWR,
+ bus_io_read_1(bc, ioh, asicbase + ED_WD790_HWR)
+ | ED_WD790_HWR_SWH);
+ switch (bus_io_read_1(bc, ioh, asicbase + ED_WD790_RAR) &
+ ED_WD790_RAR_SZ64) {
+ case ED_WD790_RAR_SZ64:
+ memsize = 65536;
+ break;
+ case ED_WD790_RAR_SZ32:
+ memsize = 32768;
+ break;
+ case ED_WD790_RAR_SZ16:
+ memsize = 16384;
+ break;
+ case ED_WD790_RAR_SZ8:
+ /* 8216 has 16K shared mem -- 8416 has 8K */
+ sc->type_str = (sc->type == ED_TYPE_SMC8216C) ?
+ "SMC8416C/SMC8416BT" : "SMC8416T";
+ memsize = 8192;
+ break;
+ }
+ bus_io_write_1(bc, ioh, asicbase + ED_WD790_HWR,
+ bus_io_read_1(bc, ioh,
+ asicbase + ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
+
isa16bit = 1;
sc->is790 = 1;
break;
#ifdef TOSH_ETHER
(sc->type != ED_TYPE_TOSHIBA1) && (sc->type != ED_TYPE_TOSHIBA4) &&
#endif
- ((inb(sc->asic_addr + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
+ ((bus_io_read_1(bc, ioh,
+ asicbase + ED_WD_ICR) & ED_WD_ICR_16BIT) == 0)) {
isa16bit = 0;
memsize = 8192;
}
-#ifdef ISAED_DEBUG
- if (isaeddebug) {
- printf("type=%x type_str=%s isa16bit=%d memsize=%d ia_msize=%d\n",
- sc->type, sc->type_str ?: "unknown", isa16bit, memsize,
- ia->ia_msize);
- for (i = 0; i < 8; i++)
- printf("%x -> %x\n", i, inb(sc->asic_addr + i));
- }
+#ifdef ED_DEBUG
+ printf("type=%x type_str=%s isa16bit=%d memsize=%d id_msize=%d\n",
+ sc->type, sc->type_str ?: "unknown", isa16bit, memsize,
+ ia->ia_msize);
+ for (i = 0; i < 8; i++)
+ printf("%x -> %x\n", i, bus_io_read_1(bc, ioh, asicbase + i));
#endif
/* Allow the user to override the autoconfiguration. */
if (ia->ia_msize)
if (sc->is790) {
u_char x;
/* Assemble together the encoded interrupt number. */
- outb(ia->ia_iobase + ED_WD790_HWR,
- inb(ia->ia_iobase + ED_WD790_HWR) | ED_WD790_HWR_SWH);
- x = inb(ia->ia_iobase + ED_WD790_GCR);
+ bus_io_write_1(bc, ioh, ED_WD790_HWR,
+ bus_io_read_1(bc, ioh, ED_WD790_HWR) | ED_WD790_HWR_SWH);
+ x = bus_io_read_1(bc, ioh, ED_WD790_GCR);
iptr = ((x & ED_WD790_GCR_IR2) >> 4) |
((x & (ED_WD790_GCR_IR1|ED_WD790_GCR_IR0)) >> 2);
- outb(ia->ia_iobase + ED_WD790_HWR,
- inb(ia->ia_iobase + ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
+ bus_io_write_1(bc, ioh, ED_WD790_HWR,
+ bus_io_read_1(bc, ioh, ED_WD790_HWR) & ~ED_WD790_HWR_SWH);
/*
* Translate it using translation table, and check for
* correctness.
*/
if (ia->ia_irq != IRQUNK) {
- if (ia->ia_irq != isaed_wd790_irq[iptr]) {
+ if (ia->ia_irq != ed_wd790_irq[iptr]) {
printf("%s: irq mismatch; kernel configured %d != board configured %d\n",
sc->sc_dev.dv_xname, ia->ia_irq,
- isaed_wd790_irq[iptr]);
- return (0);
+ ed_wd790_irq[iptr]);
+ goto out;
}
} else
- ia->ia_irq = isaed_wd790_irq[iptr];
+ ia->ia_irq = ed_wd790_irq[iptr];
/* Enable the interrupt. */
- outb(ia->ia_iobase + ED_WD790_ICR,
- inb(ia->ia_iobase + ED_WD790_ICR) | ED_WD790_ICR_EIL);
+ bus_io_write_1(bc, ioh, ED_WD790_ICR,
+ bus_io_read_1(bc, ioh, ED_WD790_ICR) | ED_WD790_ICR_EIL);
} else if (sc->type & ED_WD_SOFTCONFIG) {
/* Assemble together the encoded interrupt number. */
- iptr = (inb(ia->ia_iobase + ED_WD_ICR) & ED_WD_ICR_IR2) |
- ((inb(ia->ia_iobase + ED_WD_IRR) &
+ iptr = (bus_io_read_1(bc, ioh, ED_WD_ICR) & ED_WD_ICR_IR2) |
+ ((bus_io_read_1(bc, ioh, ED_WD_IRR) &
(ED_WD_IRR_IR0 | ED_WD_IRR_IR1)) >> 5);
/*
* Translate it using translation table, and check for
* correctness.
*/
if (ia->ia_irq != IRQUNK) {
- if (ia->ia_irq != isaed_wd584_irq[iptr]) {
+ if (ia->ia_irq != ed_wd584_irq[iptr]) {
printf("%s: irq mismatch; kernel configured %d != board configured %d\n",
sc->sc_dev.dv_xname, ia->ia_irq,
- isaed_wd584_irq[iptr]);
- return (0);
+ ed_wd584_irq[iptr]);
+ goto out;
}
} else
- ia->ia_irq = isaed_wd584_irq[iptr];
+ ia->ia_irq = ed_wd584_irq[iptr];
/* Enable the interrupt. */
- outb(ia->ia_iobase + ED_WD_IRR,
- inb(ia->ia_iobase + ED_WD_IRR) | ED_WD_IRR_IEN);
+ bus_io_write_1(bc, ioh, ED_WD_IRR,
+ bus_io_read_1(bc, ioh, ED_WD_IRR) | ED_WD_IRR_IEN);
} else {
if (ia->ia_irq == IRQUNK) {
printf("%s: %s does not have soft configuration\n",
sc->sc_dev.dv_xname, sc->type_str);
- return (0);
+ goto out;
}
}
sc->isa16bit = isa16bit;
sc->mem_shared = 1;
ia->ia_msize = memsize;
- sc->mem_start = ISA_HOLE_VADDR(ia->ia_maddr);
+ if (bus_mem_map(bc, ia->ia_maddr, memsize, 0, &memh))
+ goto out;
+ mapped_mem = 1;
+ sc->mem_start = 0; /* offset */
/* Allocate one xmit buffer if < 16k, two buffers otherwise. */
if ((memsize < 16384) || (cf->cf_flags & ED_FLAGS_NO_MULTI_BUFFERING))
/* Get station address from on-board ROM. */
for (i = 0; i < ETHER_ADDR_LEN; ++i)
sc->sc_arpcom.ac_enaddr[i] =
- inb(sc->asic_addr + ED_WD_PROM + i);
+ bus_io_read_1(bc, ioh, asicbase + ED_WD_PROM + i);
/*
* Set upper address bits and 8/16 bit access to shared memory.
if (isa16bit) {
if (sc->is790) {
sc->wd_laar_proto =
- inb(sc->asic_addr + ED_WD_LAAR) &
+ bus_io_read_1(bc, ioh, asicbase + ED_WD_LAAR) &
~ED_WD_LAAR_M16EN;
} else {
sc->wd_laar_proto =
ED_WD_LAAR_L16EN |
- ((kvtop(sc->mem_start) >> 19) &
+ ((ia->ia_maddr >> 19) &
ED_WD_LAAR_ADDRHI);
}
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
} else {
if ((sc->type & ED_WD_SOFTCONFIG) ||
#endif
(sc->type == ED_TYPE_WD8013EBT) && !sc->is790) {
sc->wd_laar_proto =
- ((kvtop(sc->mem_start) >> 19) &
+ ((ia->ia_maddr >> 19) &
ED_WD_LAAR_ADDRHI);
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
sc->wd_laar_proto);
}
}
*/
if (!sc->is790) {
#ifdef TOSH_ETHER
- outb(sc->asic_addr + ED_WD_MSR + 1,
- ((kvtop(sc->mem_start) >> 8) & 0xe0) | 4);
- outb(sc->asic_addr + ED_WD_MSR + 2,
- ((kvtop(sc->mem_start) >> 16) & 0x0f));
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR + 1,
+ ((ia->ia_maddr >> 8) & 0xe0) | 4);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR + 2,
+ ((ia->ia_maddr >> 16) & 0x0f));
sc->wd_msr_proto = ED_WD_MSR_POW;
#else
sc->wd_msr_proto =
- (kvtop(sc->mem_start) >> 13) & ED_WD_MSR_ADDR;
+ (ia->ia_maddr >> 13) & ED_WD_MSR_ADDR;
#endif
sc->cr_proto = ED_CR_RD2;
} else {
- outb(sc->asic_addr + 0x04,
- inb(sc->asic_addr + 0x04) | 0x80);
- outb(sc->asic_addr + 0x0b,
- ((kvtop(sc->mem_start) >> 13) & 0x0f) |
- ((kvtop(sc->mem_start) >> 11) & 0x40) |
- (inb(sc->asic_addr + 0x0b) & 0xb0));
- outb(sc->asic_addr + 0x04,
- inb(sc->asic_addr + 0x04) & ~0x80);
+ bus_io_write_1(bc, ioh, asicbase + 0x04,
+ bus_io_read_1(bc, ioh, asicbase + 0x04) | 0x80);
+ bus_io_write_1(bc, ioh, asicbase + 0x0b,
+ ((ia->ia_maddr >> 13) & 0x0f) |
+ ((ia->ia_maddr >> 11) & 0x40) |
+ (bus_io_read_1(bc, ioh, asicbase + 0x0b) & 0xb0));
+ bus_io_write_1(bc, ioh, asicbase + 0x04,
+ bus_io_read_1(bc, ioh, asicbase + 0x04) & ~0x80);
sc->wd_msr_proto = 0x00;
sc->cr_proto = 0;
}
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
sc->wd_msr_proto | ED_WD_MSR_MENB);
- (void) inb(0x84);
- (void) inb(0x84);
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
/* Now zero memory and verify that it is clear. */
- bzero(sc->mem_start, memsize);
+ for (i = 0; i < memsize; ++i)
+ bus_mem_write_1(bc, memh, sc->mem_start + i, 0);
for (i = 0; i < memsize; ++i)
- if (sc->mem_start[i]) {
+ if (bus_mem_read_1(bc, memh, sc->mem_start + i)) {
printf("%s: failed to clear shared memory at %x - check configuration\n",
sc->sc_dev.dv_xname,
- kvtop(sc->mem_start + i));
+ (ia->ia_maddr + sc->mem_start + i));
/* Disable 16 bit access to shared memory. */
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
sc->wd_msr_proto);
if (isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
sc->wd_laar_proto);
- (void) inb(0x84);
- (void) inb(0x84);
- return (0);
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ goto out;
}
/*
* and 2) so that other 8 bit devices with shared memory can be
* used in this 128k region, too.
*/
- outb(sc->asic_addr + ED_WD_MSR, sc->wd_msr_proto);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR, sc->wd_msr_proto);
if (isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR, sc->wd_laar_proto);
- (void) inb(0x84);
- (void) inb(0x84);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
+ sc->wd_laar_proto);
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
ia->ia_iosize = ED_WD_IO_PORTS;
- return (1);
+ rv = 1;
+
+ out:
+ /*
+ * XXX Sould always unmap, but we can't yet.
+ * XXX Need to squish "indirect" first.
+ */
+ if (rv == 0) {
+ bus_io_unmap(bc, ioh, ED_WD_IO_PORTS);
+ if (mapped_mem)
+ bus_mem_unmap(bc, memh, memsize);
+ } else {
+ /* XXX this is all "indirect" brokenness */
+ sc->sc_bc = bc;
+ sc->sc_ioh = ioh;
+ sc->sc_memh = memh;
+ }
+ return (rv);
}
-int isaed_3com_iobase[] = {0x2e0, 0x2a0, 0x280, 0x250, 0x350, 0x330, 0x310, 0x300};
-int isaed_3com_maddr[] = {MADDRUNK, MADDRUNK, MADDRUNK, MADDRUNK, 0xc8000, 0xcc000, 0xd8000, 0xdc000};
+int ed_3com_iobase[] = {0x2e0, 0x2a0, 0x280, 0x250, 0x350, 0x330, 0x310, 0x300};
+int ed_3com_maddr[] = {MADDRUNK, MADDRUNK, MADDRUNK, MADDRUNK, 0xc8000, 0xcc000, 0xd8000, 0xdc000};
#if 0
-int isaed_3com_irq[] = {IRQUNK, IRQUNK, IRQUNK, IRQUNK, 9, 3, 4, 5};
+int ed_3com_irq[] = {IRQUNK, IRQUNK, IRQUNK, IRQUNK, 9, 3, 4, 5};
#endif
/*
* Probe and vendor-specific initialization routine for 3Com 3c503 boards.
*/
int
-isaed_probe_3Com(sc, cf, ia)
- struct isaed_softc *sc;
+ed_find_3Com(sc, cf, ia)
+ struct ed_softc *sc;
struct cfdata *cf;
struct isa_attach_args *ia;
{
- int i;
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ bus_mem_handle_t memh;
+ int i, rv, mapped_mem = 0;
u_int memsize;
u_char isa16bit, sum, x;
- int ptr;
+ int ptr, asicbase, nicbase;
- sc->asic_addr = ia->ia_iobase + ED_3COM_ASIC_OFFSET;
- sc->nic_addr = ia->ia_iobase + ED_3COM_NIC_OFFSET;
+ bc = ia->ia_bc;
+ rv = 0;
+
+ if (bus_io_map(bc, ia->ia_iobase, ED_WD_IO_PORTS, &ioh))
+ return (0);
+
+ sc->asic_base = asicbase = ED_3COM_ASIC_OFFSET;
+ sc->nic_base = nicbase = ED_3COM_NIC_OFFSET;
/*
* Verify that the kernel configured I/O address matches the board
* board is there; after all, we are already talking it at that
* address.
*/
- x = inb(sc->asic_addr + ED_3COM_BCFR);
+ x = bus_io_read_1(bc, ioh, asicbase + ED_3COM_BCFR);
if (x == 0 || (x & (x - 1)) != 0)
- return (0);
+ goto out;
ptr = ffs(x) - 1;
if (ia->ia_iobase != IOBASEUNK) {
- if (ia->ia_iobase != isaed_3com_iobase[ptr]) {
+ if (ia->ia_iobase != ed_3com_iobase[ptr]) {
printf("%s: %s mismatch; kernel configured %x != board configured %x\n",
"iobase", sc->sc_dev.dv_xname, ia->ia_iobase,
- isaed_3com_iobase[ptr]);
- return (0);
+ ed_3com_iobase[ptr]);
+ goto out;
}
} else
- ia->ia_iobase = isaed_3com_iobase[ptr];
+ ia->ia_iobase = ed_3com_iobase[ptr]; /* XXX --thorpej */
- x = inb(sc->asic_addr + ED_3COM_PCFR);
+ x = bus_io_read_1(bc, ioh, asicbase + ED_3COM_PCFR);
if (x == 0 || (x & (x - 1)) != 0)
- return (0);
+ goto out;
ptr = ffs(x) - 1;
if (ia->ia_maddr != MADDRUNK) {
- if (ia->ia_maddr != isaed_3com_maddr[ptr]) {
+ if (ia->ia_maddr != ed_3com_maddr[ptr]) {
printf("%s: %s mismatch; kernel configured %x != board configured %x\n",
"maddr", sc->sc_dev.dv_xname, ia->ia_maddr,
- isaed_3com_maddr[ptr]);
- return (0);
+ ed_3com_maddr[ptr]);
+ goto out;
}
} else
- ia->ia_maddr = isaed_3com_maddr[ptr];
+ ia->ia_maddr = ed_3com_maddr[ptr];
#if 0
- x = inb(sc->asic_addr + ED_3COM_IDCFR) & ED_3COM_IDCFR_IRQ;
+ x = bus_io_read_1(bc, ioh, asicbase + ED_3COM_IDCFR) &
+ ED_3COM_IDCFR_IRQ;
if (x == 0 || (x & (x - 1)) != 0)
- return (0);
+ goto out;
ptr = ffs(x) - 1;
if (ia->ia_irq != IRQUNK) {
- if (ia->ia_irq != isaed_3com_irq[ptr]) {
+ if (ia->ia_irq != ed_3com_irq[ptr]) {
printf("%s: irq mismatch; kernel configured %d != board configured %d\n",
sc->sc_dev.dv_xname, ia->ia_irq,
- isaed_3com_irq[ptr]);
- return (0);
+ ed_3com_irq[ptr]);
+ goto out;
}
} else
- ia->ia_irq = isaed_3com_irq[ptr];
+ ia->ia_irq = ed_3com_irq[ptr];
#endif
/*
* sequence because it'll lock up if the cable isn't connected if we
* don't.
*/
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_RST | ED_3COM_CR_XSEL);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR,
+ ED_3COM_CR_RST | ED_3COM_CR_XSEL);
/* Wait for a while, then un-reset it. */
delay(50);
* reset - it's important to set it again after the following outb
* (this is done when we map the PROM below).
*/
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR, ED_3COM_CR_XSEL);
/* Wait a bit for the NIC to recover from the reset. */
delay(5000);
* First, map ethernet address PROM over the top of where the NIC
* registers normally appear.
*/
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_EALO | ED_3COM_CR_XSEL);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR,
+ ED_3COM_CR_EALO | ED_3COM_CR_XSEL);
for (i = 0; i < ETHER_ADDR_LEN; ++i)
- sc->sc_arpcom.ac_enaddr[i] = NIC_GET(sc, i);
+ sc->sc_arpcom.ac_enaddr[i] = NIC_GET(bc, ioh, nicbase, i);
/*
* Unmap PROM - select NIC registers. The proper setting of the
- * tranceiver is set in isaedinit so that the attach code is given a
+ * tranceiver is set in edinit so that the attach code is given a
* chance to set the default based on a compile-time config option.
*/
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR, ED_3COM_CR_XSEL);
/* Determine if this is an 8bit or 16bit board. */
/* Select page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
/*
* Attempt to clear WTS bit. If it doesn't clear, then this is a
* 16-bit board.
*/
- NIC_PUT(sc, ED_P0_DCR, 0);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_DCR, 0);
/* Select page 2 registers. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_2 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase,
+ ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_2 | ED_CR_STP);
/* The 3c503 forces the WTS bit to a one if this is a 16bit board. */
- if (NIC_GET(sc, ED_P2_DCR) & ED_DCR_WTS)
+ if (NIC_GET(bc, ioh, nicbase, ED_P2_DCR) & ED_DCR_WTS)
isa16bit = 1;
else
isa16bit = 0;
/* Select page 0 registers. */
- NIC_PUT(sc, ED_P2_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P2_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
- sc->mem_start = ISA_HOLE_VADDR(ia->ia_maddr);
+ if (bus_mem_map(bc, ia->ia_maddr, memsize, 0, &memh))
+ goto out;
+ mapped_mem = 1;
+ sc->mem_start = 0; /* offset */
sc->mem_size = memsize;
sc->mem_end = sc->mem_start + memsize;
* Initialize GA page start/stop registers. Probably only needed if
* doing DMA, but what the Hell.
*/
- outb(sc->asic_addr + ED_3COM_PSTR, sc->rec_page_start);
- outb(sc->asic_addr + ED_3COM_PSPR, sc->rec_page_stop);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_PSTR, sc->rec_page_start);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_PSPR, sc->rec_page_stop);
/* Set IRQ. 3c503 only allows a choice of irq 3-5 or 9. */
switch (ia->ia_irq) {
case 9:
- outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ2);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_IDCFR,
+ ED_3COM_IDCFR_IRQ2);
break;
case 3:
- outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ3);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_IDCFR,
+ ED_3COM_IDCFR_IRQ3);
break;
case 4:
- outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ4);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_IDCFR,
+ ED_3COM_IDCFR_IRQ4);
break;
case 5:
- outb(sc->asic_addr + ED_3COM_IDCFR, ED_3COM_IDCFR_IRQ5);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_IDCFR,
+ ED_3COM_IDCFR_IRQ5);
break;
default:
printf("%s: invalid irq configuration (%d) must be 3-5 or 9 for 3c503\n",
sc->sc_dev.dv_xname, ia->ia_irq);
- return (0);
+ goto out;
}
/*
* Initialize GA configuration register. Set bank and enable shared
* mem.
*/
- outb(sc->asic_addr + ED_3COM_GACFR,
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_GACFR,
ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
/*
* shared memory is disabled. We set them to 0xffff0...allegedly the
* reset vector.
*/
- outb(sc->asic_addr + ED_3COM_VPTR2, 0xff);
- outb(sc->asic_addr + ED_3COM_VPTR1, 0xff);
- outb(sc->asic_addr + ED_3COM_VPTR0, 0x00);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_VPTR2, 0xff);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_VPTR1, 0xff);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_VPTR0, 0x00);
/* Zero memory and verify that it is clear. */
- zero_isa(sc->mem_start, memsize);
+ for (i = 0; i < memsize; ++i)
+ bus_mem_write_1(bc, memh, sc->mem_start + i, 0);
for (i = 0; i < memsize; ++i)
- if (ldb(sc->mem_start + i)) {
+ if (bus_mem_read_1(bc, memh, sc->mem_start + i)) {
printf("%s: failed to clear shared memory at %x - check configuration\n",
- sc->sc_dev.dv_xname, (int)(sc->mem_start + i));
- return (0);
+ sc->sc_dev.dv_xname,
+ (ia->ia_maddr + sc->mem_start + i));
+ goto out;
}
ia->ia_msize = memsize;
ia->ia_iosize = ED_3COM_IO_PORTS;
- return (1);
+ rv = 1;
+
+ out:
+ /*
+ * XXX Sould always unmap, but we can't yet.
+ * XXX Need to squish "indirect" first.
+ */
+ if (rv == 0) {
+ bus_io_unmap(bc, ioh, ED_3COM_IO_PORTS);
+ if (mapped_mem)
+ bus_mem_unmap(bc, memh, memsize);
+ } else {
+ /* XXX this is all "indirect" brokenness */
+ sc->sc_bc = bc;
+ sc->sc_ioh = ioh;
+ sc->sc_memh = memh;
+ }
+ return (rv);
}
/*
* Probe and vendor-specific initialization routine for NE1000/2000 boards.
*/
int
-isaed_probe_Novell(sc, cf, ia)
- struct isaed_softc *sc;
+ed_find_Novell(sc, cf, ia)
+ struct ed_softc *sc;
struct cfdata *cf;
struct isa_attach_args *ia;
{
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ bus_mem_handle_t memh;
u_int memsize, n;
u_char romdata[16], isa16bit = 0, tmp;
static u_char test_pattern[32] = "THIS is A memory TEST pattern";
u_char test_buffer[32];
+ int rv, asicbase, nicbase;
+
+ bc = ia->ia_bc;
+ rv = 0;
- sc->asic_addr = ia->ia_iobase + ED_NOVELL_ASIC_OFFSET;
- sc->nic_addr = ia->ia_iobase + ED_NOVELL_NIC_OFFSET;
+ if (bus_io_map(bc, ia->ia_iobase, ED_NOVELL_IO_PORTS, &ioh))
+ return (0);
+
+ sc->asic_base = asicbase = ED_NOVELL_ASIC_OFFSET;
+ sc->nic_base = nicbase = ED_NOVELL_NIC_OFFSET;
/* XXX - do Novell-specific probe here */
/* Reset the board. */
#ifdef GWETHER
- outb(sc->asic_addr + ED_NOVELL_RESET, 0);
+ bus_io_write_1(bc, ioh, asicbase + ED_NOVELL_RESET, 0);
delay(200);
#endif /* GWETHER */
- tmp = inb(sc->asic_addr + ED_NOVELL_RESET);
+ tmp = bus_io_read_1(bc, ioh, asicbase + ED_NOVELL_RESET);
/*
* I don't know if this is necessary; probably cruft leftover from
* complete documentation on what the 'right' thing to do is...so we do
* the invasive thing for now. Yuck.]
*/
- outb(sc->asic_addr + ED_NOVELL_RESET, tmp);
+ bus_io_write_1(bc, ioh, asicbase + ED_NOVELL_RESET, tmp);
delay(5000);
/*
* XXX - this makes the probe invasive! ...Done against my better
* judgement. -DLG
*/
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STP);
delay(5000);
/* Make sure that we really have an 8390 based board. */
- if (!isaed_probe_generic8390(sc))
- return (0);
+ if (!ed_probe_generic8390(bc, ioh, nicbase))
+ goto out;
sc->vendor = ED_VENDOR_NOVELL;
sc->mem_shared = 0;
* This prevents packets from being stored in the NIC memory when the
* readmem routine turns on the start bit in the CR.
*/
- NIC_PUT(sc, ED_P0_RCR, ED_RCR_MON);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RCR, ED_RCR_MON);
/* Temporarily initialize DCR for byte operations. */
- NIC_PUT(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
- NIC_PUT(sc, ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
- NIC_PUT(sc, ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTART, 8192 >> ED_PAGE_SHIFT);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTOP, 16384 >> ED_PAGE_SHIFT);
sc->isa16bit = 0;
+ /*
+ * XXX indirect brokenness, used by ed_pio{read,write}mem()
+ */
+ sc->sc_bc = bc;
+ sc->sc_ioh = ioh;
+
/*
* Write a test pattern in byte mode. If this fails, then there
* probably isn't any memory at 8k - which likely means that the board
* is an NE2000.
*/
- isaed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
- isaed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
+ ed_pio_writemem(sc, test_pattern, 8192, sizeof(test_pattern));
+ ed_pio_readmem(sc, 8192, test_buffer, sizeof(test_pattern));
if (bcmp(test_pattern, test_buffer, sizeof(test_pattern))) {
/* not an NE1000 - try NE2000 */
- NIC_PUT(sc, ED_P0_DCR,
+ NIC_PUT(bc, ioh, nicbase, ED_P0_DCR,
ED_DCR_WTS | ED_DCR_FT1 | ED_DCR_LS);
- NIC_PUT(sc, ED_P0_PSTART, 16384 >> ED_PAGE_SHIFT);
- NIC_PUT(sc, ED_P0_PSTOP, 32768 >> ED_PAGE_SHIFT);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTART, 16384 >> ED_PAGE_SHIFT);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTOP, 32768 >> ED_PAGE_SHIFT);
sc->isa16bit = 1;
* Write a test pattern in word mode. If this also fails, then
* we don't know what this board is.
*/
- isaed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
- isaed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
+ ed_pio_writemem(sc, test_pattern, 16384, sizeof(test_pattern));
+ ed_pio_readmem(sc, 16384, test_buffer, sizeof(test_pattern));
if (bcmp(test_pattern, test_buffer, sizeof(test_pattern)))
- return (0); /* not an NE2000 either */
+ goto out; /* not an NE2000 either */
sc->type = ED_TYPE_NE2000;
sc->type_str = "NE2000";
if (ia->ia_irq == IRQUNK) {
printf("%s: %s does not have soft configuration\n",
sc->sc_dev.dv_xname, sc->type_str);
- return (0);
+ goto out;
}
/* 8k of memory plus an additional 8k if 16-bit. */
/* NIC memory doesn't start at zero on an NE board. */
/* The start address is tied to the bus width. */
- sc->mem_start = (caddr_t)(8192 + sc->isa16bit * 8192);
+ sc->mem_start = (8192 + sc->isa16bit * 8192);
sc->tx_page_start = memsize >> ED_PAGE_SHIFT;
#ifdef GWETHER
if (mstart == 0) {
printf("%s: cannot find start of RAM\n",
sc->sc_dev.dv_xname);
- return (0);
+ goto out;
}
/* Search for the end of RAM. */
sc->mem_ring =
sc->mem_start + ((sc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
- isaed_pio_readmem(sc, 0, romdata, 16);
+ ed_pio_readmem(sc, 0, romdata, 16);
for (n = 0; n < ETHER_ADDR_LEN; n++)
sc->sc_arpcom.ac_enaddr[n] = romdata[n*(sc->isa16bit+1)];
#endif /* GWETHER */
/* Clear any pending interrupts that might have occurred above. */
- NIC_PUT(sc, ED_P0_ISR, 0xff);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_ISR, 0xff);
ia->ia_iosize = ED_NOVELL_IO_PORTS;
- return (1);
+ rv = 1;
+
+ out:
+ /*
+ * XXX Sould always unmap, but we can't yet.
+ * XXX Need to squish "indirect" first.
+ */
+ if (rv == 0)
+ bus_io_unmap(bc, ioh, ED_NOVELL_IO_PORTS);
+ else {
+ /* XXX this is all "indirect" brokenness */
+ sc->sc_bc = bc;
+ sc->sc_ioh = ioh;
+ sc->sc_memh = memh;
+ }
+ return (rv);
}
/*
* Install interface into kernel networking data structures.
*/
void
-isaedattach(parent, self, aux)
+edattach(parent, self, aux)
struct device *parent, *self;
void *aux;
{
- struct isaed_softc *sc = (void *)self;
+ bus_chipset_tag_t bc;
+ bus_io_handle_t ioh;
+ struct ed_softc *sc = (void *)self;
struct isa_attach_args *ia = aux;
struct cfdata *cf = sc->sc_dev.dv_cfdata;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int asicbase;
+
+ /*
+ * XXX Should re-map io and mem, but can't
+ * XXX until we squish "indirect" brokenness.
+ */
+ bc = sc->sc_bc; /* XXX */
+ ioh = sc->sc_ioh; /* XXX */
+
+ asicbase = sc->asic_base;
/* Set interface to stopped condition (reset). */
- isaedstop(sc);
+ edstop(sc);
/* Initialize ifnet structure. */
ifp->if_unit = sc->sc_dev.dv_unit;
- ifp->if_name = isaedcd.cd_name;
- ifp->if_start = isaedstart;
- ifp->if_ioctl = isaedioctl;
- ifp->if_watchdog = isaedwatchdog;
+ ifp->if_name = isaed_cd.cd_name;
+ ifp->if_start = edstart;
+ ifp->if_ioctl = edioctl;
+ ifp->if_watchdog = edwatchdog;
ifp->if_flags =
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
case ED_VENDOR_WD_SMC:
if ((sc->type & ED_WD_SOFTCONFIG) == 0)
break;
- if ((inb(sc->asic_addr + ED_WD_IRR) & ED_WD_IRR_OUT2) == 0)
+ if ((bus_io_read_1(bc, ioh, asicbase + ED_WD_IRR) &
+ ED_WD_IRR_OUT2) == 0)
ifp->if_flags |= IFF_LINK0;
break;
}
/* Attach the interface. */
- if_attach(ifp);
+ if ((sc->spec_flags & ED_REATTACH) == 0) {
+ if_attach(ifp);
+ ether_ifattach(ifp);
+ }
ether_ifattach(ifp);
/* Print additional info when attached. */
- printf(": address %s, ", ether_sprintf(sc->sc_arpcom.ac_enaddr));
+ printf("\n%s: address %s, ", sc->sc_dev.dv_xname,
+ ether_sprintf(sc->sc_arpcom.ac_enaddr));
if (sc->type_str)
printf("type %s ", sc->type_str);
printf("\n");
#if NBPFILTER > 0
- bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header));
+ if ((sc->spec_flags & ED_REATTACH) == 0)
+ bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB,
+ sizeof(struct ether_header));
#endif
- sc->sc_ih = isa_intr_establish(ia->ia_irq, IST_EDGE, IPL_NET,
- isaedintr, sc, sc->sc_dev.dv_xname);
+ sc->sc_ih = isa_intr_establish(ia->ia_ic, ia->ia_irq, IST_EDGE,
+ IPL_NET, edintr, sc, sc->sc_dev.dv_xname);
+ sc->sc_sh = shutdownhook_establish((void (*)(void *))edstop, sc);
}
/*
* Reset interface.
*/
void
-isaedreset(sc)
- struct isaed_softc *sc;
+edreset(sc)
+ struct ed_softc *sc;
{
int s;
- s = splimp();
- isaedstop(sc);
- isaedinit(sc);
+ s = splnet();
+ edstop(sc);
+ edinit(sc);
splx(s);
}
* Take interface offline.
*/
void
-isaedstop(sc)
- struct isaed_softc *sc;
+edstop(sc)
+ struct ed_softc *sc;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
+ int nicbase = sc->nic_base;
int n = 5000;
/* Stop everything on the interface, and select page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
/*
* Wait for interface to enter stopped state, but limit # of checks to
* 'n' (about 5ms). It shouldn't even take 5us on modern DS8390's, but
* just in case it's an old one.
*/
- while (((NIC_GET(sc, ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
+ while (((NIC_GET(bc, ioh, nicbase,
+ ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
}
/*
* an interrupt after a transmit has been started on it.
*/
void
-isaedwatchdog(unit)
+edwatchdog(unit)
int unit;
{
- struct isaed_softc *sc = isaedcd.cd_devs[unit];
+ struct ed_softc *sc = isaed_cd.cd_devs[unit];
log(LOG_ERR, "%s: device timeout\n", sc->sc_dev.dv_xname);
++sc->sc_arpcom.ac_if.if_oerrors;
- isaedreset(sc);
+ edreset(sc);
}
/*
* Initialize device.
*/
void
-isaedinit(sc)
- struct isaed_softc *sc;
+edinit(sc)
+ struct ed_softc *sc;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int nicbase = sc->nic_base, asicbase = sc->asic_base;
int i;
u_char command;
u_long mcaf[2];
sc->txb_next_tx = 0;
/* Set interface for page 0, remote DMA complete, stopped. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
if (sc->isa16bit) {
/*
* Set FIFO threshold to 8, No auto-init Remote DMA, byte
* order=80x86, word-wide DMA xfers,
*/
- NIC_PUT(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_DCR,
+ ED_DCR_FT1 | ED_DCR_WTS | ED_DCR_LS);
} else {
/* Same as above, but byte-wide DMA xfers. */
- NIC_PUT(sc, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_DCR, ED_DCR_FT1 | ED_DCR_LS);
}
/* Clear remote byte count registers. */
- NIC_PUT(sc, ED_P0_RBCR0, 0);
- NIC_PUT(sc, ED_P0_RBCR1, 0);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR0, 0);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR1, 0);
/* Tell RCR to do nothing for now. */
- NIC_PUT(sc, ED_P0_RCR, ED_RCR_MON);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RCR, ED_RCR_MON);
/* Place NIC in internal loopback mode. */
- NIC_PUT(sc, ED_P0_TCR, ED_TCR_LB0);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_TCR, ED_TCR_LB0);
/* Set lower bits of byte addressable framing to 0. */
if (sc->is790)
- NIC_PUT(sc, 0x09, 0);
+ NIC_PUT(bc, ioh, nicbase, 0x09, 0);
/* Initialize receive buffer ring. */
- NIC_PUT(sc, ED_P0_BNRY, sc->rec_page_start);
- NIC_PUT(sc, ED_P0_PSTART, sc->rec_page_start);
- NIC_PUT(sc, ED_P0_PSTOP, sc->rec_page_stop);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_BNRY, sc->rec_page_start);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTART, sc->rec_page_start);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_PSTOP, sc->rec_page_stop);
/*
* Clear all interrupts. A '1' in each bit position clears the
* corresponding flag.
*/
- NIC_PUT(sc, ED_P0_ISR, 0xff);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_ISR, 0xff);
/*
* Enable the following interrupts: receive/transmit complete,
*
* Counter overflow and Remote DMA complete are *not* enabled.
*/
- NIC_PUT(sc, ED_P0_IMR,
+ NIC_PUT(bc, ioh, nicbase, ED_P0_IMR,
ED_IMR_PRXE | ED_IMR_PTXE | ED_IMR_RXEE | ED_IMR_TXEE |
ED_IMR_OVWE);
/* Program command register for page 1. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STP);
/* Copy out our station address. */
for (i = 0; i < ETHER_ADDR_LEN; ++i)
- NIC_PUT(sc, ED_P1_PAR0 + i, sc->sc_arpcom.ac_enaddr[i]);
+ NIC_PUT(bc, ioh, nicbase, ED_P1_PAR0 + i,
+ sc->sc_arpcom.ac_enaddr[i]);
/* Set multicast filter on chip. */
- isaed_getmcaf(&sc->sc_arpcom, mcaf);
+ ed_getmcaf(&sc->sc_arpcom, mcaf);
for (i = 0; i < 8; i++)
- NIC_PUT(sc, ED_P1_MAR0 + i, ((u_char *)mcaf)[i]);
+ NIC_PUT(bc, ioh, nicbase, ED_P1_MAR0 + i, ((u_char *)mcaf)[i]);
/*
* Set current page pointer to one page after the boundary pointer, as
* recommended in the National manual.
*/
sc->next_packet = sc->rec_page_start + 1;
- NIC_PUT(sc, ED_P1_CURR, sc->next_packet);
+ NIC_PUT(bc, ioh, nicbase, ED_P1_CURR, sc->next_packet);
/* Program command register for page 0. */
- NIC_PUT(sc, ED_P1_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
+ NIC_PUT(bc, ioh, nicbase, ED_P1_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STP);
i = ED_RCR_AB | ED_RCR_AM;
if (ifp->if_flags & IFF_PROMISC) {
*/
i |= ED_RCR_PRO | ED_RCR_AR | ED_RCR_SEP;
}
- NIC_PUT(sc, ED_P0_RCR, i);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RCR, i);
/* Take interface out of loopback. */
- NIC_PUT(sc, ED_P0_TCR, 0);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_TCR, 0);
/*
* If this is a 3Com board, the tranceiver must be software enabled
u_char x;
case ED_VENDOR_3COM:
if (ifp->if_flags & IFF_LINK0)
- outb(sc->asic_addr + ED_3COM_CR, 0);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR, 0);
else
- outb(sc->asic_addr + ED_3COM_CR, ED_3COM_CR_XSEL);
+ bus_io_write_1(bc, ioh, asicbase + ED_3COM_CR,
+ ED_3COM_CR_XSEL);
break;
case ED_VENDOR_WD_SMC:
if ((sc->type & ED_WD_SOFTCONFIG) == 0)
break;
- x = inb(sc->asic_addr + ED_WD_IRR);
+ x = bus_io_read_1(bc, ioh, asicbase + ED_WD_IRR);
if (ifp->if_flags & IFF_LINK0)
x &= ~ED_WD_IRR_OUT2;
else
x |= ED_WD_IRR_OUT2;
- outb(sc->asic_addr + ED_WD_IRR, x);
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_IRR, x);
break;
}
/* Fire up the interface. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
/* Set 'running' flag, and clear output active flag. */
ifp->if_flags |= IFF_RUNNING;
ifp->if_flags &= ~IFF_OACTIVE;
/* ...and attempt to start output. */
- isaedstart(ifp);
+ edstart(ifp);
}
/*
* This routine actually starts the transmission on the interface.
*/
static inline void
-isaed_xmit(sc)
- struct isaed_softc *sc;
+ed_xmit(sc)
+ struct ed_softc *sc;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int nicbase = sc->nic_base;
u_short len;
len = sc->txb_len[sc->txb_next_tx];
/* Set NIC for page 0 register access. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
/* Set TX buffer start page. */
- NIC_PUT(sc, ED_P0_TPSR, sc->tx_page_start +
+ NIC_PUT(bc, ioh, nicbase, ED_P0_TPSR, sc->tx_page_start +
sc->txb_next_tx * ED_TXBUF_SIZE);
/* Set TX length. */
- NIC_PUT(sc, ED_P0_TBCR0, len);
- NIC_PUT(sc, ED_P0_TBCR1, len >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_TBCR0, len);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_TBCR1, len >> 8);
/* Set page 0, remote DMA complete, transmit packet, and *start*. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_TXP | ED_CR_STA);
/* Point to next transmit buffer slot and wrap if necessary. */
sc->txb_next_tx++;
/*
* Start output on interface.
* We make two assumptions here:
- * 1) that the current priority is set to splimp _before_ this code
+ * 1) that the current priority is set to splnet _before_ this code
* is called *and* is returned to the appropriate priority after
* return
* 2) that the IFF_OACTIVE flag is checked before this code is called
* (i.e. that the output part of the interface is idle)
*/
void
-isaedstart(ifp)
+edstart(ifp)
struct ifnet *ifp;
{
- struct isaed_softc *sc = isaedcd.cd_devs[ifp->if_unit];
+ struct ed_softc *sc = isaed_cd.cd_devs[ifp->if_unit];
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
struct mbuf *m0, *m;
- caddr_t buffer;
- int len;
+ int buffer;
+ int asicbase = sc->asic_base;
+ int len, i;
if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING)
return;
#endif
/* txb_new points to next open buffer slot. */
- buffer = sc->mem_start + ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
+ buffer = sc->mem_start +
+ ((sc->txb_new * ED_TXBUF_SIZE) << ED_PAGE_SHIFT);
if (sc->mem_shared) {
/* Special case setup for 16 bit boards... */
*/
case ED_VENDOR_3COM:
if (sc->isa16bit)
- outb(sc->asic_addr + ED_3COM_GACFR,
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_3COM_GACFR,
ED_3COM_GACFR_RSEL);
break;
/*
*/
case ED_VENDOR_WD_SMC:
if (sc->isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
sc->wd_laar_proto | ED_WD_LAAR_M16EN);
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
sc->wd_msr_proto | ED_WD_MSR_MENB);
- (void) inb(0x84);
- (void) inb(0x84);
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
break;
}
- for (len = 0; m; m = m->m_next) {
- copy_to_isa(mtod(m, caddr_t), buffer, m->m_len);
+ for (m = m0; m != 0; m = m->m_next) {
+ ed_shared_writemem(sc, mtod(m, caddr_t), buffer,
+ m->m_len);
buffer += m->m_len;
- len += m->m_len;
}
+ len = m0->m_pkthdr.len;
/* Restore previous shared memory access. */
switch (sc->vendor) {
case ED_VENDOR_3COM:
if (sc->isa16bit)
- outb(sc->asic_addr + ED_3COM_GACFR,
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_3COM_GACFR,
ED_3COM_GACFR_RSEL | ED_3COM_GACFR_MBS0);
break;
case ED_VENDOR_WD_SMC:
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_MSR,
sc->wd_msr_proto);
if (sc->isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh, asicbase + ED_WD_LAAR,
sc->wd_laar_proto);
- (void) inb(0x84);
- (void) inb(0x84);
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84); /* XXX */
break;
}
} else
- len = isaed_pio_write_mbufs(sc, m0, (long)buffer);
+ len = ed_pio_write_mbufs(sc, m0, (long)buffer);
m_freem(m0);
sc->txb_len[sc->txb_new] = max(len, ETHER_MIN_LEN);
-#ifdef DDB
- if (sc->next_packet < sc->rec_page_start || sc->next_packet >= sc->rec_page_stop)
- Debugger();
-#endif
/* Start the first packet transmitting. */
if (sc->txb_inuse == 0)
- isaed_xmit(sc);
+ ed_xmit(sc);
/* Point to next buffer slot and wrap if necessary. */
if (++sc->txb_new == sc->txb_cnt)
* Ethernet interface receiver interrupt.
*/
static inline void
-isaed_rint(sc)
- struct isaed_softc *sc;
+ed_rint(sc)
+ struct ed_softc *sc;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
+ int nicbase = sc->nic_base;
u_char boundary, current;
u_short len;
u_char nlen;
struct ed_ring packet_hdr;
- caddr_t packet_ptr;
+ int packet_ptr;
loop:
-#ifdef DDB
- if (sc->next_packet < sc->rec_page_start || sc->next_packet >= sc->rec_page_stop)
- Debugger();
-#endif
/* Set NIC to page 1 registers to get 'current' pointer. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_1 | ED_CR_STA);
/*
* 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
* until the logical beginning equals the logical end (or in other
* words, until the ring-buffer is empty).
*/
- current = NIC_GET(sc, ED_P1_CURR);
+ current = NIC_GET(bc, ioh, nicbase, ED_P1_CURR);
if (sc->next_packet == current)
return;
/* Set NIC to page 0 registers to update boundary register. */
- NIC_PUT(sc, ED_P1_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P1_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
do {
/* Get pointer to this buffer's header structure. */
* the NIC.
*/
if (sc->mem_shared)
- copy_from_isa(packet_ptr, &packet_hdr,
+ ed_shared_readmem(sc, packet_ptr, (caddr_t)&packet_hdr,
sizeof(packet_hdr));
else
- isaed_pio_readmem(sc, (long)packet_ptr,
- (caddr_t) &packet_hdr, sizeof(packet_hdr));
- len = itohs(packet_hdr.count);
-#ifdef ISAED_DEBUG
- if (isaeddebug) {
- int i;
- u_char buf[64];
-
- if (sc->mem_shared)
- copy_from_isa(((u_char *)packet_ptr + sizeof(struct ed_ring)), buf, 64);
- else
- isaed_pio_readmem(sc, (long)packet_ptr + sizeof(struct ed_ring),
- (caddr_t) buf, 64);
- printf("pkt hdr len %d hdr %02x %02x %02x %02x pkt len %d\n",
- sizeof(packet_hdr), ((u_char *)&packet_hdr)[0],
- ((u_char *)&packet_hdr)[1], ((u_char *)&packet_hdr)[2],
- ((u_char *)&packet_hdr)[3], len);
- for (i = 0; i < 64; i++)
- printf("%02x%c", buf[i], i % 16 == 15 ? '\n' : ' ');
- }
-#endif
+ ed_pio_readmem(sc, (long)packet_ptr,
+ (caddr_t)&packet_hdr, sizeof(packet_hdr));
+ len = bus_to_host_2(bc, packet_hdr.count);
/*
* Try do deal with old, buggy chips that sometimes duplicate
--nlen;
len = (len & ED_PAGE_MASK) | (nlen << ED_PAGE_SHIFT);
#ifdef DIAGNOSTIC
- if (len != itohs(packet_hdr.count)) {
- printf("%s: length does not match next packet pointer\n",
- sc->sc_dev.dv_xname);
- printf("%s: len %04x nlen %04x start %02x first %02x curr %02x next %02x stop %02x\n",
- sc->sc_dev.dv_xname, itohs(packet_hdr.count), len,
+ if (len != bus_to_host_2(bc, packet_hdr.count)) {
+ printf("%s: length does not match next packet "
+ "pointer\n", sc->sc_dev.dv_xname);
+ printf("%s: len %04x nlen %04x start %02x first %02x "
+ "curr %02x next %02x stop %02x\n",
+ sc->sc_dev.dv_xname,
+ bus_to_host_2(bc, packet_hdr.count), len,
sc->rec_page_start, sc->next_packet, current,
packet_hdr.next_packet, sc->rec_page_stop);
}
* mbuf cluster or less; the upper layer protocols can then
* figure out the length from their own length field(s).
*/
- if (len <= (MCLBYTES > ETHER_MAX_LEN ?
- MCLBYTES : ETHER_MAX_LEN) &&
+ if (len <= (MCLBYTES > ETHER_MAX_LEN ? MCLBYTES :
+ ETHER_MAX_LEN) &&
packet_hdr.next_packet >= sc->rec_page_start &&
packet_hdr.next_packet < sc->rec_page_stop) {
/* Go get packet. */
- isaedread(sc, packet_ptr + sizeof(struct ed_ring),
+ edread(sc, packet_ptr + sizeof(struct ed_ring),
len - sizeof(struct ed_ring));
} else {
/* Really BAD. The ring pointers are corrupted. */
log(LOG_ERR,
- "%s: NIC memory corrupt - invalid packet length %d or pkt link %d [%d-%d)\n",
- sc->sc_dev.dv_xname, len, packet_hdr.next_packet,
- sc->rec_page_start, sc->rec_page_stop);
+ "%s: NIC memory corrupt - invalid packet length %d\n",
+ sc->sc_dev.dv_xname, len);
++sc->sc_arpcom.ac_if.if_ierrors;
- isaedreset(sc);
+ edreset(sc);
return;
}
-
+ /* Update next packet pointer. */
sc->next_packet = packet_hdr.next_packet;
-#ifdef DDB
- if (sc->next_packet < sc->rec_page_start || sc->next_packet >= sc->rec_page_stop)
- Debugger();
-#endif
/*
* Update NIC boundary pointer - being careful to keep it one
boundary = sc->next_packet - 1;
if (boundary < sc->rec_page_start)
boundary = sc->rec_page_stop - 1;
- NIC_PUT(sc, ED_P0_BNRY, boundary);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_BNRY, boundary);
} while (sc->next_packet != current);
goto loop;
/* Ethernet interface interrupt processor. */
int
-isaedintr(arg)
+edintr(arg)
void *arg;
{
- struct isaed_softc *sc = arg;
+ struct ed_softc *sc = arg;
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int nicbase = sc->nic_base, asicbase = sc->asic_base;
u_char isr;
/* Set NIC to page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
- isr = NIC_GET(sc, ED_P0_ISR);
+ isr = NIC_GET(bc, ioh, nicbase, ED_P0_ISR);
if (!isr)
return (0);
+
/* Loop until there are no more new interrupts. */
for (;;) {
-#ifdef DDB
- if (sc->next_packet < sc->rec_page_start || sc->next_packet >= sc->rec_page_stop)
- Debugger();
-#endif
/*
* Reset all the bits that we are 'acknowledging' by writing a
* '1' to each bit position that was set.
* (Writing a '1' *clears* the bit.)
*/
- NIC_PUT(sc, ED_P0_ISR, isr);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_ISR, isr);
/*
* Handle transmitter interrupts. Handle these first because
* the receiver will reset the board under some conditions.
*/
if (isr & (ED_ISR_PTX | ED_ISR_TXE)) {
- u_char collisions = NIC_GET(sc, ED_P0_NCR) & 0x0f;
+ u_char collisions = NIC_GET(bc, ioh, nicbase,
+ ED_P0_NCR) & 0x0f;
/*
* Check for transmit error. If a TX completed with an
* course, with UDP we're screwed, but this is expected
* when a network is heavily loaded.
*/
- (void) NIC_GET(sc, ED_P0_TSR);
+ (void) NIC_GET(bc, ioh, nicbase, ED_P0_TSR);
if (isr & ED_ISR_TXE) {
/*
* Excessive collisions (16).
*/
- if ((NIC_GET(sc, ED_P0_TSR) & ED_TSR_ABT)
- && (collisions == 0)) {
+ if ((NIC_GET(bc, ioh, nicbase, ED_P0_TSR) &
+ ED_TSR_ABT) && (collisions == 0)) {
/*
* When collisions total 16, the P0_NCR
* will indicate 0, and the TSR_ABT is
* otherwise defer until after handling receiver.
*/
if (sc->txb_inuse > 0)
- isaed_xmit(sc);
+ ed_xmit(sc);
}
/* Handle receiver interrupts. */
sc->sc_dev.dv_xname);
#endif
/* Stop/reset/re-init NIC. */
- isaedreset(sc);
+ edreset(sc);
} else {
/*
* Receiver Error. One or more of: CRC error,
*/
if (isr & ED_ISR_RXE) {
++ifp->if_ierrors;
-#ifdef ISAED_DEBUG
- if (isaeddebug)
- printf("%s: receive error %x\n",
- sc->sc_dev.dv_xname,
- NIC_GET(sc, ED_P0_RSR));
+#ifdef ED_DEBUG
+ printf("%s: receive error %x\n",
+ sc->sc_dev.dv_xname,
+ NIC_GET(nicbase, ED_P0_RSR));
#endif
}
*/
if (sc->vendor == ED_VENDOR_WD_SMC) {
if (sc->isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR,
- sc->wd_laar_proto | ED_WD_LAAR_M16EN);
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_WD_LAAR,
+ sc->wd_laar_proto |
+ ED_WD_LAAR_M16EN);
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_WD_MSR,
sc->wd_msr_proto | ED_WD_MSR_MENB);
- (void) inb(0x84);
- (void) inb(0x84);
+ /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84);
+ (void) bus_io_read_1(bc, ioh, 0x84);
}
- isaed_rint(sc);
+ ed_rint(sc);
/* Disable 16-bit access. */
if (sc->vendor == ED_VENDOR_WD_SMC) {
- outb(sc->asic_addr + ED_WD_MSR,
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_WD_MSR,
sc->wd_msr_proto);
if (sc->isa16bit)
- outb(sc->asic_addr + ED_WD_LAAR,
+ bus_io_write_1(bc, ioh,
+ asicbase + ED_WD_LAAR,
sc->wd_laar_proto);
- (void) inb(0x84);
- (void) inb(0x84);
+ /* XXX */
+ (void) bus_io_read_1(bc, ioh, 0x84);
+ (void) bus_io_read_1(bc, ioh, 0x84);
}
}
}
* to start output on the interface. This is done after
* handling the receiver to give the receiver priority.
*/
- isaedstart(ifp);
+ edstart(ifp);
/*
* Return NIC CR to standard state: page 0, remote DMA
* set in the transmit routine, is *okay* - it is 'edge'
* triggered from low to high).
*/
- NIC_PUT(sc, ED_P0_CR, sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ sc->cr_proto | ED_CR_PAGE_0 | ED_CR_STA);
/*
* If the Network Talley Counters overflow, read them to reset
* otherwise - resulting in an infinite loop.
*/
if (isr & ED_ISR_CNT) {
- (void) NIC_GET(sc, ED_P0_CNTR0);
- (void) NIC_GET(sc, ED_P0_CNTR1);
- (void) NIC_GET(sc, ED_P0_CNTR2);
+ (void) NIC_GET(bc, ioh, nicbase, ED_P0_CNTR0);
+ (void) NIC_GET(bc, ioh, nicbase, ED_P0_CNTR1);
+ (void) NIC_GET(bc, ioh, nicbase, ED_P0_CNTR2);
}
- isr = NIC_GET(sc, ED_P0_ISR);
+ isr = NIC_GET(bc, ioh, nicbase, ED_P0_ISR);
if (!isr)
return (1);
}
* Process an ioctl request. This code needs some work - it looks pretty ugly.
*/
int
-isaedioctl(ifp, cmd, data)
+edioctl(ifp, cmd, data)
register struct ifnet *ifp;
u_long cmd;
caddr_t data;
{
- struct isaed_softc *sc = isaedcd.cd_devs[ifp->if_unit];
+ struct ed_softc *sc = isaed_cd.cd_devs[ifp->if_unit];
register struct ifaddr *ifa = (struct ifaddr *)data;
struct ifreq *ifr = (struct ifreq *)data;
int s, error = 0;
- s = splimp();
+ s = splnet();
+ if ((sc->spec_flags & ED_NOTPRESENT) != 0) {
+ if_down(ifp);
+ printf("%s: device offline\n", sc->sc_dev.dv_xname);
+ splx(s);
+ return ENXIO; /* may be ignored, oh well. */
+ }
switch (cmd) {
switch (ifa->ifa_addr->sa_family) {
#ifdef INET
case AF_INET:
- isaedinit(sc);
+ edinit(sc);
arp_ifinit(&sc->sc_arpcom, ifa);
break;
#endif
ina->x_host =
*(union ns_host *)(sc->sc_arpcom.ac_enaddr);
else
- copy(ina->x_host.c_host,
+ bcopy(ina->x_host.c_host,
sc->sc_arpcom.ac_enaddr,
sizeof(sc->sc_arpcom.ac_enaddr));
/* Set new address. */
- isaedinit(sc);
+ edinit(sc);
break;
}
#endif
default:
- isaedinit(sc);
+ edinit(sc);
break;
}
break;
* If interface is marked down and it is running, then
* stop it.
*/
- isaedstop(sc);
+ edstop(sc);
ifp->if_flags &= ~IFF_RUNNING;
} else if ((ifp->if_flags & IFF_UP) != 0 &&
(ifp->if_flags & IFF_RUNNING) == 0) {
* If interface is marked up and it is stopped, then
* start it.
*/
- isaedinit(sc);
+ edinit(sc);
} else {
/*
* Reset the interface to pick up changes in any other
* flags that affect hardware registers.
*/
- isaedstop(sc);
- isaedinit(sc);
+ edstop(sc);
+ edinit(sc);
}
break;
* Multicast list has changed; set the hardware filter
* accordingly.
*/
- isaedstop(sc); /* XXX for ds_setmcaf? */
- isaedinit(sc);
+ edstop(sc); /* XXX for ds_setmcaf? */
+ edinit(sc);
error = 0;
}
break;
* ether_input(). If there is a BPF listener, give a copy to BPF, too.
*/
void
-isaedread(sc, buf, len)
- struct isaed_softc *sc;
- caddr_t buf;
- int len;
+edread(sc, buf, len)
+ struct ed_softc *sc;
+ int buf, len;
{
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
- struct mbuf *m;
+ struct mbuf *m;
struct ether_header *eh;
/* Pull packet off interface. */
- m = isaedget(sc, buf, len);
+ m = edget(sc, buf, len);
if (m == 0) {
ifp->if_ierrors++;
return;
* This routine is currently Novell-specific.
*/
void
-isaed_pio_readmem(sc, src, dst, amount)
- struct isaed_softc *sc;
+ed_pio_readmem(sc, src, dst, amount)
+ struct ed_softc *sc;
u_short src;
caddr_t dst;
u_short amount;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
+ int nicbase = sc->nic_base;
+
/* Select page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
/* Round up to a word. */
if (amount & 1)
++amount;
/* Set up DMA byte count. */
- NIC_PUT(sc, ED_P0_RBCR0, amount);
- NIC_PUT(sc, ED_P0_RBCR1, amount >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR0, amount);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR1, amount >> 8);
/* Set up source address in NIC mem. */
- NIC_PUT(sc, ED_P0_RSAR0, src);
- NIC_PUT(sc, ED_P0_RSAR1, src >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR0, src);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR1, src >> 8);
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD0 | ED_CR_PAGE_0 | ED_CR_STA);
if (sc->isa16bit)
- insw(sc->asic_addr + ED_NOVELL_DATA, dst, amount / 2);
+ bus_io_read_multi_2(bc, ioh, sc->asic_base + ED_NOVELL_DATA,
+ (u_int16_t *)dst, amount / 2);
else
- insb(sc->asic_addr + ED_NOVELL_DATA, dst, amount);
+ bus_io_read_multi_1(bc, ioh, sc->asic_base + ED_NOVELL_DATA,
+ dst, amount);
}
/*
* in the probe routine to test the memory. 'len' must be even.
*/
void
-isaed_pio_writemem(sc, src, dst, len)
- struct isaed_softc *sc;
+ed_pio_writemem(sc, src, dst, len)
+ struct ed_softc *sc;
caddr_t src;
u_short dst;
u_short len;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
+ int nicbase = sc->nic_base;
int maxwait = 100; /* about 120us */
/* Select page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
/* Reset remote DMA complete flag. */
- NIC_PUT(sc, ED_P0_ISR, ED_ISR_RDC);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_ISR, ED_ISR_RDC);
/* Set up DMA byte count. */
- NIC_PUT(sc, ED_P0_RBCR0, len);
- NIC_PUT(sc, ED_P0_RBCR1, len >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR0, len);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR1, len >> 8);
/* Set up destination address in NIC mem. */
- NIC_PUT(sc, ED_P0_RSAR0, dst);
- NIC_PUT(sc, ED_P0_RSAR1, dst >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR0, dst);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR1, dst >> 8);
/* Set remote DMA write. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
if (sc->isa16bit)
- outsw(sc->asic_addr + ED_NOVELL_DATA, src, len / 2);
+ bus_io_write_multi_2(bc, ioh, sc->asic_base + ED_NOVELL_DATA,
+ (u_int16_t *)src, len / 2);
else
- outsb(sc->asic_addr + ED_NOVELL_DATA, src, len);
+ bus_io_write_multi_1(bc, ioh, sc->asic_base + ED_NOVELL_DATA,
+ src, len);
/*
* Wait for remote DMA complete. This is necessary because on the
* waiting causes really bad things to happen - like the NIC
* irrecoverably jamming the ISA bus.
*/
- while (((NIC_GET(sc, ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait);
+ while (((NIC_GET(bc, ioh, nicbase, ED_P0_ISR) & ED_ISR_RDC) !=
+ ED_ISR_RDC) && --maxwait);
}
/*
* I/O.
*/
u_short
-isaed_pio_write_mbufs(sc, m, dst)
- struct isaed_softc *sc;
+ed_pio_write_mbufs(sc, m, dst)
+ struct ed_softc *sc;
struct mbuf *m;
u_short dst;
{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_io_handle_t ioh = sc->sc_ioh;
+ int nicbase = sc->nic_base, asicbase = sc->asic_base;
u_short len;
struct mbuf *mp;
int maxwait = 100; /* about 120us */
len = m->m_pkthdr.len;
/* Select page 0 registers. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD2 | ED_CR_PAGE_0 | ED_CR_STA);
/* Reset remote DMA complete flag. */
- NIC_PUT(sc, ED_P0_ISR, ED_ISR_RDC);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_ISR, ED_ISR_RDC);
/* Set up DMA byte count. */
- NIC_PUT(sc, ED_P0_RBCR0, len);
- NIC_PUT(sc, ED_P0_RBCR1, len >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR0, len);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RBCR1, len >> 8);
/* Set up destination address in NIC mem. */
- NIC_PUT(sc, ED_P0_RSAR0, dst);
- NIC_PUT(sc, ED_P0_RSAR1, dst >> 8);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR0, dst);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_RSAR1, dst >> 8);
/* Set remote DMA write. */
- NIC_PUT(sc, ED_P0_CR, ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
+ NIC_PUT(bc, ioh, nicbase, ED_P0_CR,
+ ED_CR_RD1 | ED_CR_PAGE_0 | ED_CR_STA);
/*
* Transfer the mbuf chain to the NIC memory.
/* NE1000s are easy. */
for (; m != 0; m = m->m_next) {
if (m->m_len) {
- outsb(sc->asic_addr + ED_NOVELL_DATA,
+ bus_io_write_multi_1(bc, ioh,
+ asicbase + ED_NOVELL_DATA,
mtod(m, u_char *), m->m_len);
}
}
} else {
/* NE2000s are a bit trickier. */
- u_char *data, savebyte[2];
+ u_int8_t *data, savebyte[2];
int len, wantbyte;
wantbyte = 0;
len = m->m_len;
if (len == 0)
continue;
- data = mtod(m, u_char *);
+ data = mtod(m, u_int8_t *);
/* Finish the last word. */
if (wantbyte) {
savebyte[1] = *data;
- outw(sc->asic_addr + ED_NOVELL_DATA,
- *(u_short *)savebyte);
+ bus_io_write_2(bc, ioh,
+ asicbase + ED_NOVELL_DATA,
+ *(u_int16_t *)savebyte);
data++;
len--;
wantbyte = 0;
}
/* Output contiguous words. */
- if (len > 1)
- outsw(sc->asic_addr + ED_NOVELL_DATA,
- data, len >> 1);
+ if (len > 1) {
+ bus_io_write_multi_2(bc, ioh,
+ asicbase + ED_NOVELL_DATA,
+ (u_int16_t *)data, len >> 1);
+ }
/* Save last byte, if necessary. */
if (len & 1) {
data += len & ~1;
if (wantbyte) {
savebyte[1] = 0;
- outw(sc->asic_addr + ED_NOVELL_DATA,
- *(u_short *)savebyte);
+ bus_io_write_2(bc, ioh, asicbase + ED_NOVELL_DATA,
+ *(u_int16_t *)savebyte);
}
}
* waiting causes really bad things to happen - like the NIC
* irrecoverably jamming the ISA bus.
*/
- while (((NIC_GET(sc, ED_P0_ISR) & ED_ISR_RDC) != ED_ISR_RDC) && --maxwait);
+ while (((NIC_GET(bc, ioh, nicbase, ED_P0_ISR) & ED_ISR_RDC) !=
+ ED_ISR_RDC) && --maxwait);
if (!maxwait) {
log(LOG_WARNING,
"%s: remote transmit DMA failed to complete\n",
sc->sc_dev.dv_xname);
- isaedreset(sc);
+ edreset(sc);
}
return (len);
* Given a source and destination address, copy 'amount' of a packet from the
* ring buffer into a linear destination buffer. Takes into account ring-wrap.
*/
-static inline caddr_t
-isaed_ring_copy(sc, src, dst, amount)
- struct isaed_softc *sc;
- caddr_t src, dst;
+static inline int
+ed_ring_copy(sc, src, dst, amount)
+ struct ed_softc *sc;
+ int src;
+ caddr_t dst;
u_short amount;
{
u_short tmp_amount;
/* Copy amount up to end of NIC memory. */
if (sc->mem_shared)
- copy_from_isa(src, dst, tmp_amount);
+ ed_shared_readmem(sc, src, dst, tmp_amount);
else
- isaed_pio_readmem(sc, (long)src, dst, tmp_amount);
+ ed_pio_readmem(sc, (long)src, dst, tmp_amount);
amount -= tmp_amount;
src = sc->mem_ring;
}
if (sc->mem_shared)
- copy_from_isa(src, dst, amount);
+ ed_shared_readmem(sc, src, dst, amount);
else
- isaed_pio_readmem(sc, (long)src, dst, amount);
+ ed_pio_readmem(sc, (long)src, dst, amount);
return (src + amount);
}
/*
* Copy data from receive buffer to end of mbuf chain allocate additional mbufs
* as needed. Return pointer to last mbuf in chain.
- * sc = isaed info (softc)
- * src = pointer in isaed ring buffer
+ * sc = ed info (softc)
+ * src = pointer in ed ring buffer
* dst = pointer to last mbuf in mbuf chain to copy to
* amount = amount of data to copy
*/
struct mbuf *
-isaedget(sc, src, total_len)
- struct isaed_softc *sc;
- caddr_t src;
+edget(sc, src, total_len)
+ struct ed_softc *sc;
+ int src;
u_short total_len;
{
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
len = MCLBYTES;
}
m->m_len = len = min(total_len, len);
- src = isaed_ring_copy(sc, src, mtod(m, caddr_t), len);
+ src = ed_ring_copy(sc, src, mtod(m, caddr_t), len);
total_len -= len;
*mp = m;
mp = &m->m_next;
* need to listen to.
*/
void
-isaed_getmcaf(ac, af)
+ed_getmcaf(ac, af)
struct arpcom *ac;
u_long *af;
{
}
ifp->if_flags &= ~IFF_ALLMULTI;
}
+
+void
+ed_shared_writemem(sc, buf, card, len)
+ struct ed_softc *sc;
+ caddr_t buf;
+ int card, len;
+{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_mem_handle_t memh = sc->sc_memh;
+ u_int8_t *ptr = (u_int8_t *)buf;
+ int i;
+
+ /* XXX should have bus_mem_copyout_{1,2,4,8}() */
+
+ for (i = 0; i < len; ++i)
+ bus_mem_write_1(bc, memh, card + i, ptr[i]);
+}
+
+void
+ed_shared_readmem(sc, card, buf, len)
+ struct ed_softc *sc;
+ caddr_t buf;
+ int card, len;
+{
+ bus_chipset_tag_t bc = sc->sc_bc;
+ bus_mem_handle_t memh = sc->sc_memh;
+ u_int8_t *ptr = (u_int8_t *)buf;
+ int i;
+
+ /* XXX should have bus_mem_copyin_{1,2,4,8}() */
+
+ for (i = 0; i < len; ++i)
+ ptr[i] = bus_mem_read_1(bc, memh, card + i);
+}
+++ /dev/null
-/* $NetBSD: if_isaedreg.h,v 1.12 1994/10/27 04:17:23 cgd Exp $ */
-
-/*
- * National Semiconductor DS8390 NIC register definitions.
- *
- * Copyright (C) 1993, David Greenman. This software may be used, modified,
- * copied, distributed, and sold, in both source and binary form provided that
- * the above copyright and these terms are retained. Under no circumstances is
- * the author responsible for the proper functioning of this software, nor does
- * the author assume any responsibility for damages incurred with its use.
- */
-
-/*
- * Vendor types
- */
-#define ED_VENDOR_WD_SMC 0x00 /* Western Digital/SMC */
-#define ED_VENDOR_3COM 0x01 /* 3Com */
-#define ED_VENDOR_NOVELL 0x02 /* Novell */
-
-/*
- * Compile-time config flags
- */
-/*
- * This sets the default for enabling/disablng the tranceiver.
- */
-#define ED_FLAGS_DISABLE_TRANCEIVER 0x0001
-
-/*
- * This forces the board to be used in 8/16-bit mode even if it autoconfigs
- * differently.
- */
-#define ED_FLAGS_FORCE_8BIT_MODE 0x0002
-#define ED_FLAGS_FORCE_16BIT_MODE 0x0004
-
-/*
- * This disables the use of double transmit buffers.
- */
-#define ED_FLAGS_NO_MULTI_BUFFERING 0x0008
-
-/*
- * This forces all operations with the NIC memory to use Programmed I/O (i.e.
- * not via shared memory).
- */
-#define ED_FLAGS_FORCE_PIO 0x0010
-
-/*
- * Definitions for Western digital/SMC WD80x3 series ASIC
- */
-/*
- * Memory Select Register (MSR)
- */
-#define ED_WD_MSR 0
-
-/* next three definitions for Toshiba */
-#define ED_WD_MSR_POW 0x02 /* 0 = power save, 1 = normal (R/W) */
-#define ED_WD_MSR_BSY 0x04 /* gate array busy (R) */
-#define ED_WD_MSR_LEN 0x20 /* 0 = 16-bit, 1 = 8-bit (R/W) */
-
-#define ED_WD_MSR_ADDR 0x3f /* Memory decode bits 18-13 */
-#define ED_WD_MSR_MENB 0x40 /* Memory enable */
-#define ED_WD_MSR_RST 0x80 /* Reset board */
-
-/*
- * Interface Configuration Register (ICR)
- */
-#define ED_WD_ICR 1
-
-#define ED_WD_ICR_16BIT 0x01 /* 16-bit interface */
-#define ED_WD_ICR_OAR 0x02 /* select register (0=BIO 1=EAR) */
-#define ED_WD_ICR_IR2 0x04 /* high order bit of encoded IRQ */
-#define ED_WD_ICR_MSZ 0x08 /* memory size (0=8k 1=32k) */
-#define ED_WD_ICR_RLA 0x10 /* recall LAN address */
-#define ED_WD_ICR_RX7 0x20 /* recall all but i/o and LAN address */
-#define ED_WD_ICR_RIO 0x40 /* recall i/o address */
-#define ED_WD_ICR_STO 0x80 /* store to non-volatile memory */
-#ifdef TOSH_ETHER
-#define ED_WD_ICR_MEM 0xe0 /* shared mem address A15-A13 (R/W) */
-#define ED_WD_ICR_MSZ1 0x0f /* memory size, 0x08 = 64K, 0x04 = 32K,
- 0x02 = 16K, 0x01 = 8K */
- /* 64K can only be used if mem address
- above 1MB */
- /* IAR holds address A23-A16 (R/W) */
-#endif
-
-/*
- * IO Address Register (IAR)
- */
-#define ED_WD_IAR 2
-
-/*
- * EEROM Address Register
- */
-#define ED_WD_EAR 3
-
-/*
- * Interrupt Request Register (IRR)
- */
-#define ED_WD_IRR 4
-
-#define ED_WD_IRR_0WS 0x01 /* use 0 wait-states on 8 bit bus */
-#define ED_WD_IRR_OUT1 0x02 /* WD83C584 pin 1 output */
-#define ED_WD_IRR_OUT2 0x04 /* WD83C584 pin 2 output */
-#define ED_WD_IRR_OUT3 0x08 /* WD83C584 pin 3 output */
-#define ED_WD_IRR_FLASH 0x10 /* Flash RAM is in the ROM socket */
-
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 2/9
- * 0 0 1 3
- * 0 1 0 5
- * 0 1 1 7
- * 1 0 0 10
- * 1 0 1 11
- * 1 1 0 15
- * 1 1 1 4
- */
-#define ED_WD_IRR_IR0 0x20 /* bit 0 of encoded IRQ */
-#define ED_WD_IRR_IR1 0x40 /* bit 1 of encoded IRQ */
-#define ED_WD_IRR_IEN 0x80 /* Interrupt enable */
-
-/*
- * LA Address Register (LAAR)
- */
-#define ED_WD_LAAR 5
-
-#define ED_WD_LAAR_ADDRHI 0x1f /* bits 23-19 of RAM address */
-#define ED_WD_LAAR_0WS16 0x20 /* enable 0 wait-states on 16 bit bus */
-#define ED_WD_LAAR_L16EN 0x40 /* enable 16-bit operation */
-#define ED_WD_LAAR_M16EN 0x80 /* enable 16-bit memory access */
-
-/* i/o base offset to station address/card-ID PROM */
-#define ED_WD_PROM 8
-
-/*
- * 83C790 specific registers
- */
-/*
- * Hardware Support Register (HWR) ('790)
- */
-#define ED_WD790_HWR 4
-
-#define ED_WD790_HWR_RST 0x10 /* hardware reset */
-#define ED_WD790_HWR_LPRM 0x40 /* LAN PROM select */
-#define ED_WD790_HWR_SWH 0x80 /* switch register set */
-
-/*
- * ICR790 Interrupt Control Register for the 83C790
- */
-#define ED_WD790_ICR 6
-
-#define ED_WD790_ICR_EIL 0x01 /* enable interrupts */
-
-/*
- * General Control Register (GCR)
- * Eanbled with SWH bit == 1 in HWR register
- */
-#define ED_WD790_GCR 0x0d
-
-#define ED_WD790_GCR_IR0 0x04 /* bit 0 of encoded IRQ */
-#define ED_WD790_GCR_IR1 0x08 /* bit 1 of encoded IRQ */
-#define ED_WD790_GCR_ZWSEN 0x20 /* zero wait state enable */
-#define ED_WD790_GCR_IR2 0x40 /* bit 2 of encoded IRQ */
-/*
- * The three bits of the encoded IRQ are decoded as follows:
- *
- * IR2 IR1 IR0 IRQ
- * 0 0 0 none
- * 0 0 1 9
- * 0 1 0 3
- * 0 1 1 5
- * 1 0 0 7
- * 1 0 1 10
- * 1 1 0 11
- * 1 1 1 15
- */
-
-/* i/o base offset to CARD ID */
-#define ED_WD_CARD_ID ED_WD_PROM+6
-
-/* Board type codes in card ID */
-#define ED_TYPE_WD8003S 0x02
-#define ED_TYPE_WD8003E 0x03
-#define ED_TYPE_WD8013EBT 0x05
-#define ED_TYPE_TOSHIBA1 0x11 /* named PCETA1 */
-#define ED_TYPE_TOSHIBA2 0x12 /* named PCETA2 */
-#define ED_TYPE_TOSHIBA3 0x13 /* named PCETB */
-#define ED_TYPE_TOSHIBA4 0x14 /* named PCETC */
-#define ED_TYPE_WD8003W 0x24
-#define ED_TYPE_WD8003EB 0x25
-#define ED_TYPE_WD8013W 0x26
-#define ED_TYPE_WD8013EP 0x27
-#define ED_TYPE_WD8013WC 0x28
-#define ED_TYPE_WD8013EPC 0x29
-#define ED_TYPE_SMC8216T 0x2a
-#define ED_TYPE_SMC8216C 0x2b
-#define ED_TYPE_WD8013EBP 0x2c
-
-/* Bit definitions in card ID */
-#define ED_WD_REV_MASK 0x1f /* Revision mask */
-#define ED_WD_SOFTCONFIG 0x20 /* Soft config */
-#define ED_WD_LARGERAM 0x40 /* Large RAM */
-#define ED_MICROCHANEL 0x80 /* Microchannel bus (vs. isa) */
-
-/*
- * Checksum total. All 8 bytes in station address PROM will add up to this.
- */
-#ifdef TOSH_ETHER
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xA5
-#else
-#define ED_WD_ROM_CHECKSUM_TOTAL 0xFF
-#endif
-
-#define ED_WD_NIC_OFFSET 0x10 /* I/O base offset to NIC */
-#define ED_WD_ASIC_OFFSET 0 /* I/O base offset to ASIC */
-#define ED_WD_IO_PORTS 32 /* # of i/o addresses used */
-
-#define ED_WD_PAGE_OFFSET 0 /* page offset for NIC access to mem */
-
-/*
- * Definitions for 3Com 3c503
- */
-#define ED_3COM_NIC_OFFSET 0
-#define ED_3COM_ASIC_OFFSET 0x400 /* offset to nic i/o regs */
-
-/*
- * XXX - The I/O address range is fragmented in the 3c503; this is the
- * number of regs at iobase.
- */
-#define ED_3COM_IO_PORTS 16 /* # of i/o addresses used */
-
-/* tx memory starts in second bank on 8bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_8BIT 0x20
-
-/* tx memory starts in first bank on 16bit cards */
-#define ED_3COM_TX_PAGE_OFFSET_16BIT 0x0
-
-/* ...and rx memory starts in second bank */
-#define ED_3COM_RX_PAGE_OFFSET_16BIT 0x20
-
-
-/*
- * Page Start Register. Must match PSTART in NIC.
- */
-#define ED_3COM_PSTR 0
-
-/*
- * Page Stop Register. Must match PSTOP in NIC.
- */
-#define ED_3COM_PSPR 1
-
-/*
- * DrQ Timer Register. Determines number of bytes to be transfered during a
- * DMA burst.
- */
-#define ED_3COM_DQTR 2
-
-/*
- * Base Configuration Register. Read-only register which contains the
- * board-configured I/O base address of the adapter. Bit encoded.
- */
-#define ED_3COM_BCFR 3
-
-/*
- * EPROM Configuration Register. Read-only register which contains the
- * board-configured memory base address. Bit encoded.
- */
-#define ED_3COM_PCFR 4
-
-/*
- * GA Configuration Register. Gate-Array Configuration Register.
- *
- * mbs2 mbs1 mbs0 start address
- * 0 0 0 0x0000
- * 0 0 1 0x2000
- * 0 1 0 0x4000
- * 0 1 1 0x6000
- *
- * Note that with adapters with only 8K, the setting for 0x2000 must always be
- * used.
- */
-#define ED_3COM_GACFR 5
-
-#define ED_3COM_GACFR_MBS0 0x01
-#define ED_3COM_GACFR_MBS1 0x02
-#define ED_3COM_GACFR_MBS2 0x04
-
-#define ED_3COM_GACFR_RSEL 0x08 /* enable shared memory */
-#define ED_3COM_GACFR_TEST 0x10 /* for GA testing */
-#define ED_3COM_GACFR_OWS 0x20 /* select 0WS access to GA */
-#define ED_3COM_GACFR_TCM 0x40 /* Mask DMA interrupts */
-#define ED_3COM_GACFR_NIM 0x80 /* Mask NIC interrupts */
-
-/*
- * Control Register. Miscellaneous control functions.
- */
-#define ED_3COM_CR 6
-
-#define ED_3COM_CR_RST 0x01 /* Reset GA and NIC */
-#define ED_3COM_CR_XSEL 0x02 /* Transceiver select. BNC=1(def) AUI=0 */
-#define ED_3COM_CR_EALO 0x04 /* window EA PROM 0-15 to I/O base */
-#define ED_3COM_CR_EAHI 0x08 /* window EA PROM 16-31 to I/O base */
-#define ED_3COM_CR_SHARE 0x10 /* select interrupt sharing option */
-#define ED_3COM_CR_DBSEL 0x20 /* Double buffer select */
-#define ED_3COM_CR_DDIR 0x40 /* DMA direction select */
-#define ED_3COM_CR_START 0x80 /* Start DMA controller */
-
-/*
- * Status Register. Miscellaneous status information.
- */
-#define ED_3COM_STREG 7
-
-#define ED_3COM_STREG_REV 0x07 /* GA revision */
-#define ED_3COM_STREG_DIP 0x08 /* DMA in progress */
-#define ED_3COM_STREG_DTC 0x10 /* DMA terminal count */
-#define ED_3COM_STREG_OFLW 0x20 /* Overflow */
-#define ED_3COM_STREG_UFLW 0x40 /* Underflow */
-#define ED_3COM_STREG_DPRDY 0x80 /* Data port ready */
-
-/*
- * Interrupt/DMA Configuration Register
- */
-#define ED_3COM_IDCFR 8
-
-#define ED_3COM_IDCFR_DRQ 0x07 /* DMA request */
-#define ED_3COM_IDCFR_UNUSED 0x08 /* not used */
-#if 0
-#define ED_3COM_IDCFR_IRQ 0xF0 /* Interrupt request */
-#else
-#define ED_3COM_IDCFR_IRQ2 0x10 /* Interrupt request 2 select */
-#define ED_3COM_IDCFR_IRQ3 0x20 /* Interrupt request 3 select */
-#define ED_3COM_IDCFR_IRQ4 0x40 /* Interrupt request 4 select */
-#define ED_3COM_IDCFR_IRQ5 0x80 /* Interrupt request 5 select */
-#endif
-
-/*
- * DMA Address Register MSB
- */
-#define ED_3COM_DAMSB 9
-
-/*
- * DMA Address Register LSB
- */
-#define ED_3COM_DALSB 0x0a
-
-/*
- * Vector Pointer Register 2
- */
-#define ED_3COM_VPTR2 0x0b
-
-/*
- * Vector Pointer Register 1
- */
-#define ED_3COM_VPTR1 0x0c
-
-/*
- * Vector Pointer Register 0
- */
-#define ED_3COM_VPTR0 0x0d
-
-/*
- * Register File Access MSB
- */
-#define ED_3COM_RFMSB 0x0e
-
-/*
- * Register File Access LSB
- */
-#define ED_3COM_RFLSB 0x0f
-
-/*
- * Definitions for Novell NE1000/2000 boards
- */
-
-/*
- * Board type codes
- */
-#define ED_TYPE_NE1000 0x01
-#define ED_TYPE_NE2000 0x02
-
-/*
- * Register offsets/total
- */
-#define ED_NOVELL_NIC_OFFSET 0x00
-#define ED_NOVELL_ASIC_OFFSET 0x10
-#define ED_NOVELL_IO_PORTS 32
-
-/*
- * Remote DMA data register; for reading or writing to the NIC mem via
- * programmed I/O (offset from ASIC base).
- */
-#define ED_NOVELL_DATA 0x00
-
-/*
- * Reset register; reading from this register causes a board reset.
- */
-#define ED_NOVELL_RESET 0x0f
+++ /dev/null
-/* $OpenBSD: isa_intr.h,v 1.2 1996/02/27 15:40:58 niklas Exp $ */
-/* $NetBSD: isa_intr.h,v 1.1 1995/08/02 14:44:57 niklas Exp $ */
-
-/*
- * Copyright (c) 1995 Niklas Hallqvist.
- * All rights reserved.
- *
- * Copyright (c) 1995 Carnegie-Mellon University.
- * All rights reserved.
- *
- * Authors: Chris G. Demetriou, Niklas Hallqvist.
- *
- * Permission to use, copy, modify and distribute this software and
- * its documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
- * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-
-/* Prototypes for ISA-ish I/O interrupt functions. */
-
-/*
- * XXX
- * XXX THIS WILL LIKELY HAVE TO BE COMPLETELY CHANGED.
- * XXX
- */
-
-struct isa_intr_fcns {
- void (*isa_intr_setup) __P((void));
-
- void *(*isa_intr_establish) __P((int irq, int type, int level,
- int (*ih_fun)(void *), void *ih_arg, char *ih_what));
- void (*isa_intr_disestablish) __P((void *handler));
-
- void (*isa_iointr) __P((void *framep, int vec));
-};
-
-/*
- * Global which tells which set of functions are correct
- * for this machine.
- */
-struct isa_intr_fcns *isa_intr_fcns;
-
-extern struct isa_intr_fcns ggbus_intr_fcns;
-extern struct isa_intr_fcns cross_intr_fcns;
+++ /dev/null
-/* $OpenBSD: isa_machdep.c,v 1.2 1996/02/27 15:40:59 niklas Exp $ */
-/* $NetBSD: isa_machdep.c,v 1.1 1995/08/02 14:10:17 niklas Exp $ */
-
-/*
- * Copyright (c) 1995 Niklas Hallqvist
- * 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 Niklas Hallqvist.
- * 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 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.
- */
-#include <sys/param.h>
-#include <sys/device.h>
-#include <sys/malloc.h>
-
-#include <dev/isa/isavar.h>
-
-#include <machine/pio.h>
-
-#include <amiga/amiga/device.h>
-#include <amiga/isa/isa_intr.h>
-
-void isaattach __P((struct device *, struct device *, void *));
-int isamatch __P((struct device *, void *, void *));
-
-/*
- * After careful thought about this issue I decided that allowing only
- * one isabus configured into a system would be sufficient. I'm not
- * lazy, I did the original design with possibilities of multiple ISA
- * busses, but that made porting of existing drivers a bit harder and
- * error-prone, as well as I had to write obfuscated code. This
- * solution is more in the spirit of KISS. --niklas@appli.se
- */
-struct isa_link *isa;
-int isadebug = 0;
-
-struct cfdriver isacd = {
- NULL, "isa", isamatch, isaattach,
- DV_DULL, sizeof(struct device), 1
-};
-
-int
-isamatch(parent, cfdata, aux)
- struct device *parent;
- void *cfdata, *aux;
-{
- struct cfdata *cf = cfdata;
-
-#ifdef DEBUG
- if (isadebug)
- printf(" isamatch");
-#endif
-
- /* See if the unit number is valid. */
- if (cf->cf_unit > 0)
- return (0);
-
- return (1);
-}
-
-void
-isaattach(parent, self, aux)
- struct device *parent, *self;
- void *aux;
-{
- struct isa_softc *sc = (struct isa_softc *)self;
-
- isa = (struct isa_link *)aux;
-
- printf("\n");
-
- TAILQ_INIT (&sc->sc_subdevs);
-
- config_scan(isascan, self);
-}
-
-void *
-isa_intr_establish(intr, type, level, ih_fun, ih_arg, ih_what)
- int intr;
- int type;
- int level;
- int (*ih_fun)(void *);
- void *ih_arg;
- char *ih_what;
-{
- return (*isa_intr_fcns->isa_intr_establish)(intr, type, level,
- ih_fun, ih_arg, ih_what);
-}
-
-void
-isa_intr_disestablish(handler)
- void *handler;
-{
- (*isa_intr_fcns->isa_intr_disestablish)(handler);
-}
-
-void
-isa_outsb(port, addr, cnt)
- int port;
- void *addr;
- int cnt;
-{
- u_int8_t *p = addr;
-
- while (cnt--)
- outb(port, *p++);
-}
-
-void
-isa_insb(port, addr, cnt)
- int port;
- void *addr;
- int cnt;
-{
- u_int8_t *p = addr;
-
- while (cnt--)
- *p++ = inb(port);
-}
-
-void
-isa_outsw(port, addr, cnt)
- int port;
- void *addr;
- int cnt;
-{
- u_int16_t *p = addr;
-
- while (cnt--)
- outw(port, *p++);
-}
-
-void
-isa_insw(port, addr, cnt)
- int port;
- void *addr;
- int cnt;
-{
- u_int16_t *p = addr;
-
- while (cnt--)
- *p++ = inw(port);
-}
-/* $NetBSD: isa_machdep.h,v 1.1 1995/07/21 23:07:17 niklas Exp $ */
+/* $OpenBSD: isa_machdep.h,v 1.2 1996/04/27 18:39:04 niklas Exp $ */
/*
- * Copyright (c) 1995 Niklas Hallqvist
+ * Copyright (c) 1995, 1996 Niklas Hallqvist
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
#include <machine/endian.h>
-void isa_insb __P((int port, void *addr, int));
-void isa_outsb __P((int port, void *addr, int));
-void isa_insw __P((int port, void *addr, int));
-void isa_outsw __P((int port, void *addr, int));
-
/*
- * The link between the ISA device drivers and the bridgecard used.
+ * Types provided to machine-independent ISA code.
*/
-struct isa_link {
- struct device *il_dev;
- void (*il_stb)(struct device *, int, u_char);
- u_char (*il_ldb)(struct device *, int);
- void (*il_stw)(struct device *, int, u_short);
- u_short (*il_ldw)(struct device *, int);
-};
-
-extern struct isa_link *isa;
-extern struct cfdriver isacd;
-
-static __inline void
-stb(addr, val)
- int addr;
- u_char val;
-{
- (*isa->il_stb)(isa->il_dev, addr, val);
-}
-
-static __inline u_char
-ldb(addr)
- int addr;
-{
- return (*isa->il_ldb)(isa->il_dev, addr);
-}
-
-static __inline void
-stw(addr, val)
- int addr;
- u_short val;
-{
- (*isa->il_stw)(isa->il_dev, addr, val);
-}
-
-static __inline u_short
-ldw(addr)
- int addr;
-{
- return (*isa->il_ldw)(isa->il_dev, addr);
-}
-
-/*
- * Should these be out-of-line instead? If so, move them to isa.c!
- * How about unaligned word accesses? Does the '020 allow them? If not
- * we have to do odd to even moves and vice versa bytewise instead of
- * wordwise.
- */
-static __inline void
-copy_from_isa (void *from, void *to, int cnt)
-{
- int a = (int)from;
-
- if (a & 1 && cnt) {
- *(u_char *)to = ldb(a++);
- to = ((u_char *)to) + 1;
- cnt--;
- }
- /* Maybe use Duff's device here... */
- while (cnt > 1) {
- *(u_short *)to = ldw(a);
- a += sizeof(u_short);
- to = ((u_short *)to) + 1;
- cnt -= 2;
- }
- if (cnt)
- *(u_char *)to = ldb(a);
-}
+typedef struct amiga_isa_chipset *isa_chipset_tag_t;
-static __inline void
-copy_to_isa (const void *from, void *to, int cnt)
-{
- int a = (int)to;
+struct amiga_isa_chipset {
+ void *ic_data;
- if (a & 1 && cnt) {
- stb(a++, *(u_char *)from);
- from = ((u_char *)from) + 1;
- cnt--;
- }
- /* Maybe use Duff's device here... */
- while (cnt > 1) {
- stw(a, *(u_short *)from);
- a += sizeof(u_short);
- from = ((u_short *)from) + 1;
- cnt -= 2;
- }
- if (cnt)
- stb(a, *(u_char *)from);
-}
-
-static __inline void
-zero_isa (void *addr, int cnt)
-{
- int a = (int)addr;
-
- if (a & 1 && cnt) {
- stb(a++, 0);
- cnt--;
- }
- /* Maybe use Duff's device here... */
- while (cnt > 1) {
- stw(a, 0);
- a += sizeof(u_short);
- cnt -= 2;
- }
- if (cnt)
- stb(a, 0);
-}
-
-/*
- * These inlines convert shorts from/to isa (intel) byte order to host
- * byte-order. I know both are exactly equal, but I think it make code
- * more readable to have separate names for them as they indeed have
- * distinctive functionalities.
- */
-static __inline u_short
-swap(u_short x)
-{
- __asm("rolw #8,%0" : "=r" (x) : "0" (x));
- return x;
-}
-
-static __inline u_short
-itohs(u_short x)
-{
-#if BYTE_ORDER == LITTLE_ENDIAN
- return x;
-#else
- return swap(x);
-#endif
-}
-
-static __inline u_short
-htois(u_short x)
-{
-#if BYTE_ORDER == LITTLE_ENDIAN
- return x;
-#else
- return swap(x);
-#endif
-}
+ void (*ic_attach_hook) __P((struct device *, struct device *,
+ struct isabus_attach_args *));
+ void *(*ic_intr_establish) __P((void *, int, int, int,
+ int (*)(void *), void *, char *));
+ void (*ic_intr_disestablish) __P((void *, void *));
+};
/*
- * Given a physical address in the "hole",
- * return a kernel virtual address.
+ * Functions provided to machine-independent ISA code.
*/
-#define ISA_HOLE_VADDR(p) ((caddr_t)p)
+#define isa_attach_hook(p, s, a) \
+ (*(a)->iba_ic->ic_attach_hook)((p), (s), (a))
+#define isa_intr_establish(c, i, t, l, f, a, w) \
+ (*(c)->ic_intr_establish)((c)->ic_data, (i), (t), (l), (f), (a), (w))
+#define isa_intr_disestablish(c, h) \
+ (*(c)->ic_intr_disestablish)((c)->ic_data, (h))
#endif
-# $OpenBSD: files.i386,v 1.11 1996/04/21 22:16:15 deraadt Exp $
+# $OpenBSD: files.i386,v 1.12 1996/04/27 18:39:05 niklas Exp $
# $NetBSD: files.i386,v 1.72 1996/04/09 22:59:03 cgd Exp $
#
# new style config file for i386 architecture
attach spkr at pckbd
file arch/i386/isa/spkr.c spkr needs-flag
+# National Semiconductor DS8390/WD83C690-based boards
+# (WD/SMC 80x3 family, SMC Ultra [8216], 3Com 3C503, NE[12]000, and clones)
+# XXX conflicts with other ports; can't be in files.isa
+device ed: ether, ifnet
+attach ed at isa
+file dev/isa/if_ed.c ed
+
# AMD am7990 (Lance) -based boards
# (BICC Isolan, NE2100, DEPCA)
# XXX conflicts with other ports; can't be in files.isa
-# $OpenBSD: files.isa,v 1.9 1996/04/24 16:52:42 mickey Exp $
+# $OpenBSD: files.isa,v 1.10 1996/04/27 18:39:07 niklas Exp $
# $NetBSD: files.isa,v 1.17 1996/03/29 20:53:30 mycroft Exp $
#
# Config.new file and device description for machine-independent ISA code.
# National Semiconductor DS8390/WD83C690-based boards
# (WD/SMC 80x3 family, SMC Ultra [8216], 3Com 3C503, NE[12]000, and clones)
# XXX conflicts with amiga if_ed.c
-device ed: ether, ifnet
-attach ed at isa
-file dev/isa/if_ed.c ed needs-flag
+#device ed: ether, ifnet
+#attach ed at isa
+#file dev/isa/if_ed.c ed needs-flag
# 3Com 3C505
device eg: ether, ifnet
-/* $OpenBSD: isavar.h,v 1.8 1996/04/21 22:24:16 deraadt Exp $ */
+/* $OpenBSD: isavar.h,v 1.9 1996/04/27 18:39:07 niklas Exp $ */
/* $NetBSD: isavar.h,v 1.21 1996/04/11 22:20:50 cgd Exp $ */
/*
*/
struct isabus_attach_args;
-#if (alpha + i386 != 1)
+#if (alpha + amiga + i386 != 1)
ERROR: COMPILING FOR UNSUPPORTED MACHINE, OR MORE THAN ONE.
#endif
#if alpha
#include <alpha/isa/isa_machdep.h>
#endif
+#if amiga
+#include <amiga/isa/isa_machdep.h>
+#endif
#if i386
#include <i386/isa/isa_machdep.h>
#endif