From peter.schuller@infidyne.com  Sat Nov 29 14:42:31 2003
Return-Path: <peter.schuller@infidyne.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 1885F16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 29 Nov 2003 14:42:31 -0800 (PST)
Received: from scode.mine.nu (c-cede71d5.05-152-7570701.cust.bredbandsbolaget.se [213.113.222.206])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 979FE43FBD
	for <FreeBSD-gnats-submit@freebsd.org>; Sat, 29 Nov 2003 14:42:29 -0800 (PST)
	(envelope-from peter.schuller@infidyne.com)
Received: from localhost (localhost [127.0.0.1])
	by scode.mine.nu (Postfix) with ESMTP
	id 099DE65C31; Sat, 29 Nov 2003 23:47:34 +0100 (CET)
Message-Id: <200311292347.33406.peter.schuller@infidyne.com>
Date: Sat, 29 Nov 2003 23:47:33 +0100
From: Peter Schuller <peter.schuller@infidyne.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc: peter.schuller@infidyne.com
Subject: [patch] Suspend/resume breaks em0

>Number:         59806
>Category:       kern
>Synopsis:       [em] [patch] Suspend/resume breaks em0
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 29 14:50:22 PST 2003
>Closed-Date:    Fri Apr 07 08:54:09 GMT 2006
>Last-Modified:  Fri Apr 07 08:54:09 GMT 2006
>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@thunderbolt.scode.org:/usr/obj/usr/src/sys/THUNDERBOLT-APM i386


        IBM T40p laptop with:

        m0@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@infidyne.com>'
Key retrieval: Send an E-Mail to getpgpkey@scode.org
E-Mail: peter.schuller@infidyne.com Web: http://www.scode.org


>Release-Note:
>Audit-Trail:

