From: Greg Kroah-Hartman Date: Mon, 8 Oct 2007 17:26:30 +0000 (-0700) Subject: more 2.6.22 patches queued X-Git-Tag: v2.6.22.10~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2c348b72f049779a76fdaa6e60aeb10b8c6ff0e5;p=thirdparty%2Fkernel%2Fstable-queue.git more 2.6.22 patches queued --- diff --git a/queue-2.6.22/fix-ppp_mppe-kernel-stack-usage.patch b/queue-2.6.22/fix-ppp_mppe-kernel-stack-usage.patch new file mode 100644 index 00000000000..0da58bd2007 --- /dev/null +++ b/queue-2.6.22/fix-ppp_mppe-kernel-stack-usage.patch @@ -0,0 +1,67 @@ +From stable-bounces@linux.kernel.org Fri Sep 28 15:53:04 2007 +From: Michal Schmidt +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 + +commit 45dfd5b5dd20f17fe23dafc5cfe921474d27f849 from upstream + +Signed-off-by: Michal Schmidt +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ diff --git a/queue-2.6.22/fix-smp-poweroff-hangs.patch b/queue-2.6.22/fix-smp-poweroff-hangs.patch new file mode 100644 index 00000000000..ea2abbc0543 --- /dev/null +++ b/queue-2.6.22/fix-smp-poweroff-hangs.patch @@ -0,0 +1,43 @@ +From 4047727e5ae33f9b8d2b7766d1994ea6e5ec2991 Mon Sep 17 00:00:00 2001 +From: Mark Lord +Date: Mon, 1 Oct 2007 01:20:10 -0700 +Subject: Fix SMP poweroff hangs + +From: Mark Lord + +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 +Acked-by: Thomas Gleixner +Cc: "Rafael J. Wysocki" +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/sys.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/kernel/sys.c ++++ b/kernel/sys.c +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -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(); + } diff --git a/queue-2.6.22/fix-timer_stats-printout-of-events-sec.patch b/queue-2.6.22/fix-timer_stats-printout-of-events-sec.patch new file mode 100644 index 00000000000..4139c7313bf --- /dev/null +++ b/queue-2.6.22/fix-timer_stats-printout-of-events-sec.patch @@ -0,0 +1,42 @@ +From stable-bounces@linux.kernel.org Sun Oct 7 02:38:33 2007 +From: Anton Blanchard +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 + +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 +Acked-by: Ingo Molnar +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +--- + + 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); + diff --git a/queue-2.6.22/i2c-algo-bit-read-block-data-bugfix.patch b/queue-2.6.22/i2c-algo-bit-read-block-data-bugfix.patch new file mode 100644 index 00000000000..2d1f7b2c546 --- /dev/null +++ b/queue-2.6.22/i2c-algo-bit-read-block-data-bugfix.patch @@ -0,0 +1,124 @@ +From stable-bounces@linux.kernel.org Thu Sep 27 06:17:47 2007 +From: Jean Delvare +Date: Thu, 27 Sep 2007 15:17:25 +0200 +Subject: i2c-algo-bit: Read block data bugfix +To: stable@kernel.org +Cc: David Brownell +Message-ID: <20070927151725.6c33402b@hyperion.delvare> + + +From: David Brownell + +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 +Signed-off-by: Jean Delvare +Signed-off-by: Greg Kroah-Hartman + +--- + 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; + } diff --git a/queue-2.6.22/libata-update-drive-blacklists.patch b/queue-2.6.22/libata-update-drive-blacklists.patch new file mode 100644 index 00000000000..2df30f4b794 --- /dev/null +++ b/queue-2.6.22/libata-update-drive-blacklists.patch @@ -0,0 +1,57 @@ +From stable-bounces@linux.kernel.org Fri Sep 28 12:30:03 2007 +From: Chuck Ebbert +Date: Fri, 28 Sep 2007 15:29:32 -0400 +Subject: libata: update drive blacklists +To: linux-stable +Cc: Jeff Garzik +Message-ID: <46FD561C.70800@redhat.com> + +From: Chuck Ebbert + +Update the libata drive blacklists to the latest in 2.6.23-rc8. + +Signed-off-by: Chuck Ebbert +Cc: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + 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 */ + { } diff --git a/queue-2.6.22/nlm-fix-a-circular-lock-dependency-in-lockd.patch b/queue-2.6.22/nlm-fix-a-circular-lock-dependency-in-lockd.patch new file mode 100644 index 00000000000..307a65c6f4a --- /dev/null +++ b/queue-2.6.22/nlm-fix-a-circular-lock-dependency-in-lockd.patch @@ -0,0 +1,109 @@ +From stable-bounces@linux.kernel.org Tue Sep 25 12:56:27 2007 +From: Trond Myklebust +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 + +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 +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-2.6.22/series b/queue-2.6.22/series index 309fd33d796..18cc10cd32f 100644 --- a/queue-2.6.22/series +++ b/queue-2.6.22/series @@ -1 +1,10 @@ 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 diff --git a/queue-2.6.22/sky2-hw-watchdog.patch b/queue-2.6.22/sky2-hw-watchdog.patch new file mode 100644 index 00000000000..3180162f6fc --- /dev/null +++ b/queue-2.6.22/sky2-hw-watchdog.patch @@ -0,0 +1,161 @@ +From stable-bounces@linux.kernel.org Fri Sep 28 09:52:23 2007 +From: Stephen Hemminger +Date: Fri, 28 Sep 2007 09:48:12 -0700 +Subject: sky2: reduce impact of watchdog timer +To: Krzysztof Oledzki , Greg KH +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 + +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 +Signed-off-by: Greg Kroah-Hartman + + +--- + 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; diff --git a/queue-2.6.22/sky2-tx-sum-resume.patch b/queue-2.6.22/sky2-tx-sum-resume.patch new file mode 100644 index 00000000000..10fda8ed27e --- /dev/null +++ b/queue-2.6.22/sky2-tx-sum-resume.patch @@ -0,0 +1,60 @@ +From stable-bounces@linux.kernel.org Fri Sep 28 09:52:23 2007 +From: Stephen Hemminger +Date: Fri, 28 Sep 2007 09:48:14 -0700 +Subject: sky2: fix transmit state on resume +To: Krzysztof Oledzki , Greg KH +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 + +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 +Signed-off-by: Greg Kroah-Hartman + +--- + 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); diff --git a/queue-2.6.22/sky2-vlan-len.patch b/queue-2.6.22/sky2-vlan-len.patch new file mode 100644 index 00000000000..0ae0a37f456 --- /dev/null +++ b/queue-2.6.22/sky2-vlan-len.patch @@ -0,0 +1,51 @@ +From shemminger@linux-foundation.org Fri Sep 28 09:52:14 2007 +From: Stephen Hemminger +Date: Fri, 28 Sep 2007 09:48:13 -0700 +Subject: sky2: fix VLAN receive processing +To: Krzysztof Oledzki , Greg KH +Cc: stable@kernel.org, netdev@vger.kernel.org, Pierre-Yves Ritschard +Message-ID: <20070928164858.539587428@linux-foundation.org> +Content-Disposition: inline; filename=sky2-vlan-len.patch + +From: Stephen Hemminger + +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 +Signed-off-by: Stephen Hemminger +Signed-off-by: Greg Kroah-Hartman + +--- + 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)