diff options
| author | David S. Miller <davem@kernel.bkbits.net> | 2004-09-13 10:25:41 -0700 |
|---|---|---|
| committer | David S. Miller <davem@kernel.bkbits.net> | 2004-09-13 10:25:41 -0700 |
| commit | 5ca8dc165f099da3f72ed6f6c459d6f1f52bd5e5 (patch) | |
| tree | 5969f0de681d489068d758409b44abc2cfc07774 | |
| parent | cf11cae7380e2da18f343dc48a1bc3074f2943d0 (diff) | |
| parent | 5c422c68d6e8cb32f6d3525858c5fb8bc71ef754 (diff) | |
Merge davem@nuts.davemloft.net:/disk1/BK/net-2.6
into kernel.bkbits.net:/home/davem/net-2.6
30 files changed, 408 insertions, 237 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 541bd7965909..0e4855419a72 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig @@ -32,6 +32,10 @@ config GENERIC_ISA_DMA bool default y +config GENERIC_IOMAP + bool + default y + source "init/Kconfig" diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 95aa273cdacf..aa709d12ef58 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -63,6 +63,10 @@ config GENERIC_BUST_SPINLOCK config GENERIC_ISA_DMA bool +config GENERIC_IOMAP + bool + default y + source "init/Kconfig" menu "System Type" diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 18c722a8e656..597a9969169e 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -29,6 +29,10 @@ config GENERIC_ISA_DMA bool default y +config GENERIC_IOMAP + bool + default y + source "init/Kconfig" menu "Processor type and features" diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 4459907b0a8a..aa742c601da2 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -38,6 +38,10 @@ config EFI bool default y +config GENERIC_IOMAP + bool + default y + choice prompt "System type" default IA64_GENERIC diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 955489b17307..2f048302c51b 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -20,7 +20,7 @@ AFLAGS_KERNEL := -mconstant-gp EXTRA := cflags-y := -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \ - -falign-functions=32 -frename-registers + -falign-functions=32 -frename-registers -fno-optimize-sibling-calls CFLAGS_KERNEL := -mconstant-gp GCC_VERSION := $(call cc-version) diff --git a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c index c42d87d3d790..cb91a4d0778e 100644 --- a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c +++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c @@ -357,7 +357,20 @@ sn_pci_fixup_slot(struct pci_dev *dev) if (dev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - } + } else { + /* + * Remove other ROM resources since they don't have valid + * CPU addresses. + */ + size = dev->resource[PCI_ROM_RESOURCE].end - + dev->resource[PCI_ROM_RESOURCE].start; + + if (size) { + dev->resource[PCI_ROM_RESOURCE].start = 0; + dev->resource[PCI_ROM_RESOURCE].end = 0; + dev->resource[PCI_ROM_RESOURCE].flags = 0; + } + } /* * Update the Command Word on the Card. diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c index 3d8f77edac1b..aa98abf43f5e 100644 --- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c +++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c @@ -10,67 +10,41 @@ #ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> +#include <linux/seq_file.h> #include <asm/sn/sgi.h> #include <asm/sn/sn_sal.h> - -static int partition_id_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) { - - return sprintf(page, "%d\n", sn_local_partid()); +static int partition_id_show(struct seq_file *s, void *p) +{ + seq_printf(s, "%d\n", sn_local_partid()); + return 0; } -static struct proc_dir_entry * sgi_proc_dir; - -void -register_sn_partition_id(void) { - struct proc_dir_entry *entry; - - if (!sgi_proc_dir) { - sgi_proc_dir = proc_mkdir("sgi_sn", 0); - } - entry = create_proc_entry("partition_id", 0444, sgi_proc_dir); - if (entry) { - entry->nlink = 1; - entry->data = 0; - entry->read_proc = partition_id_read_proc; - entry->write_proc = NULL; - } +static int partition_id_open(struct inode *inode, struct file *file) +{ + return single_open(file, partition_id_show, NULL); } -static int -system_serial_number_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) { - return sprintf(page, "%s\n", sn_system_serial_number()); +static int system_serial_number_show(struct seq_file *s, void *p) +{ + seq_printf(s, "%s\n", sn_system_serial_number()); + return 0; } -static int -licenseID_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) { - return sprintf(page, "0x%lx\n",sn_partition_serial_number_val()); +static int system_serial_number_open(struct inode *inode, struct file *file) +{ + return single_open(file, system_serial_number_show, NULL); } -void -register_sn_serial_numbers(void) { - struct proc_dir_entry *entry; +static int licenseID_show(struct seq_file *s, void *p) +{ + seq_printf(s, "0x%lx\n", sn_partition_serial_number_val()); + return 0; +} - if (!sgi_proc_dir) { - sgi_proc_dir = proc_mkdir("sgi_sn", 0); - } - entry = create_proc_entry("system_serial_number", 0444, sgi_proc_dir); - if (entry) { - entry->nlink = 1; - entry->data = 0; - entry->read_proc = system_serial_number_read_proc; - entry->write_proc = NULL; - } - entry = create_proc_entry("licenseID", 0444, sgi_proc_dir); - if (entry) { - entry->nlink = 1; - entry->data = 0; - entry->read_proc = licenseID_read_proc; - entry->write_proc = NULL; - } +static int licenseID_open(struct inode *inode, struct file *file) +{ + return single_open(file, licenseID_show, NULL); } /* @@ -81,70 +55,83 @@ register_sn_serial_numbers(void) { */ int sn_force_interrupt_flag = 1; -static int -sn_force_interrupt_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) { - if (sn_force_interrupt_flag) { - return sprintf(page, "Force interrupt is enabled\n"); - } - return sprintf(page, "Force interrupt is disabled\n"); +static int sn_force_interrupt_show(struct seq_file *s, void *p) +{ + seq_printf(s, "Force interrupt is %s\n", + sn_force_interrupt_flag ? "enabled" : "disabled"); + return 0; } -static int -sn_force_interrupt_write_proc(struct file *file, const char *buffer, - unsigned long count, void *data) +static ssize_t sn_force_interrupt_write_proc(struct file *file, + const __user char *buffer, size_t count, loff_t *data) { - if (*buffer == '0') { - sn_force_interrupt_flag = 0; - } else { - sn_force_interrupt_flag = 1; - } - return 1; + sn_force_interrupt_flag = (*buffer == '0') ? 0 : 1; + return count; } -void -register_sn_force_interrupt(void) { - struct proc_dir_entry *entry; - - if (!sgi_proc_dir) { - sgi_proc_dir = proc_mkdir("sgi_sn", 0); - } - entry = create_proc_entry("sn_force_interrupt",0444, sgi_proc_dir); - if (entry) { - entry->nlink = 1; - entry->data = 0; - entry->read_proc = sn_force_interrupt_read_proc; - entry->write_proc = sn_force_interrupt_write_proc; - } +static int sn_force_interrupt_open(struct inode *inode, struct file *file) +{ + return single_open(file, sn_force_interrupt_show, NULL); } -static int coherence_id_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) { - return sprintf(page, "%d\n", cpuid_to_coherence_id(smp_processor_id())); +static int coherence_id_show(struct seq_file *s, void *p) +{ + seq_printf(s, "%d\n", cpuid_to_coherence_id(smp_processor_id())); + return 0; } -void -register_sn_coherence_id(void) { - struct proc_dir_entry *entry; +static int coherence_id_open(struct inode *inode, struct file *file) +{ + return single_open(file, coherence_id_show, NULL); +} - if (!sgi_proc_dir) { - sgi_proc_dir = proc_mkdir("sgi_sn", 0); - } - entry = create_proc_entry("coherence_id", 0444, sgi_proc_dir); - if (entry) { - entry->nlink = 1; - entry->data = 0; - entry->read_proc = coherence_id_read_proc; - entry->write_proc = NULL; +static struct proc_dir_entry *sn_procfs_create_entry( + const char *name, struct proc_dir_entry *parent, + int (*openfunc)(struct inode *, struct file *), + int (*releasefunc)(struct inode *, struct file *)) +{ + struct proc_dir_entry *e = create_proc_entry(name, 0444, parent); + + if (e) { + e->proc_fops = (struct file_operations *)kmalloc( + sizeof(struct file_operations), GFP_KERNEL); + if (e->proc_fops) { + memset(e->proc_fops, 0, sizeof(struct file_operations)); + e->proc_fops->open = openfunc; + e->proc_fops->read = seq_read; + e->proc_fops->llseek = seq_lseek; + e->proc_fops->release = releasefunc; + } } + + return e; } -void -register_sn_procfs(void) { - register_sn_partition_id(); - register_sn_serial_numbers(); - register_sn_force_interrupt(); - register_sn_coherence_id(); +void register_sn_procfs(void) +{ + static struct proc_dir_entry *sgi_proc_dir = NULL; + struct proc_dir_entry *e; + + BUG_ON(sgi_proc_dir != NULL); + if (!(sgi_proc_dir = proc_mkdir("sgi_sn", 0))) + return; + + sn_procfs_create_entry("partition_id", sgi_proc_dir, + partition_id_open, single_release); + + sn_procfs_create_entry("system_serial_number", sgi_proc_dir, + system_serial_number_open, single_release); + + sn_procfs_create_entry("licenseID", sgi_proc_dir, + licenseID_open, single_release); + + e = sn_procfs_create_entry("sn_force_interrupt", sgi_proc_dir, + sn_force_interrupt_open, single_release); + if (e) + e->proc_fops->write = sn_force_interrupt_write_proc; + + sn_procfs_create_entry("coherence_id", sgi_proc_dir, + coherence_id_open, single_release); } #endif /* CONFIG_PROC_FS */ diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index 46139ac97563..81d55092fde0 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -35,6 +35,10 @@ config GENERIC_NVRAM bool default y +config GENERIC_IOMAP + bool + default y + source "init/Kconfig" menu "Processor" diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index c11f5cc5605a..706c53f58d0f 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -24,6 +24,10 @@ config GENERIC_ISA_DMA bool default y +config GENERIC_IOMAP + bool + default y + config HAVE_DEC_LOCK bool default y diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index a131337b9dac..6f55f43975c1 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -78,6 +78,10 @@ config GENERIC_ISA_DMA bool default y +config GENERIC_IOMAP + bool + default y + source "init/Kconfig" diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 37a7d88d66b9..964f80604e27 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -954,31 +954,25 @@ static void __init init_hwif_sis5513 (ide_hwif_t *hwif) return; } -#define DECLARE_SIS_DEV(name_str) \ - { \ - .name = name_str, \ - .init_chipset = init_chipset_sis5513, \ - .init_hwif = init_hwif_sis5513, \ - .channels = 2, \ - .autodma = NOAUTODMA, \ - .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, \ - .bootable = ON_BOARD, \ - } - -static ide_pci_device_t sis5513_chipsets[] __devinitdata = { - /* 0 */ DECLARE_SIS_DEV("SIS5513"), - /* 1 */ DECLARE_SIS_DEV("SIS5518") +static ide_pci_device_t sis5513_chipset __devinitdata = { + .name = "SIS5513", + .init_chipset = init_chipset_sis5513, + .init_hwif = init_hwif_sis5513, + .channels = 2, + .autodma = NOAUTODMA, + .enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}}, + .bootable = ON_BOARD, }; static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id) { - ide_setup_pci_device(dev, &sis5513_chipsets[id->driver_data]); + ide_setup_pci_device(dev, &sis5513_chipset); return 0; } static struct pci_device_id sis5513_pci_tbl[] = { { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, + { PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5518, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sis5513_pci_tbl); diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c index 78899221f2c3..19d999fd450c 100644 --- a/fs/isofs/rock.c +++ b/fs/isofs/rock.c @@ -62,7 +62,7 @@ } #define MAYBE_CONTINUE(LABEL,DEV) \ - {if (buffer) kfree(buffer); \ + {if (buffer) { kfree(buffer); buffer = NULL; } \ if (cont_extent){ \ int block, offset, offset1; \ struct buffer_head * pbh; \ diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h new file mode 100644 index 000000000000..cbd9e7f03a2a --- /dev/null +++ b/include/asm-generic/iomap.h @@ -0,0 +1,44 @@ +#ifndef __GENERIC_IO_H +#define __GENERIC_IO_H + +#include <linux/linkage.h> + +/* + * These are the "generic" interfaces for doing new-style + * memory-mapped or PIO accesses. Architectures may do + * their own arch-optimized versions, these just act as + * wrappers around the old-style IO register access functions: + * read[bwl]/write[bwl]/in[bwl]/out[bwl] + * + * Don't include this directly, include it from <asm/io.h>. + */ + +/* + * Read/write from/to an (offsettable) iomem cookie. It might be a PIO + * access or a MMIO access, these functions don't care. The info is + * encoded in the hardware mapping set up by the mapping functions + * (or the cookie itself, depending on implementation and hw). + * + * The generic routines just encode the PIO/MMIO as part of the + * cookie, and coldly assume that the MMIO IO mappings are not + * in the low address range. Architectures for which this is not + * true can't use this generic implementation. + */ +extern unsigned int fastcall ioread8(void __iomem *); +extern unsigned int fastcall ioread16(void __iomem *); +extern unsigned int fastcall ioread32(void __iomem *); + +extern void fastcall iowrite8(u8, void __iomem *); +extern void fastcall iowrite16(u16, void __iomem *); +extern void fastcall iowrite32(u32, void __iomem *); + +/* Create a virtual mapping cookie for an IO port range */ +extern void __iomem *ioport_map(unsigned int port, unsigned int nr); +extern void ioport_unmap(void __iomem *); + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +struct pci_dev; +extern void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max); +extern void pci_iounmap(struct pci_dev *dev, void __iomem *); + +#endif diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h index eced63913860..8d432bd90f2b 100644 --- a/include/asm-i386/dma-mapping.h +++ b/include/asm-i386/dma-mapping.h @@ -1,7 +1,6 @@ #ifndef _ASM_I386_DMA_MAPPING_H #define _ASM_I386_DMA_MAPPING_H -#include <linux/device.h> #include <linux/mm.h> #include <asm/cache.h> diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h index 20a26b98ec6e..083e3b8f8c7f 100644 --- a/include/asm-i386/io.h +++ b/include/asm-i386/io.h @@ -45,6 +45,8 @@ #ifdef __KERNEL__ +#include <asm-generic/iomap.h> + #include <linux/vmalloc.h> /** diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h index 695690a5429b..6347c9845642 100644 --- a/include/asm-ia64/dma-mapping.h +++ b/include/asm-ia64/dma-mapping.h @@ -6,7 +6,6 @@ * David Mosberger-Tang <davidm@hpl.hp.com> */ #include <linux/config.h> -#include <linux/device.h> #include <asm/machvec.h> #define dma_alloc_coherent platform_dma_alloc_coherent diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index a11cf994d526..716951187bf0 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -1,7 +1,6 @@ #ifndef _ASM_DMA_MAPPING_H #define _ASM_DMA_MAPPING_H -#include <linux/device.h> #include <asm/scatterlist.h> #include <asm/cache.h> diff --git a/include/asm-ppc/dma-mapping.h b/include/asm-ppc/dma-mapping.h index 9be4f7297400..7f0487afebbe 100644 --- a/include/asm-ppc/dma-mapping.h +++ b/include/asm-ppc/dma-mapping.h @@ -8,7 +8,6 @@ #include <linux/config.h> /* need struct page definitions */ #include <linux/mm.h> -#include <linux/device.h> #include <asm/scatterlist.h> #include <asm/io.h> diff --git a/include/asm-ppc64/dma-mapping.h b/include/asm-ppc64/dma-mapping.h index 0cdc5346f6f8..1e05f389e72b 100644 --- a/include/asm-ppc64/dma-mapping.h +++ b/include/asm-ppc64/dma-mapping.h @@ -8,7 +8,6 @@ #define _ASM_DMA_MAPPING_H #include <linux/types.h> -#include <linux/device.h> #include <linux/cache.h> /* need struct page definitions */ #include <linux/mm.h> diff --git a/include/asm-ppc64/io.h b/include/asm-ppc64/io.h index 33c2dfff9815..1e9cd557352e 100644 --- a/include/asm-ppc64/io.h +++ b/include/asm-ppc64/io.h @@ -18,6 +18,8 @@ #include <asm/memory.h> #include <asm/delay.h> +#include <asm-generic/iomap.h> + #define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 *)(p), (a), (c)) #define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 *)(p), (a), (c)) #define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 *)(p), (a), (c)) diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 8f149477ee2c..8876ec7b0e4d 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -3,7 +3,6 @@ #include <linux/config.h> #include <linux/mm.h> -#include <linux/device.h> #include <asm/scatterlist.h> #include <asm/io.h> diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h index 3a6424986b4b..b8d26fe677f4 100644 --- a/include/asm-sh64/dma-mapping.h +++ b/include/asm-sh64/dma-mapping.h @@ -3,7 +3,6 @@ #include <linux/config.h> #include <linux/mm.h> -#include <linux/device.h> #include <asm/scatterlist.h> #include <asm/io.h> diff --git a/include/asm-sparc/dma-mapping.h b/include/asm-sparc/dma-mapping.h index 08ede04f7eaf..2dc5bb8effa6 100644 --- a/include/asm-sparc/dma-mapping.h +++ b/include/asm-sparc/dma-mapping.h @@ -2,7 +2,6 @@ #define _ASM_SPARC_DMA_MAPPING_H #include <linux/config.h> -#include <linux/device.h> #ifdef CONFIG_PCI #include <asm-generic/dma-mapping.h> diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index 95102ecc1b70..a416dc31634a 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h @@ -7,7 +7,6 @@ */ #include <linux/config.h> -#include <linux/device.h> #include <asm/scatterlist.h> #include <asm/io.h> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 3c545e326d57..806c305332c1 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -1,6 +1,7 @@ #ifndef _ASM_LINUX_DMA_MAPPING_H #define _ASM_LINUX_DMA_MAPPING_H +#include <linux/device.h> #include <linux/err.h> /* These definitions mirror those in pci.h, so they can be used diff --git a/include/linux/sched.h b/include/linux/sched.h index b73710a9ac12..f5d4b9cae523 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1024,6 +1024,9 @@ static inline void arch_pick_mmap_layout(struct mm_struct *mm) } #endif +extern long sched_setaffinity(pid_t pid, cpumask_t new_mask); +extern long sched_getaffinity(pid_t pid, cpumask_t *mask); + #endif /* __KERNEL__ */ #endif diff --git a/kernel/compat.c b/kernel/compat.c index 4cc18476315c..33880d224077 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -412,92 +412,58 @@ compat_sys_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, } } -/* - * for maximum compatability, we allow programs to use a single (compat) - * unsigned long bitmask if all cpus will fit. If not, you have to have - * at least the kernel size available. - */ -#define USE_COMPAT_ULONG_CPUMASK (NR_CPUS <= BITS_PER_COMPAT_LONG) - -asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, - unsigned int len, - compat_ulong_t __user *user_mask_ptr) +static int compat_get_user_cpu_mask(compat_ulong_t __user *user_mask_ptr, + unsigned len, cpumask_t *new_mask) { - cpumask_t kern_mask; - mm_segment_t old_fs; - int ret; - - if (USE_COMPAT_ULONG_CPUMASK) { - compat_ulong_t user_mask; - - if (len < sizeof(user_mask)) - return -EINVAL; + unsigned long *k; - if (get_user(user_mask, user_mask_ptr)) - return -EFAULT; + if (len < sizeof(cpumask_t)) + memset(new_mask, 0, sizeof(cpumask_t)); + else if (len > sizeof(cpumask_t)) + len = sizeof(cpumask_t); - cpus_addr(kern_mask)[0] = user_mask; - } else { - unsigned long *k; + k = cpus_addr(*new_mask); + return compat_get_bitmap(k, user_mask_ptr, len * 8); +} - if (len < sizeof(kern_mask)) - return -EINVAL; +asmlinkage long compat_sys_sched_setaffinity(compat_pid_t pid, + unsigned int len, + compat_ulong_t __user *user_mask_ptr) +{ + cpumask_t new_mask; + int retval; - k = cpus_addr(kern_mask); - ret = compat_get_bitmap(k, user_mask_ptr, - sizeof(kern_mask) * BITS_PER_LONG); - if (ret) - return ret; - } + retval = compat_get_user_cpu_mask(user_mask_ptr, len, &new_mask); + if (retval) + return retval; - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_sched_setaffinity(pid, - sizeof(kern_mask), - (unsigned long __user *) &kern_mask); - set_fs(old_fs); - - return ret; + return sched_setaffinity(pid, new_mask); } asmlinkage long compat_sys_sched_getaffinity(compat_pid_t pid, unsigned int len, compat_ulong_t __user *user_mask_ptr) { - cpumask_t kern_mask; - mm_segment_t old_fs; int ret; + cpumask_t mask; + unsigned long *k; + unsigned int min_length = sizeof(cpumask_t); - if (len < (USE_COMPAT_ULONG_CPUMASK ? sizeof(compat_ulong_t) - : sizeof(kern_mask))) - return -EINVAL; + if (NR_CPUS <= BITS_PER_COMPAT_LONG) + min_length = sizeof(compat_ulong_t); - old_fs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_sched_getaffinity(pid, - sizeof(kern_mask), - (unsigned long __user *) &kern_mask); - set_fs(old_fs); + if (len < min_length) + return -EINVAL; + ret = sched_getaffinity(pid, &mask); if (ret < 0) return ret; - if (USE_COMPAT_ULONG_CPUMASK) { - if (put_user(&cpus_addr(kern_mask)[0], user_mask_ptr)) - return -EFAULT; - ret = sizeof(compat_ulong_t); - } else { - unsigned long *k; - - k = cpus_addr(kern_mask); - ret = compat_put_bitmap(user_mask_ptr, k, - sizeof(kern_mask) * BITS_PER_LONG); - if (ret) - return ret; - - ret = sizeof(kern_mask); - } + k = cpus_addr(mask); + ret = compat_put_bitmap(user_mask_ptr, k, min_length * 8); + if (ret) + return ret; - return ret; + return min_length; } static int get_compat_itimerspec(struct itimerspec *dst, diff --git a/kernel/sched.c b/kernel/sched.c index 7dd6c27f6094..3de761b2b262 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -3362,33 +3362,10 @@ out_unlock: return retval; } -static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len, - cpumask_t *new_mask) -{ - if (len < sizeof(cpumask_t)) { - memset(new_mask, 0, sizeof(cpumask_t)); - } else if (len > sizeof(cpumask_t)) { - len = sizeof(cpumask_t); - } - return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0; -} - -/** - * sys_sched_setaffinity - set the cpu affinity of a process - * @pid: pid of the process - * @len: length in bytes of the bitmask pointed to by user_mask_ptr - * @user_mask_ptr: user-space pointer to the new cpu mask - */ -asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) +long sched_setaffinity(pid_t pid, cpumask_t new_mask) { - cpumask_t new_mask; - int retval; task_t *p; - - retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask); - if (retval) - return retval; + int retval; lock_cpu_hotplug(); read_lock(&tasklist_lock); @@ -3421,6 +3398,36 @@ out_unlock: return retval; } +static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len, + cpumask_t *new_mask) +{ + if (len < sizeof(cpumask_t)) { + memset(new_mask, 0, sizeof(cpumask_t)); + } else if (len > sizeof(cpumask_t)) { + len = sizeof(cpumask_t); + } + return copy_from_user(new_mask, user_mask_ptr, len) ? -EFAULT : 0; +} + +/** + * sys_sched_setaffinity - set the cpu affinity of a process + * @pid: pid of the process + * @len: length in bytes of the bitmask pointed to by user_mask_ptr + * @user_mask_ptr: user-space pointer to the new cpu mask + */ +asmlinkage long sys_sched_setaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr) +{ + cpumask_t new_mask; + int retval; + + retval = get_user_cpu_mask(user_mask_ptr, len, &new_mask); + if (retval) + return retval; + + return sched_setaffinity(pid, new_mask); +} + /* * Represents all cpu's present in the system * In systems capable of hotplug, this map could dynamically grow @@ -3436,24 +3443,11 @@ cpumask_t cpu_online_map = CPU_MASK_ALL; cpumask_t cpu_possible_map = CPU_MASK_ALL; #endif -/** - * sys_sched_getaffinity - get the cpu affinity of a process - * @pid: pid of the process - * @len: length in bytes of the bitmask pointed to by user_mask_ptr - * @user_mask_ptr: user-space pointer to hold the current cpu mask - */ -asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, - unsigned long __user *user_mask_ptr) +long sched_getaffinity(pid_t pid, cpumask_t *mask) { - unsigned int real_len; - cpumask_t mask; int retval; task_t *p; - real_len = sizeof(mask); - if (len < real_len) - return -EINVAL; - lock_cpu_hotplug(); read_lock(&tasklist_lock); @@ -3463,16 +3457,40 @@ asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, goto out_unlock; retval = 0; - cpus_and(mask, p->cpus_allowed, cpu_possible_map); + cpus_and(*mask, p->cpus_allowed, cpu_possible_map); out_unlock: read_unlock(&tasklist_lock); unlock_cpu_hotplug(); if (retval) return retval; - if (copy_to_user(user_mask_ptr, &mask, real_len)) + + return 0; +} + +/** + * sys_sched_getaffinity - get the cpu affinity of a process + * @pid: pid of the process + * @len: length in bytes of the bitmask pointed to by user_mask_ptr + * @user_mask_ptr: user-space pointer to hold the current cpu mask + */ +asmlinkage long sys_sched_getaffinity(pid_t pid, unsigned int len, + unsigned long __user *user_mask_ptr) +{ + int ret; + cpumask_t mask; + + if (len < sizeof(cpumask_t)) + return -EINVAL; + + ret = sched_getaffinity(pid, &mask); + if (ret < 0) + return ret; + + if (copy_to_user(user_mask_ptr, &mask, sizeof(cpumask_t))) return -EFAULT; - return real_len; + + return sizeof(cpumask_t); } /** diff --git a/lib/Makefile b/lib/Makefile index b62c9ef212ed..bcd6e855e747 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -10,6 +10,7 @@ lib-y := errno.o ctype.o string.o vsprintf.o cmdline.o \ lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o +lib-$(CONFIG_GENERIC_IOMAP) += iomap.o ifneq ($(CONFIG_HAVE_DEC_LOCK),y) lib-y += dec_and_lock.o diff --git a/lib/iomap.c b/lib/iomap.c new file mode 100644 index 000000000000..42565c1e6543 --- /dev/null +++ b/lib/iomap.c @@ -0,0 +1,121 @@ +/* + * Implement the default iomap interfaces + */ +#include <linux/pci.h> +#include <linux/module.h> +#include <asm/io.h> + +/* + * Read/write from/to an (offsettable) iomem cookie. It might be a PIO + * access or a MMIO access, these functions don't care. The info is + * encoded in the hardware mapping set up by the mapping functions + * (or the cookie itself, depending on implementation and hw). + * + * The generic routines don't assume any hardware mappings, and just + * encode the PIO/MMIO as part of the cookie. They coldly assume that + * the MMIO IO mappings are not in the low address range. + * + * Architectures for which this is not true can't use this generic + * implementation and should do their own copy. + * + * We encode the physical PIO addresses (0-0xffff) into the + * pointer by offsetting them with a constant (0x10000) and + * assuming that all the low addresses are always PIO. That means + * we can do some sanity checks on the low bits, and don't + * need to just take things for granted. + */ +#define PIO_OFFSET 0x10000 +#define PIO_MASK 0x0ffff +#define PIO_RESERVED 0x40000 + +/* + * Ugly macros are a way of life. + */ +#define VERIFY_PIO(port) BUG_ON((port & ~PIO_MASK) != PIO_OFFSET) + +#define IO_COND(addr, is_pio, is_mmio) do { \ + unsigned long port = (unsigned long __force)addr; \ + if (port < PIO_RESERVED) { \ + VERIFY_PIO(port); \ + port &= PIO_MASK; \ + is_pio; \ + } else { \ + is_mmio; \ + } \ +} while (0) + +unsigned int fastcall ioread8(void __iomem *addr) +{ + IO_COND(addr, return inb(port), return readb(addr)); +} +unsigned int fastcall ioread16(void __iomem *addr) +{ + IO_COND(addr, return inw(port), return readw(addr)); +} +unsigned int fastcall ioread32(void __iomem *addr) +{ + IO_COND(addr, return inl(port), return readl(addr)); +} +EXPORT_SYMBOL(ioread8); +EXPORT_SYMBOL(ioread16); +EXPORT_SYMBOL(ioread32); + +void fastcall iowrite8(u8 val, void __iomem *addr) +{ + IO_COND(addr, outb(val,port), writeb(val, addr)); +} +void fastcall iowrite16(u16 val, void __iomem *addr) +{ + IO_COND(addr, outw(val,port), writew(val, addr)); +} +void fastcall iowrite32(u32 val, void __iomem *addr) +{ + IO_COND(addr, outl(val,port), writel(val, addr)); +} +EXPORT_SYMBOL(iowrite8); +EXPORT_SYMBOL(iowrite16); +EXPORT_SYMBOL(iowrite32); + +/* Create a virtual mapping cookie for an IO port range */ +void __iomem *ioport_map(unsigned int port, unsigned int nr) +{ + if (port > PIO_MASK) + return NULL; + return (void __iomem *) (unsigned long) (port + PIO_OFFSET); +} + +void ioport_unmap(void __iomem *addr) +{ + /* Nothing to do */ +} +EXPORT_SYMBOL(ioport_map); +EXPORT_SYMBOL(ioport_unmap); + +/* Create a virtual mapping cookie for a PCI BAR (memory or IO) */ +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + /* What? */ + return NULL; +} + +void pci_iounmap(struct pci_dev *dev, void __iomem * addr) +{ + IO_COND(addr, /* nothing */, iounmap(addr)); +} +EXPORT_SYMBOL(pci_iomap); +EXPORT_SYMBOL(pci_iounmap); |
