diff options
309 files changed, 2096 insertions, 4083 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index c3b1430cf60..0bc8b0b2e10 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -316,3 +316,11 @@ Why: The option/code is Who: Johannes Berg <johannes@sipsolutions.net> --------------------------- + +What: i8xx_tco watchdog driver +When: in 2.6.22 +Why: the i8xx_tco watchdog driver has been replaced by the iTCO_wdt + watchdog driver. +Who: Wim Van Sebroeck <wim@iguana.be> + +--------------------------- diff --git a/Documentation/gpio.txt b/Documentation/gpio.txt index 576ce463cf4..989f1130f4f 100644 --- a/Documentation/gpio.txt +++ b/Documentation/gpio.txt @@ -105,12 +105,15 @@ setting up a platform_device using the GPIO, is mark its direction: /* 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 diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index db398a6441c..73e9a174b64 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -866,6 +866,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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 'snd_' prefix. This was removed. 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 diff --git a/MAINTAINERS b/MAINTAINERS index 17555bba20a..6d8d5b917d1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3103,6 +3103,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 @@ -1,8 +1,8 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 21 -EXTRAVERSION = -rc3 -NAME = Homicidal Dwarf Hamster +EXTRAVERSION = -rc4 +NAME = Nocturnal Monster Puppy # *DOCUMENTATION* # To see a list of typical targets execute "make help" diff --git a/arch/arm/common/Kconfig b/arch/arm/common/Kconfig index 5e34ca6d38b..3e073467cac 100644 --- a/arch/arm/common/Kconfig +++ b/arch/arm/common/Kconfig @@ -28,6 +28,7 @@ config SHARP_PARAM config SHARPSL_PM bool + select APM_EMULATION config SHARP_SCOOP bool diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c index 44211a0af19..ba4a1bb3ee4 100644 --- a/arch/arm/mach-at91/gpio.c +++ b/arch/arm/mach-at91/gpio.c @@ -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; } diff --git a/arch/arm/mach-imx/cpufreq.c b/arch/arm/mach-imx/cpufreq.c index 4f66e90db74..7e70e0b0b98 100644 --- a/arch/arm/mach-imx/cpufreq.c +++ b/arch/arm/mach-imx/cpufreq.c @@ -50,6 +50,7 @@ #define CR_920T_ASYNC_MODE 0xC0000000 static u32 mpctl0_at_boot; +static u32 bclk_div_at_boot; static void imx_set_async_mode(void) { @@ -82,13 +83,13 @@ static void imx_set_mpctl0(u32 mpctl0) * imx_compute_mpctl - compute new PLL parameters * @new_mpctl: pointer to location assigned by new PLL control register value * @cur_mpctl: current PLL control register parameters + * @f_ref: reference source frequency Hz * @freq: required frequency in Hz * @relation: is one of %CPUFREQ_RELATION_L (supremum) * and %CPUFREQ_RELATION_H (infimum) */ -long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, unsigned long freq, int relation) +long imx_compute_mpctl(u32 *new_mpctl, u32 cur_mpctl, u32 f_ref, unsigned long freq, int relation) { - u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); u32 mfi; u32 mfn; u32 mfd; @@ -182,7 +183,7 @@ static int imx_set_target(struct cpufreq_policy *policy, unsigned long flags; long freq; long sysclk; - unsigned int bclk_div = 1; + unsigned int bclk_div = bclk_div_at_boot; /* * Some governors do not respects CPU and policy lower limits @@ -202,8 +203,8 @@ static int imx_set_target(struct cpufreq_policy *policy, sysclk = imx_get_system_clk(); - if (freq > sysclk + 1000000) { - freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, freq, relation); + if (freq > sysclk / bclk_div_at_boot + 1000000) { + freq = imx_compute_mpctl(&mpctl0, mpctl0_at_boot, CLK32 * 512, freq, relation); if (freq < 0) { printk(KERN_WARNING "imx: target frequency %ld Hz cannot be set\n", freq); return -EINVAL; @@ -217,6 +218,8 @@ static int imx_set_target(struct cpufreq_policy *policy, if(bclk_div > 16) bclk_div = 16; + if(bclk_div < bclk_div_at_boot) + bclk_div = bclk_div_at_boot; } freq = (sysclk + bclk_div / 2) / bclk_div; } @@ -285,7 +288,7 @@ static struct cpufreq_driver imx_driver = { static int __init imx_cpufreq_init(void) { - + bclk_div_at_boot = __mfld2val(CSCR_BCLK_DIV, CSCR) + 1; mpctl0_at_boot = 0; if((CSCR & CSCR_MPEN) && diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index b5aa49d00ca..7a7fa51ec62 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -102,7 +102,7 @@ EXPORT_SYMBOL(imx_gpio_mode); * f = 2 * f_ref * -------------------- * pd + 1 */ -static unsigned int imx_decode_pll(unsigned int pll) +static unsigned int imx_decode_pll(unsigned int pll, u32 f_ref) { unsigned long long ll; unsigned long quot; @@ -111,7 +111,6 @@ static unsigned int imx_decode_pll(unsigned int pll) u32 mfn = pll & 0x3ff; u32 mfd = (pll >> 16) & 0x3ff; u32 pd = (pll >> 26) & 0xf; - u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); mfi = mfi <= 5 ? 5 : mfi; @@ -124,13 +123,15 @@ static unsigned int imx_decode_pll(unsigned int pll) unsigned int imx_get_system_clk(void) { - return imx_decode_pll(SPCTL0); + u32 f_ref = (CSCR & CSCR_SYSTEM_SEL) ? 16000000 : (CLK32 * 512); + + return imx_decode_pll(SPCTL0, f_ref); } EXPORT_SYMBOL(imx_get_system_clk); unsigned int imx_get_mcu_clk(void) { - return imx_decode_pll(MPCTL0); + return imx_decode_pll(MPCTL0, CLK32 * 512); } EXPORT_SYMBOL(imx_get_mcu_clk); diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c index a193dd93151..760c9d0db7c 100644 --- a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c +++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c @@ -32,7 +32,7 @@ static void __init mach_cc9p9360dev_init_machine(void) board_a9m9750dev_init_machine(); } -MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard") +MACHINE_START(CC9P9360DEV, "Digi ConnectCore 9P 9360 on an A9M9750 Devboard") .map_io = mach_cc9p9360dev_map_io, .init_irq = mach_cc9p9360dev_init_irq, .init_machine = mach_cc9p9360dev_init_machine, diff --git a/arch/arm/mach-omap1/board-h2.c b/arch/arm/mach-omap1/board-h2.c index 6e113078f7a..ad519390dd5 100644 --- a/arch/arm/mach-omap1/board-h2.c +++ b/arch/arm/mach-omap1/board-h2.c @@ -27,6 +27,7 @@ #include <linux/mtd/nand.h> #include <linux/mtd/partitions.h> #include <linux/input.h> +#include <linux/workqueue.h> #include <asm/hardware.h> #include <asm/mach-types.h> diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index 0de201c3d50..5170481afea 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -27,6 +27,7 @@ #include <asm/arch/clock.h> #include <asm/arch/sram.h> +#include <asm/div64.h> #include "prcm-regs.h" #include "memory.h" diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index 8816f5a33a2..162978fd535 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -1013,7 +1013,8 @@ static struct clk dss2_fck = { /* Alt clk used in power management */ .name = "dss2_fck", .parent = &sys_ck, /* fixed at sys_ck or 48MHz */ .flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X | - RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED, + RATE_CKCTL | CM_CORE_SEL1 | RATE_FIXED | + DELAYED_APP, .enable_reg = (void __iomem *)&CM_FCLKEN1_CORE, .enable_bit = 1, .src_offset = 13, diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 7915a5a2286..72738771fb5 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -28,6 +28,7 @@ #include <asm/hardware.h> #include <asm/irq.h> #include <asm/system.h> +#include <asm/arch/pxa-regs.h> #include <asm/arch/irda.h> #include <asm/arch/mmc.h> #include <asm/arch/udc.h> @@ -35,8 +36,6 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> #include <asm/mach/irq.h> - -#include <asm/arch/pxa-regs.h> #include <asm/arch/tosa.h> #include <asm/hardware/scoop.h> diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c index 192a5a26cf2..9e13c8358ea 100644 --- a/arch/arm/mach-sa1100/generic.c +++ b/arch/arm/mach-sa1100/generic.c @@ -27,6 +27,7 @@ #include <asm/mach/map.h> #include <asm/mach/flash.h> #include <asm/irq.h> +#include <asm/gpio.h> #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; diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c index 9ba5654cde1..1eb99b814f5 100644 --- a/arch/avr32/mach-at32ap/pio.c +++ b/arch/avr32/mach-at32ap/pio.c @@ -214,7 +214,7 @@ int gpio_direction_input(unsigned int gpio) } 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 gpio) if (!pio) return -ENODEV; + gpio_set_value(gpio, value); + pin = gpio & 0x1f; pio_writel(pio, OER, 1 << pin); diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 27e8453274e..53d62373a52 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -220,7 +220,7 @@ config PARAVIRT config VMI bool "VMI Paravirt-ops support" - depends on PARAVIRT + depends on PARAVIRT && !COMPAT_VDSO help VMI provides a paravirtualized interface to the VMware ESX server (it could be used by other hypervisors in theory too, but is not diff --git a/arch/i386/defconfig b/arch/i386/defconfig index 5ae1e0bc8fd..f4efd66e1ee 100644 --- a/arch/i386/defconfig +++ b/arch/i386/defconfig @@ -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 diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 2383bcf18c5..5cff7970911 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -338,6 +338,7 @@ 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; apic_printk(APIC_VERBOSE, "Using local APIC timer interrupts.\n" "calibrating APIC timer ...\n"); @@ -357,7 +358,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 +396,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,68 +426,41 @@ 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; } if (!local_apic_timer_verify_ok) { diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index e3d4b73bfdb..4afe26e8626 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c @@ -28,3 +28,5 @@ EXPORT_SYMBOL(__read_lock_failed); #endif EXPORT_SYMBOL(csum_partial); + +EXPORT_SYMBOL(_proxy_pda); diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index 821df34d2b3..14702427b10 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -245,14 +245,6 @@ static int __init check_nmi_watchdog(void) unsigned int *prev_nmi_count; int cpu; - /* Enable NMI watchdog for newer systems. - Probably safe on most older systems too, but let's be careful. - IBM ThinkPads use INT10 inside SMM and that allows early NMI inside SMM - which hangs the system. Disable watchdog for all thinkpads */ - if (nmi_watchdog == NMI_DEFAULT && dmi_get_year(DMI_BIOS_DATE) >= 2004 && - !dmi_name_in_vendors("ThinkPad")) - nmi_watchdog = NMI_LOCAL_APIC; - if ((nmi_watchdog == NMI_NONE) || (nmi_watchdog == NMI_DEFAULT)) return 0; diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index 602660df455..0e65f7ab63a 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -105,7 +105,7 @@ unsigned long long sched_clock(void) /* * Fall back to jiffies if there's no TSC available: */ - if (unlikely(tsc_disable)) + if (tsc_unstable || unlikely(tsc_disable)) /* No locking but a rare wrong value is not a big deal: */ return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); diff --git a/arch/i386/kernel/vmi.c b/arch/i386/kernel/vmi.c index fbf45fa0832..fb07a1aad22 100644 --- a/arch/i386/kernel/vmi.c +++ b/arch/i386/kernel/vmi.c @@ -23,7 +23,6 @@ */ #include <linux/module.h> -#include <linux/license.h> #include <linux/cpu.h> #include <linux/bootmem.h> #include <linux/mm.h> @@ -48,7 +47,6 @@ typedef u64 __attribute__((regparm(2))) (VROMLONGFUNC)(int); (((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(struct vrom_header *rom) 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; } diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 600be3ebae0..6b10e5d2848 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -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; diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a1cd84f9b3b..5f29018a653 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -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 @@ -470,11 +470,6 @@ config MIPS_XXS1500 select SOC_AU1500 select SYS_SUPPORTS_LITTLE_ENDIAN -config PNX8550_V2PCI - bool "Philips PNX8550 based Viper2-PCI board" - select PNX8550 - select SYS_SUPPORTS_LITTLE_ENDIAN - config PNX8550_JBS bool "Philips PNX8550 based JBS board" select PNX8550 @@ -1564,6 +1559,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 @@ -1578,7 +1574,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 diff --git a/arch/mips/configs/atlas_defconfig b/arch/mips/configs/atlas_defconfig index 458894933a4..39e251300c6 100644 --- a/arch/mips/configs/atlas_defconfig +++ b/arch/mips/configs/atlas_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_ATLAS=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/bigsur_defconfig b/arch/mips/configs/bigsur_defconfig index aa05e294ea6..4713a13211c 100644 --- a/arch/mips/configs/bigsur_defconfig +++ b/arch/mips/configs/bigsur_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/capcella_defconfig b/arch/mips/configs/capcella_defconfig index b2594fa556f..5e7ae56b1f3 100644 --- a/arch/mips/configs/capcella_defconfig +++ b/arch/mips/configs/capcella_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/cobalt_defconfig b/arch/mips/configs/cobalt_defconfig index 9090a7aba6c..ba593b510b7 100644 --- a/arch/mips/configs/cobalt_defconfig +++ b/arch/mips/configs/cobalt_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_COBALT=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig index 4cb8cf4255a..0db6a8b3730 100644 --- a/arch/mips/configs/db1000_defconfig +++ b/arch/mips/configs/db1000_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_DB1000=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig index d86dedf27fc..162add97c5e 100644 --- a/arch/mips/configs/db1100_defconfig +++ b/arch/mips/configs/db1100_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_DB1100=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1200_defconfig b/arch/mips/configs/db1200_defconfig index c24b6008345..82801ec43e6 100644 --- a/arch/mips/configs/db1200_defconfig +++ b/arch/mips/configs/db1200_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_DB1200=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig index baad2c5223b..545f23094e1 100644 --- a/arch/mips/configs/db1500_defconfig +++ b/arch/mips/configs/db1500_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_DB1500=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig index c29fdab0423..5bd3b4328e5 100644 --- a/arch/mips/configs/db1550_defconfig +++ b/arch/mips/configs/db1550_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_DB1550=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ddb5477_defconfig b/arch/mips/configs/ddb5477_defconfig index f4b316d2cd7..5b502a2013f 100644 --- a/arch/mips/configs/ddb5477_defconfig +++ b/arch/mips/configs/ddb5477_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set CONFIG_DDB5477=y diff --git a/arch/mips/configs/decstation_defconfig b/arch/mips/configs/decstation_defconfig index 9c38e5c7776..4bbdab078ff 100644 --- a/arch/mips/configs/decstation_defconfig +++ b/arch/mips/configs/decstation_defconfig @@ -39,7 +39,6 @@ CONFIG_MACH_DECSTATION=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/e55_defconfig b/arch/mips/configs/e55_defconfig index 922af379aa4..b5714a6a539 100644 --- a/arch/mips/configs/e55_defconfig +++ b/arch/mips/configs/e55_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/emma2rh_defconfig b/arch/mips/configs/emma2rh_defconfig index c0db8f14713..3044579f171 100644 --- a/arch/mips/configs/emma2rh_defconfig +++ b/arch/mips/configs/emma2rh_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ev64120_defconfig b/arch/mips/configs/ev64120_defconfig index ce088b36291..c10e4e06322 100644 --- a/arch/mips/configs/ev64120_defconfig +++ b/arch/mips/configs/ev64120_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_EV64120=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/excite_defconfig b/arch/mips/configs/excite_defconfig index 82f204d080b..460d7a26a8b 100644 --- a/arch/mips/configs/excite_defconfig +++ b/arch/mips/configs/excite_defconfig @@ -40,7 +40,6 @@ CONFIG_BASLER_EXCITE=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ip22_defconfig b/arch/mips/configs/ip22_defconfig index cb81f13bd45..7ec618f3c8b 100644 --- a/arch/mips/configs/ip22_defconfig +++ b/arch/mips/configs/ip22_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ip27_defconfig b/arch/mips/configs/ip27_defconfig index 46f6ac4083b..9ddc3eff479 100644 --- a/arch/mips/configs/ip27_defconfig +++ b/arch/mips/configs/ip27_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index d9e5000d532..8fc18809d5f 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/jaguar-atx_defconfig b/arch/mips/configs/jaguar-atx_defconfig index 57ef0c45a62..083104daa2c 100644 --- a/arch/mips/configs/jaguar-atx_defconfig +++ b/arch/mips/configs/jaguar-atx_defconfig @@ -39,7 +39,6 @@ CONFIG_MOMENCO_JAGUAR_ATX=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/jazz_defconfig b/arch/mips/configs/jazz_defconfig index 21d979f8326..9331cb0a19b 100644 --- a/arch/mips/configs/jazz_defconfig +++ b/arch/mips/configs/jazz_defconfig @@ -39,7 +39,6 @@ CONFIG_MACH_JAZZ=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/jmr3927_defconfig b/arch/mips/configs/jmr3927_defconfig index 98b9fbc042f..21a094752da 100644 --- a/arch/mips/configs/jmr3927_defconfig +++ b/arch/mips/configs/jmr3927_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/lasat200_defconfig b/arch/mips/configs/lasat200_defconfig index b3f767ff1c5..fd4272c1458 100644 --- a/arch/mips/configs/lasat200_defconfig +++ b/arch/mips/configs/lasat200_defconfig @@ -39,7 +39,6 @@ CONFIG_LASAT=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/malta_defconfig b/arch/mips/configs/malta_defconfig index a5f379d626d..1f64d7632a0 100644 --- a/arch/mips/configs/malta_defconfig +++ b/arch/mips/configs/malta_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_MALTA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/mipssim_defconfig b/arch/mips/configs/mipssim_defconfig index 5ff53e18491..a2db5c20121 100644 --- a/arch/mips/configs/mipssim_defconfig +++ b/arch/mips/configs/mipssim_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_SIM=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/mpc30x_defconfig b/arch/mips/configs/mpc30x_defconfig index 750e6445c61..ad5c0bf87b2 100644 --- a/arch/mips/configs/mpc30x_defconfig +++ b/arch/mips/configs/mpc30x_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ocelot_3_defconfig b/arch/mips/configs/ocelot_3_defconfig index 2febd0a7fba..28547313ce1 100644 --- a/arch/mips/configs/ocelot_3_defconfig +++ b/arch/mips/configs/ocelot_3_defconfig @@ -39,7 +39,6 @@ CONFIG_MOMENCO_OCELOT_3=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ocelot_c_defconfig b/arch/mips/configs/ocelot_c_defconfig index b8f457300bb..82ff6fc0cd4 100644 --- a/arch/mips/configs/ocelot_c_defconfig +++ b/arch/mips/configs/ocelot_c_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y CONFIG_MOMENCO_OCELOT_C=y # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ocelot_defconfig b/arch/mips/configs/ocelot_defconfig index 8ade072271c..15a027e00ee 100644 --- a/arch/mips/configs/ocelot_defconfig +++ b/arch/mips/configs/ocelot_defconfig @@ -39,7 +39,6 @@ CONFIG_MOMENCO_OCELOT=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/ocelot_g_defconfig b/arch/mips/configs/ocelot_g_defconfig index d20a2216c11..7078e6b3ea1 100644 --- a/arch/mips/configs/ocelot_g_defconfig +++ b/arch/mips/configs/ocelot_g_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set CONFIG_MOMENCO_OCELOT_G=y # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pb1100_defconfig b/arch/mips/configs/pb1100_defconfig index 33fcc8133bc..69678d99ae6 100644 --- a/arch/mips/configs/pb1100_defconfig +++ b/arch/mips/configs/pb1100_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_PB1100=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pb1500_defconfig b/arch/mips/configs/pb1500_defconfig index e07c55dc8dc..070672799da 100644 --- a/arch/mips/configs/pb1500_defconfig +++ b/arch/mips/configs/pb1500_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_PB1500=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pb1550_defconfig b/arch/mips/configs/pb1550_defconfig index df210dd2247..354e49b7a5f 100644 --- a/arch/mips/configs/pb1550_defconfig +++ b/arch/mips/configs/pb1550_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_PB1550=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pnx8550-jbs_defconfig b/arch/mips/configs/pnx8550-jbs_defconfig index 106a1641c0b..fae16c5ec52 100644 --- a/arch/mips/configs/pnx8550-jbs_defconfig +++ b/arch/mips/configs/pnx8550-jbs_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set CONFIG_PNX8550_JBS=y # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pnx8550-stb810_defconfig b/arch/mips/configs/pnx8550-stb810_defconfig index 8caa2cd1aa7..cd821e52181 100644 --- a/arch/mips/configs/pnx8550-stb810_defconfig +++ b/arch/mips/configs/pnx8550-stb810_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set CONFIG_PNX8550_STB810=y # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/pnx8550-v2pci_defconfig b/arch/mips/configs/pnx8550-v2pci_defconfig index 43f1becec2a..3d6c2d74350 100644 --- a/arch/mips/configs/pnx8550-v2pci_defconfig +++ b/arch/mips/configs/pnx8550-v2pci_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -CONFIG_PNX8550_V2PCI=y # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/qemu_defconfig b/arch/mips/configs/qemu_defconfig index f68396d19f9..8e8d0315795 100644 --- a/arch/mips/configs/qemu_defconfig +++ b/arch/mips/configs/qemu_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig index a6a824fcc87..29e0df9f4be 100644 --- a/arch/mips/configs/rbhma4500_defconfig +++ b/arch/mips/configs/rbhma4500_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/rm200_defconfig b/arch/mips/configs/rm200_defconfig index bee3702d501..5593cde9f74 100644 --- a/arch/mips/configs/rm200_defconfig +++ b/arch/mips/configs/rm200_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/sb1250-swarm_defconfig b/arch/mips/configs/sb1250-swarm_defconfig index 3c891ed1014..6c4f09a381e 100644 --- a/arch/mips/configs/sb1250-swarm_defconfig +++ b/arch/mips/configs/sb1250-swarm_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/sead_defconfig b/arch/mips/configs/sead_defconfig index e31d964a053..988b9cdef01 100644 --- a/arch/mips/configs/sead_defconfig +++ b/arch/mips/configs/sead_defconfig @@ -39,7 +39,6 @@ CONFIG_MIPS_SEAD=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/tb0226_defconfig b/arch/mips/configs/tb0226_defconfig index 5771c1aee76..b5be8b74d89 100644 --- a/arch/mips/configs/tb0226_defconfig +++ b/arch/mips/configs/tb0226_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/tb0229_defconfig b/arch/mips/configs/tb0229_defconfig index a8eb4b182d3..1756d2bdf6b 100644 --- a/arch/mips/configs/tb0229_defconfig +++ b/arch/mips/configs/tb0229_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig index c58afa2eac6..8bb6be4342b 100644 --- a/arch/mips/configs/tb0287_defconfig +++ b/arch/mips/configs/tb0287_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/workpad_defconfig b/arch/mips/configs/workpad_defconfig index 2abbd682772..8f019ffcc71 100644 --- a/arch/mips/configs/workpad_defconfig +++ b/arch/mips/configs/workpad_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/wrppmc_defconfig b/arch/mips/configs/wrppmc_defconfig index 44b6b7c1fdb..52b48c0715d 100644 --- a/arch/mips/configs/wrppmc_defconfig +++ b/arch/mips/configs/wrppmc_defconfig @@ -39,7 +39,6 @@ CONFIG_WR_PPMC=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/configs/yosemite_defconfig b/arch/mips/configs/yosemite_defconfig index f24e1c6fc48..6824606309e 100644 --- a/arch/mips/configs/yosemite_defconfig +++ b/arch/mips/configs/yosemite_defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 8cb8f591919..41211f8b773 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -39,7 +39,6 @@ CONFIG_ZONE_DMA=y # CONFIG_MOMENCO_OCELOT_C is not set # CONFIG_MOMENCO_OCELOT_G is not set # CONFIG_MIPS_XXS1500 is not set -# CONFIG_PNX8550_V2PCI is not set # CONFIG_PNX8550_JBS is not set # CONFIG_PNX8550_STB810 is not set # CONFIG_DDB5477 is not set diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c index 5929f883e46..29eadd404fa 100644 --- a/arch/mips/kernel/kspd.c +++ b/arch/mips/kernel/kspd.c @@ -70,6 +70,7 @@ static int sp_stopping = 0; #define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7) #define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8) #define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9) +#define MTSP_SYSCALL_IOCTL (MTSP_SYSCALL_BASE + 10) #define MTSP_O_RDONLY 0x0000 #define MTSP_O_WRONLY 0x0001 @@ -110,7 +111,8 @@ struct apsp_table syscall_command_table[] = { { MTSP_SYSCALL_CLOSE, __NR_close }, { MTSP_SYSCALL_READ, __NR_read }, { MTSP_SYSCALL_WRITE, __NR_write }, - { MTSP_SYSCALL_LSEEK32, __NR_lseek } + { MTSP_SYSCALL_LSEEK32, __NR_lseek }, + { MTSP_SYSCALL_IOCTL, __NR_ioctl } }; static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3) @@ -189,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; @@ -199,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; } @@ -207,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; } @@ -280,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"); } diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 1df544c1f96..37849edd064 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c @@ -311,6 +311,8 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, 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 second, int third, u32 ptr, u32 fifth) 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) { diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 656bde2e11b..28c2e2e6af7 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S @@ -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. diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S index 59c1577ecbb..dbd42adc52e 100644 --- a/arch/mips/kernel/r4k_fpu.S +++ b/arch/mips/kernel/r4k_fpu.S @@ -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) diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index cc566cf1224..c7698fd9955 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S @@ -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 diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index e14ae09eda2..e6e3047151a 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c @@ -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) +ssize_t rtlx_read(int index, void __user *buff, 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) -{ - 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); - /* update the index */ - lx->lx_read += count; - lx->lx_read %= lx->buffer_size; +out: + count -= failed; + + 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 *buffer, size_t count, int user) 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); + } + +out: + count -= cailed; - rt->rt_write += count; - rt->rt_write %= rt->buffer_size; + smp_wmb(); + rt->rt_write = (rt->rt_write + count) % rt->buffer_size; + smp_wmb(); + mutex_unlock(&channel_wqs[index].mutex); - return(count); + return count; } @@ -403,7 +422,7 @@ static ssize_t file_read(struct file *file, char __user * buffer, size_t count, 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 *file, const char __user * buffer, 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); diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index fdbdbdc65b5..297dfcb9752 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h @@ -31,4 +31,7 @@ extern void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, */ 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 */ diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index f091786187a..8c3c5a5789b 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -82,6 +82,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) { 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 *regs, struct sigcontext __user *sc) 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 *regs, struct sigcontext __user *sc) 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_regargs struct pt_regs regs) { 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_regargs struct pt_regs regs) 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_regargs struct pt_regs regs) 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_regargs struct pt_regs regs) 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; diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 19bbef00195..151fd2f0893 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c @@ -181,6 +181,7 @@ static int setup_sigcontext32(struct pt_regs *regs, { 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_regs *regs, 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 pt_regs *regs, 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_regargs struct pt_regs regs) { 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_regargs struct pt_regs regs) 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_no_regargs struct pt_regs regs) 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_no_regargs struct pt_regs regs) 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)) diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index ecf1f7ecaad..a9202fa9598 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c @@ -127,6 +127,7 @@ asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) 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_no_regargs struct pt_regs regs) 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)) diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 18f56a9dbcf..7d76a85422b 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c @@ -610,16 +610,6 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) 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 *regs, unsigned long fcr31) * 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 *regs, unsigned long fcr31) 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 *regs) { 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 *regs) 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) { diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c index 5b3390f6491..ed49ef01ac5 100644 --- a/arch/mips/math-emu/kernel_linkage.c +++ b/arch/mips/math-emu/kernel_linkage.c @@ -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 sigcontext *sc) 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 sigcontext *sc) * 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 sigcontext32 *sc) return err; } -int fpu_emulator_restore_context32(struct sigcontext32 *sc) +int fpu_emulator_restore_context32(struct sigcontext32 __user *sc) { int i; int err = 0; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 9d08608aaa5..69a8bcfe72b 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c @@ -74,13 +74,13 @@ static inline void w_c0_ ## r ## n(unsigned int value) \ __define_perf_accessors(perfcntr, 0, 2) __define_perf_accessors(perfcntr, 1, 3) -__define_perf_accessors(perfcntr, 2, 2) -__define_perf_accessors(perfcntr, 3, 2) +__define_perf_accessors(perfcntr, 2, 0) +__define_perf_accessors(perfcntr, 3, 1) __define_perf_accessors(perfctrl, 0, 2) __define_perf_accessors(perfctrl, 1, 3) -__define_perf_accessors(perfctrl, 2, 2) -__define_perf_accessors(perfctrl, 3, 2) +__define_perf_accessors(perfctrl, 2, 0) +__define_perf_accessors(perfctrl, 3, 1) struct op_mips_model op_model_mipsxx_ops; @@ -97,7 +97,6 @@ static void mipsxx_reg_setup(struct op_counter_config *ctr) int i; /* Compute the performance counter control word. */ - /* For now count kernel and user mode */ for (i = 0; i < counters; i++) { reg.control[i] = 0; reg.counter[i] = 0; @@ -234,9 +233,6 @@ static inline int n_counters(void) counters = __n_counters(); } -#ifdef CONFIG_MIPS_MT_SMP - counters >> 1; -#endif return counters; } @@ -270,6 +266,10 @@ static int __init mipsxx_init(void) reset_counters(counters); +#ifdef CONFIG_MIPS_MT_SMP + counters >>= 1; +#endif + op_model_mipsxx_ops.num_counters = counters; switch (current_cpu_data.cputype) { case CPU_20KC: @@ -326,7 +326,11 @@ static int __init mipsxx_init(void) static void mipsxx_exit(void) { - reset_counters(op_model_mipsxx_ops.num_counters); + int counters = op_model_mipsxx_ops.num_counters; +#ifdef CONFIG_MIPS_MT_SMP + counters <<= 1; +#endif + reset_counters(counters); perf_irq = null_perf_irq; } diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index d48665ebd33..b1c4805a0b9 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c @@ -204,19 +204,7 @@ void __init arch_init_irq(void) * Note, PCI INTA is active low on the bus, but inverted * in the GIC, so to us it's active high. */ -#ifdef CONFIG_PNX8550_V2PCI - if (gic_int_line == (PNX8550_INT_GPIO0 - PNX8550_INT_GIC_MIN)) { - /* PCI INT through gpio 8, which is setup in - * pnx8550_setup.c and routed to GPIO - * Interrupt Level 0 (GPIO Connection 58). - * Set it active low. */ - - PNX8550_GIC_REQ(gic_int_line) = 0x1E020000; - } else -#endif - { - PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000; - } + PNX8550_GIC_REQ(i - PNX8550_INT_GIC_MIN) = 0x1E000000; /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 24367319ce2..cf7e316ad4f 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.20-rc5 -# Mon Jan 22 22:12:56 2007 +# Linux kernel version: 2.6.21-rc3 +# Fri Mar 9 23:34:53 2007 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -61,6 +61,7 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_IPC_NS is not set +CONFIG_SYSVIPC_SYSCTL=y # CONFIG_POSIX_MQUEUE is not set # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set @@ -71,6 +72,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_CPUSETS=y 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 @@ -133,6 +135,7 @@ CONFIG_PPC_MULTIPLATFORM=y # CONFIG_PPC_PSERIES is not set # CONFIG_PPC_ISERIES is not set # CONFIG_PPC_MPC52xx is not set +# CONFIG_PPC_MPC5200 is not set # CONFIG_PPC_PMAC is not set # CONFIG_PPC_MAPLE is not set # CONFIG_PPC_PASEMI is not set @@ -140,8 +143,10 @@ CONFIG_PPC_CELL=y CONFIG_PPC_CELL_NATIVE=y CONFIG_PPC_IBM_CELL_BLADE=y CONFIG_PPC_PS3=y +CONFIG_PPC_CELLEB=y CONFIG_PPC_NATIVE=y CONFIG_UDBG_RTAS_CONSOLE=y +CONFIG_PPC_UDBG_BEAT=y # CONFIG_U3_DART is not set CONFIG_PPC_RTAS=y # CONFIG_RTAS_ERROR_LOGGING is not set @@ -181,10 +186,13 @@ CONFIG_CBE_CPUFREQ=m # # PS3 Platform Options # +# CONFIG_PS3_ADVANCED is not set CONFIG_PS3_HTAB_SIZE=20 # CONFIG_PS3_DYNAMIC_DMA is not set CONFIG_PS3_USE_LPAR_ADDR=y CONFIG_PS3_VUART=y +CONFIG_PS3_PS3AV=y +CONFIG_PS3_SYS_MANAGER=y # # Kernel options @@ -226,6 +234,7 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y CONFIG_RESOURCES_64BIT=y +CONFIG_ZONE_DMA_FLAG=1 CONFIG_ARCH_MEMORY_PROBE=y CONFIG_NODES_SPAN_OTHER_NODES=y CONFIG_PPC_64K_PAGES=y @@ -239,6 +248,7 @@ CONFIG_ISA_DMA_API=y # # Bus options # +CONFIG_ZONE_DMA=y CONFIG_GENERIC_ISA_DMA=y # CONFIG_MPIC_WEIRD is not set # CONFIG_PPC_I8259 is not set @@ -274,6 +284,7 @@ CONFIG_UNIX=y CONFIG_XFRM=y # CONFIG_XFRM_USER is not set # CONFIG_XFRM_SUB_POLICY is not set +# CONFIG_XFRM_MIGRATE is not set # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y @@ -340,6 +351,7 @@ CONFIG_NETFILTER_XT_TARGET_DSCP=m CONFIG_NETFILTER_XT_TARGET_MARK=m CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m CONFIG_NETFILTER_XT_TARGET_NFLOG=m +CONFIG_NETFILTER_XT_TARGET_TCPMSS=m CONFIG_NETFILTER_XT_MATCH_COMMENT=m CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_DSCP=m @@ -376,7 +388,6 @@ CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m @@ -444,6 +455,7 @@ CONFIG_STANDALONE=y CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_FW_LOADER=y # CONFIG_DEBUG_DRIVER is not set +# CONFIG_DEBUG_DEVRES is not set # CONFIG_SYS_HYPERVISOR is not set # @@ -464,6 +476,7 @@ CONFIG_FW_LOADER=y # # Plug and Play support # +# CONFIG_PNPACPI is not set # # Block devices @@ -483,7 +496,6 @@ CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=16 CONFIG_BLK_DEV_RAM_SIZE=131072 CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024 -CONFIG_BLK_DEV_INITRD=y # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -537,6 +549,7 @@ CONFIG_BLK_DEV_AEC62XX=y # CONFIG_BLK_DEV_JMICRON is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT8213 is not set # CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set @@ -547,6 +560,8 @@ CONFIG_BLK_DEV_SIIMAGE=y # CONFIG_BLK_DEV_SLC90E66 is not set # CONFIG_BLK_DEV_TRM290 is not set # CONFIG_BLK_DEV_VIA82CXXX is not set +# CONFIG_BLK_DEV_TC86C001 is not set +CONFIG_BLK_DEV_IDE_CELLEB=y # CONFIG_IDE_ARM is not set CONFIG_BLK_DEV_IDEDMA=y # CONFIG_IDEDMA_IVB is not set @@ -557,7 +572,7 @@ CONFIG_IDEDMA_AUTO=y # SCSI device support # # CONFIG_RAID_ATTRS is not set -CONFIG_SCSI=m +CONFIG_SCSI=y # CONFIG_SCSI_TGT is not set # CONFIG_SCSI_NETLINK is not set CONFIG_SCSI_PROC_FS=y @@ -565,12 +580,12 @@ CONFIG_SCSI_PROC_FS=y # # SCSI support type (disk, tape, CD-ROM) # -CONFIG_BLK_DEV_SD=m +CONFIG_BLK_DEV_SD=y # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=m # CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_CHR_DEV_SG=m +CONFIG_CHR_DEV_SG=y # CONFIG_CHR_DEV_SCH is not set # @@ -587,7 +602,7 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_SPI_ATTRS is not set # CONFIG_SCSI_FC_ATTRS is not set # CONFIG_SCSI_ISCSI_ATTRS is not set -# CONFIG_SCSI_SAS_ATTRS is not set +CONFIG_SCSI_SAS_ATTRS=y # CONFIG_SCSI_SAS_LIBSAS is not set # @@ -617,6 +632,7 @@ CONFIG_CHR_DEV_SG=m # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_STEX is not set # CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_QLA_ISCSI is not set @@ -629,7 +645,60 @@ CONFIG_CHR_DEV_SG=m # # Serial ATA (prod) and Parallel ATA (experimental) drivers # -# CONFIG_ATA is not set +CONFIG_ATA=y +# CONFIG_ATA_NONSTANDARD is not set +# CONFIG_SATA_AHCI is not set +# CONFIG_SATA_SVW is not set +# CONFIG_ATA_PIIX is not set +# CONFIG_SATA_MV is not set +# CONFIG_SATA_NV is not set +# CONFIG_PDC_ADMA is not set +# CONFIG_SATA_QSTOR is not set +CONFIG_SATA_PROMISE=y +# CONFIG_SATA_SX4 is not set +# CONFIG_SATA_SIL is not set +# CONFIG_SATA_SIL24 is not set +# CONFIG_SATA_SIS is not set +# CONFIG_SATA_ULI is not set +# CONFIG_SATA_VIA is not set +# CONFIG_SATA_VITESSE is not set +# CONFIG_SATA_INIC162X is not set +# CONFIG_PATA_ALI is not set +# CONFIG_PATA_AMD is not set +# CONFIG_PATA_ARTOP is not set +# CONFIG_PATA_ATIIXP is not set +# CONFIG_PATA_CMD64X is not set +# CONFIG_PATA_CS5520 is not set +# CONFIG_PATA_CS5530 is not set +# CONFIG_PATA_CYPRESS is not set +# CONFIG_PATA_EFAR is not set +# CONFIG_ATA_GENERIC is not set +# CONFIG_PATA_HPT366 is not set +# CONFIG_PATA_HPT37X is not set +# CONFIG_PATA_HPT3X2N is not set +# CONFIG_PATA_HPT3X3 is not set +# CONFIG_PATA_IT821X is not set +# CONFIG_PATA_IT8213 is not set +# CONFIG_PATA_JMICRON is not set +# CONFIG_PATA_TRIFLEX is not set +# CONFIG_PATA_MARVELL is not set +# CONFIG_PATA_MPIIX is not set +# CONFIG_PATA_OLDPIIX is not set +# CONFIG_PATA_NETCELL is not set +# CONFIG_PATA_NS87410 is not set +# CONFIG_PATA_OPTI is not set +# CONFIG_PATA_OPTIDMA is not set +# CONFIG_PATA_PDC_OLD is not set +# CONFIG_PATA_RADISYS is not set +# CONFIG_PATA_RZ1000 is not set +# CONFIG_PATA_SC1200 is not set +# CONFIG_PATA_SERVERWORKS is not set +CONFIG_PATA_PDC2027X=m +# CONFIG_PATA_SIL680 is not set +# CONFIG_PATA_SIS is not set +# CONFIG_PATA_VIA is not set +# CONFIG_PATA_WINBOND is not set +# CONFIG_PATA_SCC is not set # # Multi-device support (RAID and LVM) @@ -655,10 +724,12 @@ CONFIG_DM_MULTIPATH=m # # Fusion MPT device support # -# CONFIG_FUSION is not set +CONFIG_FUSION=y # CONFIG_FUSION_SPI is not set # CONFIG_FUSION_FC is not set -# CONFIG_FUSION_SAS is not set +CONFIG_FUSION_SAS=y +CONFIG_FUSION_MAX_SGE=128 +# CONFIG_FUSION_CTL is not set # # IEEE 1394 (FireWire) support @@ -732,15 +803,18 @@ CONFIG_TIGON3=y # CONFIG_BNX2 is not set CONFIG_SPIDER_NET=y # CONFIG_QLA3XXX is not set +# CONFIG_ATL1 is not set # # Ethernet (10000 Mbit) # # CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set # CONFIG_IXGB is not set # CONFIG_S2IO is not set # CONFIG_MYRI10GE is not set # CONFIG_NETXEN_NIC is not set +# CONFIG_PASEMI_MAC is not set # # Token Ring devices @@ -853,16 +927,27 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_TXX9=y +CONFIG_HAS_TXX9_SERIAL=y +CONFIG_SERIAL_TXX9_NR_UARTS=2 +CONFIG_SERIAL_TXX9_CONSOLE=y # CONFIG_SERIAL_JSM is not set +CONFIG_SERIAL_OF_PLATFORM=y CONFIG_UNIX98_PTYS=y # CONFIG_LEGACY_PTYS is not set CONFIG_HVC_DRIVER=y CONFIG_HVC_RTAS=y +# CONFIG_HVC_BEAT is not set # # IPMI # -# CONFIG_IPMI_HANDLER is not set +CONFIG_IPMI_HANDLER=m +# CONFIG_IPMI_PANIC_EVENT is not set +CONFIG_IPMI_DEVICE_INTERFACE=m +CONFIG_IPMI_SI=m +CONFIG_IPMI_WATCHDOG=m +CONFIG_IPMI_POWEROFF=m # # Watchdog Cards @@ -874,7 +959,7 @@ CONFIG_WATCHDOG=y # Watchdog Device Drivers # # CONFIG_SOFT_WATCHDOG is not set -CONFIG_WATCHDOG_RTAS=y +# CONFIG_WATCHDOG_RTAS is not set # # PCI-based Watchdog Cards @@ -929,6 +1014,7 @@ CONFIG_I2C_ALGOBIT=y # 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 @@ -973,6 +1059,11 @@ CONFIG_I2C_ALGOBIT=y # CONFIG_HWMON_VID is not set # +# Multifunction device drivers +# +# CONFIG_MFD_SM501 is not set + +# # Multimedia devices # # CONFIG_VIDEO_DEV is not set @@ -986,7 +1077,7 @@ CONFIG_I2C_ALGOBIT=y # # Graphics support # -CONFIG_FIRMWARE_EDID=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # CONFIG_FB is not set # CONFIG_FB_IBM_GXT4500 is not set @@ -995,7 +1086,6 @@ CONFIG_FIRMWARE_EDID=y # # CONFIG_VGA_CONSOLE is not set CONFIG_DUMMY_CONSOLE=y -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -1006,6 +1096,7 @@ CONFIG_DUMMY_CONSOLE=y # HID Devices # CONFIG_HID=m +# CONFIG_HID_DEBUG is not set # # USB support @@ -1020,9 +1111,7 @@ CONFIG_USB=m # Miscellaneous USB options # CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set # CONFIG_USB_DYNAMIC_MINORS is not set -# CONFIG_USB_MULTITHREAD_PROBE is not set # CONFIG_USB_OTG is not set # @@ -1032,9 +1121,15 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set # CONFIG_USB_EHCI_TT_NEWSCHED is not set +CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y # CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_HCD_PPC_OF=y +CONFIG_USB_OHCI_HCD_PPC_OF_BE=y +# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set +CONFIG_USB_OHCI_HCD_PCI=y +CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y +CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set @@ -1088,6 +1183,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_ATI_REMOTE2 is not set # CONFIG_USB_KEYSPAN_REMOTE is not set # CONFIG_USB_APPLETOUCH is not set +# CONFIG_USB_GTCO is not set # # USB Imaging devices @@ -1125,6 +1221,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 @@ -1135,6 +1232,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 # @@ -1175,6 +1273,7 @@ CONFIG_INFINIBAND_MTHCA=m CONFIG_INFINIBAND_MTHCA_DEBUG=y # CONFIG_INFINIBAND_AMSO1100 is not set CONFIG_INFINIBAND_IPOIB=m +# CONFIG_INFINIBAND_IPOIB_CM is not set CONFIG_INFINIBAND_IPOIB_DEBUG=y CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y # CONFIG_INFINIBAND_SRP is not set @@ -1203,6 +1302,10 @@ CONFIG_INFINIBAND_IPOIB_DEBUG_DATA=y # # +# Auxiliary Display support +# + +# # Virtualization # @@ -1395,7 +1498,8 @@ CONFIG_TEXTSEARCH_KMP=m CONFIG_TEXTSEARCH_BM=m CONFIG_TEXTSEARCH_FSM=m CONFIG_PLIST=y -CONFIG_IOMAP_COPY=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT=y # # Instrumentation Support @@ -1414,15 +1518,16 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_FS=y # CONFIG_HEADERS_CHECK is not set CONFIG_DEBUG_KERNEL=y +# CONFIG_DEBUG_SHIRQ is not set CONFIG_LOG_BUF_SHIFT=15 -CONFIG_DETECT_SOFTLOCKUP=y +# CONFIG_DETECT_SOFTLOCKUP is not set # 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 # CONFIG_DEBUG_SPINLOCK is not set CONFIG_DEBUG_MUTEXES=y -# CONFIG_DEBUG_RWSEMS is not set CONFIG_DEBUG_SPINLOCK_SLEEP=y # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set # CONFIG_DEBUG_KOBJECT is not set @@ -1432,6 +1537,7 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_LIST is not set # CONFIG_FORCED_INLINING is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_FAULT_INJECTION is not set # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUGGER=y @@ -1469,8 +1575,10 @@ CONFIG_CRYPTO_SHA1=m # CONFIG_CRYPTO_GF128MUL is not set CONFIG_CRYPTO_ECB=m CONFIG_CRYPTO_CBC=m +CONFIG_CRYPTO_PCBC=m # CONFIG_CRYPTO_LRW is not set CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_FCRYPT is not set # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set # CONFIG_CRYPTO_SERPENT is not set @@ -1484,6 +1592,7 @@ CONFIG_CRYPTO_DES=m CONFIG_CRYPTO_DEFLATE=m # CONFIG_CRYPTO_MICHAEL_MIC is not set # CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_CAMELLIA is not set # CONFIG_CRYPTO_TEST is not set # diff --git a/arch/powerpc/kernel/udbg_16550.c b/arch/powerpc/kernel/udbg_16550.c index e738f93b42f..a963f657222 100644 --- a/arch/powerpc/kernel/udbg_16550.c +++ b/arch/powerpc/kernel/udbg_16550.c @@ -184,7 +184,7 @@ void udbg_pas_real_putc(char c) void udbg_init_pas_realmode(void) { - udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8; + udbg_comport = (volatile struct NS16550 __iomem *)0xfcff03f8UL; udbg_putc = udbg_pas_real_putc; udbg_getc = NULL; diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index c0d2a694fa3..3c7fe2c65b5 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -685,6 +685,9 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) "non-cacheable mapping\n"); psize = mmu_vmalloc_psize = MMU_PAGE_4K; } +#ifdef CONFIG_SPE_BASE + spu_flush_all_slbs(mm); +#endif } if (user_region) { if (psize != get_paca()->context.user_psize) { @@ -759,6 +762,9 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, mmu_psize_defs[MMU_PAGE_4K].sllp; get_paca()->context = mm->context; slb_flush_and_rebolt(); +#ifdef CONFIG_SPE_BASE + spu_flush_all_slbs(mm); +#endif } } if (mm->context.user_psize == MMU_PAGE_64K) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 8c77c791f87..f6ffaaa7a5b 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -24,6 +24,7 @@ #include <asm/machdep.h> #include <asm/cputable.h> #include <asm/tlb.h> +#include <asm/spu.h> #include <linux/sysctl.h> @@ -513,6 +514,9 @@ int prepare_hugepage_range(unsigned long addr, unsigned long len, pgoff_t pgoff) if ((addr + len) > 0x100000000UL) err = open_high_hpage_areas(current->mm, HTLB_AREA_MASK(addr, len)); +#ifdef CONFIG_SPE_BASE + spu_flush_all_slbs(current->mm); +#endif if (err) { printk(KERN_DEBUG "prepare_hugepage_range(%lx, %lx)" " failed (lowmask: 0x%04hx, highmask: 0x%04hx)\n", diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index c43999a10de..eba7a2641dc 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -38,8 +38,61 @@ const struct spu_management_ops *spu_management_ops; const struct spu_priv1_ops *spu_priv1_ops; +static struct list_head spu_list[MAX_NUMNODES]; +static LIST_HEAD(spu_full_list); +static DEFINE_MUTEX(spu_mutex); +static spinlock_t spu_list_lock = SPIN_LOCK_UNLOCKED; + EXPORT_SYMBOL_GPL(spu_priv1_ops); +void spu_invalidate_slbs(struct spu *spu) +{ + struct spu_priv2 __iomem *priv2 = spu->priv2; + + if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) + out_be64(&priv2->slb_invalidate_all_W, 0UL); +} +EXPORT_SYMBOL_GPL(spu_invalidate_slbs); + +/* This is called by the MM core when a segment size is changed, to + * request a flush of all the SPEs using a given mm + */ +void spu_flush_all_slbs(struct mm_struct *mm) +{ + struct spu *spu; + unsigned long flags; + + spin_lock_irqsave(&spu_list_lock, flags); + list_for_each_entry(spu, &spu_full_list, full_list) { + if (spu->mm == mm) + spu_invalidate_slbs(spu); + } + spin_unlock_irqrestore(&spu_list_lock, flags); +} + +/* The hack below stinks... try to do something better one of + * these days... Does it even work properly with NR_CPUS == 1 ? + */ +static inline void mm_needs_global_tlbie(struct mm_struct *mm) +{ + int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; + + /* Global TLBIE broadcast required with SPEs. */ + __cpus_setall(&mm->cpu_vm_mask, nr); +} + +void spu_associate_mm(struct spu *spu, struct mm_struct *mm) +{ + unsigned long flags; + + spin_lock_irqsave(&spu_list_lock, flags); + spu->mm = mm; + spin_unlock_irqrestore(&spu_list_lock, flags); + if (mm) + mm_needs_global_tlbie(mm); +} +EXPORT_SYMBOL_GPL(spu_associate_mm); + static int __spu_trap_invalid_dma(struct spu *spu) { pr_debug("%s\n", __FUNCTION__); @@ -74,6 +127,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) struct spu_priv2 __iomem *priv2 = spu->priv2; struct mm_struct *mm = spu->mm; u64 esid, vsid, llp; + int psize; pr_debug("%s\n", __FUNCTION__); @@ -90,22 +144,25 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) case USER_REGION_ID: #ifdef CONFIG_HUGETLB_PAGE if (in_hugepage_area(mm->context, ea)) - llp = mmu_psize_defs[mmu_huge_psize].sllp; + psize = mmu_huge_psize; else #endif - llp = mmu_psize_defs[mmu_virtual_psize].sllp; + psize = mm->context.user_psize; vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | - SLB_VSID_USER | llp; + SLB_VSID_USER; break; case VMALLOC_REGION_ID: - llp = mmu_psize_defs[mmu_virtual_psize].sllp; + if (ea < VMALLOC_END) + psize = mmu_vmalloc_psize; + else + psize = mmu_io_psize; vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | - SLB_VSID_KERNEL | llp; + SLB_VSID_KERNEL; break; case KERNEL_REGION_ID: - llp = mmu_psize_defs[mmu_linear_psize].sllp; + psize = mmu_linear_psize; vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | - SLB_VSID_KERNEL | llp; + SLB_VSID_KERNEL; break; default: /* Future: support kernel segments so that drivers @@ -114,9 +171,10 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) pr_debug("invalid region access at %016lx\n", ea); return 1; } + llp = mmu_psize_defs[psize].sllp; out_be64(&priv2->slb_index_W, spu->slb_replace); - out_be64(&priv2->slb_vsid_RW, vsid); + out_be64(&priv2->slb_vsid_RW, vsid | llp); out_be64(&priv2->slb_esid_RW, esid); spu->slb_replace++; @@ -330,10 +388,6 @@ static void spu_free_irqs(struct spu *spu) free_irq(spu->irqs[2], spu); } -static struct list_head spu_list[MAX_NUMNODES]; -static LIST_HEAD(spu_full_list); -static DEFINE_MUTEX(spu_mutex); - static void spu_init_channels(struct spu *spu) { static const struct { @@ -593,6 +647,7 @@ static int __init create_spu(void *data) struct spu *spu; int ret; static int number; + unsigned long flags; ret = -ENOMEM; spu = kzalloc(sizeof (*spu), GFP_KERNEL); @@ -620,8 +675,10 @@ static int __init create_spu(void *data) goto out_free_irqs; mutex_lock(&spu_mutex); + spin_lock_irqsave(&spu_list_lock, flags); list_add(&spu->list, &spu_list[spu->node]); list_add(&spu->full_list, &spu_full_list); + spin_unlock_irqrestore(&spu_list_lock, flags); mutex_unlock(&spu_mutex); goto out; diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index b00653d69c0..505266a568d 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -63,8 +63,8 @@ static ssize_t spufs_mem_read(struct file *file, char __user *buffer, size_t size, loff_t *pos) { - int ret; struct spu_context *ctx = file->private_data; + ssize_t ret; spu_acquire(ctx); ret = __spufs_mem_read(ctx, buffer, size, pos); @@ -74,25 +74,29 @@ spufs_mem_read(struct file *file, char __user *buffer, static ssize_t spufs_mem_write(struct file *file, const char __user *buffer, - size_t size, loff_t *pos) + size_t size, loff_t *ppos) { struct spu_context *ctx = file->private_data; char *local_store; + loff_t pos = *ppos; int ret; - size = min_t(ssize_t, LS_SIZE - *pos, size); - if (size <= 0) + if (pos < 0) + return -EINVAL; + if (pos > LS_SIZE) return -EFBIG; - *pos += size; + if (size > LS_SIZE - pos) + size = LS_SIZE - pos; spu_acquire(ctx); - local_store = ctx->ops->get_ls(ctx); - ret = copy_from_user(local_store + *pos - size, - buffer, size) ? -EFAULT : size; - + ret = copy_from_user(local_store + pos, buffer, size); spu_release(ctx); - return ret; + + if (ret) + return -EFAULT; + *ppos = pos + size; + return size; } static unsigned long spufs_mem_mmap_nopfn(struct vm_area_struct *vma, diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c index 353a8fa07ab..f95a611ca36 100644 --- a/arch/powerpc/platforms/cell/spufs/run.c +++ b/arch/powerpc/platforms/cell/spufs/run.c @@ -143,7 +143,7 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc) int ret; unsigned long runcntl = SPU_RUNCNTL_RUNNABLE; - ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE); + ret = spu_acquire_runnable(ctx, 0); if (ret) return ret; @@ -155,7 +155,7 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc) spu_release(ctx); ret = spu_setup_isolated(ctx); if (!ret) - ret = spu_acquire_runnable(ctx, SPU_ACTIVATE_NOWAKE); + ret = spu_acquire_runnable(ctx, 0); } /* if userspace has set the runcntrl register (eg, to issue an diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index 2f25e68b4ba..39823cec084 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c @@ -127,14 +127,6 @@ static void spu_remove_from_active_list(struct spu *spu) mutex_unlock(&spu_prio->active_mutex[node]); } -static inline void mm_needs_global_tlbie(struct mm_struct *mm) -{ - int nr = (NR_CPUS > 1) ? NR_CPUS : NR_CPUS + 1; - - /* Global TLBIE broadcast required with SPEs. */ - __cpus_setall(&mm->cpu_vm_mask, nr); -} - static BLOCKING_NOTIFIER_HEAD(spu_switch_notifier); static void spu_switch_notify(struct spu *spu, struct spu_context *ctx) @@ -167,8 +159,7 @@ static void spu_bind_context(struct spu *spu, struct spu_context *ctx) ctx->spu = spu; ctx->ops = &spu_hw_ops; spu->pid = current->pid; - spu->mm = ctx->owner; - mm_needs_global_tlbie(spu->mm); + spu_associate_mm(spu, ctx->owner); spu->ibox_callback = spufs_ibox_callback; spu->wbox_callback = spufs_wbox_callback; spu->stop_callback = spufs_stop_callback; @@ -205,7 +196,7 @@ static void spu_unbind_context(struct spu *spu, struct spu_context *ctx) spu->stop_callback = NULL; spu->mfc_callback = NULL; spu->dma_callback = NULL; - spu->mm = NULL; + spu_associate_mm(spu, NULL); spu->pid = 0; ctx->ops = &spu_backing_ops; ctx->spu = NULL; @@ -263,7 +254,6 @@ static void spu_prio_wait(struct spu_context *ctx) { DEFINE_WAIT(wait); - set_bit(SPU_SCHED_WAKE, &ctx->sched_flags); prepare_to_wait_exclusive(&ctx->stop_wq, &wait, TASK_INTERRUPTIBLE); if (!signal_pending(current)) { mutex_unlock(&ctx->state_mutex); @@ -272,7 +262,6 @@ static void spu_prio_wait(struct spu_context *ctx) } __set_current_state(TASK_RUNNING); remove_wait_queue(&ctx->stop_wq, &wait); - clear_bit(SPU_SCHED_WAKE, &ctx->sched_flags); } /** @@ -292,7 +281,7 @@ static void spu_reschedule(struct spu *spu) best = sched_find_first_bit(spu_prio->bitmap); if (best < MAX_PRIO) { struct spu_context *ctx = spu_grab_context(best); - if (ctx && test_bit(SPU_SCHED_WAKE, &ctx->sched_flags)) + if (ctx) wake_up(&ctx->stop_wq); } spin_unlock(&spu_prio->runq_lock); @@ -414,8 +403,7 @@ int spu_activate(struct spu_context *ctx, unsigned long flags) } spu_add_to_rq(ctx); - if (!(flags & SPU_ACTIVATE_NOWAKE)) - spu_prio_wait(ctx); + spu_prio_wait(ctx); spu_del_from_rq(ctx); } while (!signal_pending(current)); diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h index 0c437891dfd..5c4e47d69d7 100644 --- a/arch/powerpc/platforms/cell/spufs/spufs.h +++ b/arch/powerpc/platforms/cell/spufs/spufs.h @@ -41,7 +41,7 @@ struct spu_gang; /* ctx->sched_flags */ enum { - SPU_SCHED_WAKE = 0, + SPU_SCHED_WAKE = 0, /* currently unused */ }; struct spu_context { @@ -191,9 +191,7 @@ void spu_forget(struct spu_context *ctx); int spu_acquire_runnable(struct spu_context *ctx, unsigned long flags); void spu_acquire_saved(struct spu_context *ctx); int spu_acquire_exclusive(struct spu_context *ctx); -enum { - SPU_ACTIVATE_NOWAKE = 1, -}; + int spu_activate(struct spu_context *ctx, unsigned long flags); void spu_deactivate(struct spu_context *ctx); void spu_yield(struct spu_context *ctx); diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index c08981ff7fc..fd91c73de34 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c @@ -468,26 +468,6 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) MFC_CNTL_PURGE_DMA_COMPLETE); } -static inline void save_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Save, Step 29: - * If MFC_SR1[R]='1', save SLBs in CSA. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - csa->priv2.slb_index_W = in_be64(&priv2->slb_index_W); - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - csa->slb_esid_RW[i] = in_be64(&priv2->slb_esid_RW); - csa->slb_vsid_RW[i] = in_be64(&priv2->slb_vsid_RW); - eieio(); - } - } -} - static inline void setup_mfc_sr1(struct spu_state *csa, struct spu *spu) { /* Save, Step 30: @@ -708,20 +688,6 @@ static inline void resume_mfc_queue(struct spu_state *csa, struct spu *spu) out_be64(&priv2->mfc_control_RW, MFC_CNTL_RESUME_DMA_QUEUE); } -static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - - /* Save, Step 45: - * Restore, Step 19: - * If MFC_SR1[R]=1, write 0 to SLB_Invalidate_All. - */ - if (spu_mfc_sr1_get(spu) & MFC_STATE1_RELOCATE_MASK) { - out_be64(&priv2->slb_invalidate_all_W, 0UL); - eieio(); - } -} - static inline void get_kernel_slb(u64 ea, u64 slb[2]) { u64 llp; @@ -765,7 +731,7 @@ static inline void setup_mfc_slbs(struct spu_state *csa, struct spu *spu) * MFC_SR1[R]=1 (in other words, assume that * translation is desired by OS environment). */ - invalidate_slbs(csa, spu); + spu_invalidate_slbs(spu); get_kernel_slb((unsigned long)&spu_save_code[0], code_slb); get_kernel_slb((unsigned long)csa->lscsa, lscsa_slb); load_mfc_slb(spu, code_slb, 0); @@ -1718,27 +1684,6 @@ static inline void check_ppuint_mb_stat(struct spu_state *csa, struct spu *spu) } } -static inline void restore_mfc_slbs(struct spu_state *csa, struct spu *spu) -{ - struct spu_priv2 __iomem *priv2 = spu->priv2; - int i; - - /* Restore, Step 68: - * If MFC_SR1[R]='1', restore SLBs from CSA. - */ - if (csa->priv1.mfc_sr1_RW & MFC_STATE1_RELOCATE_MASK) { - for (i = 0; i < 8; i++) { - out_be64(&priv2->slb_index_W, i); - eieio(); - out_be64(&priv2->slb_esid_RW, csa->slb_esid_RW[i]); - out_be64(&priv2->slb_vsid_RW, csa->slb_vsid_RW[i]); - eieio(); - } - out_be64(&priv2->slb_index_W, csa->priv2.slb_index_W); - eieio(); - } -} - static inline void restore_mfc_sr1(struct spu_state *csa, struct spu *spu) { /* Restore, Step 69: @@ -1875,7 +1820,6 @@ static void save_csa(struct spu_state *prev, struct spu *spu) set_mfc_tclass_id(prev, spu); /* Step 26. */ purge_mfc_queue(prev, spu); /* Step 27. */ wait_purge_complete(prev, spu); /* Step 28. */ - save_mfc_slbs(prev, spu); /* Step 29. */ setup_mfc_sr1(prev, spu); /* Step 30. */ save_spu_npc(prev, spu); /* Step 31. */ save_spu_privcntl(prev, spu); /* Step 32. */ @@ -1987,7 +1931,7 @@ static void harvest(struct spu_state *prev, struct spu *spu) reset_spu_privcntl(prev, spu); /* Step 16. */ reset_spu_lslr(prev, spu); /* Step 17. */ setup_mfc_sr1(prev, spu); /* Step 18. */ - invalidate_slbs(prev, spu); /* Step 19. */ + spu_invalidate_slbs(spu); /* Step 19. */ reset_ch_part1(prev, spu); /* Step 20. */ reset_ch_part2(prev, spu); /* Step 21. */ enable_interrupts(prev, spu); /* Step 22. */ @@ -2055,7 +1999,7 @@ static void restore_csa(struct spu_state *next, struct spu *spu) restore_spu_mb(next, spu); /* Step 65. */ check_ppu_mb_stat(next, spu); /* Step 66. */ check_ppuint_mb_stat(next, spu); /* Step 67. */ - restore_mfc_slbs(next, spu); /* Step 68. */ + spu_invalidate_slbs(spu); /* Modified Step 68. */ restore_mfc_sr1(next, spu); /* Step 69. */ restore_other_spu_access(next, spu); /* Step 70. */ restore_spu_runcntl(next, spu); /* Step 71. */ diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index 459a53b7d24..71dbf1a56e1 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c @@ -77,7 +77,7 @@ #define IOBMAP_L2E_V 0x80000000 #define IOBMAP_L2E_V_CACHED 0xc0000000 -static u32 *iob; +static u32 __iomem *iob; static u32 iob_l1_emptyval; static u32 iob_l2_emptyval; static u32 *iob_l2_base; diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c index 42354de3f55..2014d2b4444 100644 --- a/arch/powerpc/platforms/ps3/mm.c +++ b/arch/powerpc/platforms/ps3/mm.c @@ -294,7 +294,7 @@ static int __init ps3_mm_add_memory(void) unsigned long nr_pages; if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return 0; + return -ENODEV; BUG_ON(!mem_init_done); diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c index a9f7e4a39a2..3c48cce98a5 100644 --- a/arch/powerpc/platforms/ps3/system-bus.c +++ b/arch/powerpc/platforms/ps3/system-bus.c @@ -172,7 +172,7 @@ int __init ps3_system_bus_init(void) int result; if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return 0; + return -ENODEV; result = bus_register(&ps3_system_bus_type); BUG_ON(result); diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c index 4ca61578870..697eb30a68a 100644 --- a/arch/s390/appldata/appldata_mem.c +++ b/arch/s390/appldata/appldata_mem.c @@ -117,7 +117,10 @@ static void appldata_get_mem_data(void *data) mem_data->pgpgout = ev[PGPGOUT] >> 1; mem_data->pswpin = ev[PSWPIN]; mem_data->pswpout = ev[PSWPOUT]; - mem_data->pgalloc = ev[PGALLOC_NORMAL] + ev[PGALLOC_DMA]; + mem_data->pgalloc = ev[PGALLOC_NORMAL]; +#ifdef CONFIG_ZONE_DMA + mem_data->pgalloc += ev[PGALLOC_DMA]; +#endif mem_data->pgfault = ev[PGFAULT]; mem_data->pgmajfault = ev[PGMAJFAULT]; diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 113bd48a89b..fc874e63a49 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -348,7 +348,7 @@ void exit_thread(void) #ifndef CONFIG_SMP if(last_task_used_math == current) { #else - if(current_thread_info()->flags & _TIF_USEDFPU) { + if (test_thread_flag(TIF_USEDFPU)) { #endif /* Keep process from leaving FPU in a bogon state. */ put_psr(get_psr() | PSR_EF); @@ -357,7 +357,7 @@ void exit_thread(void) #ifndef CONFIG_SMP last_task_used_math = NULL; #else - current_thread_info()->flags &= ~_TIF_USEDFPU; + clear_thread_flag(TIF_USEDFPU); #endif } } @@ -371,7 +371,7 @@ void flush_thread(void) #ifndef CONFIG_SMP if(last_task_used_math == current) { #else - if(current_thread_info()->flags & _TIF_USEDFPU) { + if (test_thread_flag(TIF_USEDFPU)) { #endif /* Clean the fpu. */ put_psr(get_psr() | PSR_EF); @@ -380,7 +380,7 @@ void flush_thread(void) #ifndef CONFIG_SMP last_task_used_math = NULL; #else - current_thread_info()->flags &= ~_TIF_USEDFPU; + clear_thread_flag(TIF_USEDFPU); #endif } @@ -466,13 +466,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, #ifndef CONFIG_SMP if(last_task_used_math == current) { #else - if(current_thread_info()->flags & _TIF_USEDFPU) { + if (test_thread_flag(TIF_USEDFPU)) { #endif put_psr(get_psr() | PSR_EF); fpsave(&p->thread.float_regs[0], &p->thread.fsr, &p->thread.fpqueue[0], &p->thread.fpqdepth); #ifdef CONFIG_SMP - current_thread_info()->flags &= ~_TIF_USEDFPU; + clear_thread_flag(TIF_USEDFPU); #endif } @@ -609,13 +609,13 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs) return 1; } #ifdef CONFIG_SMP - if (current_thread_info()->flags & _TIF_USEDFPU) { + if (test_thread_flag(TIF_USEDFPU)) { put_psr(get_psr() | PSR_EF); fpsave(¤t->thread.float_regs[0], ¤t->thread.fsr, ¤t->thread.fpqueue[0], ¤t->thread.fpqdepth); if (regs != NULL) { regs->psr &= ~(PSR_EF); - current_thread_info()->flags &= ~(_TIF_USEDFPU); + clear_thread_flag(TIF_USEDFPU); } } #else diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index ea75ca56905..3a69778c836 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -78,7 +78,8 @@ sys_call_table: /*285*/ .long sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .long sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages +/*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy +/*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait #ifdef CONFIG_SUNOS_EMUL /* Now the SunOS syscall table. */ @@ -192,5 +193,8 @@ sunos_sys_table: .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_nosys /*300*/ .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys, sunos_nosys, sunos_nosys + .long sunos_nosys #endif diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c index 6a70d215fd0..527687afc1c 100644 --- a/arch/sparc/kernel/traps.c +++ b/arch/sparc/kernel/traps.c @@ -259,7 +259,7 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, } else { fpload(¤t->thread.float_regs[0], ¤t->thread.fsr); } - current_thread_info()->flags |= _TIF_USEDFPU; + set_thread_flag(TIF_USEDFPU); #endif } @@ -290,7 +290,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, #ifndef CONFIG_SMP if(!fpt) { #else - if(!(task_thread_info(fpt)->flags & _TIF_USEDFPU)) { + if (!test_tsk_thread_flag(fpt, TIF_USEDFPU)) { #endif fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth); regs->psr &= ~PSR_EF; @@ -333,7 +333,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc, /* nope, better SIGFPE the offending process... */ #ifdef CONFIG_SMP - task_thread_info(fpt)->flags &= ~_TIF_USEDFPU; + clear_tsk_thread_flag(fpt, TIF_USEDFPU); #endif if(psr & PSR_PS) { /* The first fsr store/load we tried trapped, diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index c85ddf31274..a532922e2e3 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -75,7 +75,7 @@ void show_mem(void) printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT-10)); printk("%ld pages of RAM\n", totalram_pages); - printk("%d free pages\n", nr_free_pages()); + printk("%ld free pages\n", nr_free_pages()); #if 0 /* undefined pgtable_cache_size, pgd_cache_size */ printk("%ld pages in page table cache\n",pgtable_cache_size); #ifndef CONFIG_SMP diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index f75a686ba64..1a6348b565f 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -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" diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 860b8b60526..120c9c33b7a 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -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 diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S index e492db845ea..d4024ac0d61 100644 --- a/arch/sparc64/kernel/ktlb.S +++ b/arch/sparc64/kernel/ktlb.S @@ -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). */ diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 7d75cd4eb29..b291060c25a 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c @@ -413,8 +413,13 @@ void flush_thread(void) struct thread_info *t = current_thread_info(); struct mm_struct *mm; - 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); + } mm = t->task->mm; if (mm) diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index 948b7d2d587..aaeb5e06735 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S @@ -79,7 +79,8 @@ sys_call_table32: .word sys_mkdirat, sys_mknodat, sys_fchownat, compat_sys_futimesat, compat_sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare -/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages +/*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy + .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait #endif /* CONFIG_COMPAT */ @@ -149,7 +150,8 @@ sys_call_table: .word sys_mkdirat, sys_mknodat, sys_fchownat, sys_futimesat, sys_fstatat64 /*290*/ .word sys_unlinkat, sys_renameat, sys_linkat, sys_symlinkat, sys_readlinkat .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare -/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages +/*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy + .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ defined(CONFIG_SOLARIS_EMUL_MODULE) @@ -264,5 +266,8 @@ sunos_sys_table: .word sunos_nosys, sunos_nosys, sunos_nosys .word sunos_nosys /*300*/ .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys, sunos_nosys, sunos_nosys + .word sunos_nosys #endif diff --git a/arch/sparc64/mm/hugetlbpage.c b/arch/sparc64/mm/hugetlbpage.c index 33fd0b265e7..00677b5e1d7 100644 --- a/arch/sparc64/mm/hugetlbpage.c +++ b/arch/sparc64/mm/hugetlbpage.c @@ -248,6 +248,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, if (!pte_present(*ptep) && pte_present(entry)) mm->context.huge_pte_count++; + addr &= HPAGE_MASK; for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { set_pte_at(mm, addr, ptep, entry); ptep++; @@ -266,6 +267,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, if (pte_present(entry)) mm->context.huge_pte_count--; + addr &= HPAGE_MASK; + for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) { pte_clear(mm, addr, ptep); addr += PAGE_SIZE; diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index b1a1ee0cc6b..f146071a4b2 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c @@ -59,8 +59,10 @@ unsigned long kern_linear_pte_xor[2] __read_mostly; */ 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(void) 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(void) _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); diff --git a/arch/um/Kconfig b/arch/um/Kconfig index b3a21ba77cd..354cc6b7053 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -44,7 +44,7 @@ config LOCKDEP_SUPPORT config STACKTRACE_SUPPORT bool - default y + default n config GENERIC_CALIBRATE_DELAY bool diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 813077fb1e5..a9a4b85ca51 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -10,7 +10,7 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ - -Dunix -D__unix__ -D__$(SUBARCH)__ + -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of # using it directly. @@ -19,7 +19,7 @@ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file)) $(UNPROFILE_OBJS:.o=.%): \ c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o) $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ - -Dunix -D__unix__ -D__$(SUBARCH)__ + -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) # The stubs and unmap.o can't try to call mcount or update basic block data define unprofile diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 293a4a4c609..7a1e251e333 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig @@ -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 diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index eda7a0d4dc1..796df6992f6 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S @@ -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 diff --git a/arch/x86_64/kernel/cpufreq/Kconfig b/arch/x86_64/kernel/cpufreq/Kconfig index ced15d06f0f..40acb67fb88 100644 --- a/arch/x86_64/kernel/cpufreq/Kconfig +++ b/arch/x86_64/kernel/cpufreq/Kconfig @@ -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 diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 4651fd22b21..a490fabfcf4 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c @@ -662,7 +662,7 @@ static int __init parse_memmap_opt(char *p) } 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"); diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index dec587b293b..148c6bcf5bb 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -16,7 +16,7 @@ #include <asm/proto.h> #include <asm/dma.h> -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(struct acpi_table_header *header) } #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 }, diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 50dd8bef850..455aa0b932f 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c @@ -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; diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 486f4c61a94..82d9d85d527 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -187,10 +187,7 @@ void nmi_watchdog_default(void) { if (nmi_watchdog != NMI_DEFAULT) return; - if (nmi_known_cpu()) - nmi_watchdog = NMI_LOCAL_APIC; - else - nmi_watchdog = NMI_IO_APIC; + nmi_watchdog = NMI_NONE; } static int endflag __initdata = 0; diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index 030eb375335..2bac8c60ad6 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c @@ -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; diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index cbbc6adc1a9..d8d5ccc245c 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -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; diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 180ff919eaf..b43c698cf7d 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -112,7 +112,7 @@ static __always_inline void do_vgettimeofday(struct timeval * tv) vread = __vsyscall_gtod_data.clock.vread; if (unlikely(!__vsyscall_gtod_data.sysctl_enabled || !vread)) { - gettimeofday(tv,0); + gettimeofday(tv,NULL); return; } now = vread(); diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 0dffae69f4a..77c25b30763 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c @@ -59,3 +59,4 @@ EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(init_level4_pgt); EXPORT_SYMBOL(load_gs_index); +EXPORT_SYMBOL(_proxy_pda); diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index 8dcade63b04..3a799b9b5df 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -549,7 +549,7 @@ acpi_status acpi_ev_release_global_lock(void) acpi_gbl_global_lock_acquired = FALSE; /* Release the local GL mutex */ - acpi_ev_global_lock_thread_id = 0; + acpi_ev_global_lock_thread_id = NULL; acpi_ev_global_lock_acquired = 0; acpi_os_release_mutex(acpi_gbl_global_lock_mutex); return_ACPI_STATUS(status); diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c index 7ef834250a4..55cc293e748 100644 --- a/drivers/ata/pata_cs5520.c +++ b/drivers/ata/pata_cs5520.c @@ -208,7 +208,7 @@ static struct ata_port_operations cs5520_port_ops = { static int __devinit cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id) { u8 pcicfg; - void *iomap[5]; + void __iomem *iomap[5]; static struct ata_probe_ent probe[2]; int ports = 0; diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c index f5d88729ca7..882c36eaf29 100644 --- a/drivers/ata/pata_mpc52xx.c +++ b/drivers/ata/pata_mpc52xx.c @@ -329,7 +329,7 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv) ae->dev = dev; ae->irq = priv->ata_irq; - aio->cmd_addr = 0; /* Don't have a classic reg block */ + aio->cmd_addr = NULL; /* Don't have a classic reg block */ aio->altstatus_addr = &priv->ata_regs->tf_control; aio->ctl_addr = &priv->ata_regs->tf_control; aio->data_addr = &priv->ata_regs->tf_data; diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c index 1879e0cd56a..a787f0d4a5b 100644 --- a/drivers/ata/sata_sis.c +++ b/drivers/ata/sata_sis.c @@ -354,7 +354,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) return -ENOMEM; if (!(probe_ent->port_flags & SIS_FLAG_CFGSCR)) { - void *mmio; + void __iomem *mmio; mmio = pcim_iomap(pdev, SIS_SCR_PCI_BAR, 0); if (!mmio) diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 0d7091e2077..2ad2527cf5b 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c @@ -1177,7 +1177,7 @@ static void __devinit eprom_get_esi(struct atm_dev *dev) /*--------------------------------- entries ---------------------------------*/ -static int __init zatm_init(struct atm_dev *dev) +static int __devinit zatm_init(struct atm_dev *dev) { struct zatm_dev *zatm_dev; struct pci_dev *pci_dev; @@ -1256,7 +1256,7 @@ static int __init zatm_init(struct atm_dev *dev) } -static int __init zatm_start(struct atm_dev *dev) +static int __devinit zatm_start(struct atm_dev *dev) { struct zatm_dev *zatm_dev = ZATM_DEV(dev); struct pci_dev *pdev = zatm_dev->pci_dev; diff --git a/drivers/base/core.c b/drivers/base/core.c index f191afe62b4..ad0f4a2f25c 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -407,6 +407,35 @@ void device_remove_bin_file(struct device *dev, struct bin_attribute *attr) } EXPORT_SYMBOL_GPL(device_remove_bin_file); +/** + * device_schedule_callback - helper to schedule a callback for a device + * @dev: device. + * @func: callback function to invoke later. + * + * Attribute methods must not unregister themselves or their parent device + * (which would amount to the same thing). Attempts to do so will deadlock, + * since unregistration is mutually exclusive with driver callbacks. + * + * Instead methods can call this routine, which will attempt to allocate + * and schedule a workqueue request to call back @func with @dev as its + * argument in the workqueue's process context. @dev will be pinned until + * @func returns. + * + * Returns 0 if the request was submitted, -ENOMEM if storage could not + * be allocated. + * + * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an + * underlying sysfs routine (since it is intended for use by attribute + * methods), and if sysfs isn't available you'll get nothing but -ENOSYS. + */ +int device_schedule_callback(struct device *dev, + void (*func)(struct device *)) +{ + return sysfs_schedule_callback(&dev->kobj, + (void (*)(void *)) func, dev); +} +EXPORT_SYMBOL_GPL(device_schedule_callback); + static void klist_children_get(struct klist_node *n) { struct device *dev = container_of(n, struct device, knode_parent); diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 0c716ee905d..072e18e6d76 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1439,7 +1439,7 @@ static int rebuild_lun_table(ctlr_info_t *h, struct gendisk *del_disk) if (return_code == IO_OK) { listlength = - be32_to_cpu(*(__u32 *) ld_buff->LUNListLength); + be32_to_cpu(*(__be32 *) ld_buff->LUNListLength); } else { /* reading number of logical volumes failed */ printk(KERN_WARNING "cciss: report logical volume" " command failed\n"); @@ -1961,8 +1961,8 @@ cciss_read_capacity(int ctlr, int logvol, int withirq, sector_t *total_size, ctlr, buf, sizeof(ReadCapdata_struct), 1, logvol, 0, NULL, TYPE_CMD); if (return_code == IO_OK) { - *total_size = be32_to_cpu(*(__u32 *) buf->total_size); - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); + *total_size = be32_to_cpu(*(__be32 *) buf->total_size); + *block_size = be32_to_cpu(*(__be32 *) buf->block_size); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; @@ -1997,8 +1997,8 @@ cciss_read_capacity_16(int ctlr, int logvol, int withirq, sector_t *total_size, 1, logvol, 0, NULL, TYPE_CMD); } if (return_code == IO_OK) { - *total_size = be64_to_cpu(*(__u64 *) buf->total_size); - *block_size = be32_to_cpu(*(__u32 *) buf->block_size); + *total_size = be64_to_cpu(*(__be64 *) buf->total_size); + *block_size = be32_to_cpu(*(__be32 *) buf->block_size); } else { /* read capacity command failed */ printk(KERN_WARNING "cciss: read capacity failed\n"); *total_size = 0; diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c index 99e2c8ce1cc..31e01488eb5 100644 --- a/drivers/block/paride/pd.c +++ b/drivers/block/paride/pd.c @@ -663,11 +663,11 @@ static enum action pd_identify(struct pd_unit *disk) return Fail; pi_read_block(disk->pi, pd_scratch, 512); disk->can_lba = pd_scratch[99] & 2; - disk->sectors = le16_to_cpu(*(u16 *) (pd_scratch + 12)); - disk->heads = le16_to_cpu(*(u16 *) (pd_scratch + 6)); - disk->cylinders = le16_to_cpu(*(u16 *) (pd_scratch + 2)); + disk->sectors = le16_to_cpu(*(__le16 *) (pd_scratch + 12)); + disk->heads = le16_to_cpu(*(__le16 *) (pd_scratch + 6)); + disk->cylinders = le16_to_cpu(*(__le16 *) (pd_scratch + 2)); if (disk->can_lba) - disk->capacity = le32_to_cpu(*(u32 *) (pd_scratch + 120)); + disk->capacity = le32_to_cpu(*(__le32 *) (pd_scratch + 120)); else disk->capacity = disk->sectors * disk->heads * disk->cylinders; diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 5f4fdcf7c96..1f0962616ee 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -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 <linux/types.h> #include <linux/errno.h> #include <linux/miscdevice.h> @@ -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); diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index e4532685668..7a32df59490 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -1376,6 +1376,8 @@ static void do_tty_hangup(struct work_struct *work) 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 task_struct *tsk, struct tty_struct *tt { 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)); } diff --git a/drivers/char/vt.c b/drivers/char/vt.c index c3f8e383933..1bbb45b937f 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c @@ -724,6 +724,7 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */ 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_struct *ignored) 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; diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 3a5d301e783..1fa2da8f4fb 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -34,7 +34,7 @@ #include <linux/kbd_diacr.h> #include <linux/selection.h> -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) diff --git a/drivers/char/watchdog/Kconfig b/drivers/char/watchdog/Kconfig index ea09d0c974e..e812aa129e2 100644 --- a/drivers/char/watchdog/Kconfig +++ b/drivers/char/watchdog/Kconfig @@ -301,6 +301,7 @@ config I6300ESB_WDT config I8XX_TCO tristate "Intel i8xx TCO Timer/Watchdog" depends on WATCHDOG && (X86 || IA64) && PCI + default n ---help--- Hardware driver for the TCO timer built into the Intel 82801 I/O Controller Hub family. The TCO (Total Cost of Ownership) diff --git a/drivers/char/watchdog/machzwd.c b/drivers/char/watchdog/machzwd.c index 4a328ba0d26..76c7fa37fa6 100644 --- a/drivers/char/watchdog/machzwd.c +++ b/drivers/char/watchdog/machzwd.c @@ -314,21 +314,21 @@ static int zf_ioctl(struct inode *inode, struct file *file, unsigned int cmd, { 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; + 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_GETSTATUS: + return put_user(0, p); - case WDIOC_KEEPALIVE: - zf_ping(0); - break; + case WDIOC_KEEPALIVE: + zf_ping(0); + break; - default: - return -ENOTTY; + default: + return -ENOTTY; } return 0; diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 15278044295..322ee2984e3 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -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_register(dma_event_callback event_callback) 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 dma_client *client) 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(struct dma_client *client, 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_device *device) 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 dma_device *device) 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); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f4ee1afe488..67f3347afcf 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -26,6 +26,7 @@ #include <asm/byteorder.h> #include <linux/input.h> #include <linux/wait.h> +#include <linux/vmalloc.h> #include <linux/hid.h> #include <linux/hiddev.h> @@ -654,12 +655,13 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) memcpy(device->rdesc, start, size); device->rsize = size; - if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) { + if (!(parser = vmalloc(sizeof(struct hid_parser)))) { kfree(device->rdesc); kfree(device->collection); kfree(device); return NULL; } + memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; @@ -668,7 +670,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (item.format != HID_ITEM_FORMAT_SHORT) { dbg("unexpected long global item"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } @@ -676,7 +678,7 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) dbg("item %u %u %u %u parsing failed\n", item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } @@ -684,23 +686,23 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) if (parser->collection_stack_ptr) { dbg("unbalanced collection at end of report description"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } if (parser->local.delimiter_depth) { dbg("unbalanced delimiter at end of report description"); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } - kfree(parser); + vfree(parser); return device; } } dbg("item fetching failed at offset %d\n", (int)(end - start)); hid_free_device(device); - kfree(parser); + vfree(parser); return NULL; } EXPORT_SYMBOL_GPL(hid_parse_report); @@ -753,8 +755,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) report += offset >> 3; /* adjust byte index */ offset &= 7; /* now only need bit offset into one byte */ - x = get_unaligned((u64 *) report); - x = le64_to_cpu(x); + x = le64_to_cpu(get_unaligned((__le64 *) report)); x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ return (u32) x; } @@ -769,7 +770,7 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) */ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) { - u64 x; + __le64 x; u64 m = (1ULL << n) - 1; WARN_ON(n > 32); @@ -780,10 +781,10 @@ static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u3 report += offset >> 3; offset &= 7; - x = get_unaligned((u64 *)report); + x = get_unaligned((__le64 *)report); x &= cpu_to_le64(~(m << offset)); x |= cpu_to_le64(((u64) value) << offset); - put_unaligned(x, (u64 *) report); + put_unaligned(x, (__le64 *) report); } /* @@ -873,10 +874,6 @@ static void hid_output_field(struct hid_field *field, __u8 *data) unsigned size = field->report_size; unsigned n; - /* make sure the unused bits in the last byte are zeros */ - if (count > 0 && size > 0) - data[(offset+count*size-1)/8] = 0; - for (n = 0; n < count; n++) { if (field->logical_minimum < 0) /* signed values */ implement(data, offset + n * size, size, s32ton(field->value[n], size)); diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c3d4856fb61..6d105a1d41b 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -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. diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5d134bb75ba..8f1fd017679 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -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 - 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 diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 28feedfbd21..d9f029e8ff7 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -37,7 +37,6 @@ ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o # 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 diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index 40e5c66b81c..e2953fc1faf 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c @@ -196,11 +196,6 @@ static void icside_maskproc(ide_drive_t *drive, int mask) } #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_t *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) 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; diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 08e7cd043bc..fd213088b06 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -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 */ diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index dfbd7445852..695610f0e3e 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -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); diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c index b2dc028dc8c..d54d9fe92a7 100644 --- a/drivers/ide/mips/au1xxx-ide.c +++ b/drivers/ide/mips/au1xxx-ide.c @@ -639,6 +639,7 @@ static int au_ide_probe(struct device *dev) _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 *dev) /* 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; diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 6591ff4753c..95d1ea8f1f1 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o 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 diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c index b0d4825c56a..561197f7b5b 100644 --- a/drivers/ide/pci/cmd64x.c +++ b/drivers/ide/pci/cmd64x.c @@ -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, char **addr, off_t offset, int count) #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_drive_t *drive, int setup_count, int activ */ 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; + 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 = (recovery_time + clock_time - 1) / clock_time; - recovery_count2 = cycle_count - (setup_count + active_count); - if (recovery_count2 > recovery_count) - recovery_count = recovery_count2; + 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; diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c index 53f25500c22..be4fc96c29e 100644 --- a/drivers/ide/pci/jmicron.c +++ b/drivers/ide/pci/jmicron.c @@ -240,12 +240,31 @@ static int __devinit jmicron_init_one(struct pci_dev *dev, const struct pci_devi 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, }, }; diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/pci/scc_pata.c index f84bf791f72..f84bf791f72 100644 --- a/drivers/ide/ppc/scc_pata.c +++ b/drivers/ide/pci/scc_pata.c diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index a52c80fe7d3..118fb3205ca 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -505,11 +505,6 @@ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwi } } } - -#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*/ /** diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c index f6f94904082..f87f003e3ef 100644 --- a/drivers/infiniband/hw/ipath/ipath_dma.c +++ b/drivers/infiniband/hw/ipath/ipath_dma.c @@ -167,7 +167,7 @@ static void *ipath_dma_alloc_coherent(struct ib_device *dev, size_t size, } static void ipath_dma_free_coherent(struct ib_device *dev, size_t size, - void *cpu_addr, dma_addr_t dma_handle) + void *cpu_addr, u64 dma_handle) { free_pages((unsigned long) cpu_addr, get_order(size)); } diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index a163bca3897..dc7a8c78cbf 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -2464,7 +2464,7 @@ int kvm_init_arch(struct kvm_arch_ops *ops, struct module *module) 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; } diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index a1a93368f31..e85b4c7c36f 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c @@ -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 kvm_vcpu *vcpu, u64 gfn) 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 *vcpu, gpa_t gpa, int bytes) } 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; } } diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index c07178e6112..bfa0ce42ea9 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c @@ -371,10 +371,10 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) 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 *vcpu, u32 msr_index, u64 data) 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); diff --git a/drivers/md/linear.c b/drivers/md/linear.c index c625ddb8833..d5ecd2d5304 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c @@ -188,7 +188,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) for (i=0; i < cnt-1 ; i++) { sector_t sz = 0; int j; - for (j=i; i<cnt-1 && sz < min_spacing ; j++) + for (j = i; j < cnt - 1 && sz < min_spacing; j++) sz += conf->disks[j].size; if (sz >= min_spacing && sz < conf->hash_spacing) conf->hash_spacing = sz; diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 1ff5138e4bb..9916cf32494 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c @@ -1248,10 +1248,10 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) ret |= pvr2_write_register(hdw, 0xaa18, 0x00840000); /*unknown*/ LOCK_TAKE(hdw->ctl_lock); do { hdw->cmd_buffer[0] = FX2CMD_FWPOST1; - ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,0,0); + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,1,NULL,0); hdw->cmd_buffer[0] = FX2CMD_MEMSEL; hdw->cmd_buffer[1] = 0; - ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); } while (0); LOCK_GIVE(hdw->ctl_lock); if (ret) { @@ -1320,7 +1320,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) LOCK_TAKE(hdw->ctl_lock); do { hdw->cmd_buffer[0] = FX2CMD_MEMSEL; hdw->cmd_buffer[1] = 0; - ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,0,0); + ret |= pvr2_send_request(hdw,hdw->cmd_buffer,2,NULL,0); } while (0); LOCK_GIVE(hdw->ctl_lock); if (ret) { diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 5313d342666..25d3830b482 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -808,11 +808,11 @@ static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp) { if (vp->dev_video) { pvr2_v4l2_dev_destroy(vp->dev_video); - vp->dev_video = 0; + vp->dev_video = NULL; } if (vp->dev_radio) { pvr2_v4l2_dev_destroy(vp->dev_radio); - vp->dev_radio = 0; + vp->dev_radio = NULL; } pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp); @@ -1138,7 +1138,7 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip, { int mindevnum; int unit_number; - int *nr_ptr = 0; + int *nr_ptr = NULL; dip->v4lp = vp; diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index b060d4bfba2..0de5c9e94e7 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c @@ -569,10 +569,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) if(host->dma_dir == DMA_FROM_DEVICE) { imxmci_busy_wait_for_status(host, &stat, - STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE, + STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE | + STATUS_TIME_OUT_READ, 50, "imxmci_cpu_driven_data read"); while((stat & (STATUS_APPL_BUFF_FF | STATUS_DATA_TRANS_DONE)) && + !(stat & STATUS_TIME_OUT_READ) && (host->data_cnt < 512)) { udelay(20); /* required for clocks < 8MHz*/ @@ -602,6 +604,12 @@ static int imxmci_cpu_driven_data(struct imxmci_host *host, unsigned int *pstat) if(host->dma_size & 0x1ff) stat &= ~STATUS_CRC_READ_ERR; + if(stat & STATUS_TIME_OUT_READ) { + dev_dbg(mmc_dev(host->mmc), "imxmci_cpu_driven_data read timeout STATUS = 0x%x\n", + stat); + trans_done = -1; + } + } else { imxmci_busy_wait_for_status(host, &stat, STATUS_APPL_BUFF_FE, @@ -709,6 +717,9 @@ static void imxmci_tasklet_fnc(unsigned long data) */ stat |= host->status_reg; + if(test_bit(IMXMCI_PEND_CPU_DATA_b, &host->pending_events)) + stat &= ~STATUS_CRC_READ_ERR; + if(test_bit(IMXMCI_PEND_WAIT_RESP_b, &host->pending_events)) { imxmci_busy_wait_for_status(host, &stat, STATUS_END_CMD_RESP | STATUS_ERR_MASK, diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 88d4f70035b..dee3638ad74 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -1328,7 +1328,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { cso = skb->h.raw - skb->data; - css = (skb->h.raw + skb->csum) - skb->data; + css = (skb->h.raw + skb->csum_offset) - skb->data; if (unlikely(cso & 0x1)) { printk(KERN_DEBUG "%s: payload offset != even number\n", atl1_driver_name); @@ -1562,7 +1562,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* mss will be nonzero if we're doing segment offload (TSO/GSO) */ mss = skb_shinfo(skb)->gso_size; if (mss) { - if (skb->protocol == ntohs(ETH_P_IP)) { + if (skb->protocol == htons(ETH_P_IP)) { proto_hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2)); if (unlikely(proto_hdr_len > len)) { diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index c6172a77a6d..349b96a3ec4 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1712,7 +1712,7 @@ static void init_registers(struct net_device *dev) /* Enable interrupts by setting the interrupt mask. */ writel(DEFAULT_INTR, ioaddr + IntrMask); - writel(1, ioaddr + IntrEnable); + natsemi_irq_enable(dev); writel(RxOn | TxOn, ioaddr + ChipCmd); writel(StatsClear, ioaddr + StatsCtrl); /* Clear Stats */ @@ -2119,28 +2119,35 @@ static irqreturn_t intr_handler(int irq, void *dev_instance) struct netdev_private *np = netdev_priv(dev); void __iomem * ioaddr = ns_ioaddr(dev); - if (np->hands_off) + /* Reading IntrStatus automatically acknowledges so don't do + * that while interrupts are disabled, (for example, while a + * poll is scheduled). */ + if (np->hands_off || !readl(ioaddr + IntrEnable)) return IRQ_NONE; - /* Reading automatically acknowledges. */ np->intr_status = readl(ioaddr + IntrStatus); + if (!np->intr_status) + return IRQ_NONE; + if (netif_msg_intr(np)) printk(KERN_DEBUG "%s: Interrupt, status %#08x, mask %#08x.\n", dev->name, np->intr_status, readl(ioaddr + IntrMask)); - if (!np->intr_status) - return IRQ_NONE; - prefetch(&np->rx_skbuff[np->cur_rx % RX_RING_SIZE]); if (netif_rx_schedule_prep(dev)) { /* Disable interrupts and register for poll */ natsemi_irq_disable(dev); __netif_rx_schedule(dev); - } + } else + printk(KERN_WARNING + "%s: Ignoring interrupt, status %#08x, mask %#08x.\n", + dev->name, np->intr_status, + readl(ioaddr + IntrMask)); + return IRQ_HANDLED; } @@ -2156,6 +2163,20 @@ static int natsemi_poll(struct net_device *dev, int *budget) int work_done = 0; do { + if (netif_msg_intr(np)) + printk(KERN_DEBUG + "%s: Poll, status %#08x, mask %#08x.\n", + dev->name, np->intr_status, + readl(ioaddr + IntrMask)); + + /* netdev_rx() may read IntrStatus again if the RX state + * machine falls over so do it first. */ + if (np->intr_status & + (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | + IntrRxErr | IntrRxOverrun)) { + netdev_rx(dev, &work_done, work_to_do); + } + if (np->intr_status & (IntrTxDone | IntrTxIntr | IntrTxIdle | IntrTxErr)) { spin_lock(&np->lock); @@ -2167,12 +2188,6 @@ static int natsemi_poll(struct net_device *dev, int *budget) if (np->intr_status & IntrAbnormalSummary) netdev_error(dev, np->intr_status); - if (np->intr_status & - (IntrRxDone | IntrRxIntr | RxStatusFIFOOver | - IntrRxErr | IntrRxOverrun)) { - netdev_rx(dev, &work_done, work_to_do); - } - *budget -= work_done; dev->quota -= work_done; @@ -2399,19 +2414,8 @@ static struct net_device_stats *get_stats(struct net_device *dev) #ifdef CONFIG_NET_POLL_CONTROLLER static void natsemi_poll_controller(struct net_device *dev) { - struct netdev_private *np = netdev_priv(dev); - disable_irq(dev->irq); - - /* - * A real interrupt might have already reached us at this point - * but NAPI might still haven't called us back. As the interrupt - * status register is cleared by reading, we should prevent an - * interrupt loss in this case... - */ - if (!np->intr_status) - intr_handler(dev->irq, dev); - + intr_handler(dev->irq, dev); enable_irq(dev->irq); } #endif @@ -3071,7 +3075,7 @@ static void enable_wol_mode(struct net_device *dev, int enable_intr) * Could be used to send a netlink message. */ writel(WOLPkt | LinkChange, ioaddr + IntrMask); - writel(1, ioaddr + IntrEnable); + natsemi_irq_enable(dev); } } @@ -3202,7 +3206,7 @@ static int natsemi_suspend (struct pci_dev *pdev, pm_message_t state) disable_irq(dev->irq); spin_lock_irq(&np->lock); - writel(0, ioaddr + IntrEnable); + natsemi_irq_disable(dev); np->hands_off = 1; natsemi_stop_rxtx(dev); netif_stop_queue(dev); diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 81742e4e561..dd8ce35332f 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h @@ -232,6 +232,7 @@ enum { #define MPORT_SINGLE_FUNCTION_MODE 0x1111 extern unsigned long long netxen_dma_mask; +extern unsigned long last_schedule_time; /* * NetXen host-peg signal message structure diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c index 986ef98db22..ee1b5a24cbe 100644 --- a/drivers/net/netxen/netxen_nic_ethtool.c +++ b/drivers/net/netxen/netxen_nic_ethtool.c @@ -462,6 +462,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom, } printk(KERN_INFO "%s: flash unlocked. \n", netxen_nic_driver_name); + last_schedule_time = jiffies; ret = netxen_flash_erase_secondary(adapter); if (ret != FLASH_SUCCESS) { printk(KERN_ERR "%s: Flash erase failed.\n", diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 1be55702557..6537574a9cd 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -822,7 +822,10 @@ int netxen_nic_set_mtu_xgb(struct netxen_port *port, int new_mtu) { struct netxen_adapter *adapter = port->adapter; new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE; - netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); + if (port->portnum == 0) + netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE, new_mtu); + else if (port->portnum == 1) + netxen_nic_write_w0(adapter, NETXEN_NIU_XG1_MAX_FRAME_SIZE, new_mtu); return 0; } diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 586d32b676a..229aa1c4fb7 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -42,6 +42,8 @@ struct crb_addr_pair { u32 data; }; +unsigned long last_schedule_time; + #define NETXEN_MAX_CRB_XFORM 60 static unsigned int crb_addr_xform[NETXEN_MAX_CRB_XFORM]; #define NETXEN_ADDR_ERROR (0xffffffff) @@ -404,9 +406,14 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, static inline int do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) { + if (jiffies > (last_schedule_time + (8 * HZ))) { + last_schedule_time = jiffies; + schedule(); + } + netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); - udelay(70); /* prevent bursting on CRB */ + udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_INSTR_OPCODE, 0xb); if (netxen_wait_rom_done(adapter)) { @@ -415,7 +422,7 @@ do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) } /* reset abyte_cnt and dummy_byte_cnt */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 0); - udelay(70); /* prevent bursting on CRB */ + udelay(100); /* prevent bursting on CRB */ netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_DUMMY_BYTE_CNT, 0); *valp = netxen_nic_reg_read(adapter, NETXEN_ROMUSB_ROM_RDATA); diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c index a956a51d284..1060154ae75 100644 --- a/drivers/net/pcmcia/ibmtr_cs.c +++ b/drivers/net/pcmcia/ibmtr_cs.c @@ -138,7 +138,7 @@ static const struct ethtool_ops netdev_ethtool_ops = { ======================================================================*/ -static int ibmtr_attach(struct pcmcia_device *link) +static int __devinit ibmtr_attach(struct pcmcia_device *link) { ibmtr_dev_t *info; struct net_device *dev; @@ -217,7 +217,7 @@ static void ibmtr_detach(struct pcmcia_device *link) #define CS_CHECK(fn, ret) \ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0) -static int ibmtr_config(struct pcmcia_device *link) +static int __devinit ibmtr_config(struct pcmcia_device *link) { ibmtr_dev_t *info = link->priv; struct net_device *dev = info->dev; diff --git a/drivers/net/skge.c b/drivers/net/skge.c index eea75a401b0..8fecf1b817f 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -3275,24 +3275,30 @@ static int skge_set_mac_address(struct net_device *dev, void *p) struct skge_hw *hw = skge->hw; unsigned port = skge->port; const struct sockaddr *addr = p; + u16 ctrl; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - mutex_lock(&hw->phy_mutex); memcpy(dev->dev_addr, addr->sa_data, 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 (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); + /* disable Rx */ + 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); + + 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); + } } - mutex_unlock(&hw->phy_mutex); + + gma_write16(hw, port, GM_GP_CTRL, ctrl); return 0; } diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c index 36202e94ee9..01d55315ee8 100644 --- a/drivers/net/tokenring/ibmtr.c +++ b/drivers/net/tokenring/ibmtr.c @@ -346,7 +346,7 @@ static void ibmtr_cleanup_card(struct net_device *dev) * which references it. ****************************************************************************/ -static int __init ibmtr_probe(struct net_device *dev) +static int __devinit ibmtr_probe(struct net_device *dev) { int i; int base_addr = dev->base_addr; @@ -366,7 +366,7 @@ static int __init ibmtr_probe(struct net_device *dev) return -ENODEV; } -int __init ibmtr_probe_card(struct net_device *dev) +int __devinit ibmtr_probe_card(struct net_device *dev) { int err = ibmtr_probe(dev); if (!err) { diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 24a29c99ba9..9aeac76184f 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -190,13 +190,13 @@ /* Structure/enum declaration ------------------------------- */ struct tx_desc { - u32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ + __le32 tdes0, tdes1, tdes2, tdes3; /* Data for the card */ char *tx_buf_ptr; /* Data for us */ struct tx_desc *next_tx_desc; } __attribute__(( aligned(32) )); struct rx_desc { - u32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ + __le32 rdes0, rdes1, rdes2, rdes3; /* Data for the card */ struct sk_buff *rx_skb_ptr; /* Data for us */ struct rx_desc *next_rx_desc; } __attribute__(( aligned(32) )); @@ -458,7 +458,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev, /* read 64 word srom data */ for (i = 0; i < 64; i++) - ((u16 *) db->srom)[i] = + ((__le16 *) db->srom)[i] = cpu_to_le16(read_srom_word(db->ioaddr, i)); /* Set Node address */ diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 01869b1782e..ad33e015951 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -100,6 +100,7 @@ static void msi_set_mask_bit(unsigned int irq, int flag) BUG(); break; } + entry->msi_attrib.masked = !!flag; } void read_msi_msg(unsigned int irq, struct msi_msg *msg) @@ -179,6 +180,7 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) default: BUG(); } + entry->msg = *msg; } void mask_msi_irq(unsigned int irq) @@ -225,164 +227,60 @@ static struct msi_desc* alloc_msi_entry(void) } #ifdef CONFIG_PM -static int __pci_save_msi_state(struct pci_dev *dev) -{ - int pos, i = 0; - u16 control; - struct pci_cap_saved_state *save_state; - u32 *cap; - - if (!dev->msi_enabled) - return 0; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (pos <= 0) - return 0; - - save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u32) * 5, - GFP_KERNEL); - if (!save_state) { - printk(KERN_ERR "Out of memory in pci_save_msi_state\n"); - return -ENOMEM; - } - cap = &save_state->data[0]; - - pci_read_config_dword(dev, pos, &cap[i++]); - control = cap[0] >> 16; - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, &cap[i++]); - if (control & PCI_MSI_FLAGS_64BIT) { - pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, &cap[i++]); - pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, &cap[i++]); - } else - pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); - if (control & PCI_MSI_FLAGS_MASKBIT) - pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); - save_state->cap_nr = PCI_CAP_ID_MSI; - pci_add_saved_cap(dev, save_state); - return 0; -} - static void __pci_restore_msi_state(struct pci_dev *dev) { - int i = 0, pos; + int pos; u16 control; - struct pci_cap_saved_state *save_state; - u32 *cap; + struct msi_desc *entry; if (!dev->msi_enabled) return; - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSI); - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!save_state || pos <= 0) - return; - cap = &save_state->data[0]; + entry = get_irq_msi(dev->irq); + pos = entry->msi_attrib.pos; pci_intx(dev, 0); /* disable intx */ - control = cap[i++] >> 16; msi_set_enable(dev, 0); - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, cap[i++]); - if (control & PCI_MSI_FLAGS_64BIT) { - pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, cap[i++]); - pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, cap[i++]); - } else - pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, cap[i++]); - if (control & PCI_MSI_FLAGS_MASKBIT) - pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, cap[i++]); + write_msi_msg(dev->irq, &entry->msg); + if (entry->msi_attrib.maskbit) + msi_set_mask_bit(dev->irq, entry->msi_attrib.masked); + + pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control); + control &= ~(PCI_MSI_FLAGS_QSIZE | PCI_MSI_FLAGS_ENABLE); + if (entry->msi_attrib.maskbit || !entry->msi_attrib.masked) + control |= PCI_MSI_FLAGS_ENABLE; pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); - pci_remove_saved_cap(save_state); - kfree(save_state); -} - -static int __pci_save_msix_state(struct pci_dev *dev) -{ - int pos; - int irq, head, tail = 0; - u16 control; - struct pci_cap_saved_state *save_state; - - if (!dev->msix_enabled) - return 0; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos <= 0) - return 0; - - /* save the capability */ - pci_read_config_word(dev, msi_control_reg(pos), &control); - save_state = kzalloc(sizeof(struct pci_cap_saved_state) + sizeof(u16), - GFP_KERNEL); - if (!save_state) { - printk(KERN_ERR "Out of memory in pci_save_msix_state\n"); - return -ENOMEM; - } - *((u16 *)&save_state->data[0]) = control; - - /* save the table */ - irq = head = dev->first_msi_irq; - while (head != tail) { - struct msi_desc *entry; - - entry = get_irq_msi(irq); - read_msi_msg(irq, &entry->msg_save); - - tail = entry->link.tail; - irq = tail; - } - - save_state->cap_nr = PCI_CAP_ID_MSIX; - pci_add_saved_cap(dev, save_state); - return 0; -} - -int pci_save_msi_state(struct pci_dev *dev) -{ - int rc; - - rc = __pci_save_msi_state(dev); - if (rc) - return rc; - - rc = __pci_save_msix_state(dev); - - return rc; } static void __pci_restore_msix_state(struct pci_dev *dev) { - u16 save; int pos; int irq, head, tail = 0; struct msi_desc *entry; - struct pci_cap_saved_state *save_state; + u16 control; if (!dev->msix_enabled) return; - save_state = pci_find_saved_cap(dev, PCI_CAP_ID_MSIX); - if (!save_state) - return; - save = *((u16 *)&save_state->data[0]); - pci_remove_saved_cap(save_state); - kfree(save_state); - - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (pos <= 0) - return; - /* route the table */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 0); irq = head = dev->first_msi_irq; + entry = get_irq_msi(irq); + pos = entry->msi_attrib.pos; while (head != tail) { entry = get_irq_msi(irq); - write_msi_msg(irq, &entry->msg_save); + write_msi_msg(irq, &entry->msg); + msi_set_mask_bit(irq, entry->msi_attrib.masked); tail = entry->link.tail; irq = tail; } - pci_write_config_word(dev, msi_control_reg(pos), save); + pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); + control &= ~PCI_MSIX_FLAGS_MASKALL; + control |= PCI_MSIX_FLAGS_ENABLE; + pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); } void pci_restore_msi_state(struct pci_dev *dev) @@ -420,6 +318,7 @@ static int msi_capability_init(struct pci_dev *dev) entry->msi_attrib.is_64 = is_64bit_address(control); entry->msi_attrib.entry_nr = 0; entry->msi_attrib.maskbit = is_mask_bit_support(control); + entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */ entry->msi_attrib.pos = pos; if (is_mask_bit_support(control)) { @@ -507,6 +406,7 @@ static int msix_capability_init(struct pci_dev *dev, entry->msi_attrib.is_64 = 1; entry->msi_attrib.entry_nr = j; entry->msi_attrib.maskbit = 1; + entry->msi_attrib.masked = 1; entry->msi_attrib.default_irq = dev->irq; entry->msi_attrib.pos = pos; entry->dev = dev; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a32db062815..d3eab057b2d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -551,7 +551,9 @@ static int pci_save_pcie_state(struct pci_dev *dev) if (pos <= 0) return 0; - save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); + if (!save_state) + save_state = kzalloc(sizeof(*save_state) + sizeof(u16) * 4, GFP_KERNEL); if (!save_state) { dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); return -ENOMEM; @@ -582,8 +584,6 @@ static void pci_restore_pcie_state(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]); pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]); pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]); - pci_remove_saved_cap(save_state); - kfree(save_state); } @@ -597,7 +597,9 @@ static int pci_save_pcix_state(struct pci_dev *dev) if (pos <= 0) return 0; - save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); + save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP); + if (!save_state) + save_state = kzalloc(sizeof(*save_state) + sizeof(u16), GFP_KERNEL); if (!save_state) { dev_err(&dev->dev, "Out of memory in pci_save_pcie_state\n"); return -ENOMEM; @@ -622,8 +624,6 @@ static void pci_restore_pcix_state(struct pci_dev *dev) cap = (u16 *)&save_state->data[0]; pci_write_config_word(dev, pos + PCI_X_CMD, cap[i++]); - pci_remove_saved_cap(save_state); - kfree(save_state); } @@ -638,8 +638,6 @@ pci_save_state(struct pci_dev *dev) /* XXX: 100% dword access ok here? */ for (i = 0; i < 16; i++) pci_read_config_dword(dev, i * 4,&dev->saved_config_space[i]); - if ((i = pci_save_msi_state(dev)) != 0) - return i; if ((i = pci_save_pcie_state(dev)) != 0) return i; if ((i = pci_save_pcix_state(dev)) != 0) diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index ae7a975995a..62ea04c8af6 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -52,10 +52,8 @@ static inline void pci_no_msi(void) { } #endif #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) -int pci_save_msi_state(struct pci_dev *dev); void pci_restore_msi_state(struct pci_dev *dev); #else -static inline int pci_save_msi_state(struct pci_dev *dev) { return 0; } static inline void pci_restore_msi_state(struct pci_dev *dev) {} #endif diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 5026b345cb3..57e6ab1004d 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -451,7 +451,7 @@ int pnp_auto_config_dev(struct pnp_dev *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 *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) { diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 1926b4d3e1f..d21e04ccb02 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c @@ -24,6 +24,8 @@ #include <linux/reboot.h> #include <linux/kernel.h> #include <linux/ioctl.h> + +#include <asm/firmware.h> #include <asm/lv1call.h> #include <asm/ps3av.h> #include <asm/ps3.h> @@ -947,7 +949,12 @@ static struct ps3_vuart_port_driver ps3av_driver = { static int ps3av_module_init(void) { - int error = ps3_vuart_port_driver_register(&ps3av_driver); + int error; + + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return -ENODEV; + + error = ps3_vuart_port_driver_register(&ps3av_driver); if (error) { printk(KERN_ERR "%s: ps3_vuart_port_driver_register failed %d\n", diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c index 21c97c80aa2..bc70e81f8cb 100644 --- a/drivers/ps3/ps3av_cmd.c +++ b/drivers/ps3/ps3av_cmd.c @@ -485,12 +485,12 @@ static u8 ps3av_cnv_mclk(u32 fs) static const u32 ps3av_ns_table[][5] = { /* D1, D2, D3, D4, D5 */ - [PS3AV_CMD_AUDIO_FS_44K-BASE] { 6272, 6272, 17836, 17836, 8918 }, - [PS3AV_CMD_AUDIO_FS_48K-BASE] { 6144, 6144, 11648, 11648, 5824 }, - [PS3AV_CMD_AUDIO_FS_88K-BASE] { 12544, 12544, 35672, 35672, 17836 }, - [PS3AV_CMD_AUDIO_FS_96K-BASE] { 12288, 12288, 23296, 23296, 11648 }, - [PS3AV_CMD_AUDIO_FS_176K-BASE] { 25088, 25088, 71344, 71344, 35672 }, - [PS3AV_CMD_AUDIO_FS_192K-BASE] { 24576, 24576, 46592, 46592, 23296 } + [PS3AV_CMD_AUDIO_FS_44K-BASE] = { 6272, 6272, 17836, 17836, 8918 }, + [PS3AV_CMD_AUDIO_FS_48K-BASE] = { 6144, 6144, 11648, 11648, 5824 }, + [PS3AV_CMD_AUDIO_FS_88K-BASE] = { 12544, 12544, 35672, 35672, 17836 }, + [PS3AV_CMD_AUDIO_FS_96K-BASE] = { 12288, 12288, 23296, 23296, 11648 }, + [PS3AV_CMD_AUDIO_FS_176K-BASE] = { 25088, 25088, 71344, 71344, 35672 }, + [PS3AV_CMD_AUDIO_FS_192K-BASE] = { 24576, 24576, 46592, 46592, 23296 } }; static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) @@ -543,9 +543,10 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) #undef BASE -static u8 ps3av_cnv_enable(u32 source, u8 *enable) +static u8 ps3av_cnv_enable(u32 source, const u8 *enable) { - u8 *p, ret = 0; + const u8 *p; + u8 ret = 0; if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) { ret = 0x03; @@ -559,9 +560,10 @@ static u8 ps3av_cnv_enable(u32 source, u8 *enable) return ret; } -static u8 ps3av_cnv_fifomap(u8 *map) +static u8 ps3av_cnv_fifomap(const u8 *map) { - u8 *p, ret = 0; + const u8 *p; + u8 ret = 0; p = map; ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6); @@ -615,7 +617,7 @@ static void ps3av_cnv_info(struct ps3av_audio_info_frame *info, info->pb5.lsv = mode->audio_downmix_level; } -static void ps3av_cnv_chstat(u8 *chstat, u8 *cs_info) +static void ps3av_cnv_chstat(u8 *chstat, const u8 *cs_info) { memcpy(chstat, cs_info, 5); } diff --git a/drivers/ps3/sys-manager.c b/drivers/ps3/sys-manager.c index 0fc30be8b81..3aa2b0dcc36 100644 --- a/drivers/ps3/sys-manager.c +++ b/drivers/ps3/sys-manager.c @@ -22,7 +22,10 @@ #include <linux/module.h> #include <linux/workqueue.h> #include <linux/reboot.h> + +#include <asm/firmware.h> #include <asm/ps3.h> + #include "vuart.h" MODULE_AUTHOR("Sony Corporation"); @@ -598,6 +601,9 @@ static struct ps3_vuart_port_driver ps3_sys_manager = { static int __init ps3_sys_manager_init(void) { + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return -ENODEV; + return ps3_vuart_port_driver_register(&ps3_sys_manager); } diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c index 746298107d6..6c12744eeb9 100644 --- a/drivers/ps3/vuart.c +++ b/drivers/ps3/vuart.c @@ -952,7 +952,7 @@ fail_alloc_irq: kfree(dev->priv); dev->priv = NULL; fail_alloc: - vuart_bus_priv.devices[port_number] = 0; + vuart_bus_priv.devices[port_number] = NULL; fail_match: up(&vuart_bus_priv.probe_mutex); dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); @@ -978,7 +978,7 @@ static int ps3_vuart_remove(struct device *_dev) dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, __LINE__, dev->core.bus_id); - vuart_bus_priv.devices[dev->priv->port_number] = 0; + vuart_bus_priv.devices[dev->priv->port_number] = NULL; if (--vuart_bus_priv.use_count == 0) { BUG(); @@ -1031,7 +1031,7 @@ int __init ps3_vuart_bus_init(void) pr_debug("%s:%d:\n", __func__, __LINE__); if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) - return 0; + return -ENODEV; init_MUTEX(&vuart_bus_priv.probe_mutex); result = bus_register(&ps3_vuart_bus); diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index d48e3ca4752..5aeb68e732b 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -71,19 +71,31 @@ __ccwgroup_remove_symlinks(struct ccwgroup_device *gdev) * Provide an 'ungroup' attribute so the user can remove group devices no * longer needed or accidentially created. Saves memory :) */ +static void ccwgroup_ungroup_callback(struct device *dev) +{ + struct ccwgroup_device *gdev = to_ccwgroupdev(dev); + + __ccwgroup_remove_symlinks(gdev); + device_unregister(dev); +} + static ssize_t ccwgroup_ungroup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct ccwgroup_device *gdev; + int rc; gdev = to_ccwgroupdev(dev); if (gdev->state != CCWGROUP_OFFLINE) return -EINVAL; - __ccwgroup_remove_symlinks(gdev); - device_unregister(dev); - + /* Note that we cannot unregister the device from one of its + * attribute methods, so we have to use this roundabout approach. + */ + rc = device_schedule_callback(dev, ccwgroup_ungroup_callback); + if (rc) + count = rc; return count; } diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h index e95c281f1e3..84b108d7c7f 100644 --- a/drivers/s390/net/qeth.h +++ b/drivers/s390/net/qeth.h @@ -873,7 +873,7 @@ qeth_realloc_headroom(struct qeth_card *card, struct sk_buff *skb, int size) } static inline struct sk_buff * -qeth_pskb_unshare(struct sk_buff *skb, int pri) +qeth_pskb_unshare(struct sk_buff *skb, gfp_t pri) { struct sk_buff *nskb; if (!skb_cloned(skb)) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index c275dcac3f1..939de0de18b 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -452,10 +452,22 @@ store_rescan_field (struct device *dev, struct device_attribute *attr, const cha } static DEVICE_ATTR(rescan, S_IWUSR, NULL, store_rescan_field); +static void sdev_store_delete_callback(struct device *dev) +{ + scsi_remove_device(to_scsi_device(dev)); +} + static ssize_t sdev_store_delete(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - scsi_remove_device(to_scsi_device(dev)); + int rc; + + /* An attribute cannot be unregistered by one of its own methods, + * so we have to use this roundabout approach. + */ + rc = device_schedule_callback(dev, sdev_store_delete_callback); + if (rc) + count = rc; return count; }; static DEVICE_ATTR(delete, S_IWUSR, NULL, sdev_store_delete); diff --git a/drivers/spi/at25.c b/drivers/spi/at25.c index 48e4f48e779..8efa07e8b8c 100644 --- a/drivers/spi/at25.c +++ b/drivers/spi/at25.c @@ -291,7 +291,7 @@ static int at25_probe(struct spi_device *spi) */ 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; } diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 6fa260d1a9b..66e7bc98579 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -425,7 +425,7 @@ static int atmel_spi_setup(struct spi_device *spi) 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, diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c index 24a330d8239..88425e1af4d 100644 --- a/drivers/spi/spi_bitbang.c +++ b/drivers/spi/spi_bitbang.c @@ -302,10 +302,6 @@ static void bitbang_work(struct work_struct *work) 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_device *spi, struct spi_message *m) 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); diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 651379c51ae..220abce63e4 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c @@ -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 */ diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 7f5a5983681..e4f0dd00ae8 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -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 diff --git a/drivers/video/backlight/locomolcd.c b/drivers/video/backlight/locomolcd.c index d1312477813..6b488b8a7ee 100644 --- a/drivers/video/backlight/locomolcd.c +++ b/drivers/video/backlight/locomolcd.c @@ -199,8 +199,8 @@ static int locomolcd_remove(struct locomo_dev *dev) { unsigned long flags; - locomobl_data.brightness = 0; - locomobl_data.power = 0; + locomolcd_bl_device->props.brightness = 0; + locomolcd_bl_device->props.power = 0; locomolcd_set_intensity(locomolcd_bl_device); backlight_device_unregister(locomolcd_bl_device); diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c index 70226935786..836ab4df0ef 100644 --- a/drivers/video/backlight/progear_bl.c +++ b/drivers/video/backlight/progear_bl.c @@ -65,13 +65,13 @@ static int progearbl_probe(struct platform_device *pdev) u8 temp; struct backlight_device *progear_backlight_device; - pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, 0); + pmu_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL); if (!pmu_dev) { printk("ALI M7101 PMU not found.\n"); return -ENODEV; } - sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, 0); + sb_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); if (!sb_dev) { printk("ALI 1533 SB not found.\n"); pci_dev_put(pmu_dev); diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 9bb6257d691..b0b2e40bbd9 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -186,8 +186,7 @@ static int bw2_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) * Initialisation */ -static void -bw2_init_fix(struct fb_info *info, int linebytes) +static void __devinit bw2_init_fix(struct fb_info *info, int linebytes) { strlcpy(info->fix.id, "bwtwo", sizeof(info->fix.id)); @@ -199,43 +198,44 @@ bw2_init_fix(struct fb_info *info, int linebytes) info->fix.accel = FB_ACCEL_SUN_BWTWO; } -static u8 bw2regs_1600[] __initdata = { +static u8 bw2regs_1600[] __devinitdata = { 0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13, 0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e, 0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x21, 0 }; -static u8 bw2regs_ecl[] __initdata = { +static u8 bw2regs_ecl[] __devinitdata = { 0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c, 0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23, 0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static u8 bw2regs_analog[] __initdata = { +static u8 bw2regs_analog[] __devinitdata = { 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13, 0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22, 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static u8 bw2regs_76hz[] __initdata = { +static u8 bw2regs_76hz[] __devinitdata = { 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f, 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a, 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x24, 0 }; -static u8 bw2regs_66hz[] __initdata = { +static u8 bw2regs_66hz[] __devinitdata = { 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14, 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24, 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01, 0x10, 0x20, 0 }; -static void bw2_do_default_mode(struct bw2_par *par, struct fb_info *info, - int *linebytes) +static void __devinit bw2_do_default_mode(struct bw2_par *par, + struct fb_info *info, + int *linebytes) { u8 status, mon; u8 *p; diff --git a/drivers/video/cg14.c b/drivers/video/cg14.c index ec6a51a5822..b071bb632b9 100644 --- a/drivers/video/cg14.c +++ b/drivers/video/cg14.c @@ -354,7 +354,8 @@ static int cg14_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) * Initialisation */ -static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_node *dp) +static void __devinit cg14_init_fix(struct fb_info *info, int linebytes, + struct device_node *dp) { const char *name = dp->name; @@ -368,7 +369,7 @@ static void cg14_init_fix(struct fb_info *info, int linebytes, struct device_nod info->fix.accel = FB_ACCEL_SUN_CG14; } -static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __initdata = { +static struct sbus_mmap_map __cg14_mmap_map[CG14_MMAP_ENTRIES] __devinitdata = { { .voff = CG14_REGS, .poff = 0x80000000, diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 4afa30522fd..0166ec2ccf3 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c @@ -384,6 +384,19 @@ SavageSetup2DEngine(struct savagefb_par *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, int min_m, int min_n1, int max_n1, #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_info *info) savagefb_set_fix(info); savagefb_set_clip(info); - SavagePrintRegs(); + SavagePrintRegs(par); return 0; } @@ -2155,7 +2168,6 @@ static int __devinit savagefb_probe(struct pci_dev* dev, int video_len; DBG("savagefb_probe"); - SavagePrintRegs(); info = framebuffer_alloc(sizeof(struct savagefb_par), &dev->dev); if (!info) diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index 59cd1e750f3..62fa5500361 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -257,6 +257,7 @@ static void __sst_dac_write(u8 __iomem *vbase, u8 reg, u8 val) 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 */ diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 51db1182b27..a2fceba7ef8 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c @@ -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) diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 0efdf35aab2..3af76249dc8 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -220,7 +220,7 @@ */ #define CIFS_NO_HANDLE 0xFFFF -#define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL +#define NO_CHANGE_64 cpu_to_le64(0xFFFFFFFFFFFFFFFFULL) #define NO_CHANGE_32 0xFFFFFFFFUL /* IPC$ in ASCII */ diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 34750d5e4ff..5e6e37e58f3 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c @@ -1141,25 +1141,22 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) err = -ENOMEM; dentry = d_alloc(configfs_sb->s_root, &name); - if (!dentry) - goto out_release; - - d_add(dentry, NULL); + if (dentry) { + d_add(dentry, NULL); - err = configfs_attach_group(sd->s_element, &group->cg_item, - dentry); - if (!err) - dentry = NULL; - else - d_delete(dentry); + err = configfs_attach_group(sd->s_element, &group->cg_item, + dentry); + if (err) { + d_delete(dentry); + dput(dentry); + } + } mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); - if (dentry) { - dput(dentry); -out_release: - unlink_group(group); - configfs_release_fs(); + if (err) { + unlink_group(group); + configfs_release_fs(); } return err; diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 329efcd3d8c..cb20b964419 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c @@ -78,18 +78,13 @@ struct kmem_cache *ecryptfs_dentry_info_cache; */ 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; } diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index af53c02f473..93d046c85f5 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -429,7 +429,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 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. diff --git a/fs/nfs/super.c b/fs/nfs/super.c index bb516a2cfba..f1eae44b9a1 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -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; } diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c index fcdcafbb329..b62481dabae 100644 --- a/fs/nfs/sysctl.c +++ b/fs/nfs/sysctl.c @@ -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 } }; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index febdade9167..2867e6b7096 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -12,6 +12,7 @@ #include <linux/pagemap.h> #include <linux/file.h> #include <linux/writeback.h> +#include <linux/swap.h> #include <linux/sunrpc/clnt.h> #include <linux/nfs_fs.h> @@ -38,7 +39,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*, 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_cachep; 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_control *wbc) } /* + * 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 page *page) 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, struct writeback_control *wbc) 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 *mapping, struct writeback_control *wbc) 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 inode *inode, struct nfs_page *req) } /* - * 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 inode *inode, struct list_head *dst, un } #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(struct address_space *mapping, int intr) 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(struct address_space *mapping, int intr) 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, struct page *page, 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(struct rpc_task *task, void *calldata) 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; } diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index c2660cbfcd9..8d995bcef80 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -17,7 +17,6 @@ #include <linux/stat.h> #include <linux/dcache.h> #include <linux/mount.h> -#include <asm/pgtable.h> #include <linux/sunrpc/clnt.h> #include <linux/sunrpc/svc.h> diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 93628b02ef5..875c1144381 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -614,6 +614,27 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, ocfs2_rw_unlock(inode, 0); } +/* + * ocfs2_invalidatepage() and ocfs2_releasepage() are shamelessly stolen + * from ext3. PageChecked() bits have been removed as OCFS2 does not + * do journalled data. + */ +static void ocfs2_invalidatepage(struct page *page, unsigned long offset) +{ + journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; + + journal_invalidatepage(journal, page, offset); +} + +static int ocfs2_releasepage(struct page *page, gfp_t wait) +{ + journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; + + if (!page_has_buffers(page)) + return 0; + return journal_try_to_free_buffers(journal, page, wait); +} + static ssize_t ocfs2_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, @@ -661,5 +682,8 @@ const struct address_space_operations ocfs2_aops = { .commit_write = ocfs2_commit_write, .bmap = ocfs2_bmap, .sync_page = block_sync_page, - .direct_IO = ocfs2_direct_IO + .direct_IO = ocfs2_direct_IO, + .invalidatepage = ocfs2_invalidatepage, + .releasepage = ocfs2_releasepage, + .migratepage = buffer_migrate_page, }; diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 5a9779bb923..eba282da500 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1234,6 +1234,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, const char *page, size_t count) { + struct task_struct *hb_task; long fd; int sectsize; char *p = (char *)page; @@ -1319,20 +1320,28 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, */ atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); - reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s", - reg->hr_item.ci_name); - if (IS_ERR(reg->hr_task)) { - ret = PTR_ERR(reg->hr_task); + hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", + reg->hr_item.ci_name); + if (IS_ERR(hb_task)) { + ret = PTR_ERR(hb_task); mlog_errno(ret); - reg->hr_task = NULL; goto out; } + spin_lock(&o2hb_live_lock); + reg->hr_task = hb_task; + spin_unlock(&o2hb_live_lock); + ret = wait_event_interruptible(o2hb_steady_queue, atomic_read(®->hr_steady_iterations) == 0); if (ret) { - kthread_stop(reg->hr_task); + spin_lock(&o2hb_live_lock); + hb_task = reg->hr_task; reg->hr_task = NULL; + spin_unlock(&o2hb_live_lock); + + if (hb_task) + kthread_stop(hb_task); goto out; } @@ -1354,10 +1363,17 @@ out: static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, char *page) { - if (!reg->hr_task) + pid_t pid = 0; + + spin_lock(&o2hb_live_lock); + if (reg->hr_task) + pid = reg->hr_task->pid; + spin_unlock(&o2hb_live_lock); + + if (!pid) return 0; - return sprintf(page, "%u\n", reg->hr_task->pid); + return sprintf(page, "%u\n", pid); } struct o2hb_region_attribute { @@ -1495,13 +1511,17 @@ out: static void o2hb_heartbeat_group_drop_item(struct config_group *group, struct config_item *item) { + struct task_struct *hb_task; struct o2hb_region *reg = to_o2hb_region(item); /* stop the thread when the user removes the region dir */ - if (reg->hr_task) { - kthread_stop(reg->hr_task); - reg->hr_task = NULL; - } + spin_lock(&o2hb_live_lock); + hb_task = reg->hr_task; + reg->hr_task = NULL; + spin_unlock(&o2hb_live_lock); + + if (hb_task) + kthread_stop(hb_task); config_item_put(item); } @@ -1682,7 +1702,7 @@ out: } EXPORT_SYMBOL_GPL(o2hb_register_callback); -int o2hb_unregister_callback(struct o2hb_callback_func *hc) +void o2hb_unregister_callback(struct o2hb_callback_func *hc) { BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); @@ -1690,15 +1710,13 @@ int o2hb_unregister_callback(struct o2hb_callback_func *hc) __builtin_return_address(0), hc); if (list_empty(&hc->hc_item)) - return 0; + return; down_write(&o2hb_callback_sem); list_del_init(&hc->hc_item); up_write(&o2hb_callback_sem); - - return 0; } EXPORT_SYMBOL_GPL(o2hb_unregister_callback); diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h index cac6223206a..cc6d40b3977 100644 --- a/fs/ocfs2/cluster/heartbeat.h +++ b/fs/ocfs2/cluster/heartbeat.h @@ -70,7 +70,7 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, void *data, int priority); int o2hb_register_callback(struct o2hb_callback_func *hc); -int o2hb_unregister_callback(struct o2hb_callback_func *hc); +void o2hb_unregister_callback(struct o2hb_callback_func *hc); void o2hb_fill_node_map(unsigned long *map, unsigned bytes); void o2hb_init(void); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1718215fc01..69caf3e12fe 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -1638,17 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, void o2net_unregister_hb_callbacks(void) { - int ret; - - ret = o2hb_unregister_callback(&o2net_hb_up); - if (ret < 0) - mlog(ML_ERROR, "Status return %d unregistering heartbeat up " - "callback!\n", ret); - - ret = o2hb_unregister_callback(&o2net_hb_down); - if (ret < 0) - mlog(ML_ERROR, "Status return %d unregistering heartbeat down " - "callback!\n", ret); + o2hb_unregister_callback(&o2net_hb_up); + o2hb_unregister_callback(&o2net_hb_down); } int o2net_register_hb_callbacks(void) diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 77e4e6169a0..9229e04362f 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c @@ -2730,14 +2730,17 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) int ret; int lock_dropped = 0; + spin_lock(&res->spinlock); if (res->owner != dlm->node_num) { if (!__dlm_lockres_unused(res)) { mlog(ML_ERROR, "%s:%.*s: this node is not master, " "trying to free this but locks remain\n", dlm->name, res->lockname.len, res->lockname.name); } + spin_unlock(&res->spinlock); goto leave; } + spin_unlock(&res->spinlock); /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ spin_unlock(&dlm->spinlock); diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 8ffa0916eb8..6421a8fae1d 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -265,8 +265,10 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, /* This may drop and reacquire the dlm spinlock if it * has to do migration. */ mlog(0, "calling dlm_purge_lockres!\n"); + dlm_lockres_get(lockres); if (dlm_purge_lockres(dlm, lockres)) BUG(); + dlm_lockres_put(lockres); mlog(0, "DONE calling dlm_purge_lockres!\n"); /* Avoid adding any scheduling latencies */ diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index 8fc52d6d0ce..b25ef63781b 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c @@ -164,8 +164,10 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb) } status = o2hb_register_callback(&osb->osb_hb_up); - if (status < 0) + if (status < 0) { mlog_errno(status); + o2hb_unregister_callback(&osb->osb_hb_down); + } bail: return status; @@ -173,18 +175,11 @@ bail: void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) { - int status; - if (ocfs2_mount_local(osb)) return; - status = o2hb_unregister_callback(&osb->osb_hb_down); - if (status < 0) - mlog_errno(status); - - status = o2hb_unregister_callback(&osb->osb_hb_up); - if (status < 0) - mlog_errno(status); + o2hb_unregister_callback(&osb->osb_hb_down); + o2hb_unregister_callback(&osb->osb_hb_up); } void ocfs2_stop_heartbeat(struct ocfs2_super *osb) diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 74552c60b67..6e8bb66fe61 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig @@ -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. diff --git a/fs/partitions/check.c b/fs/partitions/check.c index e46d237b10f..8a7d0035ad7 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -541,7 +541,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) 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; diff --git a/fs/proc/base.c b/fs/proc/base.c index 01f7769da8e..989af5e55d1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1558,29 +1558,20 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, size_t count, loff_t *ppos) { struct inode * inode = file->f_path.dentry->d_inode; - unsigned long page; + char *p = NULL; ssize_t length; struct task_struct *task = get_proc_task(inode); - length = -ESRCH; if (!task) - goto out_no_task; - - if (count > PAGE_SIZE) - count = PAGE_SIZE; - length = -ENOMEM; - if (!(page = __get_free_page(GFP_KERNEL))) - goto out; + return -ESRCH; length = security_getprocattr(task, (char*)file->f_path.dentry->d_name.name, - (void*)page, count); - if (length >= 0) - length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); - free_page(page); -out: + &p); put_task_struct(task); -out_no_task: + if (length > 0) + length = simple_read_from_buffer(buf, count, ppos, p, length); + kfree(p); return length; } diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 42261dbdf60..723f7c66766 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c @@ -181,6 +181,7 @@ static int smb_setup_request(struct smb_request *req) req->rq_errno = 0; req->rq_fragment = 0; kfree(req->rq_trans2buffer); + req->rq_trans2buffer = NULL; return 0; } diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 8d4d839a9d8..fc4633378dc 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -168,12 +168,12 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) ssize_t retval = 0; down(&buffer->sem); - if (buffer->orphaned) { - retval = -ENODEV; - goto out; - } if (buffer->needs_read_fill) { - if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) + if (buffer->orphaned) + retval = -ENODEV; + else + retval = fill_read_buffer(file->f_path.dentry,buffer); + if (retval) goto out; } pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", @@ -629,6 +629,60 @@ void sysfs_remove_file_from_group(struct kobject *kobj, } EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); +struct sysfs_schedule_callback_struct { + struct kobject *kobj; + void (*func)(void *); + void *data; + struct work_struct work; +}; + +static void sysfs_schedule_callback_work(struct work_struct *work) +{ + struct sysfs_schedule_callback_struct *ss = container_of(work, + struct sysfs_schedule_callback_struct, work); + + (ss->func)(ss->data); + kobject_put(ss->kobj); + kfree(ss); +} + +/** + * sysfs_schedule_callback - helper to schedule a callback for a kobject + * @kobj: object we're acting for. + * @func: callback function to invoke later. + * @data: argument to pass to @func. + * + * sysfs attribute methods must not unregister themselves or their parent + * kobject (which would amount to the same thing). Attempts to do so will + * deadlock, since unregistration is mutually exclusive with driver + * callbacks. + * + * Instead methods can call this routine, which will attempt to allocate + * and schedule a workqueue request to call back @func with @data as its + * argument in the workqueue's process context. @kobj will be pinned + * until @func returns. + * + * Returns 0 if the request was submitted, -ENOMEM if storage could not + * be allocated. + */ +int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), + void *data) +{ + struct sysfs_schedule_callback_struct *ss; + + ss = kmalloc(sizeof(*ss), GFP_KERNEL); + if (!ss) + return -ENOMEM; + kobject_get(kobj); + ss->kobj = kobj; + ss->func = func; + ss->data = data; + INIT_WORK(&ss->work, sysfs_schedule_callback_work); + schedule_work(&ss->work); + return 0; +} +EXPORT_SYMBOL_GPL(sysfs_schedule_callback); + EXPORT_SYMBOL_GPL(sysfs_create_file); EXPORT_SYMBOL_GPL(sysfs_remove_file); diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index ccb7d722c55..4de5c6b8991 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c @@ -222,13 +222,17 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) static inline void orphan_all_buffers(struct inode *node) { - struct sysfs_buffer_collection *set = node->i_private; + struct sysfs_buffer_collection *set; struct sysfs_buffer *buf; mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); - if (node->i_private) { - list_for_each_entry(buf, &set->associates, associates) + set = node->i_private; + if (set) { + list_for_each_entry(buf, &set->associates, associates) { + down(&buf->sem); buf->orphaned = 1; + up(&buf->sem); + } } mutex_unlock(&node->i_mutex); } diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index bcc44084e00..841ac25fd95 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c @@ -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 *inode, void *p, u64 fragment, 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); diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index b868878009b..c28a8b6f2fe 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c @@ -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) diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index fb34ad03e22..013d7afe7cd 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -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, struct ufs2_inode *ufs2_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 inode *inode, struct ufs2_inode *ufs_inode) 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); diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 749581fa772..79c54c85fb5 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c @@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode *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 *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 inode *inode, u64 offset, void *p) } 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 inode *inode, u64 offset, void *p) 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 inode *inode, u64 offset, void *p) } 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 inode *inode) 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 inode *inode) } 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 inode *inode) } 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 inode *inode) 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: diff --git a/include/asm-arm/arch-at91/gpio.h b/include/asm-arm/arch-at91/gpio.h index 98ad2114f43..0a241e2fb67 100644 --- a/include/asm-arm/arch-at91/gpio.h +++ b/include/asm-arm/arch-at91/gpio.h @@ -223,7 +223,7 @@ static inline void gpio_free(unsigned gpio) } 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) { diff --git a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h index 9444958bec1..ed35e5c94f4 100644 --- a/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h +++ b/include/asm-arm/arch-ixp4xx/ixp4xx-regs.h @@ -144,9 +144,9 @@ #define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000) #define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000) #define IXP4XX_TIMER_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x5000) -#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x6000) -#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x7000) -#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_PHYS + 0x8000) +#define IXP4XX_NPEA_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x6000) +#define IXP4XX_NPEB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x7000) +#define IXP4XX_NPEC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x8000) #define IXP4XX_EthB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x9000) #define IXP4XX_EthC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xA000) #define IXP4XX_USB_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0xB000) diff --git a/include/asm-arm/arch-lh7a40x/entry-macro.S b/include/asm-arm/arch-lh7a40x/entry-macro.S index 502700604e0..ffe397250f0 100644 --- a/include/asm-arm/arch-lh7a40x/entry-macro.S +++ b/include/asm-arm/arch-lh7a40x/entry-macro.S @@ -86,6 +86,12 @@ branch_irq_lh7a400: b 1000f .macro disable_fiq .endm + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0 mov \base, #io_p2v(0x80000000) @ APB registers @@ -105,6 +111,12 @@ branch_irq_lh7a400: b 1000f .macro disable_fiq .endm + .macro get_irqnr_preamble, base, tmp + .endm + + .macro arch_ret_to_user, tmp1, tmp2 + .endm + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp mov \irqnr, #0 @ VIC1 irq base mov \base, #io_p2v(0x80000000) @ APB registers diff --git a/include/asm-arm/arch-omap/gpio.h b/include/asm-arm/arch-omap/gpio.h index 3762a6ae6a7..590917efc94 100644 --- a/include/asm-arm/arch-omap/gpio.h +++ b/include/asm-arm/arch-omap/gpio.h @@ -113,8 +113,9 @@ static inline int gpio_direction_input(unsigned gpio) 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); } diff --git a/include/asm-arm/arch-pxa/gpio.h b/include/asm-arm/arch-pxa/gpio.h index 3d348a35115..aeba24347f8 100644 --- a/include/asm-arm/arch-pxa/gpio.h +++ b/include/asm-arm/arch-pxa/gpio.h @@ -43,9 +43,9 @@ static inline int gpio_direction_input(unsigned gpio) 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) diff --git a/include/asm-arm/arch-s3c2410/gpio.h b/include/asm-arm/arch-s3c2410/gpio.h index d47ae453f8c..7583895fd33 100644 --- a/include/asm-arm/arch-s3c2410/gpio.h +++ b/include/asm-arm/arch-s3c2410/gpio.h @@ -44,9 +44,11 @@ static inline int gpio_direction_input(unsigned gpio) 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; } diff --git a/include/asm-arm/arch-sa1100/gpio.h b/include/asm-arm/arch-sa1100/gpio.h index da7575b0e5d..e7a9d26e22a 100644 --- a/include/asm-arm/arch-sa1100/gpio.h +++ b/include/asm-arm/arch-sa1100/gpio.h @@ -38,7 +38,7 @@ static inline void gpio_free(unsigned gpio) } 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) diff --git a/include/asm-avr32/arch-at32ap/gpio.h b/include/asm-avr32/arch-at32ap/gpio.h index fcb756bdaa8..80a21aa9ae7 100644 --- a/include/asm-avr32/arch-at32ap/gpio.h +++ b/include/asm-avr32/arch-at32ap/gpio.h @@ -10,7 +10,7 @@ int __must_check gpio_request(unsigned int gpio, const char *label); 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); diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h index 64544cb85d6..b04333ea6f3 100644 --- a/include/asm-i386/nmi.h +++ b/include/asm-i386/nmi.h @@ -33,7 +33,7 @@ extern int nmi_watchdog_tick (struct pt_regs * regs, unsigned reason); extern atomic_t nmi_active; extern unsigned int nmi_watchdog; -#define NMI_DEFAULT 0 +#define NMI_DEFAULT -1 #define NMI_NONE 0 #define NMI_IO_APIC 1 #define NMI_LOCAL_APIC 2 diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index f8319cae2ac..46dc34ca887 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -130,7 +130,7 @@ struct paravirt_ops void (*flush_tlb_kernel)(void); void (*flush_tlb_single)(u32 addr); - void (fastcall *map_pt_hook)(int type, pte_t *va, u32 pfn); + void (*map_pt_hook)(int type, pte_t *va, u32 pfn); void (*alloc_pt)(u32 pfn); void (*alloc_pd)(u32 pfn); diff --git a/include/asm-i386/sync_bitops.h b/include/asm-i386/sync_bitops.h index c94d51c993e..7d72351bea7 100644 --- a/include/asm-i386/sync_bitops.h +++ b/include/asm-i386/sync_bitops.h @@ -130,7 +130,7 @@ static inline int sync_test_and_change_bit(int nr, volatile unsigned long* addr) 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; diff --git a/include/asm-i386/vmi_time.h b/include/asm-i386/vmi_time.h index 94d0a12a411..c3a1fcf66c9 100644 --- a/include/asm-i386/vmi_time.h +++ b/include/asm-i386/vmi_time.h @@ -54,7 +54,7 @@ extern unsigned long vmi_cpu_khz(void); #ifdef CONFIG_X86_LOCAL_APIC extern void __init vmi_timer_setup_boot_alarm(void); -extern void __init vmi_timer_setup_secondary_alarm(void); +extern void __devinit vmi_timer_setup_secondary_alarm(void); extern void apic_vmi_timer_interrupt(void); #endif diff --git a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h index 3c96ac19154..ca33eb181ff 100644 --- a/include/asm-ia64/machvec.h +++ b/include/asm-ia64/machvec.h @@ -168,6 +168,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *); # 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; diff --git a/include/asm-m32r/dma-mapping.h b/include/asm-m32r/dma-mapping.h index a7fa0302bda..f9b58ebba36 100644 --- a/include/asm-m32r/dma-mapping.h +++ b/include/asm-m32r/dma-mapping.h @@ -1,23 +1,6 @@ #ifndef _ASM_M32R_DMA_MAPPING_H #define _ASM_M32R_DMA_MAPPING_H -/* - * NOTE: Do not include <asm-generic/dma-mapping.h> - * Because it requires PCI stuffs, but current M32R don't provide these. - */ - -static inline void * -dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - gfp_t flag) -{ - return (void *)NULL; -} - -static inline void -dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, - dma_addr_t dma_handle) -{ - return; -} +#include <asm-generic/dma-mapping-broken.h> #endif /* _ASM_M32R_DMA_MAPPING_H */ diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index 00259ed6fc9..a26cdeb46a5 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -32,7 +32,7 @@ extern void dma_free_coherent(struct device *, size_t, void *, dma_addr_t); static inline void *dma_alloc_noncoherent(struct device *dev, size_t size, - dma_addr_t *handle, int flag) + dma_addr_t *handle, gfp_t flag) { return dma_alloc_coherent(dev, size, handle, flag); } diff --git a/include/asm-m68k/mc146818rtc.h b/include/asm-m68k/mc146818rtc.h index 11fe12ddb91..9f70a01f73d 100644 --- a/include/asm-m68k/mc146818rtc.h +++ b/include/asm-m68k/mc146818rtc.h @@ -11,6 +11,7 @@ #include <asm/atarihw.h> #define RTC_PORT(x) (TT_RTC_BAS + 2*(x)) +#define RTC_ALWAYS_BCD 0 #define CMOS_READ(addr) ({ \ atari_outb_p((addr),RTC_PORT(0)); \ diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 8578869a8bc..1ac50b6c47a 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -79,9 +79,9 @@ static __inline__ void atomic_add(int i, atomic_t * v) } 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, atomic_t * v) } 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(int i, atomic_t * v) } 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(int i, atomic_t * v) } 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_positive(int i, atomic_t * v) } 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 i, atomic64_t * v) } 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 i, atomic64_t * v) } 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_return(long i, atomic64_t * v) } 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_return(long i, atomic64_t * v) } 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_positive(long i, atomic64_t * v) } 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(); diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 8959da245cf..d995413e11f 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -100,9 +100,9 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr) 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 long nr, volatile unsigned long *addr) 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 long nr, volatile unsigned long *addr) 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(unsigned long nr, 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(unsigned long nr, 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(unsigned long nr, 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; } diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index eadca266f15..5e4bed123b4 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h @@ -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) diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h index 610d0cdeaa9..22fe8453fcc 100644 --- a/include/asm-mips/cpu-info.h +++ b/include/asm-mips/cpu-info.h @@ -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); diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h index efef843b93f..4e12d1f9534 100644 --- a/include/asm-mips/fpu.h +++ b/include/asm-mips/fpu.h @@ -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(struct task_struct *tsk) 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 */ diff --git a/include/asm-mips/mach-au1x00/au1xxx_ide.h b/include/asm-mips/mach-au1x00/au1xxx_ide.h index e9fa252f8a3..8fcae21adbd 100644 --- a/include/asm-mips/mach-au1x00/au1xxx_ide.h +++ b/include/asm-mips/mach-au1x00/au1xxx_ide.h @@ -141,40 +141,6 @@ static int auide_ddma_init( _auide_hwif *auide ); 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 : * * * diff --git a/include/asm-mips/mach-ip27/dma-coherence.h b/include/asm-mips/mach-ip27/dma-coherence.h index 659816e200d..3fdbbf68e95 100644 --- a/include/asm-mips/mach-ip27/dma-coherence.h +++ b/include/asm-mips/mach-ip27/dma-coherence.h @@ -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_phys(dma_addr_t dma_addr) 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) { } diff --git a/include/asm-mips/mach-ip32/dma-coherence.h b/include/asm-mips/mach-ip32/dma-coherence.h index 950be17bbb8..c3f9a6a20eb 100644 --- a/include/asm-mips/mach-ip32/dma-coherence.h +++ b/include/asm-mips/mach-ip32/dma-coherence.h @@ -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_phys(dma_addr_t dma_addr) 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) { } diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h index 59162f74a79..65778c890a6 100644 --- a/include/asm-mips/rtlx.h +++ b/include/asm-mips/rtlx.h @@ -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); diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 597a3743f6a..290887077e4 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -121,10 +121,10 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val) } 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 __u64 * m, __u64 val) } 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_u32(volatile int * m, unsigned long old, } 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_u64(volatile int * m, unsigned long old, } 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(); diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index fbcda820447..6cf05f4a4e7 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h @@ -119,6 +119,7 @@ register struct thread_info *__current_thread_info __asm__("$28"); #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<<TIF_SYSCALL_TRACE) diff --git a/include/asm-powerpc/floppy.h b/include/asm-powerpc/floppy.h index a0f14eea1da..afa700ded87 100644 --- a/include/asm-powerpc/floppy.h +++ b/include/asm-powerpc/floppy.h @@ -178,7 +178,7 @@ static struct fd_dma_ops virt_dma_ops = ._dma_setup = vdma_dma_setup }; -static int fd_request_dma() +static int fd_request_dma(void) { if (can_use_virtual_dma & 1) { fd_ops = &virt_dma_ops; diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h index 0f9f2dd24a7..31d5054be20 100644 --- a/include/asm-powerpc/spu.h +++ b/include/asm-powerpc/spu.h @@ -165,6 +165,13 @@ int spu_irq_class_0_bottom(struct spu *spu); int spu_irq_class_1_bottom(struct spu *spu); void spu_irq_setaffinity(struct spu *spu, int cpu); +extern void spu_invalidate_slbs(struct spu *spu); +extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm); + +/* Calls from the memory management to the SPU */ +struct mm_struct; +extern void spu_flush_all_slbs(struct mm_struct *mm); + /* system callbacks from the SPU */ struct spu_syscall_block { u64 nr_ret; diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h index bdbf906a767..8aad0619eb8 100644 --- a/include/asm-powerpc/spu_csa.h +++ b/include/asm-powerpc/spu_csa.h @@ -221,8 +221,6 @@ struct spu_priv2_collapsed { * @spu_chnlcnt_RW: Array of saved channel counts. * @spu_chnldata_RW: Array of saved channel data. * @suspend_time: Time stamp when decrementer disabled. - * @slb_esid_RW: Array of saved SLB esid entries. - * @slb_vsid_RW: Array of saved SLB vsid entries. * * Structure representing the whole of the SPU * context save area (CSA). This struct contains @@ -245,8 +243,6 @@ struct spu_state { u32 spu_mailbox_data[4]; u32 pu_mailbox_data[1]; unsigned long suspend_time; - u64 slb_esid_RW[8]; - u64 slb_vsid_RW[8]; spinlock_t register_lock; }; diff --git a/include/asm-powerpc/systbl.h b/include/asm-powerpc/systbl.h index 418e5c7e972..8d853c55463 100644 --- a/include/asm-powerpc/systbl.h +++ b/include/asm-powerpc/systbl.h @@ -304,5 +304,6 @@ SYSCALL_SPU(fchmodat) SYSCALL_SPU(faccessat) COMPAT_SYS_SPU(get_robust_list) COMPAT_SYS_SPU(set_robust_list) -COMPAT_SYS(move_pages) +COMPAT_SYS_SPU(move_pages) SYSCALL_SPU(getcpu) +COMPAT_SYS(epoll_pwait) diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 0ae954e3d25..2baedbe54e1 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -324,10 +324,12 @@ #define __NR_get_robust_list 299 #define __NR_set_robust_list 300 #define __NR_move_pages 301 +#define __NR_getcpu 302 +#define __NR_epoll_pwait 303 #ifdef __KERNEL__ -#define __NR_syscalls 302 +#define __NR_syscalls 304 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h index 6db83dc93cb..f3a641e6b2c 100644 --- a/include/asm-sparc/dma-mapping.h +++ b/include/asm-sparc/dma-mapping.h @@ -5,20 +5,7 @@ #ifdef CONFIG_PCI #include <asm-generic/dma-mapping.h> #else - -static inline void *dma_alloc_coherent(struct device *dev, size_t size, - dma_addr_t *dma_handle, gfp_t flag) -{ - BUG(); - return NULL; -} - -static inline void dma_free_coherent(struct device *dev, size_t size, - void *vaddr, dma_addr_t dma_handle) -{ - BUG(); -} - +#include <asm-generic/dma-mapping-broken.h> #endif /* PCI */ #endif /* _ASM_SPARC_DMA_MAPPING_H */ diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index d5b2f8053b3..e43ed1d63a9 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -319,16 +319,17 @@ #define __NR_set_robust_list 300 #define __NR_get_robust_list 301 #define __NR_migrate_pages 302 +#define __NR_mbind 303 +#define __NR_get_mempolicy 304 +#define __NR_set_mempolicy 305 +#define __NR_kexec_load 306 +#define __NR_move_pages 307 +#define __NR_getcpu 308 +#define __NR_epoll_pwait 309 -#define NR_SYSCALLS 303 +#define NR_SYSCALLS 310 #ifdef __KERNEL__ -/* WARNING: You MAY NOT add syscall numbers larger than 302, since - * all of the syscall tables in the Sparc kernel are - * sized to have 302 entries (starting at zero). Therefore - * find a free slot in the 0-302 range. - */ - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 @@ -345,7 +346,6 @@ #define __ARCH_WANT_SYS_GETPGRP #define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK diff --git a/include/asm-sparc64/tsb.h b/include/asm-sparc64/tsb.h index e82612cd9f3..ab55ffcb7bf 100644 --- a/include/asm-sparc64/tsb.h +++ b/include/asm-sparc64/tsb.h @@ -264,6 +264,7 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; 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_phys_patch, __tsb_phys_patch_end; cmp REG3, TAG; \ be,a,pt %xcc, OK_LABEL; \ mov REG4, REG1; +#endif #endif /* !(_SPARC64_TSB_H) */ diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 47047536f26..e2dcb87e0c6 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -321,17 +321,17 @@ #define __NR_set_robust_list 300 #define __NR_get_robust_list 301 #define __NR_migrate_pages 302 +#define __NR_mbind 303 +#define __NR_get_mempolicy 304 +#define __NR_set_mempolicy 305 +#define __NR_kexec_load 306 +#define __NR_move_pages 307 +#define __NR_getcpu 308 +#define __NR_epoll_pwait 309 -#define NR_SYSCALLS 303 +#define NR_SYSCALLS 310 #ifdef __KERNEL__ - -/* WARNING: You MAY NOT add syscall numbers larger than 302, since - * all of the syscall tables in the Sparc kernel are - * sized to have 302 entries (starting at zero). Therefore - * find a free slot in the 0-302 range. - */ - /* sysconf options, for SunOS compatibility */ #define _SC_ARG_MAX 1 #define _SC_CHILD_MAX 2 @@ -359,7 +359,6 @@ #define __ARCH_WANT_SYS_GETPGRP #define __ARCH_WANT_SYS_LLSEEK #define __ARCH_WANT_SYS_NICE -#define __ARCH_WANT_SYS_OLD_GETRLIMIT #define __ARCH_WANT_SYS_OLDUMOUNT #define __ARCH_WANT_SYS_SIGPENDING #define __ARCH_WANT_SYS_SIGPROCMASK diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h index ceb3d8dac33..72375e7d32a 100644 --- a/include/asm-x86_64/nmi.h +++ b/include/asm-x86_64/nmi.h @@ -64,7 +64,7 @@ extern int setup_nmi_watchdog(char *); extern atomic_t nmi_active; extern unsigned int nmi_watchdog; -#define NMI_DEFAULT 0 +#define NMI_DEFAULT -1 #define NMI_NONE 0 #define NMI_IO_APIC 1 #define NMI_LOCAL_APIC 2 diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index f54f3abf93c..b6e65a699f2 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -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; diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index e17b9ec42e9..de592a408c0 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -7,6 +7,7 @@ #include <linux/threads.h> #include <linux/cpumask.h> #include <linux/bitops.h> +#include <linux/init.h> extern int disable_apic; #include <asm/fixmap.h> @@ -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 */ diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index 1981f70fcad..9df30b939c4 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h @@ -373,12 +373,12 @@ extern long __copy_user_nocache(void *dst, const void __user *src, unsigned size static inline int __copy_from_user_nocache(void *dst, const void __user *src, unsigned size) { might_sleep(); - return __copy_user_nocache(dst, (__force void *)src, size, 1); + return __copy_user_nocache(dst, src, size, 1); } static inline int __copy_from_user_inatomic_nocache(void *dst, const void __user *src, unsigned size) { - return __copy_user_nocache(dst, (__force void *)src, size, 0); + return __copy_user_nocache(dst, src, size, 0); } #endif /* __X86_64_UACCESS_H */ diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index 7011d625559..f2542c24b32 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h @@ -93,6 +93,7 @@ static inline int bdi_rw_congested(struct backing_dev_info *bdi) 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) \ diff --git a/include/linux/device.h b/include/linux/device.h index 39a3199a826..caad9bba965 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -353,6 +353,8 @@ extern int __must_check device_create_bin_file(struct device *dev, struct bin_attribute *attr); extern void device_remove_bin_file(struct device *dev, struct bin_attribute *attr); +extern int device_schedule_callback(struct device *dev, + void (*func)(struct device *)); /* device resource management */ typedef void (*dr_release_t)(struct device *dev, void *res); diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 06c58c423fe..506ad20c18f 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -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) diff --git a/include/linux/ktime.h b/include/linux/ktime.h index c68c7ac6b23..248305bb9a1 100644 --- a/include/linux/ktime.h +++ b/include/linux/ktime.h @@ -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: diff --git a/include/linux/msi.h b/include/linux/msi.h index 74c8a2ecc9d..e38fe6822cb 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -17,7 +17,7 @@ struct msi_desc { struct { __u8 type : 5; /* {0: unused, 5h:MSI, 11h:MSI-X} */ __u8 maskbit : 1; /* mask-pending bit supported ? */ - __u8 unused : 1; + __u8 masked : 1; __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */ __u8 pos; /* Location of the msi capability */ __u16 entry_nr; /* specific enabled entry */ @@ -32,10 +32,8 @@ struct msi_desc { void __iomem *mask_base; struct pci_dev *dev; -#ifdef CONFIG_PM - /* PM save area for MSIX address/data */ - struct msi_msg msg_save; -#endif + /* Last set MSI message */ + struct msi_msg msg; }; /* diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 47aaa2c6673..e9ae0c6e2c6 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -415,6 +415,7 @@ extern void nfs_complete_unlink(struct dentry *); /* * 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); diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 95796e6924f..c95d5e64254 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h @@ -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 */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 78417e421b4..481ea0663f1 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -209,11 +209,6 @@ static inline void pci_add_saved_cap(struct pci_dev *pci_dev, hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); } -static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) -{ - hlist_del(&cap->next); -} - /* * For PCI devices, the region numbers are assigned this way: * diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index f09cce2357f..495d368390e 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -296,6 +296,7 @@ #define PCI_MSIX_FLAGS 2 #define PCI_MSIX_FLAGS_QSIZE 0x7FF #define PCI_MSIX_FLAGS_ENABLE (1 << 15) +#define PCI_MSIX_FLAGS_MASKALL (1 << 14) #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) #define PCI_MSIX_FLAGS_BITMASK (1 << 0) diff --git a/include/linux/security.h b/include/linux/security.h index 7f88d97575f..47e82c120f9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1324,7 +1324,7 @@ struct security_operations { void (*d_instantiate) (struct dentry *dentry, struct inode *inode); - int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); + int (*getprocattr)(struct task_struct *p, char *name, char **value); int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); void (*release_secctx)(char *secdata, u32 seclen); @@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * security_ops->d_instantiate (dentry, inode); } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { - return security_ops->getprocattr(p, name, value, size); + return security_ops->getprocattr(p, name, value); } static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) @@ -2749,7 +2749,7 @@ static inline int security_sem_semop (struct sem_array * sma, static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 2e8c048b9b8..9dbca629dcf 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -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; diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 523405e1e1f..fea9a6b3fb7 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h @@ -11,6 +11,7 @@ #define _SYSFS_H_ #include <linux/compiler.h> +#include <linux/errno.h> #include <linux/list.h> #include <asm/atomic.h> @@ -78,6 +79,9 @@ struct sysfs_ops { #ifdef CONFIG_SYSFS +extern int sysfs_schedule_callback(struct kobject *kobj, + void (*func)(void *), void *data); + extern int __must_check sysfs_create_dir(struct kobject *, struct dentry *); @@ -132,6 +136,12 @@ extern int __must_check sysfs_init(void); #else /* CONFIG_SYSFS */ +static inline int sysfs_schedule_callback(struct kobject *kobj, + void (*func)(void *), void *data) +{ + return -ENOSYS; +} + static inline int sysfs_create_dir(struct kobject * k, struct dentry *shadow) { return 0; diff --git a/include/linux/ufs_fs.h b/include/linux/ufs_fs.h index dc2e9fe6941..daeba22b765 100644 --- a/include/linux/ufs_fs.h +++ b/include/linux/ufs_fs.h @@ -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. */ diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 37a1a41f5b6..e0db669998f 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -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; diff --git a/include/sound/version.h b/include/sound/version.h index 5f727500010..42a18cc95f3 100644 --- a/include/sound/version.h +++ b/include/sound/version.h @@ -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)" diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 359955800dd..628c7ac590a 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -739,28 +739,26 @@ static inline void audit_free_context(struct audit_context *context) void audit_log_task_context(struct audit_buffer *ab) { char *ctx = NULL; - ssize_t len = 0; + unsigned len; + int error; + u32 sid; + + selinux_get_task_sid(current, &sid); + if (!sid) + return; - len = security_getprocattr(current, "current", NULL, 0); - if (len < 0) { - if (len != -EINVAL) + error = selinux_sid_to_string(sid, &ctx, &len); + if (error) { + if (error != -EINVAL) goto error_path; return; } - ctx = kmalloc(len, GFP_KERNEL); - if (!ctx) - goto error_path; - - len = security_getprocattr(current, "current", ctx, len); - if (len < 0 ) - goto error_path; - audit_log_format(ab, " subj=%s", ctx); + kfree(ctx); return; error_path: - kfree(ctx); audit_panic("error in audit_log_task_context"); return; } diff --git a/kernel/fork.c b/kernel/fork.c index d154cc78648..6af959c034d 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -933,8 +933,8 @@ asmlinkage long sys_set_tid_address(int __user *tidptr) 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 diff --git a/kernel/futex.c b/kernel/futex.c index e749e7df14b..5a270b5e3f9 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -565,6 +565,7 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) 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 *uaddr, u32 uval, struct futex_q *this) 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; diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index ec4cb9f3e3b..6a7938a0d51 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -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(struct hrtimer_cpu_base *base) #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, ktime_t now, ktime_t interval) 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; } diff --git a/kernel/power/console.c b/kernel/power/console.c index 623786d4415..89bcf4973ee 100644 --- a/kernel/power/console.c +++ b/kernel/power/console.c @@ -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)) { diff --git a/kernel/power/disk.c b/kernel/power/disk.c index 406b20adb27..873cdf8ea5a 100644 --- a/kernel/power/disk.c +++ b/kernel/power/disk.c @@ -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) { @@ -251,6 +252,7 @@ static int software_resume(void) error = swsusp_read(); if (error) { swsusp_free(); + platform_finish(); goto Thaw; } diff --git a/kernel/power/user.c b/kernel/power/user.c index dd09efe7df5..d6a8dcc26ae 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -398,9 +398,10 @@ static int snapshot_ioctl(struct inode *inode, struct file *filp, 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; diff --git a/kernel/time/tick-broadcast.c b/kernel/time/tick-broadcast.c index 5567745470f..eadfce2fff7 100644 --- a/kernel/time/tick-broadcast.c +++ b/kernel/time/tick-broadcast.c @@ -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(ktime_t expires, int force) } } +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: * diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index 43ba1bdec14..bfda3f7f071 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -298,18 +298,17 @@ static void tick_shutdown(unsigned int *cpup) 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_block *nb, unsigned long reason, 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: diff --git a/kernel/time/tick-internal.h b/kernel/time/tick-internal.h index 75890efd24f..c9d203bde51 100644 --- a/kernel/time/tick-internal.h +++ b/kernel/time/tick-internal.h @@ -19,12 +19,13 @@ extern void tick_setup_oneshot(struct clock_event_device *newdev, 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_event_device *newdev, { 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_oneshot(struct clock_event_device *bc) } 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 */ /* diff --git a/kernel/time/tick-oneshot.c b/kernel/time/tick-oneshot.c index 2e8b7ff863c..f6997ab0c3c 100644 --- a/kernel/time/tick-oneshot.c +++ b/kernel/time/tick-oneshot.c @@ -41,6 +41,18 @@ int tick_program_event(ktime_t expires, int force) } /** + * 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, diff --git a/mm/backing-dev.c b/mm/backing-dev.c index f50a2811f9d..e5de3781d3f 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c @@ -55,6 +55,22 @@ long congestion_wait(int rw, long timeout) } 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 diff --git a/mm/filemap.c b/mm/filemap.c index d1060b8d3cd..5dfc093ceb3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -2379,7 +2379,8 @@ generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, 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 kiocb *iocb, const struct iovec *iov, */ 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; } diff --git a/mm/madvise.c b/mm/madvise.c index 4e196155a0c..77916e9fc52 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -155,11 +155,14 @@ static long madvise_dontneed(struct vm_area_struct * vma, * 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, struct vm_area_struct **prev, 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: diff --git a/mm/oom_kill.c b/mm/oom_kill.c index b278b8d60ee..2f3916986ab 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -320,7 +320,7 @@ static int oom_kill_task(struct task_struct *p) * 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); diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 820761f9eee..702fa8f0874 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -463,6 +463,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask) memcpy(n->cb, skb->cb, sizeof(skb->cb)); C(len); C(data_len); + C(mac_len); C(csum); C(local_df); n->cloned = 1; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c976dd7e975..2ce5b693a8b 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -1933,6 +1933,11 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb, &cipso_ptr[6], secattr); break; + case CIPSO_V4_TAG_RANGE: + ret_val = cipso_v4_parsetag_rng(doi_def, + &cipso_ptr[6], + secattr); + break; } skbuff_getattr_return: diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 72b3036bbc0..ada9b3db507 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1527,7 +1527,6 @@ static int trie_leaf_remove(struct trie *t, t_key key) 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 *t, t_key key) rcu_assign_pointer(t->trie, trie_rebalance(t, tp)); } else rcu_assign_pointer(t->trie, NULL); - preempt_enable(); return 1; } diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 1c6a084b5fb..8cedb2a2c9d 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -1255,9 +1255,9 @@ out: */ void ip_mc_rejoin_group(struct ip_mc_list *im) { +#ifdef CONFIG_IP_MULTICAST struct in_device *in_dev = im->interface; -#ifdef CONFIG_IP_MULTICAST if (im->multiaddr == IGMP_ALL_HOSTS) return; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 74c4d103ebc..3834b10b511 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -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); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f57a9baa6b2..92f99927d12 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1453,6 +1453,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, First: no IPv4 options. */ newinet->opt = NULL; + newnp->ipv6_fl_list = NULL; /* Clone RX bits */ newnp->rxopt.all = np->rxopt.all; diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 8c34f1ca6c8..f92d5310847 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -700,23 +700,7 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le unsigned char cause, diagnostic; struct net_device *dev; ax25_uid_assoc *user; - int n; - - if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { - sock->state = SS_CONNECTED; - return 0; /* Connect completed during a ERESTARTSYS event */ - } - - if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { - sock->state = SS_UNCONNECTED; - return -ECONNREFUSED; - } - - if (sk->sk_state == TCP_ESTABLISHED) - return -EISCONN; /* No reconnect on a seqpacket socket */ - - sk->sk_state = TCP_CLOSE; - sock->state = SS_UNCONNECTED; + int n, err = 0; if (addr_len != sizeof(struct sockaddr_rose) && addr_len != sizeof(struct full_sockaddr_rose)) return -EINVAL; @@ -734,24 +718,53 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le if ((rose->source_ndigis + addr->srose_ndigis) > ROSE_MAX_DIGIS) return -EINVAL; + lock_sock(sk); + + if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { + /* Connect completed during a ERESTARTSYS event */ + sock->state = SS_CONNECTED; + goto out_release; + } + + if (sk->sk_state == TCP_CLOSE && sock->state == SS_CONNECTING) { + sock->state = SS_UNCONNECTED; + err = -ECONNREFUSED; + goto out_release; + } + + if (sk->sk_state == TCP_ESTABLISHED) { + /* No reconnect on a seqpacket socket */ + err = -EISCONN; + goto out_release; + } + + sk->sk_state = TCP_CLOSE; + sock->state = SS_UNCONNECTED; + rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic); if (!rose->neighbour) return -ENETUNREACH; rose->lci = rose_new_lci(rose->neighbour); - if (!rose->lci) - return -ENETUNREACH; + if (!rose->lci) { + err = -ENETUNREACH; + goto out_release; + } if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */ sock_reset_flag(sk, SOCK_ZAPPED); - if ((dev = rose_dev_first()) == NULL) - return -ENETUNREACH; + if ((dev = rose_dev_first()) == NULL) { + err = -ENETUNREACH; + goto out_release; + } user = ax25_findbyuid(current->euid); - if (!user) - return -EINVAL; + if (!user) { + err = -EINVAL; + goto out_release; + } memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN); rose->source_call = user->call; @@ -789,8 +802,10 @@ rose_try_next_neigh: rose_start_t1timer(sk); /* Now the loop */ - if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) - return -EINPROGRESS; + if (sk->sk_state != TCP_ESTABLISHED && (flags & O_NONBLOCK)) { + err = -EINPROGRESS; + goto out_release; + } /* * A Connect Ack with Choke or timeout or failed routing will go to @@ -805,8 +820,10 @@ rose_try_next_neigh: set_current_state(TASK_INTERRUPTIBLE); if (sk->sk_state != TCP_SYN_SENT) break; + release_sock(sk); if (!signal_pending(tsk)) { schedule(); + lock_sock(sk); continue; } current->state = TASK_RUNNING; @@ -822,14 +839,19 @@ rose_try_next_neigh: rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause, &diagnostic); if (rose->neighbour) goto rose_try_next_neigh; - /* No more neighbour */ + + /* No more neighbours */ sock->state = SS_UNCONNECTED; - return sock_error(sk); /* Always set at this point */ + err = sock_error(sk); /* Always set at this point */ + goto out_release; } sock->state = SS_CONNECTED; - return 0; +out_release: + release_sock(sk); + + return err; } static int rose_accept(struct socket *sock, struct socket *newsock, int flags) @@ -877,6 +899,8 @@ static int rose_accept(struct socket *sock, struct socket *newsock, int flags) lock_sock(sk); continue; } + current->state = TASK_RUNNING; + remove_wait_queue(sk->sk_sleep, &wait); return -ERESTARTSYS; } current->state = TASK_RUNNING; diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c deleted file mode 100644 index 41d7e32be70..00000000000 --- a/net/wanrouter/af_wanpipe.c +++ /dev/null @@ -1,2600 +0,0 @@ -/***************************************************************************** -* af_wanpipe.c WANPIPE(tm) Secure Socket Layer. -* -* Author: Nenad Corbic <ncorbic@sangoma.com> -* -* Copyright: (c) 2000 Sangoma Technologies Inc. -* -* 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. -* ============================================================================ -* Due Credit: -* Wanpipe socket layer is based on Packet and -* the X25 socket layers. The above sockets were -* used for the specific use of Sangoma Technologies -* API programs. -* Packet socket Authors: Ross Biro, Fred N. van Kempen and -* Alan Cox. -* X25 socket Author: Jonathan Naylor. -* ============================================================================ -* Mar 15, 2002 Arnaldo C. Melo o Use wp_sk()->num, as it isnt anymore in sock -* Apr 25, 2000 Nenad Corbic o Added the ability to send zero length packets. -* Mar 13, 2000 Nenad Corbic o Added a tx buffer check via ioctl call. -* Mar 06, 2000 Nenad Corbic o Fixed the corrupt sock lcn problem. -* Server and client application can run -* simultaneously without conflicts. -* Feb 29, 2000 Nenad Corbic o Added support for PVC protocols, such as -* CHDLC, Frame Relay and HDLC API. -* Jan 17, 2000 Nenad Corbic o Initial version, based on AF_PACKET socket. -* X25API support only. -* -******************************************************************************/ - -#include <linux/types.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/capability.h> -#include <linux/fcntl.h> -#include <linux/socket.h> -#include <linux/in.h> -#include <linux/inet.h> -#include <linux/netdevice.h> -#include <linux/poll.h> -#include <linux/wireless.h> -#include <linux/kmod.h> -#include <net/ip.h> -#include <net/protocol.h> -#include <linux/skbuff.h> -#include <net/sock.h> -#include <linux/errno.h> -#include <linux/timer.h> -#include <asm/system.h> -#include <asm/uaccess.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/if_wanpipe.h> -#include <linux/pkt_sched.h> -#include <linux/tcp_states.h> -#include <linux/if_wanpipe_common.h> - -#ifdef CONFIG_INET -#include <net/inet_common.h> -#endif - -#define SLOW_BACKOFF 0.1*HZ -#define FAST_BACKOFF 0.01*HZ - -//#define PRINT_DEBUG -#ifdef PRINT_DEBUG - #define DBG_PRINTK(format, a...) printk(format, ## a) -#else - #define DBG_PRINTK(format, a...) -#endif - - -/* SECURE SOCKET IMPLEMENTATION - * - * TRANSMIT: - * - * When the user sends a packet via send() system call - * the wanpipe_sendmsg() function is executed. - * - * Each packet is enqueud into sk->sk_write_queue transmit - * queue. When the packet is enqueued, a delayed transmit - * timer is triggerd which acts as a Bottom Half hander. - * - * wanpipe_delay_transmit() function (BH), dequeues packets - * from the sk->sk_write_queue transmit queue and sends it - * to the deriver via dev->hard_start_xmit(skb, dev) function. - * Note, this function is actual a function pointer of if_send() - * routine in the wanpipe driver. - * - * X25API GUARANTEED DELIVERY: - * - * In order to provide 100% guaranteed packet delivery, - * an atomic 'packet_sent' counter is implemented. Counter - * is incremented for each packet enqueued - * into sk->sk_write_queue. Counter is decremented each - * time wanpipe_delayed_transmit() function successfuly - * passes the packet to the driver. Before each send(), a poll - * routine checks the sock resources The maximum value of - * packet sent counter is 1, thus if one packet is queued, the - * application will block until that packet is passed to the - * driver. - * - * RECEIVE: - * - * Wanpipe device drivers call the socket bottom half - * function, wanpipe_rcv() to queue the incoming packets - * into an AF_WANPIPE socket queue. Based on wanpipe_rcv() - * return code, the driver knows whether the packet was - * successfully queued. If the socket queue is full, - * protocol flow control is used by the driver, if any, - * to slow down the traffic until the sock queue is free. - * - * Every time a packet arrives into a socket queue the - * socket wakes up processes which are waiting to receive - * data. - * - * If the socket queue is full, the driver sets a block - * bit which signals the socket to kick the wanpipe driver - * bottom half hander when the socket queue is partialy - * empty. wanpipe_recvmsg() function performs this action. - * - * In case of x25api, packets will never be dropped, since - * flow control is available. - * - * In case of streaming protocols like CHDLC, packets will - * be dropped but the statistics will be generated. - */ - - -/* The code below is used to test memory leaks. It prints out - * a message every time kmalloc and kfree system calls get executed. - * If the calls match there is no leak :) - */ - -/***********FOR DEBUGGING PURPOSES********************************************* -#define KMEM_SAFETYZONE 8 - -static void * dbg_kmalloc(unsigned int size, int prio, int line) { - void * v = kmalloc(size,prio); - printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v); - return v; -} -static void dbg_kfree(void * v, int line) { - printk(KERN_INFO "line %d kfree(%p)\n",line,v); - kfree(v); -} - -#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__) -#define kfree(x) dbg_kfree(x,__LINE__) -******************************************************************************/ - - -/* List of all wanpipe sockets. */ -HLIST_HEAD(wanpipe_sklist); -static DEFINE_RWLOCK(wanpipe_sklist_lock); - -atomic_t wanpipe_socks_nr; -static unsigned long wanpipe_tx_critical; - -#if 0 -/* Private wanpipe socket structures. */ -struct wanpipe_opt -{ - void *mbox; /* Mail box */ - void *card; /* Card bouded to */ - struct net_device *dev; /* Bounded device */ - unsigned short lcn; /* Binded LCN */ - unsigned char svc; /* 0=pvc, 1=svc */ - unsigned char timer; /* flag for delayed transmit*/ - struct timer_list tx_timer; - unsigned poll_cnt; - unsigned char force; /* Used to force sock release */ - atomic_t packet_sent; -}; -#endif - -static int sk_count; -extern const struct proto_ops wanpipe_ops; -static unsigned long find_free_critical; - -static void wanpipe_unlink_driver(struct sock *sk); -static void wanpipe_link_driver(struct net_device *dev, struct sock *sk); -static void wanpipe_wakeup_driver(struct sock *sk); -static int execute_command(struct sock *, unsigned char, unsigned int); -static int check_dev(struct net_device *dev, sdla_t *card); -struct net_device *wanpipe_find_free_dev(sdla_t *card); -static void wanpipe_unlink_card (struct sock *); -static int wanpipe_link_card (struct sock *); -static struct sock *wanpipe_make_new(struct sock *); -static struct sock *wanpipe_alloc_socket(void); -static inline int get_atomic_device(struct net_device *dev); -static int wanpipe_exec_cmd(struct sock *, int, unsigned int); -static int get_ioctl_cmd (struct sock *, void *); -static int set_ioctl_cmd (struct sock *, void *); -static void release_device(struct net_device *dev); -static void wanpipe_kill_sock_timer (unsigned long data); -static void wanpipe_kill_sock_irq (struct sock *); -static void wanpipe_kill_sock_accept (struct sock *); -static int wanpipe_do_bind(struct sock *sk, struct net_device *dev, - int protocol); -struct sock * get_newsk_from_skb (struct sk_buff *); -static int wanpipe_debug (struct sock *, void *); -static void wanpipe_delayed_transmit (unsigned long data); -static void release_driver(struct sock *); -static void start_cleanup_timer (struct sock *); -static void check_write_queue(struct sock *); -static int check_driver_busy (struct sock *); - -/*============================================================ - * wanpipe_rcv - * - * Wanpipe socket bottom half handler. This function - * is called by the WANPIPE device drivers to queue a - * incoming packet into the socket receive queue. - * Once the packet is queued, all processes waiting to - * read are woken up. - * - * During socket bind, this function is bounded into - * WANPIPE driver private. - *===========================================================*/ - -static int wanpipe_rcv(struct sk_buff *skb, struct net_device *dev, - struct sock *sk) -{ - struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)skb->cb; - wanpipe_common_t *chan = dev->priv; - /* - * When we registered the protocol we saved the socket in the data - * field for just this event. - */ - - skb->dev = dev; - - sll->sll_family = AF_WANPIPE; - sll->sll_hatype = dev->type; - sll->sll_protocol = skb->protocol; - sll->sll_pkttype = skb->pkt_type; - sll->sll_ifindex = dev->ifindex; - sll->sll_halen = 0; - - if (dev->hard_header_parse) - sll->sll_halen = dev->hard_header_parse(skb, sll->sll_addr); - - /* - * WAN_PACKET_DATA : Data which should be passed up the receive queue. - * WAN_PACKET_ASYC : Asynchronous data like place call, which should - * be passed up the listening sock. - * WAN_PACKET_ERR : Asynchronous data like clear call or restart - * which should go into an error queue. - */ - switch (skb->pkt_type){ - - case WAN_PACKET_DATA: - if (sock_queue_rcv_skb(sk,skb)<0){ - return -ENOMEM; - } - break; - case WAN_PACKET_CMD: - sk->sk_state = chan->state; - /* Bug fix: update Mar6. - * Do not set the sock lcn number here, since - * cmd is not guaranteed to be executed on the - * board, thus Lcn could be wrong */ - sk->sk_data_ready(sk, skb->len); - kfree_skb(skb); - break; - case WAN_PACKET_ERR: - sk->sk_state = chan->state; - if (sock_queue_err_skb(sk,skb)<0){ - return -ENOMEM; - } - break; - default: - printk(KERN_INFO "wansock: BH Illegal Packet Type Dropping\n"); - kfree_skb(skb); - break; - } - -//?????????????????????? -// if (sk->sk_state == WANSOCK_DISCONNECTED){ -// if (sk->sk_zapped) { -// //printk(KERN_INFO "wansock: Disconnected, killing early\n"); -// wanpipe_unlink_driver(sk); -// sk->sk_bound_dev_if = 0; -// } -// } - - return 0; -} - -/*============================================================ - * wanpipe_listen_rcv - * - * Wanpipe LISTEN socket bottom half handler. This function - * is called by the WANPIPE device drivers to queue an - * incoming call into the socket listening queue. - * Once the packet is queued, the waiting accept() process - * is woken up. - * - * During socket bind, this function is bounded into - * WANPIPE driver private. - * - * IMPORTANT NOTE: - * The accept call() is waiting for an skb packet - * which contains a pointer to a device structure. - * - * When we do a bind to a device structre, we - * bind a newly created socket into "chan->sk". Thus, - * when accept receives the skb packet, it will know - * from which dev it came form, and in turn it will know - * the address of the new sock. - * - * NOTE: This function gets called from driver ISR. - *===========================================================*/ - -static int wanpipe_listen_rcv (struct sk_buff *skb, struct sock *sk) -{ - wanpipe_opt *wp = wp_sk(sk), *newwp; - struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)skb->cb; - struct sock *newsk; - struct net_device *dev; - sdla_t *card; - mbox_cmd_t *mbox_ptr; - wanpipe_common_t *chan; - - /* Find a free device, if none found, all svc's are busy - */ - - card = (sdla_t*)wp->card; - if (!card){ - printk(KERN_INFO "wansock: LISTEN ERROR, No Card\n"); - return -ENODEV; - } - - dev = wanpipe_find_free_dev(card); - if (!dev){ - printk(KERN_INFO "wansock: LISTEN ERROR, No Free Device\n"); - return -ENODEV; - } - - chan=dev->priv; - chan->state = WANSOCK_CONNECTING; - - /* Allocate a new sock, which accept will bind - * and pass up to the user - */ - if ((newsk = wanpipe_make_new(sk)) == NULL){ - release_device(dev); - return -ENOMEM; - } - - - /* Initialize the new sock structure - */ - newsk->sk_bound_dev_if = dev->ifindex; - newwp = wp_sk(newsk); - newwp->card = wp->card; - - /* Insert the sock into the main wanpipe - * sock list. - */ - atomic_inc(&wanpipe_socks_nr); - - /* Allocate and fill in the new Mail Box. Then - * bind the mail box to the sock. It will be - * used by the ioctl call to read call information - * and to execute commands. - */ - if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) { - wanpipe_kill_sock_irq (newsk); - release_device(dev); - return -ENOMEM; - } - memcpy(mbox_ptr,skb->data,skb->len); - - /* Register the lcn on which incoming call came - * from. Thus, if we have to clear it, we know - * which lcn to clear - */ - - newwp->lcn = mbox_ptr->cmd.lcn; - newwp->mbox = (void *)mbox_ptr; - - DBG_PRINTK(KERN_INFO "NEWSOCK : Device %s, bind to lcn %i\n", - dev->name,mbox_ptr->cmd.lcn); - - chan->lcn = mbox_ptr->cmd.lcn; - card->u.x.svc_to_dev_map[(chan->lcn%MAX_X25_LCN)] = dev; - - sock_reset_flag(newsk, SOCK_ZAPPED); - newwp->num = htons(X25_PROT); - - if (wanpipe_do_bind(newsk, dev, newwp->num)) { - wanpipe_kill_sock_irq (newsk); - release_device(dev); - return -EINVAL; - } - newsk->sk_state = WANSOCK_CONNECTING; - - - /* Fill in the standard sock address info */ - - sll->sll_family = AF_WANPIPE; - sll->sll_hatype = dev->type; - sll->sll_protocol = skb->protocol; - sll->sll_pkttype = skb->pkt_type; - sll->sll_ifindex = dev->ifindex; - sll->sll_halen = 0; - - skb->dev = dev; - sk->sk_ack_backlog++; - - /* We must do this manually, since the sock_queue_rcv_skb() - * function sets the skb->dev to NULL. However, we use - * the dev field in the accept function.*/ - if (atomic_read(&sk->sk_rmem_alloc) + skb->truesize >= - (unsigned)sk->sk_rcvbuf) { - - wanpipe_unlink_driver(newsk); - wanpipe_kill_sock_irq (newsk); - --sk->sk_ack_backlog; - return -ENOMEM; - } - - skb_set_owner_r(skb, sk); - skb_queue_tail(&sk->sk_receive_queue, skb); - sk->sk_data_ready(sk, skb->len); - - return 0; -} - - - -/*============================================================ - * wanpipe_make_new - * - * Create a new sock, and allocate a wanpipe private - * structure to it. Also, copy the important data - * from the original sock to the new sock. - * - * This function is used by wanpipe_listen_rcv() listen - * bottom half handler. A copy of the listening sock - * is created using this function. - * - *===========================================================*/ - -static struct sock *wanpipe_make_new(struct sock *osk) -{ - struct sock *sk; - - if (osk->sk_type != SOCK_RAW) - return NULL; - - if ((sk = wanpipe_alloc_socket()) == NULL) - return NULL; - - sk->sk_type = osk->sk_type; - sk->sk_socket = osk->sk_socket; - sk->sk_priority = osk->sk_priority; - sk->sk_protocol = osk->sk_protocol; - wp_sk(sk)->num = wp_sk(osk)->num; - sk->sk_rcvbuf = osk->sk_rcvbuf; - sk->sk_sndbuf = osk->sk_sndbuf; - sk->sk_state = WANSOCK_CONNECTING; - sk->sk_sleep = osk->sk_sleep; - - if (sock_flag(osk, SOCK_DBG)) - sock_set_flag(sk, SOCK_DBG); - - return sk; -} - -/* - * FIXME: wanpipe_opt has to include a sock in its definition and stop using - * sk_protinfo, but this code is not even compilable now, so lets leave it for - * later. - */ -static struct proto wanpipe_proto = { - .name = "WANPIPE", - .owner = THIS_MODULE, - .obj_size = sizeof(struct sock), -}; - -/*============================================================ - * wanpipe_make_new - * - * Allocate memory for the a new sock, and sock - * private data. - * - * Increment the module use count. - * - * This function is used by wanpipe_create() and - * wanpipe_make_new() functions. - * - *===========================================================*/ - -static struct sock *wanpipe_alloc_socket(void) -{ - struct sock *sk; - struct wanpipe_opt *wan_opt; - - if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL) - return NULL; - - if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) { - sk_free(sk); - return NULL; - } - - wp_sk(sk) = wan_opt; - - /* Use timer to send data to the driver. This will act - * as a BH handler for sendmsg functions */ - init_timer(&wan_opt->tx_timer); - wan_opt->tx_timer.data = (unsigned long)sk; - wan_opt->tx_timer.function = wanpipe_delayed_transmit; - - sock_init_data(NULL, sk); - return sk; -} - - -/*============================================================ - * wanpipe_sendmsg - * - * This function implements a sendto() system call, - * for AF_WANPIPE socket family. - * During socket bind() sk->sk_bound_dev_if is initialized - * to a correct network device. This number is used - * to find a network device to which the packet should - * be passed to. - * - * Each packet is queued into sk->sk_write_queue and - * delayed transmit bottom half handler is marked for - * execution. - * - * A socket must be in WANSOCK_CONNECTED state before - * a packet is queued into sk->sk_write_queue. - *===========================================================*/ - -static int wanpipe_sendmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, int len) -{ - wanpipe_opt *wp; - struct sock *sk = sock->sk; - struct wan_sockaddr_ll *saddr=(struct wan_sockaddr_ll *)msg->msg_name; - struct sk_buff *skb; - struct net_device *dev; - unsigned short proto; - unsigned char *addr; - int ifindex, err, reserve = 0; - - - if (!sock_flag(sk, SOCK_ZAPPED)) - return -ENETDOWN; - - if (sk->sk_state != WANSOCK_CONNECTED) - return -ENOTCONN; - - if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT)) - return(-EINVAL); - - /* it was <=, now one can send - * zero length packets */ - if (len < sizeof(x25api_hdr_t)) - return -EINVAL; - - wp = wp_sk(sk); - - if (saddr == NULL) { - ifindex = sk->sk_bound_dev_if; - proto = wp->num; - addr = NULL; - - }else{ - if (msg->msg_namelen < sizeof(struct wan_sockaddr_ll)){ - return -EINVAL; - } - - ifindex = sk->sk_bound_dev_if; - proto = saddr->sll_protocol; - addr = saddr->sll_addr; - } - - dev = dev_get_by_index(ifindex); - if (dev == NULL){ - printk(KERN_INFO "wansock: Send failed, dev index: %i\n",ifindex); - return -ENXIO; - } - dev_put(dev); - - if (sock->type == SOCK_RAW) - reserve = dev->hard_header_len; - - if (len > dev->mtu+reserve){ - return -EMSGSIZE; - } - - skb = sock_alloc_send_skb(sk, len + LL_RESERVED_SPACE(dev), - msg->msg_flags & MSG_DONTWAIT, &err); - - if (skb==NULL){ - goto out_unlock; - } - - skb_reserve(skb, LL_RESERVED_SPACE(dev)); - skb->nh.raw = skb->data; - - /* Returns -EFAULT on error */ - err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); - if (err){ - goto out_free; - } - - if (dev->hard_header) { - int res; - err = -EINVAL; - res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); - if (res<0){ - goto out_free; - } - } - - skb->protocol = proto; - skb->dev = dev; - skb->priority = sk->sk_priority; - skb->pkt_type = WAN_PACKET_DATA; - - err = -ENETDOWN; - if (!(dev->flags & IFF_UP)) - goto out_free; - - if (atomic_read(&sk->sk_wmem_alloc) + skb->truesize > - (unsigned int)sk->sk_sndbuf){ - kfree_skb(skb); - return -ENOBUFS; - } - - skb_queue_tail(&sk->sk_write_queue,skb); - atomic_inc(&wp->packet_sent); - - if (!(test_and_set_bit(0, &wp->timer))) - mod_timer(&wp->tx_timer, jiffies + 1); - - return(len); - -out_free: - kfree_skb(skb); -out_unlock: - return err; -} - -/*============================================================ - * wanpipe_delayed_tarnsmit - * - * Transmit bottom half handler. It dequeues packets - * from sk->sk_write_queue and passes them to the - * driver. If the driver is busy, the packet is - * re-enqueued. - * - * Packet Sent counter is decremented on successful - * transmission. - *===========================================================*/ - - -static void wanpipe_delayed_transmit (unsigned long data) -{ - struct sock *sk=(struct sock *)data; - struct sk_buff *skb; - wanpipe_opt *wp = wp_sk(sk); - struct net_device *dev = wp->dev; - sdla_t *card = (sdla_t*)wp->card; - - if (!card || !dev){ - clear_bit(0, &wp->timer); - DBG_PRINTK(KERN_INFO "wansock: Transmit delay, no dev or card\n"); - return; - } - - if (sk->sk_state != WANSOCK_CONNECTED || !sock_flag(sk, SOCK_ZAPPED)) { - clear_bit(0, &wp->timer); - DBG_PRINTK(KERN_INFO "wansock: Tx Timer, State not CONNECTED\n"); - return; - } - - /* If driver is executing command, we must offload - * the board by not sending data. Otherwise a - * pending command will never get a free buffer - * to execute */ - if (atomic_read(&card->u.x.command_busy)){ - wp->tx_timer.expires = jiffies + SLOW_BACKOFF; - add_timer(&wp->tx_timer); - DBG_PRINTK(KERN_INFO "wansock: Tx Timer, command bys BACKOFF\n"); - return; - } - - - if (test_and_set_bit(0,&wanpipe_tx_critical)){ - printk(KERN_INFO "WanSock: Tx timer critical %s\n",dev->name); - wp->tx_timer.expires = jiffies + SLOW_BACKOFF; - add_timer(&wp->tx_timer); - return; - } - - /* Check for a packet in the fifo and send */ - if ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL){ - - if (dev->hard_start_xmit(skb, dev) != 0){ - - /* Driver failed to transmit, re-enqueue - * the packet and retry again later */ - skb_queue_head(&sk->sk_write_queue,skb); - clear_bit(0,&wanpipe_tx_critical); - return; - }else{ - - /* Packet Sent successful. Check for more packets - * if more packets, re-trigger the transmit routine - * other wise exit - */ - atomic_dec(&wp->packet_sent); - - if (skb_peek(&sk->sk_write_queue) == NULL) { - /* If there is nothing to send, kick - * the poll routine, which will trigger - * the application to send more data */ - sk->sk_data_ready(sk, 0); - clear_bit(0, &wp->timer); - }else{ - /* Reschedule as fast as possible */ - wp->tx_timer.expires = jiffies + 1; - add_timer(&wp->tx_timer); - } - } - } - clear_bit(0,&wanpipe_tx_critical); -} - -/*============================================================ - * execute_command - * - * Execute x25api commands. The atomic variable - * chan->command is used to indicate to the driver that - * command is pending for execution. The acutal command - * structure is placed into a sock mbox structure - * (wp_sk(sk)->mbox). - * - * The sock private structure, mbox is - * used as shared memory between sock and the driver. - * Driver uses the sock mbox to execute the command - * and return the result. - * - * For all command except PLACE CALL, the function - * waits for the result. PLACE CALL can be ether - * blocking or nonblocking. The user sets this option - * via ioctl call. - *===========================================================*/ - - -static int execute_command(struct sock *sk, unsigned char cmd, unsigned int flags) -{ - wanpipe_opt *wp = wp_sk(sk); - struct net_device *dev; - wanpipe_common_t *chan=NULL; - int err=0; - DECLARE_WAITQUEUE(wait, current); - - dev = dev_get_by_index(sk->sk_bound_dev_if); - if (dev == NULL){ - printk(KERN_INFO "wansock: Exec failed no dev %i\n", - sk->sk_bound_dev_if); - return -ENODEV; - } - dev_put(dev); - - if ((chan=dev->priv) == NULL){ - printk(KERN_INFO "wansock: Exec cmd failed no priv area\n"); - return -ENODEV; - } - - if (atomic_read(&chan->command)){ - printk(KERN_INFO "wansock: ERROR: Command already running %x, %s\n", - atomic_read(&chan->command),dev->name); - return -EINVAL; - } - - if (!wp->mbox) { - printk(KERN_INFO "wansock: In execute without MBOX\n"); - return -EINVAL; - } - - ((mbox_cmd_t*)wp->mbox)->cmd.command = cmd; - ((mbox_cmd_t*)wp->mbox)->cmd.lcn = wp->lcn; - ((mbox_cmd_t*)wp->mbox)->cmd.result = 0x7F; - - - if (flags & O_NONBLOCK){ - cmd |= 0x80; - atomic_set(&chan->command, cmd); - }else{ - atomic_set(&chan->command, cmd); - } - - add_wait_queue(sk->sk_sleep,&wait); - current->state = TASK_INTERRUPTIBLE; - for (;;){ - if (((mbox_cmd_t*)wp->mbox)->cmd.result != 0x7F) { - err = 0; - break; - } - if (signal_pending(current)) { - err = -ERESTARTSYS; - break; - } - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(sk->sk_sleep,&wait); - - return err; -} - -/*============================================================ - * wanpipe_destroy_timer - * - * Used by wanpipe_release, to delay release of - * the socket. - *===========================================================*/ - -static void wanpipe_destroy_timer(unsigned long data) -{ - struct sock *sk=(struct sock *)data; - wanpipe_opt *wp = wp_sk(sk); - - if ((!atomic_read(&sk->sk_wmem_alloc) && - !atomic_read(&sk->sk_rmem_alloc)) || - (++wp->force == 5)) { - - if (atomic_read(&sk->sk_wmem_alloc) || - atomic_read(&sk->sk_rmem_alloc)) - printk(KERN_INFO "wansock: Warning, Packet Discarded due to sock shutdown!\n"); - - kfree(wp); - wp_sk(sk) = NULL; - - if (atomic_read(&sk->sk_refcnt) != 1) { - atomic_set(&sk->sk_refcnt, 1); - DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :delay.\n", - atomic_read(&sk->sk_refcnt)); - } - sock_put(sk); - atomic_dec(&wanpipe_socks_nr); - return; - } - - sk->sk_timer.expires = jiffies + 5 * HZ; - add_timer(&sk->sk_timer); - printk(KERN_INFO "wansock: packet sk destroy delayed\n"); -} - -/*============================================================ - * wanpipe_unlink_driver - * - * When the socket is released, this function is - * used to remove links that bind the sock and the - * driver together. - *===========================================================*/ -static void wanpipe_unlink_driver (struct sock *sk) -{ - struct net_device *dev; - wanpipe_common_t *chan=NULL; - - sock_reset_flag(sk, SOCK_ZAPPED); - sk->sk_state = WANSOCK_DISCONNECTED; - wp_sk(sk)->dev = NULL; - - dev = dev_get_by_index(sk->sk_bound_dev_if); - if (!dev){ - printk(KERN_INFO "wansock: No dev on release\n"); - return; - } - dev_put(dev); - - if ((chan = dev->priv) == NULL){ - printk(KERN_INFO "wansock: No Priv Area on release\n"); - return; - } - - set_bit(0,&chan->common_critical); - chan->sk=NULL; - chan->func=NULL; - chan->mbox=NULL; - chan->tx_timer=NULL; - clear_bit(0,&chan->common_critical); - release_device(dev); - - return; -} - -/*============================================================ - * wanpipe_link_driver - * - * Upon successful bind(), sock is linked to a driver - * by binding in the wanpipe_rcv() bottom half handler - * to the driver function pointer, as well as sock and - * sock mailbox addresses. This way driver can pass - * data up the socket. - *===========================================================*/ - -static void wanpipe_link_driver(struct net_device *dev, struct sock *sk) -{ - wanpipe_opt *wp = wp_sk(sk); - wanpipe_common_t *chan = dev->priv; - if (!chan) - return; - set_bit(0,&chan->common_critical); - chan->sk=sk; - chan->func=wanpipe_rcv; - chan->mbox = wp->mbox; - chan->tx_timer = &wp->tx_timer; - wp->dev = dev; - sock_set_flag(sk, SOCK_ZAPPED); - clear_bit(0,&chan->common_critical); -} - - -/*============================================================ - * release_device - * - * During sock release, clear a critical bit, which - * marks the device a being taken. - *===========================================================*/ - - -static void release_device(struct net_device *dev) -{ - wanpipe_common_t *chan=dev->priv; - clear_bit(0,(void*)&chan->rw_bind); -} - -/*============================================================ - * wanpipe_release - * - * Close a PACKET socket. This is fairly simple. We - * immediately go to 'closed' state and remove our - * protocol entry in the device list. - *===========================================================*/ - -static int wanpipe_release(struct socket *sock) -{ - wanpipe_opt *wp; - struct sock *sk = sock->sk; - - if (!sk) - return 0; - - wp = wp_sk(sk); - check_write_queue(sk); - - /* Kill the tx timer, if we don't kill it now, the timer - * will run after we kill the sock. Timer code will - * try to access the sock which has been killed and cause - * kernel panic */ - - del_timer(&wp->tx_timer); - - /* - * Unhook packet receive handler. - */ - - if (wp->num == htons(X25_PROT) && - sk->sk_state != WANSOCK_DISCONNECTED && sock_flag(sk, SOCK_ZAPPED)) { - struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if); - wanpipe_common_t *chan; - if (dev){ - chan=dev->priv; - atomic_set(&chan->disconnect,1); - DBG_PRINTK(KERN_INFO "wansock: Sending Clear Indication %i\n", - sk->sk_state); - dev_put(dev); - } - } - - set_bit(1,&wanpipe_tx_critical); - write_lock(&wanpipe_sklist_lock); - sk_del_node_init(sk); - write_unlock(&wanpipe_sklist_lock); - clear_bit(1,&wanpipe_tx_critical); - - - - release_driver(sk); - - - /* - * Now the socket is dead. No more input will appear. - */ - - sk->sk_state_change(sk); /* It is useless. Just for sanity. */ - - sock->sk = NULL; - sk->sk_socket = NULL; - sock_set_flag(sk, SOCK_DEAD); - - /* Purge queues */ - skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); - skb_queue_purge(&sk->sk_error_queue); - - if (atomic_read(&sk->sk_rmem_alloc) || - atomic_read(&sk->sk_wmem_alloc)) { - del_timer(&sk->sk_timer); - printk(KERN_INFO "wansock: Killing in Timer R %i , W %i\n", - atomic_read(&sk->sk_rmem_alloc), - atomic_read(&sk->sk_wmem_alloc)); - sk->sk_timer.data = (unsigned long)sk; - sk->sk_timer.expires = jiffies + HZ; - sk->sk_timer.function = wanpipe_destroy_timer; - add_timer(&sk->sk_timer); - return 0; - } - - kfree(wp); - wp_sk(sk) = NULL; - - if (atomic_read(&sk->sk_refcnt) != 1) { - DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i !:release.\n", - atomic_read(&sk->sk_refcnt)); - atomic_set(&sk->sk_refcnt, 1); - } - sock_put(sk); - atomic_dec(&wanpipe_socks_nr); - return 0; -} - -/*============================================================ - * check_write_queue - * - * During sock shutdown, if the sock state is - * WANSOCK_CONNECTED and there is transmit data - * pending. Wait until data is released - * before proceeding. - *===========================================================*/ - -static void check_write_queue(struct sock *sk) -{ - - if (sk->sk_state != WANSOCK_CONNECTED) - return; - - if (!atomic_read(&sk->sk_wmem_alloc)) - return; - - printk(KERN_INFO "wansock: MAJOR ERROR, Data lost on sock release !!!\n"); - -} - -/*============================================================ - * release_driver - * - * This function is called during sock shutdown, to - * release any resources and links that bind the sock - * to the driver. It also changes the state of the - * sock to WANSOCK_DISCONNECTED - *===========================================================*/ - -static void release_driver(struct sock *sk) -{ - wanpipe_opt *wp; - struct sk_buff *skb=NULL; - struct sock *deadsk=NULL; - - if (sk->sk_state == WANSOCK_LISTEN || - sk->sk_state == WANSOCK_BIND_LISTEN) { - while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { - if ((deadsk = get_newsk_from_skb(skb))){ - DBG_PRINTK (KERN_INFO "wansock: RELEASE: FOUND DEAD SOCK\n"); - sock_set_flag(deadsk, SOCK_DEAD); - start_cleanup_timer(deadsk); - } - kfree_skb(skb); - } - if (sock_flag(sk, SOCK_ZAPPED)) - wanpipe_unlink_card(sk); - }else{ - if (sock_flag(sk, SOCK_ZAPPED)) - wanpipe_unlink_driver(sk); - } - sk->sk_state = WANSOCK_DISCONNECTED; - sk->sk_bound_dev_if = 0; - sock_reset_flag(sk, SOCK_ZAPPED); - wp = wp_sk(sk); - - if (wp) { - kfree(wp->mbox); - wp->mbox = NULL; - } -} - -/*============================================================ - * start_cleanup_timer - * - * If new incoming call's are pending but the socket - * is being released, start the timer which will - * envoke the kill routines for pending socks. - *===========================================================*/ - - -static void start_cleanup_timer (struct sock *sk) -{ - del_timer(&sk->sk_timer); - sk->sk_timer.data = (unsigned long)sk; - sk->sk_timer.expires = jiffies + HZ; - sk->sk_timer.function = wanpipe_kill_sock_timer; - add_timer(&sk->sk_timer); -} - - -/*============================================================ - * wanpipe_kill_sock - * - * This is a function which performs actual killing - * of the sock. It releases socket resources, - * and unlinks the sock from the driver. - *===========================================================*/ - -static void wanpipe_kill_sock_timer (unsigned long data) -{ - - struct sock *sk = (struct sock *)data; - struct sock **skp; - - if (!sk) - return; - - /* This function can be called from interrupt. We must use - * appropriate locks */ - - if (test_bit(1,&wanpipe_tx_critical)){ - sk->sk_timer.expires = jiffies + 10; - add_timer(&sk->sk_timer); - return; - } - - write_lock(&wanpipe_sklist_lock); - sk_del_node_init(sk); - write_unlock(&wanpipe_sklist_lock); - - - if (wp_sk(sk)->num == htons(X25_PROT) && - sk->sk_state != WANSOCK_DISCONNECTED) { - struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if); - wanpipe_common_t *chan; - if (dev){ - chan=dev->priv; - atomic_set(&chan->disconnect,1); - dev_put(dev); - } - } - - release_driver(sk); - - sk->sk_socket = NULL; - - /* Purge queues */ - skb_queue_purge(&sk->sk_receive_queue); - skb_queue_purge(&sk->sk_write_queue); - skb_queue_purge(&sk->sk_error_queue); - - if (atomic_read(&sk->sk_rmem_alloc) || - atomic_read(&sk->sk_wmem_alloc)) { - del_timer(&sk->sk_timer); - printk(KERN_INFO "wansock: Killing SOCK in Timer\n"); - sk->sk_timer.data = (unsigned long)sk; - sk->sk_timer.expires = jiffies + HZ; - sk->sk_timer.function = wanpipe_destroy_timer; - add_timer(&sk->sk_timer); - return; - } - - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; - - if (atomic_read(&sk->sk_refcnt) != 1) { - atomic_set(&sk->sk_refcnt, 1); - DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :timer.\n", - atomic_read(&sk->sk_refcnt)); - } - sock_put(sk); - atomic_dec(&wanpipe_socks_nr); - return; -} - -static void wanpipe_kill_sock_accept (struct sock *sk) -{ - - struct sock **skp; - - if (!sk) - return; - - /* This function can be called from interrupt. We must use - * appropriate locks */ - - write_lock(&wanpipe_sklist_lock); - sk_del_node_init(sk); - write_unlock(&wanpipe_sklist_lock); - - sk->sk_socket = NULL; - - - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; - - if (atomic_read(&sk->sk_refcnt) != 1) { - atomic_set(&sk->sk_refcnt, 1); - DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i ! :timer.\n", - atomic_read(&sk->sk_refcnt)); - } - sock_put(sk); - atomic_dec(&wanpipe_socks_nr); - return; -} - - -static void wanpipe_kill_sock_irq (struct sock *sk) -{ - - if (!sk) - return; - - sk->sk_socket = NULL; - - kfree(wp_sk(sk)); - wp_sk(sk) = NULL; - - if (atomic_read(&sk->sk_refcnt) != 1) { - atomic_set(&sk->sk_refcnt, 1); - DBG_PRINTK(KERN_INFO "wansock: Error, wrong reference count: %i !:listen.\n", - atomic_read(&sk->sk_refcnt)); - } - sock_put(sk); - atomic_dec(&wanpipe_socks_nr); -} - - -/*============================================================ - * wanpipe_do_bind - * - * Bottom half of the binding system call. - * Once the wanpipe_bind() function checks the - * legality of the call, this function binds the - * sock to the driver. - *===========================================================*/ - -static int wanpipe_do_bind(struct sock *sk, struct net_device *dev, - int protocol) -{ - wanpipe_opt *wp = wp_sk(sk); - wanpipe_common_t *chan=NULL; - int err=0; - - if (sock_flag(sk, SOCK_ZAPPED)) { - err = -EALREADY; - goto bind_unlock_exit; - } - - wp->num = protocol; - - if (protocol == 0){ - release_device(dev); - err = -EINVAL; - goto bind_unlock_exit; - } - - if (dev) { - if (dev->flags&IFF_UP) { - chan=dev->priv; - sk->sk_state = chan->state; - - if (wp->num == htons(X25_PROT) && - sk->sk_state != WANSOCK_DISCONNECTED && - sk->sk_state != WANSOCK_CONNECTING) { - DBG_PRINTK(KERN_INFO - "wansock: Binding to Device not DISCONNECTED %i\n", - sk->sk_state); - release_device(dev); - err = -EAGAIN; - goto bind_unlock_exit; - } - - wanpipe_link_driver(dev,sk); - sk->sk_bound_dev_if = dev->ifindex; - - /* X25 Specific option */ - if (wp->num == htons(X25_PROT)) - wp_sk(sk)->svc = chan->svc; - - } else { - sk->sk_err = ENETDOWN; - sk->sk_error_report(sk); - release_device(dev); - err = -EINVAL; - } - } else { - err = -ENODEV; - } -bind_unlock_exit: - /* FIXME where is this lock */ - - return err; -} - -/*============================================================ - * wanpipe_bind - * - * BIND() System call, which is bound to the AF_WANPIPE - * operations structure. It checks for correct wanpipe - * card name, and cross references interface names with - * the card names. Thus, interface name must belong to - * the actual card. - *===========================================================*/ - - -static int wanpipe_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) -{ - struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)uaddr; - struct sock *sk=sock->sk; - wanpipe_opt *wp = wp_sk(sk); - struct net_device *dev = NULL; - sdla_t *card=NULL; - char name[15]; - - /* - * Check legality - */ - - if (addr_len < sizeof(struct wan_sockaddr_ll)){ - printk(KERN_INFO "wansock: Address length error\n"); - return -EINVAL; - } - if (sll->sll_family != AF_WANPIPE){ - printk(KERN_INFO "wansock: Illegal family name specified.\n"); - return -EINVAL; - } - - card = wanpipe_find_card (sll->sll_card); - if (!card){ - printk(KERN_INFO "wansock: Wanpipe card not found: %s\n",sll->sll_card); - return -ENODEV; - }else{ - wp_sk(sk)->card = (void *)card; - } - - if (!strcmp(sll->sll_device,"svc_listen")){ - - /* Bind a sock to a card structure for listening - */ - int err=0; - - /* This is x25 specific area if protocol doesn't - * match, return error */ - if (sll->sll_protocol != htons(X25_PROT)) - return -EINVAL; - - err= wanpipe_link_card (sk); - if (err < 0) - return err; - - if (sll->sll_protocol) - wp->num = sll->sll_protocol; - sk->sk_state = WANSOCK_BIND_LISTEN; - return 0; - - }else if (!strcmp(sll->sll_device,"svc_connect")){ - - /* This is x25 specific area if protocol doesn't - * match, return error */ - if (sll->sll_protocol != htons(X25_PROT)) - return -EINVAL; - - /* Find a free device - */ - dev = wanpipe_find_free_dev(card); - if (dev == NULL){ - DBG_PRINTK(KERN_INFO "wansock: No free network devices for card %s\n", - card->devname); - return -EINVAL; - } - }else{ - /* Bind a socket to a interface name - * This is used by PVC mostly - */ - strlcpy(name,sll->sll_device,sizeof(name)); - dev = dev_get_by_name(name); - if (dev == NULL){ - printk(KERN_INFO "wansock: Failed to get Dev from name: %s,\n", - name); - return -ENODEV; - } - - dev_put(dev); - - if (check_dev(dev, card)){ - printk(KERN_INFO "wansock: Device %s, doesn't belong to card %s\n", - dev->name, card->devname); - return -EINVAL; - } - if (get_atomic_device (dev)) - return -EINVAL; - } - - return wanpipe_do_bind(sk, dev, sll->sll_protocol ? : wp->num); -} - -/*============================================================ - * get_atomic_device - * - * Sets a bit atomically which indicates that - * the interface is taken. This avoids race conditions. - *===========================================================*/ - - -static inline int get_atomic_device(struct net_device *dev) -{ - wanpipe_common_t *chan = dev->priv; - if (!test_and_set_bit(0,(void *)&chan->rw_bind)){ - return 0; - } - return 1; -} - -/*============================================================ - * check_dev - * - * Check that device name belongs to a particular card. - *===========================================================*/ - -static int check_dev(struct net_device *dev, sdla_t *card) -{ - struct net_device* tmp_dev; - - for (tmp_dev = card->wandev.dev; tmp_dev; - tmp_dev = *((struct net_device **)tmp_dev->priv)) { - if (tmp_dev->ifindex == dev->ifindex){ - return 0; - } - } - return 1; -} - -/*============================================================ - * wanpipe_find_free_dev - * - * Find a free network interface. If found set atomic - * bit indicating that the interface is taken. - * X25API Specific. - *===========================================================*/ - -struct net_device *wanpipe_find_free_dev(sdla_t *card) -{ - struct net_device* dev; - volatile wanpipe_common_t *chan; - - if (test_and_set_bit(0,&find_free_critical)){ - printk(KERN_INFO "CRITICAL in Find Free\n"); - } - - for (dev = card->wandev.dev; dev; - dev = *((struct net_device **)dev->priv)) { - chan = dev->priv; - if (!chan) - continue; - if (chan->usedby == API && chan->svc){ - if (!get_atomic_device (dev)){ - if (chan->state != WANSOCK_DISCONNECTED){ - release_device(dev); - }else{ - clear_bit(0,&find_free_critical); - return dev; - } - } - } - } - clear_bit(0,&find_free_critical); - return NULL; -} - -/*============================================================ - * wanpipe_create - * - * SOCKET() System call. It allocates a sock structure - * and adds the socket to the wanpipe_sk_list. - * Crates AF_WANPIPE socket. - *===========================================================*/ - -static int wanpipe_create(struct socket *sock, int protocol) -{ - struct sock *sk; - - //FIXME: This checks for root user, SECURITY ? - //if (!capable(CAP_NET_RAW)) - // return -EPERM; - - if (sock->type != SOCK_DGRAM && sock->type != SOCK_RAW) - return -ESOCKTNOSUPPORT; - - sock->state = SS_UNCONNECTED; - - if ((sk = wanpipe_alloc_socket()) == NULL) - return -ENOBUFS; - - sk->sk_reuse = 1; - sock->ops = &wanpipe_ops; - sock_init_data(sock,sk); - - sock_reset_flag(sk, SOCK_ZAPPED); - sk->sk_family = PF_WANPIPE; - wp_sk(sk)->num = protocol; - sk->sk_state = WANSOCK_DISCONNECTED; - sk->sk_ack_backlog = 0; - sk->sk_bound_dev_if = 0; - - atomic_inc(&wanpipe_socks_nr); - - /* We must disable interrupts because the ISR - * can also change the list */ - set_bit(1,&wanpipe_tx_critical); - write_lock(&wanpipe_sklist_lock); - sk_add_node(sk, &wanpipe_sklist); - write_unlock(&wanpipe_sklist_lock); - clear_bit(1,&wanpipe_tx_critical); - - return(0); -} - - -/*============================================================ - * wanpipe_recvmsg - * - * Pull a packet from our receive queue and hand it - * to the user. If necessary we block. - *===========================================================*/ - -static int wanpipe_recvmsg(struct kiocb *iocb, struct socket *sock, - struct msghdr *msg, int len, int flags) -{ - struct sock *sk = sock->sk; - struct sk_buff *skb; - int copied, err=-ENOBUFS; - - - /* - * If the address length field is there to be filled in, we fill - * it in now. - */ - - msg->msg_namelen = sizeof(struct wan_sockaddr_ll); - - /* - * Call the generic datagram receiver. This handles all sorts - * of horrible races and re-entrancy so we can forget about it - * in the protocol layers. - * - * Now it will return ENETDOWN, if device have just gone down, - * but then it will block. - */ - - if (flags & MSG_OOB){ - skb = skb_dequeue(&sk->sk_error_queue); - }else{ - skb=skb_recv_datagram(sk,flags,1,&err); - } - /* - * An error occurred so return it. Because skb_recv_datagram() - * handles the blocking we don't see and worry about blocking - * retries. - */ - - if(skb==NULL) - goto out; - - /* - * You lose any data beyond the buffer you gave. If it worries a - * user program they can ask the device for its MTU anyway. - */ - - copied = skb->len; - if (copied > len) - { - copied=len; - msg->msg_flags|=MSG_TRUNC; - } - - wanpipe_wakeup_driver(sk); - - /* We can't use skb_copy_datagram here */ - err = memcpy_toiovec(msg->msg_iov, skb->data, copied); - if (err) - goto out_free; - - sock_recv_timestamp(msg, sk, skb); - - if (msg->msg_name) - memcpy(msg->msg_name, skb->cb, msg->msg_namelen); - - /* - * Free or return the buffer as appropriate. Again this - * hides all the races and re-entrancy issues from us. - */ - err = (flags&MSG_TRUNC) ? skb->len : copied; - -out_free: - skb_free_datagram(sk, skb); -out: - return err; -} - - -/*============================================================ - * wanpipe_wakeup_driver - * - * If socket receive buffer is full and driver cannot - * pass data up the sock, it sets a packet_block flag. - * This function check that flag and if sock receive - * queue has room it kicks the driver BH handler. - * - * This way, driver doesn't have to poll the sock - * receive queue. - *===========================================================*/ - -static void wanpipe_wakeup_driver(struct sock *sk) -{ - struct net_device *dev = NULL; - wanpipe_common_t *chan=NULL; - - dev = dev_get_by_index(sk->sk_bound_dev_if); - if (!dev) - return; - - dev_put(dev); - - if ((chan = dev->priv) == NULL) - return; - - if (atomic_read(&chan->receive_block)){ - if (atomic_read(&sk->sk_rmem_alloc) < - ((unsigned)sk->sk_rcvbuf * 0.9)) { - printk(KERN_INFO "wansock: Queuing task for wanpipe\n"); - atomic_set(&chan->receive_block,0); - wanpipe_queue_tq(&chan->wanpipe_task); - wanpipe_mark_bh(); - } - } -} - -/*============================================================ - * wanpipe_getname - * - * I don't know what to do with this yet. - * User can use this function to get sock address - * information. Not very useful for Sangoma's purposes. - *===========================================================*/ - - -static int wanpipe_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) -{ - struct net_device *dev; - struct sock *sk = sock->sk; - struct wan_sockaddr_ll *sll = (struct wan_sockaddr_ll*)uaddr; - - sll->sll_family = AF_WANPIPE; - sll->sll_ifindex = sk->sk_bound_dev_if; - sll->sll_protocol = wp_sk(sk)->num; - dev = dev_get_by_index(sk->sk_bound_dev_if); - if (dev) { - sll->sll_hatype = dev->type; - sll->sll_halen = dev->addr_len; - memcpy(sll->sll_addr, dev->dev_addr, dev->addr_len); - } else { - sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */ - sll->sll_halen = 0; - } - *uaddr_len = sizeof(*sll); - - dev_put(dev); - - return 0; -} - -/*============================================================ - * wanpipe_notifier - * - * If driver turns off network interface, this function - * will be envoked. Currently I treate it as a - * call disconnect. More thought should go into this - * function. - * - * FIXME: More thought should go into this function. - * - *===========================================================*/ - -static int wanpipe_notifier(struct notifier_block *this, unsigned long msg, void *data) -{ - struct sock *sk; - hlist_node *node; - struct net_device *dev = (struct net_device *)data; - - sk_for_each(sk, node, &wanpipe_sklist) { - struct wanpipe_opt *po = wp_sk(sk); - - if (!po) - continue; - if (dev == NULL) - continue; - - switch (msg) { - case NETDEV_DOWN: - case NETDEV_UNREGISTER: - if (dev->ifindex == sk->sk_bound_dev_if) { - printk(KERN_INFO "wansock: Device down %s\n",dev->name); - if (sock_flag(sk, SOCK_ZAPPED)) { - wanpipe_unlink_driver(sk); - sk->sk_err = ENETDOWN; - sk->sk_error_report(sk); - } - - if (msg == NETDEV_UNREGISTER) { - printk(KERN_INFO "wansock: Unregistering Device: %s\n", - dev->name); - wanpipe_unlink_driver(sk); - sk->sk_bound_dev_if = 0; - } - } - break; - case NETDEV_UP: - if (dev->ifindex == sk->sk_bound_dev_if && - po->num && !sock_flag(sk, SOCK_ZAPPED)) { - printk(KERN_INFO "wansock: Registering Device: %s\n", - dev->name); - wanpipe_link_driver(dev,sk); - } - break; - } - } - return NOTIFY_DONE; -} - -/*============================================================ - * wanpipe_ioctl - * - * Execute a user commands, and set socket options. - * - * FIXME: More thought should go into this function. - * - *===========================================================*/ - -static int wanpipe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) -{ - struct sock *sk = sock->sk; - int err; - - switch(cmd) - { - case SIOCGSTAMP: - return sock_get_timestamp(sk, (struct timeval __user *)arg); - - case SIOC_WANPIPE_CHECK_TX: - - return atomic_read(&sk->sk_wmem_alloc); - - case SIOC_WANPIPE_SOCK_STATE: - - if (sk->sk_state == WANSOCK_CONNECTED) - return 0; - - return 1; - - - case SIOC_WANPIPE_GET_CALL_DATA: - - return get_ioctl_cmd (sk,(void*)arg); - - case SIOC_WANPIPE_SET_CALL_DATA: - - return set_ioctl_cmd (sk,(void*)arg); - - case SIOC_WANPIPE_ACCEPT_CALL: - case SIOC_WANPIPE_CLEAR_CALL: - case SIOC_WANPIPE_RESET_CALL: - - if ((err=set_ioctl_cmd(sk,(void*)arg)) < 0) - return err; - - err=wanpipe_exec_cmd(sk,cmd,0); - get_ioctl_cmd(sk,(void*)arg); - return err; - - case SIOC_WANPIPE_DEBUG: - - return wanpipe_debug(sk,(void*)arg); - - case SIOC_WANPIPE_SET_NONBLOCK: - - if (sk->sk_state != WANSOCK_DISCONNECTED) - return -EINVAL; - - sock->file->f_flags |= O_NONBLOCK; - return 0; - -#ifdef CONFIG_INET - case SIOCADDRT: - case SIOCDELRT: - case SIOCDARP: - case SIOCGARP: - case SIOCSARP: - case SIOCDRARP: - case SIOCGRARP: - case SIOCSRARP: - case SIOCGIFADDR: - case SIOCSIFADDR: - case SIOCGIFBRDADDR: - case SIOCSIFBRDADDR: - case SIOCGIFNETMASK: - case SIOCSIFNETMASK: - case SIOCGIFDSTADDR: - case SIOCSIFDSTADDR: - case SIOCSIFFLAGS: - return inet_dgram_ops.ioctl(sock, cmd, arg); -#endif - - default: - return -ENOIOCTLCMD; - } - /*NOTREACHED*/ -} - -/*============================================================ - * wanpipe_debug - * - * This function will pass up information about all - * active sockets. - * - * FIXME: More thought should go into this function. - * - *===========================================================*/ - -static int wanpipe_debug (struct sock *origsk, void *arg) -{ - struct sock *sk; - struct hlist_node *node; - struct net_device *dev = NULL; - wanpipe_common_t *chan=NULL; - int cnt=0, err=0; - wan_debug_t *dbg_data = (wan_debug_t *)arg; - - sk_for_each(sk, node, &wanpipe_sklist) { - wanpipe_opt *wp = wp_sk(sk); - - if (sk == origsk){ - continue; - } - - if ((err=put_user(1, &dbg_data->debug[cnt].free))) - return err; - if ((err = put_user(sk->sk_state, - &dbg_data->debug[cnt].state_sk))) - return err; - if ((err = put_user(sk->sk_rcvbuf, - &dbg_data->debug[cnt].rcvbuf))) - return err; - if ((err = put_user(atomic_read(&sk->sk_rmem_alloc), - &dbg_data->debug[cnt].rmem))) - return err; - if ((err = put_user(atomic_read(&sk->sk_wmem_alloc), - &dbg_data->debug[cnt].wmem))) - return err; - if ((err = put_user(sk->sk_sndbuf, - &dbg_data->debug[cnt].sndbuf))) - return err; - if ((err=put_user(sk_count, &dbg_data->debug[cnt].sk_count))) - return err; - if ((err=put_user(wp->poll_cnt, &dbg_data->debug[cnt].poll_cnt))) - return err; - if ((err = put_user(sk->sk_bound_dev_if, - &dbg_data->debug[cnt].bound))) - return err; - - if (sk->sk_bound_dev_if) { - dev = dev_get_by_index(sk->sk_bound_dev_if); - if (!dev) - continue; - - chan=dev->priv; - dev_put(dev); - - if ((err=put_user(chan->state, &dbg_data->debug[cnt].d_state))) - return err; - if ((err=put_user(chan->svc, &dbg_data->debug[cnt].svc))) - return err; - - if ((err=put_user(atomic_read(&chan->command), - &dbg_data->debug[cnt].command))) - return err; - - - if (wp){ - sdla_t *card = (sdla_t*)wp->card; - - if (card){ - if ((err=put_user(atomic_read(&card->u.x.command_busy), - &dbg_data->debug[cnt].cmd_busy))) - return err; - } - - if ((err=put_user(wp->lcn, - &dbg_data->debug[cnt].lcn))) - return err; - - if (wp->mbox) { - if ((err=put_user(1, &dbg_data->debug[cnt].mbox))) - return err; - } - } - - if ((err=put_user(atomic_read(&chan->receive_block), - &dbg_data->debug[cnt].rblock))) - return err; - - if (copy_to_user(dbg_data->debug[cnt].name, dev->name, strlen(dev->name))) - return -EFAULT; - } - - if (++cnt == MAX_NUM_DEBUG) - break; - } - return 0; -} - -/*============================================================ - * get_ioctl_cmd - * - * Pass up the contents of socket MBOX to the user. - *===========================================================*/ - -static int get_ioctl_cmd (struct sock *sk, void *arg) -{ - x25api_t *usr_data = (x25api_t *)arg; - mbox_cmd_t *mbox_ptr; - int err; - - if (usr_data == NULL) - return -EINVAL; - - if (!wp_sk(sk)->mbox) { - return -EINVAL; - } - - mbox_ptr = (mbox_cmd_t *)wp_sk(sk)->mbox; - - if ((err=put_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm))) - return err; - if ((err=put_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause))) - return err; - if ((err=put_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn))) - return err; - if ((err=put_user(mbox_ptr->cmd.length, &usr_data->hdr.length))) - return err; - if ((err=put_user(mbox_ptr->cmd.result, &usr_data->hdr.result))) - return err; - if ((err=put_user(mbox_ptr->cmd.lcn, &usr_data->hdr.lcn))) - return err; - - if (mbox_ptr->cmd.length > 0){ - if (mbox_ptr->cmd.length > X25_MAX_DATA) - return -EINVAL; - - if (copy_to_user(usr_data->data, mbox_ptr->data, mbox_ptr->cmd.length)){ - printk(KERN_INFO "wansock: Copy failed !!!\n"); - return -EFAULT; - } - } - return 0; -} - -/*============================================================ - * set_ioctl_cmd - * - * Before command can be execute, socket MBOX must - * be created, and initialized with user data. - *===========================================================*/ - -static int set_ioctl_cmd (struct sock *sk, void *arg) -{ - x25api_t *usr_data = (x25api_t *)arg; - mbox_cmd_t *mbox_ptr; - int err; - - if (!wp_sk(sk)->mbox) { - void *mbox_ptr; - struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if); - if (!dev) - return -ENODEV; - - dev_put(dev); - - if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) - return -ENOMEM; - - wp_sk(sk)->mbox = mbox_ptr; - - wanpipe_link_driver(dev,sk); - } - - mbox_ptr = (mbox_cmd_t*)wp_sk(sk)->mbox; - memset(mbox_ptr, 0, sizeof(mbox_cmd_t)); - - if (usr_data == NULL){ - return 0; - } - if ((err=get_user(mbox_ptr->cmd.qdm, &usr_data->hdr.qdm))) - return err; - if ((err=get_user(mbox_ptr->cmd.cause, &usr_data->hdr.cause))) - return err; - if ((err=get_user(mbox_ptr->cmd.diagn, &usr_data->hdr.diagn))) - return err; - if ((err=get_user(mbox_ptr->cmd.length, &usr_data->hdr.length))) - return err; - if ((err=get_user(mbox_ptr->cmd.result, &usr_data->hdr.result))) - return err; - - if (mbox_ptr->cmd.length > 0){ - if (mbox_ptr->cmd.length > X25_MAX_DATA) - return -EINVAL; - - if (copy_from_user(mbox_ptr->data, usr_data->data, mbox_ptr->cmd.length)){ - printk(KERN_INFO "Copy failed\n"); - return -EFAULT; - } - } - return 0; -} - - -/*====================================================================== - * wanpipe_poll - * - * Datagram poll: Again totally generic. This also handles - * sequenced packet sockets providing the socket receive queue - * is only ever holding data ready to receive. - * - * Note: when you _don't_ use this routine for this protocol, - * and you use a different write policy from sock_writeable() - * then please supply your own write_space callback. - *=====================================================================*/ - -unsigned int wanpipe_poll(struct file * file, struct socket *sock, poll_table *wait) -{ - struct sock *sk = sock->sk; - unsigned int mask; - - ++wp_sk(sk)->poll_cnt; - - poll_wait(file, sk->sk_sleep, wait); - mask = 0; - - /* exceptional events? */ - if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) { - mask |= POLLPRI; - return mask; - } - if (sk->sk_shutdown & RCV_SHUTDOWN) - mask |= POLLHUP; - - /* readable? */ - if (!skb_queue_empty(&sk->sk_receive_queue)) { - mask |= POLLIN | POLLRDNORM; - } - - /* connection hasn't started yet */ - if (sk->sk_state == WANSOCK_CONNECTING) { - return mask; - } - - if (sk->sk_state == WANSOCK_DISCONNECTED) { - mask = POLLPRI; - return mask; - } - - /* This check blocks the user process if there is - * a packet already queued in the socket write queue. - * This option is only for X25API protocol, for other - * protocol like chdlc enable streaming mode, - * where multiple packets can be pending in the socket - * transmit queue */ - - if (wp_sk(sk)->num == htons(X25_PROT)) { - if (atomic_read(&wp_sk(sk)->packet_sent)) - return mask; - } - - /* writable? */ - if (sock_writeable(sk)){ - mask |= POLLOUT | POLLWRNORM | POLLWRBAND; - }else{ - set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); - } - - return mask; -} - -/*====================================================================== - * wanpipe_listen - * - * X25API Specific function. Set a socket into LISTENING MODE. - *=====================================================================*/ - - -static int wanpipe_listen(struct socket *sock, int backlog) -{ - struct sock *sk = sock->sk; - - /* This is x25 specific area if protocol doesn't - * match, return error */ - if (wp_sk(sk)->num != htons(X25_PROT)) - return -EINVAL; - - if (sk->sk_state == WANSOCK_BIND_LISTEN) { - - sk->sk_max_ack_backlog = backlog; - sk->sk_state = WANSOCK_LISTEN; - return 0; - }else{ - printk(KERN_INFO "wansock: Listening sock was not binded\n"); - } - - return -EINVAL; -} - -/*====================================================================== - * wanpipe_link_card - * - * Connects the listening socket to the driver - *=====================================================================*/ - -static int wanpipe_link_card (struct sock *sk) -{ - sdla_t *card = (sdla_t*)wp_sk(sk)->card; - - if (!card) - return -ENOMEM; - - if ((card->sk != NULL) || (card->func != NULL)){ - printk(KERN_INFO "wansock: Listening queue is already established\n"); - return -EINVAL; - } - - card->sk=sk; - card->func=wanpipe_listen_rcv; - sock_set_flag(sk, SOCK_ZAPPED); - - return 0; -} - -/*====================================================================== - * wanpipe_listen - * - * X25API Specific function. Disconnect listening socket from - * the driver. - *=====================================================================*/ - -static void wanpipe_unlink_card (struct sock *sk) -{ - sdla_t *card = (sdla_t*)wp_sk(sk)->card; - - if (card){ - card->sk=NULL; - card->func=NULL; - } -} - -/*====================================================================== - * wanpipe_exec_cmd - * - * Ioctl function calls this function to execute user command. - * Connect() sytem call also calls this function to execute - * place call. This function blocks until command is executed. - *=====================================================================*/ - -static int wanpipe_exec_cmd(struct sock *sk, int cmd, unsigned int flags) -{ - int err = -EINVAL; - wanpipe_opt *wp = wp_sk(sk); - mbox_cmd_t *mbox_ptr = (mbox_cmd_t*)wp->mbox; - - if (!mbox_ptr){ - printk(KERN_INFO "NO MBOX PTR !!!!!\n"); - return -EINVAL; - } - - /* This is x25 specific area if protocol doesn't - * match, return error */ - if (wp->num != htons(X25_PROT)) - return -EINVAL; - - - switch (cmd){ - - case SIOC_WANPIPE_ACCEPT_CALL: - - if (sk->sk_state != WANSOCK_CONNECTING) { - err = -EHOSTDOWN; - break; - } - - err = execute_command(sk,X25_ACCEPT_CALL,0); - if (err < 0) - break; - - /* Update. Mar6 2000. - * Do not set the sock lcn number here, since - * it is done in wanpipe_listen_rcv(). - */ - if (sk->sk_state == WANSOCK_CONNECTED) { - wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn; - DBG_PRINTK(KERN_INFO "\nwansock: Accept OK %i\n", - wp->lcn); - err = 0; - - }else{ - DBG_PRINTK (KERN_INFO "\nwansock: Accept Failed %i\n", - wp->lcn); - wp->lcn = 0; - err = -ECONNREFUSED; - } - break; - - case SIOC_WANPIPE_CLEAR_CALL: - - if (sk->sk_state == WANSOCK_DISCONNECTED) { - err = -EINVAL; - break; - } - - - /* Check if data buffers are pending for transmission, - * if so, check whether user wants to wait until data - * is transmitted, or clear a call and drop packets */ - - if (atomic_read(&sk->sk_wmem_alloc) || - check_driver_busy(sk)) { - mbox_cmd_t *mbox = wp->mbox; - if (mbox->cmd.qdm & 0x80){ - mbox->cmd.result = 0x35; - err = -EAGAIN; - break; - } - } - - sk->sk_state = WANSOCK_DISCONNECTING; - - err = execute_command(sk,X25_CLEAR_CALL,0); - if (err < 0) - break; - - err = -ECONNREFUSED; - if (sk->sk_state == WANSOCK_DISCONNECTED) { - DBG_PRINTK(KERN_INFO "\nwansock: CLEAR OK %i\n", - wp->lcn); - wp->lcn = 0; - err = 0; - } - break; - - case SIOC_WANPIPE_RESET_CALL: - - if (sk->sk_state != WANSOCK_CONNECTED) { - err = -EINVAL; - break; - } - - - /* Check if data buffers are pending for transmission, - * if so, check whether user wants to wait until data - * is transmitted, or reset a call and drop packets */ - - if (atomic_read(&sk->sk_wmem_alloc) || - check_driver_busy(sk)) { - mbox_cmd_t *mbox = wp->mbox; - if (mbox->cmd.qdm & 0x80){ - mbox->cmd.result = 0x35; - err = -EAGAIN; - break; - } - } - - - err = execute_command(sk, X25_RESET,0); - if (err < 0) - break; - - err = mbox_ptr->cmd.result; - break; - - - case X25_PLACE_CALL: - - err=execute_command(sk,X25_PLACE_CALL,flags); - if (err < 0) - break; - - if (sk->sk_state == WANSOCK_CONNECTED) { - - wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn; - - DBG_PRINTK(KERN_INFO "\nwansock: PLACE CALL OK %i\n", - wp->lcn); - err = 0; - - } else if (sk->sk_state == WANSOCK_CONNECTING && - (flags & O_NONBLOCK)) { - wp->lcn = ((mbox_cmd_t*)wp->mbox)->cmd.lcn; - DBG_PRINTK(KERN_INFO "\nwansock: Place Call OK: Waiting %i\n", - wp->lcn); - - err = 0; - - }else{ - DBG_PRINTK(KERN_INFO "\nwansock: Place call Failed\n"); - err = -ECONNREFUSED; - } - - break; - - default: - return -EINVAL; - } - - return err; -} - -static int check_driver_busy (struct sock *sk) -{ - struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if); - wanpipe_common_t *chan; - - if (!dev) - return 0; - - dev_put(dev); - - if ((chan=dev->priv) == NULL) - return 0; - - return atomic_read(&chan->driver_busy); -} - - -/*====================================================================== - * wanpipe_accept - * - * ACCEPT() System call. X25API Specific function. - * For each incoming call, create a new socket and - * return it to the user. - *=====================================================================*/ - -static int wanpipe_accept(struct socket *sock, struct socket *newsock, int flags) -{ - struct sock *sk; - struct sock *newsk; - struct sk_buff *skb; - DECLARE_WAITQUEUE(wait, current); - int err=0; - - if (newsock->sk != NULL){ - wanpipe_kill_sock_accept(newsock->sk); - newsock->sk=NULL; - } - - if ((sk = sock->sk) == NULL) - return -EINVAL; - - if (sk->sk_type != SOCK_RAW) - return -EOPNOTSUPP; - - if (sk->sk_state != WANSOCK_LISTEN) - return -EINVAL; - - if (wp_sk(sk)->num != htons(X25_PROT)) - return -EINVAL; - - add_wait_queue(sk->sk_sleep,&wait); - current->state = TASK_INTERRUPTIBLE; - for (;;){ - skb = skb_dequeue(&sk->sk_receive_queue); - if (skb){ - err=0; - break; - } - if (signal_pending(current)) { - err = -ERESTARTSYS; - break; - } - schedule(); - } - current->state = TASK_RUNNING; - remove_wait_queue(sk->sk_sleep,&wait); - - if (err != 0) - return err; - - newsk = get_newsk_from_skb(skb); - if (!newsk){ - return -EINVAL; - } - - set_bit(1,&wanpipe_tx_critical); - write_lock(&wanpipe_sklist_lock); - sk_add_node(newsk, &wanpipe_sklist); - write_unlock(&wanpipe_sklist_lock); - clear_bit(1,&wanpipe_tx_critical); - - newsk->sk_socket = newsock; - newsk->sk_sleep = &newsock->wait; - - /* Now attach up the new socket */ - sk->sk_ack_backlog--; - newsock->sk = newsk; - - kfree_skb(skb); - - DBG_PRINTK(KERN_INFO "\nwansock: ACCEPT Got LCN %i\n", - wp_sk(newsk)->lcn); - return 0; -} - -/*====================================================================== - * get_newsk_from_skb - * - * Accept() uses this function to get the address of the new - * socket structure. - *=====================================================================*/ - -struct sock * get_newsk_from_skb (struct sk_buff *skb) -{ - struct net_device *dev = skb->dev; - wanpipe_common_t *chan; - - if (!dev){ - return NULL; - } - - if ((chan = dev->priv) == NULL){ - return NULL; - } - - if (!chan->sk){ - return NULL; - } - return (struct sock *)chan->sk; -} - -/*====================================================================== - * wanpipe_connect - * - * CONNECT() System Call. X25API specific function - * Check the state of the sock, and execute PLACE_CALL command. - * Connect can ether block or return without waiting for connection, - * if specified by user. - *=====================================================================*/ - -static int wanpipe_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) -{ - struct sock *sk = sock->sk; - struct wan_sockaddr_ll *addr = (struct wan_sockaddr_ll*)uaddr; - struct net_device *dev; - int err; - - if (wp_sk(sk)->num != htons(X25_PROT)) - return -EINVAL; - - if (sk->sk_state == WANSOCK_CONNECTED) - return -EISCONN; /* No reconnect on a seqpacket socket */ - - if (sk->sk_state != WAN_DISCONNECTED) { - printk(KERN_INFO "wansock: Trying to connect on channel NON DISCONNECT\n"); - return -ECONNREFUSED; - } - - sk->sk_state = WANSOCK_DISCONNECTED; - sock->state = SS_UNCONNECTED; - - if (addr_len != sizeof(struct wan_sockaddr_ll)) - return -EINVAL; - - if (addr->sll_family != AF_WANPIPE) - return -EINVAL; - - if ((dev = dev_get_by_index(sk->sk_bound_dev_if)) == NULL) - return -ENETUNREACH; - - dev_put(dev); - - if (!sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */ - return -EINVAL; - - sock->state = SS_CONNECTING; - sk->sk_state = WANSOCK_CONNECTING; - - if (!wp_sk(sk)->mbox) { - if (wp_sk (sk)->svc) - return -EINVAL; - else { - int err; - if ((err=set_ioctl_cmd(sk,NULL)) < 0) - return err; - } - } - - if ((err=wanpipe_exec_cmd(sk, X25_PLACE_CALL,flags)) != 0){ - sock->state = SS_UNCONNECTED; - sk->sk_state = WANSOCK_CONNECTED; - return err; - } - - if (sk->sk_state != WANSOCK_CONNECTED && (flags & O_NONBLOCK)) { - return 0; - } - - if (sk->sk_state != WANSOCK_CONNECTED) { - sock->state = SS_UNCONNECTED; - return -ECONNREFUSED; - } - - sock->state = SS_CONNECTED; - return 0; -} - -const struct proto_ops wanpipe_ops = { - .family = PF_WANPIPE, - .owner = THIS_MODULE, - .release = wanpipe_release, - .bind = wanpipe_bind, - .connect = wanpipe_connect, - .socketpair = sock_no_socketpair, - .accept = wanpipe_accept, - .getname = wanpipe_getname, - .poll = wanpipe_poll, - .ioctl = wanpipe_ioctl, - .listen = wanpipe_listen, - .shutdown = sock_no_shutdown, - .setsockopt = sock_no_setsockopt, - .getsockopt = sock_no_getsockopt, - .sendmsg = wanpipe_sendmsg, - .recvmsg = wanpipe_recvmsg -}; - -static struct net_proto_family wanpipe_family_ops = { - .family = PF_WANPIPE, - .create = wanpipe_create, - .owner = THIS_MODULE, -}; - -struct notifier_block wanpipe_netdev_notifier = { - .notifier_call = wanpipe_notifier, -}; - - -#ifdef MODULE -void cleanup_module(void) -{ - printk(KERN_INFO "wansock: Cleaning up \n"); - unregister_netdevice_notifier(&wanpipe_netdev_notifier); - sock_unregister(PF_WANPIPE); - proto_unregister(&wanpipe_proto); -} - -int init_module(void) -{ - int rc; - - printk(KERN_INFO "wansock: Registering Socket \n"); - - rc = proto_register(&wanpipe_proto, 0); - if (rc != 0) - goto out; - - sock_register(&wanpipe_family_ops); - register_netdevice_notifier(&wanpipe_netdev_notifier); -out: - return rc; -} -#endif -MODULE_LICENSE("GPL"); -MODULE_ALIAS_NETPROTO(PF_WANPIPE); diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index a35f9e4ede2..5c5f6dcab97 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -704,7 +704,8 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re x->props.mode != mode || x->props.family != family || x->km.state != XFRM_STATE_ACQ || - x->id.spi != 0) + x->id.spi != 0 || + x->id.proto != proto) continue; switch (family) { @@ -801,7 +802,8 @@ int xfrm_state_add(struct xfrm_state *x) if (use_spi && x->km.seq) { x1 = __xfrm_find_acq_byseq(x->km.seq); - if (x1 && xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family)) { + if (x1 && ((x1->id.proto != x->id.proto) || + xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { xfrm_state_put(x1); x1 = NULL; } diff --git a/security/dummy.c b/security/dummy.c index 558795b237d..8ffd76405b5 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) return; } -static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static int dummy_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 19a385e9968..d41e24d6ae4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -4468,11 +4468,12 @@ static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) } static int selinux_getprocattr(struct task_struct *p, - char *name, void *value, size_t size) + char *name, char **value) { struct task_security_struct *tsec; u32 sid; int error; + unsigned len; if (current != p) { error = task_has_perm(current, p, PROCESS__GETATTR); @@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, if (!sid) return 0; - return selinux_getsecurity(sid, value, size); + error = security_sid_to_context(sid, value, &len); + if (error) + return error; + return len; } static int selinux_setprocattr(struct task_struct *p, diff --git a/sound/oss/dmasound/dmasound_core.c b/sound/oss/dmasound/dmasound_core.c index a0ec886f2aa..f4056a9c371 100644 --- a/sound/oss/dmasound/dmasound_core.c +++ b/sound/oss/dmasound/dmasound_core.c @@ -1346,22 +1346,34 @@ static const struct file_operations sq_fops = .ioctl = sq_ioctl, .open = sq_open, .release = sq_release, +}; + #ifdef HAS_RECORD - .read = NULL /* default to no read for compat mode */ -#endif +static const struct file_operations sq_fops_record = +{ + .owner = THIS_MODULE, + .llseek = no_llseek, + .write = sq_write, + .poll = sq_poll, + .ioctl = sq_ioctl, + .open = sq_open, + .release = sq_release, + .read = sq_read, }; +#endif static int sq_init(void) { + const struct file_operations *fops = &sq_fops; #ifndef MODULE int sq_unit; #endif #ifdef HAS_RECORD if (dmasound.mach.record) - sq_fops.read = sq_read ; + fops = &sq_fops_record; #endif - sq_unit = register_sound_dsp(&sq_fops, -1); + sq_unit = register_sound_dsp(fops, -1); if (sq_unit < 0) { printk(KERN_ERR "dmasound_core: couldn't register fops\n") ; return sq_unit ; diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 37fabf75daa..b188a4df58c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -1962,9 +1962,11 @@ static int snd_ac97_ad1888_downmix_put(struct snd_kcontrol *kcontrol, struct snd 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_ac97_ad1985_controls[] = { 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 snd_ac97 *ac97) 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) */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b9a8e238b0a..1672cace1ae 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -199,7 +199,6 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; /* 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 azx *chip, struct azx_dev *azx_dev) * 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(struct azx *chip, const char *model) 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_substream *substream) 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); diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 00ace59b05c..f94f1f22889 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -833,12 +833,14 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { 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_codec *codec) 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_MODELS] = { [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_tbl[] = { /* 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 *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_MODEL_LAST] = { [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 *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; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 84d005ef30e..fba3cb11bc2 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -4186,6 +4186,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { 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), diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4c7b03996be..c94291bc536 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -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[10] = { 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[STAC_922X_MODELS] = { [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_922X_MODELS] = { [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_codec *codec) 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_codec *codec) /* 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; } } diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index a289abfc717..7cf2dcb9d8d 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -725,10 +725,11 @@ static void fill_nocache(void *buf, int size, int nocache) 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(struct intel8x0 *chip, struct ichdev *ich 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_dev *pci, pm_message_t state) } 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; } diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index ec821a57f84..dccaa4be679 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -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 diff --git a/sound/soc/at91/Kconfig b/sound/soc/at91/Kconfig index 5bcf08b728b..a5b2558916c 100644 --- a/sound/soc/at91/Kconfig +++ b/sound/soc/at91/Kconfig @@ -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 diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index 579e1c8d2b2..b9ab3b8e1d3 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -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 |