--- /dev/null
+From stable-bounces@linux.kernel.org Fri Sep 28 15:53:04 2007
+From: Michal Schmidt <mschmidt@redhat.com>
+Date: Fri, 28 Sep 2007 15:52:46 -0700 (PDT)
+Subject: Fix ppp_mppe kernel stack usage.
+To: stable@kernel.org
+Cc: bunk@kernel.org
+Message-ID: <20070928.155246.57176640.davem@davemloft.net>
+
+From: Michal Schmidt <mschmidt@redhat.com>
+
+commit 45dfd5b5dd20f17fe23dafc5cfe921474d27f849 from upstream
+
+Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/ppp_mppe.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/ppp_mppe.c
++++ b/drivers/net/ppp_mppe.c
+@@ -136,7 +136,7 @@ struct ppp_mppe_state {
+ * Key Derivation, from RFC 3078, RFC 3079.
+ * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079.
+ */
+-static void get_new_key_from_sha(struct ppp_mppe_state * state, unsigned char *InterimKey)
++static void get_new_key_from_sha(struct ppp_mppe_state * state)
+ {
+ struct hash_desc desc;
+ struct scatterlist sg[4];
+@@ -153,8 +153,6 @@ static void get_new_key_from_sha(struct
+ desc.flags = 0;
+
+ crypto_hash_digest(&desc, sg, nbytes, state->sha1_digest);
+-
+- memcpy(InterimKey, state->sha1_digest, state->keylen);
+ }
+
+ /*
+@@ -163,21 +161,21 @@ static void get_new_key_from_sha(struct
+ */
+ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
+ {
+- unsigned char InterimKey[MPPE_MAX_KEY_LEN];
+ struct scatterlist sg_in[1], sg_out[1];
+ struct blkcipher_desc desc = { .tfm = state->arc4 };
+
+- get_new_key_from_sha(state, InterimKey);
++ get_new_key_from_sha(state);
+ if (!initial_key) {
+- crypto_blkcipher_setkey(state->arc4, InterimKey, state->keylen);
+- setup_sg(sg_in, InterimKey, state->keylen);
++ crypto_blkcipher_setkey(state->arc4, state->sha1_digest,
++ state->keylen);
++ setup_sg(sg_in, state->sha1_digest, state->keylen);
+ setup_sg(sg_out, state->session_key, state->keylen);
+ if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
+ state->keylen) != 0) {
+ printk(KERN_WARNING "mppe_rekey: cipher_encrypt failed\n");
+ }
+ } else {
+- memcpy(state->session_key, InterimKey, state->keylen);
++ memcpy(state->session_key, state->sha1_digest, state->keylen);
+ }
+ if (state->keylen == 8) {
+ /* See RFC 3078 */
--- /dev/null
+From 4047727e5ae33f9b8d2b7766d1994ea6e5ec2991 Mon Sep 17 00:00:00 2001
+From: Mark Lord <lkml@rtr.ca>
+Date: Mon, 1 Oct 2007 01:20:10 -0700
+Subject: Fix SMP poweroff hangs
+
+From: Mark Lord <lkml@rtr.ca>
+
+commit 4047727e5ae33f9b8d2b7766d1994ea6e5ec2991 from upstream
+
+We need to disable all CPUs other than the boot CPU (usually 0) before
+attempting to power-off modern SMP machines. This fixes the
+hang-on-poweroff issue on my MythTV SMP box, and also on Thomas Gleixner's
+new toybox.
+
+Signed-off-by: Mark Lord <mlord@pobox.com>
+Acked-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ kernel/sys.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/sys.c
++++ b/kernel/sys.c
+@@ -31,6 +31,7 @@
+ #include <linux/cn_proc.h>
+ #include <linux/getcpu.h>
+ #include <linux/task_io_accounting_ops.h>
++#include <linux/cpu.h>
+
+ #include <linux/compat.h>
+ #include <linux/syscalls.h>
+@@ -865,6 +866,7 @@ EXPORT_SYMBOL_GPL(kernel_halt);
+ void kernel_power_off(void)
+ {
+ kernel_shutdown_prepare(SYSTEM_POWER_OFF);
++ disable_nonboot_cpus();
+ printk(KERN_EMERG "Power down.\n");
+ machine_power_off();
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Sun Oct 7 02:38:33 2007
+From: Anton Blanchard <anton@samba.org>
+Date: Sun, 07 Oct 2007 00:24:31 -0700
+Subject: Fix timer_stats printout of events/sec
+To: torvalds@linux-foundation.org
+Cc: akpm@linux-foundation.org, mingo@elte.hu, anton@samba.org, stable@kernel.org
+Message-ID: <200710070724.l977OVlu029051@imap1.linux-foundation.org>
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 74922be1485818ed368c4cf4f0b100f70bf01e08 upstream.
+
+When using /proc/timer_stats on ppc64 I noticed the events/sec field wasnt
+accurate. Sometimes the integer part was incorrect due to rounding (we
+werent taking the fractional seconds into consideration).
+
+The fraction part is also wrong, we need to pad the printf statement and
+take the bottom three digits of 1000 times the value.
+
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Acked-by: Ingo Molnar <mingo@elte.hu>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+---
+
+ kernel/time/timer_stats.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/kernel/time/timer_stats.c
++++ b/kernel/time/timer_stats.c
+@@ -319,8 +319,9 @@ static int tstats_show(struct seq_file *
+ ms = 1;
+
+ if (events && period.tv_sec)
+- seq_printf(m, "%ld total events, %ld.%ld events/sec\n", events,
+- events / period.tv_sec, events * 1000 / ms);
++ seq_printf(m, "%ld total events, %ld.%03ld events/sec\n",
++ events, events * 1000 / ms,
++ (events * 1000000 / ms) % 1000);
+ else
+ seq_printf(m, "%ld total events\n", events);
+
--- /dev/null
+From stable-bounces@linux.kernel.org Thu Sep 27 06:17:47 2007
+From: Jean Delvare <khali@linux-fr.org>
+Date: Thu, 27 Sep 2007 15:17:25 +0200
+Subject: i2c-algo-bit: Read block data bugfix
+To: stable@kernel.org
+Cc: David Brownell <david-b@pacbell.net>
+Message-ID: <20070927151725.6c33402b@hyperion.delvare>
+
+
+From: David Brownell <david-b@pacbell.net>
+
+In Linus tree already:
+http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=939bc4943d0483961edc45b63a7d27b4ffe547e3
+
+This fixes a bug in the way i2c-algo-bit handles I2C_M_RECV_LEN,
+used to implement i2c_smbus_read_block_data(). Previously, in the
+absence of PEC (rarely used!) it would NAK the "length" byte:
+
+ S addr Rd [A] [length] NA
+
+That prevents the subsequent data bytes from being read:
+
+ S addr Rd [A] [length] { A [data] }* NA
+
+The primary fix just reorders two code blocks, so the length used
+in the "should I NAK now?" check incorporates the data which it
+just read from the slave device.
+
+However, that move also highlighted other fault handling glitches.
+This fixes those by abstracting the RX path ack/nak logic, so it
+can be used in more than one location.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Jean Delvare <khali@linux-fr.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/i2c/algos/i2c-algo-bit.c | 52 ++++++++++++++++++++++++---------------
+ 1 file changed, 32 insertions(+), 20 deletions(-)
+
+--- a/drivers/i2c/algos/i2c-algo-bit.c
++++ b/drivers/i2c/algos/i2c-algo-bit.c
+@@ -357,13 +357,29 @@ static int sendbytes(struct i2c_adapter
+ return wrcount;
+ }
+
++static int acknak(struct i2c_adapter *i2c_adap, int is_ack)
++{
++ struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
++
++ /* assert: sda is high */
++ if (is_ack) /* send ack */
++ setsda(adap, 0);
++ udelay((adap->udelay + 1) / 2);
++ if (sclhi(adap) < 0) { /* timeout */
++ dev_err(&i2c_adap->dev, "readbytes: ack/nak timeout\n");
++ return -ETIMEDOUT;
++ }
++ scllo(adap);
++ return 0;
++}
++
+ static int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
+ {
+ int inval;
+ int rdcount=0; /* counts bytes read */
+- struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
+ unsigned char *temp = msg->buf;
+ int count = msg->len;
++ const unsigned flags = msg->flags;
+
+ while (count > 0) {
+ inval = i2c_inb(i2c_adap);
+@@ -377,28 +393,12 @@ static int readbytes(struct i2c_adapter
+ temp++;
+ count--;
+
+- if (msg->flags & I2C_M_NO_RD_ACK) {
+- bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x\n",
+- inval);
+- continue;
+- }
+-
+- /* assert: sda is high */
+- if (count) /* send ack */
+- setsda(adap, 0);
+- udelay((adap->udelay + 1) / 2);
+- bit_dbg(2, &i2c_adap->dev, "i2c_inb: 0x%02x %s\n", inval,
+- count ? "A" : "NA");
+- if (sclhi(adap)<0) { /* timeout */
+- dev_err(&i2c_adap->dev, "readbytes: timeout at ack\n");
+- return -ETIMEDOUT;
+- };
+- scllo(adap);
+-
+ /* Some SMBus transactions require that we receive the
+ transaction length as the first read byte. */
+- if (rdcount == 1 && (msg->flags & I2C_M_RECV_LEN)) {
++ if (rdcount == 1 && (flags & I2C_M_RECV_LEN)) {
+ if (inval <= 0 || inval > I2C_SMBUS_BLOCK_MAX) {
++ if (!(flags & I2C_M_NO_RD_ACK))
++ acknak(i2c_adap, 0);
+ dev_err(&i2c_adap->dev, "readbytes: invalid "
+ "block length (%d)\n", inval);
+ return -EREMOTEIO;
+@@ -409,6 +409,18 @@ static int readbytes(struct i2c_adapter
+ count += inval;
+ msg->len += inval;
+ }
++
++ bit_dbg(2, &i2c_adap->dev, "readbytes: 0x%02x %s\n",
++ inval,
++ (flags & I2C_M_NO_RD_ACK)
++ ? "(no ack/nak)"
++ : (count ? "A" : "NA"));
++
++ if (!(flags & I2C_M_NO_RD_ACK)) {
++ inval = acknak(i2c_adap, count);
++ if (inval < 0)
++ return inval;
++ }
+ }
+ return rdcount;
+ }
--- /dev/null
+From stable-bounces@linux.kernel.org Fri Sep 28 12:30:03 2007
+From: Chuck Ebbert <cebbert@redhat.com>
+Date: Fri, 28 Sep 2007 15:29:32 -0400
+Subject: libata: update drive blacklists
+To: linux-stable <stable@kernel.org>
+Cc: Jeff Garzik <jeff@garzik.org>
+Message-ID: <46FD561C.70800@redhat.com>
+
+From: Chuck Ebbert <cebbert@redhat.com>
+
+Update the libata drive blacklists to the latest in 2.6.23-rc8.
+
+Signed-off-by: Chuck Ebbert <cebbert@redhat.com>
+Cc: Jeff Garzik <jeff@garzik.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/ata/libata-core.c | 13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -3774,6 +3774,8 @@ static const struct ata_blacklist_entry
+ { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
+ { "Seagate STT20000A", NULL, ATA_HORKAGE_NODMA },
+ { "IOMEGA ZIP 250 ATAPI", NULL, ATA_HORKAGE_NODMA }, /* temporary fix */
++ { "IOMEGA ZIP 250 ATAPI Floppy",
++ NULL, ATA_HORKAGE_NODMA },
+
+ /* Weird ATAPI devices */
+ { "TORiSAN DVD-ROM DRD-N216", NULL, ATA_HORKAGE_MAX_SEC_128 },
+@@ -3787,7 +3789,13 @@ static const struct ata_blacklist_entry
+ { "FUJITSU MHT2060BH", NULL, ATA_HORKAGE_NONCQ },
+ /* NCQ is broken */
+ { "Maxtor 6L250S0", "BANC1G10", ATA_HORKAGE_NONCQ },
++ { "Maxtor 6B200M0", "BANC1BM0", ATA_HORKAGE_NONCQ },
+ { "Maxtor 6B200M0", "BANC1B10", ATA_HORKAGE_NONCQ },
++ { "Maxtor 7B250S0", "BANC1B70", ATA_HORKAGE_NONCQ, },
++ { "Maxtor 7B300S0", "BANC1B70", ATA_HORKAGE_NONCQ },
++ { "Maxtor 7V300F0", "VA111630", ATA_HORKAGE_NONCQ },
++ { "HITACHI HDS7250SASUN500G 0621KTAWSD", "K2AOAJ0AHITACHI",
++ ATA_HORKAGE_NONCQ },
+ /* NCQ hard hangs device under heavier load, needs hard power cycle */
+ { "Maxtor 6B250S0", "BANC1B70", ATA_HORKAGE_NONCQ },
+ /* Blacklist entries taken from Silicon Image 3124/3132
+@@ -3801,8 +3809,9 @@ static const struct ata_blacklist_entry
+ { "Hitachi HTS541616J9SA00", "SB4OC70P", ATA_HORKAGE_NONCQ, },
+ { "WDC WD740ADFD-00NLR1", NULL, ATA_HORKAGE_NONCQ, },
+ { "FUJITSU MHV2080BH", "00840028", ATA_HORKAGE_NONCQ, },
+-
+- /* Devices with NCQ limits */
++ { "ST9160821AS", "3.CLF", ATA_HORKAGE_NONCQ, },
++ { "ST3160812AS", "3.AD", ATA_HORKAGE_NONCQ, },
++ { "SAMSUNG HD401LJ", "ZZ100-15", ATA_HORKAGE_NONCQ, },
+
+ /* End Marker */
+ { }
--- /dev/null
+From stable-bounces@linux.kernel.org Tue Sep 25 12:56:27 2007
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+Date: Tue, 25 Sep 2007 15:56:00 -0400
+Subject: NLM: Fix a circular lock dependency in lockd
+To: stable@kernel.org
+Message-ID: <1190750160.7330.34.camel@heimdal.trondhjem.org>
+
+From: Trond Myklebust <Trond.Myklebust@netapp.com>
+
+commit 255129d1e9ca0ed3d69d5517fae3e03d7ab4b806 in upstream.
+
+The problem is that the garbage collector for the 'host' structures
+nlm_gc_hosts(), holds nlm_host_mutex while calling down to
+nlmsvc_mark_resources, which, eventually takes the file->f_mutex.
+
+We cannot therefore call nlmsvc_lookup_host() from within
+nlmsvc_create_block, since the caller will already hold file->f_mutex, so
+the attempt to grab nlm_host_mutex may deadlock.
+
+Fix the problem by calling nlmsvc_lookup_host() outside the file->f_mutex.
+
+Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ fs/lockd/svclock.c | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+--- a/fs/lockd/svclock.c
++++ b/fs/lockd/svclock.c
+@@ -171,19 +171,14 @@ found:
+ * GRANTED_RES message by cookie, without having to rely on the client's IP
+ * address. --okir
+ */
+-static inline struct nlm_block *
+-nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_file *file,
+- struct nlm_lock *lock, struct nlm_cookie *cookie)
++static struct nlm_block *
++nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
++ struct nlm_file *file, struct nlm_lock *lock,
++ struct nlm_cookie *cookie)
+ {
+ struct nlm_block *block;
+- struct nlm_host *host;
+ struct nlm_rqst *call = NULL;
+
+- /* Create host handle for callback */
+- host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
+- if (host == NULL)
+- return NULL;
+-
+ call = nlm_alloc_call(host);
+ if (call == NULL)
+ return NULL;
+@@ -366,6 +361,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, stru
+ struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
+ {
+ struct nlm_block *block = NULL;
++ struct nlm_host *host;
+ int error;
+ __be32 ret;
+
+@@ -377,6 +373,10 @@ nlmsvc_lock(struct svc_rqst *rqstp, stru
+ (long long)lock->fl.fl_end,
+ wait);
+
++ /* Create host handle for callback */
++ host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
++ if (host == NULL)
++ return nlm_lck_denied_nolocks;
+
+ /* Lock file against concurrent access */
+ mutex_lock(&file->f_mutex);
+@@ -385,7 +385,8 @@ nlmsvc_lock(struct svc_rqst *rqstp, stru
+ */
+ block = nlmsvc_lookup_block(file, lock);
+ if (block == NULL) {
+- block = nlmsvc_create_block(rqstp, file, lock, cookie);
++ block = nlmsvc_create_block(rqstp, nlm_get_host(host), file,
++ lock, cookie);
+ ret = nlm_lck_denied_nolocks;
+ if (block == NULL)
+ goto out;
+@@ -449,6 +450,7 @@ nlmsvc_lock(struct svc_rqst *rqstp, stru
+ out:
+ mutex_unlock(&file->f_mutex);
+ nlmsvc_release_block(block);
++ nlm_release_host(host);
+ dprintk("lockd: nlmsvc_lock returned %u\n", ret);
+ return ret;
+ }
+@@ -477,10 +479,15 @@ nlmsvc_testlock(struct svc_rqst *rqstp,
+
+ if (block == NULL) {
+ struct file_lock *conf = kzalloc(sizeof(*conf), GFP_KERNEL);
++ struct nlm_host *host;
+
+ if (conf == NULL)
+ return nlm_granted;
+- block = nlmsvc_create_block(rqstp, file, lock, cookie);
++ /* Create host handle for callback */
++ host = nlmsvc_lookup_host(rqstp, lock->caller, lock->len);
++ if (host == NULL)
++ return nlm_lck_denied_nolocks;
++ block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
+ if (block == NULL) {
+ kfree(conf);
+ return nlm_granted;
scsi_transport_spi-fix-domain-validation-failure-from-incorrect-width-setting.patch
+sky2-hw-watchdog.patch
+sky2-vlan-len.patch
+sky2-tx-sum-resume.patch
+libata-update-drive-blacklists.patch
+fix-ppp_mppe-kernel-stack-usage.patch
+i2c-algo-bit-read-block-data-bugfix.patch
+nlm-fix-a-circular-lock-dependency-in-lockd.patch
+fix-smp-poweroff-hangs.patch
+fix-timer_stats-printout-of-events-sec.patch
--- /dev/null
+From stable-bounces@linux.kernel.org Fri Sep 28 09:52:23 2007
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+Date: Fri, 28 Sep 2007 09:48:12 -0700
+Subject: sky2: reduce impact of watchdog timer
+To: Krzysztof Oledzki <olel@ans.pl>, Greg KH <greg@kroah.com>
+Cc: netdev@vger.kernel.org, stable@kernel.org
+Message-ID: <20070928164858.474820246@linux-foundation.org>
+Content-Disposition: inline; filename=sky2-hw-watchdog.patch
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+This is the 2.6.22 version of a regression fix that is already
+in 2.6.23. Change the watchdog timer form 10 per second all the time,
+to 1 per second and only if interface is up.
+
+Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/net/sky2.c | 45 ++++++++++++++++++---------------------------
+ drivers/net/sky2.h | 2 +-
+ 2 files changed, 19 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -96,10 +96,6 @@ static int disable_msi = 0;
+ module_param(disable_msi, int, 0);
+ MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
+
+-static int idle_timeout = 100;
+-module_param(idle_timeout, int, 0);
+-MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
+-
+ static const struct pci_device_id sky2_id_table[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */
+ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */
+@@ -1693,6 +1689,8 @@ static void sky2_link_up(struct sky2_por
+
+ netif_carrier_on(sky2->netdev);
+
++ mod_timer(&hw->watchdog_timer, jiffies + 1);
++
+ /* Turn on link LED */
+ sky2_write8(hw, SK_REG(port, LNK_LED_REG),
+ LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF);
+@@ -2384,25 +2382,25 @@ static void sky2_le_error(struct sky2_hw
+ sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK);
+ }
+
+-/* If idle then force a fake soft NAPI poll once a second
+- * to work around cases where sharing an edge triggered interrupt.
+- */
+-static inline void sky2_idle_start(struct sky2_hw *hw)
+-{
+- if (idle_timeout > 0)
+- mod_timer(&hw->idle_timer,
+- jiffies + msecs_to_jiffies(idle_timeout));
+-}
+-
+-static void sky2_idle(unsigned long arg)
++/* Force a fake soft NAPI poll to handle lost IRQ's */
++static void sky2_watchdog(unsigned long arg)
+ {
+ struct sky2_hw *hw = (struct sky2_hw *) arg;
+ struct net_device *dev = hw->dev[0];
++ int i, active = 0;
+
+ if (__netif_rx_schedule_prep(dev))
+ __netif_rx_schedule(dev);
+
+- mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout));
++ for (i = 0; i < hw->ports; i++) {
++ dev = hw->dev[i];
++ if (!netif_running(dev))
++ continue;
++ ++active;
++ }
++
++ if (active)
++ mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ));
+ }
+
+ /* Hardware/software error handling */
+@@ -2692,8 +2690,6 @@ static void sky2_restart(struct work_str
+
+ dev_dbg(&hw->pdev->dev, "restarting\n");
+
+- del_timer_sync(&hw->idle_timer);
+-
+ rtnl_lock();
+ sky2_write32(hw, B0_IMSK, 0);
+ sky2_read32(hw, B0_IMSK);
+@@ -2722,8 +2718,6 @@ static void sky2_restart(struct work_str
+ }
+ }
+
+- sky2_idle_start(hw);
+-
+ rtnl_unlock();
+ }
+
+@@ -3713,11 +3707,9 @@ static int __devinit sky2_probe(struct p
+ sky2_show_addr(dev1);
+ }
+
+- setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
++ setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw);
+ INIT_WORK(&hw->restart_work, sky2_restart);
+
+- sky2_idle_start(hw);
+-
+ pci_set_drvdata(pdev, hw);
+
+ return 0;
+@@ -3752,7 +3744,7 @@ static void __devexit sky2_remove(struct
+ if (!hw)
+ return;
+
+- del_timer_sync(&hw->idle_timer);
++ del_timer_sync(&hw->watchdog_timer);
+
+ flush_scheduled_work();
+
+@@ -3796,7 +3788,7 @@ static int sky2_suspend(struct pci_dev *
+ if (!hw)
+ return 0;
+
+- del_timer_sync(&hw->idle_timer);
++ del_timer_sync(&hw->watchdog_timer);
+ netif_poll_disable(hw->dev[0]);
+
+ for (i = 0; i < hw->ports; i++) {
+@@ -3862,7 +3854,7 @@ static int sky2_resume(struct pci_dev *p
+ }
+
+ netif_poll_enable(hw->dev[0]);
+- sky2_idle_start(hw);
++
+ return 0;
+ out:
+ dev_err(&pdev->dev, "resume failed (%d)\n", err);
+@@ -3879,7 +3871,6 @@ static void sky2_shutdown(struct pci_dev
+ if (!hw)
+ return;
+
+- del_timer_sync(&hw->idle_timer);
+ netif_poll_disable(hw->dev[0]);
+
+ for (i = 0; i < hw->ports; i++) {
+--- a/drivers/net/sky2.h
++++ b/drivers/net/sky2.h
+@@ -1921,7 +1921,7 @@ struct sky2_hw {
+ u32 st_idx;
+ dma_addr_t st_dma;
+
+- struct timer_list idle_timer;
++ struct timer_list watchdog_timer;
+ struct work_struct restart_work;
+ int msi;
+ wait_queue_head_t msi_wait;
--- /dev/null
+From stable-bounces@linux.kernel.org Fri Sep 28 09:52:23 2007
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+Date: Fri, 28 Sep 2007 09:48:14 -0700
+Subject: sky2: fix transmit state on resume
+To: Krzysztof Oledzki <olel@ans.pl>, Greg KH <greg@kroah.com>
+Cc: netdev@vger.kernel.org, stable@kernel.org
+Message-ID: <20070928164858.593540259@linux-foundation.org>
+Content-Disposition: inline; filename=sky2-tx-sum-resume.patch
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+Already upstream.
+
+After resume, driver has reset the chip so the current state
+of transmit checksum offload state machine and DMA state machine
+will be undefined.
+
+The fix is to set the state so that first Tx will set MSS and offset
+values.
+
+Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/sky2.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -831,6 +831,20 @@ static inline struct sky2_tx_le *get_tx_
+ return le;
+ }
+
++static void tx_init(struct sky2_port *sky2)
++{
++ struct sky2_tx_le *le;
++
++ sky2->tx_prod = sky2->tx_cons = 0;
++ sky2->tx_tcpsum = 0;
++ sky2->tx_last_mss = 0;
++
++ le = get_tx_le(sky2);
++ le->addr = 0;
++ le->opcode = OP_ADDR64 | HW_OWNER;
++ sky2->tx_addr64 = 0;
++}
++
+ static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
+ struct sky2_tx_le *le)
+ {
+@@ -1244,7 +1258,8 @@ static int sky2_up(struct net_device *de
+ GFP_KERNEL);
+ if (!sky2->tx_ring)
+ goto err_out;
+- sky2->tx_prod = sky2->tx_cons = 0;
++
++ tx_init(sky2);
+
+ sky2->rx_le = pci_alloc_consistent(hw->pdev, RX_LE_BYTES,
+ &sky2->rx_le_map);
--- /dev/null
+From shemminger@linux-foundation.org Fri Sep 28 09:52:14 2007
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+Date: Fri, 28 Sep 2007 09:48:13 -0700
+Subject: sky2: fix VLAN receive processing
+To: Krzysztof Oledzki <olel@ans.pl>, Greg KH <greg@kroah.com>
+Cc: stable@kernel.org, netdev@vger.kernel.org, Pierre-Yves Ritschard <pyr@spootnik.org>
+Message-ID: <20070928164858.539587428@linux-foundation.org>
+Content-Disposition: inline; filename=sky2-vlan-len.patch
+
+From: Stephen Hemminger <shemminger@linux-foundation.org>
+
+Already upstream.
+
+The length check for truncated frames was not correctly handling
+the case where VLAN acceleration had already read the tag.
+Also, the Yukon EX has some features that use high bit of status
+as security tag.
+
+Signed-off-by: Pierre-Yves Ritschard <pyr@spootnik.org>
+Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/sky2.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/sky2.c
++++ b/drivers/net/sky2.c
+@@ -2049,6 +2049,7 @@ static struct sk_buff *sky2_receive(stru
+ struct sky2_port *sky2 = netdev_priv(dev);
+ struct rx_ring_info *re = sky2->rx_ring + sky2->rx_next;
+ struct sk_buff *skb = NULL;
++ u16 count;
+
+ if (unlikely(netif_msg_rx_status(sky2)))
+ printk(KERN_DEBUG PFX "%s: rx slot %u status 0x%x len %d\n",
+@@ -2063,7 +2064,13 @@ static struct sk_buff *sky2_receive(stru
+ if (!(status & GMR_FS_RX_OK))
+ goto resubmit;
+
+- if (status >> 16 != length)
++ count = (status & GMR_FS_LEN) >> 16;
++#ifdef SKY2_VLAN_TAG_USED
++ /* Account for vlan tag */
++ if (sky2->vlgrp && (status & GMR_FS_VLAN))
++ count -= VLAN_HLEN;
++#endif
++ if (count != length)
+ goto len_mismatch;
+
+ if (length < copybreak)