Skip to contentSkip to conversation

Software suspend and RTL 8139too in 2.6.0-test1

PATCH Peter Osterlund 2 participants 3 messages Jul 14, 2003 – Jul 20, 2003

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

Hi!

This patch is needed to make software suspend work with the 8139too driver loaded.

drivers/net/8139too.c renamed from drivers/net/8139too.c.old +4 -0
@@ -110,6 +110,7 @@
 #include <linux/mii.h>
 #include <linux/completion.h>
 #include <linux/crc32.h>
+#include <linux/suspend.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
 
@@ -1597,6 +1598,9 @@
 		timeout = next_tick;
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
+			/* make swsusp happy with our thread */
+			if (current->flags & PF_FREEZE)
+				refrigerator(PF_IOTHREAD);
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
Signature · 2 lines
Peter Osterlund - [email protected]
http://w1.894.telia.com/~u89404340
#1 lore raw

Hi!

Quoted 2 lines

This patch is needed to make software suspend work with the 8139too driver loaded.

There's more complicated patch at
http://mrohne.home.cern.ch/mrohne/P2120/P2120_Linux_S3.html. Could you test it, perhaps?
Pavel

drivers/net/8139too.c +12 -1
diff -Nru -X dontdiff linux-2.5.64bk11/drivers/net/8139too.c linux-2.5.64bk11-p2120/drivers/net/8139too.c
@@ -109,6 +109,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/completion.h>
+#include <linux/suspend.h>
 #include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -565,6 +566,7 @@
 	void *mmio_addr;
 	int drv_flags;
 	struct pci_dev *pci_dev;
+        u32 pci_state[16];
 	struct net_device_stats stats;
 	unsigned char *rx_ring;
 	unsigned int cur_rx;	/* Index into the Rx buffer of next Rx pkt. */
@@ -1595,6 +1597,8 @@
 		timeout = next_tick;
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
+			if (current->flags & PF_FREEZE)
+				refrigerator(PF_IOTHREAD);
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
@@ -2562,6 +2566,9 @@
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
 
+	pci_save_state (pdev, tp->pci_state);
+	pci_set_power_state (pdev, 3);
+
 	spin_unlock_irqrestore (&tp->lock, flags);
 	return 0;
 }
@@ -2570,11 +2577,15 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = dev->priv;
 
 	if (!netif_running (dev))
 		return 0;
-	netif_device_attach (dev);
+	pci_set_power_state (pdev, 0);
+	pci_restore_state (pdev, tp->pci_state);
+	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
+	netif_device_attach (dev);
 	return 0;
 }
 
drivers/pci/pci-driver.c +3 -5
diff -Nru -X dontdiff linux-2.5.64bk11/drivers/pci/pci-driver.c linux-2.5.64bk11-p2120/drivers/pci/pci-driver.c
@@ -91,11 +91,9 @@
 	struct pci_dev * pci_dev = to_pci_dev(dev);
 
 	if (pci_dev->driver) {
-		/* We may not call PCI drivers resume at
-		   RESUME_POWER_ON because interrupts are not yet
-		   working at that point. Calling resume at
-		   RESUME_RESTORE_STATE seems like solution. */
-		if (level == RESUME_RESTORE_STATE && pci_dev->driver->resume)
+	        if (level == RESUME_POWER_ON && pci_dev->driver->power_on)
+			pci_dev->driver->power_on(pci_dev);
+		else if (level == RESUME_RESTORE_STATE && pci_dev->driver->resume)
 			pci_dev->driver->resume(pci_dev);
 	}
 	return 0;
drivers/video/radeonfb.c +55 -2

85 lines not on this page · raw message

include/linux/pci.h +1 -0
diff -Nru -X dontdiff linux-2.5.64bk11/include/linux/pci.h linux-2.5.64bk11-p2120/include/linux/pci.h
@@ -500,6 +500,7 @@
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
 	int  (*save_state) (struct pci_dev *dev, u32 state);    /* Save Device Context */
 	int  (*suspend) (struct pci_dev *dev, u32 state);	/* Device suspended */
+	int  (*power_on) (struct pci_dev *dev);	                /* Device power on */
 	int  (*resume) (struct pci_dev *dev);	                /* Device woken up */
 	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
 
Signature · 2 lines
When do you have a heart between your knees?
[Johanka's followup: and *two* hearts?]
#2 lore raw
Quoted 8 lines · Pavel Machek

Hi!

Quoted 2 lines

This patch is needed to make software suspend work with the 8139too driver loaded.

There's more complicated patch at
http://mrohne.home.cern.ch/mrohne/P2120/P2120_Linux_S3.html. Could you test it, perhaps?

It works even better than my patch. With my patch the NIC would not work for a few seconds after resume, until the driver realized something was wrong and reinitialized the card. With this patch I don't see that problem.

Here is the patch for 2.6.0-test1 with only the 8139too changes.

drivers/net/8139too.c renamed from drivers/net/8139too.c.old +12 -1
@@ -109,6 +109,7 @@
 #include <linux/ethtool.h>
 #include <linux/mii.h>
 #include <linux/completion.h>
+#include <linux/suspend.h>
 #include <linux/crc32.h>
 #include <asm/io.h>
 #include <asm/uaccess.h>
@@ -565,6 +566,7 @@
 	void *mmio_addr;
 	int drv_flags;
 	struct pci_dev *pci_dev;
+	u32 pci_state[16];
 	struct net_device_stats stats;
 	unsigned char *rx_ring;
 	unsigned int cur_rx;	/* Index into the Rx buffer of next Rx pkt. */
@@ -1597,6 +1599,8 @@
 		timeout = next_tick;
 		do {
 			timeout = interruptible_sleep_on_timeout (&tp->thr_wait, timeout);
+			if (current->flags & PF_FREEZE)
+				refrigerator(PF_IOTHREAD);
 		} while (!signal_pending (current) && (timeout > 0));
 
 		if (signal_pending (current)) {
@@ -2566,6 +2570,9 @@
 	tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
 	RTL_W32 (RxMissed, 0);
 
+	pci_save_state (pdev, tp->pci_state);
+	pci_set_power_state (pdev, 3);
+
 	spin_unlock_irqrestore (&tp->lock, flags);
 	return 0;
 }
@@ -2574,11 +2581,15 @@
 static int rtl8139_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
+	struct rtl8139_private *tp = dev->priv;
 
 	if (!netif_running (dev))
 		return 0;
-	netif_device_attach (dev);
+	pci_set_power_state (pdev, 0);
+	pci_restore_state (pdev, tp->pci_state);
+	rtl8139_init_ring (dev);
 	rtl8139_hw_start (dev);
+	netif_device_attach (dev);
 	return 0;
 }
 
Signature · 2 lines
Peter Osterlund - [email protected]
http://w1.894.telia.com/~u89404340