Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci - Allocate control structures at attach time rat...



details:   https://anonhg.NetBSD.org/src/rev/7e3cb9e93532
branches:  trunk
changeset: 515242:7e3cb9e93532
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Thu Sep 20 10:04:10 2001 +0000

description:
- Allocate control structures at attach time rather than at init time.
  Avoids using bus_dmamem_alloc/bus_dmamem_map at interrupt time.
  Should fix PRs kern/13924 and kern/13979 from dive%endersgame.net@localhost
- while I'm there convert to use ether_ioctl.

diffstat:

 sys/dev/pci/if_tl.c    |  178 +++++++++++-------------------------------------
 sys/dev/pci/if_tlvar.h |    3 +-
 2 files changed, 45 insertions(+), 136 deletions(-)

diffs (294 lines):

diff -r 61c9f94fd14f -r 7e3cb9e93532 sys/dev/pci/if_tl.c
--- a/sys/dev/pci/if_tl.c       Thu Sep 20 08:25:59 2001 +0000
+++ b/sys/dev/pci/if_tl.c       Thu Sep 20 10:04:10 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tl.c,v 1.45 2001/08/07 16:53:06 bouyer Exp $        */
+/*     $NetBSD: if_tl.c,v 1.46 2001/09/20 10:04:10 bouyer Exp $        */
 
 /* XXX ALTQ XXX */
 
@@ -128,7 +128,8 @@
 
 static void tl_ifstart __P((struct ifnet *));
 static void tl_reset __P((tl_softc_t*));
-static int  tl_init __P((tl_softc_t*));
+static int  tl_init __P((struct ifnet *));
+static void tl_stop __P((struct ifnet *, int));
 static void tl_restart __P((void  *));
 static int  tl_add_RxBuff __P((tl_softc_t*, struct Rx_list*, struct mbuf*));
 static void tl_read_stats __P((tl_softc_t*));
@@ -399,12 +400,23 @@
        sc->Rx_list = NULL;
        sc->Tx_list = NULL;
 
+       /* allocate DMA-safe memory for control structs */
+       if (bus_dmamem_alloc(sc->tl_dmatag,
+               PAGE_SIZE, 0, PAGE_SIZE,
+               &sc->ctrl_segs, 1, &sc->ctrl_nsegs, BUS_DMA_NOWAIT) != 0 ||
+           bus_dmamem_map(sc->tl_dmatag, &sc->ctrl_segs,
+               sc->ctrl_nsegs, PAGE_SIZE, (caddr_t*)&sc->ctrl,
+               BUS_DMA_NOWAIT | BUS_DMA_COHERENT) != 0) {
+                       printf("%s: can't allocate DMA memory for lists\n",
+                           sc->sc_dev.dv_xname);
+                       return;
+       }
        /*
         * Add shutdown hook so that DMA is disabled prior to reboot. Not
         * doing do could allow DMA to corrupt kernel memory during the
         * reboot before the driver initializes.
         */
-       (void) shutdownhook_establish(tl_shutdown, sc);
+       (void) shutdownhook_establish(tl_shutdown, ifp);
 
        /*
         * Initialize our media structures and probe the MII.
@@ -435,6 +447,8 @@
        ifp->if_ioctl = tl_ifioctl;
        ifp->if_start = tl_ifstart;
        ifp->if_watchdog = tl_ifwatchdog;
+       ifp->if_init = tl_init;
+       ifp->if_stop = tl_stop;
        ifp->if_timer = 0;
        if_attach(ifp);
        ether_ifattach(&(sc)->tl_if, (sc)->tl_enaddr);
@@ -484,11 +498,18 @@
 static void tl_shutdown(v)
        void *v;
 {
-       tl_softc_t *sc = v;
+       tl_stop(v, 1);
+}
+
+static void tl_stop(ifp, disable)
+       struct ifnet *ifp;
+       int disable;
+{
+       tl_softc_t *sc = ifp->if_softc;
        struct Tx_list *Tx;
        int i;
        
-       if ((sc->tl_if.if_flags & IFF_RUNNING) == 0)
+       if ((ifp->if_flags & IFF_RUNNING) == 0)
                return;
        /* disable interrupts */
        TL_HR_WRITE(sc, TL_HOST_CMD, HOST_CMD_IntOff);
@@ -536,10 +557,10 @@
                sc->Tx_list = NULL;
                bus_dmamap_unload(sc->tl_dmatag, sc->Tx_dmamap);
                bus_dmamap_destroy(sc->tl_dmatag, sc->Tx_dmamap);
