IBM T42 freezes when going to sleep under X11
Gleb Smirnoff
glebius at FreeBSD.org
Sat Dec 3 08:53:02 GMT 2005
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
-------------- next part --------------
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
More information about the freebsd-mobile
mailing list