]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
.31 patches
authorGreg Kroah-Hartman <gregkh@suse.de>
Wed, 16 Dec 2009 18:55:07 +0000 (10:55 -0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Wed, 16 Dec 2009 18:55:07 +0000 (10:55 -0800)
27 files changed:
queue-2.6.31/au1x00-fix-crash-when-trying-register_netdev.patch [new file with mode: 0644]
queue-2.6.31/b44-fix-wedge-when-using-netconsole.patch [new file with mode: 0644]
queue-2.6.31/b44-wol-setup-one-bit-off-stack-corruption-kernel-panic-fix.patch [new file with mode: 0644]
queue-2.6.31/e100-use-pci-pool-to-work-around-gfp_atomic-order-5-memory-allocation-failure.patch [new file with mode: 0644]
queue-2.6.31/gro-fix-illegal-merging-of-trailer-trash.patch [new file with mode: 0644]
queue-2.6.31/ide-fix-ioctl-to-pass-requested-transfer-mode-to-ide_find_dma_mode-instead-of-udma6.patch [new file with mode: 0644]
queue-2.6.31/ide-serialize-cmd643-and-cmd646-to-fix-a-hardware-bug-with-ssd.patch [new file with mode: 0644]
queue-2.6.31/ip_fragment-also-adjust-skb-truesize-for-packets-not-owned-by-a-socket.patch [new file with mode: 0644]
queue-2.6.31/net-fix-the-rollback-test-in-dev_change_name.patch [new file with mode: 0644]
queue-2.6.31/net-smc91x-fix-irq-flags.patch [new file with mode: 0644]
queue-2.6.31/revert-ide-try-to-use-pio-mode-0-during-probe-if-possible.patch [new file with mode: 0644]
queue-2.6.31/revert-isdn-isdn_ppp-use-skb-list-facilities-instead-of-home-grown-implementation.patch [new file with mode: 0644]
queue-2.6.31/serial-suncore-add-ignore_line-argument-to-sunserial_console_match.patch [new file with mode: 0644]
queue-2.6.31/serial-suncore-fix-rsc-lom-handling-in-sunserial_console_termios.patch [new file with mode: 0644]
queue-2.6.31/series
queue-2.6.31/slc90e66-fix-udma-handling.patch [new file with mode: 0644]
queue-2.6.31/smsc9420-prevent-bug-if-ethtool-is-called-with-interface-down.patch [new file with mode: 0644]
queue-2.6.31/sparc-set-uts_machine-correctly.patch [new file with mode: 0644]
queue-2.6.31/sparc64-don-t-specify-irqf_shared-for-ldc-interrupts.patch [new file with mode: 0644]
queue-2.6.31/sparc64-fix-definition-of-vmemmap_size.patch [new file with mode: 0644]
queue-2.6.31/sparc64-fix-overly-strict-range-type-matching-for-pci-devices.patch [new file with mode: 0644]
queue-2.6.31/sparc64-fix-stack-debugging-irq-stack-regression.patch [new file with mode: 0644]
queue-2.6.31/sunsab-do-not-set-sunsab_reg.cons-right-before-registering-minors.patch [new file with mode: 0644]
queue-2.6.31/sunsu-fix-detection-of-su-ports-which-are-rsc-console-or-control.patch [new file with mode: 0644]
queue-2.6.31/sunsu-pass-true-ignore_line-to-console-match-when-rsc-or-lom-console.patch [new file with mode: 0644]
queue-2.6.31/sunsu-use-sunserial_console_termios-in-sunsu_console_setup.patch [new file with mode: 0644]
queue-2.6.31/vlan-fix-register_vlan_dev-error-path.patch [new file with mode: 0644]

diff --git a/queue-2.6.31/au1x00-fix-crash-when-trying-register_netdev.patch b/queue-2.6.31/au1x00-fix-crash-when-trying-register_netdev.patch
new file mode 100644 (file)
index 0000000..270db0e
--- /dev/null
@@ -0,0 +1,53 @@
+From 31e1b0665a0c40911f3b40f3f2e2d82cbea3f8eb Mon Sep 17 00:00:00 2001
+From: Alexander Beregalov <a.beregalov@gmail.com>
+Date: Sun, 22 Nov 2009 20:40:52 -0800
+Subject: Au1x00: fix crash when trying register_netdev()
+
+From: Alexander Beregalov <a.beregalov@gmail.com>
+
+[ Upstream commit 63edaf647607795a065e6956a79c47f500dc8447 ]
+
+Andreas Lohre reported that the driver crashes when trying
+to register_netdev(), he sugessted to move dev->netdev_ops initialization
+before calling register_netdev(), it worked for him.
+
+Reported-by: Andreas Lohre <alohre@gmail.com>
+Signed-off-by: Alexander Beregalov <a.beregalov@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/au1000_eth.c |   15 ++++++++-------
+ 1 file changed, 8 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/au1000_eth.c
++++ b/drivers/net/au1000_eth.c
+@@ -1089,7 +1089,14 @@ static struct net_device * au1000_probe(
+               return NULL;
+       }
+-      if ((err = register_netdev(dev)) != 0) {
++      dev->base_addr = base;
++      dev->irq = irq;
++      dev->netdev_ops = &au1000_netdev_ops;
++      SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
++      dev->watchdog_timeo = ETH_TX_TIMEOUT;
++
++      err = register_netdev(dev);
++      if (err != 0) {
+               printk(KERN_ERR "%s: Cannot register net device, error %d\n",
+                               DRV_NAME, err);
+               free_netdev(dev);
+@@ -1207,12 +1214,6 @@ static struct net_device * au1000_probe(
+               aup->tx_db_inuse[i] = pDB;
+       }
+-      dev->base_addr = base;
+-      dev->irq = irq;
+-      dev->netdev_ops = &au1000_netdev_ops;
+-      SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops);
+-      dev->watchdog_timeo = ETH_TX_TIMEOUT;
+-
+       /*
+        * The boot code uses the ethernet controller, so reset it to start
+        * fresh.  au1000_init() expects that the device is in reset state.
diff --git a/queue-2.6.31/b44-fix-wedge-when-using-netconsole.patch b/queue-2.6.31/b44-fix-wedge-when-using-netconsole.patch
new file mode 100644 (file)
index 0000000..27ecee6
--- /dev/null
@@ -0,0 +1,38 @@
+From 174385035d1b037bd5d361d0732fc0e68180baf8 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 30 Nov 2009 00:13:28 -0800
+Subject: b44: Fix wedge when using netconsole.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 0cae200eec6330cd2c20b24279597be1da50dc93 ]
+
+Fixes kernel bugzilla #14691
+
+Due to the way netpoll works, it is perfectly legal to see
+NAPI already scheduled when new device events are pending
+in b44_interrupt().
+
+So logging a message about it is wrong and in fact harmful.
+
+Based upon a patch by Andreas Mohr.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/b44.c |    3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/drivers/net/b44.c
++++ b/drivers/net/b44.c
+@@ -913,9 +913,6 @@ static irqreturn_t b44_interrupt(int irq
+                       bp->istat = istat;
+                       __b44_disable_ints(bp);
+                       __napi_schedule(&bp->napi);
+-              } else {
+-                      printk(KERN_ERR PFX "%s: Error, poll already scheduled\n",
+-                             dev->name);
+               }
+ irq_ack:
diff --git a/queue-2.6.31/b44-wol-setup-one-bit-off-stack-corruption-kernel-panic-fix.patch b/queue-2.6.31/b44-wol-setup-one-bit-off-stack-corruption-kernel-panic-fix.patch
new file mode 100644 (file)
index 0000000..910f1dc
--- /dev/null
@@ -0,0 +1,45 @@
+From afd08c8325cfaef9587786ff258d14e3ca599b1e Mon Sep 17 00:00:00 2001
+From: Stanislav Brabec <sbrabec@suse.cz>
+Date: Tue, 8 Dec 2009 21:00:22 -0800
+Subject: b44 WOL setup: one-bit-off stack corruption kernel panic fix
+
+
+From: Stanislav Brabec <sbrabec@suse.cz>
+
+[ Upstream commit: e0188829cb724e7d12a2d4e343b368ff1d6e1471 ]
+
+About 50% of shutdowns of b44 Ethernet adapter ends by kernel panic
+with kernels compiled with stack-protector.
+
+Checking b44_magic_pattern() return values, one call of
+b44_magic_pattern() returns 127. It means, that set_bit(128, pmask)
+was called on line 1509. It means that bit 0 of 17th byte of pmask was
+overwritten. But pmask has only 16 bytes. Stack corruption happens.
+
+It seems that set_bit() on line 1509 always writes one bit off.
+
+The fix does not only solve the stack corruption, but also makes Wake
+On LAN working on my onboard B44 on Asus A7V-333X mainboard.
+
+It seems that this problem affects all kernel versions since commit
+725ad800 ([PATCH] b44: add wol for old nic) on 2006-06-20.
+
+Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/b44.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/b44.c
++++ b/drivers/net/b44.c
+@@ -1505,8 +1505,7 @@ static int b44_magic_pattern(u8 *macaddr
+               for (k = 0; k< ethaddr_bytes; k++) {
+                       ppattern[offset + magicsync +
+                               (j * ETH_ALEN) + k] = macaddr[k];
+-                      len++;
+-                      set_bit(len, (unsigned long *) pmask);
++                      set_bit(len++, (unsigned long *) pmask);
+               }
+       }
+       return len - 1;
diff --git a/queue-2.6.31/e100-use-pci-pool-to-work-around-gfp_atomic-order-5-memory-allocation-failure.patch b/queue-2.6.31/e100-use-pci-pool-to-work-around-gfp_atomic-order-5-memory-allocation-failure.patch
new file mode 100644 (file)
index 0000000..4f0b3c6
--- /dev/null
@@ -0,0 +1,83 @@
+From 09adf51b23cfdfc9a46840213eb75e0132a33420 Mon Sep 17 00:00:00 2001
+From: Roger Oksanen <roger.oksanen@cs.helsinki.fi>
+Date: Sun, 29 Nov 2009 17:17:29 -0800
+Subject: e100: Use pci pool to work around GFP_ATOMIC order 5 memory allocation failure
+
+
+From: Roger Oksanen <roger.oksanen@cs.helsinki.fi>
+
+[ Upstream commit 98468efddb101f8a29af974101c17ba513b07be1 ]
+
+pci_alloc_consistent uses GFP_ATOMIC allocation that may fail on some systems
+with limited memory (Bug #14265). pci_pool_alloc allows waiting with
+GFP_KERNEL.
+
+Tested-by: Karol Lewandowski <karol.k.lewandowski@gmail.com>
+Signed-off-by: Roger Oksanen <roger.oksanen@cs.helsinki.fi>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/e100.c |   17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/e100.c
++++ b/drivers/net/e100.c
+@@ -156,6 +156,7 @@
+ #include <linux/init.h>
+ #include <linux/pci.h>
+ #include <linux/dma-mapping.h>
++#include <linux/dmapool.h>
+ #include <linux/netdevice.h>
+ #include <linux/etherdevice.h>
+ #include <linux/mii.h>
+@@ -601,6 +602,7 @@ struct nic {
+       struct mem *mem;
+       dma_addr_t dma_addr;
++      struct pci_pool *cbs_pool;
+       dma_addr_t cbs_dma_addr;
+       u8 adaptive_ifs;
+       u8 tx_threshold;
+@@ -1779,9 +1781,7 @@ static void e100_clean_cbs(struct nic *n
+                       nic->cb_to_clean = nic->cb_to_clean->next;
+                       nic->cbs_avail++;
+               }
+-              pci_free_consistent(nic->pdev,
+-                      sizeof(struct cb) * nic->params.cbs.count,
+-                      nic->cbs, nic->cbs_dma_addr);
++              pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr);
+               nic->cbs = NULL;
+               nic->cbs_avail = 0;
+       }
+@@ -1799,8 +1799,8 @@ static int e100_alloc_cbs(struct nic *ni
+       nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL;
+       nic->cbs_avail = 0;
+-      nic->cbs = pci_alloc_consistent(nic->pdev,
+-              sizeof(struct cb) * count, &nic->cbs_dma_addr);
++      nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL,
++                                &nic->cbs_dma_addr);
+       if (!nic->cbs)
+               return -ENOMEM;
+@@ -2827,7 +2827,11 @@ static int __devinit e100_probe(struct p
+               DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n");
+               goto err_out_free;
+       }
+-
++      nic->cbs_pool = pci_pool_create(netdev->name,
++                         nic->pdev,
++                         nic->params.cbs.count * sizeof(struct cb),
++                         sizeof(u32),
++                         0);
+       DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n",
+               (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0),
+               pdev->irq, netdev->dev_addr);
+@@ -2857,6 +2861,7 @@ static void __devexit e100_remove(struct
+               unregister_netdev(netdev);
+               e100_free(nic);
+               pci_iounmap(pdev, nic->csr);
++              pci_pool_destroy(nic->cbs_pool);
+               free_netdev(netdev);
+               pci_release_regions(pdev);
+               pci_disable_device(pdev);
diff --git a/queue-2.6.31/gro-fix-illegal-merging-of-trailer-trash.patch b/queue-2.6.31/gro-fix-illegal-merging-of-trailer-trash.patch
new file mode 100644 (file)
index 0000000..fb751f2
--- /dev/null
@@ -0,0 +1,42 @@
+From d6ad89d9e034e0815cd166ed2b55241dc0d8d102 Mon Sep 17 00:00:00 2001
+From: Herbert Xu <herbert@gondor.apana.org.au>
+Date: Tue, 17 Nov 2009 05:18:18 -0800
+Subject: gro: Fix illegal merging of trailer trash
+
+
+From: Herbert Xu <herbert@gondor.apana.org.au>
+
+[ Upstream commit 69c0cab120a85471054614418b447349caba22d7 ]
+
+When we've merged skb's with page frags, and subsequently receive
+a trailer skb (< MSS) that is not completely non-linear (this can
+occur on Intel NICs if the packet size falls below the threshold),
+GRO ends up producing an illegal GSO skb with a frag_list.
+
+This is harmless unless the skb is then forwarded through an
+interface that requires software GSO, whereupon the GSO code
+will BUG.
+
+This patch detects this case in GRO and avoids merging the
+trailer skb.
+
+Reported-by: Mark Wagner <mwagner@redhat.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/core/skbuff.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -2704,7 +2704,8 @@ int skb_gro_receive(struct sk_buff **hea
+               NAPI_GRO_CB(skb)->free = 1;
+               goto done;
+-      }
++      } else if (skb_gro_len(p) != pinfo->gso_size)
++              return -E2BIG;
+       headroom = skb_headroom(p);
+       nskb = netdev_alloc_skb(p->dev, headroom + skb_gro_offset(p));
diff --git a/queue-2.6.31/ide-fix-ioctl-to-pass-requested-transfer-mode-to-ide_find_dma_mode-instead-of-udma6.patch b/queue-2.6.31/ide-fix-ioctl-to-pass-requested-transfer-mode-to-ide_find_dma_mode-instead-of-udma6.patch
new file mode 100644 (file)
index 0000000..17eb68f
--- /dev/null
@@ -0,0 +1,47 @@
+From 85ede3ba652c6308bd387098c56c3a32aa4cc018 Mon Sep 17 00:00:00 2001
+From: Hemant Pedanekar <hemantp@ti.com>
+Date: Wed, 25 Nov 2009 15:04:54 -0800
+Subject: ide: fix ioctl to pass requested transfer mode to ide_find_dma_mode instead of UDMA6
+
+From: Hemant Pedanekar <hemantp@ti.com>
+
+[ Upstream commit 28c1969ff887bc2a7df39272850dece01de03285 ]
+
+Currently, ide_cmd_ioctl when invoked for setting DMA transfer mode calls
+ide_find_dma_mode with requested mode as XFER_UDMA_6. This prevents setting DMA
+mode to any other value than the default (maximum) supported by the device (or
+UDMA6, if supported) irrespective of the actual requested transfer mode and
+returns error.
+
+For example, setting mode to UDMA2 using hdparm, where UDMA4 is the default
+transfer mode gives following error:
+       # ./hdparm -d1 -Xudma2  /dev/hda
+        /dev/hda:hda: UDMA/66 mode selected
+        setting using_dma to 1 (on)
+        hda: UDMA/66 mode selected
+        setting xfermode to 66 (UltraDMA mode2)
+        HDIO_DRIVE_CMD(setxfermode) failed: Invalid argument
+        using_dma     =  1 (on)
+
+This patch fixes the issue.
+
+Signed-off-by: Hemant Pedanekar <hemantp@ti.com>
+Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ide/ide-ioctls.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/ide/ide-ioctls.c
++++ b/drivers/ide/ide-ioctls.c
+@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *dr
+       if (tf->command == ATA_CMD_SET_FEATURES &&
+           tf->feature == SETFEATURES_XFER &&
+           tf->nsect >= XFER_SW_DMA_0) {
+-              xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6);
++              xfer_rate = ide_find_dma_mode(drive, tf->nsect);
+               if (xfer_rate != tf->nsect) {
+                       err = -EINVAL;
+                       goto abort;
diff --git a/queue-2.6.31/ide-serialize-cmd643-and-cmd646-to-fix-a-hardware-bug-with-ssd.patch b/queue-2.6.31/ide-serialize-cmd643-and-cmd646-to-fix-a-hardware-bug-with-ssd.patch
new file mode 100644 (file)
index 0000000..b829d2e
--- /dev/null
@@ -0,0 +1,59 @@
+From ba40be559055c896281ed494e1afc335ec82c1b2 Mon Sep 17 00:00:00 2001
+From: Mikulas Patocka <mpatocka@redhat.com>
+Date: Wed, 21 Oct 2009 08:55:28 +0000
+Subject: ide: Serialize CMD643 and CMD646 to fix a hardware bug with SSD
+
+From: Mikulas Patocka <mpatocka@redhat.com>
+
+[ Upstream commit 9bd7496f5dd488e109e91d9d5743915fb4dfbfde ]
+
+CMD646 corrupts data on concurrent transfers on both channels when IDE SSD is
+connected to one of the channels.
+
+Setup that demonstrates this hardware bug: Ultra 5, onboard CMD646, rev 3.
+/dev/hda is 8GB Seagate ST38410A in MWDMA2
+/dev/hdd is 32GB SSD SiliconHardDisk in MWDMA2
+
+- When reading /dev/hdd (for example with dd or fsck), reads from /dev/hda
+  are corrupted, there are twiddled single bits 1->0 and some full 32-bit
+  words corrupted, sometimes commands fail (which switches /dev/hda to
+  PIO mode but the corruptions happen even in PIO).
+- Reads from /dev/hdd don't seem to be corrupted (i.e. fsck passes fine).
+- When I connected normal rotating harddisk to /dev/hdd, there was no
+  corruption, so the corruption is something specific to SSD.
+- I tried the same setup on a PCI card with CMD649 and saw no corruption.
+
+This patch serializes the operation for CMD646 and 643 (I didn't test
+CMD643 but it may have the same hw bug too because it's earlier design).
+CMD649 is good. I don't know anything about CMD 648.
+
+Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
+Tested-by: Frans Pop <elendil@planet.nl>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ide/cmd64x.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/ide/cmd64x.c
++++ b/drivers/ide/cmd64x.c
+@@ -379,7 +379,8 @@ static const struct ide_port_info cmd64x
+               .enablebits     = {{0x00,0x00,0x00}, {0x51,0x08,0x08}},
+               .port_ops       = &cmd64x_port_ops,
+               .host_flags     = IDE_HFLAG_CLEAR_SIMPLEX |
+-                                IDE_HFLAG_ABUSE_PREFETCH,
++                                IDE_HFLAG_ABUSE_PREFETCH |
++                                IDE_HFLAG_SERIALIZE,
+               .pio_mask       = ATA_PIO5,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = 0x00, /* no udma */
+@@ -389,7 +390,8 @@ static const struct ide_port_info cmd64x
+               .init_chipset   = init_chipset_cmd64x,
+               .enablebits     = {{0x51,0x04,0x04}, {0x51,0x08,0x08}},
+               .port_ops       = &cmd648_port_ops,
+-              .host_flags     = IDE_HFLAG_ABUSE_PREFETCH,
++              .host_flags     = IDE_HFLAG_ABUSE_PREFETCH |
++                                IDE_HFLAG_SERIALIZE,
+               .pio_mask       = ATA_PIO5,
+               .mwdma_mask     = ATA_MWDMA2,
+               .udma_mask      = ATA_UDMA2,
diff --git a/queue-2.6.31/ip_fragment-also-adjust-skb-truesize-for-packets-not-owned-by-a-socket.patch b/queue-2.6.31/ip_fragment-also-adjust-skb-truesize-for-packets-not-owned-by-a-socket.patch
new file mode 100644 (file)
index 0000000..9b66df6
--- /dev/null
@@ -0,0 +1,41 @@
+From 147e157dcbcc8cbf392d25eb07c8d8685621c2dd Mon Sep 17 00:00:00 2001
+From: Patrick McHardy <kaber@trash.net>
+Date: Tue, 1 Dec 2009 15:53:57 -0800
+Subject: ip_fragment: also adjust skb->truesize for packets not owned by a socket
+
+
+From: Patrick McHardy <kaber@trash.net>
+
+[ Upstream commit b2722b1c3a893ec6021508da15b32282ec79f4da ]
+
+When a large packet gets reassembled by ip_defrag(), the head skb
+accounts for all the fragments in skb->truesize. If this packet is
+refragmented again, skb->truesize is not re-adjusted to reflect only
+the head size since its not owned by a socket. If the head fragment
+then gets recycled and reused for another received fragment, it might
+exceed the defragmentation limits due to its large truesize value.
+
+skb_recycle_check() explicitly checks for linear skbs, so any recycled
+skb should reflect its true size in skb->truesize. Change ip_fragment()
+to also adjust the truesize value of skbs not owned by a socket.
+
+Reported-and-tested-by: Ben Menchaca <ben@bigfootnetworks.com>
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/ipv4/ip_output.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -500,8 +500,8 @@ int ip_fragment(struct sk_buff *skb, int
+                       if (skb->sk) {
+                               frag->sk = skb->sk;
+                               frag->destructor = sock_wfree;
+-                              truesizes += frag->truesize;
+                       }
++                      truesizes += frag->truesize;
+               }
+               /* Everything is OK. Generate! */
diff --git a/queue-2.6.31/net-fix-the-rollback-test-in-dev_change_name.patch b/queue-2.6.31/net-fix-the-rollback-test-in-dev_change_name.patch
new file mode 100644 (file)
index 0000000..d4e08d4
--- /dev/null
@@ -0,0 +1,50 @@
+From 8197fc4e7f06a6474247f62651092fd55b55d768 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Sun, 15 Nov 2009 23:30:24 +0000
+Subject: net: Fix the rollback test in dev_change_name()
+
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 91e9c07bd635353d1a278bdb38dbb56ac371bcb8 ]
+
+net: Fix the rollback test in dev_change_name()
+
+In dev_change_name() an err variable is used for storing the original
+call_netdevice_notifiers() errno (negative) and testing for a rollback
+error later, but the test for non-zero is wrong, because the err might
+have positive value as well - from dev_alloc_name(). It means the
+rollback for a netdevice with a number > 0 will never happen. (The err
+test is reordered btw. to make it more readable.)
+
+Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/core/dev.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -933,14 +933,15 @@ rollback:
+       ret = notifier_to_errno(ret);
+       if (ret) {
+-              if (err) {
+-                      printk(KERN_ERR
+-                             "%s: name change rollback failed: %d.\n",
+-                             dev->name, ret);
+-              } else {
++              /* err >= 0 after dev_alloc_name() or stores the first errno */
++              if (err >= 0) {
+                       err = ret;
+                       memcpy(dev->name, oldname, IFNAMSIZ);
+                       goto rollback;
++              } else {
++                      printk(KERN_ERR
++                             "%s: name change rollback failed: %d.\n",
++                             dev->name, ret);
+               }
+       }
diff --git a/queue-2.6.31/net-smc91x-fix-irq-flags.patch b/queue-2.6.31/net-smc91x-fix-irq-flags.patch
new file mode 100644 (file)
index 0000000..dbac4f5
--- /dev/null
@@ -0,0 +1,41 @@
+From 24c367bd0d9cede64ec21cb5f9a5b7b0b9143a81 Mon Sep 17 00:00:00 2001
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+Date: Sat, 28 Nov 2009 00:13:23 +0000
+Subject: NET: smc91x: Fix irq flags
+
+
+From: Russell King - ARM Linux <linux@arm.linux.org.uk>
+
+[ Upstream commit d5ccd67bb77ced5249067d05171992a7d5020393 ]
+
+smc91x.h defines SMC_IRQ_FLAGS to be -1 when it wants the interrupt
+flags to be taken from the resource structure.  However, d280ead
+changed this to checking for non-zero resource flags.
+
+Unfortunately, this means that on some platforms, we end up passing
+'-1' to request_irq rather than the desired result.  Combine the two
+conditions into one so that the IRQ flags are taken from the resource
+if either SMC_IRQ_FLAGS is -1 or the resource flags specify an
+interrupt trigger.
+
+This restores network on at least the Versatile platform.
+
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Acked-by: Eric Miao <eric.y.miao@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/smc91x.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/smc91x.c
++++ b/drivers/net/smc91x.c
+@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struc
+       ndev->irq = ires->start;
+-      if (ires->flags & IRQF_TRIGGER_MASK)
++      if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK)
+               irq_flags = ires->flags & IRQF_TRIGGER_MASK;
+       ret = smc_request_attrib(pdev, ndev);
diff --git a/queue-2.6.31/revert-ide-try-to-use-pio-mode-0-during-probe-if-possible.patch b/queue-2.6.31/revert-ide-try-to-use-pio-mode-0-during-probe-if-possible.patch
new file mode 100644 (file)
index 0000000..74ad546
--- /dev/null
@@ -0,0 +1,64 @@
+From 8fd67c36816a1c905a2ef11bfc0071be9d8106e0 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Fri, 6 Nov 2009 04:52:50 -0800
+Subject: Revert "ide: try to use PIO Mode 0 during probe if possible"
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 0fb18c4777ff424c1db694af98443a201fa4fc30 ]
+
+This reverts commit 6029336426a2b43e4bc6f4a84be8789a047d139e.
+
+Ok, we really do need to revert this, even with Bart's sis5513.c
+fix in there.
+
+The problem is that several driver's ->set_pio_mode() method
+depends upon the drive->media type being set properly.  Most
+of them use this to enable prefetching, which can only be done
+for disk media.
+
+But the commit being reverted here calls ->set_pio_mode() before
+it's setup.  Actually it considers everything disk because that
+is the default media type set by ide_port_init_devices_data().
+
+The set of drivers that depend upon the media type in their
+->set_pio_method() are:
+
+drivers/ide/alim15x3.c
+drivers/ide/it8172.c
+drivers/ide/it8213.c
+drivers/ide/pdc202xx_old.c
+drivers/ide/piix.c
+drivers/ide/qd65xx.c
+drivers/ide/sis5513.c
+drivers/ide/slc90e66.c
+
+And it is possible that we could fix this by guarding the prefetching
+and other media dependent setting changes with a test on
+IDE_PFLAG_PROBING in hwif->port_flags, that's simply too risky for
+2.6.32-rcX and -stable.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ide/ide-probe.c |    9 ---------
+ 1 file changed, 9 deletions(-)
+
+--- a/drivers/ide/ide-probe.c
++++ b/drivers/ide/ide-probe.c
+@@ -1035,15 +1035,6 @@ static void ide_port_init_devices(ide_hw
+               if (port_ops && port_ops->init_dev)
+                       port_ops->init_dev(drive);
+       }
+-
+-      ide_port_for_each_dev(i, drive, hwif) {
+-              /*
+-               * default to PIO Mode 0 before we figure out
+-               * the most suited mode for the attached device
+-               */
+-              if (port_ops && port_ops->set_pio_mode)
+-                      port_ops->set_pio_mode(drive, 0);
+-      }
+ }
+ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
diff --git a/queue-2.6.31/revert-isdn-isdn_ppp-use-skb-list-facilities-instead-of-home-grown-implementation.patch b/queue-2.6.31/revert-isdn-isdn_ppp-use-skb-list-facilities-instead-of-home-grown-implementation.patch
new file mode 100644 (file)
index 0000000..7f0e162
--- /dev/null
@@ -0,0 +1,533 @@
+From 8a4be359396891878b81c71c52e4d41c628b9df2 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sun, 15 Nov 2009 22:23:47 -0800
+Subject: Revert "isdn: isdn_ppp: Use SKB list facilities instead of home-grown implementation."
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit e29d4363174949a7a4e46f670993d7ff43342c1c ]
+
+This reverts commit 38783e671399b5405f1fd177d602c400a9577ae6.
+
+It causes kernel bugzilla #14594
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/isdn/i4l/isdn_ppp.c |  348 ++++++++++++++++++++------------------------
+ include/linux/isdn_ppp.h    |    2 
+ 2 files changed, 162 insertions(+), 188 deletions(-)
+
+--- a/drivers/isdn/i4l/isdn_ppp.c
++++ b/drivers/isdn/i4l/isdn_ppp.c
+@@ -1535,10 +1535,8 @@ static int isdn_ppp_mp_bundle_array_init
+       int sz = ISDN_MAX_CHANNELS*sizeof(ippp_bundle);
+       if( (isdn_ppp_bundle_arr = kzalloc(sz, GFP_KERNEL)) == NULL )
+               return -ENOMEM;
+-      for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
++      for( i = 0; i < ISDN_MAX_CHANNELS; i++ )
+               spin_lock_init(&isdn_ppp_bundle_arr[i].lock);
+-              skb_queue_head_init(&isdn_ppp_bundle_arr[i].frags);
+-      }
+       return 0;
+ }
+@@ -1571,7 +1569,7 @@ static int isdn_ppp_mp_init( isdn_net_lo
+               if ((lp->netdev->pb = isdn_ppp_mp_bundle_alloc()) == NULL)
+                       return -ENOMEM;
+               lp->next = lp->last = lp;       /* nobody else in a queue */
+-              skb_queue_head_init(&lp->netdev->pb->frags);
++              lp->netdev->pb->frags = NULL;
+               lp->netdev->pb->frames = 0;
+               lp->netdev->pb->seq = UINT_MAX;
+       }
+@@ -1583,29 +1581,28 @@ static int isdn_ppp_mp_init( isdn_net_lo
+ static u32 isdn_ppp_mp_get_seq( int short_seq, 
+                                       struct sk_buff * skb, u32 last_seq );
+-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
+-                              struct sk_buff *to);
+-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+-                                 struct sk_buff *from, struct sk_buff *to,
+-                                 u32 lastseq);
+-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb);
++static struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
++                      struct sk_buff * from, struct sk_buff * to );
++static void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
++                              struct sk_buff * from, struct sk_buff * to );
++static void isdn_ppp_mp_free_skb( ippp_bundle * mp, struct sk_buff * skb );
+ static void isdn_ppp_mp_print_recv_pkt( int slot, struct sk_buff * skb );
+ static void isdn_ppp_mp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, 
+-                              struct sk_buff *skb)
++                                                      struct sk_buff *skb)
+ {
+-      struct sk_buff *newfrag, *frag, *start, *nextf;
+-      u32 newseq, minseq, thisseq;
+-      isdn_mppp_stats *stats;
+       struct ippp_struct *is;
++      isdn_net_local * lpq;
++      ippp_bundle * mp;
++      isdn_mppp_stats * stats;
++      struct sk_buff * newfrag, * frag, * start, *nextf;
++      u32 newseq, minseq, thisseq;
+       unsigned long flags;
+-      isdn_net_local *lpq;
+-      ippp_bundle *mp;
+       int slot;
+       spin_lock_irqsave(&net_dev->pb->lock, flags);
+-      mp = net_dev->pb;
+-      stats = &mp->stats;
++      mp = net_dev->pb;
++        stats = &mp->stats;
+       slot = lp->ppp_slot;
+       if (slot < 0 || slot >= ISDN_MAX_CHANNELS) {
+               printk(KERN_ERR "%s: lp->ppp_slot(%d)\n",
+@@ -1616,19 +1613,20 @@ static void isdn_ppp_mp_receive(isdn_net
+               return;
+       }
+       is = ippp_table[slot];
+-      if (++mp->frames > stats->max_queue_len)
++      if( ++mp->frames > stats->max_queue_len )
+               stats->max_queue_len = mp->frames;
+-
++
+       if (is->debug & 0x8)
+               isdn_ppp_mp_print_recv_pkt(lp->ppp_slot, skb);
+-      newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
+-                                   skb, is->last_link_seqno);
++      newseq = isdn_ppp_mp_get_seq(is->mpppcfg & SC_IN_SHORT_SEQ,
++                                              skb, is->last_link_seqno);
++
+       /* if this packet seq # is less than last already processed one,
+        * toss it right away, but check for sequence start case first 
+        */
+-      if (mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT)) {
++      if( mp->seq > MP_LONGSEQ_MAX && (newseq & MP_LONGSEQ_MAXBIT) ) {
+               mp->seq = newseq;       /* the first packet: required for
+                                        * rfc1990 non-compliant clients --
+                                        * prevents constant packet toss */
+@@ -1638,7 +1636,7 @@ static void isdn_ppp_mp_receive(isdn_net
+               spin_unlock_irqrestore(&mp->lock, flags);
+               return;
+       }
+-
++
+       /* find the minimum received sequence number over all links */
+       is->last_link_seqno = minseq = newseq;
+       for (lpq = net_dev->queue;;) {
+@@ -1659,31 +1657,22 @@ static void isdn_ppp_mp_receive(isdn_net
+                                        * packets */
+       newfrag = skb;
+-      /* Insert new fragment into the proper sequence slot.  */
+-      skb_queue_walk(&mp->frags, frag) {
+-              if (MP_SEQ(frag) == newseq) {
+-                      isdn_ppp_mp_free_skb(mp, newfrag);
+-                      newfrag = NULL;
+-                      break;
+-              }
+-              if (MP_LT(newseq, MP_SEQ(frag))) {
+-                      __skb_queue_before(&mp->frags, frag, newfrag);
+-                      newfrag = NULL;
+-                      break;
+-              }
+-      }
+-      if (newfrag)
+-              __skb_queue_tail(&mp->frags, newfrag);
++      /* if this new fragment is before the first one, then enqueue it now. */
++      if ((frag = mp->frags) == NULL || MP_LT(newseq, MP_SEQ(frag))) {
++              newfrag->next = frag;
++              mp->frags = frag = newfrag;
++              newfrag = NULL;
++      }
+-      frag = skb_peek(&mp->frags);
+-      start = ((MP_FLAGS(frag) & MP_BEGIN_FRAG) &&
+-               (MP_SEQ(frag) == mp->seq)) ? frag : NULL;
+-      if (!start)
+-              goto check_overflow;
++      start = MP_FLAGS(frag) & MP_BEGIN_FRAG &&
++                              MP_SEQ(frag) == mp->seq ? frag : NULL;
+-      /* main fragment traversing loop
++      /*
++       * main fragment traversing loop
+        *
+        * try to accomplish several tasks:
++       * - insert new fragment into the proper sequence slot (once that's done
++       *   newfrag will be set to NULL)
+        * - reassemble any complete fragment sequence (non-null 'start'
+        *   indicates there is a continguous sequence present)
+        * - discard any incomplete sequences that are below minseq -- due
+@@ -1692,46 +1681,71 @@ static void isdn_ppp_mp_receive(isdn_net
+        *   come to complete such sequence and it should be discarded
+        *
+        * loop completes when we accomplished the following tasks:
++       * - new fragment is inserted in the proper sequence ('newfrag' is
++       *   set to NULL)
+        * - we hit a gap in the sequence, so no reassembly/processing is 
+        *   possible ('start' would be set to NULL)
+        *
+        * algorithm for this code is derived from code in the book
+        * 'PPP Design And Debugging' by James Carlson (Addison-Wesley)
+        */
+-      skb_queue_walk_safe(&mp->frags, frag, nextf) {
+-              thisseq = MP_SEQ(frag);
++      while (start != NULL || newfrag != NULL) {
+-              /* check for misplaced start */
+-              if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
+-                      printk(KERN_WARNING"isdn_mppp(seq %d): new "
+-                             "BEGIN flag with no prior END", thisseq);
+-                      stats->seqerrs++;
+-                      stats->frame_drops++;
+-                      isdn_ppp_mp_discard(mp, start, frag);
+-                      start = frag;
+-              } else if (MP_LE(thisseq, minseq)) {            
+-                      if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
++              thisseq = MP_SEQ(frag);
++              nextf = frag->next;
++
++              /* drop any duplicate fragments */
++              if (newfrag != NULL && thisseq == newseq) {
++                              isdn_ppp_mp_free_skb(mp, newfrag);
++                              newfrag = NULL;
++              }
++
++              /* insert new fragment before next element if possible. */
++              if (newfrag != NULL && (nextf == NULL ||
++                                              MP_LT(newseq, MP_SEQ(nextf)))) {
++                              newfrag->next = nextf;
++                              frag->next = nextf = newfrag;
++                              newfrag = NULL;
++              }
++
++              if (start != NULL) {
++                      /* check for misplaced start */
++                              if (start != frag && (MP_FLAGS(frag) & MP_BEGIN_FRAG)) {
++                              printk(KERN_WARNING"isdn_mppp(seq %d): new "
++                                    "BEGIN flag with no prior END", thisseq);
++                              stats->seqerrs++;
++                              stats->frame_drops++;
++                              start = isdn_ppp_mp_discard(mp, start,frag);
++                              nextf = frag->next;
++                              }
++              } else if (MP_LE(thisseq, minseq)) {
++                              if (MP_FLAGS(frag) & MP_BEGIN_FRAG)
+                               start = frag;
+-                      else {
++                              else {
+                               if (MP_FLAGS(frag) & MP_END_FRAG)
+-                                      stats->frame_drops++;
+-                              __skb_unlink(skb, &mp->frags);
++                                      stats->frame_drops++;
++                              if( mp->frags == frag )
++                                      mp->frags = nextf;
+                               isdn_ppp_mp_free_skb(mp, frag);
++                              frag = nextf;
+                               continue;
+-                      }
++                              }
+               }
+-
+-              /* if we have end fragment, then we have full reassembly
+-               * sequence -- reassemble and process packet now
++
++              /* if start is non-null and we have end fragment, then
++               * we have full reassembly sequence -- reassemble
++               * and process packet now
+                */
+-              if (MP_FLAGS(frag) & MP_END_FRAG) {
+-                      minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
+-                      /* Reassemble the packet then dispatch it */
+-                      isdn_ppp_mp_reassembly(net_dev, lp, start, frag, thisseq);
++              if (start != NULL && (MP_FLAGS(frag) & MP_END_FRAG)) {
++                              minseq = mp->seq = (thisseq+1) & MP_LONGSEQ_MASK;
++                              /* Reassemble the packet then dispatch it */
++                      isdn_ppp_mp_reassembly(net_dev, lp, start, nextf);
++
++                              start = NULL;
++                              frag = NULL;
+-                      start = NULL;
+-                      frag = NULL;
+-              }
++                              mp->frags = nextf;
++              }
+               /* check if need to update start pointer: if we just
+                * reassembled the packet and sequence is contiguous
+@@ -1742,25 +1756,26 @@ static void isdn_ppp_mp_receive(isdn_net
+                * below low watermark and set start to the next frag or
+                * clear start ptr.
+                */ 
+-              if (nextf != (struct sk_buff *)&mp->frags && 
++              if (nextf != NULL &&
+                   ((thisseq+1) & MP_LONGSEQ_MASK) == MP_SEQ(nextf)) {
+-                      /* if we just reassembled and the next one is here, 
+-                       * then start another reassembly.
+-                       */
+-                      if (frag == NULL) {
++                              /* if we just reassembled and the next one is here,
++                       * then start another reassembly. */
++
++                              if (frag == NULL) {
+                               if (MP_FLAGS(nextf) & MP_BEGIN_FRAG)
+-                                      start = nextf;
+-                              else {
+-                                      printk(KERN_WARNING"isdn_mppp(seq %d):"
+-                                             " END flag with no following "
+-                                             "BEGIN", thisseq);
++                                      start = nextf;
++                              else
++                              {
++                                      printk(KERN_WARNING"isdn_mppp(seq %d):"
++                                              " END flag with no following "
++                                              "BEGIN", thisseq);
+                                       stats->seqerrs++;
+                               }
+                       }
+-              } else {
+-                      if (nextf != (struct sk_buff *)&mp->frags &&
+-                          frag != NULL &&
+-                          MP_LT(thisseq, minseq)) {
++
++              } else {
++                      if ( nextf != NULL && frag != NULL &&
++                                              MP_LT(thisseq, minseq)) {
+                               /* we've got a break in the sequence
+                                * and we not at the end yet
+                                * and we did not just reassembled
+@@ -1769,39 +1784,41 @@ static void isdn_ppp_mp_receive(isdn_net
+                                * discard all the frames below low watermark 
+                                * and start over */
+                               stats->frame_drops++;
+-                              isdn_ppp_mp_discard(mp, start, nextf);
++                              mp->frags = isdn_ppp_mp_discard(mp,start,nextf);
+                       }
+                       /* break in the sequence, no reassembly */
+-                      start = NULL;
+-              }
+-              if (!start)
+-                      break;
+-      }
+-
+-check_overflow:
++                              start = NULL;
++              }
++
++              frag = nextf;
++      }       /* while -- main loop */
++
++      if (mp->frags == NULL)
++              mp->frags = frag;
++
+       /* rather straighforward way to deal with (not very) possible 
+-       * queue overflow
+-       */
++       * queue overflow */
+       if (mp->frames > MP_MAX_QUEUE_LEN) {
+               stats->overflows++;
+-              skb_queue_walk_safe(&mp->frags, frag, nextf) {
+-                      if (mp->frames <= MP_MAX_QUEUE_LEN)
+-                              break;
+-                      __skb_unlink(frag, &mp->frags);
+-                      isdn_ppp_mp_free_skb(mp, frag);
++              while (mp->frames > MP_MAX_QUEUE_LEN) {
++                      frag = mp->frags->next;
++                      isdn_ppp_mp_free_skb(mp, mp->frags);
++                      mp->frags = frag;
+               }
+       }
+       spin_unlock_irqrestore(&mp->lock, flags);
+ }
+-static void isdn_ppp_mp_cleanup(isdn_net_local *lp)
++static void isdn_ppp_mp_cleanup( isdn_net_local * lp )
+ {
+-      struct sk_buff *skb, *tmp;
+-
+-      skb_queue_walk_safe(&lp->netdev->pb->frags, skb, tmp) {
+-              __skb_unlink(skb, &lp->netdev->pb->frags);
+-              isdn_ppp_mp_free_skb(lp->netdev->pb, skb);
++      struct sk_buff * frag = lp->netdev->pb->frags;
++      struct sk_buff * nextfrag;
++      while( frag ) {
++              nextfrag = frag->next;
++              isdn_ppp_mp_free_skb(lp->netdev->pb, frag);
++              frag = nextfrag;
+       }
++      lp->netdev->pb->frags = NULL;
+ }
+ static u32 isdn_ppp_mp_get_seq( int short_seq, 
+@@ -1838,115 +1855,72 @@ static u32 isdn_ppp_mp_get_seq( int shor
+       return seq;
+ }
+-static void isdn_ppp_mp_discard(ippp_bundle *mp, struct sk_buff *from,
+-                              struct sk_buff *to)
++struct sk_buff * isdn_ppp_mp_discard( ippp_bundle * mp,
++                      struct sk_buff * from, struct sk_buff * to )
+ {
+-      if (from) {
+-              struct sk_buff *skb, *tmp;
+-              int freeing = 0;
+-
+-              skb_queue_walk_safe(&mp->frags, skb, tmp) {
+-                      if (skb == to)
+-                              break;
+-                      if (skb == from)
+-                              freeing = 1;
+-                      if (!freeing)
+-                              continue;
+-                      __skb_unlink(skb, &mp->frags);
+-                      isdn_ppp_mp_free_skb(mp, skb);
++      if( from )
++              while (from != to) {
++                      struct sk_buff * next = from->next;
++                      isdn_ppp_mp_free_skb(mp, from);
++                      from = next;
+               }
+-      }
++      return from;
+ }
+-static unsigned int calc_tot_len(struct sk_buff_head *queue,
+-                               struct sk_buff *from, struct sk_buff *to)
+-{
+-      unsigned int tot_len = 0;
+-      struct sk_buff *skb;
+-      int found_start = 0;
+-
+-      skb_queue_walk(queue, skb) {
+-              if (skb == from)
+-                      found_start = 1;
+-              if (!found_start)
+-                      continue;
+-              tot_len += skb->len - MP_HEADER_LEN;
+-              if (skb == to)
+-                      break;
+-      }
+-      return tot_len;
+-}
+-
+-/* Reassemble packet using fragments in the reassembly queue from
+- * 'from' until 'to', inclusive.
+- */
+-static void isdn_ppp_mp_reassembly(isdn_net_dev *net_dev, isdn_net_local *lp,
+-                                 struct sk_buff *from, struct sk_buff *to,
+-                                 u32 lastseq)
++void isdn_ppp_mp_reassembly( isdn_net_dev * net_dev, isdn_net_local * lp,
++                              struct sk_buff * from, struct sk_buff * to )
+ {
+-      ippp_bundle *mp = net_dev->pb;
+-      unsigned int tot_len;
+-      struct sk_buff *skb;
++      ippp_bundle * mp = net_dev->pb;
+       int proto;
++      struct sk_buff * skb;
++      unsigned int tot_len;
+       if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
+               printk(KERN_ERR "%s: lp->ppp_slot(%d) out of range\n",
+                       __func__, lp->ppp_slot);
+               return;
+       }
+-
+-      tot_len = calc_tot_len(&mp->frags, from, to);
+-
+-      if (MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG)) {
+-              if (ippp_table[lp->ppp_slot]->debug & 0x40)
++      if( MP_FLAGS(from) == (MP_BEGIN_FRAG | MP_END_FRAG) ) {
++              if( ippp_table[lp->ppp_slot]->debug & 0x40 )
+                       printk(KERN_DEBUG "isdn_mppp: reassembly: frame %d, "
+-                             "len %d\n", MP_SEQ(from), from->len);
++                                      "len %d\n", MP_SEQ(from), from->len );
+               skb = from;
+               skb_pull(skb, MP_HEADER_LEN);
+-              __skb_unlink(skb, &mp->frags);
+               mp->frames--;   
+       } else {
+-              struct sk_buff *walk, *tmp;
+-              int found_start = 0;
++              struct sk_buff * frag;
++              int n;
+-              if (ippp_table[lp->ppp_slot]->debug & 0x40)
+-                      printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
+-                             "to %d, len %d\n", MP_SEQ(from), lastseq,
+-                             tot_len);
++              for(tot_len=n=0, frag=from; frag != to; frag=frag->next, n++)
++                      tot_len += frag->len - MP_HEADER_LEN;
+-              skb = dev_alloc_skb(tot_len);
+-              if (!skb)
++              if( ippp_table[lp->ppp_slot]->debug & 0x40 )
++                      printk(KERN_DEBUG"isdn_mppp: reassembling frames %d "
++                              "to %d, len %d\n", MP_SEQ(from),
++                              (MP_SEQ(from)+n-1) & MP_LONGSEQ_MASK, tot_len );
++              if( (skb = dev_alloc_skb(tot_len)) == NULL ) {
+                       printk(KERN_ERR "isdn_mppp: cannot allocate sk buff "
+-                             "of size %d\n", tot_len);
+-
+-              found_start = 0;
+-              skb_queue_walk_safe(&mp->frags, walk, tmp) {
+-                      if (walk == from)
+-                              found_start = 1;
+-                      if (!found_start)
+-                              continue;
++                                      "of size %d\n", tot_len);
++                      isdn_ppp_mp_discard(mp, from, to);
++                      return;
++              }
+-                      if (skb) {
+-                              unsigned int len = walk->len - MP_HEADER_LEN;
+-                              skb_copy_from_linear_data_offset(walk, MP_HEADER_LEN,
+-                                                               skb_put(skb, len),
+-                                                               len);
+-                      }
+-                      __skb_unlink(walk, &mp->frags);
+-                      isdn_ppp_mp_free_skb(mp, walk);
++              while( from != to ) {
++                      unsigned int len = from->len - MP_HEADER_LEN;
+-                      if (walk == to)
+-                              break;
++                      skb_copy_from_linear_data_offset(from, MP_HEADER_LEN,
++                                                       skb_put(skb,len),
++                                                       len);
++                      frag = from->next;
++                      isdn_ppp_mp_free_skb(mp, from);
++                      from = frag;
+               }
+       }
+-      if (!skb)
+-              return;
+-
+       proto = isdn_ppp_strip_proto(skb);
+       isdn_ppp_push_higher(net_dev, lp, skb, proto);
+ }
+-static void isdn_ppp_mp_free_skb(ippp_bundle *mp, struct sk_buff *skb)
++static void isdn_ppp_mp_free_skb(ippp_bundle * mp, struct sk_buff * skb)
+ {
+       dev_kfree_skb(skb);
+       mp->frames--;
+--- a/include/linux/isdn_ppp.h
++++ b/include/linux/isdn_ppp.h
+@@ -157,7 +157,7 @@ typedef struct {
+ typedef struct {
+   int mp_mrru;                        /* unused                             */
+-  struct sk_buff_head frags;  /* fragments sl list */
++  struct sk_buff * frags;     /* fragments sl list -- use skb->next */
+   long frames;                        /* number of frames in the frame list */
+   unsigned int seq;           /* last processed packet seq #: any packets
+                                * with smaller seq # will be dropped
diff --git a/queue-2.6.31/serial-suncore-add-ignore_line-argument-to-sunserial_console_match.patch b/queue-2.6.31/serial-suncore-add-ignore_line-argument-to-sunserial_console_match.patch
new file mode 100644 (file)
index 0000000..296332d
--- /dev/null
@@ -0,0 +1,124 @@
+From 56304e06e5d4b1142e58f40048b2388ba767a76f Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 14:03:34 -0800
+Subject: serial: suncore: Add 'ignore_line' argument to sunserial_console_match().
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 4e3533d05b6e5e66d1cda27f6671251c99c62894 ]
+
+This tells the logic to ignore the line match when deciding whether the
+device is the OpenFirmware specified console device or not.
+
+This is going to be used in the SU driver for rsc-console detection.
+
+There is probably a better way to handle this, but this is the least
+intrusive solution for now which we can validate won't break any other
+cases.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/suncore.c  |   19 ++++++++++---------
+ drivers/serial/suncore.h  |    2 +-
+ drivers/serial/sunsab.c   |    6 ++++--
+ drivers/serial/sunsu.c    |    3 ++-
+ drivers/serial/sunzilog.c |    6 ++++--
+ 5 files changed, 21 insertions(+), 15 deletions(-)
+
+--- a/drivers/serial/suncore.c
++++ b/drivers/serial/suncore.c
+@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct 
+ EXPORT_SYMBOL(sunserial_unregister_minors);
+ int sunserial_console_match(struct console *con, struct device_node *dp,
+-                          struct uart_driver *drv, int line)
++                          struct uart_driver *drv, int line, bool ignore_line)
+ {
+-      int off;
+-
+       if (!con || of_console_device != dp)
+               return 0;
+-      off = 0;
+-      if (of_console_options &&
+-          *of_console_options == 'b')
+-              off = 1;
++      if (!ignore_line) {
++              int off = 0;
+-      if ((line & 1) != off)
+-              return 0;
++              if (of_console_options &&
++                  *of_console_options == 'b')
++                      off = 1;
++
++              if ((line & 1) != off)
++                      return 0;
++      }
+       con->index = line;
+       drv->cons = con;
+--- a/drivers/serial/suncore.h
++++ b/drivers/serial/suncore.h
+@@ -26,7 +26,7 @@ extern int sunserial_register_minors(str
+ extern void sunserial_unregister_minors(struct uart_driver *, int);
+ extern int sunserial_console_match(struct console *, struct device_node *,
+-                                 struct uart_driver *, int);
++                                 struct uart_driver *, int, bool);
+ extern void sunserial_console_termios(struct console *);
+ #endif /* !(_SERIAL_SUN_H) */
+--- a/drivers/serial/sunsab.c
++++ b/drivers/serial/sunsab.c
+@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of
+               goto out1;
+       sunserial_console_match(SUNSAB_CONSOLE(), op->node,
+-                              &sunsab_reg, up[0].port.line);
++                              &sunsab_reg, up[0].port.line,
++                              false);
+       sunserial_console_match(SUNSAB_CONSOLE(), op->node,
+-                              &sunsab_reg, up[1].port.line);
++                              &sunsab_reg, up[1].port.line,
++                              false);
+       err = uart_add_one_port(&sunsab_reg, &up[0].port);
+       if (err)
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1468,7 +1468,8 @@ static int __devinit su_probe(struct of_
+       up->port.ops = &sunsu_pops;
+       sunserial_console_match(SUNSU_CONSOLE(), dp,
+-                              &sunsu_reg, up->port.line);
++                              &sunsu_reg, up->port.line,
++                              false);
+       err = uart_add_one_port(&sunsu_reg, &up->port);
+       if (err)
+               goto out_unmap;
+--- a/drivers/serial/sunzilog.c
++++ b/drivers/serial/sunzilog.c
+@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_
+       if (!keyboard_mouse) {
+               if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
+-                                          &sunzilog_reg, up[0].port.line))
++                                          &sunzilog_reg, up[0].port.line,
++                                          false))
+                       up->flags |= SUNZILOG_FLAG_IS_CONS;
+               err = uart_add_one_port(&sunzilog_reg, &up[0].port);
+               if (err) {
+@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_
+                       return err;
+               }
+               if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node,
+-                                          &sunzilog_reg, up[1].port.line))
++                                          &sunzilog_reg, up[1].port.line,
++                                          false))
+                       up->flags |= SUNZILOG_FLAG_IS_CONS;
+               err = uart_add_one_port(&sunzilog_reg, &up[1].port);
+               if (err) {
diff --git a/queue-2.6.31/serial-suncore-fix-rsc-lom-handling-in-sunserial_console_termios.patch b/queue-2.6.31/serial-suncore-fix-rsc-lom-handling-in-sunserial_console_termios.patch
new file mode 100644 (file)
index 0000000..d968f1c
--- /dev/null
@@ -0,0 +1,117 @@
+From c10afdede88005f7a4e7f3213560adfa9a06e58c Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 14:09:56 -0800
+Subject: serial: suncore: Fix RSC/LOM handling in sunserial_console_termios().
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 457931de3b0925dc2eb941bc7d611a509be36dff ]
+
+RSC and LOM devices have fixed speed settings.
+
+We already had some code to match and handle "rsc" named devices on
+E250 systems, but we also have to handle 'rsc-console', 'rsc-control',
+and 'lom-console'.
+
+Also, in order to get this right regardless of what 'output-device'
+happens to be, explicitly pass the UART device node pointer to this
+routine.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/suncore.c  |   18 ++++++++++--------
+ drivers/serial/suncore.h  |    3 ++-
+ drivers/serial/sunhv.c    |    2 +-
+ drivers/serial/sunsab.c   |    2 +-
+ drivers/serial/sunzilog.c |    2 +-
+ 5 files changed, 15 insertions(+), 12 deletions(-)
+
+--- a/drivers/serial/suncore.c
++++ b/drivers/serial/suncore.c
+@@ -77,23 +77,24 @@ int sunserial_console_match(struct conso
+ }
+ EXPORT_SYMBOL(sunserial_console_match);
+-void
+-sunserial_console_termios(struct console *con)
++void sunserial_console_termios(struct console *con, struct device_node *uart_dp)
+ {
+-      struct device_node *dp;
+-      const char *od, *mode, *s;
++      const char *mode, *s;
+       char mode_prop[] = "ttyX-mode";
+       int baud, bits, stop, cflag;
+       char parity;
+-      dp = of_find_node_by_path("/options");
+-      od = of_get_property(dp, "output-device", NULL);
+-      if (!strcmp(od, "rsc")) {
+-              mode = of_get_property(of_console_device,
++      if (!strcmp(uart_dp->name, "rsc") ||
++          !strcmp(uart_dp->name, "rsc-console") ||
++          !strcmp(uart_dp->name, "rsc-control")) {
++              mode = of_get_property(uart_dp,
+                                      "ssp-console-modes", NULL);
+               if (!mode)
+                       mode = "115200,8,n,1,-";
++      } else if (!strcmp(uart_dp->name, "lom-console")) {
++              mode = "9600,8,n,1,-";
+       } else {
++              struct device_node *dp;
+               char c;
+               c = 'a';
+@@ -102,6 +103,7 @@ sunserial_console_termios(struct console
+               mode_prop[3] = c;
++              dp = of_find_node_by_path("/options");
+               mode = of_get_property(dp, mode_prop, NULL);
+               if (!mode)
+                       mode = "9600,8,n,1,-";
+--- a/drivers/serial/suncore.h
++++ b/drivers/serial/suncore.h
+@@ -27,6 +27,7 @@ extern void sunserial_unregister_minors(
+ extern int sunserial_console_match(struct console *, struct device_node *,
+                                  struct uart_driver *, int, bool);
+-extern void sunserial_console_termios(struct console *);
++extern void sunserial_console_termios(struct console *,
++                                    struct device_node *);
+ #endif /* !(_SERIAL_SUN_H) */
+--- a/drivers/serial/sunhv.c
++++ b/drivers/serial/sunhv.c
+@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_
+               goto out_free_con_read_page;
+       sunserial_console_match(&sunhv_console, op->node,
+-                              &sunhv_reg, port->line);
++                              &sunhv_reg, port->line, false);
+       err = uart_add_one_port(&sunhv_reg, port);
+       if (err)
+--- a/drivers/serial/sunsab.c
++++ b/drivers/serial/sunsab.c
+@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct c
+       printk("Console: ttyS%d (SAB82532)\n",
+              (sunsab_reg.minor - 64) + con->index);
+-      sunserial_console_termios(con);
++      sunserial_console_termios(con, to_of_device(up->port.dev)->node);
+       switch (con->cflag & CBAUD) {
+       case B150: baud = 150; break;
+--- a/drivers/serial/sunzilog.c
++++ b/drivers/serial/sunzilog.c
+@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup
+              (sunzilog_reg.minor - 64) + con->index, con->index);
+       /* Get firmware console settings.  */
+-      sunserial_console_termios(con);
++      sunserial_console_termios(con, to_of_device(up->port.dev)->node);
+       /* Firmware console speed is limited to 150-->38400 baud so
+        * this hackish cflag thing is OK.
index 6f2b71b34136373309afa6fbdeac3649224334c7..fb66532fbb45a57cc39a308d4854216f8e88096f 100644 (file)
@@ -40,3 +40,29 @@ mm-hugetlb-fix-hugepage-memory-leak-in-mincore.patch
 mm-hugetlb-fix-hugepage-memory-leak-in-walk_page_range.patch
 powerpc-fix-usage-of-64-bit-instruction-in-32-bit-altivec-code.patch
 serial-do-not-read-iir-in-serial8250_start_tx-when-uart_bug_txen.patch
+ide-serialize-cmd643-and-cmd646-to-fix-a-hardware-bug-with-ssd.patch
+ide-fix-ioctl-to-pass-requested-transfer-mode-to-ide_find_dma_mode-instead-of-udma6.patch
+revert-ide-try-to-use-pio-mode-0-during-probe-if-possible.patch
+slc90e66-fix-udma-handling.patch
+au1x00-fix-crash-when-trying-register_netdev.patch
+b44-wol-setup-one-bit-off-stack-corruption-kernel-panic-fix.patch
+b44-fix-wedge-when-using-netconsole.patch
+e100-use-pci-pool-to-work-around-gfp_atomic-order-5-memory-allocation-failure.patch
+gro-fix-illegal-merging-of-trailer-trash.patch
+ip_fragment-also-adjust-skb-truesize-for-packets-not-owned-by-a-socket.patch
+revert-isdn-isdn_ppp-use-skb-list-facilities-instead-of-home-grown-implementation.patch
+net-fix-the-rollback-test-in-dev_change_name.patch
+net-smc91x-fix-irq-flags.patch
+smsc9420-prevent-bug-if-ethtool-is-called-with-interface-down.patch
+vlan-fix-register_vlan_dev-error-path.patch
+sparc64-fix-definition-of-vmemmap_size.patch
+sunsab-do-not-set-sunsab_reg.cons-right-before-registering-minors.patch
+sunsu-fix-detection-of-su-ports-which-are-rsc-console-or-control.patch
+serial-suncore-add-ignore_line-argument-to-sunserial_console_match.patch
+serial-suncore-fix-rsc-lom-handling-in-sunserial_console_termios.patch
+sunsu-pass-true-ignore_line-to-console-match-when-rsc-or-lom-console.patch
+sunsu-use-sunserial_console_termios-in-sunsu_console_setup.patch
+sparc64-don-t-specify-irqf_shared-for-ldc-interrupts.patch
+sparc64-fix-overly-strict-range-type-matching-for-pci-devices.patch
+sparc64-fix-stack-debugging-irq-stack-regression.patch
+sparc-set-uts_machine-correctly.patch
diff --git a/queue-2.6.31/slc90e66-fix-udma-handling.patch b/queue-2.6.31/slc90e66-fix-udma-handling.patch
new file mode 100644 (file)
index 0000000..35709ea
--- /dev/null
@@ -0,0 +1,31 @@
+From d5720d6de4ab65c106a619ed614f1c178ea4191f Mon Sep 17 00:00:00 2001
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Date: Mon, 30 Nov 2009 08:55:18 +0000
+Subject: slc90e66: fix UDMA handling
+
+From: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+
+[ Upstream commit ee31527a02b0a8e1aa4a5e4084d2db5fa34737ed ]
+
+Fix checking of the currently programmed UDMA mode.
+
+Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
+Acked-by: Sergei Shtylyov <sshtylyov@ru.mvista.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/ide/slc90e66.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/ide/slc90e66.c
++++ b/drivers/ide/slc90e66.c
+@@ -91,8 +91,7 @@ static void slc90e66_set_dma_mode(ide_dr
+               if (!(reg48 & u_flag))
+                       pci_write_config_word(dev, 0x48, reg48|u_flag);
+-              /* FIXME: (reg4a & a_speed) ? */
+-              if ((reg4a & u_speed) != u_speed) {
++              if ((reg4a & a_speed) != u_speed) {
+                       pci_write_config_word(dev, 0x4a, reg4a & ~a_speed);
+                       pci_read_config_word(dev, 0x4a, &reg4a);
+                       pci_write_config_word(dev, 0x4a, reg4a|u_speed);
diff --git a/queue-2.6.31/smsc9420-prevent-bug-if-ethtool-is-called-with-interface-down.patch b/queue-2.6.31/smsc9420-prevent-bug-if-ethtool-is-called-with-interface-down.patch
new file mode 100644 (file)
index 0000000..638283b
--- /dev/null
@@ -0,0 +1,65 @@
+From 1769701360367e205676fdf6130d6ad88d4a9641 Mon Sep 17 00:00:00 2001
+From: Steve Glendinning <steve.glendinning@smsc.com>
+Date: Sun, 29 Nov 2009 23:14:45 -0800
+Subject: smsc9420: prevent BUG() if ethtool is called with interface down
+
+
+From: Steve Glendinning <steve.glendinning@smsc.com>
+
+[ Upstream commit 6c53b1b15e222244358d3cbbefd2a13920faa352 ]
+
+This patch fixes a null pointer dereference BUG() if ethtool is used on
+an smsc9420 interface while it is down, because the phy_dev is only
+allocated while the interface is up.
+
+Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/net/smsc9420.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/drivers/net/smsc9420.c
++++ b/drivers/net/smsc9420.c
+@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings
+ {
+       struct smsc9420_pdata *pd = netdev_priv(dev);
++      if (!pd->phy_dev)
++              return -ENODEV;
++
+       cmd->maxtxpkt = 1;
+       cmd->maxrxpkt = 1;
+       return phy_ethtool_gset(pd->phy_dev, cmd);
+@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings
+ {
+       struct smsc9420_pdata *pd = netdev_priv(dev);
++      if (!pd->phy_dev)
++              return -ENODEV;
++
+       return phy_ethtool_sset(pd->phy_dev, cmd);
+ }
+@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msgleve
+ static int smsc9420_ethtool_nway_reset(struct net_device *netdev)
+ {
+       struct smsc9420_pdata *pd = netdev_priv(netdev);
++
++      if (!pd->phy_dev)
++              return -ENODEV;
++
+       return phy_start_aneg(pd->phy_dev);
+ }
+@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_devi
+       for (i = 0; i < 0x100; i += (sizeof(u32)))
+               data[j++] = smsc9420_reg_read(pd, i);
++      // cannot read phy registers if the net device is down
++      if (!phy_dev)
++              return;
++
+       for (i = 0; i <= 31; i++)
+               data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i);
+ }
diff --git a/queue-2.6.31/sparc-set-uts_machine-correctly.patch b/queue-2.6.31/sparc-set-uts_machine-correctly.patch
new file mode 100644 (file)
index 0000000..8b7addb
--- /dev/null
@@ -0,0 +1,43 @@
+From 58a71837b825747d382679c1813c1e55efc0166d Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Sat, 5 Dec 2009 17:17:55 -0800
+Subject: sparc: Set UTS_MACHINE correctly.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 7f5620a5fcd658f219e85831d3691908f1eccbde ]
+
+"ARCH" can be just about anything, so we shouldn't end up
+with UTS_MACHINE of "sparc" in a 64-bit kernel build just
+because someone set the personality using 'sparc32' or
+similar.  CONFIG_SPARC64 drives the compilation and
+therefore provides the definitive value, not "ARCH".
+
+This mirrors commit 8c6531f7a99f29ba8817ffb12cc9ecf190049bd6
+(x86: correctly set UTS_MACHINE for "make ARCH=x86")
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/sparc/Makefile |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/arch/sparc/Makefile
++++ b/arch/sparc/Makefile
+@@ -27,6 +27,7 @@ AS             := $(AS) -32
+ LDFLAGS        := -m elf32_sparc
+ CHECKFLAGS     += -D__sparc__
+ export BITS    := 32
++UTS_MACHINE    := sparc
+ #KBUILD_CFLAGS += -g -pipe -fcall-used-g5 -fcall-used-g7
+ KBUILD_CFLAGS += -m32 -pipe -mno-fpu -fcall-used-g5 -fcall-used-g7
+@@ -50,6 +51,7 @@ CHECKFLAGS      += -D__sparc__ -D__sparc
+ LDFLAGS              := -m elf64_sparc
+ export BITS          := 64
++UTS_MACHINE          := sparc64
+ KBUILD_CFLAGS += -m64 -pipe -mno-fpu -mcpu=ultrasparc -mcmodel=medlow   \
+                  -ffixed-g4 -ffixed-g5 -fcall-used-g7 -Wno-sign-compare \
diff --git a/queue-2.6.31/sparc64-don-t-specify-irqf_shared-for-ldc-interrupts.patch b/queue-2.6.31/sparc64-don-t-specify-irqf_shared-for-ldc-interrupts.patch
new file mode 100644 (file)
index 0000000..09e1096
--- /dev/null
@@ -0,0 +1,36 @@
+From daec54d1e317e56120617f6d6c00285eee8216e4 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 9 Dec 2009 23:44:43 -0800
+Subject: sparc64: Don't specify IRQF_SHARED for LDC interrupts.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 08a036d583409e3517e3d15b7478d029b25f2cf2 ]
+
+IRQF_SHARED and IRQF_DISABLED don't mix.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/sparc/kernel/ldc.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/kernel/ldc.c
++++ b/arch/sparc/kernel/ldc.c
+@@ -1242,13 +1242,13 @@ int ldc_bind(struct ldc_channel *lp, con
+       snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
+       err = request_irq(lp->cfg.rx_irq, ldc_rx,
+-                        IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
++                        IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+                         lp->rx_irq_name, lp);
+       if (err)
+               return err;
+       err = request_irq(lp->cfg.tx_irq, ldc_tx,
+-                        IRQF_SAMPLE_RANDOM | IRQF_DISABLED | IRQF_SHARED,
++                        IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+                         lp->tx_irq_name, lp);
+       if (err) {
+               free_irq(lp->cfg.rx_irq, lp);
diff --git a/queue-2.6.31/sparc64-fix-definition-of-vmemmap_size.patch b/queue-2.6.31/sparc64-fix-definition-of-vmemmap_size.patch
new file mode 100644 (file)
index 0000000..577d7cb
--- /dev/null
@@ -0,0 +1,42 @@
+From f3cec21be6a80baadeded3dfa59f9741a7a9be4a Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Mon, 23 Nov 2009 16:38:56 -0800
+Subject: sparc64: Fix definition of VMEMMAP_SIZE.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit bffbc94a4d2c1769c3826fceddd2dbb75e72c80b ]
+
+This was the cause of various boot failures on V480, V880, etc.
+systems.
+
+Kernel image memory was being overwritten because the vmemmap[]
+array was being sized to small.  So if you had physical memory
+addresses past a certain point, the early bootup would spam
+all over variables in the kernel data section.
+
+The vmemmap mappings map page structs, not page struct pointers.
+And that was the key thinko in the macro definition.
+
+This was fixable thanks to the help, reports, and tireless patience
+of Hermann Lauer.
+
+Reported-by: Hermann Lauer <Hermann.Lauer@iwr.uni-heidelberg.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/sparc/mm/init_64.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/sparc/mm/init_64.h
++++ b/arch/sparc/mm/init_64.h
+@@ -45,7 +45,7 @@ extern void free_initmem(void);
+ #define VMEMMAP_ALIGN(x)      (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
+ #define VMEMMAP_SIZE  ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
+-                        sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
++                        sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT)
+ extern unsigned long vmemmap_table[VMEMMAP_SIZE];
+ #endif
diff --git a/queue-2.6.31/sparc64-fix-overly-strict-range-type-matching-for-pci-devices.patch b/queue-2.6.31/sparc64-fix-overly-strict-range-type-matching-for-pci-devices.patch
new file mode 100644 (file)
index 0000000..3bd5355
--- /dev/null
@@ -0,0 +1,54 @@
+From 09a1a6d16b7efe582bf5733d17ad5f7b3ab497ea Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 9 Dec 2009 01:39:09 -0800
+Subject: sparc64: Fix overly strict range type matching for PCI devices.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 4230fa3b89ea1c413766bd411a8315a3d05aa6c7 ]
+
+When we are trying to see if a range property entry applies
+to a given address, we are overly strict about the type.
+
+We should only allow I/O ranges for I/O addresses, and only allow
+CONFIG space ranges for CONFIG space address.
+
+However for MEM ranges, they come in 32-bit and 64-bit flavors.
+And a lack of an exact match is OK if the range is 32-bit and
+the address is 64-bit.  We can assign a 64-bit address properly
+into a 32-bit parent range just fine.
+
+So allow it.
+
+Reported-by: Patrick Finnegan <pat@computer-refuge.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/sparc/kernel/of_device_64.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/kernel/of_device_64.c
++++ b/arch/sparc/kernel/of_device_64.c
+@@ -104,9 +104,19 @@ static int of_bus_pci_map(u32 *addr, con
+       int i;
+       /* Check address type match */
+-      if ((addr[0] ^ range[0]) & 0x03000000)
+-              return -EINVAL;
++      if (!((addr[0] ^ range[0]) & 0x03000000))
++              goto type_match;
++
++      /* Special exception, we can map a 64-bit address into
++       * a 32-bit range.
++       */
++      if ((addr[0] & 0x03000000) == 0x03000000 &&
++          (range[0] & 0x03000000) == 0x02000000)
++              goto type_match;
++
++      return -EINVAL;
++type_match:
+       if (of_out_of_range(addr + 1, range + 1, range + na + pna,
+                           na - 1, ns))
+               return -EINVAL;
diff --git a/queue-2.6.31/sparc64-fix-stack-debugging-irq-stack-regression.patch b/queue-2.6.31/sparc64-fix-stack-debugging-irq-stack-regression.patch
new file mode 100644 (file)
index 0000000..276f818
--- /dev/null
@@ -0,0 +1,46 @@
+From 218d766a248de863a492a94988fc6730afd3bfe4 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Wed, 9 Dec 2009 01:43:45 -0800
+Subject: sparc64: Fix stack debugging IRQ stack regression.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 166e553a575f09485f6d0df8a1ef3c5991f7d953 ]
+
+Commit 4f70f7a91bffdcc39f088748dc678953eb9a3fbd
+(sparc64: Implement IRQ stacks.) has two bugs.
+
+First, the softirq range check forgets to subtract STACK_BIAS
+before comparing with %sp.  Next, on failure the wrong label
+is jumped to, resulting in a bogus stack being loaded.
+
+Reported-by: Igor Kovalenko <igor.v.kovalenko@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ arch/sparc/lib/mcount.S |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/sparc/lib/mcount.S
++++ b/arch/sparc/lib/mcount.S
+@@ -64,8 +64,9 @@ mcount:
+ 2:     sethi          %hi(softirq_stack), %g3
+       or              %g3, %lo(softirq_stack), %g3
+       ldx             [%g3 + %g1], %g7
++      sub             %g7, STACK_BIAS, %g7
+       cmp             %sp, %g7
+-      bleu,pt         %xcc, 2f
++      bleu,pt         %xcc, 3f
+        sethi          %hi(THREAD_SIZE), %g3
+       add             %g7, %g3, %g7
+       cmp             %sp, %g7
+@@ -75,7 +76,7 @@ mcount:
+        * again, we are already trying to output the stack overflow
+        * message.
+        */
+-      sethi           %hi(ovstack), %g7               ! cant move to panic stack fast enough
++3:    sethi           %hi(ovstack), %g7               ! cant move to panic stack fast enough
+        or             %g7, %lo(ovstack), %g7
+       add             %g7, OVSTACKSIZE, %g3
+       sub             %g3, STACK_BIAS + 192, %g3
diff --git a/queue-2.6.31/sunsab-do-not-set-sunsab_reg.cons-right-before-registering-minors.patch b/queue-2.6.31/sunsab-do-not-set-sunsab_reg.cons-right-before-registering-minors.patch
new file mode 100644 (file)
index 0000000..0bfd35b
--- /dev/null
@@ -0,0 +1,31 @@
+From 97a9e207553c1dc937bdcccd71aca2e254e9f306 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 13:56:39 -0800
+Subject: sunsab: Do not set sunsab_reg.cons right before registering minors.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 4e68e188411ea98e40309700cf0c89ad4469ac1d ]
+
+Other Sun serial drivers do not do this, and if we keep it this way
+it ends up registering all serial devices as consoles rather than
+just the one which we explicitly register via sunserial_console_match()
+which uses add_preferred_console().
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/sunsab.c |    1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/drivers/serial/sunsab.c
++++ b/drivers/serial/sunsab.c
+@@ -1116,7 +1116,6 @@ static int __init sunsab_init(void)
+               if (!sunsab_ports)
+                       return -ENOMEM;
+-              sunsab_reg.cons = SUNSAB_CONSOLE();
+               err = sunserial_register_minors(&sunsab_reg, num_channels);
+               if (err) {
+                       kfree(sunsab_ports);
diff --git a/queue-2.6.31/sunsu-fix-detection-of-su-ports-which-are-rsc-console-or-control.patch b/queue-2.6.31/sunsu-fix-detection-of-su-ports-which-are-rsc-console-or-control.patch
new file mode 100644 (file)
index 0000000..4bdcb0c
--- /dev/null
@@ -0,0 +1,46 @@
+From 9a6e6d7b8e49af0c650a9eaff6789f20fa379d29 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 13:58:52 -0800
+Subject: sunsu: Fix detection of SU ports which are RSC console or control.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 8301d386afc55c877bafe2c6c7dc75a96ddd2838 ]
+
+These device nodes are named "rsc-console" and "rsc-control" rather
+than 'serial', but the device_type property is 'serial' so we'll
+tip off of that for detection.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/sunsu.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1517,6 +1517,10 @@ static const struct of_device_id su_matc
+               .name = "serial",
+               .compatible = "su",
+       },
++      {
++              .type = "serial",
++              .compatible = "su",
++      },
+       {},
+ };
+ MODULE_DEVICE_TABLE(of, su_match);
+@@ -1548,6 +1552,12 @@ static int __init sunsu_init(void)
+                               num_uart++;
+               }
+       }
++      for_each_node_by_type(dp, "serial") {
++              if (of_device_is_compatible(dp, "su")) {
++                      if (su_get_type(dp) == SU_PORT_PORT)
++                              num_uart++;
++              }
++      }
+       if (num_uart) {
+               err = sunserial_register_minors(&sunsu_reg, num_uart);
diff --git a/queue-2.6.31/sunsu-pass-true-ignore_line-to-console-match-when-rsc-or-lom-console.patch b/queue-2.6.31/sunsu-pass-true-ignore_line-to-console-match-when-rsc-or-lom-console.patch
new file mode 100644 (file)
index 0000000..12d9b4d
--- /dev/null
@@ -0,0 +1,42 @@
+From 02fa1a221d2777da2e8a7bbe081404dda8be4182 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 14:11:40 -0800
+Subject: sunsu: Pass true 'ignore_line' to console match when RSC or LOM console.
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit 1917d17b903955b8b2903626a2e01d071a5d0ec9 ]
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/sunsu.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1409,6 +1409,7 @@ static int __devinit su_probe(struct of_
+       struct uart_sunsu_port *up;
+       struct resource *rp;
+       enum su_type type;
++      bool ignore_line;
+       int err;
+       type = su_get_type(dp);
+@@ -1467,9 +1468,14 @@ static int __devinit su_probe(struct of_
+       up->port.ops = &sunsu_pops;
++      ignore_line = false;
++      if (!strcmp(dp->name, "rsc-console") ||
++          !strcmp(dp->name, "lom-console"))
++              ignore_line = true;
++
+       sunserial_console_match(SUNSU_CONSOLE(), dp,
+                               &sunsu_reg, up->port.line,
+-                              false);
++                              ignore_line);
+       err = uart_add_one_port(&sunsu_reg, &up->port);
+       if (err)
+               goto out_unmap;
diff --git a/queue-2.6.31/sunsu-use-sunserial_console_termios-in-sunsu_console_setup.patch b/queue-2.6.31/sunsu-use-sunserial_console_termios-in-sunsu_console_setup.patch
new file mode 100644 (file)
index 0000000..410437d
--- /dev/null
@@ -0,0 +1,55 @@
+From 0b11d5874da282528190b5a3cc417f5a7b5e8737 Mon Sep 17 00:00:00 2001
+From: David S. Miller <davem@davemloft.net>
+Date: Tue, 24 Nov 2009 14:12:50 -0800
+Subject: sunsu: Use sunserial_console_termios() in sunsu_console_setup().
+
+
+From: David S. Miller <davem@davemloft.net>
+
+[ Upstream commit be24656a5e2d68bfd0744f0742c4aceef2cf44b5 ]
+
+Be like the other Sun serial drivers otherwise the special handling of
+OpenFirmware options and hard-coded overrides for LOM/RSC consoles
+will not be handled.
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ drivers/serial/sunsu.c |   17 ++++++++++-------
+ 1 file changed, 10 insertions(+), 7 deletions(-)
+
+--- a/drivers/serial/sunsu.c
++++ b/drivers/serial/sunsu.c
+@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct c
+  */
+ static int __init sunsu_console_setup(struct console *co, char *options)
+ {
++      static struct ktermios dummy;
++      struct ktermios termios;
+       struct uart_port *port;
+-      int baud = 9600;
+-      int bits = 8;
+-      int parity = 'n';
+-      int flow = 'n';
+       printk("Console: ttyS%d (SU)\n",
+              (sunsu_reg.minor - 64) + co->index);
+@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(st
+        */
+       spin_lock_init(&port->lock);
+-      if (options)
+-              uart_parse_options(options, &baud, &parity, &bits, &flow);
++      /* Get firmware console settings.  */
++      sunserial_console_termios(co, to_of_device(port->dev)->node);
+-      return uart_set_options(port, co, baud, parity, bits, flow);
++      memset(&termios, 0, sizeof(struct ktermios));
++      termios.c_cflag = co->cflag;
++      port->mctrl |= TIOCM_DTR;
++      port->ops->set_termios(port, &termios, &dummy);
++
++      return 0;
+ }
+ static struct console sunsu_console = {
diff --git a/queue-2.6.31/vlan-fix-register_vlan_dev-error-path.patch b/queue-2.6.31/vlan-fix-register_vlan_dev-error-path.patch
new file mode 100644 (file)
index 0000000..b5567d8
--- /dev/null
@@ -0,0 +1,40 @@
+From 96fe75c1c83367d14a87082190bbdb53b64b4e89 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Tue, 17 Nov 2009 06:45:04 -0800
+Subject: vlan: Fix register_vlan_dev() error path
+
+
+From: Eric Dumazet <eric.dumazet@gmail.com>
+
+[ Upstream commit 6b863d1d3239eff0f45c2e6e672f5b56db828db0 ]
+
+In case register_netdevice() returns an error, and a new vlan_group
+was allocated and inserted in vlan_group_hash[] we call
+vlan_group_free() without deleting group from hash table. Future
+lookups can give infinite loops or crashes.
+
+We must delete the vlan_group using RCU safe procedure.
+
+Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+---
+ net/8021q/vlan.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -287,8 +287,11 @@ out_uninit_applicant:
+       if (ngrp)
+               vlan_gvrp_uninit_applicant(real_dev);
+ out_free_group:
+-      if (ngrp)
+-              vlan_group_free(ngrp);
++      if (ngrp) {
++              hlist_del_rcu(&ngrp->hlist);
++              /* Free the group, after all cpu's are done. */
++              call_rcu(&ngrp->rcu, vlan_rcu_free);
++      }
+       return err;
+ }