Author: jhb
Date: Tue Jan 18 16:27:40 2011
New Revision: 217542
URL: http://svn.freebsd.org/changeset/base/217542

Log:
  Fix some bugs in my last set of changes to ale(4):
  - Remove extra unlock from end of ale_start_locked().
  - Expand scope of locking in interrupt handler.
  - Move ether_ifdetach() earlier and retire now-unneeded DETACH flag.
  
  Tested by:    Aryeh Friedman
  Reviewed by:  yongari (earlier version)

Modified:
  head/sys/dev/ale/if_ale.c
  head/sys/dev/ale/if_alevar.h

Modified: head/sys/dev/ale/if_ale.c
==============================================================================
--- head/sys/dev/ale/if_ale.c   Tue Jan 18 15:49:01 2011        (r217541)
+++ head/sys/dev/ale/if_ale.c   Tue Jan 18 16:27:40 2011        (r217542)
@@ -675,14 +675,13 @@ ale_detach(device_t dev)
 
        ifp = sc->ale_ifp;
        if (device_is_attached(dev)) {
+               ether_ifdetach(ifp);
                ALE_LOCK(sc);
-               sc->ale_flags |= ALE_FLAG_DETACH;
                ale_stop(sc);
                ALE_UNLOCK(sc);
                callout_drain(&sc->ale_tick_ch);
                taskqueue_drain(sc->ale_tq, &sc->ale_int_task);
                taskqueue_drain(taskqueue_swi, &sc->ale_link_task);
-               ether_ifdetach(ifp);
        }
 
        if (sc->ale_tq != NULL) {
@@ -1907,8 +1906,6 @@ ale_start_locked(struct ifnet *ifp)
                /* Set a timeout in case the chip goes out to lunch. */
                sc->ale_watchdog_timer = ALE_TX_TIMEOUT;
        }
-
-       ALE_UNLOCK(sc);
 }
 
 static void
@@ -1972,8 +1969,7 @@ ale_ioctl(struct ifnet *ifp, u_long cmd,
                                    & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
                                        ale_rxfilter(sc);
                        } else {
-                               if ((sc->ale_flags & ALE_FLAG_DETACH) == 0)
-                                       ale_init_locked(sc);
+                               ale_init_locked(sc);
                        }
                } else {
                        if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
@@ -2284,6 +2280,7 @@ ale_int_task(void *arg, int pending)
        sc = (struct ale_softc *)arg;
 
        status = CSR_READ_4(sc, ALE_INTR_STATUS);
+       ALE_LOCK(sc);
        if (sc->ale_morework != 0)
                status |= INTR_RX_PKT;
        if ((status & ALE_INTRS) == 0)
@@ -2299,7 +2296,6 @@ ale_int_task(void *arg, int pending)
                if (more == EAGAIN)
                        sc->ale_morework = 1;
                else if (more == EIO) {
-                       ALE_LOCK(sc);
                        sc->ale_stats.reset_brk_seq++;
                        ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
                        ale_init_locked(sc);
@@ -2314,7 +2310,6 @@ ale_int_task(void *arg, int pending)
                        if ((status & INTR_DMA_WR_TO_RST) != 0)
                                device_printf(sc->ale_dev,
                                    "DMA write error! -- resetting\n");
-                       ALE_LOCK(sc);
                        ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
                        ale_init_locked(sc);
                        ALE_UNLOCK(sc);
@@ -2326,11 +2321,14 @@ ale_int_task(void *arg, int pending)
 
        if (more == EAGAIN ||
            (CSR_READ_4(sc, ALE_INTR_STATUS) & ALE_INTRS) != 0) {
+               ALE_UNLOCK(sc);
                taskqueue_enqueue(sc->ale_tq, &sc->ale_int_task);
                return;
        }
 
 done:
+       ALE_UNLOCK(sc);
+
        /* Re-enable interrupts. */
        CSR_WRITE_4(sc, ALE_INTR_STATUS, 0x7FFFFFFF);
 }
@@ -2587,7 +2585,9 @@ ale_rxeof(struct ale_softc *sc, int coun
                }
 
                /* Pass it to upper layer. */
+               ALE_UNLOCK(sc);
                (*ifp->if_input)(ifp, m);
+               ALE_LOCK(sc);
 
                ale_rx_update_page(sc, &rx_page, length, &prod);
        }

Modified: head/sys/dev/ale/if_alevar.h
==============================================================================
--- head/sys/dev/ale/if_alevar.h        Tue Jan 18 15:49:01 2011        
(r217541)
+++ head/sys/dev/ale/if_alevar.h        Tue Jan 18 16:27:40 2011        
(r217542)
@@ -206,7 +206,6 @@ struct ale_softc {
 #define        ALE_FLAG_RXCSUM_BUG     0x0080
 #define        ALE_FLAG_TXCSUM_BUG     0x0100
 #define        ALE_FLAG_TXCMB_BUG      0x0200
-#define        ALE_FLAG_DETACH         0x4000
 #define        ALE_FLAG_LINK           0x8000
 
        struct callout          ale_tick_ch;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to