diff options
268 files changed, 2055 insertions, 1693 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 1808f11..82d6aeb 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -2048,7 +2048,9 @@ and is between 256 and 4096 characters. It is defined in the file WARNING: Forcing ASPM on may cause system lockups. pcie_pme= [PCIE,PM] Native PCIe PME signaling options: - off Do not use native PCIe PME signaling. + Format: {auto|force}[,nomsi] + auto Use native PCIe PME signaling if the BIOS allows the + kernel to control PCIe config registers of root ports. force Use native PCIe PME signaling even if the BIOS refuses to allow the kernel to control the relevant PCIe config registers. diff --git a/MAINTAINERS b/MAINTAINERS index b7ae5fb..f9730fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1581,7 +1581,7 @@ F: include/linux/coda*.h COMMON INTERNET FILE SYSTEM (CIFS) M: Steve French <sfrench@samba.org> -L: linux-cifs-client@lists.samba.org (moderated for non-subscribers) +L: linux-cifs@vger.kernel.org L: samba-technical@lists.samba.org (moderated for non-subscribers) W: http://linux-cifs.samba.org/ Q: http://patchwork.ozlabs.org/project/linux-cifs-client/list/ @@ -2887,6 +2887,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git S: Maintained F: drivers/input/ +INPUT MULTITOUCH (MT) PROTOCOL +M: Henrik Rydberg <rydberg@euromail.se> +L: linux-input@vger.kernel.org +S: Maintained +F: Documentation/input/multi-touch-protocol.txt +K: \b(ABS|SYN)_MT_ + INTEL IDLE DRIVER M: Len Brown <lenb@kernel.org> L: linux-pm@lists.linux-foundation.org @@ -2978,20 +2985,14 @@ F: drivers/net/ixgb/ F: drivers/net/ixgbe/ INTEL PRO/WIRELESS 2100 NETWORK CONNECTION SUPPORT -M: Reinette Chatre <reinette.chatre@intel.com> -M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org -W: http://ipw2100.sourceforge.net -S: Odd Fixes +S: Orphan F: Documentation/networking/README.ipw2100 F: drivers/net/wireless/ipw2x00/ipw2100.* INTEL PRO/WIRELESS 2915ABG NETWORK CONNECTION SUPPORT -M: Reinette Chatre <reinette.chatre@intel.com> -M: Intel Linux Wireless <ilw@linux.intel.com> L: linux-wireless@vger.kernel.org -W: http://ipw2200.sourceforge.net -S: Odd Fixes +S: Orphan F: Documentation/networking/README.ipw2200 F: drivers/net/wireless/ipw2x00/ipw2200.* @@ -4205,6 +4206,7 @@ OPEN FIRMWARE AND FLATTENED DEVICE TREE M: Grant Likely <grant.likely@secretlab.ca> L: devicetree-discuss@lists.ozlabs.org W: http://fdt.secretlab.ca +T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: drivers/of F: include/linux/of*.h @@ -5377,6 +5379,7 @@ M: David Brownell <dbrownell@users.sourceforge.net> M: Grant Likely <grant.likely@secretlab.ca> L: spi-devel-general@lists.sourceforge.net Q: http://patchwork.kernel.org/project/spi-devel-general/list/ +T: git git://git.secretlab.ca/git/linux-2.6.git S: Maintained F: Documentation/spi/ F: drivers/spi/ @@ -944,7 +944,7 @@ ifdef CONFIG_LOCALVERSION_AUTO localver-extra = $(scm-identifier) else ifneq ($(scm-identifier),) - ifeq ($(LOCALVERSION),) + ifeq ("$(origin LOCALVERSION)", "undefined") localver-extra = + endif endif diff --git a/arch/alpha/include/asm/bitops.h b/arch/alpha/include/asm/bitops.h index 1dce24b..adfab8a 100644 --- a/arch/alpha/include/asm/bitops.h +++ b/arch/alpha/include/asm/bitops.h @@ -410,7 +410,7 @@ static inline unsigned long __arch_hweight64(unsigned long w) return __kernel_ctpop(w); } -static inline unsigned int __arch_weight32(unsigned int w) +static inline unsigned int __arch_hweight32(unsigned int w) { return __arch_hweight64(w); } diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 7739a62..5a62fb4 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -35,7 +35,7 @@ endif obj-y += irq_pyxis.o irq_i8259.o irq_srm.o obj-y += err_ev6.o -obj-y += es1888.o smc37c669.o smc37c93x.o ns87312.o gct.o +obj-y += es1888.o smc37c669.o smc37c93x.o pc873xx.o gct.o obj-y += srmcons.o else @@ -63,11 +63,11 @@ obj-$(CONFIG_ALPHA_WILDFIRE) += core_wildfire.o # Board support obj-$(CONFIG_ALPHA_ALCOR) += sys_alcor.o irq_i8259.o irq_srm.o obj-$(CONFIG_ALPHA_CABRIOLET) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_EB164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_EB66P) += sys_cabriolet.o irq_i8259.o irq_srm.o \ - ns87312.o + pc873xx.o obj-$(CONFIG_ALPHA_LX164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ smc37c93x.o obj-$(CONFIG_ALPHA_PC164) += sys_cabriolet.o irq_i8259.o irq_srm.o \ @@ -90,14 +90,14 @@ obj-$(CONFIG_ALPHA_RUFFIAN) += sys_ruffian.o irq_pyxis.o irq_i8259.o obj-$(CONFIG_ALPHA_RX164) += sys_rx164.o irq_i8259.o obj-$(CONFIG_ALPHA_SABLE) += sys_sable.o obj-$(CONFIG_ALPHA_LYNX) += sys_sable.o -obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o -obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o ns87312.o +obj-$(CONFIG_ALPHA_BOOK1) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_AVANTI) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_NONAME) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_P2K) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o +obj-$(CONFIG_ALPHA_XL) += sys_sio.o irq_i8259.o irq_srm.o pc873xx.o obj-$(CONFIG_ALPHA_SX164) += sys_sx164.o irq_pyxis.o irq_i8259.o \ irq_srm.o smc37c669.o -obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o ns87312.o +obj-$(CONFIG_ALPHA_TAKARA) += sys_takara.o irq_i8259.o pc873xx.o obj-$(CONFIG_ALPHA_WILDFIRE) += sys_wildfire.o irq_i8259.o # Error support diff --git a/arch/alpha/kernel/ns87312.c b/arch/alpha/kernel/ns87312.c deleted file mode 100644 index 342b56d..0000000 --- a/arch/alpha/kernel/ns87312.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * linux/arch/alpha/kernel/ns87312.c - */ - -#include <linux/init.h> -#include <asm/io.h> -#include "proto.h" - - -/* - * The SRM console *disables* the IDE interface, this code ensures it's - * enabled. - * - * This code bangs on a control register of the 87312 Super I/O chip - * that implements parallel port/serial ports/IDE/FDI. Depending on - * the motherboard, the Super I/O chip can be configured through a - * pair of registers that are located either at I/O ports 0x26e/0x26f - * or 0x398/0x399. Unfortunately, autodetecting which base address is - * in use works only once (right after a reset). The Super I/O chip - * has the additional quirk that configuration register data must be - * written twice (I believe this is a safety feature to prevent - * accidental modification---fun, isn't it?). - */ - -void __init -ns87312_enable_ide(long ide_base) -{ - int data; - unsigned long flags; - - local_irq_save(flags); - outb(0, ide_base); /* set the index register for reg #0 */ - data = inb(ide_base+1); /* read the current contents */ - outb(0, ide_base); /* set the index register for reg #0 */ - outb(data | 0x40, ide_base+1); /* turn on IDE */ - outb(data | 0x40, ide_base+1); /* turn on IDE, really! */ - local_irq_restore(flags); -} diff --git a/arch/alpha/kernel/pc873xx.c b/arch/alpha/kernel/pc873xx.c new file mode 100644 index 0000000..27dcbff --- /dev/null +++ b/arch/alpha/kernel/pc873xx.c @@ -0,0 +1,88 @@ +#include <linux/ioport.h> +#include <asm/io.h> + +#include "pc873xx.h" + +static unsigned pc873xx_probelist[] = {0x398, 0x26e, 0}; + +static char *pc873xx_names[] = { + "PC87303", "PC87306", "PC87312", "PC87332", "PC87334" +}; + +static unsigned int base, model; + + +unsigned int __init pc873xx_get_base() +{ + return base; +} + +char *__init pc873xx_get_model() +{ + return pc873xx_names[model]; +} + +static unsigned char __init pc873xx_read(unsigned int base, int reg) +{ + outb(reg, base); + return inb(base + 1); +} + +static void __init pc873xx_write(unsigned int base, int reg, unsigned char data) +{ + unsigned long flags; + + local_irq_save(flags); + outb(reg, base); + outb(data, base + 1); + outb(data, base + 1); /* Must be written twice */ + local_irq_restore(flags); +} + +int __init pc873xx_probe(void) +{ + int val, index = 0; + + while ((base = pc873xx_probelist[index++])) { + + if (request_region(base, 2, "Super IO PC873xx") == NULL) + continue; + + val = pc873xx_read(base, REG_SID); + if ((val & 0xf0) == 0x10) { + model = PC87332; + break; + } else if ((val & 0xf8) == 0x70) { + model = PC87306; + break; + } else if ((val & 0xf8) == 0x50) { + model = PC87334; + break; + } else if ((val & 0xf8) == 0x40) { + model = PC87303; + break; + } + + release_region(base, 2); + } + + return (base == 0) ? -1 : 1; +} + +void __init pc873xx_enable_epp19(void) +{ + unsigned char data; + + printk(KERN_INFO "PC873xx enabling EPP v1.9\n"); + data = pc873xx_read(base, REG_PCR); + pc873xx_write(base, REG_PCR, (data & 0xFC) | 0x02); +} + +void __init pc873xx_enable_ide(void) +{ + unsigned char data; + + printk(KERN_INFO "PC873xx enabling IDE interrupt\n"); + data = pc873xx_read(base, REG_FER); + pc873xx_write(base, REG_FER, data | 0x40); +} diff --git a/arch/alpha/kernel/pc873xx.h b/arch/alpha/kernel/pc873xx.h new file mode 100644 index 0000000..25e1695 --- /dev/null +++ b/arch/alpha/kernel/pc873xx.h @@ -0,0 +1,35 @@ + +#ifndef _PC873xx_H_ +#define _PC873xx_H_ + +/* + * Control Register Values + */ +#define REG_FER 0x00 +#define REG_FAR 0x01 +#define REG_PTR 0x02 +#define REG_FCR 0x03 +#define REG_PCR 0x04 +#define REG_KRR 0x05 +#define REG_PMC 0x06 +#define REG_TUP 0x07 +#define REG_SID 0x08 +#define REG_ASC 0x09 +#define REG_IRC 0x0e + +/* + * Model numbers + */ +#define PC87303 0 +#define PC87306 1 +#define PC87312 2 +#define PC87332 3 +#define PC87334 4 + +int pc873xx_probe(void); +unsigned int pc873xx_get_base(void); +char *pc873xx_get_model(void); +void pc873xx_enable_epp19(void); +void pc873xx_enable_ide(void); + +#endif diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c index a5fffc8..738fc82 100644 --- a/arch/alpha/kernel/pci-sysfs.c +++ b/arch/alpha/kernel/pci-sysfs.c @@ -53,7 +53,6 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, /** * pci_mmap_resource - map a PCI resource into user memory space - * @filp: open sysfs file * @kobj: kobject for mapping * @attr: struct bin_attribute for the file being mapped * @vma: struct vm_area_struct passed into the mmap @@ -61,7 +60,7 @@ static int __pci_mmap_fits(struct pci_dev *pdev, int num, * * Use the bus mapping routines to map a PCI resource into userspace. */ -static int pci_mmap_resource(struct file *filp, struct kobject *kobj, +static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma, int sparse) { diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c index d4327e4..85b4aea 100644 --- a/arch/alpha/kernel/sys_sio.c +++ b/arch/alpha/kernel/sys_sio.c @@ -34,6 +34,7 @@ #include "irq_impl.h" #include "pci_impl.h" #include "machvec_impl.h" +#include "pc873xx.h" #if defined(ALPHA_RESTORE_SRM_SETUP) /* Save LCA configuration data as the console had it set up. */ @@ -208,7 +209,27 @@ noname_init_pci(void) common_init_pci(); sio_pci_route(); sio_fixup_irq_levels(sio_collect_irq_levels()); - ns87312_enable_ide(0x26e); + + if (pc873xx_probe() == -1) { + printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n"); + } else { + printk(KERN_INFO "Found %s Super IO chip at 0x%x\n", + pc873xx_get_model(), pc873xx_get_base()); + + /* Enabling things in the Super IO chip doesn't actually + * configure and enable things, the legacy drivers still + * need to do the actual configuration and enabling. + * This only unblocks them. + */ + +#if !defined(CONFIG_ALPHA_AVANTI) + /* Don't bother on the Avanti family. + * None of them had on-board IDE. + */ + pc873xx_enable_ide(); +#endif + pc873xx_enable_epp19(); + } } static inline void __init diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index e6f7303..9b11eed 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c @@ -2,6 +2,7 @@ * Versatile Express Core Tile Cortex A9x4 Support */ #include <linux/init.h> +#include <linux/gfp.h> #include <linux/device.h> #include <linux/dma-mapping.h> #include <linux/platform_device.h> diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug index 53696da..2d38a50 100644 --- a/arch/powerpc/Kconfig.debug +++ b/arch/powerpc/Kconfig.debug @@ -135,13 +135,6 @@ config DEBUGGER depends on KGDB || XMON default y -config IRQSTACKS - bool "Use separate kernel stacks when processing interrupts" - help - If you say Y here the kernel will use separate kernel stacks - for handling hard and soft interrupts. This can help avoid - overflowing the process kernel stacks. - config VIRQ_DEBUG bool "Expose hardware/virtual IRQ mapping via debugfs" depends on DEBUG_FS diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index ad0df7d..fae8192 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -141,7 +141,7 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S FORCE $(obj)/wrapper.a: $(obj-wlib) FORCE $(call if_changed,bootar) -hostprogs-y := addnote addRamDisk hack-coff mktree +hostprogs-y := addnote hack-coff mktree targets += $(patsubst $(obj)/%,%,$(obj-boot) wrapper.a) extra-y := $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ diff --git a/arch/powerpc/boot/addRamDisk.c b/arch/powerpc/boot/addRamDisk.c deleted file mode 100644 index 893f446..0000000 --- a/arch/powerpc/boot/addRamDisk.c +++ /dev/null @@ -1,311 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <netinet/in.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <elf.h> - -#define ElfHeaderSize (64 * 1024) -#define ElfPages (ElfHeaderSize / 4096) -#define KERNELBASE (0xc000000000000000) -#define _ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) - -struct addr_range { - unsigned long long addr; - unsigned long memsize; - unsigned long offset; -}; - -static int check_elf64(void *p, int size, struct addr_range *r) -{ - Elf64_Ehdr *elf64 = p; - Elf64_Phdr *elf64ph; - - if (elf64->e_ident[EI_MAG0] != ELFMAG0 || - elf64->e_ident[EI_MAG1] != ELFMAG1 || - elf64->e_ident[EI_MAG2] != ELFMAG2 || - elf64->e_ident[EI_MAG3] != ELFMAG3 || - elf64->e_ident[EI_CLASS] != ELFCLASS64 || - elf64->e_ident[EI_DATA] != ELFDATA2MSB || - elf64->e_type != ET_EXEC || elf64->e_machine != EM_PPC64) - return 0; - - if ((elf64->e_phoff + sizeof(Elf64_Phdr)) > size) - return 0; - - elf64ph = (Elf64_Phdr *) ((unsigned long)elf64 + - (unsigned long)elf64->e_phoff); - - r->memsize = (unsigned long)elf64ph->p_memsz; - r->offset = (unsigned long)elf64ph->p_offset; - r->addr = (unsigned long long)elf64ph->p_vaddr; - -#ifdef DEBUG - printf("PPC64 ELF file, ph:\n"); - printf("p_type 0x%08x\n", elf64ph->p_type); - printf("p_flags 0x%08x\n", elf64ph->p_flags); - printf("p_offset 0x%016llx\n", elf64ph->p_offset); - printf("p_vaddr 0x%016llx\n", elf64ph->p_vaddr); - printf("p_paddr 0x%016llx\n", elf64ph->p_paddr); - printf("p_filesz 0x%016llx\n", elf64ph->p_filesz); - printf("p_memsz 0x%016llx\n", elf64ph->p_memsz); - printf("p_align 0x%016llx\n", elf64ph->p_align); - printf("... skipping 0x%08lx bytes of ELF header\n", - (unsigned long)elf64ph->p_offset); -#endif - - return 64; -} -static void get4k(FILE *file, char *buf ) -{ - unsigned j; - unsigned num = fread(buf, 1, 4096, file); - for ( j=num; j<4096; ++j ) - buf[j] = 0; -} - -static void put4k(FILE *file, char *buf ) -{ - fwrite(buf, 1, 4096, file); -} - -static void death(const char *msg, FILE *fdesc, const char *fname) -{ - fprintf(stderr, msg); - fclose(fdesc); - unlink(fname); - exit(1); -} - -int main(int argc, char **argv) -{ - char inbuf[4096]; - struct addr_range vmlinux; - FILE *ramDisk; - FILE *inputVmlinux; - FILE *outputVmlinux; - - char *rd_name, *lx_name, *out_name; - - size_t i; - unsigned long ramFileLen; - unsigned long ramLen; - unsigned long roundR; - unsigned long offset_end; - - unsigned long kernelLen; - unsigned long actualKernelLen; - unsigned long round; - unsigned long roundedKernelLen; - unsigned long ramStartOffs; - unsigned long ramPages; - unsigned long roundedKernelPages; - unsigned long hvReleaseData; - u_int32_t eyeCatcher = 0xc8a5d9c4; - unsigned long naca; - unsigned long xRamDisk; - unsigned long xRamDiskSize; - long padPages; - - - if (argc < 2) { - fprintf(stderr, "Name of RAM disk file missing.\n"); - exit(1); - } - rd_name = argv[1]; - - if (argc < 3) { - fprintf(stderr, "Name of vmlinux file missing.\n"); - exit(1); - } - lx_name = argv[2]; - - if (argc < 4) { - fprintf(stderr, "Name of vmlinux output file missing.\n"); - exit(1); - } - out_name = argv[3]; - - - ramDisk = fopen(rd_name, "r"); - if ( ! ramDisk ) { - fprintf(stderr, "RAM disk file \"%s\" failed to open.\n", rd_name); - exit(1); - } - - inputVmlinux = fopen(lx_name, "r"); - if ( ! inputVmlinux ) { - fprintf(stderr, "vmlinux file \"%s\" failed to open.\n", lx_name); - exit(1); - } - - outputVmlinux = fopen(out_name, "w+"); - if ( ! outputVmlinux ) { - fprintf(stderr, "output vmlinux file \"%s\" failed to open.\n", out_name); - exit(1); - } - - i = fread(inbuf, 1, sizeof(inbuf), inputVmlinux); - if (i != sizeof(inbuf)) { - fprintf(stderr, "can not read vmlinux file %s: %u\n", lx_name, i); - exit(1); - } - - i = check_elf64(inbuf, sizeof(inbuf), &vmlinux); - if (i == 0) { - fprintf(stderr, "You must have a linux kernel specified as argv[2]\n"); - exit(1); - } - - /* Input Vmlinux file */ - fseek(inputVmlinux, 0, SEEK_END); - kernelLen = ftell(inputVmlinux); - fseek(inputVmlinux, 0, SEEK_SET); - printf("kernel file size = %lu\n", kernelLen); - - actualKernelLen = kernelLen - ElfHeaderSize; - - printf("actual kernel length (minus ELF header) = %lu\n", actualKernelLen); - - round = actualKernelLen % 4096; - roundedKernelLen = actualKernelLen; - if ( round ) - roundedKernelLen += (4096 - round); - printf("Vmlinux length rounded up to a 4k multiple = %ld/0x%lx \n", roundedKernelLen, roundedKernelLen); - roundedKernelPages = roundedKernelLen / 4096; - printf("Vmlinux pages to copy = %ld/0x%lx \n", roundedKernelPages, roundedKernelPages); - - offset_end = _ALIGN_UP(vmlinux.memsize, 4096); - /* calc how many pages we need to insert between the vmlinux and the start of the ram disk */ - padPages = offset_end/4096 - roundedKernelPages; - - /* Check and see if the vmlinux is already larger than _end in System.map */ - if (padPages < 0) { - /* vmlinux is larger than _end - adjust the offset to the start of the embedded ram disk */ - offset_end = roundedKernelLen; - printf("vmlinux is larger than _end indicates it needs to be - offset_end = %lx \n", offset_end); - padPages = 0; - printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); - } - else { - /* _end is larger than vmlinux - use the offset to _end that we calculated from the system map */ - printf("vmlinux is smaller than _end indicates is needed - offset_end = %lx \n", offset_end); - printf("will insert %lx pages between the vmlinux and the start of the ram disk \n", padPages); - } - - - - /* Input Ram Disk file */ - // Set the offset that the ram disk will be started at. - ramStartOffs = offset_end; /* determined from the input vmlinux file and the system map */ - printf("Ram Disk will start at offset = 0x%lx \n", ramStartOffs); - - fseek(ramDisk, 0, SEEK_END); - ramFileLen = ftell(ramDisk); - fseek(ramDisk, 0, SEEK_SET); - printf("%s file size = %ld/0x%lx \n", rd_name, ramFileLen, ramFileLen); - - ramLen = ramFileLen; - - roundR = 4096 - (ramLen % 4096); - if ( roundR ) { - printf("Rounding RAM disk file up to a multiple of 4096, adding %ld/0x%lx \n", roundR, roundR); - ramLen += roundR; - } - - printf("Rounded RAM disk size is %ld/0x%lx \n", ramLen, ramLen); - ramPages = ramLen / 4096; - printf("RAM disk pages to copy = %ld/0x%lx\n", ramPages, ramPages); - - - - // Copy 64K ELF header - for (i=0; i<(ElfPages); ++i) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Copy the vmlinux (as full pages). */ - fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); - for ( i=0; i<roundedKernelPages; ++i ) { - get4k( inputVmlinux, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Insert pad pages (if appropriate) that are needed between */ - /* | the end of the vmlinux and the ram disk. */ - for (i=0; i<padPages; ++i) { - memset(inbuf, 0, 4096); - put4k(outputVmlinux, inbuf); - } - - /* Copy the ram disk (as full pages). */ - for ( i=0; i<ramPages; ++i ) { - get4k( ramDisk, inbuf ); - put4k( outputVmlinux, inbuf ); - } - - /* Close the input files */ - fclose(ramDisk); - fclose(inputVmlinux); - /* And flush the written output file */ - fflush(outputVmlinux); - - - - /* Fixup the new vmlinux to contain the ram disk starting offset (xRamDisk) and the ram disk size (xRamDiskSize) */ - /* fseek to the hvReleaseData pointer */ - fseek(outputVmlinux, ElfHeaderSize + 0x24, SEEK_SET); - if (fread(&hvReleaseData, 4, 1, outputVmlinux) != 1) { - death("Could not read hvReleaseData pointer\n", outputVmlinux, out_name); - } - hvReleaseData = ntohl(hvReleaseData); /* Convert to native int */ - printf("hvReleaseData is at %08lx\n", hvReleaseData); - - /* fseek to the hvReleaseData */ - fseek(outputVmlinux, ElfHeaderSize + hvReleaseData, SEEK_SET); - if (fread(inbuf, 0x40, 1, outputVmlinux) != 1) { - death("Could not read hvReleaseData\n", outputVmlinux, out_name); - } - /* Check hvReleaseData sanity */ - if (memcmp(inbuf, &eyeCatcher, 4) != 0) { - death("hvReleaseData is invalid\n", outputVmlinux, out_name); - } - /* Get the naca pointer */ - naca = ntohl(*((u_int32_t*) &inbuf[0x0C])) - KERNELBASE; - printf("Naca is at offset 0x%lx \n", naca); - - /* fseek to the naca */ - fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); - if (fread(inbuf, 0x18, 1, outputVmlinux) != 1) { - death("Could not read naca\n", outputVmlinux, out_name); - } - xRamDisk = ntohl(*((u_int32_t *) &inbuf[0x0c])); - xRamDiskSize = ntohl(*((u_int32_t *) &inbuf[0x14])); - /* Make sure a RAM disk isn't already present */ - if ((xRamDisk != 0) || (xRamDiskSize != 0)) { - death("RAM disk is already attached to this kernel\n", outputVmlinux, out_name); - } - /* Fill in the values */ - *((u_int32_t *) &inbuf[0x0c]) = htonl(ramStartOffs); - *((u_int32_t *) &inbuf[0x14]) = htonl(ramPages); - - /* Write out the new naca */ - fflush(outputVmlinux); - fseek(outputVmlinux, ElfHeaderSize + naca, SEEK_SET); - if (fwrite(inbuf, 0x18, 1, outputVmlinux) != 1) { - death("Could not write naca\n", outputVmlinux, out_name); - } - printf("Ram Disk of 0x%lx pages is attached to the kernel at offset 0x%08lx\n", - ramPages, ramStartOffs); - - /* Done */ - fclose(outputVmlinux); - /* Set permission to executable */ - chmod(out_name, S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - - return 0; -} - diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts index 82ff2b1..179a178 100644 --- a/arch/powerpc/boot/dts/lite5200.dts +++ b/arch/powerpc/boot/dts/lite5200.dts @@ -134,12 +134,16 @@ compatible = "fsl,mpc5200-gpio"; reg = <0xb00 0x40>; interrupts = <1 7 0>; + gpio-controller; + #gpio-cells = <2>; }; gpio@c00 { compatible = "fsl,mpc5200-gpio-wkup"; reg = <0xc00 0x40>; interrupts = <1 8 0 0 3 0>; + gpio-controller; + #gpio-cells = <2>; }; spi@f00 { @@ -230,8 +234,8 @@ reg = <0x3000 0x400>; // fec range, since we need to setup fec interrupts interrupts = <2 5 0>; // these are for "mii command finished", not link changes & co. - phy0: ethernet-phy@1 { - reg = <1>; + phy0: ethernet-phy@0 { + reg = <0>; }; }; @@ -255,7 +259,13 @@ compatible = "fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + }; }; + sram@8000 { compatible = "fsl,mpc5200-sram"; reg = <0x8000 0x4000>; @@ -281,4 +291,18 @@ 0x02000000 0 0xa0000000 0xa0000000 0 0x10000000 0x01000000 0 0x00000000 0xb0000000 0 0x01000000>; }; + + localbus { + compatible = "fsl,mpc5200-lpb","simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + + ranges = <0 0 0xff000000 0x01000000>; + + flash@0,0 { + compatible = "amd,am29lv652d", "cfi-flash"; + reg = <0 0 0x01000000>; + bank-width = <1>; + }; + }; }; diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts index e45a63b..59702ac 100644 --- a/arch/powerpc/boot/dts/lite5200b.dts +++ b/arch/powerpc/boot/dts/lite5200b.dts @@ -259,6 +259,11 @@ compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; reg = <0x3d40 0x40>; interrupts = <2 16 0>; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + }; }; sram@8000 { diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index 8e95f8d..4aa17b6 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index 918f23f..9a5f1ab 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/hcu4_defconfig b/arch/powerpc/configs/40x/hcu4_defconfig index f87ef03..0b45213 100644 --- a/arch/powerpc/configs/40x/hcu4_defconfig +++ b/arch/powerpc/configs/40x/hcu4_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index 19fbcb0..4d2de0b 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index eb41cd6..a1f3f50 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -98,8 +98,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index 416e79a..c763135 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -77,8 +77,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index bfff0ea..6597b2f 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -98,8 +98,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig index 1f6d049..2d3dfb5 100644 --- a/arch/powerpc/configs/44x/arches_defconfig +++ b/arch/powerpc/configs/44x/arches_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig index 788faac..51a00c4 100644 --- a/arch/powerpc/configs/44x/bamboo_defconfig +++ b/arch/powerpc/configs/44x/bamboo_defconfig @@ -102,8 +102,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig index 4ef8bca..1028b1b 100644 --- a/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/arch/powerpc/configs/44x/canyonlands_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig index ca17b14..69f5633 100644 --- a/arch/powerpc/configs/44x/ebony_defconfig +++ b/arch/powerpc/configs/44x/ebony_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index e3149ba..dcd859c 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig index af244e1..a2c24d1 100644 --- a/arch/powerpc/configs/44x/katmai_defconfig +++ b/arch/powerpc/configs/44x/katmai_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig index 8fed3b2..3bb55b5 100644 --- a/arch/powerpc/configs/44x/rainier_defconfig +++ b/arch/powerpc/configs/44x/rainier_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig index a67ec91..684f40d 100644 --- a/arch/powerpc/configs/44x/redwood_defconfig +++ b/arch/powerpc/configs/44x/redwood_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/sam440ep_defconfig b/arch/powerpc/configs/44x/sam440ep_defconfig index 886cb6a..e202924 100644 --- a/arch/powerpc/configs/44x/sam440ep_defconfig +++ b/arch/powerpc/configs/44x/sam440ep_defconfig @@ -103,8 +103,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index 1b2f41d..c348a46 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig @@ -102,8 +102,7 @@ CONFIG_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig index 12041d3..f4cb7e8 100644 --- a/arch/powerpc/configs/44x/taishan_defconfig +++ b/arch/powerpc/configs/44x/taishan_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig index 2518b85..c7ead0e 100644 --- a/arch/powerpc/configs/44x/virtex5_defconfig +++ b/arch/powerpc/configs/44x/virtex5_defconfig @@ -80,8 +80,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index 218d49b..7664c83 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 90492ff..eac7c17 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -96,8 +96,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index dffc8ca..27afb6e 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig index 3cb2a52..5fe39dd 100644 --- a/arch/powerpc/configs/52xx/pcm030_defconfig +++ b/arch/powerpc/configs/52xx/pcm030_defconfig @@ -98,8 +98,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 96181c6..a108b84 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig index 183c59c..b728a7d 100644 --- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig +++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig index 1524d94..8e738de 100644 --- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig index 767c204..59bf9e2 100644 --- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig +++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig index 55b9e4e..4e8b01e 100644 --- a/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig +++ b/arch/powerpc/configs/86xx/mpc8610_hpcd_defconfig @@ -98,8 +98,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig index 1be38eb..20fde63 100644 --- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig +++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig @@ -103,8 +103,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/86xx/sbc8641d_defconfig b/arch/powerpc/configs/86xx/sbc8641d_defconfig index a630094..74f714d 100644 --- a/arch/powerpc/configs/86xx/sbc8641d_defconfig +++ b/arch/powerpc/configs/86xx/sbc8641d_defconfig @@ -102,8 +102,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig index 9f89d5c..a670cee 100644 --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -92,8 +92,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index b63cc38..851287e 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -87,8 +87,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/c2k_defconfig b/arch/powerpc/configs/c2k_defconfig index 4ab6074..b429a65 100644 --- a/arch/powerpc/configs/c2k_defconfig +++ b/arch/powerpc/configs/c2k_defconfig @@ -102,8 +102,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index c6d2baa..9433719 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -83,8 +83,7 @@ CONFIG_CPUSETS=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y # CONFIG_RELAY is not set CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/celleb_defconfig b/arch/powerpc/configs/celleb_defconfig index d212377..6be6c09 100644 --- a/arch/powerpc/configs/celleb_defconfig +++ b/arch/powerpc/configs/celleb_defconfig @@ -78,8 +78,7 @@ CONFIG_LOG_BUF_SHIFT=15 # CONFIG_GROUP_SCHED is not set # CONFIG_USER_SCHED is not set # CONFIG_CGROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index 5094a65..2fdab66 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -77,8 +77,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=15 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig index 81e904e..6b70839 100644 --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig index c5af46e..1cee889 100644 --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -91,8 +91,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 826a65d..57d3ffa 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -82,8 +82,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index 942e119..1c2dbf0 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -101,8 +101,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig index a211a79..a60d61b 100644 --- a/arch/powerpc/configs/holly_defconfig +++ b/arch/powerpc/configs/holly_defconfig @@ -73,7 +73,6 @@ CONFIG_SYSVIPC_SYSCTL=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set # CONFIG_FAIR_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y # CONFIG_RELAY is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index 76982c5..151c8e1 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig @@ -81,8 +81,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index 588a2ad..8ecacf7 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -97,8 +97,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 8b24400..dc50eec 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -78,8 +78,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 0cbd56f..b36ebb7 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/mgsuvd_defconfig b/arch/powerpc/configs/mgsuvd_defconfig index c1be261..0dd5015 100644 --- a/arch/powerpc/configs/mgsuvd_defconfig +++ b/arch/powerpc/configs/mgsuvd_defconfig @@ -90,8 +90,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index a047272..aa2654e 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 CONFIG_LOG_BUF_SHIFT=16 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 7012ac0..f875ec2 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -97,8 +97,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index 27c63ce..b1e88fe 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 20ba0cf..74a7216 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=64 CONFIG_LOG_BUF_SHIFT=17 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index ea8870a..753bb79 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -93,8 +93,7 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 35b6068..afb4d1b 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig @@ -99,8 +99,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 46f5c47..bd3d23f 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -103,8 +103,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index dad617e..369f4e0 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -93,8 +93,7 @@ CONFIG_CPUSETS=y # CONFIG_GROUP_SCHED is not set # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 8195f16..403e82e 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -107,8 +107,7 @@ CONFIG_CPUSETS=y CONFIG_PROC_PID_CPUSET=y # CONFIG_CGROUP_CPUACCT is not set # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig index 68c175e..12c8ee8 100644 --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -96,8 +96,7 @@ CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/configs/prpmc2800_defconfig b/arch/powerpc/configs/prpmc2800_defconfig index 93f4505..a18f597 100644 --- a/arch/powerpc/configs/prpmc2800_defconfig +++ b/arch/powerpc/configs/prpmc2800_defconfig @@ -98,8 +98,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set CONFIG_NAMESPACES=y # CONFIG_UTS_NS is not set diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 16a1458..16ae717 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -92,8 +92,7 @@ CONFIG_CPUSETS=y # CONFIG_GROUP_SCHED is not set CONFIG_CGROUP_CPUACCT=y # CONFIG_RESOURCE_COUNTERS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_PROC_PID_CPUSET=y CONFIG_RELAY=y CONFIG_NAMESPACES=y diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig index b162580..01be0e2 100644 --- a/arch/powerpc/configs/storcenter_defconfig +++ b/arch/powerpc/configs/storcenter_defconfig @@ -95,8 +95,7 @@ CONFIG_RCU_FANOUT=32 # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set # CONFIG_RELAY is not set # CONFIG_NAMESPACES is not set # CONFIG_BLK_DEV_INITRD is not set diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index c386828..ee054f8 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -102,8 +102,7 @@ CONFIG_FAIR_GROUP_SCHED=y CONFIG_USER_SCHED=y # CONFIG_CGROUP_SCHED is not set # CONFIG_CGROUPS is not set -CONFIG_SYSFS_DEPRECATED=y -CONFIG_SYSFS_DEPRECATED_V2=y +# CONFIG_SYSFS_DEPRECATED_V2 is not set CONFIG_RELAY=y # CONFIG_NAMESPACES is not set CONFIG_BLK_DEV_INITRD=y diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h index e054bae..ecba37a 100644 --- a/arch/powerpc/include/asm/irq.h +++ b/arch/powerpc/include/asm/irq.h @@ -358,7 +358,6 @@ extern void exc_lvl_ctx_init(void); #define exc_lvl_ctx_init() #endif -#ifdef CONFIG_IRQSTACKS /* * Per-cpu stacks for handling hard and soft interrupts. */ @@ -369,11 +368,6 @@ extern void irq_ctx_init(void); extern void call_do_softirq(struct thread_info *tp); extern int call_handle_irq(int irq, void *p1, struct thread_info *tp, void *func); -#else -#define irq_ctx_init() - -#endif /* CONFIG_IRQSTACKS */ - extern void do_IRQ(struct pt_regs *regs); #endif /* _ASM_IRQ_H */ diff --git a/arch/powerpc/include/asm/kdump.h b/arch/powerpc/include/asm/kdump.h index 5ebfe5d..6857af5 100644 --- a/arch/powerpc/include/asm/kdump.h +++ b/arch/powerpc/include/asm/kdump.h @@ -3,8 +3,17 @@ #include <asm/page.h> -/* Kdump kernel runs at 32 MB, change at your peril. */ +/* + * If CONFIG_RELOCATABLE is enabled we can place the kdump kernel anywhere. + * To keep enough space in the RMO for the first stage kernel on 64bit, we + * place it at 64MB. If CONFIG_RELOCATABLE is not enabled we must place + * the second stage at 32MB. + */ +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_PPC64) +#define KDUMP_KERNELBASE 0x4000000 +#else #define KDUMP_KERNELBASE 0x2000000 +#endif /* How many bytes to reserve at zero for kdump. The reserve limit should * be greater or equal to the trampoline's end address. diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 30817d9..3333bbd 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -317,7 +317,6 @@ void fixup_irqs(const struct cpumask *map) } #endif -#ifdef CONFIG_IRQSTACKS static inline void handle_one_irq(unsigned int irq) { struct thread_info *curtp, *irqtp; @@ -358,12 +357,6 @@ static inline void handle_one_irq(unsigned int irq) if (irqtp->flags) set_bits(irqtp->flags, &curtp->flags); } -#else -static inline void handle_one_irq(unsigned int irq) -{ - generic_handle_irq(irq); -} -#endif static inline void check_stack_overflow(void) { @@ -455,7 +448,6 @@ void exc_lvl_ctx_init(void) } #endif -#ifdef CONFIG_IRQSTACKS struct thread_info *softirq_ctx[NR_CPUS] __read_mostly; struct thread_info *hardirq_ctx[NR_CPUS] __read_mostly; @@ -492,10 +484,6 @@ static inline void do_softirq_onstack(void) irqtp->task = NULL; } -#else -#define do_softirq_onstack() __do_softirq() -#endif /* CONFIG_IRQSTACKS */ - void do_softirq(void) { unsigned long flags; diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c index 26f9900..ed31a29 100644 --- a/arch/powerpc/kernel/machine_kexec_64.c +++ b/arch/powerpc/kernel/machine_kexec_64.c @@ -182,28 +182,12 @@ static void kexec_prepare_cpus_wait(int wait_state) my_cpu = get_cpu(); /* Make sure each CPU has atleast made it to the state we need */ - for (i=0; i < NR_CPUS; i++) { + for_each_online_cpu(i) { if (i == my_cpu) continue; while (paca[i].kexec_state < wait_state) { barrier(); - if (!cpu_possible(i)) { - printk("kexec: cpu %d hw_cpu_id %d is not" - " possible, ignoring\n", - i, paca[i].hw_cpu_id); - break; - } - if (!cpu_online(i)) { - /* Fixme: this can be spinning in - * pSeries_secondary_wait with a paca - * waiting for it to go online. - */ - printk("kexec: cpu %d hw_cpu_id %d is not" - " online, ignoring\n", - i, paca[i].hw_cpu_id); - break; - } if (i != notified) { printk( "kexec: waiting for cpu %d (physical" " %d) to enter %i state\n", diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index dc66d52..6bbd7a6 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -33,7 +33,6 @@ .text -#ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) mflr r0 stw r0,4(r1) @@ -56,7 +55,6 @@ _GLOBAL(call_handle_irq) lwz r0,4(r1) mtlr r0 blr -#endif /* CONFIG_IRQSTACKS */ /* * This returns the high 64 bits of the product of two 64-bit numbers. diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index a2b18df..e514490 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -28,7 +28,6 @@ .text -#ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) mflr r0 std r0,16(r1) @@ -52,7 +51,6 @@ _GLOBAL(call_handle_irq) ld r0,16(r1) mtlr r0 blr -#endif /* CONFIG_IRQSTACKS */ .section ".toc","aw" PPC64_CACHES: diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 9d255b4..773424d 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -1005,7 +1005,6 @@ out: return error; } -#ifdef CONFIG_IRQSTACKS static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, unsigned long nbytes) { @@ -1030,10 +1029,6 @@ static inline int valid_irq_stack(unsigned long sp, struct task_struct *p, return 0; } -#else -#define valid_irq_stack(sp, p, nb) 0 -#endif /* CONFIG_IRQSTACKS */ - int validate_sp(unsigned long sp, struct task_struct *p, unsigned long nbytes) { diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c index bfc2aba..67a84d8 100644 --- a/arch/powerpc/kernel/rtas_flash.c +++ b/arch/powerpc/kernel/rtas_flash.c @@ -94,12 +94,8 @@ struct flash_block_list { struct flash_block_list *next; struct flash_block blocks[FLASH_BLOCKS_PER_NODE]; }; -struct flash_block_list_header { /* just the header of flash_block_list */ - unsigned long num_blocks; - struct flash_block_list *next; -}; -static struct flash_block_list_header rtas_firmware_flash_list = {0, NULL}; +static struct flash_block_list *rtas_firmware_flash_list; /* Use slab cache to guarantee 4k alignment */ static struct kmem_cache *flash_block_cache = NULL; @@ -108,13 +104,14 @@ static struct kmem_cache *flash_block_cache = NULL; /* Local copy of the flash block list. * We only allow one open of the flash proc file and create this - * list as we go. This list will be put in the - * rtas_firmware_flash_list var once it is fully read. + * list as we go. The rtas_firmware_flash_list varable will be + * set once the data is fully read. * * For convenience as we build the list we use virtual addrs, * we do not fill in the version number, and the length field * is treated as the number of entries currently in the block - * (i.e. not a byte count). This is all fixed on release. + * (i.e. not a byte count). This is all fixed when calling + * the flash routine. */ /* Status int must be first member of struct */ @@ -201,16 +198,16 @@ static int rtas_flash_release(struct inode *inode, struct file *file) if (uf->flist) { /* File was opened in write mode for a new flash attempt */ /* Clear saved list */ - if (rtas_firmware_flash_list.next) { - free_flash_list(rtas_firmware_flash_list.next); - rtas_firmware_flash_list.next = NULL; + if (rtas_firmware_flash_list) { + free_flash_list(rtas_firmware_flash_list); + rtas_firmware_flash_list = NULL; } if (uf->status != FLASH_AUTH) uf->status = flash_list_valid(uf->flist); if (uf->status == FLASH_IMG_READY) - rtas_firmware_flash_list.next = uf->flist; + rtas_firmware_flash_list = uf->flist; else free_flash_list(uf->flist); @@ -593,7 +590,7 @@ static void rtas_flash_firmware(int reboot_type) unsigned long rtas_block_list; int i, status, update_token; - if (rtas_firmware_flash_list.next == NULL) + if (rtas_firmware_flash_list == NULL) return; /* nothing to do */ if (reboot_type != SYS_RESTART) { @@ -610,20 +607,25 @@ static void rtas_flash_firmware(int reboot_type) return; } - /* NOTE: the "first" block list is a global var with no data - * blocks in the kernel data segment. We do this because - * we want to ensure this block_list addr is under 4GB. + /* + * NOTE: the "first" block must be under 4GB, so we create + * an entry with no data blocks in the reserved buffer in + * the kernel data segment. */ - rtas_firmware_flash_list.num_blocks = 0; - flist = (struct flash_block_list *)&rtas_firmware_flash_list; + spin_lock(&rtas_data_buf_lock); + flist = (struct flash_block_list *)&rtas_data_buf[0]; + flist->num_blocks = 0; + flist->next = rtas_firmware_flash_list; rtas_block_list = virt_to_abs(flist); if (rtas_block_list >= 4UL*1024*1024*1024) { printk(KERN_ALERT "FLASH: kernel bug...flash list header addr above 4GB\n"); + spin_unlock(&rtas_data_buf_lock); return; } printk(KERN_ALERT "FLASH: preparing saved firmware image for flash\n"); /* Update the block_list in place. */ + rtas_firmware_flash_list = NULL; /* too hard to backout on error */ image_size = 0; for (f = flist; f; f = next) { /* Translate data addrs to absolute */ @@ -664,6 +666,7 @@ static void rtas_flash_firmware(int reboot_type) printk(KERN_ALERT "FLASH: unknown flash return code %d\n", status); break; } + spin_unlock(&rtas_data_buf_lock); } static void remove_flash_pde(struct proc_dir_entry *dp) diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c index 8f58986..7d84b21 100644 --- a/arch/powerpc/kernel/setup_32.c +++ b/arch/powerpc/kernel/setup_32.c @@ -241,7 +241,6 @@ int __init ppc_init(void) arch_initcall(ppc_init); -#ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { unsigned int i; @@ -255,9 +254,6 @@ static void __init irqstack_early_init(void) __va(lmb_alloc(THREAD_SIZE, THREAD_SIZE)); } } -#else -#define irqstack_early_init() -#endif #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) static void __init exc_lvl_early_init(void) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index f3fb5a7..643dcac 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -432,7 +432,6 @@ static u64 slb0_limit(void) return 1UL << SID_SHIFT; } -#ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { u64 limit = slb0_limit(); @@ -451,9 +450,6 @@ static void __init irqstack_early_init(void) THREAD_SIZE, limit)); } } -#else -#define irqstack_early_init() -#endif #ifdef CONFIG_PPC_BOOK3E static void __init exc_lvl_early_init(void) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 9fc02dc..34347b2 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -115,11 +115,7 @@ pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long address) { struct page *ptepage; -#ifdef CONFIG_HIGHPTE - gfp_t flags = GFP_KERNEL | __GFP_HIGHMEM | __GFP_REPEAT | __GFP_ZERO; -#else gfp_t flags = GFP_KERNEL | __GFP_REPEAT | __GFP_ZERO; -#endif ptepage = alloc_pages(flags, 0); if (!ptepage) diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index a55b0b6..7672253 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -64,10 +64,19 @@ int mpc52xx_pm_prepare(void) { .type = "builtin", .compatible = "mpc5200", }, /* efika */ {} }; + struct resource res; /* map the whole register space */ np = of_find_matching_node(NULL, immr_ids); - mbar = of_iomap(np, 0); + + if (of_address_to_resource(np, 0, &res)) { + pr_err("mpc52xx_pm_prepare(): could not get IMMR address\n"); + of_node_put(np); + return -ENOSYS; + } + + mbar = ioremap(res.start, 0xc000); /* we should map whole region including SRAM */ + of_node_put(np); if (!mbar) { pr_err("mpc52xx_pm_prepare(): could not map registers\n"); diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c index 2102487..20b73c0 100644 --- a/arch/powerpc/sysdev/mpic.c +++ b/arch/powerpc/sysdev/mpic.c @@ -1666,7 +1666,7 @@ static int mpic_resume(struct sys_device *dev) mpic->save_data[i].dest); #ifdef CONFIG_MPIC_U3_HT_IRQS - { + if (mpic->fixups) { struct mpic_irq_fixup *fixup = &mpic->fixups[i]; if (fixup->base) { diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index be1d114..1d7b495 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c @@ -25,7 +25,6 @@ #include <linux/spi/spi.h> #include <linux/spi/sh_msiof.h> #include <linux/spi/mmc_spi.h> -#include <linux/mmc/host.h> #include <linux/input.h> #include <linux/input/sh_keysc.h> #include <video/sh_mobile_lcdc.h> diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 953af13..1e9598d 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -139,8 +139,6 @@ static void pcibios_fixup_device_resources(struct pci_dev *dev, for (i = 0; i < PCI_NUM_RESOURCES; i++) { if (!dev->resource[i].start) continue; - if (dev->resource[i].flags & IORESOURCE_PCI_FIXED) - continue; if (dev->resource[i].flags & IORESOURCE_IO) offset = hose->io_offset; else if (dev->resource[i].flags & IORESOURCE_MEM) diff --git a/arch/sh/mm/pmb.c b/arch/sh/mm/pmb.c index 18623ba..6379091 100644 --- a/arch/sh/mm/pmb.c +++ b/arch/sh/mm/pmb.c @@ -770,7 +770,7 @@ static void __init pmb_resize(void) spin_unlock_irqrestore(&pmbe->lock, flags); } - read_lock(&pmb_rwlock); + read_unlock(&pmb_rwlock); } #endif diff --git a/arch/um/include/asm/arch_hweight.h b/arch/um/include/asm/arch_hweight.h new file mode 100644 index 0000000..c656cf4 --- /dev/null +++ b/arch/um/include/asm/arch_hweight.h @@ -0,0 +1,6 @@ +#ifndef _ASM_UM_HWEIGHT_H +#define _ASM_UM_HWEIGHT_H + +#include <asm-generic/bitops/arch_hweight.h> + +#endif diff --git a/arch/x86/boot/video-vga.c b/arch/x86/boot/video-vga.c index ed7aeff..45bc940 100644 --- a/arch/x86/boot/video-vga.c +++ b/arch/x86/boot/video-vga.c @@ -41,13 +41,12 @@ static __videocard video_vga; static u8 vga_set_basic_mode(void) { struct biosregs ireg, oreg; - u16 ax; u8 mode; initregs(&ireg); /* Query current mode */ - ax = 0x0f00; + ireg.ax = 0x0f00; intcall(0x10, &ireg, &oreg); mode = oreg.al; diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h index 63cb409..9cb2edb 100644 --- a/arch/x86/include/asm/io_apic.h +++ b/arch/x86/include/asm/io_apic.h @@ -183,7 +183,7 @@ struct mp_ioapic_gsi{ u32 gsi_end; }; extern struct mp_ioapic_gsi mp_gsi_routing[]; -extern u32 gsi_end; +extern u32 gsi_top; int mp_find_ioapic(u32 gsi); int mp_find_ioapic_pin(int ioapic, u32 gsi); void __init mp_register_ioapic(int id, u32 address, u32 gsi_base); @@ -197,7 +197,7 @@ static const int timer_through_8259 = 0; static inline void ioapic_init_mappings(void) { } static inline void ioapic_insert_resources(void) { } static inline void probe_nr_irqs_gsi(void) { } -#define gsi_end (NR_IRQS_LEGACY - 1) +#define gsi_top (NR_IRQS_LEGACY) static inline int mp_find_ioapic(u32 gsi) { return 0; } struct io_apic_irq_attr; diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h index 0797e74..cd28f9a 100644 --- a/arch/x86/include/asm/percpu.h +++ b/arch/x86/include/asm/percpu.h @@ -77,6 +77,7 @@ do { \ if (0) { \ pto_T__ pto_tmp__; \ pto_tmp__ = (val); \ + (void)pto_tmp__; \ } \ switch (sizeof(var)) { \ case 1: \ @@ -115,6 +116,7 @@ do { \ if (0) { \ pao_T__ pao_tmp__; \ pao_tmp__ = (val); \ + (void)pao_tmp__; \ } \ switch (sizeof(var)) { \ case 1: \ diff --git a/arch/x86/include/asm/pgtable_32_types.h b/arch/x86/include/asm/pgtable_32_types.h index 5e67c15..ed5903b 100644 --- a/arch/x86/include/asm/pgtable_32_types.h +++ b/arch/x86/include/asm/pgtable_32_types.h @@ -26,7 +26,7 @@ */ #define VMALLOC_OFFSET (8 * 1024 * 1024) -#ifndef __ASSEMBLER__ +#ifndef __ASSEMBLY__ extern bool __vmalloc_start_set; /* set once high_memory is set */ #endif diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h index b8fe48e..e7f4d33 100644 --- a/arch/x86/include/asm/system.h +++ b/arch/x86/include/asm/system.h @@ -451,7 +451,7 @@ void stop_this_cpu(void *dummy); * * (Could use an alternative three way for this if there was one.) */ -static inline void rdtsc_barrier(void) +static __always_inline void rdtsc_barrier(void) { alternative(ASM_NOP3, "mfence", X86_FEATURE_MFENCE_RDTSC); alternative(ASM_NOP3, "lfence", X86_FEATURE_LFENCE_RDTSC); diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 60cc405..c05872a 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -118,7 +118,7 @@ static unsigned int gsi_to_irq(unsigned int gsi) if (gsi >= NR_IRQS_LEGACY) irq = gsi; else - irq = gsi_end + 1 + gsi; + irq = gsi_top + gsi; return irq; } @@ -129,10 +129,10 @@ static u32 irq_to_gsi(int irq) if (irq < NR_IRQS_LEGACY) gsi = isa_irq_to_gsi[irq]; - else if (irq <= gsi_end) + else if (irq < gsi_top) gsi = irq; - else if (irq <= (gsi_end + NR_IRQS_LEGACY)) - gsi = irq - gsi_end; + else if (irq < (gsi_top + NR_IRQS_LEGACY)) + gsi = irq - gsi_top; else gsi = 0xffffffff; diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 33f3563..e41ed24 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -89,8 +89,8 @@ int nr_ioapics; /* IO APIC gsi routing info */ struct mp_ioapic_gsi mp_gsi_routing[MAX_IO_APICS]; -/* The last gsi number used */ -u32 gsi_end; +/* The one past the highest gsi number used */ +u32 gsi_top; /* MP IRQ source entries */ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES]; @@ -1035,7 +1035,7 @@ static int pin_2_irq(int idx, int apic, int pin) if (gsi >= NR_IRQS_LEGACY) irq = gsi; else - irq = gsi_end + 1 + gsi; + irq = gsi_top + gsi; } #ifdef CONFIG_X86_32 @@ -3853,7 +3853,7 @@ void __init probe_nr_irqs_gsi(void) { int nr; - nr = gsi_end + 1 + NR_IRQS_LEGACY; + nr = gsi_top + NR_IRQS_LEGACY; if (nr > nr_irqs_gsi) nr_irqs_gsi = nr; @@ -4294,8 +4294,8 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base) */ nr_ioapic_registers[idx] = entries; - if (mp_gsi_routing[idx].gsi_end > gsi_end) - gsi_end = mp_gsi_routing[idx].gsi_end; + if (mp_gsi_routing[idx].gsi_end >= gsi_top) + gsi_top = mp_gsi_routing[idx].gsi_end + 1; printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, " "GSI %d-%d\n", idx, mp_ioapics[idx].apicid, diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index fdbc652..214ac86 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c @@ -72,6 +72,7 @@ static struct event_constraint intel_westmere_event_constraints[] = INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */ INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */ INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */ + INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */ EVENT_CONSTRAINT_END }; diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 7bca3c6..0d6fc71 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c @@ -729,7 +729,7 @@ static int __init e820_mark_nvs_memory(void) struct e820entry *ei = &e820.map[i]; if (ei->type == E820_NVS) - hibernate_nvs_register(ei->addr, ei->size); + suspend_nvs_register(ei->addr, ei->size); } return 0; diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index 5ae5d24..d86dbf7 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -123,7 +123,7 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m) printk(KERN_INFO "I/O APIC #%d Version %d at 0x%X.\n", m->apicid, m->apicver, m->apicaddr); - mp_register_ioapic(m->apicid, m->apicaddr, gsi_end + 1); + mp_register_ioapic(m->apicid, m->apicaddr, gsi_top); } static void print_MP_intsrc_info(struct mpc_intsrc *m) diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c index fb99f7e..0b96b55 100644 --- a/arch/x86/kernel/pci-calgary_64.c +++ b/arch/x86/kernel/pci-calgary_64.c @@ -103,11 +103,16 @@ int use_calgary __read_mostly = 0; #define PMR_SOFTSTOPFAULT 0x40000000 #define PMR_HARDSTOP 0x20000000 -#define MAX_NUM_OF_PHBS 8 /* how many PHBs in total? */ -#define MAX_NUM_CHASSIS 8 /* max number of chassis */ -/* MAX_PHB_BUS_NUM is the maximal possible dev->bus->number */ -#define MAX_PHB_BUS_NUM (MAX_NUM_OF_PHBS * MAX_NUM_CHASSIS * 2) -#define PHBS_PER_CALGARY 4 +/* + * The maximum PHB bus number. + * x3950M2 (rare): 8 chassis, 48 PHBs per chassis = 384 + * x3950M2: 4 chassis, 48 PHBs per chassis = 192 + * x3950 (PCIE): 8 chassis, 32 PHBs per chassis = 256 + * x3950 (PCIX): 8 chassis, 16 PHBs per chassis = 128 + */ +#define MAX_PHB_BUS_NUM 384 + +#define PHBS_PER_CALGARY 4 /* register offsets in Calgary's internal register space */ static const unsigned long tar_offsets[] = { diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 8e1aac8..e3af342 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c @@ -228,6 +228,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), }, }, + { /* Handle problems with rebooting on Dell T7400's */ + .callback = set_bios_reboot, + .ident = "Dell Precision T7400", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), + DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T7400"), + }, + }, { /* Handle problems with rebooting on HP laptops */ .callback = set_bios_reboot, .ident = "HP Compaq Laptop", diff --git a/arch/x86/kernel/sfi.c b/arch/x86/kernel/sfi.c index 7ded578..cb22acf 100644 --- a/arch/x86/kernel/sfi.c +++ b/arch/x86/kernel/sfi.c @@ -93,7 +93,7 @@ static int __init sfi_parse_ioapic(struct sfi_table_header *table) pentry = (struct sfi_apic_table_entry *)sb->pentry; for (i = 0; i < num; i++) { - mp_register_ioapic(i, pentry->phys_addr, gsi_end + 1); + mp_register_ioapic(i, pentry->phys_addr, gsi_top); pentry++; } diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index acc15b2..64121a1 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c @@ -302,7 +302,7 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, return -EINVAL; } - new = kmalloc(sizeof(struct memtype), GFP_KERNEL); + new = kzalloc(sizeof(struct memtype), GFP_KERNEL); if (!new) return -ENOMEM; diff --git a/arch/x86/mm/pat_rbtree.c b/arch/x86/mm/pat_rbtree.c index f537087..f20eeec 100644 --- a/arch/x86/mm/pat_rbtree.c +++ b/arch/x86/mm/pat_rbtree.c @@ -226,6 +226,7 @@ int rbt_memtype_check_insert(struct memtype *new, unsigned long *ret_type) if (ret_type) new->type = *ret_type; + new->subtree_max_end = new->end; memtype_rb_insert(&memtype_rbroot, new); } return err; diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index d269a8f..446aced 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c @@ -46,6 +46,8 @@ static unsigned long power_saving_mwait_eax; static unsigned char tsc_detected_unstable; static unsigned char tsc_marked_unstable; +static unsigned char lapic_detected_unstable; +static unsigned char lapic_marked_unstable; static void power_saving_mwait_init(void) { @@ -75,9 +77,6 @@ static void power_saving_mwait_init(void) power_saving_mwait_eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) | (highest_subcstate - 1); - for_each_online_cpu(i) - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &i); - #if defined(CONFIG_GENERIC_TIME) && defined(CONFIG_X86) switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_AMD: @@ -86,13 +85,15 @@ static void power_saving_mwait_init(void) * AMD Fam10h TSC will tick in all * C/P/S0/S1 states when this bit is set. */ - if (boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) - return; - - /*FALL THROUGH*/ + if (!boot_cpu_has(X86_FEATURE_NONSTOP_TSC)) + tsc_detected_unstable = 1; + if (!boot_cpu_has(X86_FEATURE_ARAT)) + lapic_detected_unstable = 1; + break; default: - /* TSC could halt in idle */ + /* TSC & LAPIC could halt in idle */ tsc_detected_unstable = 1; + lapic_detected_unstable = 1; } #endif } @@ -180,10 +181,20 @@ static int power_saving_thread(void *data) mark_tsc_unstable("TSC halts in idle"); tsc_marked_unstable = 1; } + if (lapic_detected_unstable && !lapic_marked_unstable) { + int i; + /* LAPIC could halt in idle, so notify users */ + for_each_online_cpu(i) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_ON, + &i); + lapic_marked_unstable = 1; + } local_irq_disable(); cpu = smp_processor_id(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, - &cpu); + if (lapic_marked_unstable) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu); stop_critical_timings(); __monitor((void *)¤t_thread_info()->flags, 0, 0); @@ -192,8 +203,9 @@ static int power_saving_thread(void *data) __mwait(power_saving_mwait_eax, 1); start_critical_timings(); - clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, - &cpu); + if (lapic_marked_unstable) + clockevents_notify( + CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu); local_irq_enable(); if (jiffies > expire_time) { diff --git a/drivers/acpi/acpica/acconfig.h b/drivers/acpi/acpica/acconfig.h index 33181ad..b17d8de 100644 --- a/drivers/acpi/acpica/acconfig.h +++ b/drivers/acpi/acpica/acconfig.h @@ -119,6 +119,10 @@ #define ACPI_MAX_LOOP_ITERATIONS 0xFFFF +/* Maximum sleep allowed via Sleep() operator */ + +#define ACPI_MAX_SLEEP 20000 /* Two seconds */ + /****************************************************************************** * * ACPI Specification constants (Do not change unless the specification changes) diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index 64d1e5c..c3f43da 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h @@ -80,10 +80,6 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info *gpe_xrupt_list); acpi_status acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); -acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); - -acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); - struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, u32 gpe_number); diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index 9070f1f..899d68a 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h @@ -125,6 +125,14 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE); */ u8 ACPI_INIT_GLOBAL(acpi_gbl_copy_dsdt_locally, FALSE); +/* + * Optionally truncate I/O addresses to 16 bits. Provides compatibility + * with other ACPI implementations. NOTE: During ACPICA initialization, + * this value is set to TRUE if any Windows OSI strings have been + * requested by the BIOS. + */ +u8 ACPI_INIT_GLOBAL(acpi_gbl_truncate_io_addresses, FALSE); + /* acpi_gbl_FADT is a local copy of the FADT, converted to a common format. */ struct acpi_table_fadt acpi_gbl_FADT; diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5900f13..3239158 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h @@ -90,7 +90,11 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width); /* * hwgpe - GPE support */ -acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); +u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, + struct acpi_gpe_register_info *gpe_register_info); + +acpi_status +acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); acpi_status acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info *gpe_event_info); diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index a221ad4..7c2c336 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c @@ -69,7 +69,7 @@ acpi_status acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) { struct acpi_gpe_register_info *gpe_register_info; - u8 register_bit; + u32 register_bit; ACPI_FUNCTION_TRACE(ev_update_gpe_enable_masks); @@ -78,9 +78,8 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_NOT_EXIST); } - register_bit = (u8) - (1 << - (gpe_event_info->gpe_number - gpe_register_info->base_gpe_number)); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* Clear the wake/run bits up front */ @@ -100,106 +99,6 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info) return_ACPI_STATUS(AE_OK); } -/******************************************************************************* - * - * FUNCTION: acpi_ev_enable_gpe - * - * PARAMETERS: gpe_event_info - GPE to enable - * - * RETURN: Status - * - * DESCRIPTION: Hardware-enable a GPE. Always enables the GPE, regardless - * of type or number of references. - * - * Note: The GPE lock should be already acquired when this function is called. - * - ******************************************************************************/ - -acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - - ACPI_FUNCTION_TRACE(ev_enable_gpe); - - - /* - * We will only allow a GPE to be enabled if it has either an - * associated method (_Lxx/_Exx) or a handler. Otherwise, the - * GPE will be immediately disabled by acpi_ev_gpe_dispatch the - * first time it fires. - */ - if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { - return_ACPI_STATUS(AE_NO_HANDLER); - } - - /* Ensure the HW enable masks are current */ - - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Clear the GPE (of stale events) */ - - status = acpi_hw_clear_gpe(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* Enable the requested GPE */ - - status = acpi_hw_write_gpe_enable_reg(gpe_event_info); - return_ACPI_STATUS(status); -} - -/******************************************************************************* - * - * FUNCTION: acpi_ev_disable_gpe - * - * PARAMETERS: gpe_event_info - GPE to disable - * - * RETURN: Status - * - * DESCRIPTION: Hardware-disable a GPE. Always disables the requested GPE, - * regardless of the type or number of references. - * - * Note: The GPE lock should be already acquired when this function is called. - * - ******************************************************************************/ - -acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) -{ - acpi_status status; - - ACPI_FUNCTION_TRACE(ev_disable_gpe); - - - /* - * Note: Always disable the GPE, even if we think that that it is already - * disabled. It is possible that the AML or some other code has enabled - * the GPE behind our back. - */ - - /* Ensure the HW enable masks are current */ - - status = acpi_ev_update_gpe_enable_masks(gpe_event_info); - if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); - } - - /* - * Always H/W disable this GPE, even if we don't know the GPE type. - * Simply clear the enable bit for this particular GPE, but do not - * write out the current GPE enable mask since this may inadvertently - * enable GPEs too early. An example is a rogue GPE that has arrived - * during ACPICA initialization - possibly because AML or other code - * has enabled the GPE. - */ - status = acpi_hw_low_disable_gpe(gpe_event_info); - return_ACPI_STATUS(status); -} - /******************************************************************************* * @@ -451,10 +350,6 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) return_VOID; } - /* Update the GPE register masks for return to enabled state */ - - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); - /* * Take a snapshot of the GPE info for this level - we copy the info to * prevent a race condition with remove_handler/remove_block. @@ -607,7 +502,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * Disable the GPE, so it doesn't keep firing before the method has a * chance to run (it runs asynchronously with interrupts enabled). */ - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE[0x%2X]", @@ -644,7 +539,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) * Disable the GPE. The GPE will remain disabled a handler * is installed or ACPICA is restarted. */ - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Unable to disable GPE[0x%2X]", diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 7c28f2d..341a38c 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c @@ -500,6 +500,19 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; gpe_event_info = &gpe_block->event_info[gpe_index]; + gpe_number = gpe_index + gpe_block->block_base_number; + + /* + * If the GPE has already been enabled for runtime + * signaling, make sure it remains enabled, but do not + * increment its reference counter. + */ + if (gpe_event_info->runtime_count) { + acpi_set_gpe(gpe_device, gpe_number, + ACPI_GPE_ENABLE); + gpe_enabled_count++; + continue; + } if (gpe_event_info->flags & ACPI_GPE_CAN_WAKE) { wake_gpe_count++; @@ -516,7 +529,6 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device, /* Enable this GPE */ - gpe_number = gpe_index + gpe_block->block_base_number; status = acpi_enable_gpe(gpe_device, gpe_number, ACPI_GPE_TYPE_RUNTIME); if (ACPI_FAILURE(status)) { diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index cc82502..4a531cd 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c @@ -719,13 +719,6 @@ acpi_install_gpe_handler(acpi_handle gpe_device, handler->context = context; handler->method_node = gpe_event_info->dispatch.method_node; - /* Disable the GPE before installing the handler */ - - status = acpi_ev_disable_gpe(gpe_event_info); - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - /* Install the handler */ flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index d5a5efc..d97b8dc 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c @@ -210,6 +210,44 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) /******************************************************************************* * + * FUNCTION: acpi_clear_and_enable_gpe + * + * PARAMETERS: gpe_event_info - GPE to enable + * + * RETURN: Status + * + * DESCRIPTION: Clear the given GPE from stale events and enable it. + * + ******************************************************************************/ +static acpi_status +acpi_clear_and_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) +{ + acpi_status status; + + /* + * We will only allow a GPE to be enabled if it has either an + * associated method (_Lxx/_Exx) or a handler. Otherwise, the + * GPE will be immediately disabled by acpi_ev_gpe_dispatch the + * first time it fires. + */ + if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { + return_ACPI_STATUS(AE_NO_HANDLER); + } + + /* Clear the GPE (of stale events) */ + status = acpi_hw_clear_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) { + return_ACPI_STATUS(status); + } + + /* Enable the requested GPE */ + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_ENABLE); + + return_ACPI_STATUS(status); +} + +/******************************************************************************* + * * FUNCTION: acpi_set_gpe * * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 @@ -249,11 +287,11 @@ acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action) switch (action) { case ACPI_GPE_ENABLE: - status = acpi_ev_enable_gpe(gpe_event_info); + status = acpi_clear_and_enable_gpe(gpe_event_info); break; case ACPI_GPE_DISABLE: - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); break; default: @@ -316,7 +354,11 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) gpe_event_info->runtime_count++; if (gpe_event_info->runtime_count == 1) { - status = acpi_ev_enable_gpe(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_clear_and_enable_gpe(gpe_event_info); + } + if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count--; goto unlock_and_exit; @@ -343,7 +385,7 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type) */ gpe_event_info->wakeup_count++; if (gpe_event_info->wakeup_count == 1) { - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); } } @@ -403,7 +445,12 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type gpe_event_info->runtime_count--; if (!gpe_event_info->runtime_count) { - status = acpi_ev_disable_gpe(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); + if (ACPI_SUCCESS(status)) { + status = acpi_hw_low_set_gpe(gpe_event_info, + ACPI_GPE_DISABLE); + } + if (ACPI_FAILURE(status)) { gpe_event_info->runtime_count++; goto unlock_and_exit; @@ -424,7 +471,7 @@ acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number, u8 gpe_type gpe_event_info->wakeup_count--; if (!gpe_event_info->wakeup_count) { - (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); + status = acpi_ev_update_gpe_enable_masks(gpe_event_info); } } diff --git a/drivers/acpi/acpica/exsystem.c b/drivers/acpi/acpica/exsystem.c index 6d32e09..675aaa9 100644 --- a/drivers/acpi/acpica/exsystem.c +++ b/drivers/acpi/acpica/exsystem.c @@ -201,6 +201,14 @@ acpi_status acpi_ex_system_do_sleep(u64 how_long) acpi_ex_relinquish_interpreter(); + /* + * For compatibility with other ACPI implementations and to prevent + * accidental deep sleeps, limit the sleep time to something reasonable. + */ + if (how_long > ACPI_MAX_SLEEP) { + how_long = ACPI_MAX_SLEEP; + } + acpi_os_sleep(how_long); /* And now we must get the interpreter again */ diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index bd72319..3450309 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c @@ -57,21 +57,47 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, /****************************************************************************** * - * FUNCTION: acpi_hw_low_disable_gpe + * FUNCTION: acpi_hw_gpe_register_bit + * + * PARAMETERS: gpe_event_info - Info block for the GPE + * gpe_register_info - Info block for the GPE register + * + * RETURN: Status + * + * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given + * GPE set. + * + ******************************************************************************/ + +u32 acpi_hw_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, + struct acpi_gpe_register_info *gpe_register_info) +{ + return (u32)1 << (gpe_event_info->gpe_number - + gpe_register_info->base_gpe_number); +} + +/****************************************************************************** + * + * FUNCTION: acpi_hw_low_set_gpe * * PARAMETERS: gpe_event_info - Info block for the GPE to be disabled + * action - Enable or disable * * RETURN: Status * - * DESCRIPTION: Disable a single GPE in the enable register. + * DESCRIPTION: Enable or disable a single GPE in its enable register. * ******************************************************************************/ -acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) +acpi_status +acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) { struct acpi_gpe_register_info *gpe_register_info; acpi_status status; u32 enable_mask; + u32 register_bit; + + ACPI_FUNCTION_ENTRY(); /* Get the info block for the entire GPE register */ @@ -87,11 +113,27 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) return (status); } - /* Clear just the bit that corresponds to this GPE */ + /* Set ot clear just the bit that corresponds to this GPE */ - ACPI_CLEAR_BIT(enable_mask, ((u32)1 << - (gpe_event_info->gpe_number - - gpe_register_info->base_gpe_number))); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); + switch (action) { + case ACPI_GPE_COND_ENABLE: + if (!(register_bit & gpe_register_info->enable_for_run)) + return (AE_BAD_PARAMETER); + + case ACPI_GPE_ENABLE: + ACPI_SET_BIT(enable_mask, register_bit); + break; + + case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT(enable_mask, register_bit); + break; + + default: + ACPI_ERROR((AE_INFO, "Invalid action\n")); + return (AE_BAD_PARAMETER); + } /* Write the updated enable mask */ @@ -116,23 +158,11 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) acpi_status acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) { - struct acpi_gpe_register_info *gpe_register_info; acpi_status status; ACPI_FUNCTION_ENTRY(); - /* Get the info block for the entire GPE register */ - - gpe_register_info = gpe_event_info->register_info; - if (!gpe_register_info) { - return (AE_NOT_EXIST); - } - - /* Write the entire GPE (runtime) enable register */ - - status = acpi_hw_write(gpe_register_info->enable_for_run, - &gpe_register_info->enable_address); - + status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); return (status); } @@ -150,21 +180,28 @@ acpi_hw_write_gpe_enable_reg(struct acpi_gpe_event_info * gpe_event_info) acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) { + struct acpi_gpe_register_info *gpe_register_info; acpi_status status; - u8 register_bit; + u32 register_bit; ACPI_FUNCTION_ENTRY(); - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + /* Get the info block for the entire GPE register */ + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + return (AE_NOT_EXIST); + } + + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* * Write a one to the appropriate bit in the status register to * clear this GPE. */ status = acpi_hw_write(register_bit, - &gpe_event_info->register_info->status_address); + &gpe_register_info->status_address); return (status); } @@ -187,7 +224,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, acpi_event_status * event_status) { u32 in_byte; - u8 register_bit; + u32 register_bit; struct acpi_gpe_register_info *gpe_register_info; acpi_status status; acpi_event_status local_event_status = 0; @@ -204,9 +241,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, /* Get the register bitmask for this GPE */ - register_bit = (u8)(1 << - (gpe_event_info->gpe_number - - gpe_event_info->register_info->base_gpe_number)); + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); /* GPE currently enabled? (enabled for runtime?) */ diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c index c10d587..e1d9c77 100644 --- a/drivers/acpi/acpica/hwvalid.c +++ b/drivers/acpi/acpica/hwvalid.c @@ -222,6 +222,12 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width) u32 one_byte; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); @@ -279,6 +285,12 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width) acpi_status status; u32 i; + /* Truncate address to 16 bits if requested */ + + if (acpi_gbl_truncate_io_addresses) { + address &= ACPI_UINT16_MAX; + } + /* Validate the entire request and perform the I/O */ status = acpi_hw_validate_io_request(address, width); diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c index 9bd6f05..4e5272c 100644 --- a/drivers/acpi/acpica/nsinit.c +++ b/drivers/acpi/acpica/nsinit.c @@ -193,6 +193,15 @@ acpi_status acpi_ns_initialize_devices(void) acpi_ns_init_one_device, NULL, &info, NULL); + /* + * Any _OSI requests should be completed by now. If the BIOS has + * requested any Windows OSI strings, we will always truncate + * I/O addresses to 16 bits -- for Windows compatibility. + */ + if (acpi_gbl_osi_data >= ACPI_OSI_WIN_2000) { + acpi_gbl_truncate_io_addresses = TRUE; + } + ACPI_FREE(info.evaluate_info); if (ACPI_FAILURE(status)) { goto error_exit; diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index db3946e..216e1e9 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/acpi.h> +#include <linux/slab.h> #include <linux/io.h> #include <linux/kref.h> #include <linux/rculist.h> diff --git a/drivers/acpi/atomicio.c b/drivers/acpi/atomicio.c index 814b192..8f8bd73 100644 --- a/drivers/acpi/atomicio.c +++ b/drivers/acpi/atomicio.c @@ -31,6 +31,7 @@ #include <linux/kref.h> #include <linux/rculist.h> #include <linux/interrupt.h> +#include <linux/slab.h> #include <acpi/atomicio.h> #define ACPI_PFX "ACPI: " diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index 2815df6..01381be 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c @@ -218,6 +218,14 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { }, }, { + .callback = dmi_disable_osi_vista, + .ident = "VGN-NS50B_L", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NS50B_L"), + }, + }, + { .callback = dmi_disable_osi_win7, .ident = "ASUS K50IJ", .matches = { diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index fd51c4a..7d857da 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -425,7 +425,7 @@ static int acpi_button_add(struct acpi_device *device) /* Button's GPE is run-wake GPE */ acpi_enable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); + ACPI_GPE_TYPE_RUNTIME); device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; } @@ -449,7 +449,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) if (device->wakeup.flags.valid) { acpi_disable_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE_RUN); + ACPI_GPE_TYPE_RUNTIME); device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; } diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index acf2ab2..8a3b840 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c @@ -347,7 +347,6 @@ static int __init acpi_fan_init(void) { int result = 0; - #ifdef CONFIG_ACPI_PROCFS acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir); if (!acpi_fan_dir) @@ -356,7 +355,9 @@ static int __init acpi_fan_init(void) result = acpi_bus_register_driver(&acpi_fan_driver); if (result < 0) { +#ifdef CONFIG_ACPI_PROCFS remove_proc_entry(ACPI_FAN_CLASS, acpi_root_dir); +#endif return -ENODEV; } diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index b1034a9..38ea0cc 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -581,6 +581,11 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return 0; } +#ifdef CONFIG_SMP + if (pr->id >= setup_max_cpus && pr->id != 0) + return 0; +#endif + BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); /* diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 3fb4bde..5b7c52e 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -114,6 +114,8 @@ static int __acpi_pm_prepare(void) { int error = acpi_sleep_prepare(acpi_target_sleep_state); + suspend_nvs_save(); + if (error) acpi_target_sleep_state = ACPI_STATE_S0; return error; @@ -143,6 +145,9 @@ static void acpi_pm_finish(void) { u32 acpi_state = acpi_target_sleep_state; + suspend_nvs_free(); + acpi_ec_unblock_transactions(); + if (acpi_state == ACPI_STATE_S0) return; @@ -192,6 +197,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state) u32 acpi_state = acpi_suspend_states[pm_state]; int error = 0; + error = suspend_nvs_alloc(); + + if (error) + return error; + if (sleep_states[acpi_state]) { acpi_target_sleep_state = acpi_state; acpi_sleep_tts_switch(acpi_target_sleep_state); @@ -269,12 +279,13 @@ static int acpi_suspend_enter(suspend_state_t pm_state) if (acpi_state == ACPI_STATE_S3) acpi_restore_state_mem(); + suspend_nvs_restore(); + return ACPI_SUCCESS(status) ? 0 : -EFAULT; } static void acpi_suspend_finish(void) { - acpi_ec_unblock_transactions(); acpi_pm_finish(); } @@ -404,7 +415,7 @@ static int acpi_hibernation_begin(void) { int error; - error = s4_no_nvs ? 0 : hibernate_nvs_alloc(); + error = s4_no_nvs ? 0 : suspend_nvs_alloc(); if (!error) { acpi_target_sleep_state = ACPI_STATE_S4; acpi_sleep_tts_switch(acpi_target_sleep_state); @@ -418,7 +429,7 @@ static int acpi_hibernation_pre_snapshot(void) int error = acpi_pm_prepare(); if (!error) - hibernate_nvs_save(); + suspend_nvs_save(); return error; } @@ -441,13 +452,6 @@ static int acpi_hibernation_enter(void) return ACPI_SUCCESS(status) ? 0 : -EFAULT; } -static void acpi_hibernation_finish(void) -{ - hibernate_nvs_free(); - acpi_ec_unblock_transactions(); - acpi_pm_finish(); -} - static void acpi_hibernation_leave(void) { /* @@ -464,7 +468,7 @@ static void acpi_hibernation_leave(void) panic("ACPI S4 hardware signature mismatch"); } /* Restore the NVS memory area */ - hibernate_nvs_restore(); + suspend_nvs_restore(); /* Allow EC transactions to happen. */ acpi_ec_unblock_transactions_early(); } @@ -479,7 +483,7 @@ static struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, .pre_snapshot = acpi_hibernation_pre_snapshot, - .finish = acpi_hibernation_finish, + .finish = acpi_pm_finish, .prepare = acpi_pm_prepare, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, @@ -507,7 +511,7 @@ static int acpi_hibernation_begin_old(void) if (!error) { if (!s4_no_nvs) - error = hibernate_nvs_alloc(); + error = suspend_nvs_alloc(); if (!error) acpi_target_sleep_state = ACPI_STATE_S4; } @@ -517,7 +521,7 @@ static int acpi_hibernation_begin_old(void) static int acpi_hibernation_pre_snapshot_old(void) { acpi_pm_freeze(); - hibernate_nvs_save(); + suspend_nvs_save(); return 0; } @@ -529,8 +533,8 @@ static struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, .pre_snapshot = acpi_hibernation_pre_snapshot_old, - .finish = acpi_hibernation_finish, .prepare = acpi_pm_freeze, + .finish = acpi_pm_finish, .enter = acpi_hibernation_enter, .leave = acpi_hibernation_leave, .pre_restore = acpi_pm_freeze, diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c index c79e789..f8db50a 100644 --- a/drivers/acpi/system.c +++ b/drivers/acpi/system.c @@ -388,10 +388,12 @@ static ssize_t counter_set(struct kobject *kobj, if (index < num_gpes) { if (!strcmp(buf, "disable\n") && (status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_set_gpe(handle, index, ACPI_GPE_DISABLE); + result = acpi_disable_gpe(handle, index, + ACPI_GPE_TYPE_RUNTIME); else if (!strcmp(buf, "enable\n") && !(status & ACPI_EVENT_FLAG_ENABLED)) - result = acpi_set_gpe(handle, index, ACPI_GPE_ENABLE); + result = acpi_enable_gpe(handle, index, + ACPI_GPE_TYPE_RUNTIME); else if (!strcmp(buf, "clear\n") && (status & ACPI_EVENT_FLAG_SET)) result = acpi_clear_gpe(handle, index); diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index 4b9d339..388747a 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c @@ -64,16 +64,13 @@ void acpi_enable_wakeup_device(u8 sleep_state) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid) - continue; - - if ((!dev->wakeup.state.enabled && !dev->wakeup.prepare_count) + if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled || sleep_state > (u32) dev->wakeup.sleep_state) continue; /* The wake-up power should have been enabled already. */ - acpi_set_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_ENABLE); + acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE); } } @@ -96,6 +93,8 @@ void acpi_disable_wakeup_device(u8 sleep_state) || (sleep_state > (u32) dev->wakeup.sleep_state)) continue; + acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_TYPE_WAKE); acpi_disable_wakeup_device_power(dev); } } @@ -109,13 +108,8 @@ int __init acpi_wakeup_device_init(void) struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - /* In case user doesn't load button driver */ - if (!dev->wakeup.flags.always_enabled || - dev->wakeup.state.enabled) - continue; - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - dev->wakeup.state.enabled = 1; + if (dev->wakeup.flags.always_enabled) + dev->wakeup.state.enabled = 1; } mutex_unlock(&acpi_device_lock); return 0; diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 5d15630..5d64e3a 100644 --- a/drivers/char/sysrq.c +++ b/drivers/char/sysrq.c @@ -580,8 +580,12 @@ static bool sysrq_filter(struct input_handle *handle, unsigned int type, case KEY_RIGHTALT: if (value) sysrq_alt = code; - else if (sysrq_down && code == sysrq_alt_use) - sysrq_down = false; + else { + if (sysrq_down && code == sysrq_alt_use) + sysrq_down = false; + + sysrq_alt = 0; + } break; case KEY_SYSRQ: diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 8e00b4d..792868d 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -224,6 +224,7 @@ struct tpm_readpubek_params_out { u8 algorithm[4]; u8 encscheme[2]; u8 sigscheme[2]; + __be32 paramsize; u8 parameters[12]; /*assuming RSA*/ __be32 keysize; u8 modulus[256]; diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index f3d3898..717305d 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -449,7 +449,7 @@ static int sh_cmt_register_clocksource(struct sh_cmt_priv *p, clk_disable(p->clk); /* TODO: calculate good shift from rate and counter bit width */ - cs->shift = 10; + cs->shift = 0; cs->mult = clocksource_hz2mult(p->rate, cs->shift); dev_info(&p->pdev->dev, "used as clock source\n"); diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c index e880e2c..9379834 100644 --- a/drivers/hwmon/i5k_amb.c +++ b/drivers/hwmon/i5k_amb.c @@ -289,6 +289,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_label; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -303,6 +304,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_temp; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -318,6 +320,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_min; iattr->s_attr.dev_attr.store = store_amb_min; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -333,6 +336,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_mid; iattr->s_attr.dev_attr.store = store_amb_mid; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -348,6 +352,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.show = show_amb_max; iattr->s_attr.dev_attr.store = store_amb_max; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) @@ -362,6 +367,7 @@ static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) iattr->s_attr.dev_attr.attr.mode = S_IRUGO; iattr->s_attr.dev_attr.show = show_amb_alarm; iattr->s_attr.index = k; + sysfs_attr_init(&iattr->s_attr.dev_attr.attr); res = device_create_file(&pdev->dev, &iattr->s_attr.dev_attr); if (res) diff --git a/drivers/hwmon/k10temp.c b/drivers/hwmon/k10temp.c index 099a213..da5a240 100644 --- a/drivers/hwmon/k10temp.c +++ b/drivers/hwmon/k10temp.c @@ -112,11 +112,21 @@ static bool __devinit has_erratum_319(struct pci_dev *pdev) if (pkg_type != CPUID_PKGTYPE_AM2R2_AM3) return false; - /* Differentiate between AM2+ (bad) and AM3 (good) */ + /* DDR3 memory implies socket AM3, which is good */ pci_bus_read_config_dword(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 2), REG_DCT0_CONFIG_HIGH, ®_dram_cfg); - return !(reg_dram_cfg & DDR3_MODE); + if (reg_dram_cfg & DDR3_MODE) + return false; + + /* + * Unfortunately it is possible to run a socket AM3 CPU with DDR2 + * memory. We blacklist all the cores which do exist in socket AM2+ + * format. It still isn't perfect, as RB-C2 cores exist in both AM2+ + * and AM3 formats, but that's the best we can do. + */ + return boot_cpu_data.x86_model < 4 || + (boot_cpu_data.x86_model == 4 && boot_cpu_data.x86_mask <= 2); } static int __devinit k10temp_probe(struct pci_dev *pdev, diff --git a/drivers/hwmon/k8temp.c b/drivers/hwmon/k8temp.c index 0ceb6d6..f26acdb 100644 --- a/drivers/hwmon/k8temp.c +++ b/drivers/hwmon/k8temp.c @@ -120,7 +120,7 @@ static ssize_t show_temp(struct device *dev, int temp; struct k8temp_data *data = k8temp_update_device(dev); - if (data->swap_core_select) + if (data->swap_core_select && (data->sensorsp & SEL_CORE)) core = core ? 0 : 1; temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index d8fa5d7..0f9a478 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -69,7 +69,7 @@ config KEYBOARD_ATARI module will be called atakbd. config KEYBOARD_ATKBD - tristate "AT keyboard" if EMBEDDED || !X86 + tristate "AT keyboard" if EMBEDDED || !X86 || X86_MRST default y select SERIO select SERIO_LIBPS2 diff --git a/drivers/input/misc/pcf8574_keypad.c b/drivers/input/misc/pcf8574_keypad.c index 0ac47d2..4b42ffc 100644 --- a/drivers/input/misc/pcf8574_keypad.c +++ b/drivers/input/misc/pcf8574_keypad.c @@ -69,7 +69,7 @@ static irqreturn_t pcf8574_kp_irq_handler(int irq, void *dev_id) unsigned char nextstate = read_state(lp); if (lp->laststate != nextstate) { - int key_down = nextstate <= ARRAY_SIZE(lp->btncode); + int key_down = nextstate < ARRAY_SIZE(lp->btncode); unsigned short keycode = key_down ? lp->btncode[nextstate] : lp->btncode[lp->laststate]; diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 3bfe8fa..256b9e9 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -22,7 +22,7 @@ config SERIO_I8042 tristate "i8042 PC Keyboard controller" if EMBEDDED || !X86 default y depends on !PARISC && (!ARM || ARCH_SHARK || FOOTBRIDGE_HOST) && \ - (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN + (!SUPERH || SH_CAYMAN) && !M68K && !BLACKFIN && !X86_MRST help i8042 is the chip over which the standard AT keyboard and PS/2 mouse are connected to the computer. If you use these devices, diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index d564af5..415f630 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -284,12 +284,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom) (data[4] << 20) + (data[5] << 12) + (data[6] << 4) + (data[7] >> 4); - wacom->id[idx] = (data[2] << 4) | (data[3] >> 4); + wacom->id[idx] = (data[2] << 4) | (data[3] >> 4) | + ((data[7] & 0x0f) << 20) | ((data[8] & 0xf0) << 12); - switch (wacom->id[idx]) { + switch (wacom->id[idx] & 0xfffff) { case 0x812: /* Inking pen */ case 0x801: /* Intuos3 Inking pen */ - case 0x20802: /* Intuos4 Classic Pen */ + case 0x20802: /* Intuos4 Inking Pen */ case 0x012: wacom->tool[idx] = BTN_TOOL_PENCIL; break; @@ -513,7 +514,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) input_report_abs(input, ABS_RX, ((data[1] & 0x1f) << 8) | data[2]); input_report_abs(input, ABS_RY, ((data[3] & 0x1f) << 8) | data[4]); - if ((data[5] & 0x1f) | (data[6] & 0x1f) | (data[1] & 0x1f) | + if ((data[5] & 0x1f) | data[6] | (data[1] & 0x1f) | data[2] | (data[3] & 0x1f) | data[4] | data[8] | (data[7] & 0x01)) { input_report_key(input, wacom->tool[1], 1); diff --git a/drivers/input/touchscreen/ad7877.c b/drivers/input/touchscreen/ad7877.c index 0d2d7e5..5f0221c 100644 --- a/drivers/input/touchscreen/ad7877.c +++ b/drivers/input/touchscreen/ad7877.c @@ -679,6 +679,13 @@ static int __devinit ad7877_probe(struct spi_device *spi) return -EINVAL; } + spi->bits_per_word = 16; + err = spi_setup(spi); + if (err) { + dev_dbg(&spi->dev, "spi master doesn't support 16 bits/word\n"); + return err; + } + ts = kzalloc(sizeof(struct ad7877), GFP_KERNEL); input_dev = input_allocate_device(); if (!ts || !input_dev) { diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index c5016bd..c3b1dc3 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c @@ -126,26 +126,6 @@ static unsigned lock_loop(unsigned numbytes, struct inbuf_t *inbuf) return numbytes; } -/* set up next receive skb for data mode - */ -static void new_rcv_skb(struct bc_state *bcs) -{ - struct cardstate *cs = bcs->cs; - unsigned short hw_hdr_len = cs->hw_hdr_len; - - if (bcs->ignore) { - bcs->skb = NULL; - return; - } - - bcs->skb = dev_alloc_skb(SBUFSIZE + hw_hdr_len); - if (bcs->skb == NULL) { - dev_warn(cs->dev, "could not allocate new skb\n"); - return; - } - skb_reserve(bcs->skb, hw_hdr_len); -} - /* process a block of received bytes in HDLC data mode * (mstate != MS_LOCKED && !(inputstate & INS_command) && proto2 == L2_HDLC) * Collect HDLC frames, undoing byte stuffing and watching for DLE escapes. @@ -159,8 +139,8 @@ static unsigned hdlc_loop(unsigned numbytes, struct inbuf_t *inbuf) struct cardstate *cs = inbuf->cs; struct bc_state *bcs = cs->bcs; int inputstate = bcs->inputstate; - __u16 fcs = bcs->fcs; - struct sk_buff *skb = bcs->skb; + __u16 fcs = bcs->rx_fcs; + struct sk_buff *skb = bcs->rx_skb; unsigned char *src = inbuf->data + inbuf->head; unsigned procbytes = 0; unsigned char c; @@ -245,8 +225,7 @@ byte_stuff: /* prepare reception of next frame */ inputstate &= ~INS_have_data; - new_rcv_skb(bcs); - skb = bcs->skb; + skb = gigaset_new_rx_skb(bcs); } else { /* empty frame (7E 7E) */ #ifdef CONFIG_GIGASET_DEBUG @@ -255,8 +234,7 @@ byte_stuff: if (!skb) { /* skipped (?) */ gigaset_isdn_rcv_err(bcs); - new_rcv_skb(bcs); - skb = bcs->skb; + skb = gigaset_new_rx_skb(bcs); } } @@ -279,11 +257,11 @@ byte_stuff: #endif inputstate |= INS_have_data; if (skb) { - if (skb->len == SBUFSIZE) { + if (skb->len >= bcs->rx_bufsize) { dev_warn(cs->dev, "received packet too long\n"); dev_kfree_skb_any(skb); /* skip remainder of packet */ - bcs->skb = skb = NULL; + bcs->rx_skb = skb = NULL; } else { *__skb_put(skb, 1) = c; fcs = crc_ccitt_byte(fcs, c); @@ -292,7 +270,7 @@ byte_stuff: } bcs->inputstate = inputstate; - bcs->fcs = fcs; + bcs->rx_fcs = fcs; return procbytes; } @@ -308,18 +286,18 @@ static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf) struct cardstate *cs = inbuf->cs; struct bc_state *bcs = cs->bcs; int inputstate = bcs->inputstate; - struct sk_buff *skb = bcs->skb; + struct sk_buff *skb = bcs->rx_skb; unsigned char *src = inbuf->data + inbuf->head; unsigned procbytes = 0; unsigned char c; if (!skb) { /* skip this block */ - new_rcv_skb(bcs); + gigaset_new_rx_skb(bcs); return numbytes; } - while (procbytes < numbytes && skb->len < SBUFSIZE) { + while (procbytes < numbytes && skb->len < bcs->rx_bufsize) { c = *src++; procbytes++; @@ -343,7 +321,7 @@ static unsigned iraw_loop(unsigned numbytes, struct inbuf_t *inbuf) if (inputstate & INS_have_data) { gigaset_skb_rcvd(bcs, skb); inputstate &= ~INS_have_data; - new_rcv_skb(bcs); + gigaset_new_rx_skb(bcs); } bcs->inputstate = inputstate; diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index 8f78f15..6fbe899 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c @@ -70,7 +70,7 @@ #define MAX_NUMBER_DIGITS 20 #define MAX_FMT_IE_LEN 20 -/* values for gigaset_capi_appl.connected */ +/* values for bcs->apconnstate */ #define APCONN_NONE 0 /* inactive/listening */ #define APCONN_SETUP 1 /* connecting */ #define APCONN_ACTIVE 2 /* B channel up */ @@ -80,10 +80,10 @@ struct gigaset_capi_appl { struct list_head ctrlist; struct gigaset_capi_appl *bcnext; u16 id; + struct capi_register_params rp; u16 nextMessageNumber; u32 listenInfoMask; u32 listenCIPmask; - int connected; }; /* CAPI specific controller data structure */ @@ -319,6 +319,39 @@ static const char *format_ie(const char *ie) return result; } +/* + * emit DATA_B3_CONF message + */ +static void send_data_b3_conf(struct cardstate *cs, struct capi_ctr *ctr, + u16 appl, u16 msgid, int channel, + u16 handle, u16 info) +{ + struct sk_buff *cskb; + u8 *msg; + + cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC); + if (!cskb) { + dev_err(cs->dev, "%s: out of memory\n", __func__); + return; + } + /* frequent message, avoid _cmsg overhead */ + msg = __skb_put(cskb, CAPI_DATA_B3_CONF_LEN); + CAPIMSG_SETLEN(msg, CAPI_DATA_B3_CONF_LEN); + CAPIMSG_SETAPPID(msg, appl); + CAPIMSG_SETCOMMAND(msg, CAPI_DATA_B3); + CAPIMSG_SETSUBCOMMAND(msg, CAPI_CONF); + CAPIMSG_SETMSGID(msg, msgid); + CAPIMSG_SETCONTROLLER(msg, ctr->cnr); + CAPIMSG_SETPLCI_PART(msg, channel); + CAPIMSG_SETNCCI_PART(msg, 1); + CAPIMSG_SETHANDLE_CONF(msg, handle); + CAPIMSG_SETINFO_CONF(msg, info); + + /* emit message */ + dump_rawmsg(DEBUG_MCMD, __func__, msg); + capi_ctr_handle_message(ctr, appl, cskb); +} + /* * driver interface functions @@ -339,7 +372,6 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb) struct gigaset_capi_ctr *iif = cs->iif; struct gigaset_capi_appl *ap = bcs->ap; unsigned char *req = skb_mac_header(dskb); - struct sk_buff *cskb; u16 flags; /* update statistics */ @@ -351,39 +383,22 @@ void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *dskb) } /* don't send further B3 messages if disconnected */ - if (ap->connected < APCONN_ACTIVE) { + if (bcs->apconnstate < APCONN_ACTIVE) { gig_dbg(DEBUG_LLDATA, "disconnected, discarding ack"); return; } - /* ToDo: honor unset "delivery confirmation" bit */ + /* + * send DATA_B3_CONF if "delivery confirmation" bit was set in request; + * otherwise it has already been sent by do_data_b3_req() + */ flags = CAPIMSG_FLAGS(req); - - /* build DATA_B3_CONF message */ - cskb = alloc_skb(CAPI_DATA_B3_CONF_LEN, GFP_ATOMIC); - if (!cskb) { - dev_err(cs->dev, "%s: out of memory\n", __func__); - return; - } - /* frequent message, avoid _cmsg overhead */ - CAPIMSG_SETLEN(cskb->data, CAPI_DATA_B3_CONF_LEN); - CAPIMSG_SETAPPID(cskb->data, ap->id); - CAPIMSG_SETCOMMAND(cskb->data, CAPI_DATA_B3); - CAPIMSG_SETSUBCOMMAND(cskb->data, CAPI_CONF); - CAPIMSG_SETMSGID(cskb->data, CAPIMSG_MSGID(req)); - CAPIMSG_SETCONTROLLER(cskb->data, iif->ctr.cnr); - CAPIMSG_SETPLCI_PART(cskb->data, bcs->channel + 1); - CAPIMSG_SETNCCI_PART(cskb->data, 1); - CAPIMSG_SETHANDLE_CONF(cskb->data, CAPIMSG_HANDLE_REQ(req)); - if (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) - CAPIMSG_SETINFO_CONF(cskb->data, - CapiFlagsNotSupportedByProtocol); - else - CAPIMSG_SETINFO_CONF(cskb->data, CAPI_NOERROR); - - /* emit message */ - dump_rawmsg(DEBUG_LLDATA, "DATA_B3_CONF", cskb->data); - capi_ctr_handle_message(&iif->ctr, ap->id, cskb); + if (flags & CAPI_FLAGS_DELIVERY_CONFIRMATION) + send_data_b3_conf(cs, &iif->ctr, ap->id, CAPIMSG_MSGID(req), + bcs->channel + 1, CAPIMSG_HANDLE_REQ(req), + (flags & ~CAPI_FLAGS_DELIVERY_CONFIRMATION) ? + CapiFlagsNotSupportedByProtocol : + CAPI_NOERROR); } EXPORT_SYMBOL_GPL(gigaset_skb_sent); @@ -412,7 +427,7 @@ void gigaset_skb_rcvd(struct bc_state *bcs, struct sk_buff *skb) } /* don't send further B3 messages if disconnected */ - if (ap->connected < APCONN_ACTIVE) { + if (bcs->apconnstate < APCONN_ACTIVE) { gig_dbg(DEBUG_LLDATA, "disconnected, discarding data"); dev_kfree_skb_any(skb); return; @@ -484,6 +499,7 @@ int gigaset_isdn_icall(struct at_state_t *at_state) u32 actCIPmask; struct sk_buff *skb; unsigned int msgsize; + unsigned long flags; int i; /* @@ -608,7 +624,14 @@ int gigaset_isdn_icall(struct at_state_t *at_state) format_ie(iif->hcmsg.CalledPartyNumber)); /* scan application list for matching listeners */ - bcs->ap = NULL; + spin_lock_irqsave(&bcs->aplock, flags); + if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE) { + dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n", + __func__, bcs->ap, bcs->apconnstate); + bcs->ap = NULL; + bcs->apconnstate = APCONN_NONE; + } + spin_unlock_irqrestore(&bcs->aplock, flags); actCIPmask = 1 | (1 << iif->hcmsg.CIPValue); list_for_each_entry(ap, &iif->appls, ctrlist) if (actCIPmask & ap->listenCIPmask) { @@ -626,10 +649,12 @@ int gigaset_isdn_icall(struct at_state_t *at_state) dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); /* add to listeners on this B channel, update state */ + spin_lock_irqsave(&bcs->aplock, flags); ap->bcnext = bcs->ap; bcs->ap = ap; bcs->chstate |= CHS_NOTIFY_LL; - ap->connected = APCONN_SETUP; + bcs->apconnstate = APCONN_SETUP; + spin_unlock_irqrestore(&bcs->aplock, flags); /* emit message */ capi_ctr_handle_message(&iif->ctr, ap->id, skb); @@ -654,7 +679,7 @@ static void send_disconnect_ind(struct bc_state *bcs, struct gigaset_capi_ctr *iif = cs->iif; struct sk_buff *skb; - if (ap->connected == APCONN_NONE) + if (bcs->apconnstate == APCONN_NONE) return; capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT, CAPI_IND, @@ -668,7 +693,6 @@ static void send_disconnect_ind(struct bc_state *bcs, } capi_cmsg2message(&iif->hcmsg, __skb_put(skb, CAPI_DISCONNECT_IND_LEN)); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); - ap->connected = APCONN_NONE; capi_ctr_handle_message(&iif->ctr, ap->id, skb); } @@ -685,9 +709,9 @@ static void send_disconnect_b3_ind(struct bc_state *bcs, struct sk_buff *skb; /* nothing to do if no logical connection active */ - if (ap->connected < APCONN_ACTIVE) + if (bcs->apconnstate < APCONN_ACTIVE) return; - ap->connected = APCONN_SETUP; + bcs->apconnstate = APCONN_SETUP; capi_cmsg_header(&iif->hcmsg, ap->id, CAPI_DISCONNECT_B3, CAPI_IND, ap->nextMessageNumber++, @@ -714,14 +738,25 @@ void gigaset_isdn_connD(struct bc_state *bcs) { struct cardstate *cs = bcs->cs; struct gigaset_capi_ctr *iif = cs->iif; - struct gigaset_capi_appl *ap = bcs->ap; + struct gigaset_capi_appl *ap; struct sk_buff *skb; unsigned int msgsize; + unsigned long flags; + spin_lock_irqsave(&bcs->aplock, flags); + ap = bcs->ap; if (!ap) { + spin_unlock_irqrestore(&bcs->aplock, flags); dev_err(cs->dev, "%s: no application\n", __func__); return; } + if (bcs->apconnstate == APCONN_NONE) { + spin_unlock_irqrestore(&bcs->aplock, flags); + dev_warn(cs->dev, "%s: application %u not connected\n", + __func__, ap->id); + return; + } + spin_unlock_irqrestore(&bcs->aplock, flags); while (ap->bcnext) { /* this should never happen */ dev_warn(cs->dev, "%s: dropping extra application %u\n", @@ -730,11 +765,6 @@ void gigaset_isdn_connD(struct bc_state *bcs) CapiCallGivenToOtherApplication); ap->bcnext = ap->bcnext->bcnext; } - if (ap->connected == APCONN_NONE) { - dev_warn(cs->dev, "%s: application %u not connected\n", - __func__, ap->id); - return; - } /* prepare CONNECT_ACTIVE_IND message * Note: LLC not supported by device @@ -772,17 +802,24 @@ void gigaset_isdn_connD(struct bc_state *bcs) void gigaset_isdn_hupD(struct bc_state *bcs) { struct gigaset_capi_appl *ap; + unsigned long flags; /* * ToDo: pass on reason code reported by device * (requires ev-layer state machine extension to collect * ZCAU device reply) */ - for (ap = bcs->ap; ap != NULL; ap = ap->bcnext) { + spin_lock_irqsave(&bcs->aplock, flags); + while (bcs->ap != NULL) { + ap = bcs->ap; + bcs->ap = ap->bcnext; + spin_unlock_irqrestore(&bcs->aplock, flags); send_disconnect_b3_ind(bcs, ap); send_disconnect_ind(bcs, ap, 0); + spin_lock_irqsave(&bcs->aplock, flags); } - bcs->ap = NULL; + bcs->apconnstate = APCONN_NONE; + spin_unlock_irqrestore(&bcs->aplock, flags); } /** @@ -796,24 +833,21 @@ void gigaset_isdn_connB(struct bc_state *bcs) { struct cardstate *cs = bcs->cs; struct gigaset_capi_ctr *iif = cs->iif; - struct gigaset_capi_appl *ap = bcs->ap; + struct gigaset_capi_appl *ap; struct sk_buff *skb; + unsigned long flags; unsigned int msgsize; u8 command; + spin_lock_irqsave(&bcs->aplock, flags); + ap = bcs->ap; if (!ap) { + spin_unlock_irqrestore(&bcs->aplock, flags); dev_err(cs->dev, "%s: no application\n", __func__); return; } - while (ap->bcnext) { - /* this should never happen */ - dev_warn(cs->dev, "%s: dropping extra application %u\n", - __func__, ap->bcnext->id); - send_disconnect_ind(bcs, ap->bcnext, - CapiCallGivenToOtherApplication); - ap->bcnext = ap->bcnext->bcnext; - } - if (!ap->connected) { + if (!bcs->apconnstate) { + spin_unlock_irqrestore(&bcs->aplock, flags); dev_warn(cs->dev, "%s: application %u not connected\n", __func__, ap->id); return; @@ -825,13 +859,26 @@ void gigaset_isdn_connB(struct bc_state *bcs) * CONNECT_B3_ACTIVE_IND in reply to CONNECT_B3_RESP * Parameters in both cases always: NCCI = 1, NCPI empty */ - if (ap->connected >= APCONN_ACTIVE) { + if (bcs->apconnstate >= APCONN_ACTIVE) { command = CAPI_CONNECT_B3_ACTIVE; msgsize = CAPI_CONNECT_B3_ACTIVE_IND_BASELEN; } else { command = CAPI_CONNECT_B3; msgsize = CAPI_CONNECT_B3_IND_BASELEN; } + bcs->apconnstate = APCONN_ACTIVE; + + spin_unlock_irqrestore(&bcs->aplock, flags); + + while (ap->bcnext) { + /* this should never happen */ + dev_warn(cs->dev, "%s: dropping extra application %u\n", + __func__, ap->bcnext->id); + send_disconnect_ind(bcs, ap->bcnext, + CapiCallGivenToOtherApplication); + ap->bcnext = ap->bcnext->bcnext; + } + capi_cmsg_header(&iif->hcmsg, ap->id, command, CAPI_IND, ap->nextMessageNumber++, iif->ctr.cnr | ((bcs->channel + 1) << 8) | (1 << 16)); @@ -842,7 +889,6 @@ void gigaset_isdn_connB(struct bc_state *bcs) } capi_cmsg2message(&iif->hcmsg, __skb_put(skb, msgsize)); dump_cmsg(DEBUG_CMD, __func__, &iif->hcmsg); - ap->connected = APCONN_ACTIVE; capi_ctr_handle_message(&iif->ctr, ap->id, skb); } @@ -945,8 +991,64 @@ static void gigaset_register_appl(struct capi_ctr *ctr, u16 appl, return; } ap->id = appl; + ap->rp = *rp; list_add(&ap->ctrlist, &iif->appls); + dev_info(cs->dev, "application %u registered\n", ap->id); +} + +/* + * remove CAPI application from channel + * helper function to keep indentation levels down and stay in 80 columns + */ + +static inline void remove_appl_from_channel(struct bc_state *bcs, + struct gigaset_capi_appl *ap) +{ + struct cardstate *cs = bcs->cs; + struct gigaset_capi_appl *bcap; + unsigned long flags; + int prevconnstate; + + spin_lock_irqsave(&bcs->aplock, flags); + bcap = bcs->ap; + if (bcap == NULL) { + spin_unlock_irqrestore(&bcs->aplock, flags); + return; + } + + /* check first application on channel */ + if (bcap == ap) { + bcs->ap = ap->bcnext; + if (bcs->ap != NULL) { + spin_unlock_irqrestore(&bcs->aplock, flags); + return; + } + + /* none left, clear channel state */ + prevconnstate = bcs->apconnstate; + bcs->apconnstate = APCONN_NONE; + spin_unlock_irqrestore(&bcs->aplock, flags); + + if (prevconnstate == APCONN_ACTIVE) { + dev_notice(cs->dev, "%s: hanging up channel %u\n", + __func__, bcs->channel); + gigaset_add_event(cs, &bcs->at_state, + EV_HUP, NULL, 0, NULL); + gigaset_schedule_event(cs); + } + return; + } + + /* check remaining list */ + do { + if (bcap->bcnext == ap) { + bcap->bcnext = bcap->bcnext->bcnext; + return; + } + bcap = bcap->bcnext; + } while (bcap != NULL); + spin_unlock_irqrestore(&bcs->aplock, flags); } /* @@ -958,19 +1060,19 @@ static void gigaset_release_appl(struct capi_ctr *ctr, u16 appl) = container_of(ctr, struct gigaset_capi_ctr, ctr); struct cardstate *cs = iif->ctr.driverdata; struct gigaset_capi_appl *ap, *tmp; + unsigned ch; list_for_each_entry_safe(ap, tmp, &iif->appls, ctrlist) if (ap->id == appl) { - if (ap->connected != APCONN_NONE) { - dev_err(cs->dev, - "%s: application %u still connected\n", - __func__, ap->id); - /* ToDo: clear active connection */ - } + /* remove from any channels */ + for (ch = 0; ch < cs->channels; ch++) + remove_appl_from_channel(&cs->bcs[ch], ap); + + /* remove from registration list */ list_del(&ap->ctrlist); kfree(ap); + dev_info(cs->dev, "application %u released\n", appl); } - } /* @@ -1149,7 +1251,8 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, char **commands; char *s; u8 *pp; - int i, l; + unsigned long flags; + int i, l, lbc, lhlc; u16 info; /* decode message */ @@ -1164,8 +1267,18 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, send_conf(iif, ap, skb, CapiNoPlciAvailable); return; } + spin_lock_irqsave(&bcs->aplock, flags); + if (bcs->ap != NULL || bcs->apconnstate != APCONN_NONE) + dev_warn(cs->dev, "%s: channel not properly cleared (%p/%d)\n", + __func__, bcs->ap, bcs->apconnstate); ap->bcnext = NULL; bcs->ap = ap; + bcs->apconnstate = APCONN_SETUP; + spin_unlock_irqrestore(&bcs->aplock, flags); + + bcs->rx_bufsize = ap->rp.datablklen; + dev_kfree_skb(bcs->rx_skb); + gigaset_new_rx_skb(bcs); cmsg->adr.adrPLCI |= (bcs->channel + 1) << 8; /* build command table */ @@ -1273,42 +1386,59 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, goto error; } - /* check/encode parameter: BC */ - if (cmsg->BC && cmsg->BC[0]) { - /* explicit BC overrides CIP */ - l = 2*cmsg->BC[0] + 7; + /* + * check/encode parameters: BC & HLC + * must be encoded together as device doesn't accept HLC separately + * explicit parameters override values derived from CIP + */ + + /* determine lengths */ + if (cmsg->BC && cmsg->BC[0]) /* BC specified explicitly */ + lbc = 2*cmsg->BC[0]; + else if (cip2bchlc[cmsg->CIPValue].bc) /* BC derived from CIP */ + lbc = strlen(cip2bchlc[cmsg->CIPValue].bc); + else /* no BC */ + lbc = 0; + if (cmsg->HLC && cmsg->HLC[0]) /* HLC specified explicitly */ + lhlc = 2*cmsg->HLC[0]; + else if (cip2bchlc[cmsg->CIPValue].hlc) /* HLC derived from CIP */ + lhlc = strlen(cip2bchlc[cmsg->CIPValue].hlc); + else /* no HLC */ + lhlc = 0; + + if (lbc) { + /* have BC: allocate and assemble command string */ + l = lbc + 7; /* "^SBC=" + value + "\r" + null byte */ + if (lhlc) + l += lhlc + 7; /* ";^SHLC=" + value */ commands[AT_BC] = kmalloc(l, GFP_KERNEL); if (!commands[AT_BC]) goto oom; strcpy(commands[AT_BC], "^SBC="); - decode_ie(cmsg->BC, commands[AT_BC]+5); + if (cmsg->BC && cmsg->BC[0]) /* BC specified explicitly */ + decode_ie(cmsg->BC, commands[AT_BC] + 5); + else /* BC derived from CIP */ + strcpy(commands[AT_BC] + 5, + cip2bchlc[cmsg->CIPValue].bc); + if (lhlc) { + strcpy(commands[AT_BC] + lbc + 5, ";^SHLC="); + if (cmsg->HLC && cmsg->HLC[0]) + /* HLC specified explicitly */ + decode_ie(cmsg->HLC, + commands[AT_BC] + lbc + 12); + else /* HLC derived from CIP */ + strcpy(commands[AT_BC] + lbc + 12, + cip2bchlc[cmsg->CIPValue].hlc); + } strcpy(commands[AT_BC] + l - 2, "\r"); - } else if (cip2bchlc[cmsg->CIPValue].bc) { - l = strlen(cip2bchlc[cmsg->CIPValue].bc) + 7; - commands[AT_BC] = kmalloc(l, GFP_KERNEL); - if (!commands[AT_BC]) - goto oom; - snprintf(commands[AT_BC], l, "^SBC=%s\r", - cip2bchlc[cmsg->CIPValue].bc); - } - - /* check/encode parameter: HLC */ - if (cmsg->HLC && cmsg->HLC[0]) { - /* explicit HLC overrides CIP */ - l = 2*cmsg->HLC[0] + 7; - commands[AT_HLC] = kmalloc(l, GFP_KERNEL); - if (!commands[AT_HLC]) - goto oom; - strcpy(commands[AT_HLC], "^SHLC="); - decode_ie(cmsg->HLC, commands[AT_HLC]+5); - strcpy(commands[AT_HLC] + l - 2, "\r"); - } else if (cip2bchlc[cmsg->CIPValue].hlc) { - l = strlen(cip2bchlc[cmsg->CIPValue].hlc) + 7; - commands[AT_HLC] = kmalloc(l, GFP_KERNEL); - if (!commands[AT_HLC]) - goto oom; - snprintf(commands[AT_HLC], l, "^SHLC=%s\r", - cip2bchlc[cmsg->CIPValue].hlc); + } else { + /* no BC */ + if (lhlc) { + dev_notice(cs->dev, "%s: cannot set HLC without BC\n", + "CONNECT_REQ"); + info = CapiIllMessageParmCoding; /* ? */ + goto error; + } } /* check/encode parameter: B Protocol */ @@ -1322,13 +1452,13 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, bcs->proto2 = L2_HDLC; break; case 1: - bcs->proto2 = L2_BITSYNC; + bcs->proto2 = L2_VOICE; break; default: dev_warn(cs->dev, "B1 Protocol %u unsupported, using Transparent\n", cmsg->B1protocol); - bcs->proto2 = L2_BITSYNC; + bcs->proto2 = L2_VOICE; } if (cmsg->B2protocol != 1) dev_warn(cs->dev, @@ -1382,7 +1512,6 @@ static void do_connect_req(struct gigaset_capi_ctr *iif, goto error; } gigaset_schedule_event(cs); - ap->connected = APCONN_SETUP; send_conf(iif, ap, skb, CapiSuccess); return; @@ -1410,6 +1539,7 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif, _cmsg *cmsg = &iif->acmsg; struct bc_state *bcs; struct gigaset_capi_appl *oap; + unsigned long flags; int channel; /* decode message */ @@ -1429,12 +1559,24 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif, switch (cmsg->Reject) { case 0: /* Accept */ /* drop all competing applications, keep only this one */ - for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) - if (oap != ap) + spin_lock_irqsave(&bcs->aplock, flags); + while (bcs->ap != NULL) { + oap = bcs->ap; + bcs->ap = oap->bcnext; + if (oap != ap) { + spin_unlock_irqrestore(&bcs->aplock, flags); send_disconnect_ind(bcs, oap, CapiCallGivenToOtherApplication); + spin_lock_irqsave(&bcs->aplock, flags); + } + } ap->bcnext = NULL; bcs->ap = ap; + spin_unlock_irqrestore(&bcs->aplock, flags); + + bcs->rx_bufsize = ap->rp.datablklen; + dev_kfree_skb(bcs->rx_skb); + gigaset_new_rx_skb(bcs); bcs->chstate |= CHS_NOTIFY_LL; /* check/encode B channel protocol */ @@ -1448,13 +1590,13 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif, bcs->proto2 = L2_HDLC; break; case 1: - bcs->proto2 = L2_BITSYNC; + bcs->proto2 = L2_VOICE; break; default: dev_warn(cs->dev, "B1 Protocol %u unsupported, using Transparent\n", cmsg->B1protocol); - bcs->proto2 = L2_BITSYNC; + bcs->proto2 = L2_VOICE; } if (cmsg->B2protocol != 1) dev_warn(cs->dev, @@ -1502,31 +1644,45 @@ static void do_connect_resp(struct gigaset_capi_ctr *iif, send_disconnect_ind(bcs, ap, 0); /* remove it from the list of listening apps */ + spin_lock_irqsave(&bcs->aplock, flags); if (bcs->ap == ap) { bcs->ap = ap->bcnext; - if (bcs->ap == NULL) + if (bcs->ap == NULL) { /* last one: stop ev-layer hupD notifications */ + bcs->apconnstate = APCONN_NONE; bcs->chstate &= ~CHS_NOTIFY_LL; + } + spin_unlock_irqrestore(&bcs->aplock, flags); return; } for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) { if (oap->bcnext == ap) { oap->bcnext = oap->bcnext->bcnext; + spin_unlock_irqrestore(&bcs->aplock, flags); return; } } + spin_unlock_irqrestore(&bcs->aplock, flags); dev_err(cs->dev, "%s: application %u not found\n", __func__, ap->id); return; default: /* Reject */ /* drop all competing applications, keep only this one */ - for (oap = bcs->ap; oap != NULL; oap = oap->bcnext) - if (oap != ap) + spin_lock_irqsave(&bcs->aplock, flags); + while (bcs->ap != NULL) { + oap = bcs->ap; + bcs->ap = oap->bcnext; + if (oap != ap) { + spin_unlock_irqrestore(&bcs->aplock, flags); send_disconnect_ind(bcs, oap, CapiCallGivenToOtherApplication); + spin_lock_irqsave(&bcs->aplock, flags); + } + } ap->bcnext = NULL; bcs->ap = ap; + spin_unlock_irqrestore(&bcs->aplock, flags); /* reject call - will trigger DISCONNECT_IND for this app */ dev_info(cs->dev, "%s: Reject=%x\n", @@ -1549,6 +1705,7 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif, { struct cardstate *cs = iif->ctr.driverdata; _cmsg *cmsg = &iif->acmsg; + struct bc_state *bcs; int channel; /* decode message */ @@ -1563,9 +1720,10 @@ static void do_connect_b3_req(struct gigaset_capi_ctr *iif, send_conf(iif, ap, skb, CapiIllContrPlciNcci); return; } + bcs = &cs->bcs[channel-1]; /* mark logical connection active */ - ap->connected = APCONN_ACTIVE; + bcs->apconnstate = APCONN_ACTIVE; /* build NCCI: always 1 (one B3 connection only) */ cmsg->adr.adrNCCI |= 1 << 16; @@ -1611,7 +1769,7 @@ static void do_connect_b3_resp(struct gigaset_capi_ctr *iif, if (cmsg->Reject) { /* Reject: clear B3 connect received flag */ - ap->connected = APCONN_SETUP; + bcs->apconnstate = APCONN_SETUP; /* trigger hangup, causing eventual DISCONNECT_IND */ if (!gigaset_add_event(cs, &bcs->at_state, @@ -1683,11 +1841,11 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif, } /* skip if DISCONNECT_IND already sent */ - if (!ap->connected) + if (!bcs->apconnstate) return; /* check for active logical connection */ - if (ap->connected >= APCONN_ACTIVE) { + if (bcs->apconnstate >= APCONN_ACTIVE) { /* * emit DISCONNECT_B3_IND with cause 0x3301 * use separate cmsg structure, as the content of iif->acmsg @@ -1736,6 +1894,7 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif, { struct cardstate *cs = iif->ctr.driverdata; _cmsg *cmsg = &iif->acmsg; + struct bc_state *bcs; int channel; /* decode message */ @@ -1751,17 +1910,17 @@ static void do_disconnect_b3_req(struct gigaset_capi_ctr *iif, send_conf(iif, ap, skb, CapiIllContrPlciNcci); return; } + bcs = &cs->bcs[channel-1]; /* reject if logical connection not active */ - if (ap->connected < APCONN_ACTIVE) { + if (bcs->apconnstate < APCONN_ACTIVE) { send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState); return; } /* trigger hangup, causing eventual DISCONNECT_B3_IND */ - if (!gigaset_add_event(cs, &cs->bcs[channel-1].at_state, - EV_HUP, NULL, 0, NULL)) { + if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); return; } @@ -1782,11 +1941,14 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, struct sk_buff *skb) { struct cardstate *cs = iif->ctr.driverdata; + struct bc_state *bcs; int channel = CAPIMSG_PLCI_PART(skb->data); u16 ncci = CAPIMSG_NCCI_PART(skb->data); u16 msglen = CAPIMSG_LEN(skb->data); u16 datalen = CAPIMSG_DATALEN(skb->data); u16 flags = CAPIMSG_FLAGS(skb->data); + u16 msgid = CAPIMSG_MSGID(skb->data); + u16 handle = CAPIMSG_HANDLE_REQ(skb->data); /* frequent message, avoid _cmsg overhead */ dump_rawmsg(DEBUG_LLDATA, "DATA_B3_REQ", skb->data); @@ -1802,6 +1964,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, send_conf(iif, ap, skb, CapiIllContrPlciNcci); return; } + bcs = &cs->bcs[channel-1]; if (msglen != CAPI_DATA_B3_REQ_LEN && msglen != CAPI_DATA_B3_REQ_LEN64) dev_notice(cs->dev, "%s: unexpected length %d\n", "DATA_B3_REQ", msglen); @@ -1821,7 +1984,7 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, } /* reject if logical connection not active */ - if (ap->connected < APCONN_ACTIVE) { + if (bcs->apconnstate < APCONN_ACTIVE) { send_conf(iif, ap, skb, CapiMessageNotSupportedInCurrentState); return; } @@ -1832,17 +1995,19 @@ static void do_data_b3_req(struct gigaset_capi_ctr *iif, skb_pull(skb, msglen); /* pass to device-specific module */ - if (cs->ops->send_skb(&cs->bcs[channel-1], skb) < 0) { + if (cs->ops->send_skb(bcs, skb) < 0) { send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); return; } - /* DATA_B3_CONF reply will be sent by gigaset_skb_sent() */ - /* - * ToDo: honor unset "delivery confirmation" bit - * (send DATA_B3_CONF immediately?) + * DATA_B3_CONF will be sent by gigaset_skb_sent() only if "delivery + * confirmation" bit is set; otherwise we have to send it now */ + if (!(flags & CAPI_FLAGS_DELIVERY_CONFIRMATION)) + send_data_b3_conf(cs, &iif->ctr, ap->id, msgid, channel, handle, + flags ? CapiFlagsNotSupportedByProtocol + : CAPI_NOERROR); } /* diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index f6f45f2..5d4befb 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -399,8 +399,8 @@ static void gigaset_freebcs(struct bc_state *bcs) gig_dbg(DEBUG_INIT, "clearing bcs[%d]->at_state", bcs->channel); clear_at_state(&bcs->at_state); gig_dbg(DEBUG_INIT, "freeing bcs[%d]->skb", bcs->channel); - dev_kfree_skb(bcs->skb); - bcs->skb = NULL; + dev_kfree_skb(bcs->rx_skb); + bcs->rx_skb = NULL; for (i = 0; i < AT_NUM; ++i) { kfree(bcs->commands[i]); @@ -634,19 +634,10 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, bcs->emptycount = 0; #endif - gig_dbg(DEBUG_INIT, "allocating bcs[%d]->skb", channel); - bcs->fcs = PPP_INITFCS; + bcs->rx_bufsize = 0; + bcs->rx_skb = NULL; + bcs->rx_fcs = PPP_INITFCS; bcs->inputstate = 0; - if (cs->ignoreframes) { - bcs->skb = NULL; - } else { - bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); - if (bcs->skb != NULL) - skb_reserve(bcs->skb, cs->hw_hdr_len); - else - pr_err("out of memory\n"); - } - bcs->channel = channel; bcs->cs = cs; @@ -658,16 +649,15 @@ static struct bc_state *gigaset_initbcs(struct bc_state *bcs, for (i = 0; i < AT_NUM; ++i) bcs->commands[i] = NULL; + spin_lock_init(&bcs->aplock); + bcs->ap = NULL; + bcs->apconnstate = 0; + gig_dbg(DEBUG_INIT, " setting up bcs[%d]->hw", channel); if (cs->ops->initbcshw(bcs)) return bcs; gig_dbg(DEBUG_INIT, " failed"); - - gig_dbg(DEBUG_INIT, " freeing bcs[%d]->skb", channel); - dev_kfree_skb(bcs->skb); - bcs->skb = NULL; - return NULL; } @@ -839,14 +829,12 @@ void gigaset_bcs_reinit(struct bc_state *bcs) bcs->emptycount = 0; #endif - bcs->fcs = PPP_INITFCS; + bcs->rx_fcs = PPP_INITFCS; bcs->chstate = 0; bcs->ignore = cs->ignoreframes; - if (bcs->ignore) { - dev_kfree_skb(bcs->skb); - bcs->skb = NULL; - } + dev_kfree_skb(bcs->rx_skb); + bcs->rx_skb = NULL; cs->ops->reinitbcshw(bcs); } diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index 206c380..ceaef9a 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c @@ -282,9 +282,7 @@ struct reply_t gigaset_tab_cid[] = /* dial */ {EV_DIAL, -1, -1, -1, -1, -1, {ACT_DIAL} }, {RSP_INIT, 0, 0, SEQ_DIAL, 601, 5, {ACT_CMD+AT_BC} }, -{RSP_OK, 601, 601, -1, 602, 5, {ACT_CMD+AT_HLC} }, -{RSP_NULL, 602, 602, -1, 603, 5, {ACT_CMD+AT_PROTO} }, -{RSP_OK, 602, 602, -1, 603, 5, {ACT_CMD+AT_PROTO} }, +{RSP_OK, 601, 601, -1, 603, 5, {ACT_CMD+AT_PROTO} }, {RSP_OK, 603, 603, -1, 604, 5, {ACT_CMD+AT_TYPE} }, {RSP_OK, 604, 604, -1, 605, 5, {ACT_CMD+AT_MSN} }, {RSP_NULL, 605, 605, -1, 606, 5, {ACT_CMD+AT_CLIP} }, diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 05947f9..8738b08 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -45,10 +45,6 @@ #define MAX_EVENTS 64 /* size of event queue */ #define RBUFSIZE 8192 -#define SBUFSIZE 4096 /* sk_buff payload size */ - -#define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ -#define MAX_BUF_SIZE (SBUFSIZE - 2) /* Max. size of a data packet from LL */ /* compile time options */ #define GIG_MAJOR 0 @@ -190,10 +186,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, #define AT_BC 3 #define AT_PROTO 4 #define AT_TYPE 5 -#define AT_HLC 6 -#define AT_CLIP 7 +#define AT_CLIP 6 /* total number */ -#define AT_NUM 8 +#define AT_NUM 7 /* variables in struct at_state_t */ #define VAR_ZSAU 0 @@ -380,8 +375,10 @@ struct bc_state { struct at_state_t at_state; - __u16 fcs; - struct sk_buff *skb; + /* receive buffer */ + unsigned rx_bufsize; /* max size accepted by application */ + struct sk_buff *rx_skb; + __u16 rx_fcs; int inputstate; /* see INS_XXXX */ int channel; @@ -406,7 +403,9 @@ struct bc_state { struct bas_bc_state *bas; /* usb hardware driver (base) */ } hw; - void *ap; /* LL application structure */ + void *ap; /* associated LL application */ + int apconnstate; /* LL application connection state */ + spinlock_t aplock; }; struct cardstate { @@ -801,8 +800,23 @@ static inline void gigaset_bchannel_up(struct bc_state *bcs) gigaset_schedule_event(bcs->cs); } -/* handling routines for sk_buff */ -/* ============================= */ +/* set up next receive skb for data mode */ +static inline struct sk_buff *gigaset_new_rx_skb(struct bc_state *bcs) +{ + struct cardstate *cs = bcs->cs; + unsigned short hw_hdr_len = cs->hw_hdr_len; + + if (bcs->ignore) { + bcs->rx_skb = NULL; + } else { + bcs->rx_skb = dev_alloc_skb(bcs->rx_bufsize + hw_hdr_len); + if (bcs->rx_skb == NULL) + dev_warn(cs->dev, "could not allocate skb\n"); + else + skb_reserve(bcs->rx_skb, hw_hdr_len); + } + return bcs->rx_skb; +} /* append received bytes to inbuf */ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index c22e5ac..f01c3c2 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c @@ -16,7 +16,10 @@ #include "gigaset.h" #include <linux/isdnif.h> +#define SBUFSIZE 4096 /* sk_buff payload size */ +#define TRANSBUFSIZE 768 /* bytes per skb for transparent receive */ #define HW_HDR_LEN 2 /* Header size used to store ack info */ +#define MAX_BUF_SIZE (SBUFSIZE - HW_HDR_LEN) /* max data packet from LL */ /* == Handling of I4L IO =====================================================*/ @@ -231,6 +234,15 @@ static int command_from_LL(isdn_ctrl *cntrl) dev_err(cs->dev, "ISDN_CMD_DIAL: channel not free\n"); return -EBUSY; } + switch (bcs->proto2) { + case L2_HDLC: + bcs->rx_bufsize = SBUFSIZE; + break; + default: /* assume transparent */ + bcs->rx_bufsize = TRANSBUFSIZE; + } + dev_kfree_skb(bcs->rx_skb); + gigaset_new_rx_skb(bcs); commands = kzalloc(AT_NUM*(sizeof *commands), GFP_ATOMIC); if (!commands) { @@ -314,6 +326,15 @@ static int command_from_LL(isdn_ctrl *cntrl) return -EINVAL; } bcs = cs->bcs + ch; + switch (bcs->proto2) { + case L2_HDLC: + bcs->rx_bufsize = SBUFSIZE; + break; + default: /* assume transparent */ + bcs->rx_bufsize = TRANSBUFSIZE; + } + dev_kfree_skb(bcs->rx_skb); + gigaset_new_rx_skb(bcs); if (!gigaset_add_event(cs, &bcs->at_state, EV_ACCEPT, NULL, 0, NULL)) return -ENOMEM; diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 16fd3bd..2dfd346 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c @@ -500,19 +500,18 @@ int gigaset_isoc_buildframe(struct bc_state *bcs, unsigned char *in, int len) */ static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs) { - bcs->fcs = crc_ccitt_byte(bcs->fcs, c); - if (unlikely(bcs->skb == NULL)) { + bcs->rx_fcs = crc_ccitt_byte(bcs->rx_fcs, c); + if (bcs->rx_skb == NULL) /* skipping */ return; - } - if (unlikely(bcs->skb->len == SBUFSIZE)) { + if (bcs->rx_skb->len >= bcs->rx_bufsize) { dev_warn(bcs->cs->dev, "received oversized packet discarded\n"); bcs->hw.bas->giants++; - dev_kfree_skb_any(bcs->skb); - bcs->skb = NULL; + dev_kfree_skb_any(bcs->rx_skb); + bcs->rx_skb = NULL; return; } - *__skb_put(bcs->skb, 1) = c; + *__skb_put(bcs->rx_skb, 1) = c; } /* hdlc_flush @@ -521,18 +520,13 @@ static inline void hdlc_putbyte(unsigned char c, struct bc_state *bcs) static inline void hdlc_flush(struct bc_state *bcs) { /* clear skb or allocate new if not skipping */ - if (likely(bcs->skb != NULL)) - skb_trim(bcs->skb, 0); - else if (!bcs->ignore) { - bcs->skb = dev_alloc_skb(SBUFSIZE + bcs->cs->hw_hdr_len); - if (bcs->skb) - skb_reserve(bcs->skb, bcs->cs->hw_hdr_len); - else - dev_err(bcs->cs->dev, "could not allocate skb\n"); - } + if (bcs->rx_skb != NULL) + skb_trim(bcs->rx_skb, 0); + else + gigaset_new_rx_skb(bcs); /* reset packet state */ - bcs->fcs = PPP_INITFCS; + bcs->rx_fcs = PPP_INITFCS; } /* hdlc_done @@ -549,7 +543,7 @@ static inline void hdlc_done(struct bc_state *bcs) hdlc_flush(bcs); return; } - procskb = bcs->skb; + procskb = bcs->rx_skb; if (procskb == NULL) { /* previous error */ gig_dbg(DEBUG_ISO, "%s: skb=NULL", __func__); @@ -560,8 +554,8 @@ static inline void hdlc_done(struct bc_state *bcs) bcs->hw.bas->runts++; dev_kfree_skb_any(procskb); gigaset_isdn_rcv_err(bcs); - } else if (bcs->fcs != PPP_GOODFCS) { - dev_notice(cs->dev, "frame check error (0x%04x)\n", bcs->fcs); + } else if (bcs->rx_fcs != PPP_GOODFCS) { + dev_notice(cs->dev, "frame check error\n"); bcs->hw.bas->fcserrs++; dev_kfree_skb_any(procskb); gigaset_isdn_rcv_err(bcs); @@ -574,13 +568,8 @@ static inline void hdlc_done(struct bc_state *bcs) bcs->hw.bas->goodbytes += len; gigaset_skb_rcvd(bcs, procskb); } - - bcs->skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); - if (bcs->skb) - skb_reserve(bcs->skb, cs->hw_hdr_len); - else - dev_err(cs->dev, "could not allocate skb\n"); - bcs->fcs = PPP_INITFCS; + gigaset_new_rx_skb(bcs); + bcs->rx_fcs = PPP_INITFCS; } /* hdlc_frag @@ -597,8 +586,8 @@ static inline void hdlc_frag(struct bc_state *bcs, unsigned inbits) dev_notice(bcs->cs->dev, "received partial byte (%d bits)\n", inbits); bcs->hw.bas->alignerrs++; gigaset_isdn_rcv_err(bcs); - __skb_trim(bcs->skb, 0); - bcs->fcs = PPP_INITFCS; + __skb_trim(bcs->rx_skb, 0); + bcs->rx_fcs = PPP_INITFCS; } /* bit counts lookup table for HDLC bit unstuffing @@ -847,7 +836,6 @@ static inline void hdlc_unpack(unsigned char *src, unsigned count, static inline void trans_receive(unsigned char *src, unsigned count, struct bc_state *bcs) { - struct cardstate *cs = bcs->cs; struct sk_buff *skb; int dobytes; unsigned char *dst; @@ -857,17 +845,11 @@ static inline void trans_receive(unsigned char *src, unsigned count, hdlc_flush(bcs); return; } - skb = bcs->skb; - if (unlikely(skb == NULL)) { - bcs->skb = skb = dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); - if (!skb) { - dev_err(cs->dev, "could not allocate skb\n"); - return; - } - skb_reserve(skb, cs->hw_hdr_len); - } + skb = bcs->rx_skb; + if (skb == NULL) + skb = gigaset_new_rx_skb(bcs); bcs->hw.bas->goodbytes += skb->len; - dobytes = TRANSBUFSIZE - skb->len; + dobytes = bcs->rx_bufsize - skb->len; while (count > 0) { dst = skb_put(skb, count < dobytes ? count : dobytes); while (count > 0 && dobytes > 0) { @@ -879,14 +861,10 @@ static inline void trans_receive(unsigned char *src, unsigned count, dump_bytes(DEBUG_STREAM_DUMP, "rcv data", skb->data, skb->len); gigaset_skb_rcvd(bcs, skb); - bcs->skb = skb = - dev_alloc_skb(SBUFSIZE + cs->hw_hdr_len); - if (!skb) { - dev_err(cs->dev, "could not allocate skb\n"); + skb = gigaset_new_rx_skb(bcs); + if (skb == NULL) return; - } - skb_reserve(skb, cs->hw_hdr_len); - dobytes = TRANSBUFSIZE; + dobytes = bcs->rx_bufsize; } } } diff --git a/drivers/isdn/hysdn/hysdn_net.c b/drivers/isdn/hysdn/hysdn_net.c index 72eb926..feec8d8 100644 --- a/drivers/isdn/hysdn/hysdn_net.c +++ b/drivers/isdn/hysdn/hysdn_net.c @@ -187,12 +187,13 @@ void hysdn_rx_netpkt(hysdn_card * card, unsigned char *buf, unsigned short len) { struct net_local *lp = card->netif; - struct net_device *dev = lp->dev; + struct net_device *dev; struct sk_buff *skb; if (!lp) return; /* non existing device */ + dev = lp->dev; dev->stats.rx_bytes += len; skb = dev_alloc_skb(len); diff --git a/drivers/md/md.c b/drivers/md/md.c index 46b3a04..cb20d0b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2087,6 +2087,7 @@ static void sync_sbs(mddev_t * mddev, int nospares) /* First make sure individual recovery_offsets are correct */ list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk >= 0 && + mddev->delta_disks >= 0 && !test_bit(In_sync, &rdev->flags) && mddev->curr_resync_completed > rdev->recovery_offset) rdev->recovery_offset = mddev->curr_resync_completed; @@ -3001,6 +3002,9 @@ level_store(mddev_t *mddev, const char *buf, size_t len) return -EINVAL; } + list_for_each_entry(rdev, &mddev->disks, same_set) + rdev->new_raid_disk = rdev->raid_disk; + /* ->takeover must set new_* and/or delta_disks * if it succeeds, and may set them when it fails. */ @@ -3051,13 +3055,35 @@ level_store(mddev_t *mddev, const char *buf, size_t len) mddev->safemode = 0; } - module_put(mddev->pers->owner); - /* Invalidate devices that are now superfluous */ - list_for_each_entry(rdev, &mddev->disks, same_set) - if (rdev->raid_disk >= mddev->raid_disks) { - rdev->raid_disk = -1; + list_for_each_entry(rdev, &mddev->disks, same_set) { + char nm[20]; + if (rdev->raid_disk < 0) + continue; + if (rdev->new_raid_disk > mddev->raid_disks) + rdev->new_raid_disk = -1; + if (rdev->new_raid_disk == rdev->raid_disk) + continue; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + } + list_for_each_entry(rdev, &mddev->disks, same_set) { + if (rdev->raid_disk < 0) + continue; + if (rdev->new_raid_disk == rdev->raid_disk) + continue; + rdev->raid_disk = rdev->new_raid_disk; + if (rdev->raid_disk < 0) clear_bit(In_sync, &rdev->flags); + else { + char nm[20]; + sprintf(nm, "rd%d", rdev->raid_disk); + if(sysfs_create_link(&mddev->kobj, &rdev->kobj, nm)) + printk("md: cannot register %s for %s after level change\n", + nm, mdname(mddev)); } + } + + module_put(mddev->pers->owner); mddev->pers = pers; mddev->private = priv; strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel)); @@ -5895,6 +5921,7 @@ static int md_open(struct block_device *bdev, fmode_t mode) atomic_inc(&mddev->openers); mutex_unlock(&mddev->open_mutex); + check_disk_size_change(mddev->gendisk, bdev); out: return err; } @@ -6846,6 +6873,7 @@ void md_do_sync(mddev_t *mddev) rcu_read_lock(); list_for_each_entry_rcu(rdev, &mddev->disks, same_set) if (rdev->raid_disk >= 0 && + mddev->delta_disks >= 0 && !test_bit(Faulty, &rdev->flags) && !test_bit(In_sync, &rdev->flags) && rdev->recovery_offset < mddev->curr_resync) diff --git a/drivers/md/md.h b/drivers/md/md.h index 7ab5ea1..10597bf 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -78,6 +78,9 @@ struct mdk_rdev_s int desc_nr; /* descriptor index in the superblock */ int raid_disk; /* role of device in array */ + int new_raid_disk; /* role that the device will have in + * the array after a level-change completes. + */ int saved_raid_disk; /* role that device used to have in the * array and could again if we did a partial * resync from the bitmap diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index e70f004..563abed 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -173,9 +173,11 @@ static int create_strip_zones(mddev_t *mddev, raid0_conf_t **private_conf) list_for_each_entry(rdev1, &mddev->disks, same_set) { int j = rdev1->raid_disk; - if (mddev->level == 10) + if (mddev->level == 10) { /* taking over a raid10-n2 array */ j /= 2; + rdev1->new_raid_disk = j; + } if (j < 0 || j >= mddev->raid_disks) { printk(KERN_ERR "md/raid0:%s: bad disk number %d - " @@ -361,12 +363,6 @@ static int raid0_run(mddev_t *mddev) mddev->private = conf; } conf = mddev->private; - if (conf->scale_raid_disks) { - int i; - for (i=0; i < conf->strip_zone[0].nb_dev; i++) - conf->devlist[i]->raid_disk /= conf->scale_raid_disks; - /* FIXME update sysfs rd links */ - } /* calculate array device size */ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0)); @@ -573,7 +569,7 @@ static void raid0_status(struct seq_file *seq, mddev_t *mddev) return; } -static void *raid0_takeover_raid5(mddev_t *mddev) +static void *raid0_takeover_raid45(mddev_t *mddev) { mdk_rdev_t *rdev; raid0_conf_t *priv_conf; @@ -596,6 +592,7 @@ static void *raid0_takeover_raid5(mddev_t *mddev) /* Set new parameters */ mddev->new_level = 0; + mddev->new_layout = 0; mddev->new_chunk_sectors = mddev->chunk_sectors; mddev->raid_disks--; mddev->delta_disks = -1; @@ -635,6 +632,7 @@ static void *raid0_takeover_raid10(mddev_t *mddev) /* Set new parameters */ mddev->new_level = 0; + mddev->new_layout = 0; mddev->new_chunk_sectors = mddev->chunk_sectors; mddev->delta_disks = - mddev->raid_disks / 2; mddev->raid_disks += mddev->delta_disks; @@ -643,19 +641,22 @@ static void *raid0_takeover_raid10(mddev_t *mddev) mddev->recovery_cp = MaxSector; create_strip_zones(mddev, &priv_conf); - priv_conf->scale_raid_disks = 2; return priv_conf; } static void *raid0_takeover(mddev_t *mddev) { /* raid0 can take over: + * raid4 - if all data disks are active. * raid5 - providing it is Raid4 layout and one disk is faulty * raid10 - assuming we have all necessary active disks */ + if (mddev->level == 4) + return raid0_takeover_raid45(mddev); + if (mddev->level == 5) { if (mddev->layout == ALGORITHM_PARITY_N) - return raid0_takeover_raid5(mddev); + return raid0_takeover_raid45(mddev); printk(KERN_ERR "md/raid0:%s: Raid can only takeover Raid5 with layout: %d\n", mdname(mddev), ALGORITHM_PARITY_N); diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h index d724e66..91f8e87 100644 --- a/drivers/md/raid0.h +++ b/drivers/md/raid0.h @@ -13,9 +13,6 @@ struct raid0_private_data struct strip_zone *strip_zone; mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */ int nr_strip_zones; - int scale_raid_disks; /* divide rdev->raid_disks by this in run() - * to handle conversion from raid10 - */ }; typedef struct raid0_private_data raid0_conf_t; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 0372499..42e64e4 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1482,14 +1482,14 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) int sectors = r10_bio->sectors; mdk_rdev_t*rdev; int max_read_errors = atomic_read(&mddev->max_corr_read_errors); + int d = r10_bio->devs[r10_bio->read_slot].devnum; rcu_read_lock(); - { - int d = r10_bio->devs[r10_bio->read_slot].devnum; + rdev = rcu_dereference(conf->mirrors[d].rdev); + if (rdev) { /* If rdev is not NULL */ char b[BDEVNAME_SIZE]; int cur_read_error_count = 0; - rdev = rcu_dereference(conf->mirrors[d].rdev); bdevname(rdev->bdev, b); if (test_bit(Faulty, &rdev->flags)) { @@ -1530,7 +1530,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) rcu_read_lock(); do { - int d = r10_bio->devs[sl].devnum; + d = r10_bio->devs[sl].devnum; rdev = rcu_dereference(conf->mirrors[d].rdev); if (rdev && test_bit(In_sync, &rdev->flags)) { @@ -1564,7 +1564,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) rcu_read_lock(); while (sl != r10_bio->read_slot) { char b[BDEVNAME_SIZE]; - int d; + if (sl==0) sl = conf->copies; sl--; @@ -1601,7 +1601,7 @@ static void fix_read_error(conf_t *conf, mddev_t *mddev, r10bio_t *r10_bio) } sl = start; while (sl != r10_bio->read_slot) { - int d; + if (sl==0) sl = conf->copies; sl--; @@ -2161,22 +2161,22 @@ static conf_t *setup_conf(mddev_t *mddev) sector_t stride, size; int err = -EINVAL; - if (mddev->chunk_sectors < (PAGE_SIZE >> 9) || - !is_power_of_2(mddev->chunk_sectors)) { + if (mddev->new_chunk_sectors < (PAGE_SIZE >> 9) || + !is_power_of_2(mddev->new_chunk_sectors)) { printk(KERN_ERR "md/raid10:%s: chunk size must be " "at least PAGE_SIZE(%ld) and be a power of 2.\n", mdname(mddev), PAGE_SIZE); goto out; } - nc = mddev->layout & 255; - fc = (mddev->layout >> 8) & 255; - fo = mddev->layout & (1<<16); + nc = mddev->new_layout & 255; + fc = (mddev->new_layout >> 8) & 255; + fo = mddev->new_layout & (1<<16); if ((nc*fc) <2 || (nc*fc) > mddev->raid_disks || - (mddev->layout >> 17)) { + (mddev->new_layout >> 17)) { printk(KERN_ERR "md/raid10:%s: unsupported raid10 layout: 0x%8x\n", - mdname(mddev), mddev->layout); + mdname(mddev), mddev->new_layout); goto out; } @@ -2241,7 +2241,6 @@ static conf_t *setup_conf(mddev_t *mddev) if (!conf->thread) goto out; - conf->scale_disks = 0; conf->mddev = mddev; return conf; @@ -2300,11 +2299,6 @@ static int run(mddev_t *mddev) if (disk_idx >= conf->raid_disks || disk_idx < 0) continue; - if (conf->scale_disks) { - disk_idx *= conf->scale_disks; - rdev->raid_disk = disk_idx; - /* MOVE 'rd%d' link !! */ - } disk = conf->mirrors + disk_idx; disk->rdev = rdev; @@ -2435,26 +2429,22 @@ static void *raid10_takeover_raid0(mddev_t *mddev) return ERR_PTR(-EINVAL); } - /* Update slot numbers to obtain - * degraded raid10 with missing mirrors - */ - list_for_each_entry(rdev, &mddev->disks, same_set) { - rdev->raid_disk *= 2; - } - /* Set new parameters */ mddev->new_level = 10; /* new layout: far_copies = 1, near_copies = 2 */ mddev->new_layout = (1<<8) + 2; mddev->new_chunk_sectors = mddev->chunk_sectors; mddev->delta_disks = mddev->raid_disks; - mddev->degraded = mddev->raid_disks; mddev->raid_disks *= 2; /* make sure it will be not marked as dirty */ mddev->recovery_cp = MaxSector; conf = setup_conf(mddev); - conf->scale_disks = 2; + if (!IS_ERR(conf)) + list_for_each_entry(rdev, &mddev->disks, same_set) + if (rdev->raid_disk >= 0) + rdev->new_raid_disk = rdev->raid_disk * 2; + return conf; } diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 3824a08..2316ac2 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -38,11 +38,6 @@ struct r10_private_data_s { int chunk_shift; /* shift from chunks to sectors */ sector_t chunk_mask; - int scale_disks; /* When starting array, multiply - * each ->raid_disk by this. - * Need for raid0->raid10 migration - */ - struct list_head retry_list; /* queue pending writes and submit them on unplug */ struct bio_list pending_bio_list; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index d2c0f94..96c6902 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -277,12 +277,13 @@ out: return sh; } -static void shrink_buffers(struct stripe_head *sh, int num) +static void shrink_buffers(struct stripe_head *sh) { struct page *p; int i; + int num = sh->raid_conf->pool_size; - for (i=0; i<num ; i++) { + for (i = 0; i < num ; i++) { p = sh->dev[i].page; if (!p) continue; @@ -291,11 +292,12 @@ static void shrink_buffers(struct stripe_head *sh, int num) } } -static int grow_buffers(struct stripe_head *sh, int num) +static int grow_buffers(struct stripe_head *sh) { int i; + int num = sh->raid_conf->pool_size; - for (i=0; i<num; i++) { + for (i = 0; i < num; i++) { struct page *page; if (!(page = alloc_page(GFP_KERNEL))) { @@ -364,6 +366,73 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, return NULL; } +/* + * Need to check if array has failed when deciding whether to: + * - start an array + * - remove non-faulty devices + * - add a spare + * - allow a reshape + * This determination is simple when no reshape is happening. + * However if there is a reshape, we need to carefully check + * both the before and after sections. + * This is because some failed devices may only affect one + * of the two sections, and some non-in_sync devices may + * be insync in the section most affected by failed devices. + */ +static int has_failed(raid5_conf_t *conf) +{ + int degraded; + int i; + if (conf->mddev->reshape_position == MaxSector) + return conf->mddev->degraded > conf->max_degraded; + + rcu_read_lock(); + degraded = 0; + for (i = 0; i < conf->previous_raid_disks; i++) { + mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + if (!rdev || test_bit(Faulty, &rdev->flags)) + degraded++; + else if (test_bit(In_sync, &rdev->flags)) + ; + else + /* not in-sync or faulty. + * If the reshape increases the number of devices, + * this is being recovered by the reshape, so + * this 'previous' section is not in_sync. + * If the number of devices is being reduced however, + * the device can only be part of the array if + * we are reverting a reshape, so this section will + * be in-sync. + */ + if (conf->raid_disks >= conf->previous_raid_disks) + degraded++; + } + rcu_read_unlock(); + if (degraded > conf->max_degraded) + return 1; + rcu_read_lock(); + degraded = 0; + for (i = 0; i < conf->raid_disks; i++) { + mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev); + if (!rdev || test_bit(Faulty, &rdev->flags)) + degraded++; + else if (test_bit(In_sync, &rdev->flags)) + ; + else + /* not in-sync or faulty. + * If reshape increases the number of devices, this + * section has already been recovered, else it + * almost certainly hasn't. + */ + if (conf->raid_disks <= conf->previous_raid_disks) + degraded++; + } + rcu_read_unlock(); + if (degraded > conf->max_degraded) + return 1; + return 0; +} + static void unplug_slaves(mddev_t *mddev); static void raid5_unplug_device(struct request_queue *q); @@ -1240,19 +1309,18 @@ static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) static int grow_one_stripe(raid5_conf_t *conf) { struct stripe_head *sh; - int disks = max(conf->raid_disks, conf->previous_raid_disks); sh = kmem_cache_alloc(conf->slab_cache, GFP_KERNEL); if (!sh) return 0; - memset(sh, 0, sizeof(*sh) + (disks-1)*sizeof(struct r5dev)); + memset(sh, 0, sizeof(*sh) + (conf->pool_size-1)*sizeof(struct r5dev)); sh->raid_conf = conf; spin_lock_init(&sh->lock); #ifdef CONFIG_MULTICORE_RAID456 init_waitqueue_head(&sh->ops.wait_for_ops); #endif - if (grow_buffers(sh, disks)) { - shrink_buffers(sh, disks); + if (grow_buffers(sh)) { + shrink_buffers(sh); kmem_cache_free(conf->slab_cache, sh); return 0; } @@ -1468,7 +1536,7 @@ static int drop_one_stripe(raid5_conf_t *conf) if (!sh) return 0; BUG_ON(atomic_read(&sh->count)); - shrink_buffers(sh, conf->pool_size); + shrink_buffers(sh); kmem_cache_free(conf->slab_cache, sh); atomic_dec(&conf->active_stripes); return 1; @@ -2963,7 +3031,6 @@ static void handle_stripe5(struct stripe_head *sh) mdk_rdev_t *rdev; dev = &sh->dev[i]; - clear_bit(R5_Insync, &dev->flags); pr_debug("check %d: state 0x%lx toread %p read %p write %p " "written %p\n", i, dev->flags, dev->toread, dev->read, @@ -3000,17 +3067,27 @@ static void handle_stripe5(struct stripe_head *sh) blocked_rdev = rdev; atomic_inc(&rdev->nr_pending); } - if (!rdev || !test_bit(In_sync, &rdev->flags)) { + clear_bit(R5_Insync, &dev->flags); + if (!rdev) + /* Not in-sync */; + else if (test_bit(In_sync, &rdev->flags)) + set_bit(R5_Insync, &dev->flags); + else { + /* could be in-sync depending on recovery/reshape status */ + if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) + set_bit(R5_Insync, &dev->flags); + } + if (!test_bit(R5_Insync, &dev->flags)) { /* The ReadError flag will just be confusing now */ clear_bit(R5_ReadError, &dev->flags); clear_bit(R5_ReWrite, &dev->flags); } - if (!rdev || !test_bit(In_sync, &rdev->flags) - || test_bit(R5_ReadError, &dev->flags)) { + if (test_bit(R5_ReadError, &dev->flags)) + clear_bit(R5_Insync, &dev->flags); + if (!test_bit(R5_Insync, &dev->flags)) { s.failed++; s.failed_num = i; - } else - set_bit(R5_Insync, &dev->flags); + } } rcu_read_unlock(); @@ -3244,7 +3321,6 @@ static void handle_stripe6(struct stripe_head *sh) for (i=disks; i--; ) { mdk_rdev_t *rdev; dev = &sh->dev[i]; - clear_bit(R5_Insync, &dev->flags); pr_debug("check %d: state 0x%lx read %p write %p written %p\n", i, dev->flags, dev->toread, dev->towrite, dev->written); @@ -3282,18 +3358,28 @@ static void handle_stripe6(struct stripe_head *sh) blocked_rdev = rdev; atomic_inc(&rdev->nr_pending); } - if (!rdev || !test_bit(In_sync, &rdev->flags)) { + clear_bit(R5_Insync, &dev->flags); + if (!rdev) + /* Not in-sync */; + else if (test_bit(In_sync, &rdev->flags)) + set_bit(R5_Insync, &dev->flags); + else { + /* in sync if before recovery_offset */ + if (sh->sector + STRIPE_SECTORS <= rdev->recovery_offset) + set_bit(R5_Insync, &dev->flags); + } + if (!test_bit(R5_Insync, &dev->flags)) { /* The ReadError flag will just be confusing now */ clear_bit(R5_ReadError, &dev->flags); clear_bit(R5_ReWrite, &dev->flags); } - if (!rdev || !test_bit(In_sync, &rdev->flags) - || test_bit(R5_ReadError, &dev->flags)) { + if (test_bit(R5_ReadError, &dev->flags)) + clear_bit(R5_Insync, &dev->flags); + if (!test_bit(R5_Insync, &dev->flags)) { if (s.failed < 2) r6s.failed_num[s.failed] = i; s.failed++; - } else - set_bit(R5_Insync, &dev->flags); + } } rcu_read_unlock(); @@ -4971,8 +5057,10 @@ static int run(mddev_t *mddev) list_for_each_entry(rdev, &mddev->disks, same_set) { if (rdev->raid_disk < 0) continue; - if (test_bit(In_sync, &rdev->flags)) + if (test_bit(In_sync, &rdev->flags)) { working_disks++; + continue; + } /* This disc is not fully in-sync. However if it * just stored parity (beyond the recovery_offset), * when we don't need to be concerned about the @@ -5005,7 +5093,7 @@ static int run(mddev_t *mddev) mddev->degraded = (max(conf->raid_disks, conf->previous_raid_disks) - working_disks); - if (mddev->degraded > conf->max_degraded) { + if (has_failed(conf)) { printk(KERN_ERR "md/raid:%s: not enough operational devices" " (%d/%d failed)\n", mdname(mddev), mddev->degraded, conf->raid_disks); @@ -5207,6 +5295,7 @@ static int raid5_spare_active(mddev_t *mddev) for (i = 0; i < conf->raid_disks; i++) { tmp = conf->disks + i; if (tmp->rdev + && tmp->rdev->recovery_offset == MaxSector && !test_bit(Faulty, &tmp->rdev->flags) && !test_and_set_bit(In_sync, &tmp->rdev->flags)) { unsigned long flags; @@ -5242,7 +5331,7 @@ static int raid5_remove_disk(mddev_t *mddev, int number) * isn't possible. */ if (!test_bit(Faulty, &rdev->flags) && - mddev->degraded <= conf->max_degraded && + !has_failed(conf) && number < conf->raid_disks) { err = -EBUSY; goto abort; @@ -5270,7 +5359,7 @@ static int raid5_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) int first = 0; int last = conf->raid_disks - 1; - if (mddev->degraded > conf->max_degraded) + if (has_failed(conf)) /* no point adding a device */ return -EINVAL; @@ -5362,7 +5451,7 @@ static int check_reshape(mddev_t *mddev) if (mddev->bitmap) /* Cannot grow a bitmap yet */ return -EBUSY; - if (mddev->degraded > conf->max_degraded) + if (has_failed(conf)) return -EINVAL; if (mddev->delta_disks < 0) { /* We might be able to shrink, but the devices must @@ -5437,8 +5526,13 @@ static int raid5_start_reshape(mddev_t *mddev) /* Add some new drives, as many as will fit. * We know there are enough to make the newly sized array work. + * Don't add devices if we are reducing the number of + * devices in the array. This is because it is not possible + * to correctly record the "partially reconstructed" state of + * such devices during the reshape and confusion could result. */ - list_for_each_entry(rdev, &mddev->disks, same_set) + if (mddev->delta_disks >= 0) + list_for_each_entry(rdev, &mddev->disks, same_set) if (rdev->raid_disk < 0 && !test_bit(Faulty, &rdev->flags)) { if (raid5_add_disk(mddev, rdev) == 0) { @@ -5460,7 +5554,7 @@ static int raid5_start_reshape(mddev_t *mddev) } /* When a reshape changes the number of devices, ->degraded - * is measured against the large of the pre and post number of + * is measured against the larger of the pre and post number of * devices.*/ if (mddev->delta_disks > 0) { spin_lock_irqsave(&conf->device_lock, flags); diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 2decc59..ce2fcdd 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2754,6 +2754,7 @@ config MYRI10GE_DCA config NETXEN_NIC tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC" depends on PCI + select FW_LOADER help This enables the support for NetXen's Gigabit Ethernet card. @@ -2819,6 +2820,7 @@ config BNX2X config QLCNIC tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support" depends on PCI + select FW_LOADER help This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet devices. diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 949d7a9..1174322 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -3073,7 +3073,6 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod; struct l2_fhdr *rx_hdr; int rx_pkt = 0, pg_ring_used = 0; - struct pci_dev *pdev = bp->pdev; hw_cons = bnx2_get_hw_rx_cons(bnapi); sw_cons = rxr->rx_cons; @@ -3099,12 +3098,10 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget) skb = rx_buf->skb; prefetchw(skb); - if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) { - next_rx_buf = - &rxr->rx_buf_ring[ - RX_RING_IDX(NEXT_RX_BD(sw_cons))]; - prefetch(next_rx_buf->desc); - } + next_rx_buf = + &rxr->rx_buf_ring[RX_RING_IDX(NEXT_RX_BD(sw_cons))]; + prefetch(next_rx_buf->desc); + rx_buf->skb = NULL; dma_addr = dma_unmap_addr(rx_buf, mapping); diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index fe92566..8047126 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c @@ -3919,8 +3919,9 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) HC_INDEX_DEF_C_ETH_ISCSI_CQ_CONS; context->cstorm_st_context.status_block_id = BNX2X_DEF_SB_ID; - context->xstorm_st_context.statistics_data = (cli | - XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE); + if (cli < MAX_X_STAT_COUNTER_ID) + context->xstorm_st_context.statistics_data = cli | + XSTORM_ETH_ST_CONTEXT_STATISTICS_ENABLE; context->xstorm_ag_context.cdu_reserved = CDU_RSRVD_VALUE_TYPE_A(BNX2X_HW_CID(BNX2X_ISCSI_L2_CID, func), @@ -3928,10 +3929,12 @@ static void cnic_init_bnx2x_tx_ring(struct cnic_dev *dev) ETH_CONNECTION_TYPE); /* reset xstorm per client statistics */ - val = BAR_XSTRORM_INTMEM + - XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); + if (cli < MAX_X_STAT_COUNTER_ID) { + val = BAR_XSTRORM_INTMEM + + XSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); + for (i = 0; i < sizeof(struct xstorm_per_client_stats) / 4; i++) + CNIC_WR(dev, val + i * 4, 0); + } cp->tx_cons_ptr = &cp->bnx2x_def_status_blk->c_def_status_block.index_values[ @@ -3978,9 +3981,11 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) BNX2X_ISCSI_RX_SB_INDEX_NUM; context->ustorm_st_context.common.clientId = cli; context->ustorm_st_context.common.status_block_id = BNX2X_DEF_SB_ID; - context->ustorm_st_context.common.flags = - USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; - context->ustorm_st_context.common.statistics_counter_id = cli; + if (cli < MAX_U_STAT_COUNTER_ID) { + context->ustorm_st_context.common.flags = + USTORM_ETH_ST_CONTEXT_CONFIG_ENABLE_STATISTICS; + context->ustorm_st_context.common.statistics_counter_id = cli; + } context->ustorm_st_context.common.mc_alignment_log_size = 0; context->ustorm_st_context.common.bd_buff_size = cp->l2_single_buf_size; @@ -4011,10 +4016,13 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) /* client tstorm info */ tstorm_client.mtu = cp->l2_single_buf_size - 14; - tstorm_client.config_flags = - (TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE | - TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE); - tstorm_client.statistics_counter_id = cli; + tstorm_client.config_flags = TSTORM_ETH_CLIENT_CONFIG_E1HOV_REM_ENABLE; + + if (cli < MAX_T_STAT_COUNTER_ID) { + tstorm_client.config_flags |= + TSTORM_ETH_CLIENT_CONFIG_STATSITICS_ENABLE; + tstorm_client.statistics_counter_id = cli; + } CNIC_WR(dev, BAR_TSTRORM_INTMEM + TSTORM_CLIENT_CONFIG_OFFSET(port, cli), @@ -4024,16 +4032,21 @@ static void cnic_init_bnx2x_rx_ring(struct cnic_dev *dev) ((u32 *)&tstorm_client)[1]); /* reset tstorm per client statistics */ - val = BAR_TSTRORM_INTMEM + - TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); + if (cli < MAX_T_STAT_COUNTER_ID) { + + val = BAR_TSTRORM_INTMEM + + TSTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); + for (i = 0; i < sizeof(struct tstorm_per_client_stats) / 4; i++) + CNIC_WR(dev, val + i * 4, 0); + } /* reset ustorm per client statistics */ - val = BAR_USTRORM_INTMEM + - USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); - for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) - CNIC_WR(dev, val + i * 4, 0); + if (cli < MAX_U_STAT_COUNTER_ID) { + val = BAR_USTRORM_INTMEM + + USTORM_PER_COUNTER_ID_STATS_OFFSET(port, cli); + for (i = 0; i < sizeof(struct ustorm_per_client_stats) / 4; i++) + CNIC_WR(dev, val + i * 4, 0); + } cp->rx_cons_ptr = &cp->bnx2x_def_status_blk->u_def_status_block.index_values[ diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c index 3c58db5..23786ee 100644 --- a/drivers/net/cpmac.c +++ b/drivers/net/cpmac.c @@ -1181,7 +1181,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) if (netif_msg_drv(priv)) printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(priv->phy); + rc = PTR_ERR(priv->phy); + goto fail; } if ((rc = register_netdev(dev))) { diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index ebdea08..68a8089 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -1047,15 +1047,14 @@ static int __devinit e1000_probe(struct pci_dev *pdev, goto err_register; /* print bus type/speed/width info */ - e_info("(PCI%s:%s:%s) ", - ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), - ((hw->bus_speed == e1000_bus_speed_133) ? "133MHz" : - (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" : - (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" : - (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"), - ((hw->bus_width == e1000_bus_width_64) ? "64-bit" : "32-bit")); - - e_info("%pM\n", netdev->dev_addr); + e_info("(PCI%s:%dMHz:%d-bit) %pM\n", + ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : ""), + ((hw->bus_speed == e1000_bus_speed_133) ? 133 : + (hw->bus_speed == e1000_bus_speed_120) ? 120 : + (hw->bus_speed == e1000_bus_speed_100) ? 100 : + (hw->bus_speed == e1000_bus_speed_66) ? 66 : 33), + ((hw->bus_width == e1000_bus_width_64) ? 64 : 32), + netdev->dev_addr); /* carrier off reporting is important to ethtool even BEFORE open */ netif_carrier_off(netdev); diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h index 0630980..0060e42 100644 --- a/drivers/net/ehea/ehea.h +++ b/drivers/net/ehea/ehea.h @@ -40,7 +40,7 @@ #include <asm/io.h> #define DRV_NAME "ehea" -#define DRV_VERSION "EHEA_0103" +#define DRV_VERSION "EHEA_0105" /* eHEA capability flags */ #define DLPAR_PORT_ADD_REM 1 diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index f547894..8b92acb 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -867,6 +867,7 @@ static int ehea_poll(struct napi_struct *napi, int budget) ehea_reset_cq_ep(pr->send_cq); ehea_reset_cq_n1(pr->recv_cq); ehea_reset_cq_n1(pr->send_cq); + rmb(); cqe = ehea_poll_rq1(pr->qp, &wqe_index); cqe_skb = ehea_poll_cq(pr->send_cq); @@ -2859,6 +2860,7 @@ static void ehea_reset_port(struct work_struct *work) container_of(work, struct ehea_port, reset_task); struct net_device *dev = port->netdev; + mutex_lock(&dlpar_mem_lock); port->resets++; mutex_lock(&port->port_lock); netif_stop_queue(dev); @@ -2881,6 +2883,7 @@ static void ehea_reset_port(struct work_struct *work) netif_wake_queue(dev); out: mutex_unlock(&port->port_lock); + mutex_unlock(&dlpar_mem_lock); } static void ehea_rereg_mrs(struct work_struct *work) @@ -3542,10 +3545,7 @@ static int ehea_mem_notifier(struct notifier_block *nb, int ret = NOTIFY_BAD; struct memory_notify *arg = data; - if (!mutex_trylock(&dlpar_mem_lock)) { - ehea_info("ehea_mem_notifier must not be called parallelized"); - goto out; - } + mutex_lock(&dlpar_mem_lock); switch (action) { case MEM_CANCEL_OFFLINE: @@ -3574,7 +3574,6 @@ static int ehea_mem_notifier(struct notifier_block *nb, out_unlock: mutex_unlock(&dlpar_mem_lock); -out: return ret; } diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 2b3e16d..e0d3328 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c @@ -709,7 +709,7 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len) { u64 a0, a1 = len; int wait = 1000; - u64 prov_pa; + dma_addr_t prov_pa; void *prov_buf; int ret; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 46c69cd..28b53d1 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -381,10 +381,14 @@ static void gfar_init_mac(struct net_device *ndev) /* Insert receive time stamps into padding alignment bytes */ if (priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER) { rctrl &= ~RCTRL_PAL_MASK; - rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE | RCTRL_PADDING(8); + rctrl |= RCTRL_PADDING(8); priv->padding = 8; } + /* Enable HW time stamping if requested from user space */ + if (priv->hwts_rx_en) + rctrl |= RCTRL_PRSDEP_INIT | RCTRL_TS_ENABLE; + /* keep vlan related bits if it's enabled */ if (priv->vlgrp) { rctrl |= RCTRL_VLEX | RCTRL_PRSDEP_INIT; @@ -747,7 +751,8 @@ static int gfar_of_init(struct of_device *ofdev, struct net_device **pdev) FSL_GIANFAR_DEV_HAS_CSUM | FSL_GIANFAR_DEV_HAS_VLAN | FSL_GIANFAR_DEV_HAS_MAGIC_PACKET | - FSL_GIANFAR_DEV_HAS_EXTENDED_HASH; + FSL_GIANFAR_DEV_HAS_EXTENDED_HASH | + FSL_GIANFAR_DEV_HAS_TIMER; ctype = of_get_property(np, "phy-connection-type", NULL); @@ -805,12 +810,20 @@ static int gfar_hwtstamp_ioctl(struct net_device *netdev, switch (config.rx_filter) { case HWTSTAMP_FILTER_NONE: - priv->hwts_rx_en = 0; + if (priv->hwts_rx_en) { + stop_gfar(netdev); + priv->hwts_rx_en = 0; + startup_gfar(netdev); + } break; default: if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)) return -ERANGE; - priv->hwts_rx_en = 1; + if (!priv->hwts_rx_en) { + stop_gfar(netdev); + priv->hwts_rx_en = 1; + startup_gfar(netdev); + } config.rx_filter = HWTSTAMP_FILTER_ALL; break; } @@ -2642,6 +2655,10 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) dma_unmap_single(&priv->ofdev->dev, bdp->bufPtr, priv->rx_buffer_size, DMA_FROM_DEVICE); + if (unlikely(!(bdp->status & RXBD_ERR) && + bdp->length > priv->rx_buffer_size)) + bdp->status = RXBD_LARGE; + /* We drop the frame if we failed to allocate a new buffer */ if (unlikely(!newskb || !(bdp->status & RXBD_LAST) || bdp->status & RXBD_ERR)) { diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c index c50a754..3a93a81 100644 --- a/drivers/net/ixgbe/ixgbe_ethtool.c +++ b/drivers/net/ixgbe/ixgbe_ethtool.c @@ -2077,25 +2077,6 @@ static int ixgbe_get_coalesce(struct net_device *netdev, return 0; } -/* - * this function must be called before setting the new value of - * rx_itr_setting - */ -static bool ixgbe_reenable_rsc(struct ixgbe_adapter *adapter, - struct ethtool_coalesce *ec) -{ - /* check the old value and enable RSC if necessary */ - if ((adapter->rx_itr_setting == 0) && - (adapter->flags2 & IXGBE_FLAG2_RSC_CAPABLE)) { - adapter->flags2 |= IXGBE_FLAG2_RSC_ENABLED; - adapter->netdev->features |= NETIF_F_LRO; - DPRINTK(PROBE, INFO, "rx-usecs set to %d, re-enabling RSC\n", - ec->rx_coalesce_usecs); - return true; - } - return false; -} - static int ixgbe_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *ec) { @@ -2124,9 +2105,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev, (1000000/ec->rx_coalesce_usecs < IXGBE_MIN_INT_RATE)) return -EINVAL; - /* check the old value and enable RSC if necessary */ - need_reset = ixgbe_reenable_rsc(adapter, ec); - /* store the value in ints/second */ adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs; @@ -2135,9 +2113,6 @@ static int ixgbe_set_coalesce(struct net_device *netdev, /* clear the lower bit as its used for dynamic state */ adapter->rx_itr_setting &= ~1; } else if (ec->rx_coalesce_usecs == 1) { - /* check the old value and enable RSC if necessary */ - need_reset = ixgbe_reenable_rsc(adapter, ec); - /* 1 means dynamic mode */ adapter->rx_eitr_param = 20000; adapter->rx_itr_setting = 1; @@ -2157,10 +2132,11 @@ static int ixgbe_set_coalesce(struct net_device *netdev, */ if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { adapter->flags2 &= ~IXGBE_FLAG2_RSC_ENABLED; - netdev->features &= ~NETIF_F_LRO; - DPRINTK(PROBE, INFO, - "rx-usecs set to 0, disabling RSC\n"); - + if (netdev->features & NETIF_F_LRO) { + netdev->features &= ~NETIF_F_LRO; + DPRINTK(PROBE, INFO, "rx-usecs set to 0, " + "disabling LRO/RSC\n"); + } need_reset = true; } } @@ -2255,6 +2231,9 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data) } } else if (!adapter->rx_itr_setting) { netdev->features &= ~ETH_FLAG_LRO; + if (data & ETH_FLAG_LRO) + DPRINTK(PROBE, INFO, "rx-usecs set to 0, " + "LRO/RSC cannot be enabled.\n"); } } diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index b2af2f6..ce30c62 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c @@ -5282,6 +5282,10 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter) u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot; u64 non_eop_descs = 0, restart_queue = 0; + if (test_bit(__IXGBE_DOWN, &adapter->state) || + test_bit(__IXGBE_RESETTING, &adapter->state)) + return; + if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) { u64 rsc_count = 0; u64 rsc_flush = 0; diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c index 09e1911..48325a5 100644 --- a/drivers/net/ixgbe/ixgbe_phy.c +++ b/drivers/net/ixgbe/ixgbe_phy.c @@ -575,6 +575,8 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) * 4 SFP_DA_CORE1 - 82599-specific * 5 SFP_SR/LR_CORE0 - 82599-specific * 6 SFP_SR/LR_CORE1 - 82599-specific + * 7 SFP_act_lmt_DA_CORE0 - 82599-specific + * 8 SFP_act_lmt_DA_CORE1 - 82599-specific */ if (hw->mac.type == ixgbe_mac_82598EB) { if (cable_tech & IXGBE_SFF_DA_PASSIVE_CABLE) diff --git a/drivers/net/lib82596.c b/drivers/net/lib82596.c index ce5d6e9..c27f429 100644 --- a/drivers/net/lib82596.c +++ b/drivers/net/lib82596.c @@ -1343,7 +1343,7 @@ static void set_multicast_list(struct net_device *dev) DEB(DEB_MULTI, printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n", - dev->name, dev->mc_count, + dev->name, netdev_mc_count(dev), dev->flags & IFF_PROMISC ? "ON" : "OFF", dev->flags & IFF_ALLMULTI ? "ON" : "OFF")); diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c index 8e9704f..869f0ea 100644 --- a/drivers/net/mipsnet.c +++ b/drivers/net/mipsnet.c @@ -247,7 +247,7 @@ static const struct net_device_ops mipsnet_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, }; -static int __init mipsnet_probe(struct platform_device *dev) +static int __devinit mipsnet_probe(struct platform_device *dev) { struct net_device *netdev; int err; diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c index f26e547..3a41b6a 100644 --- a/drivers/net/netxen/netxen_nic_ctx.c +++ b/drivers/net/netxen/netxen_nic_ctx.c @@ -629,7 +629,8 @@ int netxen_alloc_hw_resources(struct netxen_adapter *adapter) if (addr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate tx desc ring\n", netdev->name); - return -ENOMEM; + err = -ENOMEM; + goto err_out_free; } tx_ring->desc_head = (struct cmd_desc_type0 *)addr; diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 5c496f8..29d7b93 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c @@ -1159,9 +1159,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off) window = CRB_HI(off); - if (adapter->ahw.crb_win == window) - return; - writel(window, addr); if (readl(addr) != window) { if (printk_ratelimit()) @@ -1169,7 +1166,6 @@ netxen_nic_pci_set_crbwindow_2M(struct netxen_adapter *adapter, ulong off) "failed to set CRB window to %d off 0x%lx\n", window, off); } - adapter->ahw.crb_win = window; } static void __iomem * diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index 045a7c8..c865dda 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c @@ -218,7 +218,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) if (cmd_buf_arr == NULL) { dev_err(&pdev->dev, "%s: failed to allocate cmd buffer ring\n", netdev->name); - return -ENOMEM; + goto err_out; } memset(cmd_buf_arr, 0, TX_BUFF_RINGSIZE(tx_ring)); tx_ring->cmd_buf_arr = cmd_buf_arr; @@ -230,7 +230,7 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) if (rds_ring == NULL) { dev_err(&pdev->dev, "%s: failed to allocate rds ring struct\n", netdev->name); - return -ENOMEM; + goto err_out; } recv_ctx->rds_rings = rds_ring; @@ -1805,9 +1805,10 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, netxen_ctx_msg msg = 0; struct list_head *head; + spin_lock(&rds_ring->lock); + producer = rds_ring->producer; - spin_lock(&rds_ring->lock); head = &rds_ring->free_list; while (!list_empty(head)) { @@ -1829,7 +1830,6 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, producer = get_next_index(producer, rds_ring->num_desc); } - spin_unlock(&rds_ring->lock); if (count) { rds_ring->producer = producer; @@ -1853,6 +1853,8 @@ netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ringid, NETXEN_RCV_PRODUCER_OFFSET), msg); } } + + spin_unlock(&rds_ring->lock); } static void @@ -1864,10 +1866,11 @@ netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter, int producer, count = 0; struct list_head *head; - producer = rds_ring->producer; if (!spin_trylock(&rds_ring->lock)) return; + producer = rds_ring->producer; + head = &rds_ring->free_list; while (!list_empty(head)) { diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 6f77a76..bfdef72 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c @@ -1727,6 +1727,7 @@ static struct pcmcia_device_id pcnet_ids[] = { PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(0, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID12(0, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID4(0, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(0, 0x0175, 0x0000, "cis/DP83903.cis"), diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c index 64e6a84..307cd17 100644 --- a/drivers/net/pcmcia/smc91c92_cs.c +++ b/drivers/net/pcmcia/smc91c92_cs.c @@ -1505,12 +1505,20 @@ irq_done: writeb(cor & ~COR_IREQ_ENA, smc->base + MOT_LAN + CISREG_COR); writeb(cor, smc->base + MOT_LAN + CISREG_COR); } -#ifdef DOES_NOT_WORK - if (smc->base != NULL) { /* Megahertz MFC's */ - readb(smc->base+MEGAHERTZ_ISR); - readb(smc->base+MEGAHERTZ_ISR); + + if ((smc->base != NULL) && /* Megahertz MFC's */ + (smc->manfid == MANFID_MEGAHERTZ) && + (smc->cardid == PRODID_MEGAHERTZ_EM3288)) { + + u_char tmp; + tmp = readb(smc->base+MEGAHERTZ_ISR); + tmp = readb(smc->base+MEGAHERTZ_ISR); + + /* Retrigger interrupt if needed */ + writeb(tmp, smc->base + MEGAHERTZ_ISR); + writeb(tmp, smc->base + MEGAHERTZ_ISR); } -#endif + spin_unlock(&smc->lock); return IRQ_RETVAL(handled); } diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c index dbd0034..29c39ff 100644 --- a/drivers/net/phy/lxt.c +++ b/drivers/net/phy/lxt.c @@ -226,6 +226,7 @@ module_exit(lxt_exit); static struct mdio_device_id lxt_tbl[] = { { 0x78100000, 0xfffffff0 }, { 0x001378e0, 0xfffffff0 }, + { 0x00137a10, 0xfffffff0 }, { } }; diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 2111c7b..7985165 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port) sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } +/* Enable Rx/Tx */ +static void sky2_enable_rx_tx(struct sky2_port *sky2) +{ + struct sky2_hw *hw = sky2->hw; + unsigned port = sky2->port; + u16 reg; + + reg = gma_read16(hw, port, GM_GP_CTRL); + reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; + gma_write16(hw, port, GM_GP_CTRL, reg); +} + /* Force a renegotiation */ static void sky2_phy_reinit(struct sky2_port *sky2) { spin_lock_bh(&sky2->phy_lock); sky2_phy_init(sky2->hw, sky2->port); + sky2_enable_rx_tx(sky2); spin_unlock_bh(&sky2->phy_lock); } @@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2) { struct sky2_hw *hw = sky2->hw; unsigned port = sky2->port; - u16 reg; static const char *fc_name[] = { [FC_NONE] = "none", [FC_TX] = "tx", @@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2) [FC_BOTH] = "both", }; - /* enable Rx/Tx */ - reg = gma_read16(hw, port, GM_GP_CTRL); - reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; - gma_write16(hw, port, GM_GP_CTRL, reg); + sky2_enable_rx_tx(sky2); gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index c0e7000..06b552f 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -367,8 +367,8 @@ static u16 t21041_csr14[] = { 0xFFFF, 0xF7FD, 0xF7FD, 0x6F3F, 0x6F3D, }; static u16 t21041_csr15[] = { 0x0008, 0x0006, 0x000E, 0x0008, 0x0008, }; -#define dr32(reg) readl(de->regs + (reg)) -#define dw32(reg,val) writel((val), de->regs + (reg)) +#define dr32(reg) ioread32(de->regs + (reg)) +#define dw32(reg, val) iowrite32((val), de->regs + (reg)) static void de_rx_err_acct (struct de_private *de, unsigned rx_tail, @@ -1706,6 +1706,7 @@ static void __devinit de21040_get_mac_address (struct de_private *de) int value, boguscnt = 100000; do { value = dr32(ROMCmd); + rmb(); } while (value < 0 && --boguscnt > 0); de->dev->dev_addr[i] = value; udelay(1); diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index 4a34833..807470e 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -3215,6 +3215,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit __func__, __LINE__, (u32) skb); if (skb) { skb->data = skb->head + NET_SKB_PAD; + skb->len = 0; + skb_reset_tail_pointer(skb); __skb_queue_head(&ugeth->rx_recycle, skb); } diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 0a3c41f..4dd2351 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c @@ -1334,7 +1334,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp) /* check for port already opened, if not set the termios */ serial->open_count++; if (serial->open_count == 1) { - tty->low_latency = 1; serial->rx_state = RX_IDLE; /* Force default termio settings */ _hso_serial_set_termios(tty, NULL); diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c index b504bd5..d14e207 100644 --- a/drivers/net/vxge/vxge-main.c +++ b/drivers/net/vxge/vxge-main.c @@ -2262,7 +2262,8 @@ start: vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", VXGE_DRIVER_NAME); - return -ENOMEM; + ret = -ENOMEM; + goto alloc_entries_failed; } vdev->vxge_entries = @@ -2271,8 +2272,8 @@ start: if (!vdev->vxge_entries) { vxge_debug_init(VXGE_ERR, "%s: memory allocation failed", VXGE_DRIVER_NAME); - kfree(vdev->entries); - return -ENOMEM; + ret = -ENOMEM; + goto alloc_vxge_entries_failed; } for (i = 0, j = 0; i < vdev->no_of_vpath; i++) { @@ -2303,22 +2304,32 @@ start: vxge_debug_init(VXGE_ERR, "%s: MSI-X enable failed for %d vectors, ret: %d", VXGE_DRIVER_NAME, vdev->intr_cnt, ret); + if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) { + ret = -ENODEV; + goto enable_msix_failed; + } + kfree(vdev->entries); kfree(vdev->vxge_entries); vdev->entries = NULL; vdev->vxge_entries = NULL; - - if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) - return -ENODEV; /* Try with less no of vector by reducing no of vpaths count */ temp = (ret - 1)/2; vxge_close_vpaths(vdev, temp); vdev->no_of_vpath = temp; goto start; - } else if (ret < 0) - return -ENODEV; - + } else if (ret < 0) { + ret = -ENODEV; + goto enable_msix_failed; + } return 0; + +enable_msix_failed: + kfree(vdev->vxge_entries); +alloc_vxge_entries_failed: + kfree(vdev->entries); +alloc_entries_failed: + return ret; } static int vxge_enable_msix(struct vxgedev *vdev) diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index e0c244b..31c0080 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c @@ -126,6 +126,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; ah->ah_noise_floor = -95; /* until first NF calibration is run */ sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; + ah->ah_current_channel = &sc->channels[0]; /* * Find the mac version diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index db72461..29b31a6 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link) local_info_t *local; int ret = 1; struct hostap_cs_priv *hw_priv; + unsigned long flags; PDEBUG(DEBUG_FLOW, "prism2_config()\n"); @@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link) local->hw_priv = hw_priv; hw_priv->link = link; + /* + * Make sure the IRQ handler cannot proceed until at least + * dev->base_addr is initialized. + */ + spin_lock_irqsave(&local->irq_init_lock, flags); + ret = pcmcia_request_irq(link, prism2_interrupt); if (ret) - goto failed; + goto failed_unlock; /* * This actually configures the PCMCIA socket -- setting up @@ -636,11 +643,13 @@ static int prism2_config(struct pcmcia_device *link) */ ret = pcmcia_request_configuration(link, &link->conf); if (ret) - goto failed; + goto failed_unlock; dev->irq = link->irq; dev->base_addr = link->io.BasePort1; + spin_unlock_irqrestore(&local->irq_init_lock, flags); + /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev_info, link->conf.ConfigIndex); @@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link) return ret; + failed_unlock: + spin_unlock_irqrestore(&local->irq_init_lock, flags); failed: kfree(hw_priv); prism2_release((u_long)link); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index ff9b5c8..2f999fc 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -2621,6 +2621,18 @@ static irqreturn_t prism2_interrupt(int irq, void *dev_id) iface = netdev_priv(dev); local = iface->local; + /* Detect early interrupt before driver is fully configued */ + spin_lock(&local->irq_init_lock); + if (!dev->base_addr) { + if (net_ratelimit()) { + printk(KERN_DEBUG "%s: Interrupt, but dev not configured\n", + dev->name); + } + spin_unlock(&local->irq_init_lock); + return IRQ_HANDLED; + } + spin_unlock(&local->irq_init_lock); + prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_INTERRUPT, 0, 0); if (local->func->card_present && !local->func->card_present(local)) { @@ -3138,6 +3150,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx, spin_lock_init(&local->cmdlock); spin_lock_init(&local->baplock); spin_lock_init(&local->lock); + spin_lock_init(&local->irq_init_lock); mutex_init(&local->rid_bap_mtx); if (card_idx < 0 || card_idx >= MAX_PARM_DEVICES) diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h index 3d23891..1ba33be 100644 --- a/drivers/net/wireless/hostap/hostap_wlan.h +++ b/drivers/net/wireless/hostap/hostap_wlan.h @@ -654,7 +654,7 @@ struct local_info { rwlock_t iface_lock; /* hostap_interfaces read lock; use write lock * when removing entries from the list. * TX and RX paths can use read lock. */ - spinlock_t cmdlock, baplock, lock; + spinlock_t cmdlock, baplock, lock, irq_init_lock; struct mutex rid_bap_mtx; u16 infofid; /* MAC buffer id for info frame */ /* txfid, intransmitfid, next_txtid, and next_alloc are protected by diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index a732f10..7d614c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -1299,6 +1299,11 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv, sta_id = ba_resp->sta_id; tid = ba_resp->tid; agg = &priv->stations[sta_id].tid[tid].agg; + if (unlikely(agg->txq_id != scd_flow)) { + IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n", + scd_flow, agg->txq_id); + return; + } /* Find index just before block-ack window */ index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7726e67..24aff65 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -3391,10 +3391,12 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, int ret; u8 sta_id; - sta_priv->common.sta_id = IWL_INVALID_STATION; - IWL_DEBUG_INFO(priv, "received request to add station %pM\n", sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", + sta->addr); + sta_priv->common.sta_id = IWL_INVALID_STATION; atomic_set(&sta_priv->pending_frames, 0); if (vif->type == NL80211_IFTYPE_AP) @@ -3406,6 +3408,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ + mutex_unlock(&priv->mutex); return ret; } @@ -3415,6 +3418,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw, IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", sta->addr); iwl_rs_rate_init(priv, sta, sta_id); + mutex_unlock(&priv->mutex); return 0; } diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 5d3f51f..386c5f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -491,6 +491,7 @@ void iwl_bg_abort_scan(struct work_struct *work) mutex_lock(&priv->mutex); + cancel_delayed_work_sync(&priv->scan_check); set_bit(STATUS_SCAN_ABORTING, &priv->status); iwl_send_scan_abort(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 83a2636..c27c13f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -1373,10 +1373,14 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw, IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to remove station %pM\n", + sta->addr); ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr); if (ret) IWL_ERR(priv, "Error removing station %pM\n", sta->addr); + mutex_unlock(&priv->mutex); return ret; } EXPORT_SYMBOL(iwl_mac_sta_remove); diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 6c353ca..a27872d 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -3437,10 +3437,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, bool is_ap = vif->type == NL80211_IFTYPE_STATION; u8 sta_id; - sta_priv->common.sta_id = IWL_INVALID_STATION; - IWL_DEBUG_INFO(priv, "received request to add station %pM\n", sta->addr); + mutex_lock(&priv->mutex); + IWL_DEBUG_INFO(priv, "proceeding to add station %pM\n", + sta->addr); + sta_priv->common.sta_id = IWL_INVALID_STATION; + ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, &sta_id); @@ -3448,6 +3451,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, IWL_ERR(priv, "Unable to add station %pM (%d)\n", sta->addr, ret); /* Should we return success if return code is EEXIST ? */ + mutex_unlock(&priv->mutex); return ret; } @@ -3457,6 +3461,7 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw, IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", sta->addr); iwl3945_rs_rate_init(priv, sta, sta_id); + mutex_unlock(&priv->mutex); return 0; } diff --git a/drivers/net/wireless/libertas_tf/main.c b/drivers/net/wireless/libertas_tf/main.c index 6a04c21..817fffc 100644 --- a/drivers/net/wireless/libertas_tf/main.c +++ b/drivers/net/wireless/libertas_tf/main.c @@ -549,7 +549,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb) prxpd = (struct rxpd *) skb->data; - stats.flag = 0; + memset(&stats, 0, sizeof(stats)); if (!(prxpd->status & cpu_to_le16(MRVDRV_RXPD_STATUS_OK))) stats.flag |= RX_FLAG_FAILED_FCS_CRC; stats.freq = priv->cur_freq; diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index 07c4528..a5ea89c 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c @@ -41,6 +41,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = { { PCI_DEVICE(0x1260, 0x3877) }, /* Intersil PRISM Javelin/Xbow Wireless LAN adapter */ { PCI_DEVICE(0x1260, 0x3886) }, + /* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */ + { PCI_DEVICE(0x1260, 0xffff) }, { }, }; diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 796828f..c9171be 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c @@ -340,7 +340,7 @@ int dmar_disabled = 0; int dmar_disabled = 1; #endif /*CONFIG_DMAR_DEFAULT_ON*/ -static int __initdata dmar_map_gfx = 1; +static int dmar_map_gfx = 1; static int dmar_forcedac; static int intel_iommu_strict; @@ -1874,14 +1874,15 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) } } if (found) { + spin_unlock_irqrestore(&device_domain_lock, flags); free_devinfo_mem(info); domain_exit(domain); domain = found; } else { list_add(&info->link, &domain->devices); list_add(&info->global, &device_domain_list); + spin_unlock_irqrestore(&device_domain_lock, flags); } - spin_unlock_irqrestore(&device_domain_lock, flags); } found_domain: @@ -3603,7 +3604,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain, pte = dmar_domain->pgd; if (dma_pte_present(pte)) { free_pgtable_page(dmar_domain->pgd); - dmar_domain->pgd = (struct dma_pte *)dma_pte_addr(pte); + dmar_domain->pgd = (struct dma_pte *) + phys_to_virt(dma_pte_addr(pte)); } dmar_domain->agaw--; } @@ -3719,6 +3721,12 @@ static void __devinit quirk_iommu_rwbf(struct pci_dev *dev) */ printk(KERN_INFO "DMAR: Forcing write-buffer flush capability\n"); rwbf_quirk = 1; + + /* https://bugzilla.redhat.com/show_bug.cgi?id=538163 */ + if (dev->revision == 0x07) { + printk(KERN_INFO "DMAR: Disabling IOMMU for graphics on this chipset\n"); + dmar_map_gfx = 0; + } } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x2a40, quirk_iommu_rwbf); diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 60f30e7..740fb4e 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2292,6 +2292,7 @@ void pci_msi_off(struct pci_dev *dev) pci_write_config_word(dev, pos + PCI_MSIX_FLAGS, control); } } +EXPORT_SYMBOL_GPL(pci_msi_off); #ifndef HAVE_ARCH_PCI_SET_DMA_MAX_SEGMENT_SIZE int pci_set_dma_max_seg_size(struct pci_dev *dev, unsigned int size) diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c index aac285a..d672a0a 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme/pcie_pme.c @@ -34,7 +34,7 @@ * being registered. Consequently, the interrupt-based PCIe PME signaling will * not be used by any PCIe root ports in that case. */ -static bool pcie_pme_disabled; +static bool pcie_pme_disabled = true; /* * The PCI Express Base Specification 2.0, Section 6.1.8, states the following: @@ -64,12 +64,19 @@ bool pcie_pme_msi_disabled; static int __init pcie_pme_setup(char *str) { - if (!strcmp(str, "off")) - pcie_pme_disabled = true; - else if (!strcmp(str, "force")) + if (!strncmp(str, "auto", 4)) + pcie_pme_disabled = false; + else if (!strncmp(str, "force", 5)) pcie_pme_force_enable = true; - else if (!strcmp(str, "nomsi")) - pcie_pme_msi_disabled = true; + + str = strchr(str, ','); + if (str) { + str++; + str += strspn(str, " \t"); + if (*str && !strcmp(str, "nomsi")) + pcie_pme_msi_disabled = true; + } + return 1; } __setup("pcie_pme=", pcie_pme_setup); diff --git a/drivers/rtc/rtc-davinci.c b/drivers/rtc/rtc-davinci.c index 92a8f6c..34647fc 100644 --- a/drivers/rtc/rtc-davinci.c +++ b/drivers/rtc/rtc-davinci.c @@ -29,6 +29,7 @@ #include <linux/bcd.h> #include <linux/platform_device.h> #include <linux/io.h> +#include <linux/slab.h> /* * The DaVinci RTC is a simple RTC with the following diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 5263073..ab17c08 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c @@ -821,6 +821,7 @@ static struct pcmcia_device_id serial_ids[] = { PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet GSM", 0xf5f025c2, 0x4ae85d35, "cis/PCMLM28.cis"), PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "LINKSYS", "PCMLM28", 0xf7cb0b07, 0x66881874, "cis/PCMLM28.cis"), + PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "TOSHIBA", "Modem/LAN Card", 0xb4585a1a, 0x53f922f8, "cis/PCMLM28.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID12(1, "DAYNA COMMUNICATIONS", "LAN AND MODEM MULTIFUNCTION", 0x8fdf8f89, 0xdd5ed9e8, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_PROD_ID4(1, "NSC MF LAN/Modem", 0x58fc6056, "cis/DP83903.cis"), PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0556, "cis/3CCFEM556.cis"), diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c index ce081cd..273e26e 100644 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ b/drivers/staging/tm6000/tm6000-alsa.c @@ -15,6 +15,7 @@ #include <linux/device.h> #include <linux/interrupt.h> #include <linux/usb.h> +#include <linux/slab.h> #include <asm/delay.h> #include <sound/core.h> diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c index cedd904..6a9ae40 100644 --- a/drivers/staging/tm6000/tm6000-cards.c +++ b/drivers/staging/tm6000/tm6000-cards.c @@ -24,6 +24,7 @@ #include <linux/i2c.h> #include <linux/usb.h> #include <linux/version.h> +#include <linux/slab.h> #include <media/v4l2-common.h> #include <media/tuner.h> #include <media/tvaudio.h> diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c index 27f3f55..c3690e3 100644 --- a/drivers/staging/tm6000/tm6000-core.c +++ b/drivers/staging/tm6000/tm6000-core.c @@ -22,6 +22,7 @@ #include <linux/module.h> #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/usb.h> #include <linux/i2c.h> #include "tm6000.h" diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c index 261e66a..86c1c8b 100644 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ b/drivers/staging/tm6000/tm6000-dvb.c @@ -18,6 +18,7 @@ */ #include <linux/kernel.h> +#include <linux/slab.h> #include <linux/usb.h> #include "tm6000.h" diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c index 43ab7d8..7767338 100644 --- a/drivers/video/omap/lcdc.c +++ b/drivers/video/omap/lcdc.c @@ -572,22 +572,12 @@ static enum omapfb_update_mode omap_lcdc_get_update_mode(void) /* PM code called only in internal controller mode */ static void omap_lcdc_suspend(void) { - if (lcdc.update_mode == OMAPFB_AUTO_UPDATE) { - disable_controller(); - omap_stop_lcd_dma(); - } + omap_lcdc_set_update_mode(OMAPFB_UPDATE_DISABLED); } static void omap_lcdc_resume(void) { - if (lcdc.update_mode == OMAPFB_AUTO_UPDATE) { - setup_regs(); - load_palette(); - setup_lcd_dma(); - set_load_mode(OMAP_LCDC_LOAD_FRAME); - enable_irqs(OMAP_LCDC_IRQ_DONE); - enable_controller(); - } + omap_lcdc_set_update_mode(OMAPFB_AUTO_UPDATE); } static void omap_lcdc_get_caps(int plane, struct omapfb_caps *caps) diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c index 1162603..eada9f1 100644 --- a/drivers/video/omap/rfbi.c +++ b/drivers/video/omap/rfbi.c @@ -26,6 +26,7 @@ #include <linux/interrupt.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/platform_device.h> #include "omapfb.h" #include "dispc.h" @@ -83,13 +84,13 @@ static inline u32 rfbi_read_reg(int idx) static int rfbi_get_clocks(void) { - rfbi.dss_ick = clk_get(&dispc.fbdev->dssdev->dev, "ick"); + rfbi.dss_ick = clk_get(&rfbi.fbdev->dssdev->dev, "ick"); if (IS_ERR(rfbi.dss_ick)) { dev_err(rfbi.fbdev->dev, "can't get ick\n"); return PTR_ERR(rfbi.dss_ick); } - rfbi.dss1_fck = clk_get(&dispc.fbdev->dssdev->dev, "dss1_fck"); + rfbi.dss1_fck = clk_get(&rfbi.fbdev->dssdev->dev, "dss1_fck"); if (IS_ERR(rfbi.dss1_fck)) { dev_err(rfbi.fbdev->dev, "can't get dss1_fck\n"); clk_put(rfbi.dss_ick); diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index 95896f3..ef8d9d5 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -636,6 +636,9 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, INIT_LIST_HEAD(&vp_dev->virtqueues); spin_lock_init(&vp_dev->lock); + /* Disable MSI/MSIX to bring device to a known good state. */ + pci_msi_off(pci_dev); + /* enable the device */ err = pci_enable_device(pci_dev); if (err) diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index 1ca8890..afe7e21 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -119,7 +119,7 @@ static int vring_add_indirect(struct vring_virtqueue *vq, desc = kmalloc((out + in) * sizeof(struct vring_desc), gfp); if (!desc) - return vq->vring.num; + return -ENOMEM; /* Transfer entries from the sg list into the indirect page */ for (i = 0; i < out; i++) { diff --git a/drivers/watchdog/at32ap700x_wdt.c b/drivers/watchdog/at32ap700x_wdt.c index 1cddf92..750bc52 100644 --- a/drivers/watchdog/at32ap700x_wdt.c +++ b/drivers/watchdog/at32ap700x_wdt.c @@ -346,9 +346,13 @@ static int __init at32_wdt_probe(struct platform_device *pdev) } else { wdt->users = 0; } - wdt->miscdev.minor = WATCHDOG_MINOR; - wdt->miscdev.name = "watchdog"; - wdt->miscdev.fops = &at32_wdt_fops; + + wdt->miscdev.minor = WATCHDOG_MINOR; + wdt->miscdev.name = "watchdog"; + wdt->miscdev.fops = &at32_wdt_fops; + wdt->miscdev.parent = &pdev->dev; + + platform_set_drvdata(pdev, wdt); if (at32_wdt_settimeout(timeout)) { at32_wdt_settimeout(TIMEOUT_DEFAULT); @@ -360,17 +364,17 @@ static int __init at32_wdt_probe(struct platform_device *pdev) ret = misc_register(&wdt->miscdev); if (ret) { dev_dbg(&pdev->dev, "failed to register wdt miscdev\n"); - goto err_iounmap; + goto err_register; } - platform_set_drvdata(pdev, wdt); - wdt->miscdev.parent = &pdev->dev; dev_info(&pdev->dev, "AT32AP700X WDT at 0x%p, timeout %d sec (nowayout=%d)\n", wdt->regs, wdt->timeout, nowayout); return 0; +err_register: + platform_set_drvdata(pdev, NULL); err_iounmap: iounmap(wdt->regs); err_free: diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index ea25885..2ee7dac 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c @@ -330,7 +330,6 @@ static void imx2_wdt_shutdown(struct platform_device *pdev) } static struct platform_driver imx2_wdt_driver = { - .probe = imx2_wdt_probe, .remove = __exit_p(imx2_wdt_remove), .shutdown = imx2_wdt_shutdown, .driver = { diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 78c02eb..484e52b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -473,14 +473,24 @@ static int cifs_remount(struct super_block *sb, int *flags, char *data) return 0; } +void cifs_drop_inode(struct inode *inode) +{ + struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); + + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) + return generic_drop_inode(inode); + + return generic_delete_inode(inode); +} + static const struct super_operations cifs_super_ops = { .put_super = cifs_put_super, .statfs = cifs_statfs, .alloc_inode = cifs_alloc_inode, .destroy_inode = cifs_destroy_inode, -/* .drop_inode = generic_delete_inode, - .delete_inode = cifs_delete_inode, */ /* Do not need above two - functions unless later we add lazy close of inodes or unless the + .drop_inode = cifs_drop_inode, +/* .delete_inode = cifs_delete_inode, */ /* Do not need above + function unless later we add lazy close of inodes or unless the kernel forgets to call us with the same number of releases (closes) as opens */ .show_options = cifs_show_options, diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index fb1657e..fb6318b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -106,7 +106,6 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, struct file *file, struct vfsmount *mnt, unsigned int oflags); extern int cifs_posix_open(char *full_path, struct inode **pinode, - struct vfsmount *mnt, struct super_block *sb, int mode, int oflags, __u32 *poplock, __u16 *pnetfid, int xid); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 391816b..e7ae78b 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -25,6 +25,7 @@ #include <linux/slab.h> #include <linux/namei.h> #include <linux/mount.h> +#include <linux/file.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" @@ -184,12 +185,13 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, } write_unlock(&GlobalSMBSeslock); + file->private_data = pCifsFile; + return pCifsFile; } int cifs_posix_open(char *full_path, struct inode **pinode, - struct vfsmount *mnt, struct super_block *sb, - int mode, int oflags, + struct super_block *sb, int mode, int oflags, __u32 *poplock, __u16 *pnetfid, int xid) { int rc; @@ -258,19 +260,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, cifs_fattr_to_inode(*pinode, &fattr); } - /* - * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to - * file->private_data. - */ - if (mnt) { - struct cifsFileInfo *pfile_info; - - pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt, - oflags); - if (pfile_info == NULL) - rc = -ENOMEM; - } - posix_open_ret: kfree(presp_data); return rc; @@ -298,7 +287,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, int create_options = CREATE_NOT_DIR; __u32 oplock = 0; int oflags; - bool posix_create = false; /* * BB below access is probably too much for mknod to request * but we have to do query and setpathinfo so requesting @@ -339,7 +327,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, (CIFS_UNIX_POSIX_PATH_OPS_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))) { rc = cifs_posix_open(full_path, &newinode, - nd ? nd->path.mnt : NULL, inode->i_sb, mode, oflags, &oplock, &fileHandle, xid); /* EIO could indicate that (posix open) operation is not supported, despite what server claimed in capability @@ -347,7 +334,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, handled in posix open */ if (rc == 0) { - posix_create = true; if (newinode == NULL) /* query inode info */ goto cifs_create_get_file_info; else /* success, no need to query */ @@ -478,21 +464,28 @@ cifs_create_set_dentry: else cFYI(1, "Create worked, get_inode_info failed rc = %d", rc); - /* nfsd case - nfs srv does not set nd */ - if ((nd == NULL) || (!(nd->flags & LOOKUP_OPEN))) { - /* mknod case - do not leave file open */ - CIFSSMBClose(xid, tcon, fileHandle); - } else if (!(posix_create) && (newinode)) { + if (newinode && nd && (nd->flags & LOOKUP_OPEN)) { struct cifsFileInfo *pfile_info; - /* - * cifs_fill_filedata() takes care of setting cifsFileInfo - * pointer to file->private_data. - */ - pfile_info = cifs_new_fileinfo(newinode, fileHandle, NULL, + struct file *filp; + + filp = lookup_instantiate_filp(nd, direntry, generic_file_open); + if (IS_ERR(filp)) { + rc = PTR_ERR(filp); + CIFSSMBClose(xid, tcon, fileHandle); + goto cifs_create_out; + } + + pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, nd->path.mnt, oflags); - if (pfile_info == NULL) + if (pfile_info == NULL) { + fput(filp); + CIFSSMBClose(xid, tcon, fileHandle); rc = -ENOMEM; + } + } else { + CIFSSMBClose(xid, tcon, fileHandle); } + cifs_create_out: kfree(buf); kfree(full_path); @@ -636,6 +629,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, bool posix_open = false; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *pTcon; + struct cifsFileInfo *cfile; struct inode *newInode = NULL; char *full_path = NULL; struct file *filp; @@ -703,7 +697,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && (nd->intent.open.flags & O_CREAT)) { - rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, + rc = cifs_posix_open(full_path, &newInode, parent_dir_inode->i_sb, nd->intent.open.create_mode, nd->intent.open.flags, &oplock, @@ -733,8 +727,25 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, else direntry->d_op = &cifs_dentry_ops; d_add(direntry, newInode); - if (posix_open) - filp = lookup_instantiate_filp(nd, direntry, NULL); + if (posix_open) { + filp = lookup_instantiate_filp(nd, direntry, + generic_file_open); + if (IS_ERR(filp)) { + rc = PTR_ERR(filp); + CIFSSMBClose(xid, pTcon, fileHandle); + goto lookup_out; + } + + cfile = cifs_new_fileinfo(newInode, fileHandle, filp, + nd->path.mnt, + nd->intent.open.flags); + if (cfile == NULL) { + fput(filp); + CIFSSMBClose(xid, pTcon, fileHandle); + rc = -ENOMEM; + goto lookup_out; + } + } /* since paths are not looked up by component - the parent directories are presumed to be good here */ renew_parental_timestamps(direntry); @@ -755,6 +766,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, is a common return code */ } +lookup_out: kfree(full_path); FreeXid(xid); return ERR_PTR(rc); diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 75541af..409e4f5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -162,44 +162,12 @@ psx_client_can_cache: return 0; } -static struct cifsFileInfo * -cifs_fill_filedata(struct file *file) -{ - struct list_head *tmp; - struct cifsFileInfo *pCifsFile = NULL; - struct cifsInodeInfo *pCifsInode = NULL; - - /* search inode for this file and fill in file->private_data */ - pCifsInode = CIFS_I(file->f_path.dentry->d_inode); - read_lock(&GlobalSMBSeslock); - list_for_each(tmp, &pCifsInode->openFileList) { - pCifsFile = list_entry(tmp, struct cifsFileInfo, flist); - if ((pCifsFile->pfile == NULL) && - (pCifsFile->pid == current->tgid)) { - /* mode set in cifs_create */ - - /* needed for writepage */ - pCifsFile->pfile = file; - file->private_data = pCifsFile; - break; - } - } - read_unlock(&GlobalSMBSeslock); - - if (file->private_data != NULL) { - return pCifsFile; - } else if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL)) - cERROR(1, "could not find file instance for " - "new file %p", file); - return NULL; -} - /* all arguments to this function must be checked for validity in caller */ -static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, - struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile, +static inline int cifs_open_inode_helper(struct inode *inode, struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf, char *full_path, int xid) { + struct cifsInodeInfo *pCifsInode = CIFS_I(inode); struct timespec temp; int rc; @@ -213,36 +181,35 @@ static inline int cifs_open_inode_helper(struct inode *inode, struct file *file, /* if not oplocked, invalidate inode pages if mtime or file size changed */ temp = cifs_NTtimeToUnix(buf->LastWriteTime); - if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) && - (file->f_path.dentry->d_inode->i_size == + if (timespec_equal(&inode->i_mtime, &temp) && + (inode->i_size == (loff_t)le64_to_cpu(buf->EndOfFile))) { cFYI(1, "inode unchanged on server"); } else { - if (file->f_path.dentry->d_inode->i_mapping) { + if (inode->i_mapping) { /* BB no need to lock inode until after invalidate since namei code should already have it locked? */ - rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping); + rc = filemap_write_and_wait(inode->i_mapping); if (rc != 0) - CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc; + pCifsInode->write_behind_rc = rc; } cFYI(1, "invalidating remote inode since open detected it " "changed"); - invalidate_remote_inode(file->f_path.dentry->d_inode); + invalidate_remote_inode(inode); } client_can_cache: if (pTcon->unix_ext) - rc = cifs_get_inode_info_unix(&file->f_path.dentry->d_inode, - full_path, inode->i_sb, xid); + rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, + xid); else - rc = cifs_get_inode_info(&file->f_path.dentry->d_inode, - full_path, buf, inode->i_sb, xid, NULL); + 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", - file->f_path.dentry->d_inode); + cFYI(1, "Exclusive Oplock granted on inode %p", inode); } else if ((*oplock & 0xF) == OPLOCK_READ) pCifsInode->clientCanCacheRead = true; @@ -256,7 +223,7 @@ int cifs_open(struct inode *inode, struct file *file) __u32 oplock; struct cifs_sb_info *cifs_sb; struct cifsTconInfo *tcon; - struct cifsFileInfo *pCifsFile; + struct cifsFileInfo *pCifsFile = NULL; struct cifsInodeInfo *pCifsInode; char *full_path = NULL; int desiredAccess; @@ -270,12 +237,6 @@ int cifs_open(struct inode *inode, struct file *file) tcon = cifs_sb->tcon; pCifsInode = CIFS_I(file->f_path.dentry->d_inode); - pCifsFile = cifs_fill_filedata(file); - if (pCifsFile) { - rc = 0; - FreeXid(xid); - return rc; - } full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { @@ -299,8 +260,7 @@ int cifs_open(struct inode *inode, struct file *file) int oflags = (int) cifs_posix_convert_flags(file->f_flags); oflags |= SMB_O_CREAT; /* can not refresh inode info since size could be stale */ - rc = cifs_posix_open(full_path, &inode, file->f_path.mnt, - inode->i_sb, + rc = cifs_posix_open(full_path, &inode, inode->i_sb, cifs_sb->mnt_file_mode /* ignored */, oflags, &oplock, &netfid, xid); if (rc == 0) { @@ -308,9 +268,20 @@ int cifs_open(struct inode *inode, struct file *file) /* no need for special case handling of setting mode on read only files needed here */ - pCifsFile = cifs_fill_filedata(file); - cifs_posix_open_inode_helper(inode, file, pCifsInode, - oplock, netfid); + rc = cifs_posix_open_inode_helper(inode, file, + pCifsInode, oplock, netfid); + if (rc != 0) { + CIFSSMBClose(xid, tcon, netfid); + goto out; + } + + pCifsFile = cifs_new_fileinfo(inode, netfid, file, + file->f_path.mnt, + oflags); + if (pCifsFile == NULL) { + CIFSSMBClose(xid, tcon, netfid); + rc = -ENOMEM; + } goto out; } else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { if (tcon->ses->serverNOS) @@ -391,17 +362,17 @@ int cifs_open(struct inode *inode, struct file *file) goto out; } + rc = cifs_open_inode_helper(inode, tcon, &oplock, buf, full_path, xid); + if (rc != 0) + goto out; + pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, file->f_flags); - file->private_data = pCifsFile; - if (file->private_data == NULL) { + if (pCifsFile == NULL) { rc = -ENOMEM; goto out; } - rc = cifs_open_inode_helper(inode, file, pCifsInode, pCifsFile, tcon, - &oplock, buf, full_path, xid); - if (oplock & CIFS_CREATE_ACTION) { /* time to set mode which we can not set earlier due to problems creating new read-only files */ @@ -513,8 +484,7 @@ reopen_error_exit: le64_to_cpu(tcon->fsUnixInfo.Capability))) { int oflags = (int) cifs_posix_convert_flags(file->f_flags); /* can not refresh inode info since size could be stale */ - rc = cifs_posix_open(full_path, NULL, file->f_path.mnt, - inode->i_sb, + rc = cifs_posix_open(full_path, NULL, inode->i_sb, cifs_sb->mnt_file_mode /* ignored */, oflags, &oplock, &netfid, xid); if (rc == 0) { diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 62b324f..6f0683c 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -1401,6 +1401,10 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath, if (rc == 0 || rc != -ETXTBSY) return rc; + /* open-file renames don't work across directories */ + if (to_dentry->d_parent != from_dentry->d_parent) + return rc; + /* open the file to be renamed -- we need DELETE perms */ rc = CIFSSMBOpen(xid, pTcon, fromPath, FILE_OPEN, DELETE, CREATE_NOT_DIR, &srcfid, &oplock, NULL, diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 7707389..0a57cb7 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -730,15 +730,7 @@ ssetup_ntlmssp_authenticate: /* calculate session key */ setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp); - if (first_time) /* should this be moved into common code - with similar ntlmv2 path? */ - /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, - response BB FIXME, v2_sess_key); */ - - /* copy session key */ - - /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); - bcc_ptr += LM2_SESS_KEY_SIZE; */ + /* FIXME: calculate MAC key */ memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp)); bcc_ptr += sizeof(struct ntlmv2_resp); diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c index ca7e2a0..2bcc043 100644 --- a/fs/ext2/acl.c +++ b/fs/ext2/acl.c @@ -200,6 +200,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; else { inode->i_mode = mode; + inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); if (error == 0) acl = NULL; diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index 01552ab..8a11fe2 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c @@ -205,6 +205,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, return error; else { inode->i_mode = mode; + inode->i_ctime = CURRENT_TIME_SEC; ext3_mark_inode_dirty(handle, inode); if (error == 0) acl = NULL; diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 7ec9b34..d25b525 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c @@ -1286,6 +1286,55 @@ static void nfs4_session_set_rwsize(struct nfs_server *server) #endif /* CONFIG_NFS_V4_1 */ } +static int nfs4_server_common_setup(struct nfs_server *server, + struct nfs_fh *mntfh) +{ + struct nfs_fattr *fattr; + int error; + + BUG_ON(!server->nfs_client); + BUG_ON(!server->nfs_client->rpc_ops); + BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); + + fattr = nfs_alloc_fattr(); + if (fattr == NULL) + return -ENOMEM; + + /* We must ensure the session is initialised first */ + error = nfs4_init_session(server); + if (error < 0) + goto out; + + /* Probe the root fh to retrieve its FSID and filehandle */ + error = nfs4_get_rootfh(server, mntfh); + if (error < 0) + goto out; + + dprintk("Server FSID: %llx:%llx\n", + (unsigned long long) server->fsid.major, + (unsigned long long) server->fsid.minor); + dprintk("Mount FH: %d\n", mntfh->size); + + nfs4_session_set_rwsize(server); + + error = nfs_probe_fsinfo(server, mntfh, fattr); + if (error < 0) + goto out; + + if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) + server->namelen = NFS4_MAXNAMLEN; + + spin_lock(&nfs_client_lock); + list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); + list_add_tail(&server->master_link, &nfs_volume_list); + spin_unlock(&nfs_client_lock); + + server->mount_time = jiffies; +out: + nfs_free_fattr(fattr); + return error; +} + /* * Create a version 4 volume record */ @@ -1346,7 +1395,6 @@ error: struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, struct nfs_fh *mntfh) { - struct nfs_fattr *fattr; struct nfs_server *server; int error; @@ -1356,55 +1404,19 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, if (!server) return ERR_PTR(-ENOMEM); - error = -ENOMEM; - fattr = nfs_alloc_fattr(); - if (fattr == NULL) - goto error; - /* set up the general RPC client */ error = nfs4_init_server(server, data); if (error < 0) goto error; - BUG_ON(!server->nfs_client); - BUG_ON(!server->nfs_client->rpc_ops); - BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); - - error = nfs4_init_session(server); - if (error < 0) - goto error; - - /* Probe the root fh to retrieve its FSID */ - error = nfs4_get_rootfh(server, mntfh); + error = nfs4_server_common_setup(server, mntfh); if (error < 0) goto error; - dprintk("Server FSID: %llx:%llx\n", - (unsigned long long) server->fsid.major, - (unsigned long long) server->fsid.minor); - dprintk("Mount FH: %d\n", mntfh->size); - - nfs4_session_set_rwsize(server); - - error = nfs_probe_fsinfo(server, mntfh, fattr); - if (error < 0) - goto error; - - if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) - server->namelen = NFS4_MAXNAMLEN; - - spin_lock(&nfs_client_lock); - list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); - list_add_tail(&server->master_link, &nfs_volume_list); - spin_unlock(&nfs_client_lock); - - server->mount_time = jiffies; dprintk("<-- nfs4_create_server() = %p\n", server); - nfs_free_fattr(fattr); return server; error: - nfs_free_fattr(fattr); nfs_free_server(server); dprintk("<-- nfs4_create_server() = error %d\n", error); return ERR_PTR(error); @@ -1418,7 +1430,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, { struct nfs_client *parent_client; struct nfs_server *server, *parent_server; - struct nfs_fattr *fattr; int error; dprintk("--> nfs4_create_referral_server()\n"); @@ -1427,11 +1438,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, if (!server) return ERR_PTR(-ENOMEM); - error = -ENOMEM; - fattr = nfs_alloc_fattr(); - if (fattr == NULL) - goto error; - parent_server = NFS_SB(data->sb); parent_client = parent_server->nfs_client; @@ -1456,40 +1462,14 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, if (error < 0) goto error; - BUG_ON(!server->nfs_client); - BUG_ON(!server->nfs_client->rpc_ops); - BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); - - /* Probe the root fh to retrieve its FSID and filehandle */ - error = nfs4_get_rootfh(server, mntfh); - if (error < 0) - goto error; - - /* probe the filesystem info for this server filesystem */ - error = nfs_probe_fsinfo(server, mntfh, fattr); + error = nfs4_server_common_setup(server, mntfh); if (error < 0) goto error; - if (server->namelen == 0 || server->namelen > NFS4_MAXNAMLEN) - server->namelen = NFS4_MAXNAMLEN; - - dprintk("Referral FSID: %llx:%llx\n", - (unsigned long long) server->fsid.major, - (unsigned long long) server->fsid.minor); - - spin_lock(&nfs_client_lock); - list_add_tail(&server->client_link, &server->nfs_client->cl_superblocks); - list_add_tail(&server->master_link, &nfs_volume_list); - spin_unlock(&nfs_client_lock); - - server->mount_time = jiffies; - - nfs_free_fattr(fattr); dprintk("<-- nfs_create_referral_server() = %p\n", server); return server; error: - nfs_free_fattr(fattr); nfs_free_server(server); dprintk("<-- nfs4_create_referral_server() = error %d\n", error); return ERR_PTR(error); diff --git a/fs/nfs/getroot.c b/fs/nfs/getroot.c index 7428f7d..a70e446 100644 --- a/fs/nfs/getroot.c +++ b/fs/nfs/getroot.c @@ -146,7 +146,7 @@ int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh) goto out; } - if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_MODE) + if (!(fsinfo.fattr->valid & NFS_ATTR_FATTR_TYPE) || !S_ISDIR(fsinfo.fattr->mode)) { printk(KERN_ERR "nfs4_get_rootfh:" " getroot encountered non-directory\n"); diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6bdef28..65c8dae 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -862,8 +862,8 @@ static void encode_attrs(struct xdr_stream *xdr, const struct iattr *iap, const bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; *p++ = cpu_to_be32(NFS4_SET_TO_CLIENT_TIME); *p++ = cpu_to_be32(0); - *p++ = cpu_to_be32(iap->ia_mtime.tv_sec); - *p++ = cpu_to_be32(iap->ia_mtime.tv_nsec); + *p++ = cpu_to_be32(iap->ia_atime.tv_sec); + *p++ = cpu_to_be32(iap->ia_atime.tv_nsec); } else if (iap->ia_valid & ATTR_ATIME) { bmval1 |= FATTR4_WORD1_TIME_ACCESS_SET; diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 04214fc..f9df16d 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -570,6 +570,22 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, nfs_show_mountd_netid(m, nfss, showdefaults); } +#ifdef CONFIG_NFS_V4 +static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, + int showdefaults) +{ + struct nfs_client *clp = nfss->nfs_client; + + seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); + seq_printf(m, ",minorversion=%u", clp->cl_minorversion); +} +#else +static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, + int showdefaults) +{ +} +#endif + /* * Describe the mount options in force on this server representation */ @@ -631,11 +647,9 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, if (version != 4) nfs_show_mountd_options(m, nfss, showdefaults); + else + nfs_show_nfsv4_options(m, nfss, showdefaults); -#ifdef CONFIG_NFS_V4 - if (clp->rpc_ops->version == 4) - seq_printf(m, ",clientaddr=%s", clp->cl_ipaddr); -#endif if (nfss->options & NFS_OPTION_FSCACHE) seq_printf(m, ",fsc"); } diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c index 4065002..d8b6e42 100644 --- a/fs/ocfs2/reservations.c +++ b/fs/ocfs2/reservations.c @@ -26,7 +26,6 @@ #include <linux/fs.h> #include <linux/types.h> -#include <linux/slab.h> #include <linux/highmem.h> #include <linux/bitops.h> #include <linux/list.h> diff --git a/fs/proc/proc_devtree.c b/fs/proc/proc_devtree.c index ce94801..d9396a4 100644 --- a/fs/proc/proc_devtree.c +++ b/fs/proc/proc_devtree.c @@ -209,6 +209,9 @@ void proc_device_tree_add_node(struct device_node *np, for (pp = np->properties; pp != NULL; pp = pp->next) { p = pp->name; + if (strchr(p, '/')) + continue; + if (duplicate_name(de, p)) p = fixup_name(np, de, p); diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index 5958d78..17714be 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -212,7 +212,7 @@ char const *acpi_gbl_exception_names_env[] = { "AE_NO_GLOBAL_LOCK", "AE_ABORT_METHOD", "AE_SAME_HANDLER", - "AE_WAKE_ONLY_GPE", + "AE_NO_HANDLER", "AE_OWNER_ID_LIMIT" }; diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 0e4ab1f..1371cc9 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -69,6 +69,7 @@ extern acpi_name acpi_gbl_trace_method_name; extern u32 acpi_gbl_trace_flags; extern u8 acpi_gbl_enable_aml_debug_object; extern u8 acpi_gbl_copy_dsdt_locally; +extern u8 acpi_gbl_truncate_io_addresses; extern u32 acpi_current_gpe_count; extern struct acpi_table_fadt acpi_gbl_FADT; diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index bade172..d55f4a7 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -663,10 +663,11 @@ typedef u32 acpi_event_status; #define ACPI_GPE_MAX 0xFF #define ACPI_NUM_GPE 256 -/* Actions for acpi_set_gpe */ +/* Actions for acpi_set_gpe and acpi_hw_low_set_gpe */ #define ACPI_GPE_ENABLE 0 #define ACPI_GPE_DISABLE 1 +#define ACPI_GPE_COND_ENABLE 2 /* gpe_types for acpi_enable_gpe and acpi_disable_gpe */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 0c62160..e3d00fd 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -525,13 +525,21 @@ static inline struct cgroup_subsys_state *cgroup_subsys_state( return cgrp->subsys[subsys_id]; } -static inline struct cgroup_subsys_state *task_subsys_state( - struct task_struct *task, int subsys_id) +/* + * function to get the cgroup_subsys_state which allows for extra + * rcu_dereference_check() conditions, such as locks used during the + * cgroup_subsys::attach() methods. + */ +#define task_subsys_state_check(task, subsys_id, __c) \ + rcu_dereference_check(task->cgroups->subsys[subsys_id], \ + rcu_read_lock_held() || \ + lockdep_is_held(&task->alloc_lock) || \ + cgroup_lock_is_held() || (__c)) + +static inline struct cgroup_subsys_state * +task_subsys_state(struct task_struct *task, int subsys_id) { - return rcu_dereference_check(task->cgroups->subsys[subsys_id], - rcu_read_lock_held() || - lockdep_is_held(&task->alloc_lock) || - cgroup_lock_is_held()); + return task_subsys_state_check(task, subsys_id, false); } static inline struct cgroup* task_cgroup(struct task_struct *task, diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 5e781d8..bc7d6bb 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -256,22 +256,22 @@ static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } #endif /* CONFIG_HIBERNATION */ -#ifdef CONFIG_HIBERNATION_NVS -extern int hibernate_nvs_register(unsigned long start, unsigned long size); -extern int hibernate_nvs_alloc(void); -extern void hibernate_nvs_free(void); -extern void hibernate_nvs_save(void); -extern void hibernate_nvs_restore(void); -#else /* CONFIG_HIBERNATION_NVS */ -static inline int hibernate_nvs_register(unsigned long a, unsigned long b) +#ifdef CONFIG_SUSPEND_NVS +extern int suspend_nvs_register(unsigned long start, unsigned long size); +extern int suspend_nvs_alloc(void); +extern void suspend_nvs_free(void); +extern void suspend_nvs_save(void); +extern void suspend_nvs_restore(void); +#else /* CONFIG_SUSPEND_NVS */ +static inline int suspend_nvs_register(unsigned long a, unsigned long b) { return 0; } -static inline int hibernate_nvs_alloc(void) { return 0; } -static inline void hibernate_nvs_free(void) {} -static inline void hibernate_nvs_save(void) {} -static inline void hibernate_nvs_restore(void) {} -#endif /* CONFIG_HIBERNATION_NVS */ +static inline int suspend_nvs_alloc(void) { return 0; } +static inline void suspend_nvs_free(void) {} +static inline void suspend_nvs_save(void) {} +static inline void suspend_nvs_restore(void) {} +#endif /* CONFIG_SUSPEND_NVS */ #ifdef CONFIG_PM_SLEEP void save_processor_state(void); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 9a59d1f..103d1b6 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -14,6 +14,7 @@ * See the file COPYING for more details. */ +#include <linux/errno.h> #include <linux/types.h> #include <linux/rcupdate.h> diff --git a/include/net/snmp.h b/include/net/snmp.h index 92456f1..899003d 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -134,7 +134,7 @@ struct linux_xfrm_mib { #define SNMP_ADD_STATS_USER(mib, field, addend) \ this_cpu_add(mib[1]->mibs[field], addend) #define SNMP_ADD_STATS(mib, field, addend) \ - this_cpu_add(mib[0]->mibs[field], addend) + this_cpu_add(mib[!in_softirq()]->mibs[field], addend) /* * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" * to make @ptr a non-percpu pointer. diff --git a/init/main.c b/init/main.c index e2a2bf3..e407a05 100644 --- a/init/main.c +++ b/init/main.c @@ -123,7 +123,9 @@ static char *ramdisk_execute_command; #ifdef CONFIG_SMP /* Setup configured maximum number of CPUs to activate */ -unsigned int __initdata setup_max_cpus = NR_CPUS; +unsigned int setup_max_cpus = NR_CPUS; +EXPORT_SYMBOL(setup_max_cpus); + /* * Setup routine for controlling SMP activation diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 3164ba7..e149748 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c @@ -456,6 +456,9 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq, /* note that IRQF_TRIGGER_MASK == IRQ_TYPE_SENSE_MASK */ desc->status &= ~(IRQ_LEVEL | IRQ_TYPE_SENSE_MASK); desc->status |= flags; + + if (chip != desc->chip) + irq_chip_set_defaults(desc->chip); } return ret; diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 5c36ea9..ca6066a 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -99,9 +99,13 @@ config PM_SLEEP_ADVANCED_DEBUG depends on PM_ADVANCED_DEBUG default n +config SUSPEND_NVS + bool + config SUSPEND bool "Suspend to RAM and standby" depends on PM && ARCH_SUSPEND_POSSIBLE + select SUSPEND_NVS if HAS_IOMEM default y ---help--- Allow the system to enter sleep states in which main memory is @@ -130,13 +134,10 @@ config SUSPEND_FREEZER Turning OFF this setting is NOT recommended! If in doubt, say Y. -config HIBERNATION_NVS - bool - config HIBERNATION bool "Hibernation (aka 'suspend to disk')" depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE - select HIBERNATION_NVS if HAS_IOMEM + select SUSPEND_NVS if HAS_IOMEM ---help--- Enable the suspend to disk (STD) functionality, which is usually called "hibernation" in user interfaces. STD checkpoints the diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 524e058..f9063c6 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -10,6 +10,6 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ block_io.o -obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o +obj-$(CONFIG_SUSPEND_NVS) += nvs.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/hibernate_nvs.c b/kernel/power/nvs.c index fdcad9e..1836db6 100644 --- a/kernel/power/hibernate_nvs.c +++ b/kernel/power/nvs.c @@ -15,7 +15,7 @@ /* * Platforms, like ACPI, may want us to save some memory used by them during - * hibernation and to restore the contents of this memory during the subsequent + * suspend and to restore the contents of this memory during the subsequent * resume. The code below implements a mechanism allowing us to do that. */ @@ -30,7 +30,7 @@ struct nvs_page { static LIST_HEAD(nvs_list); /** - * hibernate_nvs_register - register platform NVS memory region to save + * suspend_nvs_register - register platform NVS memory region to save * @start - physical address of the region * @size - size of the region * @@ -38,7 +38,7 @@ static LIST_HEAD(nvs_list); * things so that the data from page-aligned addresses in this region will * be copied into separate RAM pages. */ -int hibernate_nvs_register(unsigned long start, unsigned long size) +int suspend_nvs_register(unsigned long start, unsigned long size) { struct nvs_page *entry, *next; @@ -68,9 +68,9 @@ int hibernate_nvs_register(unsigned long start, unsigned long size) } /** - * hibernate_nvs_free - free data pages allocated for saving NVS regions + * suspend_nvs_free - free data pages allocated for saving NVS regions */ -void hibernate_nvs_free(void) +void suspend_nvs_free(void) { struct nvs_page *entry; @@ -86,16 +86,16 @@ void hibernate_nvs_free(void) } /** - * hibernate_nvs_alloc - allocate memory necessary for saving NVS regions + * suspend_nvs_alloc - allocate memory necessary for saving NVS regions */ -int hibernate_nvs_alloc(void) +int suspend_nvs_alloc(void) { struct nvs_page *entry; list_for_each_entry(entry, &nvs_list, node) { entry->data = (void *)__get_free_page(GFP_KERNEL); if (!entry->data) { - hibernate_nvs_free(); + suspend_nvs_free(); return -ENOMEM; } } @@ -103,9 +103,9 @@ int hibernate_nvs_alloc(void) } /** - * hibernate_nvs_save - save NVS memory regions + * suspend_nvs_save - save NVS memory regions */ -void hibernate_nvs_save(void) +void suspend_nvs_save(void) { struct nvs_page *entry; @@ -119,12 +119,12 @@ void hibernate_nvs_save(void) } /** - * hibernate_nvs_restore - restore NVS memory regions + * suspend_nvs_restore - restore NVS memory regions * * This function is going to be called with interrupts disabled, so it * cannot iounmap the virtual addresses used to access the NVS region. */ -void hibernate_nvs_restore(void) +void suspend_nvs_restore(void) { struct nvs_page *entry; diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 56e7dbb..f37cb7d 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -16,6 +16,12 @@ #include <linux/cpu.h> #include <linux/syscalls.h> #include <linux/gfp.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/list.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/suspend.h> #include "power.h" diff --git a/kernel/sched.c b/kernel/sched.c index 3c5d34a..8c473ad 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -306,52 +306,6 @@ static int init_task_group_load = INIT_TASK_GROUP_LOAD; */ struct task_group init_task_group; -/* return group to which a task belongs */ -static inline struct task_group *task_group(struct task_struct *p) -{ - struct task_group *tg; - -#ifdef CONFIG_CGROUP_SCHED - tg = container_of(task_subsys_state(p, cpu_cgroup_subsys_id), - struct task_group, css); -#else - tg = &init_task_group; -#endif - return tg; -} - -/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ -static inline void set_task_rq(struct task_struct *p, unsigned int cpu) -{ - /* - * Strictly speaking this rcu_read_lock() is not needed since the - * task_group is tied to the cgroup, which in turn can never go away - * as long as there are tasks attached to it. - * - * However since task_group() uses task_subsys_state() which is an - * rcu_dereference() user, this quiets CONFIG_PROVE_RCU. - */ - rcu_read_lock(); -#ifdef CONFIG_FAIR_GROUP_SCHED - p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; - p->se.parent = task_group(p)->se[cpu]; -#endif - -#ifdef CONFIG_RT_GROUP_SCHED - p->rt.rt_rq = task_group(p)->rt_rq[cpu]; - p->rt.parent = task_group(p)->rt_se[cpu]; -#endif - rcu_read_unlock(); -} - -#else - -static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { } -static inline struct task_group *task_group(struct task_struct *p) -{ - return NULL; -} - #endif /* CONFIG_CGROUP_SCHED */ /* CFS-related fields in a runqueue */ @@ -644,6 +598,49 @@ static inline int cpu_of(struct rq *rq) #define cpu_curr(cpu) (cpu_rq(cpu)->curr) #define raw_rq() (&__raw_get_cpu_var(runqueues)) +#ifdef CONFIG_CGROUP_SCHED + +/* + * Return the group to which this tasks belongs. + * + * We use task_subsys_state_check() and extend the RCU verification + * with lockdep_is_held(&task_rq(p)->lock) because cpu_cgroup_attach() + * holds that lock for each task it moves into the cgroup. Therefore + * by holding that lock, we pin the task to the current cgroup. + */ +static inline struct task_group *task_group(struct task_struct *p) +{ + struct cgroup_subsys_state *css; + + css = task_subsys_state_check(p, cpu_cgroup_subsys_id, + lockdep_is_held(&task_rq(p)->lock)); + return container_of(css, struct task_group, css); +} + +/* Change a task's cfs_rq and parent entity if it moves across CPUs/groups */ +static inline void set_task_rq(struct task_struct *p, unsigned int cpu) +{ +#ifdef CONFIG_FAIR_GROUP_SCHED + p->se.cfs_rq = task_group(p)->cfs_rq[cpu]; + p->se.parent = task_group(p)->se[cpu]; +#endif + +#ifdef CONFIG_RT_GROUP_SCHED + p->rt.rt_rq = task_group(p)->rt_rq[cpu]; + p->rt.parent = task_group(p)->rt_se[cpu]; +#endif +} + +#else /* CONFIG_CGROUP_SCHED */ + +static inline void set_task_rq(struct task_struct *p, unsigned int cpu) { } +static inline struct task_group *task_group(struct task_struct *p) +{ + return NULL; +} + +#endif /* CONFIG_CGROUP_SCHED */ + inline void update_rq_clock(struct rq *rq) { if (!rq->skip_clock_update) @@ -1257,6 +1254,12 @@ static void sched_avg_update(struct rq *rq) s64 period = sched_avg_period(); while ((s64)(rq->clock - rq->age_stamp) > period) { + /* + * Inline assembly required to prevent the compiler + * optimising this loop into a divmod call. + * See __iter_div_u64_rem() for another example of this. + */ + asm("" : "+rm" (rq->age_stamp)); rq->age_stamp += period; rq->rt_avg /= 2; } @@ -1660,9 +1663,6 @@ static void update_shares(struct sched_domain *sd) static void update_h_load(long cpu) { - if (root_task_group_empty()) - return; - walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); } @@ -2494,7 +2494,16 @@ void sched_fork(struct task_struct *p, int clone_flags) if (p->sched_class->task_fork) p->sched_class->task_fork(p); + /* + * The child is not yet in the pid-hash so no cgroup attach races, + * and the cgroup is pinned to this child due to cgroup_fork() + * is ran before sched_fork(). + * + * Silence PROVE_RCU. + */ + rcu_read_lock(); set_task_cpu(p, cpu); + rcu_read_unlock(); #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) if (likely(sched_info_on())) @@ -4465,16 +4474,6 @@ recheck: } if (user) { -#ifdef CONFIG_RT_GROUP_SCHED - /* - * Do not allow realtime tasks into groups that have no runtime - * assigned. - */ - if (rt_bandwidth_enabled() && rt_policy(policy) && - task_group(p)->rt_bandwidth.rt_runtime == 0) - return -EPERM; -#endif - retval = security_task_setscheduler(p, policy, param); if (retval) return retval; @@ -4490,6 +4489,22 @@ recheck: * runqueue lock must be held. */ rq = __task_rq_lock(p); + +#ifdef CONFIG_RT_GROUP_SCHED + if (user) { + /* + * Do not allow realtime tasks into groups that have no runtime + * assigned. + */ + if (rt_bandwidth_enabled() && rt_policy(policy) && + task_group(p)->rt_bandwidth.rt_runtime == 0) { + __task_rq_unlock(rq); + raw_spin_unlock_irqrestore(&p->pi_lock, flags); + return -EPERM; + } + } +#endif + /* recheck policy now with rq lock held */ if (unlikely(oldpolicy != -1 && oldpolicy != p->policy)) { policy = oldpolicy = -1; diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index eed35ed..a878b53 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c @@ -1240,6 +1240,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync) * effect of the currently running task from the load * of the current CPU: */ + rcu_read_lock(); if (sync) { tg = task_group(current); weight = current->se.load.weight; @@ -1275,6 +1276,7 @@ static int wake_affine(struct sched_domain *sd, struct task_struct *p, int sync) balanced = this_eff_load <= prev_eff_load; } else balanced = true; + rcu_read_unlock(); /* * If the currently running task will sleep within diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 1d7b9bc..783fbad 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -315,9 +315,6 @@ void tick_nohz_stop_sched_tick(int inidle) goto end; } - if (nohz_ratelimit(cpu)) - goto end; - ts->idle_calls++; /* Read jiffies and the time when jiffies were updated last */ do { @@ -328,7 +325,7 @@ void tick_nohz_stop_sched_tick(int inidle) } while (read_seqretry(&xtime_lock, seq)); if (rcu_needs_cpu(cpu) || printk_needs_cpu(cpu) || - arch_needs_cpu(cpu)) { + arch_needs_cpu(cpu) || nohz_ratelimit(cpu)) { next_jiffies = last_jiffies + 1; delta_jiffies = 1; } else { diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index 4799d70..6053982 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c @@ -94,7 +94,9 @@ int perf_trace_init(struct perf_event *p_event) mutex_lock(&event_mutex); list_for_each_entry(tp_event, &ftrace_events, list) { if (tp_event->event.type == event_id && - tp_event->class && tp_event->class->perf_probe && + tp_event->class && + (tp_event->class->perf_probe || + tp_event->class->reg) && try_module_get(tp_event->mod)) { ret = perf_trace_event_init(tp_event, p_event); break; @@ -602,7 +602,7 @@ void *idr_get_next(struct idr *idp, int *nextidp) /* find first ent */ n = idp->layers * IDR_BITS; max = 1 << n; - p = rcu_dereference(idp->top); + p = rcu_dereference_raw(idp->top); if (!p) return NULL; @@ -610,7 +610,7 @@ void *idr_get_next(struct idr *idp, int *nextidp) while (n > 0 && p) { n -= IDR_BITS; *paa++ = p; - p = rcu_dereference(p->ary[(id >> n) & IDR_MASK]); + p = rcu_dereference_raw(p->ary[(id >> n) & IDR_MASK]); } if (p) { diff --git a/mm/percpu.c b/mm/percpu.c index 39f7dfd..6470e77 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -229,8 +229,8 @@ static int __maybe_unused pcpu_page_idx(unsigned int cpu, int page_idx) return pcpu_unit_map[cpu] * pcpu_unit_pages + page_idx; } -static unsigned long __maybe_unused pcpu_chunk_addr(struct pcpu_chunk *chunk, - unsigned int cpu, int page_idx) +static unsigned long pcpu_chunk_addr(struct pcpu_chunk *chunk, + unsigned int cpu, int page_idx) { return (unsigned long)chunk->base_addr + pcpu_unit_offsets[cpu] + (page_idx << PAGE_SHIFT); @@ -978,7 +978,32 @@ bool is_kernel_percpu_address(unsigned long addr) */ phys_addr_t per_cpu_ptr_to_phys(void *addr) { - if (pcpu_addr_in_first_chunk(addr)) { + void __percpu *base = __addr_to_pcpu_ptr(pcpu_base_addr); + bool in_first_chunk = false; + unsigned long first_start, first_end; + unsigned int cpu; + + /* + * The following test on first_start/end isn't strictly + * necessary but will speed up lookups of addresses which + * aren't in the first chunk. + */ + first_start = pcpu_chunk_addr(pcpu_first_chunk, pcpu_first_unit_cpu, 0); + first_end = pcpu_chunk_addr(pcpu_first_chunk, pcpu_last_unit_cpu, + pcpu_unit_pages); + if ((unsigned long)addr >= first_start && + (unsigned long)addr < first_end) { + for_each_possible_cpu(cpu) { + void *start = per_cpu_ptr(base, cpu); + + if (addr >= start && addr < start + pcpu_unit_size) { + in_first_chunk = true; + break; + } + } + } + + if (in_first_chunk) { if ((unsigned long)addr < VMALLOC_START || (unsigned long)addr >= VMALLOC_END) return __pa(addr); @@ -1086,7 +1111,7 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( static int group_map[NR_CPUS] __initdata; static int group_cnt[NR_CPUS] __initdata; const size_t static_size = __per_cpu_end - __per_cpu_start; - int group_cnt_max = 0, nr_groups = 1, nr_units = 0; + int nr_groups = 1, nr_units = 0; size_t size_sum, min_unit_size, alloc_size; int upa, max_upa, uninitialized_var(best_upa); /* units_per_alloc */ int last_allocs, group, unit; @@ -1096,7 +1121,7 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( /* this function may be called multiple times */ memset(group_map, 0, sizeof(group_map)); - memset(group_cnt, 0, sizeof(group_map)); + memset(group_cnt, 0, sizeof(group_cnt)); /* * Determine min_unit_size, alloc_size and max_upa such that @@ -1130,7 +1155,6 @@ struct pcpu_alloc_info * __init pcpu_build_alloc_info( } group_map[cpu] = group; group_cnt[group]++; - group_cnt_max = max(group_cnt_max, group_cnt[group]); } /* diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 0faad5c..8c100c9 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c @@ -104,6 +104,8 @@ static void bnep_net_set_mc_list(struct net_device *dev) break; memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); memcpy(__skb_put(skb, ETH_ALEN), ha->addr, ETH_ALEN); + + i++; } r->len = htons(skb->len - len); } diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 2663743..b01dde3 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c @@ -128,7 +128,7 @@ void br_fdb_cleanup(unsigned long _data) { struct net_bridge *br = (struct net_bridge *)_data; unsigned long delay = hold_time(br); - unsigned long next_timer = jiffies + br->forward_delay; + unsigned long next_timer = jiffies + br->ageing_time; int i; spin_lock_bh(&br->hash_lock); @@ -149,9 +149,7 @@ void br_fdb_cleanup(unsigned long _data) } spin_unlock_bh(&br->hash_lock); - /* Add HZ/4 to ensure we round the jiffies upwards to be after the next - * timer, otherwise we might round down and will have no-op run. */ - mod_timer(&br->gc_timer, round_jiffies(next_timer + HZ/4)); + mod_timer(&br->gc_timer, round_jiffies_up(next_timer)); } /* Completely flush all dynamic entries in forwarding database.*/ diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index a98ef13..a4e72a8 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -140,10 +140,10 @@ static int deliver_clone(const struct net_bridge_port *prev, void (*__packet_hook)(const struct net_bridge_port *p, struct sk_buff *skb)) { + struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; + skb = skb_clone(skb, GFP_ATOMIC); if (!skb) { - struct net_device *dev = BR_INPUT_SKB_CB(skb)->brdev; - dev->stats.tx_dropped++; return -ENOMEM; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 9f07e74..34432b4 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -532,6 +532,7 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->ip_summed = old->ip_summed; skb_copy_queue_mapping(new, old); new->priority = old->priority; + new->deliver_no_wcard = old->deliver_no_wcard; #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) new->ipvs_property = old->ipvs_property; #endif @@ -569,7 +570,6 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) C(len); C(data_len); C(mac_len); - C(rxhash); n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; n->cloned = 1; n->nohdr = 0; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 9a4a6c9..041d41d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -873,8 +873,10 @@ int ip_append_data(struct sock *sk, !exthdrlen) csummode = CHECKSUM_PARTIAL; + skb = skb_peek_tail(&sk->sk_write_queue); + inet->cork.length += length; - if (((length> mtu) || !skb_queue_empty(&sk->sk_write_queue)) && + if (((length > mtu) || (skb && skb_is_gso(skb))) && (sk->sk_protocol == IPPROTO_UDP) && (rt->u.dst.dev->features & NETIF_F_UFO)) { err = ip_ufo_append_data(sk, getfrag, from, length, hh_len, @@ -892,7 +894,7 @@ int ip_append_data(struct sock *sk, * adding appropriate IP header. */ - if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) + if (!skb) goto alloc_new_skb; while (length > 0) { @@ -1121,7 +1123,8 @@ ssize_t ip_append_page(struct sock *sk, struct page *page, return -EINVAL; inet->cork.length += size; - if ((sk->sk_protocol == IPPROTO_UDP) && + if ((size + skb->len > mtu) && + (sk->sk_protocol == IPPROTO_UDP) && (rt->u.dst.dev->features & NETIF_F_UFO)) { skb_shinfo(skb)->gso_size = mtu - fragheaderlen; skb_shinfo(skb)->gso_type = SKB_GSO_UDP; diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 0abdc24..2efef52 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -586,6 +586,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, src_addr = solicited_addr; if (ifp->flags & IFA_F_OPTIMISTIC) override = 0; + inc_opt |= ifp->idev->cnf.force_tllao; in6_ifa_put(ifp); } else { if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr, @@ -599,7 +600,6 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, icmp6h.icmp6_solicited = solicited; icmp6h.icmp6_override = override; - inc_opt |= ifp->idev->cnf.force_tllao; __ndisc_send(dev, neigh, daddr, src_addr, &icmp6h, solicited_addr, inc_opt ? ND_OPT_TARGET_LL_ADDR : 0); diff --git a/net/mac80211/work.c b/net/mac80211/work.c index be3d4a6..b025dc7 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c @@ -715,7 +715,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, struct ieee80211_rx_status *rx_status; struct ieee80211_mgmt *mgmt; struct ieee80211_work *wk; - enum work_action rma; + enum work_action rma = WORK_ACT_NONE; u16 fc; rx_status = (struct ieee80211_rx_status *) skb->cb; diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c index d8f7e8e..ff04e9e 100644 --- a/net/netfilter/ipvs/ip_vs_conn.c +++ b/net/netfilter/ipvs/ip_vs_conn.c @@ -162,6 +162,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp) hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); ct_write_lock(hash); + spin_lock(&cp->lock); if (!(cp->flags & IP_VS_CONN_F_HASHED)) { list_add(&cp->c_list, &ip_vs_conn_tab[hash]); @@ -174,6 +175,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp) ret = 0; } + spin_unlock(&cp->lock); ct_write_unlock(hash); return ret; @@ -193,6 +195,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport); ct_write_lock(hash); + spin_lock(&cp->lock); if (cp->flags & IP_VS_CONN_F_HASHED) { list_del(&cp->c_list); @@ -202,6 +205,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp) } else ret = 0; + spin_unlock(&cp->lock); ct_write_unlock(hash); return ret; diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c index 3415b6c..807643b 100644 --- a/net/sched/sch_teql.c +++ b/net/sched/sch_teql.c @@ -449,6 +449,7 @@ static __init void teql_master_setup(struct net_device *dev) dev->tx_queue_len = 100; dev->flags = IFF_NOARP; dev->hard_header_len = LL_MAX_HEADER; + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; } static LIST_HEAD(master_dev_list); diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 2a96751..7ca65c7 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c @@ -210,7 +210,8 @@ struct sock_xprt { * State of TCP reply receive */ __be32 tcp_fraghdr, - tcp_xid; + tcp_xid, + tcp_calldir; u32 tcp_offset, tcp_reclen; @@ -927,7 +928,7 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport, { size_t len, used; u32 offset; - __be32 calldir; + char *p; /* * We want transport->tcp_offset to be 8 at the end of this routine @@ -936,26 +937,33 @@ static inline void xs_tcp_read_calldir(struct sock_xprt *transport, * transport->tcp_offset is 4 (after having already read the xid). */ offset = transport->tcp_offset - sizeof(transport->tcp_xid); - len = sizeof(calldir) - offset; + len = sizeof(transport->tcp_calldir) - offset; dprintk("RPC: reading CALL/REPLY flag (%Zu bytes)\n", len); - used = xdr_skb_read_bits(desc, &calldir, len); + p = ((char *) &transport->tcp_calldir) + offset; + used = xdr_skb_read_bits(desc, p, len); transport->tcp_offset += used; if (used != len) return; transport->tcp_flags &= ~TCP_RCV_READ_CALLDIR; - transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; - transport->tcp_flags |= TCP_RCV_COPY_DATA; /* * We don't yet have the XDR buffer, so we will write the calldir * out after we get the buffer from the 'struct rpc_rqst' */ - if (ntohl(calldir) == RPC_REPLY) + switch (ntohl(transport->tcp_calldir)) { + case RPC_REPLY: + transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; + transport->tcp_flags |= TCP_RCV_COPY_DATA; transport->tcp_flags |= TCP_RPC_REPLY; - else + break; + case RPC_CALL: + transport->tcp_flags |= TCP_RCV_COPY_CALLDIR; + transport->tcp_flags |= TCP_RCV_COPY_DATA; transport->tcp_flags &= ~TCP_RPC_REPLY; - dprintk("RPC: reading %s CALL/REPLY flag %08x\n", - (transport->tcp_flags & TCP_RPC_REPLY) ? - "reply for" : "request with", calldir); + break; + default: + dprintk("RPC: invalid request message type\n"); + xprt_force_disconnect(&transport->xprt); + } xs_tcp_check_fraghdr(transport); } @@ -975,12 +983,10 @@ static inline void xs_tcp_read_common(struct rpc_xprt *xprt, /* * Save the RPC direction in the XDR buffer */ - __be32 calldir = transport->tcp_flags & TCP_RPC_REPLY ? - htonl(RPC_REPLY) : 0; - memcpy(rcvbuf->head[0].iov_base + transport->tcp_copied, - &calldir, sizeof(calldir)); - transport->tcp_copied += sizeof(calldir); + &transport->tcp_calldir, + sizeof(transport->tcp_calldir)); + transport->tcp_copied += sizeof(transport->tcp_calldir); transport->tcp_flags &= ~TCP_RCV_COPY_CALLDIR; } diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 4bf27d9..af1c173 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -2300,7 +2300,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first, return 0; if (xdst->xfrm_genid != dst->xfrm->genid) return 0; - if (xdst->policy_genid != atomic_read(&xdst->pols[0]->genid)) + if (xdst->num_pols > 0 && + xdst->policy_genid != atomic_read(&xdst->pols[0]->genid)) return 0; if (strict && fl && diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3318692..f877900 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1342,7 +1342,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = sechdr->sh_info; return (void *)elf->hdr + sechdrs[section].sh_offset + - (r->r_offset - sechdrs[section].sh_addr); + r->r_offset - sechdrs[section].sh_addr; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 13074b4..6261745 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -33,7 +33,7 @@ static int key_get_type_from_user(char *type, ret = strncpy_from_user(type, _type, len); if (ret < 0) - return -EFAULT; + return ret; if (ret == 0 || ret >= len) return -EINVAL; @@ -1080,7 +1080,7 @@ set: return old_setting; error: abort_creds(new); - return -EINVAL; + return ret; } /* end keyctl_set_reqkey_keyring() */ diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index e89991e..3b44134 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c @@ -941,11 +941,11 @@ static void outstream_host_buffer_free(struct hpi_adapter_obj *pao, } -static long outstream_get_space_available(struct hpi_hostbuffer_status +static u32 outstream_get_space_available(struct hpi_hostbuffer_status *status) { - return status->size_in_bytes - ((long)(status->host_index) - - (long)(status->dSP_index)); + return status->size_in_bytes - (status->host_index - + status->dSP_index); } static void outstream_write(struct hpi_adapter_obj *pao, @@ -954,7 +954,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface = phw->p_interface_buffer; struct hpi_hostbuffer_status *status; - long space_available; + u32 space_available; if (!phw->outstream_host_buffer_size[phm->obj_index]) { /* there is no BBM buffer, write via message */ @@ -1007,7 +1007,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, } space_available = outstream_get_space_available(status); - if (space_available < (long)phm->u.d.u.data.data_size) { + if (space_available < phm->u.d.u.data.data_size) { phr->error = HPI_ERROR_INVALID_DATASIZE; return; } @@ -1018,7 +1018,7 @@ static void outstream_write(struct hpi_adapter_obj *pao, && hpios_locked_mem_valid(&phw->outstream_host_buffers[phm-> obj_index])) { u8 *p_bbm_data; - long l_first_write; + u32 l_first_write; u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; if (hpios_locked_mem_get_virt_addr(&phw-> @@ -1248,9 +1248,9 @@ static void instream_start(struct hpi_adapter_obj *pao, hw_message(pao, phm, phr); } -static long instream_get_bytes_available(struct hpi_hostbuffer_status *status) +static u32 instream_get_bytes_available(struct hpi_hostbuffer_status *status) { - return (long)(status->dSP_index) - (long)(status->host_index); + return status->dSP_index - status->host_index; } static void instream_read(struct hpi_adapter_obj *pao, @@ -1259,9 +1259,9 @@ static void instream_read(struct hpi_adapter_obj *pao, struct hpi_hw_obj *phw = pao->priv; struct bus_master_interface *interface = phw->p_interface_buffer; struct hpi_hostbuffer_status *status; - long data_available; + u32 data_available; u8 *p_bbm_data; - long l_first_read; + u32 l_first_read; u8 *p_app_data = (u8 *)phm->u.d.u.data.pb_data; if (!phw->instream_host_buffer_size[phm->obj_index]) { @@ -1272,7 +1272,7 @@ static void instream_read(struct hpi_adapter_obj *pao, status = &interface->instream_host_buffer_status[phm->obj_index]; data_available = instream_get_bytes_available(status); - if (data_available < (long)phm->u.d.u.data.data_size) { + if (data_available < phm->u.d.u.data.data_size) { phr->error = HPI_ERROR_INVALID_DATASIZE; return; } diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fc767b6..f1ce7d7 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2619,16 +2619,18 @@ static int alc_build_controls(struct hda_codec *codec) } /* assign Capture Source enums to NID */ - kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); - if (!kctl) - kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); - for (i = 0; kctl && i < kctl->count; i++) { - hda_nid_t *nids = spec->capsrc_nids; - if (!nids) - nids = spec->adc_nids; - err = snd_hda_add_nid(codec, kctl, i, nids[i]); - if (err < 0) - return err; + if (spec->capsrc_nids || spec->adc_nids) { + kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); + if (!kctl) + kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); + for (i = 0; kctl && i < kctl->count; i++) { + hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nid(codec, kctl, i, nids[i]); + if (err < 0) + return err; + } } if (spec->cap_mixer) { const char *kname = kctl ? kctl->id.name : NULL; @@ -6948,7 +6950,7 @@ static struct hda_input_mux mb5_capture_source = { .num_items = 3, .items = { { "Mic", 0x1 }, - { "Line", 0x2 }, + { "Line", 0x7 }, { "CD", 0x4 }, }, }; @@ -7469,8 +7471,8 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT), + HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Line Boost", 0x15, 0x00, HDA_INPUT), @@ -7853,10 +7855,9 @@ static struct hda_verb alc885_mb5_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)}, { } }; diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 79f0f4a..d395509 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c @@ -612,7 +612,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) NUMDMA_MASK); mcasp_mod_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, ((dev->txnumevt * tx_ser) << 8), NUMEVT_MASK); - mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, FIFO_ENABLE); } if (dev->rxnumevt && stream == SNDRV_PCM_STREAM_CAPTURE) { @@ -623,7 +622,6 @@ static void davinci_hw_common_param(struct davinci_audio_dev *dev, int stream) NUMDMA_MASK); mcasp_mod_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, ((dev->rxnumevt * rx_ser) << 8), NUMEVT_MASK); - mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, FIFO_ENABLE); } } diff --git a/sound/soc/fsl/mpc5200_dma.h b/sound/soc/fsl/mpc5200_dma.h index 22208b3..e1ec6d9 100644 --- a/sound/soc/fsl/mpc5200_dma.h +++ b/sound/soc/fsl/mpc5200_dma.h @@ -73,7 +73,7 @@ struct psc_dma { }; /* Utility for retrieving psc_dma_stream structure from a substream */ -inline struct psc_dma_stream * +static inline struct psc_dma_stream * to_psc_dma_stream(struct snd_pcm_substream *substream, struct psc_dma *psc_dma) { if (substream->pstr->stream == SNDRV_PCM_STREAM_CAPTURE) diff --git a/sound/usb/clock.c b/sound/usb/clock.c index b7aadd6..b585511 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c @@ -103,7 +103,8 @@ static int uac_clock_selector_get_val(struct snd_usb_audio *chip, int selector_i ret = snd_usb_ctl_msg(chip->dev, usb_rcvctrlpipe(chip->dev, 0), UAC2_CS_CUR, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, - UAC2_CX_CLOCK_SELECTOR << 8, selector_id << 8, + UAC2_CX_CLOCK_SELECTOR << 8, + snd_usb_ctrl_intf(chip) | (selector_id << 8), &buf, sizeof(buf), 1000); if (ret < 0) @@ -120,7 +121,8 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_CLOCK_VALID << 8, source_id << 8, + UAC2_CS_CONTROL_CLOCK_VALID << 8, + snd_usb_ctrl_intf(chip) | (source_id << 8), &data, sizeof(data), 1000); if (err < 0) { @@ -269,7 +271,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, data[3] = rate >> 24; if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { snd_printk(KERN_ERR "%d:%d:%d: cannot set freq %d (v2)\n", dev->devnum, iface, fmt->altsetting, rate); @@ -278,7 +281,8 @@ static int set_sample_rate_v2(struct snd_usb_audio *chip, int iface, if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, sizeof(data), 1000)) < 0) { snd_printk(KERN_WARNING "%d:%d:%d: cannot get freq (v2)\n", dev->devnum, iface, fmt->altsetting); diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 9593b91..6f6596c 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c @@ -427,6 +427,7 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no) if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) { kfree(fp->rate_table); kfree(fp); + fp = NULL; continue; } diff --git a/sound/usb/format.c b/sound/usb/format.c index 5367cd1..30364ab 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c @@ -206,6 +206,60 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof } /* + * Helper function to walk the array of sample rate triplets reported by + * the device. The problem is that we need to parse whole array first to + * get to know how many sample rates we have to expect. + * Then fp->rate_table can be allocated and filled. + */ +static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets, + const unsigned char *data) +{ + int i, nr_rates = 0; + + fp->rates = fp->rate_min = fp->rate_max = 0; + + for (i = 0; i < nr_triplets; i++) { + int min = combine_quad(&data[2 + 12 * i]); + int max = combine_quad(&data[6 + 12 * i]); + int res = combine_quad(&data[10 + 12 * i]); + int rate; + + if ((max < 0) || (min < 0) || (res < 0) || (max < min)) + continue; + + /* + * for ranges with res == 1, we announce a continuous sample + * rate range, and this function should return 0 for no further + * parsing. + */ + if (res == 1) { + fp->rate_min = min; + fp->rate_max = max; + fp->rates = SNDRV_PCM_RATE_CONTINUOUS; + return 0; + } + + for (rate = min; rate <= max; rate += res) { + if (fp->rate_table) + fp->rate_table[nr_rates] = rate; + if (!fp->rate_min || rate < fp->rate_min) + fp->rate_min = rate; + if (!fp->rate_max || rate > fp->rate_max) + fp->rate_max = rate; + fp->rates |= snd_pcm_rate_to_rate_bit(rate); + + nr_rates++; + + /* avoid endless loop */ + if (res == 0) + break; + } + } + + return nr_rates; +} + +/* * parse the format descriptor and stores the possible sample rates * on the audioformat table (audio class v2). */ @@ -215,13 +269,20 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, { struct usb_device *dev = chip->dev; unsigned char tmp[2], *data; - int i, nr_rates, data_size, ret = 0; + int nr_triplets, data_size, ret = 0; int clock = snd_usb_clock_find_source(chip, chip->ctrl_intf, fp->clock); + if (clock < 0) { + snd_printk(KERN_ERR "%s(): unable to find clock source (clock %d)\n", + __func__, clock); + goto err; + } + /* get the number of sample rates first by only fetching 2 bytes */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), tmp, sizeof(tmp), 1000); if (ret < 0) { @@ -230,8 +291,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, goto err; } - nr_rates = (tmp[1] << 8) | tmp[0]; - data_size = 2 + 12 * nr_rates; + nr_triplets = (tmp[1] << 8) | tmp[0]; + data_size = 2 + 12 * nr_triplets; data = kzalloc(data_size, GFP_KERNEL); if (!data) { ret = -ENOMEM; @@ -241,7 +302,8 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, /* now get the full information */ ret = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_RANGE, USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, - UAC2_CS_CONTROL_SAM_FREQ << 8, clock << 8, + UAC2_CS_CONTROL_SAM_FREQ << 8, + snd_usb_ctrl_intf(chip) | (clock << 8), data, data_size, 1000); if (ret < 0) { @@ -251,26 +313,28 @@ static int parse_audio_format_rates_v2(struct snd_usb_audio *chip, goto err_free; } - fp->rate_table = kmalloc(sizeof(int) * nr_rates, GFP_KERNEL); + /* Call the triplet parser, and make sure fp->rate_table is NULL. + * We just use the return value to know how many sample rates we + * will have to deal with. */ + kfree(fp->rate_table); + fp->rate_table = NULL; + fp->nr_rates = parse_uac2_sample_rate_range(fp, nr_triplets, data); + + if (fp->nr_rates == 0) { + /* SNDRV_PCM_RATE_CONTINUOUS */ + ret = 0; + goto err_free; + } + + fp->rate_table = kmalloc(sizeof(int) * fp->nr_rates, GFP_KERNEL); if (!fp->rate_table) { ret = -ENOMEM; goto err_free; } - fp->nr_rates = 0; - fp->rate_min = fp->rate_max = 0; - - for (i = 0; i < nr_rates; i++) { - int rate = combine_quad(&data[2 + 12 * i]); - - fp->rate_table[fp->nr_rates] = rate; - if (!fp->rate_min || rate < fp->rate_min) - fp->rate_min = rate; - if (!fp->rate_max || rate > fp->rate_max) - fp->rate_max = rate; - fp->rates |= snd_pcm_rate_to_rate_bit(rate); - fp->nr_rates++; - } + /* Call the triplet parser again, but this time, fp->rate_table is + * allocated, so the rates will be stored */ + parse_uac2_sample_rate_range(fp, nr_triplets, data); err_free: kfree(data); diff --git a/sound/usb/helper.h b/sound/usb/helper.h index a6b0e51..09bd943 100644 --- a/sound/usb/helper.h +++ b/sound/usb/helper.h @@ -28,5 +28,9 @@ unsigned char snd_usb_parse_datainterval(struct snd_usb_audio *chip, #define snd_usb_get_speed(dev) ((dev)->speed) #endif +static inline int snd_usb_ctrl_intf(struct snd_usb_audio *chip) +{ + return get_iface_desc(chip->ctrl_intf)->bInterfaceNumber; +} #endif /* __USBAUDIO_HELPER_H */ diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index a060d00..6939d0f 100644 --- a/sound/usb/mixer.c +++ b/sound/usb/mixer.c @@ -297,20 +297,27 @@ static int get_ctl_value_v1(struct usb_mixer_elem_info *cval, int request, int v static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int validx, int *value_ret) { - unsigned char buf[14]; /* enough space for one range of 4 bytes */ + unsigned char buf[2 + 3*sizeof(__u16)]; /* enough space for one range */ unsigned char *val; - int ret; + int ret, size; __u8 bRequest; - bRequest = (request == UAC_GET_CUR) ? - UAC2_CS_CUR : UAC2_CS_RANGE; + if (request == UAC_GET_CUR) { + bRequest = UAC2_CS_CUR; + size = sizeof(__u16); + } else { + bRequest = UAC2_CS_RANGE; + size = sizeof(buf); + } + + memset(buf, 0, sizeof(buf)); ret = snd_usb_ctl_msg(cval->mixer->chip->dev, usb_rcvctrlpipe(cval->mixer->chip->dev, 0), bRequest, USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN, validx, cval->mixer->ctrlif | (cval->id << 8), - buf, sizeof(buf), 1000); + buf, size, 1000); if (ret < 0) { snd_printk(KERN_ERR "cannot get ctl value: req = %#x, wValue = %#x, wIndex = %#x, type = %d\n", @@ -318,6 +325,8 @@ static int get_ctl_value_v2(struct usb_mixer_elem_info *cval, int request, int v return ret; } + /* FIXME: how should we handle multiple triplets here? */ + switch (request) { case UAC_GET_CUR: val = buf; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 0df6408..b938796 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -194,7 +194,7 @@ static void sig_handler(int sig) static void sig_atexit(void) { - if (child_pid != -1) + if (child_pid > 0) kill(child_pid, SIGTERM); if (signr == -1) diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index a746086..d7f21d7 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c @@ -538,8 +538,10 @@ int event__process_task(event_t *self, struct perf_session *session) dump_printf("(%d:%d):(%d:%d)\n", self->fork.pid, self->fork.tid, self->fork.ppid, self->fork.ptid); - if (self->header.type == PERF_RECORD_EXIT) + if (self->header.type == PERF_RECORD_EXIT) { + perf_session__remove_thread(session, thread); return 0; + } if (thread == NULL || parent == NULL || thread__fork(thread, parent) < 0) { diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c index 7bdbfd3..89c52fc 100644 --- a/tools/perf/util/newt.c +++ b/tools/perf/util/newt.c @@ -43,6 +43,9 @@ struct ui_progress *ui_progress__new(const char *title, u64 total) if (self != NULL) { int cols; + + if (use_browser <= 0) + return self; newtGetScreenSize(&cols, NULL); cols -= 4; newtCenteredWindow(cols, 1, title); @@ -67,14 +70,22 @@ out_free_self: void ui_progress__update(struct ui_progress *self, u64 curr) { + /* + * FIXME: We should have a per UI backend way of showing progress, + * stdio will just show a percentage as NN%, etc. + */ + if (use_browser <= 0) + return; newtScaleSet(self->scale, curr); newtRefresh(); } void ui_progress__delete(struct ui_progress *self) { - newtFormDestroy(self->form); - newtPopWindow(); + if (use_browser > 0) { + newtFormDestroy(self->form); + newtPopWindow(); + } free(self); } diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 0564a5c..0307918 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -92,6 +92,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc memcpy(self->filename, filename, len); self->threads = RB_ROOT; + INIT_LIST_HEAD(&self->dead_threads); self->hists_tree = RB_ROOT; self->last_match = NULL; self->mmap_window = 32; @@ -133,6 +134,16 @@ void perf_session__delete(struct perf_session *self) free(self); } +void perf_session__remove_thread(struct perf_session *self, struct thread *th) +{ + rb_erase(&th->rb_node, &self->threads); + /* + * We may have references to this thread, for instance in some hist_entry + * instances, so just move them to a separate list. + */ + list_add_tail(&th->node, &self->dead_threads); +} + static bool symbol__match_parent_regex(struct symbol *sym) { if (sym->name && !regexec(&parent_regex, sym->name, 0, NULL, 0)) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 55c6881..9fa0fc2 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -26,6 +26,7 @@ struct perf_session { unsigned long size; unsigned long mmap_window; struct rb_root threads; + struct list_head dead_threads; struct thread *last_match; struct machine host_machine; struct rb_root machines; @@ -99,6 +100,7 @@ int perf_session__create_kernel_maps(struct perf_session *self); int do_read(int fd, void *buf, size_t size); void perf_session__update_sample_type(struct perf_session *self); +void perf_session__remove_thread(struct perf_session *self, struct thread *th); static inline struct machine *perf_session__find_host_machine(struct perf_session *self) diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h index 1dfd9ff..ee6bbcf 100644 --- a/tools/perf/util/thread.h +++ b/tools/perf/util/thread.h @@ -6,7 +6,10 @@ #include "symbol.h" struct thread { - struct rb_node rb_node; + union { + struct rb_node rb_node; + struct list_head node; + }; struct map_groups mg; pid_t pid; char shortname[3]; |