From: Peter Schuller <peter.schuller@infidyne.com>
To: freebsd-gnats-submit@FreeBSD.org, peter.schuller@infidyne.com
Cc:  
Subject: Re: i386/59806: [patch] Suspend/resume breaks em0
Date: Sun, 30 Nov 2003 06:59:54 +0100

 Sorry, I'm afraid I munched the indentation with cut'n'paste. Here's the 
 patch, uuencoded.
 
 begin-base64 644 patch-59806
 KioqIHN5cy9kZXYvZW0vaWZfZW0uYy5vbGQJU2F0IE5vdiAyOSAyMTozMzoz
 NCAyMDAzCi0tLSBzeXMvZGV2L2VtL2lmX2VtLmMJU2F0IE5vdiAyOSAyMjo1
 ODoxNyAyMDAzCioqKioqKioqKioqKioqKgoqKiogMTI1LDEzMCAqKioqCi0t
 LSAxMjUsMTMyIC0tLS0KICBzdGF0aWMgdm9pZCBlbV9pbml0KHZvaWQgKik7
 CiAgc3RhdGljIHZvaWQgZW1faW5pdF9sb2NrZWQoc3RydWN0IGFkYXB0ZXIg
 Kik7CiAgc3RhdGljIHZvaWQgZW1fc3RvcCh2b2lkICopOworIHN0YXRpYyBp
 bnQgIGVtX3N1c3BlbmQoZGV2aWNlX3QpOworIHN0YXRpYyBpbnQgIGVtX3Jl
 c3VtZShkZXZpY2VfdCk7CiAgc3RhdGljIHZvaWQgZW1fbWVkaWFfc3RhdHVz
 KHN0cnVjdCBpZm5ldCAqLCBzdHJ1Y3QgaWZtZWRpYXJlcSAqKTsKICBzdGF0
 aWMgaW50ICBlbV9tZWRpYV9jaGFuZ2Uoc3RydWN0IGlmbmV0ICopOwogIHN0
 YXRpYyB2b2lkIGVtX2lkZW50aWZ5X2hhcmR3YXJlKHN0cnVjdCBhZGFwdGVy
 ICopOwoqKioqKioqKioqKioqKioKKioqIDE5MywxOTggKioqKgotLS0gMTk1
 LDIwMiAtLS0tCiAgCURFVk1FVEhPRChkZXZpY2VfYXR0YWNoLCBlbV9hdHRh
 Y2gpLAogIAlERVZNRVRIT0QoZGV2aWNlX2RldGFjaCwgZW1fZGV0YWNoKSwK
 ICAJREVWTUVUSE9EKGRldmljZV9zaHV0ZG93biwgZW1fc2h1dGRvd24pLAor
 IAlERVZNRVRIT0QoZGV2aWNlX3N1c3BlbmQsIGVtX3N1c3BlbmQpLAorIAlE
 RVZNRVRIT0QoZGV2aWNlX3Jlc3VtZSwgZW1fcmVzdW1lKSwKICAJezAsIDB9
 CiAgfTsKICAKKioqKioqKioqKioqKioqCioqKiAxNjIyLDE2MjcgKioqKgot
 LS0gMTYyNiwxNjY0IC0tLS0KICAJcmV0dXJuOwogIH0KICAKKyAvKioqKioq
 KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
 KioqKioqKioqKioqKioqKioqCisgKgorICogUHJlcGFyZXMgdGhlIGludGVy
 ZmFjZSBmb3Igc3VzcGVuZCBieSBzdG9wcGluZyBpdC4KKyAqCisgKioqKioq
 KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
 KioqKioqKioqKioqKioqKioqKiovCisgCisgc3RhdGljIGludAorIGVtX3N1
 c3BlbmQoZGV2aWNlX3QgZGV2KQorIHsKKyAgICAgICAgIHN0cnVjdCBhZGFw
 dGVyICphZGFwdGVyID0gZGV2aWNlX2dldF9zb2Z0YyhkZXYpOworICAgICAg
 ICAgRU1fTE9DSyhhZGFwdGVyKTsKKyAgICAgICAgIGVtX3N0b3AoYWRhcHRl
 cik7CisgICAgICAgICBFTV9VTkxPQ0soYWRhcHRlcik7CisgICAgICAgICBy
 ZXR1cm4oMCk7CisgfQorIAorIC8qKioqKioqKioqKioqKioqKioqKioqKioq
 KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioK
 KyAqCisgKiBSZWluaXRpYWxpemVzIHRoZSBpbnRlcmZhY2UgKGNhbGxlZCB3
 aGVuIHJlc3VtaW5nIGZyb20gc3VzcGVuZGVkCisgKiBzdGF0ZSkuCisgKgor
 ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
 KioqKioqKioqKioqKioqKioqKioqKioqKioqLworIAorIHN0YXRpYyBpbnQK
 KyBlbV9yZXN1bWUoZGV2aWNlX3QgZGV2KQorIHsKKyAgICAgICAgIHN0cnVj
 dCBhZGFwdGVyICphZGFwdGVyID0gZGV2aWNlX2dldF9zb2Z0YyhkZXYpOwor
 IAorICAgICAgICAgRU1fTE9DSyhhZGFwdGVyKTsKKyAgICAgICAgIGVtX2lu
 aXRfbG9ja2VkKGFkYXB0ZXIpOworICAgICAgICAgRU1fVU5MT0NLKGFkYXB0
 ZXIpOworICAgICAgICAgcmV0dXJuKDApOworIH0KICAKICAvKioqKioqKioq
 KioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq
 KioqKioqKioqKioqKioqCiAgICoK
 ====
 
 -- 
 / Peter Schuller, InfiDyne Technologies HB
 
 PGP userID: 0xE9758B7D or 'Peter Schuller <peter.schuller@infidyne.com>'
 Key retrieval: Send an E-Mail to getpgpkey@scode.org
 E-Mail: peter.schuller@infidyne.com Web: http://www.scode.org
 
 