-               bus_dmamem_free(sc->tl_dmatag, &sc->ctrl_segs, sc->ctrl_nsegs);
                sc->hw_Tx_list = NULL;
        }
-       sc->tl_if.if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+       ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
+       ifp->if_timer = 0;
        sc->tl_mii.mii_media_status &= ~IFM_ACTIVE;
 }
 
@@ -549,18 +570,17 @@
        tl_init(v);
 }
 
-static int tl_init(sc)
-       tl_softc_t *sc;
+static int tl_init(ifp)
+       struct ifnet *ifp;
 {
-       struct ifnet *ifp = &sc->tl_if;
+       tl_softc_t *sc = ifp->if_softc;
        int i, s, error;
        char *errstring;
-       char *ctrl;
        char *nullbuf;
 
        s = splnet();
        /* cancel any pending IO */
-       tl_shutdown(sc);
+       tl_stop(ifp, 1);
        tl_reset(sc);
        if ((sc->tl_if.if_flags & IFF_UP) == 0) {
                splx(s);
@@ -616,21 +636,11 @@
                errstring = "can't allocate DMA maps for lists";
                goto bad;
        }
-       error = bus_dmamem_alloc(sc->tl_dmatag,
-           PAGE_SIZE, 0, PAGE_SIZE,
-           &sc->ctrl_segs, 1, &sc->ctrl_nsegs, BUS_DMA_NOWAIT);
-       if (error == 0)
-               error = bus_dmamem_map(sc->tl_dmatag, &sc->ctrl_segs,
-                   sc->ctrl_nsegs, PAGE_SIZE, (caddr_t*)&ctrl,
-                   BUS_DMA_WAITOK | BUS_DMA_COHERENT);
-       if (error) {
-               errstring = "can't allocate DMA memory for lists";
-               goto bad;
-       }
-       memset(ctrl, 0, PAGE_SIZE);
-       sc->hw_Rx_list = (void*)ctrl;
-       sc->hw_Tx_list = (void*)(ctrl + sizeof(struct tl_Rx_list) * TL_NBUF);
-       nullbuf = ctrl + sizeof(struct tl_Rx_list) * TL_NBUF +
+       memset(sc->ctrl, 0, PAGE_SIZE);
+       sc->hw_Rx_list = (void *)sc->ctrl;
+       sc->hw_Tx_list =
+           (void *)(sc->ctrl + sizeof(struct tl_Rx_list) * TL_NBUF);
+       nullbuf = sc->ctrl + sizeof(struct tl_Rx_list) * TL_NBUF +
            sizeof(struct tl_Tx_list) * TL_NBUF;
        error = bus_dmamap_load(sc->tl_dmatag, sc->Rx_dmamap,
            sc->hw_Rx_list, sizeof(struct tl_Rx_list) * TL_NBUF, NULL,
@@ -710,7 +720,6 @@
        return 0;
 bad:
        printf("%s: %s\n", sc->sc_dev.dv_xname, errstring);
-       sc->tl_if.if_flags &= ~IFF_UP;
        splx(s);
        return error;
 }
@@ -1187,117 +1196,16 @@
        
        s = splnet();
        switch(cmd) {
-       case SIOCSIFADDR: {
-               struct ifaddr *ifa = (struct ifaddr *)data;
-               sc->tl_if.if_flags |= IFF_UP;
-               if ((error = tl_init(sc)) != NULL) {
-                       sc->tl_if.if_flags &= ~IFF_UP;
-                       break;
-               }
-               switch (ifa->ifa_addr->sa_family) {
-#ifdef INET
-               case AF_INET:
-                       arp_ifinit(ifp, ifa);
-                       break;
-#endif
-#ifdef NS
-               case AF_NS: {
-                       struct ns_addr *ina = &IA_SNS(ifa)->sns_addr;
-
-                       if (ns_nullhost(*ina))
-                               ina->x_host  = 
-                                   *(union ns_host*) LLADDR(ifp->if_sadl);
-                       else
-                               memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host,
-                                       ifp->if_addrlen);
-                       break;
-               }
-#endif
-               default:
-                       break;
-               }
-       break;
-       }
-       case SIOCSIFFLAGS:
-       {
-               u_int8_t reg;
-               /*
-                * If interface is marked up and not running, then start it.
-                * If it is marked down and running, stop it.
-                */
-               if (ifp->if_flags & IFF_UP) {
-                       if ((ifp->if_flags & IFF_RUNNING) == 0) {
-                               error = tl_init(sc);
-                               /* all flags have been handled by init */
-                               break;
-                       }
-                       error = 0;
-                       reg = tl_intreg_read_byte(sc,
-                           TL_INT_NET + TL_INT_NetCmd);
-                       if (ifp->if_flags & IFF_PROMISC)
-                               reg |= TL_NETCOMMAND_CAF;
-                       else
-                               reg &= ~TL_NETCOMMAND_CAF;
-                       tl_intreg_write_byte(sc, TL_INT_NET + TL_INT_NetCmd,
-                           reg);
-#ifdef TL_PRIV_STATS
-                       if (ifp->if_flags & IFF_LINK0) {
-                               ifp->if_flags &= ~IFF_LINK0;
-                               printf("%s errors statistics\n",
-                                   sc->sc_dev.dv_xname);
-                               printf("    %4d RX buffer overrun\n",
-                                   sc->ierr_overr);
-                               printf("    %4d RX code error\n",
-                                   sc->ierr_code);
-                               printf("    %4d RX crc error\n",
-                                   sc->ierr_crc);
-                               printf("    %4d RX out of memory\n",
-                                   sc->ierr_nomem);
-                               printf("    %4d TX buffer underrun\n",
-                                   sc->oerr_underr);
-                               printf("    %4d TX deffered frames\n",
-                                   sc->oerr_deffered);
-                               printf("    %4d TX single collisions\n",
-                                   sc->oerr_coll);
-                               printf("    %4d TX multi collisions\n",
-                                   sc->oerr_multicoll);
-                               printf("    %4d TX exessive collisions\n",
-                                   sc->oerr_exesscoll);
-                               printf("    %4d TX late collisions\n",
-                                   sc->oerr_latecoll);
-                               printf("    %4d TX carrier loss\n",
-                                   sc->oerr_carrloss);
-                               printf("    %4d TX mbuf copy\n",
-                                   sc->oerr_mcopy);
-                       }
-#endif
-               } else {
-                       if (ifp->if_flags & IFF_RUNNING)
-                               tl_shutdown(sc);
-                       error = 0;
-               }
-               break;
-       }
-       case SIOCADDMULTI:
-       case SIOCDELMULTI:
-               /*
-                * Update multicast listeners
-                */
-               if (cmd == SIOCADDMULTI)
-                       error = ether_addmulti(ifr, &sc->tl_ec);
-               else
-                       error = ether_delmulti(ifr, &sc->tl_ec);
-               if (error == ENETRESET) {
-                       tl_addr_filter(sc);
-                       error = 0;
-               }
-               break;
        case SIOCSIFMEDIA:
        case SIOCGIFMEDIA:
                error = ifmedia_ioctl(ifp, ifr, &sc->tl_mii.mii_media, cmd);
                break;
        default:
-               error = EINVAL;
+               error = ether_ioctl(ifp, cmd, data);
+               if (error == ENETRESET) {
+                       tl_addr_filter(sc);
+                       error = 0;
+               }
        }
        splx(s);
        return error;
