i386/59806: [patch] Suspend/resume breaks em0

Peter Schuller peter.schuller at infidyne.com
Sat Nov 29 14:50:26 PST 2003


>Number:         59806
>Category:       i386
>Synopsis:       [patch] Suspend/resume breaks em0
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-i386
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 29 14:50:22 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Peter Schuller
>Release:        FreeBSD 5.2-BETA i386
>Organization:
InfiDyne Technologies
>Environment:
System: FreeBSD thunderbolt.scode.org 5.2-BETA FreeBSD 5.2-BETA #2: Sat Nov 29 
22:26:11 CET 2003 
scode at thunderbolt.scode.org:/usr/obj/usr/src/sys/THUNDERBOLT-APM i386


        IBM T40p laptop with:

        m0 at pci2:1:0:   class=0x020000 card=0x05491014 chip=0x101e8086 rev=0x03 
hdr=0x00
            vendor   = 'Intel Corporation'
            device   = '82540EP Gigabit Ethernet Controller (Mobile)'
            class    = network
            subclass = ethernet

>Description:
        On my laptop the em0 device breaks after an APM suspend/resume
        cycle, in that no traffic is seemingly received/transmitted.
        After a while, I get a kernel panic saying the em0 mutex
        is not owned. It is trigged at line 1608 (pre-patch) in
        if_em.c in em_stop():

                mtx_assert(&adapter->mtx, MA_OWNED);
        
        This behavior *may* be triggered by the activities of 'dhclient',
        controlling the interface at the time of the suspend/resume
        and afterwords.

>How-To-Repeat:
        Enable APM and disable ACPI on a T40p and attempt a suspend/resume
        with the ethernet cable inserted and dhclient running on em0.
>Fix:

The following patch is my attempt at adding suspend/resume support to
the driver. It works and solved the problem on my machine, but I have
not tested the modified driver on any other machine.

Also, if this is considered for inclusion in CURRENT, please be
aware that I have no past experience with network device
drivers and this is my first attempt at making any kind of
kernel modification, so I am not making any claims as to the
correctness of this patch beyond the fact that it works for me
on my particular machine and under my particular circumstances.

*** sys/dev/em/if_em.c.old      Sat Nov 29 21:33:34 2003
--- sys/dev/em/if_em.c  Sat Nov 29 22:58:17 2003
***************
*** 125,130 ****
--- 125,132 ----
  static void em_init(void *);
  static void em_init_locked(struct adapter *);
  static void em_stop(void *);
+ static int  em_suspend(device_t);
+ static int  em_resume(device_t);
  static void em_media_status(struct ifnet *, struct ifmediareq *);
  static int  em_media_change(struct ifnet *);
  static void em_identify_hardware(struct adapter *);
***************
*** 193,198 ****
--- 195,202 ----
        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}
  };
  
***************
*** 1622,1627 ****
--- 1626,1664 ----
        return;
  }
  
+ /*********************************************************************
+ *
+ * Prepares the interface for suspend by stopping it.
+ *
+ ***********************************************************************/
+ 
+ static int
+ em_suspend(device_t dev)
+ {
+         struct adapter *adapter = device_get_softc(dev);
+         EM_LOCK(adapter);
+         em_stop(adapter);
+         EM_UNLOCK(adapter);
+         return(0);
+ }
+ 
+ /*********************************************************************
+ *
+ * Reinitializes the interface (called when resuming from suspended
+ * state).
+ *
+ ***********************************************************************/
+ 
+ static int
+ em_resume(device_t dev)
+ {
+         struct adapter *adapter = device_get_softc(dev);
+ 
+         EM_LOCK(adapter);
+         em_init_locked(adapter);
+         EM_UNLOCK(adapter);
+         return(0);
+ }
  
  /*********************************************************************
   *
-- 
/ Peter Schuller, InfiDyne Technologies HB

PGP userID: 0xE9758B7D or 'Peter Schuller <peter.schuller at infidyne.com>'
Key retrieval: Send an E-Mail to getpgpkey at scode.org
E-Mail: peter.schuller at infidyne.com Web: http://www.scode.org


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-i386 mailing list