aboutsummaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/mach-ebsa110/io.c8
-rw-r--r--arch/arm/mm/consistent.c3
-rw-r--r--arch/mips/mm/c-sb1.c22
-rw-r--r--arch/powerpc/kernel/time.c42
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c19
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c4
-rw-r--r--arch/um/include/os.h2
-rw-r--r--arch/um/os-Linux/Makefile10
-rw-r--r--arch/um/os-Linux/execvp.c149
-rw-r--r--arch/um/os-Linux/helper.c14
11 files changed, 215 insertions, 60 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index adb05de40e2..ce00c570459 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -879,6 +879,8 @@ endif
source "drivers/scsi/Kconfig"
+source "drivers/ata/Kconfig"
+
source "drivers/md/Kconfig"
source "drivers/message/fusion/Kconfig"
diff --git a/arch/arm/mach-ebsa110/io.c b/arch/arm/mach-ebsa110/io.c
index c648bfb676a..db38afb2aa8 100644
--- a/arch/arm/mach-ebsa110/io.c
+++ b/arch/arm/mach-ebsa110/io.c
@@ -28,7 +28,7 @@
#include <asm/io.h>
#include <asm/page.h>
-static void __iomem *__isamem_convert_addr(void __iomem *addr)
+static void __iomem *__isamem_convert_addr(const volatile void __iomem *addr)
{
u32 ret, a = (u32 __force) addr;
@@ -63,7 +63,7 @@ static void __iomem *__isamem_convert_addr(void __iomem *addr)
/*
* read[bwl] and write[bwl]
*/
-u8 __readb(void __iomem *addr)
+u8 __readb(const volatile void __iomem *addr)
{
void __iomem *a = __isamem_convert_addr(addr);
u32 ret;
@@ -75,7 +75,7 @@ u8 __readb(void __iomem *addr)
return ret;
}
-u16 __readw(void __iomem *addr)
+u16 __readw(const volatile void __iomem *addr)
{
void __iomem *a = __isamem_convert_addr(addr);
@@ -85,7 +85,7 @@ u16 __readw(void __iomem *addr)
return __raw_readw(a);
}
-u32 __readl(void __iomem *addr)
+u32 __readl(const volatile void __iomem *addr)
{
void __iomem *a = __isamem_convert_addr(addr);
u32 ret;
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 50e6b6bfb2e..b797217e82b 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -476,6 +476,9 @@ core_initcall(consistent_init);
/*
* Make an area consistent for devices.
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
*/
void consistent_sync(void *vaddr, size_t size, int direction)
{
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c
index d0ddb4a768a..3a8afd47fea 100644
--- a/arch/mips/mm/c-sb1.c
+++ b/arch/mips/mm/c-sb1.c
@@ -19,6 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <linux/init.h>
+#include <linux/hardirq.h>
#include <asm/asm.h>
#include <asm/bootinfo.h>
@@ -242,6 +243,25 @@ void sb1_flush_cache_page(struct vm_area_struct *vma, unsigned long addr, unsign
__attribute__((alias("local_sb1_flush_cache_page")));
#endif
+#ifdef CONFIG_SMP
+static void sb1_flush_cache_data_page_ipi(void *info)
+{
+ unsigned long start = (unsigned long)info;
+
+ __sb1_writeback_inv_dcache_range(start, start + PAGE_SIZE);
+}
+
+static void sb1_flush_cache_data_page(unsigned long addr)
+{
+ if (in_atomic())
+ __sb1_writeback_inv_dcache_range(addr, addr + PAGE_SIZE);
+ else
+ on_each_cpu(sb1_flush_cache_data_page_ipi, (void *) addr, 1, 1);
+}
+#else
+void sb1_flush_cache_data_page(unsigned long)
+ __attribute__((alias("local_sb1_flush_cache_data_page")));
+#endif
/*
* Invalidate all caches on this CPU
@@ -481,7 +501,7 @@ void sb1_cache_init(void)
flush_cache_sigtramp = sb1_flush_cache_sigtramp;
local_flush_data_cache_page = (void *) sb1_nop;
- flush_data_cache_page = (void *) sb1_nop;
+ flush_data_cache_page = sb1_flush_cache_data_page;
/* Full flush */
__flush_cache_all = sb1___flush_cache_all;
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index a1b5e4b1615..46a24de36fe 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -1014,48 +1014,6 @@ void __init time_init(void)
set_dec(tb_ticks_per_jiffy);
}
-#ifdef CONFIG_RTC_CLASS
-static int set_rtc_class_time(struct rtc_time *tm)
-{
- int err;
- struct class_device *class_dev =
- rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-
- if (class_dev == NULL)
- return -ENODEV;
-
- err = rtc_set_time(class_dev, tm);
-
- rtc_class_close(class_dev);
-
- return 0;
-}
-
-static void get_rtc_class_time(struct rtc_time *tm)
-{
- int err;
- struct class_device *class_dev =
- rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
-
- if (class_dev == NULL)
- return;
-
- err = rtc_read_time(class_dev, tm);
-
- rtc_class_close(class_dev);
-
- return;
-}
-
-int __init rtc_class_hookup(void)
-{
- ppc_md.get_rtc_time = get_rtc_class_time;
- ppc_md.set_rtc_time = set_rtc_class_time;
-
- return 0;
-}
-#endif /* CONFIG_RTC_CLASS */
-
#define FEBRUARY 2
#define STARTOFTIME 1970
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 54dea9d42dc..a43ac71ab74 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -24,6 +24,7 @@
#include <linux/root_dev.h>
#include <linux/initrd.h>
+#include <asm/of_device.h>
#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/time.h>
@@ -136,6 +137,24 @@ static void __init mpc832x_sys_setup_arch(void)
#endif
}
+static int __init mpc832x_declare_of_platform_devices(void)
+{
+ struct device_node *np;
+
+ for (np = NULL; (np = of_find_compatible_node(np, "network",
+ "ucc_geth")) != NULL;) {
+ int ucc_num;
+ char bus_id[BUS_ID_SIZE];
+
+ ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1;
+ snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num);
+ of_platform_device_create(np, bus_id, NULL);
+ }
+
+ return 0;
+}
+device_initcall(mpc832x_declare_of_platform_devices);
+
void __init mpc832x_sys_init_IRQ(void)
{
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 5446bab08ec..e2bcaaf6b32 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -108,10 +108,6 @@ static int __init mpc834x_itx_probe(void)
return 1;
}
-#ifdef CONFIG_RTC_CLASS
-late_initcall(rtc_class_hookup);
-#endif
-
define_machine(mpc834x_itx) {
.name = "MPC834x ITX",
.probe = mpc834x_itx_probe,
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 6516f6dca96..13a86bd383d 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -233,6 +233,8 @@ extern unsigned long __do_user_copy(void *to, const void *from, int n,
void (*op)(void *to, const void *from,
int n), int *faulted_out);
+/* execvp.c */
+extern int execvp_noalloc(char *buf, const char *file, char *const argv[]);
/* helper.c */
extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
unsigned long *stack_out);
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index b4183929b32..2f8c7946401 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,8 +3,8 @@
# Licensed under the GPL
#
-obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \
- signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
+obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
+ sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \
user_syms.o util.o drivers/ sys-$(SUBARCH)/
obj-$(CONFIG_MODE_SKAS) += skas/
@@ -15,9 +15,9 @@ user-objs-$(CONFIG_MODE_TT) += tt.o
obj-$(CONFIG_TTY_LOG) += tty_log.o
user-objs-$(CONFIG_TTY_LOG) += tty_log.o
-USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \
- process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \
- uaccess.o umid.o util.o
+USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
+ main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \
+ tls.o uaccess.o umid.o util.o
CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c
new file mode 100644
index 00000000000..66e583a4031
--- /dev/null
+++ b/arch/um/os-Linux/execvp.c
@@ -0,0 +1,149 @@
+/* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c.
+ Original copyright notice follows:
+
+ Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+#include <unistd.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#ifndef TEST
+#include "um_malloc.h"
+#else
+#include <stdio.h>
+#define um_kmalloc malloc
+#endif
+#include "os.h"
+
+/* Execute FILE, searching in the `PATH' environment variable if it contains
+ no slashes, with arguments ARGV and environment from `environ'. */
+int execvp_noalloc(char *buf, const char *file, char *const argv[])
+{
+ if (*file == '\0') {
+ return -ENOENT;
+ }
+
+ if (strchr (file, '/') != NULL) {
+ /* Don't search when it contains a slash. */
+ execv(file, argv);
+ } else {
+ int got_eacces;
+ size_t len, pathlen;
+ char *name, *p;
+ char *path = getenv("PATH");
+ if (path == NULL)
+ path = ":/bin:/usr/bin";
+
+ len = strlen(file) + 1;
+ pathlen = strlen(path);
+ /* Copy the file name at the top. */
+ name = memcpy(buf + pathlen + 1, file, len);
+ /* And add the slash. */
+ *--name = '/';
+
+ got_eacces = 0;
+ p = path;
+ do {
+ char *startp;
+
+ path = p;
+ //Let's avoid this GNU extension.
+ //p = strchrnul (path, ':');
+ p = strchr(path, ':');
+ if (!p)
+ p = strchr(path, '\0');
+
+ if (p == path)
+ /* Two adjacent colons, or a colon at the beginning or the end
+ of `PATH' means to search the current directory. */
+ startp = name + 1;
+ else
+ startp = memcpy(name - (p - path), path, p - path);
+
+ /* Try to execute this name. If it works, execv will not return. */
+ execv(startp, argv);
+
+ /*
+ if (errno == ENOEXEC) {
+ }
+ */
+
+ switch (errno) {
+ case EACCES:
+ /* Record the we got a `Permission denied' error. If we end
+ up finding no executable we can use, we want to diagnose
+ that we did find one but were denied access. */
+ got_eacces = 1;
+ case ENOENT:
+ case ESTALE:
+ case ENOTDIR:
+ /* Those errors indicate the file is missing or not executable
+ by us, in which case we want to just try the next path
+ directory. */
+ case ENODEV:
+ case ETIMEDOUT:
+ /* Some strange filesystems like AFS return even
+ stranger error numbers. They cannot reasonably mean
+ anything else so ignore those, too. */
+ case ENOEXEC:
+ /* We won't go searching for the shell
+ * if it is not executable - the Linux
+ * kernel already handles this enough,
+ * for us. */
+ break;
+
+ default:
+ /* Some other error means we found an executable file, but
+ something went wrong executing it; return the error to our
+ caller. */
+ return -errno;
+ }
+ } while (*p++ != '\0');
+
+ /* We tried every element and none of them worked. */
+ if (got_eacces)
+ /* At least one failure was due to permissions, so report that
+ error. */
+ return -EACCES;
+ }
+
+ /* Return the error from the last attempt (probably ENOENT). */
+ return -errno;
+}
+#ifdef TEST
+int main(int argc, char**argv)
+{
+ char buf[PATH_MAX];
+ int ret;
+ argc--;
+ if (!argc) {
+ fprintf(stderr, "Not enough arguments\n");
+ return 1;
+ }
+ argv++;
+ if (ret = execvp_noalloc(buf, argv[0], argv)) {
+ errno = -ret;
+ perror("execvp_noalloc");
+ }
+ return 0;
+}
+#endif
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index d13299cfa31..c7ad6306e22 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -8,18 +8,21 @@
#include <unistd.h>
#include <errno.h>
#include <sched.h>
+#include <limits.h>
#include <sys/signal.h>
#include <sys/wait.h>
#include "user.h"
#include "kern_util.h"
#include "user_util.h"
#include "os.h"
+#include "um_malloc.h"
struct helper_data {
void (*pre_exec)(void*);
void *pre_data;
char **argv;
int fd;
+ char *buf;
};
/* Debugging aid, changed only from gdb */
@@ -41,9 +44,8 @@ static int helper_child(void *arg)
}
if (data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data);
- execvp(argv[0], argv);
- errval = -errno;
- printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
+ errval = execvp_noalloc(data->buf, argv[0], argv);
+ printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval);
os_write_file(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL);
return 0;
@@ -84,11 +86,13 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
data.pre_data = pre_data;
data.argv = argv;
data.fd = fds[1];
+ data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) :
+ um_kmalloc(PATH_MAX);
pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
if (pid < 0) {
ret = -errno;
printk("run_helper : clone failed, errno = %d\n", errno);
- goto out_close;
+ goto out_free2;
}
close(fds[1]);
@@ -109,6 +113,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
CATCH_EINTR(waitpid(pid, NULL, 0));
}
+out_free2:
+ kfree(data.buf);
out_close:
if (fds[1] != -1)
close(fds[1]);