summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-12-10 10:45:11 +0000
committerphk <phk@FreeBSD.org>1999-12-10 10:45:11 +0000
commitf4febe538dac10815b00750a63cf5c54cdabfae9 (patch)
tree951537a5370dc265f21b108da0e92a2df578274f
parentc48451203a194b8b0c9f644aad17d077d8593513 (diff)
downloadFreeBSD-src-f4febe538dac10815b00750a63cf5c54cdabfae9.zip
FreeBSD-src-f4febe538dac10815b00750a63cf5c54cdabfae9.tar.gz
Remove the if_ze and if_zp drivers.
These drivers were cloned from the ed and ep drivers back in 1994 when PCMCIA cards were a very new thing and we had no other support for such devices. They treated the PCIC (the chip which controls the PCCARD slot) as part of their device and generally hacked their way to success. They have significantly bit-rotted relative to their ancestor drivers (ed & ep) and they were a dead-end on the evolution path to proper PCCARD support in FreeBSD. They have been terminally broken since August 18 where mdodd forgot them and nobody seems to have missed them enough to fix them since. I found no outstanding PRs against these drivers.
-rw-r--r--sys/amd64/conf/GENERIC6
-rw-r--r--sys/conf/NOTES4
-rw-r--r--sys/conf/files.i3864
-rw-r--r--sys/i386/conf/GENERIC6
-rw-r--r--sys/i386/conf/LINT4
-rw-r--r--sys/i386/conf/NOTES4
-rw-r--r--sys/i386/conf/PCCARD6
-rw-r--r--sys/i386/conf/files.i3864
-rw-r--r--sys/i386/isa/if_ze.c1560
-rw-r--r--sys/i386/isa/if_zp.c1118
-rw-r--r--sys/i386/isa/if_zpreg.h293
-rw-r--r--sys/i386/isa/isa_compat.h10
-rw-r--r--sys/i386/isa/pcic.h181
-rw-r--r--sys/i386/isa/pcicx.c232
14 files changed, 0 insertions, 3432 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC
index 8ffe394..731267f 100644
--- a/sys/amd64/conf/GENERIC
+++ b/sys/amd64/conf/GENERIC
@@ -190,12 +190,6 @@ device cs0 at isa? port 0x300 irq ?
# requires PCCARD (PCMCIA) support to be activated
#device xe0 at isa? port? irq ?
-# PCCARD NIC drivers.
-# ze and zp take over the pcic and cannot coexist with generic pccard
-# support, nor the ed and ep drivers they replace.
-#device ze0 at isa? port 0x300 irq 10 iomem 0xd8000
-#device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
-
# Pseudo devices - the number indicates how many units to allocated.
pseudo-device loop # Network loopback
pseudo-device ether # Ethernet support
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index b6775be..c98937f 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -1297,10 +1297,6 @@ options WLCACHE # enables the signal-strength cache
options WLDEBUG # enables verbose debugging output
device wl0 at isa? port 0x300 irq ?
device xe0 at isa? port? irq ?
-# We can (bogusly) include both the dedicated PCCARD drivers and the generic
-# support when COMPILING_LINT.
-device ze0 at isa? port 0x300 irq 5 iomem 0xd8000
-device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
device oltr0 at isa?
diff --git a/sys/conf/files.i386 b/sys/conf/files.i386
index 39c1c66..4f09bb9 100644
--- a/sys/conf/files.i386
+++ b/sys/conf/files.i386
@@ -226,8 +226,6 @@ i386/isa/if_sr.c optional sr
i386/isa/if_wi.c optional wi card
i386/isa/if_wl.c optional wl
i386/isa/if_wlp.c optional wlp
-i386/isa/if_ze.c optional ze
-i386/isa/if_zp.c optional zp
i386/isa/intr_machdep.c standard
i386/isa/ipl_funcs.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} $<"
@@ -245,8 +243,6 @@ i386/isa/npx.c mandatory npx
i386/isa/pcaudio.c optional pca
i386/isa/pcf.c optional pcf
i386/isa/pcibus.c optional pci
-i386/isa/pcicx.c optional ze
-i386/isa/pcicx.c optional zp
i386/isa/pcvt/pcvt_drv.c optional vt
i386/isa/pcvt/pcvt_ext.c optional vt
i386/isa/pcvt/pcvt_kbd.c optional vt
diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC
index 8ffe394..731267f 100644
--- a/sys/i386/conf/GENERIC
+++ b/sys/i386/conf/GENERIC
@@ -190,12 +190,6 @@ device cs0 at isa? port 0x300 irq ?
# requires PCCARD (PCMCIA) support to be activated
#device xe0 at isa? port? irq ?
-# PCCARD NIC drivers.
-# ze and zp take over the pcic and cannot coexist with generic pccard
-# support, nor the ed and ep drivers they replace.
-#device ze0 at isa? port 0x300 irq 10 iomem 0xd8000
-#device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
-
# Pseudo devices - the number indicates how many units to allocated.
pseudo-device loop # Network loopback
pseudo-device ether # Ethernet support
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index b6775be..c98937f 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -1297,10 +1297,6 @@ options WLCACHE # enables the signal-strength cache
options WLDEBUG # enables verbose debugging output
device wl0 at isa? port 0x300 irq ?
device xe0 at isa? port? irq ?
-# We can (bogusly) include both the dedicated PCCARD drivers and the generic
-# support when COMPILING_LINT.
-device ze0 at isa? port 0x300 irq 5 iomem 0xd8000
-device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
device oltr0 at isa?
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index b6775be..c98937f 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -1297,10 +1297,6 @@ options WLCACHE # enables the signal-strength cache
options WLDEBUG # enables verbose debugging output
device wl0 at isa? port 0x300 irq ?
device xe0 at isa? port? irq ?
-# We can (bogusly) include both the dedicated PCCARD drivers and the generic
-# support when COMPILING_LINT.
-device ze0 at isa? port 0x300 irq 5 iomem 0xd8000
-device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
device oltr0 at isa?
diff --git a/sys/i386/conf/PCCARD b/sys/i386/conf/PCCARD
index 148ce23..ee1b016 100644
--- a/sys/i386/conf/PCCARD
+++ b/sys/i386/conf/PCCARD
@@ -191,12 +191,6 @@ device cs0 at isa? port 0x300 irq ?
# requires PCCARD (PCMCIA) support to be activated
device xe0 at isa? port? irq ?
-# PCCARD NIC drivers.
-# ze and zp take over the pcic and cannot coexist with generic pccard
-# support, nor the ed and ep drivers they replace.
-#device ze0 at isa? port 0x300 irq 10 iomem 0xd8000
-#device zp0 at isa? port 0x300 irq 10 iomem 0xd8000
-
# Pseudo devices - the number indicates how many units to allocated.
pseudo-device loop # Network loopback
pseudo-device ether # Ethernet support
diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386
index 39c1c66..4f09bb9 100644
--- a/sys/i386/conf/files.i386
+++ b/sys/i386/conf/files.i386
@@ -226,8 +226,6 @@ i386/isa/if_sr.c optional sr
i386/isa/if_wi.c optional wi card
i386/isa/if_wl.c optional wl
i386/isa/if_wlp.c optional wlp
-i386/isa/if_ze.c optional ze
-i386/isa/if_zp.c optional zp
i386/isa/intr_machdep.c standard
i386/isa/ipl_funcs.c standard \
compile-with "${CC} -c ${CFLAGS} ${DEFINED_PROF:S/^$/-fomit-frame-pointer/} $<"
@@ -245,8 +243,6 @@ i386/isa/npx.c mandatory npx
i386/isa/pcaudio.c optional pca
i386/isa/pcf.c optional pcf
i386/isa/pcibus.c optional pci
-i386/isa/pcicx.c optional ze
-i386/isa/pcicx.c optional zp
i386/isa/pcvt/pcvt_drv.c optional vt
i386/isa/pcvt/pcvt_ext.c optional vt
i386/isa/pcvt/pcvt_kbd.c optional vt
diff --git a/sys/i386/isa/if_ze.c b/sys/i386/isa/if_ze.c
deleted file mode 100644
index dd6cf3c8..0000000
--- a/sys/i386/isa/if_ze.c
+++ /dev/null
@@ -1,1560 +0,0 @@
-/*-
- * TODO:
- * [1] integrate into current if_ed.c
- * [2] parse tuples to find out where to map the shared memory buffer,
- * and what to write into the configuration register
- * [3] move pcic-specific code into a separate module.
- *
- * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
- * if_ze.c
- *
- * Based on the Device driver for National Semiconductor DS8390 ethernet
- * adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
- * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
- *
- * Currently supports only the IBM Credit Card Adapter for Ethernet, but
- * could probably work with other PCMCIA cards also, if it were modified
- * to get the locations of the PCMCIA configuration option register (COR)
- * by parsing the configuration tuples, rather than by hard-coding in
- * the value expected by IBM's card.
- *
- * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
- *
- * [1] _Local Area Network Credit Card Adapters Technical Reference_,
- * IBM Corp., SC30-3585-00, part # 33G9243.
- * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
- * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
- * Order Number 290423-002
- * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
- * Interface Controller for Twisted Pair data sheet.
- *
- *
- * 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.
- */
-/*
- * I doubled delay loops in this file because it is not enough for some
- * laptop machines' PCIC (especially, on my Chaplet ILFA 350 ^^;).
- * HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
- */
-/*
- * Very small patch for IBM Ethernet PCMCIA Card II and IBM ThinkPad230Cs.
- * ETO, Toshihisa <eto@osl.fujitsu.co.jp>
- */
-
-/*
- * $FreeBSD$
- */
-
-/* XXX don't mix different PCCARD support code. */
-#include "card.h"
-#include "pcic.h"
-#if NCARD > 0 || NPCIC > 0
-#include "opt_lint.h"
-#ifdef COMPILING_LINT
-static char const zedummy[] = "code to use the includes of card.h and pcic.h";
-#else
-#error "Dedicated PCMCIA drivers and generic PCMCIA support can't be mixed"
-#endif
-#endif
-
-#include "ze.h"
-#if NZE > 0
-#include "opt_inet.h"
-#include "opt_ipx.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/sockio.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/syslog.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <net/bpf.h>
-
-#include <machine/clock.h>
-#include <machine/md_var.h>
-
-#include <i386/isa/isa_device.h>
-#ifndef SMP
-#include <i386/isa/icu.h>
-#endif
-#include <dev/ed/if_edreg.h>
-#include <i386/isa/pcic.h>
-
-#include "apm.h"
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif /* NAPM > 0 */
-
-
-/*****************************************************************************
- * Driver for Ethernet Adapter *
- *****************************************************************************/
-/*
- * ze_softc: per line info and status
- */
-static struct ze_softc {
-
- struct arpcom arpcom; /* ethernet common */
-
- caddr_t maddr;
- u_long iobase, irq;
-
- char *type_str; /* pointer to type string */
- char *mau; /* type of media access unit */
- u_short nic_addr; /* NIC (DS8390) I/O bus address */
-
- caddr_t smem_start; /* shared memory start address */
- caddr_t smem_end; /* shared memory end address */
- u_long smem_size; /* total shared memory size */
- caddr_t smem_ring; /* start of RX ring-buffer (in smem) */
-
- u_char memwidth; /* width of access to card mem 8 or 16 */
- u_char xmit_busy; /* transmitter is busy */
- u_char txb_cnt; /* Number of transmit buffers */
- u_char txb_next; /* Pointer to next buffer ready to xmit */
- u_short txb_next_len; /* next xmit buffer length */
- u_char data_buffered; /* data has been buffered in interface memory */
- u_char tx_page_start; /* first page of TX buffer area */
-
- u_char rec_page_start; /* first page of RX ring-buffer */
- u_char rec_page_stop; /* last page of RX ring-buffer */
- u_char next_packet; /* pointer to next unread RX packet */
- int slot; /* information for reconfiguration */
- u_char last_alive; /* information for reconfiguration */
- u_char last_up; /* information for reconfiguration */
-#if NAPM > 0
- struct apmhook s_hook; /* reconfiguration support */
- struct apmhook r_hook; /* reconfiguration support */
-#endif /* NAPM > 0 */
-} ze_softc[NZE];
-
-static int ze_check_cis __P((unsigned char *scratch));
-static int ze_find_adapter __P((unsigned char *scratch, int reconfig));
-static int ze_probe __P((struct isa_device *isa_dev));
-static void ze_setup __P((struct ze_softc *sc));
-static int ze_suspend __P((void *visa_dev));
-static int ze_resume __P((void *visa_dev));
-static int ze_attach __P((struct isa_device *isa_dev));
-static void ze_reset __P((int unit));
-static void ze_stop __P((int unit));
-static void ze_watchdog __P((struct ifnet *ifp));
-static void ze_init __P((int unit));
-static __inline void ze_xmit __P((struct ifnet *ifp));
-static void ze_start __P((struct ifnet *ifp));
-static __inline void ze_rint __P((int unit));
-static ointhand2_t zeintr;
-static int ze_ioctl __P((struct ifnet *ifp, u_long command, caddr_t data));
-static void ze_get_packet __P((struct ze_softc *sc, char *buf, int len));
-static __inline char *ze_ring_copy __P((struct ze_softc *sc, char *src,
- char *dst, int amount));
-static struct mbuf *ze_ring_to_mbuf __P((struct ze_softc *sc, char *src, struct mbuf *dst, int total_len));
-
-struct isa_driver zedriver = {
- ze_probe,
- ze_attach,
- "ze"
-};
-
-static unsigned char enet_addr[6];
-static unsigned char card_info[256];
-
-#define CARD_INFO "IBM Corp.~Ethernet~0933495"
-
-/*
- * IBM Ethernet PCMCIA Card II returns following info.
- */
-#define CARD2_INFO "IBM Corp.~Ethernet~0934214"
-
-/* */
-
-#define CARD3_INFO "National Semiconductor~InfoMover NE4"
-
-/*
- * scan the card information structure looking for the version/product info
- * tuple. when we find it, compare it to the string we are looking for.
- * return 1 if we find it, 0 otherwise.
- */
-
-static int
-ze_check_cis (unsigned char *scratch)
-{
- int i,j,k;
-
- card_info[0] = '\0';
- i = 0;
- while (scratch[i] != 0xff && i < 1024) {
- unsigned char link = scratch[i+2];
-
-#if 0
- printf ("[%02x] %02x ", i, link);
- for (j = 4; j < 2 * link + 4 && j < 32; j += 2)
- printf ("%02x ", scratch[j + i]);
- printf ("\n");
-#endif
- if (scratch[i] == 0x15) {
- /*
- * level 1 version/product info
- * copy to card_info, translating '\0' to '~'
- */
- k = 0;
- for (j = i+8; scratch[j] != 0xff; j += 2)
- card_info[k++] = scratch[j] == '\0' ? '~' : scratch[j];
- card_info[k++] = '\0';
-#if 0
- return (bcmp (card_info, CARD_INFO, sizeof(CARD_INFO)-1) == 0);
-#else
- if ((bcmp (card_info, CARD_INFO, sizeof(CARD_INFO)-1) == 0) ||
- (bcmp (card_info, CARD2_INFO, sizeof(CARD2_INFO)-1) == 0) ||
- (bcmp (card_info, CARD3_INFO, sizeof(CARD3_INFO)-1) == 0)) {
- return 1;
- }
- return 0;
-#endif
- }
- i += 4 + 2 * link;
- }
- return 0;
-}
-
-/*
- * Probe each slot looking for an IBM Credit Card Adapter for Ethernet
- * For each card that we find, map its card information structure
- * into system memory at 'scratch' and see whether it's one of ours.
- * Return the slot number if we find a card, or -1 otherwise.
- *
- * Side effects:
- * + On success, leaves CIS mapped into memory at 'scratch';
- * caller must free it.
- * + On success, leaves ethernet address in enet_addr.
- * + Leaves product/vendor id of last card probed in 'card_info'
- */
-
-static int prev_slot = 0;
-
-static int
-ze_find_adapter (unsigned char *scratch, int reconfig)
-{
- int slot;
-
- for (slot = prev_slot; slot < MAXSLOT; ++slot) {
- /*
- * see if there's a PCMCIA controller here
- * Intel PCMCIA controllers use 0x82 and 0x83
- * IBM clone chips use 0x88 and 0x89, apparently
- */
- /*
- * IBM ThinkPad230Cs use 0x84.
- */
- unsigned char idbyte = pcic_getb (slot, PCIC_ID_REV);
-
- if (idbyte != 0x82 && idbyte != 0x83 &&
- idbyte != 0x84 && /* for IBM ThinkPad 230Cs */
- idbyte != 0x88 && idbyte != 0x89) {
-#if 0
- printf ("ibmccae: pcic slot %d: wierd id/rev code 0x%02x\n",
- slot, idbyte);
-#endif
- continue;
- }
- if ((pcic_getb (slot, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
- if (!reconfig) {
- printf ("ze: slot %d: no card in slot\n", slot);
- }
- else {
- log (LOG_NOTICE, "ze: slot %d: no card in slot\n", slot);
- }
- /* no card in slot */
- continue;
- }
- pcic_power_on (slot);
- pcic_reset (slot);
- /*
- * map the card's attribute memory and examine its
- * card information structure tuples for something
- * we recognize.
- */
- pcic_map_memory (slot, 0, kvtop (scratch), 0L,
- 0xFFFL, ATTRIBUTE, 1);
-
- if ((ze_check_cis (scratch)) > 0) {
- /* found it */
- if (!reconfig) {
- printf ("ze: found card in slot %d\n", slot);
- }
- else {
- log (LOG_NOTICE, "ze: found card in slot %d\n", slot);
- }
- prev_slot = (prev_slot == MAXSLOT - 1) ? 0 : prev_slot+1;
-
- return slot;
- }
- else {
- if (!reconfig) {
- printf ("ze: pcmcia slot %d: %s\n", slot, card_info);
- }
- else {
- log (LOG_NOTICE, "ze: pcmcia slot %d: %s\n", slot, card_info);
- }
- }
- pcic_unmap_memory (slot, 0);
- }
- prev_slot = 0;
- return -1;
-}
-
-
-/*
- * macros to handle casting unsigned long to (char *) so we can
- * read/write into physical memory space.
- */
-
-#define PEEK(addr) (*((unsigned char *)(addr)))
-#define POKE(addr,val) do { PEEK(addr) = (val); } while (0)
-
-/*
- * Determine if the device is present
- *
- * on entry:
- * a pointer to an isa_device struct
- * on exit:
- * NULL if device not found
- * or # of i/o addresses used (if found)
- pcic(
- */
-static int
-ze_probe(isa_dev)
- struct isa_device *isa_dev;
-{
- struct ze_softc *sc = &ze_softc[isa_dev->id_unit];
- int i;
- u_int memsize;
- u_char tmp;
- int slot;
-
- if ((slot = ze_find_adapter (isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
- return 0;
-
- /*
- * okay, we found a card, so set it up
- */
- /*
- * Inhibit 16 bit memory delay.
- * POINTETH.SYS apparently does this, for what reason I don't know.
- */
- pcic_putb (slot, PCIC_CDGC,
- pcic_getb (slot, PCIC_CDGC) | PCIC_16_DL_INH);
- /*
- * things to map
- * (1) card's EEPROM is already mapped by the find_adapter routine
- * but we still need to get the card's ethernet address.
- * after that we unmap that part of attribute memory.
- * (2) card configuration registers need to be mapped in so we
- * can set the configuration and socket # registers.
- * (3) shared memory packet buffer
- * (4) i/o ports
- * (5) IRQ
- */
- /*
- * Sigh. Location of the ethernet address isn't documented in [1].
- * It was derived by doing a hex dump of all of attribute memory
- * and looking for the IBM vendor prefix.
- */
- enet_addr[0] = PEEK(isa_dev->id_maddr+0xff0);
- enet_addr[1] = PEEK(isa_dev->id_maddr+0xff2);
- enet_addr[2] = PEEK(isa_dev->id_maddr+0xff4);
- enet_addr[3] = PEEK(isa_dev->id_maddr+0xff6);
- enet_addr[4] = PEEK(isa_dev->id_maddr+0xff8);
- enet_addr[5] = PEEK(isa_dev->id_maddr+0xffa);
- pcic_unmap_memory (slot, 0);
-
- sc->maddr = isa_dev->id_maddr;
- sc->irq = isa_dev->id_irq;
- sc->iobase = isa_dev->id_iobase;
- sc->slot = slot;
- /*
- * Setup i/o addresses
- */
- sc->nic_addr = sc->iobase;
- sc->smem_start = (caddr_t)sc->maddr;
-
- ze_setup(sc);
-
- tmp = inb (sc->iobase + ZE_RESET);
- sc->mau = tmp & 0x09 ? "10base2" : "10baseT";
-
- /* set width/size */
- sc->type_str = "IBM PCMCIA";
- memsize = 16*1024;
- sc->memwidth = 16;
-
- /* allocate 1 xmit buffer */
- sc->smem_ring = sc->smem_start + (ED_PAGE_SIZE * ED_TXBUF_SIZE);
- sc->txb_cnt = 1;
- sc->rec_page_start = ED_TXBUF_SIZE + ZE_PAGE_OFFSET;
- sc->smem_size = memsize;
- sc->smem_end = sc->smem_start + memsize;
- sc->rec_page_stop = memsize / ED_PAGE_SIZE + ZE_PAGE_OFFSET;
- sc->tx_page_start = ZE_PAGE_OFFSET;
-
- /* get station address */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- sc->arpcom.ac_enaddr[i] = enet_addr[i];
-
- isa_dev->id_msize = memsize;
-
-
- /* information for reconfiguration */
- sc->last_alive = 0;
- sc->last_up = 0;
-
- return 32;
-}
-
-
-static void
-ze_setup(struct ze_softc *sc)
-{
- int re_init_flag = 0,tmp,slot = sc->slot;
-
-re_init:
- /*
- * (2) map card configuration registers. these are offset
- * in card memory space by 0x20000. normally we could get
- * this offset from the card information structure, but I'm
- * too lazy and am not quite sure if I understand the CIS anyway.
- *
- * XXX IF YOU'RE TRYING TO PORT THIS DRIVER FOR A DIFFERENT
- * PCMCIA CARD, the most likely thing to change is the constant
- * 0x20000 in the next statement. Oh yes, also change the
- * card id string that we probe for.
- */
- pcic_map_memory (slot, 0, kvtop (sc->maddr), 0x20000, 8L,
- ATTRIBUTE, 1);
- POKE(sc->maddr, 0x80); /* reset the card (how long?) */
- DELAY (40000);
- /*
- * Set the configuration index. According to [1], the adapter won't
- * respond to any i/o signals until we do this; it uses the
- * Memory Only interface (whatever that is; it's not documented).
- * Also turn on "level" (not pulse) interrupts.
- *
- * XXX probably should init the socket and copy register also,
- * so that we can deal with multiple instances of the same card.
- */
- POKE(sc->maddr, 0x41);
- pcic_unmap_memory (slot, 0);
-
- /*
- * (3) now map in the shared memory buffer. This has to be mapped
- * as words, not bytes, and on a 16k boundary. The offset value
- * was derived by installing IBM's POINTETH.SYS under DOS and
- * looking at the PCIC registers; it's not documented in IBM's
- * tech ref manual ([1]).
- */
- pcic_map_memory (slot, 0, kvtop (sc->maddr), 0x4000L, 0x4000L,
- COMMON, 2);
-
- /*
- * (4) map i/o ports.
- *
- * XXX is it possible that the config file leaves this unspecified,
- * in which case we have to pick one?
- *
- * At least one PCMCIA device driver I'v seen maps a block
- * of 32 consecutive i/o ports as two windows of 16 ports each.
- * Maybe some other pcic chips are restricted to 16-port windows;
- * the 82365SL doesn't seem to have that problem. But since
- * we have an extra window anyway...
- */
-#ifdef SHARED_MEMORY
- pcic_map_io (slot, 0, sc->iobase, 32, 1);
-#else
- pcic_map_io (slot, 0, sc->iobase, 16, 1);
- pcic_map_io (slot, 1, sc->iobase+16, 16, 2);
-#endif /* SHARED_MEMORY */
-
- /*
- * (5) configure the card for the desired interrupt
- *
- * XXX is it possible that the config file leaves this unspecified?
- */
- pcic_map_irq (slot, ffs (sc->irq) - 1);
-
- /* tell the PCIC that this is an I/O card (not memory) */
- pcic_putb (slot, PCIC_INT_GEN,
- pcic_getb (slot, PCIC_INT_GEN) | PCIC_CARDTYPE);
-
-#if 0
- /* tell the PCIC to use level-mode interrupts */
- /* XXX this register may not be present on all controllers */
- pcic_putb (slot, PCIC_GLO_CTRL,
- pcic_getb (slot, PCIC_GLO_CTRL) | PCIC_LVL_MODE);
-#endif
-
-#if 0
- pcic_print_regs (slot);
-#endif
-
- /* reset card to force it into a known state */
- tmp = inb (sc->iobase + ZE_RESET);
- DELAY(20000);
- outb (sc->iobase + ZE_RESET, tmp);
- DELAY(20000);
-
-#if 0
- tmp = inb(sc->iobase);
- printf("CR = 0x%x\n", tmp);
-#endif
- /*
- * query MAM bit in misc register for 10base2
- */
- tmp = inb (sc->iobase + ZE_MISC);
-
- /*
- * Some Intel-compatible PCICs of Cirrus Logic fails in
- * initializing them. This is a quick hack to fix this
- * problem.
- * HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
- */
- if (!tmp && !re_init_flag) {
- re_init_flag++;
- goto re_init;
- }
-}
-
-#if NAPM > 0
-static int
-ze_suspend(visa_dev)
- void *visa_dev;
-{
- struct isa_device *isa_dev = visa_dev;
- struct ze_softc *sc = &ze_softc[isa_dev->id_unit];
-
- pcic_power_off(sc->slot);
- return 0;
-}
-
-static int
-ze_resume(visa_dev)
- void *visa_dev;
-{
- struct isa_device *isa_dev = visa_dev;
-
-#if 0
- printf("Resume ze:\n");
-#endif
- prev_slot = 0;
- reconfig_isadev(isa_dev, &net_imask);
- return 0;
-}
-#endif /* NAPM > 0 */
-
-/*
- * Install interface into kernel networking data structures
- */
-
-static int
-ze_attach(isa_dev)
- struct isa_device *isa_dev;
-{
- struct ze_softc *sc = &ze_softc[isa_dev->id_unit];
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int pl;
-
- isa_dev->id_ointr = zeintr;
-
- /* PCMCIA card can be offlined. Reconfiguration is required */
- if (isa_dev->id_reconfig) {
- ze_reset(isa_dev->id_unit);
- if (!isa_dev->id_alive && sc->last_alive) {
- pl = splimp();
- sc->last_up = (ifp->if_flags & IFF_UP);
- if_down(ifp);
- splx(pl);
- sc->last_alive = 0;
- }
- if (isa_dev->id_alive && !sc->last_alive) {
- if (sc->last_up) {
- pl = splimp();
- if_up(ifp);
- splx(pl);
- }
- sc->last_alive = 1;
- }
- return 1;
- }
- else {
- sc->last_alive = 1;
- }
-
- /*
- * Set interface to stopped condition (reset)
- */
- ze_stop(isa_dev->id_unit);
-
- /*
- * Initialize ifnet structure
- */
- ifp->if_softc = sc;
- ifp->if_unit = isa_dev->id_unit;
- ifp->if_name = "ze" ;
- ifp->if_mtu = ETHERMTU;
- ifp->if_output = ether_output;
- ifp->if_start = ze_start;
- ifp->if_ioctl = ze_ioctl;
- ifp->if_watchdog = ze_watchdog;
-
- ifp->if_flags = (IFF_BROADCAST | IFF_SIMPLEX);
-
- /*
- * Attach the interface
- */
- if_attach(ifp);
- ether_ifattach(ifp);
-
- /*
- * Print additional info when attached
- */
- printf("ze%d: address %6D, type %s (%dbit), MAU %s\n",
- isa_dev->id_unit,
- sc->arpcom.ac_enaddr, ":", sc->type_str,
- sc->memwidth,
- sc->mau);
-
- /*
- * If BPF is in the kernel, call the attach for it
- */
- bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
-
-#if NAPM > 0
- sc->s_hook.ah_fun = ze_suspend;
- sc->s_hook.ah_arg = (void *)isa_dev;
- sc->s_hook.ah_name = "IBM PCMCIA Ethernet I/II";
- sc->s_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_SUSPEND , &sc->s_hook);
- sc->r_hook.ah_fun = ze_resume;
- sc->r_hook.ah_arg = (void *)isa_dev;
- sc->r_hook.ah_name = "IBM PCMCIA Ethernet I/II";
- sc->r_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_RESUME , &sc->r_hook);
-#endif /* NAPM > 0 */
-
- return 1;
-}
-
-/*
- * Reset interface.
- */
-static void
-ze_reset(unit)
- int unit;
-{
- int s;
-
- s = splnet();
-
- /*
- * Stop interface and re-initialize.
- */
- ze_stop(unit);
- ze_init(unit);
-
- (void) splx(s);
-}
-
-/*
- * Take interface offline.
- */
-static void
-ze_stop(unit)
- int unit;
-{
- struct ze_softc *sc = &ze_softc[unit];
- int n = 5000;
-
- /*
- * Stop everything on the interface, and select page 0 registers.
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|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 (((inb(sc->nic_addr + ED_P0_ISR) & ED_ISR_RST) == 0) && --n);
- pcic_power_off(sc->slot);
-
-}
-
-/*
- * Device timeout/watchdog routine. Entered if the device neglects to
- * generate an interrupt after a transmit has been started on it.
- */
-static void
-ze_watchdog(ifp)
- struct ifnet *ifp;
-{
-#if 1
- struct ze_softc *sc = (struct ze_softc *)ifp;
- u_char isr, imr;
-#ifndef SMP
- u_int imask;
-#endif
-
- if(!(ifp->if_flags & IFF_UP))
- return;
- /* select page zero */
- outb (sc->nic_addr + ED_P0_CR,
- (inb (sc->nic_addr + ED_P0_CR) & 0x3f) | ED_CR_PAGE_0);
-
- /* read interrupt status register */
- isr = inb (sc->nic_addr + ED_P0_ISR) & 0xff;
-
- /* select page two */
- outb (sc->nic_addr + ED_P0_CR,
- (inb (sc->nic_addr + ED_P0_CR) & 0x3f) | ED_CR_PAGE_2);
-
- /* read interrupt mask register */
- imr = inb (sc->nic_addr + ED_P2_IMR) & 0xff;
-#ifdef SMP
- /* INTRGET() is NOT MP_SAFE, forgo printing it for now... */
- log (LOG_ERR, "ze%d: device timeout, isr=%02x, imr=%02x\n",
- ifp->if_unit, isr, imr);
-#else
- imask = INTRGET();
-
- log (LOG_ERR, "ze%d: device timeout, isr=%02x, imr=%02x, imask=%04x\n",
- ifp->if_unit, isr, imr, imask);
-#endif /* SMP */
-#else
- log(LOG_ERR, "ze%d: device timeout\n", ifp->if_unit);
-#endif
-
- ze_reset(ifp->if_unit);
-}
-
-/*
- * Initialize device.
- */
-static void
-ze_init(unit)
- int unit;
-{
- struct ze_softc *sc = &ze_softc[unit];
- struct ifnet *ifp = &sc->arpcom.ac_if;
- int i, s;
-
-
- pcic_power_on(sc->slot);
- pcic_reset(sc->slot);
- if(!(sc->arpcom.ac_if.if_flags & IFF_UP))
- Debugger("here!!");
- ze_setup(sc);
- /* address not known */
- if (TAILQ_EMPTY(&ifp->if_addrhead)) return; /* XXX unlikely! */
-
- /*
- * Initialize the NIC in the exact order outlined in the NS manual.
- * This init procedure is "mandatory"...don't change what or when
- * things happen.
- */
- s = splnet();
-
- /* reset transmitter flags */
- sc->data_buffered = 0;
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_timer = 0;
-
- sc->txb_next = 0;
-
- /* This variable is used below - don't move this assignment */
- sc->next_packet = sc->rec_page_start + 1;
-
- /*
- * Set interface for page 0, Remote DMA complete, Stopped
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STP);
-
- if (sc->memwidth == 16) {
- /*
- * Set FIFO threshold to 8, No auto-init Remote DMA,
- * byte order=80x86, word-wide DMA xfers
- */
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1|ED_DCR_WTS);
- } else {
- /*
- * Same as above, but byte-wide DMA xfers
- */
- outb(sc->nic_addr + ED_P0_DCR, ED_DCR_FT1);
- }
-
- /*
- * Clear Remote Byte Count Registers
- */
- outb(sc->nic_addr + ED_P0_RBCR0, 0);
- outb(sc->nic_addr + ED_P0_RBCR1, 0);
-
- /*
- * Enable reception of broadcast packets
- */
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
-
- /*
- * Place NIC in internal loopback mode
- */
- outb(sc->nic_addr + ED_P0_TCR, ED_TCR_LB0);
-
- /*
- * Initialize transmit/receive (ring-buffer) Page Start
- */
- outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start);
- outb(sc->nic_addr + ED_P0_PSTART, sc->rec_page_start);
-
- /*
- * Initialize Receiver (ring-buffer) Page Stop and Boundry
- */
- outb(sc->nic_addr + ED_P0_PSTOP, sc->rec_page_stop);
- outb(sc->nic_addr + ED_P0_BNRY, sc->rec_page_start);
-
- /*
- * Clear all interrupts. A '1' in each bit position clears the
- * corresponding flag.
- */
- outb(sc->nic_addr + ED_P0_ISR, 0xff);
-
- /*
- * Enable the following interrupts: receive/transmit complete,
- * receive/transmit error, and Receiver OverWrite.
- *
- * Counter overflow and Remote DMA complete are *not* enabled.
- */
- outb(sc->nic_addr + ED_P0_IMR,
- ED_IMR_PRXE|ED_IMR_PTXE|ED_IMR_RXEE|ED_IMR_TXEE|ED_IMR_OVWE);
-
- /*
- * Program Command Register for page 1
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STP);
-
- /*
- * Copy out our station address
- */
- for (i = 0; i < ETHER_ADDR_LEN; ++i)
- outb(sc->nic_addr + ED_P1_PAR0 + i, sc->arpcom.ac_enaddr[i]);
-
- /*
- * Initialize multicast address hashing registers to accept
- * all multicasts (only used when in promiscuous mode)
- */
- for (i = 0; i < 8; ++i)
- outb(sc->nic_addr + ED_P1_MAR0 + i, 0xff);
-
- /*
- * Set Current Page pointer to next_packet (initialized above)
- */
- outb(sc->nic_addr + ED_P1_CURR, sc->next_packet);
-
- /*
- * Set Command Register for page 0, Remote DMA complete,
- * and interface Start.
- */
- outb(sc->nic_addr + ED_P1_CR, ED_CR_RD2|ED_CR_STA);
-
- /*
- * Take interface out of loopback
- */
- outb(sc->nic_addr + ED_P0_TCR, 0);
-
- /*
- * Set 'running' flag, and clear output active flag.
- */
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE;
-
- /*
- * ...and attempt to start output
- */
- ze_start(ifp);
-
- (void) splx(s);
-}
-
-/*
- * This routine actually starts the transmission on the interface
- */
-static __inline void
-ze_xmit(ifp)
- struct ifnet *ifp;
-{
- struct ze_softc *sc = ifp->if_softc;
- u_short len = sc->txb_next_len;
-
- /*
- * Set NIC for page 0 register access
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
-
- /*
- * Set TX buffer start page
- */
- outb(sc->nic_addr + ED_P0_TPSR, sc->tx_page_start +
- sc->txb_next * ED_TXBUF_SIZE);
-
- /*
- * Set TX length
- */
- outb(sc->nic_addr + ED_P0_TBCR0, len & 0xff);
- outb(sc->nic_addr + ED_P0_TBCR1, len >> 8);
-
- /*
- * Set page 0, Remote DMA complete, Transmit Packet, and *Start*
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_TXP|ED_CR_STA);
-
- sc->xmit_busy = 1;
- sc->data_buffered = 0;
-
- /*
- * Switch buffers if we are doing double-buffered transmits
- */
- if ((sc->txb_next == 0) && (sc->txb_cnt > 1))
- sc->txb_next = 1;
- else
- sc->txb_next = 0;
-
- /*
- * Set a timer just in case we never hear from the board again
- */
- ifp->if_timer = 2;
-}
-
-/*
- * Start output on interface.
- * We make two assumptions here:
- * 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)
- */
-static void
-ze_start(ifp)
- struct ifnet *ifp;
-{
- struct ze_softc *sc = ifp->if_softc;
- struct mbuf *m0, *m;
- caddr_t buffer;
- int len;
-
-outloop:
- /*
- * See if there is room to send more data (i.e. one or both of the
- * buffers is empty).
- */
- if (sc->data_buffered) {
- if (sc->xmit_busy) {
- /*
- * No room. Indicate this to the outside world
- * and exit.
- */
- ifp->if_flags |= IFF_OACTIVE;
- return;
- } else {
- /*
- * Data is buffered, but we're not transmitting, so
- * start the xmit on the buffered data.
- * Note that ze_xmit() resets the data_buffered flag
- * before returning.
- */
- ze_xmit(ifp);
- }
- }
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
- if (m == NULL) {
- /*
- * The following isn't pretty; we are using the !OACTIVE flag to
- * indicate to the outside world that we can accept an additional
- * packet rather than that the transmitter is _actually_
- * active. Indeed, the transmitter may be active, but if we haven't
- * filled the secondary buffer with data then we still want to
- * accept more.
- * Note that it isn't necessary to test the data_buffered flag -
- * we wouldn't have tried to de-queue the packet in the first place
- * if it was set.
- */
- ifp->if_flags &= ~IFF_OACTIVE;
- return;
- }
-
- /*
- * Copy the mbuf chain into the transmit buffer
- */
-
- buffer = sc->smem_start + (sc->txb_next * ED_TXBUF_SIZE * ED_PAGE_SIZE);
- len = 0;
- for (m0 = m; m != 0; m = m->m_next) {
- bcopy(mtod(m, caddr_t), buffer, m->m_len);
- buffer += m->m_len;
- len += m->m_len;
- }
-
- sc->txb_next_len = max(len, ETHER_MIN_LEN);
-
- if (sc->txb_cnt > 1)
- /*
- * only set 'buffered' flag if doing multiple buffers
- */
- sc->data_buffered = 1;
-
- if (sc->xmit_busy == 0)
- ze_xmit(ifp);
- /*
- * If there is BPF support in the configuration, tap off here.
- */
- if (ifp->if_bpf) {
- bpf_mtap(ifp, m0);
- }
-
- m_freem(m0);
-
- /*
- * If we are doing double-buffering, a buffer might be free to
- * fill with another packet, so loop back to the top.
- */
- if (sc->txb_cnt > 1)
- goto outloop;
- else {
- ifp->if_flags |= IFF_OACTIVE;
- return;
- }
-}
-
-/*
- * Ethernet interface receiver interrupt.
- */
-static __inline void /* only called from one place, so may as well inline */
-ze_rint(unit)
- int unit;
-{
- register struct ze_softc *sc = &ze_softc[unit];
- u_char boundry;
- u_short len;
- struct ed_ring *packet_ptr;
-
- /*
- * Set NIC to page 1 registers to get 'current' pointer
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
-
- /*
- * 'sc->next_packet' is the logical beginning of the ring-buffer - i.e.
- * it points to where new data has been buffered. The 'CURR'
- * (current) register points to the logical end of the ring-buffer
- * - i.e. it points to where additional new data will be added.
- * We loop here until the logical beginning equals the logical
- * end (or in other words, until the ring-buffer is empty).
- */
- while (sc->next_packet != inb(sc->nic_addr + ED_P1_CURR)) {
-
- /* get pointer to this buffer header structure */
- packet_ptr = (struct ed_ring *)(sc->smem_ring +
- (sc->next_packet - sc->rec_page_start) * ED_PAGE_SIZE);
-
- /*
- * The byte count includes the FCS - Frame Check Sequence (a
- * 32 bit CRC).
- */
- len = packet_ptr->count;
- if ((len >= ETHER_MIN_LEN) && (len <= ETHER_MAX_LEN)) {
- /*
- * Go get packet. len - 4 removes CRC from length.
- * (packet_ptr + 1) points to data just after the packet ring
- * header (+4 bytes)
- */
- ze_get_packet(sc, (caddr_t)(packet_ptr + 1), len - 4);
- ++sc->arpcom.ac_if.if_ipackets;
- } else {
- /*
- * Really BAD...probably indicates that the ring pointers
- * are corrupted. Also seen on early rev chips under
- * high load - the byte order of the length gets switched.
- */
- log(LOG_ERR,
- "ze%d: shared memory corrupt - invalid packet length %d\n",
- unit, len);
- ze_reset(unit);
- return;
- }
-
- /*
- * Update next packet pointer
- */
- sc->next_packet = packet_ptr->next_packet;
-
- /*
- * Update NIC boundry pointer - being careful to keep it
- * one buffer behind. (as recommended by NS databook)
- */
- boundry = sc->next_packet - 1;
- if (boundry < sc->rec_page_start)
- boundry = sc->rec_page_stop - 1;
-
- /*
- * Set NIC to page 0 registers to update boundry register
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
-
- outb(sc->nic_addr + ED_P0_BNRY, boundry);
-
- /*
- * Set NIC to page 1 registers before looping to top (prepare to
- * get 'CURR' current pointer)
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_PAGE_1|ED_CR_RD2|ED_CR_STA);
- }
-}
-
-/*
- * Ethernet interface interrupt processor
- */
-static void
-zeintr(unit)
- int unit;
-{
- struct ze_softc *sc = &ze_softc[unit];
- u_char isr;
-
- if(!(sc->arpcom.ac_if.if_flags & IFF_UP))
- return;
- /*
- * Set NIC to page 0 registers
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
-
- /*
- * loop until there are no more new interrupts
- */
- while ((isr = inb(sc->nic_addr + ED_P0_ISR)) != 0) {
-
- /*
- * reset all the bits that we are 'acknowleging'
- * by writing a '1' to each bit position that was set
- * (writing a '1' *clears* the bit)
- */
- outb(sc->nic_addr + ED_P0_ISR, isr);
-
- /*
- * Transmit error. If a TX completed with an error, we end up
- * throwing the packet away. Really the only error that is
- * possible is excessive collisions, and in this case it is
- * best to allow the automatic mechanisms of TCP to backoff
- * the flow. Of course, with UDP we're screwed, but this is
- * expected when a network is heavily loaded.
- */
- if (isr & ED_ISR_TXE) {
- u_char tsr = inb(sc->nic_addr + ED_P0_TSR);
- u_char ncr = inb(sc->nic_addr + ED_P0_NCR);
-
- /*
- * Excessive collisions (16)
- */
- if ((tsr & ED_TSR_ABT) && (ncr == 0)) {
- /*
- * When collisions total 16, the P0_NCR will
- * indicate 0, and the TSR_ABT is set.
- */
- sc->arpcom.ac_if.if_collisions += 16;
- } else
- sc->arpcom.ac_if.if_collisions += ncr;
-
- /*
- * update output errors counter
- */
- ++sc->arpcom.ac_if.if_oerrors;
-
- /*
- * reset tx busy and output active flags
- */
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-
- /*
- * clear watchdog timer
- */
- sc->arpcom.ac_if.if_timer = 0;
- }
-
-
- /*
- * Receiver Error. One or more of: CRC error, frame alignment error
- * FIFO overrun, or missed packet.
- */
- if (isr & ED_ISR_RXE) {
- ++sc->arpcom.ac_if.if_ierrors;
-#ifdef ZE_DEBUG
- printf("ze%d: receive error %b\n", unit,
- inb(sc->nic_addr + ED_P0_RSR),
- "\20\8DEF\7REC DISAB\6PHY/MC\5MISSED\4OVR\3ALIGN\2FCS\1RCVD");
-#endif
- }
-
- /*
- * Overwrite warning. In order to make sure that a lockup
- * of the local DMA hasn't occurred, we reset and
- * re-init the NIC. The NSC manual suggests only a
- * partial reset/re-init is necessary - but some
- * chips seem to want more. The DMA lockup has been
- * seen only with early rev chips - Methinks this
- * bug was fixed in later revs. -DG
- */
- if (isr & ED_ISR_OVW) {
- ++sc->arpcom.ac_if.if_ierrors;
- /*
- * Stop/reset/re-init NIC
- */
- ze_reset(unit);
- }
-
- /*
- * Transmission completed normally.
- */
- if (isr & ED_ISR_PTX) {
-
- /*
- * reset tx busy and output active flags
- */
- sc->xmit_busy = 0;
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
-
- /*
- * clear watchdog timer
- */
- sc->arpcom.ac_if.if_timer = 0;
-
- /*
- * Update total number of successfully transmitted
- * packets.
- */
- ++sc->arpcom.ac_if.if_opackets;
-
- /*
- * Add in total number of collisions on last
- * transmission.
- */
- sc->arpcom.ac_if.if_collisions += inb(sc->nic_addr +
- ED_P0_TBCR0);
- }
-
- /*
- * Receive Completion. Go and get the packet.
- * XXX - Doing this on an error is dubious because there
- * shouldn't be any data to get (we've configured the
- * interface to not accept packets with errors).
- */
- if (isr & (ED_ISR_PRX|ED_ISR_RXE)) {
- ze_rint (unit);
- }
-
- /*
- * If it looks like the transmitter can take more data,
- * attempt to start output on the interface. If data is
- * already buffered and ready to go, send it first.
- */
- if ((sc->arpcom.ac_if.if_flags & IFF_OACTIVE) == 0) {
- if (sc->data_buffered)
- ze_xmit(&sc->arpcom.ac_if);
- ze_start(&sc->arpcom.ac_if);
- }
-
- /*
- * return NIC CR to standard state: page 0, remote DMA complete,
- * start (toggling the TXP bit off, even if was just set
- * in the transmit routine, is *okay* - it is 'edge'
- * triggered from low to high)
- */
- outb(sc->nic_addr + ED_P0_CR, ED_CR_RD2|ED_CR_STA);
-
- /*
- * If the Network Talley Counters overflow, read them to
- * reset them. It appears that old 8390's won't
- * clear the ISR flag otherwise - resulting in an
- * infinite loop.
- */
- if (isr & ED_ISR_CNT) {
- (void) inb(sc->nic_addr + ED_P0_CNTR0);
- (void) inb(sc->nic_addr + ED_P0_CNTR1);
- (void) inb(sc->nic_addr + ED_P0_CNTR2);
- }
- }
-}
-
-/*
- * Process an ioctl request. This code needs some work - it looks
- * pretty ugly.
- */
-static int
-ze_ioctl(ifp, command, data)
- register struct ifnet *ifp;
- u_long command;
- caddr_t data;
-{
- struct ze_softc *sc = ifp->if_softc;
- int s, error = 0;
-
- s = splnet();
-
- switch (command) {
- case SIOCSIFADDR:
- case SIOCGIFADDR:
- case SIOCSIFMTU:
- error = ether_ioctl(ifp, command, data);
- break;
-
- case SIOCSIFFLAGS:
- /*
- * When the card is offlined, `up' operation can't be permitted
- */
- if (!sc->last_alive) {
- int tmp;
- tmp = (ifp->if_flags & IFF_UP);
- if (!sc->last_up && (ifp->if_flags & IFF_UP)) {
- ifp->if_flags &= ~(IFF_UP);
- }
- sc->last_up = tmp;
- }
- /*
- * If interface is marked down and it is running, then stop it
- */
- if (((ifp->if_flags & IFF_UP) == 0) &&
- (ifp->if_flags & IFF_RUNNING)) {
- ze_stop(ifp->if_unit);
- ifp->if_flags &= ~IFF_RUNNING;
- } else {
- /*
- * If interface is marked up and it is stopped, then start it
- */
- if ((ifp->if_flags & IFF_UP) &&
- ((ifp->if_flags & IFF_RUNNING) == 0))
- ze_init(ifp->if_unit);
- }
- if (ifp->if_flags & IFF_PROMISC) {
- /*
- * Set promiscuous mode on interface.
- * XXX - for multicasts to work, we would need to
- * write 1's in all bits of multicast
- * hashing array. For now we assume that
- * this was done in ze_init().
- */
- outb(sc->nic_addr + ED_P0_RCR,
- ED_RCR_PRO|ED_RCR_AM|ED_RCR_AB);
- } else {
- /*
- * XXX - for multicasts to work, we would need to
- * rewrite the multicast hashing array with the
- * proper hash (would have been destroyed above).
- */
- outb(sc->nic_addr + ED_P0_RCR, ED_RCR_AB);
- }
- break;
-
- default:
- error = EINVAL;
- }
- (void) splx(s);
- return (error);
-}
-
-/*
- * Macro to calculate a new address within shared memory when given an offset
- * from an address, taking into account ring-wrap.
- */
-#define ringoffset(sc, start, off, type) \
- ((type)( ((caddr_t)(start)+(off) >= (sc)->smem_end) ? \
- (((caddr_t)(start)+(off))) - (sc)->smem_end \
- + (sc)->smem_ring: \
- ((caddr_t)(start)+(off)) ))
-
-/*
- * Retreive packet from shared memory and send to the next level up via
- * ether_input(). If there is a BPF listener, give a copy to BPF, too.
- */
-static void
-ze_get_packet(sc, buf, len)
- struct ze_softc *sc;
- char *buf;
- u_short len;
-{
- struct ether_header *eh;
- struct mbuf *m, *head = NULL;
-
- /* Allocate a header mbuf */
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- goto bad;
- m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- m->m_pkthdr.len = len;
- m->m_len = 0;
- head = m;
-
- eh = (struct ether_header *)buf;
-
- /* The following sillines is to make NFS happy */
-#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
-#define EOFF (EROUND - sizeof(struct ether_header))
-
- /*
- * The following assumes there is room for
- * the ether header in the header mbuf
- */
- head->m_data += EOFF;
- bcopy(buf, mtod(head, caddr_t), sizeof(struct ether_header));
- buf += sizeof(struct ether_header);
- head->m_len += sizeof(struct ether_header);
- len -= sizeof(struct ether_header);
-
- /*
- * Pull packet off interface. Or if this was a trailer packet,
- * the data portion is appended.
- */
- m = ze_ring_to_mbuf(sc, buf, m, len);
- if (m == NULL) goto bad;
-
- /*
- * Check if there's a BPF listener on this interface.
- * If so, hand off the raw packet to bpf.
- */
- if (sc->arpcom.ac_if.if_bpf) {
- bpf_mtap(&sc->arpcom.ac_if, head);
-
- /*
- * Note that the interface cannot be in promiscuous mode if
- * there are no BPF listeners. And if we are in promiscuous
- * mode, we have to check if this packet is really ours.
- *
- * XXX This test does not support multicasts.
- */
- if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
- bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
- sizeof(eh->ether_dhost)) != 0 &&
- bcmp(eh->ether_dhost, etherbroadcastaddr,
- sizeof(eh->ether_dhost)) != 0) {
-
- m_freem(head);
- return;
- }
- }
-
- /*
- * Fix up data start offset in mbuf to point past ether header
- */
- m_adj(head, sizeof(struct ether_header));
-
- ether_input(&sc->arpcom.ac_if, eh, head);
- return;
-
-bad: if (head)
- m_freem(head);
- return;
-}
-
-/*
- * Supporting routines
- */
-
-/*
- * 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 char *
-ze_ring_copy(sc,src,dst,amount)
- struct ze_softc *sc;
- char *src;
- char *dst;
- u_short amount;
-{
- u_short tmp_amount;
-
- /* does copy wrap to lower addr in ring buffer? */
- if (src + amount > sc->smem_end) {
- tmp_amount = sc->smem_end - src;
- bcopy(src,dst,tmp_amount); /* copy amount up to end of smem */
- amount -= tmp_amount;
- src = sc->smem_ring;
- dst += tmp_amount;
- }
-
- bcopy(src, dst, amount);
-
- return(src + amount);
-}
-
-/*
- * Copy data from receive buffer to end of mbuf chain
- * allocate additional mbufs as needed. return pointer
- * to last mbuf in chain.
- * sc = ze info (softc)
- * src = pointer in ze ring buffer
- * dst = pointer to last mbuf in mbuf chain to copy to
- * amount = amount of data to copy
- */
-static struct mbuf *
-ze_ring_to_mbuf(sc,src,dst,total_len)
- struct ze_softc *sc;
- char *src;
- struct mbuf *dst;
- u_short total_len;
-{
- register struct mbuf *m = dst;
-
- while (total_len) {
- register u_short amount = min(total_len, M_TRAILINGSPACE(m));
-
- if (amount == 0) { /* no more data in this mbuf, alloc another */
- /*
- * If there is enough data for an mbuf cluster, attempt
- * to allocate one of those, otherwise, a regular
- * mbuf will do.
- * Note that a regular mbuf is always required, even if
- * we get a cluster - getting a cluster does not
- * allocate any mbufs, and one is needed to assign
- * the cluster to. The mbuf that has a cluster
- * extension can not be used to contain data - only
- * the cluster can contain data.
- */
- dst = m;
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- return (0);
-
- if (total_len >= MINCLSIZE)
- MCLGET(m, M_DONTWAIT);
-
- m->m_len = 0;
- dst->m_next = m;
- amount = min(total_len, M_TRAILINGSPACE(m));
- }
-
- src = ze_ring_copy(sc, src, mtod(m, caddr_t) + m->m_len, amount);
-
- m->m_len += amount;
- total_len -= amount;
-
- }
- return (m);
-}
-#endif
-
diff --git a/sys/i386/isa/if_zp.c b/sys/i386/isa/if_zp.c
deleted file mode 100644
index 4de0ea1..0000000
--- a/sys/i386/isa/if_zp.c
+++ /dev/null
@@ -1,1118 +0,0 @@
-/*
- * This code is based on
- * (1) FreeBSD implementation on ISA/EISA Ethelink III by Herb Peyerl
- * (2) Linux implementation on PCMCIA Etherlink III by David Hinds
- * (3) FreeBSD implementation on PCMCIA IBM Ethernet Card I/II
- * by David Greenman
- * (4) RT-Mach implementation on PCMCIA/ISA/EISA Etherlink III
- * by Seiji Murata
- *
- * Copyright (c) by HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
- * Copyright (c) by Seiji Murata <seiji@mt.cs.keio.ac.jp>
- */
-/*
- * Copyright (c) 1993 Herb Peyerl <hpeyerl@novatel.ca>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software 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.
- *
- * From: if_ep.c,v 1.9 1994/01/25 10:46:29 deraadt Exp $
- * $FreeBSD$
- */
-/*-
- * TODO:
- * [1] integrate into current if_ed.c
- * [2] parse tuples to find out where to map the shared memory buffer,
- * and what to write into the configuration register
- * [3] move pcic-specific code into a separate module.
- *
- * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
- * if_ze.c
- *
- * Based on the Device driver for National Semiconductor DS8390 ethernet
- * adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
- * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
- *
- * Currently supports only the IBM Credit Card Adapter for Ethernet, but
- * could probably work with other PCMCIA cards also, if it were modified
- * to get the locations of the PCMCIA configuration option register (COR)
- * by parsing the configuration tuples, rather than by hard-coding in
- * the value expected by IBM's card.
- *
- * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
- *
- * [1] _Local Area Network Credit Card Adapters Technical Reference_,
- * IBM Corp., SC30-3585-00, part # 33G9243.
- * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
- * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
- * Order Number 290423-002
- * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
- * Interface Controller for Twisted Pair data sheet.
- *
- *
- * 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.
- */
-/*======================================================================
-
- A PCMCIA ethernet driver for the 3com 3c589 card.
-
- Written by David Hinds, dhinds@allegro.stanford.edu
-
- The network driver code is based on Donald Becker's 3c589 code:
-
- Written 1994 by Donald Becker.
- Copyright 1993 United States Government as represented by the
- Director, National Security Agency. This software may be used and
- distributed according to the terms of the GNU Public License,
- incorporated herein by reference.
- Donald Becker may be reached at becker@cesdis1.gsfc.nasa.gov
-
-======================================================================*/
-/*
- * I doubled delay loops in this file because it is not enough for some
- * laptop machines' PCIC (especially, on my Chaplet ILFA 350 ^^;).
- * HOSOKAWA, Tatsumi <hosokawa@mt.cs.keio.ac.jp>
- */
-/*
- * Very small patch for IBM Ethernet PCMCIA Card II and IBM ThinkPad230Cs.
- * ETO, Toshihisa <eto@osl.fujitsu.co.jp>
- */
-
-/* XXX don't mix different PCCARD support code. */
-#include "card.h"
-#include "pcic.h"
-#if NCARD > 0 || NPCIC > 0
-#include "opt_lint.h"
-#ifdef COMPILING_LINT
-static char const zpdummy[] = "code to use the includes of card.h and pcic.h";
-#else
-#error "Dedicated PCMCIA drivers and generic PCMCIA support can't be mixed"
-#endif
-#endif
-
-#include "zp.h"
-
-#include "opt_inet.h"
-#include "opt_ipx.h"
-
-#include <sys/param.h>
-#if defined(__FreeBSD__)
-#include <sys/systm.h>
-#include <sys/conf.h>
-#endif
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/sockio.h>
-#include <sys/syslog.h>
-
-#include <net/ethernet.h>
-#include <net/if.h>
-
-#include <netinet/in.h>
-#include <netinet/if_ether.h>
-
-#include <net/bpf.h>
-
-#include <machine/clock.h>
-#include <machine/md_var.h>
-
-#include <i386/isa/isa_device.h>
-#include <i386/isa/if_zpreg.h>
-#include <i386/isa/pcic.h>
-
-#include "apm.h"
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif /* NAPM > 0 */
-
-
-/*****************************************************************************
- * Driver for Ethernet Adapter *
- *****************************************************************************/
-/*
- * zp_softc: per line info and status
- */
-static struct zp_softc {
- struct arpcom arpcom; /* Ethernet common part */
-#define MAX_MBS 8 /* # of mbufs we keep around */
- struct mbuf *mb[MAX_MBS]; /* spare mbuf storage. */
- int next_mb; /* Which mbuf to use next. */
- int last_mb; /* Last mbuf. */
- int ep_io_addr; /* i/o bus address */
- char ep_connectors; /* Connectors on this card. */
- int tx_start_thresh;/* Current TX_start_thresh. */
- char bus32bit; /* 32bit access possible */
- u_short if_port;
- u_char last_alive; /* information for reconfiguration */
- u_char last_up; /* information for reconfiguration */
- int slot; /* PCMCIA slot */
- struct callout_handle ch; /* Callout handle for timeouts */
- int buffill_pending;
-#if NAPM > 0
- struct apmhook s_hook; /* reconfiguration support */
- struct apmhook r_hook; /* reconfiguration support */
-#endif /* NAPM > 0 */
-} zp_softc[NZP];
-
-static int zpprobe __P((struct isa_device *));
-static int zpattach __P((struct isa_device *));
-static int zp_suspend __P((void *visa_dev));
-static int zp_resume __P((void *visa_dev));
-static int zpioctl __P((struct ifnet * ifp, u_long, caddr_t));
-static u_short read_eeprom_data __P((int, int));
-
-static void zpinit __P((int));
-static ointhand2_t zpintr;
-static void zpmbuffill __P((void *));
-static void zpmbufempty __P((struct zp_softc *));
-static void zpread __P((struct zp_softc *));
-static void zpreset __P((int));
-static void zpstart __P((struct ifnet *));
-static void zpstop __P((int));
-static void zpwatchdog __P((struct ifnet *));
-
-struct isa_driver zpdriver = {
- zpprobe,
- zpattach,
- "zp"
-};
-#define CARD_INFO "3Com Corporation~3C589"
-
-static unsigned char card_info[256];
-
-/*
- * scan the card information structure looking for the version/product info
- * tuple. when we find it, compare it to the string we are looking for.
- * return 1 if we find it, 0 otherwise.
- */
-
-static int
-zp_check_cis(unsigned char *scratch)
-{
- int i, j, k;
-
- card_info[0] = '\0';
- i = 0;
- while (scratch[i] != 0xff && i < 1024) {
- unsigned char link = scratch[i + 2];
-
- if (scratch[i] == 0x15) {
- /* level 1 version/product info copy to card_info,
- * translating '\0' to '~' */
- k = 0;
- for (j = i + 8; scratch[j] != 0xff; j += 2)
- card_info[k++] = scratch[j] == '\0' ? '~' : scratch[j];
- card_info[k++] = '\0';
- return (bcmp(card_info, CARD_INFO, sizeof(CARD_INFO) - 1) == 0);
- }
- i += 4 + 2 * link;
- }
- return 0;
-}
-/*
- * Probe each slot looking for an IBM Credit Card Adapter for Ethernet
- * For each card that we find, map its card information structure
- * into system memory at 'scratch' and see whether it's one of ours.
- * Return the slot number if we find a card, or -1 otherwise.
- *
- * Side effects:
- * + On success, leaves CIS mapped into memory at 'scratch';
- * caller must free it.
- * + On success, leaves ethernet address in enet_addr.
- * + Leaves product/vendor id of last card probed in 'card_info'
- */
-
-static int prev_slot = 0;
-
-static int
-zp_find_adapter(unsigned char *scratch, int reconfig)
-{
- int slot;
-
- for (slot = prev_slot; slot < MAXSLOT; ++slot) {
- /* see if there's a PCMCIA controller here Intel PCMCIA
- * controllers use 0x82 and 0x83 IBM clone chips use 0x88 and
- * 0x89, apparently */
- /* IBM ThinkPad230Cs use 0x84. */
- unsigned char idbyte = pcic_getb(slot, PCIC_ID_REV);
-
- if (idbyte != 0x82 && idbyte != 0x83 &&
- idbyte != 0x84 && /* for IBM ThinkPad 230Cs */
- idbyte != 0x88 && idbyte != 0x89) {
- continue;
- }
- if ((pcic_getb(slot, PCIC_STATUS) & PCIC_CD) != PCIC_CD) {
- if (!reconfig) {
- printf("zp: slot %d: no card in slot\n", slot);
- } else {
- log(LOG_NOTICE, "zp: slot %d: no card in slot\n", slot);
- }
- /* no card in slot */
- continue;
- }
- pcic_power_on(slot);
- pcic_reset(slot);
- DELAY(50000);
- /* map the card's attribute memory and examine its card
- * information structure tuples for something we recognize. */
- pcic_map_memory(slot, 0, kvtop(scratch), 0L,
- 0xFFFL, ATTRIBUTE, 1);
-
- if ((zp_check_cis(scratch)) > 0) {
- /* found it */
- if (!reconfig) {
- printf("zp: found card in slot %d\n", slot);
- } else {
- log(LOG_NOTICE, "zp: found card in slot %d\n", slot);
- }
- prev_slot = (prev_slot == MAXSLOT - 1) ? 0 : prev_slot + 1;
-
- return slot;
- } else {
- if (!reconfig) {
- printf("zp: pcmcia slot %d: %s\n", slot, card_info);
- } else {
- log(LOG_NOTICE, "zp: pcmcia slot %d: %s\n", slot, card_info);
- }
- }
- pcic_unmap_memory(slot, 0);
- }
- prev_slot = 0;
- return -1;
-}
-
-
-/*
- * macros to handle casting unsigned long to (char *) so we can
- * read/write into physical memory space.
- */
-
-#define PEEK(addr) (*((unsigned char *)(addr)))
-#define POKE(addr,val) do { PEEK(addr) = (val); } while (0)
-
-/*
- * Determine if the device is present
- *
- * on entry:
- * a pointer to an isa_device struct
- * on exit:
- * NULL if device not found
- * or # of i/o addresses used (if found)
- */
-static int
-zpprobe(struct isa_device * isa_dev)
-{
- struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
- int slot;
- u_short k;
- int re_init_flag;
-
- if ((slot = zp_find_adapter(isa_dev->id_maddr, isa_dev->id_reconfig)) < 0)
- return 0;
-
- /* okay, we found a card, so set it up */
- /* Inhibit 16 bit memory delay. POINTETH.SYS apparently does this, for
- * what reason I don't know. */
- pcic_putb(slot, PCIC_CDGC,
- pcic_getb(slot, PCIC_CDGC) | PCIC_16_DL_INH);
- /* things to map (1) card's EEPROM is already mapped by the
- * find_adapter routine but we still need to get the card's ethernet
- * address. after that we unmap that part of attribute memory. (2)
- * card configuration registers need to be mapped in so we can set the
- * configuration and socket # registers. (3) shared memory packet
- * buffer (4) i/o ports (5) IRQ */
-#ifdef notdef
- /* Sigh. Location of the ethernet address isn't documented in [1]. It
- * was derived by doing a hex dump of all of attribute memory and
- * looking for the IBM vendor prefix. */
- enet_addr[0] = PEEK(isa_dev->id_maddr + 0xff0);
- enet_addr[1] = PEEK(isa_dev->id_maddr + 0xff2);
- enet_addr[2] = PEEK(isa_dev->id_maddr + 0xff4);
- enet_addr[3] = PEEK(isa_dev->id_maddr + 0xff6);
- enet_addr[4] = PEEK(isa_dev->id_maddr + 0xff8);
- enet_addr[5] = PEEK(isa_dev->id_maddr + 0xffa);
-#endif
- re_init_flag = 0;
-re_init:
- /* (2) map card configuration registers. these are offset in card
- * memory space by 0x20000. normally we could get this offset from
- * the card information structure, but I'm too lazy and am not quite
- * sure if I understand the CIS anyway.
- *
- * XXX IF YOU'RE TRYING TO PORT THIS DRIVER FOR A DIFFERENT PCMCIA CARD,
- * the most likely thing to change is the constant 0x20000 in the next
- * statement. Oh yes, also change the card id string that we probe
- * for. */
- pcic_map_memory(slot, 0, kvtop(isa_dev->id_maddr), 0x10000, 8L,
- ATTRIBUTE, 1);
-#if OLD_3C589B_CARDS
- POKE(isa_dev->id_maddr, 0x80); /* reset the card (how long?) */
- DELAY(40000);
-#endif
- /* Set the configuration index. According to [1], the adapter won't
- * respond to any i/o signals until we do this; it uses the Memory
- * Only interface (whatever that is; it's not documented). Also turn
- * on "level" (not pulse) interrupts.
- *
- * XXX probably should init the socket and copy register also, so that we
- * can deal with multiple instances of the same card. */
- POKE(isa_dev->id_maddr, 0x41);
- pcic_unmap_memory(slot, 0);
-
- /* (4) map i/o ports.
- *
- * XXX is it possible that the config file leaves this unspecified, in
- * which case we have to pick one?
- *
- * At least one PCMCIA device driver I'v seen maps a block of 32
- * consecutive i/o ports as two windows of 16 ports each. Maybe some
- * other pcic chips are restricted to 16-port windows; the 82365SL
- * doesn't seem to have that problem. But since we have an extra
- * window anyway... */
- pcic_map_io(slot, 0, isa_dev->id_iobase, 16, 2);
-
- /* (5) configure the card for the desired interrupt
- *
- * XXX is it possible that the config file leaves this unspecified? */
- pcic_map_irq(slot, ffs(isa_dev->id_irq) - 1);
-
- /* tell the PCIC that this is an I/O card (not memory) */
- pcic_putb(slot, PCIC_INT_GEN,
- pcic_getb(slot, PCIC_INT_GEN) | PCIC_CARDTYPE);
-
- sc->ep_io_addr = isa_dev->id_iobase;
- GO_WINDOW(0);
- k = read_eeprom_data(BASE, EEPROM_ADDR_CFG); /* get addr cfg */
- sc->if_port = k >> 14;
- k = (k & 0x1f) * 0x10 + 0x200; /* decode base addr. */
- if (k != (u_short) isa_dev->id_iobase) {
- if (!re_init_flag) {
- re_init_flag++;
- goto re_init;
- }
- return (0);
- }
- k = read_eeprom_data(BASE, EEPROM_RESOURCE_CFG);
-
- k >>= 12;
-
- if (isa_dev->id_irq != (1 << ((k == 2) ? 9 : k)))
- return (0);
-
- outb(BASE, ACTIVATE_ADAPTER_TO_CONFIG);
-
-
- /* information for reconfiguration */
- sc->last_alive = 0;
- sc->last_up = 0;
- sc->slot = slot;
-
- return (0x10); /* 16 bytes of I/O space used. */
-}
-#if NAPM > 0
-static int
-zp_suspend(visa_dev)
- void *visa_dev;
-{
-#if 0
- struct isa_device *isa_dev = visa_dev;
- struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
-
- pcic_power_off(sc->slot);
-#endif
- return 0;
-}
-
-static int
-zp_resume(visa_dev)
- void *visa_dev;
-{
- struct isa_device *isa_dev = visa_dev;
-
- prev_slot = 0;
- reconfig_isadev(isa_dev, &net_imask);
- return 0;
-}
-#endif /* NAPM > 0 */
-
-
-/*
- * Install interface into kernel networking data structures
- */
-
-static int
-zpattach(isa_dev)
- struct isa_device *isa_dev;
-{
- struct zp_softc *sc = &zp_softc[isa_dev->id_unit];
- struct ifnet *ifp = &sc->arpcom.ac_if;
- u_short i;
- int pl;
-
- isa_dev->id_ointr = zpintr;
-
- /* PCMCIA card can be offlined. Reconfiguration is required */
- if (isa_dev->id_reconfig) {
- if (!isa_dev->id_alive && sc->last_alive) {
- pl = splimp();
- sc->last_up = (ifp->if_flags & IFF_UP);
- if_down(ifp);
- splx(pl);
- sc->last_alive = 0;
- }
- if (isa_dev->id_alive && !sc->last_alive) {
- zpreset(isa_dev->id_unit);
- if (sc->last_up) {
- pl = splimp();
- if_up(ifp);
- splx(pl);
- }
- sc->last_alive = 1;
- }
- return 1;
- } else {
- sc->last_alive = 1;
- }
-
-
- sc->ep_io_addr = isa_dev->id_iobase;
- printf("zp%d: ", isa_dev->id_unit);
-
- sc->buffill_pending = 0;
- callout_handle_init(&sc->ch);
-
- sc->ep_connectors = 0;
-
- i = inw(isa_dev->id_iobase + EP_W0_CONFIG_CTRL);
-
- if (i & IS_AUI) {
- printf("aui");
- sc->ep_connectors |= AUI;
- }
- if (i & IS_BNC) {
- if (sc->ep_connectors)
- printf("/");
- printf("bnc");
- sc->ep_connectors |= BNC;
- }
- if (i & IS_UTP) {
- if (sc->ep_connectors)
- printf("/");
- printf("utp");
- sc->ep_connectors |= UTP;
- }
- if (!sc->ep_connectors)
- printf("no connectors!");
-
- GO_WINDOW(0);
- {
- short tmp_addr[3];
- int j;
- for (j = 0; j < 3; j++) {
- tmp_addr[j] = htons(read_eeprom_data(BASE, j));
- }
- bcopy(tmp_addr, sc->arpcom.ac_enaddr, 6);
- }
-
- printf(" address %6D\n", sc->arpcom.ac_enaddr, ":");
-
- sc->arpcom.ac_if.if_snd.ifq_maxlen = ifqmaxlen;
- ifp->if_softc = sc;
- ifp->if_mtu = ETHERMTU;
- ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
- ifp->if_unit = isa_dev->id_unit;
- ifp->if_name = "zp";
- ifp->if_output = ether_output;
- ifp->if_start = zpstart;
- ifp->if_ioctl = zpioctl;
- ifp->if_watchdog = zpwatchdog;
- /* Select connector according to board setting. */
- ifp->if_flags |= IFF_LINK0;
-
- if_attach(ifp);
- ether_ifattach(ifp);
-
- bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
-#if NAPM > 0
- sc->s_hook.ah_fun = zp_suspend;
- sc->s_hook.ah_arg = (void *) isa_dev;
- sc->s_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
- sc->s_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_SUSPEND, &sc->s_hook);
- sc->r_hook.ah_fun = zp_resume;
- sc->r_hook.ah_arg = (void *) isa_dev;
- sc->r_hook.ah_name = "3Com PCMCIA Etherlink III 3C589";
- sc->r_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_RESUME, &sc->r_hook);
-#endif /* NAPM > 0 */
- return 1;
-}
-/*
- * The order in here seems important. Otherwise we may not receive
- * interrupts. ?!
- */
-static void
-zpinit(unit)
- int unit;
-{
- register struct zp_softc *sc = &zp_softc[unit];
- register struct ifnet *ifp = &sc->arpcom.ac_if;
- int s, i;
-
- if (TAILQ_EMPTY(&ifp->if_addrhead)) /* XXX unlikely */
- return;
-
- s = splimp();
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
-
- GO_WINDOW(0);
-
- /* Disable the card */
- outw(BASE + EP_W0_CONFIG_CTRL, 0);
-
- /* Enable the card */
- outw(BASE + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
-
- GO_WINDOW(2);
-
- /* Reload the ether_addr. */
- for (i = 0; i < 6; i++)
- outb(BASE + EP_W2_ADDR_0 + i, sc->arpcom.ac_enaddr[i]);
-
- outw(BASE + EP_COMMAND, RX_RESET);
- outw(BASE + EP_COMMAND, TX_RESET);
-
- /* Window 1 is operating window */
- GO_WINDOW(1);
- for (i = 0; i < 31; i++)
- inb(BASE + EP_W1_TX_STATUS);
-
- /* get rid of stray intr's */
- outw(BASE + EP_COMMAND, ACK_INTR | 0xff);
-
- outw(BASE + EP_COMMAND, SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
- S_TX_COMPLETE | S_TX_AVAIL);
- outw(BASE + EP_COMMAND, SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
- S_TX_COMPLETE | S_TX_AVAIL);
-
-#ifndef IFF_MULTICAST
-#define IFF_MULTICAST 0x10000
-#endif
-
- outw(BASE + EP_COMMAND, SET_RX_FILTER | FIL_INDIVIDUAL |
- ((sc->arpcom.ac_if.if_flags & IFF_MULTICAST) ? FIL_GROUP : 0) |
- FIL_BRDCST |
- ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) ? FIL_ALL : 0));
- /* you can `ifconfig (link0|-link0) ep0' to get the following
- * behaviour: -link0 disable AUI/UTP. enable BNC. link0 disable
- * BNC. enable AUI. if the card has a UTP connector, that is enabled
- * too. not sure, but it seems you have to be careful to not plug
- * things into both AUI & UTP. */
-
- if (!(ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & BNC)) {
- GO_WINDOW(0);
- /* set the xcvr */
- outw(BASE + EP_W0_ADDRESS_CFG, 3 << 14);
- GO_WINDOW(2);
- outw(BASE + EP_COMMAND, START_TRANSCEIVER);
- GO_WINDOW(1);
- }
-#if defined(__NetBSD__) || defined(__FreeBSD__)
- if ((ifp->if_flags & IFF_LINK0) && (sc->ep_connectors & UTP)) {
-#else
- if ((ifp->if_flags & IFF_ALTPHYS) && (sc->ep_connectors & UTP)) {
-#endif
- GO_WINDOW(4);
- outw(BASE + EP_W4_MEDIA_TYPE, ENABLE_UTP);
- GO_WINDOW(1);
- }
- outw(BASE + EP_COMMAND, RX_ENABLE);
- outw(BASE + EP_COMMAND, TX_ENABLE);
-
- ifp->if_flags |= IFF_RUNNING;
- ifp->if_flags &= ~IFF_OACTIVE; /* just in case */
- sc->tx_start_thresh = 20; /* probably a good starting point. */
- /* Store up a bunch of mbuf's for use later. (MAX_MBS). First we free
- * up any that we had in case we're being called from intr or
- * somewhere else. */
- sc->last_mb = 0;
- sc->next_mb = 0;
- if (sc->buffill_pending != 0) {
- untimeout(zpmbuffill, sc, sc->ch);
- sc->buffill_pending = 0;
- }
- zpmbuffill(sc);
- zpstart(ifp);
- splx(s);
-}
-
-static const char padmap[] = {0, 3, 2, 1};
-static void
-zpstart(ifp)
- struct ifnet *ifp;
-{
- register struct zp_softc *sc = ifp->if_softc;
- struct mbuf *m, *top;
-
- int s, len, pad;
-
- s = splimp();
-
- if (sc->arpcom.ac_if.if_flags & IFF_OACTIVE) {
- splx(s);
- return;
- }
-startagain:
-
- /* Sneak a peek at the next packet */
- m = sc->arpcom.ac_if.if_snd.ifq_head;
- if (m == 0) {
- splx(s);
- return;
- }
- for (len = 0, top = m; m; m = m->m_next)
- len += m->m_len;
-
- pad = padmap[len & 3];
-
- /* The 3c509 automatically pads short packets to minimum ethernet
- * length, but we drop packets that are too large. Perhaps we should
- * truncate them instead? */
- if (len + pad > ETHER_MAX_LEN) {
- /* packet is obviously too large: toss it */
- ++sc->arpcom.ac_if.if_oerrors;
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
- m_freem(m);
- goto readcheck;
- }
- if (inw(BASE + EP_W1_FREE_TX) < len + pad + 4) {
- /* no room in FIFO */
- outw(BASE + EP_COMMAND, SET_TX_AVAIL_THRESH | (len + pad + 4));
- sc->arpcom.ac_if.if_flags |= IFF_OACTIVE;
- splx(s);
-
- return;
- }
- IF_DEQUEUE(&sc->arpcom.ac_if.if_snd, m);
-
- if (m == 0) { /* not really needed */
- splx(s);
- return;
- }
- outw(BASE + EP_COMMAND, SET_TX_START_THRESH |
- (len / 4 + sc->tx_start_thresh));
-
- outw(BASE + EP_W1_TX_PIO_WR_1, len);
- outw(BASE + EP_W1_TX_PIO_WR_1, 0xffff); /* Second dword meaningless */
-
- for (top = m; m != 0; m = m->m_next) {
- if (sc->bus32bit) {
- outsl(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t),
- m->m_len / 4);
- if (m->m_len & 3)
- outsb(BASE + EP_W1_TX_PIO_WR_1,
- mtod(m, caddr_t) + (m->m_len & (~3)),
- m->m_len & 3);
- } else {
- outsw(BASE + EP_W1_TX_PIO_WR_1, mtod(m, caddr_t), m->m_len / 2);
- if (m->m_len & 1)
- outb(BASE + EP_W1_TX_PIO_WR_1,
- *(mtod(m, caddr_t) + m->m_len - 1));
- }
- }
- while (pad--)
- outb(BASE + EP_W1_TX_PIO_WR_1, 0); /* Padding */
-
- if (sc->arpcom.ac_if.if_bpf) {
- bpf_mtap(&sc->arpcom.ac_if, top);
- }
-
- m_freem(top);
- ++sc->arpcom.ac_if.if_opackets;
- /* Is another packet coming in? We don't want to overflow the tiny RX
- * fifo. */
-readcheck:
- if (inw(BASE + EP_W1_RX_STATUS) & RX_BYTES_MASK) {
- splx(s);
- return;
- }
- goto startagain;
-}
-static void
-zpintr(unit)
- int unit;
-{
- int status, i;
- register struct zp_softc *sc = &zp_softc[unit];
-
- struct ifnet *ifp = &sc->arpcom.ac_if;
-
-
- status = 0;
-checkintr:
- status = inw(BASE + EP_STATUS) &
- (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE | S_CARD_FAILURE);
-checkintr2:
- if (status == 0) {
- /* No interrupts. */
- outw(BASE + EP_COMMAND, C_INTR_LATCH);
-
- status = inw(BASE + EP_STATUS) &
- (S_TX_COMPLETE | S_TX_AVAIL | S_RX_COMPLETE |
- S_CARD_FAILURE);
- if (status)
- goto checkintr2;
-
- return;
- }
- /* important that we do this first. */
- outw(BASE + EP_COMMAND, ACK_INTR | status);
-
- if (status & S_TX_AVAIL) {
- status &= ~S_TX_AVAIL;
- inw(BASE + EP_W1_FREE_TX);
- sc->arpcom.ac_if.if_flags &= ~IFF_OACTIVE;
- zpstart(&sc->arpcom.ac_if);
-
- }
- if (status & S_RX_COMPLETE) {
- status &= ~S_RX_COMPLETE;
- zpread(sc);
- }
- if (status & S_CARD_FAILURE) {
- printf("zp%d: reset (status: %x)\n", unit, status);
- outw(BASE + EP_COMMAND, C_INTR_LATCH);
- zpinit(unit);
- return;
- }
- if (status & S_TX_COMPLETE) {
- status &= ~S_TX_COMPLETE;
- /* We need to read TX_STATUS until we get a 0 status in order
- * to turn off the interrupt flag. */
- while ((i = inb(BASE + EP_W1_TX_STATUS)) & TXS_COMPLETE) {
- outw(BASE + EP_W1_TX_STATUS, 0x0);
- if (i & (TXS_MAX_COLLISION | TXS_JABBER | TXS_UNDERRUN)) {
- if (i & TXS_MAX_COLLISION)
- ++sc->arpcom.ac_if.if_collisions;
- if (i & (TXS_JABBER | TXS_UNDERRUN)) {
- outw(BASE + EP_COMMAND, TX_RESET);
- if (i & TXS_UNDERRUN) {
- if (sc->tx_start_thresh < ETHER_MAX_LEN) {
- sc->tx_start_thresh += 20;
- outw(BASE + EP_COMMAND,
- SET_TX_START_THRESH |
- sc->tx_start_thresh);
- }
- }
- }
- outw(BASE + EP_COMMAND, TX_ENABLE);
- ++sc->arpcom.ac_if.if_oerrors;
- }
- }
- zpstart(ifp);
- }
- goto checkintr;
-}
-
-static void
-zpread(sc)
- register struct zp_softc *sc;
-{
- struct ether_header *eh;
- struct mbuf *mcur, *m, *m0, *top;
- int totlen, lenthisone;
- int save_totlen;
- int off;
-
-
- totlen = inw(BASE + EP_W1_RX_STATUS);
- off = 0;
- top = 0;
-
- if (totlen & ERR_RX) {
- ++sc->arpcom.ac_if.if_ierrors;
- goto out;
- }
- save_totlen = totlen &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */
-
- m = sc->mb[sc->next_mb];
- sc->mb[sc->next_mb] = 0;
-
- if (m == 0) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
- goto out;
- } else {
- /* Convert one of our saved mbuf's */
- sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
- m->m_data = m->m_pktdat;
- m->m_flags = M_PKTHDR;
- }
-
- top = m0 = m; /* We assign top so we can "goto out" */
-#define EROUND ((sizeof(struct ether_header) + 3) & ~3)
-#define EOFF (EROUND - sizeof(struct ether_header))
- m0->m_data += EOFF;
- /* Read what should be the header. */
- insw(BASE + EP_W1_RX_PIO_RD_1,
- mtod(m0, caddr_t), sizeof(struct ether_header) / 2);
- m->m_len = sizeof(struct ether_header);
- totlen -= sizeof(struct ether_header);
- /* mostly deal with trailer here. (untested) We do this in a couple
- * of parts. First we check for a trailer, if we have one we convert
- * the mbuf back to a regular mbuf and set the offset and subtract
- * sizeof(struct ether_header) from the pktlen. After we've read the
- * packet off the interface (all except for the trailer header, we
- * then get a header mbuf, read the trailer into it, and fix up the
- * mbuf pointer chain. */
- eh = mtod(m, struct ether_header *);
- while (totlen > 0) {
- lenthisone = min(totlen, M_TRAILINGSPACE(m));
- if (lenthisone == 0) { /* no room in this one */
- mcur = m;
- m = sc->mb[sc->next_mb];
- sc->mb[sc->next_mb] = 0;
- if (!m) {
- MGET(m, M_DONTWAIT, MT_DATA);
- if (m == 0)
- goto out;
- } else if (sc->buffill_pending == 0) {
- sc->ch = timeout(zpmbuffill, sc, 0);
- sc->buffill_pending = 1;
- sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
- }
- if (totlen >= MINCLSIZE)
- MCLGET(m, M_DONTWAIT);
- m->m_len = 0;
- mcur->m_next = m;
- lenthisone = min(totlen, M_TRAILINGSPACE(m));
- }
- if (sc->bus32bit) {
- insl(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
- lenthisone / 4);
- m->m_len += (lenthisone & ~3);
- if (lenthisone & 3)
- insb(BASE + EP_W1_RX_PIO_RD_1,
- mtod(m, caddr_t) + m->m_len,
- lenthisone & 3);
- m->m_len += (lenthisone & 3);
- } else {
- insw(BASE + EP_W1_RX_PIO_RD_1, mtod(m, caddr_t) + m->m_len,
- lenthisone / 2);
- m->m_len += lenthisone;
- if (lenthisone & 1)
- *(mtod(m, caddr_t) + m->m_len - 1) = inb(BASE + EP_W1_RX_PIO_RD_1);
- }
- totlen -= lenthisone;
- }
- if (off) {
- top = sc->mb[sc->next_mb];
- sc->mb[sc->next_mb] = 0;
- if (top == 0) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (top == 0) {
- top = m0;
- goto out;
- }
- } else {
- /* Convert one of our saved mbuf's */
- sc->next_mb = (sc->next_mb + 1) % MAX_MBS;
- top->m_data = top->m_pktdat;
- top->m_flags = M_PKTHDR;
- }
- insw(BASE + EP_W1_RX_PIO_RD_1, mtod(top, caddr_t),
- sizeof(struct ether_header));
- top->m_next = m0;
- top->m_len = sizeof(struct ether_header);
- /* XXX Accomodate for type and len from beginning of trailer */
- top->m_pkthdr.len = save_totlen - (2 * sizeof(u_short));
- } else {
- top = m0;
- top->m_pkthdr.len = save_totlen;
- }
-
- top->m_pkthdr.rcvif = &sc->arpcom.ac_if;
- outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
- ++sc->arpcom.ac_if.if_ipackets;
- if (sc->arpcom.ac_if.if_bpf) {
- bpf_mtap(&sc->arpcom.ac_if, top);
-
- /* Note that the interface cannot be in promiscuous mode if
- * there are no BPF listeners. And if we are in promiscuous
- * mode, we have to check if this packet is really ours. */
- if ((sc->arpcom.ac_if.if_flags & IFF_PROMISC) &&
- (eh->ether_dhost[0] & 1) == 0 &&
- bcmp(eh->ether_dhost, sc->arpcom.ac_enaddr,
- sizeof(eh->ether_dhost)) != 0 &&
- bcmp(eh->ether_dhost, etherbroadcastaddr,
- sizeof(eh->ether_dhost)) != 0) {
- m_freem(top);
- return;
- }
- }
- m_adj(top, sizeof(struct ether_header));
- ether_input(&sc->arpcom.ac_if, eh, top);
- return;
-
-out: outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
- if (top)
- m_freem(top);
-
-}
-
-
-/*
- * Look familiar?
- */
-static int
-zpioctl(ifp, cmd, data)
- register struct ifnet *ifp;
- u_long cmd;
- caddr_t data;
-{
- struct zp_softc *sc = ifp->if_softc;
- int error = 0;
-
-
- switch (cmd) {
- case SIOCSIFADDR:
- case SIOCGIFADDR:
- case SIOCSIFMTU:
- error = ether_ioctl(ifp, cmd, data);
- break;
-
- case SIOCSIFFLAGS:
- if ((ifp->if_flags & IFF_UP) == 0 && ifp->if_flags & IFF_RUNNING) {
- ifp->if_flags &= ~IFF_RUNNING;
- zpstop(ifp->if_unit);
- zpmbufempty(sc);
- break;
- }
- zpinit(ifp->if_unit);
- break;
- default:
- error = EINVAL;
- }
- return (error);
-}
-
-static void
-zpreset(unit)
- int unit;
-{
- int s = splimp();
-
- zpstop(unit);
- zpinit(unit);
- splx(s);
-}
-
-static void
-zpwatchdog(ifp)
- struct ifnet *ifp;
-{
- log(LOG_ERR, "zp%d: watchdog\n", ifp->if_unit);
- ifp->if_oerrors++;
- zpreset(ifp->if_unit);
-}
-
-static void
-zpstop(unit)
- int unit;
-{
- struct zp_softc *sc = &zp_softc[unit];
-
- outw(BASE + EP_COMMAND, RX_DISABLE);
- outw(BASE + EP_COMMAND, RX_DISCARD_TOP_PACK);
- while (inw(BASE + EP_STATUS) & S_COMMAND_IN_PROGRESS);
- outw(BASE + EP_COMMAND, TX_DISABLE);
- outw(BASE + EP_COMMAND, STOP_TRANSCEIVER);
- outw(BASE + EP_COMMAND, RX_RESET);
- outw(BASE + EP_COMMAND, TX_RESET);
- outw(BASE + EP_COMMAND, C_INTR_LATCH);
- outw(BASE + EP_COMMAND, SET_RD_0_MASK);
- outw(BASE + EP_COMMAND, SET_INTR_MASK);
- outw(BASE + EP_COMMAND, SET_RX_FILTER);
-}
-
-
-
-static u_short
-read_eeprom_data(id_port, offset)
- int id_port;
- int offset;
-{
-
- outb(id_port + 10, 0x80 + offset);
- DELAY(1000);
- return inw(id_port + 12);
-}
-
-
-
-
-static void
-zpmbuffill(sp)
- void *sp;
-{
- struct zp_softc *sc = (struct zp_softc *) sp;
- int s, i;
-
- s = splimp();
- i = sc->last_mb;
- do {
- if (sc->mb[i] == NULL)
- MGET(sc->mb[i], M_DONTWAIT, MT_DATA);
- if (sc->mb[i] == NULL)
- break;
- i = (i + 1) % MAX_MBS;
- } while (i != sc->next_mb);
- sc->buffill_pending = 0;
- sc->last_mb = i;
- splx(s);
-}
-
-static void
-zpmbufempty(sc)
- struct zp_softc *sc;
-{
- int s, i;
-
- s = splimp();
- for (i = 0; i < MAX_MBS; i++) {
- if (sc->mb[i]) {
- m_freem(sc->mb[i]);
- sc->mb[i] = NULL;
- }
- }
- sc->last_mb = sc->next_mb = 0;
- if (sc->buffill_pending != 0) {
- untimeout(zpmbuffill, sc, sc->ch);
- sc->buffill_pending = 0;
- }
- splx(s);
-}
diff --git a/sys/i386/isa/if_zpreg.h b/sys/i386/isa/if_zpreg.h
deleted file mode 100644
index b9848f7..0000000
--- a/sys/i386/isa/if_zpreg.h
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- * derived from this software 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.
- *
- * $FreeBSD$
- */
-/**************************************************************************
- * *
- * These define the EEPROM data structure. They are used in the probe
- * function to verify the existence of the adapter after having sent
- * the ID_Sequence.
- *
- * There are others but only the ones we use are defined here.
- *
- **************************************************************************/
-
-#define EEPROM_NODE_ADDR_0 0x0 /* Word */
-#define EEPROM_NODE_ADDR_1 0x1 /* Word */
-#define EEPROM_NODE_ADDR_2 0x2 /* Word */
-#define EEPROM_PROD_ID 0x3 /* 0x9[0-f]50 */
-#define EEPROM_MFG_ID 0x7 /* 0x6d50 */
-#define EEPROM_ADDR_CFG 0x8 /* Base addr */
-#define EEPROM_RESOURCE_CFG 0x9 /* IRQ. Bits 12-15 */
-
-/**************************************************************************
- * *
- * These are the registers for the 3Com 3c509 and their bit patterns when *
- * applicable. They have been taken out the the "EtherLink III Parallel *
- * Tasking EISA and ISA Technical Reference" "Beta Draft 10/30/92" manual *
- * from 3com. *
- * *
- **************************************************************************/
-
-#define EP_COMMAND 0x0e /* Write. BASE+0x0e is always a command reg. */
-#define EP_STATUS 0x0e /* Read. BASE+0x0e is always status reg. */
-#define EP_WINDOW 0x0f /* Read. BASE+0x0f is always window reg. */
-/*
- * Window 0 registers. Setup.
- */
- /* Write */
-#define EP_W0_EEPROM_DATA 0x0c
-#define EP_W0_EEPROM_COMMAND 0x0a
-#define EP_W0_RESOURCE_CFG 0x08
-#define EP_W0_ADDRESS_CFG 0x06
-#define EP_W0_CONFIG_CTRL 0x04
- /* Read */
-#define EP_W0_PRODUCT_ID 0x02
-#define EP_W0_MFG_ID 0x00
-
-/*
- * Window 1 registers. Operating Set.
- */
- /* Write */
-#define EP_W1_TX_PIO_WR_2 0x02
-#define EP_W1_TX_PIO_WR_1 0x00
- /* Read */
-#define EP_W1_FREE_TX 0x0c
-#define EP_W1_TX_STATUS 0x0b /* byte */
-#define EP_W1_TIMER 0x0a /* byte */
-#define EP_W1_RX_STATUS 0x08
-#define EP_W1_RX_PIO_RD_2 0x02
-#define EP_W1_RX_PIO_RD_1 0x00
-
-/*
- * Window 2 registers. Station Address Setup/Read
- */
- /* Read/Write */
-#define EP_W2_ADDR_5 0x05
-#define EP_W2_ADDR_4 0x04
-#define EP_W2_ADDR_3 0x03
-#define EP_W2_ADDR_2 0x02
-#define EP_W2_ADDR_1 0x01
-#define EP_W2_ADDR_0 0x00
-
-/*
- * Window 3 registers. FIFO Management.
- */
- /* Read */
-#define EP_W3_FREE_TX 0x0c
-#define EP_W3_FREE_RX 0x0a
-
-/*
- * Window 4 registers. Diagnostics.
- */
- /* Read/Write */
-#define EP_W4_MEDIA_TYPE 0x0a
-#define EP_W4_CTRLR_STATUS 0x08
-#define EP_W4_NET_DIAG 0x06
-#define EP_W4_FIFO_DIAG 0x04
-#define EP_W4_HOST_DIAG 0x02
-#define EP_W4_TX_DIAG 0x00
-
-/*
- * Window 5 Registers. Results and Internal status.
- */
- /* Read */
-#define EP_W5_READ_0_MASK 0x0c
-#define EP_W5_INTR_MASK 0x0a
-#define EP_W5_RX_FILTER 0x08
-#define EP_W5_RX_EARLY_THRESH 0x06
-#define EP_W5_TX_AVAIL_THRESH 0x02
-#define EP_W5_TX_START_THRESH 0x00
-
-/*
- * Window 6 registers. Statistics.
- */
- /* Read/Write */
-#define TX_TOTAL_OK 0x0c
-#define RX_TOTAL_OK 0x0a
-#define TX_DEFERRALS 0x08
-#define RX_FRAMES_OK 0x07
-#define TX_FRAMES_OK 0x06
-#define RX_OVERRUNS 0x05
-#define TX_COLLISIONS 0x04
-#define TX_AFTER_1_COLLISION 0x03
-#define TX_AFTER_X_COLLISIONS 0x02
-#define TX_NO_SQE 0x01
-#define TX_CD_LOST 0x00
-
-/****************************************
- *
- * Register definitions.
- *
- ****************************************/
-
-/*
- * Command register. All windows.
- *
- * 16 bit register.
- * 15-11: 5-bit code for command to be executed.
- * 10-0: 11-bit arg if any. For commands with no args;
- * this can be set to anything.
- */
-#define GLOBAL_RESET (u_short) 0x0000 /* Wait at least 1ms after issuing */
-#define WINDOW_SELECT (u_short) (0x1<<11)
-#define START_TRANSCEIVER (u_short) (0x2<<11) /* Read ADDR_CFG reg to determine
- whether this is needed. If so;
- wait 800 uSec before using trans-
- ceiver. */
-#define RX_DISABLE (u_short) (0x3<<11) /* state disabled on power-up */
-#define RX_ENABLE (u_short) (0x4<<11)
-#define RX_RESET (u_short) (0x5<<11)
-#define RX_DISCARD_TOP_PACK (u_short) (0x8<<11)
-#define TX_ENABLE (u_short) (0x9<<11)
-#define TX_DISABLE (u_short) (0xa<<11)
-#define TX_RESET (u_short) (0xb<<11)
-#define REQ_INTR (u_short) (0xc<<11)
- /*
- * The following C_* acknowledge the various interrupts.
- * Some of them don't do anything. See the manual.
- */
-#define ACK_INTR (u_short) (0x6800)
-# define C_INTR_LATCH (u_short) (ACK_INTR|0x1)
-# define C_CARD_FAILURE (u_short) (ACK_INTR|0x2)
-# define C_TX_COMPLETE (u_short) (ACK_INTR|0x4)
-# define C_TX_AVAIL (u_short) (ACK_INTR|0x8)
-# define C_RX_COMPLETE (u_short) (ACK_INTR|0x10)
-# define C_RX_EARLY (u_short) (ACK_INTR|0x20)
-# define C_INT_RQD (u_short) (ACK_INTR|0x40)
-# define C_UPD_STATS (u_short) (ACK_INTR|0x80)
-#define SET_INTR_MASK (u_short) (0xe<<11)
-#define SET_RD_0_MASK (u_short) (0xf<<11)
-#define SET_RX_FILTER (u_short) (0x10<<11)
-# define FIL_INDIVIDUAL (u_short) (0x1)
-# define FIL_GROUP (u_short) (0x2)
-# define FIL_BRDCST (u_short) (0x4)
-# define FIL_ALL (u_short) (0x8)
-#define SET_RX_EARLY_THRESH (u_short) (0x11<<11)
-#define SET_TX_AVAIL_THRESH (u_short) (0x12<<11)
-#define SET_TX_START_THRESH (u_short) (0x13<<11)
-#define STATS_ENABLE (u_short) (0x15<<11)
-#define STATS_DISABLE (u_short) (0x16<<11)
-#define STOP_TRANSCEIVER (u_short) (0x17<<11)
-
-/*
- * Status register. All windows.
- *
- * 15-13: Window number(0-7).
- * 12: Command_in_progress.
- * 11: reserved.
- * 10: reserved.
- * 9: reserved.
- * 8: reserved.
- * 7: Update Statistics.
- * 6: Interrupt Requested.
- * 5: RX Early.
- * 4: RX Complete.
- * 3: TX Available.
- * 2: TX Complete.
- * 1: Adapter Failure.
- * 0: Interrupt Latch.
- */
-#define S_INTR_LATCH (u_short) (0x1)
-#define S_CARD_FAILURE (u_short) (0x2)
-#define S_TX_COMPLETE (u_short) (0x4)
-#define S_TX_AVAIL (u_short) (0x8)
-#define S_RX_COMPLETE (u_short) (0x10)
-#define S_RX_EARLY (u_short) (0x20)
-#define S_INT_RQD (u_short) (0x40)
-#define S_UPD_STATS (u_short) (0x80)
-#define S_COMMAND_IN_PROGRESS (u_short) (0x1000)
-
-/*
- * FIFO Registers. RX Status.
- *
- * 15: Incomplete or FIFO empty.
- * 14: 1: Error in RX Packet 0: Incomplete or no error.
- * 13-11: Type of error.
- * 1000 = Overrun.
- * 1011 = Run Packet Error.
- * 1100 = Alignment Error.
- * 1101 = CRC Error.
- * 1001 = Oversize Packet Error (>1514 bytes)
- * 0010 = Dribble Bits.
- * (all other error codes, no errors.)
- *
- * 10-0: RX Bytes (0-1514)
- */
-#define ERR_INCOMPLETE (u_short) (0x8000)
-#define ERR_RX (u_short) (0x4000)
-#define ERR_RX_PACKET (u_short) (0x2000)
-#define ERR_OVERRUN (u_short) (0x1000)
-#define ERR_RUNT (u_short) (0x1300)
-#define ERR_ALIGNMENT (u_short) (0x1400)
-#define ERR_CRC (u_short) (0x1500)
-#define ERR_OVERSIZE (u_short) (0x1100)
-#define ERR_DRIBBLE (u_short) (0x200)
-
-/*
- * TX Status
- *
- * Reports the transmit status of a completed transmission. Writing this
- * register pops the transmit completion stack.
- *
- * Window 1/Port 0x0b.
- *
- * 7: Complete
- * 6: Interrupt on successful transmission requested.
- * 5: Jabber Error (TP Only, TX Reset required. )
- * 4: Underrun (TX Reset required. )
- * 3: Maximum Collisions.
- * 2: TX Status Overflow.
- * 1-0: Undefined.
- *
- */
-#define TXS_COMPLETE 0x80
-#define TXS_INTR_REQ 0x40
-#define TXS_JABBER 0x20
-#define TXS_UNDERRUN 0x10
-#define TXS_MAX_COLLISION 0x8
-#define TXS_STATUS_OVERFLOW 0x4
-
-/*
- * Misc defines for various things.
- */
-#define TAG_ADAPTER_0 0xd0
-#define ACTIVATE_ADAPTER_TO_CONFIG 0xff
-#define ENABLE_DRQ_IRQ 0x0001
-#define MFG_ID 0x6d50
-#define PROD_ID 0x9150
-#define BASE sc->ep_io_addr
-#define GO_WINDOW(x) outw(BASE+EP_COMMAND, WINDOW_SELECT|x)
-#define AUI 0x1
-#define BNC 0x2
-#define UTP 0x4
-#define IS_AUI (1<<13)
-#define IS_BNC (1<<12)
-#define IS_UTP (1<<9)
-#define EEPROM_BUSY (1<<15)
-#define EEPROM_TST_MODE (1<<14)
-#define READ_EEPROM (1<<7)
-#define ENABLE_UTP 0xc0
-#define DISABLE_UTP 0x0
-#define RX_BYTES_MASK (u_short) (0x07ff)
diff --git a/sys/i386/isa/isa_compat.h b/sys/i386/isa/isa_compat.h
index 5196d24..9185b138 100644
--- a/sys/i386/isa/isa_compat.h
+++ b/sys/i386/isa/isa_compat.h
@@ -41,8 +41,6 @@
#include "rdp.h"
#include "sr.h"
#include "wl.h"
-#include "ze.h"
-#include "zp.h"
#include "oltr.h"
#include "pcm.h"
#include "pas.h"
@@ -105,8 +103,6 @@ extern struct isa_driver lncdriver;
extern struct isa_driver rdpdriver;
extern struct isa_driver srdriver;
extern struct isa_driver wldriver;
-extern struct isa_driver zedriver;
-extern struct isa_driver zpdriver;
extern struct isa_driver oltrdriver;
extern struct isa_driver pasdriver;
extern struct isa_driver sbdriver;
@@ -251,12 +247,6 @@ static struct old_isa_driver old_drivers[] = {
#if NLNC > 0
{ INTR_TYPE_NET, &lncdriver },
#endif
-#if NZE > 0
- { INTR_TYPE_NET, &zedriver },
-#endif
-#if NZP > 0
- { INTR_TYPE_NET, &zpdriver },
-#endif
#if NCS > 0
{ INTR_TYPE_NET, &csdriver },
#endif
diff --git a/sys/i386/isa/pcic.h b/sys/i386/isa/pcic.h
deleted file mode 100644
index e5f3c58..0000000
--- a/sys/i386/isa/pcic.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*-
- * TODO:
- * [1] integrate into current if_ed.c
- * [2] parse tuples to find out where to map the shared memory buffer,
- * and what to write into the configuration register
- * [3] move pcic-specific code into a separate module.
- *
- * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
- * if_ze.c
- *
- * Based on the Device driver for National Semiconductor DS8390 ethernet
- * adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
- * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
- *
- * Currently supports only the IBM Credit Card Adapter for Ethernet, but
- * could probably work with other PCMCIA cards also, if it were modified
- * to get the locations of the PCMCIA configuration option register (COR)
- * by parsing the configuration tuples, rather than by hard-coding in
- * the value expected by IBM's card.
- *
- * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
- *
- * [1] _Local Area Network Credit Card Adapters Technical Reference_,
- * IBM Corp., SC30-3585-00, part # 33G9243.
- * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
- * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
- * Order Number 290423-002
- * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
- * Interface Controller for Twisted Pair data sheet.
- *
- *
- * 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.
- */
-
-#ifndef __PCIC_H__
-#define __PCIC_H__
-
-/*****************************************************************************
- * pcmcia controller chip (PCIC) support *
- * (eventually, move this to a separate file) *
- *****************************************************************************/
-#include <i386/isa/ic/i82365.h>
-
-/*
- * Each PCIC chip (82365SL or clone) can handle two card slots, and there
- * can be up to four PCICs in a system. (On some machines, not all of the
- * address lines are decoded, so a card may appear to be in more than one
- * slot.)
- */
-#define MAXSLOT 8
-
-/*
- * To access a register on the PCIC for a particular slot, you
- * first write the correct OFFSET value for that slot in the
- * INDEX register for the PCIC controller. You then read or write
- * the value from or to the DATA register for that controller.
- *
- * The first pair of chips shares I/O addresses for DATA and INDEX,
- * as does the second pair. (To the programmer, it looks like each
- * pair is a single chip.) The i/o port addresses are hard-wired
- * into the PCIC; so the following addresses should be valid for
- * any machine that uses this chip.
- */
-
-#define PCIC_INDEX_0 0x3E0 /* index reg, chips 0 and 1 */
-#define PCIC_DATA_0 0x3E1 /* data register, chips 0 and 1 */
-#define PCIC_INDEX_1 0x3E2 /* index reg, chips 1 and 2 */
-#define PCIC_DATA_1 0x3E3 /* data register, chips 1 and 2 */
-
-/*
- * Given a slot number, calculate the INDEX and DATA registers
- * to talk to that slot. OFFSET is added to the register number
- * to address the registers for a particular slot.
- */
-#define INDEX(slot) ((slot) < 4 ? PCIC_INDEX_0 : PCIC_INDEX_1)
-#define DATA(slot) ((slot) < 4 ? PCIC_DATA_0 : PCIC_DATA_1)
-#define OFFSET(slot) ((slot) % 4 * 0x40)
-
-/*
- * There are 5 sets (windows) of memory mapping registers on the PCIC chip
- * for each slot, numbered 0..4.
- *
- * They start at 10/50 hex within the chip's register space (not system
- * I/O space), and are eight addresses apart. These are actually pairs of
- * 8-bit-wide registers (low byte first, then high byte) since the
- * address fields are actually 12 bits long. The upper bits are used
- * for other things like 8/16-bit select and wait states.
- *
- * Memory mapping registers include start/stop addresses to define the
- * region to be mapped (in terms of system memory addresses), and
- * an offset register to allow for translation from system space
- * to card space. The lower 12 bits aren't included in these, so memory is
- * mapped in 4K chunks.
- */
-#define MEM_START_ADDR(window) (((window) * 0x08) + 0x10)
-#define MEM_STOP_ADDR(window) (((window) * 0x08) + 0x12)
-#define MEM_OFFSET(window) (((window) * 0x08) + 0x14)
-/*
- * this bit gets set in the address window enable register (PCIC_ADDRWINE)
- * to enable a particular address window.
- */
-#define MEM_ENABLE_BIT(window) ((1) << (window))
-
-/*
- * There are two i/o port addressing windows. I/O ports cannot be
- * relocated within system i/o space (unless the card doesn't decode
- * all of the address bits); unlike card memory, there is no address
- * translation offset.
- */
-#define IO_START_ADDR(window) ((window) ? PCIC_IO1_STL : PCIC_IO0_STL)
-#define IO_STOP_ADDR(window) ((window) ? PCIC_IO1_SPL : PCIC_IO0_SPL)
-#define IO_ENABLE_BIT(window) ((window) ? PCIC_IO1_EN : PCIC_IO0_EN)
-#define IO_CS16_BIT(window) ((window) ? PCIC_IO1_CS16 : PCIC_IO0_CS16)
-
-/*
- * types of mapped memory
- */
-enum memtype { COMMON, ATTRIBUTE };
-
-/*
- * read a byte from a pcic register for a particular slot
- */
-static __inline unsigned char
-pcic_getb (int slot, int reg)
-{
- outb (INDEX(slot), OFFSET (slot) + reg);
- return inb (DATA (slot));
-}
-
-/*
- * write a byte to a pcic register for a particular slot
- */
-static __inline void
-pcic_putb (int slot, int reg, unsigned char val)
-{
- outb (INDEX(slot), OFFSET (slot) + reg);
- outb (DATA (slot), val);
-}
-
-/*
- * read a word from a pcic register for a particular slot
- */
-static __inline unsigned short
-pcic_getw (int slot, int reg)
-{
- return pcic_getb (slot, reg) | (pcic_getb (slot, reg+1) << 8);
-}
-
-/*
- * write a word to a pcic register at a particular slot
- */
-static __inline void
-pcic_putw (int slot, int reg, unsigned short val)
-{
- pcic_putb (slot, reg, val & 0xff);
- pcic_putb (slot, reg + 1, (val >> 8) & 0xff);
-}
-
-
-void pcic_print_regs (int slot);
-void pcic_map_memory (int slot, int window, unsigned long sys_addr,
- unsigned long card_addr, unsigned long length,
- enum memtype type, int width);
-void pcic_unmap_memory (int slot, int window);
-void pcic_map_io (int slot, int window, unsigned short base,
- unsigned short length, unsigned short width);
-#ifdef TEST
-void pcic_unmap_io (int slot, int window);
-#endif /* TEST */
-void pcic_map_irq (int slot, int irq);
-void pcic_power_on (int slot);
-void pcic_power_off (int slot);
-void pcic_reset (int slot);
-
-
-#endif /* __PCIC_H__ */
diff --git a/sys/i386/isa/pcicx.c b/sys/i386/isa/pcicx.c
deleted file mode 100644
index 07d950e..0000000
--- a/sys/i386/isa/pcicx.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*-
- * TODO:
- * [1] integrate into current if_ed.c
- * [2] parse tuples to find out where to map the shared memory buffer,
- * and what to write into the configuration register
- * [3] move pcic-specific code into a separate module.
- *
- * Device driver for IBM PCMCIA Credit Card Adapter for Ethernet,
- * if_ze.c
- *
- * Based on the Device driver for National Semiconductor DS8390 ethernet
- * adapters by David Greenman. Modifications for PCMCIA by Keith Moore.
- * Adapted for FreeBSD 1.1.5 by Jordan Hubbard.
- *
- * Currently supports only the IBM Credit Card Adapter for Ethernet, but
- * could probably work with other PCMCIA cards also, if it were modified
- * to get the locations of the PCMCIA configuration option register (COR)
- * by parsing the configuration tuples, rather than by hard-coding in
- * the value expected by IBM's card.
- *
- * Sources for data on the PCMCIA/IBM CCAE specific portions of the driver:
- *
- * [1] _Local Area Network Credit Card Adapters Technical Reference_,
- * IBM Corp., SC30-3585-00, part # 33G9243.
- * [2] "pre-alpha" PCMCIA support code for Linux by Barry Jaspan.
- * [3] Intel 82536SL PC Card Interface Controller Data Sheet, Intel
- * Order Number 290423-002
- * [4] National Semiconductor DP83902A ST-NIC (tm) Serial Network
- * Interface Controller for Twisted Pair data sheet.
- *
- *
- * 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.
- *
- * $FreeBSD$
- */
-#include <sys/param.h>
-#if defined(__FreeBSD__)
-#include <sys/systm.h>
-#include <machine/clock.h>
-#endif
-#include <i386/isa/pcic.h>
-
-/*
- * map a portion of the card's memory space into system memory
- * space.
- *
- * slot = # of the slot the card is plugged into
- * window = which pcic memory map registers to use (0..4)
- * sys_addr = base system PHYSICAL memory address where we want it. must
- * be on an appropriate boundary (lower 12 bits are zero).
- * card_addr = the base address of the card's memory to correspond
- * to sys_addr
- * length = length of the segment to map (may be rounded up as necessary)
- * type = which card memory space to map (attribute or shared)
- * width = 1 for byte-wide mapping; 2 for word (16-bit) mapping.
- */
-
-void
-pcic_map_memory (int slot, int window, unsigned long sys_addr,
- unsigned long card_addr, unsigned long length,
- enum memtype type, int width)
-{
- unsigned short offset;
- unsigned short mem_start_addr;
- unsigned short mem_stop_addr;
-
- sys_addr >>= 12;
- card_addr >>= 12;
- length >>= 12;
- /*
- * compute an offset for the chip such that
- * (sys_addr + offset) = card_addr
- * but the arithmetic is done modulo 2^14
- */
- offset = (card_addr - sys_addr) & 0x3FFF;
- /*
- * now OR in the bit for "attribute memory" if necessary
- */
- if (type == ATTRIBUTE) {
- offset |= (PCIC_REG << 8);
- /* REG == "region active" pin on card */
- }
- /*
- * okay, set up the chip memory mapping registers, and turn
- * on the enable bit for this window.
- * if we are doing 16-bit wide accesses (width == 2),
- * turn on the appropriate bit.
- *
- * XXX for now, we set all of the wait state bits to zero.
- * Not really sure how they should be set.
- */
- mem_start_addr = sys_addr & 0xFFF;
- if (width == 2)
- mem_start_addr |= (PCIC_DATA16 << 8);
- mem_stop_addr = (sys_addr + length) & 0xFFF;
-
- pcic_putw (slot, MEM_START_ADDR(window), mem_start_addr);
- pcic_putw (slot, MEM_STOP_ADDR(window), mem_stop_addr);
- pcic_putw (slot, MEM_OFFSET(window), offset);
- /*
- * Assert the bit (PCIC_MEMCS16) that says to decode all of
- * the address lines.
- */
- pcic_putb (slot, PCIC_ADDRWINE,
- pcic_getb (slot, PCIC_ADDRWINE) |
- MEM_ENABLE_BIT(window) | PCIC_MEMCS16);
-}
-
-void
-pcic_unmap_memory (int slot, int window)
-{
- /*
- * seems like we need to turn off the enable bit first, after which
- * we can clear the registers out just to be sure.
- */
- pcic_putb (slot, PCIC_ADDRWINE,
- pcic_getb (slot, PCIC_ADDRWINE) & ~MEM_ENABLE_BIT(window));
- pcic_putw (slot, MEM_START_ADDR(window), 0);
- pcic_putw (slot, MEM_STOP_ADDR(window), 0);
- pcic_putw (slot, MEM_OFFSET(window), 0);
-}
-
-/*
- * map a range of addresses into system i/o space
- * (no translation of i/o addresses is possible)
- *
- * 'width' is:
- * + 0 to tell the PCIC to generate the ISA IOCS16* signal from
- * the PCMCIA IOIS16* signal.
- * + 1 to select 8-bit width
- * + 2 to select 16-bit width
- */
-
-void
-pcic_map_io (int slot, int window, unsigned short base, unsigned short length,
- unsigned short width)
-{
- unsigned char x;
-
- pcic_putw (slot, IO_START_ADDR(window), base);
- pcic_putw (slot, IO_STOP_ADDR(window), base+length-1);
- /*
- * select the bits that determine whether
- * an i/o operation is 8 or 16 bits wide
- */
- x = pcic_getb (slot, PCIC_IOCTL);
- switch (width) {
- case 0: /* PCMCIA card decides */
- if (window)
- x = (x & 0xf0) | PCIC_IO1_CS16;
- else
- x = (x & 0x0f) | PCIC_IO0_CS16;
- break;
- case 1: /* 8 bits wide */
- break;
- case 2: /* 16 bits wide */
- if (window)
- x = (x & 0xf0) | PCIC_IO1_16BIT;
- else
- x = (x & 0x0f) | PCIC_IO0_16BIT;
- break;
- }
- pcic_putb (slot, PCIC_IOCTL, x);
- pcic_putb (slot, PCIC_ADDRWINE,
- pcic_getb (slot, PCIC_ADDRWINE) | IO_ENABLE_BIT(window));
-}
-
-#ifdef TEST
-void
-pcic_unmap_io (int slot, int window)
-{
- pcic_putb (slot, PCIC_ADDRWINE,
- pcic_getb (slot, PCIC_ADDRWINE) & ~IO_ENABLE_BIT(window));
- pcic_putw (slot, IO_START_ADDR(window), 0);
- pcic_putw (slot, IO_STOP_ADDR(window), 0);
-}
-#endif /* TEST */
-
-/*
- * tell the PCIC which irq we want to use. only the following are legal:
- * 3, 4, 5, 7, 9, 10, 11, 12, 14, 15
- *
- * NB: 'irq' is an interrupt NUMBER, not a MASK as in struct isa_device.
- */
-
-void
-pcic_map_irq (int slot, int irq)
-{
- if (irq < 3 || irq == 6 || irq == 8 || irq == 13 || irq > 15) {
- printf ("zp: pcic_map_irq (slot %d): illegal irq %d\n", slot, irq);
- return;
- }
- pcic_putb (slot, PCIC_INT_GEN,
- pcic_getb (slot, PCIC_INT_GEN) | (irq & 0x0F));
-}
-
-void
-pcic_power_on (int slot)
-{
- pcic_putb (slot, PCIC_STATUS,
- pcic_getb (slot, PCIC_STATUS) | PCIC_POW);
- DELAY (100000);
- pcic_putb (slot, PCIC_POWER,
- pcic_getb (slot, PCIC_POWER) | PCIC_DISRST | PCIC_PCPWRE);
- DELAY (100000);
- pcic_putb (slot, PCIC_POWER,
- pcic_getb (slot, PCIC_POWER) | PCIC_OUTENA);
-}
-
-void
-pcic_power_off (int slot)
-{
- pcic_putb (slot, PCIC_POWER,
- pcic_getb (slot, PCIC_POWER) & ~(PCIC_OUTENA|PCIC_PCPWRE));
-}
-
-void
-pcic_reset (int slot)
-{
- /* assert RESET (by clearing a bit!), wait a bit, and de-assert it */
- pcic_putb (slot, PCIC_INT_GEN,
- pcic_getb (slot, PCIC_INT_GEN) & ~PCIC_CARDRESET);
- DELAY (100000);
- pcic_putb (slot, PCIC_INT_GEN,
- pcic_getb (slot, PCIC_INT_GEN) | PCIC_CARDRESET);
-}
-
OpenPOWER on IntegriCloud