From 1617406a763870a84ffe6bba3659f30f96ac4a61 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Wed, 24 May 2006 21:21:31 -0400 Subject: [PATCH 01/95] [PATCH] pcmcia: missing pcmcia_get_socket() result check The result of pcmcia_get_socket() may be NULL but ds_event() uses it without checking. Coverity CID: 436. Signed-off-by: Florin Malita Signed-off-by: Dominik Brodowski --- drivers/pcmcia/ds.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 48d3b3d30c21..74b3124e8247 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -1143,6 +1143,12 @@ static int ds_event(struct pcmcia_socket *skt, event_t event, int priority) { struct pcmcia_socket *s = pcmcia_get_socket(skt); + if (!s) { + printk(KERN_ERR "PCMCIA obtaining reference to socket %p " \ + "failed, event 0x%x lost!\n", skt, event); + return -ENODEV; + } + ds_dbg(1, "ds_event(0x%06x, %d, 0x%p)\n", event, priority, skt); From 2b0dd802ba1ff9b7001f5f9bd9b4d192a4aabf81 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 1 Jun 2006 18:29:20 +0200 Subject: [PATCH 02/95] [PATCH] pcmcia: fix zeroing of cm4000_cs.c data Fix the incorrect calculation of how much to zero out in struct cm4000_dev on device initialization. Signed-off-by: Dominik Brodowski --- drivers/char/pcmcia/cm4000_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index 128b2632512d..eab5394da666 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -149,7 +149,7 @@ struct cm4000_dev { #define ZERO_DEV(dev) \ memset(&dev->atr_csum,0, \ sizeof(struct cm4000_dev) - \ - /*link*/ sizeof(struct pcmcia_device) - \ + /*link*/ sizeof(struct pcmcia_device *) - \ /*node*/ sizeof(dev_node_t) - \ /*atr*/ MAX_ATR*sizeof(char) - \ /*rbuf*/ 512*sizeof(char) - \ From baca2da4c9c5de63b215b1d82f8e774449d15655 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 4 Jun 2006 17:36:31 +0100 Subject: [PATCH 03/95] [MMC] Add maintainers entry for MMC subsystem Signed-off-by: Russell King --- MAINTAINERS | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 74d71cafb17c..f38be60312e9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1877,6 +1877,11 @@ L: linux-kernel@vger.kernel.org W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html S: Maintained +MULTIMEDIA CARD SUBSYSTEM +P: Russell King +M: rmk+mmc@arm.linux.org.uk +S: Maintained + MULTISOUND SOUND DRIVER P: Andrew Veliath M: andrewtv@usa.net From 092d01e260da628b01d4229c31a296111e3cd97a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 4 Jun 2006 17:40:58 +0100 Subject: [PATCH 04/95] [MMC] Prevent au1xmmc.c breakage on non-Au1200 Alchemy The driver is selectable on other than Au1200 Alchemy systems but won't build nor work - there is no MMC hw. Signed-off-by: Ralf Baechle Signed-off-by: Russell King --- drivers/mmc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 003b077c2324..45bcf098e762 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -84,7 +84,7 @@ config MMC_WBSD config MMC_AU1X tristate "Alchemy AU1XX0 MMC Card Interface support" - depends on SOC_AU1X00 && MMC + depends on MMC && SOC_AU1200 help This selects the AMD Alchemy(R) Multimedia card interface. If you have a Alchemy platform with a MMC slot, say Y or M here. From c41045a43a08f898ef5490036f761c87a43dcddc Mon Sep 17 00:00:00 2001 From: Egry Gabor Date: Sun, 4 Jun 2006 21:22:11 +0100 Subject: [PATCH 05/95] [ARM] Trivial typo fixes Trivial typo fixes in Kconfig files (ARM). Signed-off-by: Egry Gabor Signed-off-by: Russell King --- arch/arm/Kconfig.debug | 2 +- arch/arm/mach-ixp4xx/Kconfig | 2 +- arch/arm/mach-s3c2410/Kconfig | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 5d3acff8c596..d22f38b957db 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -101,7 +101,7 @@ config DEBUG_S3C2410_UART help Choice for UART for kernel low-level using S3C2410 UARTS, should be between zero and two. The port must have been - initalised by the boot-loader before use. + initialised by the boot-loader before use. The uncompressor code port configuration is now handled by CONFIG_S3C2410_LOWLEVEL_UART_PORT. diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 2a39f9e481ad..3b23f43cb160 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -141,7 +141,7 @@ config IXP4XX_INDIRECT_PCI 2) If > 64MB of memory space is required, the IXP4xx can be configured to use indirect registers to access PCI This allows for up to 128MB (0x48000000 to 0x4fffffff) of memory on the bus. - The disadvantadge of this is that every PCI access requires + The disadvantage of this is that every PCI access requires three local register accesses plus a spinlock, but in some cases the performance hit is acceptable. In addition, you cannot mmap() PCI devices in this case due to the indirect nature diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index ce7d81000695..970f98dadffc 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -170,7 +170,7 @@ config S3C2410_PM_DEBUG depends on ARCH_S3C2410 && PM help Say Y here if you want verbose debugging from the PM Suspend and - Resume code. See `Documentation/arm/Samsing-S3C24XX/Suspend.txt` + Resume code. See for more information. config S3C2410_PM_CHECK From ae5de0ff0bc24664a053109c6caa782ba2ad7c53 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 4 Jun 2006 21:32:01 -0700 Subject: [PATCH 06/95] [SPARC64]: Fix missing fold at end of checksums. Both csum_partial() and the csum_partial_copy*() family of routines forget to do a final fold on the computed checksum value on sparc64. So do the standard Sparc "add + set condition codes, add carry" sequence, then make sure the high 32-bits of the return value are clear. Based upon some excellent detective work and debugging done by Richard Braun and Samuel Thibault. Signed-off-by: David S. Miller --- arch/sparc64/lib/checksum.S | 5 +++-- arch/sparc64/lib/csum_copy.S | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/arch/sparc64/lib/checksum.S b/arch/sparc64/lib/checksum.S index ba9cd3ccc2b2..1d230f693dc4 100644 --- a/arch/sparc64/lib/checksum.S +++ b/arch/sparc64/lib/checksum.S @@ -165,8 +165,9 @@ csum_partial_end_cruft: sll %g1, 8, %g1 or %o5, %g1, %o4 -1: add %o2, %o4, %o2 +1: addcc %o2, %o4, %o2 + addc %g0, %o2, %o2 csum_partial_finish: retl - mov %o2, %o0 + srl %o2, 0, %o0 diff --git a/arch/sparc64/lib/csum_copy.S b/arch/sparc64/lib/csum_copy.S index 71af48839064..e566c770a0f6 100644 --- a/arch/sparc64/lib/csum_copy.S +++ b/arch/sparc64/lib/csum_copy.S @@ -221,11 +221,12 @@ FUNC_NAME: /* %o0=src, %o1=dst, %o2=len, %o3=sum */ sll %g1, 8, %g1 or %o5, %g1, %o4 -1: add %o3, %o4, %o3 +1: addcc %o3, %o4, %o3 + addc %g0, %o3, %o3 70: retl - mov %o3, %o0 + srl %o3, 0, %o0 95: mov 0, GLOBAL_SPARE brlez,pn %o2, 4f From e853534e6b94f87e48f29e1701c3f6f8a63669c5 Mon Sep 17 00:00:00 2001 From: Horst Schirmeier Date: Mon, 5 Jun 2006 10:45:30 +0100 Subject: [PATCH 07/95] [SERIAL] typo: buad -> baud Replacing mistyped "buad" with "baud" where applicable. Signed-off-by: Horst Schirmeier Signed-off-by: Russell King --- arch/mips/ddb5xxx/ddb5476/dbg_io.c | 2 +- arch/mips/ddb5xxx/ddb5477/kgdb_io.c | 2 +- arch/mips/gt64120/ev64120/serialGT.c | 2 +- arch/mips/gt64120/momenco_ocelot/dbg_io.c | 2 +- arch/mips/ite-boards/generic/dbg_io.c | 2 +- arch/mips/momentum/jaguar_atx/dbg_io.c | 2 +- arch/mips/momentum/ocelot_c/dbg_io.c | 2 +- arch/mips/momentum/ocelot_g/dbg_io.c | 2 +- include/asm-arm/arch-l7200/serial_l7200.h | 2 +- include/asm-arm/arch-l7200/uncompress.h | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/mips/ddb5xxx/ddb5476/dbg_io.c b/arch/mips/ddb5xxx/ddb5476/dbg_io.c index 85e9e5013679..f2296a999953 100644 --- a/arch/mips/ddb5xxx/ddb5476/dbg_io.c +++ b/arch/mips/ddb5xxx/ddb5476/dbg_io.c @@ -86,7 +86,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c index 1d18d590495b..385bbdb10170 100644 --- a/arch/mips/ddb5xxx/ddb5477/kgdb_io.c +++ b/arch/mips/ddb5xxx/ddb5477/kgdb_io.c @@ -86,7 +86,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/gt64120/ev64120/serialGT.c b/arch/mips/gt64120/ev64120/serialGT.c index 16e34a546e54..8f0d835491ff 100644 --- a/arch/mips/gt64120/ev64120/serialGT.c +++ b/arch/mips/gt64120/ev64120/serialGT.c @@ -149,7 +149,7 @@ void serial_set(int channel, unsigned long baud) #else /* * Note: Set baud rate, hardcoded here for rate of 115200 - * since became unsure of above "buad rate" algorithm (??). + * since became unsure of above "baud rate" algorithm (??). */ outreg(channel, LCR, 0x83); outreg(channel, DLM, 0x00); // See note above diff --git a/arch/mips/gt64120/momenco_ocelot/dbg_io.c b/arch/mips/gt64120/momenco_ocelot/dbg_io.c index 8720bccfdea2..f0a6a38fcf4d 100644 --- a/arch/mips/gt64120/momenco_ocelot/dbg_io.c +++ b/arch/mips/gt64120/momenco_ocelot/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/ite-boards/generic/dbg_io.c b/arch/mips/ite-boards/generic/dbg_io.c index c4f8530fd07e..6a7ccaf93502 100644 --- a/arch/mips/ite-boards/generic/dbg_io.c +++ b/arch/mips/ite-boards/generic/dbg_io.c @@ -72,7 +72,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/momentum/jaguar_atx/dbg_io.c b/arch/mips/momentum/jaguar_atx/dbg_io.c index 542eac82b63c..d7dea0a136aa 100644 --- a/arch/mips/momentum/jaguar_atx/dbg_io.c +++ b/arch/mips/momentum/jaguar_atx/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/momentum/ocelot_c/dbg_io.c b/arch/mips/momentum/ocelot_c/dbg_io.c index 8720bccfdea2..f0a6a38fcf4d 100644 --- a/arch/mips/momentum/ocelot_c/dbg_io.c +++ b/arch/mips/momentum/ocelot_c/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/arch/mips/momentum/ocelot_g/dbg_io.c b/arch/mips/momentum/ocelot_g/dbg_io.c index 8720bccfdea2..f0a6a38fcf4d 100644 --- a/arch/mips/momentum/ocelot_g/dbg_io.c +++ b/arch/mips/momentum/ocelot_g/dbg_io.c @@ -73,7 +73,7 @@ void debugInit(uint32 baud, uint8 data, uint8 parity, uint8 stop) /* disable interrupts */ UART16550_WRITE(OFS_INTR_ENABLE, 0); - /* set up buad rate */ + /* set up baud rate */ { uint32 divisor; diff --git a/include/asm-arm/arch-l7200/serial_l7200.h b/include/asm-arm/arch-l7200/serial_l7200.h index 238c595d97ea..b1008a9d23e5 100644 --- a/include/asm-arm/arch-l7200/serial_l7200.h +++ b/include/asm-arm/arch-l7200/serial_l7200.h @@ -28,7 +28,7 @@ #define UARTDR 0x00 /* Tx/Rx data */ #define RXSTAT 0x04 /* Rx status */ #define H_UBRLCR 0x08 /* mode register high */ -#define M_UBRLCR 0x0C /* mode reg mid (MSB of buad)*/ +#define M_UBRLCR 0x0C /* mode reg mid (MSB of baud)*/ #define L_UBRLCR 0x10 /* mode reg low (LSB of baud)*/ #define UARTCON 0x14 /* control register */ #define UARTFLG 0x18 /* flag register */ diff --git a/include/asm-arm/arch-l7200/uncompress.h b/include/asm-arm/arch-l7200/uncompress.h index 9fcd40aee3e3..04be2a088639 100644 --- a/include/asm-arm/arch-l7200/uncompress.h +++ b/include/asm-arm/arch-l7200/uncompress.h @@ -6,7 +6,7 @@ * Changelog: * 05-01-2000 SJH Created * 05-13-2000 SJH Filled in function bodies - * 07-26-2000 SJH Removed hard coded buad rate + * 07-26-2000 SJH Removed hard coded baud rate */ #include From 959eb39297e8c82f61fbfc283ad4ff11c883bf1e Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 5 Jun 2006 09:51:36 -0700 Subject: [PATCH 08/95] IPoIB: Fix AH leak at interface down When ipoib_stop() is called it first calls netif_stop_queue() to stop the kernel from passing more packets to the network driver. However, the completion handler may call netif_wake_queue() re-enabling packet transfer. This might result in leaks (we see AH leaks which we think can be attributed to this bug) as new packets get posted while the interface is going down. Signed-off-by: Eli Cohen Signed-off-by: Michael Tsirkin Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_ib.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c index a54da42849ae..8406839b91cf 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c @@ -275,6 +275,7 @@ static void ipoib_ib_handle_wc(struct net_device *dev, spin_lock_irqsave(&priv->tx_lock, flags); ++priv->tx_tail; if (netif_queue_stopped(dev) && + test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags) && priv->tx_head - priv->tx_tail <= ipoib_sendq_size >> 1) netif_wake_queue(dev); spin_unlock_irqrestore(&priv->tx_lock, flags); From a7d14f875f03cb78992da8387be81a4c9197f101 Mon Sep 17 00:00:00 2001 From: Steve Yang Date: Mon, 5 Jun 2006 19:47:17 +0100 Subject: [PATCH 09/95] [ARM] 3543/1: [Fwd: PXA270 bootparams address not set] Patch from Steve Yang MACHINE_START struct doesn't have any bootargs location for the mainstone. Result is no kernel command args get passed; no serial driver is selected for console and results in a silent boot failure. Signed-off-by: Steve Yang Signed-off-by: Russell King --- arch/arm/mach-pxa/mainstone.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 02e188d98e7d..b307f11951df 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -493,6 +493,7 @@ static void __init mainstone_map_io(void) MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") /* Maintainer: MontaVista Software Inc. */ .phys_io = 0x40000000, + .boot_params = 0xa0000100, /* BLOB boot parameter setting */ .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = mainstone_map_io, .init_irq = mainstone_init_irq, From 6f258910733a8dbde368acc2ede4b8184ff0e09a Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Sun, 4 Jun 2006 02:51:26 -0700 Subject: [PATCH 10/95] [PATCH] nmclan_cs: dereferencing skb after netif_rx() From: Florin Malita The skb may be gone after netif_rx(), we can't use 'skb->len' to update the stats. 'pkt_len' should work instead. Coverity CID: 911. Signed-off-by: Florin Malita Cc: Dominik Brodowski Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/pcmcia/nmclan_cs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 4260c2128f47..a8f6bfc96fd2 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c @@ -1204,7 +1204,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt) dev->last_rx = jiffies; lp->linux_stats.rx_packets++; - lp->linux_stats.rx_bytes += skb->len; + lp->linux_stats.rx_bytes += pkt_len; outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */ continue; } else { From e0ec574987a3301f7767750bb6e8be47d6323bfa Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Sun, 4 Jun 2006 02:51:27 -0700 Subject: [PATCH 11/95] [PATCH] s390: irb memcpy argument swap From: Cornelia Huck Swapped memcpy arguments in ccw_device_irq() when doing basic sense after unsolicited interrupt. Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/cio/device_fsm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index 180b3bf8b90d..49ec562d7f60 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -749,7 +749,7 @@ ccw_device_irq(struct ccw_device *cdev, enum dev_event dev_event) /* Unit check but no sense data. Need basic sense. */ if (ccw_device_do_sense(cdev, irb) != 0) goto call_handler_unsol; - memcpy(irb, &cdev->private->irb, sizeof(struct irb)); + memcpy(&cdev->private->irb, irb, sizeof(struct irb)); cdev->private->state = DEV_STATE_W4SENSE; cdev->private->intparm = 0; return; From 4ae9538dd02824257e8e72c053c69ad6680aba04 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Sun, 4 Jun 2006 02:51:28 -0700 Subject: [PATCH 12/95] [PATCH] s390: cio non-unique path group ids From: Peter Oberparleiter The path grouping can fail due to non-unique pathgroup-IDs. The source for the CPU-ID part of the ID was incorrectly specified on 64 bit systems. Additionally, the length of the ID was too large due to incorrect data packing declaration. Fix CPU-ID lowcore address and add missing packing declaration. Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/s390/cio/css.h | 4 ++-- include/asm-s390/lowcore.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h index 74a257b23383..e210f89a2449 100644 --- a/drivers/s390/cio/css.h +++ b/drivers/s390/cio/css.h @@ -45,11 +45,11 @@ struct pgid { union { __u8 fc; /* SPID function code */ struct path_state ps; /* SNID path state */ - } inf; + } __attribute__ ((packed)) inf; union { __u32 cpu_addr : 16; /* CPU address */ struct extended_cssid ext_cssid; - } pgid_high; + } __attribute__ ((packed)) pgid_high; __u32 cpu_id : 24; /* CPU identification */ __u32 cpu_model : 16; /* CPU model */ __u32 tod_high; /* high word TOD clock */ diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h index db0606c1abd4..bea727904287 100644 --- a/include/asm-s390/lowcore.h +++ b/include/asm-s390/lowcore.h @@ -98,8 +98,8 @@ #define __LC_KERNEL_ASCE 0xD58 #define __LC_USER_ASCE 0xD60 #define __LC_PANIC_STACK 0xD68 -#define __LC_CPUID 0xD90 -#define __LC_CPUADDR 0xD98 +#define __LC_CPUID 0xD80 +#define __LC_CPUADDR 0xD88 #define __LC_IPLDEV 0xDB8 #define __LC_JIFFY_TIMER 0xDC0 #define __LC_CURRENT 0xDD8 From 93ff66bf1ef29881dffd6fdc344555dab03cdb42 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Sun, 4 Jun 2006 02:51:29 -0700 Subject: [PATCH 13/95] [PATCH] Sparsemem build fix From: Ralf Baechle uses PAGE_SIZE, PAGE_SHIFT from without including that header itself. For some sparsemem configurations this may result in build errors like: CC init/initramfs.o In file included from include/linux/gfp.h:4, from include/linux/slab.h:15, from include/linux/percpu.h:4, from include/linux/rcupdate.h:41, from include/linux/dcache.h:10, from include/linux/fs.h:226, from init/initramfs.c:2: include/linux/mmzone.h:498:22: warning: "PAGE_SHIFT" is not defined In file included from include/linux/gfp.h:4, from include/linux/slab.h:15, from include/linux/percpu.h:4, from include/linux/rcupdate.h:41, from include/linux/dcache.h:10, from include/linux/fs.h:226, from init/initramfs.c:2: include/linux/mmzone.h:526: error: `PAGE_SIZE' undeclared here (not in a function) include/linux/mmzone.h: In function `__pfn_to_section': include/linux/mmzone.h:573: error: `PAGE_SHIFT' undeclared (first use in this function) include/linux/mmzone.h:573: error: (Each undeclared identifier is reported only once include/linux/mmzone.h:573: error: for each function it appears in.) include/linux/mmzone.h: In function `pfn_valid': include/linux/mmzone.h:578: error: `PAGE_SHIFT' undeclared (first use in this function) make[1]: *** [init/initramfs.o] Error 1 make: *** [init] Error 2 Signed-off-by: Ralf Baechle Seems-reasonable-to: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 36740354d4db..2d8337150493 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -15,6 +15,7 @@ #include #include #include +#include /* Free memory management - zoned buddy allocator. */ #ifndef CONFIG_FORCE_MAX_ZONEORDER From ba0c19ed6a61a96d4b42b81cb19d4bc81b5f728c Mon Sep 17 00:00:00 2001 From: Stephen Smalley Date: Sun, 4 Jun 2006 02:51:30 -0700 Subject: [PATCH 14/95] [PATCH] selinux: fix sb_lock/sb_security_lock nesting From: Stephen Smalley Fix unsafe nesting of sb_lock inside sb_security_lock in selinux_complete_init. Detected by the kernel locking validator. Signed-off-by: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 21dad415b896..90b4cdc0c948 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4422,6 +4422,7 @@ void selinux_complete_init(void) /* Set up any superblocks initialized prior to the policy load. */ printk(KERN_INFO "SELinux: Setting up existing superblocks.\n"); + spin_lock(&sb_lock); spin_lock(&sb_security_lock); next_sb: if (!list_empty(&superblock_security_head)) { @@ -4430,19 +4431,20 @@ next_sb: struct superblock_security_struct, list); struct super_block *sb = sbsec->sb; - spin_lock(&sb_lock); sb->s_count++; - spin_unlock(&sb_lock); spin_unlock(&sb_security_lock); + spin_unlock(&sb_lock); down_read(&sb->s_umount); if (sb->s_root) superblock_doinit(sb, NULL); drop_super(sb); + spin_lock(&sb_lock); spin_lock(&sb_security_lock); list_del_init(&sbsec->list); goto next_sb; } spin_unlock(&sb_security_lock); + spin_unlock(&sb_lock); } /* SELinux requires early initialization in order to label From c7d2d28b9851d0ffc9924b0e36bac806d18ebf25 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Sun, 4 Jun 2006 02:51:34 -0700 Subject: [PATCH 15/95] [PATCH] alpha: SMP IRQ routing fix From: Ivan Kokshaysky After removal of fixup_cpu_present_map() function Alpha ended up with an empty cpu_present_map, so secondary CPUs on SMP systems are not being started. Worse, on some platforms we route interrupts to secondary CPUs using cpu_possible_map which is still populated properly. As a result, these interrupts go nowhere so the machines like DP264 aren't able to boot even with a primary CPU. Fixed basically by s/cpu_present_mask/cpu_present_map/. Thanks to Ernst Herzberg for reporting the bug and testing the fix. Cc: Ernst Herzberg Cc: Richard Henderson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/alpha/kernel/alpha_ksyms.c | 1 - arch/alpha/kernel/process.c | 6 +++--- arch/alpha/kernel/smp.c | 14 ++++---------- arch/alpha/kernel/sys_titan.c | 2 +- include/asm-alpha/smp.h | 4 +--- 5 files changed, 9 insertions(+), 18 deletions(-) diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index c645c5e14786..2b245ad731ee 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -182,7 +182,6 @@ EXPORT_SYMBOL(smp_num_cpus); EXPORT_SYMBOL(smp_call_function); EXPORT_SYMBOL(smp_call_function_on_cpu); EXPORT_SYMBOL(_atomic_dec_and_lock); -EXPORT_SYMBOL(cpu_present_mask); #endif /* CONFIG_SMP */ /* diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 9924fd07743a..c760a831fd1a 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -94,7 +94,7 @@ common_shutdown_1(void *generic_ptr) if (cpuid != boot_cpuid) { flags |= 0x00040000UL; /* "remain halted" */ *pflags = flags; - clear_bit(cpuid, &cpu_present_mask); + cpu_clear(cpuid, cpu_present_map); halt(); } #endif @@ -120,8 +120,8 @@ common_shutdown_1(void *generic_ptr) #ifdef CONFIG_SMP /* Wait for the secondaries to halt. */ - cpu_clear(boot_cpuid, cpu_possible_map); - while (cpus_weight(cpu_possible_map)) + cpu_clear(boot_cpuid, cpu_present_map); + while (cpus_weight(cpu_present_map)) barrier(); #endif diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 185255416e85..4dc273e537fd 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c @@ -68,7 +68,6 @@ enum ipi_message_type { static int smp_secondary_alive __initdata = 0; /* Which cpus ids came online. */ -cpumask_t cpu_present_mask; cpumask_t cpu_online_map; EXPORT_SYMBOL(cpu_online_map); @@ -439,7 +438,7 @@ setup_smp(void) if ((cpu->flags & 0x1cc) == 0x1cc) { smp_num_probed++; /* Assume here that "whami" == index */ - cpu_set(i, cpu_present_mask); + cpu_set(i, cpu_present_map); cpu->pal_revision = boot_cpu_palrev; } @@ -450,11 +449,10 @@ setup_smp(void) } } else { smp_num_probed = 1; - cpu_set(boot_cpuid, cpu_present_mask); } - printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_mask = %lx\n", - smp_num_probed, cpu_possible_map.bits[0]); + printk(KERN_INFO "SMP: %d CPUs probed -- cpu_present_map = %lx\n", + smp_num_probed, cpu_present_map.bits[0]); } /* @@ -473,7 +471,7 @@ smp_prepare_cpus(unsigned int max_cpus) /* Nothing to do on a UP box, or when told not to. */ if (smp_num_probed == 1 || max_cpus == 0) { - cpu_present_mask = cpumask_of_cpu(boot_cpuid); + cpu_present_map = cpumask_of_cpu(boot_cpuid); printk(KERN_INFO "SMP mode deactivated.\n"); return; } @@ -486,10 +484,6 @@ smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { - /* - * Mark the boot cpu (current cpu) as online - */ - cpu_set(smp_processor_id(), cpu_online_map); } int __devinit diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c index 5f84417eeb7b..2551fb49ae09 100644 --- a/arch/alpha/kernel/sys_titan.c +++ b/arch/alpha/kernel/sys_titan.c @@ -66,7 +66,7 @@ titan_update_irq_hw(unsigned long mask) register int bcpu = boot_cpuid; #ifdef CONFIG_SMP - cpumask_t cpm = cpu_present_mask; + cpumask_t cpm = cpu_present_map; volatile unsigned long *dim0, *dim1, *dim2, *dim3; unsigned long mask0, mask1, mask2, mask3, dummy; diff --git a/include/asm-alpha/smp.h b/include/asm-alpha/smp.h index 9950706abdf8..e1432102be05 100644 --- a/include/asm-alpha/smp.h +++ b/include/asm-alpha/smp.h @@ -45,10 +45,8 @@ extern struct cpuinfo_alpha cpu_data[NR_CPUS]; #define hard_smp_processor_id() __hard_smp_processor_id() #define raw_smp_processor_id() (current_thread_info()->cpu) -extern cpumask_t cpu_present_mask; -extern cpumask_t cpu_online_map; extern int smp_num_cpus; -#define cpu_possible_map cpu_present_mask +#define cpu_possible_map cpu_present_map int smp_call_function_on_cpu(void (*func) (void *info), void *info,int retry, int wait, cpumask_t cpu); From 6d09bb627d2470299dfb1af0e6d27fb4aece9196 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sun, 4 Jun 2006 02:51:37 -0700 Subject: [PATCH 16/95] [PATCH] fs/namei.c: Call to file_permission() under a spinlock in do_lookup_path() From: Trond Myklebust We're presently running lock_kernel() under fs_lock via nfs's ->permission handler. That's a ranking bug and sometimes a sleep-in-spinlock bug. This problem was introduced in the openat() patchset. We should not need to hold the current->fs->lock for a codepath that doesn't use current->fs. [vsu@altlinux.ru: fix error path] Signed-off-by: Trond Myklebust Cc: Al Viro Signed-off-by: Sergey Vlasov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/namei.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/fs/namei.c b/fs/namei.c index 96723ae83c89..d6e2ee251736 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -1080,8 +1080,8 @@ static int fastcall do_path_lookup(int dfd, const char *name, nd->flags = flags; nd->depth = 0; - read_lock(¤t->fs->lock); if (*name=='/') { + read_lock(¤t->fs->lock); if (current->fs->altroot && !(nd->flags & LOOKUP_NOALT)) { nd->mnt = mntget(current->fs->altrootmnt); nd->dentry = dget(current->fs->altroot); @@ -1092,33 +1092,35 @@ static int fastcall do_path_lookup(int dfd, const char *name, } nd->mnt = mntget(current->fs->rootmnt); nd->dentry = dget(current->fs->root); + read_unlock(¤t->fs->lock); } else if (dfd == AT_FDCWD) { + read_lock(¤t->fs->lock); nd->mnt = mntget(current->fs->pwdmnt); nd->dentry = dget(current->fs->pwd); + read_unlock(¤t->fs->lock); } else { struct dentry *dentry; file = fget_light(dfd, &fput_needed); retval = -EBADF; if (!file) - goto unlock_fail; + goto out_fail; dentry = file->f_dentry; retval = -ENOTDIR; if (!S_ISDIR(dentry->d_inode->i_mode)) - goto fput_unlock_fail; + goto fput_fail; retval = file_permission(file, MAY_EXEC); if (retval) - goto fput_unlock_fail; + goto fput_fail; nd->mnt = mntget(file->f_vfsmnt); nd->dentry = dget(dentry); fput_light(file, fput_needed); } - read_unlock(¤t->fs->lock); current->total_link_count = 0; retval = link_path_walk(name, nd); out: @@ -1127,13 +1129,12 @@ out: nd->dentry->d_inode)) audit_inode(name, nd->dentry->d_inode, flags); } +out_fail: return retval; -fput_unlock_fail: +fput_fail: fput_light(file, fput_needed); -unlock_fail: - read_unlock(¤t->fs->lock); - return retval; + goto out_fail; } int fastcall path_lookup(const char *name, unsigned int flags, From 78b86e579f11e7d7bd45acd90b6a87cd4b7c5a54 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sun, 4 Jun 2006 02:51:38 -0700 Subject: [PATCH 17/95] [PATCH] pmf_register_irq_client() gives sleep with locks held warning From: Benjamin Herrenschmidt This fixes request_irq() potentially called from atomic context. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/powermac/pfunc_core.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index 4baa75b1d36f..f08173b0f065 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -546,6 +547,7 @@ struct pmf_device { static LIST_HEAD(pmf_devices); static spinlock_t pmf_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_MUTEX(pmf_irq_mutex); static void pmf_release_device(struct kref *kref) { @@ -864,15 +866,17 @@ int pmf_register_irq_client(struct device_node *target, spin_lock_irqsave(&pmf_lock, flags); func = __pmf_find_function(target, name, PMF_FLAGS_INT_GEN); - if (func == NULL) { - spin_unlock_irqrestore(&pmf_lock, flags); + if (func) + func = pmf_get_function(func); + spin_unlock_irqrestore(&pmf_lock, flags); + if (func == NULL) return -ENODEV; - } + mutex_lock(&pmf_irq_mutex); if (list_empty(&func->irq_clients)) func->dev->handlers->irq_enable(func); list_add(&client->link, &func->irq_clients); client->func = func; - spin_unlock_irqrestore(&pmf_lock, flags); + mutex_unlock(&pmf_irq_mutex); return 0; } @@ -881,16 +885,16 @@ EXPORT_SYMBOL_GPL(pmf_register_irq_client); void pmf_unregister_irq_client(struct pmf_irq_client *client) { struct pmf_function *func = client->func; - unsigned long flags; BUG_ON(func == NULL); - spin_lock_irqsave(&pmf_lock, flags); + mutex_lock(&pmf_irq_mutex); client->func = NULL; list_del(&client->link); if (list_empty(&func->irq_clients)) func->dev->handlers->irq_disable(func); - spin_unlock_irqrestore(&pmf_lock, flags); + mutex_unlock(&pmf_irq_mutex); + pmf_put_function(func); } EXPORT_SYMBOL_GPL(pmf_unregister_irq_client); From 0674d594ad8e0856243536c0bcc22e4583554bfb Mon Sep 17 00:00:00 2001 From: Zachary Amsden Date: Sun, 4 Jun 2006 02:51:38 -0700 Subject: [PATCH 18/95] [PATCH] Implement get / set tso for forcedeth driver From: Zachary Amsden Signed-off-by: Zachary Amsden Cc: Ayaz Abdulla Cc: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/forcedeth.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 705e1229d89d..feb5b223cd60 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -2615,6 +2615,18 @@ static int nv_nway_reset(struct net_device *dev) return ret; } +#ifdef NETIF_F_TSO +static int nv_set_tso(struct net_device *dev, u32 value) +{ + struct fe_priv *np = netdev_priv(dev); + + if ((np->driver_data & DEV_HAS_CHECKSUM)) + return ethtool_op_set_tso(dev, value); + else + return value ? -EOPNOTSUPP : 0; +} +#endif + static struct ethtool_ops ops = { .get_drvinfo = nv_get_drvinfo, .get_link = ethtool_op_get_link, @@ -2626,6 +2638,10 @@ static struct ethtool_ops ops = { .get_regs = nv_get_regs, .nway_reset = nv_nway_reset, .get_perm_addr = ethtool_op_get_perm_addr, +#ifdef NETIF_F_TSO + .get_tso = ethtool_op_get_tso, + .set_tso = nv_set_tso +#endif }; static void nv_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) From 948c51e6a8d71df99ef57c61bc80dc7c20cbf7bc Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sun, 4 Jun 2006 02:51:39 -0700 Subject: [PATCH 19/95] [PATCH] MAINTAINERS: Add entries for BNX2 and TG3 From: "Michael Chan" Add maintainer entries for Broadcom BNX2 and TG3 drivers. Signed-off-by: Michael Chan Cc: "David S. Miller" Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 74d71cafb17c..141c22269eba 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -568,6 +568,18 @@ L: linuxppc-dev@ozlabs.org W: http://www.penguinppc.org/ppc64/ S: Supported +BROADCOM BNX2 GIGABIT ETHERNET DRIVER +P: Michael Chan +M: mchan@broadcom.com +L: netdev@vger.kernel.org +S: Supported + +BROADCOM TG3 GIGABIT ETHERNET DRIVER +P: Michael Chan +M: mchan@broadcom.com +L: netdev@vger.kernel.org +S: Supported + BTTV VIDEO4LINUX DRIVER P: Mauro Carvalho Chehab M: mchehab@infradead.org From 829a1985e732698ee98def146410e6e9f532781f Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sun, 4 Jun 2006 02:51:40 -0700 Subject: [PATCH 20/95] [PATCH] sbp2: fix check of return value of hpsb_allocate_and_register_addrspace() From: Stefan Richter I added a failure check in patch "sbp2: variable status FIFO address (fix login timeout)" --- alas for a wrong error value. This is a bug since Linux 2.6.16. Leads to NULL pointer dereference if the call failed, and bogus failure handling if call succeeded. Signed-off-by: Stefan Richter Cc: Cc: Ben Collins Cc: Jody McIntyre Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/ieee1394/sbp2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 8a23fb54c693..5413dc43b9f1 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -845,7 +845,7 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud &sbp2_highlevel, ud->ne->host, &sbp2_ops, sizeof(struct sbp2_status_block), sizeof(quadlet_t), 0x010000000000ULL, CSR1212_ALL_SPACE_END); - if (!scsi_id->status_fifo_addr) { + if (scsi_id->status_fifo_addr == ~0ULL) { SBP2_ERR("failed to allocate status FIFO address range"); goto failed_alloc; } From 67f672f61bb75e74805046e4a301f4923b0ef753 Mon Sep 17 00:00:00 2001 From: Rune Torgersen Date: Sun, 4 Jun 2006 02:51:41 -0700 Subject: [PATCH 21/95] [PATCH] sata_sil24: SII3124 sata driver endian problem From: "Rune Torgersen" Fix an endian issue in the sil24 driver. Signed-off-by: Rune Torgersen Acked-by: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/sata_sil24.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c index f7264fd611c2..cb9082fd7e2f 100644 --- a/drivers/scsi/sata_sil24.c +++ b/drivers/scsi/sata_sil24.c @@ -454,7 +454,7 @@ static int sil24_softreset(struct ata_port *ap, int verbose, */ msleep(10); - prb->ctrl = PRB_CTRL_SRST; + prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); prb->fis[1] = 0; /* no PM yet */ writel((u32)paddr, port + PORT_CMD_ACTIVATE); @@ -551,9 +551,9 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) { if (qc->tf.flags & ATA_TFLAG_WRITE) - prb->ctrl = PRB_CTRL_PACKET_WRITE; + prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_WRITE); else - prb->ctrl = PRB_CTRL_PACKET_READ; + prb->ctrl = cpu_to_le16(PRB_CTRL_PACKET_READ); } else prb->ctrl = 0; From 2d7b20c1884777e66009be1a533641c19c4705f6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sun, 4 Jun 2006 02:51:42 -0700 Subject: [PATCH 22/95] [PATCH] m48t86: ia64 build fix From: Andrew Morton drivers/rtc/rtc-m48t86.c: In function `m48t86_rtc_read_time': drivers/rtc/rtc-m48t86.c:51: error: structure has no member named `ia64_mv' drivers/rtc/rtc-m48t86.c:55: error: structure has no member named `ia64_mv' drivers/rtc/rtc-m48t86.c:56: error: structure has no member named `ia64_mv' drivers/rtc/rtc-m48t86.c:57: error: structure has no member named `ia64_mv' drivers/rtc/rtc-m48t86.c:58: error: structure has no member named `ia64_mv' drivers/rtc/rtc-m48t86.c:60: error: structure has no member named `ia64_mv' readb() and writeb() are macros on ia64. Cc: Alessandro Zummo Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m48t86.c | 72 ++++++++++++++++++++-------------------- include/linux/m48t86.h | 4 +-- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index f6e7ee04f3dc..8c0d1a6739ad 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -48,33 +48,33 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) struct platform_device *pdev = to_platform_device(dev); struct m48t86_ops *ops = pdev->dev.platform_data; - reg = ops->readb(M48T86_REG_B); + reg = ops->readbyte(M48T86_REG_B); if (reg & M48T86_REG_B_DM) { /* data (binary) mode */ - tm->tm_sec = ops->readb(M48T86_REG_SEC); - tm->tm_min = ops->readb(M48T86_REG_MIN); - tm->tm_hour = ops->readb(M48T86_REG_HOUR) & 0x3F; - tm->tm_mday = ops->readb(M48T86_REG_DOM); + tm->tm_sec = ops->readbyte(M48T86_REG_SEC); + tm->tm_min = ops->readbyte(M48T86_REG_MIN); + tm->tm_hour = ops->readbyte(M48T86_REG_HOUR) & 0x3F; + tm->tm_mday = ops->readbyte(M48T86_REG_DOM); /* tm_mon is 0-11 */ - tm->tm_mon = ops->readb(M48T86_REG_MONTH) - 1; - tm->tm_year = ops->readb(M48T86_REG_YEAR) + 100; - tm->tm_wday = ops->readb(M48T86_REG_DOW); + tm->tm_mon = ops->readbyte(M48T86_REG_MONTH) - 1; + tm->tm_year = ops->readbyte(M48T86_REG_YEAR) + 100; + tm->tm_wday = ops->readbyte(M48T86_REG_DOW); } else { /* bcd mode */ - tm->tm_sec = BCD2BIN(ops->readb(M48T86_REG_SEC)); - tm->tm_min = BCD2BIN(ops->readb(M48T86_REG_MIN)); - tm->tm_hour = BCD2BIN(ops->readb(M48T86_REG_HOUR) & 0x3F); - tm->tm_mday = BCD2BIN(ops->readb(M48T86_REG_DOM)); + tm->tm_sec = BCD2BIN(ops->readbyte(M48T86_REG_SEC)); + tm->tm_min = BCD2BIN(ops->readbyte(M48T86_REG_MIN)); + tm->tm_hour = BCD2BIN(ops->readbyte(M48T86_REG_HOUR) & 0x3F); + tm->tm_mday = BCD2BIN(ops->readbyte(M48T86_REG_DOM)); /* tm_mon is 0-11 */ - tm->tm_mon = BCD2BIN(ops->readb(M48T86_REG_MONTH)) - 1; - tm->tm_year = BCD2BIN(ops->readb(M48T86_REG_YEAR)) + 100; - tm->tm_wday = BCD2BIN(ops->readb(M48T86_REG_DOW)); + tm->tm_mon = BCD2BIN(ops->readbyte(M48T86_REG_MONTH)) - 1; + tm->tm_year = BCD2BIN(ops->readbyte(M48T86_REG_YEAR)) + 100; + tm->tm_wday = BCD2BIN(ops->readbyte(M48T86_REG_DOW)); } /* correct the hour if the clock is in 12h mode */ if (!(reg & M48T86_REG_B_H24)) - if (ops->readb(M48T86_REG_HOUR) & 0x80) + if (ops->readbyte(M48T86_REG_HOUR) & 0x80) tm->tm_hour += 12; return 0; @@ -86,35 +86,35 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) struct platform_device *pdev = to_platform_device(dev); struct m48t86_ops *ops = pdev->dev.platform_data; - reg = ops->readb(M48T86_REG_B); + reg = ops->readbyte(M48T86_REG_B); /* update flag and 24h mode */ reg |= M48T86_REG_B_SET | M48T86_REG_B_H24; - ops->writeb(reg, M48T86_REG_B); + ops->writebyte(reg, M48T86_REG_B); if (reg & M48T86_REG_B_DM) { /* data (binary) mode */ - ops->writeb(tm->tm_sec, M48T86_REG_SEC); - ops->writeb(tm->tm_min, M48T86_REG_MIN); - ops->writeb(tm->tm_hour, M48T86_REG_HOUR); - ops->writeb(tm->tm_mday, M48T86_REG_DOM); - ops->writeb(tm->tm_mon + 1, M48T86_REG_MONTH); - ops->writeb(tm->tm_year % 100, M48T86_REG_YEAR); - ops->writeb(tm->tm_wday, M48T86_REG_DOW); + ops->writebyte(tm->tm_sec, M48T86_REG_SEC); + ops->writebyte(tm->tm_min, M48T86_REG_MIN); + ops->writebyte(tm->tm_hour, M48T86_REG_HOUR); + ops->writebyte(tm->tm_mday, M48T86_REG_DOM); + ops->writebyte(tm->tm_mon + 1, M48T86_REG_MONTH); + ops->writebyte(tm->tm_year % 100, M48T86_REG_YEAR); + ops->writebyte(tm->tm_wday, M48T86_REG_DOW); } else { /* bcd mode */ - ops->writeb(BIN2BCD(tm->tm_sec), M48T86_REG_SEC); - ops->writeb(BIN2BCD(tm->tm_min), M48T86_REG_MIN); - ops->writeb(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR); - ops->writeb(BIN2BCD(tm->tm_mday), M48T86_REG_DOM); - ops->writeb(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH); - ops->writeb(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR); - ops->writeb(BIN2BCD(tm->tm_wday), M48T86_REG_DOW); + ops->writebyte(BIN2BCD(tm->tm_sec), M48T86_REG_SEC); + ops->writebyte(BIN2BCD(tm->tm_min), M48T86_REG_MIN); + ops->writebyte(BIN2BCD(tm->tm_hour), M48T86_REG_HOUR); + ops->writebyte(BIN2BCD(tm->tm_mday), M48T86_REG_DOM); + ops->writebyte(BIN2BCD(tm->tm_mon + 1), M48T86_REG_MONTH); + ops->writebyte(BIN2BCD(tm->tm_year % 100), M48T86_REG_YEAR); + ops->writebyte(BIN2BCD(tm->tm_wday), M48T86_REG_DOW); } /* update ended */ reg &= ~M48T86_REG_B_SET; - ops->writeb(reg, M48T86_REG_B); + ops->writebyte(reg, M48T86_REG_B); return 0; } @@ -125,12 +125,12 @@ static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) struct platform_device *pdev = to_platform_device(dev); struct m48t86_ops *ops = pdev->dev.platform_data; - reg = ops->readb(M48T86_REG_B); + reg = ops->readbyte(M48T86_REG_B); seq_printf(seq, "mode\t\t: %s\n", (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); - reg = ops->readb(M48T86_REG_D); + reg = ops->readbyte(M48T86_REG_D); seq_printf(seq, "battery\t\t: %s\n", (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); @@ -157,7 +157,7 @@ static int __devinit m48t86_rtc_probe(struct platform_device *dev) platform_set_drvdata(dev, rtc); /* read battery status */ - reg = ops->readb(M48T86_REG_D); + reg = ops->readbyte(M48T86_REG_D); dev_info(&dev->dev, "battery %s\n", (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); diff --git a/include/linux/m48t86.h b/include/linux/m48t86.h index 9065199319d0..915d6b4f0f89 100644 --- a/include/linux/m48t86.h +++ b/include/linux/m48t86.h @@ -11,6 +11,6 @@ struct m48t86_ops { - void (*writeb)(unsigned char value, unsigned long addr); - unsigned char (*readb)(unsigned long addr); + void (*writebyte)(unsigned char value, unsigned long addr); + unsigned char (*readbyte)(unsigned long addr); }; From 65e62974a8a6157140259b26e7156e39f53031b6 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 4 Jun 2006 02:51:43 -0700 Subject: [PATCH 23/95] [PATCH] uml: add asm/irqflags.h From: Jeff Dike Add an empty asm/irqflags.h, which seems to satisfy the lock validator enough that UML builds. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-um/irqflags.h | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 include/asm-um/irqflags.h diff --git a/include/asm-um/irqflags.h b/include/asm-um/irqflags.h new file mode 100644 index 000000000000..659b9abdfdba --- /dev/null +++ b/include/asm-um/irqflags.h @@ -0,0 +1,6 @@ +#ifndef __UM_IRQFLAGS_H +#define __UM_IRQFLAGS_H + +/* Empty for now */ + +#endif From 5cb38bc47bf370570fce81f89e05e5250169060f Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 4 Jun 2006 02:51:46 -0700 Subject: [PATCH 24/95] [PATCH] uml: fix wall_to_monotonic initialization From: Jeff Dike Initialize wall_to_monotonic correctly. This fixes a problem where sleeps lasted about one secone less than they should. This also called for a bit of code restructuring, following a patch which Blaisorblade had been keeping. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/kern_util.h | 13 ++----------- arch/um/kernel/time_kern.c | 10 ++++++++++ arch/um/os-Linux/time.c | 10 +--------- 3 files changed, 13 insertions(+), 20 deletions(-) diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index efa3d33c0be6..310980b32173 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -120,20 +120,11 @@ extern int is_syscall(unsigned long addr); extern void free_irq(unsigned int, void *); extern int cpu(void); +extern void time_init_kern(void); + /* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ extern int __cant_sleep(void); extern void segv_handler(int sig, union uml_pt_regs *regs); extern void sigio_handler(int sig, union uml_pt_regs *regs); #endif - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-file-style: "linux" - * End: - */ diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 528cf623f8b4..86f51d04c98d 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c @@ -84,6 +84,16 @@ void timer_irq(union uml_pt_regs *regs) } } + +void time_init_kern(void) +{ + unsigned long long nsecs; + + nsecs = os_nsecs(); + set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, + -nsecs % BILLION); +} + void do_boot_timer_handler(struct sigcontext * sc) { struct pt_regs regs; diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 6f7626775acb..280c4fb9b585 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c @@ -81,20 +81,12 @@ void uml_idle_timer(void) set_interval(ITIMER_REAL); } -extern void ktime_get_ts(struct timespec *ts); -#define do_posix_clock_monotonic_gettime(ts) ktime_get_ts(ts) - void time_init(void) { - struct timespec now; - if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) panic("Couldn't set SIGVTALRM handler"); set_interval(ITIMER_VIRTUAL); - - do_posix_clock_monotonic_gettime(&now); - wall_to_monotonic.tv_sec = -now.tv_sec; - wall_to_monotonic.tv_nsec = -now.tv_nsec; + time_init_kern(); } unsigned long long os_nsecs(void) From f218312582350900443125137e6c5fc484dc1de1 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 4 Jun 2006 02:51:47 -0700 Subject: [PATCH 25/95] [PATCH] uml: fix a typo in do_uml_initcalls From: Jeff Dike We had a spurious semicolon somehow. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/os-Linux/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 3a0ac38e978b..90912aaca7aa 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c @@ -59,7 +59,7 @@ static __init void do_uml_initcalls(void) initcall_t *call; call = &__uml_initcall_start; - while (call < &__uml_initcall_end){; + while (call < &__uml_initcall_end){ (*call)(); call++; } From ca34fb1a8786af43457ec4f1bfc101a66d1160e0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 4 Jun 2006 02:51:47 -0700 Subject: [PATCH 26/95] [PATCH] uml: __user annotation in arch_prctl From: Al Viro fix uml/amd64 prctl() put_user() there should go to (long __user *)addr, not &addr Signed-off-by: Al Viro Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-x86_64/syscalls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 6acee5c4ada6..6fce9f45dfdc 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -45,7 +45,7 @@ static long arch_prctl_tt(int code, unsigned long addr) case ARCH_GET_GS: ret = arch_prctl(code, (unsigned long) &tmp); if(!ret) - ret = put_user(tmp, &addr); + ret = put_user(tmp, (long __user *)addr); break; default: ret = -EINVAL; From b8719c31a30a4a1054d99fbd51a88c2f6444392a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 4 Jun 2006 02:51:48 -0700 Subject: [PATCH 27/95] [PATCH] uml: more __user annotations From: Al Viro uml __user annotations Signed-off-by: Al Viro Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/sys-i386/syscalls.c | 9 +++++---- arch/um/sys-x86_64/signal.c | 24 ++++++++++++++---------- include/asm-um/uaccess.h | 6 +++--- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c index 749dd1bfe60f..710d5fb807e1 100644 --- a/arch/um/sys-i386/syscalls.c +++ b/arch/um/sys-i386/syscalls.c @@ -99,11 +99,12 @@ long sys_ipc (uint call, int first, int second, switch (call) { case SEMOP: - return sys_semtimedop(first, (struct sembuf *) ptr, second, - NULL); + return sys_semtimedop(first, (struct sembuf __user *) ptr, + second, NULL); case SEMTIMEDOP: - return sys_semtimedop(first, (struct sembuf *) ptr, second, - (const struct timespec *) fifth); + return sys_semtimedop(first, (struct sembuf __user *) ptr, + second, + (const struct timespec __user *) fifth); case SEMGET: return sys_semget (first, second, third); case SEMCTL: { diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index a4c46a8af008..9edf114faf79 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -21,7 +21,7 @@ #include "skas.h" static int copy_sc_from_user_skas(struct pt_regs *regs, - struct sigcontext *from) + struct sigcontext __user *from) { int err = 0; @@ -54,7 +54,8 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, return(err); } -int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, +int copy_sc_to_user_skas(struct sigcontext __user *to, + struct _fpstate __user *to_fp, struct pt_regs *regs, unsigned long mask, unsigned long sp) { @@ -106,10 +107,11 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, #endif #ifdef CONFIG_MODE_TT -int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, +int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, int fpsize) { - struct _fpstate *to_fp, *from_fp; + struct _fpstate *to_fp; + struct _fpstate __user *from_fp; unsigned long sigs; int err; @@ -124,13 +126,14 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from, return(err); } -int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp, +int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, struct sigcontext *from, int fpsize, unsigned long sp) { - struct _fpstate *to_fp, *from_fp; + struct _fpstate __user *to_fp; + struct _fpstate *from_fp; int err; - to_fp = (fp ? fp : (struct _fpstate *) (to + 1)); + to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); from_fp = from->fpstate; err = copy_to_user(to, from, sizeof(*to)); /* The SP in the sigcontext is the updated one for the signal @@ -158,7 +161,8 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) return(ret); } -static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, +static int copy_sc_to_user(struct sigcontext __user *to, + struct _fpstate __user *fp, struct pt_regs *from, unsigned long mask, unsigned long sp) { @@ -169,7 +173,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, struct rt_sigframe { - char *pretcode; + char __user *pretcode; struct ucontext uc; struct siginfo info; }; @@ -188,7 +192,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; - frame = (struct rt_sigframe *) ((unsigned long) frame - 128); + frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128); if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) goto out; diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h index bea5a015f667..16c734af9193 100644 --- a/include/asm-um/uaccess.h +++ b/include/asm-um/uaccess.h @@ -41,11 +41,11 @@ #define __get_user(x, ptr) \ ({ \ - const __typeof__(ptr) __private_ptr = ptr; \ + const __typeof__(*(ptr)) __user *__private_ptr = (ptr); \ __typeof__(x) __private_val; \ int __private_ret = -EFAULT; \ (x) = (__typeof__(*(__private_ptr)))0; \ - if (__copy_from_user((void *) &__private_val, (__private_ptr), \ + if (__copy_from_user((__force void *)&__private_val, (__private_ptr),\ sizeof(*(__private_ptr))) == 0) { \ (x) = (__typeof__(*(__private_ptr))) __private_val; \ __private_ret = 0; \ @@ -62,7 +62,7 @@ #define __put_user(x, ptr) \ ({ \ - __typeof__(ptr) __private_ptr = ptr; \ + __typeof__(*(ptr)) __user *__private_ptr = ptr; \ __typeof__(*(__private_ptr)) __private_val; \ int __private_ret = -EFAULT; \ __private_val = (__typeof__(*(__private_ptr))) (x); \ From fec468b0c9e0a75b89514408e3b35b1576b57071 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Sun, 4 Jun 2006 02:51:49 -0700 Subject: [PATCH 28/95] [PATCH] uml: add -ffreestanding to CFLAGS From: Jeff Dike This fixes the undefined reference to strcpy seen when building modules on i386. Tracked down by Al Viro. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/Makefile-i386 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index 7a0e04e34bf9..b65ca115ef77 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 @@ -33,5 +33,9 @@ include $(srctree)/arch/i386/Makefile.cpu # prevent gcc from keeping the stack 16 byte aligned. Taken from i386. cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) +# Prevent sprintf in nfsd from being converted to strcpy and resulting in +# an unresolved reference. +cflags-y += -ffreestanding + CFLAGS += $(cflags-y) USER_CFLAGS += $(cflags-y) From f291196979ca80cdef199ca2b55e2758e8c23a0d Mon Sep 17 00:00:00 2001 From: Herbert Xu ~{PmVHI~} Date: Mon, 5 Jun 2006 15:03:37 -0700 Subject: [PATCH 29/95] [TCP]: Avoid skb_pull if possible when trimming head Trimming the head of an skb by calling skb_pull can cause the packet to become unaligned if the length pulled is odd. Since the length is entirely arbitrary for a FIN packet carrying data, this is actually quite common. Unaligned data is not the end of the world, but we should avoid it if it's easily done. In this case it is trivial. Since we're discarding all of the head data it doesn't matter whether we move skb->data forward or back. However, it is still possible to have unaligned skb->data in general. So network drivers should be prepared to handle it instead of crashing. This patch also adds an unlikely marking on len < headlen since partial ACKs on head data are extremely rare in the wild. As the return value of __pskb_trim_head is no longer ever NULL that has been removed. Signed-off-by: Herbert Xu ~{PmV>HI~} Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 743016baa048..f33c9dddaa12 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -642,7 +642,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss * eventually). The difference is that pulled data not copied, but * immediately discarded. */ -static unsigned char *__pskb_trim_head(struct sk_buff *skb, int len) +static void __pskb_trim_head(struct sk_buff *skb, int len) { int i, k, eat; @@ -667,7 +667,6 @@ static unsigned char *__pskb_trim_head(struct sk_buff *skb, int len) skb->tail = skb->data; skb->data_len -= len; skb->len = skb->data_len; - return skb->tail; } int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) @@ -676,12 +675,11 @@ int tcp_trim_head(struct sock *sk, struct sk_buff *skb, u32 len) pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) return -ENOMEM; - if (len <= skb_headlen(skb)) { + /* If len == headlen, we avoid __skb_pull to preserve alignment. */ + if (unlikely(len < skb_headlen(skb))) __skb_pull(skb, len); - } else { - if (__pskb_trim_head(skb, len-skb_headlen(skb)) == NULL) - return -ENOMEM; - } + else + __pskb_trim_head(skb, len - skb_headlen(skb)); TCP_SKB_CB(skb)->seq += len; skb->ip_summed = CHECKSUM_HW; From 92cd6eeea62e235fcb6634d87d1572c3da59f088 Mon Sep 17 00:00:00 2001 From: Matt Mackall Date: Mon, 5 Jun 2006 15:04:37 -0700 Subject: [PATCH 30/95] [NETCONSOLE]: Clean up initcall warning. From: Matt Mackall netconsole is being wrong here. If it wasn't enabled there's no error. Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 66e74f740261..bf58db29e2ed 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -107,7 +107,7 @@ static int init_netconsole(void) if(!configured) { printk("netconsole: not configured, aborting\n"); - return -EINVAL; + return 0; } if(netpoll_setup(&np)) From 6569a351da7e58d6f0fbc92fcf0bef5d4a4bc0a4 Mon Sep 17 00:00:00 2001 From: Jes Sorensen Date: Mon, 5 Jun 2006 15:34:11 -0700 Subject: [PATCH 31/95] [NET]: Eliminate unused /proc/sys/net/ethernet The /proc/sys/net/ethernet directory has been sitting empty for more than 10 years! Time to eliminate it! Signed-off-by: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/ethernet/Makefile | 1 - net/ethernet/sysctl_net_ether.c | 14 -------------- net/sysctl_net.c | 8 -------- 3 files changed, 23 deletions(-) delete mode 100644 net/ethernet/sysctl_net_ether.c diff --git a/net/ethernet/Makefile b/net/ethernet/Makefile index 69b74a9a0fc3..7cef1d8ace27 100644 --- a/net/ethernet/Makefile +++ b/net/ethernet/Makefile @@ -3,6 +3,5 @@ # obj-y += eth.o -obj-$(CONFIG_SYSCTL) += sysctl_net_ether.o obj-$(subst m,y,$(CONFIG_IPX)) += pe2.o obj-$(subst m,y,$(CONFIG_ATALK)) += pe2.o diff --git a/net/ethernet/sysctl_net_ether.c b/net/ethernet/sysctl_net_ether.c deleted file mode 100644 index 66b39fc342d2..000000000000 --- a/net/ethernet/sysctl_net_ether.c +++ /dev/null @@ -1,14 +0,0 @@ -/* -*- linux-c -*- - * sysctl_net_ether.c: sysctl interface to net Ethernet subsystem. - * - * Begun April 1, 1996, Mike Shaver. - * Added /proc/sys/net/ether directory entry (empty =) ). [MS] - */ - -#include -#include -#include - -ctl_table ether_table[] = { - {0} -}; diff --git a/net/sysctl_net.c b/net/sysctl_net.c index 55538f6b60ff..58a1b6b42ddd 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -37,14 +37,6 @@ struct ctl_table net_table[] = { .mode = 0555, .child = core_table, }, -#ifdef CONFIG_NET - { - .ctl_name = NET_ETHER, - .procname = "ethernet", - .mode = 0555, - .child = ether_table, - }, -#endif #ifdef CONFIG_INET { .ctl_name = NET_IPV4, From 9bc18091a5e44a368827f539289b99788eb27d4e Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Mon, 5 Jun 2006 15:34:33 -0700 Subject: [PATCH 32/95] [PPPOE]: Missing result check in __pppoe_xmit(). skb_clone() may fail, we should check the result. Coverity CID: 1215. Signed-off-by: Florin Malita Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/net/pppoe.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 475dc930380f..0d101a18026a 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -861,6 +861,9 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) * give dev_queue_xmit something it can free. */ skb2 = skb_clone(skb, GFP_ATOMIC); + + if (skb2 == NULL) + goto abort; } ph = (struct pppoe_hdr *) skb_push(skb2, sizeof(struct pppoe_hdr)); From 8c893ff6abbac0c7c05b1cb9bfb6e2dfc4538c75 Mon Sep 17 00:00:00 2001 From: Florin Malita Date: Mon, 5 Jun 2006 15:34:52 -0700 Subject: [PATCH 33/95] [IRDA]: Missing allocation result check in irlap_change_speed(). The skb allocation may fail, which can result in a NULL pointer dereference in irlap_queue_xmit(). Coverity CID: 434. Signed-off-by: Florin Malita Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- net/irda/irlap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 7029618f5719..a16528657b4c 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -884,7 +884,8 @@ static void irlap_change_speed(struct irlap_cb *self, __u32 speed, int now) if (now) { /* Send down empty frame to trigger speed change */ skb = dev_alloc_skb(0); - irlap_queue_xmit(self, skb); + if (skb) + irlap_queue_xmit(self, skb); } } From acf518cbba773e2c20fe313acb340da65001c7a8 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 18 May 2006 01:16:10 +0200 Subject: [PATCH 34/95] [MIPS] Remove duplicate declaration of cpu_online_map. Signed-off-by: Ralf Baechle --- include/asm-mips/smp.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 75c6fe7c2126..5a4fad910d82 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -48,7 +48,6 @@ extern struct call_data_struct *call_data; #define SMP_CALL_FUNCTION 0x2 extern cpumask_t phys_cpu_present_map; -extern cpumask_t cpu_online_map; #define cpu_possible_map phys_cpu_present_map extern cpumask_t cpu_callout_map; From 320e6aba26892b016293190e079f15e83a5c28b9 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 22 May 2006 14:24:04 +0100 Subject: [PATCH 35/95] [MIPS] Fix SMP now that fixup_cpu_present_map is gone. Signed-off-by: Ralf Baechle --- arch/mips/kernel/smp.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index d42f358754ad..298f82fe8440 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c @@ -247,6 +247,9 @@ void __init smp_prepare_cpus(unsigned int max_cpus) current_thread_info()->cpu = 0; smp_tune_scheduling(); plat_prepare_cpus(max_cpus); +#ifndef CONFIG_HOTPLUG_CPU + cpu_present_map = cpu_possible_map; +#endif } /* preload SMP state for boot cpu */ @@ -442,7 +445,7 @@ static int __init topology_init(void) int cpu; int ret; - for_each_cpu(cpu) { + for_each_present_cpu(cpu) { ret = register_cpu(&per_cpu(cpu_devices, cpu), cpu, NULL); if (ret) printk(KERN_WARNING "topology_init: register_cpu %d " From f3bf07b9a367c342bcbc9f47d525d3cf5e8b4f3b Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 23 May 2006 00:45:07 +0900 Subject: [PATCH 36/95] [MIPS] Ignore unresolved weak symbols in modules. Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/module.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/arch/mips/kernel/module.c b/arch/mips/kernel/module.c index e54a7f442f8a..d7bf0215bc1d 100644 --- a/arch/mips/kernel/module.c +++ b/arch/mips/kernel/module.c @@ -288,6 +288,9 @@ int apply_relocate(Elf_Shdr *sechdrs, const char *strtab, sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); if (!sym->st_value) { + /* Ignore unresolved weak symbol */ + if (ELF_ST_BIND(sym->st_info) == STB_WEAK) + continue; printk(KERN_WARNING "%s: Unknown symbol %s\n", me->name, strtab + sym->st_name); return -ENOENT; @@ -325,6 +328,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab, sym = (Elf_Sym *)sechdrs[symindex].sh_addr + ELF_MIPS_R_SYM(rel[i]); if (!sym->st_value) { + /* Ignore unresolved weak symbol */ + if (ELF_ST_BIND(sym->st_info) == STB_WEAK) + continue; printk(KERN_WARNING "%s: Unknown symbol %s\n", me->name, strtab + sym->st_name); return -ENOENT; From 5ee823507b3c7d2187df2160125a4f64232d3a60 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 23 May 2006 16:37:32 +0100 Subject: [PATCH 37/95] [MIPS] Fix instable BogoMIPS on multi-issue processors. Increase alignment of BogoMIPS loop to 8 bytes. Having the delay loop overlap cache line boundaries may cause instable delays. Signed-off-by: Ralf Baechle --- include/asm-mips/delay.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h index 64dd45150f64..928f30f8c45c 100644 --- a/include/asm-mips/delay.h +++ b/include/asm-mips/delay.h @@ -19,20 +19,22 @@ static inline void __delay(unsigned long loops) { if (sizeof(long) == 4) __asm__ __volatile__ ( - ".set\tnoreorder\n" - "1:\tbnez\t%0,1b\n\t" - "subu\t%0,1\n\t" - ".set\treorder" + " .set noreorder \n" + " .align 3 \n" + "1: bnez %0, 1b \n" + " subu %0, 1 \n" + " .set reorder \n" : "=r" (loops) : "0" (loops)); else if (sizeof(long) == 8) __asm__ __volatile__ ( - ".set\tnoreorder\n" - "1:\tbnez\t%0,1b\n\t" - "dsubu\t%0,1\n\t" - ".set\treorder" - :"=r" (loops) - :"0" (loops)); + " .set noreorder \n" + " .align 3 \n" + "1: bnez %0, 1b \n" + " dsubu %0, 1 \n" + " .set reorder \n" + : "=r" (loops) + : "0" (loops)); } From 1acf1ca7e906cf7453d76d76a6c953996295c220 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 23 May 2006 16:42:38 +0900 Subject: [PATCH 38/95] [MIPS] Fix modpost warning: Rename op_model_xxx to op_model_xxx_ops. The modpost uses a whitelist for commonly used suffix on checking the section mismatch. Adding "_ops" suffix to op_modex_xxx get rid of this modpost warning. WARNING: arch/mips/oprofile/oprofile.o - Section mismatch: reference to .init.text: from .data after 'op_model_mipsxx' (at offset 0x528) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/oprofile/common.c | 8 +++---- arch/mips/oprofile/op_model_mipsxx.c | 32 ++++++++++++++-------------- arch/mips/oprofile/op_model_rm9000.c | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c index 91b799d2cd88..c31e4cff64e0 100644 --- a/arch/mips/oprofile/common.c +++ b/arch/mips/oprofile/common.c @@ -14,8 +14,8 @@ #include "op_impl.h" -extern struct op_mips_model op_model_mipsxx __attribute__((weak)); -extern struct op_mips_model op_model_rm9000 __attribute__((weak)); +extern struct op_mips_model op_model_mipsxx_ops __attribute__((weak)); +extern struct op_mips_model op_model_rm9000_ops __attribute__((weak)); static struct op_mips_model *model; @@ -83,11 +83,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) case CPU_74K: case CPU_SB1: case CPU_SB1A: - lmodel = &op_model_mipsxx; + lmodel = &op_model_mipsxx_ops; break; case CPU_RM9000: - lmodel = &op_model_rm9000; + lmodel = &op_model_rm9000_ops; break; }; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index e7ce92391303..f26a00e13204 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -23,7 +23,7 @@ #define M_COUNTER_OVERFLOW (1UL << 31) -struct op_mips_model op_model_mipsxx; +struct op_mips_model op_model_mipsxx_ops; static struct mipsxx_register_config { unsigned int control[4]; @@ -34,7 +34,7 @@ static struct mipsxx_register_config { static void mipsxx_reg_setup(struct op_counter_config *ctr) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; int i; /* Compute the performance counter control word. */ @@ -62,7 +62,7 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) static void mipsxx_cpu_setup (void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -83,7 +83,7 @@ static void mipsxx_cpu_setup (void *args) /* Start all counters on current CPU */ static void mipsxx_cpu_start(void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -100,7 +100,7 @@ static void mipsxx_cpu_start(void *args) /* Stop all counters on current CPU */ static void mipsxx_cpu_stop(void *args) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; switch (counters) { case 4: @@ -116,7 +116,7 @@ static void mipsxx_cpu_stop(void *args) static int mipsxx_perfcount_handler(struct pt_regs *regs) { - unsigned int counters = op_model_mipsxx.num_counters; + unsigned int counters = op_model_mipsxx_ops.num_counters; unsigned int control; unsigned int counter; int handled = 0; @@ -187,37 +187,37 @@ static int __init mipsxx_init(void) reset_counters(counters); - op_model_mipsxx.num_counters = counters; + op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_data.cputype) { case CPU_20KC: - op_model_mipsxx.cpu_type = "mips/20K"; + op_model_mipsxx_ops.cpu_type = "mips/20K"; break; case CPU_24K: - op_model_mipsxx.cpu_type = "mips/24K"; + op_model_mipsxx_ops.cpu_type = "mips/24K"; break; case CPU_25KF: - op_model_mipsxx.cpu_type = "mips/25K"; + op_model_mipsxx_ops.cpu_type = "mips/25K"; break; #ifndef CONFIG_SMP case CPU_34K: - op_model_mipsxx.cpu_type = "mips/34K"; + op_model_mipsxx_ops.cpu_type = "mips/34K"; break; case CPU_74K: - op_model_mipsxx.cpu_type = "mips/74K"; + op_model_mipsxx_ops.cpu_type = "mips/74K"; break; #endif case CPU_5KC: - op_model_mipsxx.cpu_type = "mips/5K"; + op_model_mipsxx_ops.cpu_type = "mips/5K"; break; case CPU_SB1: case CPU_SB1A: - op_model_mipsxx.cpu_type = "mips/sb1"; + op_model_mipsxx_ops.cpu_type = "mips/sb1"; break; default: @@ -233,12 +233,12 @@ static int __init mipsxx_init(void) static void mipsxx_exit(void) { - reset_counters(op_model_mipsxx.num_counters); + reset_counters(op_model_mipsxx_ops.num_counters); perf_irq = null_perf_irq; } -struct op_mips_model op_model_mipsxx = { +struct op_mips_model op_model_mipsxx_ops = { .reg_setup = mipsxx_reg_setup, .cpu_setup = mipsxx_cpu_setup, .init = mipsxx_init, diff --git a/arch/mips/oprofile/op_model_rm9000.c b/arch/mips/oprofile/op_model_rm9000.c index 9b75e41c78ef..b7063fefa65b 100644 --- a/arch/mips/oprofile/op_model_rm9000.c +++ b/arch/mips/oprofile/op_model_rm9000.c @@ -126,7 +126,7 @@ static void rm9000_exit(void) free_irq(rm9000_perfcount_irq, NULL); } -struct op_mips_model op_model_rm9000 = { +struct op_mips_model op_model_rm9000_ops = { .reg_setup = rm9000_reg_setup, .cpu_setup = rm9000_cpu_setup, .init = rm9000_init, From 722ace9dfb73a62bf78c2db619795cfc128fef5a Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 24 May 2006 03:04:18 +0100 Subject: [PATCH 39/95] [MIPS] Fix declaration of smp_prepare_cpus() platform hook. A while ago prom_prepare_cpus was replaced by plat_prepare_cpus but the declaration has stayed unchanged. Signed-off-by: Ralf Baechle --- include/asm-mips/smp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index 5a4fad910d82..e14e4b69de21 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -85,9 +85,9 @@ extern void prom_init_secondary(void); extern void plat_smp_setup(void); /* - * Called after init_IRQ but before __cpu_up. + * Called in smp_prepare_cpus. */ -extern void prom_prepare_cpus(unsigned int max_cpus); +extern void plat_prepare_cpus(unsigned int max_cpus); /* * Last chance for the board code to finish SMP initialization before From cac4bcbce0e800f2219a27b66aaeb4a33f2e3dbc Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 24 May 2006 16:51:02 +0100 Subject: [PATCH 40/95] [MIPS] Print more information if we're struck by a machine check exception. Signed-off-by: Ralf Baechle --- arch/mips/kernel/traps.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 35cb08da3820..a7564b08eb4d 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -819,15 +819,30 @@ asmlinkage void do_watch(struct pt_regs *regs) asmlinkage void do_mcheck(struct pt_regs *regs) { + const int field = 2 * sizeof(unsigned long); + int multi_match = regs->cp0_status & ST0_TS; + show_regs(regs); - dump_tlb_all(); + + if (multi_match) { + printk("Index : %0x\n", read_c0_index()); + printk("Pagemask: %0x\n", read_c0_pagemask()); + printk("EntryHi : %0*lx\n", field, read_c0_entryhi()); + printk("EntryLo0: %0*lx\n", field, read_c0_entrylo0()); + printk("EntryLo1: %0*lx\n", field, read_c0_entrylo1()); + printk("\n"); + dump_tlb_all(); + } + + show_code((unsigned int *) regs->cp0_epc); + /* * Some chips may have other causes of machine check (e.g. SB1 * graduation timer) */ panic("Caught Machine Check exception - %scaused by multiple " "matching entries in the TLB.", - (regs->cp0_status & ST0_TS) ? "" : "not "); + (multi_match) ? "" : "not "); } asmlinkage void do_mt(struct pt_regs *regs) From 9370b35175ca43fad7d24bc7b391473f3becbee8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 26 May 2006 19:44:54 +0400 Subject: [PATCH 41/95] [MIPS] Save write-only Config.OD from being clobbered Save the Config.OD bit from being clobbered by coherency_setup(). This bit, when set, fixes various errata in the early steppings of Au1x00 SOCs. Unfortunately, the bit was write-only on the most early of them. In addition, also restore the bit after a wakeup from sleep. Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/sleeper.S | 5 +++++ arch/mips/mm/c-r4k.c | 34 +++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/arch/mips/au1000/common/sleeper.S b/arch/mips/au1000/common/sleeper.S index 44dac3b0df3b..683d9da84b66 100644 --- a/arch/mips/au1000/common/sleeper.S +++ b/arch/mips/au1000/common/sleeper.S @@ -112,6 +112,11 @@ sdsleep: mtc0 k0, CP0_PAGEMASK lw k0, 0x14(sp) mtc0 k0, CP0_CONFIG + + /* We need to catch the ealry Alchemy SOCs with + * the write-only Config[OD] bit and set it back to one... + */ + jal au1x00_fixup_config_od lw $1, PT_R1(sp) lw $2, PT_R2(sp) lw $3, PT_R3(sp) diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 6b3541769602..4a43924cd4fc 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c @@ -1161,6 +1161,31 @@ static void __init setup_scache(void) c->options |= MIPS_CPU_SUBSET_CACHES; } +void au1x00_fixup_config_od(void) +{ + /* + * c0_config.od (bit 19) was write only (and read as 0) + * on the early revisions of Alchemy SOCs. It disables the bus + * transaction overlapping and needs to be set to fix various errata. + */ + switch (read_c0_prid()) { + case 0x00030100: /* Au1000 DA */ + case 0x00030201: /* Au1000 HA */ + case 0x00030202: /* Au1000 HB */ + case 0x01030200: /* Au1500 AB */ + /* + * Au1100 errata actually keeps silence about this bit, so we set it + * just in case for those revisions that require it to be set according + * to arch/mips/au1000/common/cputable.c + */ + case 0x02030200: /* Au1100 AB */ + case 0x02030201: /* Au1100 BA */ + case 0x02030202: /* Au1100 BC */ + set_c0_config(1 << 19); + break; + } +} + static inline void coherency_setup(void) { change_c0_config(CONF_CM_CMASK, CONF_CM_DEFAULT); @@ -1181,6 +1206,15 @@ static inline void coherency_setup(void) case CPU_R4400MC: clear_c0_config(CONF_CU); break; + /* + * We need to catch the ealry Alchemy SOCs with + * the write-only co_config.od bit and set it back to one... + */ + case CPU_AU1000: /* rev. DA, HA, HB */ + case CPU_AU1100: /* rev. AB, BA, BC ?? */ + case CPU_AU1500: /* rev. AB */ + au1x00_fixup_config_od(); + break; } } From 79e0bc37255a4b934291b4d3ea5a4561fbd78da4 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Wed, 3 May 2006 22:56:43 +0400 Subject: [PATCH 42/95] [MIPS] Fix mprotect() syscall for MIPS32 w/36-bit physical address support Fix mprotect() syscall for MIPS32 CPUs with 36-bit physical address support: pte_modify() macro didn't clear the hardware page protection bits before modifying... Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- include/asm-mips/pgtable.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index f80fe75c7800..d0af2a3b0152 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -353,8 +353,9 @@ static inline pgprot_t pgprot_noncached(pgprot_t _prot) #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { - pte.pte_low &= _PAGE_CHG_MASK; - pte.pte_low |= pgprot_val(newprot); + pte.pte_low &= _PAGE_CHG_MASK; + pte.pte_high &= ~0x3f; + pte.pte_low |= pgprot_val(newprot); pte.pte_high |= pgprot_val(newprot) & 0x3f; return pte; } From 6ebba0e2f56ee77270a9ef8e92c1b4ec38e5f419 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 27 May 2006 20:43:04 +0400 Subject: [PATCH 43/95] [MIPS] Fix swap entry for MIPS32 36-bit physical address With 64-bit physical address enabled, 'swapon' was causing kernel oops on Alchemy CPUs (MIPS32) because of the swap entry type field corrupting the _PAGE_FILE bit in 'pte_low' field. So, switch to storing the swap entry in 'pte_high' field using all its bits except _PAGE_GLOBAL and _PAGE_VALID which gives 25 bits for the swap entry offset. Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- include/asm-mips/pgtable-32.h | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index 4d6bc45df594..a5ce3f17a989 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -191,10 +191,17 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #else /* Swap entries must have VALID and GLOBAL bits cleared. */ -#define __swp_type(x) (((x).val >> 8) & 0x1f) -#define __swp_offset(x) ((x).val >> 13) +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#define __swp_type(x) (((x).val >> 2) & 0x1f) +#define __swp_offset(x) ((x).val >> 7) #define __swp_entry(type,offset) \ - ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) + ((swp_entry_t) { ((type) << 2) | ((offset) << 7) }) +#else +#define __swp_type(x) (((x).val >> 8) & 0x1f) +#define __swp_offset(x) ((x).val >> 13) +#define __swp_entry(type,offset) \ + ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) +#endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ /* * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset @@ -218,7 +225,12 @@ pfn_pte(unsigned long pfn, pgprot_t prot) #endif +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) +#define __pte_to_swp_entry(pte) ((swp_entry_t) { (pte).pte_high }) +#define __swp_entry_to_pte(x) ((pte_t) { 0, (x).val }) +#else #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) +#endif #endif /* _ASM_PGTABLE_32_H */ From fef6d6a73a3985e4fdb5ab1910909c0c73539829 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 27 May 2006 23:36:41 +0400 Subject: [PATCH 44/95] [MIPS] Au1xx0: fix prom_getenv() to handle YAMON style environment Alchemy boards use YAMON which passes the environment variables as the tuples of strings (the name followed by the value) unlike PMON which passes "name=" strings. Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- arch/mips/au1000/common/prom.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c index 9c171afd9a53..ae7d8c57bf3f 100644 --- a/arch/mips/au1000/common/prom.c +++ b/arch/mips/au1000/common/prom.c @@ -1,10 +1,9 @@ /* * * BRIEF MODULE DESCRIPTION - * PROM library initialisation code, assuming a version of - * pmon is the boot code. + * PROM library initialisation code, assuming YAMON is the boot loader. * - * Copyright 2000,2001 MontaVista Software Inc. + * Copyright 2000, 2001, 2006 MontaVista Software Inc. * Author: MontaVista Software, Inc. * ppopov@mvista.com or source@mvista.com * @@ -49,9 +48,9 @@ extern char **prom_argv, **prom_envp; typedef struct { - char *name; -/* char *val; */ -}t_env_var; + char *name; + char *val; +} t_env_var; char * prom_getcmdline(void) @@ -85,21 +84,16 @@ char *prom_getenv(char *envname) { /* * Return a pointer to the given environment variable. - * Environment variables are stored in the form of "memsize=64". */ t_env_var *env = (t_env_var *)prom_envp; - int i; - i = strlen(envname); - - while(env->name) { - if(strncmp(envname, env->name, i) == 0) { - return(env->name + strlen(envname) + 1); - } + while (env->name) { + if (strcmp(envname, env->name) == 0) + return env->val; env++; } - return(NULL); + return NULL; } inline unsigned char str2hexnum(unsigned char c) From 7155262e180d3b50fdea0f58f3329d9ae81ef80b Mon Sep 17 00:00:00 2001 From: Thiemo Seufer Date: Sun, 28 May 2006 15:02:53 +0100 Subject: [PATCH 45/95] [MIPS] open() forces O_LARGEFILE for o32 on 64bit kernels open() always sets the O_LARGEFILE flag for the o32 ABI implementation of a 64bit kernel. The appended patch fixes it. Signed-off-by: Thiemo Seufer Signed-off-by: Ralf Baechle --- arch/mips/kernel/scall64-o32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index b53a9207f530..8efb23a84131 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S @@ -209,7 +209,7 @@ sys_call_table: PTR sys_fork PTR sys_read PTR sys_write - PTR sys_open /* 4005 */ + PTR compat_sys_open /* 4005 */ PTR sys_close PTR sys_waitpid PTR sys_creat From aa32374aaa2e516a9b0719477efae0782a62a79e Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Mon, 29 May 2006 00:02:12 +0100 Subject: [PATCH 46/95] [MIPS] SB1: Only pass1 FPUs are broken beyond recovery. The wrong revision number in the check was forcing a fallback to FPU emulation for all SB1 cores in 2.6. Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-probe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index bef3e2dc7c52..8c2c359a05f4 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c @@ -655,7 +655,7 @@ static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) case PRID_IMP_SB1: c->cputype = CPU_SB1; /* FPU in pass1 is known to have issues. */ - if ((c->processor_id & 0xff) < 0x20) + if ((c->processor_id & 0xff) < 0x02) c->options &= ~(MIPS_CPU_FPU | MIPS_CPU_32FPR); break; case PRID_IMP_SB1A: From 7cb710c9a617384cd0ed30638f3acc00125690fc Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sat, 27 May 2006 22:39:39 +0400 Subject: [PATCH 47/95] [MIPS] Fix non-linear memory mapping on MIPS Fix the non-linear memory mapping done via remap_file_pages() -- it didn't work on any MIPS CPU because the page offset clashing with _PAGE_FILE and some other page protection bits which should have been left zeros for this kind of pages. Signed-off-by: Konstantin Baydarov Signed-off-by: Sergei Shtylyov Signed-off-by: Ralf Baechle --- include/asm-mips/pgtable-32.h | 45 ++++++++++++++++++++--------------- include/asm-mips/pgtable-64.h | 13 ++++------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/include/asm-mips/pgtable-32.h b/include/asm-mips/pgtable-32.h index a5ce3f17a989..087c20769256 100644 --- a/include/asm-mips/pgtable-32.h +++ b/include/asm-mips/pgtable-32.h @@ -177,16 +177,18 @@ pfn_pte(unsigned long pfn, pgprot_t prot) ((swp_entry_t) { ((type) << 10) | ((offset) << 15) }) /* - * Bits 0, 1, 2, 9 and 10 are taken, split up the 27 bits of offset - * into this range: + * Bits 0, 4, 8, and 9 are taken, split up 28 bits of offset into this range: */ -#define PTE_FILE_MAX_BITS 27 +#define PTE_FILE_MAX_BITS 28 -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x3f ) + (((_pte).pte >> 11) << 8 )) +#define pte_to_pgoff(_pte) ((((_pte).pte >> 1 ) & 0x07) | \ + (((_pte).pte >> 2 ) & 0x38) | \ + (((_pte).pte >> 10) << 6 )) -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x3f) << 3) + (((off) >> 8) << 11) + _PAGE_FILE }) +#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x07) << 1 ) | \ + (((off) & 0x38) << 2 ) | \ + (((off) >> 6 ) << 10) | \ + _PAGE_FILE }) #else @@ -203,24 +205,29 @@ pfn_pte(unsigned long pfn, pgprot_t prot) ((swp_entry_t) { ((type) << 8) | ((offset) << 13) }) #endif /* defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) */ +#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) /* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 27 bits of offset - * into this range: + * Bits 0 and 1 of pte_high are taken, use the rest for the page offset... */ -#define PTE_FILE_MAX_BITS 27 +#define PTE_FILE_MAX_BITS 30 -#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32_R1) - /* fixme */ -#define pte_to_pgoff(_pte) (((_pte).pte_high >> 6) + ((_pte).pte_high & 0x3f)) -#define pgoff_to_pte(off) \ - ((pte_t){(((off) & 0x3f) + ((off) << 6) + _PAGE_FILE)}) +#define pte_to_pgoff(_pte) ((_pte).pte_high >> 2) +#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) << 2 }) #else -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) +/* + * Bits 0, 4, 6, and 7 are taken, split up 28 bits of offset into this range: + */ +#define PTE_FILE_MAX_BITS 28 -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) +#define pte_to_pgoff(_pte) ((((_pte).pte >> 1) & 0x7) | \ + (((_pte).pte >> 2) & 0x8) | \ + (((_pte).pte >> 8) << 4)) + +#define pgoff_to_pte(off) ((pte_t) { (((off) & 0x7) << 1) | \ + (((off) & 0x8) << 2) | \ + (((off) >> 4) << 8) | \ + _PAGE_FILE }) #endif #endif diff --git a/include/asm-mips/pgtable-64.h b/include/asm-mips/pgtable-64.h index 82166b254b27..2faf5c9ff127 100644 --- a/include/asm-mips/pgtable-64.h +++ b/include/asm-mips/pgtable-64.h @@ -224,15 +224,12 @@ static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) /* - * Bits 0, 1, 2, 7 and 8 are taken, split up the 32 bits of offset - * into this range: + * Bits 0, 4, 6, and 7 are taken. Let's leave bits 1, 2, 3, and 5 alone to + * make things easier, and only use the upper 56 bits for the page offset... */ -#define PTE_FILE_MAX_BITS 32 +#define PTE_FILE_MAX_BITS 56 -#define pte_to_pgoff(_pte) \ - ((((_pte).pte >> 3) & 0x1f ) + (((_pte).pte >> 9) << 6 )) - -#define pgoff_to_pte(off) \ - ((pte_t) { (((off) & 0x1f) << 3) + (((off) >> 6) << 9) + _PAGE_FILE }) +#define pte_to_pgoff(_pte) ((_pte).pte >> 8) +#define pgoff_to_pte(off) ((pte_t) { ((off) << 8) | _PAGE_FILE }) #endif /* _ASM_PGTABLE_64_H */ From b6d7c7a91138c883f890c204cd5300172145b0b3 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 30 May 2006 02:13:16 +0100 Subject: [PATCH 48/95] [MIPS] IP32: Fix warnings. The expressions are volatile; no need for temporary variables. Signed-off-by: Ralf Baechle --- arch/mips/sgi-ip32/ip32-irq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index de01c9815bdd..8ba08047d164 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c @@ -31,12 +31,12 @@ /* issue a PIO read to make sure no PIO writes are pending */ static void inline flush_crime_bus(void) { - volatile unsigned long junk = crime->control; + crime->control; } static void inline flush_mace_bus(void) { - volatile unsigned long junk = mace->perif.ctrl.misc; + mace->perif.ctrl.misc; } #undef DEBUG_IRQ From e32b699335b70fae94ce041c9a1c6d3a31a3f7e4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Tue, 30 May 2006 15:55:05 +0100 Subject: [PATCH 49/95] [MIPS] Fix 64-bit build for RM7000. RM7000 has 40-bit virtual / 36-bit physical address space. Signed-off-by: Ralf Baechle --- include/asm-mips/addrspace.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-mips/addrspace.h b/include/asm-mips/addrspace.h index 42520cc84b0f..1386af1cb7d9 100644 --- a/include/asm-mips/addrspace.h +++ b/include/asm-mips/addrspace.h @@ -129,6 +129,7 @@ #if defined (CONFIG_CPU_R4300) \ || defined (CONFIG_CPU_R4X00) \ || defined (CONFIG_CPU_R5000) \ + || defined (CONFIG_CPU_RM7000) \ || defined (CONFIG_CPU_NEVADA) \ || defined (CONFIG_CPU_TX49XX) \ || defined (CONFIG_CPU_MIPS64) From 460c0422c3861ab63a14c2be600a96a9e68b89f2 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 1 Jun 2006 01:00:39 +0900 Subject: [PATCH 50/95] [MIPS] Fix sparse warnings about too big constants. Fix following warnings: linux/arch/mips/kernel/setup.c:249:12: warning: constant 0xffffffff00000000 is so big it is unsigned long linux/arch/mips/kernel/cpu-bugs64.c:209:10: warning: constant 0xffffffffffffdb9a is so big it is unsigned long linux/arch/mips/kernel/cpu-bugs64.c:227:10: warning: constant 0xffffffffffffdb9a is so big it is unsigned long linux/arch/mips/kernel/cpu-bugs64.c:283:10: warning: constant 0xffffffffffffdb9a is so big it is unsigned long linux/arch/mips/kernel/cpu-bugs64.c:299:10: warning: constant 0xffffffffffffdb9a is so big it is unsigned long Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/cpu-bugs64.c | 8 ++++---- arch/mips/kernel/setup.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/mips/kernel/cpu-bugs64.c b/arch/mips/kernel/cpu-bugs64.c index 47a087b6c11b..d268827c62bd 100644 --- a/arch/mips/kernel/cpu-bugs64.c +++ b/arch/mips/kernel/cpu-bugs64.c @@ -206,7 +206,7 @@ static inline void check_daddi(void) "daddi %0, %1, %3\n\t" ".set pop" : "=r" (v), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -224,7 +224,7 @@ static inline void check_daddi(void) "dsrl %1, %1, 1\n\t" "daddi %0, %1, %3" : "=r" (v), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); set_except_vector(12, handler); local_irq_restore(flags); @@ -280,7 +280,7 @@ static inline void check_daddiu(void) "daddu %1, %2\n\t" ".set pop" : "=&r" (v), "=&r" (w), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); if (v == w) { printk("no.\n"); @@ -296,7 +296,7 @@ static inline void check_daddiu(void) "addiu %1, $0, %4\n\t" "daddu %1, %2" : "=&r" (v), "=&r" (w), "=&r" (tmp) - : "I" (0xffffffffffffdb9a), "I" (0x1234)); + : "I" (0xffffffffffffdb9aUL), "I" (0x1234)); if (v == w) { printk("yes.\n"); diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index bcf1b10e518f..faeed5f4cf26 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -246,7 +246,7 @@ static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_en #ifdef CONFIG_64BIT /* HACK: Guess if the sign extension was forgotten */ if (start > 0x0000000080000000 && start < 0x00000000ffffffff) - start |= 0xffffffff00000000; + start |= 0xffffffff00000000UL; #endif end = start + size; From ecf52d3c895c8bc069b9ae07c18acf39d846c2ef Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Thu, 1 Jun 2006 01:00:03 +0900 Subject: [PATCH 51/95] [MIPS] Fix compiler warnings (field width, unused variable) Fix following warnings: linux/arch/mips/kernel/setup.c:432: warning: field width is not type int (arg 2) linux/arch/mips/kernel/setup.c:432: warning: field width is not type int (arg 4) linux/arch/mips/kernel/syscall.c:279: warning: unused variable `len' linux/arch/mips/kernel/syscall.c:280: warning: unused variable `name' linux/arch/mips/math-emu/dp_fint.c:32: warning: unused variable `xc' linux/arch/mips/math-emu/dp_flong.c:32: warning: unused variable `xc' linux/arch/mips/math-emu/sp_fint.c:32: warning: unused variable `xc' linux/arch/mips/math-emu/sp_flong.c:32: warning: unused variable `xc' (original patch by Atsushi, slight changes to the setup.c part by me.) Signed-off-by: Atsushi Nemoto Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 13 ++++++++----- arch/mips/kernel/syscall.c | 3 +-- arch/mips/math-emu/dp_fint.c | 4 +++- arch/mips/math-emu/dp_flong.c | 4 +++- arch/mips/math-emu/sp_fint.c | 4 +++- arch/mips/math-emu/sp_flong.c | 4 +++- 6 files changed, 21 insertions(+), 11 deletions(-) diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index faeed5f4cf26..a481be047696 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -419,17 +419,20 @@ static inline void bootmem_init(void) #ifdef CONFIG_BLK_DEV_INITRD initrd_below_start_ok = 1; if (initrd_start) { - unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start); + unsigned long initrd_size = ((unsigned char *)initrd_end) - + ((unsigned char *)initrd_start); + const int width = sizeof(long) * 2; + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", (void *)initrd_start, initrd_size); if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) { printk("initrd extends beyond end of memory " "(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n", - sizeof(long) * 2, - (unsigned long long)CPHYSADDR(initrd_end), - sizeof(long) * 2, - (unsigned long long)PFN_PHYS(max_low_pfn)); + width, + (unsigned long long) CPHYSADDR(initrd_end), + width, + (unsigned long long) PFN_PHYS(max_low_pfn)); initrd_start = initrd_end = 0; initrd_reserve_bootmem = 0; } diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 8f4fdd94dbd0..5e8a18a8e2bd 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -276,8 +276,7 @@ void sys_set_thread_area(unsigned long addr) asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) { - int tmp, len; - char __user *name; + int tmp; switch(cmd) { case MIPS_ATOMIC_SET: diff --git a/arch/mips/math-emu/dp_fint.c b/arch/mips/math-emu/dp_fint.c index a1962eb460f8..39a71de16f47 100644 --- a/arch/mips/math-emu/dp_fint.c +++ b/arch/mips/math-emu/dp_fint.c @@ -29,7 +29,9 @@ ieee754dp ieee754dp_fint(int x) { - COMPXDP; + u64 xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/dp_flong.c b/arch/mips/math-emu/dp_flong.c index eae90a866aa1..f08f223e488a 100644 --- a/arch/mips/math-emu/dp_flong.c +++ b/arch/mips/math-emu/dp_flong.c @@ -29,7 +29,9 @@ ieee754dp ieee754dp_flong(s64 x) { - COMPXDP; + u64 xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/sp_fint.c b/arch/mips/math-emu/sp_fint.c index 7aac13afb09a..e88e125e01c2 100644 --- a/arch/mips/math-emu/sp_fint.c +++ b/arch/mips/math-emu/sp_fint.c @@ -29,7 +29,9 @@ ieee754sp ieee754sp_fint(int x) { - COMPXSP; + unsigned xm; + int xe; + int xs; CLEARCX; diff --git a/arch/mips/math-emu/sp_flong.c b/arch/mips/math-emu/sp_flong.c index 3d6c1d11c178..26d6919a269a 100644 --- a/arch/mips/math-emu/sp_flong.c +++ b/arch/mips/math-emu/sp_flong.c @@ -29,7 +29,9 @@ ieee754sp ieee754sp_flong(s64 x) { - COMPXDP; /* <--- need 64-bit mantissa temp */ + u64 xm; /* <--- need 64-bit mantissa temp */ + int xe; + int xs; CLEARCX; From b1c231f5a57cb4a417c38a8a946f1e66db3bb9c0 Mon Sep 17 00:00:00 2001 From: Chad Reese Date: Tue, 30 May 2006 17:16:49 -0700 Subject: [PATCH 52/95] [MIPS] Fix sparsemem support. Move memory_present() in arch/mips/kernel/setup.c. When using sparsemem extreme, this function does an allocate for bootmem. This would always fail since init_bootmem hasn't been called yet. Move memory_present after free_bootmem. This only marks actual memory ranges as present instead of the entire address space. Signed-off-by: Chad Reese Signed-off-by: Ralf Baechle --- arch/mips/kernel/setup.c | 3 +-- arch/mips/mm/init.c | 2 +- include/asm-mips/page.h | 2 ++ include/asm-mips/sparsemem.h | 14 ++++++++++++++ 4 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 include/asm-mips/sparsemem.h diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a481be047696..397a70e651b5 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -355,8 +355,6 @@ static inline void bootmem_init(void) } #endif - memory_present(0, first_usable_pfn, max_low_pfn); - /* Initialize the boot-time allocator with low memory only. */ bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn); @@ -410,6 +408,7 @@ static inline void bootmem_init(void) /* Register lowmem ranges */ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); + memory_present(0, curr_pfn, curr_pfn + size - 1); } /* Reserve the bootmap memory. */ diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index c22308b93ff0..33f6e1cdfd5b 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -227,7 +227,7 @@ void __init mem_init(void) for (tmp = 0; tmp < max_low_pfn; tmp++) if (page_is_ram(tmp)) { ram++; - if (PageReserved(mem_map+tmp)) + if (PageReserved(pfn_to_page(tmp))) reservedpages++; } diff --git a/include/asm-mips/page.h b/include/asm-mips/page.h index a1eab136ff6c..4035ec79ecd4 100644 --- a/include/asm-mips/page.h +++ b/include/asm-mips/page.h @@ -139,9 +139,11 @@ typedef struct { unsigned long pgprot; } pgprot_t; #define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) +#ifndef CONFIG_SPARSEMEM #ifndef CONFIG_NEED_MULTIPLE_NODES #define pfn_valid(pfn) ((pfn) < max_mapnr) #endif +#endif #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) diff --git a/include/asm-mips/sparsemem.h b/include/asm-mips/sparsemem.h new file mode 100644 index 000000000000..795ac6c23203 --- /dev/null +++ b/include/asm-mips/sparsemem.h @@ -0,0 +1,14 @@ +#ifndef _MIPS_SPARSEMEM_H +#define _MIPS_SPARSEMEM_H +#ifdef CONFIG_SPARSEMEM + +/* + * SECTION_SIZE_BITS 2^N: how big each section will be + * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space + */ +#define SECTION_SIZE_BITS 28 +#define MAX_PHYSMEM_BITS 35 + +#endif /* CONFIG_SPARSEMEM */ +#endif /* _MIPS_SPARSEMEM_H */ + From 36485707bbd9729e0c52315b173aeed9bc2303dd Mon Sep 17 00:00:00 2001 From: Jiri Benc Date: Mon, 5 Jun 2006 16:39:34 -0700 Subject: [PATCH 53/95] [BRIDGE]: fix locking and memory leak in br_add_bridge There are several bugs in error handling in br_add_bridge: - when dev_alloc_name fails, allocated net_device is not freed - unregister_netdev is called when rtnl lock is held - free_netdev is called before netdev_run_todo has a chance to be run after unregistering net_device Signed-off-by: Jiri Benc Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- net/bridge/br_if.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index ad1c7af65ec8..f5d47bf4f967 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -300,25 +300,20 @@ int br_add_bridge(const char *name) rtnl_lock(); if (strchr(dev->name, '%')) { ret = dev_alloc_name(dev, dev->name); - if (ret < 0) - goto err1; + if (ret < 0) { + free_netdev(dev); + goto out; + } } ret = register_netdevice(dev); if (ret) - goto err2; + goto out; ret = br_sysfs_addbr(dev); if (ret) - goto err3; - rtnl_unlock(); - return 0; - - err3: - unregister_netdev(dev); - err2: - free_netdev(dev); - err1: + unregister_netdevice(dev); + out: rtnl_unlock(); return ret; } From 1def630a6a49dda5bc89dfbd86656293640456f0 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 5 Jun 2006 17:57:02 -0700 Subject: [PATCH 54/95] Linux 2.6.17-rc6 --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 435d209f42d8..a3a7baad8555 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 17 -EXTRAVERSION =-rc5 -NAME=Lordi Rules +EXTRAVERSION =-rc6 +NAME=Crazed Snow-Weasel # *DOCUMENTATION* # To see a list of typical targets execute "make help" From b9b6e78b11de295ef073271979355d5fab71b877 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 8 Jun 2006 09:28:38 -0700 Subject: [PATCH 55/95] e1000: fix ethtool test irq alloc as "probe" New code added in 2.6.17 caused setup_irq to print a warning when running ethtool -t eth0 offline. This test marks the request_irq call made by this test as a "probe" to see if the interrupt is shared or not. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_ethtool.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index ecccca35c6f4..d1c705b412c2 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c @@ -870,13 +870,16 @@ e1000_intr_test(struct e1000_adapter *adapter, uint64_t *data) *data = 0; /* Hook up test interrupt handler just for this test */ - if (!request_irq(irq, &e1000_test_intr, 0, netdev->name, netdev)) { + if (!request_irq(irq, &e1000_test_intr, SA_PROBEIRQ, netdev->name, + netdev)) { shared_int = FALSE; } else if (request_irq(irq, &e1000_test_intr, SA_SHIRQ, netdev->name, netdev)){ *data = 1; return -1; } + DPRINTK(PROBE,INFO, "testing %s interrupt\n", + (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ E1000_WRITE_REG(&adapter->hw, IMC, 0xFFFFFFFF); From 24f476eeecba66524af3f95e31ac208eea99e617 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 8 Jun 2006 09:28:47 -0700 Subject: [PATCH 56/95] e1000: remove risky prefetch on next_skb->data It was brought to our attention that the prefetches break e1000 traffic on xscale/arm architectures. Remove them for now. We'll let them stay in mm for a while, or find a better solution to enable. Signed-off-by: Jesse Brandeburg Signed-off-by: Auke Kok --- drivers/net/e1000/e1000_main.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ed15fcaedaf9..97e71a4fe8eb 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -3519,7 +3519,7 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, buffer_info = &rx_ring->buffer_info[i]; while (rx_desc->status & E1000_RXD_STAT_DD) { - struct sk_buff *skb, *next_skb; + struct sk_buff *skb; u8 status; #ifdef CONFIG_E1000_NAPI if (*work_done >= work_to_do) @@ -3537,8 +3537,6 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; - next_skb = next_buffer->skb; - prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; @@ -3668,7 +3666,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *skb, *next_skb; + struct sk_buff *skb; unsigned int i, j; uint32_t length, staterr; int cleaned_count = 0; @@ -3697,8 +3695,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, prefetch(next_rxd); next_buffer = &rx_ring->buffer_info[i]; - next_skb = next_buffer->skb; - prefetch(next_skb->data - NET_IP_ALIGN); cleaned = TRUE; cleaned_count++; From d782f33df706f1b8a4496b41fd7d339c6e23aa59 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 8 Jun 2006 17:59:31 +0100 Subject: [PATCH 57/95] [ARM] Fix Neponset IRQ handling While testing the genirq code on ARM, a condition was found whereby the Neponset IRQ handler was being re-entered, causing the system to deadlock. Under the ARM IRQ code, this would not have been a visible problem because the "simple" IRQ handling had no re-entrancy protection. Resolve this by acknowledging the parent interrupt after we mask it when we are going to handle one of our "special" level-based sources (from ethernet or USAR chip.) Signed-off-by: Russell King --- arch/arm/mach-sa1100/neponset.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c index 9e02bc3712a0..af6d2775cf82 100644 --- a/arch/arm/mach-sa1100/neponset.c +++ b/arch/arm/mach-sa1100/neponset.c @@ -59,6 +59,14 @@ neponset_irq_handler(unsigned int irq, struct irqdesc *desc, struct pt_regs *reg if (irr & (IRR_ETHERNET | IRR_USAR)) { desc->chip->mask(irq); + /* + * Ack the interrupt now to prevent re-entering + * this neponset handler. Again, this is safe + * since we'll check the IRR register prior to + * leaving. + */ + desc->chip->ack(irq); + if (irr & IRR_ETHERNET) { d = irq_desc + IRQ_NEPONSET_SMC9196; desc_handle_irq(IRQ_NEPONSET_SMC9196, d, regs); From 0c27c5d5b93339df4def7ced77ea5be26df4d84b Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 8 Jun 2006 22:44:07 +0100 Subject: [PATCH 58/95] [ARM] 3547/1: PXA-OHCI: Allow platforms to specify a power budget Patch from Richard Purdie Add a power budget variable to the PXA OHCI platform data and add a default value for the spitz platform(s) which prevents known failures with certain USB devices. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/mach-pxa/spitz.c | 1 + drivers/usb/host/ohci-pxa27x.c | 3 +++ include/asm-arm/arch-pxa/ohci.h | 2 ++ 3 files changed, 6 insertions(+) diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index 19b372df544a..44bcb8097c7a 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -371,6 +371,7 @@ static int spitz_ohci_init(struct device *dev) static struct pxaohci_platform_data spitz_ohci_platform_data = { .port_mode = PMM_NPS_MODE, .init = spitz_ohci_init, + .power_budget = 150, }; diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index acde8868da21..fafe7c1265b3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c @@ -185,6 +185,9 @@ int usb_hcd_pxa27x_probe (const struct hc_driver *driver, struct platform_device /* Select Power Management Mode */ pxa27x_ohci_select_pmm(inf->port_mode); + if (inf->power_budget) + hcd->power_budget = inf->power_budget; + ohci_hcd_init(hcd_to_ohci(hcd)); retval = usb_add_hcd(hcd, pdev->resource[1].start, SA_INTERRUPT); diff --git a/include/asm-arm/arch-pxa/ohci.h b/include/asm-arm/arch-pxa/ohci.h index 7da89569061e..e848a47128cd 100644 --- a/include/asm-arm/arch-pxa/ohci.h +++ b/include/asm-arm/arch-pxa/ohci.h @@ -11,6 +11,8 @@ struct pxaohci_platform_data { #define PMM_NPS_MODE 1 #define PMM_GLOBAL_MODE 2 #define PMM_PERPORT_MODE 3 + + int power_budget; }; extern void pxa_set_ohci_info(struct pxaohci_platform_data *info); From e2f04e18941dbd3826901540a0be03f1728f8822 Mon Sep 17 00:00:00 2001 From: Matt Reimer Date: Thu, 8 Jun 2006 22:46:48 +0100 Subject: [PATCH 59/95] [ARM] 3546/1: PATCH: subtle lost interrupts bug on i.MX Patch from Matt Reimer There is a subtle bug in the GPIO interrupt status register handling in arch/arm/mach-imx/irq.c:imx_gpio_ack_irq(). The documentation states that a 1 should be written to the relevant bit to acknowledge a GPIO interrupt, but that is not what the code does. The problem is that the |= writes back 1s for all the *other* interrupts represented in the register, so interrupts could get lost. For example, if interrupts are pending for GPIO B10 and B12, ISR_B would have the value 0x00001400. Then when the interrupt code handles GPIO B10, it eventually calls imx_gpio_ack_irq(IRQ_GPIOB(10)), which effectively does this: ISR_B |= 1 << 10; with the result that (0x00001400 | 0x00000400) is written, clearing the interrupt status bits for *both* GPIO B10 and B12. The fix is to write 1s only for the interrupts we want to clear. The same problem seems to be occurring in the DMA code; this patch does not address those issues. Acked-by: Sascha Hauer Signed-off-by: Matt Reimer Signed-off-by: Russell King --- arch/arm/mach-imx/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-imx/irq.c b/arch/arm/mach-imx/irq.c index eeb8a6d4a399..a5de5f1da9f2 100644 --- a/arch/arm/mach-imx/irq.c +++ b/arch/arm/mach-imx/irq.c @@ -127,7 +127,7 @@ static void imx_gpio_ack_irq(unsigned int irq) { DEBUG_IRQ("%s: irq %d\n", __FUNCTION__, irq); - ISR(IRQ_TO_REG(irq)) |= 1 << ((irq - IRQ_GPIOA(0)) % 32); + ISR(IRQ_TO_REG(irq)) = 1 << ((irq - IRQ_GPIOA(0)) % 32); } static void From d44647b0a6e48d18a1402dfa9052d85c4fe98341 Mon Sep 17 00:00:00 2001 From: Andy Currid Date: Thu, 8 Jun 2006 00:43:38 -0700 Subject: [PATCH 60/95] [PATCH] Fix HPET operation on 32-bit NVIDIA platforms From: "Andy Currid" This patch fixes a kernel panic during boot that occurs on NVIDIA platforms that have HPET enabled. When HPET is enabled, the standard timer IRQ is routed to IOAPIC pin 2 and is advertised as such in the ACPI APIC table - but an earlier workaround in the kernel was ignoring this override. The fix is to honor timer IRQ overrides from ACPI when HPET is detected on an NVIDIA platform. Signed-off-by: Andy Currid Cc: "Brown, Len" Cc: "Yu, Luming" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/acpi/earlyquirk.c | 23 ++++++++++++++++++++--- arch/i386/kernel/setup.c | 11 +++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index 2e3b643a4dc4..1649a175a206 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -5,17 +5,34 @@ #include #include #include +#include + #include #include #include +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + static int __init check_bridge(int vendor, int device) { #ifdef CONFIG_ACPI - /* According to Nvidia all timer overrides are bogus. Just ignore - them all. */ + /* According to Nvidia all timer overrides are bogus unless HPET + is enabled. */ if (vendor == PCI_VENDOR_ID_NVIDIA) { - acpi_skip_timer_override = 1; + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + } } #endif if (vendor == PCI_VENDOR_ID_ATI && timer_over_8254 == 1) { diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index 846e1639ef7c..dd6b0e3386ce 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c @@ -1547,15 +1547,18 @@ void __init setup_arch(char **cmdline_p) if (efi_enabled) efi_map_memmap(); -#ifdef CONFIG_X86_IO_APIC - check_acpi_pci(); /* Checks more than just ACPI actually */ -#endif - #ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. */ acpi_boot_table_init(); +#endif + +#ifdef CONFIG_X86_IO_APIC + check_acpi_pci(); /* Checks more than just ACPI actually */ +#endif + +#ifdef CONFIG_ACPI acpi_boot_init(); #if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) From a2ef3a50f19f64d350bdc0aa15c31ae4b8973f57 Mon Sep 17 00:00:00 2001 From: Andy Currid Date: Thu, 8 Jun 2006 00:43:39 -0700 Subject: [PATCH 61/95] [PATCH] Fix HPET operation on 64-bit NVIDIA platforms From: "Andy Currid" This patch fixes a kernel panic during boot that occurs on NVIDIA platforms that have HPET enabled. When HPET is enabled, the standard timer IRQ is routed to IOAPIC pin 2 and is advertised as such in the ACPI APIC table - but an earlier workaround in the kernel was ignoring this override. The fix is to honor timer IRQ overrides from ACPI when HPET is detected on an NVIDIA platform. Signed-off-by: Andy Currid Cc: "Brown, Len" Cc: "Yu, Luming" Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/io_apic.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 0de3ea938830..9cc7031b7151 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -271,6 +271,18 @@ __setup("enable_8254_timer", setup_enable_8254_timer); #include #include + +#ifdef CONFIG_ACPI + +static int nvidia_hpet_detected __initdata; + +static int __init nvidia_hpet_check(unsigned long phys, unsigned long size) +{ + nvidia_hpet_detected = 1; + return 0; +} +#endif + /* Temporary Hack. Nvidia and VIA boards currently only work with IO-APIC off. Check for an Nvidia or VIA PCI bridge and turn it off. Use pci direct infrastructure because this runs before the PCI subsystem. @@ -317,11 +329,19 @@ void __init check_ioapic(void) return; case PCI_VENDOR_ID_NVIDIA: #ifdef CONFIG_ACPI - /* All timer overrides on Nvidia - seem to be wrong. Skip them. */ - acpi_skip_timer_override = 1; - printk(KERN_INFO - "Nvidia board detected. Ignoring ACPI timer override.\n"); + /* + * All timer overrides on Nvidia are + * wrong unless HPET is enabled. + */ + nvidia_hpet_detected = 0; + acpi_table_parse(ACPI_HPET, + nvidia_hpet_check); + if (nvidia_hpet_detected == 0) { + acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + } #endif /* RED-PEN skip them on mptables too? */ return; From fd0a0ac1c5393b226640a30bae753983068136b3 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Thu, 8 Jun 2006 00:43:40 -0700 Subject: [PATCH 62/95] [PATCH] ep93xx build fix From: Lennert Buytenhek The recent renaming of m48t86's ->readb() and ->writeb() platform driver methods (2d7b20c1884777e66009be1a533641c19c4705f6) to ->readbyte() and ->writebyte() to fix the ia64 build broke the build of the cirrus ep93xx ARM platform. This patch fixes it up. Signed-off-by: Lennert Buytenhek Cc: Alessandro Zummo Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mach-ep93xx/ts72xx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 9be01b0c3f48..e24566b88a78 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c @@ -111,21 +111,21 @@ static void __init ts72xx_map_io(void) } } -static unsigned char ts72xx_rtc_readb(unsigned long addr) +static unsigned char ts72xx_rtc_readbyte(unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); } -static void ts72xx_rtc_writeb(unsigned char value, unsigned long addr) +static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) { __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); } static struct m48t86_ops ts72xx_rtc_ops = { - .readb = ts72xx_rtc_readb, - .writeb = ts72xx_rtc_writeb, + .readbyte = ts72xx_rtc_readbyte, + .writebyte = ts72xx_rtc_writebyte, }; static struct platform_device ts72xx_rtc_device = { From 45b35a5ced474b9fbbbfcfd5cf346c432d28d9fd Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Thu, 8 Jun 2006 00:43:41 -0700 Subject: [PATCH 63/95] [PATCH] Fix mempolicy.h build error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Ralf Baechle uses struct mm_struct and relies on a definition or declaration somehow magically being dragged in which may result in a build: [...] CC mm/mempolicy.o In file included from mm/mempolicy.c:69: include/linux/mempolicy.h:150: warning: ‘struct mm_struct’ declared inside parameter list include/linux/mempolicy.h:150: warning: its scope is only this definition or declaration, which is probably not what you want include/linux/mempolicy.h:175: warning: ‘struct mm_struct’ declared inside parameter list mm/mempolicy.c:622: error: conflicting types for ‘do_migrate_pages’ include/linux/mempolicy.h:175: error: previous declaration of ‘do_migrate_pages’ was here mm/mempolicy.c:1661: error: conflicting types for ‘mpol_rebind_mm’ include/linux/mempolicy.h:150: error: previous declaration of ‘mpol_rebind_mm’ was here make[1]: *** [mm/mempolicy.o] Error 1 make: *** [mm] Error 2 [ralf@denk linux-ip35]$ Including is a step into direction of include hell so fixed by adding a forward declaration of struct mm_struct instead. Signed-off-by: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mempolicy.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h index 6a7621b2b12b..f5fdca1d67e6 100644 --- a/include/linux/mempolicy.h +++ b/include/linux/mempolicy.h @@ -36,6 +36,7 @@ #include struct vm_area_struct; +struct mm_struct; #ifdef CONFIG_NUMA From 26e780e8ef1cc3ef581a07aafe2346bb5a07b4f9 Mon Sep 17 00:00:00 2001 From: Malcom Parsons Date: Thu, 8 Jun 2006 00:43:42 -0700 Subject: [PATCH 64/95] [PATCH] fbcon: fix limited scroll in SCROLL_PAN_REDRAW mode From: Malcom Parsons When scrolling up in SCROLL_PAN_REDRAW mode with a large limited scroll region, the bottom few lines have to be redrawn. Without this patch, the wrong text is drawn into these lines, corrupting the display. Observed in 2.6.14 when running an IRC client in the Nintendo DS linux port. I haven't tested if scrolling down has the same problem. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/fbcon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 953eb8c171d6..47ba1a79adcd 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -1745,7 +1745,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, fbcon_redraw_move(vc, p, 0, t, count); ypan_up_redraw(vc, t, count); if (vc->vc_rows - b > 0) - fbcon_redraw_move(vc, p, b - count, + fbcon_redraw_move(vc, p, b, vc->vc_rows - b, b); } else fbcon_redraw_move(vc, p, t + count, b - t - count, t); From bc1c116974a5c3f498112a6f175d3e4a8cd5bdbc Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 8 Jun 2006 08:49:06 +0200 Subject: [PATCH 65/95] [PATCH] elevator switching race There's a race between shutting down one io scheduler and firing up the next, in which a new io could enter and cause the io scheduler to be invoked with bad or NULL data. To fix this, we need to maintain the queue lock for a bit longer. Unfortunately we cannot do that, since the elevator init requires to be run without the lock held. This isn't easily fixable, without also changing the mempool API. So split the initialization into two parts, and alloc-init operation and an attach operation. Then we can preallocate the io scheduler and related structures, and run the attach inside the lock after we detach the old one. This patch has survived 30 minutes of 1 second io scheduler switching with a very busy io load. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- block/as-iosched.c | 13 +++++----- block/cfq-iosched.c | 10 +++----- block/deadline-iosched.c | 13 +++++----- block/elevator.c | 55 +++++++++++++++++++++++++--------------- block/noop-iosched.c | 7 +++-- include/linux/elevator.h | 2 +- 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/block/as-iosched.c b/block/as-iosched.c index e25a5d79ab27..a7caf35ca0c2 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c @@ -1648,17 +1648,17 @@ static void as_exit_queue(elevator_t *e) * initialize elevator private data (as_data), and alloc a arq for * each request on the free lists */ -static int as_init_queue(request_queue_t *q, elevator_t *e) +static void *as_init_queue(request_queue_t *q, elevator_t *e) { struct as_data *ad; int i; if (!arq_pool) - return -ENOMEM; + return NULL; ad = kmalloc_node(sizeof(*ad), GFP_KERNEL, q->node); if (!ad) - return -ENOMEM; + return NULL; memset(ad, 0, sizeof(*ad)); ad->q = q; /* Identify what queue the data belongs to */ @@ -1667,7 +1667,7 @@ static int as_init_queue(request_queue_t *q, elevator_t *e) GFP_KERNEL, q->node); if (!ad->hash) { kfree(ad); - return -ENOMEM; + return NULL; } ad->arq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, @@ -1675,7 +1675,7 @@ static int as_init_queue(request_queue_t *q, elevator_t *e) if (!ad->arq_pool) { kfree(ad->hash); kfree(ad); - return -ENOMEM; + return NULL; } /* anticipatory scheduling helpers */ @@ -1696,14 +1696,13 @@ static int as_init_queue(request_queue_t *q, elevator_t *e) ad->antic_expire = default_antic_expire; ad->batch_expire[REQ_SYNC] = default_read_batch_expire; ad->batch_expire[REQ_ASYNC] = default_write_batch_expire; - e->elevator_data = ad; ad->current_batch_expires = jiffies + ad->batch_expire[REQ_SYNC]; ad->write_batch_count = ad->batch_expire[REQ_ASYNC] / 10; if (ad->write_batch_count < 2) ad->write_batch_count = 2; - return 0; + return ad; } /* diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 8e9d84825e1c..a46d030e092a 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2251,14 +2251,14 @@ static void cfq_exit_queue(elevator_t *e) kfree(cfqd); } -static int cfq_init_queue(request_queue_t *q, elevator_t *e) +static void *cfq_init_queue(request_queue_t *q, elevator_t *e) { struct cfq_data *cfqd; int i; cfqd = kmalloc(sizeof(*cfqd), GFP_KERNEL); if (!cfqd) - return -ENOMEM; + return NULL; memset(cfqd, 0, sizeof(*cfqd)); @@ -2288,8 +2288,6 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e) for (i = 0; i < CFQ_QHASH_ENTRIES; i++) INIT_HLIST_HEAD(&cfqd->cfq_hash[i]); - e->elevator_data = cfqd; - cfqd->queue = q; cfqd->max_queued = q->nr_requests / 4; @@ -2316,14 +2314,14 @@ static int cfq_init_queue(request_queue_t *q, elevator_t *e) cfqd->cfq_slice_async_rq = cfq_slice_async_rq; cfqd->cfq_slice_idle = cfq_slice_idle; - return 0; + return cfqd; out_crqpool: kfree(cfqd->cfq_hash); out_cfqhash: kfree(cfqd->crq_hash); out_crqhash: kfree(cfqd); - return -ENOMEM; + return NULL; } static void cfq_slab_kill(void) diff --git a/block/deadline-iosched.c b/block/deadline-iosched.c index 399fa1e60e1f..3bd0415a9828 100644 --- a/block/deadline-iosched.c +++ b/block/deadline-iosched.c @@ -613,24 +613,24 @@ static void deadline_exit_queue(elevator_t *e) * initialize elevator private data (deadline_data), and alloc a drq for * each request on the free lists */ -static int deadline_init_queue(request_queue_t *q, elevator_t *e) +static void *deadline_init_queue(request_queue_t *q, elevator_t *e) { struct deadline_data *dd; int i; if (!drq_pool) - return -ENOMEM; + return NULL; dd = kmalloc_node(sizeof(*dd), GFP_KERNEL, q->node); if (!dd) - return -ENOMEM; + return NULL; memset(dd, 0, sizeof(*dd)); dd->hash = kmalloc_node(sizeof(struct list_head)*DL_HASH_ENTRIES, GFP_KERNEL, q->node); if (!dd->hash) { kfree(dd); - return -ENOMEM; + return NULL; } dd->drq_pool = mempool_create_node(BLKDEV_MIN_RQ, mempool_alloc_slab, @@ -638,7 +638,7 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e) if (!dd->drq_pool) { kfree(dd->hash); kfree(dd); - return -ENOMEM; + return NULL; } for (i = 0; i < DL_HASH_ENTRIES; i++) @@ -653,8 +653,7 @@ static int deadline_init_queue(request_queue_t *q, elevator_t *e) dd->writes_starved = writes_starved; dd->front_merges = 1; dd->fifo_batch = fifo_batch; - e->elevator_data = dd; - return 0; + return dd; } static void deadline_put_request(request_queue_t *q, struct request *rq) diff --git a/block/elevator.c b/block/elevator.c index 8768a367fdde..a0afdd317cef 100644 --- a/block/elevator.c +++ b/block/elevator.c @@ -121,16 +121,16 @@ static struct elevator_type *elevator_get(const char *name) return e; } -static int elevator_attach(request_queue_t *q, struct elevator_queue *eq) +static void *elevator_init_queue(request_queue_t *q, struct elevator_queue *eq) { - int ret = 0; + return eq->ops->elevator_init_fn(q, eq); +} +static void elevator_attach(request_queue_t *q, struct elevator_queue *eq, + void *data) +{ q->elevator = eq; - - if (eq->ops->elevator_init_fn) - ret = eq->ops->elevator_init_fn(q, eq); - - return ret; + eq->elevator_data = data; } static char chosen_elevator[16]; @@ -181,6 +181,7 @@ int elevator_init(request_queue_t *q, char *name) struct elevator_type *e = NULL; struct elevator_queue *eq; int ret = 0; + void *data; INIT_LIST_HEAD(&q->queue_head); q->last_merge = NULL; @@ -202,10 +203,13 @@ int elevator_init(request_queue_t *q, char *name) if (!eq) return -ENOMEM; - ret = elevator_attach(q, eq); - if (ret) + data = elevator_init_queue(q, eq); + if (!data) { kobject_put(&eq->kobj); + return -ENOMEM; + } + elevator_attach(q, eq, data); return ret; } @@ -722,13 +726,16 @@ int elv_register_queue(struct request_queue *q) return error; } +static void __elv_unregister_queue(elevator_t *e) +{ + kobject_uevent(&e->kobj, KOBJ_REMOVE); + kobject_del(&e->kobj); +} + void elv_unregister_queue(struct request_queue *q) { - if (q) { - elevator_t *e = q->elevator; - kobject_uevent(&e->kobj, KOBJ_REMOVE); - kobject_del(&e->kobj); - } + if (q) + __elv_unregister_queue(q->elevator); } int elv_register(struct elevator_type *e) @@ -780,6 +787,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) { elevator_t *old_elevator, *e; + void *data; /* * Allocate new elevator @@ -788,6 +796,12 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) if (!e) return 0; + data = elevator_init_queue(q, e); + if (!data) { + kobject_put(&e->kobj); + return 0; + } + /* * Turn on BYPASS and drain all requests w/ elevator private data */ @@ -806,19 +820,19 @@ static int elevator_switch(request_queue_t *q, struct elevator_type *new_e) elv_drain_elevator(q); } - spin_unlock_irq(q->queue_lock); - /* - * unregister old elevator data + * Remember old elevator. */ - elv_unregister_queue(q); old_elevator = q->elevator; /* * attach and start new elevator */ - if (elevator_attach(q, e)) - goto fail; + elevator_attach(q, e, data); + + spin_unlock_irq(q->queue_lock); + + __elv_unregister_queue(old_elevator); if (elv_register_queue(q)) goto fail_register; @@ -837,7 +851,6 @@ fail_register: */ elevator_exit(e); e = NULL; -fail: q->elevator = old_elevator; elv_register_queue(q); clear_bit(QUEUE_FLAG_ELVSWITCH, &q->queue_flags); diff --git a/block/noop-iosched.c b/block/noop-iosched.c index f370e4a7fe6d..56a7c620574f 100644 --- a/block/noop-iosched.c +++ b/block/noop-iosched.c @@ -65,16 +65,15 @@ noop_latter_request(request_queue_t *q, struct request *rq) return list_entry(rq->queuelist.next, struct request, queuelist); } -static int noop_init_queue(request_queue_t *q, elevator_t *e) +static void *noop_init_queue(request_queue_t *q, elevator_t *e) { struct noop_data *nd; nd = kmalloc(sizeof(*nd), GFP_KERNEL); if (!nd) - return -ENOMEM; + return NULL; INIT_LIST_HEAD(&nd->queue); - e->elevator_data = nd; - return 0; + return nd; } static void noop_exit_queue(elevator_t *e) diff --git a/include/linux/elevator.h b/include/linux/elevator.h index ad133fcfb239..1713ace808bf 100644 --- a/include/linux/elevator.h +++ b/include/linux/elevator.h @@ -21,7 +21,7 @@ typedef void (elevator_put_req_fn) (request_queue_t *, struct request *); typedef void (elevator_activate_req_fn) (request_queue_t *, struct request *); typedef void (elevator_deactivate_req_fn) (request_queue_t *, struct request *); -typedef int (elevator_init_fn) (request_queue_t *, elevator_t *); +typedef void *(elevator_init_fn) (request_queue_t *, elevator_t *); typedef void (elevator_exit_fn) (elevator_t *); struct elevator_ops From 71601e2b33dad9acb8d7844f7321f90ed9d1bce8 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 8 Jun 2006 10:26:39 +0200 Subject: [PATCH 66/95] [PATCH] debugfs inode leak Looking at the reiser4 crash, I found a leak in debugfs. In debugfs_mknod(), we create the inode before checking if the dentry already has one attached. We don't free it if that is the case. These bugs happen quite often, I'm starting to think we should disallow such coding in CodingStyle. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- fs/debugfs/inode.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 85d166cdcae4..b55b4ea9a676 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -67,12 +67,13 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d static int debugfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { - struct inode *inode = debugfs_get_inode(dir->i_sb, mode, dev); + struct inode *inode; int error = -EPERM; if (dentry->d_inode) return -EEXIST; + inode = debugfs_get_inode(dir->i_sb, mode, dev); if (inode) { d_instantiate(dentry, inode); dget(dentry); From bafe00cc9297ca77b66e5c83e5e65e17c0c997c8 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Thu, 8 Jun 2006 01:36:20 -0700 Subject: [PATCH 67/95] [PATCH] s390: fix in-user atomic futex operation. From: Martin Schwidefsky __futex_atomic_op needs to do an atomic operation in the user address space, not the kernel address space. Add the missing sacf 256/sacf 0 to switch to the secondary mode before doing the compare-and-swap. In addition add another fixup for catch specification exceptions if the compare-and-swap address is not aligned. Signed-off-by: Martin Schwidefsky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-s390/futex.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/asm-s390/futex.h b/include/asm-s390/futex.h index 40c25e166a9b..1802775568b9 100644 --- a/include/asm-s390/futex.h +++ b/include/asm-s390/futex.h @@ -11,23 +11,24 @@ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 4\n" \ - " .long 0b,2b,1b,2b\n" \ + " .long 0b,4b,2b,4b,3b,4b\n" \ ".previous" #else /* __s390x__ */ #define __futex_atomic_fixup \ ".section __ex_table,\"a\"\n" \ " .align 8\n" \ - " .quad 0b,2b,1b,2b\n" \ + " .quad 0b,4b,2b,4b,3b,4b\n" \ ".previous" #endif /* __s390x__ */ #define __futex_atomic_op(insn, ret, oldval, newval, uaddr, oparg) \ - asm volatile(" l %1,0(%6)\n" \ - "0: " insn \ - " cs %1,%2,0(%6)\n" \ - "1: jl 0b\n" \ + asm volatile(" sacf 256\n" \ + "0: l %1,0(%6)\n" \ + "1: " insn \ + "2: cs %1,%2,0(%6)\n" \ + "3: jl 1b\n" \ " lhi %0,0\n" \ - "2:\n" \ + "4: sacf 0\n" \ __futex_atomic_fixup \ : "=d" (ret), "=&d" (oldval), "=&d" (newval), \ "=m" (*uaddr) \ From 7c85d1f9d358b24c5b05c3a2783a78423775a080 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 9 Jun 2006 13:02:59 +1000 Subject: [PATCH 68/95] powerpc: Fix machine check problem on 32-bit kernels This fixes a bug found by Dave Jones that means that it is possible for userspace to provoke a machine check on 32-bit kernels. This also fixes a couple of other places where I found similar problems by inspection. Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/signal_32.c | 11 ++++++++++- arch/powerpc/kernel/signal_64.c | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 01e3c08cb550..8fdeca2d4597 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -803,10 +803,13 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int if (__get_user(cmcp, &ucp->uc_regs)) return -EFAULT; mcp = (struct mcontext __user *)(u64)cmcp; + /* no need to check access_ok(mcp), since mcp < 4GB */ } #else if (__get_user(mcp, &ucp->uc_regs)) return -EFAULT; + if (!access_ok(VERIFY_READ, mcp, sizeof(*mcp))) + return -EFAULT; #endif restore_sigmask(&set); if (restore_user_regs(regs, mcp, sig)) @@ -908,13 +911,14 @@ int sys_debug_setcontext(struct ucontext __user *ctx, { struct sig_dbg_op op; int i; + unsigned char tmp; unsigned long new_msr = regs->msr; #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) unsigned long new_dbcr0 = current->thread.dbcr0; #endif for (i=0; ithread.dbcr0 = new_dbcr0; #endif + if (!access_ok(VERIFY_READ, ctx, sizeof(*ctx)) + || __get_user(tmp, (u8 __user *) ctx) + || __get_user(tmp, (u8 __user *) (ctx + 1) - 1)) + return -EFAULT; + /* * If we get a fault copying the context into the kernel's * image of the user's registers, we can't just return -EFAULT diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c index 27f65b95184d..c2db642f4cdd 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -182,6 +182,8 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig, err |= __get_user(msr, &sc->gp_regs[PT_MSR]); if (err) return err; + if (v_regs && !access_ok(VERIFY_READ, v_regs, 34 * sizeof(vector128))) + return -EFAULT; /* Copy 33 vec registers (vr0..31 and vscr) from the stack */ if (v_regs != 0 && (msr & MSR_VEC) != 0) err |= __copy_from_user(current->thread.vr, v_regs, From 33b7497794424181dca87f18e43ecbc07f86bba5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Wed, 7 Jun 2006 12:01:32 +1000 Subject: [PATCH 69/95] [PATCH] powerpc: Fix call to ibm,client-architecture-support The code in prom_init.c calling the firmware ibm,client-architecture-support method on pSeries has a bug where it fails to properly pass the instance handle of the firmware object when trying to call a method. Result ranges from the call doing nothing to the firmware crashing. (Found by Segher, thanks !) Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Segher Boessenkool Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 41e9ab40cd54..f393a3867430 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -822,6 +822,7 @@ static void __init prom_send_capabilities(void) /* try calling the ibm,client-architecture-support method */ if (call_prom_ret("call-method", 3, 2, &ret, ADDR("ibm,client-architecture-support"), + root, ADDR(ibm_architecture_vec)) == 0) { /* the call exists... */ if (ret) From 133dda1e4f757e036fa838cba6804d0344931c4a Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 7 Jun 2006 12:04:18 +1000 Subject: [PATCH 70/95] [PATCH] powerpc: Fix cell blade detection The IBM Cell blade firmware might confuse the kernel to think it's a pSeries machine. This fixes it for now. With a bit of luck, the firmware will be updated to avoid that in the future but currently that patch is needed. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Paul Mackerras --- arch/powerpc/kernel/prom_init.c | 9 +++++++++ arch/powerpc/platforms/cell/setup.c | 11 +++++------ arch/powerpc/platforms/pseries/setup.c | 8 ++++++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index f393a3867430..f70bd090dacd 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1623,6 +1623,15 @@ static int __init prom_find_machine_type(void) if (strstr(p, RELOC("Power Macintosh")) || strstr(p, RELOC("MacRISC"))) return PLATFORM_POWERMAC; +#ifdef CONFIG_PPC64 + /* We must make sure we don't detect the IBM Cell + * blades as pSeries due to some firmware issues, + * so we do it here. + */ + if (strstr(p, RELOC("IBM,CBEA")) || + strstr(p, RELOC("IBM,CPBW-1.0"))) + return PLATFORM_GENERIC; +#endif /* CONFIG_PPC64 */ i += sl + 1; } } diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index 6574b22b3cf3..fd3e5609e3e0 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c @@ -125,14 +125,13 @@ static void __init cell_init_early(void) static int __init cell_probe(void) { - /* XXX This is temporary, the Cell maintainer will come up with - * more appropriate detection logic - */ unsigned long root = of_get_flat_dt_root(); - if (!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 0; - return 1; + if (of_flat_dt_is_compatible(root, "IBM,CBEA") || + of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 1; + + return 0; } /* diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 5f79f01c44f2..3ba87835757e 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -389,6 +389,7 @@ static int __init pSeries_probe_hypertas(unsigned long node, static int __init pSeries_probe(void) { + unsigned long root = of_get_flat_dt_root(); char *dtype = of_get_flat_dt_prop(of_get_flat_dt_root(), "device_type", NULL); if (dtype == NULL) @@ -396,6 +397,13 @@ static int __init pSeries_probe(void) if (strcmp(dtype, "chrp")) return 0; + /* Cell blades firmware claims to be chrp while it's not. Until this + * is fixed, we need to avoid those here. + */ + if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0") || + of_flat_dt_is_compatible(root, "IBM,CBEA")) + return 0; + DBG("pSeries detected, looking for LPAR capability...\n"); /* Now try to figure out if we are running on LPAR */ From 5224e6cc3ab5ae03895bbb67f4a26ce72e62ce58 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 6 Jun 2006 17:37:41 -0700 Subject: [PATCH 71/95] [SPARC64]: Dump local cpu registers in sun4v_log_error() This makes the debugging information more usable. Signed-off-by: David S. Miller --- arch/sparc64/kernel/traps.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 2793a5d82380..563db528e031 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c @@ -1797,7 +1797,9 @@ static const char *sun4v_err_type_to_str(u32 type) }; } -static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) +extern void __show_regs(struct pt_regs * regs); + +static void sun4v_log_error(struct pt_regs *regs, struct sun4v_error_entry *ent, int cpu, const char *pfx, atomic_t *ocnt) { int cnt; @@ -1830,6 +1832,8 @@ static void sun4v_log_error(struct sun4v_error_entry *ent, int cpu, const char * pfx, ent->err_raddr, ent->err_size, ent->err_cpu); + __show_regs(regs); + if ((cnt = atomic_read(ocnt)) != 0) { atomic_set(ocnt, 0); wmb(); @@ -1862,7 +1866,7 @@ void sun4v_resum_error(struct pt_regs *regs, unsigned long offset) put_cpu(); - sun4v_log_error(&local_copy, cpu, + sun4v_log_error(regs, &local_copy, cpu, KERN_ERR "RESUMABLE ERROR", &sun4v_resum_oflow_cnt); } @@ -1910,7 +1914,7 @@ void sun4v_nonresum_error(struct pt_regs *regs, unsigned long offset) } #endif - sun4v_log_error(&local_copy, cpu, + sun4v_log_error(regs, &local_copy, cpu, KERN_EMERG "NON-RESUMABLE ERROR", &sun4v_nonresum_oflow_cnt); @@ -2200,7 +2204,6 @@ static inline struct reg_window *kernel_stack_up(struct reg_window *rw) void die_if_kernel(char *str, struct pt_regs *regs) { static int die_counter; - extern void __show_regs(struct pt_regs * regs); extern void smp_report_regs(void); int count = 0; From f49639e643e69ff233b14966b8d48541d2e17517 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 9 Jun 2006 11:58:36 -0700 Subject: [PATCH 72/95] [TG3]: Handle Sun onboard tg3 chips more correctly. Get rid of all the SUN_570X logic and instead: 1) Make sure MEMARB_ENABLE is set when we probe the SRAM for config information. If that is off we will get timeouts. 2) Always try to sync with the firmware, if there is no firmware running do not treat it as an error and instead just report it the first time we notice this condition. 3) If there is no valid SRAM signature, assume the device is onboard by setting TG3_FLAG_EEPROM_WRITE_PROT. Update driver version and release date. With help from Michael Chan and Fabio Massimo Di Nitto. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 144 ++++++++++++++++------------------------------ drivers/net/tg3.h | 3 +- 2 files changed, 50 insertions(+), 97 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 49ad60b72657..862c226dbbe2 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -69,8 +69,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.58" -#define DRV_MODULE_RELDATE "May 22, 2006" +#define DRV_MODULE_VERSION "3.59" +#define DRV_MODULE_RELDATE "June 8, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -4485,9 +4485,8 @@ static void tg3_disable_nvram_access(struct tg3 *tp) /* tp->lock is held. */ static void tg3_write_sig_pre_reset(struct tg3 *tp, int kind) { - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) - tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, - NIC_SRAM_FIRMWARE_MBOX_MAGIC1); + tg3_write_mem(tp, NIC_SRAM_FIRMWARE_MBOX, + NIC_SRAM_FIRMWARE_MBOX_MAGIC1); if (tp->tg3_flags2 & TG3_FLG2_ASF_NEW_HANDSHAKE) { switch (kind) { @@ -4568,13 +4567,12 @@ static int tg3_chip_reset(struct tg3 *tp) void (*write_op)(struct tg3 *, u32, u32); int i; - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { - tg3_nvram_lock(tp); - /* No matching tg3_nvram_unlock() after this because - * chip reset below will undo the nvram lock. - */ - tp->nvram_lock_cnt = 0; - } + tg3_nvram_lock(tp); + + /* No matching tg3_nvram_unlock() after this because + * chip reset below will undo the nvram lock. + */ + tp->nvram_lock_cnt = 0; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5755 || @@ -4727,20 +4725,25 @@ static int tg3_chip_reset(struct tg3 *tp) tw32_f(MAC_MODE, 0); udelay(40); - if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { - /* Wait for firmware initialization to complete. */ - for (i = 0; i < 100000; i++) { - tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); - if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) - break; - udelay(10); - } - if (i >= 100000) { - printk(KERN_ERR PFX "tg3_reset_hw timed out for %s, " - "firmware will not restart magic=%08x\n", - tp->dev->name, val); - return -ENODEV; - } + /* Wait for firmware initialization to complete. */ + for (i = 0; i < 100000; i++) { + tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); + if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) + break; + udelay(10); + } + + /* Chip might not be fitted with firmare. Some Sun onboard + * parts are configured like that. So don't signal the timeout + * of the above loop as an error, but do report the lack of + * running firmware once. + */ + if (i >= 100000 && + !(tp->tg3_flags2 & TG3_FLG2_NO_FWARE_REPORTED)) { + tp->tg3_flags2 |= TG3_FLG2_NO_FWARE_REPORTED; + + printk(KERN_INFO PFX "%s: No firmware running.\n", + tp->dev->name); } if ((tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) && @@ -9075,9 +9078,6 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) { int j; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) - return; - tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << @@ -9210,11 +9210,6 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) { int ret; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - printk(KERN_ERR PFX "Attempt to do nvram_read on Sun 570X\n"); - return -EINVAL; - } - if (!(tp->tg3_flags & TG3_FLAG_NVRAM)) return tg3_nvram_read_using_eeprom(tp, offset, val); @@ -9447,11 +9442,6 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) { int ret; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - printk(KERN_ERR PFX "Attempt to do nvram_write on Sun 570X\n"); - return -EINVAL; - } - if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl & ~GRC_LCLCTRL_GPIO_OUTPUT1); @@ -9578,15 +9568,19 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, tp->misc_host_ctrl); + /* The memory arbiter has to be enabled in order for SRAM accesses + * to succeed. Normally on powerup the tg3 chip firmware will make + * sure it is enabled, but other entities such as system netboot + * code might disable it. + */ + val = tr32(MEMARB_MODE); + tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE); + tp->phy_id = PHY_ID_INVALID; tp->led_ctrl = LED_CTRL_MODE_PHY_1; - /* Do not even try poking around in here on Sun parts. */ - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - /* All SUN chips are built-in LOMs. */ - tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - return; - } + /* Assume an onboard device by default. */ + tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; tg3_read_mem(tp, NIC_SRAM_DATA_SIG, &val); if (val == NIC_SRAM_DATA_SIG_MAGIC) { @@ -9686,6 +9680,8 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; + else + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; @@ -9834,16 +9830,8 @@ static void __devinit tg3_read_partno(struct tg3 *tp) int i; u32 magic; - if (tp->tg3_flags2 & TG3_FLG2_SUN_570X) { - /* Sun decided not to put the necessary bits in the - * NVRAM of their onboard tg3 parts :( - */ - strcpy(tp->board_part_number, "Sun 570X"); - return; - } - if (tg3_nvram_read_swab(tp, 0x0, &magic)) - return; + goto out_not_found; if (magic == TG3_EEPROM_MAGIC) { for (i = 0; i < 256; i += 4) { @@ -9874,6 +9862,9 @@ static void __devinit tg3_read_partno(struct tg3 *tp) break; msleep(1); } + if (!(tmp16 & 0x8000)) + goto out_not_found; + pci_read_config_dword(tp->pdev, vpd_cap + PCI_VPD_DATA, &tmp); tmp = cpu_to_le32(tmp); @@ -9965,37 +9956,6 @@ static void __devinit tg3_read_fw_ver(struct tg3 *tp) } } -#ifdef CONFIG_SPARC64 -static int __devinit tg3_is_sun_570X(struct tg3 *tp) -{ - struct pci_dev *pdev = tp->pdev; - struct pcidev_cookie *pcp = pdev->sysdata; - - if (pcp != NULL) { - int node = pcp->prom_node; - u32 venid; - int err; - - err = prom_getproperty(node, "subsystem-vendor-id", - (char *) &venid, sizeof(venid)); - if (err == 0 || err == -1) - return 0; - if (venid == PCI_VENDOR_ID_SUN) - return 1; - - /* TG3 chips onboard the SunBlade-2500 don't have the - * subsystem-vendor-id set to PCI_VENDOR_ID_SUN but they - * are distinguishable from non-Sun variants by being - * named "network" by the firmware. Non-Sun cards will - * show up as being named "ethernet". - */ - if (!strcmp(pcp->prom_name, "network")) - return 1; - } - return 0; -} -#endif - static int __devinit tg3_get_invariants(struct tg3 *tp) { static struct pci_device_id write_reorder_chipsets[] = { @@ -10012,11 +9972,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) u16 pci_cmd; int err; -#ifdef CONFIG_SPARC64 - if (tg3_is_sun_570X(tp)) - tp->tg3_flags2 |= TG3_FLG2_SUN_570X; -#endif - /* Force memory write invalidate off. If we leave it on, * then on 5700_BX chips we have to enable a workaround. * The workaround is to set the TG3PCI_DMA_RW_CTRL boundary @@ -10312,8 +10267,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) if (tp->write32 == tg3_write_indirect_reg32 || ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5700 || - GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701)) || - (tp->tg3_flags2 & TG3_FLG2_SUN_570X)) + GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5701))) tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; /* Get eeprom hw config before calling tg3_set_power_state(). @@ -10594,8 +10548,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) #endif mac_offset = 0x7c; - if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 && - !(tp->tg3_flags & TG3_FLG2_SUN_570X)) || + if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) { if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID) mac_offset = 0xcc; @@ -10622,8 +10575,7 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) } if (!addr_ok) { /* Next, try NVRAM. */ - if (!(tp->tg3_flags & TG3_FLG2_SUN_570X) && - !tg3_nvram_read(tp, mac_offset + 0, &hi) && + if (!tg3_nvram_read(tp, mac_offset + 0, &hi) && !tg3_nvram_read(tp, mac_offset + 4, &lo)) { dev->dev_addr[0] = ((hi >> 16) & 0xff); dev->dev_addr[1] = ((hi >> 24) & 0xff); diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 0e29b885d449..ff0faab94bd5 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2184,7 +2184,7 @@ struct tg3 { #define TG3_FLAG_INIT_COMPLETE 0x80000000 u32 tg3_flags2; #define TG3_FLG2_RESTART_TIMER 0x00000001 -#define TG3_FLG2_SUN_570X 0x00000002 +/* 0x00000002 available */ #define TG3_FLG2_NO_ETH_WIRE_SPEED 0x00000004 #define TG3_FLG2_IS_5788 0x00000008 #define TG3_FLG2_MAX_RXPEND_64 0x00000010 @@ -2216,6 +2216,7 @@ struct tg3 { #define TG3_FLG2_HW_TSO (TG3_FLG2_HW_TSO_1 | TG3_FLG2_HW_TSO_2) #define TG3_FLG2_1SHOT_MSI 0x10000000 #define TG3_FLG2_PHY_JITTER_BUG 0x20000000 +#define TG3_FLG2_NO_FWARE_REPORTED 0x40000000 u32 split_mode_max_reqs; #define SPLIT_MODE_5704_MAX_REQ 3 From c29ca9d1812f2abacaefa7daa31e085600128938 Mon Sep 17 00:00:00 2001 From: "Tom \"spot\" Callaway" Date: Fri, 9 Jun 2006 17:01:48 -0700 Subject: [PATCH 73/95] [FUSION]: Fix mptspi.c build with CONFIG_PM not set. Signed-off-by: Tom "spot" Callaway Signed-off-by: David S. Miller --- drivers/message/fusion/mptspi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index f2a4d382ea19..3201de053943 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -831,6 +831,7 @@ mptspi_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) return rc; } +#ifdef CONFIG_PM /* * spi module resume handler */ @@ -846,6 +847,7 @@ mptspi_resume(struct pci_dev *pdev) return rc; } +#endif /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ From 46b304934de417a2238d659ef6459a74cb3f5e6b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 10 Jun 2006 01:06:25 -0700 Subject: [PATCH 74/95] [SPARC64]: Avoid JBUS errors on some Niagara systems. Doing PCI config space accesses to non-present PCI slots can result in fatal JBUS errors if the PCI config access hypervisor call is performed on cpus other than the boot cpu. PCI config space accesses to present PCI slots works just fine. Recursively traverse the OBP device tree under the PCI controller node and record all present device IDs into a small hash table. Avoid the hypervisor call for any PCI config space access attempt for a device not recorded in the hash table. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_sun4v.c | 124 ++++++++++++++++++++++++++++++-- 1 file changed, 118 insertions(+), 6 deletions(-) diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 2b7a1f316a93..0c0895202970 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -599,18 +599,128 @@ struct pci_iommu_ops pci_sun4v_iommu_ops = { /* SUN4V PCI configuration space accessors. */ -static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) +struct pdev_entry { + struct pdev_entry *next; + u32 devhandle; + unsigned int bus; + unsigned int device; + unsigned int func; +}; + +#define PDEV_HTAB_SIZE 16 +#define PDEV_HTAB_MASK (PDEV_HTAB_SIZE - 1) +static struct pdev_entry *pdev_htab[PDEV_HTAB_SIZE]; + +static inline unsigned int pdev_hashfn(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) { - if (bus == pbm->pci_first_busno) { - if (device == 0 && func == 0) - return 0; - return 1; + unsigned int val; + + val = (devhandle ^ (devhandle >> 4)); + val ^= bus; + val ^= device; + val ^= func; + + return val & PDEV_HTAB_MASK; +} + +static int pdev_htab_add(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) +{ + struct pdev_entry *p = kmalloc(sizeof(*p), GFP_KERNEL); + struct pdev_entry **slot; + + if (!p) + return -ENOMEM; + + slot = &pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; + p->next = *slot; + *slot = p; + + p->devhandle = devhandle; + p->bus = bus; + p->device = device; + p->func = func; + + return 0; +} + +/* Recursively descend into the OBP device tree, rooted at toplevel_node, + * looking for a PCI device matching bus and devfn. + */ +static int obp_find(struct linux_prom_pci_registers *pregs, int toplevel_node, unsigned int bus, unsigned int devfn) +{ + toplevel_node = prom_getchild(toplevel_node); + + while (toplevel_node != 0) { + int ret = obp_find(pregs, toplevel_node, bus, devfn); + + if (ret != 0) + return ret; + + ret = prom_getproperty(toplevel_node, "reg", (char *) pregs, + sizeof(*pregs) * PROMREG_MAX); + if (ret == 0 || ret == -1) + goto next_sibling; + + if (((pregs[0].phys_hi >> 16) & 0xff) == bus && + ((pregs[0].phys_hi >> 8) & 0xff) == devfn) + break; + + next_sibling: + toplevel_node = prom_getsibling(toplevel_node); } + return toplevel_node; +} + +static int pdev_htab_populate(struct pci_pbm_info *pbm) +{ + struct linux_prom_pci_registers pr[PROMREG_MAX]; + u32 devhandle = pbm->devhandle; + unsigned int bus; + + for (bus = pbm->pci_first_busno; bus <= pbm->pci_last_busno; bus++) { + unsigned int devfn; + + for (devfn = 0; devfn < 256; devfn++) { + unsigned int device = PCI_SLOT(devfn); + unsigned int func = PCI_FUNC(devfn); + + if (obp_find(pr, pbm->prom_node, bus, devfn)) { + int err = pdev_htab_add(devhandle, bus, + device, func); + if (err) + return err; + } + } + } + + return 0; +} + +static struct pdev_entry *pdev_find(u32 devhandle, unsigned int bus, unsigned int device, unsigned int func) +{ + struct pdev_entry *p; + + p = pdev_htab[pdev_hashfn(devhandle, bus, device, func)]; + while (p) { + if (p->devhandle == devhandle && + p->bus == bus && + p->device == device && + p->func == func) + break; + + p = p->next; + } + + return p; +} + +static inline int pci_sun4v_out_of_range(struct pci_pbm_info *pbm, unsigned int bus, unsigned int device, unsigned int func) +{ if (bus < pbm->pci_first_busno || bus > pbm->pci_last_busno) return 1; - return 0; + return pdev_find(pbm->devhandle, bus, device, func) == NULL; } static int pci_sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, @@ -1063,6 +1173,8 @@ static void pci_sun4v_pbm_init(struct pci_controller_info *p, int prom_node, u32 pci_sun4v_get_bus_range(pbm); pci_sun4v_iommu_init(pbm); + + pdev_htab_populate(pbm); } void sun4v_pci_init(int node, char *model_name) From 56f1319e877a969b814b3805c77ea9c31d849f54 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sat, 10 Jun 2006 12:42:12 +0100 Subject: [PATCH 75/95] [ARM] Fix Integrator and Versatile interrupt initialisation Both Integrator and Versatile were using set_irq_handler() and enable_irq(), and working around the initialisation of the chained interrupt, instead of the more correct set_irq_chained_handler() function. Fix Integrator and Versatile to use the right function, and remove these work-arounds. Signed-off-by: Russell King --- arch/arm/mach-integrator/integrator_cp.c | 5 +---- arch/arm/mach-versatile/core.c | 5 ++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index a0724f2b24ce..9f55f5ae1044 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -232,8 +232,6 @@ static void __init intcp_init_irq(void) for (i = IRQ_PIC_START; i <= IRQ_PIC_END; i++) { if (i == 11) i = 22; - if (i == IRQ_CP_CPPLDINT) - i++; if (i == 29) break; set_irq_chip(i, &pic_chip); @@ -259,8 +257,7 @@ static void __init intcp_init_irq(void) set_irq_flags(i, IRQF_VALID | IRQF_PROBE); } - set_irq_handler(IRQ_CP_CPPLDINT, sic_handle_irq); - pic_unmask_irq(IRQ_CP_CPPLDINT); + set_irq_chained_handler(IRQ_CP_CPPLDINT, sic_handle_irq); } /* diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 799697d32dec..cebd48a3dae4 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -112,10 +112,9 @@ void __init versatile_init_irq(void) { unsigned int i; - vic_init(VA_VIC_BASE, IRQ_VIC_START, ~(1 << 31)); + vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0); - set_irq_handler(IRQ_VICSOURCE31, sic_handle_irq); - enable_irq(IRQ_VICSOURCE31); + set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq); /* Do second interrupt controller */ writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR); From 670bd95e0413c43f878b73a4a3919d1f452a4157 Mon Sep 17 00:00:00 2001 From: David Howells Date: Sat, 10 Jun 2006 09:54:12 -0700 Subject: [PATCH 76/95] [PATCH] Further alterations for memory barrier document From: David Howells Apply some alterations to the memory barrier document that I worked out with Paul McKenney of IBM, plus some of the alterations suggested by Alan Stern. The following changes were made: (*) One of the examples given for what can happen with overlapping memory barriers was wrong. (*) The description of general memory barriers said that a general barrier is a combination of a read barrier and a write barrier. This isn't entirely true: it implies both, but is more than a combination of both. (*) The first example in the "SMP Barrier Pairing" section was wrong: the loads around the read barrier need to touch the memory locations in the opposite order to the stores around the write barrier. (*) Added a note to make explicit that the loads should be in reverse order to the stores. (*) Adjusted the diagrams in the "Examples Of Memory Barrier Sequences" section to make them clearer. Added a couple of diagrams to make it more clear as to how it could go wrong without the barrier. (*) Added a section on memory speculation. (*) Dropped any references to memory allocation routines doing memory barriers. They may do sometimes, but it can't be relied on. This may be worthy of further documentation later. (*) Made the fact that a LOCK followed by an UNLOCK should not be considered a full memory barrier more explicit and gave an example. Signed-off-by: David Howells Acked-by: Paul E. McKenney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/memory-barriers.txt | 344 +++++++++++++++++++++++------- 1 file changed, 268 insertions(+), 76 deletions(-) diff --git a/Documentation/memory-barriers.txt b/Documentation/memory-barriers.txt index c61d8b876fdb..4710845dbac4 100644 --- a/Documentation/memory-barriers.txt +++ b/Documentation/memory-barriers.txt @@ -19,6 +19,7 @@ Contents: - Control dependencies. - SMP barrier pairing. - Examples of memory barrier sequences. + - Read memory barriers vs load speculation. (*) Explicit kernel barriers. @@ -248,7 +249,7 @@ And there are a number of things that _must_ or _must_not_ be assumed: we may get either of: STORE *A = X; Y = LOAD *A; - STORE *A = Y; + STORE *A = Y = X; ========================= @@ -344,9 +345,12 @@ Memory barriers come in four basic varieties: (4) General memory barriers. - A general memory barrier is a combination of both a read memory barrier - and a write memory barrier. It is a partial ordering over both loads and - stores. + A general memory barrier gives a guarantee that all the LOAD and STORE + operations specified before the barrier will appear to happen before all + the LOAD and STORE operations specified after the barrier with respect to + the other components of the system. + + A general memory barrier is a partial ordering over both loads and stores. General memory barriers imply both read and write memory barriers, and so can substitute for either. @@ -546,9 +550,9 @@ write barrier, though, again, a general barrier is viable: =============== =============== a = 1; - b = 2; x = a; + b = 2; x = b; - y = b; + y = a; Or: @@ -563,6 +567,18 @@ Or: Basically, the read barrier always has to be there, even though it can be of the "weaker" type. +[!] Note that the stores before the write barrier would normally be expected to +match the loads after the read barrier or data dependency barrier, and vice +versa: + + CPU 1 CPU 2 + =============== =============== + a = 1; }---- --->{ v = c + b = 2; } \ / { w = d + \ + c = 3; } / \ { x = a; + d = 4; }---- --->{ y = b; + EXAMPLES OF MEMORY BARRIER SEQUENCES ------------------------------------ @@ -600,8 +616,8 @@ STORE B, STORE C } all occuring before the unordered set of { STORE D, STORE E | | +------+ +-------+ : : | - | Sequence in which stores committed to memory system - | by CPU 1 + | Sequence in which stores are committed to the + | memory system by CPU 1 V @@ -683,14 +699,12 @@ then the following will occur: | : : | | | : : | CPU 2 | | +-------+ | | - \ | X->9 |------>| | - \ +-------+ | | - ----->| B->2 | | | - +-------+ | | - Makes sure all effects ---> ddddddddddddddddd | | - prior to the store of C +-------+ | | - are perceptible to | B->2 |------>| | - successive loads +-------+ | | + | | X->9 |------>| | + | +-------+ | | + Makes sure all effects ---> \ ddddddddddddddddd | | + prior to the store of C \ +-------+ | | + are perceptible to ----->| B->2 |------>| | + subsequent loads +-------+ | | : : +-------+ @@ -699,73 +713,239 @@ following sequence of events: CPU 1 CPU 2 ======================= ======================= + { A = 0, B = 9 } STORE A=1 - STORE B=2 - STORE C=3 - STORE D=4 - STORE E=5 - LOAD A + STORE B=2 LOAD B - LOAD C - LOAD D - LOAD E + LOAD A Without intervention, CPU 2 may then choose to perceive the events on CPU 1 in some effectively random order, despite the write barrier issued by CPU 1: - +-------+ : : - | | +------+ - | |------>| C=3 | } - | | : +------+ } - | | : | A=1 | } - | | : +------+ } - | CPU 1 | : | B=2 | }--- - | | +------+ } \ - | | wwwwwwwwwwwww} \ - | | +------+ } \ : : +-------+ - | | : | E=5 | } \ +-------+ | | - | | : +------+ } \ { | C->3 |------>| | - | |------>| D=4 | } \ { +-------+ : | | - | | +------+ \ { | E->5 | : | | - +-------+ : : \ { +-------+ : | | - Transfer -->{ | A->1 | : | CPU 2 | - from CPU 1 { +-------+ : | | - to CPU 2 { | D->4 | : | | - { +-------+ : | | - { | B->2 |------>| | - +-------+ | | - : : +-------+ + +-------+ : : : : + | | +------+ +-------+ + | |------>| A=1 |------ --->| A->0 | + | | +------+ \ +-------+ + | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | + | | +------+ | +-------+ + | |------>| B=2 |--- | : : + | | +------+ \ | : : +-------+ + +-------+ : : \ | +-------+ | | + ---------->| B->2 |------>| | + | +-------+ | CPU 2 | + | | A->0 |------>| | + | +-------+ | | + | : : +-------+ + \ : : + \ +-------+ + ---->| A->1 | + +-------+ + : : -If, however, a read barrier were to be placed between the load of C and the -load of D on CPU 2, then the partial ordering imposed by CPU 1 will be -perceived correctly by CPU 2. +If, however, a read barrier were to be placed between the load of E and the +load of A on CPU 2: - +-------+ : : - | | +------+ - | |------>| C=3 | } - | | : +------+ } - | | : | A=1 | }--- - | | : +------+ } \ - | CPU 1 | : | B=2 | } \ - | | +------+ \ - | | wwwwwwwwwwwwwwww \ - | | +------+ \ : : +-------+ - | | : | E=5 | } \ +-------+ | | - | | : +------+ }--- \ { | C->3 |------>| | - | |------>| D=4 | } \ \ { +-------+ : | | - | | +------+ \ -->{ | B->2 | : | | - +-------+ : : \ { +-------+ : | | - \ { | A->1 | : | CPU 2 | - \ +-------+ | | - At this point the read ----> \ rrrrrrrrrrrrrrrrr | | - barrier causes all effects \ +-------+ | | - prior to the storage of C \ { | E->5 | : | | - to be perceptible to CPU 2 -->{ +-------+ : | | - { | D->4 |------>| | - +-------+ | | - : : +-------+ + CPU 1 CPU 2 + ======================= ======================= + { A = 0, B = 9 } + STORE A=1 + + STORE B=2 + LOAD B + + LOAD A + +then the partial ordering imposed by CPU 1 will be perceived correctly by CPU +2: + + +-------+ : : : : + | | +------+ +-------+ + | |------>| A=1 |------ --->| A->0 | + | | +------+ \ +-------+ + | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | + | | +------+ | +-------+ + | |------>| B=2 |--- | : : + | | +------+ \ | : : +-------+ + +-------+ : : \ | +-------+ | | + ---------->| B->2 |------>| | + | +-------+ | CPU 2 | + | : : | | + | : : | | + At this point the read ----> \ rrrrrrrrrrrrrrrrr | | + barrier causes all effects \ +-------+ | | + prior to the storage of B ---->| A->1 |------>| | + to be perceptible to CPU 2 +-------+ | | + : : +-------+ + + +To illustrate this more completely, consider what could happen if the code +contained a load of A either side of the read barrier: + + CPU 1 CPU 2 + ======================= ======================= + { A = 0, B = 9 } + STORE A=1 + + STORE B=2 + LOAD B + LOAD A [first load of A] + + LOAD A [second load of A] + +Even though the two loads of A both occur after the load of B, they may both +come up with different values: + + +-------+ : : : : + | | +------+ +-------+ + | |------>| A=1 |------ --->| A->0 | + | | +------+ \ +-------+ + | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | + | | +------+ | +-------+ + | |------>| B=2 |--- | : : + | | +------+ \ | : : +-------+ + +-------+ : : \ | +-------+ | | + ---------->| B->2 |------>| | + | +-------+ | CPU 2 | + | : : | | + | : : | | + | +-------+ | | + | | A->0 |------>| 1st | + | +-------+ | | + At this point the read ----> \ rrrrrrrrrrrrrrrrr | | + barrier causes all effects \ +-------+ | | + prior to the storage of B ---->| A->1 |------>| 2nd | + to be perceptible to CPU 2 +-------+ | | + : : +-------+ + + +But it may be that the update to A from CPU 1 becomes perceptible to CPU 2 +before the read barrier completes anyway: + + +-------+ : : : : + | | +------+ +-------+ + | |------>| A=1 |------ --->| A->0 | + | | +------+ \ +-------+ + | CPU 1 | wwwwwwwwwwwwwwww \ --->| B->9 | + | | +------+ | +-------+ + | |------>| B=2 |--- | : : + | | +------+ \ | : : +-------+ + +-------+ : : \ | +-------+ | | + ---------->| B->2 |------>| | + | +-------+ | CPU 2 | + | : : | | + \ : : | | + \ +-------+ | | + ---->| A->1 |------>| 1st | + +-------+ | | + rrrrrrrrrrrrrrrrr | | + +-------+ | | + | A->1 |------>| 2nd | + +-------+ | | + : : +-------+ + + +The guarantee is that the second load will always come up with A == 1 if the +load of B came up with B == 2. No such guarantee exists for the first load of +A; that may come up with either A == 0 or A == 1. + + +READ MEMORY BARRIERS VS LOAD SPECULATION +---------------------------------------- + +Many CPUs speculate with loads: that is they see that they will need to load an +item from memory, and they find a time where they're not using the bus for any +other loads, and so do the load in advance - even though they haven't actually +got to that point in the instruction execution flow yet. This permits the +actual load instruction to potentially complete immediately because the CPU +already has the value to hand. + +It may turn out that the CPU didn't actually need the value - perhaps because a +branch circumvented the load - in which case it can discard the value or just +cache it for later use. + +Consider: + + CPU 1 CPU 2 + ======================= ======================= + LOAD B + DIVIDE } Divide instructions generally + DIVIDE } take a long time to perform + LOAD A + +Which might appear as this: + + : : +-------+ + +-------+ | | + --->| B->2 |------>| | + +-------+ | CPU 2 | + : :DIVIDE | | + +-------+ | | + The CPU being busy doing a ---> --->| A->0 |~~~~ | | + division speculates on the +-------+ ~ | | + LOAD of A : : ~ | | + : :DIVIDE | | + : : ~ | | + Once the divisions are complete --> : : ~-->| | + the CPU can then perform the : : | | + LOAD with immediate effect : : +-------+ + + +Placing a read barrier or a data dependency barrier just before the second +load: + + CPU 1 CPU 2 + ======================= ======================= + LOAD B + DIVIDE + DIVIDE + + LOAD A + +will force any value speculatively obtained to be reconsidered to an extent +dependent on the type of barrier used. If there was no change made to the +speculated memory location, then the speculated value will just be used: + + : : +-------+ + +-------+ | | + --->| B->2 |------>| | + +-------+ | CPU 2 | + : :DIVIDE | | + +-------+ | | + The CPU being busy doing a ---> --->| A->0 |~~~~ | | + division speculates on the +-------+ ~ | | + LOAD of A : : ~ | | + : :DIVIDE | | + : : ~ | | + : : ~ | | + rrrrrrrrrrrrrrrr~ | | + : : ~ | | + : : ~-->| | + : : | | + : : +-------+ + + +but if there was an update or an invalidation from another CPU pending, then +the speculation will be cancelled and the value reloaded: + + : : +-------+ + +-------+ | | + --->| B->2 |------>| | + +-------+ | CPU 2 | + : :DIVIDE | | + +-------+ | | + The CPU being busy doing a ---> --->| A->0 |~~~~ | | + division speculates on the +-------+ ~ | | + LOAD of A : : ~ | | + : :DIVIDE | | + : : ~ | | + : : ~ | | + rrrrrrrrrrrrrrrrr | | + +-------+ | | + The speculation is discarded ---> --->| A->1 |------>| | + and an updated value is +-------+ | | + retrieved : : +-------+ ======================== @@ -901,7 +1081,7 @@ IMPLICIT KERNEL MEMORY BARRIERS =============================== Some of the other functions in the linux kernel imply memory barriers, amongst -which are locking, scheduling and memory allocation functions. +which are locking and scheduling functions. This specification is a _minimum_ guarantee; any particular architecture may provide more substantial guarantees, but these may not be relied upon outside @@ -966,6 +1146,20 @@ equivalent to a full barrier, but a LOCK followed by an UNLOCK is not. barriers is that the effects instructions outside of a critical section may seep into the inside of the critical section. +A LOCK followed by an UNLOCK may not be assumed to be full memory barrier +because it is possible for an access preceding the LOCK to happen after the +LOCK, and an access following the UNLOCK to happen before the UNLOCK, and the +two accesses can themselves then cross: + + *A = a; + LOCK + UNLOCK + *B = b; + +may occur as: + + LOCK, STORE *B, STORE *A, UNLOCK + Locks and semaphores may not provide any guarantee of ordering on UP compiled systems, and so cannot be counted on in such a situation to actually achieve anything at all - especially with respect to I/O accesses - unless combined @@ -1016,8 +1210,6 @@ Other functions that imply barriers: (*) schedule() and similar imply full memory barriers. - (*) Memory allocation and release functions imply full memory barriers. - ================================= INTER-CPU LOCKING BARRIER EFFECTS From a913f50706b21c7933f53cec678bb9a1c2383499 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 10 Jun 2006 09:54:13 -0700 Subject: [PATCH 77/95] [PATCH] powernow-k8 crash workaround From: Andrew Morton Work around the oops reported in http://bugzilla.kernel.org/show_bug.cgi?id=6478. Thanks to Ralf Hildebrandt for testing and reporting. Acked-by: Dave Jones Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/acpi/processor_perflib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index abbdb37a7f5f..f36db22ce1ae 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -577,6 +577,8 @@ acpi_processor_register_performance(struct acpi_processor_performance return_VALUE(-EBUSY); } + WARN_ON(!performance); + pr->performance = performance; if (acpi_processor_get_performance_info(pr)) { @@ -609,7 +611,8 @@ acpi_processor_unregister_performance(struct acpi_processor_performance return_VOID; } - kfree(pr->performance->states); + if (pr->performance) + kfree(pr->performance->states); pr->performance = NULL; acpi_cpufreq_remove_file(pr); From 57a62fed871eb2a95f296fe6c5c250ce21b81a79 Mon Sep 17 00:00:00 2001 From: Markus Lidel Date: Sat, 10 Jun 2006 09:54:14 -0700 Subject: [PATCH 78/95] [PATCH] I2O: Bugfixes to get I2O working again From: Markus Lidel - Fixed locking of struct i2o_exec_wait in Executive-OSM - Removed LCT Notify in i2o_exec_probe() which caused freeing memory and accessing freed memory during first enumeration of I2O devices - Added missing locking in i2o_exec_lct_notify() - removed put_device() of I2O controller in i2o_iop_remove() which caused the controller structure get freed to early - Fixed size of mempool in i2o_iop_alloc() - Fixed access to freed memory in i2o_msg_get() See http://bugzilla.kernel.org/show_bug.cgi?id=6561 Signed-off-by: Markus Lidel Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/message/i2o/exec-osm.c | 72 +++++++++++++++++----------------- drivers/message/i2o/iop.c | 4 +- include/linux/i2o.h | 5 ++- 3 files changed, 42 insertions(+), 39 deletions(-) diff --git a/drivers/message/i2o/exec-osm.c b/drivers/message/i2o/exec-osm.c index 5ea133c59afb..7bd4d85d0b42 100644 --- a/drivers/message/i2o/exec-osm.c +++ b/drivers/message/i2o/exec-osm.c @@ -55,6 +55,7 @@ struct i2o_exec_wait { u32 m; /* message id */ struct i2o_message *msg; /* pointer to the reply message */ struct list_head list; /* node in global wait list */ + spinlock_t lock; /* lock before modifying */ }; /* Work struct needed to handle LCT NOTIFY replies */ @@ -87,6 +88,7 @@ static struct i2o_exec_wait *i2o_exec_wait_alloc(void) return NULL; INIT_LIST_HEAD(&wait->list); + spin_lock_init(&wait->lock); return wait; }; @@ -125,6 +127,7 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, DECLARE_WAIT_QUEUE_HEAD(wq); struct i2o_exec_wait *wait; static u32 tcntxt = 0x80000000; + long flags; int rc = 0; wait = i2o_exec_wait_alloc(); @@ -146,33 +149,28 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, wait->tcntxt = tcntxt++; msg->u.s.tcntxt = cpu_to_le32(wait->tcntxt); + wait->wq = &wq; + /* + * we add elements to the head, because if a entry in the list will + * never be removed, we have to iterate over it every time + */ + list_add(&wait->list, &i2o_exec_wait_list); + /* * Post the message to the controller. At some point later it will * return. If we time out before it returns then complete will be zero. */ i2o_msg_post(c, msg); - if (!wait->complete) { - wait->wq = &wq; - /* - * we add elements add the head, because if a entry in the list - * will never be removed, we have to iterate over it every time - */ - list_add(&wait->list, &i2o_exec_wait_list); + wait_event_interruptible_timeout(wq, wait->complete, timeout * HZ); - wait_event_interruptible_timeout(wq, wait->complete, - timeout * HZ); + spin_lock_irqsave(&wait->lock, flags); - wait->wq = NULL; - } + wait->wq = NULL; - barrier(); - - if (wait->complete) { + if (wait->complete) rc = le32_to_cpu(wait->msg->body[0]) >> 24; - i2o_flush_reply(c, wait->m); - i2o_exec_wait_free(wait); - } else { + else { /* * We cannot remove it now. This is important. When it does * terminate (which it must do if the controller has not @@ -186,6 +184,13 @@ int i2o_msg_post_wait_mem(struct i2o_controller *c, struct i2o_message *msg, rc = -ETIMEDOUT; } + spin_unlock_irqrestore(&wait->lock, flags); + + if (rc != -ETIMEDOUT) { + i2o_flush_reply(c, wait->m); + i2o_exec_wait_free(wait); + } + return rc; }; @@ -213,7 +218,6 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, { struct i2o_exec_wait *wait, *tmp; unsigned long flags; - static spinlock_t lock = SPIN_LOCK_UNLOCKED; int rc = 1; /* @@ -223,23 +227,24 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, * already expired. Not much we can do about that except log it for * debug purposes, increase timeout, and recompile. */ - spin_lock_irqsave(&lock, flags); list_for_each_entry_safe(wait, tmp, &i2o_exec_wait_list, list) { if (wait->tcntxt == context) { - list_del(&wait->list); + spin_lock_irqsave(&wait->lock, flags); - spin_unlock_irqrestore(&lock, flags); + list_del(&wait->list); wait->m = m; wait->msg = msg; wait->complete = 1; - barrier(); - - if (wait->wq) { - wake_up_interruptible(wait->wq); + if (wait->wq) rc = 0; - } else { + else + rc = -1; + + spin_unlock_irqrestore(&wait->lock, flags); + + if (rc) { struct device *dev; dev = &c->pdev->dev; @@ -248,15 +253,13 @@ static int i2o_msg_post_wait_complete(struct i2o_controller *c, u32 m, c->name); i2o_dma_free(dev, &wait->dma); i2o_exec_wait_free(wait); - rc = -1; - } + } else + wake_up_interruptible(wait->wq); return rc; } } - spin_unlock_irqrestore(&lock, flags); - osm_warn("%s: Bogus reply in POST WAIT (tr-context: %08x)!\n", c->name, context); @@ -322,14 +325,9 @@ static DEVICE_ATTR(product_id, S_IRUGO, i2o_exec_show_product_id, NULL); static int i2o_exec_probe(struct device *dev) { struct i2o_device *i2o_dev = to_i2o_device(dev); - struct i2o_controller *c = i2o_dev->iop; i2o_event_register(i2o_dev, &i2o_exec_driver, 0, 0xffffffff); - c->exec = i2o_dev; - - i2o_exec_lct_notify(c, c->lct->change_ind + 1); - device_create_file(dev, &dev_attr_vendor_id); device_create_file(dev, &dev_attr_product_id); @@ -523,6 +521,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) struct device *dev; struct i2o_message *msg; + down(&c->lct_lock); + dev = &c->pdev->dev; if (i2o_dma_realloc @@ -545,6 +545,8 @@ static int i2o_exec_lct_notify(struct i2o_controller *c, u32 change_ind) i2o_msg_post(c, msg); + up(&c->lct_lock); + return 0; }; diff --git a/drivers/message/i2o/iop.c b/drivers/message/i2o/iop.c index 492167446936..febbdd4e0605 100644 --- a/drivers/message/i2o/iop.c +++ b/drivers/message/i2o/iop.c @@ -804,8 +804,6 @@ void i2o_iop_remove(struct i2o_controller *c) /* Ask the IOP to switch to RESET state */ i2o_iop_reset(c); - - put_device(&c->device); } /** @@ -1059,7 +1057,7 @@ struct i2o_controller *i2o_iop_alloc(void) snprintf(poolname, sizeof(poolname), "i2o_%s_msg_inpool", c->name); if (i2o_pool_alloc - (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4, + (&c->in_msg, poolname, I2O_INBOUND_MSG_FRAME_SIZE * 4 + sizeof(u32), I2O_MSG_INPOOL_MIN)) { kfree(c); return ERR_PTR(-ENOMEM); diff --git a/include/linux/i2o.h b/include/linux/i2o.h index dd7d627bf66f..c115e9e840b4 100644 --- a/include/linux/i2o.h +++ b/include/linux/i2o.h @@ -1114,8 +1114,11 @@ static inline struct i2o_message *i2o_msg_get(struct i2o_controller *c) mmsg->mfa = readl(c->in_port); if (unlikely(mmsg->mfa >= c->in_queue.len)) { + u32 mfa = mmsg->mfa; + mempool_free(mmsg, c->in_msg.mempool); - if(mmsg->mfa == I2O_QUEUE_EMPTY) + + if (mfa == I2O_QUEUE_EMPTY) return ERR_PTR(-EBUSY); return ERR_PTR(-EFAULT); } From 938473b24636d77dc5e9c3f41090d071b6cf4389 Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Sat, 10 Jun 2006 09:54:16 -0700 Subject: [PATCH 79/95] [PATCH] powerpc: console_initcall ordering issues From: Milton Miller The add_preferred_console call in rtas_console.c was not causing the console to be selected. It turns out that the add_preferred_console was being called after the hvc_console driver was registered. It only works when it is called before the console driver is registered. Reorder hvc_console.o after the hvc_console drivers to allow the selection during console_initcall processing. Signed-off-by: Milton Miller Signed-off-by: Anton Blanchard Cc: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/Makefile b/drivers/char/Makefile index f5b01c6d498e..fb919bfb2824 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -41,9 +41,9 @@ obj-$(CONFIG_N_HDLC) += n_hdlc.o obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o obj-$(CONFIG_SX) += sx.o generic_serial.o obj-$(CONFIG_RIO) += rio/ generic_serial.o -obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_HVC_CONSOLE) += hvc_vio.o hvsi.o obj-$(CONFIG_HVC_RTAS) += hvc_rtas.o +obj-$(CONFIG_HVC_DRIVER) += hvc_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o obj-$(CONFIG_MMTIMER) += mmtimer.o From 9145bcf63575a8b78590a5beaf604001e9c8d2ef Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 10 Jun 2006 22:02:17 -0700 Subject: [PATCH 80/95] [SPARC64]: Set appropriate max_cache_size. Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 4e8cd79156e0..f03d52d0b88d 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -1287,6 +1287,40 @@ int setup_profiling_timer(unsigned int multiplier) return 0; } +static void __init smp_tune_scheduling(void) +{ + int instance, node; + unsigned int def, smallest = ~0U; + + def = ((tlb_type == hypervisor) ? + (3 * 1024 * 1024) : + (4 * 1024 * 1024)); + + instance = 0; + while (!cpu_find_by_instance(instance, &node, NULL)) { + unsigned int val; + + val = prom_getintdefault(node, "ecache-size", def); + if (val < smallest) + smallest = val; + + instance++; + } + + /* Any value less than 256K is nonsense. */ + if (smallest < (256U * 1024U)) + smallest = 256 * 1024; + + max_cache_size = smallest; + + if (smallest < 1U * 1024U * 1024U) + printk(KERN_INFO "Using max_cache_size of %uKB\n", + smallest / 1024U); + else + printk(KERN_INFO "Using max_cache_size of %uMB\n", + smallest / 1024U / 1024U); +} + /* Constrain the number of cpus to max_cpus. */ void __init smp_prepare_cpus(unsigned int max_cpus) { @@ -1322,6 +1356,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) } smp_store_cpu_info(boot_cpu_id); + smp_tune_scheduling(); } /* Set this up early so that things like the scheduler can init From 650fb8382287f7990d5127a82a54295139224606 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Sat, 10 Jun 2006 22:03:43 -0700 Subject: [PATCH 81/95] [SPARC]: Migration cost tune up in sparc smp. This patch sets the max_cache_size value required to tune up scheduler in SMP systems. Otherwise, the calculated migration_cost is too high and task scheduling may lock up. Signed-off-by: Krzysztof Helt Signed-off-by: David S. Miller --- arch/sparc/kernel/smp.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index a93f5da6855d..40b42c88e6a7 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -69,6 +69,17 @@ void __init smp_store_cpu_info(int id) "clock-frequency", 0); cpu_data(id).prom_node = cpu_node; cpu_data(id).mid = cpu_get_hwmid(cpu_node); + + /* this is required to tune the scheduler correctly */ + /* is it possible to have CPUs with different cache sizes? */ + if (id == boot_cpu_id) { + int cache_line,cache_nlines; + cache_line = 0x20; + cache_line = prom_getintdefault(cpu_node, "ecache-line-size", cache_line); + cache_nlines = 0x8000; + cache_nlines = prom_getintdefault(cpu_node, "ecache-nlines", cache_nlines); + max_cache_size = cache_line * cache_nlines; + } if (cpu_data(id).mid < 0) panic("No MID found for CPU%d at node 0x%08d", id, cpu_node); } From 0ce030395b92270567423d57d9d432eb77df32f2 Mon Sep 17 00:00:00 2001 From: "akpm@osdl.org" Date: Sat, 13 May 2006 08:30:52 -0700 Subject: [PATCH 82/95] [PATCH] PCI: fix pciehp compile issue when CONFIG_ACPI is not enabled Fix build error when CONFIG_ACPI not defined Signed-off-by: Kristen Carlson Accardi Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci-acpi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h index 4877e35ae202..936ef82ed76a 100644 --- a/include/linux/pci-acpi.h +++ b/include/linux/pci-acpi.h @@ -50,7 +50,7 @@ extern acpi_status pci_osc_control_set(acpi_handle handle, u32 flags); extern acpi_status pci_osc_support_set(u32 flags); #else -#if !defined(acpi_status) +#if !defined(AE_ERROR) typedef u32 acpi_status; #define AE_ERROR (acpi_status) (0x0001) #endif From 8d92bc2270d67a43b1d7e94a8cb6f81f1435fe9a Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 18 Apr 2006 14:49:56 +0200 Subject: [PATCH 83/95] [PATCH] PCI: Error handling on PCI device resume We currently don't handle errors properly when resuming a PCI device: * In pci_default_resume() we capture the error code returned by pci_enable_device() but don't pass it up to the caller. Introduced by commit 95a629657dbe28e44a312c47815b3dc3f1ce0970 * In pci_resume_device(), the errors possibly returned by the driver's .resume method or by the generic pci_default_resume() function are ignored. This patch fixes both issues. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 1456759936c5..10e1a905c144 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -285,9 +285,9 @@ static int pci_device_suspend(struct device * dev, pm_message_t state) * Default resume method for devices that have no driver provided resume, * or not even a driver at all. */ -static void pci_default_resume(struct pci_dev *pci_dev) +static int pci_default_resume(struct pci_dev *pci_dev) { - int retval; + int retval = 0; /* restore the PCI config space */ pci_restore_state(pci_dev); @@ -297,18 +297,21 @@ static void pci_default_resume(struct pci_dev *pci_dev) /* if the device was busmaster before the suspend, make it busmaster again */ if (pci_dev->is_busmaster) pci_set_master(pci_dev); + + return retval; } static int pci_device_resume(struct device * dev) { + int error; struct pci_dev * pci_dev = to_pci_dev(dev); struct pci_driver * drv = pci_dev->driver; if (drv && drv->resume) - drv->resume(pci_dev); + error = drv->resume(pci_dev); else - pci_default_resume(pci_dev); - return 0; + error = pci_default_resume(pci_dev); + return error; } static void pci_device_shutdown(struct device *dev) From 04d9c1a1100b6bdeffa7e1bfc30080bdac28e183 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 18 Apr 2006 21:06:51 -0700 Subject: [PATCH 84/95] [PATCH] PCI: Improve PCI config space writeback At least one laptop blew up on resume from suspend with a black screen due to a lack of this patch. By only writing back config space that is different, we minimise the possibility of accidents like this. Signed-off-by: Dave Jones Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2329f941a0dc..d2520451f36b 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -461,9 +461,19 @@ int pci_restore_state(struct pci_dev *dev) { int i; + int val; - for (i = 0; i < 16; i++) - pci_write_config_dword(dev,i * 4, dev->saved_config_space[i]); + for (i = 0; i < 16; i++) { + pci_read_config_dword(dev, i * 4, &val); + if (val != dev->saved_config_space[i]) { + printk(KERN_DEBUG "PM: Writing back config space on " + "device %s at offset %x (was %x, writing %x)\n", + pci_name(dev), i, + val, (int)dev->saved_config_space[i]); + pci_write_config_dword(dev,i * 4, + dev->saved_config_space[i]); + } + } pci_restore_msi_state(dev); pci_restore_msix_state(dev); return 0; From 8b8c8d280ab2d18fe6e42d671f60d4ffed451cdc Mon Sep 17 00:00:00 2001 From: "Yu, Luming" Date: Tue, 25 Apr 2006 00:00:34 -0700 Subject: [PATCH 85/95] [PATCH] PCI: reverse pci config space restore order According to Intel ICH spec, there are several rules that Base Address should be programmed before IOSE (PCICMD register ) enabled. For example ICH7: 12.1.3 SATA : the base address register for the bus master register should be programmed before this bit is set. 11.1.3: PCICMD (USB): The base address register for USB should be programmed before this bit is set. .... To make sure kernel code follow this rule , and prevent unnecessary confusion. I proposal this patch. Signed-off-by: Luming Yu Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index d2520451f36b..12286275b1c8 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -463,7 +463,11 @@ pci_restore_state(struct pci_dev *dev) int i; int val; - for (i = 0; i < 16; i++) { + /* + * The Base Address register should be programmed before the command + * register(s) + */ + for (i = 15; i >= 0; i--) { pci_read_config_dword(dev, i * 4, &val); if (val != dev->saved_config_space[i]) { printk(KERN_DEBUG "PM: Writing back config space on " From c0bbbc73d58f1b774cd987b5687a478a027f137c Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 11 Jun 2006 15:22:26 -0700 Subject: [PATCH 86/95] [PATCH] typo in vmscan.c From: Christoph Lameter Looks like a comma was left from the conversion from a struct to an assignment. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- mm/vmscan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/vmscan.c b/mm/vmscan.c index 4649a63a8cb6..440a733fe2e9 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1061,7 +1061,7 @@ static unsigned long balance_pgdat(pg_data_t *pgdat, unsigned long nr_pages, loop_again: total_scanned = 0; nr_reclaimed = 0; - sc.may_writepage = !laptop_mode, + sc.may_writepage = !laptop_mode; sc.nr_mapped = read_page_state(nr_mapped); inc_page_state(pageoutrun); From 2f9719b61e1fcf7422a016ac4f2420a0cc6ba320 Mon Sep 17 00:00:00 2001 From: Mark Lord Date: Wed, 7 Jun 2006 12:53:29 -0400 Subject: [PATCH 87/95] [PATCH] sata_mv: grab host lock inside eng_timeout Bug fix: mv_eng_timeout() calls mv_err_intr() without first grabbing the host lock, which can lead to all sorts of interesting scenarios. This whole error-handling portion of sata_mv is nasty (and will get fixed for the new EH stuff), but for now this patch will help keep it on life-support. Signed-off-by: Mark Lord Signed-off-by: Jeff Garzik --- drivers/scsi/sata_mv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c index 9b8bca1ac1f0..f16f92a6ec0f 100644 --- a/drivers/scsi/sata_mv.c +++ b/drivers/scsi/sata_mv.c @@ -2035,6 +2035,7 @@ static void mv_phy_reset(struct ata_port *ap) static void mv_eng_timeout(struct ata_port *ap) { struct ata_queued_cmd *qc; + unsigned long flags; printk(KERN_ERR "ata%u: Entering mv_eng_timeout\n",ap->id); DPRINTK("All regs @ start of eng_timeout\n"); @@ -2046,8 +2047,10 @@ static void mv_eng_timeout(struct ata_port *ap) ap->host_set->mmio_base, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd); + spin_lock_irqsave(&ap->host_set->lock, flags); mv_err_intr(ap, 0); mv_stop_and_reset(ap); + spin_unlock_irqrestore(&ap->host_set->lock, flags); WARN_ON(!(qc->flags & ATA_QCFLAG_ACTIVE)); if (qc->flags & ATA_QCFLAG_ACTIVE) { From 289a1e995e74734b5ec76ca8a5490058f4fecc24 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 12 Jun 2006 12:16:26 +1000 Subject: [PATCH 88/95] [PATCH] Fix for the PPTP hangs that have been reported People have been reporting that PPP connections over ptys, such as used with PPTP, will hang randomly when transferring large amounts of data, for instance in http://bugzilla.kernel.org/show_bug.cgi?id=6530. I have managed to reproduce the problem, and the patch below fixes the actual cause. The problem is not in fact in ppp_async.c but in n_tty.c. What happens is that when pptp reads from the pty, we call read_chan() in drivers/char/n_tty.c on the master side of the pty. That copies all the characters out of its buffer to userspace and then calls check_unthrottle(), which calls the pty unthrottle routine, which calls tty_wakeup on the slave side, which calls ppp_asynctty_wakeup, which calls tasklet_schedule. So far so good. Since we are in process context, the tasklet runs immediately and calls ppp_async_process(), which calls ppp_async_push, which calls the tty->driver->write function to send some more output. However, tty->driver->write() returns zero, because the master tty->receive_room is still zero. We haven't returned from check_unthrottle() yet, and read_chan() only updates tty->receive_room _after_ calling check_unthrottle. That means that the driver->write call in ppp_async_process() returns 0. That would be fine if we were going to get a subsequent wakeup call, but we aren't (we just had it, and the buffer is now empty). The solution is for n_tty.c to update tty->receive_room _before_ calling the driver unthrottle routine. The patch below does this. With this patch I was able to transfer a 900MB file over a PPTP connection (taking about 25 minutes), whereas without the patch the connection would always stall in under a minute. Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- drivers/char/n_tty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index ede365d05387..b9371d5bf790 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c @@ -1384,8 +1384,10 @@ do_it_again: * longer than TTY_THRESHOLD_UNTHROTTLE in canonical mode, * we won't get any more characters. */ - if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) + if (n_tty_chars_in_buffer(tty) <= TTY_THRESHOLD_UNTHROTTLE) { + n_tty_set_room(tty); check_unthrottle(tty); + } if (b - buf >= minimum) break; From ccefb5f3f60cd116d9a8ce2fa9e82e67206e49e5 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 11 Jun 2006 21:00:46 -0700 Subject: [PATCH 89/95] [SPARC64]: Do not double-export sys_close() when CONFIG_SOLARIS_EMUL_MODULE It is already exported by fs/open.c Noticed by Ben Collins. Signed-off-by: David S. Miller --- arch/sparc64/kernel/sparc64_ksyms.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 62d8a99271ea..38e569f786dd 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -297,7 +297,6 @@ EXPORT_SYMBOL(svr4_getcontext); EXPORT_SYMBOL(svr4_setcontext); EXPORT_SYMBOL(compat_sys_ioctl); EXPORT_SYMBOL(sparc32_open); -EXPORT_SYMBOL(sys_close); #endif /* Special internal versions of library functions. */ From afec35e3fee900b3016519d0b5512064e4625b2c Mon Sep 17 00:00:00 2001 From: Andrea Bittau Date: Sun, 11 Jun 2006 20:58:33 -0700 Subject: [PATCH 90/95] [DCCP] Ackvec: fix soft lockup in ackvec handling code A soft lockup existed in the handling of ack vector records. Specifically, when a tail of the list of ack vector records was removed, it was possible to end up iterating infinitely on an element of the tail. Signed-off-by: Andrea Bittau Signed-off-by: Ian McDonald Signed-off-by: David S. Miller --- net/dccp/ackvec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c index b5981e5f6b00..8c211c58893b 100644 --- a/net/dccp/ackvec.c +++ b/net/dccp/ackvec.c @@ -452,6 +452,7 @@ found: (unsigned long long) avr->dccpavr_ack_ackno); dccp_ackvec_throw_record(av, avr); + break; } /* * If it wasn't received, continue scanning... we might From 79320d7e14900c549c3520791a297328f53ff71e Mon Sep 17 00:00:00 2001 From: Aki M Nyrhinen Date: Sun, 11 Jun 2006 21:18:56 -0700 Subject: [PATCH 91/95] [TCP]: continued: reno sacked_out count fix From: Aki M Nyrhinen IMHO the current fix to the problem (in_flight underflow in reno) is incorrect. it treats the symptons but ignores the problem. the problem is timing out packets other than the head packet when we don't have sack. i try to explain (sorry if explaining the obvious). with sack, scanning the retransmit queue for timed out packets is fine because we know which packets in our retransmit queue have been acked by the receiver. without sack, we know only how many packets in our retransmit queue the receiver has acknowledged, but no idea which packets. think of a "typical" slow-start overshoot case, where for example every third packet in a window get lost because a router buffer gets full. with sack, we check for timeouts on those every third packet (as the rest have been sacked). the packet counting works out and if there is no reordering, we'll retransmit exactly the packets that were lost. without sack, however, we check for timeout on every packet and end up retransmitting consecutive packets in the retransmit queue. in our slow-start example, 2/3 of those retransmissions are unnecessary. these unnecessary retransmissions eat the congestion window and evetually prevent fast recovery from continuing, if enough packets were lost. Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 4a538bc1683d..b5521a9d3dc1 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1649,7 +1649,7 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp) * Hence, we can detect timed out packets during fast * retransmit without falling to slow start. */ - if (tcp_head_timedout(sk, tp)) { + if (!IsReno(tp) && tcp_head_timedout(sk, tp)) { struct sk_buff *skb; skb = tp->scoreboard_skb_hint ? tp->scoreboard_skb_hint @@ -1662,8 +1662,6 @@ static void tcp_update_scoreboard(struct sock *sk, struct tcp_sock *tp) if (!(TCP_SKB_CB(skb)->sacked&TCPCB_TAGBITS)) { TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; tp->lost_out += tcp_skb_pcount(skb); - if (IsReno(tp)) - tcp_remove_reno_sacks(sk, tp, tcp_skb_pcount(skb) + 1); /* clear xmit_retrans hint */ if (tp->retransmit_skb_hint && From d374c1c1281d6188a0d0676172b1c0e3de35c6e7 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 12 Jun 2006 12:53:27 -0700 Subject: [PATCH 92/95] [sky2] Fix sky2 network driver suspend/resume This fixes two independent problems: it would not save the PCI state on suspend (and thus try to resume a nonexistent state on resume), and while shut off, if an interrupt happened on the same shared irq, the irq handler would react very badly to the interrupt status being an invalid all-ones state. Acked-by: Jeff Garzik Signed-off-by: Linus Torvalds --- drivers/net/sky2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 959109609d85..6b87c7a5c906 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -2183,6 +2183,9 @@ static int sky2_poll(struct net_device *dev0, int *budget) int work_done = 0; u32 status = sky2_read32(hw, B0_Y2_SP_EISR); + if (!~status) + return 0; + if (status & Y2_IS_HW_ERR) sky2_hw_intr(hw); @@ -3438,6 +3441,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) } } + pci_save_state(pdev); return sky2_set_power_state(hw, pci_choose_state(pdev, state)); } From 42d1d52e695d87475846e9a09964cae1209eeecb Mon Sep 17 00:00:00 2001 From: Weidong Date: Mon, 12 Jun 2006 13:09:59 -0700 Subject: [PATCH 93/95] [IPV4]: Increment ipInHdrErrors when TTL expires. Signed-off-by: Weidong Signed-off-by: David S. Miller --- net/ipv4/ip_forward.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 0923add122b4..9f0bb529ab70 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c @@ -116,6 +116,7 @@ sr_failed: too_many_hops: /* Tell the sender its packet died... */ + IP_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0); drop: kfree_skb(skb); From cfd95a9cf58cd9e92d4c23b5ee20b07a3d121477 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Mon, 12 Jun 2006 21:50:25 +0100 Subject: [PATCH 94/95] [PATCH] tmpfs: time granularity fix for [acm]time going backwards I noticed a strange behavior in a tmpfs file system the other day, while building packages - occasionally, and seemingly at random, make decided to rebuild a target. However, only on tmpfs. A file would be created, and if checked, it had a sub-second timestamp. However, after an utimes related call where sub-seconds should be set, they were zeroed instead. In the case that a file was created, and utimes(...,NULL) was used on it in the same second, the timestamp on the file moved backwards. After some digging, I found that this was being caused by tmpfs not having a time granularity set, thus inheriting the default 1 second granularity. Hugh adds: yes, we missed tmpfs when the s_time_gran mods went into 2.6.11. Unfortunately, the granularity of CURRENT_TIME, often used in filesystems, does not match the default granularity set by alloc_super. A few more such discrepancies have been found, but this is the most important to fix now. Signed-off-by: Robin H. Johnson Acked-by: Andi Kleen Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- mm/shmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/shmem.c b/mm/shmem.c index 4c5e68e4e9ae..73f7a9dfcd37 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2102,6 +2102,7 @@ static int shmem_fill_super(struct super_block *sb, sb->s_blocksize_bits = PAGE_CACHE_SHIFT; sb->s_magic = TMPFS_MAGIC; sb->s_op = &shmem_ops; + sb->s_time_gran = 1; inode = shmem_get_inode(sb, S_IFDIR | mode, 0); if (!inode) From 86bc843a268058df558844b6bf64531617fbc698 Mon Sep 17 00:00:00 2001 From: Sergey Vlasov Date: Mon, 12 Jun 2006 21:53:23 +0100 Subject: [PATCH 95/95] [PATCH] tmpfs: Decrement i_nlink correctly in shmem_rmdir() shmem_rmdir() must undo the increment of i_nlink done in shmem_get_inode() for directories, otherwise at least IN_DELETE_SELF inotify event generation is broken. Signed-off-by: Sergey Vlasov Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- mm/shmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/shmem.c b/mm/shmem.c index 73f7a9dfcd37..1e43c8a865ba 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1780,6 +1780,7 @@ static int shmem_rmdir(struct inode *dir, struct dentry *dentry) if (!simple_empty(dentry)) return -ENOTEMPTY; + dentry->d_inode->i_nlink--; dir->i_nlink--; return shmem_unlink(dir, dentry); }