From: Dan Langille <dan@langille.org>
To: freebsd-gnats-submit@FreeBSD.org, peter.schuller@infidyne.com
Cc: dan@langille.org
Subject: Re: i386/59806: [patch] Suspend/resume breaks em0
Date: Wed, 16 Jun 2004 07:08:17 -0400 (EDT)

 Is there any reason not to commit this PR?
 
 I have a slightly amended patch [I think it's from the Originator of this
 PR].  I have tested it and found it to work well on my IBM ThinkPad T41.
 
 Any else eager to test this patch?
 
 
 --- /usr/src/sys/dev/em/if_em.c	Sun Dec  7 11:53:50 2003
 +++ if_em.c	Tue Jun 15 12:18:17 2004
 @@ -125,6 +125,8 @@
  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 *);
 @@ -192,6 +194,8 @@
  	DEVMETHOD(device_probe, em_probe),
  	DEVMETHOD(device_attach, em_attach),
  	DEVMETHOD(device_detach, em_detach),
 +	DEVMETHOD(device_suspend, em_suspend),
 +	DEVMETHOD(device_resume, em_resume),
  	DEVMETHOD(device_shutdown, em_shutdown),
  	{0, 0}
  };
 @@ -1619,6 +1623,53 @@
  	ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
 
  	return;
 +}
 +
 +/*********************************************************************
 + *
 + *  Prepares the interface for suspend by stopping it.
 + *
 + *********************************************************************/
 +
 +static int
 +em_suspend(device_t dev)
 +{
 +	int i;
 +	struct adapter *adapter = device_get_softc(dev);
 +
 +	EM_LOCK(adapter);
 +	em_stop(adapter);
 +
 +	/* bulk copy pci regs for fixy TKTKTK */
 +	for (i = 0; i < 28; i++) {
 +		adapter->pci_backup[i] = pci_read_config(dev, i, 1);
 +	}
 +
 +	EM_UNLOCK(adapter);
 +	return(0);
 +}
 +
 +/*********************************************************************
 + *
 + *  Reinit the interface when resuming.
 + *
 + *********************************************************************/
 +
 +static int
 +em_resume(device_t dev)
 +{
 +	int i;
 +	struct adapter *adapter = device_get_softc(dev);
 +	EM_LOCK(adapter);
 +
 +	/* bulk copy pci regs back for fixy TKTKTK */
 +	for (i = 0; i < 28; i++) {
 +		pci_write_config(dev, i, adapter->pci_backup[i], 1);
 +	}
 +
 +	em_init_locked(adapter);
 +	EM_UNLOCK(adapter);
 +	return(0);
  }
 
 
 --- /usr/src/sys/dev/em/if_em.h	Fri Nov 14 13:02:24 2003
 +++ if_em.h	Tue Jun 15 12:18:17 2004
 @@ -424,6 +424,8 @@
 
  #endif
  	struct em_hw_stats stats;
 +
 +	u_int8_t pci_backup[28];
  };
 
  #define	EM_LOCK_INIT(_sc, _name) \
Responsible-Changed-From-To: freebsd-i386->tackerman 
Responsible-Changed-By: simon 
Responsible-Changed-When: Wed Jun 16 20:28:46 GMT 2004 
Responsible-Changed-Why:  
Over to em(4) maintainer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=59806 

From: Peter Schuller <peter.schuller@infidyne.com>
To: Dan Langille <dan@langille.org>
Cc: freebsd-gnats-submit@FreeBSD.org
Subject: Re: i386/59806: [patch] Suspend/resume breaks em0
Date: Wed, 23 Jun 2004 23:29:20 +0200

 > Is there any reason not to commit this PR?
 
 There may be; i have noticed the em driver has been significantly updated 
 since I made the patch. I'll have to retest things. Perhaps the patch is no 
 longer needed even. Dunno.
 
 > I have a slightly amended patch [I think it's from the Originator of this
 > PR].  I have tested it and found it to work well on my IBM ThinkPad T41.
 
 Not from me, nope.
 
 > Any else eager to test this patch?
 
 Will do.
 
 -- 
 / Peter Schuller, InfiDyne Technologies HB
 
 PGP userID: 0xE9758B7D or 'Peter Schuller <peter.schuller@infidyne.com>'
 Key retrieval: Send an E-Mail to getpgpkey@scode.org
 E-Mail: peter.schuller@infidyne.com Web: http://www.scode.org
 

