#ifndef __ALPHA_PERCPU_H
#define __ALPHA_PERCPU_H
+
#include <linux/compiler.h>
#include <linux/threads.h>
+#include <linux/percpu-defs.h>
/*
* Determine the real variable name from the name visible in the
#endif /* SMP */
-#include <asm-generic/percpu.h>
+#ifdef CONFIG_SMP
+#define PER_CPU_BASE_SECTION ".data.percpu"
+#else
+#define PER_CPU_BASE_SECTION ".data"
+#endif
+
+#ifdef CONFIG_SMP
+
+#ifdef MODULE
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#else
+#define PER_CPU_SHARED_ALIGNED_SECTION ".shared_aligned"
+#endif
+#define PER_CPU_FIRST_SECTION ".first"
+
+#else
+
+#define PER_CPU_SHARED_ALIGNED_SECTION ""
+#define PER_CPU_FIRST_SECTION ""
+
+#endif
+
+#define PER_CPU_ATTRIBUTES
#endif /* __ALPHA_PERCPU_H */
# cris object files path
OBJ_ARCH = $(objtree)/arch/cris
-boot := arch/cris/$(SARCH)/boot
+boot := arch/cris/boot
MACHINE := arch/cris/$(SARCH)
all: zImage
archprepare:
archclean:
- $(Q)if [ -e arch/cris/$(SARCH)/boot ]; then \
- $(MAKE) $(clean)=arch/cris/$(SARCH)/boot; \
+ $(Q)if [ -e arch/cris/boot ]; then \
+ $(MAKE) $(clean)=arch/cris/boot; \
fi
CLEAN_FILES += \
- $(MACHINE)/boot/zImage \
- $(MACHINE)/boot/compressed/decompress.bin \
- $(MACHINE)/boot/compressed/piggy.gz \
- $(MACHINE)/boot/rescue/rescue.bin
+ $(boot)/zImage \
+ $(boot)/compressed/decompress.bin \
+ $(boot)/compressed/piggy.gz \
+ $(boot)/rescue/rescue.bin
# MRPROPER_FILES +=
+++ /dev/null
-Creation of the self-extracting compressed kernel image (vmlinuz)
------------------------------------------------------------------
-$Id: README,v 1.1 2001/12/17 13:59:27 bjornw Exp $
-
-This can be slightly confusing because it's a process with many steps.
-
-The kernel object built by the arch/etrax100/Makefile, vmlinux, is split
-by that makefile into text and data binary files, vmlinux.text and
-vmlinux.data.
-
-Those files together with a ROM filesystem can be catted together and
-burned into a flash or executed directly at the DRAM origin.
-
-They can also be catted together and compressed with gzip, which is what
-happens in this makefile. Together they make up piggy.img.
-
-The decompressor is built into the file decompress.o. It is turned into
-the binary file decompress.bin, which is catted together with piggy.img
-into the file vmlinuz. It can be executed in an arbitrary place in flash.
-
-Be careful - it assumes some things about free locations in DRAM. It
-assumes the DRAM starts at 0x40000000 and that it is at least 8 MB,
-so it puts its code at 0x40700000, and initial stack at 0x40800000.
-
--Bjorn
+++ /dev/null
-/*
- * misc.c
- *
- * This is a collection of several routines from gzip-1.0.3
- * adapted for Linux.
- *
- * malloc by Hannu Savolainen 1993 and Matthias Urlichs 1994
- * puts by Nick Holloway 1993, better puts by Martin Mares 1995
- * adaptation for Linux/CRIS Axis Communications AB, 1999
- *
- */
-
-/* where the piggybacked kernel image expects itself to live.
- * it is the same address we use when we network load an uncompressed
- * image into DRAM, and it is the address the kernel is linked to live
- * at by vmlinux.lds.S
- */
-
-#define KERNEL_LOAD_ADR 0x40004000
-
-
-#include <linux/types.h>
-#include <arch/svinto.h>
-
-/*
- * gzip declarations
- */
-
-#define OF(args) args
-#define STATIC static
-
-void *memset(void *s, int c, size_t n);
-void *memcpy(void *__dest, __const void *__src, size_t __n);
-
-#define memzero(s, n) memset((s), 0, (n))
-
-typedef unsigned char uch;
-typedef unsigned short ush;
-typedef unsigned long ulg;
-
-#define WSIZE 0x8000 /* Window size must be at least 32k, */
- /* and a power of two */
-
-static uch *inbuf; /* input buffer */
-static uch window[WSIZE]; /* Sliding window buffer */
-
-unsigned inptr = 0; /* index of next byte to be processed in inbuf
- * After decompression it will contain the
- * compressed size, and head.S will read it.
- */
-
-static unsigned outcnt = 0; /* bytes in output buffer */
-
-/* gzip flag byte */
-#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
-#define CONTINUATION 0x02 /* bit 1 set: continuation of multi-part gzip file */
-#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
-#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
-#define COMMENT 0x10 /* bit 4 set: file comment present */
-#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
-#define RESERVED 0xC0 /* bit 6,7: reserved */
-
-#define get_byte() (inbuf[inptr++])
-
-/* Diagnostic functions */
-#ifdef DEBUG
-# define Assert(cond, msg) do { \
- if (!(cond)) \
- error(msg); \
- } while (0)
-# define Trace(x) fprintf x
-# define Tracev(x) do { \
- if (verbose) \
- fprintf x; \
- } while (0)
-# define Tracevv(x) do { \
- if (verbose > 1) \
- fprintf x; \
- } while (0)
-# define Tracec(c, x) do { \
- if (verbose && (c)) \
- fprintf x; \
- } while (0)
-# define Tracecv(c, x) do { \
- if (verbose > 1 && (c)) \
- fprintf x; \
- } while (0)
-#else
-# define Assert(cond, msg)
-# define Trace(x)
-# define Tracev(x)
-# define Tracevv(x)
-# define Tracec(c, x)
-# define Tracecv(c, x)
-#endif
-
-static void flush_window(void);
-static void error(char *m);
-
-extern char *input_data; /* lives in head.S */
-
-static long bytes_out = 0;
-static uch *output_data;
-static unsigned long output_ptr = 0;
-static void puts(const char *);
-
-/* the "heap" is put directly after the BSS ends, at end */
-
-extern int _end;
-static long free_mem_ptr = (long)&_end;
-static long free_mem_end_ptr;
-
-#include "../../../../../lib/inflate.c"
-
-/* decompressor info and error messages to serial console */
-
-static void
-puts(const char *s)
-{
-#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
- while (*s) {
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
- while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
- *R_SERIAL0_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
- while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
- *R_SERIAL1_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
- while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
- *R_SERIAL2_TR_DATA = *s++;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
- while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
- *R_SERIAL3_TR_DATA = *s++;
-#endif
- }
-#endif
-}
-
-void *memset(void *s, int c, size_t n)
-{
- int i;
- char *ss = (char *)s;
-
- for (i = 0; i < n; i++)
- ss[i] = c;
-
- return s;
-}
-
-void *memcpy(void *__dest, __const void *__src, size_t __n)
-{
- int i;
- char *d = (char *)__dest, *s = (char *)__src;
-
- for (i = 0; i < __n; i++)
- d[i] = s[i];
-
- return __dest;
-}
-
-/* ===========================================================================
- * Write the output window window[0..outcnt-1] and update crc and bytes_out.
- * (Used for the decompressed data only.)
- */
-
-static void flush_window(void)
-{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++) {
- ch = *out = *in;
- out++;
- in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
-}
-
-static void error(char *x)
-{
- puts("\n\n");
- puts(x);
- puts("\n\n -- System halted\n");
-
- while (1); /* Halt */
-}
-
-void setup_normal_output_buffer(void)
-{
- output_data = (char *)KERNEL_LOAD_ADR;
-}
-
-void decompress_kernel(void)
-{
- char revision;
-
- /* input_data is set in head.S */
- inbuf = input_data;
-
-#ifdef CONFIG_ETRAX_DEBUG_PORT0
- *R_SERIAL0_XOFF = 0;
- *R_SERIAL0_BAUD = 0x99;
- *R_SERIAL0_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT1
- *R_SERIAL1_XOFF = 0;
- *R_SERIAL1_BAUD = 0x99;
- *R_SERIAL1_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT2
- *R_GEN_CONFIG = 0x08;
- *R_SERIAL2_XOFF = 0;
- *R_SERIAL2_BAUD = 0x99;
- *R_SERIAL2_TR_CTRL = 0x40;
-#endif
-#ifdef CONFIG_ETRAX_DEBUG_PORT3
- *R_GEN_CONFIG = 0x100;
- *R_SERIAL3_XOFF = 0;
- *R_SERIAL3_BAUD = 0x99;
- *R_SERIAL3_TR_CTRL = 0x40;
-#endif
-
- setup_normal_output_buffer();
-
- makecrc();
-
- __asm__ volatile ("move $vr,%0" : "=rm" (revision));
- if (revision < 10) {
- puts("You need an ETRAX 100LX to run linux 2.6\n");
- while (1);
- }
-
- puts("Uncompressing Linux...\n");
- gunzip();
- puts("Done. Now booting the kernel.\n");
-}
movem $r13, [$sp]
push $r10 ; push orig_r10
clear.d [$sp=$sp-4] ; frametype == 0, normal frame
-
+
move.d $sp, $r10
jsr do_multiple_IRQ
-
+
jump ret_from_intr
do_sigtrap:
pop $r0 ; Restore r0.
ba do_sigtrap ; SIGTRAP the offending process.
pop $dccr ; Restore dccr in delay slot.
-
+
.global kernel_execve
kernel_execve:
move.d __NR_execve, $r9
.long sys_fallocate
.long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime
+ .long sys_signalfd4
+ .long sys_eventfd2
+ .long sys_epoll_create1
+ .long sys_dup3 /* 330 */
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
/*
* NOTE!! This doesn't have to be exact - we just have
+++ /dev/null
-#
-# arch/cris/arch-v32/boot/Makefile
-#
-
-OBJCOPYFLAGS = -O binary -R .note -R .comment
-
-subdir- := compressed rescue
-targets := Image
-
-$(obj)/Image: vmlinux FORCE
- $(call if_changed,objcopy)
- @echo ' Kernel: $@ is ready'
-
-$(obj)/compressed/vmlinux: $(obj)/Image FORCE
- $(Q)$(MAKE) $(build)=$(obj)/compressed $@
- $(Q)$(MAKE) $(build)=$(obj)/rescue $(obj)/rescue/rescue.bin
-
-$(obj)/zImage: $(obj)/compressed/vmlinux
- @cp $< $@
- @echo ' Kernel: $@ is ready'
+++ /dev/null
-#
-# arch/cris/arch-v32/boot/compressed/Makefile
-#
-
-asflags-y += -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
-ccflags-y += -O2 -I$(srctree)/include/asm/mach/ -I$(srctree)/include/asm/arch
-ldflags-y += -T$(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-
-quiet_cmd_image = BUILD $@
-cmd_image = cat $(obj)/decompress.bin $(obj)/piggy.gz > $@
-
-targets := vmlinux piggy.gz decompress.o decompress.bin
-
-$(obj)/decompress.o: $(OBJECTS) FORCE
- $(call if_changed,ld)
-
-$(obj)/decompress.bin: $(obj)/decompress.o FORCE
- $(call if_changed,objcopy)
-
-$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
- $(call if_changed,image)
-
-$(obj)/piggy.gz: $(obj)/../Image FORCE
- $(call if_changed,gzip)
+++ /dev/null
-#
-# Makefile for rescue (bootstrap) code
-#
-
-CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
-ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
- -I $(srctree)/include/asm/arch
-asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
-LD = gcc-cris -mlinux -march=v32 -nostdlib
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
-LDPOSTFLAGS = -lgcc
-OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
-
-targets := rescue.o rescue.bin
-
-quiet_cmd_ldlibgcc = LD $@
-cmd_ldlibgcc = $(LD) $(LDFLAGS) $(filter-out FORCE,$^) $(LDPOSTFLAGS) -o $@
-
-$(obj)/rescue.o: $(OBJECTS) FORCE
- $(call if_changed,ldlibgcc)
-
-$(obj)/rescue.bin: $(obj)/rescue.o FORCE
- $(call if_changed,objcopy)
- cp -p $(obj)/rescue.bin $(objtree)
shadow |= ~readl(dir_oe[priv->minor]) |
(arg & changeable_bits[priv->minor]);
i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_lock_irqrestore(&gpio_lock, flags);
+ spin_unlock_irqrestore(&gpio_lock, flags);
break;
case IO_CLRBITS:
spin_lock_irqsave(&gpio_lock, flags);
shadow |= ~readl(dir_oe[priv->minor]) &
~(arg & changeable_bits[priv->minor]);
i2c_write(VIRT_I2C_ADDR, (void *)&shadow, sizeof(shadow));
- spin_lock_irqrestore(&gpio_lock, flags);
+ spin_unlock_irqrestore(&gpio_lock, flags);
break;
case IO_HIGHALARM:
/* Set alarm when bits with 1 in arg go high. */
process.o ptrace.o setup.o signal.o traps.o time.o \
cache.o cacheflush.o
-obj-$(CONFIG_ETRAXFS_SIM) += vcs_hook.o
-
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_ETRAX_KGDB) += kgdb.o kgdb_asm.o
obj-$(CONFIG_ETRAX_FAST_TIMER) += fasttimer.o
.long sys_fallocate
.long sys_timerfd_settime /* 325 */
.long sys_timerfd_gettime
+ .long sys_signalfd4
+ .long sys_eventfd2
+ .long sys_epoll_create1
+ .long sys_dup3 /* 330 */
+ .long sys_pipe2
+ .long sys_inotify_init1
+ .long sys_preadv
+ .long sys_pwritev
/*
* NOTE!! This doesn't have to be exact - we just have
#
-# arch/cris/arch-v10/boot/Makefile
+# arch/cris/boot/Makefile
#
-OBJCOPYFLAGS = -O binary --remove-section=.bss
+objcopyflags-$(CONFIG_ETRAX_ARCH_V10) += -R .note -R .comment
+objcopyflags-$(CONFIG_ETRAX_ARCH_V32) += --remove-section=.bss
+
+OBJCOPYFLAGS = -O binary $(objcopyflags-y)
+
subdir- := compressed rescue
targets := Image
#
-# arch/cris/arch-v10/boot/compressed/Makefile
+# arch/cris/boot/compressed/Makefile
#
asflags-y += $(LINUXINCLUDE)
ccflags-y += -O2 $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/decompress.lds
-OBJECTS = $(obj)/head.o $(obj)/misc.o
+
+# asflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/mach \
+# -I$(srctree)/include/asm/arch
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -O2 -I$(srctree)/include/asm/mach
+# -I$(srctree)/include/asm/arch
+
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/decompress_$(arch-y).lds
+
+OBJECTS-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+OBJECTS-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS= $(OBJECTS-y) $(obj)/misc.o
OBJCOPYFLAGS = -O binary --remove-section=.bss
quiet_cmd_image = BUILD $@
$(obj)/piggy.gz: $(obj)/../Image FORCE
$(call if_changed,gzip)
-
beq dram_init_finished
nop
-#include "../../lib/dram_init.S"
+#include "../../arch-v10/lib/dram_init.S"
dram_init_finished:
.dword 0
_cmd_line_addr:
.dword 0
-#include "../../lib/hw_settings.S"
+#include "../../arch-v10/lib/hw_settings.S"
.globl input_data
.text
-_start:
+start:
di
;; Start clocks for used blocks.
nop
#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/dram_init.S"
+#include "../../arch-v32/mach-fs/dram_init.S"
#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/dram_init.S"
+#include "../../arch-v32/mach-a3/dram_init.S"
#else
#error Only ETRAXFS and ARTPEC-3 supported!
#endif
.dword 0
#if defined CONFIG_ETRAXFS
-#include "../../mach-fs/hw_settings.S"
+#include "../../arch-v32/mach-fs/hw_settings.S"
#elif defined CONFIG_CRIS_MACH_ARTPEC3
-#include "../../mach-a3/hw_settings.S"
+#include "../../arch-v32/mach-a3/hw_settings.S"
#else
#error Only ETRAXFS and ARTPEC-3 supported!
#endif
#define KERNEL_LOAD_ADR 0x40004000
-
#include <linux/types.h>
+
+#ifdef CONFIG_ETRAX_ARCH_V32
#include <hwregs/reg_rdwr.h>
#include <hwregs/reg_map.h>
#include <hwregs/ser_defs.h>
#ifdef CONFIG_CRIS_MACH_ARTPEC3
#include <hwregs/clkgen_defs.h>
#endif
+#else
+#include <arch/svinto.h>
+#endif
/*
* gzip declarations
#define OF(args) args
#define STATIC static
-void* memset(void* s, int c, size_t n);
-void* memcpy(void* __dest, __const void* __src,
- size_t __n);
-
-#define memzero(s, n) memset ((s), 0, (n))
+void *memset(void *s, int c, size_t n);
+void *memcpy(void *__dest, __const void *__src, size_t __n);
+#define memzero(s, n) memset((s), 0, (n))
typedef unsigned char uch;
typedef unsigned short ush;
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
#define RESERVED 0xC0 /* bit 6,7: reserved */
-#define get_byte() inbuf[inptr++]
+#define get_byte() (inbuf[inptr++])
/* Diagnostic functions */
#ifdef DEBUG
-# define Assert(cond,msg) {if(!(cond)) error(msg);}
+# define Assert(cond, msg) do { \
+ if (!(cond)) \
+ error(msg); \
+ } while (0)
# define Trace(x) fprintf x
-# define Tracev(x) {if (verbose) fprintf x ;}
-# define Tracevv(x) {if (verbose>1) fprintf x ;}
-# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
-# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
+# define Tracev(x) do { \
+ if (verbose) \
+ fprintf x; \
+ } while (0)
+# define Tracevv(x) do { \
+ if (verbose > 1) \
+ fprintf x; \
+ } while (0)
+# define Tracec(c, x) do { \
+ if (verbose && (c)) \
+ fprintf x; \
+ } while (0)
+# define Tracecv(c, x) do { \
+ if (verbose > 1 && (c)) \
+ fprintf x; \
+ } while (0)
#else
-# define Assert(cond,msg)
+# define Assert(cond, msg)
# define Trace(x)
# define Tracev(x)
# define Tracevv(x)
-# define Tracec(c,x)
-# define Tracecv(c,x)
+# define Tracec(c, x)
+# define Tracecv(c, x)
#endif
static void flush_window(void);
static void error(char *m);
+static void puts(const char *);
extern char *input_data; /* lives in head.S */
static uch *output_data;
static unsigned long output_ptr;
-static void error(char *m);
-
-static void puts(const char *);
-
/* the "heap" is put directly after the BSS ends, at end */
extern int _end;
/* decompressor info and error messages to serial console */
-static inline void
-serout(const char *s, reg_scope_instances regi_ser)
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serout(const char *s, reg_scope_instances regi_ser)
{
reg_ser_rs_stat_din rs;
reg_ser_rw_dout dout = {.data = *s};
REG_WR(ser, regi_ser, rw_dout, dout);
}
+#endif
-static void
-puts(const char *s)
+static void puts(const char *s)
{
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
while (*s) {
#ifdef CONFIG_ETRAX_DEBUG_PORT0
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser0);
+#else
+ while (!(*R_SERIAL0_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL0_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT1
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser1);
+#else
+ while (!(*R_SERIAL1_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL1_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT2
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser2);
+#else
+ while (!(*R_SERIAL2_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL2_TR_DATA = *s++;
+#endif
#endif
#ifdef CONFIG_ETRAX_DEBUG_PORT3
+#ifdef CONFIG_ETRAX_ARCH_V32
serout(s, regi_ser3);
+#else
+ while (!(*R_SERIAL3_STATUS & (1 << 5)))
+ ;
+ *R_SERIAL3_TR_DATA = *s++;
+#endif
#endif
*s++;
}
#endif
}
-void*
-memset(void* s, int c, size_t n)
+void *memset(void *s, int c, size_t n)
{
int i;
char *ss = (char*)s;
return s;
}
-void*
-memcpy(void* __dest, __const void* __src,
- size_t __n)
+void *memcpy(void *__dest, __const void *__src, size_t __n)
{
int i;
char *d = (char *)__dest, *s = (char *)__src;
- for (i=0;i<__n;i++) d[i] = s[i];
+ for (i = 0; i < __n; i++)
+ d[i] = s[i];
return __dest;
}
* (Used for the decompressed data only.)
*/
-static void
-flush_window()
+static void flush_window(void)
{
- ulg c = crc; /* temporary variable */
- unsigned n;
- uch *in, *out, ch;
-
- in = window;
- out = &output_data[output_ptr];
- for (n = 0; n < outcnt; n++) {
- ch = *out++ = *in++;
- c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
- }
- crc = c;
- bytes_out += (ulg)outcnt;
- output_ptr += (ulg)outcnt;
- outcnt = 0;
+ ulg c = crc; /* temporary variable */
+ unsigned n;
+ uch *in, *out, ch;
+
+ in = window;
+ out = &output_data[output_ptr];
+ for (n = 0; n < outcnt; n++) {
+ ch = *out = *in;
+ out++;
+ in++;
+ c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
+ }
+ crc = c;
+ bytes_out += (ulg)outcnt;
+ output_ptr += (ulg)outcnt;
+ outcnt = 0;
}
-static void
-error(char *x)
+static void error(char *x)
{
- puts("\r\n\n");
+ puts("\n\n");
puts(x);
- puts("\r\n\n -- System halted\n");
+ puts("\n\n -- System halted\n");
while(1); /* Halt */
}
-void
-setup_normal_output_buffer(void)
+void setup_normal_output_buffer(void)
{
output_data = (char *)KERNEL_LOAD_ADR;
}
-static inline void
-serial_setup(reg_scope_instances regi_ser)
+#ifdef CONFIG_ETRAX_ARCH_V32
+static inline void serial_setup(reg_scope_instances regi_ser)
{
reg_ser_rw_xoff xoff;
reg_ser_rw_tr_ctrl tr_ctrl;
REG_WR(ser, regi_ser, rw_rec_ctrl, rec_ctrl);
REG_WR(ser, regi_ser, rw_rec_baud_div, rec_baud);
}
+#endif
-void
-decompress_kernel(void)
+void decompress_kernel(void)
{
char revision;
+ char compile_rev;
+#ifdef CONFIG_ETRAX_ARCH_V32
+ /* Need at least a CRISv32 to run. */
+ compile_rev = 32;
#if defined(CONFIG_ETRAX_DEBUG_PORT1) || \
defined(CONFIG_ETRAX_DEBUG_PORT2) || \
defined(CONFIG_ETRAX_DEBUG_PORT3)
hwprot = REG_RD(pinmux, regi_pinmux, rw_hwprot);
#endif
+
#ifdef CONFIG_ETRAX_DEBUG_PORT0
serial_setup(regi_ser0);
#endif
/* input_data is set in head.S */
inbuf = input_data;
+#else /* CRISv10 */
+ /* Need at least a crisv10 to run. */
+ compile_rev = 10;
+
+ /* input_data is set in head.S */
+ inbuf = input_data;
+
+#ifdef CONFIG_ETRAX_DEBUG_PORT0
+ *R_SERIAL0_XOFF = 0;
+ *R_SERIAL0_BAUD = 0x99;
+ *R_SERIAL0_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT1
+ *R_SERIAL1_XOFF = 0;
+ *R_SERIAL1_BAUD = 0x99;
+ *R_SERIAL1_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT2
+ *R_GEN_CONFIG = 0x08;
+ *R_SERIAL2_XOFF = 0;
+ *R_SERIAL2_BAUD = 0x99;
+ *R_SERIAL2_TR_CTRL = 0x40;
+#endif
+#ifdef CONFIG_ETRAX_DEBUG_PORT3
+ *R_GEN_CONFIG = 0x100;
+ *R_SERIAL3_XOFF = 0;
+ *R_SERIAL3_BAUD = 0x99;
+ *R_SERIAL3_TR_CTRL = 0x40;
+#endif
+#endif
setup_normal_output_buffer();
makecrc();
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
- if (revision < 32)
- {
- puts("You need an ETRAX FS to run Linux 2.6/crisv32.\r\n");
+ if (revision < compile_rev) {
+#ifdef CONFIG_ETRAX_ARCH_V32
+ puts("You need an ETRAX FS to run Linux 2.6/crisv32\n");
+#else
+ puts("You need an ETRAX 100LX to run linux 2.6\n");
+#endif
while(1);
}
- puts("Uncompressing Linux...\r\n");
+ puts("Uncompressing Linux...\n");
gunzip();
- puts("Done. Now booting the kernel.\r\n");
+ puts("Done. Now booting the kernel\n");
}
# Makefile for rescue (bootstrap) code
#
-ccflags-y += -O2 $(LINUXINCLUDE)
+# CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
+# ccflags-$(CONFIG_ETRAX_ARCH_V32) += -I$(srctree)/include/asm/arch/mach/ \
+# -I$(srctree)/include/asm/arch
+# asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
+# LD = gcc-cris -mlinux -march=v32 -nostdlib
+
asflags-y += $(LINUXINCLUDE)
-ldflags-y += -T $(srctree)/$(src)/rescue.lds
+ccflags-y += -O2 $(LINUXINCLUDE)
+arch-$(CONFIG_ETRAX_ARCH_V10) = v10
+arch-$(CONFIG_ETRAX_ARCH_V32) = v32
+
+ldflags-y += -T $(srctree)/$(src)/rescue_$(arch-y).lds
OBJCOPYFLAGS = -O binary --remove-section=.bss
-obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
-OBJECT := $(obj)/head.o
+obj-$(CONFIG_ETRAX_ARCH_V32) = $(obj)/head_v32.o
+obj-$(CONFIG_ETRAX_ARCH_V10) = $(obj)/head_v10.o
+OBJECTS := $(obj-y)
targets := rescue.o rescue.bin
-$(obj)/rescue.o: $(OBJECT) FORCE
+$(obj)/rescue.o: $(OBJECTS) FORCE
$(call if_changed,ld)
$(obj)/rescue.bin: $(obj)/rescue.o FORCE
dd if=testrescue_tmp.bin of=$(obj)/testrescue.bin bs=1 count=784
rm tr.bin tmp2423 testrescue_tmp.bin
+
$(obj)/kimagerescue.bin: $(obj)/kimagerescue.o
$(OBJCOPY) $(OBJCOPYFLAGS) $(obj)/kimagerescue.o ktr.bin
# Pad it to 784 bytes, that's what the rescue loader expects
cat ktr.bin tmp2423 >kimagerescue_tmp.bin
dd if=kimagerescue_tmp.bin of=$(obj)/kimagerescue.bin bs=1 count=784
rm ktr.bin tmp2423 kimagerescue_tmp.bin
+
#endif
;; We need to setup the bus registers before we start using the DRAM
-#include "../../lib/dram_init.S"
+#include "../../../arch-v10/lib/dram_init.S"
;; we now should go through the checksum-table and check the listed
;; partitions for errors.
#define __NR_mbind 274
#define __NR_get_mempolicy 275
#define __NR_set_mempolicy 276
-#define __NR_mq_open 277
+#define __NR_mq_open 277
#define __NR_mq_unlink (__NR_mq_open+1)
#define __NR_mq_timedsend (__NR_mq_open+2)
#define __NR_mq_timedreceive (__NR_mq_open+3)
#define __NR_fallocate 324
#define __NR_timerfd_settime 325
#define __NR_timerfd_gettime 326
+#define __NR_signalfd4 327
+#define __NR_eventfd2 328
+#define __NR_epoll_create1 329
+#define __NR_dup3 330
+#define __NR_pipe2 331
+#define __NR_inotify_init1 332
+#define __NR_preadv 333
+#define __NR_pwritev 334
#ifdef __KERNEL__
-#define NR_syscalls 327
+#define NR_syscalls 335
#include <arch/unistd.h>
* ICH2 spec c #20 - IDE PRD must not cross a 64K boundary
* and must be dword aligned
* ICH2 spec c #24 - UDMA mode 4,5 t85/86 should be 6ns not 3.3
+ * ICH7 errata #16 - MWDMA1 timings are incorrect
*
* Should have been BIOS fixed:
* 450NX: errata #19 - DMA hangs on old 450NX
#include <linux/dmi.h>
#define DRV_NAME "ata_piix"
-#define DRV_VERSION "2.12"
+#define DRV_VERSION "2.13"
enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
ich_pata_33, /* ICH up to UDMA 33 only */
ich_pata_66, /* ICH up to 66 Mhz */
ich_pata_100, /* ICH up to UDMA 100 */
+ ich_pata_100_nomwdma1, /* ICH up to UDMA 100 but with no MWDMA1*/
ich5_sata,
ich6_sata,
ich6m_sata,
/* ICH6 (and 6) (i915) UDMA 100 */
{ 0x8086, 0x266F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
/* ICH7/7-R (i945, i975) UDMA 100*/
- { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
- { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
+ { 0x8086, 0x27DF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
+ { 0x8086, 0x269E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100_nomwdma1 },
/* ICH8 Mobile PATA Controller */
{ 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 },
.port_ops = &ich_pata_ops,
},
+ [ich_pata_100_nomwdma1] =
+ {
+ .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
+ .pio_mask = ATA_PIO4,
+ .mwdma_mask = ATA_MWDMA2_ONLY,
+ .udma_mask = ATA_UDMA5,
+ .port_ops = &ich_pata_ops,
+ },
+
[ich5_sata] =
{
.flags = PIIX_SATA_FLAGS,
{ 0x24CA, 0x1025, 0x003d }, /* ICH4 on ACER TM290 */
{ 0x266F, 0x1025, 0x0066 }, /* ICH6 on ACER Aspire 1694WLMi */
{ 0x2653, 0x1043, 0x82D8 }, /* ICH6M on Asus Eee 701 */
+ { 0x27df, 0x104d, 0x900e }, /* ICH7 on Sony TZ-90 */
/* end marker */
{ 0, }
};
/* fail early if !ATA && !ATAPI to avoid issuing [P]IDENTIFY to PMP */
if (ata_class_enabled(new_class) &&
- new_class != ATA_DEV_ATA && new_class != ATA_DEV_ATAPI) {
+ new_class != ATA_DEV_ATA &&
+ new_class != ATA_DEV_ATAPI &&
+ new_class != ATA_DEV_SEMB) {
ata_dev_printk(dev, KERN_INFO, "class mismatch %u != %u\n",
dev->class, new_class);
rc = -ENODEV;
} else if (dev->class == ATA_DEV_UNKNOWN &&
ehc->tries[dev->devno] &&
ata_class_enabled(ehc->classes[dev->devno])) {
+ /* Temporarily set dev->class, it will be
+ * permanently set once all configurations are
+ * complete. This is necessary because new
+ * device configuration is done in two
+ * separate loops.
+ */
dev->class = ehc->classes[dev->devno];
if (dev->class == ATA_DEV_PMP)
else
rc = ata_dev_read_id(dev, &dev->class,
readid_flags, dev->id);
+
+ /* read_id might have changed class, store and reset */
+ ehc->classes[dev->devno] = dev->class;
+ dev->class = ATA_DEV_UNKNOWN;
+
switch (rc) {
case 0:
/* clear error info accumulated during probe */
case -ENOENT:
/* IDENTIFY was issued to non-existent
* device. No need to reset. Just
- * thaw and kill the device.
+ * thaw and ignore the device.
*/
ata_eh_thaw_port(ap);
- dev->class = ATA_DEV_UNKNOWN;
break;
default:
- dev->class = ATA_DEV_UNKNOWN;
goto err;
}
}
dev->class == ATA_DEV_PMP)
continue;
+ dev->class = ehc->classes[dev->devno];
+
ehc->i.flags |= ATA_EHI_PRINTINFO;
rc = ata_dev_configure(dev);
ehc->i.flags &= ~ATA_EHI_PRINTINFO;
- if (rc)
+ if (rc) {
+ dev->class = ATA_DEV_UNKNOWN;
goto err;
+ }
spin_lock_irqsave(ap->lock, flags);
ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
*/
static void ata_eh_handle_port_resume(struct ata_port *ap)
{
+ struct ata_link *link;
+ struct ata_device *dev;
unsigned long flags;
int rc = 0;
WARN_ON(!(ap->pflags & ATA_PFLAG_SUSPENDED));
+ /*
+ * Error timestamps are in jiffies which doesn't run while
+ * suspended and PHY events during resume isn't too uncommon.
+ * When the two are combined, it can lead to unnecessary speed
+ * downs if the machine is suspended and resumed repeatedly.
+ * Clear error history.
+ */
+ ata_for_each_link(link, ap, HOST_FIRST)
+ ata_for_each_dev(dev, link, ALL)
+ ata_ering_clear(&dev->ering);
+
ata_acpi_set_state(ap, PMSG_ON);
if (ap->ops->port_resume)
return ap->ops->em_show(ap, buf);
return -EINVAL;
}
-DEVICE_ATTR(em_message, S_IRUGO | S_IWUGO,
+DEVICE_ATTR(em_message, S_IRUGO | S_IWUSR,
ata_scsi_em_message_show, ata_scsi_em_message_store);
EXPORT_SYMBOL_GPL(dev_attr_em_message);
}
return -EINVAL;
}
-DEVICE_ATTR(sw_activity, S_IWUGO | S_IRUGO, ata_scsi_activity_show,
+DEVICE_ATTR(sw_activity, S_IWUSR | S_IRUGO, ata_scsi_activity_show,
ata_scsi_activity_store);
EXPORT_SYMBOL_GPL(dev_attr_sw_activity);
* pata_pdc202xx_old.c - Promise PDC202xx PATA for new ATA layer
* (C) 2005 Red Hat Inc
* Alan Cox <alan@lxorguk.ukuu.org.uk>
- * (C) 2007 Bartlomiej Zolnierkiewicz
+ * (C) 2007,2009 Bartlomiej Zolnierkiewicz
*
* Based in part on linux/drivers/ide/pci/pdc202xx_old.c
*
u32 len;
/* Check we keep host level locking here */
- if (adev->dma_mode >= XFER_UDMA_2)
+ if (adev->dma_mode > XFER_UDMA_2)
iowrite8(ioread8(clock) | sel66, clock);
else
iowrite8(ioread8(clock) & ~sel66, clock);
iowrite8(ioread8(clock) & ~sel66, clock);
}
/* Flip back to 33Mhz for PIO */
- if (adev->dma_mode >= XFER_UDMA_2)
+ if (adev->dma_mode > XFER_UDMA_2)
iowrite8(ioread8(clock) & ~sel66, clock);
ata_bmdma_stop(qc);
pdc202xx_set_piomode(ap, adev);
FISCFG_WAIT_DEV_ERR = (1 << 8), /* wait for host on DevErr */
FISCFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+ PHY_MODE9_GEN2 = 0x398,
+ PHY_MODE9_GEN1 = 0x39c,
+ PHYCFG_OFS = 0x3a0, /* only in 65n devices */
+
MV5_PHY_MODE = 0x74,
MV5_LTMODE = 0x30,
MV5_PHY_CTL = 0x0C,
static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
.reset_bus = mv_soc_reset_bus,
};
+static const struct mv_hw_ops mv_soc_65n_ops = {
+ .phy_errata = mv_soc_65n_phy_errata,
+ .enable_leds = mv_soc_enable_leds,
+ .reset_hc = mv_soc_reset_hc,
+ .reset_flash = mv_soc_reset_flash,
+ .reset_bus = mv_soc_reset_bus,
+};
+
/*
* Functions
*/
return;
}
+static void mv_soc_65n_phy_errata(struct mv_host_priv *hpriv,
+ void __iomem *mmio, unsigned int port)
+{
+ void __iomem *port_mmio = mv_port_base(mmio, port);
+ u32 reg;
+
+ reg = readl(port_mmio + PHY_MODE3);
+ reg &= ~(0x3 << 27); /* SELMUPF (bits 28:27) to 1 */
+ reg |= (0x1 << 27);
+ reg &= ~(0x3 << 29); /* SELMUPI (bits 30:29) to 1 */
+ reg |= (0x1 << 29);
+ writel(reg, port_mmio + PHY_MODE3);
+
+ reg = readl(port_mmio + PHY_MODE4);
+ reg &= ~0x1; /* SATU_OD8 (bit 0) to 0, reserved bit 16 must be set */
+ reg |= (0x1 << 16);
+ writel(reg, port_mmio + PHY_MODE4);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN2);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN2);
+
+ reg = readl(port_mmio + PHY_MODE9_GEN1);
+ reg &= ~0xf; /* TXAMP[3:0] (bits 3:0) to 8 */
+ reg |= 0x8;
+ reg &= ~(0x1 << 14); /* TXAMP[4] (bit 14) to 0 */
+ writel(reg, port_mmio + PHY_MODE9_GEN1);
+}
+
+/**
+ * soc_is_65 - check if the soc is 65 nano device
+ *
+ * Detect the type of the SoC, this is done by reading the PHYCFG_OFS
+ * register, this register should contain non-zero value and it exists only
+ * in the 65 nano devices, when reading it from older devices we get 0.
+ */
+static bool soc_is_65n(struct mv_host_priv *hpriv)
+{
+ void __iomem *port0_mmio = mv_port_base(hpriv->base, 0);
+
+ if (readl(port0_mmio + PHYCFG_OFS))
+ return true;
+ return false;
+}
+
static void mv_setup_ifcfg(void __iomem *port_mmio, int want_gen2i)
{
u32 ifcfg = readl(port_mmio + SATA_IFCFG);
}
break;
case chip_soc:
- hpriv->ops = &mv_soc_ops;
+ if (soc_is_65n(hpriv))
+ hpriv->ops = &mv_soc_65n_ops;
+ else
+ hpriv->ops = &mv_soc_ops;
hp_flags |= MV_HP_FLAG_SOC | MV_HP_GEN_IIE |
MV_HP_ERRATA_60X1C0;
break;
n_hc = mv_get_hc_count(host->ports[0]->flags);
for (port = 0; port < host->n_ports; port++)
- hpriv->ops->read_preamp(hpriv, port, mmio);
+ if (hpriv->ops->read_preamp)
+ hpriv->ops->read_preamp(hpriv, port, mmio);
rc = hpriv->ops->reset_hc(hpriv, mmio, n_hc);
if (rc)
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE);
dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK |
+ DMA_COMPL_SRC_UNMAP_SINGLE |
+ DMA_COMPL_DEST_UNMAP_SINGLE;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE);
dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
dma_addr_t dma_dest, dma_src;
dma_cookie_t cookie;
int cpu;
+ unsigned long flags;
dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE);
dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len,
DMA_FROM_DEVICE);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len,
- DMA_CTRL_ACK);
+ flags = DMA_CTRL_ACK;
+ tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags);
if (!tx) {
dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE);
chan = dma_request_channel(mask, filter, NULL);
if (chan) {
err = dmatest_add_channel(chan);
- if (err == 0)
- continue;
- else {
+ if (err) {
dma_release_channel(chan);
break; /* add_channel failed, punt */
}
static void
ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc)
{
- /*
- * yes we are unmapping both _page and _single
- * alloc'd regions with unmap_page. Is this
- * *really* that bad?
- */
- if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP))
- pci_unmap_page(ioat_chan->device->pdev,
- pci_unmap_addr(desc, dst),
- pci_unmap_len(desc, len),
- PCI_DMA_FROMDEVICE);
-
- if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP))
- pci_unmap_page(ioat_chan->device->pdev,
- pci_unmap_addr(desc, src),
- pci_unmap_len(desc, len),
- PCI_DMA_TODEVICE);
+ if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
+ if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE)
+ pci_unmap_single(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, dst),
+ pci_unmap_len(desc, len),
+ PCI_DMA_FROMDEVICE);
+ else
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, dst),
+ pci_unmap_len(desc, len),
+ PCI_DMA_FROMDEVICE);
+ }
+
+ if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
+ if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE)
+ pci_unmap_single(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, src),
+ pci_unmap_len(desc, len),
+ PCI_DMA_TODEVICE);
+ else
+ pci_unmap_page(ioat_chan->device->pdev,
+ pci_unmap_addr(desc, src),
+ pci_unmap_len(desc, len),
+ PCI_DMA_TODEVICE);
+ }
}
/**
int err = 0;
struct completion cmp;
unsigned long tmo;
+ unsigned long flags;
src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL);
if (!src)
DMA_TO_DEVICE);
dma_dest = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE,
DMA_FROM_DEVICE);
+ flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE;
tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src,
- IOAT_TEST_SIZE, 0);
+ IOAT_TEST_SIZE, flags);
if (!tx) {
dev_err(&device->pdev->dev,
"Self-test prep failed, disabling\n");
/* Other interrupts do not interfere with this channel */
spin_lock(&ichan->lock);
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
- ((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
+ ((curbuf >> chan_id) & 1) == ichan->active_buffer &&
+ !list_is_last(ichan->queue.next, &ichan->queue))) {
int i = 100;
/* This doesn't help. See comment in ipu_disable_channel() */
struct idmac_channel *ichan = dev_id;
printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
irq, ichan->dma_chan.chan_id);
- disable_irq(irq);
+ disable_irq_nosync(irq);
return IRQ_HANDLED;
}
struct idmac_channel *ichan = dev_id;
printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
irq, ichan->dma_chan.chan_id);
- disable_irq(irq);
+ disable_irq_nosync(irq);
return IRQ_HANDLED;
}
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
select FB
+ select FRAMEBUFFER_CONSOLE if !EMBEDDED
tristate "i915 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
#define USB_VENDOR_ID_BERKSHIRE 0x0c98
#define USB_DEVICE_ID_BERKSHIRE_PCWD 0x1140
+#define USB_VENDOR_ID_CH 0x068e
+#define USB_DEVICE_ID_CH_PRO_PEDALS 0x00f2
+#define USB_DEVICE_ID_CH_COMBATSTICK 0x00f4
+#define USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE 0x00ff
+
#define USB_VENDOR_ID_CHERRY 0x046a
#define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023
goto err;
}
- hid->quirks = quirks;
+ hid->quirks |= quirks;
return 0;
err:
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_YOKE, HID_QUIRK_NOGET },
+ { USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_PRO_PEDALS, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_DMI, USB_DEVICE_ID_DMI_ENC, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_TS2700, HID_QUIRK_NOGET },
{ USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET },
config I2C_S3C2410
tristate "S3C2410 I2C Driver"
- depends on ARCH_S3C2410
+ depends on ARCH_S3C2410 || ARCH_S3C64XX
help
Say Y here to include support for I2C controller in the
Samsung S3C2410 based System-on-Chip devices.
rbdf = cpm->rbase;
for (i = 0; i < CPM_MAXBD; i++) {
- cpm->rxbuf[i] = dma_alloc_coherent(
- NULL, CPM_MAX_READ + 1, &cpm->rxdma[i], GFP_KERNEL);
+ cpm->rxbuf[i] = dma_alloc_coherent(&cpm->ofdev->dev,
+ CPM_MAX_READ + 1,
+ &cpm->rxdma[i], GFP_KERNEL);
if (!cpm->rxbuf[i]) {
ret = -ENOMEM;
goto out_muram;
}
out_be32(&rbdf[i].cbd_bufaddr, ((cpm->rxdma[i] + 1) & ~1));
- cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(
- NULL, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
+ cpm->txbuf[i] = (unsigned char *)dma_alloc_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1, &cpm->txdma[i], GFP_KERNEL);
if (!cpm->txbuf[i]) {
ret = -ENOMEM;
goto out_muram;
out_muram:
for (i = 0; i < CPM_MAXBD; i++) {
if (cpm->rxbuf[i])
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->rxbuf[i], cpm->rxdma[i]);
if (cpm->txbuf[i])
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->txbuf[i], cpm->txdma[i]);
}
cpm_muram_free(cpm->dp_addr);
/* Free all memory */
for (i = 0; i < CPM_MAXBD; i++) {
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->rxbuf[i], cpm->rxdma[i]);
- dma_free_coherent(NULL, CPM_MAX_READ + 1,
+ dma_free_coherent(&cpm->ofdev->dev, CPM_MAX_READ + 1,
cpm->txbuf[i], cpm->txdma[i]);
}
return 0;
}
-#ifdef CONFIG_PPC_52xx
+#ifdef CONFIG_PPC_MPC52xx
static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
{
- const struct mpc52xx_i2c_divider *div = NULL;
+ const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
u32 divider;
int i;
* We want to choose an FDR/DFSR that generates an I2C bus speed that
* is equal to or lower than the requested speed.
*/
- for (i = 0; i < ARRAY_SIZE(mpc52xx_i2c_dividers); i++) {
+ for (i = 0; i < ARRAY_SIZE(mpc_i2c_dividers_52xx); i++) {
div = &mpc_i2c_dividers_52xx[i];
/* Old MPC5200 rev A CPUs do not support the high bits */
if (div->fdr & 0xc0 && pvr == 0x80822011)
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
- int fdr = mpc52xx_i2c_get_fdr(node, clock, prescaler);
+ int ret, fdr;
+
+ ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
+ fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
- if (fdr < 0)
- fdr = 0x3f; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
- dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
+
+ if (ret >= 0)
+ dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
}
-#else /* !CONFIG_PPC_52xx */
+#else /* !CONFIG_PPC_MPC52xx */
static void mpc_i2c_setclock_52xx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
}
-#endif /* CONFIG_PPC_52xx*/
+#endif /* CONFIG_PPC_MPC52xx*/
#ifdef CONFIG_FSL_SOC
static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
- int fdr = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+ int ret, fdr;
+
+ ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
+ fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
- if (fdr < 0)
- fdr = 0x1031; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
writeb((fdr >> 8) & 0xff, i2c->base + MPC_I2C_DFSRR);
- dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
- clock, fdr >> 8, fdr & 0xff);
+
+ if (ret >= 0)
+ dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
+ clock, fdr >> 8, fdr & 0xff);
}
#else /* !CONFIG_FSL_SOC */
show_state(i2c);
}
- if (timeout <= 0)
+ if (timeout < 0)
show_state(i2c);
- return timeout <= 0 ? I2C_RETRY : 0;
+ return timeout < 0 ? I2C_RETRY : 0;
}
static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
show_state(i2c);
}
- if (timeout <= 0) {
+ if (timeout < 0) {
show_state(i2c);
dev_err(&i2c->adap.dev,
"i2c_pxa: timeout waiting for bus free\n");
ptr = wq->sq_rptr + count;
sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
while (ptr != wq->sq_wptr) {
+ sqp->signaled = 0;
insert_sq_cqe(wq, cq, sqp);
ptr++;
sqp = wq->sq + Q_PTR2IDX(ptr, wq->sq_size_log2);
struct mlx4_ib_fast_reg_page_list {
struct ib_fast_reg_page_list ibfrpl;
+ __be64 *mapped_page_list;
dma_addr_t map;
};
if (!mfrpl)
return ERR_PTR(-ENOMEM);
- mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
+ mfrpl->ibfrpl.page_list = kmalloc(size, GFP_KERNEL);
+ if (!mfrpl->ibfrpl.page_list)
+ goto err_free;
+
+ mfrpl->mapped_page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
size, &mfrpl->map,
GFP_KERNEL);
if (!mfrpl->ibfrpl.page_list)
return &mfrpl->ibfrpl;
err_free:
+ kfree(mfrpl->ibfrpl.page_list);
kfree(mfrpl);
return ERR_PTR(-ENOMEM);
}
struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
int size = page_list->max_page_list_len * sizeof (u64);
- dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list,
+ dma_free_coherent(&dev->dev->pdev->dev, size, mfrpl->mapped_page_list,
mfrpl->map);
+ kfree(mfrpl->ibfrpl.page_list);
kfree(mfrpl);
}
int i;
for (i = 0; i < wr->wr.fast_reg.page_list_len; ++i)
- wr->wr.fast_reg.page_list->page_list[i] =
+ mfrpl->mapped_page_list[i] =
cpu_to_be64(wr->wr.fast_reg.page_list->page_list[i] |
MLX4_MTT_FLAG_PRESENT);
*/
static void ml_combine_effects(struct ff_effect *effect,
struct ml_effect_state *state,
- int gain)
+ unsigned int gain)
{
struct ff_effect *new = state->effect;
unsigned int strong, weak, i;
INPUT_DEVICE_ID_MATCH_KEYBIT,
.evbit = { BIT_MASK(EV_KEY) },
.keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
- }, /* Avoid itouchpads, touchscreens and tablets */
+ }, /* Avoid itouchpads and touchscreens */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_KEYBIT,
+ .evbit = { BIT_MASK(EV_KEY) },
+ .keybit = { [BIT_WORD(BTN_DIGI)] = BIT_MASK(BTN_DIGI) },
+ }, /* Avoid tablets, digitisers and similar devices */
{ } /* Terminating entry */
};
0xb0, 0xae, -1U
};
+/*
+ * Amilo Xi 3650 key release for light touch bar not working
+ */
+static unsigned int atkbd_amilo_xi3650_forced_release_keys[] = {
+ 0x67, 0xed, 0x90, 0xa2, 0x99, 0xa4, 0xae, 0xb0, -1U
+};
+
/*
* atkbd_set_keycode_table() initializes keyboard's keycode table
* according to the selected scancode set
.callback = atkbd_setup_forced_release,
.driver_data = atkbd_amilo_pa1510_forced_release_keys,
},
+ {
+ .ident = "Fujitsu Amilo Xi 3650",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 3650"),
+ },
+ .callback = atkbd_setup_forced_release,
+ .driver_data = atkbd_amilo_xi3650_forced_release_keys,
+ },
{ }
};
static enum hrtimer_restart tsc2007_timer(struct hrtimer *handle)
{
struct tsc2007 *ts = container_of(handle, struct tsc2007, timer);
+ unsigned long flags;
- spin_lock_irq(&ts->lock);
+ spin_lock_irqsave(&ts->lock, flags);
if (unlikely(!ts->get_pendown_state() && ts->pendown)) {
struct input_dev *input = ts->input;
tsc2007_send_event(ts);
}
- spin_unlock_irq(&ts->lock);
+ spin_unlock_irqrestore(&ts->lock, flags);
return HRTIMER_NORESTART;
}
if (err) {
mlx4_err(mdev, "Failed to allocate qp #%d\n", qpn);
goto out;
- return err;
}
qp->event = mlx4_en_sqp_event;
#define DMA_32BIT_PFN IOVA_PFN(DMA_BIT_MASK(32))
#define DMA_64BIT_PFN IOVA_PFN(DMA_BIT_MASK(64))
+#ifndef PHYSICAL_PAGE_MASK
+#define PHYSICAL_PAGE_MASK PAGE_MASK
+#endif
+
/* global iommu list, set NULL for ignored DMAR units */
static struct intel_iommu **g_iommus;
if (!r->flags || !(r->flags & IORESOURCE_MEM))
continue;
addr = r->start;
- addr &= PAGE_MASK;
+ addr &= PHYSICAL_PAGE_MASK;
size = r->end - addr;
size = PAGE_ALIGN(size);
iova = reserve_iova(&reserved_iova_list, IOVA_PFN(addr),
* is not a big problem
*/
ret = domain_page_mapping(domain, start_paddr,
- ((u64)paddr) & PAGE_MASK, size, prot);
+ ((u64)paddr) & PHYSICAL_PAGE_MASK,
+ size, prot);
if (ret)
goto error;
addr = page_to_phys(sg_page(sg)) + sg->offset;
size = aligned_size((u64)addr, sg->length);
ret = domain_page_mapping(domain, start_addr + offset,
- ((u64)addr) & PAGE_MASK,
- size, prot);
+ ((u64)addr) & PHYSICAL_PAGE_MASK,
+ size, prot);
if (ret) {
/* clear the page */
dma_pte_clear_range(domain, start_addr,
{
irqstat = rtc_irq_bits;
- /* REVISIT alarm may need to wake us from sleep */
- mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M |
- BIT_RTC_INTERRUPTS_REG_IT_ALARM_M);
+ mask_rtc_irq_bit(BIT_RTC_INTERRUPTS_REG_IT_TIMER_M);
return 0;
}
{
struct chip_data *chip = spi_get_ctldata(spi);
+ if (!chip)
+ return;
+
if (gpio_is_valid(chip->gpio_cs))
gpio_free(chip->gpio_cs);
830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
Say Y if you have and plan to use such a board.
- If you say Y here and want DDC/I2C support you must first say Y to
- "I2C support" and "I2C bit-banging support" in the character devices
- section.
-
- If you say M here then "I2C support" and "I2C bit-banging support"
- can be build either as modules or built-in.
-
To compile this driver as a module, choose M here: the
module will be called intelfb.
pixel and 32 bpp packed pixel. You can also use font widths
different from 8.
- If you need support for G400 secondary head, you must first say Y to
- "I2C support" in the character devices section, and then to
- "Matrox I2C support" and "G400 second head support" here in the
- framebuffer section. G450/G550 secondary head and digital output
- are supported without additional modules.
+ If you need support for G400 secondary head, you must say Y to
+ "Matrox I2C support" and "G400 second head support" right below.
+ G450/G550 secondary head and digital output are supported without
+ additional modules.
The driver starts in monitor mode. You must use the matroxset tool
(available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
a framebuffer device. There are both PCI and AGP versions. You
don't need to choose this to run the Radeon in plain VGA mode.
- If you say Y here and want DDC/I2C support you must first say Y to
- "I2C support" and "I2C bit-banging support" in the character devices
- section.
-
- If you say M here then "I2C support" and "I2C bit-banging support"
- can be build either as modules or built-in.
-
There is a product page at
http://apps.ati.com/ATIcompare/
static int __devinit via_pci_probe(void)
{
- unsigned int default_xres, default_yres;
+ unsigned long default_xres, default_yres;
char *tmpc, *tmpm;
char *tmpc_sec, *tmpm_sec;
int vmode_index;
viafb_FB_MM = viaparinfo->fbmem_virt;
tmpm = viafb_mode;
tmpc = strsep(&tmpm, "x");
- strict_strtoul(tmpc, 0, (unsigned long *)&default_xres);
- strict_strtoul(tmpm, 0, (unsigned long *)&default_yres);
+ strict_strtoul(tmpc, 0, &default_xres);
+ strict_strtoul(tmpm, 0, &default_yres);
vmode_index = viafb_get_mode_index(default_xres, default_yres, 0);
DEBUG_MSG(KERN_INFO "0->index=%d\n", vmode_index);
SYSCALL_DEFINE1(epoll_create, int, size)
{
- if (size < 0)
+ if (size <= 0)
return -EINVAL;
return sys_epoll_create1(0);
{
if (unlikely(newfd == oldfd)) { /* corner case */
struct files_struct *files = current->files;
+ int retval = oldfd;
+
rcu_read_lock();
if (!fcheck_files(files, oldfd))
- oldfd = -EBADF;
+ retval = -EBADF;
rcu_read_unlock();
- return oldfd;
+ return retval;
}
return sys_dup3(oldfd, newfd, 0);
}
return retval;
}
-/*
- * Read a page. Again trivial. If it didn't already exist
- * in the page cache, it is zero-filled.
- */
-static int hugetlbfs_readpage(struct file *file, struct page * page)
-{
- unlock_page(page);
- return -EINVAL;
-}
-
static int hugetlbfs_write_begin(struct file *file,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
}
static const struct address_space_operations hugetlbfs_aops = {
- .readpage = hugetlbfs_readpage,
.write_begin = hugetlbfs_write_begin,
.write_end = hugetlbfs_write_end,
.set_page_dirty = hugetlbfs_set_page_dirty,
schedule_delayed_work(&grace_period_end, grace_period);
}
+static void restart_grace(void)
+{
+ if (nlmsvc_ops) {
+ cancel_delayed_work_sync(&grace_period_end);
+ locks_end_grace(&lockd_manager);
+ nlmsvc_invalidate_all();
+ set_grace_period();
+ }
+}
+
/*
* This is the lockd kernel thread
*/
if (signalled()) {
flush_signals(current);
- if (nlmsvc_ops) {
- nlmsvc_invalidate_all();
- set_grace_period();
- }
+ restart_grace();
continue;
}
goto out;
status = vfs_readdir(filp, nfsd4_build_namelist, &names);
fput(filp);
- mutex_lock(&dir->d_inode->i_mutex);
+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
while (!list_empty(&names)) {
entry = list_entry(names.next, struct name_list, list);
dprintk("NFSD: nfsd4_unlink_clid_dir. name %.*s\n", namlen, name);
- mutex_lock(&rec_dir.dentry->d_inode->i_mutex);
+ mutex_lock_nested(&rec_dir.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_one_len(name, rec_dir.dentry, namlen);
if (IS_ERR(dentry)) {
status = PTR_ERR(dentry);
struct nfsd4_cache_entry *e = &ses->se_slots[i].sl_cache_entry;
nfsd4_release_respages(e->ce_respages, e->ce_resused);
}
- kfree(ses->se_slots);
kfree(ses);
}
dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
if (IS_ERR(dentry))
return nfserrno(PTR_ERR(dentry));
+ if (!dentry->d_inode) {
+ /*
+ * nfsd_buffered_readdir drops the i_mutex between
+ * readdir and calling this callback, leaving a window
+ * where this directory entry could have gone away.
+ */
+ dput(dentry);
+ return nfserr_noent;
+ }
exp_get(exp);
/*
struct nfsd4_readdir *cd = container_of(ccd, struct nfsd4_readdir, common);
int buflen;
__be32 *p = cd->buffer;
+ __be32 *cookiep;
__be32 nfserr = nfserr_toosmall;
/* In nfsv4, "." and ".." never make it onto the wire.. */
goto fail;
*p++ = xdr_one; /* mark entry present */
- cd->offset = p; /* remember pointer */
+ cookiep = p;
p = xdr_encode_hyper(p, NFS_OFFSET_MAX); /* offset of next entry */
p = xdr_encode_array(p, name, namlen); /* name length & name */
goto fail;
case nfserr_dropit:
goto fail;
+ case nfserr_noent:
+ goto skip_entry;
default:
/*
* If the client requested the RDATTR_ERROR attribute,
}
cd->buflen -= (p - cd->buffer);
cd->buffer = p;
+ cd->offset = cookiep;
+skip_entry:
cd->common.err = nfs_ok;
return 0;
fail:
#include <linux/smp_lock.h> /* lock_kernel(), unlock_kernel() */
#include <linux/capability.h> /* capable() */
#include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
+#include <linux/vmalloc.h>
#include <linux/nilfs2_fs.h>
#include "nilfs.h"
#include "segment.h"
nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
- nmembs);
-}
-
-static int nilfs_ioctl_get_cpinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_cpinfo);
+ ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
+ nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
-}
-
-static int nilfs_ioctl_get_suinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_suinfo);
+ ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
void *buf, size_t size, size_t nmembs)
{
- return nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
-}
-
-static int nilfs_ioctl_get_vinfo(struct inode *inode, struct file *filp,
- unsigned int cmd, void __user *argp)
-{
- struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
- struct nilfs_argv argv;
int ret;
- if (copy_from_user(&argv, argp, sizeof(argv)))
- return -EFAULT;
-
down_read(&nilfs->ns_segctor_sem);
- ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
- nilfs_ioctl_do_get_vinfo);
+ ret = nilfs_dat_get_vinfo(nilfs_dat_inode(nilfs), buf, nmembs);
up_read(&nilfs->ns_segctor_sem);
- if (ret < 0)
- return ret;
-
- if (copy_to_user(argp, &argv, sizeof(argv)))
- ret = -EFAULT;
return ret;
}
struct nilfs_bdesc *bdescs = buf;
int ret, i;
+ down_read(&nilfs->ns_segctor_sem);
for (i = 0; i < nmembs; i++) {
ret = nilfs_bmap_lookup_at_level(bmap,
bdescs[i].bd_offset,
bdescs[i].bd_level + 1,
&bdescs[i].bd_blocknr);
if (ret < 0) {
- if (ret != -ENOENT)
+ if (ret != -ENOENT) {
+ up_read(&nilfs->ns_segctor_sem);
return ret;
+ }
bdescs[i].bd_blocknr = 0;
}
}
+ up_read(&nilfs->ns_segctor_sem);
return nmembs;
}
if (copy_from_user(&argv, argp, sizeof(argv)))
return -EFAULT;
- down_read(&nilfs->ns_segctor_sem);
+ if (argv.v_size != sizeof(struct nilfs_bdesc))
+ return -EINVAL;
+
ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
nilfs_ioctl_do_get_bdescs);
- up_read(&nilfs->ns_segctor_sem);
if (ret < 0)
return ret;
return 0;
}
-static ssize_t
-nilfs_ioctl_do_move_blocks(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
+static int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *inode;
struct nilfs_vdesc *vdesc;
struct buffer_head *bh, *n;
return ret;
}
-static inline int nilfs_ioctl_move_blocks(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_move_blocks);
-}
-
-static ssize_t
-nilfs_ioctl_do_delete_checkpoints(struct the_nilfs *nilfs, __u64 *posp,
- int flags, void *buf, size_t size,
- size_t nmembs)
+static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *cpfile = nilfs->ns_cpfile;
struct nilfs_period *periods = buf;
int ret, i;
return nmembs;
}
-static inline int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
+static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_delete_checkpoints);
-}
+ size_t nmembs = argv->v_nmembs;
+ int ret;
-static ssize_t
-nilfs_ioctl_do_free_vblocknrs(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
-{
- int ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
+ ret = nilfs_dat_freev(nilfs_dat_inode(nilfs), buf, nmembs);
return (ret < 0) ? ret : nmembs;
}
-static inline int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_free_vblocknrs);
-}
-
-static ssize_t
-nilfs_ioctl_do_mark_blocks_dirty(struct the_nilfs *nilfs, __u64 *posp,
- int flags, void *buf, size_t size,
- size_t nmembs)
+static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
+ size_t nmembs = argv->v_nmembs;
struct inode *dat = nilfs_dat_inode(nilfs);
struct nilfs_bmap *bmap = NILFS_I(dat)->i_bmap;
struct nilfs_bdesc *bdescs = buf;
return nmembs;
}
-static inline int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
+static int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
+ struct nilfs_argv *argv, void *buf)
{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_mark_blocks_dirty);
-}
-
-static ssize_t
-nilfs_ioctl_do_free_segments(struct the_nilfs *nilfs, __u64 *posp, int flags,
- void *buf, size_t size, size_t nmembs)
-{
- struct nilfs_sb_info *sbi = nilfs_get_writer(nilfs);
+ size_t nmembs = argv->v_nmembs;
+ struct nilfs_sb_info *sbi = nilfs->ns_writer;
int ret;
- if (unlikely(!sbi))
+ if (unlikely(!sbi)) {
+ /* never happens because called for a writable mount */
+ WARN_ON(1);
return -EROFS;
+ }
ret = nilfs_segctor_add_segments_to_be_freed(
NILFS_SC(sbi), buf, nmembs);
- nilfs_put_writer(nilfs);
return (ret < 0) ? ret : nmembs;
}
-static inline int nilfs_ioctl_free_segments(struct the_nilfs *nilfs,
- struct nilfs_argv *argv,
- int dir)
-{
- return nilfs_ioctl_wrap_copy(nilfs, argv, dir,
- nilfs_ioctl_do_free_segments);
-}
-
int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
- void __user *argp)
+ struct nilfs_argv *argv, void **kbufs)
{
- struct nilfs_argv argv[5];
const char *msg;
- int dir, ret;
-
- if (copy_from_user(argv, argp, sizeof(argv)))
- return -EFAULT;
+ int ret;
- dir = _IOC_WRITE;
- ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], dir);
+ ret = nilfs_ioctl_move_blocks(nilfs, &argv[0], kbufs[0]);
if (ret < 0) {
msg = "cannot read source blocks";
goto failed;
}
- ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], dir);
+
+ ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
if (ret < 0) {
/*
* can safely abort because checkpoints can be removed
msg = "cannot delete checkpoints";
goto failed;
}
- ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], dir);
+ ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
if (ret < 0) {
/*
* can safely abort because DAT file is updated atomically
msg = "cannot delete virtual blocks from DAT file";
goto failed;
}
- ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], dir);
+ ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
if (ret < 0) {
/*
* can safely abort because the operation is nondestructive.
msg = "cannot mark copying blocks dirty";
goto failed;
}
- ret = nilfs_ioctl_free_segments(nilfs, &argv[4], dir);
+ ret = nilfs_ioctl_free_segments(nilfs, &argv[4], kbufs[4]);
if (ret < 0) {
/*
* can safely abort because this operation is atomic.
static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
unsigned int cmd, void __user *argp)
{
+ struct nilfs_argv argv[5];
+ const static size_t argsz[5] = {
+ sizeof(struct nilfs_vdesc),
+ sizeof(struct nilfs_period),
+ sizeof(__u64),
+ sizeof(struct nilfs_bdesc),
+ sizeof(__u64),
+ };
+ void __user *base;
+ void *kbufs[5];
+ struct the_nilfs *nilfs;
+ size_t len, nsegs;
+ int n, ret;
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- return nilfs_clean_segments(inode->i_sb, argp);
+
+ if (copy_from_user(argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ nsegs = argv[4].v_nmembs;
+ if (argv[4].v_size != argsz[4])
+ return -EINVAL;
+ /*
+ * argv[4] points to segment numbers this ioctl cleans. We
+ * use kmalloc() for its buffer because memory used for the
+ * segment numbers is enough small.
+ */
+ kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
+ nsegs * sizeof(__u64));
+ if (IS_ERR(kbufs[4]))
+ return PTR_ERR(kbufs[4]);
+
+ nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+
+ for (n = 0; n < 4; n++) {
+ ret = -EINVAL;
+ if (argv[n].v_size != argsz[n])
+ goto out_free;
+
+ if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
+ goto out_free;
+
+ len = argv[n].v_size * argv[n].v_nmembs;
+ base = (void __user *)(unsigned long)argv[n].v_base;
+ if (len == 0) {
+ kbufs[n] = NULL;
+ continue;
+ }
+
+ kbufs[n] = vmalloc(len);
+ if (!kbufs[n]) {
+ ret = -ENOMEM;
+ goto out_free;
+ }
+ if (copy_from_user(kbufs[n], base, len)) {
+ ret = -EFAULT;
+ vfree(kbufs[n]);
+ goto out_free;
+ }
+ }
+
+ ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
+
+ out_free:
+ while (--n > 0)
+ vfree(kbufs[n]);
+ kfree(kbufs[4]);
+ return ret;
}
static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
return 0;
}
+static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
+ unsigned int cmd, void __user *argp,
+ size_t membsz,
+ ssize_t (*dofunc)(struct the_nilfs *,
+ __u64 *, int,
+ void *, size_t, size_t))
+
+{
+ struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs;
+ struct nilfs_argv argv;
+ int ret;
+
+ if (copy_from_user(&argv, argp, sizeof(argv)))
+ return -EFAULT;
+
+ if (argv.v_size != membsz)
+ return -EINVAL;
+
+ ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(argp, &argv, sizeof(argv)))
+ ret = -EFAULT;
+ return ret;
+}
+
long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
struct inode *inode = filp->f_dentry->d_inode;
case NILFS_IOCTL_DELETE_CHECKPOINT:
return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_CPINFO:
- return nilfs_ioctl_get_cpinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_cpinfo),
+ nilfs_ioctl_do_get_cpinfo);
case NILFS_IOCTL_GET_CPSTAT:
return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_SUINFO:
- return nilfs_ioctl_get_suinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_suinfo),
+ nilfs_ioctl_do_get_suinfo);
case NILFS_IOCTL_GET_SUSTAT:
return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
case NILFS_IOCTL_GET_VINFO:
- /* XXX: rename to ??? */
- return nilfs_ioctl_get_vinfo(inode, filp, cmd, argp);
+ return nilfs_ioctl_get_info(inode, filp, cmd, argp,
+ sizeof(struct nilfs_vinfo),
+ nilfs_ioctl_do_get_vinfo);
case NILFS_IOCTL_GET_BDESCS:
return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
case NILFS_IOCTL_CLEAN_SEGMENTS:
void *))
{
struct the_nilfs *nilfs = NILFS_MDT(inode)->mi_nilfs;
- struct nilfs_sb_info *writer = NULL;
struct super_block *sb = inode->i_sb;
struct nilfs_transaction_info ti;
struct buffer_head *bh;
int err;
if (!sb) {
- writer = nilfs_get_writer(nilfs);
- if (!writer) {
+ /*
+ * Make sure this function is not called from any
+ * read-only context.
+ */
+ if (!nilfs->ns_writer) {
+ WARN_ON(1);
err = -EROFS;
goto out;
}
- sb = writer->s_super;
+ sb = nilfs->ns_writer->s_super;
}
nilfs_transaction_begin(sb, &ti, 0);
err = nilfs_transaction_commit(sb);
else
nilfs_transaction_abort(sb);
- if (writer)
- nilfs_put_writer(nilfs);
out:
return err;
}
int err;
err = nilfs_bmap_delete(ii->i_bmap, block);
- if (likely(!err)) {
+ if (!err || err == -ENOENT) {
nilfs_mdt_mark_dirty(inode);
nilfs_mdt_forget_block(inode, block);
}
/* ioctl.c */
long nilfs_ioctl(struct file *, unsigned int, unsigned long);
-int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, void __user *);
+int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *,
+ void **);
/* inode.c */
extern struct inode *nilfs_new_inode(struct inode *, int);
lock_buffer(bh);
clear_buffer_nilfs_volatile(bh);
- if (test_clear_buffer_dirty(bh) && nilfs_page_buffers_clean(page))
+ clear_buffer_dirty(bh);
+ if (nilfs_page_buffers_clean(page))
__nilfs_clear_page_dirty(page);
clear_buffer_uptodate(bh);
}
static int nilfs_prepare_segment_for_recovery(struct the_nilfs *nilfs,
+ struct nilfs_sb_info *sbi,
struct nilfs_recovery_info *ri)
{
struct list_head *head = &ri->ri_used_segments;
segnum[2] = ri->ri_segnum;
segnum[3] = ri->ri_nextnum;
+ nilfs_attach_writer(nilfs, sbi);
/*
* Releasing the next segment of the latest super root.
* The next segment is invalidated by this recovery.
nilfs->ns_pseg_offset = 0;
nilfs->ns_seg_seq = ri->ri_seq + 2;
nilfs->ns_nextnum = nilfs->ns_segnum = segnum[0];
- return 0;
failed:
/* No need to recover sufile because it will be destroyed on error */
+ nilfs_detach_writer(nilfs, sbi);
return err;
}
goto failed;
if (ri->ri_need_recovery == NILFS_RECOVERY_ROLLFORWARD_DONE) {
- err = nilfs_prepare_segment_for_recovery(nilfs, ri);
+ err = nilfs_prepare_segment_for_recovery(nilfs, sbi, ri);
if (unlikely(err)) {
printk(KERN_ERR "NILFS: Error preparing segments for "
"recovery.\n");
}
}
-int nilfs_clean_segments(struct super_block *sb, void __user *argp)
+int nilfs_clean_segments(struct super_block *sb, struct nilfs_argv *argv,
+ void **kbufs)
{
struct nilfs_sb_info *sbi = NILFS_SB(sb);
struct nilfs_sc_info *sci = NILFS_SC(sbi);
err = nilfs_init_gcdat_inode(nilfs);
if (unlikely(err))
goto out_unlock;
- err = nilfs_ioctl_prepare_clean_segments(nilfs, argp);
+ err = nilfs_ioctl_prepare_clean_segments(nilfs, argv, kbufs);
if (unlikely(err))
goto out_unlock;
extern int nilfs_construct_dsync_segment(struct super_block *, struct inode *,
loff_t, loff_t);
extern void nilfs_flush_segment(struct super_block *, ino_t);
-extern int nilfs_clean_segments(struct super_block *, void __user *);
+extern int nilfs_clean_segments(struct super_block *, struct nilfs_argv *,
+ void **);
extern int nilfs_segctor_add_segments_to_be_freed(struct nilfs_sc_info *,
__u64 *, size_t);
* dependency chains
* @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s)
* @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s)
+ * @DMA_COMPL_SRC_UNMAP_SINGLE - set to do the source dma-unmapping as single
+ * (if not set, do the source dma-unmapping as page)
+ * @DMA_COMPL_DEST_UNMAP_SINGLE - set to do the destination dma-unmapping as single
+ * (if not set, do the destination dma-unmapping as page)
*/
enum dma_ctrl_flags {
DMA_PREP_INTERRUPT = (1 << 0),
DMA_CTRL_ACK = (1 << 1),
DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2),
DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3),
+ DMA_COMPL_SRC_UNMAP_SINGLE = (1 << 4),
+ DMA_COMPL_DEST_UNMAP_SINGLE = (1 << 5),
};
/**
asmlinkage long sys_fcntl64(unsigned int fd,
unsigned int cmd, unsigned long arg);
#endif
+asmlinkage long sys_pipe2(int __user *fildes, int flags);
asmlinkage long sys_dup(unsigned int fildes);
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd);
asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags);
if (!file)
return -EBADF;
- /*
- * Page cache readahead assumes page cache pages are order-0 which
- * is not the case for hugetlbfs. Do not give a bad return value
- * but ignore the advice.
- */
- if (vma->vm_flags & VM_HUGETLB)
- return 0;
-
if (file->f_mapping->a_ops->get_xip_mem) {
/* no bad return value, but ignore advice */
return 0;
frmr->page_list->page_list[page_no] =
ib_dma_map_single(xprt->sc_cm_id->device,
page_address(rqstp->rq_arg.pages[page_no]),
- PAGE_SIZE, DMA_TO_DEVICE);
+ PAGE_SIZE, DMA_FROM_DEVICE);
if (ib_dma_mapping_error(xprt->sc_cm_id->device,
frmr->page_list->page_list[page_no]))
goto fatal_err;
fatal_err:
printk("svcrdma: Error fast registering memory for xprt %p\n", xprt);
+ vec->frmr = NULL;
svc_rdma_put_frmr(xprt, frmr);
return -EIO;
}
"svcrdma: could not post a receive buffer, err=%d."
"Closing transport %p.\n", ret, rdma);
set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags);
+ svc_rdma_put_frmr(rdma, vec->frmr);
svc_rdma_put_context(ctxt, 0);
return -ENOTCONN;
}
return 0;
err:
+ svc_rdma_unmap_dma(ctxt);
svc_rdma_put_frmr(rdma, vec->frmr);
svc_rdma_put_context(ctxt, 1);
return -EIO;
svc_xprt_get(&xprt->sc_xprt);
ret = ib_post_recv(xprt->sc_qp, &recv_wr, &bad_recv_wr);
if (ret) {
- svc_xprt_put(&xprt->sc_xprt);
+ svc_rdma_unmap_dma(ctxt);
svc_rdma_put_context(ctxt, 1);
+ svc_xprt_put(&xprt->sc_xprt);
}
return ret;