diff options
162 files changed, 965 insertions, 1975 deletions
diff --git a/arch/m68k/include/asm/irqflags.h b/arch/m68k/include/asm/irqflags.h index 4a5b284a1550..7ef4115b8c4a 100644 --- a/arch/m68k/include/asm/irqflags.h +++ b/arch/m68k/include/asm/irqflags.h @@ -2,7 +2,9 @@ #define _M68K_IRQFLAGS_H #include <linux/types.h> +#ifdef CONFIG_MMU #include <linux/hardirq.h> +#endif #include <linux/preempt.h> #include <asm/thread_info.h> #include <asm/entry.h> diff --git a/arch/m68k/include/asm/machdep.h b/arch/m68k/include/asm/machdep.h index 789f3b2de0e9..415d5484916c 100644 --- a/arch/m68k/include/asm/machdep.h +++ b/arch/m68k/include/asm/machdep.h @@ -40,5 +40,6 @@ extern unsigned long hw_timer_offset(void); extern irqreturn_t arch_timer_interrupt(int irq, void *dummy); extern void config_BSP(char *command, int len); +extern void do_IRQ(int irq, struct pt_regs *fp); #endif /* _M68K_MACHDEP_H */ diff --git a/arch/powerpc/kernel/kvm.c b/arch/powerpc/kernel/kvm.c index 428d0e538aec..b06bdae04064 100644 --- a/arch/powerpc/kernel/kvm.c +++ b/arch/powerpc/kernel/kvm.c @@ -127,7 +127,7 @@ static void kvm_patch_ins_nop(u32 *inst) static void kvm_patch_ins_b(u32 *inst, int addr) { -#ifdef CONFIG_RELOCATABLE +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC_BOOK3S) /* On relocatable kernels interrupts handlers and our code can be in different regions, so we don't patch them */ diff --git a/arch/powerpc/kvm/booke_interrupts.S b/arch/powerpc/kvm/booke_interrupts.S index 049846911ce4..1cc471faac2d 100644 --- a/arch/powerpc/kvm/booke_interrupts.S +++ b/arch/powerpc/kvm/booke_interrupts.S @@ -416,7 +416,7 @@ lightweight_exit: lwz r3, VCPU_PC(r4) mtsrr0 r3 lwz r3, VCPU_SHARED(r4) - lwz r3, VCPU_SHARED_MSR(r3) + lwz r3, (VCPU_SHARED_MSR + 4)(r3) oris r3, r3, KVMPPC_MSR_MASK@h ori r3, r3, KVMPPC_MSR_MASK@l mtsrr1 r3 diff --git a/arch/powerpc/kvm/e500.c b/arch/powerpc/kvm/e500.c index 71750f2dd5d3..e3768ee9b595 100644 --- a/arch/powerpc/kvm/e500.c +++ b/arch/powerpc/kvm/e500.c @@ -138,8 +138,8 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu) struct kvmppc_vcpu_e500 *vcpu_e500 = to_e500(vcpu); free_page((unsigned long)vcpu->arch.shared); - kvmppc_e500_tlb_uninit(vcpu_e500); kvm_vcpu_uninit(vcpu); + kvmppc_e500_tlb_uninit(vcpu_e500); kmem_cache_free(kvm_vcpu_cache, vcpu_e500); } diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c index 2f87a1627f6c..38f756f25053 100644 --- a/arch/powerpc/kvm/powerpc.c +++ b/arch/powerpc/kvm/powerpc.c @@ -617,6 +617,7 @@ long kvm_arch_vm_ioctl(struct file *filp, switch (ioctl) { case KVM_PPC_GET_PVINFO: { struct kvm_ppc_pvinfo pvinfo; + memset(&pvinfo, 0, sizeof(pvinfo)); r = kvm_vm_ioctl_get_pvinfo(&pvinfo); if (copy_to_user(argp, &pvinfo, sizeof(pvinfo))) { r = -EFAULT; diff --git a/arch/powerpc/kvm/timing.c b/arch/powerpc/kvm/timing.c index 46fa04f12a9b..a021f5827a33 100644 --- a/arch/powerpc/kvm/timing.c +++ b/arch/powerpc/kvm/timing.c @@ -35,7 +35,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) int i; /* pause guest execution to avoid concurrent updates */ - local_irq_disable(); mutex_lock(&vcpu->mutex); vcpu->arch.last_exit_type = 0xDEAD; @@ -51,7 +50,6 @@ void kvmppc_init_timing_stats(struct kvm_vcpu *vcpu) vcpu->arch.timing_last_enter.tv64 = 0; mutex_unlock(&vcpu->mutex); - local_irq_enable(); } static void add_exit_timing(struct kvm_vcpu *vcpu, u64 duration, int type) diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5c075f562eba..7f217b3a50a8 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -193,6 +193,7 @@ config CPU_SH2 config CPU_SH2A bool select CPU_SH2 + select UNCACHED_MAPPING config CPU_SH3 bool diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 307b3a4a790b..9c8c6e1a2a15 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -133,10 +133,7 @@ machdir-$(CONFIG_SOLUTION_ENGINE) += mach-se machdir-$(CONFIG_SH_HP6XX) += mach-hp6xx machdir-$(CONFIG_SH_DREAMCAST) += mach-dreamcast machdir-$(CONFIG_SH_SH03) += mach-sh03 -machdir-$(CONFIG_SH_SECUREEDGE5410) += mach-snapgear machdir-$(CONFIG_SH_RTS7751R2D) += mach-r2d -machdir-$(CONFIG_SH_7751_SYSTEMH) += mach-systemh -machdir-$(CONFIG_SH_EDOSK7705) += mach-edosk7705 machdir-$(CONFIG_SH_HIGHLANDER) += mach-highlander machdir-$(CONFIG_SH_MIGOR) += mach-migor machdir-$(CONFIG_SH_AP325RXA) += mach-ap325rxa diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 9c94711aa6ca..2018c7ea4c93 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig @@ -81,13 +81,6 @@ config SH_7343_SOLUTION_ENGINE Select 7343 SolutionEngine if configuring for a Hitachi SH7343 (SH-Mobile 3AS) evaluation board. -config SH_7751_SYSTEMH - bool "SystemH7751R" - depends on CPU_SUBTYPE_SH7751R - help - Select SystemH if you are configuring for a Renesas SystemH - 7751R evaluation board. - config SH_HP6XX bool "HP6XX" select SYS_SUPPORTS_APM_EMULATION diff --git a/arch/sh/boards/Makefile b/arch/sh/boards/Makefile index 38ef655cc0f0..be7d11d04b26 100644 --- a/arch/sh/boards/Makefile +++ b/arch/sh/boards/Makefile @@ -2,10 +2,12 @@ # Specific board support, not covered by a mach group. # obj-$(CONFIG_SH_MAGIC_PANEL_R2) += board-magicpanelr2.o +obj-$(CONFIG_SH_SECUREEDGE5410) += board-secureedge5410.o obj-$(CONFIG_SH_SH2007) += board-sh2007.o obj-$(CONFIG_SH_SH7785LCR) += board-sh7785lcr.o obj-$(CONFIG_SH_URQUELL) += board-urquell.o obj-$(CONFIG_SH_SHMIN) += board-shmin.o +obj-$(CONFIG_SH_EDOSK7705) += board-edosk7705.o obj-$(CONFIG_SH_EDOSK7760) += board-edosk7760.o obj-$(CONFIG_SH_ESPT) += board-espt.o obj-$(CONFIG_SH_POLARIS) += board-polaris.o diff --git a/arch/sh/boards/board-edosk7705.c b/arch/sh/boards/board-edosk7705.c new file mode 100644 index 000000000000..4cb3bb74c36f --- /dev/null +++ b/arch/sh/boards/board-edosk7705.c @@ -0,0 +1,78 @@ +/* + * arch/sh/boards/renesas/edosk7705/setup.c + * + * Copyright (C) 2000 Kazumoto Kojima + * + * Hitachi SolutionEngine Support. + * + * Modified for edosk7705 development + * board by S. Dunn, 2003. + */ +#include <linux/init.h> +#include <linux/irq.h> +#include <linux/platform_device.h> +#include <linux/interrupt.h> +#include <linux/smc91x.h> +#include <asm/machvec.h> +#include <asm/sizes.h> + +#define SMC_IOBASE 0xA2000000 +#define SMC_IO_OFFSET 0x300 +#define SMC_IOADDR (SMC_IOBASE + SMC_IO_OFFSET) + +#define ETHERNET_IRQ 0x09 + +static void __init sh_edosk7705_init_irq(void) +{ + make_imask_irq(ETHERNET_IRQ); +} + +/* eth initialization functions */ +static struct smc91x_platdata smc91x_info = { + .flags = SMC91X_USE_16BIT | SMC91X_IO_SHIFT_1 | IORESOURCE_IRQ_LOWLEVEL, +}; + +static struct resource smc91x_res[] = { + [0] = { + .start = SMC_IOADDR, + .end = SMC_IOADDR + SZ_32 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = ETHERNET_IRQ, + .end = ETHERNET_IRQ, + .flags = IORESOURCE_IRQ , + } +}; + +static struct platform_device smc91x_dev = { + .name = "smc91x", + .id = -1, + .num_resources = ARRAY_SIZE(smc91x_res), + .resource = smc91x_res, + + .dev = { + .platform_data = &smc91x_info, + }, +}; + +/* platform init code */ +static struct platform_device *edosk7705_devices[] __initdata = { + &smc91x_dev, +}; + +static int __init init_edosk7705_devices(void) +{ + return platform_add_devices(edosk7705_devices, + ARRAY_SIZE(edosk7705_devices)); +} +__initcall(init_edosk7705_devices); + +/* + * The Machine Vector + */ +static struct sh_machine_vector mv_edosk7705 __initmv = { + .mv_name = "EDOSK7705", + .mv_nr_irqs = 80, + .mv_init_irq = sh_edosk7705_init_irq, +}; diff --git a/arch/sh/boards/mach-snapgear/setup.c b/arch/sh/boards/board-secureedge5410.c index 331745dee379..32f875e8493d 100644 --- a/arch/sh/boards/mach-snapgear/setup.c +++ b/arch/sh/boards/board-secureedge5410.c @@ -1,6 +1,4 @@ /* - * linux/arch/sh/boards/snapgear/setup.c - * * Copyright (C) 2002 David McCullough <davidm@snapgear.com> * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> * @@ -19,18 +17,19 @@ #include <linux/module.h> #include <linux/sched.h> #include <asm/machvec.h> -#include <mach/snapgear.h> +#include <mach/secureedge5410.h> #include <asm/irq.h> #include <asm/io.h> #include <cpu/timer.h> +unsigned short secureedge5410_ioport; + /* * EraseConfig handling functions */ - static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) { - (void)__raw_readb(0xb8000000); /* dummy read */ + ctrl_delay(); /* dummy read */ printk("SnapGear: erase switch interrupt!\n"); @@ -39,21 +38,22 @@ static irqreturn_t eraseconfig_interrupt(int irq, void *dev_id) static int __init eraseconfig_init(void) { + unsigned int irq = evt2irq(0x240); + printk("SnapGear: EraseConfig init\n"); + /* Setup "EraseConfig" switch on external IRQ 0 */ - if (request_irq(IRL0_IRQ, eraseconfig_interrupt, IRQF_DISABLED, + if (request_irq(irq, eraseconfig_interrupt, IRQF_DISABLED, "Erase Config", NULL)) printk("SnapGear: failed to register IRQ%d for Reset witch\n", - IRL0_IRQ); + irq); else printk("SnapGear: registered EraseConfig switch on IRQ%d\n", - IRL0_IRQ); - return(0); + irq); + return 0; } - module_init(eraseconfig_init); -/****************************************************************************/ /* * Initialize IRQ setting * @@ -62,7 +62,6 @@ module_init(eraseconfig_init); * IRL2 = eth1 * IRL3 = crypto */ - static void __init init_snapgear_IRQ(void) { printk("Setup SnapGear IRQ/IPR ...\n"); @@ -76,20 +75,5 @@ static void __init init_snapgear_IRQ(void) static struct sh_machine_vector mv_snapgear __initmv = { .mv_name = "SnapGear SecureEdge5410", .mv_nr_irqs = 72, - - .mv_inb = snapgear_inb, - .mv_inw = snapgear_inw, - .mv_inl = snapgear_inl, - .mv_outb = snapgear_outb, - .mv_outw = snapgear_outw, - .mv_outl = snapgear_outl, - - .mv_inb_p = snapgear_inb_p, - .mv_inw_p = snapgear_inw, - .mv_inl_p = snapgear_inl, - .mv_outb_p = snapgear_outb_p, - .mv_outw_p = snapgear_outw, - .mv_outl_p = snapgear_outl, - .mv_init_irq = init_snapgear_IRQ, }; diff --git a/arch/sh/boards/mach-edosk7705/Makefile b/arch/sh/boards/mach-edosk7705/Makefile deleted file mode 100644 index cd54acb51499..000000000000 --- a/arch/sh/boards/mach-edosk7705/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the EDOSK7705 specific parts of the kernel -# - -obj-y := setup.o io.o diff --git a/arch/sh/boards/mach-edosk7705/io.c b/arch/sh/boards/mach-edosk7705/io.c deleted file mode 100644 index 5b9c57c43241..000000000000 --- a/arch/sh/boards/mach-edosk7705/io.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * arch/sh/boards/renesas/edosk7705/io.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routines for Hitachi EDOSK7705 board. - * - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/io.h> -#include <mach/edosk7705.h> -#include <asm/addrspace.h> - -#define SMC_IOADDR 0xA2000000 - -/* Map the Ethernet addresses as if it is at 0x300 - 0x320 */ -static unsigned long sh_edosk7705_isa_port2addr(unsigned long port) -{ - /* - * SMC91C96 registers are 4 byte aligned rather than the - * usual 2 byte! - */ - if (port >= 0x300 && port < 0x320) - return SMC_IOADDR + ((port - 0x300) * 2); - - maybebadio(port); - return port; -} - -/* Trying to read / write bytes on odd-byte boundaries to the Ethernet - * registers causes problems. So we bit-shift the value and read / write - * in 2 byte chunks. Setting the low byte to 0 does not cause problems - * now as odd byte writes are only made on the bit mask / interrupt - * register. This may not be the case in future Mar-2003 SJD - */ -unsigned char sh_edosk7705_inb(unsigned long port) -{ - if (port >= 0x300 && port < 0x320 && port & 0x01) - return __raw_readw(port - 1) >> 8; - - return __raw_readb(sh_edosk7705_isa_port2addr(port)); -} - -void sh_edosk7705_outb(unsigned char value, unsigned long port) -{ - if (port >= 0x300 && port < 0x320 && port & 0x01) { - __raw_writew(((unsigned short)value << 8), port - 1); - return; - } - - __raw_writeb(value, sh_edosk7705_isa_port2addr(port)); -} - -void sh_edosk7705_insb(unsigned long port, void *addr, unsigned long count) -{ - unsigned char *p = addr; - - while (count--) - *p++ = sh_edosk7705_inb(port); -} - -void sh_edosk7705_outsb(unsigned long port, const void *addr, unsigned long count) -{ - unsigned char *p = (unsigned char *)addr; - - while (count--) - sh_edosk7705_outb(*p++, port); -} diff --git a/arch/sh/boards/mach-edosk7705/setup.c b/arch/sh/boards/mach-edosk7705/setup.c deleted file mode 100644 index d59225e26fb9..000000000000 --- a/arch/sh/boards/mach-edosk7705/setup.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/sh/boards/renesas/edosk7705/setup.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Hitachi SolutionEngine Support. - * - * Modified for edosk7705 development - * board by S. Dunn, 2003. - */ -#include <linux/init.h> -#include <linux/irq.h> -#include <asm/machvec.h> -#include <mach/edosk7705.h> - -static void __init sh_edosk7705_init_irq(void) -{ - /* This is the Ethernet interrupt */ - make_imask_irq(0x09); -} - -/* - * The Machine Vector - */ -static struct sh_machine_vector mv_edosk7705 __initmv = { - .mv_name = "EDOSK7705", - .mv_nr_irqs = 80, - - .mv_inb = sh_edosk7705_inb, - .mv_outb = sh_edosk7705_outb, - - .mv_insb = sh_edosk7705_insb, - .mv_outsb = sh_edosk7705_outsb, - - .mv_init_irq = sh_edosk7705_init_irq, -}; diff --git a/arch/sh/boards/mach-microdev/io.c b/arch/sh/boards/mach-microdev/io.c index 2960c659020e..acdafb0c6404 100644 --- a/arch/sh/boards/mach-microdev/io.c +++ b/arch/sh/boards/mach-microdev/io.c @@ -54,7 +54,7 @@ /* * map I/O ports to memory-mapped addresses */ -static unsigned long microdev_isa_port2addr(unsigned long offset) +void __iomem *microdev_ioport_map(unsigned long offset, unsigned int len) { unsigned long result; @@ -72,16 +72,6 @@ static unsigned long microdev_isa_port2addr(unsigned long offset) * Configuration Registers */ result = IO_SUPERIO_PHYS + (offset << 1); -#if 0 - } else if (offset == KBD_DATA_REG || offset == KBD_CNTL_REG || - offset == KBD_STATUS_REG) { - /* - * SMSC FDC37C93xAPM SuperIO chip - * - * PS/2 Keyboard + Mouse (ports 0x60 and 0x64). - */ - result = IO_SUPERIO_PHYS + (offset << 1); -#endif } else if (((offset >= IO_IDE1_BASE) && (offset < IO_IDE1_BASE + IO_IDE_EXTENT)) || (offset == IO_IDE1_MISC)) { @@ -131,237 +121,5 @@ static unsigned long microdev_isa_port2addr(unsigned long offset) result = PVR; } - return result; -} - -#define PORT2ADDR(x) (microdev_isa_port2addr(x)) - -static inline void delay(void) -{ -#if defined(CONFIG_PCI) - /* System board present, just make a dummy SRAM access. (CS0 will be - mapped to PCI memory, probably good to avoid it.) */ - __raw_readw(0xa6800000); -#else - /* CS0 will be mapped to flash, ROM etc so safe to access it. */ - __raw_readw(0xa0000000); -#endif -} - -unsigned char microdev_inb(unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) - return microdev_pci_inb(port); -#endif - return *(volatile unsigned char*)PORT2ADDR(port); -} - -unsigned short microdev_inw(unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) - return microdev_pci_inw(port); -#endif - return *(volatile unsigned short*)PORT2ADDR(port); -} - -unsigned int microdev_inl(unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) - return microdev_pci_inl(port); -#endif - return *(volatile unsigned int*)PORT2ADDR(port); -} - -void microdev_outw(unsigned short b, unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) { - microdev_pci_outw(b, port); - return; - } -#endif - *(volatile unsigned short*)PORT2ADDR(port) = b; -} - -void microdev_outb(unsigned char b, unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) { - microdev_pci_outb(b, port); - return; - } -#endif - - /* - * There is a board feature with the current SH4-202 MicroDev in - * that the 2 byte enables (nBE0 and nBE1) are tied together (and - * to the Chip Select Line (Ethernet_CS)). Due to this connectivity, - * it is not possible to safely perform 8-bit writes to the - * Ethernet registers, as 16-bits will be consumed from the Data - * lines (corrupting the other byte). Hence, this function is - * written to implement 16-bit read/modify/write for all byte-wide - * accesses. - * - * Note: there is no problem with byte READS (even or odd). - * - * Sean McGoogan - 16th June 2003. - */ - if ((port >= IO_LAN91C111_BASE) && - (port < IO_LAN91C111_BASE + IO_LAN91C111_EXTENT)) { - /* - * Then are trying to perform a byte-write to the - * LAN91C111. This needs special care. - */ - if (port % 2 == 1) { /* is the port odd ? */ - /* unset bit-0, i.e. make even */ - const unsigned long evenPort = port-1; - unsigned short word; - - /* - * do a 16-bit read/write to write to 'port', - * preserving even byte. - * - * Even addresses are bits 0-7 - * Odd addresses are bits 8-15 - */ - word = microdev_inw(evenPort); - word = (word & 0xffu) | (b << 8); - microdev_outw(word, evenPort); - } else { - /* else, we are trying to do an even byte write */ - unsigned short word; - - /* - * do a 16-bit read/write to write to 'port', - * preserving odd byte. - * - * Even addresses are bits 0-7 - * Odd addresses are bits 8-15 - */ - word = microdev_inw(port); - word = (word & 0xff00u) | (b); - microdev_outw(word, port); - } - } else { - *(volatile unsigned char*)PORT2ADDR(port) = b; - } -} - -void microdev_outl(unsigned int b, unsigned long port) -{ -#ifdef CONFIG_PCI - if (port >= PCIBIOS_MIN_IO) { - microdev_pci_outl(b, port); - return; - } -#endif - *(volatile unsigned int*)PORT2ADDR(port) = b; -} - -unsigned char microdev_inb_p(unsigned long port) -{ - unsigned char v = microdev_inb(port); - delay(); - return v; -} - -unsigned short microdev_inw_p(unsigned long port) -{ - unsigned short v = microdev_inw(port); - delay(); - return v; -} - -unsigned int microdev_inl_p(unsigned long port) -{ - unsigned int v = microdev_inl(port); - delay(); - return v; -} - -void microdev_outb_p(unsigned char b, unsigned long port) -{ - microdev_outb(b, port); - delay(); -} - -void microdev_outw_p(unsigned short b, unsigned long port) -{ - microdev_outw(b, port); - delay(); -} - -void microdev_outl_p(unsigned int b, unsigned long port) -{ - microdev_outl(b, port); - delay(); -} - -void microdev_insb(unsigned long port, void *buffer, unsigned long count) -{ - volatile unsigned char *port_addr; - unsigned char *buf = buffer; - - port_addr = (volatile unsigned char *)PORT2ADDR(port); - - while (count--) - *buf++ = *port_addr; -} - -void microdev_insw(unsigned long port, void *buffer, unsigned long count) -{ - volatile unsigned short *port_addr; - unsigned short *buf = buffer; - - port_addr = (volatile unsigned short *)PORT2ADDR(port); - - while (count--) - *buf++ = *port_addr; -} - -void microdev_insl(unsigned long port, void *buffer, unsigned long count) -{ - volatile unsigned long *port_addr; - unsigned int *buf = buffer; - - port_addr = (volatile unsigned long *)PORT2ADDR(port); - - while (count--) - *buf++ = *port_addr; -} - -void microdev_outsb(unsigned long port, const void *buffer, unsigned long count) -{ - volatile unsigned char *port_addr; - const unsigned char *buf = buffer; - - port_addr = (volatile unsigned char *)PORT2ADDR(port); - - while (count--) - *port_addr = *buf++; -} - -void microdev_outsw(unsigned long port, const void *buffer, unsigned long count) -{ - volatile unsigned short *port_addr; - const unsigned short *buf = buffer; - - port_addr = (volatile unsigned short *)PORT2ADDR(port); - - while (count--) - *port_addr = *buf++; -} - -void microdev_outsl(unsigned long port, const void *buffer, unsigned long count) -{ - volatile unsigned long *port_addr; - const unsigned int *buf = buffer; - - port_addr = (volatile unsigned long *)PORT2ADDR(port); - - while (count--) - *port_addr = *buf++; + return (void __iomem *)result; } diff --git a/arch/sh/boards/mach-microdev/setup.c b/arch/sh/boards/mach-microdev/setup.c index d1df2a4fb9b8..d8a747291e03 100644 --- a/arch/sh/boards/mach-microdev/setup.c +++ b/arch/sh/boards/mach-microdev/setup.c @@ -195,27 +195,6 @@ device_initcall(microdev_devices_setup); static struct sh_machine_vector mv_sh4202_microdev __initmv = { .mv_name = "SH4-202 MicroDev", .mv_nr_irqs = 72, - - .mv_inb = microdev_inb, - .mv_inw = microdev_inw, - .mv_inl = microdev_inl, - .mv_outb = microdev_outb, - .mv_outw = microdev_outw, - .mv_outl = microdev_outl, - - .mv_inb_p = microdev_inb_p, - .mv_inw_p = microdev_inw_p, - .mv_inl_p = microdev_inl_p, - .mv_outb_p = microdev_outb_p, - .mv_outw_p = microdev_outw_p, - .mv_outl_p = microdev_outl_p, - - .mv_insb = microdev_insb, - .mv_insw = microdev_insw, - .mv_insl = microdev_insl, - .mv_outsb = microdev_outsb, - .mv_outsw = microdev_outsw, - .mv_outsl = microdev_outsl, - + .mv_ioport_map = microdev_ioport_map, .mv_init_irq = init_microdev_irq, }; diff --git a/arch/sh/boards/mach-se/7206/Makefile b/arch/sh/boards/mach-se/7206/Makefile index 63e7ed699f39..5c9eaa0535b9 100644 --- a/arch/sh/boards/mach-se/7206/Makefile +++ b/arch/sh/boards/mach-se/7206/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7206 SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o irq.o +obj-y := setup.o irq.o diff --git a/arch/sh/boards/mach-se/7206/io.c b/arch/sh/boards/mach-se/7206/io.c deleted file mode 100644 index adadc77532ee..000000000000 --- a/arch/sh/boards/mach-se/7206/io.c +++ /dev/null @@ -1,104 +0,0 @@ -/* $Id: io.c,v 1.5 2004/02/22 23:08:43 kkojima Exp $ - * - * linux/arch/sh/boards/se/7206/io.c - * - * Copyright (C) 2006 Yoshinori Sato - * - * I/O routine for Hitachi 7206 SolutionEngine. - * - */ - -#include <linux/kernel.h> -#include <linux/types.h> -#include <asm/io.h> -#include <mach-se/mach/se7206.h> - - -static inline void delay(void) -{ - __raw_readw(0x20000000); /* P2 ROM Area */ -} - -/* MS7750 requires special versions of in*, out* routines, since - PC-like io ports are located at upper half byte of 16-bit word which - can be accessed only with 16-bit wide. */ - -static inline volatile __u16 * -port2adr(unsigned int port) -{ - if (port >= 0x2000 && port < 0x2020) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - else if (port >= 0x300 && port < 0x310) - return (volatile __u16 *) (PA_SMSC + (port - 0x300)); - - return (volatile __u16 *)port; -} - -unsigned char se7206_inb(unsigned long port) -{ - return (*port2adr(port)) & 0xff; -} - -unsigned char se7206_inb_p(unsigned long port) -{ - unsigned long v; - - v = (*port2adr(port)) & 0xff; - delay(); - return v; -} - -unsigned short se7206_inw(unsigned long port) -{ - return *port2adr(port); -} - -void se7206_outb(unsigned char value, unsigned long port) -{ - *(port2adr(port)) = value; -} - -void se7206_outb_p(unsigned char value, unsigned long port) -{ - *(port2adr(port)) = value; - delay(); -} - -void se7206_outw(unsigned short value, unsigned long port) -{ - *port2adr(port) = value; -} - -void se7206_insb(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u8 *ap = addr; - - while (count--) - *ap++ = *p; -} - -void se7206_insw(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u16 *ap = addr; - while (count--) - *ap++ = *p; -} - -void se7206_outsb(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u8 *ap = addr; - - while (count--) - *p = *ap++; -} - -void se7206_outsw(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u16 *ap = addr; - while (count--) - *p = *ap++; -} diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index 883b21eacaa6..d961949600fd 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c @@ -139,11 +139,13 @@ void __init init_se7206_IRQ(void) make_se7206_irq(IRQ0_IRQ); /* SMC91C111 */ make_se7206_irq(IRQ1_IRQ); /* ATA */ make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ - __raw_writew(inw(INTC_ICR1) | 0x000b ,INTC_ICR1 ) ; /* ICR1 */ + + __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ /* FPGA System register setup*/ __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ __raw_writew(0x0000,INTSTS1); /* Clear INTSTS1 */ + /* IRQ0=LAN, IRQ1=ATA, IRQ3=SLT,PCM */ __raw_writew(0x0001,INTSEL); } diff --git a/arch/sh/boards/mach-se/7206/setup.c b/arch/sh/boards/mach-se/7206/setup.c index 8f5c65d43d1d..7f4871c71a01 100644 --- a/arch/sh/boards/mach-se/7206/setup.c +++ b/arch/sh/boards/mach-se/7206/setup.c @@ -86,20 +86,5 @@ __initcall(se7206_devices_setup); static struct sh_machine_vector mv_se __initmv = { .mv_name = "SolutionEngine", .mv_nr_irqs = 256, - .mv_inb = se7206_inb, - .mv_inw = se7206_inw, - .mv_outb = se7206_outb, - .mv_outw = se7206_outw, - - .mv_inb_p = se7206_inb_p, - .mv_inw_p = se7206_inw, - .mv_outb_p = se7206_outb_p, - .mv_outw_p = se7206_outw, - - .mv_insb = se7206_insb, - .mv_insw = se7206_insw, - .mv_outsb = se7206_outsb, - .mv_outsw = se7206_outsw, - .mv_init_irq = init_se7206_IRQ, }; diff --git a/arch/sh/boards/mach-se/770x/Makefile b/arch/sh/boards/mach-se/770x/Makefile index 8e624b06d5ea..43ea14feef51 100644 --- a/arch/sh/boards/mach-se/770x/Makefile +++ b/arch/sh/boards/mach-se/770x/Makefile @@ -2,4 +2,4 @@ # Makefile for the 770x SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o irq.o +obj-y := setup.o irq.o diff --git a/arch/sh/boards/mach-se/770x/io.c b/arch/sh/boards/mach-se/770x/io.c deleted file mode 100644 index 28833c8786ea..000000000000 --- a/arch/sh/boards/mach-se/770x/io.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2000 Kazumoto Kojima - * - * I/O routine for Hitachi SolutionEngine. - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <asm/io.h> -#include <mach-se/mach/se.h> - -/* MS7750 requires special versions of in*, out* routines, since - PC-like io ports are located at upper half byte of 16-bit word which - can be accessed only with 16-bit wide. */ - -static inline volatile __u16 * -port2adr(unsigned int port) -{ - if (port & 0xff000000) - return ( volatile __u16 *) port; - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - else if (port >= 0x1000) - return (volatile __u16 *) (PA_83902 + (port << 1)); - else - return (volatile __u16 *) (PA_SUPERIO + (port << 1)); -} - -static inline int -shifted_port(unsigned long port) -{ - /* For IDE registers, value is not shifted */ - if ((0x1f0 <= port && port < 0x1f8) || port == 0x3f6) - return 0; - else - return 1; -} - -unsigned char se_inb(unsigned long port) -{ - if (shifted_port(port)) - return (*port2adr(port) >> 8); - else - return (*port2adr(port))&0xff; -} - -unsigned char se_inb_p(unsigned long port) -{ - unsigned long v; - - if (shifted_port(port)) - v = (*port2adr(port) >> 8); - else - v = (*port2adr(port))&0xff; - ctrl_delay(); - return v; -} - -unsigned short se_inw(unsigned long port) -{ - if (port >= 0x2000) - return *port2adr(port); - else - maybebadio(port); - return 0; -} - -unsigned int se_inl(unsigned long port) -{ - maybebadio(port); - return 0; -} - -void se_outb(unsigned char value, unsigned long port) -{ - if (shifted_port(port)) - *(port2adr(port)) = value << 8; - else - *(port2adr(port)) = value; -} - -void se_outb_p(unsigned char value, unsigned long port) -{ - if (shifted_port(port)) - *(port2adr(port)) = value << 8; - else - *(port2adr(port)) = value; - ctrl_delay(); -} - -void se_outw(unsigned short value, unsigned long port) -{ - if (port >= 0x2000) - *port2adr(port) = value; - else - maybebadio(port); -} - -void se_outl(unsigned int value, unsigned long port) -{ - maybebadio(port); -} - -void se_insb(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u8 *ap = addr; - - if (shifted_port(port)) { - while (count--) - *ap++ = *p >> 8; - } else { - while (count--) - *ap++ = *p; - } -} - -void se_insw(unsigned long port, void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - __u16 *ap = addr; - while (count--) - *ap++ = *p; -} - -void se_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - -void se_outsb(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u8 *ap = addr; - - if (shifted_port(port)) { - while (count--) - *p = *ap++ << 8; - } else { - while (count--) - *p = *ap++; - } -} - -void se_outsw(unsigned long port, const void *addr, unsigned long count) -{ - volatile __u16 *p = port2adr(port); - const __u16 *ap = addr; - - while (count--) - *p = *ap++; -} - -void se_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/arch/sh/boards/mach-se/770x/setup.c b/arch/sh/boards/mach-se/770x/setup.c index 66d39d1b0901..31330c65c0ce 100644 --- a/arch/sh/boards/mach-se/770x/setup.c +++ b/arch/sh/boards/mach-se/770x/setup.c @@ -195,27 +195,5 @@ static struct sh_machine_vector mv_se __initmv = { #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) .mv_nr_irqs = 104, #endif - - .mv_inb = se_inb, - .mv_inw = se_inw, - .mv_inl = se_inl, - .mv_outb = se_outb, - .mv_outw = se_outw, - .mv_outl = se_outl, - - .mv_inb_p = se_inb_p, - .mv_inw_p = se_inw, - .mv_inl_p = se_inl, - .mv_outb_p = se_outb_p, - .mv_outw_p = se_outw, - .mv_outl_p = se_outl, - - .mv_insb = se_insb, - .mv_insw = se_insw, - .mv_insl = se_insl, - .mv_outsb = se_outsb, - .mv_outsw = se_outsw, - .mv_outsl = se_outsl, - .mv_init_irq = init_se_IRQ, }; diff --git a/arch/sh/boards/mach-se/7751/Makefile b/arch/sh/boards/mach-se/7751/Makefile index e6f4341bfe6e..a338fd9d5039 100644 --- a/arch/sh/boards/mach-se/7751/Makefile +++ b/arch/sh/boards/mach-se/7751/Makefile @@ -2,4 +2,4 @@ # Makefile for the 7751 SolutionEngine specific parts of the kernel # -obj-y := setup.o io.o irq.o +obj-y := setup.o irq.o diff --git a/arch/sh/boards/mach-se/7751/io.c b/arch/sh/boards/mach-se/7751/io.c deleted file mode 100644 index 6e75bd4459e5..000000000000 --- a/arch/sh/boards/mach-se/7751/io.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for Hitachi 7751 SolutionEngine. - * - * Initial version only to support LAN access; some - * placeholder code from io_se.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <mach-se/mach/se7751.h> -#include <asm/addrspace.h> - -static inline volatile u16 *port2adr(unsigned int port) -{ - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - maybebadio((unsigned long)port); - return (volatile __u16*)port; -} - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -unsigned char sh7751se_inb(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned char *)port; - else - return (*port2adr(port)) & 0xff; -} - -unsigned char sh7751se_inb_p(unsigned long port) -{ - unsigned char v; - - if (PXSEG(port)) - v = *(volatile unsigned char *)port; - else - v = (*port2adr(port)) & 0xff; - ctrl_delay(); - return v; -} - -unsigned short sh7751se_inw(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (port >= 0x2000) - return *port2adr(port); - else - maybebadio(port); - return 0; -} - -unsigned int sh7751se_inl(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (port >= 0x2000) - return *port2adr(port); - else - maybebadio(port); - return 0; -} - -void sh7751se_outb(unsigned char value, unsigned long port) -{ - - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else - *(port2adr(port)) = value; -} - -void sh7751se_outb_p(unsigned char value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else - *(port2adr(port)) = value; - ctrl_delay(); -} - -void sh7751se_outw(unsigned short value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (port >= 0x2000) - *port2adr(port) = value; - else - maybebadio(port); -} - -void sh7751se_outl(unsigned int value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else - maybebadio(port); -} - -void sh7751se_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - -void sh7751se_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/arch/sh/boards/mach-se/7751/setup.c b/arch/sh/boards/mach-se/7751/setup.c index 50572512e3e8..9fbc51beb181 100644 --- a/arch/sh/boards/mach-se/7751/setup.c +++ b/arch/sh/boards/mach-se/7751/setup.c @@ -56,23 +56,5 @@ __initcall(se7751_devices_setup); static struct sh_machine_vector mv_7751se __initmv = { .mv_name = "7751 SolutionEngine", .mv_nr_irqs = 72, - - .mv_inb = sh7751se_inb, - .mv_inw = sh7751se_inw, - .mv_inl = sh7751se_inl, - .mv_outb = sh7751se_outb, - .mv_outw = sh7751se_outw, - .mv_outl = sh7751se_outl, - - .mv_inb_p = sh7751se_inb_p, - .mv_inw_p = sh7751se_inw, - .mv_inl_p = sh7751se_inl, - .mv_outb_p = sh7751se_outb_p, - .mv_outw_p = sh7751se_outw, - .mv_outl_p = sh7751se_outl, - - .mv_insl = sh7751se_insl, - .mv_outsl = sh7751se_outsl, - .mv_init_irq = init_7751se_IRQ, }; diff --git a/arch/sh/boards/mach-snapgear/Makefile b/arch/sh/boards/mach-snapgear/Makefile deleted file mode 100644 index d2d2f4b6a502..000000000000 --- a/arch/sh/boards/mach-snapgear/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -# -# Makefile for the SnapGear specific parts of the kernel -# - -obj-y := setup.o io.o diff --git a/arch/sh/boards/mach-snapgear/io.c b/arch/sh/boards/mach-snapgear/io.c deleted file mode 100644 index 476650e42dbc..000000000000 --- a/arch/sh/boards/mach-snapgear/io.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2002 David McCullough <davidm@snapgear.com> - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for Hitachi 7751 SolutionEngine. - * - * Initial version only to support LAN access; some - * placeholder code from io_se.c left in with the - * expectation of later SuperIO and PCMCIA access. - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <asm/io.h> -#include <asm/addrspace.h> - -#ifdef CONFIG_SH_SECUREEDGE5410 -unsigned short secureedge5410_ioport; -#endif - -static inline volatile __u16 *port2adr(unsigned int port) -{ - maybebadio((unsigned long)port); - return (volatile __u16*)port; -} - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -unsigned char snapgear_inb(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned char *)port; - else - return (*port2adr(port)) & 0xff; -} - -unsigned char snapgear_inb_p(unsigned long port) -{ - unsigned char v; - - if (PXSEG(port)) - v = *(volatile unsigned char *)port; - else - v = (*port2adr(port))&0xff; - ctrl_delay(); - return v; -} - -unsigned short snapgear_inw(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (port >= 0x2000) - return *port2adr(port); - else - maybebadio(port); - return 0; -} - -unsigned int snapgear_inl(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (port >= 0x2000) - return *port2adr(port); - else - maybebadio(port); - return 0; -} - -void snapgear_outb(unsigned char value, unsigned long port) -{ - - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else - *(port2adr(port)) = value; -} - -void snapgear_outb_p(unsigned char value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else - *(port2adr(port)) = value; - ctrl_delay(); -} - -void snapgear_outw(unsigned short value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (port >= 0x2000) - *port2adr(port) = value; - else - maybebadio(port); -} - -void snapgear_outl(unsigned int value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else - maybebadio(port); -} - -void snapgear_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - -void snapgear_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/arch/sh/boards/mach-systemh/Makefile b/arch/sh/boards/mach-systemh/Makefile deleted file mode 100644 index 2cc6a23d9d39..000000000000 --- a/arch/sh/boards/mach-systemh/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -# -# Makefile for the SystemH specific parts of the kernel -# - -obj-y := setup.o irq.o io.o - -# XXX: This wants to be consolidated in arch/sh/drivers/pci, and more -# importantly, with the generic sh7751_pcic_init() code. For now, we'll -# just abuse the hell out of kbuild, because we can.. - -obj-$(CONFIG_PCI) += pci.o -pci-y := ../../se/7751/pci.o - diff --git a/arch/sh/boards/mach-systemh/io.c b/arch/sh/boards/mach-systemh/io.c deleted file mode 100644 index 15577ff1f715..000000000000 --- a/arch/sh/boards/mach-systemh/io.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * linux/arch/sh/boards/renesas/systemh/io.c - * - * Copyright (C) 2001 Ian da Silva, Jeremy Siegel - * Based largely on io_se.c. - * - * I/O routine for Hitachi 7751 Systemh. - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/pci.h> -#include <mach/systemh7751.h> -#include <asm/addrspace.h> -#include <asm/io.h> - -#define ETHER_IOMAP(adr) (0xB3000000 + (adr)) /*map to 16bits access area - of smc lan chip*/ -static inline volatile __u16 * -port2adr(unsigned int port) -{ - if (port >= 0x2000) - return (volatile __u16 *) (PA_MRSHPC + (port - 0x2000)); - maybebadio((unsigned long)port); - return (volatile __u16*)port; -} - -/* - * General outline: remap really low stuff [eventually] to SuperIO, - * stuff in PCI IO space (at or above window at pci.h:PCIBIOS_MIN_IO) - * is mapped through the PCI IO window. Stuff with high bits (PXSEG) - * should be way beyond the window, and is used w/o translation for - * compatibility. - */ -unsigned char sh7751systemh_inb(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned char *)port; - else if (port <= 0x3F1) - return *(volatile unsigned char *)ETHER_IOMAP(port); - else - return (*port2adr(port))&0xff; -} - -unsigned char sh7751systemh_inb_p(unsigned long port) -{ - unsigned char v; - - if (PXSEG(port)) - v = *(volatile unsigned char *)port; - else if (port <= 0x3F1) - v = *(volatile unsigned char *)ETHER_IOMAP(port); - else - v = (*port2adr(port))&0xff; - ctrl_delay(); - return v; -} - -unsigned short sh7751systemh_inw(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned short *)port; - else if (port >= 0x2000) - return *port2adr(port); - else if (port <= 0x3F1) - return *(volatile unsigned int *)ETHER_IOMAP(port); - else - maybebadio(port); - return 0; -} - -unsigned int sh7751systemh_inl(unsigned long port) -{ - if (PXSEG(port)) - return *(volatile unsigned long *)port; - else if (port >= 0x2000) - return *port2adr(port); - else if (port <= 0x3F1) - return *(volatile unsigned int *)ETHER_IOMAP(port); - else - maybebadio(port); - return 0; -} - -void sh7751systemh_outb(unsigned char value, unsigned long port) -{ - - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else if (port <= 0x3F1) - *(volatile unsigned char *)ETHER_IOMAP(port) = value; - else - *(port2adr(port)) = value; -} - -void sh7751systemh_outb_p(unsigned char value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned char *)port = value; - else if (port <= 0x3F1) - *(volatile unsigned char *)ETHER_IOMAP(port) = value; - else - *(port2adr(port)) = value; - ctrl_delay(); -} - -void sh7751systemh_outw(unsigned short value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned short *)port = value; - else if (port >= 0x2000) - *port2adr(port) = value; - else if (port <= 0x3F1) - *(volatile unsigned short *)ETHER_IOMAP(port) = value; - else - maybebadio(port); -} - -void sh7751systemh_outl(unsigned int value, unsigned long port) -{ - if (PXSEG(port)) - *(volatile unsigned long *)port = value; - else - maybebadio(port); -} - -void sh7751systemh_insb(unsigned long port, void *addr, unsigned long count) -{ - unsigned char *p = addr; - while (count--) *p++ = sh7751systemh_inb(port); -} - -void sh7751systemh_insw(unsigned long port, void *addr, unsigned long count) -{ - unsigned short *p = addr; - while (count--) *p++ = sh7751systemh_inw(port); -} - -void sh7751systemh_insl(unsigned long port, void *addr, unsigned long count) -{ - maybebadio(port); -} - -void sh7751systemh_outsb(unsigned long port, const void *addr, unsigned long count) -{ - unsigned char *p = (unsigned char*)addr; - while (count--) sh7751systemh_outb(*p++, port); -} - -void sh7751systemh_outsw(unsigned long port, const void *addr, unsigned long count) -{ - unsigned short *p = (unsigned short*)addr; - while (count--) sh7751systemh_outw(*p++, port); -} - -void sh7751systemh_outsl(unsigned long port, const void *addr, unsigned long count) -{ - maybebadio(port); -} diff --git a/arch/sh/boards/mach-systemh/irq.c b/arch/sh/boards/mach-systemh/irq.c deleted file mode 100644 index e5ee13adeff4..000000000000 --- a/arch/sh/boards/mach-systemh/irq.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * linux/arch/sh/boards/renesas/systemh/irq.c - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Hitachi SystemH Support. - * - * Modified for 7751 SystemH by - * Jonathan Short. - */ - -#include <linux/init.h> -#include <linux/irq.h> -#include <linux/interrupt.h> -#include <linux/io.h> - -#include <mach/systemh7751.h> -#include <asm/smc37c93x.h> - -/* address of external interrupt mask register - * address must be set prior to use these (maybe in init_XXX_irq()) - * XXX : is it better to use .config than specifying it in code? */ -static unsigned long *systemh_irq_mask_register = (unsigned long *)0xB3F10004; -static unsigned long *systemh_irq_request_register = (unsigned long *)0xB3F10000; - -static void disable_systemh_irq(struct irq_data *data) -{ - unsigned long val, mask = 0x01 << 1; - - /* Clear the "irq"th bit in the mask and set it in the request */ - val = __raw_readl((unsigned long)systemh_irq_mask_register); - val &= ~mask; - __raw_writel(val, (unsigned long)systemh_irq_mask_register); - - val = __raw_readl((unsigned long)systemh_irq_request_register); - val |= mask; - __raw_writel(val, (unsigned long)systemh_irq_request_register); -} - -static void enable_systemh_irq(struct irq_data *data) -{ - unsigned long val, mask = 0x01 << 1; - - /* Set "irq"th bit in the mask register */ - val = __raw_readl((unsigned long)systemh_irq_mask_register); - val |= mask; - __raw_writel(val, (unsigned long)systemh_irq_mask_register); -} - -static struct irq_chip systemh_irq_type = { - .name = "SystemH Register", - .irq_unmask = enable_systemh_irq, - .irq_mask = disable_systemh_irq, -}; - -void make_systemh_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - set_irq_chip_and_handler(irq, &systemh_irq_type, handle_level_irq); - disable_systemh_irq(irq_get_irq_data(irq)); -} diff --git a/arch/sh/boards/mach-systemh/setup.c b/arch/sh/boards/mach-systemh/setup.c deleted file mode 100644 index 219fd800a43f..000000000000 --- a/arch/sh/boards/mach-systemh/setup.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * linux/arch/sh/boards/renesas/systemh/setup.c - * - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2003 Paul Mundt - * - * Hitachi SystemH Support. - * - * Modified for 7751 SystemH by Jonathan Short. - * - * Rewritten for 2.6 by Paul Mundt. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/init.h> -#include <asm/machvec.h> -#include <mach/systemh7751.h> - -extern void make_systemh_irq(unsigned int irq); - -/* - * Initialize IRQ setting - */ -static void __init sh7751systemh_init_irq(void) -{ - make_systemh_irq(0xb); /* Ethernet interrupt */ -} - -static struct sh_machine_vector mv_7751systemh __initmv = { - .mv_name = "7751 SystemH", - .mv_nr_irqs = 72, - - .mv_inb = sh7751systemh_inb, - .mv_inw = sh7751systemh_inw, - .mv_inl = sh7751systemh_inl, - .mv_outb = sh7751systemh_outb, - .mv_outw = sh7751systemh_outw, - .mv_outl = sh7751systemh_outl, - - .mv_inb_p = sh7751systemh_inb_p, - .mv_inw_p = sh7751systemh_inw, - .mv_inl_p = sh7751systemh_inl, - .mv_outb_p = sh7751systemh_outb_p, - .mv_outw_p = sh7751systemh_outw, - .mv_outl_p = sh7751systemh_outl, - - .mv_insb = sh7751systemh_insb, - .mv_insw = sh7751systemh_insw, - .mv_insl = sh7751systemh_insl, - .mv_outsb = sh7751systemh_outsb, - .mv_outsw = sh7751systemh_outsw, - .mv_outsl = sh7751systemh_outsl, - - .mv_init_irq = sh7751systemh_init_irq, -}; diff --git a/arch/sh/configs/snapgear_defconfig b/arch/sh/configs/secureedge5410_defconfig index 7eae4e59d7f0..7eae4e59d7f0 100644 --- a/arch/sh/configs/snapgear_defconfig +++ b/arch/sh/configs/secureedge5410_defconfig diff --git a/arch/sh/configs/systemh_defconfig b/arch/sh/configs/systemh_defconfig deleted file mode 100644 index b58dfc505efe..000000000000 --- a/arch/sh/configs/systemh_defconfig +++ /dev/null @@ -1,28 +0,0 @@ -CONFIG_EXPERIMENTAL=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set -# CONFIG_SYSCTL_SYSCALL is not set -# CONFIG_HOTPLUG is not set -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -CONFIG_CPU_SUBTYPE_SH7751R=y -CONFIG_MEMORY_START=0x0c000000 -CONFIG_MEMORY_SIZE=0x00400000 -CONFIG_FLATMEM_MANUAL=y -CONFIG_SH_7751_SYSTEMH=y -CONFIG_PREEMPT=y -# CONFIG_STANDALONE is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=1024 -# CONFIG_INPUT is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_VT is not set -CONFIG_HW_RANDOM=y -CONFIG_PROC_KCORE=y -CONFIG_TMPFS=y -CONFIG_CRAMFS=y -CONFIG_ROMFS_FS=y -# CONFIG_RCU_CPU_STALL_DETECTOR is not set diff --git a/arch/sh/include/asm/addrspace.h b/arch/sh/include/asm/addrspace.h index 446b3831c214..3d1ae2bfaa6f 100644 --- a/arch/sh/include/asm/addrspace.h +++ b/arch/sh/include/asm/addrspace.h @@ -44,10 +44,10 @@ /* * These will never work in 32-bit, don't even bother. */ -#define P1SEGADDR(a) __futile_remapping_attempt -#define P2SEGADDR(a) __futile_remapping_attempt -#define P3SEGADDR(a) __futile_remapping_attempt -#define P4SEGADDR(a) __futile_remapping_attempt +#define P1SEGADDR(a) ({ (void)(a); BUG(); NULL; }) +#define P2SEGADDR(a) ({ (void)(a); BUG(); NULL; }) +#define P3SEGADDR(a) ({ (void)(a); BUG(); NULL; }) +#define P4SEGADDR(a) ({ (void)(a); BUG(); NULL; }) #endif #endif /* P1SEG */ diff --git a/arch/sh/include/asm/system.h b/arch/sh/include/asm/system.h index 1f1af5afff03..10c8b1823a18 100644 --- a/arch/sh/include/asm/system.h +++ b/arch/sh/include/asm/system.h @@ -10,6 +10,7 @@ #include <linux/compiler.h> #include <linux/linkage.h> #include <asm/types.h> +#include <asm/uncached.h> #define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ @@ -137,9 +138,6 @@ extern unsigned int instruction_size(unsigned int insn); #define instruction_size(insn) (4) #endif -extern unsigned long cached_to_uncached; -extern unsigned long uncached_size; - void per_cpu_trap_init(void); void default_idle(void); void cpu_idle_wait(void); diff --git a/arch/sh/include/asm/system_32.h b/arch/sh/include/asm/system_32.h index c941b2739405..a4ad1cd9bc4d 100644 --- a/arch/sh/include/asm/system_32.h +++ b/arch/sh/include/asm/system_32.h @@ -145,42 +145,6 @@ do { \ __restore_dsp(prev); \ } while (0) -/* - * Jump to uncached area. - * When handling TLB or caches, we need to do it from an uncached area. - */ -#define jump_to_uncached() \ -do { \ - unsigned long __dummy; \ - \ - __asm__ __volatile__( \ - "mova 1f, %0\n\t" \ - "add %1, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1:" \ - : "=&z" (__dummy) \ - : "r" (cached_to_uncached)); \ -} while (0) - -/* - * Back to cached area. - */ -#define back_to_cached() \ -do { \ - unsigned long __dummy; \ - ctrl_barrier(); \ - __asm__ __volatile__( \ - "mov.l 1f, %0\n\t" \ - "jmp @%0\n\t" \ - " nop\n\t" \ - ".balign 4\n" \ - "1: .long 2f\n" \ - "2:" \ - : "=&r" (__dummy)); \ -} while (0) - #ifdef CONFIG_CPU_HAS_SR_RB #define lookup_exception_vector() \ ({ \ diff --git a/arch/sh/include/asm/system_64.h b/arch/sh/include/asm/system_64.h index 36338646dfc8..8593bc8d1a4e 100644 --- a/arch/sh/include/asm/system_64.h +++ b/arch/sh/include/asm/system_64.h @@ -34,9 +34,6 @@ do { \ &next->thread); \ } while (0) -#define jump_to_uncached() do { } while (0) -#define back_to_cached() do { } while (0) - #define __icbi(addr) __asm__ __volatile__ ( "icbi %0, 0\n\t" : : "r" (addr)) #define __ocbp(addr) __asm__ __volatile__ ( "ocbp %0, 0\n\t" : : "r" (addr)) #define __ocbi(addr) __asm__ __volatile__ ( "ocbi %0, 0\n\t" : : "r" (addr)) diff --git a/arch/sh/include/asm/uncached.h b/arch/sh/include/asm/uncached.h index e3419f96626a..6f8816b79cf1 100644 --- a/arch/sh/include/asm/uncached.h +++ b/arch/sh/include/asm/uncached.h @@ -4,15 +4,55 @@ #include <linux/bug.h> #ifdef CONFIG_UNCACHED_MAPPING +extern unsigned long cached_to_uncached; +extern unsigned long uncached_size; extern unsigned long uncached_start, uncached_end; extern int virt_addr_uncached(unsigned long kaddr); extern void uncached_init(void); extern void uncached_resize(unsigned long size); + +/* + * Jump to uncached area. + * When handling TLB or caches, we need to do it from an uncached area. + */ +#define jump_to_uncached() \ +do { \ + unsigned long __dummy; \ + \ + __asm__ __volatile__( \ + "mova 1f, %0\n\t" \ + "add %1, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1:" \ + : "=&z" (__dummy) \ + : "r" (cached_to_uncached)); \ +} while (0) + +/* + * Back to cached area. + */ +#define back_to_cached() \ +do { \ + unsigned long __dummy; \ + ctrl_barrier(); \ + __asm__ __volatile__( \ + "mov.l 1f, %0\n\t" \ + "jmp @%0\n\t" \ + " nop\n\t" \ + ".balign 4\n" \ + "1: .long 2f\n" \ + "2:" \ + : "=&r" (__dummy)); \ +} while (0) #else #define virt_addr_uncached(kaddr) (0) #define uncached_init() do { } while (0) #define uncached_resize(size) BUG() +#define jump_to_uncached() do { } while (0) +#define back_to_cached() do { } while (0) #endif #endif /* __ASM_SH_UNCACHED_H */ diff --git a/arch/sh/include/mach-common/mach/edosk7705.h b/arch/sh/include/mach-common/mach/edosk7705.h deleted file mode 100644 index efc43b323466..000000000000 --- a/arch/sh/include/mach-common/mach/edosk7705.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __ASM_SH_EDOSK7705_H -#define __ASM_SH_EDOSK7705_H - -#define __IO_PREFIX sh_edosk7705 -#include <asm/io_generic.h> - -#endif /* __ASM_SH_EDOSK7705_H */ diff --git a/arch/sh/include/mach-common/mach/microdev.h b/arch/sh/include/mach-common/mach/microdev.h index 1aed15856e11..dcb05fa8c164 100644 --- a/arch/sh/include/mach-common/mach/microdev.h +++ b/arch/sh/include/mach-common/mach/microdev.h @@ -68,13 +68,4 @@ extern void microdev_print_fpga_intc_status(void); #define __IO_PREFIX microdev #include <asm/io_generic.h> -#if defined(CONFIG_PCI) -unsigned char microdev_pci_inb(unsigned long port); -unsigned short microdev_pci_inw(unsigned long port); -unsigned long microdev_pci_inl(unsigned long port); -void microdev_pci_outb(unsigned char data, unsigned long port); -void microdev_pci_outw(unsigned short data, unsigned long port); -void microdev_pci_outl(unsigned long data, unsigned long port); -#endif - #endif /* __ASM_SH_MICRODEV_H */ diff --git a/arch/sh/include/mach-common/mach/snapgear.h b/arch/sh/include/mach-common/mach/secureedge5410.h index 042d95f51c4d..3653b9a4bacc 100644 --- a/arch/sh/include/mach-common/mach/snapgear.h +++ b/arch/sh/include/mach-common/mach/secureedge5410.h @@ -12,30 +12,9 @@ #ifndef _ASM_SH_IO_SNAPGEAR_H #define _ASM_SH_IO_SNAPGEAR_H -#if defined(CONFIG_CPU_SH4) -/* - * The external interrupt lines, these take up ints 0 - 15 inclusive - * depending on the priority for the interrupt. In fact the priority - * is the interrupt :-) - */ - -#define IRL0_IRQ 2 -#define IRL0_PRIORITY 13 - -#define IRL1_IRQ 5 -#define IRL1_PRIORITY 10 - -#define IRL2_IRQ 8 -#define IRL2_PRIORITY 7 - -#define IRL3_IRQ 11 -#define IRL3_PRIORITY 4 -#endif - #define __IO_PREFIX snapgear #include <asm/io_generic.h> -#ifdef CONFIG_SH_SECUREEDGE5410 /* * We need to remember what was written to the ioport as some bits * are shared with other functions and you cannot read back what was @@ -66,6 +45,5 @@ extern unsigned short secureedge5410_ioport; ((secureedge5410_ioport & ~(mask)) | ((val) & (mask))))) #define SECUREEDGE_READ_IOPORT() \ ((*SECUREEDGE_IOPORT_ADDR&0x0817) | (secureedge5410_ioport&~0x0817)) -#endif #endif /* _ASM_SH_IO_SNAPGEAR_H */ diff --git a/arch/sh/include/mach-common/mach/systemh7751.h b/arch/sh/include/mach-common/mach/systemh7751.h deleted file mode 100644 index 4161122c84ef..000000000000 --- a/arch/sh/include/mach-common/mach/systemh7751.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef __ASM_SH_SYSTEMH_7751SYSTEMH_H -#define __ASM_SH_SYSTEMH_7751SYSTEMH_H - -/* - * linux/include/asm-sh/systemh/7751systemh.h - * - * Copyright (C) 2000 Kazumoto Kojima - * - * Hitachi SystemH support - - * Modified for 7751 SystemH by - * Jonathan Short, 2002. - */ - -/* Box specific addresses. */ - -#define PA_ROM 0x00000000 /* EPROM */ -#define PA_ROM_SIZE 0x00400000 /* EPROM size 4M byte */ -#define PA_FROM 0x01000000 /* EPROM */ -#define PA_FROM_SIZE 0x00400000 /* EPROM size 4M byte */ -#define PA_EXT1 0x04000000 -#define PA_EXT1_SIZE 0x04000000 -#define PA_EXT2 0x08000000 -#define PA_EXT2_SIZE 0x04000000 -#define PA_SDRAM 0x0c000000 -#define PA_SDRAM_SIZE 0x04000000 - -#define PA_EXT4 0x12000000 -#define PA_EXT4_SIZE 0x02000000 -#define PA_EXT5 0x14000000 -#define PA_EXT5_SIZE 0x04000000 -#define PA_PCIC 0x18000000 /* MR-SHPC-01 PCMCIA */ - -#define PA_DIPSW0 0xb9000000 /* Dip switch 5,6 */ -#define PA_DIPSW1 0xb9000002 /* Dip switch 7,8 */ -#define PA_LED 0xba000000 /* LED */ -#define PA_BCR 0xbb000000 /* FPGA on the MS7751SE01 */ - -#define PA_MRSHPC 0xb83fffe0 /* MR-SHPC-01 PCMCIA controller */ -#define PA_MRSHPC_MW1 0xb8400000 /* MR-SHPC-01 memory window base */ -#define PA_MRSHPC_MW2 0xb8500000 /* MR-SHPC-01 attribute window base */ -#define PA_MRSHPC_IO 0xb8600000 /* MR-SHPC-01 I/O window base */ -#define MRSHPC_MODE (PA_MRSHPC + 4) -#define MRSHPC_OPTION (PA_MRSHPC + 6) -#define MRSHPC_CSR (PA_MRSHPC + 8) -#define MRSHPC_ISR (PA_MRSHPC + 10) -#define MRSHPC_ICR (PA_MRSHPC + 12) -#define MRSHPC_CPWCR (PA_MRSHPC + 14) -#define MRSHPC_MW0CR1 (PA_MRSHPC + 16) -#define MRSHPC_MW1CR1 (PA_MRSHPC + 18) -#define MRSHPC_IOWCR1 (PA_MRSHPC + 20) -#define MRSHPC_MW0CR2 (PA_MRSHPC + 22) -#define MRSHPC_MW1CR2 (PA_MRSHPC + 24) -#define MRSHPC_IOWCR2 (PA_MRSHPC + 26) -#define MRSHPC_CDCR (PA_MRSHPC + 28) -#define MRSHPC_PCIC_INFO (PA_MRSHPC + 30) - -#define BCR_ILCRA (PA_BCR + 0) -#define BCR_ILCRB (PA_BCR + 2) -#define BCR_ILCRC (PA_BCR + 4) -#define BCR_ILCRD (PA_BCR + 6) -#define BCR_ILCRE (PA_BCR + 8) -#define BCR_ILCRF (PA_BCR + 10) -#define BCR_ILCRG (PA_BCR + 12) - -#define IRQ_79C973 13 - -#define __IO_PREFIX sh7751systemh -#include <asm/io_generic.h> - -#endif /* __ASM_SH_SYSTEMH_7751SYSTEMH_H */ diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index 2d9700c6b53a..0fe2e9329cb2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c @@ -48,7 +48,7 @@ static struct clk r_clk = { * Default rate for the root input clock, reset this with clk_set_rate() * from the platform code. */ -struct clk extal_clk = { +static struct clk extal_clk = { .rate = 33333333, }; @@ -111,7 +111,7 @@ static struct clk div3_clk = { .parent = &pll_clk, }; -struct clk *main_clks[] = { +static struct clk *main_clks[] = { &r_clk, &extal_clk, &fll_clk, @@ -156,7 +156,7 @@ struct clk div4_clks[DIV4_NR] = { enum { DIV6_V, DIV6_FA, DIV6_FB, DIV6_I, DIV6_S, DIV6_NR }; -struct clk div6_clks[DIV6_NR] = { +static struct clk div6_clks[DIV6_NR] = { [DIV6_V] = SH_CLK_DIV6(&div3_clk, VCLKCR, 0), [DIV6_FA] = SH_CLK_DIV6(&div3_clk, FCLKACR, 0), [DIV6_FB] = SH_CLK_DIV6(&div3_clk, FCLKBCR, 0), diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig index 09370392aff1..c3e61b366493 100644 --- a/arch/sh/mm/Kconfig +++ b/arch/sh/mm/Kconfig @@ -79,7 +79,7 @@ config 29BIT config 32BIT bool - default y if CPU_SH5 + default y if CPU_SH5 || !MMU config PMB bool "Support 32-bit physical addressing through PMB" diff --git a/arch/sh/mm/consistent.c b/arch/sh/mm/consistent.c index 038793286990..40733a952402 100644 --- a/arch/sh/mm/consistent.c +++ b/arch/sh/mm/consistent.c @@ -79,21 +79,20 @@ void dma_generic_free_coherent(struct device *dev, size_t size, void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { -#if defined(CONFIG_CPU_SH5) || defined(CONFIG_PMB) - void *p1addr = vaddr; -#else - void *p1addr = (void*) P1SEGADDR((unsigned long)vaddr); -#endif + void *addr; + + addr = __in_29bit_mode() ? + (void *)P1SEGADDR((unsigned long)vaddr) : vaddr; switch (direction) { case DMA_FROM_DEVICE: /* invalidate only */ - __flush_invalidate_region(p1addr, size); + __flush_invalidate_region(addr, size); break; case DMA_TO_DEVICE: /* writeback only */ - __flush_wback_region(p1addr, size); + __flush_wback_region(addr, size); break; case DMA_BIDIRECTIONAL: /* writeback and invalidate */ - __flush_purge_region(p1addr, size); + __flush_purge_region(addr, size); break; default: BUG(); diff --git a/arch/sh/mm/uncached.c b/arch/sh/mm/uncached.c index 8a4eca551fc0..a7767da815e9 100644 --- a/arch/sh/mm/uncached.c +++ b/arch/sh/mm/uncached.c @@ -28,7 +28,7 @@ EXPORT_SYMBOL(virt_addr_uncached); void __init uncached_init(void) { -#ifdef CONFIG_29BIT +#if defined(CONFIG_29BIT) || !defined(CONFIG_MMU) uncached_start = P2SEG; #else uncached_start = memory_end; diff --git a/arch/sh/tools/mach-types b/arch/sh/tools/mach-types index 9f56eb978024..0e68465e7b50 100644 --- a/arch/sh/tools/mach-types +++ b/arch/sh/tools/mach-types @@ -26,7 +26,6 @@ HD64461 HD64461 7724SE SH_7724_SOLUTION_ENGINE 7751SE SH_7751_SOLUTION_ENGINE 7780SE SH_7780_SOLUTION_ENGINE -7751SYSTEMH SH_7751_SYSTEMH HP6XX SH_HP6XX DREAMCAST SH_DREAMCAST SNAPGEAR SH_SECUREEDGE5410 diff --git a/arch/tile/include/asm/highmem.h b/arch/tile/include/asm/highmem.h index e0f7ee186721..b2a6c5de79ab 100644 --- a/arch/tile/include/asm/highmem.h +++ b/arch/tile/include/asm/highmem.h @@ -23,7 +23,6 @@ #include <linux/interrupt.h> #include <linux/threads.h> -#include <asm/kmap_types.h> #include <asm/tlbflush.h> #include <asm/homecache.h> diff --git a/arch/tile/include/asm/kmap_types.h b/arch/tile/include/asm/kmap_types.h index 1480106d1c05..3d0f20246260 100644 --- a/arch/tile/include/asm/kmap_types.h +++ b/arch/tile/include/asm/kmap_types.h @@ -16,28 +16,42 @@ #define _ASM_TILE_KMAP_TYPES_H /* - * In TILE Linux each set of four of these uses another 16MB chunk of - * address space, given 64 tiles and 64KB pages, so we only enable - * ones that are required by the kernel configuration. + * In 32-bit TILE Linux we have to balance the desire to have a lot of + * nested atomic mappings with the fact that large page sizes and many + * processors chew up address space quickly. In a typical + * 64-processor, 64KB-page layout build, making KM_TYPE_NR one larger + * adds 4MB of required address-space. For now we leave KM_TYPE_NR + * set to depth 8. */ enum km_type { + KM_TYPE_NR = 8 +}; + +/* + * We provide dummy definitions of all the stray values that used to be + * required for kmap_atomic() and no longer are. + */ +enum { KM_BOUNCE_READ, KM_SKB_SUNRPC_DATA, KM_SKB_DATA_SOFTIRQ, KM_USER0, KM_USER1, KM_BIO_SRC_IRQ, + KM_BIO_DST_IRQ, + KM_PTE0, + KM_PTE1, KM_IRQ0, KM_IRQ1, KM_SOFTIRQ0, KM_SOFTIRQ1, - KM_MEMCPY0, - KM_MEMCPY1, -#if defined(CONFIG_HIGHPTE) - KM_PTE0, - KM_PTE1, -#endif - KM_TYPE_NR + KM_SYNC_ICACHE, + KM_SYNC_DCACHE, + KM_UML_USERCOPY, + KM_IRQ_PTE, + KM_NMI, + KM_NMI_PTE, + KM_KDB }; #endif /* _ASM_TILE_KMAP_TYPES_H */ diff --git a/arch/tile/include/asm/pgtable.h b/arch/tile/include/asm/pgtable.h index dc4ccdd855bc..a6604e9485da 100644 --- a/arch/tile/include/asm/pgtable.h +++ b/arch/tile/include/asm/pgtable.h @@ -344,10 +344,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_offset_k(address) pgd_offset(&init_mm, address) #if defined(CONFIG_HIGHPTE) -extern pte_t *_pte_offset_map(pmd_t *, unsigned long address, enum km_type); -#define pte_offset_map(dir, address) \ - _pte_offset_map(dir, address, KM_PTE0) -#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0) +extern pte_t *pte_offset_map(pmd_t *, unsigned long address); +#define pte_unmap(pte) kunmap_atomic(pte) #else #define pte_offset_map(dir, address) pte_offset_kernel(dir, address) #define pte_unmap(pte) do { } while (0) diff --git a/arch/tile/include/asm/stat.h b/arch/tile/include/asm/stat.h index 3dc90fa92c70..b16e5db8f0e7 100644 --- a/arch/tile/include/asm/stat.h +++ b/arch/tile/include/asm/stat.h @@ -1 +1,4 @@ +#ifdef CONFIG_COMPAT +#define __ARCH_WANT_STAT64 /* Used for compat_sys_stat64() etc. */ +#endif #include <asm-generic/stat.h> diff --git a/arch/tile/include/asm/unistd.h b/arch/tile/include/asm/unistd.h index f2e3ff485333..b35c2db71199 100644 --- a/arch/tile/include/asm/unistd.h +++ b/arch/tile/include/asm/unistd.h @@ -41,6 +41,7 @@ __SYSCALL(__NR_cmpxchg_badaddr, sys_cmpxchg_badaddr) #ifdef CONFIG_COMPAT #define __ARCH_WANT_SYS_LLSEEK #endif +#define __ARCH_WANT_SYS_NEWFSTATAT #endif #endif /* _ASM_TILE_UNISTD_H */ diff --git a/arch/tile/kernel/compat.c b/arch/tile/kernel/compat.c index 77739cdd9462..67617a05e602 100644 --- a/arch/tile/kernel/compat.c +++ b/arch/tile/kernel/compat.c @@ -148,11 +148,11 @@ long tile_compat_sys_msgrcv(int msqid, #define compat_sys_readahead sys32_readahead #define compat_sys_sync_file_range compat_sys_sync_file_range2 -/* The native 64-bit "struct stat" matches the 32-bit "struct stat64". */ -#define compat_sys_stat64 sys_newstat -#define compat_sys_lstat64 sys_newlstat -#define compat_sys_fstat64 sys_newfstat -#define compat_sys_fstatat64 sys_newfstatat +/* We leverage the "struct stat64" type for 32-bit time_t/nsec. */ +#define compat_sys_stat64 sys_stat64 +#define compat_sys_lstat64 sys_lstat64 +#define compat_sys_fstat64 sys_fstat64 +#define compat_sys_fstatat64 sys_fstatat64 /* The native sys_ptrace dynamically handles compat binaries. */ #define compat_sys_ptrace sys_ptrace diff --git a/arch/tile/kernel/early_printk.c b/arch/tile/kernel/early_printk.c index 2c54fd43a8a0..493a0e66d916 100644 --- a/arch/tile/kernel/early_printk.c +++ b/arch/tile/kernel/early_printk.c @@ -54,7 +54,7 @@ void early_printk(const char *fmt, ...) void early_panic(const char *fmt, ...) { va_list ap; - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); va_start(ap, fmt); early_printk("Kernel panic - not syncing: "); early_vprintk(fmt, ap); diff --git a/arch/tile/kernel/hardwall.c b/arch/tile/kernel/hardwall.c index 1e54a7843410..e910530436e6 100644 --- a/arch/tile/kernel/hardwall.c +++ b/arch/tile/kernel/hardwall.c @@ -151,12 +151,12 @@ enum direction_protect { static void enable_firewall_interrupts(void) { - raw_local_irq_unmask_now(INT_UDN_FIREWALL); + arch_local_irq_unmask_now(INT_UDN_FIREWALL); } static void disable_firewall_interrupts(void) { - raw_local_irq_mask_now(INT_UDN_FIREWALL); + arch_local_irq_mask_now(INT_UDN_FIREWALL); } /* Set up hardwall on this cpu based on the passed hardwall_info. */ @@ -768,13 +768,13 @@ static int hardwall_release(struct inode *inode, struct file *file) } static const struct file_operations dev_hardwall_fops = { + .open = nonseekable_open, .unlocked_ioctl = hardwall_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl = hardwall_compat_ioctl, #endif .flush = hardwall_flush, .release = hardwall_release, - .llseek = noop_llseek, }; static struct cdev hardwall_dev; diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c index e63917687e99..128805ef8f2c 100644 --- a/arch/tile/kernel/irq.c +++ b/arch/tile/kernel/irq.c @@ -26,7 +26,7 @@ #define IS_HW_CLEARED 1 /* - * The set of interrupts we enable for raw_local_irq_enable(). + * The set of interrupts we enable for arch_local_irq_enable(). * This is initialized to have just a single interrupt that the kernel * doesn't actually use as a sentinel. During kernel init, * interrupts are added as the kernel gets prepared to support them. @@ -225,7 +225,7 @@ void __cpuinit setup_irq_regs(void) /* Enable interrupt delivery. */ unmask_irqs(~0UL); #if CHIP_HAS_IPI() - raw_local_irq_unmask(INT_IPI_K); + arch_local_irq_unmask(INT_IPI_K); #endif } diff --git a/arch/tile/kernel/machine_kexec.c b/arch/tile/kernel/machine_kexec.c index ba7a265d6179..0d8b9e933487 100644 --- a/arch/tile/kernel/machine_kexec.c +++ b/arch/tile/kernel/machine_kexec.c @@ -182,13 +182,13 @@ static void kexec_find_and_set_command_line(struct kimage *image) if ((entry & IND_SOURCE)) { void *va = - kmap_atomic_pfn(entry >> PAGE_SHIFT, KM_USER0); + kmap_atomic_pfn(entry >> PAGE_SHIFT); r = kexec_bn2cl(va); if (r) { command_line = r; break; } - kunmap_atomic(va, KM_USER0); + kunmap_atomic(va); } } @@ -198,7 +198,7 @@ static void kexec_find_and_set_command_line(struct kimage *image) hverr = hv_set_command_line( (HV_VirtAddr) command_line, strlen(command_line)); - kunmap_atomic(command_line, KM_USER0); + kunmap_atomic(command_line); } else { pr_info("%s: no command line found; making empty\n", __func__); diff --git a/arch/tile/kernel/messaging.c b/arch/tile/kernel/messaging.c index 997e3933f726..0858ee6b520f 100644 --- a/arch/tile/kernel/messaging.c +++ b/arch/tile/kernel/messaging.c @@ -34,7 +34,7 @@ void __cpuinit init_messaging(void) panic("hv_register_message_state: error %d", rc); /* Make sure downcall interrupts will be enabled. */ - raw_local_irq_unmask(INT_INTCTRL_K); + arch_local_irq_unmask(INT_INTCTRL_K); } void hv_message_intr(struct pt_regs *regs, int intnum) diff --git a/arch/tile/kernel/ptrace.c b/arch/tile/kernel/ptrace.c index 9cd29884c09f..e92e40527d6d 100644 --- a/arch/tile/kernel/ptrace.c +++ b/arch/tile/kernel/ptrace.c @@ -50,10 +50,10 @@ long arch_ptrace(struct task_struct *child, long request, { unsigned long __user *datap = (long __user __force *)data; unsigned long tmp; - int i; long ret = -EIO; - unsigned long *childregs; char *childreg; + struct pt_regs copyregs; + int ex1_offset; switch (request) { @@ -80,6 +80,16 @@ long arch_ptrace(struct task_struct *child, long request, if (addr >= PTREGS_SIZE) break; childreg = (char *)task_pt_regs(child) + addr; + + /* Guard against overwrites of the privilege level. */ + ex1_offset = PTREGS_OFFSET_EX1; +#if defined(CONFIG_COMPAT) && defined(__BIG_ENDIAN) + if (is_compat_task()) /* point at low word */ + ex1_offset += sizeof(compat_long_t); +#endif + if (addr == ex1_offset) + data = PL_ICS_EX1(USER_PL, EX1_ICS(data)); + #ifdef CONFIG_COMPAT if (is_compat_task()) { if (addr & (sizeof(compat_long_t)-1)) @@ -96,26 +106,19 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_GETREGS: /* Get all registers from the child. */ - if (!access_ok(VERIFY_WRITE, datap, PTREGS_SIZE)) - break; - childregs = (long *)task_pt_regs(child); - for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); - ++i) { - ret = __put_user(childregs[i], &datap[i]); - if (ret != 0) - break; + if (copy_to_user(datap, task_pt_regs(child), + sizeof(struct pt_regs)) == 0) { + ret = 0; } break; case PTRACE_SETREGS: /* Set all registers in the child. */ - if (!access_ok(VERIFY_READ, datap, PTREGS_SIZE)) - break; - childregs = (long *)task_pt_regs(child); - for (i = 0; i < sizeof(struct pt_regs)/sizeof(unsigned long); - ++i) { - ret = __get_user(childregs[i], &datap[i]); - if (ret != 0) - break; + if (copy_from_user(©regs, datap, + sizeof(struct pt_regs)) == 0) { + copyregs.ex1 = + PL_ICS_EX1(USER_PL, EX1_ICS(copyregs.ex1)); + *task_pt_regs(child) = copyregs; + ret = 0; } break; diff --git a/arch/tile/kernel/reboot.c b/arch/tile/kernel/reboot.c index acd86d20beba..baa3d905fee2 100644 --- a/arch/tile/kernel/reboot.c +++ b/arch/tile/kernel/reboot.c @@ -27,7 +27,7 @@ void machine_halt(void) { warn_early_printk(); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_halt(); } @@ -35,14 +35,14 @@ void machine_halt(void) void machine_power_off(void) { warn_early_printk(); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_power_off(); } void machine_restart(char *cmd) { - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); smp_send_stop(); hv_restart((HV_VirtAddr) "vmlinux", (HV_VirtAddr) cmd); } diff --git a/arch/tile/kernel/setup.c b/arch/tile/kernel/setup.c index ae51cad12da0..fb0b3cbeae14 100644 --- a/arch/tile/kernel/setup.c +++ b/arch/tile/kernel/setup.c @@ -868,14 +868,14 @@ void __cpuinit setup_cpu(int boot) /* Allow asynchronous TLB interrupts. */ #if CHIP_HAS_TILE_DMA() - raw_local_irq_unmask(INT_DMATLB_MISS); - raw_local_irq_unmask(INT_DMATLB_ACCESS); + arch_local_irq_unmask(INT_DMATLB_MISS); + arch_local_irq_unmask(INT_DMATLB_ACCESS); #endif #if CHIP_HAS_SN_PROC() - raw_local_irq_unmask(INT_SNITLB_MISS); + arch_local_irq_unmask(INT_SNITLB_MISS); #endif #ifdef __tilegx__ - raw_local_irq_unmask(INT_SINGLE_STEP_K); + arch_local_irq_unmask(INT_SINGLE_STEP_K); #endif /* diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index fb28e85ae3ae..687719d4abd1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c @@ -71,6 +71,9 @@ int restore_sigcontext(struct pt_regs *regs, for (i = 0; i < sizeof(struct pt_regs)/sizeof(long); ++i) err |= __get_user(regs->regs[i], &sc->gregs[i]); + /* Ensure that the PL is always set to USER_PL. */ + regs->ex1 = PL_ICS_EX1(USER_PL, EX1_ICS(regs->ex1)); + regs->faultnum = INT_SWINT_1_SIGRETURN; err |= __get_user(*pr0, &sc->gregs[0]); @@ -330,7 +333,7 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; } - return; + goto done; } /* Did we come from a system call? */ @@ -358,4 +361,8 @@ void do_signal(struct pt_regs *regs) current_thread_info()->status &= ~TS_RESTORE_SIGMASK; sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); } + +done: + /* Avoid double syscall restart if there are nested signals. */ + regs->faultnum = INT_SWINT_1_SIGRETURN; } diff --git a/arch/tile/kernel/smp.c b/arch/tile/kernel/smp.c index 75255d90aff3..9575b37a8b75 100644 --- a/arch/tile/kernel/smp.c +++ b/arch/tile/kernel/smp.c @@ -115,7 +115,7 @@ static void smp_start_cpu_interrupt(void) static void smp_stop_cpu_interrupt(void) { set_cpu_online(smp_processor_id(), 0); - raw_local_irq_disable_all(); + arch_local_irq_disable_all(); for (;;) asm("nap"); } diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c index 6bed820e1421..f2e156e44692 100644 --- a/arch/tile/kernel/time.c +++ b/arch/tile/kernel/time.c @@ -132,7 +132,7 @@ static int tile_timer_set_next_event(unsigned long ticks, { BUG_ON(ticks > MAX_TICK); __insn_mtspr(SPR_TILE_TIMER_CONTROL, ticks); - raw_local_irq_unmask_now(INT_TILE_TIMER); + arch_local_irq_unmask_now(INT_TILE_TIMER); return 0; } @@ -143,7 +143,7 @@ static int tile_timer_set_next_event(unsigned long ticks, static void tile_timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { - raw_local_irq_mask_now(INT_TILE_TIMER); + arch_local_irq_mask_now(INT_TILE_TIMER); } /* @@ -172,7 +172,7 @@ void __cpuinit setup_tile_timer(void) evt->cpumask = cpumask_of(smp_processor_id()); /* Start out with timer not firing. */ - raw_local_irq_mask_now(INT_TILE_TIMER); + arch_local_irq_mask_now(INT_TILE_TIMER); /* Register tile timer. */ clockevents_register_device(evt); @@ -188,7 +188,7 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num) * Mask the timer interrupt here, since we are a oneshot timer * and there are now by definition no events pending. */ - raw_local_irq_mask(INT_TILE_TIMER); + arch_local_irq_mask(INT_TILE_TIMER); /* Track time spent here in an interrupt context */ irq_enter(); diff --git a/arch/tile/lib/memcpy_tile64.c b/arch/tile/lib/memcpy_tile64.c index dfedea7b266b..f7d4a6ad61e8 100644 --- a/arch/tile/lib/memcpy_tile64.c +++ b/arch/tile/lib/memcpy_tile64.c @@ -54,7 +54,7 @@ typedef unsigned long (*memcpy_t)(void *, const void *, unsigned long); * we must run with interrupts disabled to avoid the risk of some * other code seeing the incoherent data in our cache. (Recall that * our cache is indexed by PA, so even if the other code doesn't use - * our KM_MEMCPY virtual addresses, they'll still hit in cache using + * our kmap_atomic virtual addresses, they'll still hit in cache using * the normal VAs that aren't supposed to hit in cache.) */ static void memcpy_multicache(void *dest, const void *source, @@ -64,6 +64,7 @@ static void memcpy_multicache(void *dest, const void *source, unsigned long flags, newsrc, newdst; pmd_t *pmdp; pte_t *ptep; + int type0, type1; int cpu = get_cpu(); /* @@ -77,7 +78,8 @@ static void memcpy_multicache(void *dest, const void *source, sim_allow_multiple_caching(1); /* Set up the new dest mapping */ - idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + KM_MEMCPY0; + type0 = kmap_atomic_idx_push(); + idx = FIX_KMAP_BEGIN + (KM_TYPE_NR * cpu) + type0; newdst = __fix_to_virt(idx) + ((unsigned long)dest & (PAGE_SIZE-1)); pmdp = pmd_offset(pud_offset(pgd_offset_k(newdst), newdst), newdst); ptep = pte_offset_kernel(pmdp, newdst); @@ -87,7 +89,8 @@ static void memcpy_multicache(void *dest, const void *source, } /* Set up the new source mapping */ - idx += (KM_MEMCPY0 - KM_MEMCPY1); + type1 = kmap_atomic_idx_push(); + idx += (type0 - type1); src_pte = hv_pte_set_nc(src_pte); src_pte = hv_pte_clear_writable(src_pte); /* be paranoid */ newsrc = __fix_to_virt(idx) + ((unsigned long)source & (PAGE_SIZE-1)); @@ -119,6 +122,8 @@ static void memcpy_multicache(void *dest, const void *source, * We're done: notify the simulator that all is back to normal, * and re-enable interrupts and pre-emption. */ + kmap_atomic_idx_pop(); + kmap_atomic_idx_pop(); sim_allow_multiple_caching(0); local_irq_restore(flags); put_cpu(); diff --git a/arch/tile/mm/highmem.c b/arch/tile/mm/highmem.c index abb57331cf6e..31dbbd9afe47 100644 --- a/arch/tile/mm/highmem.c +++ b/arch/tile/mm/highmem.c @@ -227,7 +227,7 @@ EXPORT_SYMBOL(kmap_atomic_prot); void *__kmap_atomic(struct page *page) { /* PAGE_NONE is a magic value that tells us to check immutability. */ - return kmap_atomic_prot(page, type, PAGE_NONE); + return kmap_atomic_prot(page, PAGE_NONE); } EXPORT_SYMBOL(__kmap_atomic); diff --git a/arch/tile/mm/init.c b/arch/tile/mm/init.c index 78e1982cb6c9..0b9ce69b0ee5 100644 --- a/arch/tile/mm/init.c +++ b/arch/tile/mm/init.c @@ -988,8 +988,12 @@ static long __write_once initfree = 1; /* Select whether to free (1) or mark unusable (0) the __init pages. */ static int __init set_initfree(char *str) { - strict_strtol(str, 0, &initfree); - pr_info("initfree: %s free init pages\n", initfree ? "will" : "won't"); + long val; + if (strict_strtol(str, 0, &val)) { + initfree = val; + pr_info("initfree: %s free init pages\n", + initfree ? "will" : "won't"); + } return 1; } __setup("initfree=", set_initfree); diff --git a/arch/tile/mm/pgtable.c b/arch/tile/mm/pgtable.c index 335c24621c41..1f5430c53d0d 100644 --- a/arch/tile/mm/pgtable.c +++ b/arch/tile/mm/pgtable.c @@ -134,9 +134,9 @@ void __set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags) } #if defined(CONFIG_HIGHPTE) -pte_t *_pte_offset_map(pmd_t *dir, unsigned long address, enum km_type type) +pte_t *_pte_offset_map(pmd_t *dir, unsigned long address) { - pte_t *pte = kmap_atomic(pmd_page(*dir), type) + + pte_t *pte = kmap_atomic(pmd_page(*dir)) + (pmd_ptfn(*dir) << HV_LOG2_PAGE_TABLE_ALIGN) & ~PAGE_MASK; return &pte[pte_index(address)]; } diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 908ea5464a51..fb8b376bf28c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -720,7 +720,7 @@ static void rmap_remove(struct kvm *kvm, u64 *spte) } } -static void set_spte_track_bits(u64 *sptep, u64 new_spte) +static int set_spte_track_bits(u64 *sptep, u64 new_spte) { pfn_t pfn; u64 old_spte = *sptep; @@ -731,19 +731,20 @@ static void set_spte_track_bits(u64 *sptep, u64 new_spte) old_spte = __xchg_spte(sptep, new_spte); if (!is_rmap_spte(old_spte)) - return; + return 0; pfn = spte_to_pfn(old_spte); if (!shadow_accessed_mask || old_spte & shadow_accessed_mask) kvm_set_pfn_accessed(pfn); if (!shadow_dirty_mask || (old_spte & shadow_dirty_mask)) kvm_set_pfn_dirty(pfn); + return 1; } static void drop_spte(struct kvm *kvm, u64 *sptep, u64 new_spte) { - set_spte_track_bits(sptep, new_spte); - rmap_remove(kvm, sptep); + if (set_spte_track_bits(sptep, new_spte)) + rmap_remove(kvm, sptep); } static u64 *rmap_next(struct kvm *kvm, unsigned long *rmapp, u64 *spte) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 2288ad829b32..cdac9e592aa5 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2560,6 +2560,7 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, !kvm_exception_is_soft(vcpu->arch.exception.nr); events->exception.nr = vcpu->arch.exception.nr; events->exception.has_error_code = vcpu->arch.exception.has_error_code; + events->exception.pad = 0; events->exception.error_code = vcpu->arch.exception.error_code; events->interrupt.injected = @@ -2573,12 +2574,14 @@ static void kvm_vcpu_ioctl_x86_get_vcpu_events(struct kvm_vcpu *vcpu, events->nmi.injected = vcpu->arch.nmi_injected; events->nmi.pending = vcpu->arch.nmi_pending; events->nmi.masked = kvm_x86_ops->get_nmi_mask(vcpu); + events->nmi.pad = 0; events->sipi_vector = vcpu->arch.sipi_vector; events->flags = (KVM_VCPUEVENT_VALID_NMI_PENDING | KVM_VCPUEVENT_VALID_SIPI_VECTOR | KVM_VCPUEVENT_VALID_SHADOW); + memset(&events->reserved, 0, sizeof(events->reserved)); } static int kvm_vcpu_ioctl_x86_set_vcpu_events(struct kvm_vcpu *vcpu, @@ -2623,6 +2626,7 @@ static void kvm_vcpu_ioctl_x86_get_debugregs(struct kvm_vcpu *vcpu, dbgregs->dr6 = vcpu->arch.dr6; dbgregs->dr7 = vcpu->arch.dr7; dbgregs->flags = 0; + memset(&dbgregs->reserved, 0, sizeof(dbgregs->reserved)); } static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu, @@ -3106,6 +3110,7 @@ static int kvm_vm_ioctl_get_pit2(struct kvm *kvm, struct kvm_pit_state2 *ps) sizeof(ps->channels)); ps->flags = kvm->arch.vpit->pit_state.flags; mutex_unlock(&kvm->arch.vpit->pit_state.lock); + memset(&ps->reserved, 0, sizeof(ps->reserved)); return r; } @@ -3169,10 +3174,6 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_memslots *slots, *old_slots; unsigned long *dirty_bitmap; - spin_lock(&kvm->mmu_lock); - kvm_mmu_slot_remove_write_access(kvm, log->slot); - spin_unlock(&kvm->mmu_lock); - r = -ENOMEM; dirty_bitmap = vmalloc(n); if (!dirty_bitmap) @@ -3194,6 +3195,10 @@ int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, dirty_bitmap = old_slots->memslots[log->slot].dirty_bitmap; kfree(old_slots); + spin_lock(&kvm->mmu_lock); + kvm_mmu_slot_remove_write_access(kvm, log->slot); + spin_unlock(&kvm->mmu_lock); + r = -EFAULT; if (copy_to_user(log->dirty_bitmap, dirty_bitmap, n)) { vfree(dirty_bitmap); @@ -3486,6 +3491,7 @@ long kvm_arch_vm_ioctl(struct file *filp, user_ns.clock = kvm->arch.kvmclock_offset + now_ns; local_irq_enable(); user_ns.flags = 0; + memset(&user_ns.pad, 0, sizeof(user_ns.pad)); r = -EFAULT; if (copy_to_user(argp, &user_ns, sizeof(user_ns))) @@ -3972,8 +3978,10 @@ int kvm_emulate_wbinvd(struct kvm_vcpu *vcpu) return X86EMUL_CONTINUE; if (kvm_x86_ops->has_wbinvd_exit()) { + preempt_disable(); smp_call_function_many(vcpu->arch.wbinvd_dirty_mask, wbinvd_ipi, NULL, 1); + preempt_enable(); cpumask_clear(vcpu->arch.wbinvd_dirty_mask); } wbinvd(); diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 767107cce982..8f19b380ca83 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4363,9 +4363,9 @@ out_unreg_blkdev: out_put_disk: while (dr--) { del_timer(&motor_off_timer[dr]); - put_disk(disks[dr]); if (disks[dr]->queue) blk_cleanup_queue(disks[dr]->queue); + put_disk(disks[dr]); } return err; } diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 9dcb17d51aee..84eb607d6c03 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -577,17 +577,11 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, return ret; } -static int ar_context_add_page(struct ar_context *ctx) +static void ar_context_link_page(struct ar_context *ctx, + struct ar_buffer *ab, dma_addr_t ab_bus) { - struct device *dev = ctx->ohci->card.device; - struct ar_buffer *ab; - dma_addr_t uninitialized_var(ab_bus); size_t offset; - ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); - if (ab == NULL) - return -ENOMEM; - ab->next = NULL; memset(&ab->descriptor, 0, sizeof(ab->descriptor)); ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | @@ -606,6 +600,19 @@ static int ar_context_add_page(struct ar_context *ctx) reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); flush_writes(ctx->ohci); +} + +static int ar_context_add_page(struct ar_context *ctx) +{ + struct device *dev = ctx->ohci->card.device; + struct ar_buffer *ab; + dma_addr_t uninitialized_var(ab_bus); + + ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); + if (ab == NULL) + return -ENOMEM; + + ar_context_link_page(ctx, ab, ab_bus); return 0; } @@ -730,16 +737,17 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) static void ar_context_tasklet(unsigned long data) { struct ar_context *ctx = (struct ar_context *)data; - struct fw_ohci *ohci = ctx->ohci; struct ar_buffer *ab; struct descriptor *d; void *buffer, *end; + __le16 res_count; ab = ctx->current_buffer; d = &ab->descriptor; - if (d->res_count == 0) { - size_t size, rest, offset; + res_count = ACCESS_ONCE(d->res_count); + if (res_count == 0) { + size_t size, size2, rest, pktsize, size3, offset; dma_addr_t start_bus; void *start; @@ -750,29 +758,63 @@ static void ar_context_tasklet(unsigned long data) */ offset = offsetof(struct ar_buffer, data); - start = buffer = ab; + start = ab; start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + buffer = ab->data; ab = ab->next; d = &ab->descriptor; - size = buffer + PAGE_SIZE - ctx->pointer; + size = start + PAGE_SIZE - ctx->pointer; + /* valid buffer data in the next page */ rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); + /* what actually fits in this page */ + size2 = min(rest, (size_t)PAGE_SIZE - offset - size); memmove(buffer, ctx->pointer, size); - memcpy(buffer + size, ab->data, rest); - ctx->current_buffer = ab; - ctx->pointer = (void *) ab->data + rest; - end = buffer + size + rest; + memcpy(buffer + size, ab->data, size2); + + while (size > 0) { + void *next = handle_ar_packet(ctx, buffer); + pktsize = next - buffer; + if (pktsize >= size) { + /* + * We have handled all the data that was + * originally in this page, so we can now + * continue in the next page. + */ + buffer = next; + break; + } + /* move the next packet to the start of the buffer */ + memmove(buffer, next, size + size2 - pktsize); + size -= pktsize; + /* fill up this page again */ + size3 = min(rest - size2, + (size_t)PAGE_SIZE - offset - size - size2); + memcpy(buffer + size + size2, + (void *) ab->data + size2, size3); + size2 += size3; + } - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); + if (rest > 0) { + /* handle the packets that are fully in the next page */ + buffer = (void *) ab->data + + (buffer - (start + offset + size)); + end = (void *) ab->data + rest; + + while (buffer < end) + buffer = handle_ar_packet(ctx, buffer); - dma_free_coherent(ohci->card.device, PAGE_SIZE, - start, start_bus); - ar_context_add_page(ctx); + ctx->current_buffer = ab; + ctx->pointer = end; + + ar_context_link_page(ctx, start, start_bus); + } else { + ctx->pointer = start + PAGE_SIZE; + } } else { buffer = ctx->pointer; ctx->pointer = end = - (void *) ab + PAGE_SIZE - le16_to_cpu(d->res_count); + (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); while (buffer < end) buffer = handle_ar_packet(ctx, buffer); diff --git a/drivers/hwmon/ltc4261.c b/drivers/hwmon/ltc4261.c index 267626178678..4b50601027d3 100644 --- a/drivers/hwmon/ltc4261.c +++ b/drivers/hwmon/ltc4261.c @@ -82,7 +82,7 @@ static struct ltc4261_data *ltc4261_update_device(struct device *dev) val = i2c_smbus_read_byte_data(client, i); if (unlikely(val < 0)) { dev_dbg(dev, - "Failed to read ADC value: error %d", + "Failed to read ADC value: error %d\n", val); ret = ERR_PTR(val); goto abort; @@ -230,8 +230,7 @@ static int ltc4261_probe(struct i2c_client *client, return -ENODEV; if (i2c_smbus_read_byte_data(client, LTC4261_STATUS) < 0) { - dev_err(&client->dev, "Failed to read register %d:%02x:%02x\n", - adapter->id, client->addr, LTC4261_STATUS); + dev_err(&client->dev, "Failed to read status register\n"); return -ENODEV; } diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 40b914bded8c..2e72227bd071 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc) &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { - printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); - debugl1(cs, "isar modeisar analog funktions only with DP1"); + printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); + debugl1(cs, "isar modeisar analog functions only with DP1"); return(1); } break; diff --git a/drivers/leds/leds-net5501.c b/drivers/leds/leds-net5501.c index 3063f591f0dc..1739557a9038 100644 --- a/drivers/leds/leds-net5501.c +++ b/drivers/leds/leds-net5501.c @@ -92,3 +92,5 @@ unmap: } arch_initcall(soekris_init); + +MODULE_LICENSE("GPL"); diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 43579b3b24ac..53363108994e 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c @@ -3043,7 +3043,6 @@ static int __devinit atl1_probe(struct pci_dev *pdev, atl1_pcie_patch(adapter); /* assume we have no link for now */ netif_carrier_off(netdev); - netif_stop_queue(netdev); setup_timer(&adapter->phy_config_timer, atl1_phy_config, (unsigned long)adapter); diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 9eea225decaf..863e73a85fbe 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h @@ -20,8 +20,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.60.00-3" -#define DRV_MODULE_RELDATE "2010/10/19" +#define DRV_MODULE_VERSION "1.60.00-4" +#define DRV_MODULE_RELDATE "2010/11/01" #define BNX2X_BC_VER 0x040200 #define BNX2X_MULTI_QUEUE diff --git a/drivers/net/bnx2x/bnx2x_hsi.h b/drivers/net/bnx2x/bnx2x_hsi.h index 18c8e23a0e82..4cfd4e9b5586 100644 --- a/drivers/net/bnx2x/bnx2x_hsi.h +++ b/drivers/net/bnx2x/bnx2x_hsi.h @@ -244,7 +244,14 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ u16 xgxs_config_tx[4]; /* 0x1A0 */ - u32 Reserved1[57]; /* 0x1A8 */ + u32 Reserved1[56]; /* 0x1A8 */ + u32 default_cfg; /* 0x288 */ + /* Enable BAM on KR */ +#define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 +#define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 +#define PORT_HW_CFG_ENABLE_BAM_ON_KR_DISABLED 0x00000000 +#define PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED 0x00100000 + u32 speed_capability_mask2; /* 0x28C */ #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_MASK 0x0000FFFF #define PORT_HW_CFG_SPEED_CAPABILITY2_D3_SHIFT 0 diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c index 2326774df843..580919619252 100644 --- a/drivers/net/bnx2x/bnx2x_link.c +++ b/drivers/net/bnx2x/bnx2x_link.c @@ -610,7 +610,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, /* reset and unreset the BigMac */ REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); - udelay(10); + msleep(1); REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); @@ -3525,13 +3525,19 @@ static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy, DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1); /* Enable CL37 BAM */ - bnx2x_cl45_read(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, &val); - bnx2x_cl45_write(bp, phy, - MDIO_AN_DEVAD, - MDIO_AN_REG_8073_BAM, val | 1); + if (REG_RD(bp, params->shmem_base + + offsetof(struct shmem_region, dev_info. + port_hw_config[params->port].default_cfg)) & + PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) { + bnx2x_cl45_read(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, &val); + bnx2x_cl45_write(bp, phy, + MDIO_AN_DEVAD, + MDIO_AN_REG_8073_BAM, val | 1); + DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n"); + } if (params->loopback_mode == LOOPBACK_EXT) { bnx2x_807x_force_10G(bp, phy); DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n"); @@ -5302,7 +5308,7 @@ static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy, { struct bnx2x *bp = params->bp; u16 autoneg_val, an_1000_val, an_10_100_val; - bnx2x_wait_reset_complete(bp, phy); + bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4, 1 << NIG_LATCH_BC_ENABLE_MI_INT); @@ -5431,6 +5437,7 @@ static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy, /* HW reset */ bnx2x_ext_phy_hw_reset(bp, params->port); + bnx2x_wait_reset_complete(bp, phy); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); return bnx2x_848xx_cmn_config_init(phy, params, vars); @@ -5441,7 +5448,7 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, struct link_vars *vars) { struct bnx2x *bp = params->bp; - u8 port = params->port, initialize = 1; + u8 port, initialize = 1; u16 val; u16 temp; u32 actual_phy_selection; @@ -5450,11 +5457,16 @@ static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy, /* This is just for MDIO_CTL_REG_84823_MEDIA register. */ msleep(1); + if (CHIP_IS_E2(bp)) + port = BP_PATH(bp); + else + port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); - msleep(200); /* 100 is not enough */ - + bnx2x_wait_reset_complete(bp, phy); + /* Wait for GPHY to come out of reset */ + msleep(50); /* BCM84823 requires that XGXS links up first @ 10G for normal behavior */ temp = vars->line_speed; @@ -5625,7 +5637,11 @@ static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy, struct link_params *params) { struct bnx2x *bp = params->bp; - u8 port = params->port; + u8 port; + if (CHIP_IS_E2(bp)) + port = BP_PATH(bp); + else + port = params->port; bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3, MISC_REGISTERS_GPIO_OUTPUT_LOW, port); @@ -6928,7 +6944,7 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, u8 reset_ext_phy) { struct bnx2x *bp = params->bp; - u8 phy_index, port = params->port; + u8 phy_index, port = params->port, clear_latch_ind = 0; DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); /* disable attentions */ vars->link_status = 0; @@ -6966,9 +6982,18 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, params->phy[phy_index].link_reset( ¶ms->phy[phy_index], params); + if (params->phy[phy_index].flags & + FLAGS_REARM_LATCH_SIGNAL) + clear_latch_ind = 1; } } + if (clear_latch_ind) { + /* Clear latching indication */ + bnx2x_rearm_latch_signal(bp, port, 0); + bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4, + 1 << NIG_LATCH_BC_ENABLE_MI_INT); + } if (params->phy[INT_PHY].link_reset) params->phy[INT_PHY].link_reset( ¶ms->phy[INT_PHY], params); @@ -6999,6 +7024,7 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, s8 port; s8 port_of_path = 0; + bnx2x_ext_phy_hw_reset(bp, 0); /* PART1 - Reset both phys */ for (port = PORT_MAX - 1; port >= PORT_0; port--) { u32 shmem_base, shmem2_base; @@ -7021,7 +7047,8 @@ static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, return -EINVAL; } /* disable attentions */ - bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, + bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + port_of_path*4, (NIG_MASK_XGXS0_LINK_STATUS | NIG_MASK_XGXS0_LINK10G | NIG_MASK_SERDES0_LINK_STATUS | @@ -7132,7 +7159,7 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); - bnx2x_ext_phy_hw_reset(bp, 1); + bnx2x_ext_phy_hw_reset(bp, 0); msleep(5); for (port = 0; port < PORT_MAX; port++) { u32 shmem_base, shmem2_base; diff --git a/drivers/net/caif/caif_spi.c b/drivers/net/caif/caif_spi.c index 8427533fe313..8b4cea57a6c5 100644 --- a/drivers/net/caif/caif_spi.c +++ b/drivers/net/caif/caif_spi.c @@ -33,6 +33,9 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Daniel Martensson<daniel.martensson@stericsson.com>"); MODULE_DESCRIPTION("CAIF SPI driver"); +/* Returns the number of padding bytes for alignment. */ +#define PAD_POW2(x, pow) ((((x)&((pow)-1))==0) ? 0 : (((pow)-((x)&((pow)-1))))) + static int spi_loop; module_param(spi_loop, bool, S_IRUGO); MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); @@ -41,7 +44,10 @@ MODULE_PARM_DESC(spi_loop, "SPI running in loopback mode."); module_param(spi_frm_align, int, S_IRUGO); MODULE_PARM_DESC(spi_frm_align, "SPI frame alignment."); -/* SPI padding options. */ +/* + * SPI padding options. + * Warning: must be a base of 2 (& operation used) and can not be zero ! + */ module_param(spi_up_head_align, int, S_IRUGO); MODULE_PARM_DESC(spi_up_head_align, "SPI uplink head alignment."); @@ -240,15 +246,13 @@ static ssize_t dbgfs_frame(struct file *file, char __user *user_buf, static const struct file_operations dbgfs_state_fops = { .open = dbgfs_open, .read = dbgfs_state, - .owner = THIS_MODULE, - .llseek = default_llseek, + .owner = THIS_MODULE }; static const struct file_operations dbgfs_frame_fops = { .open = dbgfs_open, .read = dbgfs_frame, - .owner = THIS_MODULE, - .llseek = default_llseek, + .owner = THIS_MODULE }; static inline void dev_debugfs_add(struct cfspi *cfspi) @@ -337,6 +341,9 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) u8 *dst = buf; caif_assert(buf); + if (cfspi->slave && !cfspi->slave_talked) + cfspi->slave_talked = true; + do { struct sk_buff *skb; struct caif_payload_info *info; @@ -357,8 +364,8 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute head offset i.e. number of bytes to add to * get the start of the payload aligned. */ - if (spi_up_head_align) { - spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); + if (spi_up_head_align > 1) { + spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); *dst = (u8)(spad - 1); dst += spad; } @@ -373,7 +380,7 @@ int cfspi_xmitfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute tail offset i.e. number of bytes to add to * get the complete CAIF frame aligned. */ - epad = (skb->len + spad) & spi_up_tail_align; + epad = PAD_POW2((skb->len + spad), spi_up_tail_align); dst += epad; dev_kfree_skb(skb); @@ -417,14 +424,14 @@ int cfspi_xmitlen(struct cfspi *cfspi) * Compute head offset i.e. number of bytes to add to * get the start of the payload aligned. */ - if (spi_up_head_align) - spad = 1 + ((info->hdr_len + 1) & spi_up_head_align); + if (spi_up_head_align > 1) + spad = 1 + PAD_POW2((info->hdr_len + 1), spi_up_head_align); /* * Compute tail offset i.e. number of bytes to add to * get the complete CAIF frame aligned. */ - epad = (skb->len + spad) & spi_up_tail_align; + epad = PAD_POW2((skb->len + spad), spi_up_tail_align); if ((skb->len + spad + epad + frm_len) <= CAIF_MAX_SPI_FRAME) { skb_queue_tail(&cfspi->chead, skb); @@ -433,6 +440,7 @@ int cfspi_xmitlen(struct cfspi *cfspi) } else { /* Put back packet. */ skb_queue_head(&cfspi->qhead, skb); + break; } } while (pkts <= CAIF_MAX_SPI_PKTS); @@ -453,6 +461,15 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) { struct cfspi *cfspi = (struct cfspi *)ifc->priv; + /* + * The slave device is the master on the link. Interrupts before the + * slave has transmitted are considered spurious. + */ + if (cfspi->slave && !cfspi->slave_talked) { + printk(KERN_WARNING "CFSPI: Spurious SS interrupt.\n"); + return; + } + if (!in_interrupt()) spin_lock(&cfspi->lock); if (assert) { @@ -465,7 +482,8 @@ static void cfspi_ss_cb(bool assert, struct cfspi_ifc *ifc) spin_unlock(&cfspi->lock); /* Wake up the xfer thread. */ - wake_up_interruptible(&cfspi->wait); + if (assert) + wake_up_interruptible(&cfspi->wait); } static void cfspi_xfer_done_cb(struct cfspi_ifc *ifc) @@ -523,7 +541,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute head offset i.e. number of bytes added to * get the start of the payload aligned. */ - if (spi_down_head_align) { + if (spi_down_head_align > 1) { spad = 1 + *src; src += spad; } @@ -564,7 +582,7 @@ int cfspi_rxfrm(struct cfspi *cfspi, u8 *buf, size_t len) * Compute tail offset i.e. number of bytes added to * get the complete CAIF frame aligned. */ - epad = (pkt_len + spad) & spi_down_tail_align; + epad = PAD_POW2((pkt_len + spad), spi_down_tail_align); src += epad; } while ((src - buf) < len); @@ -625,11 +643,20 @@ int cfspi_spi_probe(struct platform_device *pdev) cfspi->ndev = ndev; cfspi->pdev = pdev; - /* Set flow info */ + /* Set flow info. */ cfspi->flow_off_sent = 0; cfspi->qd_low_mark = LOW_WATER_MARK; cfspi->qd_high_mark = HIGH_WATER_MARK; + /* Set slave info. */ + if (!strncmp(cfspi_spi_driver.driver.name, "cfspi_sspi", 10)) { + cfspi->slave = true; + cfspi->slave_talked = false; + } else { + cfspi->slave = false; + cfspi->slave_talked = false; + } + /* Assign the SPI device. */ cfspi->dev = dev; /* Assign the device ifc to this SPI interface. */ diff --git a/drivers/net/caif/caif_spi_slave.c b/drivers/net/caif/caif_spi_slave.c index 2111dbfea6fe..1b9943a4edab 100644 --- a/drivers/net/caif/caif_spi_slave.c +++ b/drivers/net/caif/caif_spi_slave.c @@ -36,10 +36,15 @@ static inline int forward_to_spi_cmd(struct cfspi *cfspi) #endif int spi_frm_align = 2; -int spi_up_head_align = 1; -int spi_up_tail_align; -int spi_down_head_align = 3; -int spi_down_tail_align = 1; + +/* + * SPI padding options. + * Warning: must be a base of 2 (& operation used) and can not be zero ! + */ +int spi_up_head_align = 1 << 1; +int spi_up_tail_align = 1 << 0; +int spi_down_head_align = 1 << 2; +int spi_down_tail_align = 1 << 1; #ifdef CONFIG_DEBUG_FS static inline void debugfs_store_prev(struct cfspi *cfspi) diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 407d4e272075..046d846c652d 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c @@ -3341,7 +3341,6 @@ static int __devinit init_one(struct pci_dev *pdev, adapter->name = adapter->port[i]->name; __set_bit(i, &adapter->registered_device_map); - netif_tx_stop_all_queues(adapter->port[i]); } } if (!adapter->registered_device_map) { diff --git a/drivers/net/cxgb4/cxgb4_main.c b/drivers/net/cxgb4/cxgb4_main.c index f17703f410b3..f50bc98310f8 100644 --- a/drivers/net/cxgb4/cxgb4_main.c +++ b/drivers/net/cxgb4/cxgb4_main.c @@ -3736,7 +3736,6 @@ static int __devinit init_one(struct pci_dev *pdev, __set_bit(i, &adapter->registered_device_map); adapter->chan_map[adap2pinfo(adapter, i)->tx_chan] = i; - netif_tx_stop_all_queues(adapter->port[i]); } } if (!adapter->registered_device_map) { diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index 555ecc5a2e93..6de5e2e448a5 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c @@ -2600,7 +2600,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, pi->xact_addr_filt = -1; pi->rx_offload = RX_CSO; netif_carrier_off(netdev); - netif_tx_stop_all_queues(netdev); netdev->irq = pdev->irq; netdev->features = (NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 | diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c index 385dc3204cb7..06bb9b799458 100644 --- a/drivers/net/ibm_newemac/core.c +++ b/drivers/net/ibm_newemac/core.c @@ -2871,7 +2871,6 @@ static int __devinit emac_probe(struct platform_device *ofdev, SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops); netif_carrier_off(ndev); - netif_stop_queue(ndev); err = register_netdev(ndev); if (err) { diff --git a/drivers/net/jme.c b/drivers/net/jme.c index d85edf3119c2..c57d9a43ceca 100644 --- a/drivers/net/jme.c +++ b/drivers/net/jme.c @@ -2955,11 +2955,7 @@ jme_init_one(struct pci_dev *pdev, * Tell stack that we are not ready to work until open() */ netif_carrier_off(netdev); - netif_stop_queue(netdev); - /* - * Register netdev - */ rc = register_netdev(netdev); if (rc) { pr_err("Cannot register net device\n"); diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index a75ba9517404..e1d30d7f2071 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c @@ -41,9 +41,6 @@ MODULE_DESCRIPTION("QLogic/NetXen (1/10) GbE Converged Ethernet Driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID); -MODULE_FIRMWARE(NX_P2_MN_ROMIMAGE_NAME); -MODULE_FIRMWARE(NX_P3_CT_ROMIMAGE_NAME); -MODULE_FIRMWARE(NX_P3_MN_ROMIMAGE_NAME); MODULE_FIRMWARE(NX_UNIFIED_ROMIMAGE_NAME); char netxen_nic_driver_name[] = "netxen_nic"; diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 7a298cdf9ab3..a3dcd04be22f 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1450,7 +1450,6 @@ qlcnic_setup_netdev(struct qlcnic_adapter *adapter, netdev->irq = adapter->msix_entries[0].vector; netif_carrier_off(netdev); - netif_stop_queue(netdev); err = register_netdev(netdev); if (err) { diff --git a/drivers/net/smsc911x.h b/drivers/net/smsc911x.h index 52f38e12a879..50f712e99e96 100644 --- a/drivers/net/smsc911x.h +++ b/drivers/net/smsc911x.h @@ -22,7 +22,7 @@ #define __SMSC911X_H__ #define TX_FIFO_LOW_THRESHOLD ((u32)1600) -#define SMSC911X_EEPROM_SIZE ((u32)7) +#define SMSC911X_EEPROM_SIZE ((u32)128) #define USE_DEBUG 0 /* This is the maximum number of packets to be received every diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index 28e1ffb13db9..c78a50586c1d 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -2021,7 +2021,6 @@ static int __devinit de_init_one (struct pci_dev *pdev, de->media_timer.data = (unsigned long) de; netif_carrier_off(dev); - netif_stop_queue(dev); /* wake up device, assign resources */ rc = pci_enable_device(pdev); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index ca7fc9df1ccf..c04d49e31f81 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -45,6 +45,7 @@ #include <linux/usb/usbnet.h> #include <linux/slab.h> #include <linux/kernel.h> +#include <linux/pm_runtime.h> #define DRIVER_VERSION "22-Aug-2005" @@ -1273,6 +1274,16 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) struct usb_device *xdev; int status; const char *name; + struct usb_driver *driver = to_usb_driver(udev->dev.driver); + + /* usbnet already took usb runtime pm, so have to enable the feature + * for usb interface, otherwise usb_autopm_get_interface may return + * failure if USB_SUSPEND(RUNTIME_PM) is enabled. + */ + if (!driver->supports_autosuspend) { + driver->supports_autosuspend = 1; + pm_runtime_enable(&udev->dev); + } name = udev->dev.driver->name; info = (struct driver_info *) prod->driver_info; diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index 32dee2ce5d31..d5ef696298ee 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -54,6 +54,7 @@ #define DRV_DESCRIPTION "802.11 data/management/control stack" #define DRV_NAME "libipw" +#define DRV_PROCNAME "ieee80211" #define DRV_VERSION LIBIPW_VERSION #define DRV_COPYRIGHT "Copyright (C) 2004-2005 Intel Corporation <jketreno@linux.intel.com>" @@ -293,16 +294,16 @@ static int __init libipw_init(void) struct proc_dir_entry *e; libipw_debug_level = debug; - libipw_proc = proc_mkdir("ieee80211", init_net.proc_net); + libipw_proc = proc_mkdir(DRV_PROCNAME, init_net.proc_net); if (libipw_proc == NULL) { - LIBIPW_ERROR("Unable to create " DRV_NAME + LIBIPW_ERROR("Unable to create " DRV_PROCNAME " proc directory\n"); return -EIO; } e = proc_create("debug_level", S_IRUGO | S_IWUSR, libipw_proc, &debug_level_proc_fops); if (!e) { - remove_proc_entry(DRV_NAME, init_net.proc_net); + remove_proc_entry(DRV_PROCNAME, init_net.proc_net); libipw_proc = NULL; return -EIO; } @@ -319,7 +320,7 @@ static void __exit libipw_exit(void) #ifdef CONFIG_LIBIPW_DEBUG if (libipw_proc) { remove_proc_entry("debug_level", libipw_proc); - remove_proc_entry(DRV_NAME, init_net.proc_net); + remove_proc_entry(DRV_PROCNAME, init_net.proc_net); libipw_proc = NULL; } #endif /* CONFIG_LIBIPW_DEBUG */ diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c index 359d1e04626c..f0d638922644 100644 --- a/drivers/rtc/rtc-ds1302.c +++ b/drivers/rtc/rtc-ds1302.c @@ -35,7 +35,7 @@ #ifdef CONFIG_SH_SECUREEDGE5410 #include <asm/rtc.h> -#include <mach/snapgear.h> +#include <mach/secureedge5410.h> #define RTC_RESET 0x1000 #define RTC_IODATA 0x0800 diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c index fd0d1b98901c..09615b51d591 100644 --- a/drivers/sh/clk/core.c +++ b/drivers/sh/clk/core.c @@ -90,8 +90,8 @@ struct clk_rate_round_data { static long clk_rate_round_helper(struct clk_rate_round_data *rounder) { unsigned long rate_error, rate_error_prev = ~0UL; - unsigned long rate_best_fit = rounder->rate; unsigned long highest, lowest, freq; + long rate_best_fit = -ENOENT; int i; highest = 0; @@ -146,7 +146,7 @@ long clk_rate_table_round(struct clk *clk, }; if (clk->nr_freqs < 1) - return 0; + return -ENOSYS; return clk_rate_round_helper(&table_round); } @@ -541,6 +541,98 @@ long clk_round_rate(struct clk *clk, unsigned long rate) } EXPORT_SYMBOL_GPL(clk_round_rate); +long clk_round_parent(struct clk *clk, unsigned long target, + unsigned long *best_freq, unsigned long *parent_freq, + unsigned int div_min, unsigned int div_max) +{ + struct cpufreq_frequency_table *freq, *best = NULL; + unsigned long error = ULONG_MAX, freq_high, freq_low, div; + struct clk *parent = clk_get_parent(clk); + + if (!parent) { + *parent_freq = 0; + *best_freq = clk_round_rate(clk, target); + return abs(target - *best_freq); + } + + for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END; + freq++) { + if (freq->frequency == CPUFREQ_ENTRY_INVALID) + continue; + + if (unlikely(freq->frequency / target <= div_min - 1)) { + unsigned long freq_max; + + freq_max = (freq->frequency + div_min / 2) / div_min; + if (error > target - freq_max) { + error = target - freq_max; + best = freq; + if (best_freq) + *best_freq = freq_max; + } + + pr_debug("too low freq %lu, error %lu\n", freq->frequency, + target - freq_max); + + if (!error) + break; + + continue; + } + + if (unlikely(freq->frequency / target >= div_max)) { + unsigned long freq_min; + + freq_min = (freq->frequency + div_max / 2) / div_max; + if (error > freq_min - target) { + error = freq_min - target; + best = freq; + if (best_freq) + *best_freq = freq_min; + } + + pr_debug("too high freq %lu, error %lu\n", freq->frequency, + freq_min - target); + + if (!error) + break; + + continue; + } + + div = freq->frequency / target; + freq_high = freq->frequency / div; + freq_low = freq->frequency / (div + 1); + + if (freq_high - target < error) { + error = freq_high - target; + best = freq; + if (best_freq) + *best_freq = freq_high; + } + + if (target - freq_low < error) { + error = target - freq_low; + best = freq; + if (best_freq) + *best_freq = freq_low; + } + + pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n", + freq->frequency, div, freq_high, div + 1, freq_low, + *best_freq, best->frequency); + + if (!error) + break; + } + + if (parent_freq) + *parent_freq = best->frequency; + + return error; +} +EXPORT_SYMBOL_GPL(clk_round_parent); + #ifdef CONFIG_PM static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state) { diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 873a99ff8f64..e5e9e6735f7d 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -79,7 +79,7 @@ static void __init intc_register_irq(struct intc_desc *desc, * Register the IRQ position with the global IRQ map, then insert * it in to the radix tree. */ - irq_reserve_irqs(irq, 1); + irq_reserve_irq(irq); raw_spin_lock_irqsave(&intc_big_lock, flags); radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); diff --git a/drivers/sh/intc/dynamic.c b/drivers/sh/intc/dynamic.c index 4187cce20ffd..a3677c9dfe36 100644 --- a/drivers/sh/intc/dynamic.c +++ b/drivers/sh/intc/dynamic.c @@ -60,5 +60,5 @@ void reserve_intc_vectors(struct intc_vect *vectors, unsigned int nr_vecs) int i; for (i = 0; i < nr_vecs; i++) - irq_reserve_irqs(evt2irq(vectors[i].vect), 1); + irq_reserve_irq(evt2irq(vectors[i].vect)); } diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index cb23355f52d3..fbe86ca95802 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c @@ -811,7 +811,6 @@ int gether_setup(struct usb_gadget *g, u8 ethaddr[ETH_ALEN]) INFO(dev, "MAC %pM\n", net->dev_addr); INFO(dev, "HOST MAC %pM\n", dev->host_mac); - netif_stop_queue(net); the_dev = dev; } diff --git a/fs/cifs/TODO b/fs/cifs/TODO index 5aff46c61e52..355abcdcda98 100644 --- a/fs/cifs/TODO +++ b/fs/cifs/TODO @@ -81,7 +81,7 @@ u) DOS attrs - returned as pseudo-xattr in Samba format (check VFAT and NTFS for v) mount check for unmatched uids -w) Add support for new vfs entry points for setlease and fallocate +w) Add support for new vfs entry point for fallocate x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of processes can proceed better in parallel (on the server) diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 525ba59a4105..e9a393c9c2ca 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -15,7 +15,7 @@ * the GNU Lesser General Public License for more details. * */ -#include <linux/radix-tree.h> +#include <linux/rbtree.h> #ifndef _CIFS_FS_SB_H #define _CIFS_FS_SB_H @@ -42,9 +42,9 @@ #define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */ struct cifs_sb_info { - struct radix_tree_root tlink_tree; -#define CIFS_TLINK_MASTER_TAG 0 /* is "master" (mount) tcon */ + struct rb_root tlink_tree; spinlock_t tlink_tree_lock; + struct tcon_link *master_tlink; struct nls_table *local_nls; unsigned int rsize; unsigned int wsize; diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 75c4eaa79588..9c3789762ab7 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -116,7 +116,7 @@ cifs_read_super(struct super_block *sb, void *data, return -ENOMEM; spin_lock_init(&cifs_sb->tlink_tree_lock); - INIT_RADIX_TREE(&cifs_sb->tlink_tree, GFP_KERNEL); + cifs_sb->tlink_tree = RB_ROOT; rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); if (rc) { @@ -321,8 +321,7 @@ cifs_alloc_inode(struct super_block *sb) /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ - cifs_inode->clientCanCacheRead = false; - cifs_inode->clientCanCacheAll = false; + cifs_set_oplock_level(cifs_inode, 0); cifs_inode->delete_pending = false; cifs_inode->invalid_mapping = false; cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */ diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index f259e4d7612d..b577bf0a1bb3 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -336,7 +336,8 @@ struct cifsTconInfo { * "get" on the container. */ struct tcon_link { - unsigned long tl_index; + struct rb_node tl_rbnode; + uid_t tl_uid; unsigned long tl_flags; #define TCON_LINK_MASTER 0 #define TCON_LINK_PENDING 1 diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index edb6d90efdf2..7ed69b6b5fe6 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -104,6 +104,7 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); extern u64 cifs_UnixTimeToNT(struct timespec); extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset); +extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); extern struct cifsFileInfo *cifs_new_fileinfo(__u16 fileHandle, struct file *file, struct tcon_link *tlink, diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9eb327defa1d..251a17c03545 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -116,6 +116,7 @@ struct smb_vol { static int ipv4_connect(struct TCP_Server_Info *server); static int ipv6_connect(struct TCP_Server_Info *server); +static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); static void cifs_prune_tlinks(struct work_struct *work); /* @@ -2900,24 +2901,16 @@ remote_path_check: goto mount_fail_check; } - tlink->tl_index = pSesInfo->linux_uid; + tlink->tl_uid = pSesInfo->linux_uid; tlink->tl_tcon = tcon; tlink->tl_time = jiffies; set_bit(TCON_LINK_MASTER, &tlink->tl_flags); set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); - rc = radix_tree_preload(GFP_KERNEL); - if (rc == -ENOMEM) { - kfree(tlink); - goto mount_fail_check; - } - + cifs_sb->master_tlink = tlink; spin_lock(&cifs_sb->tlink_tree_lock); - radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink); - radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid, - CIFS_TLINK_MASTER_TAG); + tlink_rb_insert(&cifs_sb->tlink_tree, tlink); spin_unlock(&cifs_sb->tlink_tree_lock); - radix_tree_preload_end(); queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); @@ -3107,32 +3100,25 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, int cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb) { - int i, ret; + struct rb_root *root = &cifs_sb->tlink_tree; + struct rb_node *node; + struct tcon_link *tlink; char *tmp; - struct tcon_link *tlink[8]; - unsigned long index = 0; cancel_delayed_work_sync(&cifs_sb->prune_tlinks); - do { - spin_lock(&cifs_sb->tlink_tree_lock); - ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, - (void **)tlink, index, - ARRAY_SIZE(tlink)); - /* increment index for next pass */ - if (ret > 0) - index = tlink[ret - 1]->tl_index + 1; - for (i = 0; i < ret; i++) { - cifs_get_tlink(tlink[i]); - clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); - radix_tree_delete(&cifs_sb->tlink_tree, - tlink[i]->tl_index); - } - spin_unlock(&cifs_sb->tlink_tree_lock); + spin_lock(&cifs_sb->tlink_tree_lock); + while ((node = rb_first(root))) { + tlink = rb_entry(node, struct tcon_link, tl_rbnode); + cifs_get_tlink(tlink); + clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); + rb_erase(node, root); - for (i = 0; i < ret; i++) - cifs_put_tlink(tlink[i]); - } while (ret != 0); + spin_unlock(&cifs_sb->tlink_tree_lock); + cifs_put_tlink(tlink); + spin_lock(&cifs_sb->tlink_tree_lock); + } + spin_unlock(&cifs_sb->tlink_tree_lock); tmp = cifs_sb->prepath; cifs_sb->prepathlen = 0; @@ -3271,22 +3257,10 @@ out: return tcon; } -static struct tcon_link * +static inline struct tcon_link * cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb) { - struct tcon_link *tlink; - unsigned int ret; - - spin_lock(&cifs_sb->tlink_tree_lock); - ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink, - 0, 1, CIFS_TLINK_MASTER_TAG); - spin_unlock(&cifs_sb->tlink_tree_lock); - - /* the master tcon should always be present */ - if (ret == 0) - BUG(); - - return tlink; + return cifs_sb->master_tlink; } struct cifsTconInfo * @@ -3302,6 +3276,47 @@ cifs_sb_tcon_pending_wait(void *unused) return signal_pending(current) ? -ERESTARTSYS : 0; } +/* find and return a tlink with given uid */ +static struct tcon_link * +tlink_rb_search(struct rb_root *root, uid_t uid) +{ + struct rb_node *node = root->rb_node; + struct tcon_link *tlink; + + while (node) { + tlink = rb_entry(node, struct tcon_link, tl_rbnode); + + if (tlink->tl_uid > uid) + node = node->rb_left; + else if (tlink->tl_uid < uid) + node = node->rb_right; + else + return tlink; + } + return NULL; +} + +/* insert a tcon_link into the tree */ +static void +tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink) +{ + struct rb_node **new = &(root->rb_node), *parent = NULL; + struct tcon_link *tlink; + + while (*new) { + tlink = rb_entry(*new, struct tcon_link, tl_rbnode); + parent = *new; + + if (tlink->tl_uid > new_tlink->tl_uid) + new = &((*new)->rb_left); + else + new = &((*new)->rb_right); + } + + rb_link_node(&new_tlink->tl_rbnode, parent, new); + rb_insert_color(&new_tlink->tl_rbnode, root); +} + /* * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the * current task. @@ -3309,7 +3324,7 @@ cifs_sb_tcon_pending_wait(void *unused) * If the superblock doesn't refer to a multiuser mount, then just return * the master tcon for the mount. * - * First, search the radix tree for an existing tcon for this fsuid. If one + * First, search the rbtree for an existing tcon for this fsuid. If one * exists, then check to see if it's pending construction. If it is then wait * for construction to complete. Once it's no longer pending, check to see if * it failed and either return an error or retry construction, depending on @@ -3322,14 +3337,14 @@ struct tcon_link * cifs_sb_tlink(struct cifs_sb_info *cifs_sb) { int ret; - unsigned long fsuid = (unsigned long) current_fsuid(); + uid_t fsuid = current_fsuid(); struct tcon_link *tlink, *newtlink; if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb)); spin_lock(&cifs_sb->tlink_tree_lock); - tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); + tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); if (tlink) cifs_get_tlink(tlink); spin_unlock(&cifs_sb->tlink_tree_lock); @@ -3338,36 +3353,24 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb) newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL); if (newtlink == NULL) return ERR_PTR(-ENOMEM); - newtlink->tl_index = fsuid; + newtlink->tl_uid = fsuid; newtlink->tl_tcon = ERR_PTR(-EACCES); set_bit(TCON_LINK_PENDING, &newtlink->tl_flags); set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags); cifs_get_tlink(newtlink); - ret = radix_tree_preload(GFP_KERNEL); - if (ret != 0) { - kfree(newtlink); - return ERR_PTR(ret); - } - spin_lock(&cifs_sb->tlink_tree_lock); /* was one inserted after previous search? */ - tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid); + tlink = tlink_rb_search(&cifs_sb->tlink_tree, fsuid); if (tlink) { cifs_get_tlink(tlink); spin_unlock(&cifs_sb->tlink_tree_lock); - radix_tree_preload_end(); kfree(newtlink); goto wait_for_construction; } - ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink); - spin_unlock(&cifs_sb->tlink_tree_lock); - radix_tree_preload_end(); - if (ret) { - kfree(newtlink); - return ERR_PTR(ret); - } tlink = newtlink; + tlink_rb_insert(&cifs_sb->tlink_tree, tlink); + spin_unlock(&cifs_sb->tlink_tree_lock); } else { wait_for_construction: ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING, @@ -3413,39 +3416,39 @@ cifs_prune_tlinks(struct work_struct *work) { struct cifs_sb_info *cifs_sb = container_of(work, struct cifs_sb_info, prune_tlinks.work); - struct tcon_link *tlink[8]; - unsigned long now = jiffies; - unsigned long index = 0; - int i, ret; + struct rb_root *root = &cifs_sb->tlink_tree; + struct rb_node *node = rb_first(root); + struct rb_node *tmp; + struct tcon_link *tlink; - do { - spin_lock(&cifs_sb->tlink_tree_lock); - ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree, - (void **)tlink, index, - ARRAY_SIZE(tlink)); - /* increment index for next pass */ - if (ret > 0) - index = tlink[ret - 1]->tl_index + 1; - for (i = 0; i < ret; i++) { - if (test_bit(TCON_LINK_MASTER, &tlink[i]->tl_flags) || - atomic_read(&tlink[i]->tl_count) != 0 || - time_after(tlink[i]->tl_time + TLINK_IDLE_EXPIRE, - now)) { - tlink[i] = NULL; - continue; - } - cifs_get_tlink(tlink[i]); - clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags); - radix_tree_delete(&cifs_sb->tlink_tree, - tlink[i]->tl_index); - } - spin_unlock(&cifs_sb->tlink_tree_lock); + /* + * Because we drop the spinlock in the loop in order to put the tlink + * it's not guarded against removal of links from the tree. The only + * places that remove entries from the tree are this function and + * umounts. Because this function is non-reentrant and is canceled + * before umount can proceed, this is safe. + */ + spin_lock(&cifs_sb->tlink_tree_lock); + node = rb_first(root); + while (node != NULL) { + tmp = node; + node = rb_next(tmp); + tlink = rb_entry(tmp, struct tcon_link, tl_rbnode); + + if (test_bit(TCON_LINK_MASTER, &tlink->tl_flags) || + atomic_read(&tlink->tl_count) != 0 || + time_after(tlink->tl_time + TLINK_IDLE_EXPIRE, jiffies)) + continue; - for (i = 0; i < ret; i++) { - if (tlink[i] != NULL) - cifs_put_tlink(tlink[i]); - } - } while (ret != 0); + cifs_get_tlink(tlink); + clear_bit(TCON_LINK_IN_TREE, &tlink->tl_flags); + rb_erase(tmp, root); + + spin_unlock(&cifs_sb->tlink_tree_lock); + cifs_put_tlink(tlink); + spin_lock(&cifs_sb->tlink_tree_lock); + } + spin_unlock(&cifs_sb->tlink_tree_lock); queue_delayed_work(system_nrt_wq, &cifs_sb->prune_tlinks, TLINK_IDLE_EXPIRE); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ae82159cf7fa..06c3e83fa387 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -146,12 +146,7 @@ client_can_cache: rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb, xid, NULL); - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = true; - pCifsInode->clientCanCacheRead = true; - cFYI(1, "Exclusive Oplock granted on inode %p", inode); - } else if ((oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = true; + cifs_set_oplock_level(pCifsInode, oplock); return rc; } @@ -253,12 +248,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, list_add_tail(&pCifsFile->flist, &pCifsInode->openFileList); spin_unlock(&cifs_file_list_lock); - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = true; - pCifsInode->clientCanCacheRead = true; - cFYI(1, "Exclusive Oplock inode %p", inode); - } else if ((oplock & 0xF) == OPLOCK_READ) - pCifsInode->clientCanCacheRead = true; + cifs_set_oplock_level(pCifsInode, oplock); file->private_data = pCifsFile; return pCifsFile; @@ -271,8 +261,9 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file, */ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) { + struct inode *inode = cifs_file->dentry->d_inode; struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink); - struct cifsInodeInfo *cifsi = CIFS_I(cifs_file->dentry->d_inode); + struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifsLockInfo *li, *tmp; spin_lock(&cifs_file_list_lock); @@ -288,8 +279,7 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file) if (list_empty(&cifsi->openFileList)) { cFYI(1, "closing last open instance for inode %p", cifs_file->dentry->d_inode); - cifsi->clientCanCacheRead = false; - cifsi->clientCanCacheAll = false; + cifs_set_oplock_level(cifsi, 0); } spin_unlock(&cifs_file_list_lock); @@ -607,8 +597,6 @@ reopen_success: rc = filemap_write_and_wait(inode->i_mapping); mapping_set_error(inode->i_mapping, rc); - pCifsInode->clientCanCacheAll = false; - pCifsInode->clientCanCacheRead = false; if (tcon->unix_ext) rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, xid); @@ -622,18 +610,9 @@ reopen_success: invalidate the current end of file on the server we can not go to the server to get the new inod info */ - if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) { - pCifsInode->clientCanCacheAll = true; - pCifsInode->clientCanCacheRead = true; - cFYI(1, "Exclusive Oplock granted on inode %p", - pCifsFile->dentry->d_inode); - } else if ((oplock & 0xF) == OPLOCK_READ) { - pCifsInode->clientCanCacheRead = true; - pCifsInode->clientCanCacheAll = false; - } else { - pCifsInode->clientCanCacheRead = false; - pCifsInode->clientCanCacheAll = false; - } + + cifs_set_oplock_level(pCifsInode, oplock); + cifs_relock_file(pCifsFile); reopen_error_exit: @@ -775,12 +754,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); tcon = tlink_tcon(((struct cifsFileInfo *)file->private_data)->tlink); - - if (file->private_data == NULL) { - rc = -EBADF; - FreeXid(xid); - return rc; - } netfid = ((struct cifsFileInfo *)file->private_data)->netfid; if ((tcon->ses->capabilities & CAP_UNIX) && @@ -956,6 +929,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, ssize_t cifs_user_write(struct file *file, const char __user *write_data, size_t write_size, loff_t *poffset) { + struct inode *inode = file->f_path.dentry->d_inode; int rc = 0; unsigned int bytes_written = 0; unsigned int total_written; @@ -963,7 +937,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, struct cifsTconInfo *pTcon; int xid, long_op; struct cifsFileInfo *open_file; - struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode); + struct cifsInodeInfo *cifsi = CIFS_I(inode); cifs_sb = CIFS_SB(file->f_path.dentry->d_sb); @@ -1029,21 +1003,17 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data, cifs_stats_bytes_written(pTcon, total_written); - /* since the write may have blocked check these pointers again */ - if ((file->f_path.dentry) && (file->f_path.dentry->d_inode)) { - struct inode *inode = file->f_path.dentry->d_inode; /* Do not update local mtime - server will set its actual value on write - * inode->i_ctime = inode->i_mtime = - * current_fs_time(inode->i_sb);*/ - if (total_written > 0) { - spin_lock(&inode->i_lock); - if (*poffset > file->f_path.dentry->d_inode->i_size) - i_size_write(file->f_path.dentry->d_inode, - *poffset); - spin_unlock(&inode->i_lock); - } - mark_inode_dirty_sync(file->f_path.dentry->d_inode); + * inode->i_ctime = inode->i_mtime = + * current_fs_time(inode->i_sb);*/ + if (total_written > 0) { + spin_lock(&inode->i_lock); + if (*poffset > inode->i_size) + i_size_write(inode, *poffset); + spin_unlock(&inode->i_lock); } + mark_inode_dirty_sync(inode); + FreeXid(xid); return total_written; } @@ -1178,7 +1148,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) { struct cifsFileInfo *open_file; - struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); + struct cifs_sb_info *cifs_sb; bool any_available = false; int rc; @@ -1192,6 +1162,8 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, return NULL; } + cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb); + /* only filter by fsuid on multiuser mounts */ if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)) fsuid_only = false; diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 077bf756f342..2fa22f20cfc5 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c @@ -63,8 +63,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) #ifdef CONFIG_CIFS_POSIX case FS_IOC_GETFLAGS: if (CIFS_UNIX_EXTATTR_CAP & caps) { - if (pSMBFile == NULL) - break; rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid, &ExtAttrBits, &ExtAttrMask); if (rc == 0) @@ -80,8 +78,6 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) rc = -EFAULT; break; } - if (pSMBFile == NULL) - break; /* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid, extAttrBits, &ExtAttrMask);*/ } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index c4e296fe3518..43f10281bc19 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -569,10 +569,9 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) cFYI(1, "file id match, oplock break"); pCifsInode = CIFS_I(netfile->dentry->d_inode); - pCifsInode->clientCanCacheAll = false; - if (pSMB->OplockLevel == 0) - pCifsInode->clientCanCacheRead = false; + cifs_set_oplock_level(pCifsInode, + pSMB->OplockLevel); /* * cifs_oplock_break_put() can't be called * from here. Get reference after queueing @@ -722,3 +721,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb) cifs_sb_master_tcon(cifs_sb)->treeName); } } + +void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock) +{ + oplock &= 0xF; + + if (oplock == OPLOCK_EXCLUSIVE) { + cinode->clientCanCacheAll = true; + cinode->clientCanCacheRead = true; + cFYI(1, "Exclusive Oplock granted on inode %p", + &cinode->vfs_inode); + } else if (oplock == OPLOCK_READ) { + cinode->clientCanCacheAll = false; + cinode->clientCanCacheRead = true; + cFYI(1, "Level II Oplock granted on inode %p", + &cinode->vfs_inode); + } else { + cinode->clientCanCacheAll = false; + cinode->clientCanCacheRead = false; + } +} diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 191616470466..4d78342f3bf0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -5410,9 +5410,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, * will return the blocks that include the delayed allocation * blocks for this file. */ - spin_lock(&EXT4_I(inode)->i_block_reservation_lock); delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; - spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; return 0; diff --git a/include/asm-generic/stat.h b/include/asm-generic/stat.h index 47e64170305d..bd8cad21998e 100644 --- a/include/asm-generic/stat.h +++ b/include/asm-generic/stat.h @@ -33,18 +33,18 @@ struct stat { int st_blksize; /* Optimal block size for I/O. */ int __pad2; long st_blocks; /* Number 512-byte blocks allocated. */ - int st_atime; /* Time of last access. */ - unsigned int st_atime_nsec; - int st_mtime; /* Time of last modification. */ - unsigned int st_mtime_nsec; - int st_ctime; /* Time of last status change. */ - unsigned int st_ctime_nsec; + long st_atime; /* Time of last access. */ + unsigned long st_atime_nsec; + long st_mtime; /* Time of last modification. */ + unsigned long st_mtime_nsec; + long st_ctime; /* Time of last status change. */ + unsigned long st_ctime_nsec; unsigned int __unused4; unsigned int __unused5; }; -#if __BITS_PER_LONG != 64 /* This matches struct stat64 in glibc2.1. Only used for 32 bit. */ +#if __BITS_PER_LONG != 64 || defined(__ARCH_WANT_STAT64) struct stat64 { unsigned long long st_dev; /* Device. */ unsigned long long st_ino; /* File serial number. */ diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h index 4dca992f3093..cea0c38e7a63 100644 --- a/include/linux/sh_clk.h +++ b/include/linux/sh_clk.h @@ -122,6 +122,10 @@ int clk_rate_table_find(struct clk *clk, long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, unsigned int div_max, unsigned long rate); +long clk_round_parent(struct clk *clk, unsigned long target, + unsigned long *best_freq, unsigned long *parent_freq, + unsigned int div_min, unsigned int div_max); + #define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \ { \ .parent = _parent, \ diff --git a/include/net/caif/caif_dev.h b/include/net/caif/caif_dev.h index 6da573c75d54..8eff83b95366 100644 --- a/include/net/caif/caif_dev.h +++ b/include/net/caif/caif_dev.h @@ -28,7 +28,7 @@ struct caif_param { * @sockaddr: Socket address to connect. * @priority: Priority of the connection. * @link_selector: Link selector (high bandwidth or low latency) - * @link_name: Name of the CAIF Link Layer to use. + * @ifindex: kernel index of the interface. * @param: Connect Request parameters (CAIF_SO_REQ_PARAM). * * This struct is used when connecting a CAIF channel. @@ -39,7 +39,7 @@ struct caif_connect_request { struct sockaddr_caif sockaddr; enum caif_channel_priority priority; enum caif_link_selector link_selector; - char link_name[16]; + int ifindex; struct caif_param param; }; diff --git a/include/net/caif/caif_spi.h b/include/net/caif/caif_spi.h index ce4570dff020..87c3d11b8e55 100644 --- a/include/net/caif/caif_spi.h +++ b/include/net/caif/caif_spi.h @@ -121,6 +121,8 @@ struct cfspi { wait_queue_head_t wait; spinlock_t lock; bool flow_stop; + bool slave; + bool slave_talked; #ifdef CONFIG_DEBUG_FS enum cfspi_state dbg_state; u16 pcmd; diff --git a/include/net/caif/cfcnfg.h b/include/net/caif/cfcnfg.h index bd646faffa47..f688478bfb84 100644 --- a/include/net/caif/cfcnfg.h +++ b/include/net/caif/cfcnfg.h @@ -139,10 +139,10 @@ struct dev_info *cfcnfg_get_phyid(struct cfcnfg *cnfg, enum cfcnfg_phy_preference phy_pref); /** - * cfcnfg_get_named() - Get the Physical Identifier of CAIF Link Layer + * cfcnfg_get_id_from_ifi() - Get the Physical Identifier of ifindex, + * it matches caif physical id with the kernel interface id. * @cnfg: Configuration object - * @name: Name of the Physical Layer (Caif Link Layer) + * @ifi: ifindex obtained from socket.c bindtodevice. */ -int cfcnfg_get_named(struct cfcnfg *cnfg, char *name); - +int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi); #endif /* CFCNFG_H_ */ diff --git a/include/net/netlink.h b/include/net/netlink.h index f3b201d335b3..9801c55de5d6 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -384,7 +384,7 @@ static inline int nlmsg_parse(const struct nlmsghdr *nlh, int hdrlen, * * Returns the first attribute which matches the specified type. */ -static inline struct nlattr *nlmsg_find_attr(struct nlmsghdr *nlh, +static inline struct nlattr *nlmsg_find_attr(const struct nlmsghdr *nlh, int hdrlen, int attrtype) { return nla_find(nlmsg_attrdata(nlh, hdrlen), diff --git a/kernel/exit.c b/kernel/exit.c index b194febf5799..21aa7b3001fb 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -96,6 +96,14 @@ static void __exit_signal(struct task_struct *tsk) sig->tty = NULL; } else { /* + * This can only happen if the caller is de_thread(). + * FIXME: this is the temporary hack, we should teach + * posix-cpu-timers to handle this case correctly. + */ + if (unlikely(has_group_leader_pid(tsk))) + posix_cpu_timers_exit_group(tsk); + + /* * If there is any task waiting for the group exit * then notify it: */ diff --git a/kernel/relay.c b/kernel/relay.c index c7cf397fb929..859ea5a9605f 100644 --- a/kernel/relay.c +++ b/kernel/relay.c @@ -70,17 +70,10 @@ static const struct vm_operations_struct relay_file_mmap_ops = { */ static struct page **relay_alloc_page_array(unsigned int n_pages) { - struct page **array; - size_t pa_size = n_pages * sizeof(struct page *); - - if (pa_size > PAGE_SIZE) { - array = vmalloc(pa_size); - if (array) - memset(array, 0, pa_size); - } else { - array = kzalloc(pa_size, GFP_KERNEL); - } - return array; + const size_t pa_size = n_pages * sizeof(struct page *); + if (pa_size > PAGE_SIZE) + return vzalloc(pa_size); + return kzalloc(pa_size, GFP_KERNEL); } /* diff --git a/kernel/watchdog.c b/kernel/watchdog.c index bafba687a6d8..6e3c41a4024c 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -43,7 +43,7 @@ static DEFINE_PER_CPU(unsigned long, hrtimer_interrupts_saved); static DEFINE_PER_CPU(struct perf_event *, watchdog_ev); #endif -static int __initdata no_watchdog; +static int no_watchdog; /* boot commands */ diff --git a/mm/filemap.c b/mm/filemap.c index 75572b5f2374..61ba5e405791 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1563,8 +1563,10 @@ retry_find: goto no_cached_page; } - if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) + if (!lock_page_or_retry(page, vma->vm_mm, vmf->flags)) { + page_cache_release(page); return ret | VM_FAULT_RETRY; + } /* Did it get truncated? */ if (unlikely(page->mapping != mapping)) { diff --git a/mm/vmstat.c b/mm/vmstat.c index cd2e42be7b68..42eac4d33216 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c @@ -949,7 +949,7 @@ static void *vmstat_start(struct seq_file *m, loff_t *pos) v[PGPGIN] /= 2; /* sectors -> kbytes */ v[PGPGOUT] /= 2; #endif - return m->private + *pos; + return (unsigned long *)m->private + *pos; } static void *vmstat_next(struct seq_file *m, void *arg, loff_t *pos) diff --git a/net/caif/caif_config_util.c b/net/caif/caif_config_util.c index 76ae68303d3a..d522d8c1703e 100644 --- a/net/caif/caif_config_util.c +++ b/net/caif/caif_config_util.c @@ -16,11 +16,18 @@ int connect_req_to_link_param(struct cfcnfg *cnfg, { struct dev_info *dev_info; enum cfcnfg_phy_preference pref; + int res; + memset(l, 0, sizeof(*l)); - l->priority = s->priority; + /* In caif protocol low value is high priority */ + l->priority = CAIF_PRIO_MAX - s->priority + 1; - if (s->link_name[0] != '\0') - l->phyid = cfcnfg_get_named(cnfg, s->link_name); + if (s->ifindex != 0){ + res = cfcnfg_get_id_from_ifi(cnfg, s->ifindex); + if (res < 0) + return res; + l->phyid = res; + } else { switch (s->link_selector) { case CAIF_LINK_HIGH_BANDW: diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index b99369a055d1..a42a408306e4 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c @@ -307,6 +307,8 @@ static int caif_device_notify(struct notifier_block *me, unsigned long what, case NETDEV_UNREGISTER: caifd = caif_get(dev); + if (caifd == NULL) + break; netdev_info(dev, "unregister\n"); atomic_set(&caifd->state, what); caif_device_destroy(dev); diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 2eca2dd0000f..1bf0cf503796 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c @@ -716,8 +716,7 @@ static int setsockopt(struct socket *sock, { struct sock *sk = sock->sk; struct caifsock *cf_sk = container_of(sk, struct caifsock, sk); - int prio, linksel; - struct ifreq ifreq; + int linksel; if (cf_sk->sk.sk_socket->state != SS_UNCONNECTED) return -ENOPROTOOPT; @@ -735,33 +734,6 @@ static int setsockopt(struct socket *sock, release_sock(&cf_sk->sk); return 0; - case SO_PRIORITY: - if (lvl != SOL_SOCKET) - goto bad_sol; - if (ol < sizeof(int)) - return -EINVAL; - if (copy_from_user(&prio, ov, sizeof(int))) - return -EINVAL; - lock_sock(&(cf_sk->sk)); - cf_sk->conn_req.priority = prio; - release_sock(&cf_sk->sk); - return 0; - - case SO_BINDTODEVICE: - if (lvl != SOL_SOCKET) - goto bad_sol; - if (ol < sizeof(struct ifreq)) - return -EINVAL; - if (copy_from_user(&ifreq, ov, sizeof(ifreq))) - return -EFAULT; - lock_sock(&(cf_sk->sk)); - strncpy(cf_sk->conn_req.link_name, ifreq.ifr_name, - sizeof(cf_sk->conn_req.link_name)); - cf_sk->conn_req.link_name - [sizeof(cf_sk->conn_req.link_name)-1] = 0; - release_sock(&cf_sk->sk); - return 0; - case CAIFSO_REQ_PARAM: if (lvl != SOL_CAIF) goto bad_sol; @@ -880,6 +852,18 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, sock->state = SS_CONNECTING; sk->sk_state = CAIF_CONNECTING; + /* Check priority value comming from socket */ + /* if priority value is out of range it will be ajusted */ + if (cf_sk->sk.sk_priority > CAIF_PRIO_MAX) + cf_sk->conn_req.priority = CAIF_PRIO_MAX; + else if (cf_sk->sk.sk_priority < CAIF_PRIO_MIN) + cf_sk->conn_req.priority = CAIF_PRIO_MIN; + else + cf_sk->conn_req.priority = cf_sk->sk.sk_priority; + + /*ifindex = id of the interface.*/ + cf_sk->conn_req.ifindex = cf_sk->sk.sk_bound_dev_if; + dbfs_atomic_inc(&cnt.num_connect_req); cf_sk->layer.receive = caif_sktrecv_cb; err = caif_connect_client(&cf_sk->conn_req, @@ -905,6 +889,7 @@ static int caif_connect(struct socket *sock, struct sockaddr *uaddr, cf_sk->maxframe = mtu - (headroom + tailroom); if (cf_sk->maxframe < 1) { pr_warn("CAIF Interface MTU too small (%d)\n", dev->mtu); + err = -ENODEV; goto out; } @@ -1142,7 +1127,7 @@ static int caif_create(struct net *net, struct socket *sock, int protocol, set_rx_flow_on(cf_sk); /* Set default options on configuration */ - cf_sk->conn_req.priority = CAIF_PRIO_NORMAL; + cf_sk->sk.sk_priority= CAIF_PRIO_NORMAL; cf_sk->conn_req.link_selector = CAIF_LINK_LOW_LATENCY; cf_sk->conn_req.protocol = protocol; /* Increase the number of sockets created. */ diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 41adafd18914..21ede141018a 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c @@ -173,18 +173,15 @@ static struct cfcnfg_phyinfo *cfcnfg_get_phyinfo(struct cfcnfg *cnfg, return NULL; } -int cfcnfg_get_named(struct cfcnfg *cnfg, char *name) + +int cfcnfg_get_id_from_ifi(struct cfcnfg *cnfg, int ifi) { int i; - - /* Try to match with specified name */ - for (i = 0; i < MAX_PHY_LAYERS; i++) { - if (cnfg->phy_layers[i].frm_layer != NULL - && strcmp(cnfg->phy_layers[i].phy_layer->name, - name) == 0) - return cnfg->phy_layers[i].frm_layer->id; - } - return 0; + for (i = 0; i < MAX_PHY_LAYERS; i++) + if (cnfg->phy_layers[i].frm_layer != NULL && + cnfg->phy_layers[i].ifindex == ifi) + return i; + return -ENODEV; } int cfcnfg_disconn_adapt_layer(struct cfcnfg *cnfg, struct cflayer *adap_layer) diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index 08f267a109aa..3cd8f978e309 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c @@ -361,11 +361,10 @@ void cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer) struct cfctrl_request_info *p, *tmp; struct cfctrl *ctrl = container_obj(layr); spin_lock(&ctrl->info_list_lock); - pr_warn("enter\n"); list_for_each_entry_safe(p, tmp, &ctrl->list, list) { if (p->client_layer == adap_layer) { - pr_warn("cancel req :%d\n", p->sequence_no); + pr_debug("cancel req :%d\n", p->sequence_no); list_del(&p->list); kfree(p); } diff --git a/net/caif/cfdbgl.c b/net/caif/cfdbgl.c index 496fda9ac66f..11a2af4c162a 100644 --- a/net/caif/cfdbgl.c +++ b/net/caif/cfdbgl.c @@ -12,6 +12,8 @@ #include <net/caif/cfsrvl.h> #include <net/caif/cfpkt.h> +#define container_obj(layr) ((struct cfsrvl *) layr) + static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt); static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt); @@ -38,5 +40,17 @@ static int cfdbgl_receive(struct cflayer *layr, struct cfpkt *pkt) static int cfdbgl_transmit(struct cflayer *layr, struct cfpkt *pkt) { + struct cfsrvl *service = container_obj(layr); + struct caif_payload_info *info; + int ret; + + if (!cfsrvl_ready(service, &ret)) + return ret; + + /* Add info for MUX-layer to route the packet out */ + info = cfpkt_info(pkt); + info->channel_id = service->layer.id; + info->dev_info = &service->dev_info; + return layr->dn->transmit(layr->dn, pkt); } diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index bde8481e8d25..e2fb5fa75795 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -193,7 +193,7 @@ out: static int cfrfml_transmit_segment(struct cfrfml *rfml, struct cfpkt *pkt) { - caif_assert(cfpkt_getlen(pkt) >= rfml->fragment_size); + caif_assert(cfpkt_getlen(pkt) < rfml->fragment_size); /* Add info for MUX-layer to route the packet out. */ cfpkt_info(pkt)->channel_id = rfml->serv.layer.id; diff --git a/net/core/dev.c b/net/core/dev.c index 35dfb8318483..0dd54a69dace 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2131,7 +2131,7 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev, } else { struct sock *sk = skb->sk; queue_index = sk_tx_queue_get(sk); - if (queue_index < 0) { + if (queue_index < 0 || queue_index >= dev->real_num_tx_queues) { queue_index = 0; if (dev->real_num_tx_queues > 1) diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h index a29edf2219c8..c079cc0ec651 100644 --- a/net/ipv4/fib_lookup.h +++ b/net/ipv4/fib_lookup.h @@ -47,11 +47,8 @@ extern int fib_detect_death(struct fib_info *fi, int order, static inline void fib_result_assign(struct fib_result *res, struct fib_info *fi) { - if (res->fi != NULL) - fib_info_put(res->fi); + /* we used to play games with refcounts, but we now use RCU */ res->fi = fi; - if (fi != NULL) - atomic_inc(&fi->fib_clntref); } #endif /* _FIB_LOOKUP_H */ diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index ba8042665849..2ada17129fce 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -490,9 +490,11 @@ static int inet_csk_diag_dump(struct sock *sk, { struct inet_diag_req *r = NLMSG_DATA(cb->nlh); - if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { + if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { struct inet_diag_entry entry; - struct rtattr *bc = (struct rtattr *)(r + 1); + const struct nlattr *bc = nlmsg_find_attr(cb->nlh, + sizeof(*r), + INET_DIAG_REQ_BYTECODE); struct inet_sock *inet = inet_sk(sk); entry.family = sk->sk_family; @@ -512,7 +514,7 @@ static int inet_csk_diag_dump(struct sock *sk, entry.dport = ntohs(inet->inet_dport); entry.userlocks = sk->sk_userlocks; - if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) + if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) return 0; } @@ -527,9 +529,11 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, { struct inet_diag_req *r = NLMSG_DATA(cb->nlh); - if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { + if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { struct inet_diag_entry entry; - struct rtattr *bc = (struct rtattr *)(r + 1); + const struct nlattr *bc = nlmsg_find_attr(cb->nlh, + sizeof(*r), + INET_DIAG_REQ_BYTECODE); entry.family = tw->tw_family; #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) @@ -548,7 +552,7 @@ static int inet_twsk_diag_dump(struct inet_timewait_sock *tw, entry.dport = ntohs(tw->tw_dport); entry.userlocks = 0; - if (!inet_diag_bc_run(RTA_DATA(bc), RTA_PAYLOAD(bc), &entry)) + if (!inet_diag_bc_run(nla_data(bc), nla_len(bc), &entry)) return 0; } @@ -618,7 +622,7 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, struct inet_diag_req *r = NLMSG_DATA(cb->nlh); struct inet_connection_sock *icsk = inet_csk(sk); struct listen_sock *lopt; - struct rtattr *bc = NULL; + const struct nlattr *bc = NULL; struct inet_sock *inet = inet_sk(sk); int j, s_j; int reqnum, s_reqnum; @@ -638,8 +642,9 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, if (!lopt || !lopt->qlen) goto out; - if (cb->nlh->nlmsg_len > 4 + NLMSG_SPACE(sizeof(*r))) { - bc = (struct rtattr *)(r + 1); + if (nlmsg_attrlen(cb->nlh, sizeof(*r))) { + bc = nlmsg_find_attr(cb->nlh, sizeof(*r), + INET_DIAG_REQ_BYTECODE); entry.sport = inet->inet_num; entry.userlocks = sk->sk_userlocks; } @@ -672,8 +677,8 @@ static int inet_diag_dump_reqs(struct sk_buff *skb, struct sock *sk, &ireq->rmt_addr; entry.dport = ntohs(ireq->rmt_port); - if (!inet_diag_bc_run(RTA_DATA(bc), - RTA_PAYLOAD(bc), &entry)) + if (!inet_diag_bc_run(nla_data(bc), + nla_len(bc), &entry)) continue; } diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 3cad2591ace0..3fac340a28d5 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c @@ -927,6 +927,7 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif + memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index d31b007a6d80..a846d633b3b6 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c @@ -1124,6 +1124,7 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif + memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 295c97431e43..c04787ce1a71 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c @@ -47,26 +47,6 @@ __nf_nat_proto_find(u_int8_t protonum) return rcu_dereference(nf_nat_protos[protonum]); } -static const struct nf_nat_protocol * -nf_nat_proto_find_get(u_int8_t protonum) -{ - const struct nf_nat_protocol *p; - - rcu_read_lock(); - p = __nf_nat_proto_find(protonum); - if (!try_module_get(p->me)) - p = &nf_nat_unknown_protocol; - rcu_read_unlock(); - - return p; -} - -static void -nf_nat_proto_put(const struct nf_nat_protocol *p) -{ - module_put(p->me); -} - /* We keep an extra hash for each conntrack, for fast searching. */ static inline unsigned int hash_by_src(const struct net *net, u16 zone, @@ -588,6 +568,26 @@ static struct nf_ct_ext_type nat_extend __read_mostly = { #include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/nfnetlink_conntrack.h> +static const struct nf_nat_protocol * +nf_nat_proto_find_get(u_int8_t protonum) +{ + const struct nf_nat_protocol *p; + + rcu_read_lock(); + p = __nf_nat_proto_find(protonum); + if (!try_module_get(p->me)) + p = &nf_nat_unknown_protocol; + rcu_read_unlock(); + + return p; +} + +static void +nf_nat_proto_put(const struct nf_nat_protocol *p) +{ + module_put(p->me); +} + static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = { [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 }, [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 }, diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 51df035897e7..455582384ece 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -1137,6 +1137,7 @@ static int get_info(struct net *net, void __user *user, private = &tmp; } #endif + memset(&info, 0, sizeof(info)); info.valid_hooks = t->valid_hooks; memcpy(info.hook_entry, private->hook_entry, sizeof(info.hook_entry)); diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 25661f968f3f..fc328339be99 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -2741,6 +2741,7 @@ static void __net_exit ip6_route_net_exit(struct net *net) kfree(net->ipv6.ip6_prohibit_entry); kfree(net->ipv6.ip6_blk_hole_entry); #endif + dst_entries_destroy(&net->ipv6.ip6_dst_ops); } static struct pernet_operations ip6_route_net_ops = { @@ -2832,5 +2833,6 @@ void ip6_route_cleanup(void) xfrm6_fini(); fib6_gc_cleanup(); unregister_pernet_subsys(&ip6_route_net_ops); + dst_entries_destroy(&ip6_dst_blackhole_ops); kmem_cache_destroy(ip6_dst_ops_template.kmem_cachep); } diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c index 104ec3b283d4..b8dbae82fab8 100644 --- a/net/l2tp/l2tp_debugfs.c +++ b/net/l2tp/l2tp_debugfs.c @@ -249,7 +249,7 @@ static int l2tp_dfs_seq_open(struct inode *inode, struct file *file) struct seq_file *seq; int rc = -ENOMEM; - pd = kzalloc(GFP_KERNEL, sizeof(*pd)); + pd = kzalloc(sizeof(*pd), GFP_KERNEL); if (pd == NULL) goto out; diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 1eacf8d9966a..27a5ea6b6a0f 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c @@ -1312,7 +1312,8 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls) if (!hash) { *vmalloced = 1; printk(KERN_WARNING "nf_conntrack: falling back to vmalloc.\n"); - hash = __vmalloc(sz, GFP_KERNEL | __GFP_ZERO, PAGE_KERNEL); + hash = __vmalloc(sz, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO, + PAGE_KERNEL); } if (hash && nulls) diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c index ed6d92958023..dc7bb74110df 100644 --- a/net/netfilter/nf_conntrack_proto.c +++ b/net/netfilter/nf_conntrack_proto.c @@ -292,6 +292,12 @@ int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto) for (i = 0; i < MAX_NF_CT_PROTO; i++) proto_array[i] = &nf_conntrack_l4proto_generic; + + /* Before making proto_array visible to lockless readers, + * we must make sure its content is committed to memory. + */ + smp_wmb(); + nf_ct_protos[l4proto->l3proto] = proto_array; } else if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != &nf_conntrack_l4proto_generic) { diff --git a/net/rds/loop.c b/net/rds/loop.c index c390156b426f..aeec1d483b17 100644 --- a/net/rds/loop.c +++ b/net/rds/loop.c @@ -134,8 +134,12 @@ static int rds_loop_conn_alloc(struct rds_connection *conn, gfp_t gfp) static void rds_loop_conn_free(void *arg) { struct rds_loop_connection *lc = arg; + unsigned long flags; + rdsdebug("lc %p\n", lc); + spin_lock_irqsave(&loop_conns_lock, flags); list_del(&lc->loop_node); + spin_unlock_irqrestore(&loop_conns_lock, flags); kfree(lc); } diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 08a8c6cf2d10..8e0a32001c90 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c @@ -221,7 +221,13 @@ static int rds_tcp_conn_alloc(struct rds_connection *conn, gfp_t gfp) static void rds_tcp_conn_free(void *arg) { struct rds_tcp_connection *tc = arg; + unsigned long flags; rdsdebug("freeing tc %p\n", tc); + + spin_lock_irqsave(&rds_tcp_conn_lock, flags); + list_del(&tc->t_tcp_node); + spin_unlock_irqrestore(&rds_tcp_conn_lock, flags); + kmem_cache_free(rds_tcp_conn_slab, tc); } diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 37dff78e9cb1..d49c40fb7e09 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -34,8 +34,6 @@ struct cgroup_subsys net_cls_subsys = { .populate = cgrp_populate, #ifdef CONFIG_NET_CLS_CGROUP .subsys_id = net_cls_subsys_id, -#else -#define net_cls_subsys_id net_cls_subsys.subsys_id #endif .module = THIS_MODULE, }; diff --git a/net/sched/em_text.c b/net/sched/em_text.c index 763253257411..ea8f566e720c 100644 --- a/net/sched/em_text.c +++ b/net/sched/em_text.c @@ -103,7 +103,8 @@ retry: static void em_text_destroy(struct tcf_proto *tp, struct tcf_ematch *m) { - textsearch_destroy(EM_TEXT_PRIV(m)->config); + if (EM_TEXT_PRIV(m) && EM_TEXT_PRIV(m)->config) + textsearch_destroy(EM_TEXT_PRIV(m)->config); } static int em_text_dump(struct sk_buff *skb, struct tcf_ematch *m) diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index 771bab00754b..3a8c4c419cd4 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -134,15 +134,15 @@ int x25_parse_facilities(struct sk_buff *skb, struct x25_facilities *facilities, case X25_FAC_CLASS_D: switch (*p) { case X25_FAC_CALLING_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN) - break; + if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) + return 0; dte_facs->calling_len = p[2]; memcpy(dte_facs->calling_ae, &p[3], p[1] - 1); *vc_fac_mask |= X25_MASK_CALLING_AE; break; case X25_FAC_CALLED_AE: - if (p[1] > X25_MAX_DTE_FACIL_LEN) - break; + if (p[1] > X25_MAX_DTE_FACIL_LEN || p[1] <= 1) + return 0; dte_facs->called_len = p[2]; memcpy(dte_facs->called_ae, &p[3], p[1] - 1); *vc_fac_mask |= X25_MASK_CALLED_AE; diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index 63178961efac..f729f022be69 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c @@ -119,6 +119,8 @@ static int x25_state1_machine(struct sock *sk, struct sk_buff *skb, int frametyp &x25->vc_facil_mask); if (len > 0) skb_pull(skb, len); + else + return -1; /* * Copy any Call User Data. */ diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index f7e374ec4414..1b9bf9395cfe 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c @@ -625,6 +625,8 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao, control_cache_size, (struct hpi_control_cache_info *) &phw->control_cache[0] ); + if (!phw->p_cache) + pao->has_control_cache = 0; } else pao->has_control_cache = 0; diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 22c5fc625533..2672f6591ceb 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -644,6 +644,8 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, interface->control_cache.size_in_bytes, (struct hpi_control_cache_info *) p_control_cache_virtual); + if (!phw->p_cache) + err = HPI_ERROR_MEMORY_ALLOC; } if (!err) { err = hpios_locked_mem_get_phys_addr(&phw-> diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index dda4f1c6f658..d67f4d3db911 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c @@ -571,14 +571,20 @@ struct hpi_control_cache *hpi_alloc_control_cache(const u32 { struct hpi_control_cache *p_cache = kmalloc(sizeof(*p_cache), GFP_KERNEL); + if (!p_cache) + return NULL; + p_cache->p_info = + kmalloc(sizeof(*p_cache->p_info) * number_of_controls, + GFP_KERNEL); + if (!p_cache->p_info) { + kfree(p_cache); + return NULL; + } p_cache->cache_size_in_bytes = size_in_bytes; p_cache->control_count = number_of_controls; p_cache->p_cache = (struct hpi_control_cache_single *)pDSP_control_buffer; p_cache->init = 0; - p_cache->p_info = - kmalloc(sizeof(*p_cache->p_info) * p_cache->control_count, - GFP_KERNEL); return p_cache; } diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 3e5ca8fb519f..e377287192aa 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -225,39 +225,25 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) { struct dsp_spos_instance * ins = kzalloc(sizeof(struct dsp_spos_instance), GFP_KERNEL); - if (ins == NULL) + if (ins == NULL) return NULL; /* better to use vmalloc for this big table */ - ins->symbol_table.nsymbols = 0; ins->symbol_table.symbols = vmalloc(sizeof(struct dsp_symbol_entry) * DSP_MAX_SYMBOLS); - ins->symbol_table.highest_frag_index = 0; - - if (ins->symbol_table.symbols == NULL) { + ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); + ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); + if (!ins->symbol_table.symbols || !ins->code.data || !ins->modules) { cs46xx_dsp_spos_destroy(chip); goto error; } - + ins->symbol_table.nsymbols = 0; + ins->symbol_table.highest_frag_index = 0; ins->code.offset = 0; ins->code.size = 0; - ins->code.data = kmalloc(DSP_CODE_BYTE_SIZE, GFP_KERNEL); - - if (ins->code.data == NULL) { - cs46xx_dsp_spos_destroy(chip); - goto error; - } - ins->nscb = 0; ins->ntask = 0; - ins->nmodules = 0; - ins->modules = kmalloc(sizeof(struct dsp_module_desc) * DSP_MAX_MODULES, GFP_KERNEL); - - if (ins->modules == NULL) { - cs46xx_dsp_spos_destroy(chip); - goto error; - } /* default SPDIF input sample rate to 48000 khz */ @@ -271,8 +257,8 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) /* set left and right validity bits and default channel status */ - ins->spdif_csuv_default = - ins->spdif_csuv_stream = + ins->spdif_csuv_default = + ins->spdif_csuv_stream = /* byte 0 */ ((unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF & 0xff)) << 24) | /* byte 1 */ ((unsigned int)_wrap_all_bits( ((SNDRV_PCM_DEFAULT_CON_SPDIF >> 8) & 0xff)) << 16) | /* byte 3 */ (unsigned int)_wrap_all_bits( (SNDRV_PCM_DEFAULT_CON_SPDIF >> 24) & 0xff) | @@ -281,6 +267,9 @@ struct dsp_spos_instance *cs46xx_dsp_spos_create (struct snd_cs46xx * chip) return ins; error: + kfree(ins->modules); + kfree(ins->code.data); + vfree(ins->symbol_table.symbols); kfree(ins); return NULL; } diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 460fb2ef7e39..18af38ebf757 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c @@ -1166,6 +1166,7 @@ static const char *cs420x_models[CS420X_MODELS] = { static struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), + SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index ef9af3f4ace2..1bd7a540fd49 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c @@ -425,7 +425,7 @@ exit: static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) { struct snd_pcm_substream *substream = lx_stream->stream; - const int is_capture = lx_stream->is_capture; + const unsigned int is_capture = lx_stream->is_capture; int err; @@ -473,7 +473,7 @@ static void lx_trigger_start(struct lx6464es *chip, struct lx_stream *lx_stream) static void lx_trigger_stop(struct lx6464es *chip, struct lx_stream *lx_stream) { - const int is_capture = lx_stream->is_capture; + const unsigned int is_capture = lx_stream->is_capture; int err; snd_printd(LXP "stopping: stopping stream\n"); diff --git a/sound/pci/lx6464es/lx6464es.h b/sound/pci/lx6464es/lx6464es.h index 51afc048961d..aea621eafbb5 100644 --- a/sound/pci/lx6464es/lx6464es.h +++ b/sound/pci/lx6464es/lx6464es.h @@ -60,7 +60,7 @@ struct lx_stream { snd_pcm_uframes_t frame_pos; enum lx_stream_status status; /* free, open, running, draining * pause */ - int is_capture:1; + unsigned int is_capture:1; }; diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 3086b751da4a..617f98b0cbae 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -1152,7 +1152,7 @@ static int lx_interrupt_request_new_buffer(struct lx6464es *chip, struct lx_stream *lx_stream) { struct snd_pcm_substream *substream = lx_stream->stream; - int is_capture = lx_stream->is_capture; + const unsigned int is_capture = lx_stream->is_capture; int err; unsigned long flags; diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 94a9d06b9027..3b5690d28b8b 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -25,8 +25,9 @@ config SND_SOC_ALL_CODECS select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C select SND_SOC_CS4270 if I2C + select SND_SOC_CX20442 select SND_SOC_DA7210 if I2C - select SND_SOC_JZ4740 if SOC_JZ4740 + select SND_SOC_JZ4740_CODEC if SOC_JZ4740 select SND_SOC_MAX98088 if I2C select SND_SOC_MAX9877 if I2C select SND_SOC_PCM3008 diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index d251ff54a2d3..c5ab8c805771 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -58,7 +58,7 @@ (1000000000 / ((rate * 1000) / samples)) #define US_TO_SAMPLES(rate, us) \ - (rate / (1000000 / us)) + (rate / (1000000 / (us < 1000000 ? us : 1000000))) #define UTHR_FROM_PERIOD_SIZE(samples, playrate, burstrate) \ ((samples * 5000) / ((burstrate * 5000) / (burstrate - playrate))) @@ -200,7 +200,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, u8 *value) { struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int val; + int val, ret = 0; *value = reg & 0xff; @@ -210,6 +210,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, if (val < 0) { dev_err(codec->dev, "Read failed (%d)\n", val); value[0] = dac33_read_reg_cache(codec, reg); + ret = val; } else { value[0] = val; dac33_write_reg_cache(codec, reg, val); @@ -218,7 +219,7 @@ static int dac33_read(struct snd_soc_codec *codec, unsigned int reg, value[0] = dac33_read_reg_cache(codec, reg); } - return 0; + return ret; } static int dac33_write(struct snd_soc_codec *codec, unsigned int reg, @@ -329,13 +330,18 @@ static void dac33_init_chip(struct snd_soc_codec *codec) dac33_read_reg_cache(codec, DAC33_LINER_TO_RLO_VOL)); } -static inline void dac33_read_id(struct snd_soc_codec *codec) +static inline int dac33_read_id(struct snd_soc_codec *codec) { + int i, ret = 0; u8 reg; - dac33_read(codec, DAC33_DEVICE_ID_MSB, ®); - dac33_read(codec, DAC33_DEVICE_ID_LSB, ®); - dac33_read(codec, DAC33_DEVICE_REV_ID, ®); + for (i = 0; i < 3; i++) { + ret = dac33_read(codec, DAC33_DEVICE_ID_MSB + i, ®); + if (ret < 0) + break; + } + + return ret; } static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) @@ -1076,6 +1082,9 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) /* Number of samples under i2c latency */ dac33->alarm_threshold = US_TO_SAMPLES(rate, dac33->mode1_latency); + nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - + dac33->alarm_threshold; + if (dac33->auto_fifo_config) { if (period_size <= dac33->alarm_threshold) /* @@ -1086,6 +1095,8 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) ((dac33->alarm_threshold / period_size) + (dac33->alarm_threshold % period_size ? 1 : 0)); + else if (period_size > nsample_limit) + dac33->nsample = nsample_limit; else dac33->nsample = period_size; } else { @@ -1097,8 +1108,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) */ dac33->nsample_max = substream->runtime->buffer_size - period_size; - nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - - dac33->alarm_threshold; + if (dac33->nsample_max > nsample_limit) dac33->nsample_max = nsample_limit; @@ -1414,9 +1424,15 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) dev_err(codec->dev, "Failed to power up codec: %d\n", ret); goto err_power; } - dac33_read_id(codec); + ret = dac33_read_id(codec); dac33_hard_power(codec, 0); + if (ret < 0) { + dev_err(codec->dev, "Failed to read chip ID: %d\n", ret); + ret = -ENODEV; + goto err_power; + } + /* Check if the IRQ number is valid and request it */ if (dac33->irq >= 0) { ret = request_irq(dac33->irq, dac33_interrupt_handler, diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 329acc1a2074..ee4fb201de60 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -119,13 +119,13 @@ static int tpa6130a2_power(int power) { struct tpa6130a2_data *data; u8 val; - int ret; + int ret = 0; BUG_ON(tpa6130a2_client == NULL); data = i2c_get_clientdata(tpa6130a2_client); mutex_lock(&data->mutex); - if (power) { + if (power && !data->power_state) { /* Power on */ if (data->power_gpio >= 0) gpio_set_value(data->power_gpio, 1); @@ -153,7 +153,7 @@ static int tpa6130a2_power(int power) val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val &= ~TPA6130A2_SWS; tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); - } else { + } else if (!power && data->power_state) { /* set SWS */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val |= TPA6130A2_SWS; diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index b4f11724a63f..aca4b1ea10bb 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -186,7 +186,6 @@ static int wm8900_volatile_register(unsigned int reg) { switch (reg) { case WM8900_REG_ID: - case WM8900_REG_POWER1: return 1; default: return 0; @@ -1200,11 +1199,6 @@ static int wm8900_probe(struct snd_soc_codec *codec) return -ENODEV; } - /* Read back from the chip */ - reg = snd_soc_read(codec, WM8900_REG_POWER1); - reg = (reg >> 12) & 0xf; - dev_info(codec->dev, "WM8900 revision %d\n", reg); - wm8900_reset(codec); /* Turn the chip on */ diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2cb81538cd91..19ca782ac970 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -123,7 +123,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; break; default: - WARN(1, "Unknown DCS readback method"); + WARN(1, "Unknown DCS readback method\n"); break; } diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index a3bfb2e8b70f..73d0edd8ded9 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -79,7 +79,7 @@ static void tosa_ext_control(struct snd_soc_codec *codec) static int tosa_startup(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->card->codec; + struct snd_soc_codec *codec = rtd->codec; /* check the jack status at stream startup */ tosa_ext_control(codec); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1c8f3f507f54..614a8b30d87b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -165,8 +165,11 @@ static ssize_t pmdown_time_set(struct device *dev, { struct snd_soc_pcm_runtime *rtd = container_of(dev, struct snd_soc_pcm_runtime, dev); + int ret; - strict_strtol(buf, 10, &rtd->pmdown_time); + ret = strict_strtol(buf, 10, &rtd->pmdown_time); + if (ret) + return ret; return count; } diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 7dae05d8783e..782f741cd00a 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c @@ -60,7 +60,7 @@ static const struct rc_config { { USB_ID(0x041e, 0x3000), 0, 1, 2, 1, 18, 0x0013 }, /* Extigy */ { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ - { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi */ + { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ }; @@ -183,7 +183,13 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e if (value > 1) return -EINVAL; changed = value != mixer->audigy2nx_leds[index]; - err = snd_usb_ctl_msg(mixer->chip->dev, + if (mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) + err = snd_usb_ctl_msg(mixer->chip->dev, + usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, + USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, + !value, 0, NULL, 0, 100); + else + err = snd_usb_ctl_msg(mixer->chip->dev, usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, value, index + 2, NULL, 0, 100); @@ -225,8 +231,12 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) int i, err; for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) { + /* USB X-Fi S51 doesn't have a CMSS LED */ + if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) + continue; if (i > 1 && /* Live24ext has 2 LEDs only */ (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || + mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) break; err = snd_ctl_add(mixer->chip->card, @@ -365,6 +375,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) || mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || + mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || mixer->chip->usb_id == USB_ID(0x041e, 0x3048)) { if ((err = snd_audigy2nx_controls_create(mixer)) < 0) return err; diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index cff3a3c465d7..4132522ac90f 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -676,8 +676,10 @@ static int snd_usb_pcm_check_knot(struct snd_pcm_runtime *runtime, if (!needs_knot) return 0; - subs->rate_list.count = count; subs->rate_list.list = kmalloc(sizeof(int) * count, GFP_KERNEL); + if (!subs->rate_list.list) + return -ENOMEM; + subs->rate_list.count = count; subs->rate_list.mask = 0; count = 0; list_for_each_entry(fp, &subs->fmt_list, list) { |