## Automatically generated incremental diff ## From: linux-2.6.21-rc4 ## To: linux-2.6.21-rc5 ## Robot: $Id: make-incremental-diff,v 1.12 2004/01/06 07:19:36 hpa Exp $ drivers/ide/ppc/scc_pata.c | 858 ------------------------ Documentation/crypto/api-intro.txt | 2 Documentation/gpio.txt | 5 Documentation/kernel-parameters.txt | 11 Documentation/sound/alsa/ALSA-Configuration.txt | 4 Documentation/sysrq.txt | 2 MAINTAINERS | 8 Makefile | 2 arch/arm/kernel/setup.c | 7 arch/arm/mach-at91/gpio.c | 3 arch/arm/mach-iop32x/Kconfig | 4 arch/arm/mach-iop32x/iq31244.c | 59 + arch/arm/mach-s3c2410/mach-h1940.c | 2 arch/arm/mach-s3c2440/mach-rx3715.c | 2 arch/arm/mach-s3c2443/irq.c | 2 arch/arm/mach-sa1100/generic.c | 4 arch/avr32/mach-at32ap/pio.c | 4 arch/i386/defconfig | 43 - arch/i386/kernel/apic.c | 143 ++-- arch/i386/kernel/i386_ksyms.c | 2 arch/i386/kernel/i8253.c | 10 arch/i386/kernel/tsc.c | 9 arch/i386/kernel/vmi.c | 17 arch/ia64/Kconfig | 1 arch/ia64/kernel/crash.c | 2 arch/ia64/kernel/setup.c | 22 arch/ia64/mm/contig.c | 30 arch/ia64/mm/discontig.c | 4 arch/ia64/mm/init.c | 16 arch/ia64/sn/kernel/io_init.c | 12 arch/ia64/sn/kernel/setup.c | 6 arch/mips/Kconfig | 19 arch/mips/ddb5xxx/ddb5477/irq.c | 2 arch/mips/emma2rh/markeins/irq.c | 2 arch/mips/gt64120/ev64120/irq.c | 2 arch/mips/gt64120/wrppmc/irq.c | 2 arch/mips/jazz/irq.c | 2 arch/mips/jazz/jazzdma.c | 3 arch/mips/kernel/genex.S | 16 arch/mips/kernel/kspd.c | 18 arch/mips/kernel/linux32.c | 12 arch/mips/kernel/r2300_switch.S | 10 arch/mips/kernel/r4k_fpu.S | 16 arch/mips/kernel/r4k_switch.S | 10 arch/mips/kernel/rtlx.c | 104 +- arch/mips/kernel/signal-common.h | 3 arch/mips/kernel/signal.c | 75 +- arch/mips/kernel/signal32.c | 56 + arch/mips/kernel/signal_n32.c | 6 arch/mips/kernel/traps.c | 84 +- arch/mips/math-emu/kernel_linkage.c | 8 arch/mips/mips-boards/generic/init.c | 2 arch/mips/mm/c-r3k.c | 2 arch/mips/mm/cache.c | 16 arch/mips/mm/cerr-sb1.c | 9 arch/mips/mm/dma-default.c | 17 arch/mips/mm/init.c | 6 arch/mips/mm/pg-sb1.c | 3 arch/mips/momentum/ocelot_c/irq.c | 2 arch/mips/pci/pci-bcm1480.c | 2 arch/mips/pci/pci-sb1250.c | 2 arch/mips/philips/pnx8550/common/int.c | 7 arch/mips/qemu/q-smp.c | 7 arch/mips/sgi-ip22/ip22-int.c | 2 arch/mips/sgi-ip32/ip32-irq.c | 2 arch/mips/sibyte/bcm1480/smp.c | 6 arch/mips/sibyte/sb1250/irq.c | 2 arch/mips/sibyte/swarm/setup.c | 18 arch/mips/sni/pcimt.c | 2 arch/mips/sni/pcit.c | 4 arch/mips/tx4927/common/tx4927_irq.c | 2 arch/powerpc/kernel/process.c | 9 arch/powerpc/platforms/pseries/hvCall.S | 41 + arch/powerpc/platforms/pseries/lpar.c | 2 arch/powerpc/platforms/pseries/plpar_wrappers.h | 16 arch/s390/kernel/compat_wrapper.S | 17 arch/s390/kernel/debug.c | 2 arch/s390/kernel/early.c | 10 arch/s390/kernel/ipl.c | 9 arch/s390/kernel/syscalls.S | 3 arch/sh/drivers/pci/pci-auto.c | 6 arch/sh/kernel/cpu/init.c | 20 arch/sh/kernel/cpu/sh2/entry.S | 1 arch/sh/kernel/cpu/sh3/entry.S | 5 arch/sh/kernel/cpu/sh4/probe.c | 13 arch/sh/kernel/irq.c | 15 arch/sparc64/Kconfig | 14 arch/sparc64/defconfig | 10 arch/sparc64/kernel/ktlb.S | 8 arch/sparc64/kernel/tsb.S | 1 arch/sparc64/lib/NGbzero.S | 1 arch/sparc64/lib/NGmemcpy.S | 2 arch/sparc64/lib/NGpage.S | 2 arch/sparc64/mm/init.c | 30 arch/x86_64/defconfig | 53 + arch/x86_64/ia32/ia32entry.S | 2 arch/x86_64/kernel/apic.c | 19 arch/x86_64/kernel/cpufreq/Kconfig | 1 arch/x86_64/kernel/e820.c | 2 arch/x86_64/kernel/early-quirks.c | 8 arch/x86_64/kernel/mpparse.c | 4 arch/x86_64/kernel/pci-gart.c | 2 arch/x86_64/kernel/process.c | 13 arch/x86_64/kernel/x8664_ksyms.c | 1 crypto/scatterwalk.c | 4 crypto/tcrypt.c | 2 drivers/acpi/events/evmisc.c | 8 drivers/acpi/events/evregion.c | 15 drivers/acpi/events/evxface.c | 6 drivers/acpi/executer/excreate.c | 5 drivers/acpi/executer/exsystem.c | 30 drivers/acpi/executer/exutils.c | 104 -- drivers/acpi/hardware/hwsleep.c | 5 drivers/acpi/ibm_acpi.c | 19 drivers/acpi/namespace/nseval.c | 11 drivers/acpi/namespace/nsinit.c | 7 drivers/acpi/namespace/nsxfeval.c | 11 drivers/acpi/processor_idle.c | 3 drivers/acpi/tables.c | 57 + drivers/ata/Kconfig | 2 drivers/ata/libata-core.c | 2 drivers/ata/libata-eh.c | 8 drivers/ata/pata_ixp4xx_cf.c | 3 drivers/ata/sata_inic162x.c | 4 drivers/ata/sata_sil24.c | 1 drivers/char/lcd.c | 5 drivers/char/tty_io.c | 5 drivers/char/vt.c | 21 drivers/char/vt_ioctl.c | 2 drivers/char/watchdog/machzwd.c | 28 drivers/dma/dmaengine.c | 18 drivers/hwmon/Kconfig | 1 drivers/i2c/busses/i2c-amd8111.c | 3 drivers/i2c/busses/i2c-i801.c | 25 drivers/i2c/chips/ds1374.c | 4 drivers/ide/Kconfig | 48 - drivers/ide/Makefile | 1 drivers/ide/arm/icside.c | 13 drivers/ide/ide-dma.c | 2 drivers/ide/ide.c | 4 drivers/ide/mips/au1xxx-ide.c | 3 drivers/ide/pci/Makefile | 1 drivers/ide/pci/cmd64x.c | 49 - drivers/ide/pci/jmicron.c | 29 drivers/ide/pci/scc_pata.c | 858 ++++++++++++++++++++++++ drivers/ide/setup-pci.c | 5 drivers/ieee1394/eth1394.c | 3 drivers/infiniband/hw/cxgb3/iwch_provider.c | 5 drivers/infiniband/hw/ehca/ehca_irq.c | 8 drivers/infiniband/hw/ipath/ipath_fs.c | 16 drivers/infiniband/ulp/ipoib/ipoib_cm.c | 4 drivers/infiniband/ulp/ipoib/ipoib_ib.c | 4 drivers/infiniband/ulp/ipoib/ipoib_main.c | 4 drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 6 drivers/kvm/kvm_main.c | 4 drivers/kvm/mmu.c | 52 + drivers/kvm/vmx.c | 8 drivers/md/linear.c | 2 drivers/media/dvb/frontends/nxt200x.c | 4 drivers/net/Kconfig | 27 drivers/net/cxgb3/common.h | 15 drivers/net/cxgb3/cxgb3_main.c | 90 ++ drivers/net/cxgb3/regs.h | 22 drivers/net/cxgb3/t3_hw.c | 15 drivers/net/cxgb3/xgmac.c | 133 +++ drivers/net/ewrk3.c | 3 drivers/net/irda/irda-usb.c | 2 drivers/net/mv643xx_eth.c | 14 drivers/net/myri10ge/myri10ge.c | 22 drivers/net/pci-skeleton.c | 4 drivers/net/saa9730.c | 177 ++-- drivers/net/sb1250-mac.c | 2 drivers/net/skge.c | 110 +-- drivers/net/skge.h | 6 drivers/net/ucc_geth.c | 3 drivers/net/wireless/airo.c | 4 drivers/net/wireless/bcm43xx/bcm43xx_radio.c | 14 drivers/pnp/manager.c | 6 drivers/s390/cio/qdio.c | 26 drivers/s390/crypto/ap_bus.c | 30 drivers/s390/crypto/ap_bus.h | 1 drivers/s390/crypto/zcrypt_api.c | 12 drivers/serial/8250_pnp.c | 3 drivers/serial/sh-sci.c | 11 drivers/spi/at25.c | 2 drivers/spi/atmel_spi.c | 2 drivers/spi/spi_bitbang.c | 26 drivers/spi/spi_s3c24xx.c | 2 drivers/usb/class/usblp.c | 6 drivers/usb/misc/berry_charge.c | 2 drivers/usb/net/dm9601.c | 8 drivers/usb/serial/airprime.c | 4 drivers/usb/serial/mos7720.c | 1 drivers/usb/serial/option.c | 15 drivers/usb/serial/usb-serial.c | 11 drivers/usb/storage/unusual_devs.h | 10 drivers/video/Kconfig | 6 drivers/video/riva/fbdev.c | 4 drivers/video/s3fb.c | 3 drivers/video/savage/savagefb_driver.c | 18 drivers/video/sstfb.c | 1 fs/binfmt_elf.c | 2 fs/binfmt_elf_fdpic.c | 15 fs/cifs/CHANGES | 6 fs/cifs/cifspdu.h | 8 fs/cifs/inode.c | 21 fs/cifs/readdir.c | 4 fs/ecryptfs/dentry.c | 15 fs/ext3/xattr.c | 3 fs/nfs/inode.c | 3 fs/nfs/super.c | 4 fs/nfs/sysctl.c | 8 fs/nfs/write.c | 116 ++- fs/partitions/Kconfig | 3 fs/partitions/check.c | 2 fs/smbfs/request.c | 1 fs/ufs/balloc.c | 86 +- fs/ufs/ialloc.c | 5 fs/ufs/inode.c | 36 - fs/ufs/truncate.c | 38 - fs/xfs/linux-2.6/xfs_buf.c | 4 include/acpi/acinterp.h | 6 include/acpi/actypes.h | 2 include/asm-arm/arch-at91/gpio.h | 2 include/asm-arm/arch-ns9xxx/clock.h | 10 include/asm-arm/arch-omap/gpio.h | 3 include/asm-arm/arch-pxa/gpio.h | 4 include/asm-arm/arch-pxa/pxa-regs.h | 2 include/asm-arm/arch-s3c2410/gpio.h | 4 include/asm-arm/arch-sa1100/gpio.h | 2 include/asm-arm/atomic.h | 4 include/asm-avr32/arch-at32ap/gpio.h | 2 include/asm-i386/apic.h | 1 include/asm-i386/elf.h | 10 include/asm-i386/sync_bitops.h | 2 include/asm-ia64/machvec.h | 2 include/asm-ia64/meminit.h | 1 include/asm-mips/atomic.h | 40 - include/asm-mips/bitops.h | 24 include/asm-mips/cacheflush.h | 12 include/asm-mips/cpu-features.h | 3 include/asm-mips/cpu-info.h | 1 include/asm-mips/delay.h | 2 include/asm-mips/fpu.h | 54 + include/asm-mips/hazards.h | 1 include/asm-mips/mach-au1x00/au1xxx_ide.h | 34 include/asm-mips/mach-ip27/dma-coherence.h | 5 include/asm-mips/mach-ip32/dma-coherence.h | 5 include/asm-mips/pgtable-64.h | 2 include/asm-mips/pgtable.h | 2 include/asm-mips/rtlx.h | 4 include/asm-mips/sgiarcs.h | 2 include/asm-mips/sibyte/sb1250.h | 2 include/asm-mips/system.h | 16 include/asm-mips/thread_info.h | 1 include/asm-powerpc/hvcall.h | 14 include/asm-s390/ipl.h | 5 include/asm-s390/unistd.h | 3 include/asm-sh/ioctls.h | 22 include/asm-sh/irq.h | 5 include/asm-sh/unistd.h | 1 include/asm-sparc64/tsb.h | 2 include/asm-x86_64/apic.h | 1 include/asm-x86_64/proto.h | 2 include/asm-x86_64/smp.h | 3 include/linux/backing-dev.h | 1 include/linux/bootmem.h | 2 include/linux/kbd_kern.h | 2 include/linux/ktime.h | 6 include/linux/lockdep.h | 2 include/linux/nfs_fs.h | 1 include/linux/nfs_fs_sb.h | 1 include/linux/spi/spi_bitbang.h | 1 include/linux/sysfs.h | 1 include/linux/ufs_fs.h | 8 include/linux/vt_kern.h | 1 include/net/sctp/structs.h | 1 include/net/sctp/ulpqueue.h | 1 include/sound/version.h | 2 kernel/fork.c | 2 kernel/futex.c | 2 kernel/hrtimer.c | 11 kernel/lockdep.c | 8 kernel/power/console.c | 10 kernel/power/disk.c | 8 kernel/power/user.c | 12 kernel/time/clocksource.c | 3 kernel/time/tick-broadcast.c | 27 kernel/time/tick-common.c | 13 kernel/time/tick-internal.h | 11 kernel/time/tick-oneshot.c | 12 kernel/time/timer_list.c | 6 kernel/timer.c | 19 mm/backing-dev.c | 16 mm/filemap.c | 46 - mm/madvise.c | 5 mm/nommu.c | 28 mm/oom_kill.c | 2 net/bluetooth/hidp/core.c | 2 net/bridge/br_fdb.c | 4 net/bridge/br_netfilter.c | 2 net/core/fib_rules.c | 2 net/core/skbuff.c | 1 net/core/sock.c | 2 net/ieee80211/Kconfig | 6 net/ipv4/fib_trie.c | 2 net/ipv4/netfilter/ip_nat_standalone.c | 15 net/ipv4/netfilter/nf_nat_standalone.c | 14 net/ipv4/tcp.c | 13 net/ipv6/addrconf.c | 6 net/ipv6/route.c | 4 net/ipv6/tcp_ipv6.c | 1 net/ipv6/xfrm6_tunnel.c | 4 net/irda/irnet/irnet.h | 2 net/irda/irnet/irnet_irda.c | 34 net/irda/irttp.c | 1 net/netfilter/Kconfig | 1 net/sched/cls_route.c | 2 net/sctp/associola.c | 15 net/sctp/sm_statefuns.c | 20 net/sctp/transport.c | 32 net/sctp/ulpqueue.c | 2 net/x25/x25_forward.c | 86 +- net/xfrm/xfrm_policy.c | 2 net/xfrm/xfrm_user.c | 2 sound/pci/ac97/ac97_patch.c | 13 sound/pci/hda/hda_intel.c | 17 sound/pci/hda/patch_analog.c | 41 + sound/pci/hda/patch_realtek.c | 2 sound/pci/hda/patch_sigmatel.c | 30 sound/pci/intel8x0.c | 10 sound/soc/Kconfig | 2 sound/soc/at91/Kconfig | 3 sound/soc/pxa/Kconfig | 3 334 files changed, 3688 insertions(+), 2312 deletions(-) Index: linux-2.6.21-rc5/Documentation/crypto/api-intro.txt =================================================================== --- linux-2.6.21-rc5.orig/Documentation/crypto/api-intro.txt 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Documentation/crypto/api-intro.txt 2007-03-27 14:20:38.000000000 +0100 @@ -60,7 +60,7 @@ Here's an example of how to use the API: desc.tfm = tfm; desc.flags = 0; - if (crypto_hash_digest(&desc, &sg, 2, result)) + if (crypto_hash_digest(&desc, sg, 2, result)) fail(); crypto_free_hash(tfm); Index: linux-2.6.21-rc5/Documentation/gpio.txt =================================================================== --- linux-2.6.21-rc5.orig/Documentation/gpio.txt 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Documentation/gpio.txt 2007-03-27 14:20:38.000000000 +0100 @@ -105,12 +105,15 @@ setting up a platform_device using the G /* set as input or output, returning 0 or negative errno */ int gpio_direction_input(unsigned gpio); - int gpio_direction_output(unsigned gpio); + int gpio_direction_output(unsigned gpio, int value); The return value is zero for success, else a negative errno. It should be checked, since the get/set calls don't have error returns and since misconfiguration is possible. (These calls could sleep.) +For output GPIOs, the value provided becomes the initial output value. +This helps avoid signal glitching during system startup. + Setting the direction can fail if the GPIO number is invalid, or when that particular GPIO can't be used in that mode. It's generally a bad idea to rely on boot firmware to have set the direction correctly, since Index: linux-2.6.21-rc5/Documentation/kernel-parameters.txt =================================================================== --- linux-2.6.21-rc5.orig/Documentation/kernel-parameters.txt 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Documentation/kernel-parameters.txt 2007-03-27 14:20:38.000000000 +0100 @@ -138,6 +138,12 @@ and is between 256 and 4096 characters. See also Documentation/pm.txt, pci=noacpi + acpi_apic_instance= [ACPI, IOAPIC] + Format: + 2: use 2nd APIC table, if available + 1,0: use 1st APIC table + default: 2 + acpi_sleep= [HW,ACPI] Sleep options Format: { s3_bios, s3_mode } See Documentation/power/video.txt @@ -774,6 +780,9 @@ and is between 256 and 4096 characters. lapic [IA-32,APIC] Enable the local APIC even if BIOS disabled it. + lapic_timer_c2_ok [IA-32,x86-64,APIC] trust the local apic timer in + C2 power state. + lasi= [HW,SCSI] PARISC LASI driver for the 53c700 chip Format: addr:,irq: @@ -1117,6 +1126,8 @@ and is between 256 and 4096 characters. nolapic [IA-32,APIC] Do not enable or use the local APIC. + nolapic_timer [IA-32,APIC] Do not use the local APIC timer. + noltlbs [PPC] Do not use large page/tlb entries for kernel lowmem mapping on PPC40x. Index: linux-2.6.21-rc5/Documentation/sound/alsa/ALSA-Configuration.txt =================================================================== --- linux-2.6.21-rc5.orig/Documentation/sound/alsa/ALSA-Configuration.txt 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Documentation/sound/alsa/ALSA-Configuration.txt 2007-03-27 14:20:38.000000000 +0100 @@ -866,6 +866,7 @@ Prior to version 0.9.0rc4 options had a basic 3-jack (default) hp HP nx6320 thinkpad Lenovo Thinkpad T60/X60/Z60 + toshiba Toshiba U205 AD1986A 6stack 6-jack, separate surrounds (default) @@ -906,7 +907,8 @@ Prior to version 0.9.0rc4 options had a 5stack D945 5stack + SPDIF macmini Intel Mac Mini macbook Intel Mac Book - macbook-pro Intel Mac Book Pro + macbook-pro-v1 Intel Mac Book Pro 1st generation + macbook-pro Intel Mac Book Pro 2nd generation STAC9202/9250/9251 ref Reference board, base config Index: linux-2.6.21-rc5/Documentation/sysrq.txt =================================================================== --- linux-2.6.21-rc5.orig/Documentation/sysrq.txt 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Documentation/sysrq.txt 2007-03-27 14:20:38.000000000 +0100 @@ -93,6 +93,8 @@ On all - write a character to /proc/sys 'p' - Will dump the current registers and flags to your console. +'q' - Will dump a list of all running timers. + 'r' - Turns off keyboard raw mode and sets it to XLATE. 's' - Will attempt to sync all mounted filesystems. Index: linux-2.6.21-rc5/MAINTAINERS =================================================================== --- linux-2.6.21-rc5.orig/MAINTAINERS 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/MAINTAINERS 2007-03-27 14:20:38.000000000 +0100 @@ -3066,11 +3066,10 @@ L: netdev@vger.kernel.org S: Maintained SONY VAIO CONTROL DEVICE DRIVER -P: Stelian Pop -M: stelian@popies.net P: Mattia Dongili M: malattia@linux.it -W: http://popies.net/sonypi/ +L: linux-acpi@vger.kernel.org +W: http://www.linux.it/~malattia/wiki/index.php/Sony_drivers S: Maintained SOUND @@ -3103,6 +3102,9 @@ TPM DEVICE DRIVER P: Kylene Hall M: kjhall@us.ibm.com W: http://tpmdd.sourceforge.net +P: Marcel Selhorst +M: tpm@selhorst.net +W: http://www.prosec.rub.de/tpm/ L: tpmdd-devel@lists.sourceforge.net S: Maintained Index: linux-2.6.21-rc5/Makefile =================================================================== --- linux-2.6.21-rc5.orig/Makefile 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/Makefile 2007-03-27 14:20:38.000000000 +0100 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 21 -EXTRAVERSION = -rc4 +EXTRAVERSION = -rc5 NAME = Nocturnal Monster Puppy # *DOCUMENTATION* Index: linux-2.6.21-rc5/arch/arm/kernel/setup.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/kernel/setup.c 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/kernel/setup.c 2007-03-27 14:20:38.000000000 +0100 @@ -839,8 +839,11 @@ static int __init topology_init(void) { int cpu; - for_each_possible_cpu(cpu) - register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); + for_each_possible_cpu(cpu) { + struct cpuinfo_arm *cpuinfo = &per_cpu(cpu_data, cpu); + cpuinfo->cpu.hotpluggable = 1; + register_cpu(&cpuinfo->cpu, cpu); + } return 0; } Index: linux-2.6.21-rc5/arch/arm/mach-at91/gpio.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-at91/gpio.c 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-at91/gpio.c 2007-03-27 14:20:38.000000000 +0100 @@ -215,13 +215,14 @@ int gpio_direction_input(unsigned pin) } EXPORT_SYMBOL(gpio_direction_input); -int gpio_direction_output(unsigned pin) +int gpio_direction_output(unsigned pin, int value) { void __iomem *pio = pin_to_controller(pin); unsigned mask = pin_to_mask(pin); if (!pio || !(__raw_readl(pio + PIO_PSR) & mask)) return -EINVAL; + __raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR)); __raw_writel(mask, pio + PIO_OER); return 0; } Index: linux-2.6.21-rc5/arch/arm/mach-iop32x/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-iop32x/Kconfig 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-iop32x/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -4,6 +4,9 @@ menu "IOP32x Implementation Options" comment "IOP32x Platform Types" +config MACH_EP80219 + bool + config MACH_GLANTANK bool "Enable support for the IO-Data GLAN Tank" help @@ -19,6 +22,7 @@ config ARCH_IQ80321 config ARCH_IQ31244 bool "Enable support for EP80219/IQ31244" + select MACH_EP80219 help Say Y here if you want to run your kernel on the Intel EP80219 evaluation kit for the Intel 80219 processor (a IOP321 variant) Index: linux-2.6.21-rc5/arch/arm/mach-iop32x/iq31244.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-iop32x/iq31244.c 2007-03-27 14:20:35.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-iop32x/iq31244.c 2007-03-27 14:20:38.000000000 +0100 @@ -39,22 +39,35 @@ #include /* - * The EP80219 and IQ31244 use the same machine ID. To find out - * which of the two we're running on, we look at the processor ID. + * Until March of 2007 iq31244 platforms and ep80219 platforms shared the + * same machine id, and the processor type was used to select board type. + * However this assumption breaks for an iq80219 board which is an iop219 + * processor on an iq31244 board. The force_ep80219 flag has been added + * for old boot loaders using the iq31244 machine id for an ep80219 platform. */ +static int force_ep80219; + static int is_80219(void) { extern int processor_id; return !!((processor_id & 0xffffffe0) == 0x69052e20); } +static int is_ep80219(void) +{ + if (machine_is_ep80219() || force_ep80219) + return 1; + else + return 0; +} + /* * EP80219/IQ31244 timer tick configuration. */ static void __init iq31244_timer_init(void) { - if (is_80219()) { + if (is_ep80219()) { /* 33.333 MHz crystal. */ iop_init_time(200000000); } else { @@ -165,12 +178,18 @@ static struct hw_pci iq31244_pci __initd static int __init iq31244_pci_init(void) { - if (machine_is_iq31244()) { + if (is_ep80219()) + pci_common_init(&ep80219_pci); + else if (machine_is_iq31244()) { if (is_80219()) { - pci_common_init(&ep80219_pci); - } else { - pci_common_init(&iq31244_pci); + printk("note: iq31244 board type has been selected\n"); + printk("note: to select ep80219 operation:\n"); + printk("\t1/ specify \"force_ep80219\" on the kernel" + " command line\n"); + printk("\t2/ update boot loader to pass" + " the ep80219 id: %d\n", MACH_TYPE_EP80219); } + pci_common_init(&iq31244_pci); } return 0; @@ -277,10 +296,18 @@ static void __init iq31244_init_machine( platform_device_register(&iq31244_flash_device); platform_device_register(&iq31244_serial_device); - if (is_80219()) + if (is_ep80219()) pm_power_off = ep80219_power_off; } +static int __init force_ep80219_setup(char *str) +{ + force_ep80219 = 1; + return 1; +} + +__setup("force_ep80219", force_ep80219_setup); + MACHINE_START(IQ31244, "Intel IQ31244") /* Maintainer: Intel Corp. */ .phys_io = IQ31244_UART, @@ -291,3 +318,19 @@ MACHINE_START(IQ31244, "Intel IQ31244") .timer = &iq31244_timer, .init_machine = iq31244_init_machine, MACHINE_END + +/* There should have been an ep80219 machine identifier from the beginning. + * Boot roms older than March 2007 do not know the ep80219 machine id. Pass + * "force_ep80219" on the kernel command line, otherwise iq31244 operation + * will be selected. + */ +MACHINE_START(EP80219, "Intel EP80219") + /* Maintainer: Intel Corp. */ + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .boot_params = 0xa0000100, + .map_io = iq31244_map_io, + .init_irq = iop32x_init_irq, + .timer = &iq31244_timer, + .init_machine = iq31244_init_machine, +MACHINE_END Index: linux-2.6.21-rc5/arch/arm/mach-s3c2410/mach-h1940.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-s3c2410/mach-h1940.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-s3c2410/mach-h1940.c 2007-03-27 14:20:38.000000000 +0100 @@ -202,7 +202,9 @@ static void __init h1940_map_io(void) /* setup PM */ +#ifdef CONFIG_PM_H1940 memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); +#endif s3c2410_pm_init(); } Index: linux-2.6.21-rc5/arch/arm/mach-s3c2440/mach-rx3715.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-s3c2440/mach-rx3715.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-s3c2440/mach-rx3715.c 2007-03-27 14:20:38.000000000 +0100 @@ -224,7 +224,9 @@ static void __init rx3715_init_irq(void) static void __init rx3715_init_machine(void) { +#ifdef CONFIG_PM_H1940 memcpy(phys_to_virt(H1940_SUSPEND_RESUMEAT), h1940_pm_return, 1024); +#endif s3c2410_pm_init(); s3c24xx_fb_set_platdata(&rx3715_lcdcfg); Index: linux-2.6.21-rc5/arch/arm/mach-s3c2443/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-s3c2443/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-s3c2443/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -137,7 +137,7 @@ static struct irq_chip s3c2443_irq_lcd = static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc) { - s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6); + s3c2443_irq_demux(IRQ_S3C2443_DMA0, 6); } #define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0)) Index: linux-2.6.21-rc5/arch/arm/mach-sa1100/generic.c =================================================================== --- linux-2.6.21-rc5.orig/arch/arm/mach-sa1100/generic.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/arm/mach-sa1100/generic.c 2007-03-27 14:20:38.000000000 +0100 @@ -27,6 +27,7 @@ #include #include #include +#include #include "generic.h" @@ -153,7 +154,7 @@ int gpio_direction_input(unsigned gpio) EXPORT_SYMBOL(gpio_direction_input); -int gpio_direction_output(unsigned gpio) +int gpio_direction_output(unsigned gpio, int value) { unsigned long flags; @@ -161,6 +162,7 @@ int gpio_direction_output(unsigned gpio) return -EINVAL; local_irq_save(flags); + gpio_set_value(gpio, value); GPDR |= GPIO_GPIO(gpio); local_irq_restore(flags); return 0; Index: linux-2.6.21-rc5/arch/avr32/mach-at32ap/pio.c =================================================================== --- linux-2.6.21-rc5.orig/arch/avr32/mach-at32ap/pio.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/avr32/mach-at32ap/pio.c 2007-03-27 14:20:38.000000000 +0100 @@ -214,7 +214,7 @@ int gpio_direction_input(unsigned int gp } EXPORT_SYMBOL(gpio_direction_input); -int gpio_direction_output(unsigned int gpio) +int gpio_direction_output(unsigned int gpio, int value) { struct pio_device *pio; unsigned int pin; @@ -223,6 +223,8 @@ int gpio_direction_output(unsigned int g if (!pio) return -ENODEV; + gpio_set_value(gpio, value); + pin = gpio & 0x1f; pio_writel(pio, OER, 1 << pin); Index: linux-2.6.21-rc5/arch/i386/defconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/defconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/defconfig 2007-03-27 14:20:38.000000000 +0100 @@ -1,10 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-git8 -# Tue Feb 13 11:25:18 2007 +# Linux kernel version: 2.6.21-rc3 +# Wed Mar 7 15:29:47 2007 # CONFIG_X86_32=y CONFIG_GENERIC_TIME=y +CONFIG_CLOCKSOURCE_WATCHDOG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -34,6 +37,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set @@ -44,6 +48,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y @@ -103,6 +108,9 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Processor type and features # +# CONFIG_TICK_ONESHOT is not set +# CONFIG_NO_HZ is not set +# CONFIG_HIGH_RES_TIMERS is not set CONFIG_SMP=y # CONFIG_X86_PC is not set # CONFIG_X86_ELAN is not set @@ -235,10 +243,8 @@ CONFIG_ACPI_PROCFS=y CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y -# CONFIG_ACPI_HOTKEY is not set CONFIG_ACPI_FAN=y # CONFIG_ACPI_DOCK is not set -# CONFIG_ACPI_BAY is not set CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_THERMAL=y # CONFIG_ACPI_ASUS is not set @@ -289,6 +295,7 @@ CONFIG_X86_POWERNOW_K8_ACPI=y # CONFIG_X86_CPUFREQ_NFORCE2 is not set # CONFIG_X86_LONGRUN is not set # CONFIG_X86_LONGHAUL is not set +# CONFIG_X86_E_POWERSAVER is not set # # shared options @@ -368,7 +375,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set +CONFIG_INET_TUNNEL=y CONFIG_INET_XFRM_MODE_TRANSPORT=y CONFIG_INET_XFRM_MODE_TUNNEL=y # CONFIG_INET_XFRM_MODE_BEET is not set @@ -470,7 +477,13 @@ CONFIG_FW_LOADER=y # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -490,7 +503,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -500,6 +512,7 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_IBM_ASM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_SONY_LAPTOP is not set # # ATA/ATAPI/MFM/RLL support @@ -526,6 +539,7 @@ CONFIG_BLK_DEV_IDEACPI=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -679,6 +693,7 @@ CONFIG_SATA_VIA=y # CONFIG_SATA_VITESSE is not set # CONFIG_SATA_INIC162X is not set CONFIG_SATA_INTEL_COMBINED=y +CONFIG_SATA_ACPI=y # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set @@ -786,6 +801,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set +# CONFIG_NET_SB1000 is not set # # ARCnet devices @@ -979,6 +995,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -1065,6 +1082,11 @@ CONFIG_HANGCHECK_TIMER=y # CONFIG_HWMON_VID is not set # +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -1078,7 +1100,7 @@ CONFIG_HANGCHECK_TIMER=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # @@ -1089,7 +1111,6 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=128 CONFIG_VIDEO_SELECT=y CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1238,6 +1259,7 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1248,6 +1270,7 @@ CONFIG_USB_MON=y # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # @@ -1506,6 +1529,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1525,6 +1549,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set Index: linux-2.6.21-rc5/arch/i386/kernel/apic.c =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/kernel/apic.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/kernel/apic.c 2007-03-27 14:20:38.000000000 +0100 @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -61,6 +62,11 @@ static int enable_local_apic __initdata /* Local APIC timer verification ok */ static int local_apic_timer_verify_ok; +/* Disable local APIC timer from the kernel commandline or via dmi quirk */ +static int local_apic_timer_disabled; +/* Local APIC timer works in C2 */ +int local_apic_timer_c2_ok; +EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); /* * Debug level, exported for io_apic.c @@ -266,6 +272,32 @@ static void __devinit setup_APIC_timer(v } /* + * Detect systems with known broken BIOS implementations + */ +static int __init lapic_check_broken_bios(struct dmi_system_id *d) +{ + printk(KERN_NOTICE "%s detected: disabling lapic timer.\n", + d->ident); + local_apic_timer_disabled = 1; + return 0; +} + +static struct dmi_system_id __initdata broken_bios_dmi_table[] = { + { + /* + * BIOS exports only C1 state, but uses deeper power + * modes behind the kernels back. + */ + .callback = lapic_check_broken_bios, + .ident = "HP nx6325", + .matches = { + DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"), + }, + }, + {} +}; + +/* * In this functions we calibrate APIC bus clocks to the external timer. * * We want to do the calibration only once since we want to have local timer @@ -338,6 +370,23 @@ void __init setup_boot_APIC_clock(void) void (*real_handler)(struct clock_event_device *dev); unsigned long deltaj; long delta, deltapm; + int pm_referenced = 0; + + /* Detect know broken systems */ + dmi_check_system(broken_bios_dmi_table); + + /* + * The local apic timer can be disabled via the kernel + * commandline or from the dmi quirk above. Register the lapic + * timer as a dummy clock event source on SMP systems, so the + * broadcast mechanism is used. On UP systems simply ignore it. + */ + if (local_apic_timer_disabled) { + /* No broadcast on UP ! */ + if (num_possible_cpus() > 1) + setup_APIC_timer(); + return; + } apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" "calibrating APIC timer ...\n"); @@ -357,7 +406,8 @@ void __init setup_boot_APIC_clock(void) /* Let the interrupts run */ local_irq_enable(); - while(lapic_cal_loops <= LAPIC_CAL_LOOPS); + while (lapic_cal_loops <= LAPIC_CAL_LOOPS) + cpu_relax(); local_irq_disable(); @@ -394,6 +444,7 @@ void __init setup_boot_APIC_clock(void) "%lu (%ld)\n", (unsigned long) res, delta); delta = (long) res; } + pm_referenced = 1; } /* Calculate the scaled math multiplication factor */ @@ -423,69 +474,43 @@ void __init setup_boot_APIC_clock(void) calibration_result / (1000000 / HZ), calibration_result % (1000000 / HZ)); - - apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); - - /* - * Setup the apic timer manually - */ local_apic_timer_verify_ok = 1; - levt->event_handler = lapic_cal_handler; - lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); - lapic_cal_loops = -1; - /* Let the interrupts run */ - local_irq_enable(); + /* We trust the pm timer based calibration */ + if (!pm_referenced) { + apic_printk(APIC_VERBOSE, "... verify APIC timer\n"); - while(lapic_cal_loops <= LAPIC_CAL_LOOPS); + /* + * Setup the apic timer manually + */ + levt->event_handler = lapic_cal_handler; + lapic_timer_setup(CLOCK_EVT_MODE_PERIODIC, levt); + lapic_cal_loops = -1; - local_irq_disable(); + /* Let the interrupts run */ + local_irq_enable(); - /* Stop the lapic timer */ - lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); + while(lapic_cal_loops <= LAPIC_CAL_LOOPS) + cpu_relax(); - local_irq_enable(); + local_irq_disable(); - /* Jiffies delta */ - deltaj = lapic_cal_j2 - lapic_cal_j1; - apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); + /* Stop the lapic timer */ + lapic_timer_setup(CLOCK_EVT_MODE_SHUTDOWN, levt); - /* Check, if the PM timer is available */ - deltapm = lapic_cal_pm2 - lapic_cal_pm1; - apic_printk(APIC_VERBOSE, "... PM timer delta = %ld\n", deltapm); + local_irq_enable(); - local_apic_timer_verify_ok = 0; + /* Jiffies delta */ + deltaj = lapic_cal_j2 - lapic_cal_j1; + apic_printk(APIC_VERBOSE, "... jiffies delta = %lu\n", deltaj); - if (deltapm) { - if (deltapm > (pm_100ms - pm_thresh) && - deltapm < (pm_100ms + pm_thresh)) { - apic_printk(APIC_VERBOSE, "... PM timer result ok\n"); - /* Check, if the jiffies result is consistent */ - if (deltaj < LAPIC_CAL_LOOPS-2 || - deltaj > LAPIC_CAL_LOOPS+2) { - /* - * Not sure, what we can do about this one. - * When high resultion timers are active - * and the lapic timer does not stop in C3 - * we are fine. Otherwise more trouble might - * be waiting. -- tglx - */ - printk(KERN_WARNING "Global event device %s " - "has wrong frequency " - "(%lu ticks instead of %d)\n", - global_clock_event->name, deltaj, - LAPIC_CAL_LOOPS); - } - local_apic_timer_verify_ok = 1; - } - } else { /* Check, if the jiffies result is consistent */ - if (deltaj >= LAPIC_CAL_LOOPS-2 && - deltaj <= LAPIC_CAL_LOOPS+2) { + if (deltaj >= LAPIC_CAL_LOOPS-2 && deltaj <= LAPIC_CAL_LOOPS+2) apic_printk(APIC_VERBOSE, "... jiffies result ok\n"); - local_apic_timer_verify_ok = 1; - } - } + else + local_apic_timer_verify_ok = 0; + } else + local_irq_enable(); if (!local_apic_timer_verify_ok) { printk(KERN_WARNING @@ -1203,6 +1228,20 @@ static int __init parse_nolapic(char *ar } early_param("nolapic", parse_nolapic); +static int __init parse_disable_lapic_timer(char *arg) +{ + local_apic_timer_disabled = 1; + return 0; +} +early_param("nolapic_timer", parse_disable_lapic_timer); + +static int __init parse_lapic_timer_c2_ok(char *arg) +{ + local_apic_timer_c2_ok = 1; + return 0; +} +early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); + static int __init apic_set_verbosity(char *str) { if (strcmp("debug", str) == 0) Index: linux-2.6.21-rc5/arch/i386/kernel/i386_ksyms.c =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/kernel/i386_ksyms.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/kernel/i386_ksyms.c 2007-03-27 14:20:38.000000000 +0100 @@ -28,3 +28,5 @@ EXPORT_SYMBOL(__read_lock_failed); #endif EXPORT_SYMBOL(csum_partial); + +EXPORT_SYMBOL(_proxy_pda); Index: linux-2.6.21-rc5/arch/i386/kernel/i8253.c =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/kernel/i8253.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/kernel/i8253.c 2007-03-27 14:20:38.000000000 +0100 @@ -47,9 +47,17 @@ static void init_pit_timer(enum clock_ev outb(LATCH >> 8 , PIT_CH0); /* MSB */ break; - case CLOCK_EVT_MODE_ONESHOT: + /* + * Avoid unnecessary state transitions, as it confuses + * Geode / Cyrix based boxen. + */ case CLOCK_EVT_MODE_SHUTDOWN: + if (evt->mode == CLOCK_EVT_MODE_UNUSED) + break; case CLOCK_EVT_MODE_UNUSED: + if (evt->mode == CLOCK_EVT_MODE_SHUTDOWN) + break; + case CLOCK_EVT_MODE_ONESHOT: /* One shot setup */ outb_p(0x38, PIT_MODE); udelay(10); Index: linux-2.6.21-rc5/arch/i386/kernel/tsc.c =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/kernel/tsc.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/kernel/tsc.c 2007-03-27 14:20:38.000000000 +0100 @@ -18,6 +18,8 @@ #include "mach_timer.h" +static int tsc_enabled; + /* * On some systems the TSC frequency does not * change with the cpu frequency. So we need @@ -105,7 +107,7 @@ unsigned long long sched_clock(void) /* * Fall back to jiffies if there's no TSC available: */ - if (unlikely(tsc_disable)) + if (unlikely(!tsc_enabled)) /* No locking but a rare wrong value is not a big deal: */ return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); @@ -283,6 +285,7 @@ void mark_tsc_unstable(void) { if (!tsc_unstable) { tsc_unstable = 1; + tsc_enabled = 0; /* Can be called before registration */ if (clocksource_tsc.mult) clocksource_change_rating(&clocksource_tsc, 0); @@ -383,7 +386,9 @@ void __init tsc_init(void) if (check_tsc_unstable()) { clocksource_tsc.rating = 0; clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; - } + } else + tsc_enabled = 1; + clocksource_register(&clocksource_tsc); return; Index: linux-2.6.21-rc5/arch/i386/kernel/vmi.c =================================================================== --- linux-2.6.21-rc5.orig/arch/i386/kernel/vmi.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/i386/kernel/vmi.c 2007-03-27 14:20:38.000000000 +0100 @@ -23,7 +23,6 @@ */ #include -#include #include #include #include @@ -48,7 +47,6 @@ typedef u64 __attribute__((regparm(2))) (((VROMLONGFUNC *)(rom->func)) (arg)) static struct vrom_header *vmi_rom; -static int license_gplok; static int disable_pge; static int disable_pse; static int disable_sep; @@ -629,13 +627,14 @@ static inline int __init check_vmi_rom(s rom->api_version_maj, rom->api_version_min, pci->rom_version_maj, pci->rom_version_min); - license_gplok = license_is_gpl_compatible(license); - if (!license_gplok) { - printk(KERN_WARNING "VMI: ROM license '%s' taints kernel... " - "inlining disabled\n", - license); - add_taint(TAINT_PROPRIETARY_MODULE); - } + /* Don't allow BSD/MIT here for now because we don't want to end up + with any binary only shim layers */ + if (strcmp(license, "GPL") && strcmp(license, "GPL v2")) { + printk(KERN_WARNING "VMI: Non GPL license `%s' found for ROM. Not used.\n", + license); + return 0; + } + return 1; } Index: linux-2.6.21-rc5/arch/ia64/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -13,6 +13,7 @@ config IA64 bool select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) + select PM if (!IA64_HP_SIM) default y help The Itanium Processor Family is Intel's 64-bit successor to Index: linux-2.6.21-rc5/arch/ia64/kernel/crash.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/kernel/crash.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/kernel/crash.c 2007-03-27 14:20:38.000000000 +0100 @@ -164,7 +164,7 @@ kdump_init_notifier(struct notifier_bloc nd = (struct ia64_mca_notify_die *)args->err; /* Reason code 1 means machine check rendezous*/ - if ((val == DIE_INIT_MONARCH_ENTER || DIE_INIT_SLAVE_ENTER) && + if ((val == DIE_INIT_MONARCH_ENTER || val == DIE_INIT_SLAVE_ENTER) && nd->sos->rv_rc == 1) return NOTIFY_DONE; Index: linux-2.6.21-rc5/arch/ia64/kernel/setup.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/kernel/setup.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/kernel/setup.c 2007-03-27 14:20:38.000000000 +0100 @@ -692,12 +692,15 @@ struct seq_operations cpuinfo_op = { .show = show_cpuinfo }; -static char brandname[128]; +#define MAX_BRANDS 8 +static char brandname[MAX_BRANDS][128]; static char * __cpuinit get_model_name(__u8 family, __u8 model) { + static int overflow; char brand[128]; + int i; memcpy(brand, "Unknown", 8); if (ia64_pal_get_brand_info(brand)) { @@ -709,12 +712,17 @@ get_model_name(__u8 family, __u8 model) case 2: memcpy(brand, "Madison up to 9M cache", 23); break; } } - if (brandname[0] == '\0') - return strcpy(brandname, brand); - else if (strcmp(brandname, brand) == 0) - return brandname; - else - return kstrdup(brand, GFP_KERNEL); + for (i = 0; i < MAX_BRANDS; i++) + if (strcmp(brandname[i], brand) == 0) + return brandname[i]; + for (i = 0; i < MAX_BRANDS; i++) + if (brandname[i][0] == '\0') + return strcpy(brandname[i], brand); + if (overflow++ == 0) + printk(KERN_ERR + "%s: Table overflow. Some processor model information will be missing\n", + __FUNCTION__); + return "Unknown"; } static void __cpuinit Index: linux-2.6.21-rc5/arch/ia64/mm/contig.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/mm/contig.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/mm/contig.c 2007-03-27 14:20:38.000000000 +0100 @@ -97,26 +97,6 @@ void show_mem(void) unsigned long bootmap_start; /** - * find_max_pfn - adjust the maximum page number callback - * @start: start of range - * @end: end of range - * @arg: address of pointer to global max_pfn variable - * - * Passed as a callback function to efi_memmap_walk() to determine the highest - * available page frame number in the system. - */ -int -find_max_pfn (unsigned long start, unsigned long end, void *arg) -{ - unsigned long *max_pfnp = arg, pfn; - - pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT; - if (pfn > *max_pfnp) - *max_pfnp = pfn; - return 0; -} - -/** * find_bootmap_location - callback to find a memory area for the bootmap * @start: start of region * @end: end of region @@ -177,9 +157,10 @@ find_memory (void) reserve_memory(); /* first find highest page frame number */ - max_pfn = 0; - efi_memmap_walk(find_max_pfn, &max_pfn); - + min_low_pfn = ~0UL; + max_low_pfn = 0; + efi_memmap_walk(find_max_min_low_pfn, NULL); + max_pfn = max_low_pfn; /* how many bytes to cover all the pages */ bootmap_size = bootmem_bootmap_pages(max_pfn) << PAGE_SHIFT; @@ -189,7 +170,8 @@ find_memory (void) if (bootmap_start == ~0UL) panic("Cannot find %ld bytes for bootmap\n", bootmap_size); - bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn); + bootmap_size = init_bootmem_node(NODE_DATA(0), + (bootmap_start >> PAGE_SHIFT), 0, max_pfn); /* Free all available memory, then mark bootmem-map as being in use. */ efi_memmap_walk(filter_rsvd_memory, free_bootmem); Index: linux-2.6.21-rc5/arch/ia64/mm/discontig.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/mm/discontig.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/mm/discontig.c 2007-03-27 14:20:38.000000000 +0100 @@ -88,9 +88,6 @@ static int __init build_node_maps(unsign bdp->node_low_pfn = max(epfn, bdp->node_low_pfn); } - min_low_pfn = min(min_low_pfn, bdp->node_boot_start>>PAGE_SHIFT); - max_low_pfn = max(max_low_pfn, bdp->node_low_pfn); - return 0; } @@ -438,6 +435,7 @@ void __init find_memory(void) /* These actually end up getting called by call_pernode_memory() */ efi_memmap_walk(filter_rsvd_memory, build_node_maps); efi_memmap_walk(filter_rsvd_memory, find_pernode_space); + efi_memmap_walk(find_max_min_low_pfn, NULL); for_each_online_node(node) if (mem_data[node].bootmem_data.node_low_pfn) { Index: linux-2.6.21-rc5/arch/ia64/mm/init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/mm/init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/mm/init.c 2007-03-27 14:20:38.000000000 +0100 @@ -648,6 +648,22 @@ count_reserved_pages (u64 start, u64 end return 0; } +int +find_max_min_low_pfn (unsigned long start, unsigned long end, void *arg) +{ + unsigned long pfn_start, pfn_end; +#ifdef CONFIG_FLATMEM + pfn_start = (PAGE_ALIGN(__pa(start))) >> PAGE_SHIFT; + pfn_end = (PAGE_ALIGN(__pa(end - 1))) >> PAGE_SHIFT; +#else + pfn_start = GRANULEROUNDDOWN(__pa(start)) >> PAGE_SHIFT; + pfn_end = GRANULEROUNDUP(__pa(end - 1)) >> PAGE_SHIFT; +#endif + min_low_pfn = min(min_low_pfn, pfn_start); + max_low_pfn = max(max_low_pfn, pfn_end); + return 0; +} + /* * Boot command-line option "nolwsys" can be used to disable the use of any light-weight * system call handler. When this option is in effect, all fsyscalls will end up bubbling Index: linux-2.6.21-rc5/arch/ia64/sn/kernel/io_init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/sn/kernel/io_init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/sn/kernel/io_init.c 2007-03-27 14:20:38.000000000 +0100 @@ -247,10 +247,18 @@ sn_io_slot_fixup(struct pci_dev *dev) addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; dev->resource[idx].start = addr; dev->resource[idx].end = addr + size; + + /* + * if it's already in the device structure, remove it before + * inserting + */ + if (dev->resource[idx].parent && dev->resource[idx].parent->child) + release_resource(&dev->resource[idx]); + if (dev->resource[idx].flags & IORESOURCE_IO) - dev->resource[idx].parent = &ioport_resource; + insert_resource(&ioport_resource, &dev->resource[idx]); else - dev->resource[idx].parent = &iomem_resource; + insert_resource(&iomem_resource, &dev->resource[idx]); /* If ROM, mark as shadowed in PROM */ if (idx == PCI_ROM_RESOURCE) dev->resource[idx].flags |= IORESOURCE_ROM_BIOS_COPY; Index: linux-2.6.21-rc5/arch/ia64/sn/kernel/setup.c =================================================================== --- linux-2.6.21-rc5.orig/arch/ia64/sn/kernel/setup.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/ia64/sn/kernel/setup.c 2007-03-27 14:20:38.000000000 +0100 @@ -348,8 +348,7 @@ sn_scan_pcdp(void) continue; /* not PCI interconnect */ if (if_pci.translation & PCDP_PCI_TRANS_IOPORT) - vga_console_iobase = - if_pci.ioport_tra | __IA64_UNCACHED_OFFSET; + vga_console_iobase = if_pci.ioport_tra; if (if_pci.translation & PCDP_PCI_TRANS_MMIO) vga_console_membase = @@ -429,7 +428,8 @@ void __init sn_setup(char **cmdline_p) * bus containing the VGA console. */ if (vga_console_iobase) { - io_space[0].mmio_base = vga_console_iobase; + io_space[0].mmio_base = + (unsigned long) ioremap(vga_console_iobase, 0); io_space[0].sparse = 0; } Index: linux-2.6.21-rc5/arch/mips/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -250,7 +250,7 @@ config LASAT select R5000_CPU_SCACHE select SYS_HAS_CPU_R5000 select SYS_SUPPORTS_32BIT_KERNEL - select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL + select SYS_SUPPORTS_64BIT_KERNEL if BROKEN select SYS_SUPPORTS_LITTLE_ENDIAN select GENERIC_HARDIRQS_NO__DO_IRQ @@ -542,6 +542,8 @@ config QEMU select SYS_SUPPORTS_LITTLE_ENDIAN select ARCH_SPARSEMEM_ENABLE select GENERIC_HARDIRQS_NO__DO_IRQ + select NR_CPUS_DEFAULT_1 + select SYS_SUPPORTS_SMP help Qemu is a software emulator which among other architectures also can simulate a MIPS32 4Kc system. This patch adds support for the @@ -1559,6 +1561,7 @@ config MIPS_MT_SMP select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_SRS select MIPS_MT + select NR_CPUS_DEFAULT_2 select SMP select SYS_SUPPORTS_SMP help @@ -1573,7 +1576,6 @@ config MIPS_MT_SMTC select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_SRS select MIPS_MT - select NR_CPUS_DEFAULT_2 select NR_CPUS_DEFAULT_8 select SMP select SYS_SUPPORTS_SMP @@ -1805,6 +1807,9 @@ config SMP config SYS_SUPPORTS_SMP bool +config NR_CPUS_DEFAULT_1 + bool + config NR_CPUS_DEFAULT_2 bool @@ -1825,8 +1830,9 @@ config NR_CPUS_DEFAULT_64 config NR_CPUS int "Maximum number of CPUs (2-64)" - range 2 64 + range 1 64 if NR_CPUS_DEFAULT_1 depends on SMP + default "1" if NR_CPUS_DEFAULT_1 default "2" if NR_CPUS_DEFAULT_2 default "4" if NR_CPUS_DEFAULT_4 default "8" if NR_CPUS_DEFAULT_8 @@ -1837,10 +1843,13 @@ config NR_CPUS This allows you to specify the maximum number of CPUs which this kernel will support. The maximum supported value is 32 for 32-bit kernel and 64 for 64-bit kernels; the minimum value which makes - sense is 2. + sense is 1 for Qemu (useful only for kernel debugging purposes) + and 2 for all others. This is purely to save memory - each supported CPU adds - approximately eight kilobytes to the kernel image. + approximately eight kilobytes to the kernel image. For best + performance should round up your number of processors to the next + power of two. # # Timer Interrupt Frequency Configuration Index: linux-2.6.21-rc5/arch/mips/ddb5xxx/ddb5477/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/ddb5xxx/ddb5477/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/ddb5xxx/ddb5477/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -194,7 +194,7 @@ static void vrc5477_irq_dispatch(void) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_cause() & read_c0_status(); + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(CPU_IRQ_BASE + 7); Index: linux-2.6.21-rc5/arch/mips/emma2rh/markeins/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/emma2rh/markeins/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/emma2rh/markeins/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -115,7 +115,7 @@ void __init arch_init_irq(void) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_status() & read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(CPU_IRQ_BASE + 7); Index: linux-2.6.21-rc5/arch/mips/gt64120/ev64120/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/gt64120/ev64120/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/gt64120/ev64120/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -48,7 +48,7 @@ asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_status() & read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ do_IRQ(4); Index: linux-2.6.21-rc5/arch/mips/gt64120/wrppmc/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/gt64120/wrppmc/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/gt64120/wrppmc/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -32,7 +32,7 @@ asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_status() & read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) do_IRQ(WRPPMC_MIPS_TIMER_IRQ); /* CPU Compare/Count internal timer */ Index: linux-2.6.21-rc5/arch/mips/jazz/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/jazz/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/jazz/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -122,7 +122,7 @@ static void ll_local_dev(void) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; + unsigned int pending = read_c0_cause() & read_c0_status(); if (pending & IE_IRQ5) write_c0_compare(0); Index: linux-2.6.21-rc5/arch/mips/jazz/jazzdma.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/jazz/jazzdma.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/jazz/jazzdma.c 2007-03-27 14:20:38.000000000 +0100 @@ -67,7 +67,8 @@ void __init vdma_init(void) * aligned and should be uncached to avoid cache flushing after every * update. */ - vdma_pagetable_start = alloc_bootmem_low_pages(VDMA_PGTBL_SIZE); + vdma_pagetable_start = + (unsigned long) alloc_bootmem_low_pages(VDMA_PGTBL_SIZE); if (!vdma_pagetable_start) BUG(); dma_cache_wback_inv(vdma_pagetable_start, VDMA_PGTBL_SIZE); Index: linux-2.6.21-rc5/arch/mips/kernel/genex.S =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/genex.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/genex.S 2007-03-27 14:20:38.000000000 +0100 @@ -181,13 +181,13 @@ NESTED(except_vec_vi, 0, sp) * during service by SMTC kernel, we also want to * pass the IM value to be cleared. */ -EXPORT(except_vec_vi_mori) +FEXPORT(except_vec_vi_mori) ori a0, $0, 0 #endif /* CONFIG_MIPS_MT_SMTC */ -EXPORT(except_vec_vi_lui) +FEXPORT(except_vec_vi_lui) lui v0, 0 /* Patched */ j except_vec_vi_handler -EXPORT(except_vec_vi_ori) +FEXPORT(except_vec_vi_ori) ori v0, 0 /* Patched */ .set pop END(except_vec_vi) @@ -220,7 +220,17 @@ NESTED(except_vec_vi_handler, 0, sp) _ehb #endif /* CONFIG_MIPS_MT_SMTC */ CLI +#ifdef CONFIG_TRACE_IRQFLAGS + move s0, v0 +#ifdef CONFIG_MIPS_MT_SMTC + move s1, a0 +#endif TRACE_IRQS_OFF +#ifdef CONFIG_MIPS_MT_SMTC + move a0, s1 +#endif + move v0, s0 +#endif LONG_L s0, TI_REGS($28) LONG_S sp, TI_REGS($28) Index: linux-2.6.21-rc5/arch/mips/kernel/kspd.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/kspd.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/kspd.c 2007-03-27 14:20:38.000000000 +0100 @@ -191,6 +191,8 @@ void sp_work_handle_request(void) struct mtsp_syscall_generic generic; struct mtsp_syscall_ret ret; struct kspd_notifications *n; + unsigned long written; + mm_segment_t old_fs; struct timeval tv; struct timezone tz; int cmd; @@ -201,7 +203,11 @@ void sp_work_handle_request(void) ret.retval = -1; - if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) { + old_fs = get_fs(); + set_fs(KERNEL_DS); + + if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall))) { + set_fs(old_fs); printk(KERN_ERR "Expected request but nothing to read\n"); return; } @@ -209,7 +215,8 @@ void sp_work_handle_request(void) size = sc.size; if (size) { - if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) { + if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size)) { + set_fs(old_fs); printk(KERN_ERR "Expected request but nothing to read\n"); return; } @@ -282,8 +289,11 @@ void sp_work_handle_request(void) if (vpe_getuid(SP_VPE)) sp_setfsuidgid( 0, 0); - if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0)) - < sizeof(struct mtsp_syscall_ret)) + old_fs = get_fs(); + set_fs(KERNEL_DS); + written = rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(ret)); + set_fs(old_fs); + if (written < sizeof(ret)) printk("KSPD: sp_work_handle_request failed to send to SP\n"); } Index: linux-2.6.21-rc5/arch/mips/kernel/linux32.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/linux32.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/linux32.c 2007-03-27 14:20:38.000000000 +0100 @@ -311,6 +311,8 @@ asmlinkage int sys32_sched_rr_get_interv return ret; } +#ifdef CONFIG_SYSVIPC + asmlinkage long sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) { @@ -368,6 +370,16 @@ sys32_ipc (u32 call, int first, int seco return err; } +#else + +asmlinkage long +sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) +{ + return -ENOSYS; +} + +#endif /* CONFIG_SYSVIPC */ + #ifdef CONFIG_MIPS32_N32 asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, u32 arg) { Index: linux-2.6.21-rc5/arch/mips/kernel/r2300_switch.S =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/r2300_switch.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/r2300_switch.S 2007-03-27 14:20:38.000000000 +0100 @@ -49,8 +49,7 @@ LEAF(resume) #ifndef CONFIG_CPU_HAS_LLSC sw zero, ll_bit #endif - mfc0 t1, CP0_STATUS - sw t1, THREAD_STATUS(a0) + mfc0 t2, CP0_STATUS cpu_save_nonscratch a0 sw ra, THREAD_REG31(a0) @@ -60,8 +59,8 @@ LEAF(resume) lw t3, TASK_THREAD_INFO(a0) lw t0, TI_FLAGS(t3) li t1, _TIF_USEDFPU - and t2, t0, t1 - beqz t2, 1f + and t1, t0 + beqz t1, 1f nor t1, zero, t1 and t0, t0, t1 @@ -74,10 +73,13 @@ LEAF(resume) li t1, ~ST0_CU1 and t0, t0, t1 sw t0, ST_OFF(t3) + /* clear thread_struct CU1 bit */ + and t2, t1 fpu_save_single a0, t0 # clobbers t0 1: + sw t2, THREAD_STATUS(a0) /* * The order of restoring the registers takes care of the race * updating $28, $29 and kernelsp without disabling ints. Index: linux-2.6.21-rc5/arch/mips/kernel/r4k_fpu.S =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/r4k_fpu.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/r4k_fpu.S 2007-03-27 14:20:38.000000000 +0100 @@ -114,14 +114,6 @@ LEAF(_save_fp_context32) */ LEAF(_restore_fp_context) EX lw t0, SC_FPC_CSR(a0) - - /* Fail if the CSR has exceptions pending */ - srl t1, t0, 5 - and t1, t0 - andi t1, 0x1f << 7 - bnez t1, fault - nop - #ifdef CONFIG_64BIT EX ldc1 $f1, SC_FPREGS+8(a0) EX ldc1 $f3, SC_FPREGS+24(a0) @@ -165,14 +157,6 @@ LEAF(_restore_fp_context) LEAF(_restore_fp_context32) /* Restore an o32 sigcontext. */ EX lw t0, SC32_FPC_CSR(a0) - - /* Fail if the CSR has exceptions pending */ - srl t1, t0, 5 - and t1, t0 - andi t1, 0x1f << 7 - bnez t1, fault - nop - EX ldc1 $f0, SC32_FPREGS+0(a0) EX ldc1 $f2, SC32_FPREGS+16(a0) EX ldc1 $f4, SC32_FPREGS+32(a0) Index: linux-2.6.21-rc5/arch/mips/kernel/r4k_switch.S =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/r4k_switch.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/r4k_switch.S 2007-03-27 14:20:38.000000000 +0100 @@ -48,8 +48,7 @@ #ifndef CONFIG_CPU_HAS_LLSC sw zero, ll_bit #endif - mfc0 t1, CP0_STATUS - LONG_S t1, THREAD_STATUS(a0) + mfc0 t2, CP0_STATUS cpu_save_nonscratch a0 LONG_S ra, THREAD_REG31(a0) @@ -59,8 +58,8 @@ PTR_L t3, TASK_THREAD_INFO(a0) LONG_L t0, TI_FLAGS(t3) li t1, _TIF_USEDFPU - and t2, t0, t1 - beqz t2, 1f + and t1, t0 + beqz t1, 1f nor t1, zero, t1 and t0, t0, t1 @@ -73,10 +72,13 @@ li t1, ~ST0_CU1 and t0, t0, t1 LONG_S t0, ST_OFF(t3) + /* clear thread_struct CU1 bit */ + and t2, t1 fpu_save_double a0 t0 t1 # c0_status passed in t0 # clobbers t1 1: + LONG_S t2, THREAD_STATUS(a0) /* * The order of restoring the registers takes care of the race Index: linux-2.6.21-rc5/arch/mips/kernel/rtlx.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/rtlx.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/rtlx.c 2007-03-27 14:20:38.000000000 +0100 @@ -54,6 +54,7 @@ static struct chan_waitqueues { wait_queue_head_t rt_queue; wait_queue_head_t lx_queue; atomic_t in_open; + struct mutex mutex; } channel_wqs[RTLX_CHANNELS]; static struct irqaction irq; @@ -146,7 +147,7 @@ static void stopping(int vpe) int rtlx_open(int index, int can_sleep) { - volatile struct rtlx_info **p; + struct rtlx_info **p; struct rtlx_channel *chan; enum rtlx_state state; int ret = 0; @@ -179,13 +180,24 @@ int rtlx_open(int index, int can_sleep) } } + smp_rmb(); if (*p == NULL) { if (can_sleep) { - __wait_event_interruptible(channel_wqs[index].lx_queue, - *p != NULL, - ret); - if (ret) + DEFINE_WAIT(wait); + + for (;;) { + prepare_to_wait(&channel_wqs[index].lx_queue, &wait, TASK_INTERRUPTIBLE); + smp_rmb(); + if (*p != NULL) + break; + if (!signal_pending(current)) { + schedule(); + continue; + } + ret = -ERESTARTSYS; goto out_fail; + } + finish_wait(&channel_wqs[index].lx_queue, &wait); } else { printk(" *vpe_get_shared is NULL. " "Has an SP program been loaded?\n"); @@ -277,56 +289,52 @@ unsigned int rtlx_write_poll(int index) return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); } -static inline void copy_to(void *dst, void *src, size_t count, int user) -{ - if (user) - copy_to_user(dst, src, count); - else - memcpy(dst, src, count); -} - -static inline void copy_from(void *dst, void *src, size_t count, int user) -{ - if (user) - copy_from_user(dst, src, count); - else - memcpy(dst, src, count); -} - -ssize_t rtlx_read(int index, void *buff, size_t count, int user) +ssize_t rtlx_read(int index, void __user *buff, size_t count, int user) { - size_t fl = 0L; + size_t lx_write, fl = 0L; struct rtlx_channel *lx; + unsigned long failed; if (rtlx == NULL) return -ENOSYS; lx = &rtlx->channel[index]; + mutex_lock(&channel_wqs[index].mutex); + smp_rmb(); + lx_write = lx->lx_write; + /* find out how much in total */ count = min(count, - (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) + (size_t)(lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); /* then how much from the read pointer onwards */ - fl = min( count, (size_t)lx->buffer_size - lx->lx_read); + fl = min(count, (size_t)lx->buffer_size - lx->lx_read); - copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user); + failed = copy_to_user(buff, lx->lx_buffer + lx->lx_read, fl); + if (failed) + goto out; /* and if there is anything left at the beginning of the buffer */ - if ( count - fl ) - copy_to (buff + fl, lx->lx_buffer, count - fl, user); + if (count - fl) + failed = copy_to_user(buff + fl, lx->lx_buffer, count - fl); + +out: + count -= failed; - /* update the index */ - lx->lx_read += count; - lx->lx_read %= lx->buffer_size; + smp_wmb(); + lx->lx_read = (lx->lx_read + count) % lx->buffer_size; + smp_wmb(); + mutex_unlock(&channel_wqs[index].mutex); return count; } -ssize_t rtlx_write(int index, void *buffer, size_t count, int user) +ssize_t rtlx_write(int index, const void __user *buffer, size_t count, int user) { struct rtlx_channel *rt; + size_t rt_read; size_t fl; if (rtlx == NULL) @@ -334,24 +342,35 @@ ssize_t rtlx_write(int index, void *buff rt = &rtlx->channel[index]; + mutex_lock(&channel_wqs[index].mutex); + smp_rmb(); + rt_read = rt->rt_read; + /* total number of bytes to copy */ count = min(count, - (size_t)write_spacefree(rt->rt_read, rt->rt_write, - rt->buffer_size)); + (size_t)write_spacefree(rt_read, rt->rt_write, rt->buffer_size)); /* first bit from write pointer to the end of the buffer, or count */ fl = min(count, (size_t) rt->buffer_size - rt->rt_write); - copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user); + failed = copy_from_user(rt->rt_buffer + rt->rt_write, buffer, fl); + if (failed) + goto out; /* if there's any left copy to the beginning of the buffer */ - if( count - fl ) - copy_from (rt->rt_buffer, buffer + fl, count - fl, user); + if (count - fl) { + failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl); + } - rt->rt_write += count; - rt->rt_write %= rt->buffer_size; +out: + count -= cailed; - return(count); + smp_wmb(); + rt->rt_write = (rt->rt_write + count) % rt->buffer_size; + smp_wmb(); + mutex_unlock(&channel_wqs[index].mutex); + + return count; } @@ -403,7 +422,7 @@ static ssize_t file_read(struct file *fi return 0; // -EAGAIN makes cat whinge } - return rtlx_read(minor, buffer, count, 1); + return rtlx_read(minor, buffer, count); } static ssize_t file_write(struct file *file, const char __user * buffer, @@ -429,7 +448,7 @@ static ssize_t file_write(struct file *f return ret; } - return rtlx_write(minor, (void *)buffer, count, 1); + return rtlx_write(minor, buffer, count); } static const struct file_operations rtlx_fops = { @@ -468,6 +487,7 @@ static int rtlx_module_init(void) init_waitqueue_head(&channel_wqs[i].rt_queue); init_waitqueue_head(&channel_wqs[i].lx_queue); atomic_set(&channel_wqs[i].in_open, 0); + mutex_init(&channel_wqs[i].mutex); dev = device_create(mt_class, NULL, MKDEV(major, i), "%s%d", module_name, i); Index: linux-2.6.21-rc5/arch/mips/kernel/signal-common.h =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/signal-common.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/signal-common.h 2007-03-27 14:20:38.000000000 +0100 @@ -31,4 +31,7 @@ extern void __user *get_sigframe(struct */ extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); +/* Check and clear pending FPU exceptions in saved CSR */ +extern int fpcsr_pending(unsigned int __user *fpcsr); + #endif /* __SIGNAL_COMMON_H */ Index: linux-2.6.21-rc5/arch/mips/kernel/signal.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/signal.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/signal.c 2007-03-27 14:20:38.000000000 +0100 @@ -82,6 +82,7 @@ int setup_sigcontext(struct pt_regs *reg { int err = 0; int i; + unsigned int used_math; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -104,26 +105,53 @@ int setup_sigcontext(struct pt_regs *reg err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); } - err |= __put_user(!!used_math(), &sc->sc_used_math); + used_math = !!used_math(); + err |= __put_user(used_math, &sc->sc_used_math); - if (used_math()) { + if (used_math) { /* * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ - preempt_disable(); - - if (!is_fpu_owner()) { - own_fpu(); - restore_fp(current); - } + own_fpu(1); + enable_fp_in_kernel(); err |= save_fp_context(sc); - - preempt_enable(); + disable_fp_in_kernel(); } return err; } +int fpcsr_pending(unsigned int __user *fpcsr) +{ + int err, sig = 0; + unsigned int csr, enabled; + + err = __get_user(csr, fpcsr); + enabled = FPU_CSR_UNI_X | ((csr & FPU_CSR_ALL_E) << 5); + /* + * If the signal handler set some FPU exceptions, clear it and + * send SIGFPE. + */ + if (csr & enabled) { + csr &= ~enabled; + err |= __put_user(csr, fpcsr); + sig = SIGFPE; + } + return err ?: sig; +} + +static int +check_and_restore_fp_context(struct sigcontext __user *sc) +{ + int err, sig; + + err = sig = fpcsr_pending(&sc->sc_fpc_csr); + if (err > 0) + err = 0; + err |= restore_fp_context(sc); + return err ?: sig; +} + int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { unsigned int used_math; @@ -157,19 +185,18 @@ int restore_sigcontext(struct pt_regs *r err |= __get_user(used_math, &sc->sc_used_math); conditional_used_math(used_math); - preempt_disable(); - - if (used_math()) { + if (used_math) { /* restore fpu context if we have used it before */ - own_fpu(); - err |= restore_fp_context(sc); + own_fpu(0); + enable_fp_in_kernel(); + if (!err) + err = check_and_restore_fp_context(sc); + disable_fp_in_kernel(); } else { /* signal handler may have used FPU. Give it up. */ - lose_fpu(); + lose_fpu(0); } - preempt_enable(); - return err; } @@ -332,6 +359,7 @@ asmlinkage void sys_sigreturn(nabi_no_re { struct sigframe __user *frame; sigset_t blocked; + int sig; frame = (struct sigframe __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -345,8 +373,11 @@ asmlinkage void sys_sigreturn(nabi_no_re recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->sf_sc)) + sig = restore_sigcontext(®s, &frame->sf_sc); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); /* * Don't let your children do this ... @@ -368,6 +399,7 @@ asmlinkage void sys_rt_sigreturn(nabi_no struct rt_sigframe __user *frame; sigset_t set; stack_t st; + int sig; frame = (struct rt_sigframe __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -381,8 +413,11 @@ asmlinkage void sys_rt_sigreturn(nabi_no recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st))) goto badframe; Index: linux-2.6.21-rc5/arch/mips/kernel/signal32.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/signal32.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/signal32.c 2007-03-27 14:20:38.000000000 +0100 @@ -181,6 +181,7 @@ static int setup_sigcontext32(struct pt_ { int err = 0; int i; + u32 used_math; err |= __put_user(regs->cp0_epc, &sc->sc_pc); @@ -200,26 +201,34 @@ static int setup_sigcontext32(struct pt_ err |= __put_user(mflo3(), &sc->sc_lo3); } - err |= __put_user(!!used_math(), &sc->sc_used_math); + used_math = !!used_math(); + err |= __put_user(used_math, &sc->sc_used_math); - if (used_math()) { + if (used_math) { /* * Save FPU state to signal context. Signal handler * will "inherit" current FPU state. */ - preempt_disable(); - - if (!is_fpu_owner()) { - own_fpu(); - restore_fp(current); - } + own_fpu(1); + enable_fp_in_kernel(); err |= save_fp_context32(sc); - - preempt_enable(); + disable_fp_in_kernel(); } return err; } +static int +check_and_restore_fp_context32(struct sigcontext32 __user *sc) +{ + int err, sig; + + err = sig = fpcsr_pending(&sc->sc_fpc_csr); + if (err > 0) + err = 0; + err |= restore_fp_context32(sc); + return err ?: sig; +} + static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 __user *sc) { @@ -250,19 +259,18 @@ static int restore_sigcontext32(struct p err |= __get_user(used_math, &sc->sc_used_math); conditional_used_math(used_math); - preempt_disable(); - - if (used_math()) { + if (used_math) { /* restore fpu context if we have used it before */ - own_fpu(); - err |= restore_fp_context32(sc); + own_fpu(0); + enable_fp_in_kernel(); + if (!err) + err = check_and_restore_fp_context32(sc); + disable_fp_in_kernel(); } else { /* signal handler may have used FPU. Give it up. */ - lose_fpu(); + lose_fpu(0); } - preempt_enable(); - return err; } @@ -508,6 +516,7 @@ asmlinkage void sys32_sigreturn(nabi_no_ { struct sigframe32 __user *frame; sigset_t blocked; + int sig; frame = (struct sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -521,8 +530,11 @@ asmlinkage void sys32_sigreturn(nabi_no_ recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext32(®s, &frame->sf_sc)) + sig = restore_sigcontext32(®s, &frame->sf_sc); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); /* * Don't let your children do this ... @@ -545,6 +557,7 @@ asmlinkage void sys32_rt_sigreturn(nabi_ sigset_t set; stack_t st; s32 sp; + int sig; frame = (struct rt_sigframe32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -558,8 +571,11 @@ asmlinkage void sys32_rt_sigreturn(nabi_ recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext)) + sig = restore_sigcontext32(®s, &frame->rs_uc.uc_mcontext); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) Index: linux-2.6.21-rc5/arch/mips/kernel/signal_n32.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/signal_n32.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/signal_n32.c 2007-03-27 14:20:38.000000000 +0100 @@ -127,6 +127,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi sigset_t set; stack_t st; s32 sp; + int sig; frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) @@ -140,8 +141,11 @@ asmlinkage void sysn32_rt_sigreturn(nabi recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); - if (restore_sigcontext(®s, &frame->rs_uc.uc_mcontext)) + sig = restore_sigcontext(®s, &frame->rs_uc.uc_mcontext); + if (sig < 0) goto badframe; + else if (sig) + force_sig(sig, current); /* The ucontext contains a stack32_t, so we must convert! */ if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp)) Index: linux-2.6.21-rc5/arch/mips/kernel/traps.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/kernel/traps.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/kernel/traps.c 2007-03-27 14:20:38.000000000 +0100 @@ -610,16 +610,6 @@ asmlinkage void do_fpe(struct pt_regs *r if (fcr31 & FPU_CSR_UNI_X) { int sig; - preempt_disable(); - -#ifdef CONFIG_PREEMPT - if (!is_fpu_owner()) { - /* We might lose fpu before disabling preempt... */ - own_fpu(); - BUG_ON(!used_math()); - restore_fp(current); - } -#endif /* * Unimplemented operation exception. If we've got the full * software emulator on-board, let's use it... @@ -630,18 +620,12 @@ asmlinkage void do_fpe(struct pt_regs *r * register operands before invoking the emulator, which seems * a bit extreme for what should be an infrequent event. */ - save_fp(current); /* Ensure 'resume' not overwrite saved fp context again. */ - lose_fpu(); - - preempt_enable(); + lose_fpu(1); /* Run the emulator */ sig = fpu_emulator_cop1Handler (regs, ¤t->thread.fpu, 1); - preempt_disable(); - - own_fpu(); /* Using the FPU again. */ /* * We can't allow the emulated instruction to leave any of * the cause bit set in $fcr31. @@ -649,9 +633,7 @@ asmlinkage void do_fpe(struct pt_regs *r current->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; /* Restore the hardware register state */ - restore_fp(current); - - preempt_enable(); + own_fpu(1); /* Using the FPU again. */ /* If something went wrong, signal */ if (sig) @@ -775,12 +757,11 @@ asmlinkage void do_cpu(struct pt_regs *r { unsigned int cpid; - die_if_kernel("do_cpu invoked from kernel context!", regs); - cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; switch (cpid) { case 0: + die_if_kernel("do_cpu invoked from kernel context!", regs); if (!cpu_has_llsc) if (!simulate_llsc(regs)) return; @@ -791,21 +772,30 @@ asmlinkage void do_cpu(struct pt_regs *r break; case 1: - preempt_disable(); - - own_fpu(); - if (used_math()) { /* Using the FPU again. */ - restore_fp(current); - } else { /* First time FPU user. */ + if (!test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) + die_if_kernel("do_cpu invoked from kernel context!", + regs); + if (used_math()) /* Using the FPU again. */ + own_fpu(1); + else { /* First time FPU user. */ init_fpu(); set_used_math(); } - if (cpu_has_fpu) { - preempt_enable(); + if (raw_cpu_has_fpu) { + if (test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) { + local_irq_disable(); + if (cpu_has_fpu) + regs->cp0_status |= ST0_CU1; + /* + * We must return without enabling + * interrupts to ensure keep FPU + * ownership until resume. + */ + return; + } } else { int sig; - preempt_enable(); sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 0); if (sig) @@ -1259,26 +1249,26 @@ static inline void mips_srs_init(void) /* * This is used by native signal handling */ -asmlinkage int (*save_fp_context)(struct sigcontext *sc); -asmlinkage int (*restore_fp_context)(struct sigcontext *sc); +asmlinkage int (*save_fp_context)(struct sigcontext __user *sc); +asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc); -extern asmlinkage int _save_fp_context(struct sigcontext *sc); -extern asmlinkage int _restore_fp_context(struct sigcontext *sc); +extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); +extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); -extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); -extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); +extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc); +extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc); #ifdef CONFIG_SMP -static int smp_save_fp_context(struct sigcontext *sc) +static int smp_save_fp_context(struct sigcontext __user *sc) { - return cpu_has_fpu + return raw_cpu_has_fpu ? _save_fp_context(sc) : fpu_emulator_save_context(sc); } -static int smp_restore_fp_context(struct sigcontext *sc) +static int smp_restore_fp_context(struct sigcontext __user *sc) { - return cpu_has_fpu + return raw_cpu_has_fpu ? _restore_fp_context(sc) : fpu_emulator_restore_context(sc); } @@ -1306,14 +1296,14 @@ static inline void signal_init(void) /* * This is used by 32-bit signal stuff on the 64-bit kernel */ -asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); -asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); +asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc); +asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc); -extern asmlinkage int _save_fp_context32(struct sigcontext32 *sc); -extern asmlinkage int _restore_fp_context32(struct sigcontext32 *sc); +extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc); +extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc); -extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 *sc); -extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 *sc); +extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc); +extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc); static inline void signal32_init(void) { Index: linux-2.6.21-rc5/arch/mips/math-emu/kernel_linkage.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/math-emu/kernel_linkage.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/math-emu/kernel_linkage.c 2007-03-27 14:20:38.000000000 +0100 @@ -51,7 +51,7 @@ void fpu_emulator_init_fpu(void) * with appropriate macros from uaccess.h */ -int fpu_emulator_save_context(struct sigcontext *sc) +int fpu_emulator_save_context(struct sigcontext __user *sc) { int i; int err = 0; @@ -65,7 +65,7 @@ int fpu_emulator_save_context(struct sig return err; } -int fpu_emulator_restore_context(struct sigcontext *sc) +int fpu_emulator_restore_context(struct sigcontext __user *sc) { int i; int err = 0; @@ -84,7 +84,7 @@ int fpu_emulator_restore_context(struct * This is the o32 version */ -int fpu_emulator_save_context32(struct sigcontext32 *sc) +int fpu_emulator_save_context32(struct sigcontext32 __user *sc) { int i; int err = 0; @@ -98,7 +98,7 @@ int fpu_emulator_save_context32(struct s return err; } -int fpu_emulator_restore_context32(struct sigcontext32 *sc) +int fpu_emulator_restore_context32(struct sigcontext32 __user *sc) { int i; int err = 0; Index: linux-2.6.21-rc5/arch/mips/mips-boards/generic/init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mips-boards/generic/init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mips-boards/generic/init.c 2007-03-27 14:20:38.000000000 +0100 @@ -145,7 +145,7 @@ static void __init console_config(void) char parity = '\0', bits = '\0', flow = '\0'; char *s; - if ((strstr(prom_getcmdline(), "console=ttyS")) == NULL) { + if ((strstr(prom_getcmdline(), "console=")) == NULL) { s = prom_getenv("modetty0"); if (s) { while (*s >= '0' && *s <= '9') Index: linux-2.6.21-rc5/arch/mips/mm/c-r3k.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/c-r3k.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/c-r3k.c 2007-03-27 14:20:38.000000000 +0100 @@ -260,7 +260,7 @@ static void r3k_flush_cache_page(struct { } -static void local_r3k_flush_data_cache_page(unsigned long addr) +static void local_r3k_flush_data_cache_page(void *addr) { } Index: linux-2.6.21-rc5/arch/mips/mm/cache.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/cache.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/cache.c 2007-03-27 14:20:38.000000000 +0100 @@ -3,7 +3,8 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 1994 - 2003 by Ralf Baechle + * Copyright (C) 1994 - 2003, 07 by Ralf Baechle (ralf@linux-mips.org) + * Copyright (C) 2007 MIPS Technologies, Inc. */ #include #include @@ -88,6 +89,19 @@ void __flush_dcache_page(struct page *pa EXPORT_SYMBOL(__flush_dcache_page); +void __flush_anon_page(struct page *page, unsigned long vmaddr) +{ + if (pages_do_alias((unsigned long)page_address(page), vmaddr)) { + void *kaddr; + + kaddr = kmap_coherent(page, vmaddr); + flush_data_cache_page((unsigned long)kaddr); + kunmap_coherent(kaddr); + } +} + +EXPORT_SYMBOL(__flush_anon_page); + void __update_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) { Index: linux-2.6.21-rc5/arch/mips/mm/cerr-sb1.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/cerr-sb1.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/cerr-sb1.c 2007-03-27 14:20:38.000000000 +0100 @@ -177,8 +177,8 @@ extern void check_bus_watcher(void); asmlinkage void sb1_cache_error(void) { - uint64_t cerr_dpa; uint32_t errctl, cerr_i, cerr_d, dpalo, dpahi, eepc, res; + unsigned long long cerr_dpa; #ifdef CONFIG_SIBYTE_BW_TRACE /* Freeze the trace buffer now */ @@ -329,8 +329,9 @@ static uint32_t extract_ic(unsigned shor { unsigned short way; int valid; - uint64_t taglo, va, tlo_tmp; uint32_t taghi, taglolo, taglohi; + unsigned long long taglo, va; + uint64_t tlo_tmp; uint8_t lru; int res = 0; @@ -484,8 +485,8 @@ static uint32_t extract_dc(unsigned shor { int valid, way; unsigned char state; - uint64_t taglo, pa; uint32_t taghi, taglolo, taglohi; + unsigned long long taglo, pa; uint8_t ecc, lru; int res = 0; @@ -535,8 +536,8 @@ static uint32_t extract_dc(unsigned shor } if (data) { - uint64_t datalo; uint32_t datalohi, datalolo, datahi; + unsigned long long datalo; int offset; char bad_ecc = 0; Index: linux-2.6.21-rc5/arch/mips/mm/dma-default.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/dma-default.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/dma-default.c 2007-03-27 14:20:38.000000000 +0100 @@ -19,6 +19,13 @@ #include +static inline unsigned long dma_addr_to_virt(dma_addr_t dma_addr) +{ + unsigned long addr = plat_dma_addr_to_phys(dma_addr); + + return (unsigned long)phys_to_virt(addr); +} + /* * Warning on the terminology - Linux calls an uncached area coherent; * MIPS terminology calls memory areas with hardware maintained coherency @@ -140,7 +147,7 @@ void dma_unmap_single(struct device *dev enum dma_data_direction direction) { if (cpu_is_noncoherent_r10000(dev)) - __dma_sync(plat_dma_addr_to_phys(dma_addr) + PAGE_OFFSET, size, + __dma_sync(dma_addr_to_virt(dma_addr), size, direction); plat_unmap_dma_mem(dma_addr); @@ -234,7 +241,7 @@ void dma_sync_single_for_cpu(struct devi if (cpu_is_noncoherent_r10000(dev)) { unsigned long addr; - addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle); + addr = dma_addr_to_virt(dma_handle); __dma_sync(addr, size, direction); } } @@ -249,7 +256,7 @@ void dma_sync_single_for_device(struct d if (!plat_device_is_coherent(dev)) { unsigned long addr; - addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle); + addr = dma_addr_to_virt(dma_handle); __dma_sync(addr, size, direction); } } @@ -264,7 +271,7 @@ void dma_sync_single_range_for_cpu(struc if (cpu_is_noncoherent_r10000(dev)) { unsigned long addr; - addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle); + addr = dma_addr_to_virt(dma_handle); __dma_sync(addr + offset, size, direction); } } @@ -279,7 +286,7 @@ void dma_sync_single_range_for_device(st if (!plat_device_is_coherent(dev)) { unsigned long addr; - addr = PAGE_OFFSET + plat_dma_addr_to_phys(dma_handle); + addr = dma_addr_to_virt(dma_handle); __dma_sync(addr + offset, size, direction); } } Index: linux-2.6.21-rc5/arch/mips/mm/init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/init.c 2007-03-27 14:20:38.000000000 +0100 @@ -123,7 +123,7 @@ static void __init kmap_coherent_init(vo static inline void kmap_coherent_init(void) {} #endif -static inline void *kmap_coherent(struct page *page, unsigned long addr) +void *kmap_coherent(struct page *page, unsigned long addr) { enum fixed_addresses idx; unsigned long vaddr, flags, entrylo; @@ -177,7 +177,7 @@ static inline void *kmap_coherent(struct #define UNIQUE_ENTRYHI(idx) (CKSEG0 + ((idx) << (PAGE_SHIFT + 1))) -static inline void kunmap_coherent(struct page *page) +void kunmap_coherent(struct page *page) { #ifndef CONFIG_MIPS_MT_SMTC unsigned int wired; @@ -377,7 +377,7 @@ void __init paging_init(void) #ifdef CONFIG_FLATMEM free_area_init(zones_size); #else - pfn = 0; + pfn = min_low_pfn; for (i = 0; i < MAX_NR_ZONES; i++) for (j = 0; j < zones_size[i]; j++, pfn++) if (!page_is_ram(pfn)) Index: linux-2.6.21-rc5/arch/mips/mm/pg-sb1.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/mm/pg-sb1.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/mm/pg-sb1.c 2007-03-27 14:20:38.000000000 +0100 @@ -218,8 +218,7 @@ void sb1_dma_init(void) for (i = 0; i < DM_NUM_CHANNELS; i++) { const u64 base_val = CPHYSADDR(&page_descr[i]) | V_DM_DSCR_BASE_RINGSZ(1); - volatile void *base_reg = - IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE)); + void *base_reg = IOADDR(A_DM_REGISTER(i, R_DM_DSCR_BASE)); __raw_writeq(base_val, base_reg); __raw_writeq(base_val | M_DM_DSCR_BASE_RESET, base_reg); Index: linux-2.6.21-rc5/arch/mips/momentum/ocelot_c/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/momentum/ocelot_c/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/momentum/ocelot_c/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -64,7 +64,7 @@ extern void ll_cpci_irq(void); asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_cause() & read_c0_status(); + unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; if (pending & STATUSF_IP0) do_IRQ(0); Index: linux-2.6.21-rc5/arch/mips/pci/pci-bcm1480.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/pci/pci-bcm1480.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/pci/pci-bcm1480.c 2007-03-27 14:20:38.000000000 +0100 @@ -216,7 +216,7 @@ static int __init bcm1480_pcibios_init(v /* * See if the PCI bus has been configured by the firmware. */ - reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG)); + reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG)); if (!(reg & M_BCM1480_SYS_PCI_HOST)) { bcm1480_bus_status |= PCI_DEVICE_MODE; } else { Index: linux-2.6.21-rc5/arch/mips/pci/pci-sb1250.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/pci/pci-sb1250.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/pci/pci-sb1250.c 2007-03-27 14:20:38.000000000 +0100 @@ -228,7 +228,7 @@ static int __init sb1250_pcibios_init(vo /* * See if the PCI bus has been configured by the firmware. */ - reg = *((volatile uint64_t *) IOADDR(A_SCD_SYSTEM_CFG)); + reg = __raw_readq(IOADDR(A_SCD_SYSTEM_CFG)); if (!(reg & M_SYS_PCI_HOST)) { sb1250_bus_status |= PCI_DEVICE_MODE; } else { Index: linux-2.6.21-rc5/arch/mips/philips/pnx8550/common/int.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/philips/pnx8550/common/int.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/philips/pnx8550/common/int.c 2007-03-27 14:20:38.000000000 +0100 @@ -83,16 +83,15 @@ static void timer_irqdispatch(int irq) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_status() & read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP2) hw0_irqdispatch(2); else if (pending & STATUSF_IP7) { if (read_c0_config7() & 0x01c0) timer_irqdispatch(7); - } - - spurious_interrupt(); + } else + spurious_interrupt(); } static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) Index: linux-2.6.21-rc5/arch/mips/qemu/q-smp.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/qemu/q-smp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/qemu/q-smp.c 2007-03-27 14:20:38.000000000 +0100 @@ -46,3 +46,10 @@ void __init prom_prepare_cpus(unsigned i void prom_boot_secondary(int cpu, struct task_struct *idle) { } + +void __init plat_smp_setup(void) +{ +} +void __init plat_prepare_cpus(unsigned int max_cpus) +{ +} Index: linux-2.6.21-rc5/arch/mips/sgi-ip22/ip22-int.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sgi-ip22/ip22-int.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sgi-ip22/ip22-int.c 2007-03-27 14:20:38.000000000 +0100 @@ -237,7 +237,7 @@ extern void indy_8254timer_irq(void); asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause(); /* * First we check for r4k counter/timer IRQ. Index: linux-2.6.21-rc5/arch/mips/sgi-ip32/ip32-irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sgi-ip32/ip32-irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sgi-ip32/ip32-irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -454,7 +454,7 @@ static void ip32_irq5(void) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause(); if (likely(pending & IE_IRQ0)) ip32_irq0(); Index: linux-2.6.21-rc5/arch/mips/sibyte/bcm1480/smp.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sibyte/bcm1480/smp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sibyte/bcm1480/smp.c 2007-03-27 14:20:38.000000000 +0100 @@ -34,21 +34,21 @@ extern void smp_call_function_interrupt( * independent of board/firmware */ -static volatile void *mailbox_0_set_regs[] = { +static void *mailbox_0_set_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_SET_CPU), }; -static volatile void *mailbox_0_clear_regs[] = { +static void *mailbox_0_clear_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), IOADDR(A_BCM1480_IMR_CPU3_BASE + R_BCM1480_IMR_MAILBOX_0_CLR_CPU), }; -static volatile void *mailbox_0_regs[] = { +static void *mailbox_0_regs[] = { IOADDR(A_BCM1480_IMR_CPU0_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), IOADDR(A_BCM1480_IMR_CPU1_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), IOADDR(A_BCM1480_IMR_CPU2_BASE + R_BCM1480_IMR_MAILBOX_0_CPU), Index: linux-2.6.21-rc5/arch/mips/sibyte/sb1250/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sibyte/sb1250/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sibyte/sb1250/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -421,7 +421,7 @@ asmlinkage void plat_irq_dispatch(void) * blasting the high 32 bits. */ - pending = read_c0_cause() & read_c0_status(); + pending = read_c0_cause() & read_c0_status() & ST0_IM; #ifdef CONFIG_SIBYTE_SB1250_PROF if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ Index: linux-2.6.21-rc5/arch/mips/sibyte/swarm/setup.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sibyte/swarm/setup.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sibyte/swarm/setup.c 2007-03-27 14:20:38.000000000 +0100 @@ -169,17 +169,19 @@ void __init plat_mem_setup(void) #define LEDS_PHYS MLEDS_PHYS #endif -#define setled(index, c) \ - ((unsigned char *)(IOADDR(LEDS_PHYS)+0x20))[(3-(index))<<3] = (c) void setleds(char *str) { + void *reg; int i; + for (i = 0; i < 4; i++) { - if (!str[i]) { - setled(i, ' '); - } else { - setled(i, str[i]); - } + reg = IOADDR(LEDS_PHYS) + 0x20 + ((3 - i) << 3); + + if (!str[i]) + writeb(' ', reg); + else + writeb(str[i], reg); } } -#endif + +#endif /* LEDS_PHYS */ Index: linux-2.6.21-rc5/arch/mips/sni/pcimt.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sni/pcimt.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sni/pcimt.c 2007-03-27 14:20:38.000000000 +0100 @@ -333,7 +333,7 @@ static void pcimt_hwint3(void) static void sni_pcimt_hwint(void) { - u32 pending = (read_c0_cause() & read_c0_status()); + u32 pending = read_c0_cause() & read_c0_status(); if (pending & C_IRQ5) do_IRQ (MIPS_CPU_IRQ_BASE + 7); Index: linux-2.6.21-rc5/arch/mips/sni/pcit.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/sni/pcit.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/sni/pcit.c 2007-03-27 14:20:38.000000000 +0100 @@ -271,7 +271,7 @@ static void pcit_hwint0(void) static void sni_pcit_hwint(void) { - u32 pending = (read_c0_cause() & read_c0_status()); + u32 pending = read_c0_cause() & read_c0_status(); if (pending & C_IRQ1) pcit_hwint1(); @@ -285,7 +285,7 @@ static void sni_pcit_hwint(void) static void sni_pcit_hwint_cplus(void) { - u32 pending = (read_c0_cause() & read_c0_status()); + u32 pending = read_c0_cause() & read_c0_status(); if (pending & C_IRQ0) pcit_hwint0(); Index: linux-2.6.21-rc5/arch/mips/tx4927/common/tx4927_irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/mips/tx4927/common/tx4927_irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/mips/tx4927/common/tx4927_irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -416,7 +416,7 @@ static int tx4927_irq_nested(void) asmlinkage void plat_irq_dispatch(void) { - unsigned int pending = read_c0_status() & read_c0_cause(); + unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; if (pending & STATUSF_IP7) /* cpu timer */ do_IRQ(TX4927_IRQ_CPU_TIMER); Index: linux-2.6.21-rc5/arch/powerpc/kernel/process.c =================================================================== --- linux-2.6.21-rc5.orig/arch/powerpc/kernel/process.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/powerpc/kernel/process.c 2007-03-27 14:20:38.000000000 +0100 @@ -465,8 +465,13 @@ void flush_thread(void) #ifdef CONFIG_PPC64 struct thread_info *t = current_thread_info(); - if (t->flags & _TIF_ABI_PENDING) - t->flags ^= (_TIF_ABI_PENDING | _TIF_32BIT); + if (test_ti_thread_flag(t, TIF_ABI_PENDING)) { + clear_ti_thread_flag(t, TIF_ABI_PENDING); + if (test_ti_thread_flag(t, TIF_32BIT)) + clear_ti_thread_flag(t, TIF_32BIT); + else + set_ti_thread_flag(t, TIF_32BIT); + } #endif discard_lazy_cpu_state(); Index: linux-2.6.21-rc5/arch/powerpc/platforms/pseries/hvCall.S =================================================================== --- linux-2.6.21-rc5.orig/arch/powerpc/platforms/pseries/hvCall.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/powerpc/platforms/pseries/hvCall.S 2007-03-27 14:20:38.000000000 +0100 @@ -30,9 +30,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_PURR); /* * postcall is performed immediately before function return which - * allows liberal use of volatile registers. + * allows liberal use of volatile registers. We branch around this + * in early init (eg when populating the MMU hashtable) by using an + * unconditional cpu feature. */ #define HCALL_INST_POSTCALL \ +BEGIN_FTR_SECTION; \ + b 1f; \ +END_FTR_SECTION(0, 1); \ ld r4,STK_PARM(r3)(r1); /* validate opcode */ \ cmpldi cr7,r4,MAX_HCALL_OPCODE; \ bgt- cr7,1f; \ @@ -123,6 +128,40 @@ _GLOBAL(plpar_hcall) blr /* return r3 = status */ +/* + * plpar_hcall_raw can be called in real mode. kexec/kdump need some + * hypervisor calls to be executed in real mode. So plpar_hcall_raw + * does not access the per cpu hypervisor call statistics variables, + * since these variables may not be present in the RMO region. + */ +_GLOBAL(plpar_hcall_raw) + HMT_MEDIUM + + mfcr r0 + stw r0,8(r1) + + std r4,STK_PARM(r4)(r1) /* Save ret buffer */ + + mr r4,r5 + mr r5,r6 + mr r6,r7 + mr r7,r8 + mr r8,r9 + mr r9,r10 + + HVSC /* invoke the hypervisor */ + + ld r12,STK_PARM(r4)(r1) + std r4, 0(r12) + std r5, 8(r12) + std r6, 16(r12) + std r7, 24(r12) + + lwz r0,8(r1) + mtcrf 0xff,r0 + + blr /* return r3 = status */ + _GLOBAL(plpar_hcall9) HMT_MEDIUM Index: linux-2.6.21-rc5/arch/powerpc/platforms/pseries/lpar.c =================================================================== --- linux-2.6.21-rc5.orig/arch/powerpc/platforms/pseries/lpar.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/powerpc/platforms/pseries/lpar.c 2007-03-27 14:20:38.000000000 +0100 @@ -378,7 +378,7 @@ static void pSeries_lpar_hptab_clear(voi /* TODO: Use bulk call */ for (i = 0; i < hpte_count; i++) - plpar_pte_remove(0, i, 0, &dummy1, &dummy2); + plpar_pte_remove_raw(0, i, 0, &dummy1, &dummy2); } /* Index: linux-2.6.21-rc5/arch/powerpc/platforms/pseries/plpar_wrappers.h =================================================================== --- linux-2.6.21-rc5.orig/arch/powerpc/platforms/pseries/plpar_wrappers.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/powerpc/platforms/pseries/plpar_wrappers.h 2007-03-27 14:20:38.000000000 +0100 @@ -78,6 +78,22 @@ static inline long plpar_pte_remove(unsi return rc; } +/* plpar_pte_remove_raw can be called in real mode. It calls plpar_hcall_raw */ +static inline long plpar_pte_remove_raw(unsigned long flags, unsigned long ptex, + unsigned long avpn, unsigned long *old_pteh_ret, + unsigned long *old_ptel_ret) +{ + long rc; + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; + + rc = plpar_hcall_raw(H_REMOVE, retbuf, flags, ptex, avpn); + + *old_pteh_ret = retbuf[0]; + *old_ptel_ret = retbuf[1]; + + return rc; +} + static inline long plpar_pte_read(unsigned long flags, unsigned long ptex, unsigned long *old_pteh_ret, unsigned long *old_ptel_ret) { Index: linux-2.6.21-rc5/arch/s390/kernel/compat_wrapper.S =================================================================== --- linux-2.6.21-rc5.orig/arch/s390/kernel/compat_wrapper.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/s390/kernel/compat_wrapper.S 2007-03-27 14:20:38.000000000 +0100 @@ -1665,3 +1665,20 @@ sys_getcpu_wrapper: llgtr %r3,%r3 # unsigned * llgtr %r4,%r4 # struct getcpu_cache * jg sys_getcpu + + .globl compat_sys_epoll_pwait_wrapper +compat_sys_epoll_pwait_wrapper: + lgfr %r2,%r2 # int + llgtr %r3,%r3 # struct compat_epoll_event * + lgfr %r4,%r4 # int + lgfr %r5,%r5 # int + llgtr %r6,%r6 # compat_sigset_t * + llgf %r0,164(%r15) # compat_size_t + stg %r0,160(%r15) + jg compat_sys_epoll_pwait + + .globl compat_sys_utimes_wrapper +compat_sys_utimes_wrapper: + llgtr %r2,%r2 # char * + llgtr %r3,%r3 # struct compat_timeval * + jg compat_sys_utimes Index: linux-2.6.21-rc5/arch/s390/kernel/debug.c =================================================================== --- linux-2.6.21-rc5.orig/arch/s390/kernel/debug.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/s390/kernel/debug.c 2007-03-27 14:20:38.000000000 +0100 @@ -268,7 +268,7 @@ debug_info_alloc(char *name, int pages_p rc->level = level; rc->buf_size = buf_size; rc->entry_size = sizeof(debug_entry_t) + buf_size; - strlcpy(rc->name, name, sizeof(rc->name)-1); + strlcpy(rc->name, name, sizeof(rc->name)); memset(rc->views, 0, DEBUG_MAX_VIEWS * sizeof(struct debug_view *)); memset(rc->debugfs_entries, 0 ,DEBUG_MAX_VIEWS * sizeof(struct dentry*)); Index: linux-2.6.21-rc5/arch/s390/kernel/early.c =================================================================== --- linux-2.6.21-rc5.orig/arch/s390/kernel/early.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/s390/kernel/early.c 2007-03-27 14:20:38.000000000 +0100 @@ -141,9 +141,9 @@ static noinline __init void detect_machi machine_flags |= 4; } +#ifdef CONFIG_64BIT static noinline __init int memory_fast_detect(void) { - unsigned long val0 = 0; unsigned long val1 = 0xc; int ret = -ENOSYS; @@ -161,9 +161,15 @@ static noinline __init int memory_fast_d if (ret || val0 != val1) return -ENOSYS; - memory_chunk[0].size = val0; + memory_chunk[0].size = val0 + 1; return 0; } +#else +static inline int memory_fast_detect(void) +{ + return -ENOSYS; +} +#endif #define ADDR2G (1UL << 31) Index: linux-2.6.21-rc5/arch/s390/kernel/ipl.c =================================================================== --- linux-2.6.21-rc5.orig/arch/s390/kernel/ipl.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/s390/kernel/ipl.c 2007-03-27 14:20:38.000000000 +0100 @@ -839,7 +839,7 @@ static int __init reipl_ccw_init(void) } reipl_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; - reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw); + reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; /* check if read scp info worked and set loadparm */ if (SCCB_VALID) @@ -880,8 +880,7 @@ static int __init reipl_fcp_init(void) } else { reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; - reipl_block_fcp->hdr.blk0_len = - sizeof(reipl_block_fcp->ipl_info.fcp); + reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; reipl_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; reipl_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_IPL; } @@ -930,7 +929,7 @@ static int __init dump_ccw_init(void) } dump_block_ccw->hdr.len = IPL_PARM_BLK_CCW_LEN; dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; - dump_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw); + dump_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; dump_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; dump_capabilities |= IPL_TYPE_CCW; return 0; @@ -954,7 +953,7 @@ static int __init dump_fcp_init(void) } dump_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN; dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION; - dump_block_fcp->hdr.blk0_len = sizeof(dump_block_fcp->ipl_info.fcp); + dump_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN; dump_block_fcp->hdr.pbt = DIAG308_IPL_TYPE_FCP; dump_block_fcp->ipl_info.fcp.opt = DIAG308_IPL_OPT_DUMP; dump_capabilities |= IPL_TYPE_FCP; Index: linux-2.6.21-rc5/arch/s390/kernel/syscalls.S =================================================================== --- linux-2.6.21-rc5.orig/arch/s390/kernel/syscalls.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/s390/kernel/syscalls.S 2007-03-27 14:20:38.000000000 +0100 @@ -320,4 +320,5 @@ SYSCALL(sys_tee,sys_tee,sys_tee_wrapper) SYSCALL(sys_vmsplice,sys_vmsplice,compat_sys_vmsplice_wrapper) NI_SYSCALL /* 310 sys_move_pages */ SYSCALL(sys_getcpu,sys_getcpu,sys_getcpu_wrapper) -SYSCALL(sys_epoll_pwait,sys_epoll_pwait,sys_ni_syscall) +SYSCALL(sys_epoll_pwait,sys_epoll_pwait,compat_sys_epoll_pwait_wrapper) +SYSCALL(sys_utimes,sys_utimes,compat_sys_utimes_wrapper) Index: linux-2.6.21-rc5/arch/sh/drivers/pci/pci-auto.c =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/drivers/pci/pci-auto.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/drivers/pci/pci-auto.c 2007-03-27 14:20:38.000000000 +0100 @@ -214,6 +214,12 @@ retry: continue; } + if (bar_value < *lower_limit || (bar_value + bar_size) >= *upper_limit) { + DBG(" unavailable -- skipping, value %x size %x\n", + bar_value, bar_size); + continue; + } + #ifdef CONFIG_PCI_AUTO_UPDATE_RESOURCES /* Write it out and update our limit */ early_write_config_dword(hose, top_bus, current_bus, pci_devfn, Index: linux-2.6.21-rc5/arch/sh/kernel/cpu/init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/kernel/cpu/init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/kernel/cpu/init.c 2007-03-27 14:20:38.000000000 +0100 @@ -3,7 +3,7 @@ * * CPU init code * - * Copyright (C) 2002 - 2006 Paul Mundt + * Copyright (C) 2002 - 2007 Paul Mundt * Copyright (C) 2003 Richard Curnow * * This file is subject to the terms and conditions of the GNU General Public @@ -48,8 +48,19 @@ static void __init cache_init(void) { unsigned long ccr, flags; - if (current_cpu_data.type == CPU_SH_NONE) - panic("Unknown CPU"); + /* First setup the rest of the I-cache info */ + current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr - + current_cpu_data.icache.linesz; + + current_cpu_data.icache.way_size = current_cpu_data.icache.sets * + current_cpu_data.icache.linesz; + + /* And the D-cache too */ + current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr - + current_cpu_data.dcache.linesz; + + current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * + current_cpu_data.dcache.linesz; jump_to_P2(); ccr = ctrl_inl(CCR); @@ -200,6 +211,9 @@ asmlinkage void __init sh_cpu_init(void) /* First, probe the CPU */ detect_cpu_and_cache_system(); + if (current_cpu_data.type == CPU_SH_NONE) + panic("Unknown CPU"); + /* Init the cache */ cache_init(); Index: linux-2.6.21-rc5/arch/sh/kernel/cpu/sh2/entry.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/kernel/cpu/sh2/entry.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/kernel/cpu/sh2/entry.S 2007-03-27 14:20:38.000000000 +0100 @@ -165,6 +165,7 @@ ENTRY(exception_handler) interrupt_entry: mov r9,r4 + mov r15,r5 mov.l 6f,r9 mov.l 7f,r8 jmp @r8 Index: linux-2.6.21-rc5/arch/sh/kernel/cpu/sh3/entry.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/kernel/cpu/sh3/entry.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/kernel/cpu/sh3/entry.S 2007-03-27 14:20:38.000000000 +0100 @@ -514,13 +514,16 @@ skip_save: interrupt_exception: mov.l 1f, r9 + mov.l 2f, r4 + mov.l @r4, r4 jmp @r9 - nop + mov r15, r5 rts nop .align 2 1: .long do_IRQ +2: .long INTEVT .align 2 ENTRY(exception_none) Index: linux-2.6.21-rc5/arch/sh/kernel/cpu/sh4/probe.c =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/kernel/cpu/sh4/probe.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/kernel/cpu/sh4/probe.c 2007-03-27 14:20:38.000000000 +0100 @@ -195,13 +195,6 @@ int __init detect_cpu_and_cache_system(v } - /* Setup the rest of the I-cache info */ - current_cpu_data.icache.entry_mask = current_cpu_data.icache.way_incr - - current_cpu_data.icache.linesz; - - current_cpu_data.icache.way_size = current_cpu_data.icache.sets * - current_cpu_data.icache.linesz; - /* And the rest of the D-cache */ if (current_cpu_data.dcache.ways > 1) { size = sizes[(cvr >> 16) & 0xf]; @@ -209,12 +202,6 @@ int __init detect_cpu_and_cache_system(v current_cpu_data.dcache.sets = (size >> 6); } - current_cpu_data.dcache.entry_mask = current_cpu_data.dcache.way_incr - - current_cpu_data.dcache.linesz; - - current_cpu_data.dcache.way_size = current_cpu_data.dcache.sets * - current_cpu_data.dcache.linesz; - /* * Setup the L2 cache desc * Index: linux-2.6.21-rc5/arch/sh/kernel/irq.c =================================================================== --- linux-2.6.21-rc5.orig/arch/sh/kernel/irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sh/kernel/irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -82,13 +81,9 @@ static union irq_ctx *hardirq_ctx[NR_CPU static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly; #endif -asmlinkage int do_IRQ(unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7, - struct pt_regs __regs) +asmlinkage int do_IRQ(unsigned int irq, struct pt_regs *regs) { - struct pt_regs *regs = RELOC_HIDE(&__regs, 0); struct pt_regs *old_regs = set_irq_regs(regs); - int irq; #ifdef CONFIG_4KSTACKS union irq_ctx *curctx, *irqctx; #endif @@ -111,13 +106,7 @@ asmlinkage int do_IRQ(unsigned long r4, } #endif -#ifdef CONFIG_CPU_HAS_INTEVT - irq = evt2irq(ctrl_inl(INTEVT)); -#else - irq = r4; -#endif - - irq = irq_demux(irq); + irq = irq_demux(evt2irq(irq)); #ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *)current_thread_info(); Index: linux-2.6.21-rc5/arch/sparc64/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -136,18 +136,6 @@ config SMP If you don't know what to do here, say N. -config PREEMPT - bool "Preemptible Kernel" - help - This option reduces the latency of the kernel when reacting to - real-time or interactive events by allowing a low priority process to - be preempted even if it is in kernel mode executing a system call. - This allows applications to run more reliably even when the system is - under load. - - Say Y here if you are building a kernel for a desktop, embedded - or real-time system. Say N if you are unsure. - config NR_CPUS int "Maximum number of CPUs (2-64)" range 2 64 @@ -399,6 +387,8 @@ config SCHED_SMT when dealing with UltraSPARC cpus at a cost of slightly increased overhead in some places. If unsure say N here. +source "kernel/Kconfig.preempt" + config CMDLINE_BOOL bool "Default bootloader kernel arguments" Index: linux-2.6.21-rc5/arch/sparc64/defconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/defconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/defconfig 2007-03-27 14:20:38.000000000 +0100 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.21-rc2 -# Wed Feb 28 09:50:51 2007 +# Linux kernel version: 2.6.21-rc4 +# Sat Mar 17 14:18:44 2007 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -50,6 +50,7 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_IKCONFIG is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_RELAY=y +# CONFIG_BLK_DEV_INITRD is not set CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y # CONFIG_EMBEDDED is not set @@ -108,7 +109,6 @@ CONFIG_GENERIC_HARDIRQS=y # General machine setup # # CONFIG_SMP is not set -# CONFIG_PREEMPT is not set CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_TABLE=m # CONFIG_CPU_FREQ_DEBUG is not set @@ -165,6 +165,9 @@ CONFIG_BINFMT_ELF32=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m CONFIG_SOLARIS_EMUL=y +# CONFIG_PREEMPT_NONE is not set +CONFIG_PREEMPT_VOLUNTARY=y +# CONFIG_PREEMPT is not set # CONFIG_CMDLINE_BOOL is not set # @@ -340,7 +343,6 @@ CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set # CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set CONFIG_CDROM_PKTCDVD=m CONFIG_CDROM_PKTCDVD_BUFFERS=8 CONFIG_CDROM_PKTCDVD_WCACHE=y Index: linux-2.6.21-rc5/arch/sparc64/kernel/ktlb.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/kernel/ktlb.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/kernel/ktlb.S 2007-03-27 14:20:38.000000000 +0100 @@ -138,9 +138,15 @@ kvmap_dtlb_4v: brgez,pn %g4, kvmap_dtlb_nonlinear nop +#ifdef CONFIG_DEBUG_PAGEALLOC + /* Index through the base page size TSB even for linear + * mappings when using page allocation debugging. + */ + KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) +#else /* Correct TAG_TARGET is already in %g6, check 4mb TSB. */ KERN_TSB4M_LOOKUP_TL1(%g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) - +#endif /* TSB entry address left in %g1, lookup linear PTE. * Must preserve %g1 and %g6 (TAG). */ Index: linux-2.6.21-rc5/arch/sparc64/kernel/tsb.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/kernel/tsb.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/kernel/tsb.S 2007-03-27 14:20:38.000000000 +0100 @@ -546,6 +546,7 @@ NGtsb_init: subcc %o1, 0x100, %o1 bne,pt %xcc, 1b add %o0, 0x100, %o0 + membar #Sync retl wr %g2, 0x0, %asi .size NGtsb_init, .-NGtsb_init Index: linux-2.6.21-rc5/arch/sparc64/lib/NGbzero.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/lib/NGbzero.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/lib/NGbzero.S 2007-03-27 14:20:38.000000000 +0100 @@ -88,6 +88,7 @@ NGbzero_loop: bne,pt %xcc, NGbzero_loop add %o0, 64, %o0 + membar #Sync wr %o4, 0x0, %asi brz,pn %o1, NGbzero_done NGbzero_medium: Index: linux-2.6.21-rc5/arch/sparc64/lib/NGmemcpy.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/lib/NGmemcpy.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/lib/NGmemcpy.S 2007-03-27 14:20:38.000000000 +0100 @@ -247,6 +247,8 @@ FUNC_NAME: /* %o0=dst, %o1=src, %o2=len /* fall through */ 60: + membar #Sync + /* %o2 contains any final bytes still needed to be copied * over. If anything is left, we copy it one byte at a time. */ Index: linux-2.6.21-rc5/arch/sparc64/lib/NGpage.S =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/lib/NGpage.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/lib/NGpage.S 2007-03-27 14:20:38.000000000 +0100 @@ -41,6 +41,7 @@ NGcopy_user_page: /* %o0=dest, %o1=src, subcc %g7, 64, %g7 bne,pt %xcc, 1b add %o0, 32, %o0 + membar #Sync retl nop @@ -63,6 +64,7 @@ NGclear_user_page: /* %o0=dest, %o1=vadd subcc %g7, 64, %g7 bne,pt %xcc, 1b add %o0, 32, %o0 + membar #Sync retl nop Index: linux-2.6.21-rc5/arch/sparc64/mm/init.c =================================================================== --- linux-2.6.21-rc5.orig/arch/sparc64/mm/init.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/sparc64/mm/init.c 2007-03-27 14:20:38.000000000 +0100 @@ -59,8 +59,10 @@ unsigned long kern_linear_pte_xor[2] __r */ unsigned long kpte_linear_bitmap[KPTE_BITMAP_BYTES / sizeof(unsigned long)]; +#ifndef CONFIG_DEBUG_PAGEALLOC /* A special kernel TSB for 4MB and 256MB linear mappings. */ struct tsb swapper_4m_tsb[KERNEL_TSB4M_NENTRIES]; +#endif #define MAX_BANKS 32 @@ -1301,7 +1303,12 @@ static void __init tsb_phys_patch(void) } /* Don't mark as init, we give this to the Hypervisor. */ -static struct hv_tsb_descr ktsb_descr[2]; +#ifndef CONFIG_DEBUG_PAGEALLOC +#define NUM_KTSB_DESCR 2 +#else +#define NUM_KTSB_DESCR 1 +#endif +static struct hv_tsb_descr ktsb_descr[NUM_KTSB_DESCR]; extern struct tsb swapper_tsb[KERNEL_TSB_NENTRIES]; static void __init sun4v_ktsb_init(void) @@ -1340,6 +1347,7 @@ static void __init sun4v_ktsb_init(void) ktsb_descr[0].tsb_base = ktsb_pa; ktsb_descr[0].resv = 0; +#ifndef CONFIG_DEBUG_PAGEALLOC /* Second KTSB for 4MB/256MB mappings. */ ktsb_pa = (kern_base + ((unsigned long)&swapper_4m_tsb[0] - KERNBASE)); @@ -1352,6 +1360,7 @@ static void __init sun4v_ktsb_init(void) ktsb_descr[1].ctx_idx = 0; ktsb_descr[1].tsb_base = ktsb_pa; ktsb_descr[1].resv = 0; +#endif } void __cpuinit sun4v_ktsb_register(void) @@ -1364,7 +1373,7 @@ void __cpuinit sun4v_ktsb_register(void) pa = kern_base + ((unsigned long)&ktsb_descr[0] - KERNBASE); func = HV_FAST_MMU_TSB_CTX0; - arg0 = 2; + arg0 = NUM_KTSB_DESCR; arg1 = pa; __asm__ __volatile__("ta %6" : "=&r" (func), "=&r" (arg0), "=&r" (arg1) @@ -1393,7 +1402,9 @@ void __init paging_init(void) /* Invalidate both kernel TSBs. */ memset(swapper_tsb, 0x40, sizeof(swapper_tsb)); +#ifndef CONFIG_DEBUG_PAGEALLOC memset(swapper_4m_tsb, 0x40, sizeof(swapper_4m_tsb)); +#endif if (tlb_type == hypervisor) sun4v_pgprot_init(); @@ -1725,8 +1736,13 @@ static void __init sun4u_pgprot_init(voi pg_iobits = (_PAGE_VALID | _PAGE_PRESENT_4U | __DIRTY_BITS_4U | __ACCESS_BITS_4U | _PAGE_E_4U); +#ifdef CONFIG_DEBUG_PAGEALLOC + kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4U) ^ + 0xfffff80000000000; +#else kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4U) ^ 0xfffff80000000000; +#endif kern_linear_pte_xor[0] |= (_PAGE_CP_4U | _PAGE_CV_4U | _PAGE_P_4U | _PAGE_W_4U); @@ -1769,13 +1785,23 @@ static void __init sun4v_pgprot_init(voi _PAGE_E = _PAGE_E_4V; _PAGE_CACHE = _PAGE_CACHE_4V; +#ifdef CONFIG_DEBUG_PAGEALLOC + kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ + 0xfffff80000000000; +#else kern_linear_pte_xor[0] = (_PAGE_VALID | _PAGE_SZ4MB_4V) ^ 0xfffff80000000000; +#endif kern_linear_pte_xor[0] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); +#ifdef CONFIG_DEBUG_PAGEALLOC + kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZBITS_4V) ^ + 0xfffff80000000000; +#else kern_linear_pte_xor[1] = (_PAGE_VALID | _PAGE_SZ256MB_4V) ^ 0xfffff80000000000; +#endif kern_linear_pte_xor[1] |= (_PAGE_CP_4V | _PAGE_CV_4V | _PAGE_P_4V | _PAGE_W_4V); Index: linux-2.6.21-rc5/arch/x86_64/defconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/defconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/defconfig 2007-03-27 14:20:38.000000000 +0100 @@ -1,11 +1,13 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-git8 -# Tue Feb 13 11:25:16 2007 +# Linux kernel version: 2.6.21-rc3 +# Wed Mar 7 15:29:47 2007 # CONFIG_X86_64=y CONFIG_64BIT=y CONFIG_X86=y +CONFIG_GENERIC_TIME=y +CONFIG_GENERIC_TIME_VSYSCALL=y CONFIG_ZONE_DMA32=y CONFIG_LOCKDEP_SUPPORT=y CONFIG_STACKTRACE_SUPPORT=y @@ -43,6 +45,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set @@ -53,6 +56,7 @@ CONFIG_IKCONFIG_PROC=y # CONFIG_CPUSETS is not set CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set +CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y @@ -114,11 +118,11 @@ CONFIG_X86_PC=y # CONFIG_X86_VSMP is not set # CONFIG_MK8 is not set # CONFIG_MPSC is not set -CONFIG_MCORE2=y -# CONFIG_GENERIC_CPU is not set -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_L1_CACHE_SHIFT=6 -CONFIG_X86_INTERNODE_CACHE_BYTES=64 +# CONFIG_MCORE2 is not set +CONFIG_GENERIC_CPU=y +CONFIG_X86_L1_CACHE_BYTES=128 +CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_TSC=y CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set @@ -207,10 +211,8 @@ CONFIG_ACPI_PROCFS=y CONFIG_ACPI_AC=y CONFIG_ACPI_BATTERY=y CONFIG_ACPI_BUTTON=y -# CONFIG_ACPI_HOTKEY is not set CONFIG_ACPI_FAN=y # CONFIG_ACPI_DOCK is not set -# CONFIG_ACPI_BAY is not set CONFIG_ACPI_PROCESSOR=y CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=y @@ -319,7 +321,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set # CONFIG_INET_XFRM_TUNNEL is not set -# CONFIG_INET_TUNNEL is not set +CONFIG_INET_TUNNEL=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set @@ -421,7 +423,13 @@ CONFIG_FW_LOADER=y # # Plug and Play support # -# CONFIG_PNP is not set +CONFIG_PNP=y +# CONFIG_PNP_DEBUG is not set + +# +# Protocols +# +CONFIG_PNPACPI=y # # Block devices @@ -441,7 +449,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -451,6 +458,7 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_IBM_ASM is not set # CONFIG_SGI_IOC4 is not set # CONFIG_TIFM_CORE is not set +# CONFIG_SONY_LAPTOP is not set # # ATA/ATAPI/MFM/RLL support @@ -477,6 +485,7 @@ CONFIG_BLK_DEV_IDEACPI=y # CONFIG_IDE_GENERIC=y # CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_IDEPNP is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -623,6 +632,7 @@ CONFIG_SATA_VIA=y # CONFIG_SATA_VITESSE is not set # CONFIG_SATA_INIC162X is not set CONFIG_SATA_INTEL_COMBINED=y +CONFIG_SATA_ACPI=y # CONFIG_PATA_ALI is not set # CONFIG_PATA_AMD is not set # CONFIG_PATA_ARTOP is not set @@ -726,6 +736,7 @@ CONFIG_NETDEVICES=y # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set CONFIG_TUN=y +# CONFIG_NET_SB1000 is not set # # ARCnet devices @@ -920,6 +931,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_PNP=y CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -1001,6 +1013,7 @@ CONFIG_I2C_ISA=m # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_OCORES is not set # CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_PASEMI is not set # CONFIG_I2C_PROSAVAGE is not set # CONFIG_I2C_SAVAGE4 is not set # CONFIG_I2C_SIS5595 is not set @@ -1047,6 +1060,7 @@ CONFIG_HWMON=y # CONFIG_SENSORS_ADM1021 is not set # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_K8TEMP is not set @@ -1090,6 +1104,11 @@ CONFIG_SENSORS_SMSC47B397=m # CONFIG_HWMON_DEBUG_CHIP is not set # +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -1103,7 +1122,7 @@ CONFIG_SENSORS_SMSC47B397=m # # Graphics support # -# CONFIG_FIRMWARE_EDID is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # @@ -1114,7 +1133,6 @@ CONFIG_VGACON_SOFT_SCROLLBACK=y CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=256 CONFIG_VIDEO_SELECT=y CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1130,9 +1148,8 @@ CONFIG_SOUND=y # Open Sound System # CONFIG_SOUND_PRIME=y -CONFIG_OBSOLETE_OSS=y +# CONFIG_OBSOLETE_OSS is not set # CONFIG_SOUND_BT878 is not set -# CONFIG_SOUND_ES1371 is not set CONFIG_SOUND_ICH=y # CONFIG_SOUND_TRIDENT is not set # CONFIG_SOUND_MSNDCLAS is not set @@ -1263,6 +1280,7 @@ CONFIG_USB_MON=y # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set +# CONFIG_USB_BERRY_CHARGE is not set # CONFIG_USB_LED is not set # CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set @@ -1273,6 +1291,7 @@ CONFIG_USB_MON=y # CONFIG_USB_SISUSBVGA is not set # CONFIG_USB_LD is not set # CONFIG_USB_TRANCEVIBRATOR is not set +# CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # @@ -1538,6 +1557,7 @@ CONFIG_DEBUG_KERNEL=y CONFIG_LOG_BUF_SHIFT=18 CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_SCHEDSTATS is not set +# CONFIG_TIMER_STATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_RT_MUTEX_TESTER is not set @@ -1556,6 +1576,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_LKDTM is not set +# CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_RODATA is not set # CONFIG_IOMMU_DEBUG is not set CONFIG_DEBUG_STACKOVERFLOW=y Index: linux-2.6.21-rc5/arch/x86_64/ia32/ia32entry.S =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/ia32/ia32entry.S 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/ia32/ia32entry.S 2007-03-27 14:20:38.000000000 +0100 @@ -560,7 +560,7 @@ ia32_sys_call_table: .quad sys_sched_yield .quad sys_sched_get_priority_max .quad sys_sched_get_priority_min /* 160 */ - .quad sys_sched_rr_get_interval + .quad sys32_sched_rr_get_interval .quad compat_sys_nanosleep .quad sys_mremap .quad sys_setresuid16 Index: linux-2.6.21-rc5/arch/x86_64/kernel/apic.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/apic.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/apic.c 2007-03-27 14:20:38.000000000 +0100 @@ -47,6 +47,10 @@ int apic_calibrate_pmtmr __initdata; int disable_apic_timer __initdata; +/* Local APIC timer works in C2? */ +int local_apic_timer_c2_ok; +EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok); + static struct resource *ioapic_resources; static struct resource lapic_resource = { .name = "Local APIC", @@ -930,9 +934,17 @@ EXPORT_SYMBOL(switch_APIC_timer_to_ipi); void smp_send_timer_broadcast_ipi(void) { + int cpu = smp_processor_id(); cpumask_t mask; cpus_and(mask, cpu_online_map, timer_interrupt_broadcast_ipi_mask); + + if (cpu_isset(cpu, mask)) { + cpu_clear(cpu, mask); + add_pda(apic_timer_irqs, 1); + smp_local_timer_interrupt(); + } + if (!cpus_empty(mask)) { send_IPI_mask(mask, LOCAL_TIMER_VECTOR); } @@ -1192,6 +1204,13 @@ static __init int setup_nolapic(char *st } early_param("nolapic", setup_nolapic); +static int __init parse_lapic_timer_c2_ok(char *arg) +{ + local_apic_timer_c2_ok = 1; + return 0; +} +early_param("lapic_timer_c2_ok", parse_lapic_timer_c2_ok); + static __init int setup_noapictimer(char *str) { if (str[0] != ' ' && str[0] != 0) Index: linux-2.6.21-rc5/arch/x86_64/kernel/cpufreq/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/cpufreq/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/cpufreq/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -75,6 +75,7 @@ config X86_ACPI_CPUFREQ_PROC_INTF config X86_P4_CLOCKMOD tristate "Intel Pentium 4 clock modulation" depends on EMBEDDED + select CPU_FREQ_TABLE help This adds the clock modulation driver for Intel Pentium 4 / XEON processors. When enabled it will lower CPU temperature by skipping Index: linux-2.6.21-rc5/arch/x86_64/kernel/e820.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/e820.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/e820.c 2007-03-27 14:20:38.000000000 +0100 @@ -662,7 +662,7 @@ static int __init parse_memmap_opt(char } early_param("memmap", parse_memmap_opt); -void finish_e820_parsing(void) +void __init finish_e820_parsing(void) { if (userdef) { printk(KERN_INFO "user-defined physical RAM map:\n"); Index: linux-2.6.21-rc5/arch/x86_64/kernel/early-quirks.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/early-quirks.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/early-quirks.c 2007-03-27 14:20:38.000000000 +0100 @@ -16,7 +16,7 @@ #include #include -static void via_bugs(void) +static void __init via_bugs(void) { #ifdef CONFIG_IOMMU if ((end_pfn > MAX_DMA32_PFN || force_iommu) && @@ -36,7 +36,7 @@ static int __init nvidia_hpet_check(stru } #endif -static void nvidia_bugs(void) +static void __init nvidia_bugs(void) { #ifdef CONFIG_ACPI /* @@ -62,7 +62,7 @@ static void nvidia_bugs(void) } -static void ati_bugs(void) +static void __init ati_bugs(void) { if (timer_over_8254 == 1) { timer_over_8254 = 0; @@ -88,7 +88,7 @@ struct chipset { void (*f)(void); }; -static struct chipset early_qrk[] = { +static struct __initdata chipset early_qrk[] = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, Index: linux-2.6.21-rc5/arch/x86_64/kernel/mpparse.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/mpparse.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/mpparse.c 2007-03-27 14:20:38.000000000 +0100 @@ -60,9 +60,9 @@ unsigned long mp_lapic_addr = 0; /* Processor that is doing the boot up */ unsigned int boot_cpu_id = -1U; /* Internal processor count */ -unsigned int num_processors __initdata = 0; +unsigned int num_processors __cpuinitdata = 0; -unsigned disabled_cpus __initdata; +unsigned disabled_cpus __cpuinitdata; /* Bitmask of physically existing CPUs */ physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; Index: linux-2.6.21-rc5/arch/x86_64/kernel/pci-gart.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/pci-gart.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/pci-gart.c 2007-03-27 14:20:38.000000000 +0100 @@ -675,7 +675,7 @@ void __init gart_iommu_init(void) dma_ops = &gart_dma_ops; } -void gart_parse_options(char *p) +void __init gart_parse_options(char *p) { int arg; Index: linux-2.6.21-rc5/arch/x86_64/kernel/process.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/process.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/process.c 2007-03-27 14:20:38.000000000 +0100 @@ -382,14 +382,17 @@ void exit_thread(void) void flush_thread(void) { struct task_struct *tsk = current; - struct thread_info *t = current_thread_info(); - if (t->flags & _TIF_ABI_PENDING) { - t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32); - if (t->flags & _TIF_IA32) + if (test_tsk_thread_flag(tsk, TIF_ABI_PENDING)) { + clear_tsk_thread_flag(tsk, TIF_ABI_PENDING); + if (test_tsk_thread_flag(tsk, TIF_IA32)) { + clear_tsk_thread_flag(tsk, TIF_IA32); + } else { + set_tsk_thread_flag(tsk, TIF_IA32); current_thread_info()->status |= TS_COMPAT; + } } - t->flags &= ~_TIF_DEBUG; + clear_tsk_thread_flag(tsk, TIF_DEBUG); tsk->thread.debugreg0 = 0; tsk->thread.debugreg1 = 0; Index: linux-2.6.21-rc5/arch/x86_64/kernel/x8664_ksyms.c =================================================================== --- linux-2.6.21-rc5.orig/arch/x86_64/kernel/x8664_ksyms.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/arch/x86_64/kernel/x8664_ksyms.c 2007-03-27 14:20:38.000000000 +0100 @@ -59,3 +59,4 @@ EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(init_level4_pgt); EXPORT_SYMBOL(load_gs_index); +EXPORT_SYMBOL(_proxy_pda); Index: linux-2.6.21-rc5/crypto/scatterwalk.c =================================================================== --- linux-2.6.21-rc5.orig/crypto/scatterwalk.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/crypto/scatterwalk.c 2007-03-27 14:20:38.000000000 +0100 @@ -91,6 +91,8 @@ void scatterwalk_copychunks(void *buf, s memcpy_dir(buf, vaddr, len_this_page, out); scatterwalk_unmap(vaddr, out); + scatterwalk_advance(walk, nbytes); + if (nbytes == len_this_page) break; @@ -99,7 +101,5 @@ void scatterwalk_copychunks(void *buf, s scatterwalk_pagedone(walk, out, 1); } - - scatterwalk_advance(walk, nbytes); } EXPORT_SYMBOL_GPL(scatterwalk_copychunks); Index: linux-2.6.21-rc5/crypto/tcrypt.c =================================================================== --- linux-2.6.21-rc5.orig/crypto/tcrypt.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/crypto/tcrypt.c 2007-03-27 14:20:38.000000000 +0100 @@ -768,7 +768,7 @@ static void test_deflate(void) tv = (void *)tvmem; tfm = crypto_alloc_comp("deflate", 0, CRYPTO_ALG_ASYNC); - if (tfm == NULL) { + if (IS_ERR(tfm)) { printk("failed to load transform for deflate\n"); return; } Index: linux-2.6.21-rc5/drivers/acpi/events/evmisc.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/events/evmisc.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/events/evmisc.c 2007-03-27 14:20:38.000000000 +0100 @@ -196,11 +196,15 @@ acpi_ev_queue_notify_request(struct acpi notify_info->notify.value = (u16) notify_value; notify_info->notify.handler_obj = handler_obj; - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); acpi_ev_notify_dispatch(notify_info); - acpi_ex_reacquire_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + } if (!handler_obj) { Index: linux-2.6.21-rc5/drivers/acpi/events/evregion.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/events/evregion.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/events/evregion.c 2007-03-27 14:20:38.000000000 +0100 @@ -291,6 +291,7 @@ acpi_ev_address_space_dispatch(union acp u32 bit_width, acpi_integer * value) { acpi_status status; + acpi_status status2; acpi_adr_space_handler handler; acpi_adr_space_setup region_setup; union acpi_operand_object *handler_desc; @@ -344,7 +345,7 @@ acpi_ev_address_space_dispatch(union acp * setup will potentially execute control methods * (e.g., _REG method for this region) */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = region_setup(region_obj, ACPI_REGION_ACTIVATE, handler_desc->address_space.context, @@ -352,7 +353,10 @@ acpi_ev_address_space_dispatch(union acp /* Re-enter the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } /* Check for failure of the Region Setup */ @@ -405,7 +409,7 @@ acpi_ev_address_space_dispatch(union acp * exit the interpreter because the handler *might* block -- we don't * know what it will do, so we can't hold the lock on the intepreter. */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); } /* Call the handler */ @@ -426,7 +430,10 @@ acpi_ev_address_space_dispatch(union acp * We just returned from a non-default handler, we must re-enter the * interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); Index: linux-2.6.21-rc5/drivers/acpi/events/evxface.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/events/evxface.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/events/evxface.c 2007-03-27 14:20:38.000000000 +0100 @@ -768,9 +768,11 @@ acpi_status acpi_acquire_global_lock(u16 return (AE_BAD_PARAMETER); } - /* Must lock interpreter to prevent race conditions */ + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } - acpi_ex_enter_interpreter(); status = acpi_ev_acquire_global_lock(timeout); acpi_ex_exit_interpreter(); Index: linux-2.6.21-rc5/drivers/acpi/executer/excreate.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/executer/excreate.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/executer/excreate.c 2007-03-27 14:20:38.000000000 +0100 @@ -583,7 +583,10 @@ acpi_ex_create_method(u8 * aml_start, * Get the sync_level. If method is serialized, a mutex will be * created for this method when it is parsed. */ - if (method_flags & AML_METHOD_SERIALIZED) { + if (acpi_gbl_all_methods_serialized) { + obj_desc->method.sync_level = 0; + obj_desc->method.method_flags |= AML_METHOD_SERIALIZED; + } else if (method_flags & AML_METHOD_SERIALIZED) { /* * ACPI 1.0: sync_level = 0 * ACPI 2.0: sync_level = sync_level in method declaration Index: linux-2.6.21-rc5/drivers/acpi/executer/exsystem.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/executer/exsystem.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/executer/exsystem.c 2007-03-27 14:20:38.000000000 +0100 @@ -66,6 +66,7 @@ ACPI_MODULE_NAME("exsystem") acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); @@ -78,7 +79,7 @@ acpi_status acpi_ex_system_wait_semaphor /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_wait_semaphore(semaphore, 1, timeout); @@ -88,7 +89,13 @@ acpi_status acpi_ex_system_wait_semaphor /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -112,6 +119,7 @@ acpi_status acpi_ex_system_wait_semaphor acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) { acpi_status status; + acpi_status status2; ACPI_FUNCTION_TRACE(ex_system_wait_mutex); @@ -124,7 +132,7 @@ acpi_status acpi_ex_system_wait_mutex(ac /* We must wait, so unlock the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); status = acpi_os_acquire_mutex(mutex, timeout); @@ -134,7 +142,13 @@ acpi_status acpi_ex_system_wait_mutex(ac /* Reacquire the interpreter */ - acpi_ex_reacquire_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status2)) { + + /* Report fatal error, could not acquire interpreter */ + + return_ACPI_STATUS(status2); + } } return_ACPI_STATUS(status); @@ -195,18 +209,20 @@ acpi_status acpi_ex_system_do_stall(u32 acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) { + acpi_status status; + ACPI_FUNCTION_ENTRY(); /* Since this thread will sleep, we must release the interpreter */ - acpi_ex_relinquish_interpreter(); + acpi_ex_exit_interpreter(); acpi_os_sleep(how_long); /* And now we must get the interpreter again */ - acpi_ex_reacquire_interpreter(); - return (AE_OK); + status = acpi_ex_enter_interpreter(); + return (status); } /******************************************************************************* Index: linux-2.6.21-rc5/drivers/acpi/executer/exutils.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/executer/exutils.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/executer/exutils.c 2007-03-27 14:20:38.000000000 +0100 @@ -76,15 +76,14 @@ static u32 acpi_ex_digits_needed(acpi_in * * PARAMETERS: None * - * RETURN: None + * RETURN: Status * - * DESCRIPTION: Enter the interpreter execution region. Failure to enter - * the interpreter region is a fatal system error. Used in - * conjunction with exit_interpreter. + * DESCRIPTION: Enter the interpreter execution region. Failure to enter + * the interpreter region is a fatal system error * ******************************************************************************/ -void acpi_ex_enter_interpreter(void) +acpi_status acpi_ex_enter_interpreter(void) { acpi_status status; @@ -92,42 +91,10 @@ void acpi_ex_enter_interpreter(void) status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not acquire AML Interpreter mutex")); + ACPI_ERROR((AE_INFO, "Could not acquire interpreter mutex")); } - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_reacquire_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Reacquire the interpreter execution region from within the - * interpreter code. Failure to enter the interpreter region is a - * fatal system error. Used in conjuction with - * relinquish_interpreter - * - ******************************************************************************/ - -void acpi_ex_reacquire_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_reacquire_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter, - * since it was not actually released by acpi_ex_relinquish_interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_enter_interpreter(); - } - - return_VOID; + return_ACPI_STATUS(status); } /******************************************************************************* @@ -138,9 +105,17 @@ void acpi_ex_reacquire_interpreter(void) * * RETURN: None * - * DESCRIPTION: Exit the interpreter execution region. This is the top level - * routine used to exit the interpreter when all processing has - * been completed. + * DESCRIPTION: Exit the interpreter execution region + * + * Cases where the interpreter is unlocked: + * 1) Completion of the execution of a control method + * 2) Method blocked on a Sleep() AML opcode + * 3) Method blocked on an Acquire() AML opcode + * 4) Method blocked on a Wait() AML opcode + * 5) Method blocked to acquire the global lock + * 6) Method blocked to execute a serialized control method that is + * already executing + * 7) About to invoke a user-installed opregion handler * ******************************************************************************/ @@ -152,46 +127,7 @@ void acpi_ex_exit_interpreter(void) status = acpi_ut_release_mutex(ACPI_MTX_INTERPRETER); if (ACPI_FAILURE(status)) { - ACPI_ERROR((AE_INFO, - "Could not release AML Interpreter mutex")); - } - - return_VOID; -} - -/******************************************************************************* - * - * FUNCTION: acpi_ex_relinquish_interpreter - * - * PARAMETERS: None - * - * RETURN: None - * - * DESCRIPTION: Exit the interpreter execution region, from within the - * interpreter - before attempting an operation that will possibly - * block the running thread. - * - * Cases where the interpreter is unlocked internally - * 1) Method to be blocked on a Sleep() AML opcode - * 2) Method to be blocked on an Acquire() AML opcode - * 3) Method to be blocked on a Wait() AML opcode - * 4) Method to be blocked to acquire the global lock - * 5) Method to be blocked waiting to execute a serialized control method - * that is currently executing - * 6) About to invoke a user-installed opregion handler - * - ******************************************************************************/ - -void acpi_ex_relinquish_interpreter(void) -{ - ACPI_FUNCTION_TRACE(ex_relinquish_interpreter); - - /* - * If the global serialized flag is set, do not release the interpreter. - * This forces the interpreter to be single threaded. - */ - if (!acpi_gbl_all_methods_serialized) { - acpi_ex_exit_interpreter(); + ACPI_ERROR((AE_INFO, "Could not release interpreter mutex")); } return_VOID; @@ -205,8 +141,8 @@ void acpi_ex_relinquish_interpreter(void * * RETURN: none * - * DESCRIPTION: Truncate an ACPI Integer to 32 bits if the execution mode is - * 32-bit, as determined by the revision of the DSDT. + * DESCRIPTION: Truncate a number to 32-bits if the currently executing method + * belongs to a 32-bit ACPI table. * ******************************************************************************/ Index: linux-2.6.21-rc5/drivers/acpi/hardware/hwsleep.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/hardware/hwsleep.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/hardware/hwsleep.c 2007-03-27 14:20:38.000000000 +0100 @@ -300,6 +300,11 @@ acpi_status asmlinkage acpi_enter_sleep_ /* * 2) Enable all wakeup GPEs */ + status = acpi_hw_disable_all_gpes(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + acpi_gbl_system_awake_and_running = FALSE; status = acpi_hw_enable_all_wakeup_gpes(); Index: linux-2.6.21-rc5/drivers/acpi/ibm_acpi.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/ibm_acpi.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/ibm_acpi.c 2007-03-27 14:20:38.000000000 +0100 @@ -2507,7 +2507,7 @@ static int __init setup_notify(struct ib ret = acpi_bus_get_device(*ibm->handle, &ibm->device); if (ret < 0) { printk(IBM_ERR "%s device not present\n", ibm->name); - return 0; + return -ENODEV; } acpi_driver_data(ibm->device) = ibm; @@ -2516,8 +2516,13 @@ static int __init setup_notify(struct ib status = acpi_install_notify_handler(*ibm->handle, ibm->type, dispatch_notify, ibm); if (ACPI_FAILURE(status)) { - printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n", - ibm->name, status); + if (status == AE_ALREADY_EXISTS) { + printk(IBM_NOTICE "another device driver is already handling %s events\n", + ibm->name); + } else { + printk(IBM_ERR "acpi_install_notify_handler(%s) failed: %d\n", + ibm->name, status); + } return -ENODEV; } ibm->notify_installed = 1; @@ -2553,6 +2558,8 @@ static int __init register_driver(struct return ret; } +static void ibm_exit(struct ibm_struct *ibm); + static int __init ibm_init(struct ibm_struct *ibm) { int ret; @@ -2594,6 +2601,12 @@ static int __init ibm_init(struct ibm_st if (ibm->notify) { ret = setup_notify(ibm); + if (ret == -ENODEV) { + printk(IBM_NOTICE "disabling subdriver %s\n", + ibm->name); + ibm_exit(ibm); + return 0; + } if (ret < 0) return ret; } Index: linux-2.6.21-rc5/drivers/acpi/namespace/nseval.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/namespace/nseval.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/namespace/nseval.c 2007-03-27 14:20:38.000000000 +0100 @@ -154,7 +154,11 @@ acpi_status acpi_ns_evaluate(struct acpi * Execute the method via the interpreter. The interpreter is locked * here before calling into the AML parser */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + status = acpi_ps_execute_method(info); acpi_ex_exit_interpreter(); } else { @@ -178,7 +182,10 @@ acpi_status acpi_ns_evaluate(struct acpi * resolution, we must lock it because we could access an opregion. * The opregion access code assumes that the interpreter is locked. */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } /* Function has a strange interface */ Index: linux-2.6.21-rc5/drivers/acpi/namespace/nsinit.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/namespace/nsinit.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/namespace/nsinit.c 2007-03-27 14:20:38.000000000 +0100 @@ -214,7 +214,7 @@ acpi_ns_init_one_object(acpi_handle obj_ u32 level, void *context, void **return_value) { acpi_object_type type; - acpi_status status = AE_OK; + acpi_status status; struct acpi_init_walk_info *info = (struct acpi_init_walk_info *)context; struct acpi_namespace_node *node = @@ -268,7 +268,10 @@ acpi_ns_init_one_object(acpi_handle obj_ /* * Must lock the interpreter before executing AML code */ - acpi_ex_enter_interpreter(); + status = acpi_ex_enter_interpreter(); + if (ACPI_FAILURE(status)) { + return (status); + } /* * Each of these types can contain executable AML code within the Index: linux-2.6.21-rc5/drivers/acpi/namespace/nsxfeval.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/namespace/nsxfeval.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/namespace/nsxfeval.c 2007-03-27 14:20:38.000000000 +0100 @@ -170,6 +170,7 @@ acpi_evaluate_object(acpi_handle handle, struct acpi_buffer *return_buffer) { acpi_status status; + acpi_status status2; struct acpi_evaluate_info *info; acpi_size buffer_space_needed; u32 i; @@ -328,12 +329,14 @@ acpi_evaluate_object(acpi_handle handle, * Delete the internal return object. NOTE: Interpreter must be * locked to avoid race condition. */ - acpi_ex_enter_interpreter(); + status2 = acpi_ex_enter_interpreter(); + if (ACPI_SUCCESS(status2)) { - /* Remove one reference on the return object (should delete it) */ + /* Remove one reference on the return object (should delete it) */ - acpi_ut_remove_reference(info->return_object); - acpi_ex_exit_interpreter(); + acpi_ut_remove_reference(info->return_object); + acpi_ex_exit_interpreter(); + } } cleanup: Index: linux-2.6.21-rc5/drivers/acpi/processor_idle.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/processor_idle.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/processor_idle.c 2007-03-27 14:20:38.000000000 +0100 @@ -268,6 +268,7 @@ static void acpi_timer_check_state(int s struct acpi_processor_cx *cx) { struct acpi_processor_power *pwr = &pr->power; + u8 type = local_apic_timer_c2_ok ? ACPI_STATE_C3 : ACPI_STATE_C2; /* * Check, if one of the previous states already marked the lapic @@ -276,7 +277,7 @@ static void acpi_timer_check_state(int s if (pwr->timer_broadcast_on_state < state) return; - if (cx->type >= ACPI_STATE_C2) + if (cx->type >= type) pr->power.timer_broadcast_on_state = state; } Index: linux-2.6.21-rc5/drivers/acpi/tables.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/acpi/tables.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/acpi/tables.c 2007-03-27 14:20:38.000000000 +0100 @@ -42,7 +42,9 @@ static char *mps_inti_flags_trigger[] = static struct acpi_table_desc initial_tables[ACPI_MAX_TABLES] __initdata; -void acpi_table_print_madt_entry(struct acpi_subtable_header * header) +static int acpi_apic_instance __initdata = 2; + +void acpi_table_print_madt_entry(struct acpi_subtable_header *header) { if (!header) return; @@ -183,8 +185,10 @@ acpi_table_parse_entries(char *id, if (!handler) return -EINVAL; - /* Locate the table (if exists). There should only be one. */ - acpi_get_table(id, 0, &table_header); + if (strncmp(id, ACPI_SIG_MADT, 4) == 0) + acpi_get_table(id, acpi_apic_instance, &table_header); + else + acpi_get_table(id, 0, &table_header); if (!table_header) { printk(KERN_WARNING PREFIX "%4.4s not present\n", id); @@ -237,10 +241,15 @@ acpi_table_parse_madt(enum acpi_madt_typ int __init acpi_table_parse(char *id, acpi_table_handler handler) { struct acpi_table_header *table = NULL; + if (!handler) return -EINVAL; - acpi_get_table(id, 0, &table); + if (strncmp(id, ACPI_SIG_MADT, 4) == 0) + acpi_get_table(id, acpi_apic_instance, &table); + else + acpi_get_table(id, 0, &table); + if (table) { handler(table); return 0; @@ -248,6 +257,31 @@ int __init acpi_table_parse(char *id, ac return 1; } +/* + * The BIOS is supposed to supply a single APIC/MADT, + * but some report two. Provide a knob to use either. + * (don't you wish instance 0 and 1 were not the same?) + */ +static void __init check_multiple_madt(void) +{ + struct acpi_table_header *table = NULL; + + acpi_get_table(ACPI_SIG_MADT, 2, &table); + if (table) { + printk(KERN_WARNING PREFIX + "BIOS bug: multiple APIC/MADT found," + " using %d\n", acpi_apic_instance); + printk(KERN_WARNING PREFIX + "If \"acpi_apic_instance=%d\" works better, " + "notify linux-acpi@vger.kernel.org\n", + acpi_apic_instance ? 0 : 2); + + } else + acpi_apic_instance = 0; + + return; +} + /* * acpi_table_init() * @@ -257,9 +291,22 @@ int __init acpi_table_parse(char *id, ac * result: sdt_entry[] is initialized */ - int __init acpi_table_init(void) { acpi_initialize_tables(initial_tables, ACPI_MAX_TABLES, 0); + check_multiple_madt(); + return 0; +} + +static int __init acpi_parse_apic_instance(char *str) +{ + + acpi_apic_instance = simple_strtoul(str, NULL, 0); + + printk(KERN_NOTICE PREFIX "Shall use APIC/MADT table %d\n", + acpi_apic_instance); + return 0; } + +early_param("acpi_apic_instance", acpi_parse_apic_instance); Index: linux-2.6.21-rc5/drivers/ata/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -564,7 +564,7 @@ config PATA_IXP4XX_CF config PATA_SCC tristate "Toshiba's Cell Reference Set IDE support" - depends on PCI && PPC_IBM_CELL_BLADE + depends on PCI && PPC_CELLEB help This option enables support for the built-in IDE controller on Toshiba Cell Reference Board. Index: linux-2.6.21-rc5/drivers/ata/libata-core.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/libata-core.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/libata-core.c 2007-03-27 14:20:38.000000000 +0100 @@ -826,7 +826,7 @@ static u64 ata_id_n_sectors(const u16 *i /** * ata_id_to_dma_mode - Identify DMA mode from id block * @dev: device to identify - * @mode: mode to assume if we cannot tell + * @unknown: mode to assume if we cannot tell * * Set up the timing values for the device based upon the identify * reported values for the DMA mode. This function is used by drivers Index: linux-2.6.21-rc5/drivers/ata/libata-eh.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/libata-eh.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/libata-eh.c 2007-03-27 14:20:38.000000000 +0100 @@ -1625,8 +1625,14 @@ static int ata_eh_reset(struct ata_port rc = prereset(ap); if (rc) { if (rc == -ENOENT) { - ata_port_printk(ap, KERN_DEBUG, "port disabled. ignoring.\n"); + ata_port_printk(ap, KERN_DEBUG, + "port disabled. ignoring.\n"); ap->eh_context.i.action &= ~ATA_EH_RESET_MASK; + + for (i = 0; i < ATA_MAX_DEVICES; i++) + classes[i] = ATA_DEV_NONE; + + rc = 0; } else ata_port_printk(ap, KERN_ERR, "prereset failed (errno=%d)\n", rc); Index: linux-2.6.21-rc5/drivers/ata/pata_ixp4xx_cf.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/pata_ixp4xx_cf.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/pata_ixp4xx_cf.c 2007-03-27 14:20:38.000000000 +0100 @@ -193,7 +193,7 @@ static __devinit int ixp4xx_pata_probe(s irq = platform_get_irq(pdev, 0); if (irq) - set_irq_type(irq, IRQT_HIGH); + set_irq_type(irq, IRQT_RISING); /* Setup expansion bus chip selects */ *data->cs0_cfg = data->cs0_bits; @@ -232,7 +232,6 @@ static __devexit int ixp4xx_pata_remove( struct ata_host *host = platform_get_drvdata(dev); ata_host_detach(host); - platform_set_drvdata(dev, NULL); return 0; } Index: linux-2.6.21-rc5/drivers/ata/sata_inic162x.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/sata_inic162x.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/sata_inic162x.c 2007-03-27 14:20:38.000000000 +0100 @@ -672,10 +672,6 @@ static int inic_init_one(struct pci_dev if (rc) return rc; - rc = pci_request_regions(pdev, DRV_NAME); - if (rc) - return rc; - rc = pcim_iomap_regions(pdev, 0x3f, DRV_NAME); if (rc) return rc; Index: linux-2.6.21-rc5/drivers/ata/sata_sil24.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ata/sata_sil24.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ata/sata_sil24.c 2007-03-27 14:20:38.000000000 +0100 @@ -346,6 +346,7 @@ static const struct pci_device_id sil24_ { PCI_VDEVICE(CMD, 0x3124), BID_SIL3124 }, { PCI_VDEVICE(INTEL, 0x3124), BID_SIL3124 }, { PCI_VDEVICE(CMD, 0x3132), BID_SIL3132 }, + { PCI_VDEVICE(CMD, 0x0242), BID_SIL3132 }, { PCI_VDEVICE(CMD, 0x3131), BID_SIL3131 }, { PCI_VDEVICE(CMD, 0x3531), BID_SIL3131 }, Index: linux-2.6.21-rc5/drivers/char/lcd.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/char/lcd.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/char/lcd.c 2007-03-27 14:20:38.000000000 +0100 @@ -11,9 +11,6 @@ * March 2001: Ported from 2.0.34 by Liam Davies * */ - -#define RTC_IO_EXTENT 0x10 /*Only really two ports, but... */ - #include #include #include @@ -32,8 +29,6 @@ #include "lcd.h" -static DEFINE_SPINLOCK(lcd_lock); - static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); Index: linux-2.6.21-rc5/drivers/char/tty_io.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/char/tty_io.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/char/tty_io.c 2007-03-27 14:20:38.000000000 +0100 @@ -1376,6 +1376,8 @@ static void do_tty_hangup(struct work_st read_unlock(&tasklist_lock); tty->flags = 0; + put_pid(tty->session); + put_pid(tty->pgrp); tty->session = NULL; tty->pgrp = NULL; tty->ctrl_status = 0; @@ -3841,6 +3843,9 @@ static struct pid *__proc_set_tty(struct { struct pid *old_pgrp; if (tty) { + /* We should not have a session or pgrp to here but.... */ + put_pid(tty->session); + put_pid(tty->pgrp); tty->session = get_pid(task_session(tsk)); tty->pgrp = get_pid(task_pgrp(tsk)); } Index: linux-2.6.21-rc5/drivers/char/vt.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/char/vt.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/char/vt.c 2007-03-27 14:20:38.000000000 +0100 @@ -724,6 +724,7 @@ int vc_allocate(unsigned int currcons) / return -ENOMEM; memset(vc, 0, sizeof(*vc)); vc_cons[currcons].d = vc; + INIT_WORK(&vc_cons[currcons].SAK_work, vc_SAK); visual_init(vc, currcons, 1); if (!*vc->vc_uni_pagedir_loc) con_set_default_unimap(vc); @@ -2185,10 +2186,28 @@ static void console_callback(struct work release_console_sem(); } -void set_console(int nr) +int set_console(int nr) { + struct vc_data *vc = vc_cons[fg_console].d; + + if (!vc_cons_allocated(nr) || vt_dont_switch || + (vc->vt_mode.mode == VT_AUTO && vc->vc_mode == KD_GRAPHICS)) { + + /* + * Console switch will fail in console_callback() or + * change_console() so there is no point scheduling + * the callback + * + * Existing set_console() users don't check the return + * value so this shouldn't break anything + */ + return -EINVAL; + } + want_console = nr; schedule_console_callback(); + + return 0; } struct tty_driver *console_driver; Index: linux-2.6.21-rc5/drivers/char/vt_ioctl.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/char/vt_ioctl.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/char/vt_ioctl.c 2007-03-27 14:20:38.000000000 +0100 @@ -34,7 +34,7 @@ #include #include -static char vt_dont_switch; +char vt_dont_switch; extern struct tty_driver *console_driver; #define VT_IS_IN_USE(i) (console_driver->ttys[i] && console_driver->ttys[i]->count) Index: linux-2.6.21-rc5/drivers/char/watchdog/machzwd.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/char/watchdog/machzwd.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/char/watchdog/machzwd.c 2007-03-27 14:20:38.000000000 +0100 @@ -314,21 +314,21 @@ static int zf_ioctl(struct inode *inode, { void __user *argp = (void __user *)arg; int __user *p = argp; - switch(cmd){ - case WDIOC_GETSUPPORT: - if (copy_to_user(argp, &zf_info, sizeof(zf_info))) - return -EFAULT; - break; - - case WDIOC_GETSTATUS: - return put_user(0, p); - - case WDIOC_KEEPALIVE: - zf_ping(NULL); - break; + switch (cmd) { + case WDIOC_GETSUPPORT: + if (copy_to_user(argp, &zf_info, sizeof(zf_info))) + return -EFAULT; + break; + + case WDIOC_GETSTATUS: + return put_user(0, p); + + case WDIOC_KEEPALIVE: + zf_ping(0); + break; - default: - return -ENOTTY; + default: + return -ENOTTY; } return 0; Index: linux-2.6.21-rc5/drivers/dma/dmaengine.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/dma/dmaengine.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/dma/dmaengine.c 2007-03-27 14:20:38.000000000 +0100 @@ -176,6 +176,7 @@ void dma_chan_cleanup(struct kref *kref) chan->client = NULL; kref_put(&chan->device->refcount, dma_async_device_cleanup); } +EXPORT_SYMBOL(dma_chan_cleanup); static void dma_chan_free_rcu(struct rcu_head *rcu) { @@ -261,6 +262,7 @@ struct dma_client *dma_async_client_regi return client; } +EXPORT_SYMBOL(dma_async_client_register); /** * dma_async_client_unregister - unregister a client and free the &dma_client @@ -287,6 +289,7 @@ void dma_async_client_unregister(struct kfree(client); dma_chans_rebalance(); } +EXPORT_SYMBOL(dma_async_client_unregister); /** * dma_async_client_chan_request - request DMA channels @@ -304,6 +307,7 @@ void dma_async_client_chan_request(struc client->chans_desired = number; dma_chans_rebalance(); } +EXPORT_SYMBOL(dma_async_client_chan_request); /** * dma_async_device_register - registers DMA devices found @@ -346,6 +350,7 @@ int dma_async_device_register(struct dma return 0; } +EXPORT_SYMBOL(dma_async_device_register); /** * dma_async_device_cleanup - function called when all references are released @@ -390,23 +395,12 @@ void dma_async_device_unregister(struct kref_put(&device->refcount, dma_async_device_cleanup); wait_for_completion(&device->done); } +EXPORT_SYMBOL(dma_async_device_unregister); static int __init dma_bus_init(void) { mutex_init(&dma_list_mutex); return class_register(&dma_devclass); } - subsys_initcall(dma_bus_init); -EXPORT_SYMBOL(dma_async_client_register); -EXPORT_SYMBOL(dma_async_client_unregister); -EXPORT_SYMBOL(dma_async_client_chan_request); -EXPORT_SYMBOL(dma_async_memcpy_buf_to_buf); -EXPORT_SYMBOL(dma_async_memcpy_buf_to_pg); -EXPORT_SYMBOL(dma_async_memcpy_pg_to_pg); -EXPORT_SYMBOL(dma_async_memcpy_complete); -EXPORT_SYMBOL(dma_async_memcpy_issue_pending); -EXPORT_SYMBOL(dma_async_device_register); -EXPORT_SYMBOL(dma_async_device_unregister); -EXPORT_SYMBOL(dma_chan_cleanup); Index: linux-2.6.21-rc5/drivers/hwmon/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/drivers/hwmon/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/hwmon/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -527,6 +527,7 @@ config SENSORS_W83792D config SENSORS_W83793 tristate "Winbond W83793" depends on HWMON && I2C && EXPERIMENTAL + select HWMON_VID help If you say yes here you get support for the Winbond W83793 hardware monitoring chip. Index: linux-2.6.21-rc5/drivers/i2c/busses/i2c-amd8111.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/i2c/busses/i2c-amd8111.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/i2c/busses/i2c-amd8111.c 2007-03-27 14:20:38.000000000 +0100 @@ -254,7 +254,8 @@ static s32 amd8111_access(struct i2c_ada break; case I2C_SMBUS_BLOCK_PROC_CALL: - len = min_t(u8, data->block[0], 31); + len = min_t(u8, data->block[0], + I2C_SMBUS_BLOCK_MAX - 1); amd_ec_write(smbus, AMD_SMB_CMD, command); amd_ec_write(smbus, AMD_SMB_BCNT, len); for (i = 0; i < len; i++) Index: linux-2.6.21-rc5/drivers/i2c/busses/i2c-i801.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/i2c/busses/i2c-i801.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/i2c/busses/i2c-i801.c 2007-03-27 14:20:38.000000000 +0100 @@ -97,6 +97,7 @@ static int i801_block_transaction(union int command, int hwpec); static unsigned long i801_smba; +static unsigned char i801_original_hstcfg; static struct pci_driver i801_driver; static struct pci_dev *I801_dev; static int isich4; @@ -510,6 +511,7 @@ static int __devinit i801_probe(struct p } pci_read_config_byte(I801_dev, SMBHSTCFG, &temp); + i801_original_hstcfg = temp; temp &= ~SMBHSTCFG_I2C_EN; /* SMBus timing */ if (!(temp & SMBHSTCFG_HST_EN)) { dev_info(&dev->dev, "Enabling SMBus device\n"); @@ -543,6 +545,7 @@ exit: static void __devexit i801_remove(struct pci_dev *dev) { i2c_del_adapter(&i801_adapter); + pci_write_config_byte(I801_dev, SMBHSTCFG, i801_original_hstcfg); pci_release_region(dev, SMBBAR); /* * do not call pci_disable_device(dev) since it can cause hard hangs on @@ -550,11 +553,33 @@ static void __devexit i801_remove(struct */ } +#ifdef CONFIG_PM +static int i801_suspend(struct pci_dev *dev, pm_message_t mesg) +{ + pci_save_state(dev); + pci_write_config_byte(dev, SMBHSTCFG, i801_original_hstcfg); + pci_set_power_state(dev, pci_choose_state(dev, mesg)); + return 0; +} + +static int i801_resume(struct pci_dev *dev) +{ + pci_set_power_state(dev, PCI_D0); + pci_restore_state(dev); + return pci_enable_device(dev); +} +#else +#define i801_suspend NULL +#define i801_resume NULL +#endif + static struct pci_driver i801_driver = { .name = "i801_smbus", .id_table = i801_ids, .probe = i801_probe, .remove = __devexit_p(i801_remove), + .suspend = i801_suspend, + .resume = i801_resume, }; static int __init i2c_i801_init(void) Index: linux-2.6.21-rc5/drivers/i2c/chips/ds1374.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/i2c/chips/ds1374.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/i2c/chips/ds1374.c 2007-03-27 14:20:38.000000000 +0100 @@ -207,6 +207,10 @@ static int ds1374_probe(struct i2c_adapt client->driver = &ds1374_driver; ds1374_workqueue = create_singlethread_workqueue("ds1374"); + if (!ds1374_workqueue) { + kfree(client); + return -ENOMEM; /* most expected reason */ + } if ((rc = i2c_attach_client(client)) != 0) { kfree(client); Index: linux-2.6.21-rc5/drivers/ide/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -434,24 +434,8 @@ config BLK_DEV_IDEDMA_FORCED Generally say N here. -config IDEDMA_PCI_AUTO - bool "Use PCI DMA by default when available" - ---help--- - Prior to kernel version 2.1.112, Linux used to automatically use - DMA for IDE drives and chipsets which support it. Due to concerns - about a couple of cases where buggy hardware may have caused damage, - the default is now to NOT use DMA automatically. To revert to the - previous behaviour, say Y to this question. - - If you suspect your hardware is at all flakey, say N here. - Do NOT email the IDE kernel people regarding this issue! - - It is normally safe to answer Y to this question unless your - motherboard uses a VIA VP2 chipset, in which case you should say N. - config IDEDMA_ONLYDISK bool "Enable DMA only for disks " - depends on IDEDMA_PCI_AUTO help This is used if you know your ATAPI Devices are going to fail DMA Transfers. @@ -769,6 +753,14 @@ config BLK_DEV_TC86C001 help This driver adds support for Toshiba TC86C001 GOKU-S chip. +config BLK_DEV_CELLEB + tristate "Toshiba's Cell Reference Set IDE support" + depends on PPC_CELLEB + help + This driver provides support for the built-in IDE controller on + Toshiba Cell Reference Board. + If unsure, say Y. + endif config BLK_DEV_IDE_PMAC @@ -800,14 +792,6 @@ config BLK_DEV_IDEDMA_PMAC to transfer data to and from memory. Saying Y is safe and improves performance. -config BLK_DEV_IDE_CELLEB - bool "Toshiba's Cell Reference Set IDE support" - depends on PPC_CELLEB && IDE=y - help - This driver provides support for the built-in IDE controller on - Toshiba Cell Reference Board. - If unsure, say Y. - config BLK_DEV_IDE_SWARM tristate "IDE for Sibyte evaluation boards" depends on SIBYTE_SB1xxx_SOC @@ -851,19 +835,6 @@ config BLK_DEV_IDEDMA_ICS Say Y here if you want to add DMA (Direct Memory Access) support to the ICS IDE driver. -config IDEDMA_ICS_AUTO - bool "Use ICS DMA by default" - depends on BLK_DEV_IDEDMA_ICS - help - Prior to kernel version 2.1.112, Linux used to automatically use - DMA for IDE drives and chipsets which support it. Due to concerns - about a couple of cases where buggy hardware may have caused damage, - the default is now to NOT use DMA automatically. To revert to the - previous behaviour, say Y to this question. - - If you suspect your hardware is at all flakey, say N here. - Do NOT email the IDE kernel people regarding this issue! - config BLK_DEV_IDE_RAPIDE tristate "RapIDE interface support" depends on ARM && ARCH_ACORN @@ -1086,9 +1057,6 @@ config IDEDMA_IVB It is normally safe to answer Y; however, the default is N. -config IDEDMA_AUTO - def_bool IDEDMA_PCI_AUTO || IDEDMA_ICS_AUTO - endif config BLK_DEV_HD_ONLY Index: linux-2.6.21-rc5/drivers/ide/Makefile =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/Makefile 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/Makefile 2007-03-27 14:20:38.000000000 +0100 @@ -37,7 +37,6 @@ ide-core-$(CONFIG_BLK_DEV_Q40IDE) += leg # built-in only drivers from ppc/ ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o -ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB) += ppc/scc_pata.o # built-in only drivers from h8300/ ide-core-$(CONFIG_H8300) += h8300/ide-h8300.o Index: linux-2.6.21-rc5/drivers/ide/arm/icside.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/arm/icside.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/arm/icside.c 2007-03-27 14:20:38.000000000 +0100 @@ -196,11 +196,6 @@ static void icside_maskproc(ide_drive_t } #ifdef CONFIG_BLK_DEV_IDEDMA_ICS - -#ifndef CONFIG_IDEDMA_ICS_AUTO -#warning CONFIG_IDEDMA_ICS_AUTO=n support is obsolete, and will be removed soon. -#endif - /* * SG-DMA support. * @@ -474,12 +469,6 @@ static int icside_dma_lostirq(ide_drive_ static void icside_dma_init(ide_hwif_t *hwif) { - int autodma = 0; - -#ifdef CONFIG_IDEDMA_ICS_AUTO - autodma = 1; -#endif - printk(" %s: SG-DMA", hwif->name); hwif->atapi_dma = 1; @@ -489,7 +478,7 @@ static void icside_dma_init(ide_hwif_t * hwif->dmatable_cpu = NULL; hwif->dmatable_dma = 0; hwif->speedproc = icside_set_speed; - hwif->autodma = autodma; + hwif->autodma = 1; hwif->ide_dma_check = icside_dma_check; hwif->dma_host_off = icside_dma_host_off; Index: linux-2.6.21-rc5/drivers/ide/ide-dma.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/ide-dma.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/ide-dma.c 2007-03-27 14:20:38.000000000 +0100 @@ -767,7 +767,7 @@ int ide_set_dma(ide_drive_t *drive) switch(rc) { case -1: /* DMA needs to be disabled */ hwif->dma_off_quietly(drive); - return 0; + return -1; case 0: /* DMA needs to be enabled */ return hwif->ide_dma_on(drive); case 1: /* DMA setting cannot be changed */ Index: linux-2.6.21-rc5/drivers/ide/ide.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/ide.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/ide.c 2007-03-27 14:20:38.000000000 +0100 @@ -177,11 +177,7 @@ DECLARE_MUTEX(ide_cfg_sem); static int ide_scan_direction; /* THIS was formerly 2.2.x pci=reverse */ #endif -#ifdef CONFIG_IDEDMA_AUTO int noautodma = 0; -#else -int noautodma = 1; -#endif EXPORT_SYMBOL(noautodma); Index: linux-2.6.21-rc5/drivers/ide/mips/au1xxx-ide.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/mips/au1xxx-ide.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/mips/au1xxx-ide.c 2007-03-27 14:20:38.000000000 +0100 @@ -639,6 +639,7 @@ static int au_ide_probe(struct device *d _auide_hwif *ahwif = &auide_hwif; ide_hwif_t *hwif; struct resource *res; + hw_regs_t *hw; int ret = 0; #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) @@ -681,7 +682,7 @@ static int au_ide_probe(struct device *d /* FIXME: This might possibly break PCMCIA IDE devices */ hwif = &ide_hwifs[pdev->id]; - hw_regs_t *hw = &hwif->hw; + hw = &hwif->hw; hwif->irq = hw->irq = ahwif->irq; hwif->chipset = ide_au1xxx; Index: linux-2.6.21-rc5/drivers/ide/pci/Makefile =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/pci/Makefile 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/pci/Makefile 2007-03-27 14:20:38.000000000 +0100 @@ -3,6 +3,7 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62x obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o +obj-$(CONFIG_BLK_DEV_CELLEB) += scc_pata.o obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o Index: linux-2.6.21-rc5/drivers/ide/pci/cmd64x.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/pci/cmd64x.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/pci/cmd64x.c 2007-03-27 14:20:38.000000000 +0100 @@ -1,6 +1,6 @@ /* $Id: cmd64x.c,v 1.21 2000/01/30 23:23:16 * - * linux/drivers/ide/pci/cmd64x.c Version 1.41 Feb 3, 2007 + * linux/drivers/ide/pci/cmd64x.c Version 1.42 Feb 8, 2007 * * cmd64x.c: Enable interrupts at initialization time on Ultra/PCI machines. * Note, this driver is not used at all on other systems because @@ -189,6 +189,11 @@ static int cmd64x_get_info (char *buffer #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ +static u8 quantize_timing(int timing, int quant) +{ + return (timing + quant - 1) / quant; +} + /* * This routine writes the prepared setup/active/recovery counts * for a drive into the cmd646 chipset registers to active them. @@ -268,47 +273,37 @@ static void program_drive_counts (ide_dr */ static u8 cmd64x_tune_pio (ide_drive_t *drive, u8 mode_wanted) { - int setup_time, active_time, recovery_time; - int clock_time, pio_mode, cycle_time; - u8 recovery_count2, cycle_count; - int setup_count, active_count, recovery_count; - int bus_speed = system_bus_clock(); - ide_pio_data_t d; + int setup_time, active_time, cycle_time; + u8 cycle_count, setup_count, active_count, recovery_count; + u8 pio_mode; + int clock_time = 1000 / system_bus_clock(); + ide_pio_data_t pio; - pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &d); - cycle_time = d.cycle_time; + pio_mode = ide_get_best_pio_mode(drive, mode_wanted, 5, &pio); + cycle_time = pio.cycle_time; - /* - * I copied all this complicated stuff from cmd640.c and made a few - * minor changes. For now I am just going to pray that it is correct. - */ setup_time = ide_pio_timings[pio_mode].setup_time; active_time = ide_pio_timings[pio_mode].active_time; - recovery_time = cycle_time - (setup_time + active_time); - clock_time = 1000 / bus_speed; - cycle_count = (cycle_time + clock_time - 1) / clock_time; - - setup_count = (setup_time + clock_time - 1) / clock_time; - - active_count = (active_time + clock_time - 1) / clock_time; - - recovery_count = (recovery_time + clock_time - 1) / clock_time; - recovery_count2 = cycle_count - (setup_count + active_count); - if (recovery_count2 > recovery_count) - recovery_count = recovery_count2; + + setup_count = quantize_timing( setup_time, clock_time); + cycle_count = quantize_timing( cycle_time, clock_time); + active_count = quantize_timing(active_time, clock_time); + + recovery_count = cycle_count - active_count; + /* program_drive_counts() takes care of zero recovery cycles */ if (recovery_count > 16) { active_count += recovery_count - 16; recovery_count = 16; } if (active_count > 16) - active_count = 16; /* maximum allowed by cmd646 */ + active_count = 16; /* maximum allowed by cmd64x */ program_drive_counts (drive, setup_count, active_count, recovery_count); cmdprintk("%s: PIO mode wanted %d, selected %d (%dns)%s, " "clocks=%d/%d/%d\n", drive->name, mode_wanted, pio_mode, cycle_time, - d.overridden ? " (overriding vendor mode)" : "", + pio.overridden ? " (overriding vendor mode)" : "", setup_count, active_count, recovery_count); return pio_mode; Index: linux-2.6.21-rc5/drivers/ide/pci/jmicron.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/pci/jmicron.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/pci/jmicron.c 2007-03-27 14:20:38.000000000 +0100 @@ -240,12 +240,31 @@ static int __devinit jmicron_init_one(st return 0; } +/* If libata is configured, jmicron PCI quirk will configure it such + * that the SATA ports are in AHCI function while the PATA ports are + * in a separate IDE function. In such cases, match device class and + * attach only to IDE. If libata isn't configured, keep the old + * behavior for backward compatibility. + */ +#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE) +#define JMB_CLASS PCI_CLASS_STORAGE_IDE << 8 +#define JMB_CLASS_MASK 0xffff00 +#else +#define JMB_CLASS 0 +#define JMB_CLASS_MASK 0 +#endif + static struct pci_device_id jmicron_pci_tbl[] = { - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB361, + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 0}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB363, + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 1}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB365, + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 2}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB366, + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 3}, + { PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB368, + PCI_ANY_ID, PCI_ANY_ID, JMB_CLASS, JMB_CLASS_MASK, 4}, { 0, }, }; Index: linux-2.6.21-rc5/drivers/ide/pci/scc_pata.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ linux-2.6.21-rc5/drivers/ide/pci/scc_pata.c 2007-03-27 14:20:38.000000000 +0100 @@ -0,0 +1,858 @@ +/* + * Support for IDE interfaces on Celleb platform + * + * (C) Copyright 2006 TOSHIBA CORPORATION + * + * This code is based on drivers/ide/pci/siimage.c: + * Copyright (C) 2001-2002 Andre Hedrick + * Copyright (C) 2003 Red Hat + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 + +#define SCC_PATA_NAME "scc IDE" + +#define TDVHSEL_MASTER 0x00000001 +#define TDVHSEL_SLAVE 0x00000004 + +#define MODE_JCUSFEN 0x00000080 + +#define CCKCTRL_ATARESET 0x00040000 +#define CCKCTRL_BUFCNT 0x00020000 +#define CCKCTRL_CRST 0x00010000 +#define CCKCTRL_OCLKEN 0x00000100 +#define CCKCTRL_ATACLKOEN 0x00000002 +#define CCKCTRL_LCLKEN 0x00000001 + +#define QCHCD_IOS_SS 0x00000001 + +#define QCHSD_STPDIAG 0x00020000 + +#define INTMASK_MSK 0xD1000012 +#define INTSTS_SERROR 0x80000000 +#define INTSTS_PRERR 0x40000000 +#define INTSTS_RERR 0x10000000 +#define INTSTS_ICERR 0x01000000 +#define INTSTS_BMSINT 0x00000010 +#define INTSTS_BMHE 0x00000008 +#define INTSTS_IOIRQS 0x00000004 +#define INTSTS_INTRQ 0x00000002 +#define INTSTS_ACTEINT 0x00000001 + +#define ECMODE_VALUE 0x01 + +static struct scc_ports { + unsigned long ctl, dma; + unsigned char hwif_id; /* for removing hwif from system */ +} scc_ports[MAX_HWIFS]; + +/* PIO transfer mode table */ +/* JCHST */ +static unsigned long JCHSTtbl[2][7] = { + {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHHT */ +static unsigned long JCHHTtbl[2][7] = { + {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ + {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ +}; + +/* JCHCT */ +static unsigned long JCHCTtbl[2][7] = { + {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ + {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ +}; + + +/* DMA transfer mode table */ +/* JCHDCTM/JCHDCTS */ +static unsigned long JCHDCTxtbl[2][7] = { + {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ + {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ +}; + +/* JCSTWTM/JCSTWTS */ +static unsigned long JCSTWTxtbl[2][7] = { + {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ + {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCTSS */ +static unsigned long JCTSStbl[2][7] = { + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ + {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ +}; + +/* JCENVT */ +static unsigned long JCENVTtbl[2][7] = { + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ +}; + +/* JCACTSELS/JCACTSELM */ +static unsigned long JCACTSELtbl[2][7] = { + {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ +}; + + +static u8 scc_ide_inb(unsigned long port) +{ + u32 data = in_be32((void*)port); + return (u8)data; +} + +static u16 scc_ide_inw(unsigned long port) +{ + u32 data = in_be32((void*)port); + return (u16)data; +} + +static void scc_ide_insw(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + *ptr++ = le16_to_cpu(in_be32((void*)port)); + } +} + +static void scc_ide_insl(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + *ptr++ = le16_to_cpu(in_be32((void*)port)); + *ptr++ = le16_to_cpu(in_be32((void*)port)); + } +} + +static void scc_ide_outb(u8 addr, unsigned long port) +{ + out_be32((void*)port, addr); +} + +static void scc_ide_outw(u16 addr, unsigned long port) +{ + out_be32((void*)port, addr); +} + +static void +scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) +{ + ide_hwif_t *hwif = HWIF(drive); + + out_be32((void*)port, addr); + __asm__ __volatile__("eieio":::"memory"); + in_be32((void*)(hwif->dma_base + 0x01c)); + __asm__ __volatile__("eieio":::"memory"); +} + +static void +scc_ide_outsw(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + out_be32((void*)port, cpu_to_le16(*ptr++)); + } +} + +static void +scc_ide_outsl(unsigned long port, void *addr, u32 count) +{ + u16 *ptr = (u16 *)addr; + while (count--) { + out_be32((void*)port, cpu_to_le16(*ptr++)); + out_be32((void*)port, cpu_to_le16(*ptr++)); + } +} + +/** + * scc_ratemask - Compute available modes + * @drive: IDE drive + * + * Compute the available speeds for the devices on the interface. + * Enforce UDMA33 as a limit if there is no 80pin cable present. + */ + +static u8 scc_ratemask(ide_drive_t *drive) +{ + u8 mode = 4; + + if (!eighty_ninty_three(drive)) + mode = min(mode, (u8)1); + return mode; +} + +/** + * scc_tuneproc - tune a drive PIO mode + * @drive: drive to tune + * @mode_wanted: the target operating mode + * + * Load the timing settings for this device mode into the + * controller. + */ + +static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) +{ + ide_hwif_t *hwif = HWIF(drive); + struct scc_ports *ports = ide_get_hwifdata(hwif); + unsigned long ctl_base = ports->ctl; + unsigned long cckctrl_port = ctl_base + 0xff0; + unsigned long piosht_port = ctl_base + 0x000; + unsigned long pioct_port = ctl_base + 0x004; + unsigned long reg; + unsigned char speed = XFER_PIO_0; + int offset; + + mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL); + switch (mode_wanted) { + case 4: + speed = XFER_PIO_4; + break; + case 3: + speed = XFER_PIO_3; + break; + case 2: + speed = XFER_PIO_2; + break; + case 1: + speed = XFER_PIO_1; + break; + case 0: + default: + speed = XFER_PIO_0; + break; + } + + reg = in_be32((void __iomem *)cckctrl_port); + if (reg & CCKCTRL_ATACLKOEN) { + offset = 1; /* 133MHz */ + } else { + offset = 0; /* 100MHz */ + } + reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; + out_be32((void __iomem *)piosht_port, reg); + reg = JCHCTtbl[offset][mode_wanted]; + out_be32((void __iomem *)pioct_port, reg); + + ide_config_drive_speed(drive, speed); +} + +/** + * scc_tune_chipset - tune a drive DMA mode + * @drive: Drive to set up + * @xferspeed: speed we want to achieve + * + * Load the timing settings for this device mode into the + * controller. + */ + +static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed); + struct scc_ports *ports = ide_get_hwifdata(hwif); + unsigned long ctl_base = ports->ctl; + unsigned long cckctrl_port = ctl_base + 0xff0; + unsigned long mdmact_port = ctl_base + 0x008; + unsigned long mcrcst_port = ctl_base + 0x00c; + unsigned long sdmact_port = ctl_base + 0x010; + unsigned long scrcst_port = ctl_base + 0x014; + unsigned long udenvt_port = ctl_base + 0x018; + unsigned long tdvhsel_port = ctl_base + 0x020; + int is_slave = (&hwif->drives[1] == drive); + int offset, idx; + unsigned long reg; + unsigned long jcactsel; + + reg = in_be32((void __iomem *)cckctrl_port); + if (reg & CCKCTRL_ATACLKOEN) { + offset = 1; /* 133MHz */ + } else { + offset = 0; /* 100MHz */ + } + + switch (speed) { + case XFER_UDMA_6: + idx = 6; + break; + case XFER_UDMA_5: + idx = 5; + break; + case XFER_UDMA_4: + idx = 4; + break; + case XFER_UDMA_3: + idx = 3; + break; + case XFER_UDMA_2: + idx = 2; + break; + case XFER_UDMA_1: + idx = 1; + break; + case XFER_UDMA_0: + idx = 0; + break; + default: + return 1; + } + + jcactsel = JCACTSELtbl[offset][idx]; + if (is_slave) { + out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); + out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); + jcactsel = jcactsel << 2; + out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); + } else { + out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); + out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); + out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); + } + reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; + out_be32((void __iomem *)udenvt_port, reg); + + return ide_config_drive_speed(drive, speed); +} + +/** + * scc_config_chipset_for_dma - configure for DMA + * @drive: drive to configure + * + * Called by scc_config_drive_for_dma(). + */ + +static int scc_config_chipset_for_dma(ide_drive_t *drive) +{ + u8 speed = ide_dma_speed(drive, scc_ratemask(drive)); + + if (!speed) + return 0; + + if (scc_tune_chipset(drive, speed)) + return 0; + + return ide_dma_enable(drive); +} + +/** + * scc_configure_drive_for_dma - set up for DMA transfers + * @drive: drive we are going to set up + * + * Set up the drive for DMA, tune the controller and drive as + * required. + * If the drive isn't suitable for DMA or we hit other problems + * then we will drop down to PIO and set up PIO appropriately. + * (return 1) + */ + +static int scc_config_drive_for_dma(ide_drive_t *drive) +{ + if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) + return 0; + + if (ide_use_fast_pio(drive)) + scc_tuneproc(drive, 4); + + return -1; +} + +/** + * scc_ide_dma_setup - begin a DMA phase + * @drive: target device + * + * Build an IDE DMA PRD (IDE speak for scatter gather table) + * and then set up the DMA transfer registers. + * + * Returns 0 on success. If a PIO fallback is required then 1 + * is returned. + */ + +static int scc_dma_setup(ide_drive_t *drive) +{ + ide_hwif_t *hwif = drive->hwif; + struct request *rq = HWGROUP(drive)->rq; + unsigned int reading; + u8 dma_stat; + + if (rq_data_dir(rq)) + reading = 0; + else + reading = 1 << 3; + + /* fall back to pio! */ + if (!ide_build_dmatable(drive, rq)) { + ide_map_sg(drive, rq); + return 1; + } + + /* PRD table */ + out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma); + + /* specify r/w */ + out_be32((void __iomem *)hwif->dma_command, reading); + + /* read dma_status for INTR & ERROR flags */ + dma_stat = in_be32((void __iomem *)hwif->dma_status); + + /* clear INTR & ERROR flags */ + out_be32((void __iomem *)hwif->dma_status, dma_stat|6); + drive->waiting_for_dma = 1; + return 0; +} + + +/** + * scc_ide_dma_end - Stop DMA + * @drive: IDE drive + * + * Check and clear INT Status register. + * Then call __ide_dma_end(). + */ + +static int scc_ide_dma_end(ide_drive_t * drive) +{ + ide_hwif_t *hwif = HWIF(drive); + unsigned long intsts_port = hwif->dma_base + 0x014; + u32 reg; + + while (1) { + reg = in_be32((void __iomem *)intsts_port); + + if (reg & INTSTS_SERROR) { + printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_PRERR) { + u32 maea0, maec0; + unsigned long ctl_base = hwif->config_data; + + maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); + maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); + + printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); + + out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_RERR) { + printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); + + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + continue; + } + + if (reg & INTSTS_ICERR) { + out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); + + printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); + continue; + } + + if (reg & INTSTS_BMSINT) { + printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); + out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); + + ide_do_reset(drive); + continue; + } + + if (reg & INTSTS_BMHE) { + out_be32((void __iomem *)intsts_port, INTSTS_BMHE); + continue; + } + + if (reg & INTSTS_ACTEINT) { + out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); + continue; + } + + if (reg & INTSTS_IOIRQS) { + out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); + continue; + } + break; + } + + return __ide_dma_end(drive); +} + +/* returns 1 if dma irq issued, 0 otherwise */ +static int scc_dma_test_irq(ide_drive_t *drive) +{ + ide_hwif_t *hwif = HWIF(drive); + u8 dma_stat = hwif->INB(hwif->dma_status); + + /* return 1 if INTR asserted */ + if ((dma_stat & 4) == 4) + return 1; + + /* Workaround for PTERADD: emulate DMA_INTR when + * - IDE_STATUS[ERR] = 1 + * - INT_STATUS[INTRQ] = 1 + * - DMA_STATUS[IORACTA] = 1 + */ + if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT && + in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ && + dma_stat & 1) + return 1; + + if (!drive->waiting_for_dma) + printk(KERN_WARNING "%s: (%s) called while not waiting\n", + drive->name, __FUNCTION__); + return 0; +} + +/** + * setup_mmio_scc - map CTRL/BMID region + * @dev: PCI device we are configuring + * @name: device name + * + */ + +static int setup_mmio_scc (struct pci_dev *dev, const char *name) +{ + unsigned long ctl_base = pci_resource_start(dev, 0); + unsigned long dma_base = pci_resource_start(dev, 1); + unsigned long ctl_size = pci_resource_len(dev, 0); + unsigned long dma_size = pci_resource_len(dev, 1); + void *ctl_addr; + void *dma_addr; + int i; + + for (i = 0; i < MAX_HWIFS; i++) { + if (scc_ports[i].ctl == 0) + break; + } + if (i >= MAX_HWIFS) + return -ENOMEM; + + if (!request_mem_region(ctl_base, ctl_size, name)) { + printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); + goto fail_0; + } + + if (!request_mem_region(dma_base, dma_size, name)) { + printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); + goto fail_1; + } + + if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL) + goto fail_2; + + if ((dma_addr = ioremap(dma_base, dma_size)) == NULL) + goto fail_3; + + pci_set_master(dev); + scc_ports[i].ctl = (unsigned long)ctl_addr; + scc_ports[i].dma = (unsigned long)dma_addr; + pci_set_drvdata(dev, (void *) &scc_ports[i]); + + return 1; + + fail_3: + iounmap(ctl_addr); + fail_2: + release_mem_region(dma_base, dma_size); + fail_1: + release_mem_region(ctl_base, ctl_size); + fail_0: + return -ENOMEM; +} + +/** + * init_setup_scc - set up an SCC PATA Controller + * @dev: PCI device + * @d: IDE PCI device + * + * Perform the initial set up for this device. + */ + +static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d) +{ + unsigned long ctl_base; + unsigned long dma_base; + unsigned long cckctrl_port; + unsigned long intmask_port; + unsigned long mode_port; + unsigned long ecmode_port; + unsigned long dma_status_port; + u32 reg = 0; + struct scc_ports *ports; + int rc; + + rc = setup_mmio_scc(dev, d->name); + if (rc < 0) { + return rc; + } + + ports = pci_get_drvdata(dev); + ctl_base = ports->ctl; + dma_base = ports->dma; + cckctrl_port = ctl_base + 0xff0; + intmask_port = dma_base + 0x010; + mode_port = ctl_base + 0x024; + ecmode_port = ctl_base + 0xf00; + dma_status_port = dma_base + 0x004; + + /* controller initialization */ + reg = 0; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_ATACLKOEN; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; + out_be32((void*)cckctrl_port, reg); + reg |= CCKCTRL_CRST; + out_be32((void*)cckctrl_port, reg); + + for (;;) { + reg = in_be32((void*)cckctrl_port); + if (reg & CCKCTRL_CRST) + break; + udelay(5000); + } + + reg |= CCKCTRL_ATARESET; + out_be32((void*)cckctrl_port, reg); + + out_be32((void*)ecmode_port, ECMODE_VALUE); + out_be32((void*)mode_port, MODE_JCUSFEN); + out_be32((void*)intmask_port, INTMASK_MSK); + + return ide_setup_pci_device(dev, d); +} + +/** + * init_mmio_iops_scc - set up the iops for MMIO + * @hwif: interface to set up + * + */ + +static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + struct scc_ports *ports = pci_get_drvdata(dev); + unsigned long dma_base = ports->dma; + + ide_set_hwifdata(hwif, ports); + + hwif->INB = scc_ide_inb; + hwif->INW = scc_ide_inw; + hwif->INSW = scc_ide_insw; + hwif->INSL = scc_ide_insl; + hwif->OUTB = scc_ide_outb; + hwif->OUTBSYNC = scc_ide_outbsync; + hwif->OUTW = scc_ide_outw; + hwif->OUTSW = scc_ide_outsw; + hwif->OUTSL = scc_ide_outsl; + + hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20; + hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24; + hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28; + hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c; + hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30; + hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34; + hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38; + hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c; + hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40; + + hwif->irq = hwif->pci_dev->irq; + hwif->dma_base = dma_base; + hwif->config_data = ports->ctl; + hwif->mmio = 1; +} + +/** + * init_iops_scc - set up iops + * @hwif: interface to set up + * + * Do the basic setup for the SCC hardware interface + * and then do the MMIO setup. + */ + +static void __devinit init_iops_scc(ide_hwif_t *hwif) +{ + struct pci_dev *dev = hwif->pci_dev; + hwif->hwif_data = NULL; + if (pci_get_drvdata(dev) == NULL) + return; + init_mmio_iops_scc(hwif); +} + +/** + * init_hwif_scc - set up hwif + * @hwif: interface to set up + * + * We do the basic set up of the interface structure. The SCC + * requires several custom handlers so we override the default + * ide DMA handlers appropriately. + */ + +static void __devinit init_hwif_scc(ide_hwif_t *hwif) +{ + struct scc_ports *ports = ide_get_hwifdata(hwif); + + ports->hwif_id = hwif->index; + + hwif->dma_command = hwif->dma_base; + hwif->dma_status = hwif->dma_base + 0x04; + hwif->dma_prdtable = hwif->dma_base + 0x08; + + /* PTERADD */ + out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); + + hwif->dma_setup = scc_dma_setup; + hwif->ide_dma_end = scc_ide_dma_end; + hwif->speedproc = scc_tune_chipset; + hwif->tuneproc = scc_tuneproc; + hwif->ide_dma_check = scc_config_drive_for_dma; + hwif->ide_dma_test_irq = scc_dma_test_irq; + + hwif->drives[0].autotune = IDE_TUNE_AUTO; + hwif->drives[1].autotune = IDE_TUNE_AUTO; + + if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) { + hwif->ultra_mask = 0x7f; /* 133MHz */ + } else { + hwif->ultra_mask = 0x3f; /* 100MHz */ + } + hwif->mwdma_mask = 0x00; + hwif->swdma_mask = 0x00; + hwif->atapi_dma = 1; + + /* we support 80c cable only. */ + hwif->udma_four = 1; + + hwif->autodma = 0; + if (!noautodma) + hwif->autodma = 1; + hwif->drives[0].autodma = hwif->autodma; + hwif->drives[1].autodma = hwif->autodma; +} + +#define DECLARE_SCC_DEV(name_str) \ + { \ + .name = name_str, \ + .init_setup = init_setup_scc, \ + .init_iops = init_iops_scc, \ + .init_hwif = init_hwif_scc, \ + .channels = 1, \ + .autodma = AUTODMA, \ + .bootable = ON_BOARD, \ + } + +static ide_pci_device_t scc_chipsets[] __devinitdata = { + /* 0 */ DECLARE_SCC_DEV("sccIDE"), +}; + +/** + * scc_init_one - pci layer discovery entry + * @dev: PCI device + * @id: ident table entry + * + * Called by the PCI code when it finds an SCC PATA controller. + * We then use the IDE PCI generic helper to do most of the work. + */ + +static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) +{ + ide_pci_device_t *d = &scc_chipsets[id->driver_data]; + return d->init_setup(dev, d); +} + +/** + * scc_remove - pci layer remove entry + * @dev: PCI device + * + * Called by the PCI code when it removes an SCC PATA controller. + */ + +static void __devexit scc_remove(struct pci_dev *dev) +{ + struct scc_ports *ports = pci_get_drvdata(dev); + ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id]; + unsigned long ctl_base = pci_resource_start(dev, 0); + unsigned long dma_base = pci_resource_start(dev, 1); + unsigned long ctl_size = pci_resource_len(dev, 0); + unsigned long dma_size = pci_resource_len(dev, 1); + + if (hwif->dmatable_cpu) { + pci_free_consistent(hwif->pci_dev, + PRD_ENTRIES * PRD_BYTES, + hwif->dmatable_cpu, + hwif->dmatable_dma); + hwif->dmatable_cpu = NULL; + } + + ide_unregister(hwif->index); + + hwif->chipset = ide_unknown; + iounmap((void*)ports->dma); + iounmap((void*)ports->ctl); + release_mem_region(dma_base, dma_size); + release_mem_region(ctl_base, ctl_size); + memset(ports, 0, sizeof(*ports)); +} + +static struct pci_device_id scc_pci_tbl[] = { + { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { 0, }, +}; +MODULE_DEVICE_TABLE(pci, scc_pci_tbl); + +static struct pci_driver driver = { + .name = "SCC IDE", + .id_table = scc_pci_tbl, + .probe = scc_init_one, + .remove = scc_remove, +}; + +static int scc_ide_init(void) +{ + return ide_pci_register_driver(&driver); +} + +module_init(scc_ide_init); +/* -- No exit code? +static void scc_ide_exit(void) +{ + ide_pci_unregister_driver(&driver); +} +module_exit(scc_ide_exit); + */ + + +MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); +MODULE_LICENSE("GPL"); Index: linux-2.6.21-rc5/drivers/ide/ppc/scc_pata.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/ppc/scc_pata.c 2007-03-27 14:20:36.000000000 +0100 +++ /dev/null 1970-01-01 00:00:00.000000000 +0000 @@ -1,858 +0,0 @@ -/* - * Support for IDE interfaces on Celleb platform - * - * (C) Copyright 2006 TOSHIBA CORPORATION - * - * This code is based on drivers/ide/pci/siimage.c: - * Copyright (C) 2001-2002 Andre Hedrick - * Copyright (C) 2003 Red Hat - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4 - -#define SCC_PATA_NAME "scc IDE" - -#define TDVHSEL_MASTER 0x00000001 -#define TDVHSEL_SLAVE 0x00000004 - -#define MODE_JCUSFEN 0x00000080 - -#define CCKCTRL_ATARESET 0x00040000 -#define CCKCTRL_BUFCNT 0x00020000 -#define CCKCTRL_CRST 0x00010000 -#define CCKCTRL_OCLKEN 0x00000100 -#define CCKCTRL_ATACLKOEN 0x00000002 -#define CCKCTRL_LCLKEN 0x00000001 - -#define QCHCD_IOS_SS 0x00000001 - -#define QCHSD_STPDIAG 0x00020000 - -#define INTMASK_MSK 0xD1000012 -#define INTSTS_SERROR 0x80000000 -#define INTSTS_PRERR 0x40000000 -#define INTSTS_RERR 0x10000000 -#define INTSTS_ICERR 0x01000000 -#define INTSTS_BMSINT 0x00000010 -#define INTSTS_BMHE 0x00000008 -#define INTSTS_IOIRQS 0x00000004 -#define INTSTS_INTRQ 0x00000002 -#define INTSTS_ACTEINT 0x00000001 - -#define ECMODE_VALUE 0x01 - -static struct scc_ports { - unsigned long ctl, dma; - unsigned char hwif_id; /* for removing hwif from system */ -} scc_ports[MAX_HWIFS]; - -/* PIO transfer mode table */ -/* JCHST */ -static unsigned long JCHSTtbl[2][7] = { - {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHHT */ -static unsigned long JCHHTtbl[2][7] = { - {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */ - {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */ -}; - -/* JCHCT */ -static unsigned long JCHCTtbl[2][7] = { - {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */ - {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */ -}; - - -/* DMA transfer mode table */ -/* JCHDCTM/JCHDCTS */ -static unsigned long JCHDCTxtbl[2][7] = { - {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */ - {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */ -}; - -/* JCSTWTM/JCSTWTS */ -static unsigned long JCSTWTxtbl[2][7] = { - {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */ - {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCTSS */ -static unsigned long JCTSStbl[2][7] = { - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */ - {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */ -}; - -/* JCENVT */ -static unsigned long JCENVTtbl[2][7] = { - {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */ -}; - -/* JCACTSELS/JCACTSELM */ -static unsigned long JCACTSELtbl[2][7] = { - {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */ -}; - - -static u8 scc_ide_inb(unsigned long port) -{ - u32 data = in_be32((void*)port); - return (u8)data; -} - -static u16 scc_ide_inw(unsigned long port) -{ - u32 data = in_be32((void*)port); - return (u16)data; -} - -static void scc_ide_insw(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - *ptr++ = le16_to_cpu(in_be32((void*)port)); - } -} - -static void scc_ide_insl(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - *ptr++ = le16_to_cpu(in_be32((void*)port)); - *ptr++ = le16_to_cpu(in_be32((void*)port)); - } -} - -static void scc_ide_outb(u8 addr, unsigned long port) -{ - out_be32((void*)port, addr); -} - -static void scc_ide_outw(u16 addr, unsigned long port) -{ - out_be32((void*)port, addr); -} - -static void -scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port) -{ - ide_hwif_t *hwif = HWIF(drive); - - out_be32((void*)port, addr); - __asm__ __volatile__("eieio":::"memory"); - in_be32((void*)(hwif->dma_base + 0x01c)); - __asm__ __volatile__("eieio":::"memory"); -} - -static void -scc_ide_outsw(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - out_be32((void*)port, cpu_to_le16(*ptr++)); - } -} - -static void -scc_ide_outsl(unsigned long port, void *addr, u32 count) -{ - u16 *ptr = (u16 *)addr; - while (count--) { - out_be32((void*)port, cpu_to_le16(*ptr++)); - out_be32((void*)port, cpu_to_le16(*ptr++)); - } -} - -/** - * scc_ratemask - Compute available modes - * @drive: IDE drive - * - * Compute the available speeds for the devices on the interface. - * Enforce UDMA33 as a limit if there is no 80pin cable present. - */ - -static u8 scc_ratemask(ide_drive_t *drive) -{ - u8 mode = 4; - - if (!eighty_ninty_three(drive)) - mode = min(mode, (u8)1); - return mode; -} - -/** - * scc_tuneproc - tune a drive PIO mode - * @drive: drive to tune - * @mode_wanted: the target operating mode - * - * Load the timing settings for this device mode into the - * controller. - */ - -static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted) -{ - ide_hwif_t *hwif = HWIF(drive); - struct scc_ports *ports = ide_get_hwifdata(hwif); - unsigned long ctl_base = ports->ctl; - unsigned long cckctrl_port = ctl_base + 0xff0; - unsigned long piosht_port = ctl_base + 0x000; - unsigned long pioct_port = ctl_base + 0x004; - unsigned long reg; - unsigned char speed = XFER_PIO_0; - int offset; - - mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL); - switch (mode_wanted) { - case 4: - speed = XFER_PIO_4; - break; - case 3: - speed = XFER_PIO_3; - break; - case 2: - speed = XFER_PIO_2; - break; - case 1: - speed = XFER_PIO_1; - break; - case 0: - default: - speed = XFER_PIO_0; - break; - } - - reg = in_be32((void __iomem *)cckctrl_port); - if (reg & CCKCTRL_ATACLKOEN) { - offset = 1; /* 133MHz */ - } else { - offset = 0; /* 100MHz */ - } - reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted]; - out_be32((void __iomem *)piosht_port, reg); - reg = JCHCTtbl[offset][mode_wanted]; - out_be32((void __iomem *)pioct_port, reg); - - ide_config_drive_speed(drive, speed); -} - -/** - * scc_tune_chipset - tune a drive DMA mode - * @drive: Drive to set up - * @xferspeed: speed we want to achieve - * - * Load the timing settings for this device mode into the - * controller. - */ - -static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed); - struct scc_ports *ports = ide_get_hwifdata(hwif); - unsigned long ctl_base = ports->ctl; - unsigned long cckctrl_port = ctl_base + 0xff0; - unsigned long mdmact_port = ctl_base + 0x008; - unsigned long mcrcst_port = ctl_base + 0x00c; - unsigned long sdmact_port = ctl_base + 0x010; - unsigned long scrcst_port = ctl_base + 0x014; - unsigned long udenvt_port = ctl_base + 0x018; - unsigned long tdvhsel_port = ctl_base + 0x020; - int is_slave = (&hwif->drives[1] == drive); - int offset, idx; - unsigned long reg; - unsigned long jcactsel; - - reg = in_be32((void __iomem *)cckctrl_port); - if (reg & CCKCTRL_ATACLKOEN) { - offset = 1; /* 133MHz */ - } else { - offset = 0; /* 100MHz */ - } - - switch (speed) { - case XFER_UDMA_6: - idx = 6; - break; - case XFER_UDMA_5: - idx = 5; - break; - case XFER_UDMA_4: - idx = 4; - break; - case XFER_UDMA_3: - idx = 3; - break; - case XFER_UDMA_2: - idx = 2; - break; - case XFER_UDMA_1: - idx = 1; - break; - case XFER_UDMA_0: - idx = 0; - break; - default: - return 1; - } - - jcactsel = JCACTSELtbl[offset][idx]; - if (is_slave) { - out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]); - out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]); - jcactsel = jcactsel << 2; - out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel); - } else { - out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]); - out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]); - out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel); - } - reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx]; - out_be32((void __iomem *)udenvt_port, reg); - - return ide_config_drive_speed(drive, speed); -} - -/** - * scc_config_chipset_for_dma - configure for DMA - * @drive: drive to configure - * - * Called by scc_config_drive_for_dma(). - */ - -static int scc_config_chipset_for_dma(ide_drive_t *drive) -{ - u8 speed = ide_dma_speed(drive, scc_ratemask(drive)); - - if (!speed) - return 0; - - if (scc_tune_chipset(drive, speed)) - return 0; - - return ide_dma_enable(drive); -} - -/** - * scc_configure_drive_for_dma - set up for DMA transfers - * @drive: drive we are going to set up - * - * Set up the drive for DMA, tune the controller and drive as - * required. - * If the drive isn't suitable for DMA or we hit other problems - * then we will drop down to PIO and set up PIO appropriately. - * (return 1) - */ - -static int scc_config_drive_for_dma(ide_drive_t *drive) -{ - if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive)) - return 0; - - if (ide_use_fast_pio(drive)) - scc_tuneproc(drive, 4); - - return -1; -} - -/** - * scc_ide_dma_setup - begin a DMA phase - * @drive: target device - * - * Build an IDE DMA PRD (IDE speak for scatter gather table) - * and then set up the DMA transfer registers. - * - * Returns 0 on success. If a PIO fallback is required then 1 - * is returned. - */ - -static int scc_dma_setup(ide_drive_t *drive) -{ - ide_hwif_t *hwif = drive->hwif; - struct request *rq = HWGROUP(drive)->rq; - unsigned int reading; - u8 dma_stat; - - if (rq_data_dir(rq)) - reading = 0; - else - reading = 1 << 3; - - /* fall back to pio! */ - if (!ide_build_dmatable(drive, rq)) { - ide_map_sg(drive, rq); - return 1; - } - - /* PRD table */ - out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma); - - /* specify r/w */ - out_be32((void __iomem *)hwif->dma_command, reading); - - /* read dma_status for INTR & ERROR flags */ - dma_stat = in_be32((void __iomem *)hwif->dma_status); - - /* clear INTR & ERROR flags */ - out_be32((void __iomem *)hwif->dma_status, dma_stat|6); - drive->waiting_for_dma = 1; - return 0; -} - - -/** - * scc_ide_dma_end - Stop DMA - * @drive: IDE drive - * - * Check and clear INT Status register. - * Then call __ide_dma_end(). - */ - -static int scc_ide_dma_end(ide_drive_t * drive) -{ - ide_hwif_t *hwif = HWIF(drive); - unsigned long intsts_port = hwif->dma_base + 0x014; - u32 reg; - - while (1) { - reg = in_be32((void __iomem *)intsts_port); - - if (reg & INTSTS_SERROR) { - printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT); - - out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_PRERR) { - u32 maea0, maec0; - unsigned long ctl_base = hwif->config_data; - - maea0 = in_be32((void __iomem *)(ctl_base + 0xF50)); - maec0 = in_be32((void __iomem *)(ctl_base + 0xF54)); - - printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0); - - out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT); - - out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_RERR) { - printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT); - - out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); - continue; - } - - if (reg & INTSTS_ICERR) { - out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS); - - printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT); - continue; - } - - if (reg & INTSTS_BMSINT) { - printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME); - out_be32((void __iomem *)intsts_port, INTSTS_BMSINT); - - ide_do_reset(drive); - continue; - } - - if (reg & INTSTS_BMHE) { - out_be32((void __iomem *)intsts_port, INTSTS_BMHE); - continue; - } - - if (reg & INTSTS_ACTEINT) { - out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT); - continue; - } - - if (reg & INTSTS_IOIRQS) { - out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS); - continue; - } - break; - } - - return __ide_dma_end(drive); -} - -/* returns 1 if dma irq issued, 0 otherwise */ -static int scc_dma_test_irq(ide_drive_t *drive) -{ - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); - - /* return 1 if INTR asserted */ - if ((dma_stat & 4) == 4) - return 1; - - /* Workaround for PTERADD: emulate DMA_INTR when - * - IDE_STATUS[ERR] = 1 - * - INT_STATUS[INTRQ] = 1 - * - DMA_STATUS[IORACTA] = 1 - */ - if (in_be32((void __iomem *)IDE_ALTSTATUS_REG) & ERR_STAT && - in_be32((void __iomem *)(hwif->dma_base + 0x014)) & INTSTS_INTRQ && - dma_stat & 1) - return 1; - - if (!drive->waiting_for_dma) - printk(KERN_WARNING "%s: (%s) called while not waiting\n", - drive->name, __FUNCTION__); - return 0; -} - -/** - * setup_mmio_scc - map CTRL/BMID region - * @dev: PCI device we are configuring - * @name: device name - * - */ - -static int setup_mmio_scc (struct pci_dev *dev, const char *name) -{ - unsigned long ctl_base = pci_resource_start(dev, 0); - unsigned long dma_base = pci_resource_start(dev, 1); - unsigned long ctl_size = pci_resource_len(dev, 0); - unsigned long dma_size = pci_resource_len(dev, 1); - void *ctl_addr; - void *dma_addr; - int i; - - for (i = 0; i < MAX_HWIFS; i++) { - if (scc_ports[i].ctl == 0) - break; - } - if (i >= MAX_HWIFS) - return -ENOMEM; - - if (!request_mem_region(ctl_base, ctl_size, name)) { - printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); - goto fail_0; - } - - if (!request_mem_region(dma_base, dma_size, name)) { - printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME); - goto fail_1; - } - - if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL) - goto fail_2; - - if ((dma_addr = ioremap(dma_base, dma_size)) == NULL) - goto fail_3; - - pci_set_master(dev); - scc_ports[i].ctl = (unsigned long)ctl_addr; - scc_ports[i].dma = (unsigned long)dma_addr; - pci_set_drvdata(dev, (void *) &scc_ports[i]); - - return 1; - - fail_3: - iounmap(ctl_addr); - fail_2: - release_mem_region(dma_base, dma_size); - fail_1: - release_mem_region(ctl_base, ctl_size); - fail_0: - return -ENOMEM; -} - -/** - * init_setup_scc - set up an SCC PATA Controller - * @dev: PCI device - * @d: IDE PCI device - * - * Perform the initial set up for this device. - */ - -static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d) -{ - unsigned long ctl_base; - unsigned long dma_base; - unsigned long cckctrl_port; - unsigned long intmask_port; - unsigned long mode_port; - unsigned long ecmode_port; - unsigned long dma_status_port; - u32 reg = 0; - struct scc_ports *ports; - int rc; - - rc = setup_mmio_scc(dev, d->name); - if (rc < 0) { - return rc; - } - - ports = pci_get_drvdata(dev); - ctl_base = ports->ctl; - dma_base = ports->dma; - cckctrl_port = ctl_base + 0xff0; - intmask_port = dma_base + 0x010; - mode_port = ctl_base + 0x024; - ecmode_port = ctl_base + 0xf00; - dma_status_port = dma_base + 0x004; - - /* controller initialization */ - reg = 0; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_ATACLKOEN; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN; - out_be32((void*)cckctrl_port, reg); - reg |= CCKCTRL_CRST; - out_be32((void*)cckctrl_port, reg); - - for (;;) { - reg = in_be32((void*)cckctrl_port); - if (reg & CCKCTRL_CRST) - break; - udelay(5000); - } - - reg |= CCKCTRL_ATARESET; - out_be32((void*)cckctrl_port, reg); - - out_be32((void*)ecmode_port, ECMODE_VALUE); - out_be32((void*)mode_port, MODE_JCUSFEN); - out_be32((void*)intmask_port, INTMASK_MSK); - - return ide_setup_pci_device(dev, d); -} - -/** - * init_mmio_iops_scc - set up the iops for MMIO - * @hwif: interface to set up - * - */ - -static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - struct scc_ports *ports = pci_get_drvdata(dev); - unsigned long dma_base = ports->dma; - - ide_set_hwifdata(hwif, ports); - - hwif->INB = scc_ide_inb; - hwif->INW = scc_ide_inw; - hwif->INSW = scc_ide_insw; - hwif->INSL = scc_ide_insl; - hwif->OUTB = scc_ide_outb; - hwif->OUTBSYNC = scc_ide_outbsync; - hwif->OUTW = scc_ide_outw; - hwif->OUTSW = scc_ide_outsw; - hwif->OUTSL = scc_ide_outsl; - - hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20; - hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24; - hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28; - hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c; - hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30; - hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34; - hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38; - hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c; - hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40; - - hwif->irq = hwif->pci_dev->irq; - hwif->dma_base = dma_base; - hwif->config_data = ports->ctl; - hwif->mmio = 1; -} - -/** - * init_iops_scc - set up iops - * @hwif: interface to set up - * - * Do the basic setup for the SCC hardware interface - * and then do the MMIO setup. - */ - -static void __devinit init_iops_scc(ide_hwif_t *hwif) -{ - struct pci_dev *dev = hwif->pci_dev; - hwif->hwif_data = NULL; - if (pci_get_drvdata(dev) == NULL) - return; - init_mmio_iops_scc(hwif); -} - -/** - * init_hwif_scc - set up hwif - * @hwif: interface to set up - * - * We do the basic set up of the interface structure. The SCC - * requires several custom handlers so we override the default - * ide DMA handlers appropriately. - */ - -static void __devinit init_hwif_scc(ide_hwif_t *hwif) -{ - struct scc_ports *ports = ide_get_hwifdata(hwif); - - ports->hwif_id = hwif->index; - - hwif->dma_command = hwif->dma_base; - hwif->dma_status = hwif->dma_base + 0x04; - hwif->dma_prdtable = hwif->dma_base + 0x08; - - /* PTERADD */ - out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma); - - hwif->dma_setup = scc_dma_setup; - hwif->ide_dma_end = scc_ide_dma_end; - hwif->speedproc = scc_tune_chipset; - hwif->tuneproc = scc_tuneproc; - hwif->ide_dma_check = scc_config_drive_for_dma; - hwif->ide_dma_test_irq = scc_dma_test_irq; - - hwif->drives[0].autotune = IDE_TUNE_AUTO; - hwif->drives[1].autotune = IDE_TUNE_AUTO; - - if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) { - hwif->ultra_mask = 0x7f; /* 133MHz */ - } else { - hwif->ultra_mask = 0x3f; /* 100MHz */ - } - hwif->mwdma_mask = 0x00; - hwif->swdma_mask = 0x00; - hwif->atapi_dma = 1; - - /* we support 80c cable only. */ - hwif->udma_four = 1; - - hwif->autodma = 0; - if (!noautodma) - hwif->autodma = 1; - hwif->drives[0].autodma = hwif->autodma; - hwif->drives[1].autodma = hwif->autodma; -} - -#define DECLARE_SCC_DEV(name_str) \ - { \ - .name = name_str, \ - .init_setup = init_setup_scc, \ - .init_iops = init_iops_scc, \ - .init_hwif = init_hwif_scc, \ - .channels = 1, \ - .autodma = AUTODMA, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t scc_chipsets[] __devinitdata = { - /* 0 */ DECLARE_SCC_DEV("sccIDE"), -}; - -/** - * scc_init_one - pci layer discovery entry - * @dev: PCI device - * @id: ident table entry - * - * Called by the PCI code when it finds an SCC PATA controller. - * We then use the IDE PCI generic helper to do most of the work. - */ - -static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id) -{ - ide_pci_device_t *d = &scc_chipsets[id->driver_data]; - return d->init_setup(dev, d); -} - -/** - * scc_remove - pci layer remove entry - * @dev: PCI device - * - * Called by the PCI code when it removes an SCC PATA controller. - */ - -static void __devexit scc_remove(struct pci_dev *dev) -{ - struct scc_ports *ports = pci_get_drvdata(dev); - ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id]; - unsigned long ctl_base = pci_resource_start(dev, 0); - unsigned long dma_base = pci_resource_start(dev, 1); - unsigned long ctl_size = pci_resource_len(dev, 0); - unsigned long dma_size = pci_resource_len(dev, 1); - - if (hwif->dmatable_cpu) { - pci_free_consistent(hwif->pci_dev, - PRD_ENTRIES * PRD_BYTES, - hwif->dmatable_cpu, - hwif->dmatable_dma); - hwif->dmatable_cpu = NULL; - } - - ide_unregister(hwif->index); - - hwif->chipset = ide_unknown; - iounmap((void*)ports->dma); - iounmap((void*)ports->ctl); - release_mem_region(dma_base, dma_size); - release_mem_region(ctl_base, ctl_size); - memset(ports, 0, sizeof(*ports)); -} - -static struct pci_device_id scc_pci_tbl[] = { - { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { 0, }, -}; -MODULE_DEVICE_TABLE(pci, scc_pci_tbl); - -static struct pci_driver driver = { - .name = "SCC IDE", - .id_table = scc_pci_tbl, - .probe = scc_init_one, - .remove = scc_remove, -}; - -static int scc_ide_init(void) -{ - return ide_pci_register_driver(&driver); -} - -module_init(scc_ide_init); -/* -- No exit code? -static void scc_ide_exit(void) -{ - ide_pci_unregister_driver(&driver); -} -module_exit(scc_ide_exit); - */ - - -MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE"); -MODULE_LICENSE("GPL"); Index: linux-2.6.21-rc5/drivers/ide/setup-pci.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ide/setup-pci.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ide/setup-pci.c 2007-03-27 14:20:38.000000000 +0100 @@ -505,11 +505,6 @@ static void ide_hwif_setup_dma(struct pc } } } - -#ifndef CONFIG_IDEDMA_PCI_AUTO -#warning CONFIG_IDEDMA_PCI_AUTO=n support is obsolete, and will be removed soon. -#endif - #endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/ /** Index: linux-2.6.21-rc5/drivers/ieee1394/eth1394.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/ieee1394/eth1394.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/ieee1394/eth1394.c 2007-03-27 14:20:38.000000000 +0100 @@ -584,7 +584,10 @@ static void ether1394_add_host (struct h } SET_MODULE_OWNER(dev); +#if 0 + /* FIXME - Is this the correct parent device anyway? */ SET_NETDEV_DEV(dev, &host->device); +#endif priv = netdev_priv(dev); Index: linux-2.6.21-rc5/drivers/infiniband/hw/cxgb3/iwch_provider.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/hw/cxgb3/iwch_provider.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/hw/cxgb3/iwch_provider.c 2007-03-27 14:20:38.000000000 +0100 @@ -545,11 +545,14 @@ static int iwch_reregister_phys_mem(stru php = to_iwch_pd(pd); if (mr_rereg_mask & IB_MR_REREG_ACCESS) mh.attr.perms = iwch_ib_to_tpt_access(acc); - if (mr_rereg_mask & IB_MR_REREG_TRANS) + if (mr_rereg_mask & IB_MR_REREG_TRANS) { ret = build_phys_page_list(buffer_list, num_phys_buf, iova_start, &total_size, &npages, &shift, &page_list); + if (ret) + return ret; + } ret = iwch_reregister_mem(rhp, php, &mh, shift, page_list, npages); kfree(page_list); Index: linux-2.6.21-rc5/drivers/infiniband/hw/ehca/ehca_irq.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/hw/ehca/ehca_irq.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/hw/ehca/ehca_irq.c 2007-03-27 14:20:38.000000000 +0100 @@ -66,7 +66,9 @@ static void queue_comp_task(struct ehca_cq *__cq); static struct ehca_comp_pool* pool; +#ifdef CONFIG_HOTPLUG_CPU static struct notifier_block comp_pool_callback_nb; +#endif static inline void comp_event_callback(struct ehca_cq *cq) { @@ -733,6 +735,7 @@ static void take_over_work(struct ehca_c } +#ifdef CONFIG_HOTPLUG_CPU static int comp_pool_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) @@ -775,6 +778,7 @@ static int comp_pool_callback(struct not return NOTIFY_OK; } +#endif int ehca_create_comp_pool(void) { @@ -805,9 +809,11 @@ int ehca_create_comp_pool(void) } } +#ifdef CONFIG_HOTPLUG_CPU comp_pool_callback_nb.notifier_call = comp_pool_callback; comp_pool_callback_nb.priority =0; register_cpu_notifier(&comp_pool_callback_nb); +#endif printk(KERN_INFO "eHCA scaling code enabled\n"); @@ -821,7 +827,9 @@ void ehca_destroy_comp_pool(void) if (!ehca_scaling_code) return; +#ifdef CONFIG_HOTPLUG_CPU unregister_cpu_notifier(&comp_pool_callback_nb); +#endif for (i = 0; i < NR_CPUS; i++) { if (cpu_online(i)) Index: linux-2.6.21-rc5/drivers/infiniband/hw/ipath/ipath_fs.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/hw/ipath/ipath_fs.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/hw/ipath/ipath_fs.c 2007-03-27 14:20:38.000000000 +0100 @@ -451,12 +451,18 @@ bail: return ret; } -static void remove_file(struct dentry *parent, char *name) +static int remove_file(struct dentry *parent, char *name) { struct dentry *tmp; + int ret; tmp = lookup_one_len(name, parent, strlen(name)); + if (IS_ERR(tmp)) { + ret = PTR_ERR(tmp); + goto bail; + } + spin_lock(&dcache_lock); spin_lock(&tmp->d_lock); if (!(d_unhashed(tmp) && tmp->d_inode)) { @@ -469,6 +475,14 @@ static void remove_file(struct dentry *p spin_unlock(&tmp->d_lock); spin_unlock(&dcache_lock); } + + ret = 0; +bail: + /* + * We don't expect clients to care about the return value, but + * it's there if they need it. + */ + return ret; } static int remove_device_files(struct super_block *sb, Index: linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_cm.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_cm.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_cm.c 2007-03-27 14:20:38.000000000 +0100 @@ -452,7 +452,7 @@ void ipoib_cm_send(struct net_device *de skb->len, tx->mtu); ++priv->stats.tx_dropped; ++priv->stats.tx_errors; - ipoib_cm_skb_too_long(dev, skb, tx->mtu - INFINIBAND_ALEN); + ipoib_cm_skb_too_long(dev, skb, tx->mtu - IPOIB_ENCAP_LEN); return; } @@ -1095,7 +1095,7 @@ static void ipoib_cm_stale_task(struct w /* List if sorted by LRU, start from tail, * stop when we see a recently used entry */ p = list_entry(priv->cm.passive_ids.prev, typeof(*p), list); - if (time_after_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT)) + if (time_before_eq(jiffies, p->jiffies + IPOIB_CM_RX_TIMEOUT)) break; list_del_init(&p->list); spin_unlock_irqrestore(&priv->lock, flags); Index: linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_ib.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_ib.c 2007-03-27 14:20:38.000000000 +0100 @@ -328,9 +328,9 @@ void ipoib_send(struct net_device *dev, struct ipoib_tx_buf *tx_req; u64 addr; - if (unlikely(skb->len > priv->mcast_mtu + INFINIBAND_ALEN)) { + if (unlikely(skb->len > priv->mcast_mtu + IPOIB_ENCAP_LEN)) { ipoib_warn(priv, "packet len %d (> %d) too long to send, dropping\n", - skb->len, priv->mcast_mtu + INFINIBAND_ALEN); + skb->len, priv->mcast_mtu + IPOIB_ENCAP_LEN); ++priv->stats.tx_dropped; ++priv->stats.tx_errors; ipoib_cm_skb_too_long(dev, skb, priv->mcast_mtu); Index: linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_main.c 2007-03-27 14:20:38.000000000 +0100 @@ -380,7 +380,7 @@ static void path_rec_completion(int stat struct net_device *dev = path->dev; struct ipoib_dev_priv *priv = netdev_priv(dev); struct ipoib_ah *ah = NULL; - struct ipoib_neigh *neigh; + struct ipoib_neigh *neigh, *tn; struct sk_buff_head skqueue; struct sk_buff *skb; unsigned long flags; @@ -418,7 +418,7 @@ static void path_rec_completion(int stat while ((skb = __skb_dequeue(&path->queue))) __skb_queue_tail(&skqueue, skb); - list_for_each_entry(neigh, &path->neigh_list, list) { + list_for_each_entry_safe(neigh, tn, &path->neigh_list, list) { kref_get(&path->ah->ref); neigh->ah = path->ah; memcpy(&neigh->dgid.raw, &path->pathrec.dgid.raw, Index: linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/infiniband/ulp/ipoib/ipoib_multicast.c 2007-03-27 14:20:38.000000000 +0100 @@ -644,6 +644,9 @@ static int ipoib_mcast_leave(struct net_ struct ipoib_dev_priv *priv = netdev_priv(dev); int ret = 0; + if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) + ib_sa_free_multicast(mcast->mc); + if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) { ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n", IPOIB_GID_ARG(mcast->mcmember.mgid)); @@ -655,9 +658,6 @@ static int ipoib_mcast_leave(struct net_ ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret); } - if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags)) - ib_sa_free_multicast(mcast->mc); - return 0; } Index: linux-2.6.21-rc5/drivers/kvm/kvm_main.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/kvm/kvm_main.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/kvm/kvm_main.c 2007-03-27 14:20:38.000000000 +0100 @@ -2464,7 +2464,7 @@ int kvm_init_arch(struct kvm_arch_ops *o r = kvm_arch_ops->hardware_setup(); if (r < 0) - return r; + goto out; on_each_cpu(kvm_arch_ops->hardware_enable, NULL, 0, 1); r = register_cpu_notifier(&kvm_cpu_notifier); @@ -2500,6 +2500,8 @@ out_free_2: out_free_1: on_each_cpu(kvm_arch_ops->hardware_disable, NULL, 0, 1); kvm_arch_ops->hardware_unsetup(); +out: + kvm_arch_ops = NULL; return r; } Index: linux-2.6.21-rc5/drivers/kvm/mmu.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/kvm/mmu.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/kvm/mmu.c 2007-03-27 14:20:38.000000000 +0100 @@ -131,7 +131,7 @@ static int dbg = 1; (((address) >> PT32_LEVEL_SHIFT(level)) & ((1 << PT32_LEVEL_BITS) - 1)) -#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & PAGE_MASK) +#define PT64_BASE_ADDR_MASK (((1ULL << 52) - 1) & ~(u64)(PAGE_SIZE-1)) #define PT64_DIR_BASE_ADDR_MASK \ (PT64_BASE_ADDR_MASK & ~((1ULL << (PAGE_SHIFT + PT64_LEVEL_BITS)) - 1)) @@ -406,8 +406,8 @@ static void rmap_write_protect(struct kv spte = desc->shadow_ptes[0]; } BUG_ON(!spte); - BUG_ON((*spte & PT64_BASE_ADDR_MASK) != - page_to_pfn(page) << PAGE_SHIFT); + BUG_ON((*spte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT + != page_to_pfn(page)); BUG_ON(!(*spte & PT_PRESENT_MASK)); BUG_ON(!(*spte & PT_WRITABLE_MASK)); rmap_printk("rmap_write_protect: spte %p %llx\n", spte, *spte); @@ -1093,22 +1093,40 @@ out: return r; } +static void mmu_pre_write_zap_pte(struct kvm_vcpu *vcpu, + struct kvm_mmu_page *page, + u64 *spte) +{ + u64 pte; + struct kvm_mmu_page *child; + + pte = *spte; + if (is_present_pte(pte)) { + if (page->role.level == PT_PAGE_TABLE_LEVEL) + rmap_remove(vcpu, spte); + else { + child = page_header(pte & PT64_BASE_ADDR_MASK); + mmu_page_remove_parent_pte(vcpu, child, spte); + } + } + *spte = 0; +} + void kvm_mmu_pre_write(struct kvm_vcpu *vcpu, gpa_t gpa, int bytes) { gfn_t gfn = gpa >> PAGE_SHIFT; struct kvm_mmu_page *page; - struct kvm_mmu_page *child; struct hlist_node *node, *n; struct hlist_head *bucket; unsigned index; u64 *spte; - u64 pte; unsigned offset = offset_in_page(gpa); unsigned pte_size; unsigned page_offset; unsigned misaligned; int level; int flooded = 0; + int npte; pgprintk("%s: gpa %llx bytes %d\n", __FUNCTION__, gpa, bytes); if (gfn == vcpu->last_pt_write_gfn) { @@ -1144,22 +1162,26 @@ void kvm_mmu_pre_write(struct kvm_vcpu * } page_offset = offset; level = page->role.level; + npte = 1; if (page->role.glevels == PT32_ROOT_LEVEL) { - page_offset <<= 1; /* 32->64 */ + page_offset <<= 1; /* 32->64 */ + /* + * A 32-bit pde maps 4MB while the shadow pdes map + * only 2MB. So we need to double the offset again + * and zap two pdes instead of one. + */ + if (level == PT32_ROOT_LEVEL) { + page_offset <<= 1; + npte = 2; + } page_offset &= ~PAGE_MASK; } spte = __va(page->page_hpa); spte += page_offset / sizeof(*spte); - pte = *spte; - if (is_present_pte(pte)) { - if (level == PT_PAGE_TABLE_LEVEL) - rmap_remove(vcpu, spte); - else { - child = page_header(pte & PT64_BASE_ADDR_MASK); - mmu_page_remove_parent_pte(vcpu, child, spte); - } + while (npte--) { + mmu_pre_write_zap_pte(vcpu, page, spte); + ++spte; } - *spte = 0; } } Index: linux-2.6.21-rc5/drivers/kvm/vmx.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/kvm/vmx.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/kvm/vmx.c 2007-03-27 14:20:38.000000000 +0100 @@ -371,10 +371,10 @@ static int vmx_get_msr(struct kvm_vcpu * data = vmcs_read32(GUEST_SYSENTER_CS); break; case MSR_IA32_SYSENTER_EIP: - data = vmcs_read32(GUEST_SYSENTER_EIP); + data = vmcs_readl(GUEST_SYSENTER_EIP); break; case MSR_IA32_SYSENTER_ESP: - data = vmcs_read32(GUEST_SYSENTER_ESP); + data = vmcs_readl(GUEST_SYSENTER_ESP); break; default: msr = find_msr_entry(vcpu, msr_index); @@ -412,10 +412,10 @@ static int vmx_set_msr(struct kvm_vcpu * vmcs_write32(GUEST_SYSENTER_CS, data); break; case MSR_IA32_SYSENTER_EIP: - vmcs_write32(GUEST_SYSENTER_EIP, data); + vmcs_writel(GUEST_SYSENTER_EIP, data); break; case MSR_IA32_SYSENTER_ESP: - vmcs_write32(GUEST_SYSENTER_ESP, data); + vmcs_writel(GUEST_SYSENTER_ESP, data); break; case MSR_IA32_TIME_STAMP_COUNTER: guest_write_tsc(data); Index: linux-2.6.21-rc5/drivers/md/linear.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/md/linear.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/md/linear.c 2007-03-27 14:20:38.000000000 +0100 @@ -188,7 +188,7 @@ static linear_conf_t *linear_conf(mddev_ for (i=0; i < cnt-1 ; i++) { sector_t sz = 0; int j; - for (j=i; idisks[j].size; if (sz >= min_spacing && sz < conf->hash_spacing) conf->hash_spacing = sz; Index: linux-2.6.21-rc5/drivers/media/dvb/frontends/nxt200x.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/media/dvb/frontends/nxt200x.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/media/dvb/frontends/nxt200x.c 2007-03-27 14:20:38.000000000 +0100 @@ -562,7 +562,7 @@ static int nxt200x_setup_frontend_parame /* set input */ if (state->config->set_pll_input) - state->config->set_pll_input(buf, 1); + state->config->set_pll_input(buf+1, 1); break; case VSB_8: /* Set non-punctured clock for VSB */ @@ -571,7 +571,7 @@ static int nxt200x_setup_frontend_parame /* set input */ if (state->config->set_pll_input) - state->config->set_pll_input(buf, 0); + state->config->set_pll_input(buf+1, 0); break; default: return -EINVAL; Index: linux-2.6.21-rc5/drivers/net/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -2372,22 +2372,23 @@ config CHELSIO_T1_NAPI when the driver is receiving lots of packets from the card. config CHELSIO_T3 - tristate "Chelsio Communications T3 10Gb Ethernet support" - depends on PCI - help - This driver supports Chelsio T3-based gigabit and 10Gb Ethernet - adapters. - - For general information about Chelsio and our products, visit - our website at . + tristate "Chelsio Communications T3 10Gb Ethernet support" + depends on PCI + select FW_LOADER + help + This driver supports Chelsio T3-based gigabit and 10Gb Ethernet + adapters. - For customer support, please visit our customer support page at - . + For general information about Chelsio and our products, visit + our website at . - Please send feedback to . + For customer support, please visit our customer support page at + . - To compile this driver as a module, choose M here: the module - will be called cxgb3. + Please send feedback to . + + To compile this driver as a module, choose M here: the module + will be called cxgb3. config EHEA tristate "eHEA Ethernet support" Index: linux-2.6.21-rc5/drivers/net/cxgb3/common.h =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/cxgb3/common.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/cxgb3/common.h 2007-03-27 14:20:38.000000000 +0100 @@ -260,6 +260,10 @@ struct mac_stats { unsigned long serdes_signal_loss; unsigned long xaui_pcs_ctc_err; unsigned long xaui_pcs_align_change; + + unsigned long num_toggled; /* # times toggled TxEn due to stuck TX */ + unsigned long num_resets; /* # times reset due to stuck TX */ + }; struct tp_mib_stats { @@ -400,6 +404,12 @@ struct adapter_params { unsigned int rev; /* chip revision */ }; +enum { /* chip revisions */ + T3_REV_A = 0, + T3_REV_B = 2, + T3_REV_B2 = 3, +}; + struct trace_params { u32 sip; u32 sip_mask; @@ -465,6 +475,10 @@ struct cmac { struct adapter *adapter; unsigned int offset; unsigned int nucast; /* # of address filters for unicast MACs */ + unsigned int tcnt; + unsigned int xcnt; + unsigned int toggle_cnt; + unsigned int txen; struct mac_stats stats; }; @@ -666,6 +680,7 @@ int t3_mac_set_address(struct cmac *mac, int t3_mac_set_num_ucast(struct cmac *mac, int n); const struct mac_stats *t3_mac_update_stats(struct cmac *mac); int t3_mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex, int fc); +int t3b2_mac_watchdog_task(struct cmac *mac); void t3_mc5_prep(struct adapter *adapter, struct mc5 *mc5, int mode); int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, Index: linux-2.6.21-rc5/drivers/net/cxgb3/cxgb3_main.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/cxgb3/cxgb3_main.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/cxgb3/cxgb3_main.c 2007-03-27 14:20:38.000000000 +0100 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "common.h" @@ -707,6 +708,28 @@ static void bind_qsets(struct adapter *a } } +#define FW_FNAME "t3fw-%d.%d.bin" + +static int upgrade_fw(struct adapter *adap) +{ + int ret; + char buf[64]; + const struct firmware *fw; + struct device *dev = &adap->pdev->dev; + + snprintf(buf, sizeof(buf), FW_FNAME, FW_VERSION_MAJOR, + FW_VERSION_MINOR); + ret = request_firmware(&fw, buf, dev); + if (ret < 0) { + dev_err(dev, "could not upgrade firmware: unable to load %s\n", + buf); + return ret; + } + ret = t3_load_fw(adap, fw->data, fw->size); + release_firmware(fw); + return ret; +} + /** * cxgb_up - enable the adapter * @adapter: adapter being enabled @@ -723,6 +746,8 @@ static int cxgb_up(struct adapter *adap) if (!(adap->flags & FULL_INIT_DONE)) { err = t3_check_fw_version(adap); + if (err == -EINVAL) + err = upgrade_fw(adap); if (err) goto out; @@ -1031,7 +1056,11 @@ static char stats_strings[][ETH_GSTRING_ "VLANinsertions ", "TxCsumOffload ", "RxCsumGood ", - "RxDrops " + "RxDrops ", + + "CheckTXEnToggled ", + "CheckResets ", + }; static int get_stats_count(struct net_device *dev) @@ -1145,6 +1174,9 @@ static void get_stats(struct net_device *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_TX_CSUM); *data++ = collect_sge_port_stats(adapter, pi, SGE_PSTAT_RX_CSUM_GOOD); *data++ = s->rx_cong_drops; + + *data++ = s->num_toggled; + *data++ = s->num_resets; } static inline void reg_block_dump(struct adapter *ap, void *buf, @@ -1362,23 +1394,27 @@ static int set_rx_csum(struct net_device static void get_sge_param(struct net_device *dev, struct ethtool_ringparam *e) { - struct adapter *adapter = dev->priv; + const struct adapter *adapter = dev->priv; + const struct port_info *pi = netdev_priv(dev); + const struct qset_params *q = &adapter->params.sge.qset[pi->first_qset]; e->rx_max_pending = MAX_RX_BUFFERS; e->rx_mini_max_pending = 0; e->rx_jumbo_max_pending = MAX_RX_JUMBO_BUFFERS; e->tx_max_pending = MAX_TXQ_ENTRIES; - e->rx_pending = adapter->params.sge.qset[0].fl_size; - e->rx_mini_pending = adapter->params.sge.qset[0].rspq_size; - e->rx_jumbo_pending = adapter->params.sge.qset[0].jumbo_size; - e->tx_pending = adapter->params.sge.qset[0].txq_size[0]; + e->rx_pending = q->fl_size; + e->rx_mini_pending = q->rspq_size; + e->rx_jumbo_pending = q->jumbo_size; + e->tx_pending = q->txq_size[0]; } static int set_sge_param(struct net_device *dev, struct ethtool_ringparam *e) { int i; + struct qset_params *q; struct adapter *adapter = dev->priv; + const struct port_info *pi = netdev_priv(dev); if (e->rx_pending > MAX_RX_BUFFERS || e->rx_jumbo_pending > MAX_RX_JUMBO_BUFFERS || @@ -1393,9 +1429,8 @@ static int set_sge_param(struct net_devi if (adapter->flags & FULL_INIT_DONE) return -EBUSY; - for (i = 0; i < SGE_QSETS; ++i) { - struct qset_params *q = &adapter->params.sge.qset[i]; - + q = &adapter->params.sge.qset[pi->first_qset]; + for (i = 0; i < pi->nqsets; ++i, ++q) { q->rspq_size = e->rx_mini_pending; q->fl_size = e->rx_pending; q->jumbo_size = e->rx_jumbo_pending; @@ -2067,6 +2102,40 @@ static void check_link_status(struct ada } } +static void check_t3b2_mac(struct adapter *adapter) +{ + int i; + + rtnl_lock(); /* synchronize with ifdown */ + for_each_port(adapter, i) { + struct net_device *dev = adapter->port[i]; + struct port_info *p = netdev_priv(dev); + int status; + + if (!netif_running(dev)) + continue; + + status = 0; + if (netif_running(dev)) + status = t3b2_mac_watchdog_task(&p->mac); + if (status == 1) + p->mac.stats.num_toggled++; + else if (status == 2) { + struct cmac *mac = &p->mac; + + t3_mac_set_mtu(mac, dev->mtu); + t3_mac_set_address(mac, 0, dev->dev_addr); + cxgb_set_rxmode(dev); + t3_link_start(&p->phy, mac, &p->link_config); + t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); + t3_port_intr_enable(adapter, p->port_id); + p->mac.stats.num_resets++; + } + } + rtnl_unlock(); +} + + static void t3_adap_check_task(struct work_struct *work) { struct adapter *adapter = container_of(work, struct adapter, @@ -2087,6 +2156,9 @@ static void t3_adap_check_task(struct wo adapter->check_task_cnt = 0; } + if (p->rev == T3_REV_B2) + check_t3b2_mac(adapter); + /* Schedule the next check update if any port is active. */ spin_lock(&adapter->work_lock); if (adapter->open_device_map & PORT_MASK) Index: linux-2.6.21-rc5/drivers/net/cxgb3/regs.h =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/cxgb3/regs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/cxgb3/regs.h 2007-03-27 14:20:38.000000000 +0100 @@ -1206,6 +1206,14 @@ #define A_TP_RX_TRC_KEY0 0x120 +#define A_TP_TX_DROP_CNT_CH0 0x12d + +#define S_TXDROPCNTCH0RCVD 0 +#define M_TXDROPCNTCH0RCVD 0xffff +#define V_TXDROPCNTCH0RCVD(x) ((x) << S_TXDROPCNTCH0RCVD) +#define G_TXDROPCNTCH0RCVD(x) (((x) >> S_TXDROPCNTCH0RCVD) & \ + M_TXDROPCNTCH0RCVD) + #define A_ULPRX_CTL 0x500 #define S_ROUND_ROBIN 4 @@ -1834,6 +1842,8 @@ #define V_TXPAUSEEN(x) ((x) << S_TXPAUSEEN) #define F_TXPAUSEEN V_TXPAUSEEN(1U) +#define A_XGM_TX_PAUSE_QUANTA 0x808 + #define A_XGM_RX_CTRL 0x80c #define S_RXEN 0 @@ -1920,6 +1930,11 @@ #define A_XGM_TXFIFO_CFG 0x888 +#define S_TXIPG 13 +#define M_TXIPG 0xff +#define V_TXIPG(x) ((x) << S_TXIPG) +#define G_TXIPG(x) (((x) >> S_TXIPG) & M_TXIPG) + #define S_TXFIFOTHRESH 4 #define M_TXFIFOTHRESH 0x1ff @@ -2190,6 +2205,13 @@ #define A_XGM_RX_MAX_PKT_SIZE_ERR_CNT 0x9a4 +#define A_XGM_TX_SPI4_SOP_EOP_CNT 0x9a8 + +#define S_TXSPI4SOPCNT 16 +#define M_TXSPI4SOPCNT 0xffff +#define V_TXSPI4SOPCNT(x) ((x) << S_TXSPI4SOPCNT) +#define G_TXSPI4SOPCNT(x) (((x) >> S_TXSPI4SOPCNT) & M_TXSPI4SOPCNT) + #define A_XGM_RX_SPI4_SOP_EOP_CNT 0x9ac #define XGMAC0_1_BASE_ADDR 0xa00 Index: linux-2.6.21-rc5/drivers/net/cxgb3/t3_hw.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/cxgb3/t3_hw.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/cxgb3/t3_hw.c 2007-03-27 14:20:38.000000000 +0100 @@ -681,7 +681,8 @@ enum { SF_ERASE_SECTOR = 0xd8, /* erase sector */ FW_FLASH_BOOT_ADDR = 0x70000, /* start address of FW in flash */ - FW_VERS_ADDR = 0x77ffc /* flash address holding FW version */ + FW_VERS_ADDR = 0x77ffc, /* flash address holding FW version */ + FW_MIN_SIZE = 8 /* at least version and csum */ }; /** @@ -935,7 +936,7 @@ int t3_load_fw(struct adapter *adapter, const u32 *p = (const u32 *)fw_data; int ret, addr, fw_sector = FW_FLASH_BOOT_ADDR >> 16; - if (size & 3) + if ((size & 3) || size < FW_MIN_SIZE) return -EINVAL; if (size > FW_VERS_ADDR + 8 - FW_FLASH_BOOT_ADDR) return -EFBIG; @@ -3243,15 +3244,17 @@ void early_hw_init(struct adapter *adapt } /* - * Reset the adapter. PCIe cards lose their config space during reset, PCI-X + * Reset the adapter. + * Older PCIe cards lose their config space during reset, PCI-X * ones don't. */ int t3_reset_adapter(struct adapter *adapter) { - int i; + int i, save_and_restore_pcie = + adapter->params.rev < T3_REV_B2 && is_pcie(adapter); uint16_t devid = 0; - if (is_pcie(adapter)) + if (save_and_restore_pcie) pci_save_state(adapter->pdev); t3_write_reg(adapter, A_PL_RST, F_CRSTWRM | F_CRSTWRMMODE); @@ -3269,7 +3272,7 @@ int t3_reset_adapter(struct adapter *ada if (devid != 0x1425) return -1; - if (is_pcie(adapter)) + if (save_and_restore_pcie) pci_restore_state(adapter->pdev); return 0; } Index: linux-2.6.21-rc5/drivers/net/cxgb3/xgmac.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/cxgb3/xgmac.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/cxgb3/xgmac.c 2007-03-27 14:20:38.000000000 +0100 @@ -124,9 +124,6 @@ int t3_mac_reset(struct cmac *mac) xaui_serdes_reset(mac); } - if (adap->params.rev > 0) - t3_write_reg(adap, A_XGM_PAUSE_TIMER + oft, 0xf000); - val = F_MAC_RESET_; if (is_10G(adap)) val |= F_PCS_RESET_; @@ -145,6 +142,58 @@ int t3_mac_reset(struct cmac *mac) return 0; } +int t3b2_mac_reset(struct cmac *mac) +{ + struct adapter *adap = mac->adapter; + unsigned int oft = mac->offset; + u32 val; + + if (!macidx(mac)) + t3_set_reg_field(adap, A_MPS_CFG, F_PORT0ACTIVE, 0); + else + t3_set_reg_field(adap, A_MPS_CFG, F_PORT1ACTIVE, 0); + + t3_write_reg(adap, A_XGM_RESET_CTRL + oft, F_MAC_RESET_); + t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + + msleep(10); + + /* Check for xgm Rx fifo empty */ + if (t3_wait_op_done(adap, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT + oft, + 0x80000000, 1, 5, 2)) { + CH_ERR(adap, "MAC %d Rx fifo drain failed\n", + macidx(mac)); + return -1; + } + + t3_write_reg(adap, A_XGM_RESET_CTRL + oft, 0); + t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + + val = F_MAC_RESET_; + if (is_10G(adap)) + val |= F_PCS_RESET_; + else if (uses_xaui(adap)) + val |= F_PCS_RESET_ | F_XG2G_RESET_; + else + val |= F_RGMII_RESET_ | F_XG2G_RESET_; + t3_write_reg(adap, A_XGM_RESET_CTRL + oft, val); + t3_read_reg(adap, A_XGM_RESET_CTRL + oft); /* flush */ + if ((val & F_PCS_RESET_) && adap->params.rev) { + msleep(1); + t3b_pcs_reset(mac); + } + t3_write_reg(adap, A_XGM_RX_CFG + oft, + F_DISPAUSEFRAMES | F_EN1536BFRAMES | + F_RMFCS | F_ENJUMBO | F_ENHASHMCAST); + + if (!macidx(mac)) + t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT0ACTIVE); + else + t3_set_reg_field(adap, A_MPS_CFG, 0, F_PORT1ACTIVE); + + return 0; +} + /* * Set the exact match register 'idx' to recognize the given Ethernet address. */ @@ -251,9 +300,11 @@ int t3_mac_set_mtu(struct cmac *mac, uns * Adjust the PAUSE frame watermarks. We always set the LWM, and the * HWM only if flow-control is enabled. */ - hwm = max(MAC_RXFIFO_SIZE - 3 * mtu, MAC_RXFIFO_SIZE / 2U); - hwm = min(hwm, 3 * MAC_RXFIFO_SIZE / 4 + 1024); - lwm = hwm - 1024; + hwm = max_t(unsigned int, MAC_RXFIFO_SIZE - 3 * mtu, + MAC_RXFIFO_SIZE * 38 / 100); + hwm = min(hwm, MAC_RXFIFO_SIZE - 8192); + lwm = min(3 * (int)mtu, MAC_RXFIFO_SIZE / 4); + v = t3_read_reg(adap, A_XGM_RXFIFO_CFG + mac->offset); v &= ~V_RXFIFOPAUSELWM(M_RXFIFOPAUSELWM); v |= V_RXFIFOPAUSELWM(lwm / 8); @@ -270,7 +321,15 @@ int t3_mac_set_mtu(struct cmac *mac, uns thres = mtu > thres ? (mtu - thres + 7) / 8 : 0; thres = max(thres, 8U); /* need at least 8 */ t3_set_reg_field(adap, A_XGM_TXFIFO_CFG + mac->offset, - V_TXFIFOTHRESH(M_TXFIFOTHRESH), V_TXFIFOTHRESH(thres)); + V_TXFIFOTHRESH(M_TXFIFOTHRESH) | V_TXIPG(M_TXIPG), + V_TXFIFOTHRESH(thres) | V_TXIPG(1)); + + if (adap->params.rev > 0) + t3_write_reg(adap, A_XGM_PAUSE_TIMER + mac->offset, + (hwm - lwm) * 4 / 8); + t3_write_reg(adap, A_XGM_TX_PAUSE_QUANTA + mac->offset, + MAC_RXFIFO_SIZE * 4 * 8 / 512); + return 0; } @@ -298,12 +357,6 @@ int t3_mac_set_speed_duplex_fc(struct cm V_PORTSPEED(M_PORTSPEED), val); } - val = t3_read_reg(adap, A_XGM_RXFIFO_CFG + oft); - val &= ~V_RXFIFOPAUSEHWM(M_RXFIFOPAUSEHWM); - if (fc & PAUSE_TX) - val |= V_RXFIFOPAUSEHWM(G_RXFIFOPAUSELWM(val) + 128); /* +1KB */ - t3_write_reg(adap, A_XGM_RXFIFO_CFG + oft, val); - t3_set_reg_field(adap, A_XGM_TX_CFG + oft, F_TXPAUSEEN, (fc & PAUSE_RX) ? F_TXPAUSEEN : 0); return 0; @@ -318,9 +371,17 @@ int t3_mac_enable(struct cmac *mac, int if (which & MAC_DIRECTION_TX) { t3_write_reg(adap, A_XGM_TX_CTRL + oft, F_TXEN); t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); - t3_write_reg(adap, A_TP_PIO_DATA, 0xbf000001); + t3_write_reg(adap, A_TP_PIO_DATA, 0xc0ede401); t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE); t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); + + t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + idx); + mac->tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, + A_TP_PIO_DATA))); + mac->xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, + A_XGM_TX_SPI4_SOP_EOP_CNT))); + mac->txen = F_TXEN; + mac->toggle_cnt = 0; } if (which & MAC_DIRECTION_RX) t3_write_reg(adap, A_XGM_RX_CTRL + oft, F_RXEN); @@ -337,13 +398,50 @@ int t3_mac_disable(struct cmac *mac, int t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CFG_CH0 + idx); t3_write_reg(adap, A_TP_PIO_DATA, 0xc000001f); t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_MODE); - t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 0); + t3_set_reg_field(adap, A_TP_PIO_DATA, 1 << idx, 1 << idx); + mac->txen = 0; } if (which & MAC_DIRECTION_RX) t3_write_reg(adap, A_XGM_RX_CTRL + mac->offset, 0); return 0; } +int t3b2_mac_watchdog_task(struct cmac *mac) +{ + struct adapter *adap = mac->adapter; + unsigned int tcnt, xcnt; + int status; + + t3_write_reg(adap, A_TP_PIO_ADDR, A_TP_TX_DROP_CNT_CH0 + macidx(mac)); + tcnt = (G_TXDROPCNTCH0RCVD(t3_read_reg(adap, A_TP_PIO_DATA))); + xcnt = (G_TXSPI4SOPCNT(t3_read_reg(adap, + A_XGM_TX_SPI4_SOP_EOP_CNT + + mac->offset))); + + if (tcnt != mac->tcnt && xcnt == 0 && mac->xcnt == 0) { + if (mac->toggle_cnt > 4) { + t3b2_mac_reset(mac); + mac->toggle_cnt = 0; + status = 2; + } else { + t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, 0); + t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); + t3_write_reg(adap, A_XGM_TX_CTRL + mac->offset, + mac->txen); + t3_read_reg(adap, A_XGM_TX_CTRL + mac->offset); + mac->toggle_cnt++; + status = 1; + } + } else { + mac->toggle_cnt = 0; + status = 0; + } + mac->tcnt = tcnt; + mac->xcnt = xcnt; + + return status; +} + /* * This function is called periodically to accumulate the current values of the * RMON counters into the port statistics. Since the packet counters are only @@ -375,6 +473,11 @@ const struct mac_stats *t3_mac_update_st RMON_UPDATE(mac, rx_too_long, RX_OVERSIZE_FRAMES); mac->stats.rx_too_long += RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT); + v = RMON_READ(mac, A_XGM_RX_MAX_PKT_SIZE_ERR_CNT); + if (mac->adapter->params.rev == T3_REV_B2) + v &= 0x7fffffff; + mac->stats.rx_too_long += v; + RMON_UPDATE(mac, rx_frames_64, RX_64B_FRAMES); RMON_UPDATE(mac, rx_frames_65_127, RX_65_127B_FRAMES); RMON_UPDATE(mac, rx_frames_128_255, RX_128_255B_FRAMES); Index: linux-2.6.21-rc5/drivers/net/ewrk3.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/ewrk3.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/ewrk3.c 2007-03-27 14:20:38.000000000 +0100 @@ -414,10 +414,9 @@ ewrk3_hw_init(struct net_device *dev, u_ icr &= 0x70; outb(icr, EWRK3_ICR); /* Disable all the IRQs */ - if (nicsr == (CSR_TXD | CSR_RXD)) + if (nicsr != (CSR_TXD | CSR_RXD)) return -ENXIO; - /* Check that the EEPROM is alive and well and not living on Pluto... */ for (chksum = 0, i = 0; i < EEPROM_MAX; i += 2) { union { Index: linux-2.6.21-rc5/drivers/net/irda/irda-usb.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/irda/irda-usb.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/irda/irda-usb.c 2007-03-27 14:20:38.000000000 +0100 @@ -1057,6 +1057,8 @@ static int stir421x_fw_upload(struct ird if (ret < 0) break; + + mdelay(10); } kfree(patch_block); Index: linux-2.6.21-rc5/drivers/net/mv643xx_eth.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/mv643xx_eth.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/mv643xx_eth.c 2007-03-27 14:20:38.000000000 +0100 @@ -1516,9 +1516,23 @@ static int mv643xx_eth_shared_remove(str return 0; } +static void mv643xx_eth_shutdown(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct mv643xx_private *mp = netdev_priv(dev); + unsigned int port_num = mp->port_num; + + /* Mask all interrupts on ethernet port */ + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0); + mv_read (MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); + + eth_port_reset(port_num); +} + static struct platform_driver mv643xx_eth_driver = { .probe = mv643xx_eth_probe, .remove = mv643xx_eth_remove, + .shutdown = mv643xx_eth_shutdown, .driver = { .name = MV643XX_ETH_NAME, }, Index: linux-2.6.21-rc5/drivers/net/myri10ge/myri10ge.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/myri10ge/myri10ge.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/myri10ge/myri10ge.c 2007-03-27 14:20:38.000000000 +0100 @@ -71,7 +71,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.2.0" +#define MYRI10GE_VERSION_STR "1.3.0-1.226" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); @@ -234,7 +234,7 @@ static int myri10ge_msi = 1; /* enable m module_param(myri10ge_msi, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_msi, "Enable Message Signalled Interrupts\n"); -static int myri10ge_intr_coal_delay = 25; +static int myri10ge_intr_coal_delay = 75; module_param(myri10ge_intr_coal_delay, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_intr_coal_delay, "Interrupt coalescing delay\n"); @@ -279,7 +279,7 @@ static int myri10ge_fill_thresh = 256; module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n"); -static int myri10ge_wcfifo = 1; +static int myri10ge_wcfifo = 0; module_param(myri10ge_wcfifo, int, S_IRUGO); MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); @@ -905,6 +905,14 @@ myri10ge_alloc_rx_pages(struct myri10ge_ (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) { /* we can use part of previous page */ get_page(rx->page); +#if MYRI10GE_ALLOC_SIZE > 4096 + /* Firmware cannot cross 4K boundary.. */ + if ((rx->page_offset >> 12) != + ((rx->page_offset + bytes - 1) >> 12)) { + rx->page_offset = + (rx->page_offset + bytes) & ~4095; + } +#endif } else { /* we need a new page */ page = @@ -2483,6 +2491,8 @@ static void myri10ge_enable_ecrc(struct #define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 #define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa +#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140 +#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142 static void myri10ge_select_firmware(struct myri10ge_priv *mgp) { @@ -2514,6 +2524,12 @@ static void myri10ge_select_firmware(str ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS && bridge->device == PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) + /* ServerWorks HT2100 */ + || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS + && bridge->device >= + PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST + && bridge->device <= + PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST) /* All Intel E5000 PCIE ports */ || (bridge->vendor == PCI_VENDOR_ID_INTEL && bridge->device >= Index: linux-2.6.21-rc5/drivers/net/pci-skeleton.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/pci-skeleton.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/pci-skeleton.c 2007-03-27 14:20:38.000000000 +0100 @@ -710,8 +710,8 @@ match: tp->chipset, rtl_chip_info[tp->chipset].name); - i = register_netdev (dev); - if (i) + rc = register_netdev (dev); + if (rc) goto err_out_unmap; DPRINTK ("EXIT, returning 0\n"); Index: linux-2.6.21-rc5/drivers/net/saa9730.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/saa9730.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/saa9730.c 2007-03-27 14:20:38.000000000 +0100 @@ -64,37 +64,37 @@ static unsigned int pci_irq_line; static void evm_saa9730_enable_lan_int(struct lan_saa9730_private *lp) { - outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptBlock1); - outl(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptStatus1); - outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT | - EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1); + writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptBlock1); + writel(readl(&lp->evm_saa9730_regs->InterruptStatus1) | EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptStatus1); + writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) | EVM_LAN_INT | + EVM_MASTER_EN, &lp->evm_saa9730_regs->InterruptEnable1); } static void evm_saa9730_disable_lan_int(struct lan_saa9730_private *lp) { - outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptBlock1); - outl(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptEnable1); + writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptBlock1); + writel(readl(&lp->evm_saa9730_regs->InterruptEnable1) & ~EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptEnable1); } static void evm_saa9730_clear_lan_int(struct lan_saa9730_private *lp) { - outl(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1); + writel(EVM_LAN_INT, &lp->evm_saa9730_regs->InterruptStatus1); } static void evm_saa9730_block_lan_int(struct lan_saa9730_private *lp) { - outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptBlock1); + writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) & ~EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptBlock1); } static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp) { - outl(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT, - &lp->evm_saa9730_regs->InterruptBlock1); + writel(readl(&lp->evm_saa9730_regs->InterruptBlock1) | EVM_LAN_INT, + &lp->evm_saa9730_regs->InterruptBlock1); } static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp) @@ -147,7 +147,7 @@ static void __attribute_used__ show_saa9 printk("lp->lan_saa9730_regs->RxStatus = %x\n", readl(&lp->lan_saa9730_regs->RxStatus)); for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) { - outl(i, &lp->lan_saa9730_regs->CamAddress); + writel(i, &lp->lan_saa9730_regs->CamAddress); printk("lp->lan_saa9730_regs->CamData = %x\n", readl(&lp->lan_saa9730_regs->CamData)); } @@ -288,28 +288,27 @@ static int lan_saa9730_allocate_buffers( * Set rx buffer A and rx buffer B to point to the first two buffer * spaces. */ - outl(lp->dma_addr + rxoffset, - &lp->lan_saa9730_regs->RxBuffA); - outl(lp->dma_addr + rxoffset + - LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE, - &lp->lan_saa9730_regs->RxBuffB); + writel(lp->dma_addr + rxoffset, &lp->lan_saa9730_regs->RxBuffA); + writel(lp->dma_addr + rxoffset + + LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_RCV_Q_SIZE, + &lp->lan_saa9730_regs->RxBuffB); /* * Set txm_buf_a and txm_buf_b to point to the first two buffer * space */ - outl(lp->dma_addr + txoffset, - &lp->lan_saa9730_regs->TxBuffA); - outl(lp->dma_addr + txoffset + - LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE, - &lp->lan_saa9730_regs->TxBuffB); + writel(lp->dma_addr + txoffset, + &lp->lan_saa9730_regs->TxBuffA); + writel(lp->dma_addr + txoffset + + LAN_SAA9730_PACKET_SIZE * LAN_SAA9730_TXM_Q_SIZE, + &lp->lan_saa9730_regs->TxBuffB); /* Set packet number */ - outl((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) | - (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) | - (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) | - (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF), - &lp->lan_saa9730_regs->PacketCount); + writel((lp->DmaRcvPackets << PK_COUNT_RX_A_SHF) | + (lp->DmaRcvPackets << PK_COUNT_RX_B_SHF) | + (lp->DmaTxmPackets << PK_COUNT_TX_A_SHF) | + (lp->DmaTxmPackets << PK_COUNT_TX_B_SHF), + &lp->lan_saa9730_regs->PacketCount); return 0; @@ -326,10 +325,10 @@ static int lan_saa9730_cam_load(struct l for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) { /* First set address to where data is written */ - outl(i, &lp->lan_saa9730_regs->CamAddress); - outl((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16) - | (NetworkAddress[2] << 8) | NetworkAddress[3], - &lp->lan_saa9730_regs->CamData); + writel(i, &lp->lan_saa9730_regs->CamAddress); + writel((NetworkAddress[0] << 24) | (NetworkAddress[1] << 16) | + (NetworkAddress[2] << 8) | NetworkAddress[3], + &lp->lan_saa9730_regs->CamData); NetworkAddress += 4; } return 0; @@ -365,8 +364,8 @@ static int lan_saa9730_mii_init(struct l } /* Now set the control and address register. */ - outl(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF, - &lp->lan_saa9730_regs->StationMgmtCtl); + writel(MD_CA_BUSY | PHY_STATUS | PHY_ADDRESS << MD_CA_PHY_SHF, + &lp->lan_saa9730_regs->StationMgmtCtl); /* check link status, spin here till station is not busy */ i = 0; @@ -391,23 +390,23 @@ static int lan_saa9730_mii_init(struct l /* Link is down, reset the PHY first. */ /* set PHY address = 'CONTROL' */ - outl(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL, - &lp->lan_saa9730_regs->StationMgmtCtl); + writel(PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | PHY_CONTROL, + &lp->lan_saa9730_regs->StationMgmtCtl); /* Wait for 1 ms. */ mdelay(1); /* set 'CONTROL' = force reset and renegotiate */ - outl(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG | - PHY_CONTROL_RESTART_AUTO_NEG, - &lp->lan_saa9730_regs->StationMgmtData); + writel(PHY_CONTROL_RESET | PHY_CONTROL_AUTO_NEG | + PHY_CONTROL_RESTART_AUTO_NEG, + &lp->lan_saa9730_regs->StationMgmtData); /* Wait for 50 ms. */ mdelay(50); /* set 'BUSY' to start operation */ - outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | - PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl); + writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | MD_CA_WR | + PHY_CONTROL, &lp->lan_saa9730_regs->StationMgmtCtl); /* await completion */ i = 0; @@ -427,9 +426,9 @@ static int lan_saa9730_mii_init(struct l for (l = 0; l < 2; l++) { /* set PHY address = 'STATUS' */ - outl(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | - PHY_STATUS, - &lp->lan_saa9730_regs->StationMgmtCtl); + writel(MD_CA_BUSY | PHY_ADDRESS << MD_CA_PHY_SHF | + PHY_STATUS, + &lp->lan_saa9730_regs->StationMgmtCtl); /* await completion */ i = 0; @@ -462,35 +461,35 @@ static int lan_saa9730_mii_init(struct l static int lan_saa9730_control_init(struct lan_saa9730_private *lp) { /* Initialize DMA control register. */ - outl((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) | - (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) | - (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF) - | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN | - DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN, - &lp->lan_saa9730_regs->LanDmaCtl); + writel((LANMB_ANY << DMA_CTL_MAX_XFER_SHF) | + (LANEND_LITTLE << DMA_CTL_ENDIAN_SHF) | + (LAN_SAA9730_RCV_Q_INT_THRESHOLD << DMA_CTL_RX_INT_COUNT_SHF) + | DMA_CTL_RX_INT_TO_EN | DMA_CTL_RX_INT_EN | + DMA_CTL_MAC_RX_INT_EN | DMA_CTL_MAC_TX_INT_EN, + &lp->lan_saa9730_regs->LanDmaCtl); /* Initial MAC control register. */ - outl((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP, - &lp->lan_saa9730_regs->MacCtl); + writel((MACCM_MII << MAC_CONTROL_CONN_SHF) | MAC_CONTROL_FULL_DUP, + &lp->lan_saa9730_regs->MacCtl); /* Initialize CAM control register. */ - outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC, - &lp->lan_saa9730_regs->CamCtl); + writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_BROAD_ACC, + &lp->lan_saa9730_regs->CamCtl); /* * Initialize CAM enable register, only turn on first entry, should * contain own addr. */ - outl(0x0001, &lp->lan_saa9730_regs->CamEnable); + writel(0x0001, &lp->lan_saa9730_regs->CamEnable); /* Initialize Tx control register */ - outl(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl); + writel(TX_CTL_EN_COMP, &lp->lan_saa9730_regs->TxCtl); /* Initialize Rcv control register */ - outl(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl); + writel(RX_CTL_STRIP_CRC, &lp->lan_saa9730_regs->RxCtl); /* Reset DMA engine */ - outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest); + writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest); return 0; } @@ -500,14 +499,14 @@ static int lan_saa9730_stop(struct lan_s int i; /* Stop DMA first */ - outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) & - ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA), - &lp->lan_saa9730_regs->LanDmaCtl); + writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) & + ~(DMA_CTL_EN_TX_DMA | DMA_CTL_EN_RX_DMA), + &lp->lan_saa9730_regs->LanDmaCtl); /* Set the SW Reset bits in DMA and MAC control registers */ - outl(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest); - outl(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET, - &lp->lan_saa9730_regs->MacCtl); + writel(DMA_TEST_SW_RESET, &lp->lan_saa9730_regs->DmaTest); + writel(readl(&lp->lan_saa9730_regs->MacCtl) | MAC_CONTROL_RESET, + &lp->lan_saa9730_regs->MacCtl); /* * Wait for MAC reset to have finished. The reset bit is auto cleared @@ -532,8 +531,8 @@ static int lan_saa9730_dma_init(struct l /* Stop lan controller. */ lan_saa9730_stop(lp); - outl(LAN_SAA9730_DEFAULT_TIME_OUT_CNT, - &lp->lan_saa9730_regs->Timeout); + writel(LAN_SAA9730_DEFAULT_TIME_OUT_CNT, + &lp->lan_saa9730_regs->Timeout); return 0; } @@ -552,19 +551,19 @@ static int lan_saa9730_start(struct lan_ lp->PendingTxmPacketIndex = 0; lp->PendingTxmBufferIndex = 0; - outl(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA | - DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl); + writel(readl(&lp->lan_saa9730_regs->LanDmaCtl) | DMA_CTL_EN_TX_DMA | + DMA_CTL_EN_RX_DMA, &lp->lan_saa9730_regs->LanDmaCtl); /* For Tx, turn on MAC then DMA */ - outl(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN, - &lp->lan_saa9730_regs->TxCtl); + writel(readl(&lp->lan_saa9730_regs->TxCtl) | TX_CTL_TX_EN, + &lp->lan_saa9730_regs->TxCtl); /* For Rx, turn on DMA then MAC */ - outl(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN, - &lp->lan_saa9730_regs->RxCtl); + writel(readl(&lp->lan_saa9730_regs->RxCtl) | RX_CTL_RX_EN, + &lp->lan_saa9730_regs->RxCtl); /* Set Ok2Use to let hardware own the buffers. */ - outl(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use); + writel(OK2USE_RX_A | OK2USE_RX_B, &lp->lan_saa9730_regs->Ok2Use); return 0; } @@ -587,7 +586,7 @@ static int lan_saa9730_tx(struct net_dev printk("lan_saa9730_tx interrupt\n"); /* Clear interrupt. */ - outl(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus); + writel(DMA_STATUS_MAC_TX_INT, &lp->lan_saa9730_regs->DmaStatus); while (1) { pPacket = lp->TxmBuffer[lp->PendingTxmBufferIndex] @@ -660,8 +659,8 @@ static int lan_saa9730_rx(struct net_dev printk("lan_saa9730_rx interrupt\n"); /* Clear receive interrupts. */ - outl(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT | - DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus); + writel(DMA_STATUS_MAC_RX_INT | DMA_STATUS_RX_INT | + DMA_STATUS_RX_TO_INT, &lp->lan_saa9730_regs->DmaStatus); /* Address next packet */ BufferIndex = lp->NextRcvBufferIndex; @@ -725,8 +724,8 @@ static int lan_saa9730_rx(struct net_dev *pPacket = cpu_to_le32(RXSF_READY << RX_STAT_CTL_OWNER_SHF); /* Make sure A or B is available to hardware as appropriate. */ - outl(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A, - &lp->lan_saa9730_regs->Ok2Use); + writel(BufferIndex ? OK2USE_RX_B : OK2USE_RX_A, + &lp->lan_saa9730_regs->Ok2Use); /* Go to next packet in sequence. */ lp->NextRcvPacketIndex++; @@ -844,8 +843,8 @@ static int lan_saa9730_write(struct lan_ (len << TX_STAT_CTL_LENGTH_SHF)); /* Make sure A or B is available to hardware as appropriate. */ - outl(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A, - &lp->lan_saa9730_regs->Ok2Use); + writel(BufferIndex ? OK2USE_TX_B : OK2USE_TX_A, + &lp->lan_saa9730_regs->Ok2Use); return 0; } @@ -938,15 +937,15 @@ static void lan_saa9730_set_multicast(st if (dev->flags & IFF_PROMISC) { /* accept all packets */ - outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC | - CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC, - &lp->lan_saa9730_regs->CamCtl); + writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_STATION_ACC | + CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC, + &lp->lan_saa9730_regs->CamCtl); } else { if (dev->flags & IFF_ALLMULTI) { /* accept all multicast packets */ - outl(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC | - CAM_CONTROL_BROAD_ACC, - &lp->lan_saa9730_regs->CamCtl); + writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC | + CAM_CONTROL_BROAD_ACC, + &lp->lan_saa9730_regs->CamCtl); } else { /* * Will handle the multicast stuff later. -carstenl Index: linux-2.6.21-rc5/drivers/net/sb1250-mac.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/sb1250-mac.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/sb1250-mac.c 2007-03-27 14:20:38.000000000 +0100 @@ -243,7 +243,7 @@ struct sbmac_softc { * Controller-specific things */ - volatile void __iomem *sbm_base; /* MAC's base address */ + void __iomem *sbm_base; /* MAC's base address */ sbmac_state_t sbm_state; /* current state */ volatile void __iomem *sbm_macenable; /* MAC Enable Register */ Index: linux-2.6.21-rc5/drivers/net/skge.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/skge.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/skge.c 2007-03-27 14:20:38.000000000 +0100 @@ -105,7 +105,8 @@ static const int txqaddr[] = { Q_XA1, Q_ static const int rxqaddr[] = { Q_R1, Q_R2 }; static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; -static const u32 irqmask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F }; +static const u32 napimask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F }; +static const u32 portmask[] = { IS_PORT_1, IS_PORT_2 }; static int skge_get_regs_len(struct net_device *dev) { @@ -671,7 +672,7 @@ static void skge_led(struct skge_port *s struct skge_hw *hw = skge->hw; int port = skge->port; - mutex_lock(&hw->phy_mutex); + spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) { switch (mode) { case LED_MODE_OFF: @@ -742,7 +743,7 @@ static void skge_led(struct skge_port *s PHY_M_LED_MO_RX(MO_LED_ON)); } } - mutex_unlock(&hw->phy_mutex); + spin_unlock_bh(&hw->phy_lock); } /* blink LED's for finding board */ @@ -1316,7 +1317,7 @@ static void xm_phy_init(struct skge_port xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl); /* Poll PHY for status changes */ - schedule_delayed_work(&skge->link_thread, LINK_HZ); + mod_timer(&skge->link_timer, jiffies + LINK_HZ); } static void xm_check_link(struct net_device *dev) @@ -1391,10 +1392,9 @@ static void xm_check_link(struct net_dev * Since internal PHY is wired to a level triggered pin, can't * get an interrupt when carrier is detected. */ -static void xm_link_timer(struct work_struct *work) +static void xm_link_timer(unsigned long arg) { - struct skge_port *skge = - container_of(work, struct skge_port, link_thread.work); + struct skge_port *skge = (struct skge_port *) arg; struct net_device *dev = skge->netdev; struct skge_hw *hw = skge->hw; int port = skge->port; @@ -1414,13 +1414,13 @@ static void xm_link_timer(struct work_st goto nochange; } - mutex_lock(&hw->phy_mutex); + spin_lock(&hw->phy_lock); xm_check_link(dev); - mutex_unlock(&hw->phy_mutex); + spin_unlock(&hw->phy_lock); nochange: if (netif_running(dev)) - schedule_delayed_work(&skge->link_thread, LINK_HZ); + mod_timer(&skge->link_timer, jiffies + LINK_HZ); } static void genesis_mac_init(struct skge_hw *hw, int port) @@ -2323,7 +2323,7 @@ static void skge_phy_reset(struct skge_p netif_stop_queue(skge->netdev); netif_carrier_off(skge->netdev); - mutex_lock(&hw->phy_mutex); + spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) { genesis_reset(hw, port); genesis_mac_init(hw, port); @@ -2331,7 +2331,7 @@ static void skge_phy_reset(struct skge_p yukon_reset(hw, port); yukon_init(hw, port); } - mutex_unlock(&hw->phy_mutex); + spin_unlock_bh(&hw->phy_lock); dev->set_multicast_list(dev); } @@ -2354,12 +2354,12 @@ static int skge_ioctl(struct net_device /* fallthru */ case SIOCGMIIREG: { u16 val = 0; - mutex_lock(&hw->phy_mutex); + spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); else err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val); - mutex_unlock(&hw->phy_mutex); + spin_unlock_bh(&hw->phy_lock); data->val_out = val; break; } @@ -2368,14 +2368,14 @@ static int skge_ioctl(struct net_device if (!capable(CAP_NET_ADMIN)) return -EPERM; - mutex_lock(&hw->phy_mutex); + spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f, data->val_in); else err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f, data->val_in); - mutex_unlock(&hw->phy_mutex); + spin_unlock_bh(&hw->phy_lock); break; } return err; @@ -2481,12 +2481,12 @@ static int skge_up(struct net_device *de goto free_rx_ring; /* Initialize MAC */ - mutex_lock(&hw->phy_mutex); + spin_lock_bh(&hw->phy_lock); if (hw->chip_id == CHIP_ID_GENESIS) genesis_mac_init(hw, port); else yukon_mac_init(hw, port); - mutex_unlock(&hw->phy_mutex); + spin_unlock_bh(&hw->phy_lock); /* Configure RAMbuffers */ chunk = hw->ram_size / ((hw->ports + 1)*2); @@ -2504,6 +2504,11 @@ static int skge_up(struct net_device *de skge_write8(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_START | CSR_IRQ_CL_F); skge_led(skge, LED_MODE_ON); + spin_lock_irq(&hw->hw_lock); + hw->intr_mask |= portmask[port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); + netif_poll_enable(dev); return 0; @@ -2531,7 +2536,14 @@ static int skge_down(struct net_device * netif_stop_queue(dev); if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC) - cancel_delayed_work(&skge->link_thread); + del_timer_sync(&skge->link_timer); + + netif_poll_disable(dev); + + spin_lock_irq(&hw->hw_lock); + hw->intr_mask &= ~portmask[port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + spin_unlock_irq(&hw->hw_lock); skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); if (hw->chip_id == CHIP_ID_GENESIS) @@ -2575,8 +2587,10 @@ static int skge_down(struct net_device * skge_led(skge, LED_MODE_OFF); - netif_poll_disable(dev); + netif_tx_lock_bh(dev); skge_tx_clean(dev); + netif_tx_unlock_bh(dev); + skge_rx_clean(skge); kfree(skge->rx_ring.start); @@ -2721,7 +2735,6 @@ static void skge_tx_clean(struct net_dev struct skge_port *skge = netdev_priv(dev); struct skge_element *e; - netif_tx_lock_bh(dev); for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { struct skge_tx_desc *td = e->desc; skge_tx_free(skge, e, td->control); @@ -2730,7 +2743,6 @@ static void skge_tx_clean(struct net_dev skge->tx_ring.to_clean = e; netif_wake_queue(dev); - netif_tx_unlock_bh(dev); } static void skge_tx_timeout(struct net_device *dev) @@ -3049,7 +3061,7 @@ static int skge_poll(struct net_device * spin_lock_irqsave(&hw->hw_lock, flags); __netif_rx_complete(dev); - hw->intr_mask |= irqmask[skge->port]; + hw->intr_mask |= napimask[skge->port]; skge_write32(hw, B0_IMSK, hw->intr_mask); skge_read32(hw, B0_IMSK); spin_unlock_irqrestore(&hw->hw_lock, flags); @@ -3160,28 +3172,29 @@ static void skge_error_irq(struct skge_h } /* - * Interrupt from PHY are handled in work queue + * Interrupt from PHY are handled in tasklet (softirq) * because accessing phy registers requires spin wait which might * cause excess interrupt latency. */ -static void skge_extirq(struct work_struct *work) +static void skge_extirq(unsigned long arg) { - struct skge_hw *hw = container_of(work, struct skge_hw, phy_work); + struct skge_hw *hw = (struct skge_hw *) arg; int port; - mutex_lock(&hw->phy_mutex); for (port = 0; port < hw->ports; port++) { struct net_device *dev = hw->dev[port]; - struct skge_port *skge = netdev_priv(dev); if (netif_running(dev)) { + struct skge_port *skge = netdev_priv(dev); + + spin_lock(&hw->phy_lock); if (hw->chip_id != CHIP_ID_GENESIS) yukon_phy_intr(skge); else if (hw->phy_type == SK_PHY_BCOM) bcom_phy_intr(skge); + spin_unlock(&hw->phy_lock); } } - mutex_unlock(&hw->phy_mutex); spin_lock_irq(&hw->hw_lock); hw->intr_mask |= IS_EXT_REG; @@ -3206,7 +3219,7 @@ static irqreturn_t skge_intr(int irq, vo status &= hw->intr_mask; if (status & IS_EXT_REG) { hw->intr_mask &= ~IS_EXT_REG; - schedule_work(&hw->phy_work); + tasklet_schedule(&hw->phy_task); } if (status & (IS_XA1_F|IS_R1_F)) { @@ -3282,23 +3295,28 @@ static int skge_set_mac_address(struct n memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - /* disable Rx */ - ctrl = gma_read16(hw, port, GM_GP_CTRL); - gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA); + if (!netif_running(dev)) { + memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN); + memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN); + } else { + /* disable Rx */ + spin_lock_bh(&hw->phy_lock); + ctrl = gma_read16(hw, port, GM_GP_CTRL); + gma_write16(hw, port, GM_GP_CTRL, ctrl & ~GM_GPCR_RX_ENA); - memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN); - memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN); + memcpy_toio(hw->regs + B2_MAC_1 + port*8, dev->dev_addr, ETH_ALEN); + memcpy_toio(hw->regs + B2_MAC_2 + port*8, dev->dev_addr, ETH_ALEN); - if (netif_running(dev)) { if (hw->chip_id == CHIP_ID_GENESIS) xm_outaddr(hw, port, XM_SA, dev->dev_addr); else { gma_set_addr(hw, port, GM_SRC_ADDR_1L, dev->dev_addr); gma_set_addr(hw, port, GM_SRC_ADDR_2L, dev->dev_addr); } - } - gma_write16(hw, port, GM_GP_CTRL, ctrl); + gma_write16(hw, port, GM_GP_CTRL, ctrl); + spin_unlock_bh(&hw->phy_lock); + } return 0; } @@ -3413,10 +3431,9 @@ static int skge_reset(struct skge_hw *hw else hw->ram_size = t8 * 4096; - hw->intr_mask = IS_HW_ERR | IS_PORT_1; - if (hw->ports > 1) - hw->intr_mask |= IS_PORT_2; + hw->intr_mask = IS_HW_ERR; + /* Use PHY IRQ for all but fiber based Genesis board */ if (!(hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)) hw->intr_mask |= IS_EXT_REG; @@ -3484,14 +3501,12 @@ static int skge_reset(struct skge_hw *hw skge_write32(hw, B0_IMSK, hw->intr_mask); - mutex_lock(&hw->phy_mutex); for (i = 0; i < hw->ports; i++) { if (hw->chip_id == CHIP_ID_GENESIS) genesis_reset(hw, i); else yukon_reset(hw, i); } - mutex_unlock(&hw->phy_mutex); return 0; } @@ -3539,6 +3554,7 @@ static struct net_device *skge_devinit(s skge->netdev = dev; skge->hw = hw; skge->msg_enable = netif_msg_init(debug, default_msg); + skge->tx_ring.count = DEFAULT_TX_RING_SIZE; skge->rx_ring.count = DEFAULT_RX_RING_SIZE; @@ -3555,7 +3571,7 @@ static struct net_device *skge_devinit(s skge->port = port; /* Only used for Genesis XMAC */ - INIT_DELAYED_WORK(&skge->link_thread, xm_link_timer); + setup_timer(&skge->link_timer, xm_link_timer, (unsigned long) skge); if (hw->chip_id != CHIP_ID_GENESIS) { dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; @@ -3637,9 +3653,9 @@ static int __devinit skge_probe(struct p } hw->pdev = pdev; - mutex_init(&hw->phy_mutex); - INIT_WORK(&hw->phy_work, skge_extirq); spin_lock_init(&hw->hw_lock); + spin_lock_init(&hw->phy_lock); + tasklet_init(&hw->phy_task, &skge_extirq, (unsigned long) hw); hw->regs = ioremap_nocache(pci_resource_start(pdev, 0), 0x4000); if (!hw->regs) { @@ -3725,6 +3741,8 @@ static void __devexit skge_remove(struct dev0 = hw->dev[0]; unregister_netdev(dev0); + tasklet_disable(&hw->phy_task); + spin_lock_irq(&hw->hw_lock); hw->intr_mask = 0; skge_write32(hw, B0_IMSK, 0); Index: linux-2.6.21-rc5/drivers/net/skge.h =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/skge.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/skge.h 2007-03-27 14:20:38.000000000 +0100 @@ -2424,8 +2424,8 @@ struct skge_hw { u32 ram_size; u32 ram_offset; u16 phy_addr; - struct work_struct phy_work; - struct mutex phy_mutex; + spinlock_t phy_lock; + struct tasklet_struct phy_task; }; enum pause_control { @@ -2457,7 +2457,7 @@ struct skge_port { struct net_device_stats net_stats; - struct delayed_work link_thread; + struct timer_list link_timer; enum pause_control flow_control; enum pause_status flow_status; u8 rx_csum; Index: linux-2.6.21-rc5/drivers/net/ucc_geth.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/ucc_geth.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/ucc_geth.c 2007-03-27 14:20:38.000000000 +0100 @@ -3607,7 +3607,6 @@ static int ucc_geth_start_xmit(struct sk if (bd == ugeth->confBd[txQ]) { if (!netif_queue_stopped(dev)) netif_stop_queue(dev); - return NETDEV_TX_BUSY; } ugeth->txBd[txQ] = bd; @@ -3623,7 +3622,7 @@ static int ucc_geth_start_xmit(struct sk spin_unlock_irq(&ugeth->lock); - return NETDEV_TX_OK; + return 0; } static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit) Index: linux-2.6.21-rc5/drivers/net/wireless/airo.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/wireless/airo.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/wireless/airo.c 2007-03-27 14:20:38.000000000 +0100 @@ -2852,7 +2852,7 @@ static struct net_device *_init_airo_car if (rc) { airo_print_err(dev->name, "register interrupt %d failed, rc %d", irq, rc); - goto err_out_unlink; + goto err_out_nets; } if (!is_pcmcia) { if (!request_region( dev->base_addr, 64, dev->name )) { @@ -2935,6 +2935,8 @@ err_out_res: release_region( dev->base_addr, 64 ); err_out_irq: free_irq(dev->irq, dev); +err_out_nets: + airo_networks_free(ai); err_out_unlink: del_airo_dev(dev); err_out_thr: Index: linux-2.6.21-rc5/drivers/net/wireless/bcm43xx/bcm43xx_radio.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/net/wireless/bcm43xx/bcm43xx_radio.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/net/wireless/bcm43xx/bcm43xx_radio.c 2007-03-27 14:20:38.000000000 +0100 @@ -882,10 +882,10 @@ static void _stack_save(u32 *_stackptr, { u32 *stackptr = &(_stackptr[*stackidx]); - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); + assert((offset & 0xE000) == 0x0000); + assert((id & 0xF8) == 0x00); *stackptr = offset; - *stackptr |= ((u32)id) << 12; + *stackptr |= ((u32)id) << 13; *stackptr |= ((u32)value) << 16; (*stackidx)++; assert(*stackidx < BCM43xx_INTERFSTACK_SIZE); @@ -896,12 +896,12 @@ static u16 _stack_restore(u32 *stackptr, { size_t i; - assert((offset & 0xF000) == 0x0000); - assert((id & 0xF0) == 0x00); + assert((offset & 0xE000) == 0x0000); + assert((id & 0xF8) == 0x00); for (i = 0; i < BCM43xx_INTERFSTACK_SIZE; i++, stackptr++) { - if ((*stackptr & 0x00000FFF) != offset) + if ((*stackptr & 0x00001FFF) != offset) continue; - if (((*stackptr & 0x0000F000) >> 12) != id) + if (((*stackptr & 0x00007000) >> 13) != id) continue; return ((*stackptr & 0xFFFF0000) >> 16); } Index: linux-2.6.21-rc5/drivers/pnp/manager.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/pnp/manager.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/pnp/manager.c 2007-03-27 14:20:38.000000000 +0100 @@ -451,7 +451,7 @@ int pnp_auto_config_dev(struct pnp_dev * return -EINVAL; if(!pnp_can_configure(dev)) { - pnp_info("Device %s does not support resource configuration.", dev->dev.bus_id); + pnp_dbg("Device %s does not support resource configuration.", dev->dev.bus_id); return -ENODEV; } @@ -482,7 +482,7 @@ int pnp_auto_config_dev(struct pnp_dev * int pnp_start_dev(struct pnp_dev *dev) { if (!pnp_can_write(dev)) { - pnp_info("Device %s does not support activation.", dev->dev.bus_id); + pnp_dbg("Device %s does not support activation.", dev->dev.bus_id); return -EINVAL; } @@ -506,7 +506,7 @@ int pnp_start_dev(struct pnp_dev *dev) int pnp_stop_dev(struct pnp_dev *dev) { if (!pnp_can_disable(dev)) { - pnp_info("Device %s does not support disabling.", dev->dev.bus_id); + pnp_dbg("Device %s does not support disabling.", dev->dev.bus_id); return -EINVAL; } if (dev->protocol->disable(dev)<0) { Index: linux-2.6.21-rc5/drivers/s390/cio/qdio.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/s390/cio/qdio.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/s390/cio/qdio.c 2007-03-27 14:20:38.000000000 +0100 @@ -210,9 +210,11 @@ again: goto again; } if (rc < 0) { - QDIO_DBF_TEXT3(1,trace,"sqberr"); - sprintf(dbf_text,"%2x,%2x,%d,%d",tmp_cnt,*cnt,ccq,q_no); - QDIO_DBF_TEXT3(1,trace,dbf_text); + QDIO_DBF_TEXT3(1,trace,"sqberr"); + sprintf(dbf_text,"%2x,%2x",tmp_cnt,*cnt); + QDIO_DBF_TEXT3(1,trace,dbf_text); + sprintf(dbf_text,"%d,%d",ccq,q_no); + QDIO_DBF_TEXT3(1,trace,dbf_text); q->handler(q->cdev,QDIO_STATUS_ACTIVATE_CHECK_CONDITION| QDIO_STATUS_LOOK_FOR_ERROR, 0, 0, 0, -1, -1, q->int_parm); @@ -1250,7 +1252,6 @@ qdio_is_inbound_q_done(struct qdio_q *q) if (!no_used) { QDIO_DBF_TEXT4(0,trace,"inqisdnA"); QDIO_DBF_HEX4(0,trace,&q,sizeof(void*)); - QDIO_DBF_TEXT4(0,trace,dbf_text); return 1; } if (irq->is_qebsm) { @@ -3371,10 +3372,15 @@ qdio_do_qdio_fill_input(struct qdio_q *q unsigned int count, struct qdio_buffer *buffers) { struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; + int tmp = 0; + qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); if (irq->is_qebsm) { - while (count) - set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); + while (count) { + tmp = set_slsb(q, &qidx, SLSB_CU_INPUT_EMPTY, &count); + if (!tmp) + return; + } return; } for (;;) { @@ -3390,11 +3396,15 @@ qdio_do_qdio_fill_output(struct qdio_q * unsigned int count, struct qdio_buffer *buffers) { struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; + int tmp = 0; qidx &= (QDIO_MAX_BUFFERS_PER_Q - 1); if (irq->is_qebsm) { - while (count) - set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); + while (count) { + tmp = set_slsb(q, &qidx, SLSB_CU_OUTPUT_PRIMED, &count); + if (!tmp) + return; + } return; } Index: linux-2.6.21-rc5/drivers/s390/crypto/ap_bus.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/s390/crypto/ap_bus.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/s390/crypto/ap_bus.c 2007-03-27 14:20:38.000000000 +0100 @@ -65,6 +65,8 @@ module_param_named(poll_thread, ap_threa MODULE_PARM_DESC(poll_thread, "Turn on/off poll thread, default is 1 (on)."); static struct device *ap_root_device = NULL; +static DEFINE_SPINLOCK(ap_device_lock); +static LIST_HEAD(ap_device_list); /** * Workqueue & timer for bus rescan. @@ -457,6 +459,9 @@ static int ap_device_probe(struct device int rc; ap_dev->drv = ap_drv; + spin_lock_bh(&ap_device_lock); + list_add(&ap_dev->list, &ap_device_list); + spin_unlock_bh(&ap_device_lock); rc = ap_drv->probe ? ap_drv->probe(ap_dev) : -ENODEV; return rc; } @@ -497,6 +502,9 @@ static int ap_device_remove(struct devic ap_flush_queue(ap_dev); if (ap_drv->remove) ap_drv->remove(ap_dev); + spin_lock_bh(&ap_device_lock); + list_del_init(&ap_dev->list); + spin_unlock_bh(&ap_device_lock); return 0; } @@ -772,6 +780,7 @@ static void ap_scan_bus(struct work_stru spin_lock_init(&ap_dev->lock); INIT_LIST_HEAD(&ap_dev->pendingq); INIT_LIST_HEAD(&ap_dev->requestq); + INIT_LIST_HEAD(&ap_dev->list); if (device_type == 0) ap_probe_device_type(ap_dev); else @@ -1033,14 +1042,13 @@ static void ap_poll_timeout(unsigned lon * polling until bit 2^0 of the control flags is not set. If bit 2^1 * of the control flags has been set arm the poll timer. */ -static int __ap_poll_all(struct device *dev, void *data) +static int __ap_poll_all(struct ap_device *ap_dev, unsigned long *flags) { - struct ap_device *ap_dev = to_ap_dev(dev); int rc; spin_lock(&ap_dev->lock); if (!ap_dev->unregistered) { - rc = ap_poll_queue(to_ap_dev(dev), (unsigned long *) data); + rc = ap_poll_queue(ap_dev, flags); if (rc) ap_dev->unregistered = 1; } else @@ -1054,10 +1062,15 @@ static int __ap_poll_all(struct device * static void ap_poll_all(unsigned long dummy) { unsigned long flags; + struct ap_device *ap_dev; do { flags = 0; - bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all); + spin_lock(&ap_device_lock); + list_for_each_entry(ap_dev, &ap_device_list, list) { + __ap_poll_all(ap_dev, &flags); + } + spin_unlock(&ap_device_lock); } while (flags & 1); if (flags & 2) ap_schedule_poll_timer(); @@ -1075,6 +1088,7 @@ static int ap_poll_thread(void *data) DECLARE_WAITQUEUE(wait, current); unsigned long flags; int requests; + struct ap_device *ap_dev; set_user_nice(current, 19); while (1) { @@ -1092,10 +1106,12 @@ static int ap_poll_thread(void *data) set_current_state(TASK_RUNNING); remove_wait_queue(&ap_poll_wait, &wait); - local_bh_disable(); flags = 0; - bus_for_each_dev(&ap_bus_type, NULL, &flags, __ap_poll_all); - local_bh_enable(); + spin_lock_bh(&ap_device_lock); + list_for_each_entry(ap_dev, &ap_device_list, list) { + __ap_poll_all(ap_dev, &flags); + } + spin_unlock_bh(&ap_device_lock); } set_current_state(TASK_RUNNING); remove_wait_queue(&ap_poll_wait, &wait); Index: linux-2.6.21-rc5/drivers/s390/crypto/ap_bus.h =================================================================== --- linux-2.6.21-rc5.orig/drivers/s390/crypto/ap_bus.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/s390/crypto/ap_bus.h 2007-03-27 14:20:38.000000000 +0100 @@ -106,6 +106,7 @@ struct ap_device { struct device device; struct ap_driver *drv; /* Pointer to AP device driver. */ spinlock_t lock; /* Per device lock. */ + struct list_head list; /* private list of all AP devices. */ ap_qid_t qid; /* AP queue id. */ int queue_depth; /* AP queue depth.*/ Index: linux-2.6.21-rc5/drivers/s390/crypto/zcrypt_api.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/s390/crypto/zcrypt_api.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/s390/crypto/zcrypt_api.c 2007-03-27 14:20:38.000000000 +0100 @@ -298,14 +298,14 @@ static long zcrypt_rsa_modexpo(struct ic get_device(&zdev->ap_dev->device); zdev->request_count++; __zcrypt_decrease_preference(zdev); - spin_unlock_bh(&zcrypt_device_lock); if (try_module_get(zdev->ap_dev->drv->driver.owner)) { + spin_unlock_bh(&zcrypt_device_lock); rc = zdev->ops->rsa_modexpo(zdev, mex); + spin_lock_bh(&zcrypt_device_lock); module_put(zdev->ap_dev->drv->driver.owner); } else rc = -EAGAIN; - spin_lock_bh(&zcrypt_device_lock); zdev->request_count--; __zcrypt_increase_preference(zdev); put_device(&zdev->ap_dev->device); @@ -373,14 +373,14 @@ static long zcrypt_rsa_crt(struct ica_rs get_device(&zdev->ap_dev->device); zdev->request_count++; __zcrypt_decrease_preference(zdev); - spin_unlock_bh(&zcrypt_device_lock); if (try_module_get(zdev->ap_dev->drv->driver.owner)) { + spin_unlock_bh(&zcrypt_device_lock); rc = zdev->ops->rsa_modexpo_crt(zdev, crt); + spin_lock_bh(&zcrypt_device_lock); module_put(zdev->ap_dev->drv->driver.owner); } else rc = -EAGAIN; - spin_lock_bh(&zcrypt_device_lock); zdev->request_count--; __zcrypt_increase_preference(zdev); put_device(&zdev->ap_dev->device); @@ -408,14 +408,14 @@ static long zcrypt_send_cprb(struct ica_ get_device(&zdev->ap_dev->device); zdev->request_count++; __zcrypt_decrease_preference(zdev); - spin_unlock_bh(&zcrypt_device_lock); if (try_module_get(zdev->ap_dev->drv->driver.owner)) { + spin_unlock_bh(&zcrypt_device_lock); rc = zdev->ops->send_cprb(zdev, xcRB); + spin_lock_bh(&zcrypt_device_lock); module_put(zdev->ap_dev->drv->driver.owner); } else rc = -EAGAIN; - spin_lock_bh(&zcrypt_device_lock); zdev->request_count--; __zcrypt_increase_preference(zdev); put_device(&zdev->ap_dev->device); Index: linux-2.6.21-rc5/drivers/serial/8250_pnp.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/serial/8250_pnp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/serial/8250_pnp.c 2007-03-27 14:20:38.000000000 +0100 @@ -340,6 +340,9 @@ static const struct pnp_device_id pnp_de { "FUJ02B8", 0 }, { "FUJ02B9", 0 }, { "FUJ02BC", 0 }, + /* Fujitsu Wacom Tablet PC devices */ + { "FUJ02E5", 0 }, + { "FUJ02E6", 0 }, /* Rockwell's (PORALiNK) 33600 INT PNP */ { "WCI0003", 0 }, /* Unkown PnP modems */ Index: linux-2.6.21-rc5/drivers/serial/sh-sci.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/serial/sh-sci.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/serial/sh-sci.c 2007-03-27 14:20:38.000000000 +0100 @@ -17,6 +17,9 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ +#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif #undef DEBUG @@ -49,11 +52,6 @@ #endif #include - -#if defined(CONFIG_SERIAL_SH_SCI_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) -#define SUPPORT_SYSRQ -#endif - #include "sh-sci.h" struct sci_port { @@ -645,6 +643,9 @@ static inline int sci_handle_breaks(stru struct tty_struct *tty = port->info->tty; struct sci_port *s = &sci_ports[port->line]; + if (uart_handle_break(port)) + return 0; + if (!s->break_flag && status & SCxSR_BRK(port)) { #if defined(CONFIG_CPU_SH3) /* Debounce break */ Index: linux-2.6.21-rc5/drivers/spi/at25.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/spi/at25.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/spi/at25.c 2007-03-27 14:20:38.000000000 +0100 @@ -291,7 +291,7 @@ static int at25_probe(struct spi_device */ sr = spi_w8r8(spi, AT25_RDSR); if (sr < 0 || sr & AT25_SR_nRDY) { - dev_dbg(&at25->spi->dev, "rdsr --> %d (%02x)\n", sr, sr); + dev_dbg(&spi->dev, "rdsr --> %d (%02x)\n", sr, sr); err = -ENXIO; goto fail; } Index: linux-2.6.21-rc5/drivers/spi/atmel_spi.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/spi/atmel_spi.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/spi/atmel_spi.c 2007-03-27 14:20:38.000000000 +0100 @@ -425,7 +425,7 @@ static int atmel_spi_setup(struct spi_de if (ret) return ret; spi->controller_state = (void *)npcs_pin; - gpio_direction_output(npcs_pin); + gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); } dev_dbg(&spi->dev, Index: linux-2.6.21-rc5/drivers/spi/spi_bitbang.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/spi/spi_bitbang.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/spi/spi_bitbang.c 2007-03-27 14:20:38.000000000 +0100 @@ -302,10 +302,6 @@ static void bitbang_work(struct work_str setup_transfer = NULL; list_for_each_entry (t, &m->transfers, transfer_list) { - if (bitbang->shutdown) { - status = -ESHUTDOWN; - break; - } /* override or restore speed and wordsize */ if (t->speed_hz || t->bits_per_word) { @@ -410,8 +406,6 @@ int spi_bitbang_transfer(struct spi_devi m->status = -EINPROGRESS; bitbang = spi_master_get_devdata(spi->master); - if (bitbang->shutdown) - return -ESHUTDOWN; spin_lock_irqsave(&bitbang->lock, flags); if (!spi->max_speed_hz) @@ -507,28 +501,12 @@ EXPORT_SYMBOL_GPL(spi_bitbang_start); */ int spi_bitbang_stop(struct spi_bitbang *bitbang) { - unsigned limit = 500; - - spin_lock_irq(&bitbang->lock); - bitbang->shutdown = 0; - while (!list_empty(&bitbang->queue) && limit--) { - spin_unlock_irq(&bitbang->lock); + spi_unregister_master(bitbang->master); - dev_dbg(bitbang->master->cdev.dev, "wait for queue\n"); - msleep(10); - - spin_lock_irq(&bitbang->lock); - } - spin_unlock_irq(&bitbang->lock); - if (!list_empty(&bitbang->queue)) { - dev_err(bitbang->master->cdev.dev, "queue didn't empty\n"); - return -EBUSY; - } + WARN_ON(!list_empty(&bitbang->queue)); destroy_workqueue(bitbang->workqueue); - spi_unregister_master(bitbang->master); - return 0; } EXPORT_SYMBOL_GPL(spi_bitbang_stop); Index: linux-2.6.21-rc5/drivers/spi/spi_s3c24xx.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/spi/spi_s3c24xx.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/spi/spi_s3c24xx.c 2007-03-27 14:20:38.000000000 +0100 @@ -41,7 +41,7 @@ struct s3c24xx_spi { int len; int count; - int (*set_cs)(struct s3c2410_spi_info *spi, + void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); /* data buffers */ Index: linux-2.6.21-rc5/drivers/usb/class/usblp.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/class/usblp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/class/usblp.c 2007-03-27 14:20:38.000000000 +0100 @@ -202,6 +202,7 @@ struct quirk_printer_struct { #define USBLP_QUIRK_BIDIR 0x1 /* reports bidir but requires unidirectional mode (no INs/reads) */ #define USBLP_QUIRK_USB_INIT 0x2 /* needs vendor USB init string */ +#define USBLP_QUIRK_BAD_CLASS 0x4 /* descriptor uses vendor-specific Class or SubClass */ static const struct quirk_printer_struct quirk_printers[] = { { 0x03f0, 0x0004, USBLP_QUIRK_BIDIR }, /* HP DeskJet 895C */ @@ -218,6 +219,7 @@ static const struct quirk_printer_struct { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */ { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut */ + { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ { 0, 0 } }; @@ -1048,7 +1050,8 @@ static int usblp_select_alts(struct usbl ifd = &if_alt->altsetting[i]; if (ifd->desc.bInterfaceClass != 7 || ifd->desc.bInterfaceSubClass != 1) - continue; + if (!(usblp->quirks & USBLP_QUIRK_BAD_CLASS)) + continue; if (ifd->desc.bInterfaceProtocol < USBLP_FIRST_PROTOCOL || ifd->desc.bInterfaceProtocol > USBLP_LAST_PROTOCOL) @@ -1232,6 +1235,7 @@ static struct usb_device_id usblp_ids [] { USB_INTERFACE_INFO(7, 1, 1) }, { USB_INTERFACE_INFO(7, 1, 2) }, { USB_INTERFACE_INFO(7, 1, 3) }, + { USB_DEVICE(0x04b8, 0x0202) }, /* Seiko Epson Receipt Printer M129C */ { } /* Terminating entry */ }; Index: linux-2.6.21-rc5/drivers/usb/misc/berry_charge.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/misc/berry_charge.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/misc/berry_charge.c 2007-03-27 14:20:38.000000000 +0100 @@ -69,7 +69,7 @@ static int magic_charge(struct usb_devic return retval; } - dbg(&udev->dev, "Sending first magic command\n"); + dbg(&udev->dev, "Sending second magic command\n"); retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100); if (retval != 0) { Index: linux-2.6.21-rc5/drivers/usb/net/dm9601.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/net/dm9601.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/net/dm9601.c 2007-03-27 14:20:38.000000000 +0100 @@ -578,6 +578,14 @@ static const struct usb_device_id produc USB_DEVICE(0x0a46, 0x9601), /* Davicom USB-100 */ .driver_info = (unsigned long)&dm9601_info, }, + { + USB_DEVICE(0x0a46, 0x6688), /* ZT6688 USB NIC */ + .driver_info = (unsigned long)&dm9601_info, + }, + { + USB_DEVICE(0x0a46, 0x0268), /* ShanTou ST268 USB NIC */ + .driver_info = (unsigned long)&dm9601_info, + }, {}, // END }; Index: linux-2.6.21-rc5/drivers/usb/serial/airprime.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/serial/airprime.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/serial/airprime.c 2007-03-27 14:20:38.000000000 +0100 @@ -18,10 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ - { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ - { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */ - { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */ - { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ { }, Index: linux-2.6.21-rc5/drivers/usb/serial/mos7720.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/serial/mos7720.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/serial/mos7720.c 2007-03-27 14:20:38.000000000 +0100 @@ -1628,6 +1628,7 @@ static struct usb_serial_driver moschip7 .chars_in_buffer = mos7720_chars_in_buffer, .break_ctl = mos7720_break, .read_bulk_callback = mos7720_bulk_in_callback, + .read_int_callback = mos7720_interrupt_callback, }; static int __init moschip7720_init(void) Index: linux-2.6.21-rc5/drivers/usb/serial/option.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/serial/option.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/serial/option.c 2007-03-27 14:20:38.000000000 +0100 @@ -109,7 +109,6 @@ static int option_send_setup(struct usb #define HUAWEI_PRODUCT_E220 0x1003 #define NOVATELWIRELESS_VENDOR_ID 0x1410 -#define NOVATELWIRELESS_PRODUCT_U740 0x1400 #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ID 0x6501 @@ -152,7 +151,19 @@ static struct usb_device_id option_ids[] { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, - { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1130) }, /* Novatel Merlin S720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1400) }, /* Novatel U730 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1410) }, /* Novatel U740 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1420) }, /* Novatel EU870 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1430) }, /* Novatel XU870 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2100) }, /* Novatel EV620 CDMA/EV-DO */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, { } /* Terminating entry */ }; Index: linux-2.6.21-rc5/drivers/usb/serial/usb-serial.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/serial/usb-serial.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/serial/usb-serial.c 2007-03-27 14:20:38.000000000 +0100 @@ -138,6 +138,11 @@ static void destroy_serial(struct kref * dbg("%s - %s", __FUNCTION__, serial->type->description); + serial->type->shutdown(serial); + + /* return the minor range that this device had */ + return_serial(serial); + for (i = 0; i < serial->num_ports; ++i) serial->port[i]->open_count = 0; @@ -148,12 +153,6 @@ static void destroy_serial(struct kref * serial->port[i] = NULL; } - if (serial->type->shutdown) - serial->type->shutdown(serial); - - /* return the minor range that this device had */ - return_serial(serial); - /* If this is a "fake" port, we have to clean it up here, as it will * not get cleaned up in port_release() as it was never registered with * the driver core */ Index: linux-2.6.21-rc5/drivers/usb/storage/unusual_devs.h =================================================================== --- linux-2.6.21-rc5.orig/drivers/usb/storage/unusual_devs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/usb/storage/unusual_devs.h 2007-03-27 14:20:38.000000000 +0100 @@ -1411,6 +1411,16 @@ UNUSUAL_DEV( 0x22b8, 0x3010, 0x0001, 0x US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), +/* + * Patch by Pete Zaitcev + * Report by Mark Patton. Red Hat bz#208928. + */ +UNUSUAL_DEV( 0x22b8, 0x4810, 0x0001, 0x0001, + "Motorola", + "RAZR V3i", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY), + /* Reported by Radovan Garabik */ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, "MPIO", Index: linux-2.6.21-rc5/drivers/video/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/drivers/video/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/video/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -1320,7 +1320,7 @@ config FB_AU1100 config FB_AU1200 bool "Au1200 LCD Driver" - depends on FB && MIPS && SOC_AU1200 + depends on (FB = y) && MIPS && SOC_AU1200 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1470,7 +1470,7 @@ config FB_G364 config FB_68328 bool "Motorola 68328 native frame buffer support" - depends on FB && (M68328 || M68EZ328 || M68VZ328) + depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -1616,7 +1616,7 @@ config FB_IBM_GXT4500 config FB_PS3 bool "PS3 GPU framebuffer driver" - depends on FB && PS3_PS3AV + depends on (FB = y) && PS3_PS3AV select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT Index: linux-2.6.21-rc5/drivers/video/riva/fbdev.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/video/riva/fbdev.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/video/riva/fbdev.c 2007-03-27 14:20:38.000000000 +0100 @@ -285,8 +285,6 @@ static const struct riva_regs reg_templa #define MAX_LEVEL 0x534 #define LEVEL_STEP ((MAX_LEVEL - MIN_LEVEL) / FB_BACKLIGHT_MAX) -static struct backlight_properties riva_bl_data; - static int riva_bl_get_level_brightness(struct riva_par *par, int level) { @@ -372,7 +370,7 @@ static void riva_bl_init(struct riva_par FB_BACKLIGHT_MAX); bd->props.max_brightness = FB_BACKLIGHT_LEVELS - 1; - bd->props.brightness = riva_bl_data.max_brightness; + bd->props.brightness = bd->props.max_brightness; bd->props.power = FB_BLANK_UNBLANK; backlight_update_status(bd); Index: linux-2.6.21-rc5/drivers/video/s3fb.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/video/s3fb.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/video/s3fb.c 2007-03-27 14:20:38.000000000 +0100 @@ -1000,11 +1000,12 @@ err_enable_device: static void __devexit s3_pci_remove(struct pci_dev *dev) { struct fb_info *info = pci_get_drvdata(dev); - struct s3fb_info *par = info->par; if (info) { #ifdef CONFIG_MTRR + struct s3fb_info *par = info->par; + if (par->mtrr_reg >= 0) { mtrr_del(par->mtrr_reg, 0, 0); par->mtrr_reg = -1; Index: linux-2.6.21-rc5/drivers/video/savage/savagefb_driver.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/video/savage/savagefb_driver.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/video/savage/savagefb_driver.c 2007-03-27 14:20:38.000000000 +0100 @@ -384,6 +384,19 @@ SavageSetup2DEngine(struct savagefb_par BCI_SEND(0); BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2); BCI_SEND(GlobalBitmapDescriptor); + + /* + * I don't know why, sending this twice fixes the intial black screen, + * prevents X from crashing at least in Toshiba laptops with SavageIX. + * --Tony + */ + par->bci_ptr = 0; + par->SavageWaitFifo(par, 4); + + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD1); + BCI_SEND(0); + BCI_SEND(BCI_CMD_SETREG | (1 << 16) | BCI_GBD2); + BCI_SEND(GlobalBitmapDescriptor); } static void savagefb_set_clip(struct fb_info *info) @@ -496,7 +509,7 @@ static int common_calc_clock(long freq, #ifdef SAVAGEFB_DEBUG /* This function is used to debug, it prints out the contents of s3 regs */ -static void SavagePrintRegs(void) +static void SavagePrintRegs(struct savagefb_par *par) { unsigned char i; int vgaCRIndex = 0x3d4; @@ -1525,7 +1538,7 @@ static int savagefb_set_par(struct fb_in savagefb_set_fix(info); savagefb_set_clip(info); - SavagePrintRegs(); + SavagePrintRegs(par); return 0; } @@ -2155,7 +2168,6 @@ static int __devinit savagefb_probe(stru int video_len; DBG("savagefb_probe"); - SavagePrintRegs(); info = framebuffer_alloc(sizeof(struct savagefb_par), &dev->dev); if (!info) Index: linux-2.6.21-rc5/drivers/video/sstfb.c =================================================================== --- linux-2.6.21-rc5.orig/drivers/video/sstfb.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/drivers/video/sstfb.c 2007-03-27 14:20:38.000000000 +0100 @@ -257,6 +257,7 @@ static void __sst_dac_write(u8 __iomem * r_dprintk("sst_dac_write(%#x, %#x)\n", reg, val); reg &= 0x07; __sst_write(vbase, DAC_DATA,(((u32)reg << 8)) | (u32)val); + __sst_wait_idle(vbase); } /* indexed access to ti/att dacs */ Index: linux-2.6.21-rc5/fs/binfmt_elf.c =================================================================== --- linux-2.6.21-rc5.orig/fs/binfmt_elf.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/binfmt_elf.c 2007-03-27 14:20:38.000000000 +0100 @@ -507,7 +507,7 @@ out: #define INTERPRETER_ELF 2 #ifndef STACK_RND_MASK -#define STACK_RND_MASK 0x7ff /* with 4K pages 8MB of VA */ +#define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ #endif static unsigned long randomize_stack_top(unsigned long stack_top) Index: linux-2.6.21-rc5/fs/binfmt_elf_fdpic.c =================================================================== --- linux-2.6.21-rc5.orig/fs/binfmt_elf_fdpic.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/binfmt_elf_fdpic.c 2007-03-27 14:20:38.000000000 +0100 @@ -179,6 +179,8 @@ static int load_elf_fdpic_binary(struct int executable_stack; int retval, i; + kdebug("____ LOAD %d ____", current->pid); + memset(&exec_params, 0, sizeof(exec_params)); memset(&interp_params, 0, sizeof(interp_params)); @@ -941,8 +943,11 @@ static int elf_fdpic_map_file_constdisp_ if (mm) { if (phdr->p_flags & PF_X) { - mm->start_code = seg->addr; - mm->end_code = seg->addr + phdr->p_memsz; + if (!mm->start_code) { + mm->start_code = seg->addr; + mm->end_code = seg->addr + + phdr->p_memsz; + } } else if (!mm->start_data) { mm->start_data = seg->addr; #ifndef CONFIG_MMU @@ -1123,8 +1128,10 @@ static int elf_fdpic_map_file_by_direct_ if (mm) { if (phdr->p_flags & PF_X) { - mm->start_code = maddr; - mm->end_code = maddr + phdr->p_memsz; + if (!mm->start_code) { + mm->start_code = maddr; + mm->end_code = maddr + phdr->p_memsz; + } } else if (!mm->start_data) { mm->start_data = maddr; mm->end_data = maddr + phdr->p_memsz; Index: linux-2.6.21-rc5/fs/cifs/CHANGES =================================================================== --- linux-2.6.21-rc5.orig/fs/cifs/CHANGES 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/cifs/CHANGES 2007-03-27 14:20:38.000000000 +0100 @@ -4,6 +4,12 @@ Fix mtime bouncing around from local ide Fix hang (in i_size_read) when simultaneous size update of same remote file on smp system corrupts sequence number. Do not reread unnecessarily partial page (which we are about to overwrite anyway) when writing out file opened rw. +When DOS attribute of file on non-Unix server's file changes on the server side +from read-only back to read-write, reflect this change in default file mode +(we had been leaving a file's mode read-only until the inode were reloaded). +Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute +when archive dos attribute not set and we are changing mode back to writeable +on server which does not support the Unix Extensions). Version 1.47 ------------ Index: linux-2.6.21-rc5/fs/cifs/cifspdu.h =================================================================== --- linux-2.6.21-rc5.orig/fs/cifs/cifspdu.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/cifs/cifspdu.h 2007-03-27 14:20:38.000000000 +0100 @@ -1887,7 +1887,13 @@ typedef struct { calls including posix open and posix unlink */ #ifdef CONFIG_CIFS_POSIX -#define CIFS_UNIX_CAP_MASK 0x0000003b +/* Can not set pathnames cap yet until we send new posix create SMB since + otherwise server can treat such handles opened with older ntcreatex + (by a new client which knows how to send posix path ops) + as non-posix handles (can affect write behavior with byte range locks. + We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ +/* #define CIFS_UNIX_CAP_MASK 0x0000003b */ +#define CIFS_UNIX_CAP_MASK 0x0000001b #else #define CIFS_UNIX_CAP_MASK 0x00000013 #endif /* CONFIG_CIFS_POSIX */ Index: linux-2.6.21-rc5/fs/cifs/inode.c =================================================================== --- linux-2.6.21-rc5.orig/fs/cifs/inode.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/cifs/inode.c 2007-03-27 14:20:38.000000000 +0100 @@ -494,6 +494,12 @@ int cifs_get_inode_info(struct inode **p mode e.g. 555 */ if (cifsInfo->cifsAttrs & ATTR_READONLY) inode->i_mode &= ~(S_IWUGO); + else if ((inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been */ + /* changed on server -- set any w bits */ + /* allowed by mnt_file_mode */ + inode->i_mode |= (S_IWUGO & + cifs_sb->mnt_file_mode); /* BB add code here - validate if device or weird share or device type? */ } @@ -1190,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry struct cifsFileInfo *open_file = NULL; FILE_BASIC_INFO time_buf; int set_time = FALSE; + int set_dosattr = FALSE; __u64 mode = 0xFFFFFFFFFFFFFFFFULL; __u64 uid = 0xFFFFFFFFFFFFFFFFULL; __u64 gid = 0xFFFFFFFFFFFFFFFFULL; @@ -1326,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry else if (attrs->ia_valid & ATTR_MODE) { rc = 0; if ((mode & S_IWUGO) == 0) /* not writeable */ { - if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) + if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { + set_dosattr = TRUE; time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs | ATTR_READONLY); + } } else if ((mode & S_IWUGO) == S_IWUGO) { - if (cifsInode->cifsAttrs & ATTR_READONLY) + if (cifsInode->cifsAttrs & ATTR_READONLY) { + set_dosattr = TRUE; time_buf.Attributes = cpu_to_le32(cifsInode->cifsAttrs & (~ATTR_READONLY)); + /* Windows ignores set to zero */ + if(time_buf.Attributes == 0) + time_buf.Attributes |= + cpu_to_le32(ATTR_NORMAL); + } } /* BB to be implemented - via Windows security descriptors or streams */ @@ -1372,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry } else time_buf.ChangeTime = 0; - if (set_time || time_buf.Attributes) { + if (set_time || set_dosattr) { time_buf.CreationTime = 0; /* do not change */ /* In the future we should experiment - try setting timestamps via Handle (SetFileInfo) instead of by path */ Index: linux-2.6.21-rc5/fs/cifs/readdir.c =================================================================== --- linux-2.6.21-rc5.orig/fs/cifs/readdir.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/cifs/readdir.c 2007-03-27 14:20:38.000000000 +0100 @@ -219,6 +219,10 @@ static void fill_in_inode(struct inode * tmp_inode->i_mode |= S_IFREG; if (attr & ATTR_READONLY) tmp_inode->i_mode &= ~(S_IWUGO); + else if ((tmp_inode->i_mode & S_IWUGO) == 0) + /* the ATTR_READONLY flag may have been changed on */ + /* server -- set any w bits allowed by mnt_file_mode */ + tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); } /* could add code here - to validate if device or weird share type? */ /* can not fill in nlink here as in qpathinfo version and Unx search */ Index: linux-2.6.21-rc5/fs/ecryptfs/dentry.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ecryptfs/dentry.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ecryptfs/dentry.c 2007-03-27 14:20:38.000000000 +0100 @@ -78,18 +78,13 @@ struct kmem_cache *ecryptfs_dentry_info_ */ static void ecryptfs_d_release(struct dentry *dentry) { - struct dentry *lower_dentry; - - lower_dentry = ecryptfs_dentry_to_lower(dentry); - if (ecryptfs_dentry_to_private(dentry)) + if (ecryptfs_dentry_to_private(dentry)) { + if (ecryptfs_dentry_to_lower(dentry)) { + mntput(ecryptfs_dentry_to_lower_mnt(dentry)); + dput(ecryptfs_dentry_to_lower(dentry)); + } kmem_cache_free(ecryptfs_dentry_info_cache, ecryptfs_dentry_to_private(dentry)); - if (lower_dentry) { - struct vfsmount *lower_mnt = - ecryptfs_dentry_to_lower_mnt(dentry); - - mntput(lower_mnt); - dput(lower_dentry); } return; } Index: linux-2.6.21-rc5/fs/ext3/xattr.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ext3/xattr.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ext3/xattr.c 2007-03-27 14:20:38.000000000 +0100 @@ -495,7 +495,8 @@ ext3_xattr_release_block(handle_t *handl BHDR(bh)->h_refcount = cpu_to_le32( le32_to_cpu(BHDR(bh)->h_refcount) - 1); error = ext3_journal_dirty_metadata(handle, bh); - handle->h_sync = 1; + if (IS_SYNC(inode)) + handle->h_sync = 1; DQUOT_FREE_BLOCK(inode, 1); ea_bdebug(bh, "refcount now=%d; releasing", le32_to_cpu(BHDR(bh)->h_refcount)); Index: linux-2.6.21-rc5/fs/nfs/inode.c =================================================================== --- linux-2.6.21-rc5.orig/fs/nfs/inode.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/nfs/inode.c 2007-03-27 14:20:38.000000000 +0100 @@ -429,7 +429,8 @@ int nfs_getattr(struct vfsmount *mnt, st int err; /* Flush out writes to the server in order to update c/mtime */ - nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); + if (S_ISREG(inode->i_mode)) + nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); /* * We may force a getattr if the user cares about atime. Index: linux-2.6.21-rc5/fs/nfs/super.c =================================================================== --- linux-2.6.21-rc5.orig/fs/nfs/super.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/nfs/super.c 2007-03-27 14:20:38.000000000 +0100 @@ -151,10 +151,10 @@ int __init register_nfs_fs(void) if (ret < 0) goto error_0; -#ifdef CONFIG_NFS_V4 ret = nfs_register_sysctl(); if (ret < 0) goto error_1; +#ifdef CONFIG_NFS_V4 ret = register_filesystem(&nfs4_fs_type); if (ret < 0) goto error_2; @@ -165,9 +165,9 @@ int __init register_nfs_fs(void) #ifdef CONFIG_NFS_V4 error_2: nfs_unregister_sysctl(); +#endif error_1: unregister_filesystem(&nfs_fs_type); -#endif error_0: return ret; } Index: linux-2.6.21-rc5/fs/nfs/sysctl.c =================================================================== --- linux-2.6.21-rc5.orig/fs/nfs/sysctl.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/nfs/sysctl.c 2007-03-27 14:20:38.000000000 +0100 @@ -50,6 +50,14 @@ static ctl_table nfs_cb_sysctls[] = { .proc_handler = &proc_dointvec_jiffies, .strategy = &sysctl_jiffies, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "nfs_congestion_kb", + .data = &nfs_congestion_kb, + .maxlen = sizeof(nfs_congestion_kb), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, { .ctl_name = 0 } }; Index: linux-2.6.21-rc5/fs/nfs/write.c =================================================================== --- linux-2.6.21-rc5.orig/fs/nfs/write.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/nfs/write.c 2007-03-27 14:20:38.000000000 +0100 @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -38,7 +39,6 @@ static struct nfs_page * nfs_update_requ struct page *, unsigned int, unsigned int); static void nfs_mark_request_dirty(struct nfs_page *req); -static int nfs_wait_on_write_congestion(struct address_space *, int); static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); static const struct rpc_call_ops nfs_write_partial_ops; static const struct rpc_call_ops nfs_write_full_ops; @@ -48,8 +48,6 @@ static struct kmem_cache *nfs_wdata_cach static mempool_t *nfs_wdata_mempool; static mempool_t *nfs_commit_mempool; -static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); - struct nfs_write_data *nfs_commit_alloc(void) { struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); @@ -211,6 +209,40 @@ static int wb_priority(struct writeback_ } /* + * NFS congestion control + */ + +int nfs_congestion_kb; + +#define NFS_CONGESTION_ON_THRESH (nfs_congestion_kb >> (PAGE_SHIFT-10)) +#define NFS_CONGESTION_OFF_THRESH \ + (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) + +static void nfs_set_page_writeback(struct page *page) +{ + if (!test_set_page_writeback(page)) { + struct inode *inode = page->mapping->host; + struct nfs_server *nfss = NFS_SERVER(inode); + + if (atomic_inc_return(&nfss->writeback) > + NFS_CONGESTION_ON_THRESH) + set_bdi_congested(&nfss->backing_dev_info, WRITE); + } +} + +static void nfs_end_page_writeback(struct page *page) +{ + struct inode *inode = page->mapping->host; + struct nfs_server *nfss = NFS_SERVER(inode); + + end_page_writeback(page); + if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) { + clear_bdi_congested(&nfss->backing_dev_info, WRITE); + congestion_end(WRITE); + } +} + +/* * Find an associated nfs write request, and prepare to flush it out * Returns 1 if there was no write request, or if the request was * already tagged by nfs_set_page_dirty.Returns 0 if the request @@ -247,7 +279,7 @@ static int nfs_page_mark_flush(struct pa spin_unlock(req_lock); if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { nfs_mark_request_dirty(req); - set_page_writeback(page); + nfs_set_page_writeback(page); } ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); nfs_unlock_request(req); @@ -302,13 +334,8 @@ int nfs_writepage(struct page *page, str return err; } -/* - * Note: causes nfs_update_request() to block on the assumption - * that the writeback is generated due to memory pressure. - */ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) { - struct backing_dev_info *bdi = mapping->backing_dev_info; struct inode *inode = mapping->host; int err; @@ -317,20 +344,12 @@ int nfs_writepages(struct address_space err = generic_writepages(mapping, wbc); if (err) return err; - while (test_and_set_bit(BDI_write_congested, &bdi->state) != 0) { - if (wbc->nonblocking) - return 0; - nfs_wait_on_write_congestion(mapping, 0); - } err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); if (err < 0) goto out; nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); err = 0; out: - clear_bit(BDI_write_congested, &bdi->state); - wake_up_all(&nfs_write_congestion); - congestion_end(WRITE); return err; } @@ -360,7 +379,7 @@ static int nfs_inode_add_request(struct } /* - * Insert a write request into an inode + * Remove a write request from an inode */ static void nfs_inode_remove_request(struct nfs_page *req) { @@ -531,10 +550,10 @@ static inline int nfs_scan_commit(struct } #endif -static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) +static int nfs_wait_on_write_congestion(struct address_space *mapping) { + struct inode *inode = mapping->host; struct backing_dev_info *bdi = mapping->backing_dev_info; - DEFINE_WAIT(wait); int ret = 0; might_sleep(); @@ -542,31 +561,23 @@ static int nfs_wait_on_write_congestion( if (!bdi_write_congested(bdi)) return 0; - nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT); + nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT); - if (intr) { - struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); + do { + struct rpc_clnt *clnt = NFS_CLIENT(inode); sigset_t oldset; rpc_clnt_sigmask(clnt, &oldset); - prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE); - if (bdi_write_congested(bdi)) { - if (signalled()) - ret = -ERESTARTSYS; - else - schedule(); - } + ret = congestion_wait_interruptible(WRITE, HZ/10); rpc_clnt_sigunmask(clnt, &oldset); - } else { - prepare_to_wait(&nfs_write_congestion, &wait, TASK_UNINTERRUPTIBLE); - if (bdi_write_congested(bdi)) - schedule(); - } - finish_wait(&nfs_write_congestion, &wait); + if (ret == -ERESTARTSYS) + break; + ret = 0; + } while (bdi_write_congested(bdi)); + return ret; } - /* * Try to update any existing write request, or create one if there is none. * In order to match, the request's credentials must match those of @@ -577,14 +588,15 @@ static int nfs_wait_on_write_congestion( static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, struct page *page, unsigned int offset, unsigned int bytes) { - struct inode *inode = page->mapping->host; + struct address_space *mapping = page->mapping; + struct inode *inode = mapping->host; struct nfs_inode *nfsi = NFS_I(inode); struct nfs_page *req, *new = NULL; unsigned long rqend, end; end = offset + bytes; - if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) + if (nfs_wait_on_write_congestion(mapping)) return ERR_PTR(-ERESTARTSYS); for (;;) { /* Loop over all inode entries and see if we find @@ -727,7 +739,7 @@ int nfs_updatepage(struct file *file, st static void nfs_writepage_release(struct nfs_page *req) { - end_page_writeback(req->wb_page); + nfs_end_page_writeback(req->wb_page); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (!PageError(req->wb_page)) { @@ -1042,12 +1054,12 @@ static void nfs_writeback_done_full(stru if (task->tk_status < 0) { nfs_set_pageerror(page); req->wb_context->error = task->tk_status; - end_page_writeback(page); + nfs_end_page_writeback(page); nfs_inode_remove_request(req); dprintk(", error = %d\n", task->tk_status); goto next; } - end_page_writeback(page); + nfs_end_page_writeback(page); #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { @@ -1514,6 +1526,26 @@ int __init nfs_init_writepagecache(void) if (nfs_commit_mempool == NULL) return -ENOMEM; + /* + * NFS congestion size, scale with available memory. + * + * 64MB: 8192k + * 128MB: 11585k + * 256MB: 16384k + * 512MB: 23170k + * 1GB: 32768k + * 2GB: 46340k + * 4GB: 65536k + * 8GB: 92681k + * 16GB: 131072k + * + * This allows larger machines to have larger/more transfers. + * Limit the default to 256M + */ + nfs_congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10); + if (nfs_congestion_kb > 256*1024) + nfs_congestion_kb = 256*1024; + return 0; } Index: linux-2.6.21-rc5/fs/partitions/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/fs/partitions/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/partitions/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -235,5 +235,4 @@ config EFI_PARTITION select CRC32 help Say Y here if you would like to use hard disks under Linux which - were partitioned using EFI GPT. Presently only useful on the - IA-64 platform. + were partitioned using EFI GPT. Index: linux-2.6.21-rc5/fs/partitions/check.c =================================================================== --- linux-2.6.21-rc5.orig/fs/partitions/check.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/partitions/check.c 2007-03-27 14:20:38.000000000 +0100 @@ -541,7 +541,7 @@ int rescan_partitions(struct gendisk *di if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) return 0; if (IS_ERR(state)) /* I/O error reading the partition table */ - return PTR_ERR(state); + return -EIO; for (p = 1; p < state->limit; p++) { sector_t size = state->parts[p].size; sector_t from = state->parts[p].from; Index: linux-2.6.21-rc5/fs/smbfs/request.c =================================================================== --- linux-2.6.21-rc5.orig/fs/smbfs/request.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/smbfs/request.c 2007-03-27 14:20:38.000000000 +0100 @@ -181,6 +181,7 @@ static int smb_setup_request(struct smb_ req->rq_errno = 0; req->rq_fragment = 0; kfree(req->rq_trans2buffer); + req->rq_trans2buffer = NULL; return 0; } Index: linux-2.6.21-rc5/fs/ufs/balloc.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ufs/balloc.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ufs/balloc.c 2007-03-27 14:20:38.000000000 +0100 @@ -244,62 +244,87 @@ failed: * We can come here from ufs_writepage or ufs_prepare_write, * locked_page is argument of these functions, so we already lock it. */ -static void ufs_change_blocknr(struct inode *inode, unsigned int beg, - unsigned int count, unsigned int oldb, - unsigned int newb, struct page *locked_page) +static void ufs_change_blocknr(struct inode *inode, sector_t beg, + unsigned int count, sector_t oldb, + sector_t newb, struct page *locked_page) { - const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1; + const unsigned blks_per_page = + 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); + const unsigned mask = blks_per_page - 1; struct address_space * const mapping = inode->i_mapping; - pgoff_t index, cur_index; - unsigned end, pos, j; + pgoff_t index, cur_index, last_index; + unsigned pos, j, lblock; + sector_t end, i; struct page *page; struct buffer_head *head, *bh; - UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", - inode->i_ino, count, oldb, newb); + UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n", + inode->i_ino, count, + (unsigned long long)oldb, (unsigned long long)newb); BUG_ON(!locked_page); BUG_ON(!PageLocked(locked_page)); cur_index = locked_page->index; - - for (end = count + beg; beg < end; beg = (beg | mask) + 1) { - index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits); + end = count + beg; + last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits); + for (i = beg; i < end; i = (i | mask) + 1) { + index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits); if (likely(cur_index != index)) { page = ufs_get_locked_page(mapping, index); - if (!page || IS_ERR(page)) /* it was truncated or EIO */ + if (!page)/* it was truncated */ + continue; + if (IS_ERR(page)) {/* or EIO */ + ufs_error(inode->i_sb, __FUNCTION__, + "read of page %llu failed\n", + (unsigned long long)index); continue; + } } else page = locked_page; head = page_buffers(page); bh = head; - pos = beg & mask; + pos = i & mask; for (j = 0; j < pos; ++j) bh = bh->b_this_page; - j = 0; + + + if (unlikely(index == last_index)) + lblock = end & mask; + else + lblock = blks_per_page; + do { - if (buffer_mapped(bh)) { - pos = bh->b_blocknr - oldb; - if (pos < count) { - UFSD(" change from %llu to %llu\n", - (unsigned long long)pos + oldb, - (unsigned long long)pos + newb); - bh->b_blocknr = newb + pos; - unmap_underlying_metadata(bh->b_bdev, - bh->b_blocknr); - mark_buffer_dirty(bh); - ++j; + if (j >= lblock) + break; + pos = (i - beg) + j; + + if (!buffer_mapped(bh)) + map_bh(bh, inode->i_sb, oldb + pos); + if (!buffer_uptodate(bh)) { + ll_rw_block(READ, 1, &bh); + wait_on_buffer(bh); + if (!buffer_uptodate(bh)) { + ufs_error(inode->i_sb, __FUNCTION__, + "read of block failed\n"); + break; } } + UFSD(" change from %llu to %llu, pos %u\n", + (unsigned long long)pos + oldb, + (unsigned long long)pos + newb, pos); + + bh->b_blocknr = newb + pos; + unmap_underlying_metadata(bh->b_bdev, + bh->b_blocknr); + mark_buffer_dirty(bh); + ++j; bh = bh->b_this_page; } while (bh != head); - if (j) - set_page_dirty(page); - if (likely(cur_index != index)) ufs_put_locked_page(page); } @@ -457,8 +482,9 @@ u64 ufs_new_fragments(struct inode *inod if (result) { ufs_clear_frags(inode, result + oldcount, newcount - oldcount, locked_page != NULL); - ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, - result, locked_page); + ufs_change_blocknr(inode, fragment - oldcount, oldcount, + uspi->s_sbbase + tmp, + uspi->s_sbbase + result, locked_page); ufs_cpu_to_data_ptr(sb, p, result); *err = 0; UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); Index: linux-2.6.21-rc5/fs/ufs/ialloc.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ufs/ialloc.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ufs/ialloc.c 2007-03-27 14:20:38.000000000 +0100 @@ -343,9 +343,8 @@ cg_found: lock_buffer(bh); ufs2_inode = (struct ufs2_inode *)bh->b_data; ufs2_inode += ufs_inotofsbo(inode->i_ino); - ufs2_inode->ui_birthtime.tv_sec = - cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec); - ufs2_inode->ui_birthtime.tv_usec = 0; + ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec); + ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec); mark_buffer_dirty(bh); unlock_buffer(bh); if (sb->s_flags & MS_SYNCHRONOUS) Index: linux-2.6.21-rc5/fs/ufs/inode.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ufs/inode.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ufs/inode.c 2007-03-27 14:20:38.000000000 +0100 @@ -212,7 +212,7 @@ repeat: brelse (result); goto repeat; } else { - *phys = tmp + blockoff; + *phys = uspi->s_sbbase + tmp + blockoff; return NULL; } } @@ -282,9 +282,9 @@ repeat: } if (!phys) { - result = sb_getblk(sb, tmp + blockoff); + result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); } else { - *phys = tmp + blockoff; + *phys = uspi->s_sbbase + tmp + blockoff; result = NULL; *err = 0; *new = 1; @@ -368,7 +368,7 @@ repeat: brelse (result); goto repeat; } else { - *phys = tmp + blockoff; + *phys = uspi->s_sbbase + tmp + blockoff; goto out; } } @@ -389,9 +389,9 @@ repeat: if (!phys) { - result = sb_getblk(sb, tmp + blockoff); + result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); } else { - *phys = tmp + blockoff; + *phys = uspi->s_sbbase + tmp + blockoff; *new = 1; } @@ -668,12 +668,12 @@ static void ufs2_read_inode(struct inode inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); - inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec); - inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec); - inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec); - inode->i_mtime.tv_nsec = 0; - inode->i_atime.tv_nsec = 0; - inode->i_ctime.tv_nsec = 0; + inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); + inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime); + inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime); + inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec); + inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec); + inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec); inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); @@ -803,12 +803,12 @@ static void ufs2_update_inode(struct ino ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); - ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); - ufs_inode->ui_atime.tv_usec = 0; - ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec); - ufs_inode->ui_ctime.tv_usec = 0; - ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec); - ufs_inode->ui_mtime.tv_usec = 0; + ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); + ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec); + ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec); + ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec); + ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec); + ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec); ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); Index: linux-2.6.21-rc5/fs/ufs/truncate.c =================================================================== --- linux-2.6.21-rc5.orig/fs/ufs/truncate.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/ufs/truncate.c 2007-03-27 14:20:38.000000000 +0100 @@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode unsigned i, tmp; int retry; - UFSD("ENTER\n"); + UFSD("ENTER: ino %lu\n", inode->i_ino); sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; @@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode block2 = ufs_fragstoblks (frag3); } - UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu," - " frag4 %llu\n", + UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu," + " frag3 %llu, frag4 %llu\n", inode->i_ino, (unsigned long long)frag1, (unsigned long long)frag2, (unsigned long long)block1, (unsigned long long)block2, (unsigned long long)frag3, (unsigned long long)frag4); @@ -163,7 +163,7 @@ next1: mark_inode_dirty(inode); next3: - UFSD("EXIT\n"); + UFSD("EXIT: ino %lu\n", inode->i_ino); return retry; } @@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct ino } ubh_brelse (ind_ubh); - UFSD("EXIT\n"); + UFSD("EXIT: ino %lu\n", inode->i_ino); return retry; } @@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct in void *dind; int retry = 0; - UFSD("ENTER\n"); + UFSD("ENTER: ino %lu\n", inode->i_ino); sb = inode->i_sb; uspi = UFS_SB(sb)->s_uspi; @@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct in } ubh_brelse (dind_bh); - UFSD("EXIT\n"); + UFSD("EXIT: ino %lu\n", inode->i_ino); return retry; } @@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct in void *tind, *p; int retry; - UFSD("ENTER\n"); + UFSD("ENTER: ino %lu\n", inode->i_ino); retry = 0; @@ -348,7 +348,7 @@ static int ufs_trunc_tindirect(struct in } for (i = tindirect_block ; i < uspi->s_apb ; i++) { - tind = ubh_get_addr32 (tind_bh, i); + tind = ubh_get_data_ptr(uspi, tind_bh, i); retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); ubh_mark_buffer_dirty(tind_bh); @@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct in } ubh_brelse (tind_bh); - UFSD("EXIT\n"); + UFSD("EXIT: ino %lu\n", inode->i_ino); return retry; } static int ufs_alloc_lastblock(struct inode *inode) { int err = 0; + struct super_block *sb = inode->i_sb; struct address_space *mapping = inode->i_mapping; - struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; + struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; unsigned i, end; sector_t lastfrag; struct page *lastpage; struct buffer_head *bh; + u64 phys64; lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; @@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct in set_page_dirty(lastpage); } + if (lastfrag >= UFS_IND_FRAGMENT) { + end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1; + phys64 = bh->b_blocknr + 1; + for (i = 0; i < end; ++i) { + bh = sb_getblk(sb, i + phys64); + lock_buffer(bh); + memset(bh->b_data, 0, sb->s_blocksize); + set_buffer_uptodate(bh); + mark_buffer_dirty(bh); + unlock_buffer(bh); + sync_dirty_buffer(bh); + brelse(bh); + } + } out_unlock: ufs_put_locked_page(lastpage); out: Index: linux-2.6.21-rc5/fs/xfs/linux-2.6/xfs_buf.c =================================================================== --- linux-2.6.21-rc5.orig/fs/xfs/linux-2.6/xfs_buf.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/fs/xfs/linux-2.6/xfs_buf.c 2007-03-27 14:20:38.000000000 +0100 @@ -1829,11 +1829,11 @@ xfs_buf_init(void) if (!xfs_buf_zone) goto out_free_trace_buf; - xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); + xfslogd_workqueue = create_workqueue("xfslogd"); if (!xfslogd_workqueue) goto out_free_buf_zone; - xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); + xfsdatad_workqueue = create_workqueue("xfsdatad"); if (!xfsdatad_workqueue) goto out_destroy_xfslogd_workqueue; Index: linux-2.6.21-rc5/include/acpi/acinterp.h =================================================================== --- linux-2.6.21-rc5.orig/include/acpi/acinterp.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/acpi/acinterp.h 2007-03-27 14:20:38.000000000 +0100 @@ -446,14 +446,10 @@ acpi_ex_copy_integer_to_buffer_field(uni /* * exutils - interpreter/scanner utilities */ -void acpi_ex_enter_interpreter(void); +acpi_status acpi_ex_enter_interpreter(void); void acpi_ex_exit_interpreter(void); -void acpi_ex_reacquire_interpreter(void); - -void acpi_ex_relinquish_interpreter(void); - void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc); u8 acpi_ex_acquire_global_lock(u32 rule); Index: linux-2.6.21-rc5/include/acpi/actypes.h =================================================================== --- linux-2.6.21-rc5.orig/include/acpi/actypes.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/acpi/actypes.h 2007-03-27 14:20:38.000000000 +0100 @@ -344,7 +344,7 @@ typedef u32 acpi_integer; /* 64-bit integers */ -typedef u64 acpi_integer; +typedef unsigned long long acpi_integer; #define ACPI_INTEGER_MAX ACPI_UINT64_MAX #define ACPI_INTEGER_BIT_SIZE 64 #define ACPI_MAX_DECIMAL_DIGITS 20 /* 2^64 = 18,446,744,073,709,551,616 */ Index: linux-2.6.21-rc5/include/asm-arm/arch-at91/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-at91/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-at91/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -223,7 +223,7 @@ static inline void gpio_free(unsigned gp } extern int gpio_direction_input(unsigned gpio); -extern int gpio_direction_output(unsigned gpio); +extern int gpio_direction_output(unsigned gpio, int value); static inline int gpio_get_value(unsigned gpio) { Index: linux-2.6.21-rc5/include/asm-arm/arch-ns9xxx/clock.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-ns9xxx/clock.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-ns9xxx/clock.h 2007-03-27 14:20:38.000000000 +0100 @@ -11,6 +11,7 @@ #ifndef __ASM_ARCH_CLOCK_H #define __ASM_ARCH_CLOCK_H +static inline u32 ns9xxx_systemclock(void) __attribute__((const)); static inline u32 ns9xxx_systemclock(void) { /* @@ -19,17 +20,20 @@ static inline u32 ns9xxx_systemclock(voi return 353894400; } -static inline const u32 ns9xxx_cpuclock(void) +static inline u32 ns9xxx_cpuclock(void) __attribute__((const)); +static inline u32 ns9xxx_cpuclock(void) { return ns9xxx_systemclock() / 2; } -static inline const u32 ns9xxx_ahbclock(void) +static inline u32 ns9xxx_ahbclock(void) __attribute__((const)); +static inline u32 ns9xxx_ahbclock(void) { return ns9xxx_systemclock() / 4; } -static inline const u32 ns9xxx_bbusclock(void) +static inline u32 ns9xxx_bbusclock(void) __attribute__((const)); +static inline u32 ns9xxx_bbusclock(void) { return ns9xxx_systemclock() / 8; } Index: linux-2.6.21-rc5/include/asm-arm/arch-omap/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-omap/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-omap/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -113,8 +113,9 @@ static inline int gpio_direction_input(u return __gpio_set_direction(gpio, 1); } -static inline int gpio_direction_output(unsigned gpio) +static inline int gpio_direction_output(unsigned gpio, int value) { + omap_set_gpio_dataout(gpio, value); return __gpio_set_direction(gpio, 0); } Index: linux-2.6.21-rc5/include/asm-arm/arch-pxa/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-pxa/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-pxa/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -43,9 +43,9 @@ static inline int gpio_direction_input(u return pxa_gpio_mode(gpio | GPIO_IN); } -static inline int gpio_direction_output(unsigned gpio) +static inline int gpio_direction_output(unsigned gpio, int value) { - return pxa_gpio_mode(gpio | GPIO_OUT); + return pxa_gpio_mode(gpio | GPIO_OUT | (value ? 0 : GPIO_DFLT_LOW)); } static inline int __gpio_get_value(unsigned gpio) Index: linux-2.6.21-rc5/include/asm-arm/arch-pxa/pxa-regs.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-pxa/pxa-regs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-pxa/pxa-regs.h 2007-03-27 14:20:38.000000000 +0100 @@ -1476,7 +1476,7 @@ #define GPIO112_MMCCMD_MD (112 | GPIO_ALT_FN_1_OUT) #define GPIO113_I2S_SYSCLK_MD (113 | GPIO_ALT_FN_1_OUT) #define GPIO113_AC97_RESET_N_MD (113 | GPIO_ALT_FN_2_OUT) -#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_OUT) +#define GPIO117_I2CSCL_MD (117 | GPIO_ALT_FN_1_IN) #define GPIO118_I2CSDA_MD (118 | GPIO_ALT_FN_1_IN) /* Index: linux-2.6.21-rc5/include/asm-arm/arch-s3c2410/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-s3c2410/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-s3c2410/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -44,9 +44,11 @@ static inline int gpio_direction_input(u return 0; } -static inline int gpio_direction_output(unsigned gpio) +static inline int gpio_direction_output(unsigned gpio, int value) { s3c2410_gpio_cfgpin(gpio, S3C2410_GPIO_OUTPUT); + /* REVISIT can we write the value first, to avoid glitching? */ + s3c2410_gpio_setpin(gpio, value); return 0; } Index: linux-2.6.21-rc5/include/asm-arm/arch-sa1100/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/arch-sa1100/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/arch-sa1100/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -38,7 +38,7 @@ static inline void gpio_free(unsigned gp } extern int gpio_direction_input(unsigned gpio); -extern int gpio_direction_output(unsigned gpio); +extern int gpio_direction_output(unsigned gpio, int value); static inline int gpio_get_value(unsigned gpio) Index: linux-2.6.21-rc5/include/asm-arm/atomic.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-arm/atomic.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-arm/atomic.h 2007-03-27 14:20:38.000000000 +0100 @@ -103,9 +103,9 @@ static inline void atomic_clear_mask(uns unsigned long tmp, tmp2; __asm__ __volatile__("@ atomic_clear_mask\n" -"1: ldrex %0, %2\n" +"1: ldrex %0, [%2]\n" " bic %0, %0, %3\n" -" strex %1, %0, %2\n" +" strex %1, %0, [%2]\n" " teq %1, #0\n" " bne 1b" : "=&r" (tmp), "=&r" (tmp2) Index: linux-2.6.21-rc5/include/asm-avr32/arch-at32ap/gpio.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-avr32/arch-at32ap/gpio.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-avr32/arch-at32ap/gpio.h 2007-03-27 14:20:38.000000000 +0100 @@ -10,7 +10,7 @@ int __must_check gpio_request(unsigned i void gpio_free(unsigned int gpio); int gpio_direction_input(unsigned int gpio); -int gpio_direction_output(unsigned int gpio); +int gpio_direction_output(unsigned int gpio, int value); int gpio_get_value(unsigned int gpio); void gpio_set_value(unsigned int gpio, int value); Index: linux-2.6.21-rc5/include/asm-i386/apic.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-i386/apic.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-i386/apic.h 2007-03-27 14:20:38.000000000 +0100 @@ -117,6 +117,7 @@ extern void enable_NMI_through_LVT0 (voi #define ARCH_APICTIMER_STOPS_ON_C3 1 extern int timer_over_8254; +extern int local_apic_timer_c2_ok; #else /* !CONFIG_X86_LOCAL_APIC */ static inline void lapic_shutdown(void) { } Index: linux-2.6.21-rc5/include/asm-i386/elf.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-i386/elf.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-i386/elf.h 2007-03-27 14:20:38.000000000 +0100 @@ -88,16 +88,16 @@ typedef struct user_fxsr_struct elf_fpxr pr_reg[4] = regs->edi; \ pr_reg[5] = regs->ebp; \ pr_reg[6] = regs->eax; \ - pr_reg[7] = regs->xds; \ - pr_reg[8] = regs->xes; \ - pr_reg[9] = regs->xfs; \ + pr_reg[7] = regs->xds & 0xffff; \ + pr_reg[8] = regs->xes & 0xffff; \ + pr_reg[9] = regs->xfs & 0xffff; \ savesegment(gs,pr_reg[10]); \ pr_reg[11] = regs->orig_eax; \ pr_reg[12] = regs->eip; \ - pr_reg[13] = regs->xcs; \ + pr_reg[13] = regs->xcs & 0xffff; \ pr_reg[14] = regs->eflags; \ pr_reg[15] = regs->esp; \ - pr_reg[16] = regs->xss; + pr_reg[16] = regs->xss & 0xffff; /* This yields a mask that user programs can use to figure out what instruction set this CPU supports. This could be done in user space, Index: linux-2.6.21-rc5/include/asm-i386/sync_bitops.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-i386/sync_bitops.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-i386/sync_bitops.h 2007-03-27 14:20:38.000000000 +0100 @@ -130,7 +130,7 @@ static inline int sync_test_and_change_b return oldbit; } -static __always_inline int sync_const_test_bit(int nr, const volatile unsigned long *addr) +static __always_inline int sync_constant_test_bit(int nr, const volatile unsigned long *addr) { return ((1UL << (nr & 31)) & (((const volatile unsigned int *)addr)[nr >> 5])) != 0; Index: linux-2.6.21-rc5/include/asm-ia64/machvec.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-ia64/machvec.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-ia64/machvec.h 2007-03-27 14:20:38.000000000 +0100 @@ -168,6 +168,7 @@ extern void machvec_tlb_migrate_finish ( # define platform_setup_msi_irq ia64_mv.setup_msi_irq # define platform_teardown_msi_irq ia64_mv.teardown_msi_irq # define platform_pci_fixup_bus ia64_mv.pci_fixup_bus +# define platform_kernel_launch_event ia64_mv.kernel_launch_event # endif /* __attribute__((__aligned__(16))) is required to make size of the @@ -269,6 +270,7 @@ struct ia64_machine_vector { platform_setup_msi_irq, \ platform_teardown_msi_irq, \ platform_pci_fixup_bus, \ + platform_kernel_launch_event \ } extern struct ia64_machine_vector ia64_mv; Index: linux-2.6.21-rc5/include/asm-ia64/meminit.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-ia64/meminit.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-ia64/meminit.h 2007-03-27 14:20:38.000000000 +0100 @@ -36,6 +36,7 @@ extern void reserve_memory (void); extern void find_initrd (void); extern int filter_rsvd_memory (unsigned long start, unsigned long end, void *arg); extern void efi_memmap_init(unsigned long *, unsigned long *); +extern int find_max_min_low_pfn (unsigned long , unsigned long, void *); extern unsigned long vmcore_find_descriptor_size(unsigned long address); extern int reserve_elfcorehdr(unsigned long *start, unsigned long *end); Index: linux-2.6.21-rc5/include/asm-mips/atomic.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/atomic.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/atomic.h 2007-03-27 14:20:38.000000000 +0100 @@ -79,9 +79,9 @@ static __inline__ void atomic_add(int i, } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); v->counter += i; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -124,9 +124,9 @@ static __inline__ void atomic_sub(int i, } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); v->counter -= i; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -173,11 +173,11 @@ static __inline__ int atomic_add_return( } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result += i; v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); @@ -225,11 +225,11 @@ static __inline__ int atomic_sub_return( } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result -= i; v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); @@ -293,12 +293,12 @@ static __inline__ int atomic_sub_if_posi } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result -= i; if (result >= 0) v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); @@ -454,9 +454,9 @@ static __inline__ void atomic64_add(long } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); v->counter += i; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -499,9 +499,9 @@ static __inline__ void atomic64_sub(long } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); v->counter -= i; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -548,11 +548,11 @@ static __inline__ long atomic64_add_retu } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result += i; v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); @@ -600,11 +600,11 @@ static __inline__ long atomic64_sub_retu } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result -= i; v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); @@ -668,12 +668,12 @@ static __inline__ long atomic64_sub_if_p } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); result = v->counter; result -= i; if (result >= 0) v->counter = result; - local_irq_restore(flags); + raw_local_irq_restore(flags); } smp_mb(); Index: linux-2.6.21-rc5/include/asm-mips/bitops.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/bitops.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/bitops.h 2007-03-27 14:20:38.000000000 +0100 @@ -100,9 +100,9 @@ static inline void set_bit(unsigned long a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); *a |= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -165,9 +165,9 @@ static inline void clear_bit(unsigned lo a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); *a &= ~mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -220,9 +220,9 @@ static inline void change_bit(unsigned l a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); *a ^= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); } } @@ -287,10 +287,10 @@ static inline int test_and_set_bit(unsig a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); retval = (mask & *a) != 0; *a |= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return retval; } @@ -381,10 +381,10 @@ static inline int test_and_clear_bit(uns a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); retval = (mask & *a) != 0; *a &= ~mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return retval; } @@ -452,10 +452,10 @@ static inline int test_and_change_bit(un a += nr >> SZLONG_LOG; mask = 1UL << bit; - local_irq_save(flags); + raw_local_irq_save(flags); retval = (mask & *a) != 0; *a ^= mask; - local_irq_restore(flags); + raw_local_irq_restore(flags); return retval; } Index: linux-2.6.21-rc5/include/asm-mips/cacheflush.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/cacheflush.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/cacheflush.h 2007-03-27 14:20:38.000000000 +0100 @@ -48,6 +48,15 @@ static inline void flush_dcache_page(str #define flush_dcache_mmap_lock(mapping) do { } while (0) #define flush_dcache_mmap_unlock(mapping) do { } while (0) +#define ARCH_HAS_FLUSH_ANON_PAGE +extern void __flush_anon_page(struct page *, unsigned long); +static inline void flush_anon_page(struct vm_area_struct *vma, + struct page *page, unsigned long vmaddr) +{ + if (cpu_has_dc_aliases && PageAnon(page)) + __flush_anon_page(page, vmaddr); +} + static inline void flush_icache_page(struct vm_area_struct *vma, struct page *page) { @@ -86,4 +95,7 @@ extern void (*flush_data_cache_page)(uns /* Run kernel code uncached, useful for cache probing functions. */ unsigned long __init run_uncached(void *func); +extern void *kmap_coherent(struct page *page, unsigned long addr); +extern void kunmap_coherent(struct page *page); + #endif /* _ASM_CACHEFLUSH_H */ Index: linux-2.6.21-rc5/include/asm-mips/cpu-features.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/cpu-features.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/cpu-features.h 2007-03-27 14:20:38.000000000 +0100 @@ -40,6 +40,9 @@ #endif #ifndef cpu_has_fpu #define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU) +#define raw_cpu_has_fpu (raw_current_cpu_data.options & MIPS_CPU_FPU) +#else +#define raw_cpu_has_fpu cpu_has_fpu #endif #ifndef cpu_has_32fpr #define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) Index: linux-2.6.21-rc5/include/asm-mips/cpu-info.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/cpu-info.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/cpu-info.h 2007-03-27 14:20:38.000000000 +0100 @@ -87,6 +87,7 @@ struct cpuinfo_mips { extern struct cpuinfo_mips cpu_data[]; #define current_cpu_data cpu_data[smp_processor_id()] +#define raw_current_cpu_data cpu_data[raw_smp_processor_id()] extern void cpu_probe(void); extern void cpu_report(void); Index: linux-2.6.21-rc5/include/asm-mips/delay.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/delay.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/delay.h 2007-03-27 14:20:38.000000000 +0100 @@ -79,7 +79,7 @@ static inline void __udelay(unsigned lon __delay(usecs); } -#define __udelay_val cpu_data[smp_processor_id()].udelay_val +#define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val #define udelay(usecs) __udelay((usecs),__udelay_val) Index: linux-2.6.21-rc5/include/asm-mips/fpu.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/fpu.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/fpu.h 2007-03-27 14:20:38.000000000 +0100 @@ -27,11 +27,11 @@ struct sigcontext; struct sigcontext32; -extern asmlinkage int (*save_fp_context)(struct sigcontext *sc); -extern asmlinkage int (*restore_fp_context)(struct sigcontext *sc); +extern asmlinkage int (*save_fp_context)(struct sigcontext __user *sc); +extern asmlinkage int (*restore_fp_context)(struct sigcontext __user *sc); -extern asmlinkage int (*save_fp_context32)(struct sigcontext32 *sc); -extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 *sc); +extern asmlinkage int (*save_fp_context32)(struct sigcontext32 __user *sc); +extern asmlinkage int (*restore_fp_context32)(struct sigcontext32 __user *sc); extern void fpu_emulator_init_fpu(void); extern void _init_fpu(void); @@ -68,6 +68,8 @@ do { \ /* We don't care about the c0 hazard here */ \ } while (0) +#define __fpu_enabled() (read_c0_status() & ST0_CU1) + #define enable_fpu() \ do { \ if (cpu_has_fpu) \ @@ -93,31 +95,47 @@ static inline int is_fpu_owner(void) return cpu_has_fpu && __is_fpu_owner(); } -static inline void own_fpu(void) +static inline void __own_fpu(void) { - if (cpu_has_fpu) { - __enable_fpu(); - KSTK_STATUS(current) |= ST0_CU1; - set_thread_flag(TIF_USEDFPU); + __enable_fpu(); + KSTK_STATUS(current) |= ST0_CU1; + set_thread_flag(TIF_USEDFPU); +} + +static inline void own_fpu(int restore) +{ + preempt_disable(); + if (cpu_has_fpu && !__is_fpu_owner()) { + __own_fpu(); + if (restore) + _restore_fp(current); } + preempt_enable(); } -static inline void lose_fpu(void) +static inline void lose_fpu(int save) { - if (cpu_has_fpu) { + preempt_disable(); + if (is_fpu_owner()) { + if (save) + _save_fp(current); KSTK_STATUS(current) &= ~ST0_CU1; clear_thread_flag(TIF_USEDFPU); __disable_fpu(); } + preempt_enable(); } static inline void init_fpu(void) { + preempt_disable(); if (cpu_has_fpu) { + __own_fpu(); _init_fpu(); } else { fpu_emulator_init_fpu(); } + preempt_enable(); } static inline void save_fp(struct task_struct *tsk) @@ -144,4 +162,18 @@ static inline fpureg_t *get_fpu_regs(str return tsk->thread.fpu.fpr; } +static inline void enable_fp_in_kernel(void) +{ + set_thread_flag(TIF_ALLOW_FP_IN_KERNEL); + /* make sure CU1 and FPU ownership are consistent */ + if (!__is_fpu_owner() && __fpu_enabled()) + __disable_fpu(); +} + +static inline void disable_fp_in_kernel(void) +{ + BUG_ON(!__is_fpu_owner() && __fpu_enabled()); + clear_thread_flag(TIF_ALLOW_FP_IN_KERNEL); +} + #endif /* _ASM_FPU_H */ Index: linux-2.6.21-rc5/include/asm-mips/hazards.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/hazards.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/hazards.h 2007-03-27 14:20:38.000000000 +0100 @@ -52,6 +52,7 @@ ASMMACRO(tlb_probe_hazard, _ehb ) ASMMACRO(irq_enable_hazard, + _ehb ) ASMMACRO(irq_disable_hazard, _ehb Index: linux-2.6.21-rc5/include/asm-mips/mach-au1x00/au1xxx_ide.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/mach-au1x00/au1xxx_ide.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/mach-au1x00/au1xxx_ide.h 2007-03-27 14:20:38.000000000 +0100 @@ -141,40 +141,6 @@ static int auide_ddma_init( _auide_hwif static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif); int __init auide_probe(void); -#ifdef CONFIG_PM - int au1200ide_pm_callback( au1xxx_power_dev_t *dev, - au1xxx_request_t request, void *data); - static int au1xxxide_pm_standby( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_sleep( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_resume( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_getstatus( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_access( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_idle( au1xxx_power_dev_t *dev ); - static int au1xxxide_pm_cleanup( au1xxx_power_dev_t *dev ); -#endif - - -/* - * Multi-Word DMA + DbDMA functions - */ -#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA - static int auide_build_sglist(ide_drive_t *drive, struct request *rq); - static int auide_build_dmatable(ide_drive_t *drive); - static int auide_dma_end(ide_drive_t *drive); - ide_startstop_t auide_dma_intr (ide_drive_t *drive); - static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command); - static int auide_dma_setup(ide_drive_t *drive); - static int auide_dma_check(ide_drive_t *drive); - static int auide_dma_test_irq(ide_drive_t *drive); - static int auide_dma_host_off(ide_drive_t *drive); - static int auide_dma_host_on(ide_drive_t *drive); - static int auide_dma_lostirq(ide_drive_t *drive); - static int auide_dma_on(ide_drive_t *drive); - static void auide_ddma_tx_callback(int irq, void *param); - static void auide_ddma_rx_callback(int irq, void *param); - static int auide_dma_off_quietly(ide_drive_t *drive); -#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ - /******************************************************************************* * PIO Mode timing calculation : * * * Index: linux-2.6.21-rc5/include/asm-mips/mach-ip27/dma-coherence.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/mach-ip27/dma-coherence.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/mach-ip27/dma-coherence.h 2007-03-27 14:20:38.000000000 +0100 @@ -18,7 +18,8 @@ struct device; -static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) { dma_addr_t pa = dev_to_baddr(dev, virt_to_phys(addr)); @@ -37,7 +38,7 @@ static unsigned long plat_dma_addr_to_ph return dma_addr & (0xffUL << 56); } -static void plat_unmap_dma_mem(dma_addr_t dma_addr) +static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) { } Index: linux-2.6.21-rc5/include/asm-mips/mach-ip32/dma-coherence.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/mach-ip32/dma-coherence.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/mach-ip32/dma-coherence.h 2007-03-27 14:20:38.000000000 +0100 @@ -26,7 +26,8 @@ struct device; #define RAM_OFFSET_MASK 0x3fffffffUL -static dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, size_t size) +static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr, + size_t size) { dma_addr_t pa = virt_to_phys(addr) & RAM_OFFSET_MASK; @@ -59,7 +60,7 @@ static unsigned long plat_dma_addr_to_ph return addr; } -static void plat_unmap_dma_mem(dma_addr_t dma_addr) +static inline void plat_unmap_dma_mem(dma_addr_t dma_addr) { } Index: linux-2.6.21-rc5/include/asm-mips/pgtable-64.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/pgtable-64.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/pgtable-64.h 2007-03-27 14:20:38.000000000 +0100 @@ -199,7 +199,7 @@ static inline unsigned long pud_page_vad { return pud_val(pud); } -#define pud_phys(pud) (pud_val(pud) - PAGE_OFFSET) +#define pud_phys(pud) virt_to_phys((void *)pud_val(pud)) #define pud_page(pud) (pfn_to_page(pud_phys(pud) >> PAGE_SHIFT)) /* Find an entry in the second-level page table.. */ Index: linux-2.6.21-rc5/include/asm-mips/pgtable.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/pgtable.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/pgtable.h 2007-03-27 14:20:38.000000000 +0100 @@ -75,7 +75,7 @@ extern void paging_init(void); * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ -#define pmd_phys(pmd) (pmd_val(pmd) - PAGE_OFFSET) +#define pmd_phys(pmd) virt_to_phys((void *)pmd_val(pmd)) #define pmd_page(pmd) (pfn_to_page(pmd_phys(pmd) >> PAGE_SHIFT)) #define pmd_page_vaddr(pmd) pmd_val(pmd) Index: linux-2.6.21-rc5/include/asm-mips/rtlx.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/rtlx.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/rtlx.h 2007-03-27 14:20:38.000000000 +0100 @@ -23,8 +23,8 @@ extern int rtlx_open(int index, int can_sleep); extern int rtlx_release(int index); -extern ssize_t rtlx_read(int index, void *buff, size_t count, int user); -extern ssize_t rtlx_write(int index, void *buffer, size_t count, int user); +extern ssize_t rtlx_read(int index, void __user *buff, size_t count); +extern ssize_t rtlx_write(int index, const void __user *buffer, size_t count); extern unsigned int rtlx_read_poll(int index, int can_sleep); extern unsigned int rtlx_write_poll(int index); Index: linux-2.6.21-rc5/include/asm-mips/sgiarcs.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/sgiarcs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/sgiarcs.h 2007-03-27 14:20:38.000000000 +0100 @@ -459,7 +459,7 @@ struct linux_smonblock { register signed int __a2 __asm__("$5") = (int) (long) (a2); \ register signed int __a3 __asm__("$6") = (int) (long) (a3); \ register signed int __a4 __asm__("$7") = (int) (long) (a4); \ - register signed int __a5 = (a5); \ + register signed int __a5 = (int) (long) (a5); \ long __vec = (long) romvec->dest; \ __asm__ __volatile__( \ "dsubu\t$29, 32\n\t" \ Index: linux-2.6.21-rc5/include/asm-mips/sibyte/sb1250.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/sibyte/sb1250.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/sibyte/sb1250.h 2007-03-27 14:20:38.000000000 +0100 @@ -67,6 +67,6 @@ extern void bcm1480_smp_finish(void); #endif -#define IOADDR(a) ((volatile void __iomem *)(IO_BASE + (a))) +#define IOADDR(a) ((void __iomem *)(IO_BASE + (a))) #endif Index: linux-2.6.21-rc5/include/asm-mips/system.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/system.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/system.h 2007-03-27 14:20:38.000000000 +0100 @@ -121,10 +121,10 @@ static inline unsigned long __xchg_u32(v } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); retval = *m; *m = val; - local_irq_restore(flags); /* implies memory barrier */ + raw_local_irq_restore(flags); /* implies memory barrier */ } smp_mb(); @@ -169,10 +169,10 @@ static inline __u64 __xchg_u64(volatile } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); retval = *m; *m = val; - local_irq_restore(flags); /* implies memory barrier */ + raw_local_irq_restore(flags); /* implies memory barrier */ } smp_mb(); @@ -250,11 +250,11 @@ static inline unsigned long __cmpxchg_u3 } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); retval = *m; if (retval == old) *m = new; - local_irq_restore(flags); /* implies memory barrier */ + raw_local_irq_restore(flags); /* implies memory barrier */ } smp_mb(); @@ -304,11 +304,11 @@ static inline unsigned long __cmpxchg_u6 } else { unsigned long flags; - local_irq_save(flags); + raw_local_irq_save(flags); retval = *m; if (retval == old) *m = new; - local_irq_restore(flags); /* implies memory barrier */ + raw_local_irq_restore(flags); /* implies memory barrier */ } smp_mb(); Index: linux-2.6.21-rc5/include/asm-mips/thread_info.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-mips/thread_info.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-mips/thread_info.h 2007-03-27 14:20:38.000000000 +0100 @@ -119,6 +119,7 @@ register struct thread_info *__current_t #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_MEMDIE 18 #define TIF_FREEZE 19 +#define TIF_ALLOW_FP_IN_KERNEL 20 #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ #define _TIF_SYSCALL_TRACE (1<> 5) - 16) #define irq2evt(irq) (((irq) + 16) << 5) +#else +#define evt2irq(evt) (evt) +#define irq2evt(irq) (irq) +#endif /* * Simple Mask Register Support Index: linux-2.6.21-rc5/include/asm-sh/unistd.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-sh/unistd.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-sh/unistd.h 2007-03-27 14:20:38.000000000 +0100 @@ -233,6 +233,7 @@ #define __NR_fcntl64 221 /* 223 is unused */ #define __NR_gettid 224 +#define __NR_readahead 225 #define __NR_setxattr 226 #define __NR_lsetxattr 227 #define __NR_fsetxattr 228 Index: linux-2.6.21-rc5/include/asm-sparc64/tsb.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-sparc64/tsb.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-sparc64/tsb.h 2007-03-27 14:20:38.000000000 +0100 @@ -264,6 +264,7 @@ extern struct tsb_phys_patch_entry __tsb be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; +#ifndef CONFIG_DEBUG_PAGEALLOC /* This version uses a trick, the TAG is already (VADDR >> 22) so * we can make use of that for the index computation. */ @@ -277,5 +278,6 @@ extern struct tsb_phys_patch_entry __tsb cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; +#endif #endif /* !(_SPARC64_TSB_H) */ Index: linux-2.6.21-rc5/include/asm-x86_64/apic.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-x86_64/apic.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-x86_64/apic.h 2007-03-27 14:20:38.000000000 +0100 @@ -102,5 +102,6 @@ void switch_ipi_to_APIC_timer(void *cpum #define ARCH_APICTIMER_STOPS_ON_C3 1 extern unsigned boot_cpu_id; +extern int local_apic_timer_c2_ok; #endif /* __ASM_APIC_H */ Index: linux-2.6.21-rc5/include/asm-x86_64/proto.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-x86_64/proto.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-x86_64/proto.h 2007-03-27 14:20:38.000000000 +0100 @@ -99,7 +99,7 @@ extern int force_iommu, no_iommu; extern int iommu_detected; #ifdef CONFIG_IOMMU extern void gart_iommu_init(void); -extern void gart_parse_options(char *); +extern void __init gart_parse_options(char *); extern void iommu_hole_init(void); extern int fallback_aper_order; extern int fallback_aper_force; Index: linux-2.6.21-rc5/include/asm-x86_64/smp.h =================================================================== --- linux-2.6.21-rc5.orig/include/asm-x86_64/smp.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/asm-x86_64/smp.h 2007-03-27 14:20:38.000000000 +0100 @@ -7,6 +7,7 @@ #include #include #include +#include extern int disable_apic; #include @@ -68,7 +69,7 @@ extern int __cpu_disable(void); extern void __cpu_die(unsigned int cpu); extern void prefill_possible_map(void); extern unsigned num_processors; -extern unsigned disabled_cpus; +extern unsigned __cpuinitdata disabled_cpus; #define NO_PROC_ID 0xFF /* No processor magic marker */ Index: linux-2.6.21-rc5/include/linux/backing-dev.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/backing-dev.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/backing-dev.h 2007-03-27 14:20:38.000000000 +0100 @@ -93,6 +93,7 @@ static inline int bdi_rw_congested(struc void clear_bdi_congested(struct backing_dev_info *bdi, int rw); void set_bdi_congested(struct backing_dev_info *bdi, int rw); long congestion_wait(int rw, long timeout); +long congestion_wait_interruptible(int rw, long timeout); void congestion_end(int rw); #define bdi_cap_writeback_dirty(bdi) \ Index: linux-2.6.21-rc5/include/linux/bootmem.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/bootmem.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/bootmem.h 2007-03-27 14:20:38.000000000 +0100 @@ -108,7 +108,7 @@ static inline void *alloc_remap(int nid, #endif /* CONFIG_HAVE_ARCH_ALLOC_REMAP */ extern unsigned long __meminitdata nr_kernel_pages; -extern unsigned long nr_all_pages; +extern unsigned long __meminitdata nr_all_pages; extern void *alloc_large_system_hash(const char *tablename, unsigned long bucketsize, Index: linux-2.6.21-rc5/include/linux/kbd_kern.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/kbd_kern.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/kbd_kern.h 2007-03-27 14:20:38.000000000 +0100 @@ -75,7 +75,7 @@ extern int do_poke_blanked_console; extern void (*kbd_ledfunc)(unsigned int led); -extern void set_console(int nr); +extern int set_console(int nr); extern void schedule_console_callback(void); static inline void set_leds(void) Index: linux-2.6.21-rc5/include/linux/ktime.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/ktime.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/ktime.h 2007-03-27 14:20:38.000000000 +0100 @@ -57,7 +57,11 @@ typedef union { } ktime_t; #define KTIME_MAX ((s64)~((u64)1 << 63)) -#define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) +#if (BITS_PER_LONG == 64) +# define KTIME_SEC_MAX (KTIME_MAX / NSEC_PER_SEC) +#else +# define KTIME_SEC_MAX LONG_MAX +#endif /* * ktime_t definitions when using the 64-bit scalar representation: Index: linux-2.6.21-rc5/include/linux/lockdep.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/lockdep.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/lockdep.h 2007-03-27 14:20:38.000000000 +0100 @@ -245,7 +245,7 @@ extern void lock_release(struct lockdep_ # define INIT_LOCKDEP .lockdep_recursion = 0, -#define lockdep_depth(tsk) ((tsk)->lockdep_depth) +#define lockdep_depth(tsk) (debug_locks ? (tsk)->lockdep_depth : 0) #else /* !LOCKDEP */ Index: linux-2.6.21-rc5/include/linux/nfs_fs.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/nfs_fs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/nfs_fs.h 2007-03-27 14:20:38.000000000 +0100 @@ -415,6 +415,7 @@ extern void nfs_complete_unlink(struct d /* * linux/fs/nfs/write.c */ +extern int nfs_congestion_kb; extern int nfs_writepage(struct page *page, struct writeback_control *wbc); extern int nfs_writepages(struct address_space *, struct writeback_control *); extern int nfs_flush_incompatible(struct file *file, struct page *page); Index: linux-2.6.21-rc5/include/linux/nfs_fs_sb.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/nfs_fs_sb.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/nfs_fs_sb.h 2007-03-27 14:20:38.000000000 +0100 @@ -82,6 +82,7 @@ struct nfs_server { struct rpc_clnt * client_acl; /* ACL RPC client handle */ struct nfs_iostats * io_stats; /* I/O statistics */ struct backing_dev_info backing_dev_info; + atomic_t writeback; /* number of writeback pages */ int flags; /* various flags */ unsigned int caps; /* server capabilities */ unsigned int rsize; /* read size */ Index: linux-2.6.21-rc5/include/linux/spi/spi_bitbang.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/spi/spi_bitbang.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/spi/spi_bitbang.h 2007-03-27 14:20:38.000000000 +0100 @@ -25,7 +25,6 @@ struct spi_bitbang { spinlock_t lock; struct list_head queue; u8 busy; - u8 shutdown; u8 use_dma; struct spi_master *master; Index: linux-2.6.21-rc5/include/linux/sysfs.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/sysfs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/sysfs.h 2007-03-27 14:20:38.000000000 +0100 @@ -11,6 +11,7 @@ #define _SYSFS_H_ #include +#include #include #include Index: linux-2.6.21-rc5/include/linux/ufs_fs.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/ufs_fs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/ufs_fs.h 2007-03-27 14:20:38.000000000 +0100 @@ -649,10 +649,10 @@ struct ufs2_inode { __fs32 ui_blksize; /* 12: Inode blocksize. */ __fs64 ui_size; /* 16: File byte count. */ __fs64 ui_blocks; /* 24: Bytes actually held. */ - struct ufs_timeval ui_atime; /* 32: Last access time. */ - struct ufs_timeval ui_mtime; /* 40: Last modified time. */ - struct ufs_timeval ui_ctime; /* 48: Last inode change time. */ - struct ufs_timeval ui_birthtime; /* 56: Inode creation time. */ + __fs64 ui_atime; /* 32: Last access time. */ + __fs64 ui_mtime; /* 40: Last modified time. */ + __fs64 ui_ctime; /* 48: Last inode change time. */ + __fs64 ui_birthtime; /* 56: Inode creation time. */ __fs32 ui_mtimensec; /* 64: Last modified time. */ __fs32 ui_atimensec; /* 68: Last access time. */ __fs32 ui_ctimensec; /* 72: Last inode change time. */ Index: linux-2.6.21-rc5/include/linux/vt_kern.h =================================================================== --- linux-2.6.21-rc5.orig/include/linux/vt_kern.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/linux/vt_kern.h 2007-03-27 14:20:38.000000000 +0100 @@ -83,6 +83,7 @@ void reset_vc(struct vc_data *vc); #define CON_BUF_SIZE (CONFIG_BASE_SMALL ? 256 : PAGE_SIZE) extern char con_buf[CON_BUF_SIZE]; extern struct semaphore con_buf_sem; +extern char vt_dont_switch; struct vt_spawn_console { spinlock_t lock; Index: linux-2.6.21-rc5/include/net/sctp/structs.h =================================================================== --- linux-2.6.21-rc5.orig/include/net/sctp/structs.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/net/sctp/structs.h 2007-03-27 14:20:38.000000000 +0100 @@ -1002,6 +1002,7 @@ void sctp_transport_update_rto(struct sc void sctp_transport_raise_cwnd(struct sctp_transport *, __u32, __u32); void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t); unsigned long sctp_transport_timeout(struct sctp_transport *); +void sctp_transport_reset(struct sctp_transport *); /* This is the structure we use to queue packets as they come into Index: linux-2.6.21-rc5/include/net/sctp/ulpqueue.h =================================================================== --- linux-2.6.21-rc5.orig/include/net/sctp/ulpqueue.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/net/sctp/ulpqueue.h 2007-03-27 14:20:38.000000000 +0100 @@ -59,6 +59,7 @@ struct sctp_ulpq { /* Prototypes. */ struct sctp_ulpq *sctp_ulpq_init(struct sctp_ulpq *, struct sctp_association *); +void sctp_ulpq_flush(struct sctp_ulpq *ulpq); void sctp_ulpq_free(struct sctp_ulpq *); /* Add a new DATA chunk for processing. */ Index: linux-2.6.21-rc5/include/sound/version.h =================================================================== --- linux-2.6.21-rc5.orig/include/sound/version.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/include/sound/version.h 2007-03-27 14:20:38.000000000 +0100 @@ -1,3 +1,3 @@ /* include/version.h. Generated by alsa/ksync script. */ #define CONFIG_SND_VERSION "1.0.14rc3" -#define CONFIG_SND_DATE " (Tue Mar 06 13:10:00 2007 UTC)" +#define CONFIG_SND_DATE " (Wed Mar 14 07:25:50 2007 UTC)" Index: linux-2.6.21-rc5/kernel/fork.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/fork.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/fork.c 2007-03-27 14:20:38.000000000 +0100 @@ -933,8 +933,8 @@ asmlinkage long sys_set_tid_address(int static inline void rt_mutex_init_task(struct task_struct *p) { -#ifdef CONFIG_RT_MUTEXES spin_lock_init(&p->pi_lock); +#ifdef CONFIG_RT_MUTEXES plist_head_init(&p->pi_waiters, &p->pi_lock); p->pi_blocked_on = NULL; #endif Index: linux-2.6.21-rc5/kernel/futex.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/futex.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/futex.c 2007-03-27 14:20:38.000000000 +0100 @@ -565,6 +565,7 @@ static int wake_futex_pi(u32 __user *uad if (!pi_state) return -EINVAL; + spin_lock(&pi_state->pi_mutex.wait_lock); new_owner = rt_mutex_next_owner(&pi_state->pi_mutex); /* @@ -604,6 +605,7 @@ static int wake_futex_pi(u32 __user *uad pi_state->owner = new_owner; spin_unlock_irq(&new_owner->pi_lock); + spin_unlock(&pi_state->pi_mutex.wait_lock); rt_mutex_unlock(&pi_state->pi_mutex); return 0; Index: linux-2.6.21-rc5/kernel/hrtimer.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/hrtimer.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/hrtimer.c 2007-03-27 14:20:38.000000000 +0100 @@ -135,7 +135,7 @@ EXPORT_SYMBOL_GPL(ktime_get_ts); static void hrtimer_get_softirq_time(struct hrtimer_cpu_base *base) { ktime_t xtim, tomono; - struct timespec xts; + struct timespec xts, tom; unsigned long seq; do { @@ -145,10 +145,11 @@ static void hrtimer_get_softirq_time(str #else xts = xtime; #endif + tom = wall_to_monotonic; } while (read_seqretry(&xtime_lock, seq)); xtim = timespec_to_ktime(xts); - tomono = timespec_to_ktime(wall_to_monotonic); + tomono = timespec_to_ktime(tom); base->clock_base[CLOCK_REALTIME].softirq_time = xtim; base->clock_base[CLOCK_MONOTONIC].softirq_time = ktime_add(xtim, tomono); @@ -644,6 +645,12 @@ hrtimer_forward(struct hrtimer *timer, k orun++; } timer->expires = ktime_add(timer->expires, interval); + /* + * Make sure, that the result did not wrap with a very large + * interval. + */ + if (timer->expires.tv64 < 0) + timer->expires = ktime_set(KTIME_SEC_MAX, 0); return orun; } Index: linux-2.6.21-rc5/kernel/lockdep.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/lockdep.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/lockdep.c 2007-03-27 14:20:38.000000000 +0100 @@ -2742,6 +2742,10 @@ void debug_show_all_locks(void) int count = 10; int unlock = 1; + if (unlikely(!debug_locks)) { + printk("INFO: lockdep is turned off.\n"); + return; + } printk("\nShowing all locks held in the system:\n"); /* @@ -2785,6 +2789,10 @@ EXPORT_SYMBOL_GPL(debug_show_all_locks); void debug_show_held_locks(struct task_struct *task) { + if (unlikely(!debug_locks)) { + printk("INFO: lockdep is turned off.\n"); + return; + } lockdep_print_held_locks(task); } Index: linux-2.6.21-rc5/kernel/power/console.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/power/console.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/power/console.c 2007-03-27 14:20:38.000000000 +0100 @@ -27,7 +27,15 @@ int pm_prepare_console(void) return 1; } - set_console(SUSPEND_CONSOLE); + if (set_console(SUSPEND_CONSOLE)) { + /* + * We're unable to switch to the SUSPEND_CONSOLE. + * Let the calling function know so it can decide + * what to do. + */ + release_console_sem(); + return 1; + } release_console_sem(); if (vt_waitactive(SUSPEND_CONSOLE)) { Index: linux-2.6.21-rc5/kernel/power/disk.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/power/disk.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/power/disk.c 2007-03-27 14:20:38.000000000 +0100 @@ -58,6 +58,7 @@ static inline int platform_prepare(void) static void power_down(suspend_disk_method_t mode) { + disable_nonboot_cpus(); switch(mode) { case PM_DISK_PLATFORM: if (pm_ops && pm_ops->enter) { @@ -240,12 +241,6 @@ static int software_resume(void) goto Done; } - error = platform_prepare(); - if (error) { - swsusp_free(); - goto Thaw; - } - pr_debug("PM: Reading swsusp image.\n"); error = swsusp_read(); @@ -268,7 +263,6 @@ static int software_resume(void) enable_nonboot_cpus(); Free: swsusp_free(); - platform_finish(); device_resume(); resume_console(); Thaw: Index: linux-2.6.21-rc5/kernel/power/user.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/power/user.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/power/user.c 2007-03-27 14:20:38.000000000 +0100 @@ -368,9 +368,12 @@ static int snapshot_ioctl(struct inode * if (error) { printk(KERN_ERR "Failed to suspend some devices.\n"); } else { - /* Enter S3, system is already frozen */ - suspend_enter(PM_SUSPEND_MEM); - + error = disable_nonboot_cpus(); + if (!error) { + /* Enter S3, system is already frozen */ + suspend_enter(PM_SUSPEND_MEM); + enable_nonboot_cpus(); + } /* Wake up devices */ device_resume(); } @@ -398,9 +401,10 @@ static int snapshot_ioctl(struct inode * case PMOPS_ENTER: if (data->platform_suspend) { + disable_nonboot_cpus(); kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); error = pm_ops->enter(PM_SUSPEND_DISK); - error = 0; + enable_nonboot_cpus(); } break; Index: linux-2.6.21-rc5/kernel/time/clocksource.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/clocksource.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/clocksource.c 2007-03-27 14:20:38.000000000 +0100 @@ -151,7 +151,8 @@ static void clocksource_check_watchdog(s watchdog_timer.expires = jiffies + WATCHDOG_INTERVAL; add_timer(&watchdog_timer); } - } else if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) { + } else { + if (cs->flags & CLOCK_SOURCE_IS_CONTINUOUS) cs->flags |= CLOCK_SOURCE_VALID_FOR_HRES; if (!watchdog || cs->rating > watchdog->rating) { Index: linux-2.6.21-rc5/kernel/time/tick-broadcast.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/tick-broadcast.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/tick-broadcast.c 2007-03-27 14:20:38.000000000 +0100 @@ -307,12 +307,19 @@ int tick_resume_broadcast(void) spin_lock_irqsave(&tick_broadcast_lock, flags); bc = tick_broadcast_device.evtdev; - if (bc) { - if (tick_broadcast_device.mode == TICKDEV_MODE_PERIODIC && - !cpus_empty(tick_broadcast_mask)) - tick_broadcast_start_periodic(bc); - broadcast = cpu_isset(smp_processor_id(), tick_broadcast_mask); + if (bc) { + switch (tick_broadcast_device.mode) { + case TICKDEV_MODE_PERIODIC: + if(!cpus_empty(tick_broadcast_mask)) + tick_broadcast_start_periodic(bc); + broadcast = cpu_isset(smp_processor_id(), + tick_broadcast_mask); + break; + case TICKDEV_MODE_ONESHOT: + broadcast = tick_resume_broadcast_oneshot(bc); + break; + } } spin_unlock_irqrestore(&tick_broadcast_lock, flags); @@ -347,6 +354,16 @@ static int tick_broadcast_set_event(ktim } } +int tick_resume_broadcast_oneshot(struct clock_event_device *bc) +{ + clockevents_set_mode(bc, CLOCK_EVT_MODE_ONESHOT); + + if(!cpus_empty(tick_broadcast_oneshot_mask)) + tick_broadcast_set_event(ktime_get(), 1); + + return cpu_isset(smp_processor_id(), tick_broadcast_oneshot_mask); +} + /* * Reprogram the broadcast device: * Index: linux-2.6.21-rc5/kernel/time/tick-common.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/tick-common.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/tick-common.c 2007-03-27 14:20:38.000000000 +0100 @@ -298,18 +298,17 @@ static void tick_shutdown(unsigned int * spin_unlock_irqrestore(&tick_device_lock, flags); } -static void tick_suspend_periodic(void) +static void tick_suspend(void) { struct tick_device *td = &__get_cpu_var(tick_cpu_device); unsigned long flags; spin_lock_irqsave(&tick_device_lock, flags); - if (td->mode == TICKDEV_MODE_PERIODIC) - clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); + clockevents_set_mode(td->evtdev, CLOCK_EVT_MODE_SHUTDOWN); spin_unlock_irqrestore(&tick_device_lock, flags); } -static void tick_resume_periodic(void) +static void tick_resume(void) { struct tick_device *td = &__get_cpu_var(tick_cpu_device); unsigned long flags; @@ -317,6 +316,8 @@ static void tick_resume_periodic(void) spin_lock_irqsave(&tick_device_lock, flags); if (td->mode == TICKDEV_MODE_PERIODIC) tick_setup_periodic(td->evtdev, 0); + else + tick_resume_oneshot(); spin_unlock_irqrestore(&tick_device_lock, flags); } @@ -348,13 +349,13 @@ static int tick_notify(struct notifier_b break; case CLOCK_EVT_NOTIFY_SUSPEND: - tick_suspend_periodic(); + tick_suspend(); tick_suspend_broadcast(); break; case CLOCK_EVT_NOTIFY_RESUME: if (!tick_resume_broadcast()) - tick_resume_periodic(); + tick_resume(); break; default: Index: linux-2.6.21-rc5/kernel/time/tick-internal.h =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/tick-internal.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/tick-internal.h 2007-03-27 14:20:38.000000000 +0100 @@ -19,12 +19,13 @@ extern void tick_setup_oneshot(struct cl extern int tick_program_event(ktime_t expires, int force); extern void tick_oneshot_notify(void); extern int tick_switch_to_oneshot(void (*handler)(struct clock_event_device *)); - +extern void tick_resume_oneshot(void); # ifdef CONFIG_GENERIC_CLOCKEVENTS_BROADCAST extern void tick_broadcast_setup_oneshot(struct clock_event_device *bc); extern void tick_broadcast_oneshot_control(unsigned long reason); extern void tick_broadcast_switch_to_oneshot(void); extern void tick_shutdown_broadcast_oneshot(unsigned int *cpup); +extern int tick_resume_broadcast_oneshot(struct clock_event_device *bc); # else /* BROADCAST */ static inline void tick_broadcast_setup_oneshot(struct clock_event_device *bc) { @@ -43,6 +44,10 @@ void tick_setup_oneshot(struct clock_eve { BUG(); } +static inline void tick_resume_oneshot(void) +{ + BUG(); +} static inline int tick_program_event(ktime_t expires, int force) { return 0; @@ -54,6 +59,10 @@ static inline void tick_broadcast_setup_ } static inline void tick_broadcast_oneshot_control(unsigned long reason) { } static inline void tick_shutdown_broadcast_oneshot(unsigned int *cpup) { } +static inline int tick_resume_broadcast_oneshot(struct clock_event_device *bc) +{ + return 0; +} #endif /* !TICK_ONESHOT */ /* Index: linux-2.6.21-rc5/kernel/time/tick-oneshot.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/tick-oneshot.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/tick-oneshot.c 2007-03-27 14:20:38.000000000 +0100 @@ -41,6 +41,18 @@ int tick_program_event(ktime_t expires, } /** + * tick_resume_onshot - resume oneshot mode + */ +void tick_resume_oneshot(void) +{ + struct tick_device *td = &__get_cpu_var(tick_cpu_device); + struct clock_event_device *dev = td->evtdev; + + clockevents_set_mode(dev, CLOCK_EVT_MODE_ONESHOT); + tick_program_event(ktime_get(), 1); +} + +/** * tick_setup_oneshot - setup the event device for oneshot mode (hres or nohz) */ void tick_setup_oneshot(struct clock_event_device *newdev, Index: linux-2.6.21-rc5/kernel/time/timer_list.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/time/timer_list.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/time/timer_list.c 2007-03-27 14:20:38.000000000 +0100 @@ -194,9 +194,9 @@ print_tickdevice(struct seq_file *m, str return; } SEQ_printf(m, "%s\n", dev->name); - SEQ_printf(m, " max_delta_ns: %ld\n", dev->max_delta_ns); - SEQ_printf(m, " min_delta_ns: %ld\n", dev->min_delta_ns); - SEQ_printf(m, " mult: %ld\n", dev->mult); + SEQ_printf(m, " max_delta_ns: %lu\n", dev->max_delta_ns); + SEQ_printf(m, " min_delta_ns: %lu\n", dev->min_delta_ns); + SEQ_printf(m, " mult: %lu\n", dev->mult); SEQ_printf(m, " shift: %d\n", dev->shift); SEQ_printf(m, " mode: %d\n", dev->mode); SEQ_printf(m, " next_event: %Ld nsecs\n", Index: linux-2.6.21-rc5/kernel/timer.c =================================================================== --- linux-2.6.21-rc5.orig/kernel/timer.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/kernel/timer.c 2007-03-27 14:20:38.000000000 +0100 @@ -695,15 +695,28 @@ static unsigned long cmp_next_hrtimer_ev { ktime_t hr_delta = hrtimer_get_next_event(); struct timespec tsdelta; + unsigned long delta; if (hr_delta.tv64 == KTIME_MAX) return expires; - if (hr_delta.tv64 <= TICK_NSEC) - return now; + /* + * Expired timer available, let it expire in the next tick + */ + if (hr_delta.tv64 <= 0) + return now + 1; tsdelta = ktime_to_timespec(hr_delta); - now += timespec_to_jiffies(&tsdelta); + delta = timespec_to_jiffies(&tsdelta); + /* + * Take rounding errors in to account and make sure, that it + * expires in the next tick. Otherwise we go into an endless + * ping pong due to tick_nohz_stop_sched_tick() retriggering + * the timer softirq + */ + if (delta < 1) + delta = 1; + now += delta; if (time_before(now, expires)) return now; return expires; Index: linux-2.6.21-rc5/mm/backing-dev.c =================================================================== --- linux-2.6.21-rc5.orig/mm/backing-dev.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/mm/backing-dev.c 2007-03-27 14:20:38.000000000 +0100 @@ -55,6 +55,22 @@ long congestion_wait(int rw, long timeou } EXPORT_SYMBOL(congestion_wait); +long congestion_wait_interruptible(int rw, long timeout) +{ + long ret; + DEFINE_WAIT(wait); + wait_queue_head_t *wqh = &congestion_wqh[rw]; + + prepare_to_wait(wqh, &wait, TASK_INTERRUPTIBLE); + if (signal_pending(current)) + ret = -ERESTARTSYS; + else + ret = io_schedule_timeout(timeout); + finish_wait(wqh, &wait); + return ret; +} +EXPORT_SYMBOL(congestion_wait_interruptible); + /** * congestion_end - wake up sleepers on a congested backing_dev_info * @rw: READ or WRITE Index: linux-2.6.21-rc5/mm/filemap.c =================================================================== --- linux-2.6.21-rc5.orig/mm/filemap.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/mm/filemap.c 2007-03-27 14:20:38.000000000 +0100 @@ -2379,7 +2379,8 @@ generic_file_direct_IO(int rw, struct ki struct file *file = iocb->ki_filp; struct address_space *mapping = file->f_mapping; ssize_t retval; - size_t write_len = 0; + size_t write_len; + pgoff_t end = 0; /* silence gcc */ /* * If it's a write, unmap all mmappings of the file up-front. This @@ -2388,23 +2389,46 @@ generic_file_direct_IO(int rw, struct ki */ if (rw == WRITE) { write_len = iov_length(iov, nr_segs); + end = (offset + write_len - 1) >> PAGE_CACHE_SHIFT; if (mapping_mapped(mapping)) unmap_mapping_range(mapping, offset, write_len, 0); } retval = filemap_write_and_wait(mapping); - if (retval == 0) { - retval = mapping->a_ops->direct_IO(rw, iocb, iov, - offset, nr_segs); - if (rw == WRITE && mapping->nrpages) { - pgoff_t end = (offset + write_len - 1) - >> PAGE_CACHE_SHIFT; - int err = invalidate_inode_pages2_range(mapping, + if (retval) + goto out; + + /* + * After a write we want buffered reads to be sure to go to disk to get + * the new data. We invalidate clean cached page from the region we're + * about to write. We do this *before* the write so that we can return + * -EIO without clobbering -EIOCBQUEUED from ->direct_IO(). + */ + if (rw == WRITE && mapping->nrpages) { + retval = invalidate_inode_pages2_range(mapping, offset >> PAGE_CACHE_SHIFT, end); - if (err) - retval = err; - } + if (retval) + goto out; + } + + retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs); + if (retval) + goto out; + + /* + * Finally, try again to invalidate clean pages which might have been + * faulted in by get_user_pages() if the source of the write was an + * mmap()ed region of the file we're writing. That's a pretty crazy + * thing to do, so we don't support it 100%. If this invalidation + * fails and we have -EIOCBQUEUED we ignore the failure. + */ + if (rw == WRITE && mapping->nrpages) { + int err = invalidate_inode_pages2_range(mapping, + offset >> PAGE_CACHE_SHIFT, end); + if (err && retval >= 0) + retval = err; } +out: return retval; } Index: linux-2.6.21-rc5/mm/madvise.c =================================================================== --- linux-2.6.21-rc5.orig/mm/madvise.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/mm/madvise.c 2007-03-27 14:20:38.000000000 +0100 @@ -155,11 +155,14 @@ static long madvise_dontneed(struct vm_a * Other filesystems return -ENOSYS. */ static long madvise_remove(struct vm_area_struct *vma, + struct vm_area_struct **prev, unsigned long start, unsigned long end) { struct address_space *mapping; loff_t offset, endoff; + *prev = vma; + if (vma->vm_flags & (VM_LOCKED|VM_NONLINEAR|VM_HUGETLB)) return -EINVAL; @@ -199,7 +202,7 @@ madvise_vma(struct vm_area_struct *vma, error = madvise_behavior(vma, prev, start, end, behavior); break; case MADV_REMOVE: - error = madvise_remove(vma, start, end); + error = madvise_remove(vma, prev, start, end); break; case MADV_WILLNEED: Index: linux-2.6.21-rc5/mm/nommu.c =================================================================== --- linux-2.6.21-rc5.orig/mm/nommu.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/mm/nommu.c 2007-03-27 14:20:38.000000000 +0100 @@ -826,6 +826,11 @@ unsigned long do_mmap_pgoff(struct file unsigned long pglen = (len + PAGE_SIZE - 1) >> PAGE_SHIFT; unsigned long vmpglen; + /* suppress VMA sharing for shared regions */ + if (vm_flags & VM_SHARED && + capabilities & BDI_CAP_MAP_DIRECT) + goto dont_share_VMAs; + for (rb = rb_first(&nommu_vma_tree); rb; rb = rb_next(rb)) { vma = rb_entry(rb, struct vm_area_struct, vm_rb); @@ -859,6 +864,7 @@ unsigned long do_mmap_pgoff(struct file goto shared; } + dont_share_VMAs: vma = NULL; /* obtain the address at which to make a shared mapping @@ -1193,6 +1199,28 @@ void unmap_mapping_range(struct address_ EXPORT_SYMBOL(unmap_mapping_range); /* + * ask for an unmapped area at which to create a mapping on a file + */ +unsigned long get_unmapped_area(struct file *file, unsigned long addr, + unsigned long len, unsigned long pgoff, + unsigned long flags) +{ + unsigned long (*get_area)(struct file *, unsigned long, unsigned long, + unsigned long, unsigned long); + + get_area = current->mm->get_unmapped_area; + if (file && file->f_op && file->f_op->get_unmapped_area) + get_area = file->f_op->get_unmapped_area; + + if (!get_area) + return -ENOSYS; + + return get_area(file, addr, len, pgoff, flags); +} + +EXPORT_SYMBOL(get_unmapped_area); + +/* * Check that a process has enough memory to allocate a new virtual * mapping. 0 means there is enough memory for the allocation to * succeed and -ENOMEM implies there is not. Index: linux-2.6.21-rc5/mm/oom_kill.c =================================================================== --- linux-2.6.21-rc5.orig/mm/oom_kill.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/mm/oom_kill.c 2007-03-27 14:20:38.000000000 +0100 @@ -320,7 +320,7 @@ static int oom_kill_task(struct task_str * Don't kill the process if any threads are set to OOM_DISABLE */ do_each_thread(g, q) { - if (q->mm == mm && p->oomkilladj == OOM_DISABLE) + if (q->mm == mm && q->oomkilladj == OOM_DISABLE) return 1; } while_each_thread(g, q); Index: linux-2.6.21-rc5/net/bluetooth/hidp/core.c =================================================================== --- linux-2.6.21-rc5.orig/net/bluetooth/hidp/core.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/bluetooth/hidp/core.c 2007-03-27 14:20:38.000000000 +0100 @@ -319,7 +319,7 @@ static int __hidp_send_ctrl_message(stru return 0; } -static int inline hidp_send_ctrl_message(struct hidp_session *session, +static inline int hidp_send_ctrl_message(struct hidp_session *session, unsigned char hdr, unsigned char *data, int size) { int err; Index: linux-2.6.21-rc5/net/bridge/br_fdb.c =================================================================== --- linux-2.6.21-rc5.orig/net/bridge/br_fdb.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/bridge/br_fdb.c 2007-03-27 14:20:38.000000000 +0100 @@ -197,8 +197,8 @@ struct net_bridge_fdb_entry *br_fdb_get( rcu_read_lock(); fdb = __br_fdb_get(br, addr); - if (fdb) - atomic_inc(&fdb->use_count); + if (fdb && !atomic_inc_not_zero(&fdb->use_count)) + fdb = NULL; rcu_read_unlock(); return fdb; } Index: linux-2.6.21-rc5/net/bridge/br_netfilter.c =================================================================== --- linux-2.6.21-rc5.orig/net/bridge/br_netfilter.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/bridge/br_netfilter.c 2007-03-27 14:20:38.000000000 +0100 @@ -61,7 +61,7 @@ static int brnf_filter_vlan_tagged __rea #define brnf_filter_vlan_tagged 1 #endif -static __be16 inline vlan_proto(const struct sk_buff *skb) +static inline __be16 vlan_proto(const struct sk_buff *skb) { return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; } Index: linux-2.6.21-rc5/net/core/fib_rules.c =================================================================== --- linux-2.6.21-rc5.orig/net/core/fib_rules.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/core/fib_rules.c 2007-03-27 14:20:38.000000000 +0100 @@ -374,7 +374,7 @@ int fib_rules_dump(struct sk_buff *skb, return -EAFNOSUPPORT; rcu_read_lock(); - list_for_each_entry(rule, ops->rules_list, list) { + list_for_each_entry_rcu(rule, ops->rules_list, list) { if (idx < cb->args[0]) goto skip; Index: linux-2.6.21-rc5/net/core/skbuff.c =================================================================== --- linux-2.6.21-rc5.orig/net/core/skbuff.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/core/skbuff.c 2007-03-27 14:20:38.000000000 +0100 @@ -463,6 +463,7 @@ struct sk_buff *skb_clone(struct sk_buff memcpy(n->cb, skb->cb, sizeof(skb->cb)); C(len); C(data_len); + C(mac_len); C(csum); C(local_df); n->cloned = 1; Index: linux-2.6.21-rc5/net/core/sock.c =================================================================== --- linux-2.6.21-rc5.orig/net/core/sock.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/core/sock.c 2007-03-27 14:20:38.000000000 +0100 @@ -808,7 +808,7 @@ lenout: * * (We also register the sk_lock with the lock validator.) */ -static void inline sock_lock_init(struct sock *sk) +static inline void sock_lock_init(struct sock *sk) { sock_lock_init_class_and_name(sk, af_family_slock_key_strings[sk->sk_family], Index: linux-2.6.21-rc5/net/ieee80211/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/net/ieee80211/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ieee80211/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -38,7 +38,7 @@ config IEEE80211_CRYPT_WEP Include software based cipher suites in support of IEEE 802.11's WEP. This is needed for WEP as well as 802.1x. - This can be compiled as a modules and it will be called + This can be compiled as a module and it will be called "ieee80211_crypt_wep". config IEEE80211_CRYPT_CCMP @@ -51,7 +51,7 @@ config IEEE80211_CRYPT_CCMP (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with CCMP enabled networks. - This can be compiled as a modules and it will be called + This can be compiled as a module and it will be called "ieee80211_crypt_ccmp". config IEEE80211_CRYPT_TKIP @@ -66,7 +66,7 @@ config IEEE80211_CRYPT_TKIP (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled networks. - This can be compiled as a modules and it will be called + This can be compiled as a module and it will be called "ieee80211_crypt_tkip". source "net/ieee80211/softmac/Kconfig" Index: linux-2.6.21-rc5/net/ipv4/fib_trie.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv4/fib_trie.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv4/fib_trie.c 2007-03-27 14:20:38.000000000 +0100 @@ -1527,7 +1527,6 @@ static int trie_leaf_remove(struct trie t->revision++; t->size--; - preempt_disable(); tp = NODE_PARENT(n); tnode_free((struct tnode *) n); @@ -1537,7 +1536,6 @@ static int trie_leaf_remove(struct trie rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); } else rcu_assign_pointer(t->trie, NULL); - preempt_enable(); return 1; } Index: linux-2.6.21-rc5/net/ipv4/netfilter/ip_nat_standalone.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv4/netfilter/ip_nat_standalone.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv4/netfilter/ip_nat_standalone.c 2007-03-27 14:20:38.000000000 +0100 @@ -253,14 +253,17 @@ ip_nat_local_fn(unsigned int hooknum, enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); if (ct->tuplehash[dir].tuple.dst.ip != - ct->tuplehash[!dir].tuple.src.ip -#ifdef CONFIG_XFRM - || ct->tuplehash[dir].tuple.dst.u.all != - ct->tuplehash[!dir].tuple.src.u.all -#endif - ) + ct->tuplehash[!dir].tuple.src.ip) { if (ip_route_me_harder(pskb, RTN_UNSPEC)) ret = NF_DROP; + } +#ifdef CONFIG_XFRM + else if (ct->tuplehash[dir].tuple.dst.u.all != + ct->tuplehash[!dir].tuple.src.u.all) + if (ip_xfrm_me_harder(pskb)) + ret = NF_DROP; +#endif + } return ret; } Index: linux-2.6.21-rc5/net/ipv4/netfilter/nf_nat_standalone.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv4/netfilter/nf_nat_standalone.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv4/netfilter/nf_nat_standalone.c 2007-03-27 14:20:38.000000000 +0100 @@ -245,14 +245,16 @@ nf_nat_local_fn(unsigned int hooknum, enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); if (ct->tuplehash[dir].tuple.dst.u3.ip != - ct->tuplehash[!dir].tuple.src.u3.ip -#ifdef CONFIG_XFRM - || ct->tuplehash[dir].tuple.dst.u.all != - ct->tuplehash[!dir].tuple.src.u.all -#endif - ) + ct->tuplehash[!dir].tuple.src.u3.ip) { if (ip_route_me_harder(pskb, RTN_UNSPEC)) ret = NF_DROP; + } +#ifdef CONFIG_XFRM + else if (ct->tuplehash[dir].tuple.dst.u.all != + ct->tuplehash[!dir].tuple.src.u.all) + if (ip_xfrm_me_harder(pskb)) + ret = NF_DROP; +#endif } return ret; } Index: linux-2.6.21-rc5/net/ipv4/tcp.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv4/tcp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv4/tcp.c 2007-03-27 14:20:38.000000000 +0100 @@ -2458,11 +2458,18 @@ void __init tcp_init(void) sysctl_max_syn_backlog = 128; } - /* Allow no more than 3/4 kernel memory (usually less) allocated to TCP */ - sysctl_tcp_mem[0] = (1536 / sizeof (struct inet_bind_hashbucket)) << order; - sysctl_tcp_mem[1] = sysctl_tcp_mem[0] * 4 / 3; + /* Set the pressure threshold to be a fraction of global memory that + * is up to 1/2 at 256 MB, decreasing toward zero with the amount of + * memory, with a floor of 128 pages. + */ + limit = min(nr_all_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); + limit = (limit * (nr_all_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); + limit = max(limit, 128UL); + sysctl_tcp_mem[0] = limit / 4 * 3; + sysctl_tcp_mem[1] = limit; sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; + /* Set per-socket limits to no more than 1/128 the pressure threshold */ limit = ((unsigned long)sysctl_tcp_mem[1]) << (PAGE_SHIFT - 7); max_share = min(4UL*1024*1024, limit); Index: linux-2.6.21-rc5/net/ipv6/addrconf.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv6/addrconf.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv6/addrconf.c 2007-03-27 14:20:38.000000000 +0100 @@ -804,7 +804,7 @@ struct ipv6_saddr_score { #define IPV6_SADDR_SCORE_LABEL 0x0020 #define IPV6_SADDR_SCORE_PRIVACY 0x0040 -static int inline ipv6_saddr_preferred(int type) +static inline int ipv6_saddr_preferred(int type) { if (type & (IPV6_ADDR_MAPPED|IPV6_ADDR_COMPATv4| IPV6_ADDR_LOOPBACK|IPV6_ADDR_RESERVED)) @@ -813,7 +813,7 @@ static int inline ipv6_saddr_preferred(i } /* static matching label */ -static int inline ipv6_saddr_label(const struct in6_addr *addr, int type) +static inline int ipv6_saddr_label(const struct in6_addr *addr, int type) { /* * prefix (longest match) label @@ -3318,7 +3318,7 @@ errout: rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); } -static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, +static inline void ipv6_store_devconf(struct ipv6_devconf *cnf, __s32 *array, int bytes) { BUG_ON(bytes < (DEVCONF_MAX * 4)); Index: linux-2.6.21-rc5/net/ipv6/route.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv6/route.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv6/route.c 2007-03-27 14:20:38.000000000 +0100 @@ -308,7 +308,7 @@ static inline void rt6_probe(struct rt6_ /* * Default Router Selection (RFC 2461 6.3.6) */ -static int inline rt6_check_dev(struct rt6_info *rt, int oif) +static inline int rt6_check_dev(struct rt6_info *rt, int oif) { struct net_device *dev = rt->rt6i_dev; int ret = 0; @@ -328,7 +328,7 @@ static int inline rt6_check_dev(struct r return ret; } -static int inline rt6_check_neigh(struct rt6_info *rt) +static inline int rt6_check_neigh(struct rt6_info *rt) { struct neighbour *neigh = rt->rt6i_nexthop; int m = 0; Index: linux-2.6.21-rc5/net/ipv6/tcp_ipv6.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv6/tcp_ipv6.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv6/tcp_ipv6.c 2007-03-27 14:20:38.000000000 +0100 @@ -1453,6 +1453,7 @@ static struct sock * tcp_v6_syn_recv_soc First: no IPv4 options. */ newinet->opt = NULL; + newnp->ipv6_fl_list = NULL; /* Clone RX bits */ newnp->rxopt.all = np->rxopt.all; Index: linux-2.6.21-rc5/net/ipv6/xfrm6_tunnel.c =================================================================== --- linux-2.6.21-rc5.orig/net/ipv6/xfrm6_tunnel.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/ipv6/xfrm6_tunnel.c 2007-03-27 14:20:38.000000000 +0100 @@ -58,7 +58,7 @@ static struct kmem_cache *xfrm6_tunnel_s static struct hlist_head xfrm6_tunnel_spi_byaddr[XFRM6_TUNNEL_SPI_BYADDR_HSIZE]; static struct hlist_head xfrm6_tunnel_spi_byspi[XFRM6_TUNNEL_SPI_BYSPI_HSIZE]; -static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) +static inline unsigned xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr) { unsigned h; @@ -70,7 +70,7 @@ static unsigned inline xfrm6_tunnel_spi_ return h; } -static unsigned inline xfrm6_tunnel_spi_hash_byspi(u32 spi) +static inline unsigned xfrm6_tunnel_spi_hash_byspi(u32 spi) { return spi % XFRM6_TUNNEL_SPI_BYSPI_HSIZE; } Index: linux-2.6.21-rc5/net/irda/irnet/irnet.h =================================================================== --- linux-2.6.21-rc5.orig/net/irda/irnet/irnet.h 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/irda/irnet/irnet.h 2007-03-27 14:20:38.000000000 +0100 @@ -419,7 +419,7 @@ typedef struct irnet_socket u32 raccm; /* to please pppd - dummy) */ unsigned int flags; /* PPP flags (compression, ...) */ unsigned int rbits; /* Unused receive flags ??? */ - + struct work_struct disconnect_work; /* Process context disconnection */ /* ------------------------ IrTTP part ------------------------ */ /* We create a pseudo "socket" over the IrDA tranport */ unsigned long ttp_open; /* Set when IrTTP is ready */ Index: linux-2.6.21-rc5/net/irda/irnet/irnet_irda.c =================================================================== --- linux-2.6.21-rc5.orig/net/irda/irnet/irnet_irda.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/irda/irnet/irnet_irda.c 2007-03-27 14:20:38.000000000 +0100 @@ -10,6 +10,27 @@ #include "irnet_irda.h" /* Private header */ +/* + * PPP disconnect work: we need to make sure we're in + * process context when calling ppp_unregister_channel(). + */ +static void irnet_ppp_disconnect(struct work_struct *work) +{ + irnet_socket * self = + container_of(work, irnet_socket, disconnect_work); + + if (self == NULL) + return; + /* + * If we were connected, cleanup & close the PPP + * channel, which will kill pppd (hangup) and the rest. + */ + if (self->ppp_open && !self->ttp_open && !self->ttp_connect) { + ppp_unregister_channel(&self->chan); + self->ppp_open = 0; + } +} + /************************* CONTROL CHANNEL *************************/ /* * When ppp is not active, /dev/irnet act as a control channel. @@ -499,6 +520,8 @@ irda_irnet_create(irnet_socket * self) #endif /* DISCOVERY_NOMASK */ self->tx_flow = FLOW_START; /* Flow control from IrTTP */ + INIT_WORK(&self->disconnect_work, irnet_ppp_disconnect); + DEXIT(IRDA_SOCK_TRACE, "\n"); return(0); } @@ -1134,15 +1157,8 @@ irnet_disconnect_indication(void * insta { if(test_open) { -#ifdef MISSING_PPP_API - /* ppp_unregister_channel() wants a user context, which we - * are guaranteed to NOT have here. What are we supposed - * to do here ? Jean II */ - /* If we were connected, cleanup & close the PPP channel, - * which will kill pppd (hangup) and the rest */ - ppp_unregister_channel(&self->chan); - self->ppp_open = 0; -#endif + /* ppp_unregister_channel() wants a user context. */ + schedule_work(&self->disconnect_work); } else { Index: linux-2.6.21-rc5/net/irda/irttp.c =================================================================== --- linux-2.6.21-rc5.orig/net/irda/irttp.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/irda/irttp.c 2007-03-27 14:20:38.000000000 +0100 @@ -1455,6 +1455,7 @@ struct tsap_cb *irttp_dup(struct tsap_cb /* Not everything should be copied */ new->notify.instance = instance; + spin_lock_init(&new->lock); init_timer(&new->todo_timer); skb_queue_head_init(&new->rx_queue); Index: linux-2.6.21-rc5/net/netfilter/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/net/netfilter/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/netfilter/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -275,6 +275,7 @@ config NF_CT_NETLINK tristate 'Connection tracking netlink interface (EXPERIMENTAL)' depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK depends on NF_CONNTRACK!=y || NETFILTER_NETLINK!=m + depends on NF_NAT=n || NF_NAT help This option enables support for a netlink-based userspace interface Index: linux-2.6.21-rc5/net/sched/cls_route.c =================================================================== --- linux-2.6.21-rc5.orig/net/sched/cls_route.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/sched/cls_route.c 2007-03-27 14:20:38.000000000 +0100 @@ -93,7 +93,7 @@ void route4_reset_fastmap(struct net_dev spin_unlock_bh(&dev->queue_lock); } -static void __inline__ +static inline void route4_set_fastmap(struct route4_head *head, u32 id, int iif, struct route4_filter *f) { Index: linux-2.6.21-rc5/net/sctp/associola.c =================================================================== --- linux-2.6.21-rc5.orig/net/sctp/associola.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/sctp/associola.c 2007-03-27 14:20:38.000000000 +0100 @@ -1046,6 +1046,9 @@ void sctp_assoc_update(struct sctp_assoc trans = list_entry(pos, struct sctp_transport, transports); if (!sctp_assoc_lookup_paddr(new, &trans->ipaddr)) sctp_assoc_del_peer(asoc, &trans->ipaddr); + + if (asoc->state >= SCTP_STATE_ESTABLISHED) + sctp_transport_reset(trans); } /* If the case is A (association restart), use @@ -1063,6 +1066,18 @@ void sctp_assoc_update(struct sctp_assoc */ sctp_ssnmap_clear(asoc->ssnmap); + /* Flush the ULP reassembly and ordered queue. + * Any data there will now be stale and will + * cause problems. + */ + sctp_ulpq_flush(&asoc->ulpq); + + /* reset the overall association error count so + * that the restarted association doesn't get torn + * down on the next retransmission timer. + */ + asoc->overall_error_count = 0; + } else { /* Add any peer addresses from the new association. */ list_for_each(pos, &new->peer.transport_addr_list) { Index: linux-2.6.21-rc5/net/sctp/sm_statefuns.c =================================================================== --- linux-2.6.21-rc5.orig/net/sctp/sm_statefuns.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/sctp/sm_statefuns.c 2007-03-27 14:20:38.000000000 +0100 @@ -4342,8 +4342,24 @@ sctp_disposition_t sctp_sf_do_prm_reques void *arg, sctp_cmd_seq_t *commands) { - return sctp_sf_heartbeat(ep, asoc, type, (struct sctp_transport *)arg, - commands); + if (SCTP_DISPOSITION_NOMEM == sctp_sf_heartbeat(ep, asoc, type, + (struct sctp_transport *)arg, commands)) + return SCTP_DISPOSITION_NOMEM; + + /* + * RFC 2960 (bis), section 8.3 + * + * D) Request an on-demand HEARTBEAT on a specific destination + * transport address of a given association. + * + * The endpoint should increment the respective error counter of + * the destination transport address each time a HEARTBEAT is sent + * to that address and not acknowledged within one RTO. + * + */ + sctp_add_cmd_sf(commands, SCTP_CMD_TRANSPORT_RESET, + SCTP_TRANSPORT(arg)); + return SCTP_DISPOSITION_CONSUME; } /* Index: linux-2.6.21-rc5/net/sctp/transport.c =================================================================== --- linux-2.6.21-rc5.orig/net/sctp/transport.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/sctp/transport.c 2007-03-27 14:20:38.000000000 +0100 @@ -526,3 +526,35 @@ unsigned long sctp_transport_timeout(str timeout += jiffies; return timeout; } + +/* Reset transport variables to their initial values */ +void sctp_transport_reset(struct sctp_transport *t) +{ + struct sctp_association *asoc = t->asoc; + + /* RFC 2960 (bis), Section 5.2.4 + * All the congestion control parameters (e.g., cwnd, ssthresh) + * related to this peer MUST be reset to their initial values + * (see Section 6.2.1) + */ + t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); + t->ssthresh = asoc->peer.i.a_rwnd; + t->rto = asoc->rto_initial; + t->rtt = 0; + t->srtt = 0; + t->rttvar = 0; + + /* Reset these additional varibles so that we have a clean + * slate. + */ + t->partial_bytes_acked = 0; + t->flight_size = 0; + t->error_count = 0; + t->rto_pending = 0; + + /* Initialize the state information for SFR-CACC */ + t->cacc.changeover_active = 0; + t->cacc.cycling_changeover = 0; + t->cacc.next_tsn_at_change = 0; + t->cacc.cacc_saw_newack = 0; +} Index: linux-2.6.21-rc5/net/sctp/ulpqueue.c =================================================================== --- linux-2.6.21-rc5.orig/net/sctp/ulpqueue.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/sctp/ulpqueue.c 2007-03-27 14:20:38.000000000 +0100 @@ -73,7 +73,7 @@ struct sctp_ulpq *sctp_ulpq_init(struct /* Flush the reassembly and ordering queues. */ -static void sctp_ulpq_flush(struct sctp_ulpq *ulpq) +void sctp_ulpq_flush(struct sctp_ulpq *ulpq) { struct sk_buff *skb; struct sctp_ulpevent *event; Index: linux-2.6.21-rc5/net/x25/x25_forward.c =================================================================== --- linux-2.6.21-rc5.orig/net/x25/x25_forward.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/x25/x25_forward.c 2007-03-27 14:20:38.000000000 +0100 @@ -26,64 +26,66 @@ int x25_forward_call(struct x25_address short same_lci = 0; int rc = 0; - if ((rt = x25_get_route(dest_addr)) != NULL) { + if ((rt = x25_get_route(dest_addr)) == NULL) + goto out_no_route; - if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) { - /* This shouldnt happen, if it occurs somehow - * do something sensible - */ - goto out_put_route; - } - - /* Avoid a loop. This is the normal exit path for a - * system with only one x.25 iface and default route + if ((neigh_new = x25_get_neigh(rt->dev)) == NULL) { + /* This shouldnt happen, if it occurs somehow + * do something sensible */ - if (rt->dev == from->dev) { - goto out_put_nb; - } + goto out_put_route; + } - /* Remote end sending a call request on an already - * established LCI? It shouldnt happen, just in case.. - */ - read_lock_bh(&x25_forward_list_lock); - list_for_each(entry, &x25_forward_list) { - x25_frwd = list_entry(entry, struct x25_forward, node); - if (x25_frwd->lci == lci) { - printk(KERN_WARNING "X.25: call request for lci which is already registered!, transmitting but not registering new pair\n"); - same_lci = 1; - } - } - read_unlock_bh(&x25_forward_list_lock); + /* Avoid a loop. This is the normal exit path for a + * system with only one x.25 iface and default route + */ + if (rt->dev == from->dev) { + goto out_put_nb; + } - /* Save the forwarding details for future traffic */ - if (!same_lci){ - if ((new_frwd = kmalloc(sizeof(struct x25_forward), - GFP_ATOMIC)) == NULL){ - rc = -ENOMEM; - goto out_put_nb; - } - new_frwd->lci = lci; - new_frwd->dev1 = rt->dev; - new_frwd->dev2 = from->dev; - write_lock_bh(&x25_forward_list_lock); - list_add(&new_frwd->node, &x25_forward_list); - write_unlock_bh(&x25_forward_list_lock); + /* Remote end sending a call request on an already + * established LCI? It shouldnt happen, just in case.. + */ + read_lock_bh(&x25_forward_list_lock); + list_for_each(entry, &x25_forward_list) { + x25_frwd = list_entry(entry, struct x25_forward, node); + if (x25_frwd->lci == lci) { + printk(KERN_WARNING "X.25: call request for lci which is already registered!, transmitting but not registering new pair\n"); + same_lci = 1; } + } + read_unlock_bh(&x25_forward_list_lock); - /* Forward the call request */ - if ( (skbn = skb_clone(skb, GFP_ATOMIC)) == NULL){ + /* Save the forwarding details for future traffic */ + if (!same_lci){ + if ((new_frwd = kmalloc(sizeof(struct x25_forward), + GFP_ATOMIC)) == NULL){ + rc = -ENOMEM; goto out_put_nb; } - x25_transmit_link(skbn, neigh_new); - rc = 1; + new_frwd->lci = lci; + new_frwd->dev1 = rt->dev; + new_frwd->dev2 = from->dev; + write_lock_bh(&x25_forward_list_lock); + list_add(&new_frwd->node, &x25_forward_list); + write_unlock_bh(&x25_forward_list_lock); } + /* Forward the call request */ + if ( (skbn = skb_clone(skb, GFP_ATOMIC)) == NULL){ + goto out_put_nb; + } + x25_transmit_link(skbn, neigh_new); + rc = 1; + out_put_nb: x25_neigh_put(neigh_new); out_put_route: x25_route_put(rt); + +out_no_route: return rc; } Index: linux-2.6.21-rc5/net/xfrm/xfrm_policy.c =================================================================== --- linux-2.6.21-rc5.orig/net/xfrm/xfrm_policy.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/xfrm/xfrm_policy.c 2007-03-27 14:20:38.000000000 +0100 @@ -2089,7 +2089,7 @@ void xfrm_audit_log(uid_t auid, u32 sid, sizeof(struct in6_addr)); } audit_log_format(audit_buf, - " src=" NIP6_FMT "dst=" NIP6_FMT, + " src=" NIP6_FMT " dst=" NIP6_FMT, NIP6(saddr6), NIP6(daddr6)); } break; Index: linux-2.6.21-rc5/net/xfrm/xfrm_user.c =================================================================== --- linux-2.6.21-rc5.orig/net/xfrm/xfrm_user.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/net/xfrm/xfrm_user.c 2007-03-27 14:20:38.000000000 +0100 @@ -2025,7 +2025,7 @@ nlmsg_failure: return -1; } -static int inline xfrm_sa_len(struct xfrm_state *x) +static inline int xfrm_sa_len(struct xfrm_state *x) { int l = 0; if (x->aalg) Index: linux-2.6.21-rc5/sound/pci/ac97/ac97_patch.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/ac97/ac97_patch.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/ac97/ac97_patch.c 2007-03-27 14:20:38.000000000 +0100 @@ -1962,9 +1962,11 @@ static int snd_ac97_ad1888_downmix_put(s static void ad1888_update_jacks(struct snd_ac97 *ac97) { unsigned short val = 0; - if (! is_shared_linein(ac97)) + /* clear LODIS if shared jack is to be used for Surround out */ + if (is_shared_linein(ac97)) val |= (1 << 12); - if (! is_shared_micin(ac97)) + /* clear CLDIS if shared jack is to be used for C/LFE out */ + if (is_shared_micin(ac97)) val |= (1 << 11); /* shared Line-In */ snd_ac97_update_bits(ac97, AC97_AD_MISC, (1 << 11) | (1 << 12), val); @@ -2136,8 +2138,9 @@ static const struct snd_kcontrol_new snd static void ad1985_update_jacks(struct snd_ac97 *ac97) { ad1888_update_jacks(ac97); + /* clear OMS if shared jack is to be used for C/LFE out */ snd_ac97_update_bits(ac97, AC97_AD_SERIAL_CFG, 1 << 9, - is_shared_micin(ac97) ? 0 : 1 << 9); + is_shared_micin(ac97) ? 1 << 9 : 0); } static int patch_ad1985_specific(struct snd_ac97 *ac97) @@ -2418,9 +2421,9 @@ static void ad1986_update_jacks(struct s unsigned short ser_val; /* disable SURROUND and CENTER/LFE if not surround mode */ - if (! is_surround_on(ac97)) + if (!is_surround_on(ac97)) misc_val |= AC97_AD1986_SODIS; - if (! is_clfe_on(ac97)) + if (!is_clfe_on(ac97)) misc_val |= AC97_AD1986_CLDIS; /* select line input (default=LINE_IN, SURROUND or MIC_1/2) */ Index: linux-2.6.21-rc5/sound/pci/hda/hda_intel.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/hda/hda_intel.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/hda/hda_intel.c 2007-03-27 14:20:38.000000000 +0100 @@ -199,7 +199,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO /* STATESTS int mask: SD2,SD1,SD0 */ #define STATESTS_INT_MASK 0x07 -#define AZX_MAX_CODECS 3 /* SD_CTL bits */ #define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ @@ -966,6 +965,16 @@ static int azx_setup_controller(struct a * Codec initialization */ +static unsigned int azx_max_codecs[] __devinitdata = { + [AZX_DRIVER_ICH] = 3, + [AZX_DRIVER_ATI] = 4, + [AZX_DRIVER_ATIHDMI] = 4, + [AZX_DRIVER_VIA] = 3, /* FIXME: correct? */ + [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ + [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ + [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ +}; + static int __devinit azx_codec_create(struct azx *chip, const char *model) { struct hda_bus_template bus_temp; @@ -982,7 +991,7 @@ static int __devinit azx_codec_create(st return err; codecs = 0; - for (c = 0; c < AZX_MAX_CODECS; c++) { + for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { err = snd_hda_codec_new(chip->bus, c, NULL); if (err < 0) @@ -1078,6 +1087,10 @@ static int azx_pcm_open(struct snd_pcm_s runtime->hw.rates = hinfo->rates; snd_pcm_limit_hw_rates(runtime); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + 128); + snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + 128); if ((err = hinfo->ops.open(hinfo, apcm->codec, substream)) < 0) { azx_release_device(azx_dev); mutex_unlock(&chip->open_mutex); Index: linux-2.6.21-rc5/sound/pci/hda/patch_analog.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/hda/patch_analog.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/hda/patch_analog.c 2007-03-27 14:20:38.000000000 +0100 @@ -833,12 +833,14 @@ static struct snd_pci_quirk ad1986a_cfg_ SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), + SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), SND_PCI_QUIRK(0x144d, 0xc023, "Samsung X60", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x144d, 0xc024, "Samsung R65", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x144d, 0xc026, "Samsung X11", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), + SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), @@ -1205,7 +1207,7 @@ static struct hda_verb ad1981_init_verbs /* * Patch for HP nx6320 * - * nx6320 uses EAPD in the reserve way - EAPD-on means the internal + * nx6320 uses EAPD in the reverse way - EAPD-on means the internal * speaker output enabled _and_ mute-LED off. */ @@ -1373,6 +1375,21 @@ static int ad1981_hp_init(struct hda_cod return 0; } +/* configuration for Toshiba Laptops */ +static struct hda_verb ad1981_toshiba_init_verbs[] = { + {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ + /* pin sensing on HP and Mic jacks */ + {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, + {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, + {} +}; + +static struct snd_kcontrol_new ad1981_toshiba_mixers[] = { + HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), + { } +}; + /* configuration for Lenovo Thinkpad T60 */ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), @@ -1418,6 +1435,7 @@ enum { AD1981_BASIC, AD1981_HP, AD1981_THINKPAD, + AD1981_TOSHIBA, AD1981_MODELS }; @@ -1425,6 +1443,7 @@ static const char *ad1981_models[AD1981_ [AD1981_HP] = "hp", [AD1981_THINKPAD] = "thinkpad", [AD1981_BASIC] = "basic", + [AD1981_TOSHIBA] = "toshiba" }; static struct snd_pci_quirk ad1981_cfg_tbl[] = { @@ -1435,6 +1454,7 @@ static struct snd_pci_quirk ad1981_cfg_t /* Lenovo Thinkpad T60/X60/Z6xx */ SND_PCI_QUIRK(0x17aa, 0, "Lenovo Thinkpad", AD1981_THINKPAD), SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), + SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), {} }; @@ -1485,8 +1505,17 @@ static int patch_ad1981(struct hda_codec spec->mixers[0] = ad1981_thinkpad_mixers; spec->input_mux = &ad1981_thinkpad_capture_source; break; + case AD1981_TOSHIBA: + spec->mixers[0] = ad1981_hp_mixers; + spec->mixers[1] = ad1981_toshiba_mixers; + spec->num_init_verbs = 2; + spec->init_verbs[1] = ad1981_toshiba_init_verbs; + spec->multiout.dig_out_nid = 0; + spec->input_mux = &ad1981_hp_capture_source; + codec->patch_ops.init = ad1981_hp_init; + codec->patch_ops.unsol_event = ad1981_hp_unsol_event; + break; } - return 0; } @@ -2607,6 +2636,12 @@ static const char *ad1988_models[AD1988_ [AD1988_AUTO] = "auto", }; +static struct snd_pci_quirk ad1988_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), + SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), + {} +}; + static int patch_ad1988(struct hda_codec *codec) { struct ad198x_spec *spec; @@ -2623,7 +2658,7 @@ static int patch_ad1988(struct hda_codec snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, - ad1988_models, NULL); + ad1988_models, ad1988_cfg_tbl); if (board_config < 0) { printk(KERN_INFO "hda_codec: Unknown model for AD1988, trying auto-probe from BIOS...\n"); board_config = AD1988_AUTO; Index: linux-2.6.21-rc5/sound/pci/hda/patch_realtek.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/hda/patch_realtek.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/hda/patch_realtek.c 2007-03-27 14:20:38.000000000 +0100 @@ -4186,6 +4186,8 @@ static const char *alc260_models[ALC260_ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), + SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013), + SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP), SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), Index: linux-2.6.21-rc5/sound/pci/hda/patch_sigmatel.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/hda/patch_sigmatel.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/hda/patch_sigmatel.c 2007-03-27 14:20:38.000000000 +0100 @@ -60,7 +60,8 @@ enum { STAC_D945GTP5, STAC_MACMINI, STAC_MACBOOK, - STAC_MACBOOK_PRO, + STAC_MACBOOK_PRO_V1, + STAC_MACBOOK_PRO_V2, STAC_922X_MODELS }; @@ -529,7 +530,13 @@ static unsigned int macbook_pin_configs[ 0x400000fc, 0x400000fb, }; -static unsigned int macbook_pro_pin_configs[10] = { +static unsigned int macbook_pro_v1_pin_configs[10] = { + 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, + 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, + 0x02a19320, 0x400000fb +}; + +static unsigned int macbook_pro_v2_pin_configs[10] = { 0x0221401f, 0x90a70120, 0x01813024, 0x01014010, 0x400000fd, 0x01016011, 0x1345e240, 0x13c5e22e, 0x400000fc, 0x400000fb, @@ -541,7 +548,8 @@ static unsigned int *stac922x_brd_tbl[ST [STAC_D945GTP5] = d945gtp5_pin_configs, [STAC_MACMINI] = d945gtp5_pin_configs, [STAC_MACBOOK] = macbook_pin_configs, - [STAC_MACBOOK_PRO] = macbook_pro_pin_configs, + [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { @@ -550,7 +558,8 @@ static const char *stac922x_models[STAC_ [STAC_D945GTP3] = "3stack", [STAC_MACMINI] = "macmini", [STAC_MACBOOK] = "macbook", - [STAC_MACBOOK_PRO] = "macbook-pro", + [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", + [STAC_MACBOOK_PRO_V2] = "macbook-pro", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -1600,6 +1609,11 @@ static int stac92xx_init(struct hda_code for (i = 0; i < cfg->hp_outs; i++) enable_pin_detect(codec, cfg->hp_pins[i], STAC_HP_EVENT); + /* force to enable the first line-out; the others are set up + * in unsol_event + */ + stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], + AC_PINCTL_OUT_EN); stac92xx_auto_init_hp_out(codec); /* fake event to set up pins */ codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); @@ -1889,9 +1903,13 @@ static int patch_stac922x(struct hda_cod /* Intel Macs have all same PCI SSID, so we need to check * codec SSID to distinguish the exact models */ + printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { - case 0x106b1e00: - spec->board_config = STAC_MACBOOK_PRO; + case 0x106b0200: /* MacBook Pro first generation */ + spec->board_config = STAC_MACBOOK_PRO_V1; + break; + case 0x106b1e00: /* MacBook Pro second generation */ + spec->board_config = STAC_MACBOOK_PRO_V2; break; } } Index: linux-2.6.21-rc5/sound/pci/intel8x0.c =================================================================== --- linux-2.6.21-rc5.orig/sound/pci/intel8x0.c 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/pci/intel8x0.c 2007-03-27 14:20:38.000000000 +0100 @@ -725,10 +725,11 @@ static void fill_nocache(void *buf, int static inline void snd_intel8x0_update(struct intel8x0 *chip, struct ichdev *ichdev) { unsigned long port = ichdev->reg_offset; + unsigned long flags; int status, civ, i, step; int ack = 0; - spin_lock(&chip->reg_lock); + spin_lock_irqsave(&chip->reg_lock, flags); status = igetbyte(chip, port + ichdev->roff_sr); civ = igetbyte(chip, port + ICH_REG_OFF_CIV); if (!(status & ICH_BCIS)) { @@ -768,7 +769,7 @@ static inline void snd_intel8x0_update(s ack = 1; } } - spin_unlock(&chip->reg_lock); + spin_unlock_irqrestore(&chip->reg_lock, flags); if (ack && ichdev->substream) { snd_pcm_period_elapsed(ichdev->substream); } @@ -2470,7 +2471,10 @@ static int intel8x0_suspend(struct pci_d } pci_disable_device(pci); pci_save_state(pci); - pci_set_power_state(pci, pci_choose_state(pci, state)); + /* The call below may disable built-in speaker on some laptops + * after S2RAM. So, don't touch it. + */ + /* pci_set_power_state(pci, pci_choose_state(pci, state)); */ return 0; } Index: linux-2.6.21-rc5/sound/soc/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/sound/soc/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/soc/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -10,6 +10,8 @@ config SND_SOC_AC97_BUS config SND_SOC tristate "SoC audio support" + depends on SND + select SND_PCM ---help--- If you want SoC support, you should say Y here and also to the Index: linux-2.6.21-rc5/sound/soc/at91/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/sound/soc/at91/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/soc/at91/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -2,8 +2,7 @@ menu "SoC Audio for the Atmel AT91" config SND_AT91_SOC tristate "SoC Audio for the Atmel AT91 System-on-Chip" - depends on ARCH_AT91 && SND - select SND_PCM + depends on ARCH_AT91 && SND_SOC help Say Y or M if you want to add support for codecs attached to the AT91 SSC interface. You will also need Index: linux-2.6.21-rc5/sound/soc/pxa/Kconfig =================================================================== --- linux-2.6.21-rc5.orig/sound/soc/pxa/Kconfig 2007-03-27 14:20:36.000000000 +0100 +++ linux-2.6.21-rc5/sound/soc/pxa/Kconfig 2007-03-27 14:20:38.000000000 +0100 @@ -2,8 +2,7 @@ menu "SoC Audio for the Intel PXA2xx" config SND_PXA2XX_SOC tristate "SoC Audio for the Intel PXA2xx chip" - depends on ARCH_PXA && SND - select SND_PCM + depends on ARCH_PXA && SND_SOC help Say Y or M if you want to add support for codecs attached to the PXA2xx AC97, I2S or SSP interface. You will also need