summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1999-08-08 01:17:24 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1999-08-08 01:17:24 +0000
commita180199d7f84a71f2401a43aed2c094742e44b36 (patch)
tree28c39b9ba120c7d2a1466dc327e9a0508142ff6c
parentc26ed33114e5e90c2293512caaea133a8f8b66af (diff)
Add detaching support to networking pcmcia cards
-rw-r--r--sys/dev/pcmcia/if_ep_pcmcia.c53
-rw-r--r--sys/dev/pcmcia/if_ne_pcmcia.c55
-rw-r--r--sys/dev/pcmcia/if_rl2_pcmcia.c347
-rw-r--r--sys/dev/pcmcia/if_rln_pcmcia.c77
-rw-r--r--sys/dev/pcmcia/if_sm_pcmcia.c50
-rw-r--r--sys/dev/pcmcia/if_wi.c72
-rw-r--r--sys/dev/pcmcia/if_xe.c80
7 files changed, 681 insertions, 53 deletions
diff --git a/sys/dev/pcmcia/if_ep_pcmcia.c b/sys/dev/pcmcia/if_ep_pcmcia.c
index 8aa53bcbf9d..ae024322fab 100644
--- a/sys/dev/pcmcia/if_ep_pcmcia.c
+++ b/sys/dev/pcmcia/if_ep_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ep_pcmcia.c,v 1.15 1999/07/26 05:43:15 deraadt Exp $ */
+/* $OpenBSD: if_ep_pcmcia.c,v 1.16 1999/08/08 01:17:23 niklas Exp $ */
/* $NetBSD: if_ep_pcmcia.c,v 1.16 1998/08/17 23:20:40 thorpej Exp $ */
/*-
@@ -116,6 +116,8 @@
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 *, int));
+int ep_pcmcia_activate __P((struct device *, enum devact));
int ep_pcmcia_get_enaddr __P((struct pcmcia_tuple *, void *));
int ep_pcmcia_enable __P((struct ep_softc *));
@@ -134,7 +136,8 @@ struct ep_pcmcia_softc {
};
struct cfattach ep_pcmcia_ca = {
- sizeof(struct ep_pcmcia_softc), ep_pcmcia_match, ep_pcmcia_attach
+ sizeof(struct ep_pcmcia_softc), ep_pcmcia_match, ep_pcmcia_attach,
+ ep_pcmcia_detach, ep_pcmcia_activate
};
struct ep_pcmcia_product {
@@ -279,7 +282,7 @@ ep_pcmcia_attach(parent, self, aux)
int i;
psc->sc_pf = pa->pf;
- cfe = pa->pf->cfe_head.sqh_first;
+ cfe = SIMPLEQ_FIRST(&pa->pf->cfe_head);
/* Enable the card. */
pcmcia_function_init(pa->pf, cfe);
@@ -378,6 +381,50 @@ ep_pcmcia_attach(parent, self, aux)
}
int
+ep_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct ep_pcmcia_softc *psc = (struct ep_pcmcia_softc *)dev;
+ struct ep_softc *sc = &psc->sc_ep;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+ep_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct ep_pcmcia_softc *sc = (struct ep_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ep.sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, epintr, sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ep.sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
+int
ep_pcmcia_get_enaddr(tuple, arg)
struct pcmcia_tuple *tuple;
void *arg;
diff --git a/sys/dev/pcmcia/if_ne_pcmcia.c b/sys/dev/pcmcia/if_ne_pcmcia.c
index 69a0c00045f..e2c076b6b83 100644
--- a/sys/dev/pcmcia/if_ne_pcmcia.c
+++ b/sys/dev/pcmcia/if_ne_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_ne_pcmcia.c,v 1.11 1999/07/26 05:43:16 deraadt Exp $ */
+/* $OpenBSD: if_ne_pcmcia.c,v 1.12 1999/08/08 01:17:23 niklas Exp $ */
/* $NetBSD: if_ne_pcmcia.c,v 1.17 1998/08/15 19:00:04 thorpej Exp $ */
/*
@@ -62,8 +62,10 @@
#include <dev/ic/rtl80x9reg.h>
#include <dev/ic/rtl80x9var.h>
-int ne_pcmcia_match __P((struct device *, void *, void *));
-void ne_pcmcia_attach __P((struct device *, struct device *, void *));
+int ne_pcmcia_match __P((struct device *, void *, void *));
+void ne_pcmcia_attach __P((struct device *, struct device *, void *));
+int ne_pcmcia_detach __P((struct device *, int));
+int ne_pcmcia_activate __P((struct device *, enum devact));
int ne_pcmcia_enable __P((struct dp8390_softc *));
void ne_pcmcia_disable __P((struct dp8390_softc *));
@@ -80,7 +82,8 @@ struct ne_pcmcia_softc {
};
struct cfattach ne_pcmcia_ca = {
- sizeof(struct ne_pcmcia_softc), ne_pcmcia_match, ne_pcmcia_attach
+ sizeof(struct ne_pcmcia_softc), ne_pcmcia_match, ne_pcmcia_attach,
+ ne_pcmcia_detach, ne_pcmcia_activate
};
struct ne2000dev {
@@ -543,7 +546,51 @@ ne_pcmcia_attach(parent, self, aux)
#if 0
pcmcia_function_disable(pa->pf);
#endif
+}
+
+int
+ne_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dev;
+ struct dp8390_softc *dsc = &psc->sc_ne2000.sc_dp8390;
+ struct ifnet *ifp = &dsc->sc_arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window);
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+ return (rv);
+}
+
+int
+ne_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct ne_pcmcia_softc *sc = (struct ne_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, dp8390_intr, sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
}
int
diff --git a/sys/dev/pcmcia/if_rl2_pcmcia.c b/sys/dev/pcmcia/if_rl2_pcmcia.c
new file mode 100644
index 00000000000..b94c886e055
--- /dev/null
+++ b/sys/dev/pcmcia/if_rl2_pcmcia.c
@@ -0,0 +1,347 @@
+/* $OpenBSD: if_rl2_pcmcia.c,v 1.6 1999/08/08 01:17:23 niklas Exp $ */
+/*
+ * David Leonard <d@openbsd.org>, 1999. Public domain.
+ *
+ * Proxim RangeLAN2 PC-Card and compatibles
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+#include <sys/device.h>
+#include <sys/queue.h>
+
+#include <net/if.h>
+
+#ifdef INET
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+#endif
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/ic/rl2.h>
+#include <dev/ic/rl2var.h>
+#include <dev/ic/rl2reg.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciadevs.h>
+
+struct rl2_pcmcia_softc {
+ struct rl2_softc sc_rl2; /* real "rl2" softc */
+
+ struct pcmcia_io_handle sc_pcioh; /* PCMCIA i/o information */
+ int sc_io_window; /* i/o window for the card */
+ struct pcmcia_function *sc_pf; /* our PCMCIA function */
+ void *sc_ih; /* our interrupt handle */
+};
+
+int rl2_pcmcia_match __P((struct device *, void *, void *));
+struct rl2_pcmcia_product *rl2_pcmcia_product_lookup
+ __P((struct pcmcia_attach_args *));
+void rl2_pcmcia_attach __P((struct device *, struct device *, void *));
+int rl2_pcmcia_detach __P((struct device *, int));
+int rl2_pcmcia_activate __P((struct device *, enum devact));
+int rl2intr_pcmcia __P((void *arg));
+
+#ifdef notyet
+int rl2_pcmcia_enable __P((struct rl2_softc *));
+void rl2_pcmcia_disable __P((struct rl2_softc *));
+#endif
+
+struct cfattach rln_pcmcia_ca = {
+ sizeof(struct rl2_pcmcia_softc), rl2_pcmcia_match, rl2_pcmcia_attach,
+ rl2_pcmcia_detach, rl2_pcmcia_activate
+};
+
+#define PCMCIA_CIS_RANGELAN2_7200 { "PROXIM", "LAN CARD", "RANGELAN2", NULL }
+#define PCMCIA_CIS_RANGELAN2_7400 { "PROXIM", "LAN PC CARD", "RANGELAN2", NULL }
+#define PCMCIA_CIS_SYMPHONY { "PROXIM", "LAN PC CARD", "SYMPHONY", NULL }
+
+static struct rl2_pcmcia_product {
+ u_int32_t manufacturer;
+ u_int32_t product;
+ const char *name;
+ u_int8_t flags;
+} rl2_pcmcia_products[] = {
+ { 0x0126, /* Digital */
+ 0x1058, /* RoamAbout 2400 FH */
+ "Digital RoamAbout 2400 FH",
+ 0 },
+ { 0x8a01, /* AMP */
+ 0x0066, /* Wireless */
+ "AMP Wireless",
+ 0 },
+ { 0,
+ 0,
+ "unknown RangeLAN2 wireless network card",
+ 0 },
+};
+
+/* Match the product and manufacturer codes with known card types */
+struct rl2_pcmcia_product *
+rl2_pcmcia_product_lookup(pa)
+ struct pcmcia_attach_args *pa;
+{
+ struct rl2_pcmcia_product *rpp;
+
+ for (rpp = rl2_pcmcia_products; rpp->manufacturer && rpp->product;
+ rpp++)
+ if (pa->manufacturer == rpp->manufacturer &&
+ pa->product == rpp->product)
+ break;
+ return (rpp);
+}
+
+/* Match card CIS info string with RangeLAN2 cards */
+int
+rl2_pcmcia_match(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+ struct pcmcia_attach_args *pa = aux;
+ static const char *cis_7200[] = PCMCIA_CIS_RANGELAN2_7200;
+ static const char *cis_7400[] = PCMCIA_CIS_RANGELAN2_7400;
+ static const char *cis_symp[] = PCMCIA_CIS_SYMPHONY;
+ static const char **cis_info[] = { cis_7200, cis_7400, cis_symp, NULL };
+ const char ***cis;
+ int i;
+
+ for (cis = cis_info; *cis; cis++) {
+ for (i = 0; ; i++) {
+ if ((*cis)[i] == NULL)
+ return (1);
+ if (strcmp((*cis)[i], pa->card->cis1_info[i]) != 0)
+ break;
+ }
+ }
+ return (0);
+}
+
+/* Attach and configure */
+void
+rl2_pcmcia_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct rl2_pcmcia_softc *psc = (void *) self;
+ struct rl2_softc *sc = &psc->sc_rl2;
+ struct pcmcia_attach_args *pa = aux;
+ struct pcmcia_config_entry *cfe;
+ struct rl2_pcmcia_product *rpp;
+
+#ifdef RL2DEBUG
+ /* Allowed i/o base addresses from the RoamAbout owner's manual */
+ int i;
+ static bus_addr_t iobases[] = {
+ 0x270, /* useful in user-space debugging */
+ 0x100, 0x120, 0x140, 0x218, 0x270, 0x280, 0x290, 0x298,
+ 0x2a0, 0x2a8, 0x2e0, 0x300, 0x310, 0x358, 0x360, 0x368,
+ 0
+ };
+#endif
+
+ psc->sc_pf = pa->pf;
+ cfe = psc->sc_pf->cfe_head.sqh_first;
+
+ /* Guess the transfer width we will be using */
+ if (cfe->flags & PCMCIA_CFE_IO16)
+ sc->sc_width = 16;
+ else if (cfe->flags & PCMCIA_CFE_IO8)
+ sc->sc_width = 8;
+ else
+ sc->sc_width = 0;
+
+#ifdef DIAGNOSTIC
+ /* We only expect one i/o region and no memory region */
+ if (cfe->num_memspace != 0)
+ printf(": unexpected number of memory spaces (%d)\n",
+ cfe->num_memspace);
+ if (cfe->num_iospace != 1)
+ printf(": unexpected number of i/o spaces (%d)\n",
+ cfe->num_iospace);
+ else if (cfe->iospace[0].length != RL2_NPORTS)
+ printf(": unexpected size of i/o space (0x%x)\n",
+ cfe->iospace[0].length);
+ if (sc->sc_width == 0)
+ printf(": unknown bus width\n");
+#endif /* DIAGNOSTIC */
+
+ pcmcia_function_init(psc->sc_pf, cfe);
+
+ /* Allocate i/o space */
+#ifdef RL2DEBUG
+ /* Try only those ports from the manual */
+ for (i=0; iobases[i] != 0; i++)
+ if (pcmcia_io_alloc(psc->sc_pf, iobases[i], RL2_NPORTS,
+ RL2_NPORTS, &psc->sc_pcioh) == 0)
+ break;
+ if (iobases[i] == 0) {
+#else
+ if (pcmcia_io_alloc(psc->sc_pf, 0, RL2_NPORTS,
+ RL2_NPORTS, &psc->sc_pcioh)) {
+#endif
+ printf(": can't alloc i/o space\n");
+ return;
+ }
+
+ sc->sc_iot = psc->sc_pcioh.iot;
+ sc->sc_ioh = psc->sc_pcioh.ioh;
+
+ /* Map i/o space */
+ if (pcmcia_io_map(psc->sc_pf, ((sc->sc_width == 8) ? PCMCIA_WIDTH_IO8 :
+ (sc->sc_width == 16) ? PCMCIA_WIDTH_IO16 : PCMCIA_WIDTH_AUTO),
+ 0, RL2_NPORTS, &psc->sc_pcioh, &psc->sc_io_window)) {
+ printf(": can't map i/o space\n");
+ return;
+ }
+
+ /* Enable the card */
+ if (pcmcia_function_enable(psc->sc_pf)) {
+ printf(": function enable failed\n");
+ return;
+ }
+
+#ifdef notyet
+ sc->enable = rl2_pcmcia_enable;
+ sc->disable = rl2_pcmcia_disable;
+#endif
+
+ rpp = rl2_pcmcia_product_lookup(pa);
+
+ /* Check if the device has a separate antenna module */
+ sc->sc_cardtype = 0;
+ switch (psc->sc_pf->ccr_base) {
+ case 0x0100:
+ sc->sc_cardtype |= RL2_CTYPE_ONE_PIECE;
+ break;
+ case 0x0800:
+ sc->sc_cardtype &= ~RL2_CTYPE_ONE_PIECE;
+ break;
+#ifdef DIAGNOSTIC
+ default:
+ printf("\n%s: cannot tell if one or two piece (ccr addr %x)\n",
+ sc->sc_dev.dv_xname, psc->sc_pf->ccr_base);
+#endif
+ }
+
+ /* The PC-card needs to be told to use 'irq' 15 */
+ sc->sc_irq = 15;
+
+ /*
+ * We need to get an interrupt before configuring, since
+ * polling registers (the alternative) to reading card
+ * responses, causes hard lock-ups.
+ */
+ printf("\n");
+ sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
+ rl2intr_pcmcia, sc);
+ if (sc->sc_ih == NULL)
+ printf("%s: couldn't establish interrupt\n",
+ sc->sc_dev.dv_xname);
+
+ printf("%s: %s", sc->sc_dev.dv_xname, rpp->name);
+#ifdef DIAGNOSTIC
+ if (rpp->manufacturer == 0)
+ printf(" manf %04x prod %04x", pa->manufacturer, pa->product);
+#endif
+ rl2config(sc);
+ printf("\n");
+}
+
+int
+rl2_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct rl2_pcmcia_softc *psc = (struct rl2_pcmcia_softc *)dev;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+rl2_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct rl2_pcmcia_softc *sc = (struct rl2_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_rl2.sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, rl2intr_pcmcia,
+ sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_rl2.sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
+/* Interrupt handler */
+int
+rl2intr_pcmcia(arg)
+ void *arg;
+{
+ struct rl2_softc *sc = (struct rl2_softc *)arg;
+ struct rl2_pcmcia_softc *psc = (struct rl2_pcmcia_softc *)sc;
+ int opt;
+ int ret;
+
+ /* Need to immediately read/write the option register for PC-card */
+ opt = pcmcia_ccr_read(psc->sc_pf, PCMCIA_CCR_OPTION);
+ pcmcia_ccr_write(psc->sc_pf, PCMCIA_CCR_OPTION, opt);
+
+ /* Call actual interrupt handler */
+ ret = rl2intr(arg);
+
+ return (ret);
+}
+
+#ifdef notyet
+int
+rl2_pcmcia_enable(sc)
+ struct rl2_softc *sc;
+{
+ struct rl2_pcmcia_softc *psc = (struct rl2_pcmcia_softc *) sc;
+ struct pcmcia_function *pf = psc->sc_pf;
+
+ /* Establish the interrupt */
+ sc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET,
+ rl2intr_pcmcia, sc);
+ if (sc->sc_ih == NULL) {
+ printf("%s: couldn't establish interrupt\n",
+ sc->sc_dev.dv_xname);
+ return (1);
+ }
+
+ return (pcmcia_function_enable(pf));
+}
+
+void
+rl2_pcmcia_disable(sc)
+ struct rl2_softc *sc;
+{
+ struct rl2_pcmcia_softc *psc = (struct rl2_pcmcia_softc *) sc;
+
+ pcmcia_function_disable(psc->sc_pf);
+ pcmcia_intr_disestablish(psc->sc_pf, sc->sc_ih);
+}
+#endif
diff --git a/sys/dev/pcmcia/if_rln_pcmcia.c b/sys/dev/pcmcia/if_rln_pcmcia.c
index 8f42b0f77ef..238867c1616 100644
--- a/sys/dev/pcmcia/if_rln_pcmcia.c
+++ b/sys/dev/pcmcia/if_rln_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_rln_pcmcia.c,v 1.1 1999/07/30 13:43:37 d Exp $ */
+/* $OpenBSD: if_rln_pcmcia.c,v 1.2 1999/08/08 01:17:23 niklas Exp $ */
/*
* David Leonard <d@openbsd.org>, 1999. Public domain.
*
@@ -38,19 +38,22 @@ struct rln_pcmcia_softc {
void *sc_ih; /* our interrupt handle */
};
-static int rln_pcmcia_match __P((struct device *, void *, void *));
-static struct rln_pcmcia_product * rln_pcmcia_product_lookup __P((
- struct pcmcia_attach_args *));
-static void rln_pcmcia_attach __P((struct device *, struct device *, void *));
-static int rlnintr_pcmcia __P((void *arg));
+int rln_pcmcia_match __P((struct device *, void *, void *));
+struct rln_pcmcia_product * rln_pcmcia_product_lookup
+ __P((struct pcmcia_attach_args *));
+void rln_pcmcia_attach __P((struct device *, struct device *, void *));
+int rln_pcmcia_detach __P((struct device *, int));
+int rln_pcmcia_activate __P((struct device *, enum devact));
+int rlnintr_pcmcia __P((void *arg));
#ifdef notyet
-static int rln_pcmcia_enable __P((struct rln_softc *));
-static void rln_pcmcia_disable __P((struct rln_softc *));
+int rln_pcmcia_enable __P((struct rln_softc *));
+void rln_pcmcia_disable __P((struct rln_softc *));
#endif
struct cfattach rln_pcmcia_ca = {
- sizeof(struct rln_pcmcia_softc), rln_pcmcia_match, rln_pcmcia_attach
+ sizeof(struct rln_pcmcia_softc), rln_pcmcia_match, rln_pcmcia_attach,
+ rln_pcmcia_detach, rln_pcmcia_activate
};
#define PCMCIA_CIS_RANGELAN2_7200 { "PROXIM", "LAN CARD", "RANGELAN2", NULL }
@@ -78,7 +81,7 @@ static struct rln_pcmcia_product {
};
/* Match the product and manufacturer codes with known card types */
-static struct rln_pcmcia_product *
+struct rln_pcmcia_product *
rln_pcmcia_product_lookup(pa)
struct pcmcia_attach_args *pa;
{
@@ -93,7 +96,7 @@ rln_pcmcia_product_lookup(pa)
}
/* Match card CIS info string with RangeLAN2 cards */
-static int
+int
rln_pcmcia_match(parent, match, aux)
struct device *parent;
void *match, *aux;
@@ -118,7 +121,7 @@ rln_pcmcia_match(parent, match, aux)
}
/* Attach and configure */
-static void
+void
rln_pcmcia_attach(parent, self, aux)
struct device *parent, *self;
void *aux;
@@ -248,8 +251,52 @@ rln_pcmcia_attach(parent, self, aux)
printf("\n");
}
+int
+rln_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct rln_pcmcia_softc *psc = (struct rln_pcmcia_softc *)dev;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+rln_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct rln_pcmcia_softc *sc = (struct rln_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_rln.sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, rlnintr_pcmcia,
+ sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_rln.sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
/* Interrupt handler */
-static int
+int
rlnintr_pcmcia(arg)
void *arg;
{
@@ -269,7 +316,7 @@ rlnintr_pcmcia(arg)
}
#ifdef notyet
-static int
+int
rln_pcmcia_enable(sc)
struct rln_softc *sc;
{
@@ -288,7 +335,7 @@ rln_pcmcia_enable(sc)
return (pcmcia_function_enable(pf));
}
-static void
+void
rln_pcmcia_disable(sc)
struct rln_softc *sc;
{
diff --git a/sys/dev/pcmcia/if_sm_pcmcia.c b/sys/dev/pcmcia/if_sm_pcmcia.c
index 667e8ab5eb0..dc19c7a3f0f 100644
--- a/sys/dev/pcmcia/if_sm_pcmcia.c
+++ b/sys/dev/pcmcia/if_sm_pcmcia.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_sm_pcmcia.c,v 1.4 1999/07/26 05:43:16 deraadt Exp $ */
+/* $OpenBSD: if_sm_pcmcia.c,v 1.5 1999/08/08 01:17:23 niklas Exp $ */
/* $NetBSD: if_sm_pcmcia.c,v 1.11 1998/08/15 20:47:32 thorpej Exp $ */
/*-
@@ -91,6 +91,8 @@
int sm_pcmcia_match __P((struct device *, void *, void *));
void sm_pcmcia_attach __P((struct device *, struct device *, void *));
+int sm_pcmcia_detach __P((struct device *, int));
+int sm_pcmcia_activate __P((struct device *, enum devact));
struct sm_pcmcia_softc {
struct smc91cxx_softc sc_smc; /* real "smc" softc */
@@ -103,7 +105,8 @@ struct sm_pcmcia_softc {
};
struct cfattach sm_pcmcia_ca = {
- sizeof(struct sm_pcmcia_softc), sm_pcmcia_match, sm_pcmcia_attach
+ sizeof(struct sm_pcmcia_softc), sm_pcmcia_match, sm_pcmcia_attach,
+ sm_pcmcia_detach, sm_pcmcia_activate
};
int sm_pcmcia_enable __P((struct smc91cxx_softc *));
@@ -249,6 +252,49 @@ sm_pcmcia_attach(parent, self, aux)
}
int
+sm_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct sm_pcmcia_softc *psc = (struct sm_pcmcia_softc *)dev;
+ struct ifnet *ifp = &psc->sc_smc.sc_arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+sm_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct sm_pcmcia_softc *sc = (struct sm_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih = pcmcia_intr_establish(sc->sc_pf, IPL_NET,
+ smc91cxx_intr, sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
+int
sm_pcmcia_ascii_enaddr(cisstr, myla)
const char *cisstr;
u_int8_t *myla;
diff --git a/sys/dev/pcmcia/if_wi.c b/sys/dev/pcmcia/if_wi.c
index 14db9ebac79..a959b18de47 100644
--- a/sys/dev/pcmcia/if_wi.c
+++ b/sys/dev/pcmcia/if_wi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_wi.c,v 1.1 1999/07/11 16:25:36 niklas Exp $ */
+/* $OpenBSD: if_wi.c,v 1.2 1999/08/08 01:17:23 niklas Exp $ */
/*
* Copyright (c) 1997, 1998, 1999
@@ -176,9 +176,9 @@ u_int32_t widebug = WIDEBUG;
#if !defined(lint)
static const char rcsid[] =
#ifdef __FreeBSD__
- "$Id: if_wi.c,v 1.1 1999/07/11 16:25:36 niklas Exp $";
+ "$Id: if_wi.c,v 1.2 1999/08/08 01:17:23 niklas Exp $";
#else /* !__FreeBSD__ */
- "$OpenBSD: if_wi.c,v 1.1 1999/07/11 16:25:36 niklas Exp $";
+ "$OpenBSD: if_wi.c,v 1.2 1999/08/08 01:17:23 niklas Exp $";
#endif /* __FreeBSD__ */
#endif /* lint */
@@ -448,6 +448,8 @@ STATIC int wi_attach(isa_dev)
int wi_pcmcia_match __P((struct device *, void *, void *));
void wi_pcmcia_attach __P((struct device *, struct device *, void *));
+int wi_pcmcia_detach __P((struct device *, int));
+int wi_pcmcia_activate __P((struct device *, enum devact));
int wi_intr __P((void *));
/* Autoconfig definition of driver back-end */
@@ -456,7 +458,8 @@ struct cfdriver wi_cd = {
};
struct cfattach wi_ca = {
- sizeof (struct wi_softc), wi_pcmcia_match, wi_pcmcia_attach
+ sizeof (struct wi_softc), wi_pcmcia_match, wi_pcmcia_attach,
+ wi_pcmcia_detach, wi_pcmcia_activate
};
int
@@ -488,12 +491,12 @@ wi_pcmcia_attach(parent, self, aux)
struct pcmcia_attach_args *pa = aux;
struct pcmcia_function *pf = pa->pf;
struct pcmcia_config_entry *cfe = pf->cfe_head.sqh_first;
- struct pcmcia_io_handle pcioh;
struct wi_ltv_macaddr mac;
struct wi_ltv_gen gen;
struct ifnet *ifp;
int state = 0;
- int io_window;
+
+ sc->sc_pf = pf;
/* Enable the card. */
pcmcia_function_init(pf, cfe);
@@ -503,22 +506,22 @@ wi_pcmcia_attach(parent, self, aux)
}
state++;
- if (pcmcia_io_alloc(pf, 0, WI_IOSIZ, WI_IOSIZ, &pcioh)) {
+ if (pcmcia_io_alloc(pf, 0, WI_IOSIZ, WI_IOSIZ, &sc->sc_pcioh)) {
printf(": can't alloc i/o space\n");
goto bad;
}
state++;
- if (pcmcia_io_map(pf, PCMCIA_WIDTH_IO16, 0, WI_IOSIZ, &pcioh,
- &io_window)) {
+ if (pcmcia_io_map(pf, PCMCIA_WIDTH_IO16, 0, WI_IOSIZ, &sc->sc_pcioh,
+ &sc->sc_io_window)) {
printf(": can't map io space\n");
goto bad;
}
state++;
sc->wi_gone = 0;
- sc->wi_btag = pcioh.iot;
- sc->wi_bhandle = pcioh.ioh;
+ sc->wi_btag = sc->sc_pcioh.iot;
+ sc->wi_bhandle = sc->sc_pcioh.ioh;
/* Make sure interrupts are disabled. */
CSR_WRITE_2(sc, WI_INT_EN, 0);
@@ -617,13 +620,56 @@ wi_pcmcia_attach(parent, self, aux)
bad:
if (state > 2)
- pcmcia_chip_io_unmap(pf->sc->pct, pf->sc->pch, io_window);
+ pcmcia_chip_io_unmap(pf->sc->pct, pf->sc->pch,
+ sc->sc_io_window);
if (state > 1)
- pcmcia_chip_io_free(pf->sc->pct, pf->sc->pch, &pcioh);
+ pcmcia_chip_io_free(pf->sc->pct, pf->sc->pch, &sc->sc_pcioh);
if (state > 0)
pcmcia_function_disable(pf);
}
+int
+wi_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct wi_softc *sc = (struct wi_softc *)dev;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int rv = 0;
+
+ pcmcia_io_unmap(sc->sc_pf, sc->sc_io_window);
+ pcmcia_io_free(sc->sc_pf, &sc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+wi_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct wi_softc *sc = (struct wi_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, wi_intr, sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
#endif /* __FreeBSD__ */
#ifdef __FreeBSD__
diff --git a/sys/dev/pcmcia/if_xe.c b/sys/dev/pcmcia/if_xe.c
index 8552f56c283..39eea0602b6 100644
--- a/sys/dev/pcmcia/if_xe.c
+++ b/sys/dev/pcmcia/if_xe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_xe.c,v 1.4 1999/07/26 05:43:16 deraadt Exp $ */
+/* $OpenBSD: if_xe.c,v 1.5 1999/08/08 01:17:23 niklas Exp $ */
/*
* Copyright (c) 1999 Niklas Hallqvist, C Stone, Job de Haas
@@ -127,6 +127,8 @@ int xedebug = XEDEBUG_DEF;
int xe_pcmcia_match __P((struct device *, void *, void *));
void xe_pcmcia_attach __P((struct device *, struct device *, void *));
+int xe_pcmcia_detach __P((struct device *, int));
+int xe_pcmcia_activate __P((struct device *, enum devact));
/*
* In case this chipset ever turns up out of pcmcia attachments (very
@@ -171,7 +173,8 @@ struct cfdriver xe_cd = {
};
struct cfattach xe_pcmcia_ca = {
- sizeof (struct xe_pcmcia_softc), xe_pcmcia_match, xe_pcmcia_attach
+ sizeof (struct xe_pcmcia_softc), xe_pcmcia_match, xe_pcmcia_attach,
+ xe_pcmcia_detach, xe_pcmcia_activate
};
void xe_cycle_power __P((struct xe_softc *));
@@ -382,7 +385,14 @@ xe_pcmcia_attach(parent, self, aux)
ifp->if_start = xe_start;
ifp->if_watchdog = xe_watchdog;
- printf(": address %s", ether_sprintf(sc->sc_arpcom.ac_enaddr));
+ /* Establish the interrupt. */
+ sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, xe_intr, sc);
+ if (sc->sc_ih == NULL) {
+ printf(", couldn't establish interrupt\n");
+ goto bad;
+ }
+
+ printf(": address %s\n", ether_sprintf(sc->sc_arpcom.ac_enaddr));
/* Reset and initialize the card. */
xe_full_reset(sc);
@@ -412,15 +422,6 @@ xe_pcmcia_attach(parent, self, aux)
sizeof(struct ether_header));
#endif /* NBPFILTER > 0 */
- /* Establish the interrupt. */
- sc->sc_ih = pcmcia_intr_establish(pa->pf, IPL_NET, xe_intr, sc);
- if (sc->sc_ih == NULL) {
- printf(", couldn't establish interrupt\n");
- goto bad;
- }
-
- printf("\n");
-
/*
* Reset and initialize the card again for DINGO (as found in Linux
* driver). Without this Dingo will get a watchdog timeout the first
@@ -435,11 +436,7 @@ xe_pcmcia_attach(parent, self, aux)
xe_stop(sc);
}
-
#ifdef notyet
- /*
- * XXX This should be done once the framework has enable/disable hooks.
- */
pcmcia_function_disable(pa->pf);
#endif /* notyet */
@@ -456,6 +453,57 @@ bad:
free(cfe, M_DEVBUF);
}
+int
+xe_pcmcia_detach(dev, flags)
+ struct device *dev;
+ int flags;
+{
+ struct xe_pcmcia_softc *psc = (struct xe_pcmcia_softc *)dev;
+ struct xe_softc *sc = &psc->sc_xe;
+ struct ifnet *ifp = &sc->sc_arpcom.ac_if;
+ struct mii_softc *msc;
+ int rv = 0;
+
+ for (msc = LIST_FIRST(&sc->sc_mii.mii_phys); msc;
+ msc = LIST_FIRST(&sc->sc_mii.mii_phys)) {
+ LIST_REMOVE(msc, mii_list);
+ rv |= config_detach(&msc->mii_dev, flags);
+ }
+
+ pcmcia_io_unmap(psc->sc_pf, psc->sc_io_window);
+ pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh);
+
+ ether_ifdetach(ifp);
+ if_detach(ifp);
+
+ return (rv);
+}
+
+int
+xe_pcmcia_activate(dev, act)
+ struct device *dev;
+ enum devact act;
+{
+ struct xe_pcmcia_softc *sc = (struct xe_pcmcia_softc *)dev;
+ int s;
+
+ s = splnet();
+ switch (act) {
+ case DVACT_ACTIVATE:
+ pcmcia_function_enable(sc->sc_pf);
+ sc->sc_xe.sc_ih =
+ pcmcia_intr_establish(sc->sc_pf, IPL_NET, xe_intr, sc);
+ break;
+
+ case DVACT_DEACTIVATE:
+ pcmcia_function_disable(sc->sc_pf);
+ pcmcia_intr_disestablish(sc->sc_pf, sc->sc_xe.sc_ih);
+ break;
+ }
+ splx(s);
+ return (0);
+}
+
/*
* XXX These two functions might be OK to factor out into pcmcia.c since
* if_sm_pcmcia.c uses similar ones.