@@ -1488,7 +1396,7 @@
                return;
        printf("%s: device timeout\n", sc->sc_dev.dv_xname);
        ifp->if_oerrors++;
-       tl_init(sc);
+       tl_init(ifp);
 }
 
 static int
diff -r 61c9f94fd14f -r 7e3cb9e93532 sys/dev/pci/if_tlvar.h
--- a/sys/dev/pci/if_tlvar.h    Thu Sep 20 08:25:59 2001 +0000
+++ b/sys/dev/pci/if_tlvar.h    Thu Sep 20 10:04:10 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_tlvar.h,v 1.6 2001/08/06 19:20:26 bouyer Exp $      */
+/*     $NetBSD: if_tlvar.h,v 1.7 2001/09/20 10:04:10 bouyer Exp $      */
 
 /*
  * Copyright (c) 1997 Manuel Bouyer.  All rights reserved.
@@ -56,6 +56,7 @@
        mii_data_t tl_mii;              /* mii bus */
        bus_dma_segment_t ctrl_segs; /* bus-dma memory for control blocks */
        int ctrl_nsegs;
+       char *ctrl;                     /* vaddr for ctrl_segs */
        struct Rx_list *Rx_list;        /* Receive and transmit lists */
        struct tl_Rx_list *hw_Rx_list;  /* and assocoated hw descriptor */
        bus_dmamap_t Rx_dmamap;         /* and associated DMA maps */



Home | Main Index | Thread Index | Old Index