summaryrefslogtreecommitdiff
path: root/sys/dev/isa/if_ep.c
diff options
context:
space:
mode:
authorhvozda <hvozda@cvs.openbsd.org>1996-04-29 14:17:54 +0000
committerhvozda <hvozda@cvs.openbsd.org>1996-04-29 14:17:54 +0000
commit7a9ddc83f934914d39af72bf24b67290a9e5700f (patch)
treed4e40de8eec73b77be31c346455984224213ff31 /sys/dev/isa/if_ep.c
parentfdecada6f88b495c1afc81ad3a15c0cedffa2338 (diff)
Pull in John Kohl's [jtk@netbsd.org] most recent (15Apr96) APM and PCMCIA work
(original PCMCIA framework by Stefan Grefen [grefen@convex.com]).
Diffstat (limited to 'sys/dev/isa/if_ep.c')
-rw-r--r--sys/dev/isa/if_ep.c123
1 files changed, 95 insertions, 28 deletions
diff --git a/sys/dev/isa/if_ep.c b/sys/dev/isa/if_ep.c
index 4102ad294e4..f9eab4b8368 100644
--- a/sys/dev/isa/if_ep.c
+++ b/sys/dev/isa/if_ep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ep.c,v 1.11 1996/04/21 22:23:52 deraadt Exp $ */
+/* $OpenBSD: if_ep.c,v 1.12 1996/04/29 14:16:41 hvozda Exp $ */
/* $NetBSD: if_ep.c,v 1.90 1996/04/11 22:29:15 cgd Exp $ */
/*
@@ -31,8 +31,9 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*#include "pcmciabus.h"*/
+#include "pcmcia.h"
#include "bpfilter.h"
+#include "ep.h"
#include <sys/param.h>
#include <sys/mbuf.h>
@@ -42,6 +43,7 @@
#include <sys/syslog.h>
#include <sys/select.h>
#include <sys/device.h>
+#include <sys/systm.h>
#include <net/if.h>
#include <net/netisr.h>
@@ -114,26 +116,34 @@ struct ep_softc {
#define EP_BUS_PCI 0x3
#define EP_IS_BUS_32(a) ((a) & 0x2)
+
+ u_char pcmcia_flags;
+#define EP_REATTACH 0x01
+#define EP_ABSENT 0x02
};
static int epprobe __P((struct device *, void *, void *));
static void epattach __P((struct device *, struct device *, void *));
/* XXX the following two structs should be different. */
+#if NEP_ISA > 0
struct cfattach ep_isa_ca = {
sizeof(struct ep_softc), epprobe, epattach
};
+#endif
+#if NEP_PCI > 0
struct cfattach ep_pci_ca = {
sizeof(struct ep_softc), epprobe, epattach
};
+#endif
+
struct cfdriver ep_cd = {
NULL, "ep", DV_IFNET
};
int epintr __P((void *));
-static void epxstat __P((struct ep_softc *));
static int epstatus __P((struct ep_softc *));
void epinit __P((struct ep_softc *));
int epioctl __P((struct ifnet *, u_long, caddr_t));
@@ -142,7 +152,7 @@ void epwatchdog __P((int));
void epreset __P((struct ep_softc *));
void epread __P((struct ep_softc *));
struct mbuf *epget __P((struct ep_softc *, int));
-void epmbuffill __P((struct ep_softc *));
+void epmbuffill __P((void *));
void epmbufempty __P((struct ep_softc *));
void epstop __P((struct ep_softc *));
void epsetfilter __P((struct ep_softc *));
@@ -177,31 +187,39 @@ epaddcard(iobase, irq, bustype)
epcards[nepcards].bustype = bustype;
nepcards++;
}
+
+#if NEP_PCMCIA > 0
+#include <dev/pcmcia/pcmciavar.h>
+
+int ep_pcmcia_match __P((struct device *, void *, void *));
+void ep_pcmcia_attach __P((struct device *, struct device *, void *));
+int ep_pcmcia_detach __P((struct device *));
-#if NPCMCIABUS > 0
-#include <dev/pcmcia/pcmciabus.h>
-static int ep_probe_pcmcia __P((struct device *, void *,
+static int ep_pcmcia_isa_attach __P((struct device *, void *,
void *, struct pcmcia_link *));
static int epmod __P((struct pcmcia_link *, struct device *,
struct pcmcia_conf *, struct cfdata * cf));
static int ep_remove __P((struct pcmcia_link *, struct device *));
+struct cfattach ep_pcmcia_ca = {
+ sizeof(struct ep_softc), ep_pcmcia_match, epattach, ep_pcmcia_detach
+};
+
/* additional setup needed for pcmcia devices */
static int
-ep_probe_pcmcia(parent, match, aux, pc_link)
+ep_pcmcia_isa_attach(parent, match, aux, pc_link)
struct device *parent;
void *match;
void *aux;
struct pcmcia_link *pc_link;
{
struct ep_softc *sc = (void *) match;
- struct cfdata *cf = sc->sc_dev.dv_cfdata;
+/* struct cfdata *cf = sc->sc_dev.dv_cfdata;*/
struct isa_attach_args *ia = aux;
- struct pcmciadevs *dev = pc_link->device;
+/* struct pcmciadevs *dev = pc_link->device;*/
struct ifnet *ifp = &sc->sc_arpcom.ac_if;
int i;
extern int ifqmaxlen;
- short addr[3];
outw(ia->ia_iobase + EP_COMMAND, WINDOW_SELECT | 0);
outw(ia->ia_iobase + EP_W0_CONFIG_CTRL, ENABLE_DRQ_IRQ);
@@ -211,16 +229,15 @@ ep_probe_pcmcia(parent, match, aux, pc_link)
* ok til here. Now try to figure out which link we have.
* try coax first...
*/
- sc->bustype = EP_BUS_PCMCIA;
#ifdef EP_COAX_DEFAULT
outw(ia->ia_iobase + EP_W0_ADDRESS_CFG, 0xC000);
#else
- /* COAX as default is reportet to be a problem */
+ /* COAX as default is reported to be a problem */
outw(ia->ia_iobase + EP_W0_ADDRESS_CFG, 0x0000);
#endif
ifp->if_snd.ifq_maxlen = ifqmaxlen;
- epaddcard(ia->ia_iobase, ia->ia_irq, 0);
+ epaddcard(ia->ia_iobase, ia->ia_irq, EP_BUS_PCMCIA);
for (i = 0; i < nepcards; i++) {
if (epcards[i].available == 0)
@@ -243,10 +260,11 @@ good:
ia->ia_iosize = 0x10;
ia->ia_msize = 0;
+ sc->bustype = epcards[i].bustype;
+ sc->pcmcia_flags = (pc_link->flags & PCMCIA_REATTACH) ? EP_REATTACH:0;
return 1;
}
-
/* modify config entry */
static int
epmod(pc_link, self, pc_cf, cf)
@@ -256,11 +274,11 @@ epmod(pc_link, self, pc_cf, cf)
struct cfdata *cf;
{
int err;
- struct pcmciadevs *dev = pc_link->device;
- struct ep_softc *sc = (void *) self;
+/* struct pcmciadevs *dev = pc_link->device;*/
+/* struct ep_softc *sc = (void *) self;*/
- if ((err = pc_link->adapter->bus_link->bus_config(pc_link, self,
- pc_cf, cf)) != 0) {
+ if ((err = PCMCIA_BUS_CONFIG(pc_link->adapter, pc_link, self,
+ pc_cf, cf)) != 0) {
printf("bus_config failed %d\n", err);
return err;
}
@@ -285,13 +303,14 @@ ep_remove(pc_link, self)
if_down(ifp);
epstop(sc);
ifp->if_flags &= ~(IFF_RUNNING | IFF_UP);
- return pc_link->adapter->bus_link->bus_unconfig(pc_link);
+ sc->pcmcia_flags = EP_ABSENT;
+ return PCMCIA_BUS_UNCONFIG(pc_link->adapter, pc_link);
}
static struct pcmcia_3com {
struct pcmcia_device pcd;
} pcmcia_3com = {
- "PCMCIA 3COM 3C589", epmod, ep_probe_pcmcia, NULL, ep_remove
+ {"PCMCIA 3COM 3C589", epmod, ep_pcmcia_isa_attach, NULL, ep_remove}
};
struct pcmciadevs pcmcia_ep_devs[] = {
@@ -312,8 +331,47 @@ struct pcmciadevs pcmcia_ep_devs[] = {
#endif
{ NULL }
};
+#define nep_pcmcia_devs sizeof(pcmcia_ep_devs)/sizeof(pcmcia_ep_devs[0])
+
+int
+ep_pcmcia_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ return pcmcia_slave_match(parent, match, aux, pcmcia_ep_devs,
+ nep_pcmcia_devs);
+}
+
+void
+ep_pcmcia_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct pcmcia_attach_args *paa = aux;
+
+ printf("ep_pcmcia_attach %p %p %p\n", parent, self, aux);
+ delay(2000000);
+ if (!pcmcia_configure(parent, self, paa->paa_link)) {
+ struct ep_softc *sc = (void *)self;
+ sc->pcmcia_flags |= EP_ABSENT;
+ printf(": not attached\n");
+ }
+}
+
+/*
+ * No detach; network devices are too well linked into the rest of the
+ * kernel.
+ */
+int
+ep_pcmcia_detach(self)
+ struct device *self;
+{
+ return EBUSY;
+}
+
#endif
+
/*
* 3c579 cards on the EISA bus are probed by their slot number. 3c509
* cards on the ISA bus are probed in ethernet address order. The probe
@@ -513,14 +571,15 @@ epconfig(sc, conn)
ifp->if_flags =
IFF_BROADCAST | IFF_SIMPLEX | IFF_NOTRAILERS | IFF_MULTICAST;
- if_attach(ifp);
- ether_ifattach(ifp);
+ if ((sc->pcmcia_flags & EP_REATTACH) == 0) {
+ if_attach(ifp);
+ ether_ifattach(ifp);
#if NBPFILTER > 0
- bpfattach(&sc->sc_arpcom.ac_if.if_bpf, ifp, DLT_EN10MB,
- sizeof(struct ether_header));
+ bpfattach(&sc->sc_arpcom.ac_if.if_bpf, ifp, DLT_EN10MB,
+ sizeof(struct ether_header));
#endif
-
+ }
sc->tx_start_thresh = 20; /* probably a good starting point. */
}
@@ -1219,6 +1278,13 @@ epioctl(ifp, cmd, data)
int s, error = 0;
s = splnet();
+ if (sc->bustype == EP_BUS_PCMCIA &&
+ (sc->pcmcia_flags & EP_ABSENT)) {
+ if_down(ifp);
+ printf("%s: device offline\n", sc->sc_dev.dv_xname);
+ splx(s);
+ return ENXIO;
+ }
switch (cmd) {
@@ -1412,9 +1478,10 @@ epbusyeeprom(sc)
}
void
-epmbuffill(sc)
- struct ep_softc *sc;
+epmbuffill(arg)
+ void *arg;
{
+ struct ep_softc *sc = arg;
int s, i;
s = splnet();