From: Greg Kroah-Hartman Date: Tue, 7 Aug 2007 07:33:36 +0000 (-0700) Subject: 2.6.22-stable patches started to finally get added again... X-Git-Tag: v2.6.21.7~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f3feab1b222f95051ed359e84279c9a8b8f1e147;p=thirdparty%2Fkernel%2Fstable-queue.git 2.6.22-stable patches started to finally get added again... --- diff --git a/queue-2.6.22/add-a-pci-id-for-santa-rosa-s-pata-controller.patch b/queue-2.6.22/add-a-pci-id-for-santa-rosa-s-pata-controller.patch new file mode 100644 index 00000000000..906dcefd003 --- /dev/null +++ b/queue-2.6.22/add-a-pci-id-for-santa-rosa-s-pata-controller.patch @@ -0,0 +1,35 @@ +From stable-bounces@linux.kernel.org Wed Aug 1 23:37:02 2007 +From: Christian Lamparter +Date: Thu, 2 Aug 2007 15:36:50 +0900 +Subject: Add a PCI ID for santa rosa's PATA controller. +To: stable@kernel.org +Cc: linux-ide@vger.kernel.org, Jeff Garzik +Message-ID: <20070802063650.GK13674@htj.dyndns.org> +Content-Disposition: inline + + +From: Christian Lamparter + +This is commit c1e6f28cc5de37dcd113b9668a185c0b9334ba8a which is +merged during 23-rc1 window. Considering the popularity of these +chips, I think including it in -stable release would be good idea. + +Signed-off-by: Christian Lamparter +Signed-off-by: Jeff Garzik +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/ata/ata_piix.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/ata/ata_piix.c ++++ b/drivers/ata/ata_piix.c +@@ -200,6 +200,8 @@ static const struct pci_device_id piix_p + /* ICH7/7-R (i945, i975) UDMA 100*/ + { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_133 }, + { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, ++ /* ICH8 Mobile PATA Controller */ ++ { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, + + /* NOTE: The following PCI ids must be kept in sync with the + * list in drivers/pci/quirks.c. diff --git a/queue-2.6.22/fix-deadlocks-in-sparc-serial-console.patch b/queue-2.6.22/fix-deadlocks-in-sparc-serial-console.patch new file mode 100644 index 00000000000..19f27840116 --- /dev/null +++ b/queue-2.6.22/fix-deadlocks-in-sparc-serial-console.patch @@ -0,0 +1,193 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:34:14 2007 +From: David Miller +Date: Wed, 18 Jul 2007 02:34:05 -0700 (PDT) +Subject: Fix deadlocks in sparc serial console. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.023405.58454422.davem@davemloft.net> + + +From: David S. Miller + +Subject: [PATCH] [SERIAL]: Fix console write locking in sparc drivers. + +Mirror the logic in 8250 for proper console write locking +when SYSRQ is triggered or an OOPS is in progress. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/serial/sunhv.c | 30 ++++++++++++++++++++++++++---- + drivers/serial/sunsab.c | 19 ++++++++++++++----- + drivers/serial/sunsu.c | 14 ++++++++++++++ + drivers/serial/sunzilog.c | 17 ++++++++++++++--- + 4 files changed, 68 insertions(+), 12 deletions(-) + +--- a/drivers/serial/sunhv.c ++++ b/drivers/serial/sunhv.c +@@ -440,8 +440,16 @@ static void sunhv_console_write_paged(st + { + struct uart_port *port = sunhv_port; + unsigned long flags; ++ int locked = 1; ++ ++ local_irq_save(flags); ++ if (port->sysrq) { ++ locked = 0; ++ } else if (oops_in_progress) { ++ locked = spin_trylock(&port->lock); ++ } else ++ spin_lock(&port->lock); + +- spin_lock_irqsave(&port->lock, flags); + while (n > 0) { + unsigned long ra = __pa(con_write_page); + unsigned long page_bytes; +@@ -469,7 +477,10 @@ static void sunhv_console_write_paged(st + ra += written; + } + } +- spin_unlock_irqrestore(&port->lock, flags); ++ ++ if (locked) ++ spin_unlock(&port->lock); ++ local_irq_restore(flags); + } + + static inline void sunhv_console_putchar(struct uart_port *port, char c) +@@ -488,7 +499,15 @@ static void sunhv_console_write_bychar(s + { + struct uart_port *port = sunhv_port; + unsigned long flags; +- int i; ++ int i, locked = 1; ++ ++ local_irq_save(flags); ++ if (port->sysrq) { ++ locked = 0; ++ } else if (oops_in_progress) { ++ locked = spin_trylock(&port->lock); ++ } else ++ spin_lock(&port->lock); + + spin_lock_irqsave(&port->lock, flags); + for (i = 0; i < n; i++) { +@@ -496,7 +515,10 @@ static void sunhv_console_write_bychar(s + sunhv_console_putchar(port, '\r'); + sunhv_console_putchar(port, *s++); + } +- spin_unlock_irqrestore(&port->lock, flags); ++ ++ if (locked) ++ spin_unlock(&port->lock); ++ local_irq_restore(flags); + } + + static struct console sunhv_console = { +--- a/drivers/serial/sunsab.c ++++ b/drivers/serial/sunsab.c +@@ -860,22 +860,31 @@ static int num_channels; + static void sunsab_console_putchar(struct uart_port *port, int c) + { + struct uart_sunsab_port *up = (struct uart_sunsab_port *)port; +- unsigned long flags; +- +- spin_lock_irqsave(&up->port.lock, flags); + + sunsab_tec_wait(up); + writeb(c, &up->regs->w.tic); +- +- spin_unlock_irqrestore(&up->port.lock, flags); + } + + static void sunsab_console_write(struct console *con, const char *s, unsigned n) + { + struct uart_sunsab_port *up = &sunsab_ports[con->index]; ++ unsigned long flags; ++ int locked = 1; ++ ++ local_irq_save(flags); ++ if (up->port.sysrq) { ++ locked = 0; ++ } else if (oops_in_progress) { ++ locked = spin_trylock(&up->port.lock); ++ } else ++ spin_lock(&up->port.lock); + + uart_console_write(&up->port, s, n, sunsab_console_putchar); + sunsab_tec_wait(up); ++ ++ if (locked) ++ spin_unlock(&up->port.lock); ++ local_irq_restore(flags); + } + + static int sunsab_console_setup(struct console *con, char *options) +--- a/drivers/serial/sunsu.c ++++ b/drivers/serial/sunsu.c +@@ -1288,7 +1288,17 @@ static void sunsu_console_write(struct c + unsigned int count) + { + struct uart_sunsu_port *up = &sunsu_ports[co->index]; ++ unsigned long flags; + unsigned int ier; ++ int locked = 1; ++ ++ local_irq_save(flags); ++ if (up->port.sysrq) { ++ locked = 0; ++ } else if (oops_in_progress) { ++ locked = spin_trylock(&up->port.lock); ++ } else ++ spin_lock(&up->port.lock); + + /* + * First save the UER then disable the interrupts +@@ -1304,6 +1314,10 @@ static void sunsu_console_write(struct c + */ + wait_for_xmitr(up); + serial_out(up, UART_IER, ier); ++ ++ if (locked) ++ spin_unlock(&up->port.lock); ++ local_irq_restore(flags); + } + + /* +--- a/drivers/serial/sunzilog.c ++++ b/drivers/serial/sunzilog.c +@@ -9,7 +9,7 @@ + * C. Dost, Pete Zaitcev, Ted Ts'o and Alex Buell for their + * work there. + * +- * Copyright (C) 2002, 2006 David S. Miller (davem@davemloft.net) ++ * Copyright (C) 2002, 2006, 2007 David S. Miller (davem@davemloft.net) + */ + + #include +@@ -1151,11 +1151,22 @@ sunzilog_console_write(struct console *c + { + struct uart_sunzilog_port *up = &sunzilog_port_table[con->index]; + unsigned long flags; ++ int locked = 1; ++ ++ local_irq_save(flags); ++ if (up->port.sysrq) { ++ locked = 0; ++ } else if (oops_in_progress) { ++ locked = spin_trylock(&up->port.lock); ++ } else ++ spin_lock(&up->port.lock); + +- spin_lock_irqsave(&up->port.lock, flags); + uart_console_write(&up->port, s, count, sunzilog_putchar); + udelay(2); +- spin_unlock_irqrestore(&up->port.lock, flags); ++ ++ if (locked) ++ spin_unlock(&up->port.lock); ++ local_irq_restore(flags); + } + + static int __init sunzilog_console_setup(struct console *con, char *options) diff --git a/queue-2.6.22/fix-error-queue-socket-lookup-in-ipv6.patch b/queue-2.6.22/fix-error-queue-socket-lookup-in-ipv6.patch new file mode 100644 index 00000000000..aea7b493e3f --- /dev/null +++ b/queue-2.6.22/fix-error-queue-socket-lookup-in-ipv6.patch @@ -0,0 +1,72 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:51:26 2007 +From: Dmitry Butskoy +Date: Wed, 18 Jul 2007 02:51:17 -0700 (PDT) +Subject: Fix error queue socket lookup in ipv6 +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.025117.94556618.davem@davemloft.net> + +From: Dmitry Butskoy + +[IPV6]: MSG_ERRQUEUE messages do not pass to connected raw sockets + +From: Dmitry Butskoy + +Taken from http://bugzilla.kernel.org/show_bug.cgi?id=8747 + +Problem Description: + +It is related to the possibility to obtain MSG_ERRQUEUE messages from the udp +and raw sockets, both connected and unconnected. + +There is a little typo in net/ipv6/icmp.c code, which prevents such messages +to be delivered to the errqueue of the correspond raw socket, when the socket +is CONNECTED. The typo is due to swap of local/remote addresses. + +Consider __raw_v6_lookup() function from net/ipv6/raw.c. When a raw socket is +looked up usual way, it is something like: + +sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); + +where "daddr" is a destination address of the incoming packet (IOW our local +address), "saddr" is a source address of the incoming packet (the remote end). + +But when the raw socket is looked up for some icmp error report, in +net/ipv6/icmp.c:icmpv6_notify() , daddr/saddr are obtained from the echoed +fragment of the "bad" packet, i.e. "daddr" is the original destination +address of that packet, "saddr" is our local address. Hence, for +icmpv6_notify() must use "saddr, daddr" in its arguments, not "daddr, saddr" +... + +Steps to reproduce: + +Create some raw socket, connect it to an address, and cause some error +situation: f.e. set ttl=1 where the remote address is more than 1 hop to reach. +Set IPV6_RECVERR . +Then send something and wait for the error (f.e. poll() with POLLERR|POLLIN). +You should receive "time exceeded" icmp message (because of "ttl=1"), but the +socket do not receive it. + +If you do not connect your raw socket, you will receive MSG_ERRQUEUE +successfully. (The reason is that for unconnected socket there are no actual +checks for local/remote addresses). + +Signed-off-by: Andrew Morton +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/icmp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/icmp.c ++++ b/net/ipv6/icmp.c +@@ -604,7 +604,7 @@ static void icmpv6_notify(struct sk_buff + + read_lock(&raw_v6_lock); + if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) { +- while((sk = __raw_v6_lookup(sk, nexthdr, daddr, saddr, ++ while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr, + IP6CB(skb)->iif))) { + rawv6_err(sk, skb, NULL, type, code, inner_offset, info); + sk = sk_next(sk); diff --git a/queue-2.6.22/fix-ipcomp-crashes.patch b/queue-2.6.22/fix-ipcomp-crashes.patch new file mode 100644 index 00000000000..1c92b6e0247 --- /dev/null +++ b/queue-2.6.22/fix-ipcomp-crashes.patch @@ -0,0 +1,49 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:26:40 2007 +From: Patrick McHardy +Date: Wed, 18 Jul 2007 02:26:27 -0700 (PDT) +Subject: Fix IPCOMP crashes. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.022627.107251288.davem@davemloft.net> + + +From: Patrick McHardy + +[XFRM]: Fix crash introduced by struct dst_entry reordering + +XFRM expects xfrm_dst->u.next to be same pointer as dst->next, which +was broken by the dst_entry reordering in commit 1e19e02c~, causing +an oops in xfrm_bundle_ok when walking the bundle upwards. + +Kill xfrm_dst->u.next and change the only user to use dst->next instead. + +Signed-off-by: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/net/xfrm.h | 1 - + net/xfrm/xfrm_policy.c | 2 +- + 2 files changed, 1 insertion(+), 2 deletions(-) + +--- a/include/net/xfrm.h ++++ b/include/net/xfrm.h +@@ -577,7 +577,6 @@ static inline int xfrm_sec_ctx_match(str + struct xfrm_dst + { + union { +- struct xfrm_dst *next; + struct dst_entry dst; + struct rtable rt; + struct rt6_info rt6; +--- a/net/xfrm/xfrm_policy.c ++++ b/net/xfrm/xfrm_policy.c +@@ -2141,7 +2141,7 @@ int xfrm_bundle_ok(struct xfrm_policy *p + if (last == first) + break; + +- last = last->u.next; ++ last = (struct xfrm_dst *)last->u.dst.next; + last->child_mtu_cached = mtu; + } + diff --git a/queue-2.6.22/fix-ipv6-link-down-handling.patch b/queue-2.6.22/fix-ipv6-link-down-handling.patch new file mode 100644 index 00000000000..800e4353093 --- /dev/null +++ b/queue-2.6.22/fix-ipv6-link-down-handling.patch @@ -0,0 +1,34 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:52:38 2007 +From: Vlad Yasevich +Date: Wed, 18 Jul 2007 02:52:33 -0700 (PDT) +Subject: Fix ipv6 link down handling. +To: stable@kernel.org +Message-ID: <20070718.025233.118626637.davem@davemloft.net> + +From: Vlad Yasevich + +[IPV6]: Call inet6addr_chain notifiers on link down + +Currently if the link is brought down via ip link or ifconfig down, +the inet6addr_chain notifiers are not called even though all +the addresses are removed from the interface. This caused SCTP +to add duplicate addresses to it's list. + +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/addrconf.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2472,6 +2472,7 @@ static int addrconf_ifdown(struct net_de + write_unlock_bh(&idev->lock); + + __ipv6_ifa_notify(RTM_DELADDR, ifa); ++ atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); + in6_ifa_put(ifa); + + write_lock_bh(&idev->lock); diff --git a/queue-2.6.22/fix-ipv6-tunnel-endianness-bug.patch b/queue-2.6.22/fix-ipv6-tunnel-endianness-bug.patch new file mode 100644 index 00000000000..99525a9f411 --- /dev/null +++ b/queue-2.6.22/fix-ipv6-tunnel-endianness-bug.patch @@ -0,0 +1,34 @@ +From stable-bounces@linux.kernel.org Tue Jul 24 21:44:03 2007 +From: Al Viro +Date: Tue, 24 Jul 2007 21:43:58 -0700 (PDT) +Subject: Fix ipv6 tunnel endianness bug. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070724.214358.35664196.davem@davemloft.net> + + +From: Al Viro + +[IPV6]: endianness bug in ip6_tunnel + +Signed-off-by: Al Viro +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/ip6_tunnel.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -962,8 +962,8 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, str + dsfield = ipv4_get_dsfield(iph); + + if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) +- fl.fl6_flowlabel |= ntohl(((__u32)iph->tos << IPV6_TCLASS_SHIFT) +- & IPV6_TCLASS_MASK); ++ fl.fl6_flowlabel |= htonl((__u32)iph->tos << IPV6_TCLASS_SHIFT) ++ & IPV6_TCLASS_MASK; + + err = ip6_tnl_xmit2(skb, dev, dsfield, &fl, encap_limit, &mtu); + if (err != 0) { diff --git a/queue-2.6.22/fix-rfkill-irq-flags.patch b/queue-2.6.22/fix-rfkill-irq-flags.patch new file mode 100644 index 00000000000..be8eb2316f0 --- /dev/null +++ b/queue-2.6.22/fix-rfkill-irq-flags.patch @@ -0,0 +1,52 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:45:30 2007 +From: Ingo Molnar +Date: Wed, 18 Jul 2007 02:45:14 -0700 (PDT) +Subject: Fix rfkill IRQ flags. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.024514.71553572.davem@davemloft.net> + +From: Ingo Molnar + +[RFKILL]: fix net/rfkill/rfkill-input.c bug on 64-bit systems + +Subject: [patch] net/input: fix net/rfkill/rfkill-input.c bug on 64-bit systems + +this recent commit: + + commit cf4328cd949c2086091c62c5685f1580fe9b55e4 + Author: Ivo van Doorn + Date: Mon May 7 00:34:20 2007 -0700 + + [NET]: rfkill: add support for input key to control wireless radio + +added this 64-bit bug: + + .... + unsigned int flags; + + spin_lock_irqsave(&task->lock, flags); + .... + +irq 'flags' must be unsigned long, not unsigned int. The -rt tree has +strict checks about this on 64-bit so this triggered a build failure. + +Signed-off-by: Ingo Molnar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/rfkill/rfkill-input.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/rfkill/rfkill-input.c ++++ b/net/rfkill/rfkill-input.c +@@ -55,7 +55,7 @@ static void rfkill_task_handler(struct w + + static void rfkill_schedule_toggle(struct rfkill_task *task) + { +- unsigned int flags; ++ unsigned long flags; + + spin_lock_irqsave(&task->lock, flags); + diff --git a/queue-2.6.22/fix-sparc32-memset.patch b/queue-2.6.22/fix-sparc32-memset.patch new file mode 100644 index 00000000000..cf15a349197 --- /dev/null +++ b/queue-2.6.22/fix-sparc32-memset.patch @@ -0,0 +1,89 @@ +From stable-bounces@linux.kernel.org Tue Jul 24 21:44:55 2007 +From: Alexander Shmelev +Date: Tue, 24 Jul 2007 21:44:48 -0700 (PDT) +Subject: Fix sparc32 memset() +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070724.214448.38711437.davem@davemloft.net> + +From: Alexander Shmelev + +[SPARC32]: Fix bug in sparc optimized memset. + +Sparc optimized memset (arch/sparc/lib/memset.S) does not fill last +byte of the memory area, if area size is less than 8 bytes and start +address is not word (4-bytes) aligned. + +Here is code chunk where bug located: +/* %o0 - memory address, %o1 - size, %g3 - value */ +8: + add %o0, 1, %o0 + subcc %o1, 1, %o1 + bne,a 8b + stb %g3, [%o0 - 1] + +This code should write byte every loop iteration, but last time delay +instruction stb is not executed because branch instruction sets +"annul" bit. + +Patch replaces bne,a by bne instruction. + +Error can be reproduced by simple kernel module: + +-------------------- +#include +#include +#include +#include +#include + +static void do_memset(void **p, int size) +{ + memset(p, 0x00, size); +} + +static int __init memset_test_init(void) +{ + char fooc[8]; + int *fooi; + memset(fooc, 0xba, sizeof(fooc)); + + do_memset((void**)(fooc + 3), 1); + + fooi = (int*) fooc; + printk("%08X %08X\n", fooi[0], fooi[1]); + + return -1; +} + +static void __exit memset_test_cleanup(void) +{ + return; +} + +module_init(memset_test_init); +module_exit(memset_test_cleanup); + +MODULE_LICENSE("GPL"); +EXPORT_NO_SYMBOLS; +------------------------ + +Signed-off-by: Alexander Shmelev +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc/lib/memset.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/sparc/lib/memset.S ++++ b/arch/sparc/lib/memset.S +@@ -162,7 +162,7 @@ __bzero: + 8: + add %o0, 1, %o0 + subcc %o1, 1, %o1 +- bne,a 8b ++ bne 8b + EX(stb %g3, [%o0 - 1], add %o1, 1) + 0: + retl diff --git a/queue-2.6.22/fix-sparc32-udelay-rounding-errors.patch b/queue-2.6.22/fix-sparc32-udelay-rounding-errors.patch new file mode 100644 index 00000000000..297c075a8de --- /dev/null +++ b/queue-2.6.22/fix-sparc32-udelay-rounding-errors.patch @@ -0,0 +1,65 @@ +From stable-bounces@linux.kernel.org Tue Jul 24 21:45:49 2007 +From: Mark Fortescue +Date: Tue, 24 Jul 2007 21:45:44 -0700 (PDT) +Subject: Fix sparc32 udelay() rounding errors. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070724.214544.35015303.davem@davemloft.net> + + +From: Mark Fortescue + +[SPARC32]: Fix rounding errors in ndelay/udelay implementation. + +__ndelay and __udelay have not been delayung >= specified time. +The problem with __ndelay has been tacked down to the rounding of the +multiplier constant. By changing this, delays > app 18us are correctly +calculated. +The problem with __udelay has also been tracked down to rounding issues. +Changing the multiplier constant (to match that used in sparc64) corrects +for large delays and adding in a rounding constant corrects for trunctaion +errors in the claculations. +Many short delays will return without looping. This is not an error as there +is the fixed delay of doing all the maths to calculate the loop count. + +Signed-off-by: Mark Fortescue +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc/kernel/entry.S | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +--- a/arch/sparc/kernel/entry.S ++++ b/arch/sparc/kernel/entry.S +@@ -1749,8 +1749,8 @@ fpload: + __ndelay: + save %sp, -STACKFRAME_SZ, %sp + mov %i0, %o0 +- call .umul +- mov 0x1ad, %o1 ! 2**32 / (1 000 000 000 / HZ) ++ call .umul ! round multiplier up so large ns ok ++ mov 0x1ae, %o1 ! 2**32 / (1 000 000 000 / HZ) + call .umul + mov %i1, %o1 ! udelay_val + ba delay_continue +@@ -1760,11 +1760,17 @@ __ndelay: + __udelay: + save %sp, -STACKFRAME_SZ, %sp + mov %i0, %o0 +- sethi %hi(0x10c6), %o1 ++ sethi %hi(0x10c7), %o1 ! round multiplier up so large us ok + call .umul +- or %o1, %lo(0x10c6), %o1 ! 2**32 / 1 000 000 ++ or %o1, %lo(0x10c7), %o1 ! 2**32 / 1 000 000 + call .umul + mov %i1, %o1 ! udelay_val ++ sethi %hi(0x028f4b62), %l0 ! Add in rounding constant * 2**32, ++ or %g0, %lo(0x028f4b62), %l0 ++ addcc %o0, %l0, %o0 ! 2**32 * 0.009 999 ++ bcs,a 3f ++ add %o1, 0x01, %o1 ++3: + call .umul + mov HZ, %o0 ! >>32 earlier for wider range + diff --git a/queue-2.6.22/fix-tc-deadlock.patch b/queue-2.6.22/fix-tc-deadlock.patch new file mode 100644 index 00000000000..972c280b46a --- /dev/null +++ b/queue-2.6.22/fix-tc-deadlock.patch @@ -0,0 +1,67 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:32:46 2007 +From: Patrick McHardy +Date: Wed, 18 Jul 2007 02:32:39 -0700 (PDT) +Subject: Fix TC deadlock. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.023239.13770405.davem@davemloft.net> + + +From: Patrick McHardy + +[NET_SCHED]: Revert "avoid transmit softirq on watchdog wakeup" optimization + +As noticed by Ranko Zivojnovic , calling qdisc_run +from the timer handler can result in deadlock: + +> CPU#0 +> +> qdisc_watchdog() fires and gets dev->queue_lock +> qdisc_run()...qdisc_restart()... +> -> releases dev->queue_lock and enters dev_hard_start_xmit() +> +> CPU#1 +> +> tc del qdisc dev ... +> qdisc_graft()...dev_graft_qdisc()...dev_deactivate()... +> -> grabs dev->queue_lock ... +> +> qdisc_reset()...{cbq,hfsc,htb,netem,tbf}_reset()...qdisc_watchdog_cancel()... +> -> hrtimer_cancel() - waiting for the qdisc_watchdog() to exit, while still +> holding dev->queue_lock +> +> CPU#0 +> +> dev_hard_start_xmit() returns ... +> -> wants to get dev->queue_lock(!) +> +> DEADLOCK! + +The entire optimization is a bit questionable IMO, it moves potentially +large parts of NET_TX_SOFTIRQ work to TIMER_SOFTIRQ/HRTIMER_SOFTIRQ, +which kind of defeats the separation of them. + +Signed-off-by: Patrick McHardy +Acked-by: Ranko Zivojnovic +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/sched/sch_api.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/net/sched/sch_api.c ++++ b/net/sched/sch_api.c +@@ -290,11 +290,7 @@ static enum hrtimer_restart qdisc_watchd + + wd->qdisc->flags &= ~TCQ_F_THROTTLED; + smp_wmb(); +- if (spin_trylock(&dev->queue_lock)) { +- qdisc_run(dev); +- spin_unlock(&dev->queue_lock); +- } else +- netif_schedule(dev); ++ netif_schedule(dev); + + return HRTIMER_NORESTART; + } diff --git a/queue-2.6.22/fix-tcp-ipv6-md5-bug.patch b/queue-2.6.22/fix-tcp-ipv6-md5-bug.patch new file mode 100644 index 00000000000..9844f10cfaa --- /dev/null +++ b/queue-2.6.22/fix-tcp-ipv6-md5-bug.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Tue Jul 24 21:47:13 2007 +From: YOSHIFUJI Hideaki +Date: Tue, 24 Jul 2007 21:47:05 -0700 (PDT) +Subject: Fix TCP IPV6 MD5 bug. +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070724.214705.15264479.davem@davemloft.net> + +From: YOSHIFUJI Hideaki + +[TCPv6] MD5SIG: Ensure to reset allocation count to avoid panic. + +After clearing all passwords for IPv6 peers, we need to +set allocation count to zero as well as we free the storage. +Otherwise, we panic when a user trys to (re)add a password. + +Discovered and fixed by MIYAJIMA Mitsuharu . + +Signed-off-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/tcp_ipv6.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -644,6 +644,7 @@ static int tcp_v6_md5_do_del(struct sock + if (tp->md5sig_info->entries6 == 0) { + kfree(tp->md5sig_info->keys6); + tp->md5sig_info->keys6 = NULL; ++ tp->md5sig_info->alloced6 = 0; + + tcp_free_md5sig_pool(); + diff --git a/queue-2.6.22/gen-estimator-deadlock-fix.patch b/queue-2.6.22/gen-estimator-deadlock-fix.patch new file mode 100644 index 00000000000..29741516aa3 --- /dev/null +++ b/queue-2.6.22/gen-estimator-deadlock-fix.patch @@ -0,0 +1,218 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:49:56 2007 +From: Ranko Zivojnovic +Date: Wed, 18 Jul 2007 02:49:48 -0700 (PDT) +Subject: gen estimator deadlock fix +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.024948.123972595.davem@davemloft.net> + +From: Ranko Zivojnovic + +[NET]: gen_estimator deadlock fix + +-Fixes ABBA deadlock noted by Patrick McHardy : + +> There is at least one ABBA deadlock, est_timer() does: +> read_lock(&est_lock) +> spin_lock(e->stats_lock) (which is dev->queue_lock) +> +> and qdisc_destroy calls htb_destroy under dev->queue_lock, which +> calls htb_destroy_class, then gen_kill_estimator and this +> write_locks est_lock. + +To fix the ABBA deadlock the rate estimators are now kept on an rcu list. + +-The est_lock changes the use from protecting the list to protecting +the update to the 'bstat' pointer in order to avoid NULL dereferencing. + +-The 'interval' member of the gen_estimator structure removed as it is +not needed. + +Signed-off-by: Ranko Zivojnovic +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/gen_estimator.c | 81 ++++++++++++++++++++++++++++------------------- + 1 file changed, 49 insertions(+), 32 deletions(-) + +--- a/net/core/gen_estimator.c ++++ b/net/core/gen_estimator.c +@@ -79,27 +79,27 @@ + + struct gen_estimator + { +- struct gen_estimator *next; ++ struct list_head list; + struct gnet_stats_basic *bstats; + struct gnet_stats_rate_est *rate_est; + spinlock_t *stats_lock; +- unsigned interval; + int ewma_log; + u64 last_bytes; + u32 last_packets; + u32 avpps; + u32 avbps; ++ struct rcu_head e_rcu; + }; + + struct gen_estimator_head + { + struct timer_list timer; +- struct gen_estimator *list; ++ struct list_head list; + }; + + static struct gen_estimator_head elist[EST_MAX_INTERVAL+1]; + +-/* Estimator array lock */ ++/* Protects against NULL dereference */ + static DEFINE_RWLOCK(est_lock); + + static void est_timer(unsigned long arg) +@@ -107,13 +107,17 @@ static void est_timer(unsigned long arg) + int idx = (int)arg; + struct gen_estimator *e; + +- read_lock(&est_lock); +- for (e = elist[idx].list; e; e = e->next) { ++ rcu_read_lock(); ++ list_for_each_entry_rcu(e, &elist[idx].list, list) { + u64 nbytes; + u32 npackets; + u32 rate; + + spin_lock(e->stats_lock); ++ read_lock(&est_lock); ++ if (e->bstats == NULL) ++ goto skip; ++ + nbytes = e->bstats->bytes; + npackets = e->bstats->packets; + rate = (nbytes - e->last_bytes)<<(7 - idx); +@@ -125,12 +129,14 @@ static void est_timer(unsigned long arg) + e->last_packets = npackets; + e->avpps += ((long)rate - (long)e->avpps) >> e->ewma_log; + e->rate_est->pps = (e->avpps+0x1FF)>>10; ++skip: ++ read_unlock(&est_lock); + spin_unlock(e->stats_lock); + } + +- if (elist[idx].list != NULL) ++ if (!list_empty(&elist[idx].list)) + mod_timer(&elist[idx].timer, jiffies + ((HZ<interval = parm->interval + 2; ++ idx = parm->interval + 2; + est->bstats = bstats; + est->rate_est = rate_est; + est->stats_lock = stats_lock; +@@ -174,20 +185,25 @@ int gen_new_estimator(struct gnet_stats_ + est->last_packets = bstats->packets; + est->avpps = rate_est->pps<<10; + +- est->next = elist[est->interval].list; +- if (est->next == NULL) { +- init_timer(&elist[est->interval].timer); +- elist[est->interval].timer.data = est->interval; +- elist[est->interval].timer.expires = jiffies + ((HZ<interval)/4); +- elist[est->interval].timer.function = est_timer; +- add_timer(&elist[est->interval].timer); ++ if (!elist[idx].timer.function) { ++ INIT_LIST_HEAD(&elist[idx].list); ++ setup_timer(&elist[idx].timer, est_timer, idx); + } +- write_lock_bh(&est_lock); +- elist[est->interval].list = est; +- write_unlock_bh(&est_lock); ++ ++ if (list_empty(&elist[idx].list)) ++ mod_timer(&elist[idx].timer, jiffies + ((HZ<list, &elist[idx].list); + return 0; + } + ++static void __gen_kill_estimator(struct rcu_head *head) ++{ ++ struct gen_estimator *e = container_of(head, ++ struct gen_estimator, e_rcu); ++ kfree(e); ++} ++ + /** + * gen_kill_estimator - remove a rate estimator + * @bstats: basic statistics +@@ -195,31 +211,32 @@ int gen_new_estimator(struct gnet_stats_ + * + * Removes the rate estimator specified by &bstats and &rate_est + * and deletes the timer. ++ * ++ * NOTE: Called under rtnl_mutex + */ + void gen_kill_estimator(struct gnet_stats_basic *bstats, + struct gnet_stats_rate_est *rate_est) + { + int idx; +- struct gen_estimator *est, **pest; ++ struct gen_estimator *e, *n; + + for (idx=0; idx <= EST_MAX_INTERVAL; idx++) { +- int killed = 0; +- pest = &elist[idx].list; +- while ((est=*pest) != NULL) { +- if (est->rate_est != rate_est || est->bstats != bstats) { +- pest = &est->next; ++ ++ /* Skip non initialized indexes */ ++ if (!elist[idx].timer.function) ++ continue; ++ ++ list_for_each_entry_safe(e, n, &elist[idx].list, list) { ++ if (e->rate_est != rate_est || e->bstats != bstats) + continue; +- } + + write_lock_bh(&est_lock); +- *pest = est->next; ++ e->bstats = NULL; + write_unlock_bh(&est_lock); + +- kfree(est); +- killed++; ++ list_del_rcu(&e->list); ++ call_rcu(&e->e_rcu, __gen_kill_estimator); + } +- if (killed && elist[idx].list == NULL) +- del_timer(&elist[idx].timer); + } + } + diff --git a/queue-2.6.22/gen-estimator-timer-unload-race.patch b/queue-2.6.22/gen-estimator-timer-unload-race.patch new file mode 100644 index 00000000000..6db13de0e30 --- /dev/null +++ b/queue-2.6.22/gen-estimator-timer-unload-race.patch @@ -0,0 +1,39 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:48:50 2007 +From: Patrick McHardy +Date: Wed, 18 Jul 2007 02:48:43 -0700 (PDT) +Subject: gen estimator timer unload race +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.024843.85819931.davem@davemloft.net> + +From: Patrick McHardy + +[NET]: Fix gen_estimator timer removal race + +As noticed by Jarek Poplawski , the timer removal in +gen_kill_estimator races with the timer function rearming the timer. + +Check whether the timer list is empty before rearming the timer +in the timer function to fix this. + +Signed-off-by: Patrick McHardy +Acked-by: Jarek Poplawski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/gen_estimator.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/core/gen_estimator.c ++++ b/net/core/gen_estimator.c +@@ -128,7 +128,8 @@ static void est_timer(unsigned long arg) + spin_unlock(e->stats_lock); + } + +- mod_timer(&elist[idx].timer, jiffies + ((HZ< +Date: Wed, 18 Jul 2007 02:37:05 -0700 (PDT) +Subject: Missing header include in ipt_iprange.h +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.023705.45875793.davem@davemloft.net> + +From: Adrian Bunk + +[NETFILTER]: ipt_iprange.h must #include + +ipt_iprange.h must #include since it uses __be32. + +This patch fixes kernel Bugzilla #7604. + +Signed-off-by: Adrian Bunk +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/netfilter_ipv4/ipt_iprange.h | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/include/linux/netfilter_ipv4/ipt_iprange.h ++++ b/include/linux/netfilter_ipv4/ipt_iprange.h +@@ -1,6 +1,8 @@ + #ifndef _IPT_IPRANGE_H + #define _IPT_IPRANGE_H + ++#include ++ + #define IPRANGE_SRC 0x01 /* Match source IP address */ + #define IPRANGE_DST 0x02 /* Match destination IP address */ + #define IPRANGE_SRC_INV 0x10 /* Negate the condition */ diff --git a/queue-2.6.22/netpoll-leak.patch b/queue-2.6.22/netpoll-leak.patch new file mode 100644 index 00000000000..69738e75ad8 --- /dev/null +++ b/queue-2.6.22/netpoll-leak.patch @@ -0,0 +1,52 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:54:27 2007 +From: Satyam Sharma +Date: Wed, 18 Jul 2007 02:54:19 -0700 (PDT) +Subject: Netpoll leak +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.025419.108809166.davem@davemloft.net> + +From: Satyam Sharma + +[NETPOLL]: Fix a leak-n-bug in netpoll_cleanup() + +93ec2c723e3f8a216dde2899aeb85c648672bc6b applied excessive duct tape to +the netpoll beast's netpoll_cleanup(), thus substituting one leak with +another, and opening up a little buglet :-) + +net_device->npinfo (netpoll_info) is a shared and refcounted object and +cannot simply be set NULL the first time netpoll_cleanup() is called. +Otherwise, further netpoll_cleanup()'s see np->dev->npinfo == NULL and +become no-ops, thus leaking. And it's a bug too: the first call to +netpoll_cleanup() would thus (annoyingly) "disable" other (still alive) +netpolls too. Maybe nobody noticed this because netconsole (only user +of netpoll) never supported multiple netpoll objects earlier. + +This is a trivial and obvious one-line fixlet. + +Signed-off-by: Satyam Sharma +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/core/netpoll.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -781,7 +781,6 @@ void netpoll_cleanup(struct netpoll *np) + spin_unlock_irqrestore(&npinfo->rx_lock, flags); + } + +- np->dev->npinfo = NULL; + if (atomic_dec_and_test(&npinfo->refcnt)) { + skb_queue_purge(&npinfo->arp_tx); + skb_queue_purge(&npinfo->txq); +@@ -794,6 +793,7 @@ void netpoll_cleanup(struct netpoll *np) + kfree_skb(skb); + } + kfree(npinfo); ++ np->dev->npinfo = NULL; + } + } + diff --git a/queue-2.6.22/sctp-scope_id-handling-fix.patch b/queue-2.6.22/sctp-scope_id-handling-fix.patch new file mode 100644 index 00000000000..82a68a91d33 --- /dev/null +++ b/queue-2.6.22/sctp-scope_id-handling-fix.patch @@ -0,0 +1,37 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:44:24 2007 +From: Vlad Yasevich +Date: Wed, 18 Jul 2007 02:44:12 -0700 (PDT) +Subject: SCTP scope_id handling fix +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.024412.35506936.davem@davemloft.net> + +From: Vlad Yasevich + +SCTP: Add scope_id validation for link-local binds + +SCTP currently permits users to bind to link-local addresses, +but doesn't verify that the scope id specified at bind matches +the interface that the address is configured on. It was report +that this can hang a system. + +Signed-off-by: Vlad Yasevich +Signed-off-by: Greg Kroah-Hartman + +--- + net/sctp/ipv6.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -875,6 +875,10 @@ static int sctp_inet6_send_verify(struct + dev = dev_get_by_index(addr->v6.sin6_scope_id); + if (!dev) + return 0; ++ if (!ipv6_chk_addr(&addr->v6.sin6_addr, dev, 0)) { ++ dev_put(dev); ++ return 0; ++ } + dev_put(dev); + } + af = opt->pf->af; diff --git a/queue-2.6.22/series b/queue-2.6.22/series new file mode 100644 index 00000000000..c3529d3ab60 --- /dev/null +++ b/queue-2.6.22/series @@ -0,0 +1,19 @@ +usb-cdc-acm-fix-sysfs-attribute-registration-bug.patch +tcp-frto-retransmit-bug-fix.patch +fix-tc-deadlock.patch +fix-ipcomp-crashes.patch +fix-deadlocks-in-sparc-serial-console.patch +add-a-pci-id-for-santa-rosa-s-pata-controller.patch +missing-header-include-in-ipt_iprange.h.patch +sctp-scope_id-handling-fix.patch +fix-rfkill-irq-flags.patch +gen-estimator-timer-unload-race.patch +gen-estimator-deadlock-fix.patch +fix-error-queue-socket-lookup-in-ipv6.patch +fix-ipv6-link-down-handling.patch +netpoll-leak.patch +sparc64-bootup-assembler-bug.patch +fix-ipv6-tunnel-endianness-bug.patch +fix-sparc32-memset.patch +fix-sparc32-udelay-rounding-errors.patch +fix-tcp-ipv6-md5-bug.patch diff --git a/queue-2.6.22/sparc64-bootup-assembler-bug.patch b/queue-2.6.22/sparc64-bootup-assembler-bug.patch new file mode 100644 index 00000000000..feaadc73379 --- /dev/null +++ b/queue-2.6.22/sparc64-bootup-assembler-bug.patch @@ -0,0 +1,35 @@ +From stable-bounces@linux.kernel.org Thu Jul 19 22:06:23 2007 +From: David Miller +Date: Thu, 19 Jul 2007 22:06:09 -0700 (PDT) +Subject: Sparc64 bootup assembler bug +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070719.220609.112621863.davem@davemloft.net> + + +From: David S. Miller + +[SPARC64]: Fix two year old bug in early bootup asm. + +We try to fetch the CIF entry pointer from %o4, but that +can get clobbered by the early OBP calls. It is saved +in %l7 already, so actually this "mov %o4, %l7" can just +be completely removed with no other changes. + +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + arch/sparc64/kernel/head.S | 1 - + 1 file changed, 1 deletion(-) + +--- a/arch/sparc64/kernel/head.S ++++ b/arch/sparc64/kernel/head.S +@@ -458,7 +458,6 @@ tlb_fixup_done: + or %g6, %lo(init_thread_union), %g6 + ldx [%g6 + TI_TASK], %g4 + mov %sp, %l6 +- mov %o4, %l7 + + wr %g0, ASI_P, %asi + mov 1, %g1 diff --git a/queue-2.6.22/tcp-frto-retransmit-bug-fix.patch b/queue-2.6.22/tcp-frto-retransmit-bug-fix.patch new file mode 100644 index 00000000000..220a4f8e6f8 --- /dev/null +++ b/queue-2.6.22/tcp-frto-retransmit-bug-fix.patch @@ -0,0 +1,36 @@ +From stable-bounces@linux.kernel.org Wed Jul 18 02:30:56 2007 +From: Ilpo Järvinen +Date: Wed, 18 Jul 2007 02:30:41 -0700 (PDT) +Subject: TCP FRTO retransmit bug fix +To: stable@kernel.org +Cc: bunk@stusta.de +Message-ID: <20070718.023041.52167051.davem@davemloft.net> + +From: Ilpo Järvinen + +[TCP]: Verify the presence of RETRANS bit when leaving FRTO + +For yet unknown reason, something cleared SACKED_RETRANS bit +underneath FRTO. + +Signed-off-by: Ilpo Järvinen +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv4/tcp_input.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -1398,7 +1398,9 @@ static void tcp_enter_frto_loss(struct s + * waiting for the first ACK and did not get it)... + */ + if ((tp->frto_counter == 1) && !(flag&FLAG_DATA_ACKED)) { +- tp->retrans_out += tcp_skb_pcount(skb); ++ /* For some reason this R-bit might get cleared? */ ++ if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) ++ tp->retrans_out += tcp_skb_pcount(skb); + /* ...enter this if branch just for the first segment */ + flag |= FLAG_DATA_ACKED; + } else { diff --git a/queue-2.6.22/usb-cdc-acm-fix-sysfs-attribute-registration-bug.patch b/queue-2.6.22/usb-cdc-acm-fix-sysfs-attribute-registration-bug.patch new file mode 100644 index 00000000000..5778cda80a0 --- /dev/null +++ b/queue-2.6.22/usb-cdc-acm-fix-sysfs-attribute-registration-bug.patch @@ -0,0 +1,53 @@ +From stable-bounces@linux.kernel.org Thu Aug 2 10:29:26 2007 +From: Alan Stern +Date: Thu, 2 Aug 2007 13:29:10 -0400 (EDT) +Subject: USB: cdc-acm: fix sysfs attribute registration bug +To: Greg KH , +Cc: Oliver Neukum , "A. Kalten" +Message-ID: + + +This patch (as950) fixes a bug in the cdc-acm driver. It doesn't keep +track of which interface (control or data) the sysfs attributes get +registered for, and as a result, during disconnect it will sometimes +attempt to remove the attributes from the wrong interface. The +left-over attributes can cause a crash later on, particularly if the driver +module has been unloaded. + +Signed-off-by: Alan Stern +CC: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -919,6 +919,10 @@ skip_normal_probe: + return -EINVAL; + } + } ++ ++ /* Accept probe requests only for the control interface */ ++ if (intf != control_interface) ++ return -ENODEV; + + if (usb_interface_claimed(data_interface)) { /* valid in this context */ + dev_dbg(&intf->dev,"The data interface isn't available"); +@@ -1107,10 +1111,12 @@ static void acm_disconnect(struct usb_in + return; + } + if (acm->country_codes){ +- device_remove_file(&intf->dev, &dev_attr_wCountryCodes); +- device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); ++ device_remove_file(&acm->control->dev, ++ &dev_attr_wCountryCodes); ++ device_remove_file(&acm->control->dev, ++ &dev_attr_iCountryCodeRelDate); + } +- device_remove_file(&intf->dev, &dev_attr_bmCapabilities); ++ device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); + acm->dev = NULL; + usb_set_intfdata(acm->control, NULL); + usb_set_intfdata(acm->data, NULL);