From: Jacques Garrigue <see@my.signature>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: i386/59806: [patch] Suspend/resume breaks em0
Date: 13 Aug 2004 16:00:43 +0900

 The second patch worked fine with me too.
 I tested on a ThinkPad T42.
 
 ---------------------------------------------------------------------------
 Jacques Garrigue      Kyoto University     garrigue at kurims.kyoto-u.ac.jp
 		<A HREF=http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/>JG</A>

From: Bruce M Simpson <bms@spc.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc: tackerman@FreeBSD.org
Subject: Re: i386/59806: [patch] Suspend/resume breaks em0
Date: Fri, 15 Oct 2004 15:37:27 -0700

 I believe this patch needs to be committed, with the following changes.
 
 The save/restore of PCI configuration space in the second patch is
 in fact redundant in RELENG_5 and HEAD, but may be required in RELENG_4.
 
 Bus-wide save/restore of configuration registers belonging to PCI
 children was introduced in rev 1.238 of src/sys/dev/pci/pci.c. This
 corresponds to a __FreeBSD_version of 502111 (this is the nearest
 version bump, in fact 2 days later).
 
 Therefore the PCI configuration save/restore should be conditionalized.
 
 Regards,
 BMS
State-Changed-From-To: open->feedback 
State-Changed-By: linimon 
State-Changed-When: Wed Apr 5 00:31:35 UTC 2006 
State-Changed-Why:  
Is this still a problem with recent versions of FreeBSD? 


Responsible-Changed-From-To: tackerman->linimon 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Apr 5 00:31:35 UTC 2006 
Responsible-Changed-Why:  
Reset PR assigned to inactive committer. 

Hat:	gnats-admin 

http://www.freebsd.org/cgi/query-pr.cgi?pr=59806 

From: Peter Schuller <peter.schuller@infidyne.com>
To: bug-followup@freebsd.org,
 peter.schuller@infidyne.com
Cc:  
Subject: Re: kern/59806: [em] [patch] Suspend/resume breaks em0
Date: Wed, 5 Apr 2006 20:35:13 +0200

 On the machine where I originally had these problems, suspend/resume now works 
 with ACPI enabled on 6.0-RELEASE-p4.
 
 However, after resuming I have to "poke" em0 by either cycling the DHCP client 
 or doing "ifconfig em0 down" followed by an appropriate "up". If I do not, it 
 gets stuck not being able to send and/or receive traffic (can't ping 
 anything). If I remember correctly, this is strikingly similar to the 
 original behavior - except there is no eventual kernel panic.
 
 Simply unplugging and re-plugging the cable does *not* wake it up either, 
 though the driver detects the state changes and prints them in the kernel 
 log.
 
 I was unable to test with apm because apm refused to load inspite of disabling 
 ACPI, setting apm_load="YES" and hint.apm.0.disabled="0".
 
 I would be glad to try any patches if needed.
 
 (I have not tried applying/re-writing my original patch for the updated 
 driver, on the theory that it never was correct anyway, combined with the 
 fact that the bug is no longer a show-stopper. But if there is a potentially 
 correct patch to try I will do so.)
 
 -- 
 / Peter Schuller, InfiDyne Technologies HB
 
 PGP userID: 0xE9758B7D or 'Peter Schuller <peter.schuller@infidyne.com>'
 Key retrieval: Send an E-Mail to getpgpkey@scode.org
 E-Mail: peter.schuller@infidyne.com Web: http://www.scode.org
 
State-Changed-From-To: feedback->suspended 
State-Changed-By: linimon 
State-Changed-When: Wed Apr 5 19:57:14 UTC 2006 
State-Changed-Why:  
It sounds as though there are still related problems, but this patch is no 
longer directly applicable.  Mark 'suspended' awaiting someone to take an 
interest in it. 


Responsible-Changed-From-To: linimon->freebsd-bugs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Apr 5 19:57:14 UTC 2006 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=59806 
State-Changed-From-To: suspended->closed 
State-Changed-By: glebius 
State-Changed-When: Fri Apr 7 08:50:20 UTC 2006 
State-Changed-Why:  
A similar code was added in rev. 1.95 


Responsible-Changed-From-To: freebsd-bugs->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Fri Apr 7 08:50:20 UTC 2006 
Responsible-Changed-Why:  
I did this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=59806 
>Unformatted:
