diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-08-08 01:17:24 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1999-08-08 01:17:24 +0000 |
commit | a180199d7f84a71f2401a43aed2c094742e44b36 (patch) | |
tree | 28c39b9ba120c7d2a1466dc327e9a0508142ff6c | |
parent | c26ed33114e5e90c2293512caaea133a8f8b66af (diff) |
Add detaching support to networking pcmcia cards
-rw-r--r-- | sys/dev/pcmcia/if_ep_pcmcia.c | 53 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_ne_pcmcia.c | 55 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_rl2_pcmcia.c | 347 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_rln_pcmcia.c | 77 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_sm_pcmcia.c | 50 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_wi.c | 72 | ||||
-rw-r--r-- | sys/dev/pcmcia/if_xe.c | 80 |
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. |