diff options
Diffstat (limited to 'sys/arch/amiga')
-rw-r--r-- | sys/arch/amiga/amiga/conf.c | 23 | ||||
-rw-r--r-- | sys/arch/amiga/amiga/machdep.c | 8 | ||||
-rw-r--r-- | sys/arch/amiga/conf/FILIPPA | 24 | ||||
-rw-r--r-- | sys/arch/amiga/conf/files.amiga | 23 | ||||
-rw-r--r-- | sys/arch/amiga/dev/clock.c | 3 | ||||
-rw-r--r-- | sys/arch/amiga/dev/zssc.c | 3 | ||||
-rw-r--r-- | sys/arch/amiga/include/bus.h | 186 | ||||
-rw-r--r-- | sys/arch/amiga/include/intr.h (renamed from sys/arch/amiga/isa/cross_pio.c) | 98 | ||||
-rw-r--r-- | sys/arch/amiga/include/psl.h | 14 | ||||
-rw-r--r-- | sys/arch/amiga/isa/cross.c | 530 | ||||
-rw-r--r-- | sys/arch/amiga/isa/crossreg.h | 21 | ||||
-rw-r--r-- | sys/arch/amiga/isa/crossvar.h | 46 | ||||
-rw-r--r-- | sys/arch/amiga/isa/ggbus.c | 487 | ||||
-rw-r--r-- | sys/arch/amiga/isa/ggbus_pio.c | 114 | ||||
-rw-r--r-- | sys/arch/amiga/isa/ggbusreg.h | 13 | ||||
-rw-r--r-- | sys/arch/amiga/isa/ggbusvar.h | 45 | ||||
-rw-r--r-- | sys/arch/amiga/isa/if_isaed.c | 1366 | ||||
-rw-r--r-- | sys/arch/amiga/isa/if_isaedreg.h | 398 | ||||
-rw-r--r-- | sys/arch/amiga/isa/isa_intr.h | 59 | ||||
-rw-r--r-- | sys/arch/amiga/isa/isa_machdep.c | 164 | ||||
-rw-r--r-- | sys/arch/amiga/isa/isa_machdep.h | 168 |
21 files changed, 1925 insertions, 1868 deletions
diff --git a/sys/arch/amiga/amiga/conf.c b/sys/arch/amiga/amiga/conf.c index cad954ce811..9fdc17d70f0 100644 --- a/sys/arch/amiga/amiga/conf.c +++ b/sys/arch/amiga/amiga/conf.c @@ -1,4 +1,4 @@ -/* $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 $ */ /*- @@ -115,6 +115,12 @@ int nblkdev = sizeof(bdevsw) / sizeof(bdevsw[0]); 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 @@ -175,6 +181,11 @@ cdev_decl(ipl); #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 */ @@ -211,7 +222,9 @@ struct cdevsw cdevsw[] = 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]); @@ -331,6 +344,7 @@ chrtoblk(dev) */ cons_decl(ser); cons_decl(ite); +cons_decl(com); struct consdev constab[] = { #if NSER > 0 @@ -339,5 +353,10 @@ struct consdev constab[] = { #if NITE > 0 cons_init(ite), #endif +#ifdef notyet +#if NCOM > 0 + cons_init(com), +#endif +#endif { 0 }, }; diff --git a/sys/arch/amiga/amiga/machdep.c b/sys/arch/amiga/amiga/machdep.c index d6b17a926a9..9b3bd77a769 100644 --- a/sys/arch/amiga/amiga/machdep.c +++ b/sys/arch/amiga/amiga/machdep.c @@ -1,3 +1,4 @@ +/* $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 $ */ /* @@ -168,9 +169,8 @@ walk_ipls (start_ipl, ending_psw) 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; @@ -179,8 +179,8 @@ walk_ipls (start_ipl, ending_psw) 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"); diff --git a/sys/arch/amiga/conf/FILIPPA b/sys/arch/amiga/conf/FILIPPA index 6120df7a46a..133d2bfc24d 100644 --- a/sys/arch/amiga/conf/FILIPPA +++ b/sys/arch/amiga/conf/FILIPPA @@ -1,4 +1,4 @@ -# $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 @@ -176,8 +176,8 @@ ite1 at grf1 # terminal emulators for grf's # 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 @@ -206,20 +206,17 @@ st* at scsibus? target ? lun ? # scsi tapes 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 @@ -227,17 +224,20 @@ com5 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 diff --git a/sys/arch/amiga/conf/files.amiga b/sys/arch/amiga/conf/files.amiga index 90ba56bc492..f4ec2743234 100644 --- a/sys/arch/amiga/conf/files.amiga +++ b/sys/arch/amiga/conf/files.amiga @@ -1,4 +1,4 @@ -# $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} @@ -255,29 +255,24 @@ file arch/amiga/dev/idesc.c idesc needs-flag 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... diff --git a/sys/arch/amiga/dev/clock.c b/sys/arch/amiga/dev/clock.c index 00d38bb3133..aad42f1f0b5 100644 --- a/sys/arch/amiga/dev/clock.c +++ b/sys/arch/amiga/dev/clock.c @@ -1,4 +1,4 @@ -/* $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 $ */ /* @@ -48,6 +48,7 @@ #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> diff --git a/sys/arch/amiga/dev/zssc.c b/sys/arch/amiga/dev/zssc.c index 26b734b26f0..b3fde4eb260 100644 --- a/sys/arch/amiga/dev/zssc.c +++ b/sys/arch/amiga/dev/zssc.c @@ -1,4 +1,4 @@ -/* $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 $ */ /* @@ -40,6 +40,7 @@ #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> diff --git a/sys/arch/amiga/include/bus.h b/sys/arch/amiga/include/bus.h new file mode 100644 index 00000000000..4a569dcd621 --- /dev/null +++ b/sys/arch/amiga/include/bus.h @@ -0,0 +1,186 @@ +/* $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_ */ diff --git a/sys/arch/amiga/isa/cross_pio.c b/sys/arch/amiga/include/intr.h index c2e5ed41316..cc7b6b05f02 100644 --- a/sys/arch/amiga/isa/cross_pio.c +++ b/sys/arch/amiga/include/intr.h @@ -1,7 +1,7 @@ -/* $NetBSD: cross_pio.c,v 1.1 1995/08/04 14:32:17 niklas Exp $ */ +/* $OpenBSD: intr.h,v 1.1 1996/04/27 18:38:53 niklas Exp $ */ /* - * Copyright (c) 1995 Niklas Hallqvist + * Copyright (c) 1996 Niklas Hallqvist * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,86 +29,22 @@ * (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> +#ifndef _MACHINE_INTR_H_ +#define _MACHINE_INTR_H_ -#include <dev/isa/isavar.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 */ -#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; -} +/* 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_ */ diff --git a/sys/arch/amiga/include/psl.h b/sys/arch/amiga/include/psl.h index 0e1a340cc19..ff340b33085 100644 --- a/sys/arch/amiga/include/psl.h +++ b/sys/arch/amiga/include/psl.h @@ -3,20 +3,6 @@ #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 diff --git a/sys/arch/amiga/isa/cross.c b/sys/arch/amiga/isa/cross.c index 0b98f664472..923f059eccf 100644 --- a/sys/arch/amiga/isa/cross.c +++ b/sys/arch/amiga/isa/cross.c @@ -1,8 +1,7 @@ -/* $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 @@ -15,7 +14,7 @@ * 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 * @@ -30,14 +29,16 @@ * (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> @@ -46,35 +47,93 @@ #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 @@ -93,38 +152,36 @@ crossmatch(parent, match, aux) } 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 @@ -138,184 +195,273 @@ crossprint(auxp, pnp) } -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; } diff --git a/sys/arch/amiga/isa/crossreg.h b/sys/arch/amiga/isa/crossreg.h index e348bd4bc1e..cc932f66dd8 100644 --- a/sys/arch/amiga/isa/crossreg.h +++ b/sys/arch/amiga/isa/crossreg.h @@ -1,7 +1,7 @@ -/* $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 @@ -14,7 +14,7 @@ * 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 * @@ -29,8 +29,10 @@ * (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_ + /*** * * @@ -95,6 +97,7 @@ * 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 @@ -104,16 +107,18 @@ #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 @@ -128,6 +133,6 @@ #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 diff --git a/sys/arch/amiga/isa/crossvar.h b/sys/arch/amiga/isa/crossvar.h index 0ef789c47d4..4d54719a39b 100644 --- a/sys/arch/amiga/isa/crossvar.h +++ b/sys/arch/amiga/isa/crossvar.h @@ -1,7 +1,7 @@ -/* $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 @@ -14,7 +14,7 @@ * 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 * @@ -29,18 +29,40 @@ * (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; diff --git a/sys/arch/amiga/isa/ggbus.c b/sys/arch/amiga/isa/ggbus.c index 7faeb895c85..03f546e88de 100644 --- a/sys/arch/amiga/isa/ggbus.c +++ b/sys/arch/amiga/isa/ggbus.c @@ -1,8 +1,7 @@ -/* $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 @@ -30,14 +29,16 @@ * (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> @@ -46,36 +47,120 @@ #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 @@ -94,48 +179,39 @@ ggbusmatch(parent, match, aux) } 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 @@ -148,59 +224,130 @@ ggbusprint(auxp, pnp) 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[] = { @@ -208,56 +355,126 @@ 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; } diff --git a/sys/arch/amiga/isa/ggbus_pio.c b/sys/arch/amiga/isa/ggbus_pio.c deleted file mode 100644 index c1079be64ea..00000000000 --- a/sys/arch/amiga/isa/ggbus_pio.c +++ /dev/null @@ -1,114 +0,0 @@ -/* $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; -} - diff --git a/sys/arch/amiga/isa/ggbusreg.h b/sys/arch/amiga/isa/ggbusreg.h index d835dca389c..1bc9d461b56 100644 --- a/sys/arch/amiga/isa/ggbusreg.h +++ b/sys/arch/amiga/isa/ggbusreg.h @@ -1,7 +1,7 @@ -/* $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 @@ -29,13 +29,14 @@ * (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 @@ -54,11 +55,11 @@ #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) \ diff --git a/sys/arch/amiga/isa/ggbusvar.h b/sys/arch/amiga/isa/ggbusvar.h index 1036b58411b..8bc8525f61a 100644 --- a/sys/arch/amiga/isa/ggbusvar.h +++ b/sys/arch/amiga/isa/ggbusvar.h @@ -1,7 +1,7 @@ -/* $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 @@ -29,22 +29,41 @@ * (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 diff --git a/sys/arch/amiga/isa/if_isaed.c b/sys/arch/amiga/isa/if_isaed.c index d58ed943f0e..8596e301531 100644 --- a/sys/arch/amiga/isa/if_isaed.c +++ b/sys/arch/amiga/isa/if_isaed.c @@ -1,17 +1,10 @@ -/* $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 @@ -59,32 +52,39 @@ #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 @@ -100,10 +100,10 @@ struct isaed_softc { 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 */ @@ -118,63 +118,232 @@ struct isaed_softc { 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); } @@ -201,42 +370,54 @@ isaedprobe(parent, match, aux) * 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 @@ -246,16 +427,8 @@ isaed_probe_WD80x3(sc, cf, ia) * 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) { /* @@ -263,25 +436,27 @@ isaed_probe_WD80x3(sc, cf, ia) * 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; @@ -310,7 +485,8 @@ isaed_probe_WD80x3(sc, cf, ia) 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"; @@ -333,14 +509,34 @@ isaed_probe_WD80x3(sc, cf, ia) 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; @@ -368,19 +564,18 @@ isaed_probe_WD80x3(sc, cf, ia) #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) @@ -401,55 +596,55 @@ isaed_probe_WD80x3(sc, cf, ia) 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; } } @@ -458,7 +653,10 @@ isaed_probe_WD80x3(sc, cf, ia) 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)) @@ -476,7 +674,7 @@ isaed_probe_WD80x3(sc, cf, ia) /* 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. @@ -484,15 +682,15 @@ isaed_probe_WD80x3(sc, cf, ia) 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) || @@ -502,9 +700,9 @@ isaed_probe_WD80x3(sc, cf, ia) #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); } } @@ -514,52 +712,53 @@ isaed_probe_WD80x3(sc, cf, ia) */ 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; } /* @@ -570,38 +769,65 @@ isaed_probe_WD80x3(sc, cf, ia) * 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 @@ -611,48 +837,49 @@ isaed_probe_3Com(sc, cf, ia) * 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 /* @@ -660,7 +887,8 @@ isaed_probe_3Com(sc, cf, ia) * 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); @@ -670,7 +898,7 @@ isaed_probe_3Com(sc, cf, ia) * 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); @@ -692,42 +920,49 @@ isaed_probe_3Com(sc, cf, ia) * 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; @@ -768,34 +1003,38 @@ isaed_probe_3Com(sc, cf, ia) * 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); /* @@ -804,50 +1043,79 @@ isaed_probe_3Com(sc, cf, ia) * 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 @@ -857,7 +1125,7 @@ isaed_probe_Novell(sc, cf, ia) * 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); /* @@ -866,13 +1134,14 @@ isaed_probe_Novell(sc, cf, ia) * 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; @@ -888,31 +1157,37 @@ isaed_probe_Novell(sc, cf, ia) * 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; @@ -920,11 +1195,11 @@ isaed_probe_Novell(sc, cf, ia) * 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"; @@ -936,7 +1211,7 @@ isaed_probe_Novell(sc, cf, ia) 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. */ @@ -950,7 +1225,7 @@ isaed_probe_Novell(sc, cf, ia) /* 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 @@ -981,7 +1256,7 @@ isaed_probe_Novell(sc, cf, ia) 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. */ @@ -1027,7 +1302,7 @@ isaed_probe_Novell(sc, cf, ia) 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)]; @@ -1037,34 +1312,61 @@ isaed_probe_Novell(sc, cf, ia) #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; @@ -1080,17 +1382,22 @@ isaedattach(parent, self, aux) 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); @@ -1114,25 +1421,28 @@ isaedattach(parent, self, aux) 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); } @@ -1140,20 +1450,25 @@ isaedreset(sc) * 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); } /* @@ -1161,25 +1476,28 @@ isaedstop(sc) * 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]; @@ -1198,43 +1516,45 @@ isaedinit(sc) 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, @@ -1242,31 +1562,34 @@ isaedinit(sc) * * 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) { @@ -1276,10 +1599,10 @@ isaedinit(sc) */ 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 @@ -1289,58 +1612,65 @@ isaedinit(sc) 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++; @@ -1354,20 +1684,23 @@ isaed_xmit(sc) /* * 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; @@ -1395,7 +1728,8 @@ outloop: #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... */ @@ -1407,7 +1741,8 @@ outloop: */ 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; /* @@ -1416,51 +1751,49 @@ outloop: */ 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) @@ -1475,22 +1808,22 @@ outloop: * 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. @@ -1500,12 +1833,13 @@ loop: * 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. */ @@ -1517,30 +1851,12 @@ loop: * 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 @@ -1560,11 +1876,13 @@ loop: --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); } @@ -1578,30 +1896,25 @@ loop: * 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 @@ -1610,7 +1923,7 @@ loop: 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; @@ -1618,38 +1931,40 @@ 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 @@ -1660,13 +1975,13 @@ isaedintr(arg) * 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 @@ -1706,7 +2021,7 @@ isaedintr(arg) * otherwise defer until after handling receiver. */ if (sc->txb_inuse > 0) - isaed_xmit(sc); + ed_xmit(sc); } /* Handle receiver interrupts. */ @@ -1728,7 +2043,7 @@ isaedintr(arg) sc->sc_dev.dv_xname); #endif /* Stop/reset/re-init NIC. */ - isaedreset(sc); + edreset(sc); } else { /* * Receiver Error. One or more of: CRC error, @@ -1737,11 +2052,10 @@ isaedintr(arg) */ 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 } @@ -1759,25 +2073,32 @@ isaedintr(arg) */ 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); } } } @@ -1787,7 +2108,7 @@ isaedintr(arg) * 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 @@ -1795,7 +2116,8 @@ isaedintr(arg) * 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 @@ -1803,12 +2125,12 @@ isaedintr(arg) * 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); } @@ -1818,17 +2140,23 @@ isaedintr(arg) * 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) { @@ -1838,7 +2166,7 @@ isaedioctl(ifp, cmd, data) switch (ifa->ifa_addr->sa_family) { #ifdef INET case AF_INET: - isaedinit(sc); + edinit(sc); arp_ifinit(&sc->sc_arpcom, ifa); break; #endif @@ -1852,16 +2180,16 @@ isaedioctl(ifp, cmd, data) 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; @@ -1873,7 +2201,7 @@ isaedioctl(ifp, cmd, data) * 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) { @@ -1881,14 +2209,14 @@ isaedioctl(ifp, cmd, data) * 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; @@ -1904,8 +2232,8 @@ isaedioctl(ifp, cmd, data) * 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; @@ -1924,17 +2252,16 @@ isaedioctl(ifp, cmd, data) * 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; @@ -1984,33 +2311,41 @@ isaedread(sc, buf, len) * 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); } /* @@ -2018,35 +2353,42 @@ isaed_pio_readmem(sc, src, 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 @@ -2055,7 +2397,8 @@ isaed_pio_writemem(sc, src, dst, len) * 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); } /* @@ -2063,11 +2406,14 @@ isaed_pio_writemem(sc, src, dst, len) * 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 */ @@ -2075,21 +2421,23 @@ isaed_pio_write_mbufs(sc, m, dst) 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. @@ -2101,13 +2449,14 @@ isaed_pio_write_mbufs(sc, m, dst) /* 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; @@ -2115,20 +2464,23 @@ isaed_pio_write_mbufs(sc, m, dst) 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; @@ -2139,8 +2491,8 @@ isaed_pio_write_mbufs(sc, m, dst) 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); } } @@ -2151,13 +2503,14 @@ isaed_pio_write_mbufs(sc, m, dst) * 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); @@ -2167,10 +2520,11 @@ isaed_pio_write_mbufs(sc, m, dst) * 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; @@ -2181,9 +2535,9 @@ isaed_ring_copy(sc, src, dst, 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; @@ -2191,9 +2545,9 @@ isaed_ring_copy(sc, src, dst, amount) } 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); } @@ -2201,15 +2555,15 @@ isaed_ring_copy(sc, src, dst, 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; @@ -2240,7 +2594,7 @@ isaedget(sc, src, total_len) 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; @@ -2254,7 +2608,7 @@ isaedget(sc, src, total_len) * need to listen to. */ void -isaed_getmcaf(ac, af) +ed_getmcaf(ac, af) struct arpcom *ac; u_long *af; { @@ -2320,3 +2674,37 @@ isaed_getmcaf(ac, 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); +} diff --git a/sys/arch/amiga/isa/if_isaedreg.h b/sys/arch/amiga/isa/if_isaedreg.h deleted file mode 100644 index 53d4005b7da..00000000000 --- a/sys/arch/amiga/isa/if_isaedreg.h +++ /dev/null @@ -1,398 +0,0 @@ -/* $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 diff --git a/sys/arch/amiga/isa/isa_intr.h b/sys/arch/amiga/isa/isa_intr.h deleted file mode 100644 index c25220f38f9..00000000000 --- a/sys/arch/amiga/isa/isa_intr.h +++ /dev/null @@ -1,59 +0,0 @@ -/* $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; diff --git a/sys/arch/amiga/isa/isa_machdep.c b/sys/arch/amiga/isa/isa_machdep.c deleted file mode 100644 index b615e036783..00000000000 --- a/sys/arch/amiga/isa/isa_machdep.c +++ /dev/null @@ -1,164 +0,0 @@ -/* $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); -} diff --git a/sys/arch/amiga/isa/isa_machdep.h b/sys/arch/amiga/isa/isa_machdep.h index 9fabef0dfe9..047d1282f18 100644 --- a/sys/arch/amiga/isa/isa_machdep.h +++ b/sys/arch/amiga/isa/isa_machdep.h @@ -1,7 +1,7 @@ -/* $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 @@ -34,159 +34,29 @@ #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 |