From 99f529f0b37c85276725a8044cc152776b52f81c Mon Sep 17 00:00:00 2001 From: enami Date: Wed, 9 Feb 2000 14:42:33 +0000 Subject: [PATCH] - Since all resources are mandatory, no need to manage individually. - KNF some code. - Factor out some code into function. - Disestablish an interrupt handler when failed to enable card power. --- sys/dev/ic/dp8390.c | 25 +--- sys/dev/ic/dp8390var.h | 3 +- sys/dev/ic/ne2000.c | 14 +- sys/dev/ic/ne2000var.h | 4 +- sys/dev/pcmcia/if_ne_pcmcia.c | 232 +++++++++++++++++++--------------- 5 files changed, 146 insertions(+), 132 deletions(-) diff --git a/sys/dev/ic/dp8390.c b/sys/dev/ic/dp8390.c index 247dbe18451c..645f3c7973d5 100644 --- a/sys/dev/ic/dp8390.c +++ b/sys/dev/ic/dp8390.c @@ -1,4 +1,4 @@ -/* $NetBSD: dp8390.c,v 1.31 2000/02/02 13:06:16 itojun Exp $ */ +/* $NetBSD: dp8390.c,v 1.32 2000/02/09 14:42:33 enami Exp $ */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet @@ -93,8 +93,6 @@ dp8390_config(sc, media, nmedia, defmedia) rv = 1; - sc->sc_configured = 0; - if (!sc->test_mem) sc->test_mem = dp8390_test_mem; @@ -157,8 +155,6 @@ dp8390_config(sc, media, nmedia, defmedia) printf("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, ether_sprintf(sc->sc_enaddr)); - sc->sc_configured = 1; - rv = 0; out: return (rv); @@ -1302,9 +1298,6 @@ dp8390_activate(self, act) case DVACT_DEACTIVATE: if_deactivate(&sc->sc_ec.ec_if); -#if 0 - dp8390_disable(sc); -#endif break; } splx(s); @@ -1321,21 +1314,17 @@ dp8390_detach(sc, flags) /* dp8390_disable() checks sc->sc_enabled */ dp8390_disable(sc); - if (sc->sc_configured) { - /* Delete all media. */ - ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); + /* Delete all media. */ + ifmedia_delete_instance(&sc->sc_media, IFM_INST_ANY); #if NRND > 0 - rnd_detach_source(&sc->rnd_source); + rnd_detach_source(&sc->rnd_source); #endif #if NBPFILTER > 0 - bpfdetach(ifp); + bpfdetach(ifp); #endif - ether_ifdetach(ifp); - if_detach(ifp); - - sc->sc_configured = 0; - } + ether_ifdetach(ifp); + if_detach(ifp); return (0); } diff --git a/sys/dev/ic/dp8390var.h b/sys/dev/ic/dp8390var.h index 216bc3020bd4..9c367798e77f 100644 --- a/sys/dev/ic/dp8390var.h +++ b/sys/dev/ic/dp8390var.h @@ -1,4 +1,4 @@ -/* $NetBSD: dp8390var.h,v 1.14 2000/02/02 13:06:17 itojun Exp $ */ +/* $NetBSD: dp8390var.h,v 1.15 2000/02/09 14:42:34 enami Exp $ */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet @@ -62,7 +62,6 @@ struct dp8390_softc { u_int8_t sc_enaddr[6]; /* storage for MAC address */ int sc_enabled; /* boolean; power enabled on interface */ - int sc_configured; /* boolean; 1 if dp8390_config was succesful */ #if NRND > 0 rndsource_element_t rnd_source; /* random source */ diff --git a/sys/dev/ic/ne2000.c b/sys/dev/ic/ne2000.c index bd7ac371d508..b1246b7b2d15 100644 --- a/sys/dev/ic/ne2000.c +++ b/sys/dev/ic/ne2000.c @@ -1,4 +1,4 @@ -/* $NetBSD: ne2000.c,v 1.25 2000/02/02 11:41:57 itojun Exp $ */ +/* $NetBSD: ne2000.c,v 1.26 2000/02/09 14:42:35 enami Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -98,7 +98,7 @@ void ne2000_writemem __P((bus_space_tag_t, bus_space_handle_t, void ne2000_readmem __P((bus_space_tag_t, bus_space_handle_t, bus_space_tag_t, bus_space_handle_t, int, u_int8_t *, size_t, int)); -void +int ne2000_attach(nsc, myea, media, nmedia, defmedia) struct ne2000_softc *nsc; u_int8_t *myea; @@ -121,7 +121,7 @@ ne2000_attach(nsc, myea, media, nmedia, defmedia) if (nsc->sc_type == 0) { printf("%s: where did the card go?\n", dsc->sc_dev.dv_xname); - return; + return (1); } } @@ -206,7 +206,7 @@ ne2000_attach(nsc, myea, media, nmedia, defmedia) if (mstart == 0) { printf("%s: cannot find start of RAM\n", dsc->sc_dev.dv_xname); - return; + return (1); } /* Search for the end of RAM. */ @@ -255,7 +255,7 @@ ne2000_attach(nsc, myea, media, nmedia, defmedia) if (dp8390_config(dsc, media, nmedia, defmedia)) { printf("%s: setup failed\n", dsc->sc_dev.dv_xname); - return; + return (1); } /* @@ -264,6 +264,7 @@ ne2000_attach(nsc, myea, media, nmedia, defmedia) */ dsc->mem_ring = dsc->mem_start + ((dsc->txb_cnt * ED_TXBUF_SIZE) << ED_PAGE_SHIFT); + return (0); } /* @@ -738,5 +739,6 @@ ne2000_detach(sc, flags) struct ne2000_softc *sc; int flags; { - return dp8390_detach(&sc->sc_dp8390, flags); + + return (dp8390_detach(&sc->sc_dp8390, flags)); } diff --git a/sys/dev/ic/ne2000var.h b/sys/dev/ic/ne2000var.h index 1c9e2d473358..9e774fc84c6a 100644 --- a/sys/dev/ic/ne2000var.h +++ b/sys/dev/ic/ne2000var.h @@ -1,4 +1,4 @@ -/* $NetBSD: ne2000var.h,v 1.8 2000/02/02 11:41:57 itojun Exp $ */ +/* $NetBSD: ne2000var.h,v 1.9 2000/02/09 14:42:35 enami Exp $ */ /*- * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. @@ -58,7 +58,7 @@ struct ne2000_softc { (((sc)->sc_type == NE2000_TYPE_NE2000) || \ ((sc)->sc_type == NE2000_TYPE_DL10019)) -void ne2000_attach __P((struct ne2000_softc *, u_int8_t *, +int ne2000_attach __P((struct ne2000_softc *, u_int8_t *, int *, int, int)); int ne2000_detect __P((bus_space_tag_t, bus_space_handle_t, bus_space_tag_t, bus_space_handle_t)); diff --git a/sys/dev/pcmcia/if_ne_pcmcia.c b/sys/dev/pcmcia/if_ne_pcmcia.c index 222c9103327c..325d1f61f1f7 100644 --- a/sys/dev/pcmcia/if_ne_pcmcia.c +++ b/sys/dev/pcmcia/if_ne_pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ne_pcmcia.c,v 1.52 2000/02/02 13:06:15 itojun Exp $ */ +/* $NetBSD: if_ne_pcmcia.c,v 1.53 2000/02/09 14:42:37 enami Exp $ */ /* * Copyright (c) 1997 Marc Horowitz. All rights reserved. @@ -72,15 +72,14 @@ struct ne_pcmcia_softc { int sc_nic_io_window; /* i/o window for NIC */ struct pcmcia_function *sc_pf; /* our PCMCIA function */ void *sc_ih; /* interrupt handle */ - - int sc_resource; /* resrouce alloc'ed */ -#define NE_RES_PCIC 1 -#define NE_RES_IO 2 -#define NE_RES_IOMAP 4 -#define NE_RES_MI 8 }; -static void ne_pcmcia_unmap __P((struct ne_pcmcia_softc *)); +u_int8_t * + ne_pcmcia_get_enaddr __P((struct ne_pcmcia_softc *, int, + u_int8_t [ETHER_ADDR_LEN])); +u_int8_t * + ne_pcmcia_dl10019_get_enaddr __P((struct ne_pcmcia_softc *, + u_int8_t [ETHER_ADDR_LEN])); struct cfattach ne_pcmcia_ca = { sizeof(struct ne_pcmcia_softc), ne_pcmcia_match, ne_pcmcia_attach, @@ -422,15 +421,12 @@ ne_pcmcia_attach(parent, self, aux) struct pcmcia_attach_args *pa = aux; struct pcmcia_config_entry *cfe; struct ne2000dev *ne_dev; - struct pcmcia_mem_handle pcmh; - bus_addr_t offset; - int i, j, mwindow; + int i; u_int8_t myea[6], *enaddr = NULL; void (*npp_init_media) __P((struct dp8390_softc *, int **, int *, int *)); int *media, nmedia, defmedia; const char *typestr = ""; - u_int8_t sum; npp_init_media = NULL; media = NULL; @@ -438,7 +434,6 @@ ne_pcmcia_attach(parent, self, aux) psc->sc_pf = pa->pf; cfe = pa->pf->cfe_head.sqh_first; - psc->sc_resource = 0; #if 0 /* @@ -449,18 +444,14 @@ ne_pcmcia_attach(parent, self, aux) if (cfe->num_memspace != 1) { printf(": unexpected number of memory spaces " " %d should be 1\n", cfe->num_memspace); - return; + goto fail_1; } #endif if (cfe->num_iospace == 1) { if (cfe->iospace[0].length != NE2000_NPORTS) { -#if 0 - printf(": unexpected I/O space configuration\n"); - return; -#else - printf(": unexpected I/O space configuration (continued): "); -#endif + printf(": unexpected I/O space configuration" + " (continued)\n%s", dsc->sc_dev.dv_xname); } } else if (cfe->num_iospace == 2) { /* @@ -472,19 +463,19 @@ ne_pcmcia_attach(parent, self, aux) if ((cfe->iospace[0].length + cfe->iospace[1].length) != NE2000_NPORTS) { printf(": unexpected I/O space configuration\n"); - return; + goto fail_1; } } else { printf(": unexpected number of i/o spaces %d" " should be 1 or 2\n", cfe->num_iospace); + goto fail_1; } if (pcmcia_io_alloc(pa->pf, 0, NE2000_NPORTS, NE2000_NPORTS, &psc->sc_pcioh)) { printf(": can't alloc i/o space\n"); - return; + goto fail_1; } - psc->sc_resource |= NE_RES_IO; dsc->sc_regt = psc->sc_pcioh.iot; dsc->sc_regh = psc->sc_pcioh.ioh; @@ -494,7 +485,7 @@ ne_pcmcia_attach(parent, self, aux) NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS, &nsc->sc_asich)) { printf(": can't get subregion for asic\n"); - goto fail; + goto fail_2; } /* Set up power management hooks. */ @@ -505,28 +496,24 @@ ne_pcmcia_attach(parent, self, aux) pcmcia_function_init(pa->pf, cfe); if (pcmcia_function_enable(pa->pf)) { printf(": function enable failed\n"); - goto fail; + goto fail_2; } - psc->sc_resource |= NE_RES_PCIC; /* some cards claim to be io16, but they're lying. */ if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO8, NE2000_NIC_OFFSET, NE2000_NIC_NPORTS, &psc->sc_pcioh, &psc->sc_nic_io_window)) { printf(": can't map NIC i/o space\n"); - goto fail; + goto fail_3; } if (pcmcia_io_map(pa->pf, PCMCIA_WIDTH_IO16, NE2000_ASIC_OFFSET, NE2000_ASIC_NPORTS, &psc->sc_pcioh, &psc->sc_asic_io_window)) { printf(": can't map ASIC i/o space\n"); - pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window); - goto fail; + goto fail_4; } - psc->sc_resource |= NE_RES_IOMAP; - printf("\n"); /* @@ -535,31 +522,13 @@ ne_pcmcia_attach(parent, self, aux) i = 0; again: for (; i < NE2000_NDEVS; i++) { - if ((ne_dev = ne2000_match(pa->card, pa->pf->number, i)) - != NULL) { + ne_dev = ne2000_match(pa->card, pa->pf->number, i); + if (ne_dev != NULL) { if (ne_dev->enet_maddr >= 0) { - if (pcmcia_mem_alloc(pa->pf, - ETHER_ADDR_LEN * 2, &pcmh)) { - printf("%s: can't alloc mem for" - " enet addr\n", - dsc->sc_dev.dv_xname); - goto fail; - } - if (pcmcia_mem_map(pa->pf, PCMCIA_MEM_ATTR, - ne_dev->enet_maddr, ETHER_ADDR_LEN * 2, - &pcmh, &offset, &mwindow)) { - printf("%s: can't map mem for" - " enet addr\n", - dsc->sc_dev.dv_xname); - pcmcia_mem_free(pa->pf, &pcmh); - goto fail; - } - for (j = 0; j < ETHER_ADDR_LEN; j++) - myea[j] = bus_space_read_1(pcmh.memt, - pcmh.memh, offset + (j * 2)); - pcmcia_mem_unmap(pa->pf, mwindow); - pcmcia_mem_free(pa->pf, &pcmh); - enaddr = myea; + enaddr = ne_pcmcia_get_enaddr(psc, + ne_dev->enet_maddr, myea); + if (enaddr == NULL) + continue; } break; } @@ -567,24 +536,17 @@ again: if (i == NE2000_NDEVS) { printf("%s: can't match ethernet vendor code\n", dsc->sc_dev.dv_xname); - goto fail; + goto fail_5; } if ((ne_dev->flags & NE2000DVF_DL10019) != 0) { -#define PAR0 0x04 - for (j = 0, sum = 0; j < 8; j++) - sum += bus_space_read_1(nsc->sc_asict, nsc->sc_asich, - PAR0 + j); - if (sum != 0xff) { + enaddr = ne_pcmcia_dl10019_get_enaddr(psc, myea); + if (enaddr == NULL) { ++i; goto again; } - for (j = 0; j < ETHER_ADDR_LEN; j++) - myea[j] = bus_space_read_1(nsc->sc_asict, - nsc->sc_asich, PAR0 + j); - enaddr = myea; nsc->sc_type = NE2000_TYPE_DL10019; -#undef PAR0 + typestr = " (DL10019)"; } if (enaddr != NULL) { @@ -622,20 +584,29 @@ again: if (npp_init_media != NULL) (*npp_init_media)(dsc, &media, &nmedia, &defmedia); - ne2000_attach(nsc, enaddr, media, nmedia, defmedia); - psc->sc_resource |= NE_RES_MI; + if (ne2000_attach(nsc, enaddr, media, nmedia, defmedia)) + goto fail_5; pcmcia_function_disable(pa->pf); - psc->sc_resource &= ~NE_RES_PCIC; return; -fail: - /* ne_pcmcia_unmap() takes care of NE_RES_IO and NE_RES_IOMAP */ - ne_pcmcia_unmap(psc); - if (psc->sc_resource & NE_RES_PCIC) { - pcmcia_function_disable(pa->pf); - psc->sc_resource &= ~NE_RES_PCIC; - } + fail_5: + /* Unmap ASIC i/o windows. */ + pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window); + + fail_4: + /* Unmap NIC i/o windows. */ + pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window); + + fail_3: + pcmcia_function_disable(pa->pf); + + fail_2: + /* Free our i/o space. */ + pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh); + + fail_1: + psc->sc_nic_io_window = -1; } int @@ -644,17 +615,24 @@ ne_pcmcia_detach(self, flags) int flags; { struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)self; - int rv; + int error; - if ((psc->sc_resource & NE_RES_MI) != 0) { - rv = ne2000_detach(&psc->sc_ne2000, flags); - psc->sc_resource &= ~NE_RES_MI; - } else - rv = 0; - if (rv == 0) - ne_pcmcia_unmap(psc); + if (psc->sc_nic_io_window == -1) + /* Nothing to detach. */ + return (0); - return rv; + error = ne2000_detach(&psc->sc_ne2000, flags); + if (error != 0) + return (error); + + /* Unmap our i/o windows. */ + pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window); + pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window); + + /* Free our i/o space. */ + pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh); + + return (0); } int @@ -662,7 +640,6 @@ ne_pcmcia_enable(dsc) struct dp8390_softc *dsc; { struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc; - int rv; /* set up the interrupt */ psc->sc_ih = pcmcia_intr_establish(psc->sc_pf, IPL_NET, dp8390_intr, @@ -670,12 +647,18 @@ ne_pcmcia_enable(dsc) if (psc->sc_ih == NULL) { printf("%s: couldn't establish interrupt\n", dsc->sc_dev.dv_xname); - return (1); + goto fail_1; } - rv = pcmcia_function_enable(psc->sc_pf); - psc->sc_resource |= NE_RES_PCIC; - return (rv); + if (pcmcia_function_enable(psc->sc_pf)) + goto fail_2; + + return (0); + + fail_2: + pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih); + fail_1: + return (1); } void @@ -685,25 +668,66 @@ ne_pcmcia_disable(dsc) struct ne_pcmcia_softc *psc = (struct ne_pcmcia_softc *)dsc; pcmcia_function_disable(psc->sc_pf); - psc->sc_resource &= ~NE_RES_PCIC; - pcmcia_intr_disestablish(psc->sc_pf, psc->sc_ih); } -static void -ne_pcmcia_unmap(psc) +u_int8_t * +ne_pcmcia_get_enaddr(psc, maddr, myea) struct ne_pcmcia_softc *psc; + int maddr; + u_int8_t myea[ETHER_ADDR_LEN]; { - if ((psc->sc_resource & NE_RES_IOMAP) != 0) { - /* Unmap our i/o windows. */ - pcmcia_io_unmap(psc->sc_pf, psc->sc_asic_io_window); - pcmcia_io_unmap(psc->sc_pf, psc->sc_nic_io_window); - } - psc->sc_resource &= ~NE_RES_IOMAP; + struct ne2000_softc *nsc = &psc->sc_ne2000; + struct dp8390_softc *dsc = &nsc->sc_dp8390; + struct pcmcia_mem_handle pcmh; + bus_addr_t offset; + u_int8_t *enaddr = NULL; + int j, mwindow; - if ((psc->sc_resource & NE_RES_IO) != 0) { - /* Free our i/o space. */ - pcmcia_io_free(psc->sc_pf, &psc->sc_pcioh); + if (maddr < 0) + return (NULL); + + if (pcmcia_mem_alloc(psc->sc_pf, ETHER_ADDR_LEN * 2, &pcmh)) { + printf("%s: can't alloc mem for enet addr\n", + dsc->sc_dev.dv_xname); + goto fail_1; } - psc->sc_resource &= ~NE_RES_IO; + if (pcmcia_mem_map(psc->sc_pf, PCMCIA_MEM_ATTR, maddr, + ETHER_ADDR_LEN * 2, &pcmh, &offset, &mwindow)) { + printf("%s: can't map mem for enet addr\n", + dsc->sc_dev.dv_xname); + goto fail_2; + } + for (j = 0; j < ETHER_ADDR_LEN; j++) + myea[j] = bus_space_read_1(pcmh.memt, pcmh.memh, + offset + (j * 2)); + enaddr = myea; + + pcmcia_mem_unmap(psc->sc_pf, mwindow); + fail_2: + pcmcia_mem_free(psc->sc_pf, &pcmh); + fail_1: + return (enaddr); +} + +u_int8_t * +ne_pcmcia_dl10019_get_enaddr(psc, myea) + struct ne_pcmcia_softc *psc; + u_int8_t myea[ETHER_ADDR_LEN]; +{ + struct ne2000_softc *nsc = &psc->sc_ne2000; + u_int8_t sum; + int j; + +#define PAR0 0x04 + for (j = 0, sum = 0; j < 8; j++) + sum += bus_space_read_1(nsc->sc_asict, nsc->sc_asich, + PAR0 + j); + if (sum != 0xff) + return (NULL); + for (j = 0; j < ETHER_ADDR_LEN; j++) + myea[j] = bus_space_read_1(nsc->sc_asict, + nsc->sc_asich, PAR0 + j); +#undef PAR0 + return (myea); }