On Fri, Dec 02, 2005 at 12:52:58PM -0800, George Hartzell wrote:
G>  > I finally found the cause of my problems: there has been changes in
G>  > the em driver (Gb ethernet), such that the machine freezes when trying
G>  > to switch automatically from the X11 VT to the system console, before
G>  > going to sleep. The interaction is surprising, but clearly the problem
G>  > disappears when I remove "device em" from the kernel configuration,
G>  > and it reappears when I do "kldload if_em". Since I'm using only ath
G>  > (wireless) anyway, this is fine with me...
G>  > 
G>  > A previous partial solution suggested to me was to add
G>  >   hw.syscons.sc_no_suspend_vtswitch=1
G>  > to sysctl.conf, but this means the screen gets garbled and I have to
G>  > do the switch by hand anyway, which is a real pain.
G>  > Worse still: the machine would still freeze when going to sleep while
G>  > the disk is active.
G>  > 
G>  > The last step is to track down the bug in em, as it still seems to
G>  > be there in yesterday's STABLE.
G> 
G> I don't seem to have any problem with my T42p using a kernel compiled
G> on 11/29 11:21
G> 
G> My copy of if_em.c is:
G> 
G> /*$FreeBSD: src/sys/dev/em/if_em.c,v 1.65.2.8 2005/11/25 14:11:59 glebius 
Exp $*/

George, Jacques,

what em(4) cards exactly do you have?

pciconf -lv | grep -A4 ^em

Can you please try the attached patch?

-- 
Totus tuus, Glebius.
GLEBIUS-RIPN GLEB-RIPE
Index: if_em.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/em/if_em.c,v
retrieving revision 1.85
diff -u -r1.85 if_em.c
--- if_em.c     10 Nov 2005 11:44:37 -0000      1.85
+++ if_em.c     11 Nov 2005 12:13:48 -0000
@@ -129,8 +129,11 @@
 static int  em_attach(device_t);
 static int  em_detach(device_t);
 static int  em_shutdown(device_t);
+static int  em_suspend(device_t);
+static int  em_resume(device_t);
 static void em_intr(void *);
 static void em_start(struct ifnet *);
+static void em_start_locked(struct ifnet *ifp);
 static int  em_ioctl(struct ifnet *, u_long, caddr_t);
 static void em_watchdog(struct ifnet *);
 static void em_init(void *);
@@ -208,6 +211,8 @@
        DEVMETHOD(device_attach, em_attach),
        DEVMETHOD(device_detach, em_detach),
        DEVMETHOD(device_shutdown, em_shutdown),
+       DEVMETHOD(device_suspend, em_suspend),
+       DEVMETHOD(device_resume, em_resume),
        {0, 0}
 };
 
@@ -580,6 +585,41 @@
        return(0);
 }
 
+/*
+ * Suspend/resume device methods.
+ */
+static int
+em_suspend(device_t dev)
+{
+       struct adapter *adapter = device_get_softc(dev);
+
+       EM_LOCK(adapter);
+       em_stop(adapter);
+       EM_UNLOCK(adapter);
+
+       return bus_generic_suspend(dev);
+}
+
+static int
+em_resume(device_t dev)
+{
+       struct adapter *adapter = device_get_softc(dev);
+       struct ifnet *ifp;
+
+       EM_LOCK(adapter);
+       ifp = adapter->ifp;
+       if (ifp->if_flags & IFF_UP) {
+               em_init_locked(adapter);
+               if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+                       em_start_locked(ifp);
+       }
+
+       em_init_locked(adapter);
+       EM_UNLOCK(adapter);
+
+       return bus_generic_resume(dev);
+}
+
 
 /*********************************************************************
  *  Transmit entry point
_______________________________________________
freebsd-stable@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-stable
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to